diff --git a/Cargo.toml b/Cargo.toml index 9bcc085..c91358e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,3 +9,9 @@ base64 = "0.22.1" openssl = "0.10.68" serde = { version = "1.0.210", features = ["derive"] } serde_json = "1.0" + +[source.crates-io] +replace-with = "vendored-sources" + +[source.vendored-sources] +directory = "vendor" diff --git a/vendor/anyhow/.cargo-checksum.json b/vendor/anyhow/.cargo-checksum.json new file mode 100644 index 0000000..2462a1a --- /dev/null +++ b/vendor/anyhow/.cargo-checksum.json @@ -0,0 +1 @@ +{"files":{"Cargo.toml":"9da67208798e50ce1f391b56f0983e96fa8a84e9d9231d9e50775446cbf80d84","LICENSE-APACHE":"62c7a1e35f56406896d7aa7ca52d0cc0d272ac022b5d2796e7d6905db8a3636a","LICENSE-MIT":"23f18e03dc49df91622fe2a76176497404e46ced8a715d9d2b67a7446571cca3","README.md":"136d2b44cc4060192516f18e43ec3eafb65693c1819a80a867e7a00c60a45ee6","build.rs":"1de78cc91e63321318aa336cb550e3acdcda9b39f0648436a884d783247cfcd2","build/probe.rs":"ee0a4518493c0b3cca121ed2e937b1779eb7e8313a5c4d5fc5aea28ff015366b","rust-toolchain.toml":"6bbb61302978c736b2da03e4fb40e3beab908f85d533ab46fd541e637b5f3e0f","src/backtrace.rs":"bbaa0e0e228475c9c9532786e305cf04f53729f386c48adb1d93bb8ce07f37ad","src/chain.rs":"85af447405f075633fab186b7f1c94d7f33a36474f239c50a961b2d6197d5426","src/context.rs":"1be432c32752778041e8acf0e7d98d4f6291ce53fd7df5bbb0167824bbea57f7","src/ensure.rs":"9763f418b5397764549866c111ec6db3a7bdc4c30ad95c3bbfc56c5434ea8c09","src/error.rs":"274c175ec92f4aa8bf479d39cf3023d1ead9865a242a0a63ad3998aea57219a6","src/fmt.rs":"adf4be906b29900153bfb4b767a6049d58697dc3bcce7dfbb85ca773f5de5b33","src/kind.rs":"d8cc91e73653049ca0b5593f36aee8632fcc85847b36005b90ecd9a6f0de13cb","src/lib.rs":"1a1aeac072921cc13bb71ad06a9b8bd4cf4db5d90048d51446c3b81859722f24","src/macros.rs":"875797636fde708dcb9c82e0cb3107cf38334086274aaada267fb5bfd60547a9","src/ptr.rs":"4cb31d2f815b178daf951bfb94a1930383e056c0ca68d494603f45d8eea35d50","src/wrapper.rs":"d4e45caee3c2d861d4609a8141310d5c901af59a57d5f0a0de30251347dbd23c","tests/common/mod.rs":"f9088c2d7afafa64ff730b629272045b776bfafc2f5957508242da630635f2e1","tests/compiletest.rs":"4e381aa8ca3eabb7ac14d1e0c3700b3223e47640547a6988cfa13ad68255f60f","tests/drop/mod.rs":"08c3e553c1cc0d2dbd936fc45f4b5b1105057186affd6865e8d261e05f0f0646","tests/test_autotrait.rs":"ba9bc18416115cb48fd08675a3e7fc89584de7926dad6b2be6645dc13d5931df","tests/test_backtrace.rs":"60afdd7ee5850dc22625ff486fe41c47fd322db874a93c4871ddfed2bf603930","tests/test_boxed.rs":"6b26db0e2eb72afe9af7352ea820837aab90f8d486294616dd5dc34c1b94038c","tests/test_chain.rs":"3a8a8d7569913bd98c0e27c69d0bda35101e7fde7c056ed57cdd8ed018e4cbcb","tests/test_context.rs":"8409c53b328562c11e822bd6c3cd17e0d4d50b9bbb8fc3617333fd77303a6a33","tests/test_convert.rs":"7e7a8b4772a427a911014ac4d1083f9519000e786177f898808980dd9bdfde61","tests/test_downcast.rs":"797e69a72d125758c4c4897e5dc776d549d52cc9a6a633e0a33193f588a62b88","tests/test_ensure.rs":"4014ead6596793f5eecd55cbaafa49286b75cee7b7092a8b9b8286fcd813a6da","tests/test_ffi.rs":"d0cb4c1d6d9154090982dee72ae3ebe05a5981f976058c3250f1c9da5a45edef","tests/test_fmt.rs":"0e49b48f08e4faaf03e2f202e1efc5250018876c4e1b01b8379d7a38ae8df870","tests/test_macros.rs":"68673942662a43bceee62aaed69c25d7ddbc55e25d62d528e13033c3e2e756cd","tests/test_repr.rs":"034dee888abd08741e11ac2e95ef4fcb2ab3943d0a76e8e976db404658e1a252","tests/test_source.rs":"b80723cf635a4f8c4df21891b34bfab9ed2b2aa407e7a2f826d24e334cd5f88e","tests/ui/chained-comparison.rs":"6504b03d95b5acc232a7f4defc9f343b2be6733bf475fa0992e8e6545b912bd4","tests/ui/chained-comparison.stderr":"7f1d0a8c251b0ede2d30b3087ec157fc660945c97a642c4a5acf5a14ec58de34","tests/ui/empty-ensure.rs":"ab5bf37c846a0d689f26ce9257a27228411ed64154f9c950f1602d88a355d94b","tests/ui/empty-ensure.stderr":"315782f5f4246290fe190e3767b22c3dcaffaabc19c5ace0373537d53e765278","tests/ui/ensure-nonbool.rs":"7e57cb93fbcd82959b36586ed6bd2ad978b051fe5facd5274651fde6b1600905","tests/ui/ensure-nonbool.stderr":"0b4d1611e3bb65081bf38c1e49b1f12e5096738f276608661016e68f1fe13f7c","tests/ui/must-use.rs":"fb59860b43f673bf4a430a6036ba463e95028844d8dd4243cfe5ebc7f2be582f","tests/ui/must-use.stderr":"c2848c5f254b4c061eea6714d9baf709924aba06619eaf2a8b3aee1266b75f9e","tests/ui/no-impl.rs":"fab6cbf2f6ea510b86f567dfb3b7c31250a9fd71ae5d110dbb9188be569ec593","tests/ui/no-impl.stderr":"0d8ed712d25de898eae18cfdffc575a47f4d5596346058cf6cd50d016c4f8ce8","tests/ui/temporary-value.rs":"4dcc96271b2403e6372cf4cfc813445e5ce4365fc6e156b6bc38274098499a70","tests/ui/temporary-value.stderr":"171f6c1c962503855480696e5d39e68946ec2a027b61a6f36ca1ad1b40265c5d","tests/ui/wrong-interpolation.rs":"9c44d4674c2dccd27b9dedd03341346ec02d993b41793ee89b5755202e7e367e","tests/ui/wrong-interpolation.stderr":"301e60e2eb9401782c7dc0b3580613a4cb2aafd4cc8065734a630a62e1161aa5"},"package":"37bf3594c4c988a53154954629820791dde498571819ae4ca50ca811e060cc95"} \ No newline at end of file diff --git a/vendor/anyhow/Cargo.toml b/vendor/anyhow/Cargo.toml new file mode 100644 index 0000000..d8bb814 --- /dev/null +++ b/vendor/anyhow/Cargo.toml @@ -0,0 +1,127 @@ +# 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] +edition = "2018" +rust-version = "1.39" +name = "anyhow" +version = "1.0.90" +authors = ["David Tolnay "] +build = "build.rs" +autolib = false +autobins = false +autoexamples = false +autotests = false +autobenches = false +description = "Flexible concrete Error type built on std::error::Error" +documentation = "https://docs.rs/anyhow" +readme = "README.md" +keywords = [ + "error", + "error-handling", +] +categories = [ + "rust-patterns", + "no-std", +] +license = "MIT OR Apache-2.0" +repository = "https://github.com/dtolnay/anyhow" + +[package.metadata.docs.rs] +rustdoc-args = ["--generate-link-to-definition"] +targets = ["x86_64-unknown-linux-gnu"] + +[lib] +name = "anyhow" +path = "src/lib.rs" +doc-scrape-examples = false + +[[test]] +name = "compiletest" +path = "tests/compiletest.rs" + +[[test]] +name = "test_autotrait" +path = "tests/test_autotrait.rs" + +[[test]] +name = "test_backtrace" +path = "tests/test_backtrace.rs" + +[[test]] +name = "test_boxed" +path = "tests/test_boxed.rs" + +[[test]] +name = "test_chain" +path = "tests/test_chain.rs" + +[[test]] +name = "test_context" +path = "tests/test_context.rs" + +[[test]] +name = "test_convert" +path = "tests/test_convert.rs" + +[[test]] +name = "test_downcast" +path = "tests/test_downcast.rs" + +[[test]] +name = "test_ensure" +path = "tests/test_ensure.rs" + +[[test]] +name = "test_ffi" +path = "tests/test_ffi.rs" + +[[test]] +name = "test_fmt" +path = "tests/test_fmt.rs" + +[[test]] +name = "test_macros" +path = "tests/test_macros.rs" + +[[test]] +name = "test_repr" +path = "tests/test_repr.rs" + +[[test]] +name = "test_source" +path = "tests/test_source.rs" + +[dependencies.backtrace] +version = "0.3.51" +optional = true + +[dev-dependencies.futures] +version = "0.3" +default-features = false + +[dev-dependencies.rustversion] +version = "1.0.6" + +[dev-dependencies.syn] +version = "2.0" +features = ["full"] + +[dev-dependencies.thiserror] +version = "1.0.45" + +[dev-dependencies.trybuild] +version = "1.0.66" +features = ["diff"] + +[features] +default = ["std"] +std = [] diff --git a/vendor/anyhow/LICENSE-APACHE b/vendor/anyhow/LICENSE-APACHE new file mode 100644 index 0000000..1b5ec8b --- /dev/null +++ b/vendor/anyhow/LICENSE-APACHE @@ -0,0 +1,176 @@ + 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 diff --git a/vendor/anyhow/LICENSE-MIT b/vendor/anyhow/LICENSE-MIT new file mode 100644 index 0000000..31aa793 --- /dev/null +++ b/vendor/anyhow/LICENSE-MIT @@ -0,0 +1,23 @@ +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/anyhow/README.md b/vendor/anyhow/README.md new file mode 100644 index 0000000..ff83168 --- /dev/null +++ b/vendor/anyhow/README.md @@ -0,0 +1,181 @@ +Anyhow ¯\\\_(°ペ)\_/¯ +========================== + +[github](https://github.com/dtolnay/anyhow) +[crates.io](https://crates.io/crates/anyhow) +[docs.rs](https://docs.rs/anyhow) +[build status](https://github.com/dtolnay/anyhow/actions?query=branch%3Amaster) + +This library provides [`anyhow::Error`][Error], a trait object based error type +for easy idiomatic error handling in Rust applications. + +[Error]: https://docs.rs/anyhow/1.0/anyhow/struct.Error.html + +```toml +[dependencies] +anyhow = "1.0" +``` + +*Compiler support: requires rustc 1.39+* + +
+ +## Details + +- Use `Result`, or equivalently `anyhow::Result`, as the + return type of any fallible function. + + Within the function, use `?` to easily propagate any error that implements the + [`std::error::Error`] trait. + + ```rust + use anyhow::Result; + + fn get_cluster_info() -> Result { + let config = std::fs::read_to_string("cluster.json")?; + let map: ClusterMap = serde_json::from_str(&config)?; + Ok(map) + } + ``` + + [`std::error::Error`]: https://doc.rust-lang.org/std/error/trait.Error.html + +- Attach context to help the person troubleshooting the error understand where + things went wrong. A low-level error like "No such file or directory" can be + annoying to debug without more context about what higher level step the + application was in the middle of. + + ```rust + use anyhow::{Context, Result}; + + fn main() -> Result<()> { + ... + it.detach().context("Failed to detach the important thing")?; + + let content = std::fs::read(path) + .with_context(|| format!("Failed to read instrs from {}", path))?; + ... + } + ``` + + ```console + Error: Failed to read instrs from ./path/to/instrs.json + + Caused by: + No such file or directory (os error 2) + ``` + +- Downcasting is supported and can be by value, by shared reference, or by + mutable reference as needed. + + ```rust + // If the error was caused by redaction, then return a + // tombstone instead of the content. + match root_cause.downcast_ref::() { + Some(DataStoreError::Censored(_)) => Ok(Poll::Ready(REDACTED_CONTENT)), + None => Err(error), + } + ``` + +- If using Rust ≥ 1.65, a backtrace is captured and printed with the error if + the underlying error type does not already provide its own. In order to see + backtraces, they must be enabled through the environment variables described + in [`std::backtrace`]: + + - If you want panics and errors to both have backtraces, set + `RUST_BACKTRACE=1`; + - If you want only errors to have backtraces, set `RUST_LIB_BACKTRACE=1`; + - If you want only panics to have backtraces, set `RUST_BACKTRACE=1` and + `RUST_LIB_BACKTRACE=0`. + + [`std::backtrace`]: https://doc.rust-lang.org/std/backtrace/index.html#environment-variables + +- Anyhow works with any error type that has an impl of `std::error::Error`, + including ones defined in your crate. We do not bundle a `derive(Error)` macro + but you can write the impls yourself or use a standalone macro like + [thiserror]. + + ```rust + use thiserror::Error; + + #[derive(Error, Debug)] + pub enum FormatError { + #[error("Invalid header (expected {expected:?}, got {found:?})")] + InvalidHeader { + expected: String, + found: String, + }, + #[error("Missing attribute: {0}")] + MissingAttribute(String), + } + ``` + +- One-off error messages can be constructed using the `anyhow!` macro, which + supports string interpolation and produces an `anyhow::Error`. + + ```rust + return Err(anyhow!("Missing attribute: {}", missing)); + ``` + + A `bail!` macro is provided as a shorthand for the same early return. + + ```rust + bail!("Missing attribute: {}", missing); + ``` + +
+ +## No-std support + +In no_std mode, almost all of the same API is available and works the same way. +To depend on Anyhow in no_std mode, disable our default enabled "std" feature in +Cargo.toml. A global allocator is required. + +```toml +[dependencies] +anyhow = { version = "1.0", default-features = false } +``` + +With versions of Rust older than 1.81, no_std mode may require an additional +`.map_err(Error::msg)` when working with a non-Anyhow error type inside a +function that returns Anyhow's error type, as the trait that `?`-based error +conversions are defined by is only available in std in those old versions. + +
+ +## Comparison to failure + +The `anyhow::Error` type works something like `failure::Error`, but unlike +failure ours is built around the standard library's `std::error::Error` trait +rather than a separate trait `failure::Fail`. The standard library has adopted +the necessary improvements for this to be possible as part of [RFC 2504]. + +[RFC 2504]: https://github.com/rust-lang/rfcs/blob/master/text/2504-fix-error.md + +
+ +## Comparison to thiserror + +Use Anyhow if you don't care what error type your functions return, you just +want it to be easy. This is common in application code. Use [thiserror] if you +are a library that wants to design your own dedicated error type(s) so that on +failures the caller gets exactly the information that you choose. + +[thiserror]: https://github.com/dtolnay/thiserror + +
+ +#### License + + +Licensed under either of Apache License, Version +2.0 or MIT license at your option. + + +
+ + +Unless you explicitly state otherwise, any contribution intentionally submitted +for inclusion in this crate 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/anyhow/build.rs b/vendor/anyhow/build.rs new file mode 100644 index 0000000..200b2bf --- /dev/null +++ b/vendor/anyhow/build.rs @@ -0,0 +1,192 @@ +use std::env; +use std::ffi::OsString; +use std::iter; +use std::path::Path; +use std::process::{self, Command, Stdio}; +use std::str; + +#[cfg(all(feature = "backtrace", not(feature = "std")))] +compile_error! { + "`backtrace` feature without `std` feature is not supported" +} + +fn main() { + let mut error_generic_member_access = false; + if cfg!(feature = "std") { + println!("cargo:rerun-if-changed=build/probe.rs"); + + let consider_rustc_bootstrap; + if compile_probe(false) { + // This is a nightly or dev compiler, so it supports unstable + // features regardless of RUSTC_BOOTSTRAP. No need to rerun build + // script if RUSTC_BOOTSTRAP is changed. + error_generic_member_access = true; + consider_rustc_bootstrap = false; + } else if let Some(rustc_bootstrap) = env::var_os("RUSTC_BOOTSTRAP") { + if compile_probe(true) { + // This is a stable or beta compiler for which the user has set + // RUSTC_BOOTSTRAP to turn on unstable features. Rerun build + // script if they change it. + error_generic_member_access = true; + consider_rustc_bootstrap = true; + } else if rustc_bootstrap == "1" { + // This compiler does not support the generic member access API + // in the form that anyhow expects. No need to pay attention to + // RUSTC_BOOTSTRAP. + error_generic_member_access = false; + consider_rustc_bootstrap = false; + } else { + // This is a stable or beta compiler for which RUSTC_BOOTSTRAP + // is set to restrict the use of unstable features by this + // crate. + error_generic_member_access = false; + consider_rustc_bootstrap = true; + } + } else { + // Without RUSTC_BOOTSTRAP, this compiler does not support the + // generic member access API in the form that anyhow expects, but + // try again if the user turns on unstable features. + error_generic_member_access = false; + consider_rustc_bootstrap = true; + } + + if error_generic_member_access { + println!("cargo:rustc-cfg=std_backtrace"); + println!("cargo:rustc-cfg=error_generic_member_access"); + } + + if consider_rustc_bootstrap { + println!("cargo:rerun-if-env-changed=RUSTC_BOOTSTRAP"); + } + } + + let rustc = match rustc_minor_version() { + Some(rustc) => rustc, + None => return, + }; + + if rustc >= 80 { + println!("cargo:rustc-check-cfg=cfg(anyhow_nightly_testing)"); + println!("cargo:rustc-check-cfg=cfg(anyhow_no_core_error)"); + println!("cargo:rustc-check-cfg=cfg(anyhow_no_core_unwind_safe)"); + println!("cargo:rustc-check-cfg=cfg(anyhow_no_fmt_arguments_as_str)"); + println!("cargo:rustc-check-cfg=cfg(anyhow_no_ptr_addr_of)"); + println!("cargo:rustc-check-cfg=cfg(anyhow_no_unsafe_op_in_unsafe_fn_lint)"); + println!("cargo:rustc-check-cfg=cfg(error_generic_member_access)"); + println!("cargo:rustc-check-cfg=cfg(std_backtrace)"); + } + + if rustc < 51 { + // core::ptr::addr_of + // https://blog.rust-lang.org/2021/03/25/Rust-1.51.0.html#stabilized-apis + println!("cargo:rustc-cfg=anyhow_no_ptr_addr_of"); + } + + if rustc < 52 { + // core::fmt::Arguments::as_str + // https://blog.rust-lang.org/2021/05/06/Rust-1.52.0.html#stabilized-apis + println!("cargo:rustc-cfg=anyhow_no_fmt_arguments_as_str"); + + // #![deny(unsafe_op_in_unsafe_fn)] + // https://github.com/rust-lang/rust/issues/71668 + println!("cargo:rustc-cfg=anyhow_no_unsafe_op_in_unsafe_fn_lint"); + } + + if rustc < 56 { + // core::panic::{UnwindSafe, RefUnwindSafe} + // https://blog.rust-lang.org/2021/10/21/Rust-1.56.0.html#stabilized-apis + println!("cargo:rustc-cfg=anyhow_no_core_unwind_safe"); + } + + if !error_generic_member_access && cfg!(feature = "std") && rustc >= 65 { + // std::backtrace::Backtrace + // https://blog.rust-lang.org/2022/11/03/Rust-1.65.0.html#stabilized-apis + println!("cargo:rustc-cfg=std_backtrace"); + } + + if rustc < 81 { + // core::error::Error + // https://blog.rust-lang.org/2024/09/05/Rust-1.81.0.html#coreerrorerror + println!("cargo:rustc-cfg=anyhow_no_core_error"); + } +} + +fn compile_probe(rustc_bootstrap: bool) -> bool { + if env::var_os("RUSTC_STAGE").is_some() { + // We are running inside rustc bootstrap. This is a highly non-standard + // environment with issues such as: + // + // https://github.com/rust-lang/cargo/issues/11138 + // https://github.com/rust-lang/rust/issues/114839 + // + // Let's just not use nightly features here. + return false; + } + + let rustc = cargo_env_var("RUSTC"); + let out_dir = cargo_env_var("OUT_DIR"); + let probefile = Path::new("build").join("probe.rs"); + + let rustc_wrapper = env::var_os("RUSTC_WRAPPER").filter(|wrapper| !wrapper.is_empty()); + let rustc_workspace_wrapper = + env::var_os("RUSTC_WORKSPACE_WRAPPER").filter(|wrapper| !wrapper.is_empty()); + let mut rustc = rustc_wrapper + .into_iter() + .chain(rustc_workspace_wrapper) + .chain(iter::once(rustc)); + let mut cmd = Command::new(rustc.next().unwrap()); + cmd.args(rustc); + + if !rustc_bootstrap { + cmd.env_remove("RUSTC_BOOTSTRAP"); + } + + cmd.stderr(Stdio::null()) + .arg("--edition=2018") + .arg("--crate-name=anyhow") + .arg("--crate-type=lib") + .arg("--emit=dep-info,metadata") + .arg("--cap-lints=allow") + .arg("--out-dir") + .arg(out_dir) + .arg(probefile); + + if let Some(target) = env::var_os("TARGET") { + cmd.arg("--target").arg(target); + } + + // If Cargo wants to set RUSTFLAGS, use that. + if let Ok(rustflags) = env::var("CARGO_ENCODED_RUSTFLAGS") { + if !rustflags.is_empty() { + for arg in rustflags.split('\x1f') { + cmd.arg(arg); + } + } + } + + match cmd.status() { + Ok(status) => status.success(), + Err(_) => false, + } +} + +fn rustc_minor_version() -> Option { + let rustc = cargo_env_var("RUSTC"); + let output = Command::new(rustc).arg("--version").output().ok()?; + let version = str::from_utf8(&output.stdout).ok()?; + let mut pieces = version.split('.'); + if pieces.next() != Some("rustc 1") { + return None; + } + pieces.next()?.parse().ok() +} + +fn cargo_env_var(key: &str) -> OsString { + env::var_os(key).unwrap_or_else(|| { + eprintln!( + "Environment variable ${} is not set during execution of build script", + key, + ); + process::exit(1); + }) +} diff --git a/vendor/anyhow/build/probe.rs b/vendor/anyhow/build/probe.rs new file mode 100644 index 0000000..742d15c --- /dev/null +++ b/vendor/anyhow/build/probe.rs @@ -0,0 +1,35 @@ +// This code exercises the surface area that we expect of the Error generic +// member access API. If the current toolchain is able to compile it, then +// anyhow is able to provide backtrace support. + +#![feature(error_generic_member_access)] + +use core::error::{self, Error, Request}; +use core::fmt::{self, Debug, Display}; +use std::backtrace::Backtrace; + +struct MyError(Thing); +struct Thing; + +impl Debug for MyError { + fn fmt(&self, _formatter: &mut fmt::Formatter) -> fmt::Result { + unimplemented!() + } +} + +impl Display for MyError { + fn fmt(&self, _formatter: &mut fmt::Formatter) -> fmt::Result { + unimplemented!() + } +} + +impl Error for MyError { + fn provide<'a>(&'a self, request: &mut Request<'a>) { + request.provide_ref(&self.0); + } +} + +const _: fn(&dyn Error) -> Option<&Backtrace> = |err| error::request_ref::(err); + +// Include in sccache cache key. +const _: Option<&str> = option_env!("RUSTC_BOOTSTRAP"); diff --git a/vendor/anyhow/rust-toolchain.toml b/vendor/anyhow/rust-toolchain.toml new file mode 100644 index 0000000..20fe888 --- /dev/null +++ b/vendor/anyhow/rust-toolchain.toml @@ -0,0 +1,2 @@ +[toolchain] +components = ["rust-src"] diff --git a/vendor/anyhow/src/backtrace.rs b/vendor/anyhow/src/backtrace.rs new file mode 100644 index 0000000..303f911 --- /dev/null +++ b/vendor/anyhow/src/backtrace.rs @@ -0,0 +1,411 @@ +#[cfg(std_backtrace)] +pub(crate) use std::backtrace::{Backtrace, BacktraceStatus}; + +#[cfg(all(not(std_backtrace), feature = "backtrace"))] +pub(crate) use self::capture::{Backtrace, BacktraceStatus}; + +#[cfg(not(any(std_backtrace, feature = "backtrace")))] +pub(crate) enum Backtrace {} + +#[cfg(std_backtrace)] +macro_rules! impl_backtrace { + () => { + std::backtrace::Backtrace + }; +} + +#[cfg(all(not(std_backtrace), feature = "backtrace"))] +macro_rules! impl_backtrace { + () => { + impl core::fmt::Debug + core::fmt::Display + }; +} + +#[cfg(any(std_backtrace, feature = "backtrace"))] +macro_rules! backtrace { + () => { + Some(crate::backtrace::Backtrace::capture()) + }; +} + +#[cfg(not(any(std_backtrace, feature = "backtrace")))] +macro_rules! backtrace { + () => { + None + }; +} + +#[cfg(error_generic_member_access)] +macro_rules! backtrace_if_absent { + ($err:expr) => { + match core::error::request_ref::($err as &dyn core::error::Error) + { + Some(_) => None, + None => backtrace!(), + } + }; +} + +#[cfg(all( + any(feature = "std", not(anyhow_no_core_error)), + not(error_generic_member_access), + any(std_backtrace, feature = "backtrace") +))] +macro_rules! backtrace_if_absent { + ($err:expr) => { + backtrace!() + }; +} + +#[cfg(all( + any(feature = "std", not(anyhow_no_core_error)), + not(std_backtrace), + not(feature = "backtrace"), +))] +macro_rules! backtrace_if_absent { + ($err:expr) => { + None + }; +} + +#[cfg(all(not(std_backtrace), feature = "backtrace"))] +mod capture { + use alloc::borrow::{Cow, ToOwned as _}; + use alloc::vec::Vec; + use backtrace::{BacktraceFmt, BytesOrWideString, Frame, PrintFmt, SymbolName}; + use core::cell::UnsafeCell; + use core::fmt::{self, Debug, Display}; + use core::sync::atomic::{AtomicUsize, Ordering}; + use std::env; + use std::path::{self, Path, PathBuf}; + use std::sync::Once; + + pub(crate) struct Backtrace { + inner: Inner, + } + + pub(crate) enum BacktraceStatus { + Unsupported, + Disabled, + Captured, + } + + enum Inner { + Unsupported, + Disabled, + Captured(LazilyResolvedCapture), + } + + struct Capture { + actual_start: usize, + resolved: bool, + frames: Vec, + } + + struct BacktraceFrame { + frame: Frame, + symbols: Vec, + } + + struct BacktraceSymbol { + name: Option>, + filename: Option, + lineno: Option, + colno: Option, + } + + enum BytesOrWide { + Bytes(Vec), + Wide(Vec), + } + + impl Debug for Backtrace { + fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { + let capture = match &self.inner { + Inner::Unsupported => return fmt.write_str(""), + Inner::Disabled => return fmt.write_str(""), + Inner::Captured(c) => c.force(), + }; + + let frames = &capture.frames[capture.actual_start..]; + + write!(fmt, "Backtrace ")?; + + let mut dbg = fmt.debug_list(); + + for frame in frames { + if frame.frame.ip().is_null() { + continue; + } + + dbg.entries(&frame.symbols); + } + + dbg.finish() + } + } + + impl Debug for BacktraceFrame { + fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { + let mut dbg = fmt.debug_list(); + dbg.entries(&self.symbols); + dbg.finish() + } + } + + impl Debug for BacktraceSymbol { + fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { + write!(fmt, "{{ ")?; + + if let Some(fn_name) = self.name.as_ref().map(|b| SymbolName::new(b)) { + write!(fmt, "fn: \"{:#}\"", fn_name)?; + } else { + write!(fmt, "fn: ")?; + } + + if let Some(fname) = self.filename.as_ref() { + write!(fmt, ", file: \"{:?}\"", fname)?; + } + + if let Some(line) = self.lineno { + write!(fmt, ", line: {:?}", line)?; + } + + write!(fmt, " }}") + } + } + + impl Debug for BytesOrWide { + fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { + output_filename( + fmt, + match self { + BytesOrWide::Bytes(w) => BytesOrWideString::Bytes(w), + BytesOrWide::Wide(w) => BytesOrWideString::Wide(w), + }, + PrintFmt::Short, + env::current_dir().as_ref().ok(), + ) + } + } + + impl Backtrace { + fn enabled() -> bool { + static ENABLED: AtomicUsize = AtomicUsize::new(0); + match ENABLED.load(Ordering::Relaxed) { + 0 => {} + 1 => return false, + _ => return true, + } + let enabled = match env::var_os("RUST_LIB_BACKTRACE") { + Some(s) => s != "0", + None => match env::var_os("RUST_BACKTRACE") { + Some(s) => s != "0", + None => false, + }, + }; + ENABLED.store(enabled as usize + 1, Ordering::Relaxed); + enabled + } + + #[inline(never)] // want to make sure there's a frame here to remove + pub(crate) fn capture() -> Backtrace { + if Backtrace::enabled() { + Backtrace::create(Backtrace::capture as usize) + } else { + let inner = Inner::Disabled; + Backtrace { inner } + } + } + + // Capture a backtrace which starts just before the function addressed + // by `ip` + fn create(ip: usize) -> Backtrace { + let mut frames = Vec::new(); + let mut actual_start = None; + backtrace::trace(|frame| { + frames.push(BacktraceFrame { + frame: frame.clone(), + symbols: Vec::new(), + }); + if frame.symbol_address() as usize == ip && actual_start.is_none() { + actual_start = Some(frames.len() + 1); + } + true + }); + + // If no frames came out assume that this is an unsupported platform + // since `backtrace` doesn't provide a way of learning this right + // now, and this should be a good enough approximation. + let inner = if frames.is_empty() { + Inner::Unsupported + } else { + Inner::Captured(LazilyResolvedCapture::new(Capture { + actual_start: actual_start.unwrap_or(0), + frames, + resolved: false, + })) + }; + + Backtrace { inner } + } + + pub(crate) fn status(&self) -> BacktraceStatus { + match self.inner { + Inner::Unsupported => BacktraceStatus::Unsupported, + Inner::Disabled => BacktraceStatus::Disabled, + Inner::Captured(_) => BacktraceStatus::Captured, + } + } + } + + impl Display for Backtrace { + fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { + let capture = match &self.inner { + Inner::Unsupported => return fmt.write_str("unsupported backtrace"), + Inner::Disabled => return fmt.write_str("disabled backtrace"), + Inner::Captured(c) => c.force(), + }; + + let full = fmt.alternate(); + let (frames, style) = if full { + (&capture.frames[..], PrintFmt::Full) + } else { + (&capture.frames[capture.actual_start..], PrintFmt::Short) + }; + + // When printing paths we try to strip the cwd if it exists, + // otherwise we just print the path as-is. Note that we also only do + // this for the short format, because if it's full we presumably + // want to print everything. + let cwd = env::current_dir(); + let mut print_path = move |fmt: &mut fmt::Formatter, path: BytesOrWideString| { + output_filename(fmt, path, style, cwd.as_ref().ok()) + }; + + let mut f = BacktraceFmt::new(fmt, style, &mut print_path); + f.add_context()?; + for frame in frames { + let mut f = f.frame(); + if frame.symbols.is_empty() { + f.print_raw(frame.frame.ip(), None, None, None)?; + } else { + for symbol in frame.symbols.iter() { + f.print_raw_with_column( + frame.frame.ip(), + symbol.name.as_ref().map(|b| SymbolName::new(b)), + symbol.filename.as_ref().map(|b| match b { + BytesOrWide::Bytes(w) => BytesOrWideString::Bytes(w), + BytesOrWide::Wide(w) => BytesOrWideString::Wide(w), + }), + symbol.lineno, + symbol.colno, + )?; + } + } + } + f.finish()?; + Ok(()) + } + } + + struct LazilyResolvedCapture { + sync: Once, + capture: UnsafeCell, + } + + impl LazilyResolvedCapture { + fn new(capture: Capture) -> Self { + LazilyResolvedCapture { + sync: Once::new(), + capture: UnsafeCell::new(capture), + } + } + + fn force(&self) -> &Capture { + self.sync.call_once(|| { + // Safety: This exclusive reference can't overlap with any + // others. `Once` guarantees callers will block until this + // closure returns. `Once` also guarantees only a single caller + // will enter this closure. + unsafe { &mut *self.capture.get() }.resolve(); + }); + + // Safety: This shared reference can't overlap with the exclusive + // reference above. + unsafe { &*self.capture.get() } + } + } + + // Safety: Access to the inner value is synchronized using a thread-safe + // `Once`. So long as `Capture` is `Sync`, `LazilyResolvedCapture` is too + unsafe impl Sync for LazilyResolvedCapture where Capture: Sync {} + + impl Capture { + fn resolve(&mut self) { + // If we're already resolved, nothing to do! + if self.resolved { + return; + } + self.resolved = true; + + for frame in self.frames.iter_mut() { + let symbols = &mut frame.symbols; + let frame = &frame.frame; + backtrace::resolve_frame(frame, |symbol| { + symbols.push(BacktraceSymbol { + name: symbol.name().map(|m| m.as_bytes().to_vec()), + filename: symbol.filename_raw().map(|b| match b { + BytesOrWideString::Bytes(b) => BytesOrWide::Bytes(b.to_owned()), + BytesOrWideString::Wide(b) => BytesOrWide::Wide(b.to_owned()), + }), + lineno: symbol.lineno(), + colno: symbol.colno(), + }); + }); + } + } + } + + // Prints the filename of the backtrace frame. + fn output_filename( + fmt: &mut fmt::Formatter, + bows: BytesOrWideString, + print_fmt: PrintFmt, + cwd: Option<&PathBuf>, + ) -> fmt::Result { + let file: Cow = match bows { + #[cfg(unix)] + BytesOrWideString::Bytes(bytes) => { + use std::os::unix::ffi::OsStrExt; + Path::new(std::ffi::OsStr::from_bytes(bytes)).into() + } + #[cfg(not(unix))] + BytesOrWideString::Bytes(bytes) => { + Path::new(std::str::from_utf8(bytes).unwrap_or("")).into() + } + #[cfg(windows)] + BytesOrWideString::Wide(wide) => { + use std::os::windows::ffi::OsStringExt; + Cow::Owned(std::ffi::OsString::from_wide(wide).into()) + } + #[cfg(not(windows))] + BytesOrWideString::Wide(_wide) => Path::new("").into(), + }; + if print_fmt == PrintFmt::Short && file.is_absolute() { + if let Some(cwd) = cwd { + if let Ok(stripped) = file.strip_prefix(&cwd) { + if let Some(s) = stripped.to_str() { + return write!(fmt, ".{}{}", path::MAIN_SEPARATOR, s); + } + } + } + } + Display::fmt(&file.display(), fmt) + } +} + +fn _assert_send_sync() { + fn assert() {} + assert::(); +} diff --git a/vendor/anyhow/src/chain.rs b/vendor/anyhow/src/chain.rs new file mode 100644 index 0000000..e56bc66 --- /dev/null +++ b/vendor/anyhow/src/chain.rs @@ -0,0 +1,102 @@ +use self::ChainState::*; +use crate::StdError; + +#[cfg(any(feature = "std", not(anyhow_no_core_error)))] +use alloc::vec::{self, Vec}; + +#[cfg(any(feature = "std", not(anyhow_no_core_error)))] +pub(crate) use crate::Chain; + +#[cfg(all(not(feature = "std"), anyhow_no_core_error))] +pub(crate) struct Chain<'a> { + state: ChainState<'a>, +} + +#[derive(Clone)] +pub(crate) enum ChainState<'a> { + Linked { + next: Option<&'a (dyn StdError + 'static)>, + }, + #[cfg(any(feature = "std", not(anyhow_no_core_error)))] + Buffered { + rest: vec::IntoIter<&'a (dyn StdError + 'static)>, + }, +} + +impl<'a> Chain<'a> { + #[cold] + pub fn new(head: &'a (dyn StdError + 'static)) -> Self { + Chain { + state: ChainState::Linked { next: Some(head) }, + } + } +} + +impl<'a> Iterator for Chain<'a> { + type Item = &'a (dyn StdError + 'static); + + fn next(&mut self) -> Option { + match &mut self.state { + Linked { next } => { + let error = (*next)?; + *next = error.source(); + Some(error) + } + #[cfg(any(feature = "std", not(anyhow_no_core_error)))] + Buffered { rest } => rest.next(), + } + } + + fn size_hint(&self) -> (usize, Option) { + let len = self.len(); + (len, Some(len)) + } +} + +#[cfg(any(feature = "std", not(anyhow_no_core_error)))] +impl DoubleEndedIterator for Chain<'_> { + fn next_back(&mut self) -> Option { + match &mut self.state { + Linked { mut next } => { + let mut rest = Vec::new(); + while let Some(cause) = next { + next = cause.source(); + rest.push(cause); + } + let mut rest = rest.into_iter(); + let last = rest.next_back(); + self.state = Buffered { rest }; + last + } + Buffered { rest } => rest.next_back(), + } + } +} + +impl ExactSizeIterator for Chain<'_> { + fn len(&self) -> usize { + match &self.state { + Linked { mut next } => { + let mut len = 0; + while let Some(cause) = next { + next = cause.source(); + len += 1; + } + len + } + #[cfg(any(feature = "std", not(anyhow_no_core_error)))] + Buffered { rest } => rest.len(), + } + } +} + +#[cfg(any(feature = "std", not(anyhow_no_core_error)))] +impl Default for Chain<'_> { + fn default() -> Self { + Chain { + state: ChainState::Buffered { + rest: Vec::new().into_iter(), + }, + } + } +} diff --git a/vendor/anyhow/src/context.rs b/vendor/anyhow/src/context.rs new file mode 100644 index 0000000..b52f682 --- /dev/null +++ b/vendor/anyhow/src/context.rs @@ -0,0 +1,193 @@ +use crate::error::ContextError; +use crate::{Context, Error, StdError}; +use core::convert::Infallible; +use core::fmt::{self, Debug, Display, Write}; + +#[cfg(error_generic_member_access)] +use core::error::Request; + +mod ext { + use super::*; + + pub trait StdError { + fn ext_context(self, context: C) -> Error + where + C: Display + Send + Sync + 'static; + } + + #[cfg(any(feature = "std", not(anyhow_no_core_error)))] + impl StdError for E + where + E: crate::StdError + Send + Sync + 'static, + { + fn ext_context(self, context: C) -> Error + where + C: Display + Send + Sync + 'static, + { + let backtrace = backtrace_if_absent!(&self); + Error::from_context(context, self, backtrace) + } + } + + impl StdError for Error { + fn ext_context(self, context: C) -> Error + where + C: Display + Send + Sync + 'static, + { + self.context(context) + } + } +} + +impl Context for Result +where + E: ext::StdError + Send + Sync + 'static, +{ + fn context(self, context: C) -> Result + where + C: Display + Send + Sync + 'static, + { + // Not using map_err to save 2 useless frames off the captured backtrace + // in ext_context. + match self { + Ok(ok) => Ok(ok), + Err(error) => Err(error.ext_context(context)), + } + } + + fn with_context(self, context: F) -> Result + where + C: Display + Send + Sync + 'static, + F: FnOnce() -> C, + { + match self { + Ok(ok) => Ok(ok), + Err(error) => Err(error.ext_context(context())), + } + } +} + +/// ``` +/// # type T = (); +/// # +/// use anyhow::{Context, Result}; +/// +/// fn maybe_get() -> Option { +/// # const IGNORE: &str = stringify! { +/// ... +/// # }; +/// # unimplemented!() +/// } +/// +/// fn demo() -> Result<()> { +/// let t = maybe_get().context("there is no T")?; +/// # const IGNORE: &str = stringify! { +/// ... +/// # }; +/// # unimplemented!() +/// } +/// ``` +impl Context for Option { + fn context(self, context: C) -> Result + where + C: Display + Send + Sync + 'static, + { + // Not using ok_or_else to save 2 useless frames off the captured + // backtrace. + match self { + Some(ok) => Ok(ok), + None => Err(Error::from_display(context, backtrace!())), + } + } + + fn with_context(self, context: F) -> Result + where + C: Display + Send + Sync + 'static, + F: FnOnce() -> C, + { + match self { + Some(ok) => Ok(ok), + None => Err(Error::from_display(context(), backtrace!())), + } + } +} + +impl Debug for ContextError +where + C: Display, + E: Debug, +{ + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.debug_struct("Error") + .field("context", &Quoted(&self.context)) + .field("source", &self.error) + .finish() + } +} + +impl Display for ContextError +where + C: Display, +{ + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + Display::fmt(&self.context, f) + } +} + +impl StdError for ContextError +where + C: Display, + E: StdError + 'static, +{ + fn source(&self) -> Option<&(dyn StdError + 'static)> { + Some(&self.error) + } + + #[cfg(error_generic_member_access)] + fn provide<'a>(&'a self, request: &mut Request<'a>) { + StdError::provide(&self.error, request); + } +} + +impl StdError for ContextError +where + C: Display, +{ + fn source(&self) -> Option<&(dyn StdError + 'static)> { + Some(unsafe { crate::ErrorImpl::error(self.error.inner.by_ref()) }) + } + + #[cfg(error_generic_member_access)] + fn provide<'a>(&'a self, request: &mut Request<'a>) { + Error::provide(&self.error, request); + } +} + +struct Quoted(C); + +impl Debug for Quoted +where + C: Display, +{ + fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_char('"')?; + Quoted(&mut *formatter).write_fmt(format_args!("{}", self.0))?; + formatter.write_char('"')?; + Ok(()) + } +} + +impl Write for Quoted<&mut fmt::Formatter<'_>> { + fn write_str(&mut self, s: &str) -> fmt::Result { + Display::fmt(&s.escape_debug(), self.0) + } +} + +pub(crate) mod private { + use super::*; + + pub trait Sealed {} + + impl Sealed for Result where E: ext::StdError {} + impl Sealed for Option {} +} diff --git a/vendor/anyhow/src/ensure.rs b/vendor/anyhow/src/ensure.rs new file mode 100644 index 0000000..9d0a676 --- /dev/null +++ b/vendor/anyhow/src/ensure.rs @@ -0,0 +1,919 @@ +use crate::Error; +use alloc::string::String; +use core::fmt::{self, Debug, Write}; +use core::mem::MaybeUninit; +use core::ptr; +use core::slice; +use core::str; + +#[doc(hidden)] +pub trait BothDebug { + fn __dispatch_ensure(self, msg: &'static str) -> Error; +} + +impl BothDebug for (A, B) +where + A: Debug, + B: Debug, +{ + fn __dispatch_ensure(self, msg: &'static str) -> Error { + render(msg, &self.0, &self.1) + } +} + +#[doc(hidden)] +pub trait NotBothDebug { + fn __dispatch_ensure(self, msg: &'static str) -> Error; +} + +impl NotBothDebug for &(A, B) { + fn __dispatch_ensure(self, msg: &'static str) -> Error { + Error::msg(msg) + } +} + +struct Buf { + bytes: [MaybeUninit; 40], + written: usize, +} + +impl Buf { + fn new() -> Self { + Buf { + bytes: [MaybeUninit::uninit(); 40], + written: 0, + } + } + + fn as_str(&self) -> &str { + unsafe { + str::from_utf8_unchecked(slice::from_raw_parts( + self.bytes.as_ptr().cast::(), + self.written, + )) + } + } +} + +impl Write for Buf { + fn write_str(&mut self, s: &str) -> fmt::Result { + if s.bytes().any(|b| b == b' ' || b == b'\n') { + return Err(fmt::Error); + } + + let remaining = self.bytes.len() - self.written; + if s.len() > remaining { + return Err(fmt::Error); + } + + unsafe { + ptr::copy_nonoverlapping( + s.as_ptr(), + self.bytes.as_mut_ptr().add(self.written).cast::(), + s.len(), + ); + } + self.written += s.len(); + Ok(()) + } +} + +fn render(msg: &'static str, lhs: &dyn Debug, rhs: &dyn Debug) -> Error { + let mut lhs_buf = Buf::new(); + if fmt::write(&mut lhs_buf, format_args!("{:?}", lhs)).is_ok() { + let mut rhs_buf = Buf::new(); + if fmt::write(&mut rhs_buf, format_args!("{:?}", rhs)).is_ok() { + let lhs_str = lhs_buf.as_str(); + let rhs_str = rhs_buf.as_str(); + // "{msg} ({lhs} vs {rhs})" + let len = msg.len() + 2 + lhs_str.len() + 4 + rhs_str.len() + 1; + let mut string = String::with_capacity(len); + string.push_str(msg); + string.push_str(" ("); + string.push_str(lhs_str); + string.push_str(" vs "); + string.push_str(rhs_str); + string.push(')'); + return Error::msg(string); + } + } + Error::msg(msg) +} + +#[doc(hidden)] +#[macro_export] +macro_rules! __parse_ensure { + (atom () $bail:tt $fuel:tt {($($rhs:tt)+) ($($lhs:tt)+) $op:tt} $dup:tt $(,)?) => { + $crate::__fancy_ensure!($($lhs)+, $op, $($rhs)+) + }; + + // low precedence control flow constructs + + (0 $stack:tt ($($bail:tt)*) $fuel:tt $parse:tt $dup:tt return $($rest:tt)*) => { + $crate::__fallback_ensure!($($bail)*) + }; + + (0 $stack:tt ($($bail:tt)*) $fuel:tt $parse:tt $dup:tt break $($rest:tt)*) => { + $crate::__fallback_ensure!($($bail)*) + }; + + (0 $stack:tt ($($bail:tt)*) $fuel:tt $parse:tt $dup:tt continue $($rest:tt)*) => { + $crate::__fallback_ensure!($($bail)*) + }; + + (0 $stack:tt ($($bail:tt)*) $fuel:tt $parse:tt $dup:tt yield $($rest:tt)*) => { + $crate::__fallback_ensure!($($bail)*) + }; + + (0 $stack:tt ($($bail:tt)*) $fuel:tt $parse:tt $dup:tt move $($rest:tt)*) => { + $crate::__fallback_ensure!($($bail)*) + }; + + // unary operators + + (0 $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($deref:tt $($dup:tt)*) * $($rest:tt)*) => { + $crate::__parse_ensure!(0 $stack $bail ($($fuel)*) {($($buf)* $deref) $($parse)*} ($($rest)*) $($rest)*) + }; + + (0 $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($not:tt $($dup:tt)*) ! $($rest:tt)*) => { + $crate::__parse_ensure!(0 $stack $bail ($($fuel)*) {($($buf)* $not) $($parse)*} ($($rest)*) $($rest)*) + }; + + (0 $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($neg:tt $($dup:tt)*) - $($rest:tt)*) => { + $crate::__parse_ensure!(0 $stack $bail ($($fuel)*) {($($buf)* $neg) $($parse)*} ($($rest)*) $($rest)*) + }; + + (0 $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($let:tt $($dup:tt)*) let $($rest:tt)*) => { + $crate::__parse_ensure!(pat $stack $bail ($($fuel)*) {($($buf)* $let) $($parse)*} ($($rest)*) $($rest)*) + }; + + (0 $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($lifetime:tt $colon:tt $($dup:tt)*) $label:lifetime : $($rest:tt)*) => { + $crate::__parse_ensure!(0 $stack $bail ($($fuel)*) {($($buf)* $lifetime $colon) $($parse)*} ($($rest)*) $($rest)*) + }; + + (0 $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($and:tt $mut:tt $($dup:tt)*) &mut $($rest:tt)*) => { + $crate::__parse_ensure!(0 $stack $bail ($($fuel)*) {($($buf)* $and $mut) $($parse)*} ($($rest)*) $($rest)*) + }; + + (0 $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($and:tt $($dup:tt)*) & $($rest:tt)*) => { + $crate::__parse_ensure!(0 $stack $bail ($($fuel)*) {($($buf)* $and) $($parse)*} ($($rest)*) $($rest)*) + }; + + (0 $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($andand:tt $mut:tt $($dup:tt)*) &&mut $($rest:tt)*) => { + $crate::__parse_ensure!(0 $stack $bail ($($fuel)*) {($($buf)* $andand $mut) $($parse)*} ($($rest)*) $($rest)*) + }; + + (0 $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($andand:tt $($dup:tt)*) && $($rest:tt)*) => { + $crate::__parse_ensure!(0 $stack $bail ($($fuel)*) {($($buf)* $andand) $($parse)*} ($($rest)*) $($rest)*) + }; + + // control flow constructs + + (0 $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($if:tt $($dup:tt)*) if $($rest:tt)*) => { + $crate::__parse_ensure!(0 (cond $stack) $bail ($($fuel)*) {($($buf)* $if) $($parse)*} ($($rest)*) $($rest)*) + }; + + (0 $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($match:tt $($dup:tt)*) match $($rest:tt)*) => { + $crate::__parse_ensure!(0 (cond $stack) $bail ($($fuel)*) {($($buf)* $match) $($parse)*} ($($rest)*) $($rest)*) + }; + + (0 $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($while:tt $($dup:tt)*) while $($rest:tt)*) => { + $crate::__parse_ensure!(0 (cond $stack) $bail ($($fuel)*) {($($buf)* $while) $($parse)*} ($($rest)*) $($rest)*) + }; + + (0 $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($for:tt $($dup:tt)*) for $($rest:tt)*) => { + $crate::__parse_ensure!(pat (cond $stack) $bail ($($fuel)*) {($($buf)* $for) $($parse)*} ($($rest)*) $($rest)*) + }; + + (atom (cond $stack:tt) $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($brace:tt $($dup:tt)*) {$($block:tt)*} $($rest:tt)*) => { + $crate::__parse_ensure!(cond $stack $bail ($($fuel)*) {($($buf)* $brace) $($parse)*} ($($rest)*) $($rest)*) + }; + + (cond $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($else:tt $if:tt $($dup:tt)*) else if $($rest:tt)*) => { + $crate::__parse_ensure!(0 (cond $stack) $bail ($($fuel)*) {($($buf)* $else $if) $($parse)*} ($($rest)*) $($rest)*) + }; + + (cond $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($else:tt $brace:tt $($dup:tt)*) else {$($block:tt)*} $($rest:tt)*) => { + $crate::__parse_ensure!(atom $stack $bail ($($fuel)*) {($($buf)* $else $brace) $($parse)*} ($($rest)*) $($rest)*) + }; + + (cond $stack:tt $bail:tt (~$($fuel:tt)*) $parse:tt $dup:tt $($rest:tt)*) => { + $crate::__parse_ensure!(atom $stack $bail ($($fuel)*) $parse $dup $($rest)*) + }; + + // atomic expressions + + (0 $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($paren:tt $($dup:tt)*) ($($content:tt)*) $($rest:tt)*) => { + $crate::__parse_ensure!(atom $stack $bail ($($fuel)*) {($($buf)* $paren) $($parse)*} ($($rest)*) $($rest)*) + }; + + (0 $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($bracket:tt $($dup:tt)*) [$($array:tt)*] $($rest:tt)*) => { + $crate::__parse_ensure!(atom $stack $bail ($($fuel)*) {($($buf)* $bracket) $($parse)*} ($($rest)*) $($rest)*) + }; + + (0 $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($brace:tt $($dup:tt)*) {$($block:tt)*} $($rest:tt)*) => { + $crate::__parse_ensure!(atom $stack $bail ($($fuel)*) {($($buf)* $brace) $($parse)*} ($($rest)*) $($rest)*) + }; + + (0 $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($loop:tt $block:tt $($dup:tt)*) loop {$($body:tt)*} $($rest:tt)*) => { + $crate::__parse_ensure!(atom $stack $bail ($($fuel)*) {($($buf)* $loop $block) $($parse)*} ($($rest)*) $($rest)*) + }; + + (0 $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($async:tt $block:tt $($dup:tt)*) async {$($body:tt)*} $($rest:tt)*) => { + $crate::__parse_ensure!(atom $stack $bail ($($fuel)*) {($($buf)* $async $block) $($parse)*} ($($rest)*) $($rest)*) + }; + + (0 $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($async:tt $move:tt $block:tt $($dup:tt)*) async move {$($body:tt)*} $($rest:tt)*) => { + $crate::__parse_ensure!(atom $stack $bail ($($fuel)*) {($($buf)* $async $move $block) $($parse)*} ($($rest)*) $($rest)*) + }; + + (0 $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($unsafe:tt $block:tt $($dup:tt)*) unsafe {$($body:tt)*} $($rest:tt)*) => { + $crate::__parse_ensure!(atom $stack $bail ($($fuel)*) {($($buf)* $unsafe $block) $($parse)*} ($($rest)*) $($rest)*) + }; + + (0 $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($const:tt $block:tt $($dup:tt)*) const {$($body:tt)*} $($rest:tt)*) => { + // TODO: this is mostly useless due to https://github.com/rust-lang/rust/issues/86730 + $crate::__parse_ensure!(atom $stack $bail ($($fuel)*) {($($buf)* $const $block) $($parse)*} ($($rest)*) $($rest)*) + }; + + (0 $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($literal:tt $($dup:tt)*) $lit:literal $($rest:tt)*) => { + $crate::__parse_ensure!(atom $stack $bail ($($fuel)*) {($($buf)* $literal) $($parse)*} ($($rest)*) $($rest)*) + }; + + // path expressions + + (0 $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($colons:tt $ident:tt $($dup:tt)*) :: $i:ident $($rest:tt)*) => { + $crate::__parse_ensure!(epath (atom $stack) $bail ($($fuel)*) {($($buf)* $colons $ident) $($parse)*} ($($rest)*) $($rest)*) + }; + + (0 $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($ident:tt $($dup:tt)*) $i:ident $($rest:tt)*) => { + $crate::__parse_ensure!(epath (atom $stack) $bail ($($fuel)*) {($($buf)* $ident) $($parse)*} ($($rest)*) $($rest)*) + }; + + (0 $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($langle:tt $($dup:tt)*) < $($rest:tt)*) => { + $crate::__parse_ensure!(type (qpath (epath (atom $stack))) $bail ($($fuel)*) {($($buf)* $langle) $($parse)*} ($($rest)*) $($rest)*) + }; + + (epath $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($colons:tt $langle:tt $($dup:tt)*) :: < $($rest:tt)*) => { + $crate::__parse_ensure!(generic (epath $stack) $bail ($($fuel)*) {($($buf)* $colons $langle) $($parse)*} ($($rest)*) $($rest)*) + }; + + (epath $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($colons:tt $langle:tt $($dup:tt)*) :: << $($rest:tt)*) => { + $crate::__parse_ensure!(type (qpath (tpath (arglist (epath $stack)))) $bail ($($fuel)*) {($($buf)* $colons $langle) $($parse)*} ($($rest)*) $($rest)*) + }; + + (epath $stack:tt ($($bail:tt)*) (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} $dup:tt :: <- - $($rest:tt)*) => { + $crate::__fallback_ensure!($($bail)*) + }; + + (epath $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($colons:tt $larrow:tt $($dup:tt)*) :: <- $lit:literal $($rest:tt)*) => { + $crate::__parse_ensure!(generic (epath $stack) $bail ($($fuel)*) {($($buf)* $colons $larrow) $($parse)*} ($($dup)*) $($dup)*) + }; + + (epath $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($colons:tt $ident:tt $($dup:tt)*) :: $i:ident $($rest:tt)*) => { + $crate::__parse_ensure!(epath $stack $bail ($($fuel)*) {($($buf)* $colons $ident) $($parse)*} ($($rest)*) $($rest)*) + }; + + (epath ($pop:ident $stack:tt) $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($bang:tt $args:tt $($dup:tt)*) ! ($($mac:tt)*) $($rest:tt)*) => { + $crate::__parse_ensure!($pop $stack $bail ($($fuel)*) {($($buf)* $bang $args) $($parse)*} ($($rest)*) $($rest)*) + }; + + (epath ($pop:ident $stack:tt) $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($bang:tt $args:tt $($dup:tt)*) ! [$($mac:tt)*] $($rest:tt)*) => { + $crate::__parse_ensure!($pop $stack $bail ($($fuel)*) {($($buf)* $bang $args) $($parse)*} ($($rest)*) $($rest)*) + }; + + (epath ($pop:ident $stack:tt) $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($bang:tt $args:tt $($dup:tt)*) ! {$($mac:tt)*} $($rest:tt)*) => { + $crate::__parse_ensure!($pop $stack $bail ($($fuel)*) {($($buf)* $bang $args) $($parse)*} ($($rest)*) $($rest)*) + }; + + (epath (split ($pop:ident $stack:tt)) $bail:tt (~$($fuel:tt)*) $parse:tt $dup:tt $($rest:tt)*) => { + $crate::__parse_ensure!($pop (split $stack) $bail ($($fuel)*) $parse $dup $($rest)*) + }; + + (epath ($pop:ident $stack:tt) $bail:tt (~$($fuel:tt)*) $parse:tt $dup:tt $($rest:tt)*) => { + $crate::__parse_ensure!($pop $stack $bail ($($fuel)*) $parse $dup $($rest)*) + }; + + // trailer expressions + + (atom $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($paren:tt $($dup:tt)*) ($($call:tt)*) $($rest:tt)*) => { + $crate::__parse_ensure!(atom $stack $bail ($($fuel)*) {($($buf)* $paren) $($parse)*} ($($rest)*) $($rest)*) + }; + + (atom $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($bracket:tt $($dup:tt)*) [$($index:tt)*] $($rest:tt)*) => { + $crate::__parse_ensure!(atom $stack $bail ($($fuel)*) {($($buf)* $bracket) $($parse)*} ($($rest)*) $($rest)*) + }; + + (atom $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($brace:tt $($dup:tt)*) {$($init:tt)*} $($rest:tt)*) => { + $crate::__parse_ensure!(atom $stack $bail ($($fuel)*) {($($buf)* $brace) $($parse)*} ($($rest)*) $($rest)*) + }; + + (atom $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($question:tt $($dup:tt)*) ? $($rest:tt)*) => { + $crate::__parse_ensure!(atom $stack $bail ($($fuel)*) {($($buf)* $question) $($parse)*} ($($rest)*) $($rest)*) + }; + + (atom $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($dot:tt $ident:tt $colons:tt $langle:tt $($dup:tt)*) . $i:ident :: < $($rest:tt)*) => { + $crate::__parse_ensure!(generic (atom $stack) $bail ($($fuel)*) {($($buf)* $dot $ident $colons $langle) $($parse)*} ($($rest)*) $($rest)*) + }; + + (atom $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($dot:tt $ident:tt $colons:tt $langle:tt $($dup:tt)*) . $i:ident :: << $($rest:tt)*) => { + $crate::__parse_ensure!(type (qpath (tpath (arglist (atom $stack)))) $bail ($($fuel)*) {($($buf)* $dot $ident $colons $langle) $($parse)*} ($($rest)*) $($rest)*) + }; + + (atom $stack:tt ($($bail:tt)*) (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} $dup:tt . $i:ident :: <- - $($rest:tt)*) => { + $crate::__fallback_ensure!($($bail)*) + }; + + (atom $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($dot:tt $ident:tt $colons:tt $larrow:tt $($dup:tt)*) . $i:ident :: <- $lit:literal $($rest:tt)*) => { + $crate::__parse_ensure!(generic (atom $stack) $bail ($($fuel)*) {($($buf)* $dot $ident $colons $larrow) $($parse)*} ($($dup)*) $($dup)*) + }; + + (atom $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($dot:tt $field:tt $($dup:tt)*) . $i:ident $($rest:tt)*) => { + $crate::__parse_ensure!(atom $stack $bail ($($fuel)*) {($($buf)* $dot $field) $($parse)*} ($($rest)*) $($rest)*) + }; + + (atom $stack:tt ($($bail:tt)*) (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} $dup:tt . - $($rest:tt)*) => { + $crate::__fallback_ensure!($($bail)*) + }; + + (atom $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($dot:tt $index:tt $($dup:tt)*) . $lit:literal $($rest:tt)*) => { + $crate::__parse_ensure!(atom $stack $bail ($($fuel)*) {($($buf)* $dot $index) $($parse)*} ($($rest)*) $($rest)*) + }; + + (atom $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($as:tt $($dup:tt)*) as $($rest:tt)*) => { + $crate::__parse_ensure!(type (atom $stack) $bail ($($fuel)*) {($($buf)* $as) $($parse)*} ($($rest)*) $($rest)*) + }; + + // types + + (type ($pop:ident $stack:tt) $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($bracket:tt $($dup:tt)*) [$($content:tt)*] $($rest:tt)*) => { + $crate::__parse_ensure!($pop $stack $bail ($($fuel)*) {($($buf)* $bracket) $($parse)*} ($($rest)*) $($rest)*) + }; + + (type ($pop:ident $stack:tt) $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($paren:tt $($dup:tt)*) ($($content:tt)*) $($rest:tt)*) => { + $crate::__parse_ensure!($pop $stack $bail ($($fuel)*) {($($buf)* $paren) $($parse)*} ($($rest)*) $($rest)*) + }; + + (type $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($star:tt $const:tt $($dup:tt)*) *const $($rest:tt)*) => { + $crate::__parse_ensure!(type $stack $bail ($($fuel)*) {($($buf)* $star $const) $($parse)*} ($($rest)*) $($rest)*) + }; + + (type $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($star:tt $mut:tt $($dup:tt)*) *mut $($rest:tt)*) => { + $crate::__parse_ensure!(type $stack $bail ($($fuel)*) {($($buf)* $star $mut) $($parse)*} ($($rest)*) $($rest)*) + }; + + (type $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($and:tt $lifetime:tt $mut:tt $($dup:tt)*) & $l:lifetime mut $($rest:tt)*) => { + $crate::__parse_ensure!(type $stack $bail ($($fuel)*) {($($buf)* $and $lifetime $mut) $($parse)*} ($($rest)*) $($rest)*) + }; + + (type $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($and:tt $mut:tt $($dup:tt)*) & mut $($rest:tt)*) => { + $crate::__parse_ensure!(type $stack $bail ($($fuel)*) {($($buf)* $and $mut) $($parse)*} ($($rest)*) $($rest)*) + }; + + (type $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($and:tt $lifetime:tt $($dup:tt)*) & $l:lifetime $($rest:tt)*) => { + $crate::__parse_ensure!(type $stack $bail ($($fuel)*) {($($buf)* $and $lifetime) $($parse)*} ($($rest)*) $($rest)*) + }; + + (type $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($and:tt $($dup:tt)*) & $($rest:tt)*) => { + $crate::__parse_ensure!(type $stack $bail ($($fuel)*) {($($buf)* $and) $($parse)*} ($($rest)*) $($rest)*) + }; + + (type $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($and:tt $lifetime:tt $mut:tt $($dup:tt)*) && $l:lifetime mut $($rest:tt)*) => { + $crate::__parse_ensure!(type $stack $bail ($($fuel)*) {($($buf)* $and $lifetime $mut) $($parse)*} ($($rest)*) $($rest)*) + }; + + (type $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($and:tt $mut:tt $($dup:tt)*) && mut $($rest:tt)*) => { + $crate::__parse_ensure!(type $stack $bail ($($fuel)*) {($($buf)* $and $mut) $($parse)*} ($($rest)*) $($rest)*) + }; + + (type $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($and:tt $lifetime:tt $($dup:tt)*) && $l:lifetime $($rest:tt)*) => { + $crate::__parse_ensure!(type $stack $bail ($($fuel)*) {($($buf)* $and $lifetime) $($parse)*} ($($rest)*) $($rest)*) + }; + + (type $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($and:tt $($dup:tt)*) && $($rest:tt)*) => { + $crate::__parse_ensure!(type $stack $bail ($($fuel)*) {($($buf)* $and) $($parse)*} ($($rest)*) $($rest)*) + }; + + (type $stack:tt ($($bail:tt)*) (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} $dup:tt unsafe extern - $($rest:tt)*) => { + $crate::__fallback_ensure!($($bail)*) + }; + + (type $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($unsafe:tt $(extern $($abi:literal)?)? fn $($dup:tt)*) unsafe $($rest:tt)*) => { + $crate::__parse_ensure!(type $stack $bail ($($fuel)*) {($($buf)* $unsafe) $($parse)*} ($($rest)*) $($rest)*) + }; + + (type $stack:tt ($($bail:tt)*) (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} $dup:tt extern - $($rest:tt)*) => { + $crate::__fallback_ensure!($($bail)*) + }; + + (type $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($extern:tt $abi:tt fn $($dup:tt)*) extern $lit:literal $($rest:tt)*) => { + $crate::__parse_ensure!(type $stack $bail ($($fuel)*) {($($buf)* $extern $abi) $($parse)*} ($($rest)*) $($rest)*) + }; + + (type $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($extern:tt fn $($dup:tt)*) extern $($rest:tt)*) => { + $crate::__parse_ensure!(type $stack $bail ($($fuel)*) {($($buf)* $extern) $($parse)*} ($($rest)*) $($rest)*) + }; + + (type $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($fn:tt $paren:tt $arrow:tt $($dup:tt)*) fn ($($args:tt)*) -> $($rest:tt)*) => { + $crate::__parse_ensure!(type $stack $bail ($($fuel)*) {($($buf)* $fn $paren $arrow) $($parse)*} ($($rest)*) $($rest)*) + }; + + (type ($pop:ident $stack:tt) $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($fn:tt $paren:tt $($dup:tt)*) fn ($($args:tt)*) $($rest:tt)*) => { + $crate::__parse_ensure!($pop $stack $bail ($($fuel)*) {($($buf)* $fn $paren) $($parse)*} ($($rest)*) $($rest)*) + }; + + (type $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($impl:tt $($dup:tt)*) impl $($rest:tt)*) => { + $crate::__parse_ensure!(type $stack $bail ($($fuel)*) {($($buf)* $impl) $($parse)*} ($($rest)*) $($rest)*) + }; + + (type $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($dyn:tt $($dup:tt)*) dyn $($rest:tt)*) => { + $crate::__parse_ensure!(type $stack $bail ($($fuel)*) {($($buf)* $dyn) $($parse)*} ($($rest)*) $($rest)*) + }; + + (type ($pop:ident $stack:tt) $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($wild:tt $($dup:tt)*) _ $($rest:tt)*) => { + $crate::__parse_ensure!($pop $stack $bail ($($fuel)*) {($($buf)* $wild) $($parse)*} ($($rest)*) $($rest)*) + }; + + (type ($pop:ident $stack:tt) $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($never:tt $($dup:tt)*) ! $($rest:tt)*) => { + $crate::__parse_ensure!($pop $stack $bail ($($fuel)*) {($($buf)* $never) $($parse)*} ($($rest)*) $($rest)*) + }; + + (type $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($for:tt $langle:tt $($dup:tt)*) for < $($rest:tt)*) => { + $crate::__parse_ensure!(generic (type $stack) $bail ($($fuel)*) {($($buf)* $for $langle) $($parse)*} ($($rest)*) $($rest)*) + }; + + // path types + + (type $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($colons:tt $ident:tt $($dup:tt)*) :: $i:ident $($rest:tt)*) => { + $crate::__parse_ensure!(tpath $stack $bail ($($fuel)*) {($($buf)* $colons $ident) $($parse)*} ($($rest)*) $($rest)*) + }; + + (type $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($ident:tt $($dup:tt)*) $i:ident $($rest:tt)*) => { + $crate::__parse_ensure!(tpath $stack $bail ($($fuel)*) {($($buf)* $ident) $($parse)*} ($($rest)*) $($rest)*) + }; + + (type $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($langle:tt $($dup:tt)*) < $($rest:tt)*) => { + $crate::__parse_ensure!(type (qpath (tpath $stack)) $bail ($($fuel)*) {($($buf)* $langle) $($parse)*} ($($rest)*) $($rest)*) + }; + + (tpath $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($langle:tt $($dup:tt)*) < $($rest:tt)*) => { + $crate::__parse_ensure!(generic (tpath $stack) $bail ($($fuel)*) {($($buf)* $langle) $($parse)*} ($($rest)*) $($rest)*) + }; + + (tpath $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($langle:tt $($dup:tt)*) << $($rest:tt)*) => { + $crate::__parse_ensure!(type (qpath (tpath (arglist (tpath $stack)))) $bail ($($fuel)*) {($($buf)* $langle) $($parse)*} ($($rest)*) $($rest)*) + }; + + (tpath $stack:tt ($($bail:tt)*) (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} $dup:tt <- - $($rest:tt)*) => { + $crate::__fallback_ensure!($($bail)*) + }; + + (tpath $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($larrow:tt $($dup:tt)*) <- $lit:literal $($rest:tt)*) => { + $crate::__parse_ensure!(generic (tpath $stack) $bail ($($fuel)*) {($($buf)* $larrow) $($parse)*} ($($dup)*) $($dup)*) + }; + + (tpath $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($colons:tt $langle:tt $($dup:tt)*) :: < $($rest:tt)*) => { + $crate::__parse_ensure!(generic (tpath $stack) $bail ($($fuel)*) {($($buf)* $colons $langle) $($parse)*} ($($rest)*) $($rest)*) + }; + + (tpath $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($colons:tt $langle:tt $($dup:tt)*) :: << $($rest:tt)*) => { + $crate::__parse_ensure!(type (qpath (tpath (arglist (tpath $stack)))) $bail ($($fuel)*) {($($buf)* $colons $langle) $($parse)*} ($($rest)*) $($rest)*) + }; + + (tpath $stack:tt ($($bail:tt)*) (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} $dup:tt :: <- - $($rest:tt)*) => { + $crate::__fallback_ensure!($($bail)*) + }; + + (tpath $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($colons:tt $larrow:tt $($dup:tt)*) :: <- $lit:literal $($rest:tt)*) => { + $crate::__parse_ensure!(generic (tpath $stack) $bail ($($fuel)*) {($($buf)* $colons $larrow) $($parse)*} ($($dup)*) $($dup)*) + }; + + (tpath $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($colons:tt $ident:tt $($dup:tt)*) :: $i:ident $($rest:tt)*) => { + $crate::__parse_ensure!(tpath $stack $bail ($($fuel)*) {($($buf)* $colons $ident) $($parse)*} ($($rest)*) $($rest)*) + }; + + (tpath $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($paren:tt $arrow:tt $($dup:tt)*) ($($args:tt)*) -> $($rest:tt)*) => { + $crate::__parse_ensure!(type $stack $bail ($($fuel)*) {($($buf)* $paren $arrow) $($parse)*} ($($rest)*) $($rest)*) + }; + + (tpath $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($paren:tt $($dup:tt)*) ($($args:tt)*) $($rest:tt)*) => { + $crate::__parse_ensure!(object $stack $bail ($($fuel)*) {($($buf)* $paren) $($parse)*} ($($rest)*) $($rest)*) + }; + + (tpath $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($colons:tt $paren:tt $arrow:tt $($dup:tt)*) :: ($($args:tt)*) -> $($rest:tt)*) => { + $crate::__parse_ensure!(type $stack $bail ($($fuel)*) {($($buf)* $colons $paren $arrow) $($parse)*} ($($rest)*) $($rest)*) + }; + + (tpath $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($colons:tt $paren:tt $($dup:tt)*) :: ($($args:tt)*) $($rest:tt)*) => { + $crate::__parse_ensure!(object $stack $bail ($($fuel)*) {($($buf)* $colons $paren) $($parse)*} ($($rest)*) $($rest)*) + }; + + (tpath ($pop:ident $stack:tt) $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($bang:tt $args:tt $($dup:tt)*) ! ($($mac:tt)*) $($rest:tt)*) => { + $crate::__parse_ensure!($pop $stack $bail ($($fuel)*) {($($buf)* $bang $args) $($parse)*} ($($rest)*) $($rest)*) + }; + + (tpath ($pop:ident $stack:tt) $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($bang:tt $args:tt $($dup:tt)*) ! [$($mac:tt)*] $($rest:tt)*) => { + $crate::__parse_ensure!($pop $stack $bail ($($fuel)*) {($($buf)* $bang $args) $($parse)*} ($($rest)*) $($rest)*) + }; + + (tpath ($pop:ident $stack:tt) $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($bang:tt $args:tt $($dup:tt)*) ! {$($mac:tt)*} $($rest:tt)*) => { + $crate::__parse_ensure!($pop $stack $bail ($($fuel)*) {($($buf)* $bang $args) $($parse)*} ($($rest)*) $($rest)*) + }; + + (tpath $stack:tt $bail:tt (~$($fuel:tt)*) $parse:tt $dup:tt $($rest:tt)*) => { + $crate::__parse_ensure!(object $stack $bail ($($fuel)*) $parse $dup $($rest)*) + }; + + // qualified paths + + (qpath (split ($pop:ident $stack:tt)) $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($rangle:tt $colons:tt $ident:tt $($dup:tt)*) >> :: $i:ident $($rest:tt)*) => { + $crate::__parse_ensure!($pop $stack $bail ($($fuel)*) {($($buf)* $rangle $colons $ident) $($parse)*} ($($rest)*) $($rest)*) + }; + + (qpath ($pop:ident $stack:tt) $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($rangle:tt $colons:tt $ident:tt $($dup:tt)*) > :: $i:ident $($rest:tt)*) => { + $crate::__parse_ensure!($pop $stack $bail ($($fuel)*) {($($buf)* $rangle $colons $ident) $($parse)*} ($($rest)*) $($rest)*) + }; + + (qpath $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($as:tt $($dup:tt)*) as $($rest:tt)*) => { + $crate::__parse_ensure!(type (qpath $stack) $bail ($($fuel)*) {($($buf)* $as) $($parse)*} ($($rest)*) $($rest)*) + }; + + // trait objects + + (object (arglist $stack:tt) $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($plus:tt $colons:tt $ident:tt $($dup:tt)*) + :: $i:ident $($rest:tt)*) => { + $crate::__parse_ensure!(tpath (arglist $stack) $bail ($($fuel)*) {($($buf)* $plus $colons $ident) $($parse)*} ($($rest)*) $($rest)*) + }; + + (object (arglist $stack:tt) $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($plus:tt $ident:tt $($dup:tt)*) + $i:ident $($rest:tt)*) => { + $crate::__parse_ensure!(tpath (arglist $stack) $bail ($($fuel)*) {($($buf)* $plus $ident) $($parse)*} ($($rest)*) $($rest)*) + }; + + (object (split ($pop:ident $stack:tt)) $bail:tt (~$($fuel:tt)*) $parse:tt $dup:tt $($rest:tt)*) => { + $crate::__parse_ensure!($pop (split $stack) $bail ($($fuel)*) $parse $dup $($rest)*) + }; + + (object ($pop:ident $stack:tt) $bail:tt (~$($fuel:tt)*) $parse:tt $dup:tt $($rest:tt)*) => { + $crate::__parse_ensure!($pop $stack $bail ($($fuel)*) $parse $dup $($rest)*) + }; + + // angle bracketed generic arguments + + (generic (split ($pop:ident $stack:tt)) $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($rangle:tt $($dup:tt)*) >> $($rest:tt)*) => { + $crate::__parse_ensure!($pop $stack $bail ($($fuel)*) {($($buf)* $rangle) $($parse)*} ($($rest)*) $($rest)*) + }; + + (generic ($pop:ident $stack:tt) $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($rangle:tt $($dup:tt)*) > $($rest:tt)*) => { + $crate::__parse_ensure!($pop $stack $bail ($($fuel)*) {($($buf)* $rangle) $($parse)*} ($($rest)*) $($rest)*) + }; + + (generic ($pop:ident $stack:tt) $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($rangle:tt $($dup:tt)*) >> $($rest:tt)*) => { + $crate::__parse_ensure!($pop (split $stack) $bail ($($fuel)*) {($($buf)*) $($parse)*} ($rangle $($rest)*) $rangle $($rest)*) + }; + + (generic $stack:tt ($($bail:tt)*) (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} $dup:tt - - $($rest:tt)*) => { + $crate::__fallback_ensure!($($bail)*) + }; + + (generic $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($neg:tt $($dup:tt)*) - $lit:literal $($rest:tt)*) => { + $crate::__parse_ensure!(generic $stack $bail ($($fuel)*) {($($buf)* $neg) $($parse)*} ($($dup)*) $($dup)*) + }; + + (generic $stack:tt ($($bail:tt)*) (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} $dup:tt - $($rest:tt)*) => { + $crate::__fallback_ensure!($($bail)*) + }; + + (generic $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($literal:tt $($dup:tt)*) $lit:literal $($rest:tt)*) => { + $crate::__parse_ensure!(arglist $stack $bail ($($fuel)*) {($($buf)* $literal) $($parse)*} ($($rest)*) $($rest)*) + }; + + (generic $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($brace:tt $($dup:tt)*) {$($block:tt)*} $($rest:tt)*) => { + $crate::__parse_ensure!(arglist $stack $bail ($($fuel)*) {($($buf)* $brace) $($parse)*} ($($rest)*) $($rest)*) + }; + + (generic $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($lifetime:tt $($dup:tt)*) $l:lifetime $($rest:tt)*) => { + $crate::__parse_ensure!(arglist $stack $bail ($($fuel)*) {($($buf)* $lifetime) $($parse)*} ($($rest)*) $($rest)*) + }; + + (generic $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($assoc:tt $eq:tt $($dup:tt)*) $ident:ident = $($rest:tt)*) => { + $crate::__parse_ensure!(type (arglist $stack) $bail ($($fuel)*) {($($buf)* $assoc $eq) $($parse)*} ($($rest)*) $($rest)*) + }; + + (generic $stack:tt $bail:tt (~$($fuel:tt)*) $parse:tt $dup:tt $($rest:tt)*) => { + $crate::__parse_ensure!(type (arglist $stack) $bail ($($fuel)*) $parse $dup $($rest)*) + }; + + (arglist $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($comma:tt $($dup:tt)*) , $($rest:tt)*) => { + $crate::__parse_ensure!(generic $stack $bail ($($fuel)*) {($($buf)* $comma) $($parse)*} ($($rest)*) $($rest)*) + }; + + (arglist (split ($pop:ident $stack:tt)) $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($rangle:tt $($dup:tt)*) >> $($rest:tt)*) => { + $crate::__parse_ensure!($pop $stack $bail ($($fuel)*) {($($buf)*) $rangle $($parse)*} ($($rest)*) $($rest)*) + }; + + (arglist ($pop:ident $stack:tt) $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($rangle:tt $($dup:tt)*) > $($rest:tt)*) => { + $crate::__parse_ensure!($pop $stack $bail ($($fuel)*) {($($buf)* $rangle) $($parse)*} ($($rest)*) $($rest)*) + }; + + (arglist ($pop:ident $stack:tt) $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($rangle:tt $($dup:tt)*) >> $($rest:tt)*) => { + $crate::__parse_ensure!($pop (split $stack) $bail ($($fuel)*) {($($buf)*) $($parse)*} ($rangle $($rest)*) $rangle $($rest)*) + }; + + // patterns + + (pat $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($pipe:tt $($dup:tt)*) | $($rest:tt)*) => { + $crate::__parse_ensure!(pat $stack $bail ($($fuel)*) {($($buf)* $pipe) $($parse)*} ($($rest)*) $($rest)*) + }; + + (pat $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($eq:tt $($dup:tt)*) = $($rest:tt)*) => { + $crate::__parse_ensure!(0 $stack $bail ($($fuel)*) {($($buf)* $eq) $($parse)*} ($($rest)*) $($rest)*) + }; + + (pat $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($in:tt $($dup:tt)*) in $($rest:tt)*) => { + $crate::__parse_ensure!(0 $stack $bail ($($fuel)*) {($($buf)* $in) $($parse)*} ($($rest)*) $($rest)*) + }; + + (pat $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($ref:tt $($dup:tt)*) ref $($rest:tt)*) => { + $crate::__parse_ensure!(pat $stack $bail ($($fuel)*) {($($buf)* $ref) $($parse)*} ($($rest)*) $($rest)*) + }; + + (pat $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($mut:tt $($dup:tt)*) mut $($rest:tt)*) => { + $crate::__parse_ensure!(pat $stack $bail ($($fuel)*) {($($buf)* $mut) $($parse)*} ($($rest)*) $($rest)*) + }; + + (pat $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($at:tt $($dup:tt)*) @ $($rest:tt)*) => { + $crate::__parse_ensure!(pat $stack $bail ($($fuel)*) {($($buf)* $at) $($parse)*} ($($rest)*) $($rest)*) + }; + + (pat $stack:tt ($($bail:tt)*) (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} $dup:tt - - $($rest:tt)*) => { + $crate::__fallback_ensure!($($bail)*) + }; + + (pat $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($neg:tt $($dup:tt)*) - $lit:literal $($rest:tt)*) => { + $crate::__parse_ensure!(pat $stack $bail ($($fuel)*) {($($buf)* $neg) $($parse)*} ($($dup)*) $($dup)*) + }; + + (pat $stack:tt ($($bail:tt)*) (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} $dup:tt - $($rest:tt)*) => { + $crate::__fallback_ensure!($($bail)*) + }; + + (pat $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($literal:tt $($dup:tt)*) $lit:literal $($rest:tt)*) => { + $crate::__parse_ensure!(pat $stack $bail ($($fuel)*) {($($buf)* $literal) $($parse)*} ($($rest)*) $($rest)*) + }; + + (pat $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($range:tt $($dup:tt)*) .. $($rest:tt)*) => { + $crate::__parse_ensure!(pat $stack $bail ($($fuel)*) {($($buf)* $range) $($parse)*} ($($rest)*) $($rest)*) + }; + + (pat $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($range:tt $($dup:tt)*) ..= $($rest:tt)*) => { + $crate::__parse_ensure!(pat $stack $bail ($($fuel)*) {($($buf)* $range) $($parse)*} ($($rest)*) $($rest)*) + }; + + (pat $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($and:tt $($dup:tt)*) & $($rest:tt)*) => { + $crate::__parse_ensure!(pat $stack $bail ($($fuel)*) {($($buf)* $and) $($parse)*} ($($rest)*) $($rest)*) + }; + + (pat $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($andand:tt $($dup:tt)*) && $($rest:tt)*) => { + $crate::__parse_ensure!(pat $stack $bail ($($fuel)*) {($($buf)* $andand) $($parse)*} ($($rest)*) $($rest)*) + }; + + (pat $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($paren:tt $($dup:tt)*) ($($content:tt)*) $($rest:tt)*) => { + $crate::__parse_ensure!(pat $stack $bail ($($fuel)*) {($($buf)* $paren) $($parse)*} ($($rest)*) $($rest)*) + }; + + (pat $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($bracket:tt $($dup:tt)*) [$($content:tt)*] $($rest:tt)*) => { + $crate::__parse_ensure!(pat $stack $bail ($($fuel)*) {($($buf)* $bracket) $($parse)*} ($($rest)*) $($rest)*) + }; + + (pat $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($brace:tt $($dup:tt)*) {$($content:tt)*} $($rest:tt)*) => { + $crate::__parse_ensure!(pat $stack $bail ($($fuel)*) {($($buf)* $brace) $($parse)*} ($($rest)*) $($rest)*) + }; + + (pat $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($wild:tt $($dup:tt)*) _ $($rest:tt)*) => { + $crate::__parse_ensure!(pat $stack $bail ($($fuel)*) {($($buf)* $wild) $($parse)*} ($($rest)*) $($rest)*) + }; + + (pat $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($colons:tt $ident:tt $($dup:tt)*) :: $i:ident $($rest:tt)*) => { + $crate::__parse_ensure!(epath (pat $stack) $bail ($($fuel)*) {($($buf)* $colons $ident) $($parse)*} ($($rest)*) $($rest)*) + }; + + (pat $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($ident:tt $($dup:tt)*) $i:ident $($rest:tt)*) => { + $crate::__parse_ensure!(epath (pat $stack) $bail ($($fuel)*) {($($buf)* $ident) $($parse)*} ($($rest)*) $($rest)*) + }; + + (pat $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($langle:tt $($dup:tt)*) < $($rest:tt)*) => { + $crate::__parse_ensure!(type (qpath (epath (pat $stack))) $bail ($($fuel)*) {($($buf)* $langle) $($parse)*} ($($rest)*) $($rest)*) + }; + + // comparison binary operators + + (atom () $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($eq:tt $($dup:tt)*) == $($rest:tt)*) => { + $crate::__parse_ensure!(0 () $bail ($($fuel)*) {() $($parse)* ($($buf)*) $eq} ($($rest)*) $($rest)*) + }; + + (atom $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)+) $($parse:tt)*} ($eq:tt $($dup:tt)*) == $($rest:tt)*) => { + $crate::__parse_ensure!(0 $stack $bail ($($fuel)*) {($($buf)* $eq) $($parse)*} ($($rest)*) $($rest)*) + }; + + (atom () $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($le:tt $($dup:tt)*) <= $($rest:tt)*) => { + $crate::__parse_ensure!(0 () $bail ($($fuel)*) {() $($parse)* ($($buf)*) $le} ($($rest)*) $($rest)*) + }; + + (atom $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)+) $($parse:tt)*} ($le:tt $($dup:tt)*) <= $($rest:tt)*) => { + $crate::__parse_ensure!(0 $stack $bail ($($fuel)*) {($($buf)* $le) $($parse)*} ($($rest)*) $($rest)*) + }; + + (atom () $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($lt:tt $($dup:tt)*) < $($rest:tt)*) => { + $crate::__parse_ensure!(0 () $bail ($($fuel)*) {() $($parse)* ($($buf)*) $lt} ($($rest)*) $($rest)*) + }; + + (atom $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)+) $($parse:tt)*} ($lt:tt $($dup:tt)*) < $($rest:tt)*) => { + $crate::__parse_ensure!(0 $stack $bail ($($fuel)*) {($($buf)* $lt) $($parse)*} ($($rest)*) $($rest)*) + }; + + (atom () $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($ne:tt $($dup:tt)*) != $($rest:tt)*) => { + $crate::__parse_ensure!(0 () $bail ($($fuel)*) {() $($parse)* ($($buf)*) $ne} ($($rest)*) $($rest)*) + }; + + (atom $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)+) $($parse:tt)*} ($ne:tt $($dup:tt)*) != $($rest:tt)*) => { + $crate::__parse_ensure!(0 $stack $bail ($($fuel)*) {($($buf)* $ne) $($parse)*} ($($rest)*) $($rest)*) + }; + + (atom () $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($ge:tt $($dup:tt)*) >= $($rest:tt)*) => { + $crate::__parse_ensure!(0 () $bail ($($fuel)*) {() $($parse)* ($($buf)*) $ge} ($($rest)*) $($rest)*) + }; + + (atom $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)+) $($parse:tt)*} ($ge:tt $($dup:tt)*) >= $($rest:tt)*) => { + $crate::__parse_ensure!(0 $stack $bail ($($fuel)*) {($($buf)* $ge) $($parse)*} ($($rest)*) $($rest)*) + }; + + (atom (split ()) $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} $dup:tt >> $($rest:tt)*) => { + $crate::__parse_ensure!(0 () $bail ($($fuel)*) {() $($parse)* ($($buf)* > ) > } ($($rest)*) $($rest)*) + }; + + (atom () $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($gt:tt $($dup:tt)*) > $($rest:tt)*) => { + $crate::__parse_ensure!(0 () $bail ($($fuel)*) {() $($parse)* ($($buf)*) $gt} ($($rest)*) $($rest)*) + }; + + (atom (split $stack:tt) $bail:tt (~$($fuel:tt)*) {($($buf:tt)+) $($parse:tt)*} ($rangle:tt $($dup:tt)*) >> $($rest:tt)*) => { + $crate::__parse_ensure!(0 $stack $bail ($($fuel)*) {($($buf)* $rangle) $($parse)*} ($($rest)*) $($rest)*) + }; + + (atom $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)+) $($parse:tt)*} ($gt:tt $($dup:tt)*) > $($rest:tt)*) => { + $crate::__parse_ensure!(0 $stack $bail ($($fuel)*) {($($buf)* $gt) $($parse)*} ($($rest)*) $($rest)*) + }; + + // high precedence binary operators + + (atom $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($add:tt $($dup:tt)*) + $($rest:tt)*) => { + $crate::__parse_ensure!(0 $stack $bail ($($fuel)*) {($($buf)* $add) $($parse)*} ($($rest)*) $($rest)*) + }; + + (atom $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($sub:tt $($dup:tt)*) - $($rest:tt)*) => { + $crate::__parse_ensure!(0 $stack $bail ($($fuel)*) {($($buf)* $sub) $($parse)*} ($($rest)*) $($rest)*) + }; + + (atom $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($mul:tt $($dup:tt)*) * $($rest:tt)*) => { + $crate::__parse_ensure!(0 $stack $bail ($($fuel)*) {($($buf)* $mul) $($parse)*} ($($rest)*) $($rest)*) + }; + + (atom $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($div:tt $($dup:tt)*) / $($rest:tt)*) => { + $crate::__parse_ensure!(0 $stack $bail ($($fuel)*) {($($buf)* $div) $($parse)*} ($($rest)*) $($rest)*) + }; + + (atom $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($rem:tt $($dup:tt)*) % $($rest:tt)*) => { + $crate::__parse_ensure!(0 $stack $bail ($($fuel)*) {($($buf)* $rem) $($parse)*} ($($rest)*) $($rest)*) + }; + + (atom $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($bitxor:tt $($dup:tt)*) ^ $($rest:tt)*) => { + $crate::__parse_ensure!(0 $stack $bail ($($fuel)*) {($($buf)* $bitxor) $($parse)*} ($($rest)*) $($rest)*) + }; + + (atom $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($bitand:tt $($dup:tt)*) & $($rest:tt)*) => { + $crate::__parse_ensure!(0 $stack $bail ($($fuel)*) {($($buf)* $bitand) $($parse)*} ($($rest)*) $($rest)*) + }; + + (atom $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($bitor:tt $($dup:tt)*) | $($rest:tt)*) => { + $crate::__parse_ensure!(0 $stack $bail ($($fuel)*) {($($buf)* $bitor) $($parse)*} ($($rest)*) $($rest)*) + }; + + (atom $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($shl:tt $($dup:tt)*) << $($rest:tt)*) => { + $crate::__parse_ensure!(0 $stack $bail ($($fuel)*) {($($buf)* $shl) $($parse)*} ($($rest)*) $($rest)*) + }; + + (atom $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($shr:tt $($dup:tt)*) >> $($rest:tt)*) => { + $crate::__parse_ensure!(0 $stack $bail ($($fuel)*) {($($buf)* $shr) $($parse)*} ($($rest)*) $($rest)*) + }; + + // low precedence binary operators + + (atom ($($stack:tt)+) $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($and:tt $($dup:tt)*) && $($rest:tt)*) => { + $crate::__parse_ensure!(0 ($($stack)*) $bail ($($fuel)*) {($($buf)* $and) $($parse)*} ($($rest)*) $($rest)*) + }; + + (atom ($($stack:tt)+) $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($or:tt $($dup:tt)*) || $($rest:tt)*) => { + $crate::__parse_ensure!(0 ($($stack)*) $bail ($($fuel)*) {($($buf)* $or) $($parse)*} ($($rest)*) $($rest)*) + }; + + (atom ($($stack:tt)+) $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($assign:tt $($dup:tt)*) = $($rest:tt)*) => { + $crate::__parse_ensure!(0 ($($stack)*) $bail ($($fuel)*) {($($buf)* $assign) $($parse)*} ($($rest)*) $($rest)*) + }; + + (atom ($($stack:tt)+) $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($addeq:tt $($dup:tt)*) += $($rest:tt)*) => { + $crate::__parse_ensure!(0 ($($stack)*) $bail ($($fuel)*) {($($buf)* $addeq) $($parse)*} ($($rest)*) $($rest)*) + }; + + (atom ($($stack:tt)+) $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($subeq:tt $($dup:tt)*) -= $($rest:tt)*) => { + $crate::__parse_ensure!(0 ($($stack)*) $bail ($($fuel)*) {($($buf)* $subeq) $($parse)*} ($($rest)*) $($rest)*) + }; + + (atom ($($stack:tt)+) $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($muleq:tt $($dup:tt)*) *= $($rest:tt)*) => { + $crate::__parse_ensure!(0 ($($stack)*) $bail ($($fuel)*) {($($buf)* $muleq) $($parse)*} ($($rest)*) $($rest)*) + }; + + (atom ($($stack:tt)+) $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($diveq:tt $($dup:tt)*) /= $($rest:tt)*) => { + $crate::__parse_ensure!(0 ($($stack)*) $bail ($($fuel)*) {($($buf)* $diveq) $($parse)*} ($($rest)*) $($rest)*) + }; + + (atom ($($stack:tt)+) $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($remeq:tt $($dup:tt)*) %= $($rest:tt)*) => { + $crate::__parse_ensure!(0 ($($stack)*) $bail ($($fuel)*) {($($buf)* $remeq) $($parse)*} ($($rest)*) $($rest)*) + }; + + (atom ($($stack:tt)+) $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($bitxoreq:tt $($dup:tt)*) ^= $($rest:tt)*) => { + $crate::__parse_ensure!(0 ($($stack)*) $bail ($($fuel)*) {($($buf)* $bitxoreq) $($parse)*} ($($rest)*) $($rest)*) + }; + + (atom ($($stack:tt)+) $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($bitandeq:tt $($dup:tt)*) &= $($rest:tt)*) => { + $crate::__parse_ensure!(0 ($($stack)*) $bail ($($fuel)*) {($($buf)* $bitandeq) $($parse)*} ($($rest)*) $($rest)*) + }; + + (atom ($($stack:tt)+) $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($bitoreq:tt $($dup:tt)*) |= $($rest:tt)*) => { + $crate::__parse_ensure!(0 ($($stack)*) $bail ($($fuel)*) {($($buf)* $bitoreq) $($parse)*} ($($rest)*) $($rest)*) + }; + + (atom ($($stack:tt)+) $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($shleq:tt $($dup:tt)*) <<= $($rest:tt)*) => { + $crate::__parse_ensure!(0 ($($stack)*) $bail ($($fuel)*) {($($buf)* $shleq) $($parse)*} ($($rest)*) $($rest)*) + }; + + (atom ($($stack:tt)+) $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($shreq:tt $($dup:tt)*) >>= $($rest:tt)*) => { + $crate::__parse_ensure!(0 ($($stack)*) $bail ($($fuel)*) {($($buf)* $shreq) $($parse)*} ($($rest)*) $($rest)*) + }; + + // unrecognized expression + + ($state:tt $stack:tt ($($bail:tt)*) $($rest:tt)*) => { + $crate::__fallback_ensure!($($bail)*) + }; +} + +#[doc(hidden)] +#[macro_export] +macro_rules! __fancy_ensure { + ($lhs:expr, $op:tt, $rhs:expr) => { + match (&$lhs, &$rhs) { + (lhs, rhs) => { + if !(lhs $op rhs) { + #[allow(unused_imports)] + use $crate::__private::{BothDebug, NotBothDebug}; + return Err((lhs, rhs).__dispatch_ensure( + $crate::__private::concat!( + "Condition failed: `", + $crate::__private::stringify!($lhs), + " ", + $crate::__private::stringify!($op), + " ", + $crate::__private::stringify!($rhs), + "`", + ), + )); + } + } + } + }; +} + +#[doc(hidden)] +#[macro_export] +macro_rules! __fallback_ensure { + ($cond:expr $(,)?) => { + if $crate::__private::not($cond) { + return $crate::__private::Err($crate::Error::msg( + $crate::__private::concat!("Condition failed: `", $crate::__private::stringify!($cond), "`") + )); + } + }; + ($cond:expr, $msg:literal $(,)?) => { + if $crate::__private::not($cond) { + return $crate::__private::Err($crate::__anyhow!($msg)); + } + }; + ($cond:expr, $err:expr $(,)?) => { + if $crate::__private::not($cond) { + return $crate::__private::Err($crate::__anyhow!($err)); + } + }; + ($cond:expr, $fmt:expr, $($arg:tt)*) => { + if $crate::__private::not($cond) { + return $crate::__private::Err($crate::__anyhow!($fmt, $($arg)*)); + } + }; +} diff --git a/vendor/anyhow/src/error.rs b/vendor/anyhow/src/error.rs new file mode 100644 index 0000000..a83eb7e --- /dev/null +++ b/vendor/anyhow/src/error.rs @@ -0,0 +1,1027 @@ +use crate::backtrace::Backtrace; +use crate::chain::Chain; +#[cfg(any(feature = "std", not(anyhow_no_core_error), anyhow_no_ptr_addr_of))] +use crate::ptr::Mut; +use crate::ptr::{Own, Ref}; +use crate::{Error, StdError}; +use alloc::boxed::Box; +use core::any::TypeId; +#[cfg(error_generic_member_access)] +use core::error::{self, Request}; +use core::fmt::{self, Debug, Display}; +use core::mem::ManuallyDrop; +#[cfg(any(feature = "std", not(anyhow_no_core_error)))] +use core::ops::{Deref, DerefMut}; +#[cfg(not(anyhow_no_core_unwind_safe))] +use core::panic::{RefUnwindSafe, UnwindSafe}; +#[cfg(not(anyhow_no_ptr_addr_of))] +use core::ptr; +use core::ptr::NonNull; +#[cfg(all(feature = "std", anyhow_no_core_unwind_safe))] +use std::panic::{RefUnwindSafe, UnwindSafe}; + +impl Error { + /// Create a new error object from any error type. + /// + /// The error type must be threadsafe and `'static`, so that the `Error` + /// will be as well. + /// + /// If the error type does not provide a backtrace, a backtrace will be + /// created here to ensure that a backtrace exists. + #[cfg(any(feature = "std", not(anyhow_no_core_error)))] + #[cold] + #[must_use] + pub fn new(error: E) -> Self + where + E: StdError + Send + Sync + 'static, + { + let backtrace = backtrace_if_absent!(&error); + Error::from_std(error, backtrace) + } + + /// Create a new error object from a printable error message. + /// + /// If the argument implements std::error::Error, prefer `Error::new` + /// instead which preserves the underlying error's cause chain and + /// backtrace. If the argument may or may not implement std::error::Error + /// now or in the future, use `anyhow!(err)` which handles either way + /// correctly. + /// + /// `Error::msg("...")` is equivalent to `anyhow!("...")` but occasionally + /// convenient in places where a function is preferable over a macro, such + /// as iterator or stream combinators: + /// + /// ``` + /// # mod ffi { + /// # pub struct Input; + /// # pub struct Output; + /// # pub async fn do_some_work(_: Input) -> Result { + /// # unimplemented!() + /// # } + /// # } + /// # + /// # use ffi::{Input, Output}; + /// # + /// use anyhow::{Error, Result}; + /// use futures::stream::{Stream, StreamExt, TryStreamExt}; + /// + /// async fn demo(stream: S) -> Result> + /// where + /// S: Stream, + /// { + /// stream + /// .then(ffi::do_some_work) // returns Result + /// .map_err(Error::msg) + /// .try_collect() + /// .await + /// } + /// ``` + #[cold] + #[must_use] + pub fn msg(message: M) -> Self + where + M: Display + Debug + Send + Sync + 'static, + { + Error::from_adhoc(message, backtrace!()) + } + + #[cfg(any(feature = "std", not(anyhow_no_core_error)))] + #[cold] + pub(crate) fn from_std(error: E, backtrace: Option) -> Self + where + E: StdError + Send + Sync + 'static, + { + let vtable = &ErrorVTable { + object_drop: object_drop::, + object_ref: object_ref::, + #[cfg(anyhow_no_ptr_addr_of)] + object_mut: object_mut::, + object_boxed: object_boxed::, + object_downcast: object_downcast::, + #[cfg(anyhow_no_ptr_addr_of)] + object_downcast_mut: object_downcast_mut::, + object_drop_rest: object_drop_front::, + #[cfg(all( + not(error_generic_member_access), + any(std_backtrace, feature = "backtrace") + ))] + object_backtrace: no_backtrace, + }; + + // Safety: passing vtable that operates on the right type E. + unsafe { Error::construct(error, vtable, backtrace) } + } + + #[cold] + pub(crate) fn from_adhoc(message: M, backtrace: Option) -> Self + where + M: Display + Debug + Send + Sync + 'static, + { + use crate::wrapper::MessageError; + let error: MessageError = MessageError(message); + let vtable = &ErrorVTable { + object_drop: object_drop::>, + object_ref: object_ref::>, + #[cfg(all(any(feature = "std", not(anyhow_no_core_error)), anyhow_no_ptr_addr_of))] + object_mut: object_mut::>, + object_boxed: object_boxed::>, + object_downcast: object_downcast::, + #[cfg(anyhow_no_ptr_addr_of)] + object_downcast_mut: object_downcast_mut::, + object_drop_rest: object_drop_front::, + #[cfg(all( + not(error_generic_member_access), + any(std_backtrace, feature = "backtrace") + ))] + object_backtrace: no_backtrace, + }; + + // Safety: MessageError is repr(transparent) so it is okay for the + // vtable to allow casting the MessageError to M. + unsafe { Error::construct(error, vtable, backtrace) } + } + + #[cold] + pub(crate) fn from_display(message: M, backtrace: Option) -> Self + where + M: Display + Send + Sync + 'static, + { + use crate::wrapper::DisplayError; + let error: DisplayError = DisplayError(message); + let vtable = &ErrorVTable { + object_drop: object_drop::>, + object_ref: object_ref::>, + #[cfg(all(any(feature = "std", not(anyhow_no_core_error)), anyhow_no_ptr_addr_of))] + object_mut: object_mut::>, + object_boxed: object_boxed::>, + object_downcast: object_downcast::, + #[cfg(anyhow_no_ptr_addr_of)] + object_downcast_mut: object_downcast_mut::, + object_drop_rest: object_drop_front::, + #[cfg(all( + not(error_generic_member_access), + any(std_backtrace, feature = "backtrace") + ))] + object_backtrace: no_backtrace, + }; + + // Safety: DisplayError is repr(transparent) so it is okay for the + // vtable to allow casting the DisplayError to M. + unsafe { Error::construct(error, vtable, backtrace) } + } + + #[cfg(any(feature = "std", not(anyhow_no_core_error)))] + #[cold] + pub(crate) fn from_context(context: C, error: E, backtrace: Option) -> Self + where + C: Display + Send + Sync + 'static, + E: StdError + Send + Sync + 'static, + { + let error: ContextError = ContextError { context, error }; + + let vtable = &ErrorVTable { + object_drop: object_drop::>, + object_ref: object_ref::>, + #[cfg(anyhow_no_ptr_addr_of)] + object_mut: object_mut::>, + object_boxed: object_boxed::>, + object_downcast: context_downcast::, + #[cfg(anyhow_no_ptr_addr_of)] + object_downcast_mut: context_downcast_mut::, + object_drop_rest: context_drop_rest::, + #[cfg(all( + not(error_generic_member_access), + any(std_backtrace, feature = "backtrace") + ))] + object_backtrace: no_backtrace, + }; + + // Safety: passing vtable that operates on the right type. + unsafe { Error::construct(error, vtable, backtrace) } + } + + #[cfg(any(feature = "std", not(anyhow_no_core_error)))] + #[cold] + pub(crate) fn from_boxed( + error: Box, + backtrace: Option, + ) -> Self { + use crate::wrapper::BoxedError; + let error = BoxedError(error); + let vtable = &ErrorVTable { + object_drop: object_drop::, + object_ref: object_ref::, + #[cfg(anyhow_no_ptr_addr_of)] + object_mut: object_mut::, + object_boxed: object_boxed::, + object_downcast: object_downcast::>, + #[cfg(anyhow_no_ptr_addr_of)] + object_downcast_mut: object_downcast_mut::>, + object_drop_rest: object_drop_front::>, + #[cfg(all( + not(error_generic_member_access), + any(std_backtrace, feature = "backtrace") + ))] + object_backtrace: no_backtrace, + }; + + // Safety: BoxedError is repr(transparent) so it is okay for the vtable + // to allow casting to Box. + unsafe { Error::construct(error, vtable, backtrace) } + } + + // Takes backtrace as argument rather than capturing it here so that the + // user sees one fewer layer of wrapping noise in the backtrace. + // + // Unsafe because the given vtable must have sensible behavior on the error + // value of type E. + #[cold] + unsafe fn construct( + error: E, + vtable: &'static ErrorVTable, + backtrace: Option, + ) -> Self + where + E: StdError + Send + Sync + 'static, + { + let inner: Box> = Box::new(ErrorImpl { + vtable, + backtrace, + _object: error, + }); + // Erase the concrete type of E from the compile-time type system. This + // is equivalent to the safe unsize coercion from Box> to + // Box> except that the + // result is a thin pointer. The necessary behavior for manipulating the + // underlying ErrorImpl is preserved in the vtable provided by the + // caller rather than a builtin fat pointer vtable. + let inner = Own::new(inner).cast::(); + Error { inner } + } + + /// Wrap the error value with additional context. + /// + /// For attaching context to a `Result` as it is propagated, the + /// [`Context`][crate::Context] extension trait may be more convenient than + /// this function. + /// + /// The primary reason to use `error.context(...)` instead of + /// `result.context(...)` via the `Context` trait would be if the context + /// needs to depend on some data held by the underlying error: + /// + /// ``` + /// # use std::fmt::{self, Debug, Display}; + /// # + /// # type T = (); + /// # + /// # impl std::error::Error for ParseError {} + /// # impl Debug for ParseError { + /// # fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + /// # unimplemented!() + /// # } + /// # } + /// # impl Display for ParseError { + /// # fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + /// # unimplemented!() + /// # } + /// # } + /// # + /// use anyhow::Result; + /// use std::fs::File; + /// use std::path::Path; + /// + /// struct ParseError { + /// line: usize, + /// column: usize, + /// } + /// + /// fn parse_impl(file: File) -> Result { + /// # const IGNORE: &str = stringify! { + /// ... + /// # }; + /// # unimplemented!() + /// } + /// + /// pub fn parse(path: impl AsRef) -> Result { + /// let file = File::open(&path)?; + /// parse_impl(file).map_err(|error| { + /// let context = format!( + /// "only the first {} lines of {} are valid", + /// error.line, path.as_ref().display(), + /// ); + /// anyhow::Error::new(error).context(context) + /// }) + /// } + /// ``` + #[cold] + #[must_use] + pub fn context(self, context: C) -> Self + where + C: Display + Send + Sync + 'static, + { + let error: ContextError = ContextError { + context, + error: self, + }; + + let vtable = &ErrorVTable { + object_drop: object_drop::>, + object_ref: object_ref::>, + #[cfg(all(any(feature = "std", not(anyhow_no_core_error)), anyhow_no_ptr_addr_of))] + object_mut: object_mut::>, + object_boxed: object_boxed::>, + object_downcast: context_chain_downcast::, + #[cfg(anyhow_no_ptr_addr_of)] + object_downcast_mut: context_chain_downcast_mut::, + object_drop_rest: context_chain_drop_rest::, + #[cfg(all( + not(error_generic_member_access), + any(std_backtrace, feature = "backtrace") + ))] + object_backtrace: context_backtrace::, + }; + + // As the cause is anyhow::Error, we already have a backtrace for it. + let backtrace = None; + + // Safety: passing vtable that operates on the right type. + unsafe { Error::construct(error, vtable, backtrace) } + } + + /// Get the backtrace for this Error. + /// + /// In order for the backtrace to be meaningful, one of the two environment + /// variables `RUST_LIB_BACKTRACE=1` or `RUST_BACKTRACE=1` must be defined + /// and `RUST_LIB_BACKTRACE` must not be `0`. Backtraces are somewhat + /// expensive to capture in Rust, so we don't necessarily want to be + /// capturing them all over the place all the time. + /// + /// - If you want panics and errors to both have backtraces, set + /// `RUST_BACKTRACE=1`; + /// - If you want only errors to have backtraces, set + /// `RUST_LIB_BACKTRACE=1`; + /// - If you want only panics to have backtraces, set `RUST_BACKTRACE=1` and + /// `RUST_LIB_BACKTRACE=0`. + /// + /// # Stability + /// + /// Standard library backtraces are only available when using Rust ≥ + /// 1.65. On older compilers, this function is only available if the crate's + /// "backtrace" feature is enabled, and will use the `backtrace` crate as + /// the underlying backtrace implementation. The return type of this + /// function on old compilers is `&(impl Debug + Display)`. + /// + /// ```toml + /// [dependencies] + /// anyhow = { version = "1.0", features = ["backtrace"] } + /// ``` + #[cfg(any(std_backtrace, feature = "backtrace"))] + pub fn backtrace(&self) -> &impl_backtrace!() { + unsafe { ErrorImpl::backtrace(self.inner.by_ref()) } + } + + /// An iterator of the chain of source errors contained by this Error. + /// + /// This iterator will visit every error in the cause chain of this error + /// object, beginning with the error that this error object was created + /// from. + /// + /// # Example + /// + /// ``` + /// use anyhow::Error; + /// use std::io; + /// + /// pub fn underlying_io_error_kind(error: &Error) -> Option { + /// for cause in error.chain() { + /// if let Some(io_error) = cause.downcast_ref::() { + /// return Some(io_error.kind()); + /// } + /// } + /// None + /// } + /// ``` + #[cfg(any(feature = "std", not(anyhow_no_core_error)))] + #[cold] + pub fn chain(&self) -> Chain { + unsafe { ErrorImpl::chain(self.inner.by_ref()) } + } + + /// The lowest level cause of this error — this error's cause's + /// cause's cause etc. + /// + /// The root cause is the last error in the iterator produced by + /// [`chain()`][Error::chain]. + #[cfg(any(feature = "std", not(anyhow_no_core_error)))] + pub fn root_cause(&self) -> &(dyn StdError + 'static) { + self.chain().last().unwrap() + } + + /// Returns true if `E` is the type held by this error object. + /// + /// For errors with context, this method returns true if `E` matches the + /// type of the context `C` **or** the type of the error on which the + /// context has been attached. For details about the interaction between + /// context and downcasting, [see here]. + /// + /// [see here]: trait.Context.html#effect-on-downcasting + pub fn is(&self) -> bool + where + E: Display + Debug + Send + Sync + 'static, + { + self.downcast_ref::().is_some() + } + + /// Attempt to downcast the error object to a concrete type. + pub fn downcast(mut self) -> Result + where + E: Display + Debug + Send + Sync + 'static, + { + let target = TypeId::of::(); + let inner = self.inner.by_mut(); + unsafe { + // Use vtable to find NonNull<()> which points to a value of type E + // somewhere inside the data structure. + #[cfg(not(anyhow_no_ptr_addr_of))] + let addr = match (vtable(inner.ptr).object_downcast)(inner.by_ref(), target) { + Some(addr) => addr.by_mut().extend(), + None => return Err(self), + }; + #[cfg(anyhow_no_ptr_addr_of)] + let addr = match (vtable(inner.ptr).object_downcast_mut)(inner, target) { + Some(addr) => addr.extend(), + None => return Err(self), + }; + + // Prepare to read E out of the data structure. We'll drop the rest + // of the data structure separately so that E is not dropped. + let outer = ManuallyDrop::new(self); + + // Read E from where the vtable found it. + let error = addr.cast::().read(); + + // Drop rest of the data structure outside of E. + (vtable(outer.inner.ptr).object_drop_rest)(outer.inner, target); + + Ok(error) + } + } + + /// Downcast this error object by reference. + /// + /// # Example + /// + /// ``` + /// # use anyhow::anyhow; + /// # use std::fmt::{self, Display}; + /// # use std::task::Poll; + /// # + /// # #[derive(Debug)] + /// # enum DataStoreError { + /// # Censored(()), + /// # } + /// # + /// # impl Display for DataStoreError { + /// # fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + /// # unimplemented!() + /// # } + /// # } + /// # + /// # impl std::error::Error for DataStoreError {} + /// # + /// # const REDACTED_CONTENT: () = (); + /// # + /// # let error = anyhow!("..."); + /// # let root_cause = &error; + /// # + /// # let ret = + /// // If the error was caused by redaction, then return a tombstone instead + /// // of the content. + /// match root_cause.downcast_ref::() { + /// Some(DataStoreError::Censored(_)) => Ok(Poll::Ready(REDACTED_CONTENT)), + /// None => Err(error), + /// } + /// # ; + /// ``` + pub fn downcast_ref(&self) -> Option<&E> + where + E: Display + Debug + Send + Sync + 'static, + { + let target = TypeId::of::(); + unsafe { + // Use vtable to find NonNull<()> which points to a value of type E + // somewhere inside the data structure. + let addr = (vtable(self.inner.ptr).object_downcast)(self.inner.by_ref(), target)?; + Some(addr.cast::().deref()) + } + } + + /// Downcast this error object by mutable reference. + pub fn downcast_mut(&mut self) -> Option<&mut E> + where + E: Display + Debug + Send + Sync + 'static, + { + let target = TypeId::of::(); + unsafe { + // Use vtable to find NonNull<()> which points to a value of type E + // somewhere inside the data structure. + + #[cfg(not(anyhow_no_ptr_addr_of))] + let addr = + (vtable(self.inner.ptr).object_downcast)(self.inner.by_ref(), target)?.by_mut(); + + #[cfg(anyhow_no_ptr_addr_of)] + let addr = (vtable(self.inner.ptr).object_downcast_mut)(self.inner.by_mut(), target)?; + + Some(addr.cast::().deref_mut()) + } + } + + #[cfg(error_generic_member_access)] + pub(crate) fn provide<'a>(&'a self, request: &mut Request<'a>) { + unsafe { ErrorImpl::provide(self.inner.by_ref(), request) } + } + + // Called by thiserror when you have `#[source] anyhow::Error`. This provide + // implementation includes the anyhow::Error's Backtrace if any, unlike + // deref'ing to dyn Error where the provide implementation would include + // only the original error's Backtrace from before it got wrapped into an + // anyhow::Error. + #[cfg(error_generic_member_access)] + #[doc(hidden)] + pub fn thiserror_provide<'a>(&'a self, request: &mut Request<'a>) { + Self::provide(self, request); + } +} + +#[cfg(any(feature = "std", not(anyhow_no_core_error)))] +impl From for Error +where + E: StdError + Send + Sync + 'static, +{ + #[cold] + fn from(error: E) -> Self { + let backtrace = backtrace_if_absent!(&error); + Error::from_std(error, backtrace) + } +} + +#[cfg(any(feature = "std", not(anyhow_no_core_error)))] +impl Deref for Error { + type Target = dyn StdError + Send + Sync + 'static; + + fn deref(&self) -> &Self::Target { + unsafe { ErrorImpl::error(self.inner.by_ref()) } + } +} + +#[cfg(any(feature = "std", not(anyhow_no_core_error)))] +impl DerefMut for Error { + fn deref_mut(&mut self) -> &mut Self::Target { + unsafe { ErrorImpl::error_mut(self.inner.by_mut()) } + } +} + +impl Display for Error { + fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + unsafe { ErrorImpl::display(self.inner.by_ref(), formatter) } + } +} + +impl Debug for Error { + fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + unsafe { ErrorImpl::debug(self.inner.by_ref(), formatter) } + } +} + +impl Drop for Error { + fn drop(&mut self) { + unsafe { + // Invoke the vtable's drop behavior. + (vtable(self.inner.ptr).object_drop)(self.inner); + } + } +} + +struct ErrorVTable { + object_drop: unsafe fn(Own), + object_ref: unsafe fn(Ref) -> Ref, + #[cfg(all(any(feature = "std", not(anyhow_no_core_error)), anyhow_no_ptr_addr_of))] + object_mut: unsafe fn(Mut) -> &mut (dyn StdError + Send + Sync + 'static), + object_boxed: unsafe fn(Own) -> Box, + object_downcast: unsafe fn(Ref, TypeId) -> Option>, + #[cfg(anyhow_no_ptr_addr_of)] + object_downcast_mut: unsafe fn(Mut, TypeId) -> Option>, + object_drop_rest: unsafe fn(Own, TypeId), + #[cfg(all( + not(error_generic_member_access), + any(std_backtrace, feature = "backtrace") + ))] + object_backtrace: unsafe fn(Ref) -> Option<&Backtrace>, +} + +// Safety: requires layout of *e to match ErrorImpl. +unsafe fn object_drop(e: Own) { + // Cast back to ErrorImpl so that the allocator receives the correct + // Layout to deallocate the Box's memory. + let unerased_own = e.cast::>(); + drop(unsafe { unerased_own.boxed() }); +} + +// Safety: requires layout of *e to match ErrorImpl. +unsafe fn object_drop_front(e: Own, target: TypeId) { + // Drop the fields of ErrorImpl other than E as well as the Box allocation, + // without dropping E itself. This is used by downcast after doing a + // ptr::read to take ownership of the E. + let _ = target; + let unerased_own = e.cast::>>(); + drop(unsafe { unerased_own.boxed() }); +} + +// Safety: requires layout of *e to match ErrorImpl. +unsafe fn object_ref(e: Ref) -> Ref +where + E: StdError + Send + Sync + 'static, +{ + // Attach E's native StdError vtable onto a pointer to self._object. + + let unerased_ref = e.cast::>(); + + #[cfg(not(anyhow_no_ptr_addr_of))] + return Ref::from_raw(unsafe { + NonNull::new_unchecked(ptr::addr_of!((*unerased_ref.as_ptr())._object) as *mut E) + }); + + #[cfg(anyhow_no_ptr_addr_of)] + return Ref::new(unsafe { &unerased_ref.deref()._object }); +} + +// Safety: requires layout of *e to match ErrorImpl, and for `e` to be derived +// from a `&mut` +#[cfg(all(any(feature = "std", not(anyhow_no_core_error)), anyhow_no_ptr_addr_of))] +unsafe fn object_mut(e: Mut) -> &mut (dyn StdError + Send + Sync + 'static) +where + E: StdError + Send + Sync + 'static, +{ + // Attach E's native StdError vtable onto a pointer to self._object. + let unerased_mut = e.cast::>(); + unsafe { &mut unerased_mut.deref_mut()._object } +} + +// Safety: requires layout of *e to match ErrorImpl. +unsafe fn object_boxed(e: Own) -> Box +where + E: StdError + Send + Sync + 'static, +{ + // Attach ErrorImpl's native StdError vtable. The StdError impl is below. + let unerased_own = e.cast::>(); + unsafe { unerased_own.boxed() } +} + +// Safety: requires layout of *e to match ErrorImpl. +unsafe fn object_downcast(e: Ref, target: TypeId) -> Option> +where + E: 'static, +{ + if TypeId::of::() == target { + // Caller is looking for an E pointer and e is ErrorImpl, take a + // pointer to its E field. + + let unerased_ref = e.cast::>(); + + #[cfg(not(anyhow_no_ptr_addr_of))] + return Some( + Ref::from_raw(unsafe { + NonNull::new_unchecked(ptr::addr_of!((*unerased_ref.as_ptr())._object) as *mut E) + }) + .cast::<()>(), + ); + + #[cfg(anyhow_no_ptr_addr_of)] + return Some(Ref::new(unsafe { &unerased_ref.deref()._object }).cast::<()>()); + } else { + None + } +} + +// Safety: requires layout of *e to match ErrorImpl. +#[cfg(anyhow_no_ptr_addr_of)] +unsafe fn object_downcast_mut(e: Mut, target: TypeId) -> Option> +where + E: 'static, +{ + if TypeId::of::() == target { + // Caller is looking for an E pointer and e is ErrorImpl, take a + // pointer to its E field. + let unerased_mut = e.cast::>(); + let unerased = unsafe { unerased_mut.deref_mut() }; + Some(Mut::new(&mut unerased._object).cast::<()>()) + } else { + None + } +} + +#[cfg(all( + not(error_generic_member_access), + any(std_backtrace, feature = "backtrace") +))] +fn no_backtrace(e: Ref) -> Option<&Backtrace> { + let _ = e; + None +} + +// Safety: requires layout of *e to match ErrorImpl>. +#[cfg(any(feature = "std", not(anyhow_no_core_error)))] +unsafe fn context_downcast(e: Ref, target: TypeId) -> Option> +where + C: 'static, + E: 'static, +{ + if TypeId::of::() == target { + let unerased_ref = e.cast::>>(); + let unerased = unsafe { unerased_ref.deref() }; + Some(Ref::new(&unerased._object.context).cast::<()>()) + } else if TypeId::of::() == target { + let unerased_ref = e.cast::>>(); + let unerased = unsafe { unerased_ref.deref() }; + Some(Ref::new(&unerased._object.error).cast::<()>()) + } else { + None + } +} + +// Safety: requires layout of *e to match ErrorImpl>. +#[cfg(all(feature = "std", anyhow_no_ptr_addr_of))] +unsafe fn context_downcast_mut(e: Mut, target: TypeId) -> Option> +where + C: 'static, + E: 'static, +{ + if TypeId::of::() == target { + let unerased_mut = e.cast::>>(); + let unerased = unsafe { unerased_mut.deref_mut() }; + Some(Mut::new(&mut unerased._object.context).cast::<()>()) + } else if TypeId::of::() == target { + let unerased_mut = e.cast::>>(); + let unerased = unsafe { unerased_mut.deref_mut() }; + Some(Mut::new(&mut unerased._object.error).cast::<()>()) + } else { + None + } +} + +// Safety: requires layout of *e to match ErrorImpl>. +#[cfg(any(feature = "std", not(anyhow_no_core_error)))] +unsafe fn context_drop_rest(e: Own, target: TypeId) +where + C: 'static, + E: 'static, +{ + // Called after downcasting by value to either the C or the E and doing a + // ptr::read to take ownership of that value. + if TypeId::of::() == target { + let unerased_own = e.cast::, E>>>(); + drop(unsafe { unerased_own.boxed() }); + } else { + let unerased_own = e.cast::>>>(); + drop(unsafe { unerased_own.boxed() }); + } +} + +// Safety: requires layout of *e to match ErrorImpl>. +unsafe fn context_chain_downcast(e: Ref, target: TypeId) -> Option> +where + C: 'static, +{ + let unerased_ref = e.cast::>>(); + let unerased = unsafe { unerased_ref.deref() }; + if TypeId::of::() == target { + Some(Ref::new(&unerased._object.context).cast::<()>()) + } else { + // Recurse down the context chain per the inner error's vtable. + let source = &unerased._object.error; + unsafe { (vtable(source.inner.ptr).object_downcast)(source.inner.by_ref(), target) } + } +} + +// Safety: requires layout of *e to match ErrorImpl>. +#[cfg(anyhow_no_ptr_addr_of)] +unsafe fn context_chain_downcast_mut(e: Mut, target: TypeId) -> Option> +where + C: 'static, +{ + let unerased_mut = e.cast::>>(); + let unerased = unsafe { unerased_mut.deref_mut() }; + if TypeId::of::() == target { + Some(Mut::new(&mut unerased._object.context).cast::<()>()) + } else { + // Recurse down the context chain per the inner error's vtable. + let source = &mut unerased._object.error; + unsafe { (vtable(source.inner.ptr).object_downcast_mut)(source.inner.by_mut(), target) } + } +} + +// Safety: requires layout of *e to match ErrorImpl>. +unsafe fn context_chain_drop_rest(e: Own, target: TypeId) +where + C: 'static, +{ + // Called after downcasting by value to either the C or one of the causes + // and doing a ptr::read to take ownership of that value. + if TypeId::of::() == target { + let unerased_own = e.cast::, Error>>>(); + // Drop the entire rest of the data structure rooted in the next Error. + drop(unsafe { unerased_own.boxed() }); + } else { + let unerased_own = e.cast::>>>(); + let unerased = unsafe { unerased_own.boxed() }; + // Read the Own from the next error. + let inner = unerased._object.error.inner; + drop(unerased); + let vtable = unsafe { vtable(inner.ptr) }; + // Recursively drop the next error using the same target typeid. + unsafe { (vtable.object_drop_rest)(inner, target) }; + } +} + +// Safety: requires layout of *e to match ErrorImpl>. +#[cfg(all( + not(error_generic_member_access), + any(std_backtrace, feature = "backtrace") +))] +#[allow(clippy::unnecessary_wraps)] +unsafe fn context_backtrace(e: Ref) -> Option<&Backtrace> +where + C: 'static, +{ + let unerased_ref = e.cast::>>(); + let unerased = unsafe { unerased_ref.deref() }; + let backtrace = unsafe { ErrorImpl::backtrace(unerased._object.error.inner.by_ref()) }; + Some(backtrace) +} + +// NOTE: If working with `ErrorImpl<()>`, references should be avoided in favor +// of raw pointers and `NonNull`. +// repr C to ensure that E remains in the final position. +#[repr(C)] +pub(crate) struct ErrorImpl { + vtable: &'static ErrorVTable, + backtrace: Option, + // NOTE: Don't use directly. Use only through vtable. Erased type may have + // different alignment. + _object: E, +} + +// Reads the vtable out of `p`. This is the same as `p.as_ref().vtable`, but +// avoids converting `p` into a reference. +unsafe fn vtable(p: NonNull) -> &'static ErrorVTable { + // NOTE: This assumes that `ErrorVTable` is the first field of ErrorImpl. + unsafe { *(p.as_ptr() as *const &'static ErrorVTable) } +} + +// repr C to ensure that ContextError has the same layout as +// ContextError, E> and ContextError>. +#[repr(C)] +pub(crate) struct ContextError { + pub context: C, + pub error: E, +} + +impl ErrorImpl { + fn erase(&self) -> Ref { + // Erase the concrete type of E but preserve the vtable in self.vtable + // for manipulating the resulting thin pointer. This is analogous to an + // unsize coercion. + Ref::new(self).cast::() + } +} + +impl ErrorImpl { + pub(crate) unsafe fn error(this: Ref) -> &(dyn StdError + Send + Sync + 'static) { + // Use vtable to attach E's native StdError vtable for the right + // original type E. + unsafe { (vtable(this.ptr).object_ref)(this).deref() } + } + + #[cfg(any(feature = "std", not(anyhow_no_core_error)))] + pub(crate) unsafe fn error_mut(this: Mut) -> &mut (dyn StdError + Send + Sync + 'static) { + // Use vtable to attach E's native StdError vtable for the right + // original type E. + + #[cfg(not(anyhow_no_ptr_addr_of))] + return unsafe { + (vtable(this.ptr).object_ref)(this.by_ref()) + .by_mut() + .deref_mut() + }; + + #[cfg(anyhow_no_ptr_addr_of)] + return unsafe { (vtable(this.ptr).object_mut)(this) }; + } + + #[cfg(any(std_backtrace, feature = "backtrace"))] + pub(crate) unsafe fn backtrace(this: Ref) -> &Backtrace { + // This unwrap can only panic if the underlying error's backtrace method + // is nondeterministic, which would only happen in maliciously + // constructed code. + unsafe { this.deref() } + .backtrace + .as_ref() + .or_else(|| { + #[cfg(error_generic_member_access)] + return error::request_ref::(unsafe { Self::error(this) }); + #[cfg(not(error_generic_member_access))] + return unsafe { (vtable(this.ptr).object_backtrace)(this) }; + }) + .expect("backtrace capture failed") + } + + #[cfg(error_generic_member_access)] + unsafe fn provide<'a>(this: Ref<'a, Self>, request: &mut Request<'a>) { + if let Some(backtrace) = unsafe { &this.deref().backtrace } { + request.provide_ref(backtrace); + } + unsafe { Self::error(this) }.provide(request); + } + + #[cold] + pub(crate) unsafe fn chain(this: Ref) -> Chain { + Chain::new(unsafe { Self::error(this) }) + } +} + +impl StdError for ErrorImpl +where + E: StdError, +{ + fn source(&self) -> Option<&(dyn StdError + 'static)> { + unsafe { ErrorImpl::error(self.erase()).source() } + } + + #[cfg(error_generic_member_access)] + fn provide<'a>(&'a self, request: &mut Request<'a>) { + unsafe { ErrorImpl::provide(self.erase(), request) } + } +} + +impl Debug for ErrorImpl +where + E: Debug, +{ + fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + unsafe { ErrorImpl::debug(self.erase(), formatter) } + } +} + +impl Display for ErrorImpl +where + E: Display, +{ + fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + unsafe { Display::fmt(ErrorImpl::error(self.erase()), formatter) } + } +} + +impl From for Box { + #[cold] + fn from(error: Error) -> Self { + let outer = ManuallyDrop::new(error); + unsafe { + // Use vtable to attach ErrorImpl's native StdError vtable for + // the right original type E. + (vtable(outer.inner.ptr).object_boxed)(outer.inner) + } + } +} + +impl From for Box { + fn from(error: Error) -> Self { + Box::::from(error) + } +} + +impl From for Box { + fn from(error: Error) -> Self { + Box::::from(error) + } +} + +#[cfg(any(feature = "std", not(anyhow_no_core_error)))] +impl AsRef for Error { + fn as_ref(&self) -> &(dyn StdError + Send + Sync + 'static) { + &**self + } +} + +#[cfg(any(feature = "std", not(anyhow_no_core_error)))] +impl AsRef for Error { + fn as_ref(&self) -> &(dyn StdError + 'static) { + &**self + } +} + +#[cfg(any(feature = "std", not(anyhow_no_core_unwind_safe)))] +impl UnwindSafe for Error {} + +#[cfg(any(feature = "std", not(anyhow_no_core_unwind_safe)))] +impl RefUnwindSafe for Error {} diff --git a/vendor/anyhow/src/fmt.rs b/vendor/anyhow/src/fmt.rs new file mode 100644 index 0000000..85c84a9 --- /dev/null +++ b/vendor/anyhow/src/fmt.rs @@ -0,0 +1,158 @@ +use crate::chain::Chain; +use crate::error::ErrorImpl; +use crate::ptr::Ref; +use core::fmt::{self, Debug, Write}; + +impl ErrorImpl { + pub(crate) unsafe fn display(this: Ref, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "{}", unsafe { Self::error(this) })?; + + if f.alternate() { + let chain = unsafe { Self::chain(this) }; + for cause in chain.skip(1) { + write!(f, ": {}", cause)?; + } + } + + Ok(()) + } + + pub(crate) unsafe fn debug(this: Ref, f: &mut fmt::Formatter) -> fmt::Result { + let error = unsafe { Self::error(this) }; + + if f.alternate() { + return Debug::fmt(error, f); + } + + write!(f, "{}", error)?; + + if let Some(cause) = error.source() { + write!(f, "\n\nCaused by:")?; + let multiple = cause.source().is_some(); + for (n, error) in Chain::new(cause).enumerate() { + writeln!(f)?; + let mut indented = Indented { + inner: f, + number: if multiple { Some(n) } else { None }, + started: false, + }; + write!(indented, "{}", error)?; + } + } + + #[cfg(any(std_backtrace, feature = "backtrace"))] + { + use crate::backtrace::BacktraceStatus; + use alloc::string::ToString; + + let backtrace = unsafe { Self::backtrace(this) }; + if let BacktraceStatus::Captured = backtrace.status() { + let mut backtrace = backtrace.to_string(); + write!(f, "\n\n")?; + if backtrace.starts_with("stack backtrace:") { + // Capitalize to match "Caused by:" + backtrace.replace_range(0..1, "S"); + } else { + // "stack backtrace:" prefix was removed in + // https://github.com/rust-lang/backtrace-rs/pull/286 + writeln!(f, "Stack backtrace:")?; + } + backtrace.truncate(backtrace.trim_end().len()); + write!(f, "{}", backtrace)?; + } + } + + Ok(()) + } +} + +struct Indented<'a, D> { + inner: &'a mut D, + number: Option, + started: bool, +} + +impl Write for Indented<'_, T> +where + T: Write, +{ + fn write_str(&mut self, s: &str) -> fmt::Result { + for (i, line) in s.split('\n').enumerate() { + if !self.started { + self.started = true; + match self.number { + Some(number) => write!(self.inner, "{: >5}: ", number)?, + None => self.inner.write_str(" ")?, + } + } else if i > 0 { + self.inner.write_char('\n')?; + if self.number.is_some() { + self.inner.write_str(" ")?; + } else { + self.inner.write_str(" ")?; + } + } + + self.inner.write_str(line)?; + } + + Ok(()) + } +} + +#[cfg(test)] +mod tests { + use super::*; + use alloc::string::String; + + #[test] + fn one_digit() { + let input = "verify\nthis"; + let expected = " 2: verify\n this"; + let mut output = String::new(); + + Indented { + inner: &mut output, + number: Some(2), + started: false, + } + .write_str(input) + .unwrap(); + + assert_eq!(expected, output); + } + + #[test] + fn two_digits() { + let input = "verify\nthis"; + let expected = " 12: verify\n this"; + let mut output = String::new(); + + Indented { + inner: &mut output, + number: Some(12), + started: false, + } + .write_str(input) + .unwrap(); + + assert_eq!(expected, output); + } + + #[test] + fn no_digits() { + let input = "verify\nthis"; + let expected = " verify\n this"; + let mut output = String::new(); + + Indented { + inner: &mut output, + number: None, + started: false, + } + .write_str(input) + .unwrap(); + + assert_eq!(expected, output); + } +} diff --git a/vendor/anyhow/src/kind.rs b/vendor/anyhow/src/kind.rs new file mode 100644 index 0000000..042af32 --- /dev/null +++ b/vendor/anyhow/src/kind.rs @@ -0,0 +1,121 @@ +// Tagged dispatch mechanism for resolving the behavior of `anyhow!($expr)`. +// +// When anyhow! is given a single expr argument to turn into anyhow::Error, we +// want the resulting Error to pick up the input's implementation of source() +// and backtrace() if it has a std::error::Error impl, otherwise require nothing +// more than Display and Debug. +// +// Expressed in terms of specialization, we want something like: +// +// trait AnyhowNew { +// fn new(self) -> Error; +// } +// +// impl AnyhowNew for T +// where +// T: Display + Debug + Send + Sync + 'static, +// { +// default fn new(self) -> Error { +// /* no std error impl */ +// } +// } +// +// impl AnyhowNew for T +// where +// T: std::error::Error + Send + Sync + 'static, +// { +// fn new(self) -> Error { +// /* use std error's source() and backtrace() */ +// } +// } +// +// Since specialization is not stable yet, instead we rely on autoref behavior +// of method resolution to perform tagged dispatch. Here we have two traits +// AdhocKind and TraitKind that both have an anyhow_kind() method. AdhocKind is +// implemented whether or not the caller's type has a std error impl, while +// TraitKind is implemented only when a std error impl does exist. The ambiguity +// is resolved by AdhocKind requiring an extra autoref so that it has lower +// precedence. +// +// The anyhow! macro will set up the call in this form: +// +// #[allow(unused_imports)] +// use $crate::__private::{AdhocKind, TraitKind}; +// let error = $msg; +// (&error).anyhow_kind().new(error) + +use crate::Error; +use core::fmt::{Debug, Display}; + +#[cfg(any(feature = "std", not(anyhow_no_core_error)))] +use crate::StdError; +#[cfg(any(feature = "std", not(anyhow_no_core_error)))] +use alloc::boxed::Box; + +pub struct Adhoc; + +#[doc(hidden)] +pub trait AdhocKind: Sized { + #[inline] + fn anyhow_kind(&self) -> Adhoc { + Adhoc + } +} + +impl AdhocKind for &T where T: ?Sized + Display + Debug + Send + Sync + 'static {} + +impl Adhoc { + #[cold] + pub fn new(self, message: M) -> Error + where + M: Display + Debug + Send + Sync + 'static, + { + Error::from_adhoc(message, backtrace!()) + } +} + +pub struct Trait; + +#[doc(hidden)] +pub trait TraitKind: Sized { + #[inline] + fn anyhow_kind(&self) -> Trait { + Trait + } +} + +impl TraitKind for E where E: Into {} + +impl Trait { + #[cold] + pub fn new(self, error: E) -> Error + where + E: Into, + { + error.into() + } +} + +#[cfg(any(feature = "std", not(anyhow_no_core_error)))] +pub struct Boxed; + +#[cfg(any(feature = "std", not(anyhow_no_core_error)))] +#[doc(hidden)] +pub trait BoxedKind: Sized { + #[inline] + fn anyhow_kind(&self) -> Boxed { + Boxed + } +} + +#[cfg(any(feature = "std", not(anyhow_no_core_error)))] +impl BoxedKind for Box {} + +#[cfg(any(feature = "std", not(anyhow_no_core_error)))] +impl Boxed { + #[cold] + pub fn new(self, error: Box) -> Error { + let backtrace = backtrace_if_absent!(&*error); + Error::from_boxed(error, backtrace) + } +} diff --git a/vendor/anyhow/src/lib.rs b/vendor/anyhow/src/lib.rs new file mode 100644 index 0000000..3ddcfc8 --- /dev/null +++ b/vendor/anyhow/src/lib.rs @@ -0,0 +1,732 @@ +//! [![github]](https://github.com/dtolnay/anyhow) [![crates-io]](https://crates.io/crates/anyhow) [![docs-rs]](https://docs.rs/anyhow) +//! +//! [github]: https://img.shields.io/badge/github-8da0cb?style=for-the-badge&labelColor=555555&logo=github +//! [crates-io]: https://img.shields.io/badge/crates.io-fc8d62?style=for-the-badge&labelColor=555555&logo=rust +//! [docs-rs]: https://img.shields.io/badge/docs.rs-66c2a5?style=for-the-badge&labelColor=555555&logo=docs.rs +//! +//!
+//! +//! This library provides [`anyhow::Error`][Error], a trait object based error +//! type for easy idiomatic error handling in Rust applications. +//! +//!
+//! +//! # Details +//! +//! - Use `Result`, or equivalently `anyhow::Result`, as +//! the return type of any fallible function. +//! +//! Within the function, use `?` to easily propagate any error that implements +//! the [`std::error::Error`] trait. +//! +//! ``` +//! # pub trait Deserialize {} +//! # +//! # mod serde_json { +//! # use super::Deserialize; +//! # use std::io; +//! # +//! # pub fn from_str(json: &str) -> io::Result { +//! # unimplemented!() +//! # } +//! # } +//! # +//! # struct ClusterMap; +//! # +//! # impl Deserialize for ClusterMap {} +//! # +//! use anyhow::Result; +//! +//! fn get_cluster_info() -> Result { +//! let config = std::fs::read_to_string("cluster.json")?; +//! let map: ClusterMap = serde_json::from_str(&config)?; +//! Ok(map) +//! } +//! # +//! # fn main() {} +//! ``` +//! +//! - Attach context to help the person troubleshooting the error understand +//! where things went wrong. A low-level error like "No such file or +//! directory" can be annoying to debug without more context about what higher +//! level step the application was in the middle of. +//! +//! ``` +//! # struct It; +//! # +//! # impl It { +//! # fn detach(&self) -> Result<()> { +//! # unimplemented!() +//! # } +//! # } +//! # +//! use anyhow::{Context, Result}; +//! +//! fn main() -> Result<()> { +//! # return Ok(()); +//! # +//! # const _: &str = stringify! { +//! ... +//! # }; +//! # +//! # let it = It; +//! # let path = "./path/to/instrs.json"; +//! # +//! it.detach().context("Failed to detach the important thing")?; +//! +//! let content = std::fs::read(path) +//! .with_context(|| format!("Failed to read instrs from {}", path))?; +//! # +//! # const _: &str = stringify! { +//! ... +//! # }; +//! # +//! # Ok(()) +//! } +//! ``` +//! +//! ```console +//! Error: Failed to read instrs from ./path/to/instrs.json +//! +//! Caused by: +//! No such file or directory (os error 2) +//! ``` +//! +//! - Downcasting is supported and can be by value, by shared reference, or by +//! mutable reference as needed. +//! +//! ``` +//! # use anyhow::anyhow; +//! # use std::fmt::{self, Display}; +//! # use std::task::Poll; +//! # +//! # #[derive(Debug)] +//! # enum DataStoreError { +//! # Censored(()), +//! # } +//! # +//! # impl Display for DataStoreError { +//! # fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { +//! # unimplemented!() +//! # } +//! # } +//! # +//! # impl std::error::Error for DataStoreError {} +//! # +//! # const REDACTED_CONTENT: () = (); +//! # +//! # let error = anyhow!("..."); +//! # let root_cause = &error; +//! # +//! # let ret = +//! // If the error was caused by redaction, then return a +//! // tombstone instead of the content. +//! match root_cause.downcast_ref::() { +//! Some(DataStoreError::Censored(_)) => Ok(Poll::Ready(REDACTED_CONTENT)), +//! None => Err(error), +//! } +//! # ; +//! ``` +//! +//! - If using Rust ≥ 1.65, a backtrace is captured and printed with the +//! error if the underlying error type does not already provide its own. In +//! order to see backtraces, they must be enabled through the environment +//! variables described in [`std::backtrace`]: +//! +//! - If you want panics and errors to both have backtraces, set +//! `RUST_BACKTRACE=1`; +//! - If you want only errors to have backtraces, set `RUST_LIB_BACKTRACE=1`; +//! - If you want only panics to have backtraces, set `RUST_BACKTRACE=1` and +//! `RUST_LIB_BACKTRACE=0`. +//! +//! [`std::backtrace`]: https://doc.rust-lang.org/std/backtrace/index.html#environment-variables +//! +//! - Anyhow works with any error type that has an impl of `std::error::Error`, +//! including ones defined in your crate. We do not bundle a `derive(Error)` +//! macro but you can write the impls yourself or use a standalone macro like +//! [thiserror]. +//! +//! [thiserror]: https://github.com/dtolnay/thiserror +//! +//! ``` +//! use thiserror::Error; +//! +//! #[derive(Error, Debug)] +//! pub enum FormatError { +//! #[error("Invalid header (expected {expected:?}, got {found:?})")] +//! InvalidHeader { +//! expected: String, +//! found: String, +//! }, +//! #[error("Missing attribute: {0}")] +//! MissingAttribute(String), +//! } +//! ``` +//! +//! - One-off error messages can be constructed using the `anyhow!` macro, which +//! supports string interpolation and produces an `anyhow::Error`. +//! +//! ``` +//! # use anyhow::{anyhow, Result}; +//! # +//! # fn demo() -> Result<()> { +//! # let missing = "..."; +//! return Err(anyhow!("Missing attribute: {}", missing)); +//! # Ok(()) +//! # } +//! ``` +//! +//! A `bail!` macro is provided as a shorthand for the same early return. +//! +//! ``` +//! # use anyhow::{bail, Result}; +//! # +//! # fn demo() -> Result<()> { +//! # let missing = "..."; +//! bail!("Missing attribute: {}", missing); +//! # Ok(()) +//! # } +//! ``` +//! +//!
+//! +//! # No-std support +//! +//! In no_std mode, almost all of the same API is available and works the same +//! way. To depend on Anyhow in no_std mode, disable our default enabled "std" +//! feature in Cargo.toml. A global allocator is required. +//! +//! ```toml +//! [dependencies] +//! anyhow = { version = "1.0", default-features = false } +//! ``` +//! +//! With versions of Rust older than 1.81, no_std mode may require an additional +//! `.map_err(Error::msg)` when working with a non-Anyhow error type inside a +//! function that returns Anyhow's error type, as the trait that `?`-based error +//! conversions are defined by is only available in std in those old versions. + +#![doc(html_root_url = "https://docs.rs/anyhow/1.0.90")] +#![cfg_attr(error_generic_member_access, feature(error_generic_member_access))] +#![no_std] +#![deny(dead_code, unused_imports, unused_mut)] +#![cfg_attr( + not(anyhow_no_unsafe_op_in_unsafe_fn_lint), + deny(unsafe_op_in_unsafe_fn) +)] +#![cfg_attr(anyhow_no_unsafe_op_in_unsafe_fn_lint, allow(unused_unsafe))] +#![allow( + clippy::doc_markdown, + clippy::enum_glob_use, + clippy::explicit_auto_deref, + clippy::extra_unused_type_parameters, + clippy::incompatible_msrv, + clippy::let_underscore_untyped, + clippy::missing_errors_doc, + clippy::missing_panics_doc, + clippy::module_name_repetitions, + clippy::must_use_candidate, + clippy::needless_doctest_main, + clippy::needless_lifetimes, + clippy::new_ret_no_self, + clippy::redundant_else, + clippy::return_self_not_must_use, + clippy::struct_field_names, + clippy::unused_self, + clippy::used_underscore_binding, + clippy::wildcard_imports, + clippy::wrong_self_convention +)] + +#[cfg(all( + anyhow_nightly_testing, + feature = "std", + not(error_generic_member_access) +))] +compile_error!("Build script probe failed to compile."); + +extern crate alloc; + +#[cfg(feature = "std")] +extern crate std; + +#[macro_use] +mod backtrace; +mod chain; +mod context; +mod ensure; +mod error; +mod fmt; +mod kind; +mod macros; +mod ptr; +mod wrapper; + +use crate::error::ErrorImpl; +use crate::ptr::Own; +use core::fmt::Display; + +#[cfg(all(not(feature = "std"), anyhow_no_core_error))] +use core::fmt::Debug; + +#[cfg(feature = "std")] +use std::error::Error as StdError; + +#[cfg(not(any(feature = "std", anyhow_no_core_error)))] +use core::error::Error as StdError; + +#[cfg(all(not(feature = "std"), anyhow_no_core_error))] +trait StdError: Debug + Display { + fn source(&self) -> Option<&(dyn StdError + 'static)> { + None + } +} + +#[doc(no_inline)] +pub use anyhow as format_err; + +/// The `Error` type, a wrapper around a dynamic error type. +/// +/// `Error` works a lot like `Box`, but with these +/// differences: +/// +/// - `Error` requires that the error is `Send`, `Sync`, and `'static`. +/// - `Error` guarantees that a backtrace is available, even if the underlying +/// error type does not provide one. +/// - `Error` is represented as a narrow pointer — exactly one word in +/// size instead of two. +/// +///
+/// +/// # Display representations +/// +/// When you print an error object using "{}" or to_string(), only the outermost +/// underlying error or context is printed, not any of the lower level causes. +/// This is exactly as if you had called the Display impl of the error from +/// which you constructed your anyhow::Error. +/// +/// ```console +/// Failed to read instrs from ./path/to/instrs.json +/// ``` +/// +/// To print causes as well using anyhow's default formatting of causes, use the +/// alternate selector "{:#}". +/// +/// ```console +/// Failed to read instrs from ./path/to/instrs.json: No such file or directory (os error 2) +/// ``` +/// +/// The Debug format "{:?}" includes your backtrace if one was captured. Note +/// that this is the representation you get by default if you return an error +/// from `fn main` instead of printing it explicitly yourself. +/// +/// ```console +/// Error: Failed to read instrs from ./path/to/instrs.json +/// +/// Caused by: +/// No such file or directory (os error 2) +/// ``` +/// +/// and if there is a backtrace available: +/// +/// ```console +/// Error: Failed to read instrs from ./path/to/instrs.json +/// +/// Caused by: +/// No such file or directory (os error 2) +/// +/// Stack backtrace: +/// 0: ::ext_context +/// at /git/anyhow/src/backtrace.rs:26 +/// 1: core::result::Result::map_err +/// at /git/rustc/src/libcore/result.rs:596 +/// 2: anyhow::context:: for core::result::Result>::with_context +/// at /git/anyhow/src/context.rs:58 +/// 3: testing::main +/// at src/main.rs:5 +/// 4: std::rt::lang_start +/// at /git/rustc/src/libstd/rt.rs:61 +/// 5: main +/// 6: __libc_start_main +/// 7: _start +/// ``` +/// +/// To see a conventional struct-style Debug representation, use "{:#?}". +/// +/// ```console +/// Error { +/// context: "Failed to read instrs from ./path/to/instrs.json", +/// source: Os { +/// code: 2, +/// kind: NotFound, +/// message: "No such file or directory", +/// }, +/// } +/// ``` +/// +/// If none of the built-in representations are appropriate and you would prefer +/// to render the error and its cause chain yourself, it can be done something +/// like this: +/// +/// ``` +/// use anyhow::{Context, Result}; +/// +/// fn main() { +/// if let Err(err) = try_main() { +/// eprintln!("ERROR: {}", err); +/// err.chain().skip(1).for_each(|cause| eprintln!("because: {}", cause)); +/// std::process::exit(1); +/// } +/// } +/// +/// fn try_main() -> Result<()> { +/// # const IGNORE: &str = stringify! { +/// ... +/// # }; +/// # Ok(()) +/// } +/// ``` +#[repr(transparent)] +pub struct Error { + inner: Own, +} + +/// Iterator of a chain of source errors. +/// +/// This type is the iterator returned by [`Error::chain`]. +/// +/// # Example +/// +/// ``` +/// use anyhow::Error; +/// use std::io; +/// +/// pub fn underlying_io_error_kind(error: &Error) -> Option { +/// for cause in error.chain() { +/// if let Some(io_error) = cause.downcast_ref::() { +/// return Some(io_error.kind()); +/// } +/// } +/// None +/// } +/// ``` +#[cfg(any(feature = "std", not(anyhow_no_core_error)))] +#[derive(Clone)] +pub struct Chain<'a> { + state: crate::chain::ChainState<'a>, +} + +/// `Result` +/// +/// This is a reasonable return type to use throughout your application but also +/// for `fn main`; if you do, failures will be printed along with any +/// [context][Context] and a backtrace if one was captured. +/// +/// `anyhow::Result` may be used with one *or* two type parameters. +/// +/// ```rust +/// use anyhow::Result; +/// +/// # const IGNORE: &str = stringify! { +/// fn demo1() -> Result {...} +/// // ^ equivalent to std::result::Result +/// +/// fn demo2() -> Result {...} +/// // ^ equivalent to std::result::Result +/// # }; +/// ``` +/// +/// # Example +/// +/// ``` +/// # pub trait Deserialize {} +/// # +/// # mod serde_json { +/// # use super::Deserialize; +/// # use std::io; +/// # +/// # pub fn from_str(json: &str) -> io::Result { +/// # unimplemented!() +/// # } +/// # } +/// # +/// # #[derive(Debug)] +/// # struct ClusterMap; +/// # +/// # impl Deserialize for ClusterMap {} +/// # +/// use anyhow::Result; +/// +/// fn main() -> Result<()> { +/// # return Ok(()); +/// let config = std::fs::read_to_string("cluster.json")?; +/// let map: ClusterMap = serde_json::from_str(&config)?; +/// println!("cluster info: {:#?}", map); +/// Ok(()) +/// } +/// ``` +pub type Result = core::result::Result; + +/// Provides the `context` method for `Result`. +/// +/// This trait is sealed and cannot be implemented for types outside of +/// `anyhow`. +/// +///
+/// +/// # Example +/// +/// ``` +/// use anyhow::{Context, Result}; +/// use std::fs; +/// use std::path::PathBuf; +/// +/// pub struct ImportantThing { +/// path: PathBuf, +/// } +/// +/// impl ImportantThing { +/// # const IGNORE: &'static str = stringify! { +/// pub fn detach(&mut self) -> Result<()> {...} +/// # }; +/// # fn detach(&mut self) -> Result<()> { +/// # unimplemented!() +/// # } +/// } +/// +/// pub fn do_it(mut it: ImportantThing) -> Result> { +/// it.detach().context("Failed to detach the important thing")?; +/// +/// let path = &it.path; +/// let content = fs::read(path) +/// .with_context(|| format!("Failed to read instrs from {}", path.display()))?; +/// +/// Ok(content) +/// } +/// ``` +/// +/// When printed, the outermost context would be printed first and the lower +/// level underlying causes would be enumerated below. +/// +/// ```console +/// Error: Failed to read instrs from ./path/to/instrs.json +/// +/// Caused by: +/// No such file or directory (os error 2) +/// ``` +/// +/// Refer to the [Display representations] documentation for other forms in +/// which this context chain can be rendered. +/// +/// [Display representations]: Error#display-representations +/// +///
+/// +/// # Effect on downcasting +/// +/// After attaching context of type `C` onto an error of type `E`, the resulting +/// `anyhow::Error` may be downcast to `C` **or** to `E`. +/// +/// That is, in codebases that rely on downcasting, Anyhow's context supports +/// both of the following use cases: +/// +/// - **Attaching context whose type is insignificant onto errors whose type +/// is used in downcasts.** +/// +/// In other error libraries whose context is not designed this way, it can +/// be risky to introduce context to existing code because new context might +/// break existing working downcasts. In Anyhow, any downcast that worked +/// before adding context will continue to work after you add a context, so +/// you should freely add human-readable context to errors wherever it would +/// be helpful. +/// +/// ``` +/// # use anyhow::bail; +/// # use thiserror::Error; +/// # +/// # #[derive(Error, Debug)] +/// # #[error("???")] +/// # struct SuspiciousError; +/// # +/// # fn helper() -> Result<()> { +/// # bail!(SuspiciousError); +/// # } +/// # +/// use anyhow::{Context, Result}; +/// +/// fn do_it() -> Result<()> { +/// helper().context("Failed to complete the work")?; +/// # const IGNORE: &str = stringify! { +/// ... +/// # }; +/// # unreachable!() +/// } +/// +/// fn main() { +/// let err = do_it().unwrap_err(); +/// if let Some(e) = err.downcast_ref::() { +/// // If helper() returned SuspiciousError, this downcast will +/// // correctly succeed even with the context in between. +/// # return; +/// } +/// # panic!("expected downcast to succeed"); +/// } +/// ``` +/// +/// - **Attaching context whose type is used in downcasts onto errors whose +/// type is insignificant.** +/// +/// Some codebases prefer to use machine-readable context to categorize +/// lower level errors in a way that will be actionable to higher levels of +/// the application. +/// +/// ``` +/// # use anyhow::bail; +/// # use thiserror::Error; +/// # +/// # #[derive(Error, Debug)] +/// # #[error("???")] +/// # struct HelperFailed; +/// # +/// # fn helper() -> Result<()> { +/// # bail!("no such file or directory"); +/// # } +/// # +/// use anyhow::{Context, Result}; +/// +/// fn do_it() -> Result<()> { +/// helper().context(HelperFailed)?; +/// # const IGNORE: &str = stringify! { +/// ... +/// # }; +/// # unreachable!() +/// } +/// +/// fn main() { +/// let err = do_it().unwrap_err(); +/// if let Some(e) = err.downcast_ref::() { +/// // If helper failed, this downcast will succeed because +/// // HelperFailed is the context that has been attached to +/// // that error. +/// # return; +/// } +/// # panic!("expected downcast to succeed"); +/// } +/// ``` +pub trait Context: context::private::Sealed { + /// Wrap the error value with additional context. + fn context(self, context: C) -> Result + where + C: Display + Send + Sync + 'static; + + /// Wrap the error value with additional context that is evaluated lazily + /// only once an error does occur. + fn with_context(self, f: F) -> Result + where + C: Display + Send + Sync + 'static, + F: FnOnce() -> C; +} + +/// Equivalent to Ok::<_, anyhow::Error>(value). +/// +/// This simplifies creation of an anyhow::Result in places where type inference +/// cannot deduce the `E` type of the result — without needing to write +/// `Ok::<_, anyhow::Error>(value)`. +/// +/// One might think that `anyhow::Result::Ok(value)` would work in such cases +/// but it does not. +/// +/// ```console +/// error[E0282]: type annotations needed for `std::result::Result` +/// --> src/main.rs:11:13 +/// | +/// 11 | let _ = anyhow::Result::Ok(1); +/// | - ^^^^^^^^^^^^^^^^^^ cannot infer type for type parameter `E` declared on the enum `Result` +/// | | +/// | consider giving this pattern the explicit type `std::result::Result`, where the type parameter `E` is specified +/// ``` +#[allow(non_snake_case)] +pub fn Ok(t: T) -> Result { + Result::Ok(t) +} + +// Not public API. Referenced by macro-generated code. +#[doc(hidden)] +pub mod __private { + use self::not::Bool; + use crate::Error; + use alloc::fmt; + use core::fmt::Arguments; + + #[doc(hidden)] + pub use crate::ensure::{BothDebug, NotBothDebug}; + #[doc(hidden)] + pub use alloc::format; + #[doc(hidden)] + pub use core::result::Result::Err; + #[doc(hidden)] + pub use core::{concat, format_args, stringify}; + + #[doc(hidden)] + pub mod kind { + #[doc(hidden)] + pub use crate::kind::{AdhocKind, TraitKind}; + + #[cfg(any(feature = "std", not(anyhow_no_core_error)))] + #[doc(hidden)] + pub use crate::kind::BoxedKind; + } + + #[doc(hidden)] + #[inline] + #[cold] + pub fn format_err(args: Arguments) -> Error { + #[cfg(anyhow_no_fmt_arguments_as_str)] + let fmt_arguments_as_str = None::<&str>; + #[cfg(not(anyhow_no_fmt_arguments_as_str))] + let fmt_arguments_as_str = args.as_str(); + + if let Some(message) = fmt_arguments_as_str { + // anyhow!("literal"), can downcast to &'static str + Error::msg(message) + } else { + // anyhow!("interpolate {var}"), can downcast to String + Error::msg(fmt::format(args)) + } + } + + #[doc(hidden)] + #[inline] + #[cold] + #[must_use] + pub fn must_use(error: Error) -> Error { + error + } + + #[doc(hidden)] + #[inline] + pub fn not(cond: impl Bool) -> bool { + cond.not() + } + + mod not { + #[doc(hidden)] + pub trait Bool { + fn not(self) -> bool; + } + + impl Bool for bool { + #[inline] + fn not(self) -> bool { + !self + } + } + + impl Bool for &bool { + #[inline] + fn not(self) -> bool { + !*self + } + } + } +} diff --git a/vendor/anyhow/src/macros.rs b/vendor/anyhow/src/macros.rs new file mode 100644 index 0000000..469b3d8 --- /dev/null +++ b/vendor/anyhow/src/macros.rs @@ -0,0 +1,242 @@ +/// Return early with an error. +/// +/// This macro is equivalent to +/// return Err([anyhow!($args\...)][anyhow!]). +/// +/// The surrounding function's or closure's return value is required to be +/// Result<_, [anyhow::Error][crate::Error]>. +/// +/// [anyhow!]: crate::anyhow +/// +/// # Example +/// +/// ``` +/// # use anyhow::{bail, Result}; +/// # +/// # fn has_permission(user: usize, resource: usize) -> bool { +/// # true +/// # } +/// # +/// # fn main() -> Result<()> { +/// # let user = 0; +/// # let resource = 0; +/// # +/// if !has_permission(user, resource) { +/// bail!("permission denied for accessing {}", resource); +/// } +/// # Ok(()) +/// # } +/// ``` +/// +/// ``` +/// # use anyhow::{bail, Result}; +/// # use thiserror::Error; +/// # +/// # const MAX_DEPTH: usize = 1; +/// # +/// #[derive(Error, Debug)] +/// enum ScienceError { +/// #[error("recursion limit exceeded")] +/// RecursionLimitExceeded, +/// # #[error("...")] +/// # More = (stringify! { +/// ... +/// # }, 1).1, +/// } +/// +/// # fn main() -> Result<()> { +/// # let depth = 0; +/// # +/// if depth > MAX_DEPTH { +/// bail!(ScienceError::RecursionLimitExceeded); +/// } +/// # Ok(()) +/// # } +/// ``` +#[macro_export] +macro_rules! bail { + ($msg:literal $(,)?) => { + return $crate::__private::Err($crate::__anyhow!($msg)) + }; + ($err:expr $(,)?) => { + return $crate::__private::Err($crate::__anyhow!($err)) + }; + ($fmt:expr, $($arg:tt)*) => { + return $crate::__private::Err($crate::__anyhow!($fmt, $($arg)*)) + }; +} + +macro_rules! __ensure { + ($ensure:item) => { + /// Return early with an error if a condition is not satisfied. + /// + /// This macro is equivalent to + /// if !$cond { return Err([anyhow!($args\...)][anyhow!]); }. + /// + /// The surrounding function's or closure's return value is required to be + /// Result<_, [anyhow::Error][crate::Error]>. + /// + /// Analogously to `assert!`, `ensure!` takes a condition and exits the function + /// if the condition fails. Unlike `assert!`, `ensure!` returns an `Error` + /// rather than panicking. + /// + /// [anyhow!]: crate::anyhow + /// + /// # Example + /// + /// ``` + /// # use anyhow::{ensure, Result}; + /// # + /// # fn main() -> Result<()> { + /// # let user = 0; + /// # + /// ensure!(user == 0, "only user 0 is allowed"); + /// # Ok(()) + /// # } + /// ``` + /// + /// ``` + /// # use anyhow::{ensure, Result}; + /// # use thiserror::Error; + /// # + /// # const MAX_DEPTH: usize = 1; + /// # + /// #[derive(Error, Debug)] + /// enum ScienceError { + /// #[error("recursion limit exceeded")] + /// RecursionLimitExceeded, + /// # #[error("...")] + /// # More = (stringify! { + /// ... + /// # }, 1).1, + /// } + /// + /// # fn main() -> Result<()> { + /// # let depth = 0; + /// # + /// ensure!(depth <= MAX_DEPTH, ScienceError::RecursionLimitExceeded); + /// # Ok(()) + /// # } + /// ``` + $ensure + }; +} + +#[cfg(doc)] +__ensure![ + #[macro_export] + macro_rules! ensure { + ($cond:expr $(,)?) => { + if !$cond { + return $crate::__private::Err($crate::Error::msg( + $crate::__private::concat!("Condition failed: `", $crate::__private::stringify!($cond), "`") + )); + } + }; + ($cond:expr, $msg:literal $(,)?) => { + if !$cond { + return $crate::__private::Err($crate::__anyhow!($msg)); + } + }; + ($cond:expr, $err:expr $(,)?) => { + if !$cond { + return $crate::__private::Err($crate::__anyhow!($err)); + } + }; + ($cond:expr, $fmt:expr, $($arg:tt)*) => { + if !$cond { + return $crate::__private::Err($crate::__anyhow!($fmt, $($arg)*)); + } + }; + } +]; + +#[cfg(not(doc))] +__ensure![ + #[macro_export] + macro_rules! ensure { + ($($tt:tt)*) => { + $crate::__parse_ensure!( + /* state */ 0 + /* stack */ () + /* bail */ ($($tt)*) + /* fuel */ (~~~~~~~~~~ ~~~~~~~~~~ ~~~~~~~~~~ ~~~~~~~~~~ ~~~~~~~~~~ ~~~~~~~~~~ ~~~~~~~~~~ ~~~~~~~~~~ ~~~~~~~~~~ ~~~~~~~~~~ ~~~~~~~~~~ ~~~~~~~~~~) + /* parse */ {()} + /* dup */ ($($tt)*) + /* rest */ $($tt)* + ) + }; + } +]; + +/// Construct an ad-hoc error from a string or existing non-`anyhow` error +/// value. +/// +/// This evaluates to an [`Error`][crate::Error]. It can take either just a +/// string, or a format string with arguments. It also can take any custom type +/// which implements `Debug` and `Display`. +/// +/// If called with a single argument whose type implements `std::error::Error` +/// (in addition to `Debug` and `Display`, which are always required), then that +/// Error impl's `source` is preserved as the `source` of the resulting +/// `anyhow::Error`. +/// +/// # Example +/// +/// ``` +/// # type V = (); +/// # +/// use anyhow::{anyhow, Result}; +/// +/// fn lookup(key: &str) -> Result { +/// if key.len() != 16 { +/// return Err(anyhow!("key length must be 16 characters, got {:?}", key)); +/// } +/// +/// // ... +/// # Ok(()) +/// } +/// ``` +#[macro_export] +macro_rules! anyhow { + ($msg:literal $(,)?) => { + $crate::__private::must_use({ + let error = $crate::__private::format_err($crate::__private::format_args!($msg)); + error + }) + }; + ($err:expr $(,)?) => { + $crate::__private::must_use({ + use $crate::__private::kind::*; + let error = match $err { + error => (&error).anyhow_kind().new(error), + }; + error + }) + }; + ($fmt:expr, $($arg:tt)*) => { + $crate::Error::msg($crate::__private::format!($fmt, $($arg)*)) + }; +} + +// Not public API. This is used in the implementation of some of the other +// macros, in which the must_use call is not needed because the value is known +// to be used. +#[doc(hidden)] +#[macro_export] +macro_rules! __anyhow { + ($msg:literal $(,)?) => ({ + let error = $crate::__private::format_err($crate::__private::format_args!($msg)); + error + }); + ($err:expr $(,)?) => ({ + use $crate::__private::kind::*; + let error = match $err { + error => (&error).anyhow_kind().new(error), + }; + error + }); + ($fmt:expr, $($arg:tt)*) => { + $crate::Error::msg($crate::__private::format!($fmt, $($arg)*)) + }; +} diff --git a/vendor/anyhow/src/ptr.rs b/vendor/anyhow/src/ptr.rs new file mode 100644 index 0000000..a1b7126 --- /dev/null +++ b/vendor/anyhow/src/ptr.rs @@ -0,0 +1,199 @@ +use alloc::boxed::Box; +use core::marker::PhantomData; +use core::ptr::NonNull; + +#[repr(transparent)] +pub struct Own +where + T: ?Sized, +{ + pub ptr: NonNull, +} + +unsafe impl Send for Own where T: ?Sized {} + +unsafe impl Sync for Own where T: ?Sized {} + +impl Copy for Own where T: ?Sized {} + +impl Clone for Own +where + T: ?Sized, +{ + fn clone(&self) -> Self { + *self + } +} + +impl Own +where + T: ?Sized, +{ + pub fn new(ptr: Box) -> Self { + Own { + ptr: unsafe { NonNull::new_unchecked(Box::into_raw(ptr)) }, + } + } + + pub fn cast(self) -> Own { + Own { + ptr: self.ptr.cast(), + } + } + + pub unsafe fn boxed(self) -> Box { + unsafe { Box::from_raw(self.ptr.as_ptr()) } + } + + pub fn by_ref(&self) -> Ref { + Ref { + ptr: self.ptr, + lifetime: PhantomData, + } + } + + pub fn by_mut(&mut self) -> Mut { + Mut { + ptr: self.ptr, + lifetime: PhantomData, + } + } +} + +#[repr(transparent)] +pub struct Ref<'a, T> +where + T: ?Sized, +{ + pub ptr: NonNull, + lifetime: PhantomData<&'a T>, +} + +impl<'a, T> Copy for Ref<'a, T> where T: ?Sized {} + +impl<'a, T> Clone for Ref<'a, T> +where + T: ?Sized, +{ + fn clone(&self) -> Self { + *self + } +} + +impl<'a, T> Ref<'a, T> +where + T: ?Sized, +{ + pub fn new(ptr: &'a T) -> Self { + Ref { + ptr: NonNull::from(ptr), + lifetime: PhantomData, + } + } + + #[cfg(not(anyhow_no_ptr_addr_of))] + pub fn from_raw(ptr: NonNull) -> Self { + Ref { + ptr, + lifetime: PhantomData, + } + } + + pub fn cast(self) -> Ref<'a, U::Target> { + Ref { + ptr: self.ptr.cast(), + lifetime: PhantomData, + } + } + + #[cfg(not(anyhow_no_ptr_addr_of))] + pub fn by_mut(self) -> Mut<'a, T> { + Mut { + ptr: self.ptr, + lifetime: PhantomData, + } + } + + #[cfg(not(anyhow_no_ptr_addr_of))] + pub fn as_ptr(self) -> *const T { + self.ptr.as_ptr() as *const T + } + + pub unsafe fn deref(self) -> &'a T { + unsafe { &*self.ptr.as_ptr() } + } +} + +#[repr(transparent)] +pub struct Mut<'a, T> +where + T: ?Sized, +{ + pub ptr: NonNull, + lifetime: PhantomData<&'a mut T>, +} + +impl<'a, T> Copy for Mut<'a, T> where T: ?Sized {} + +impl<'a, T> Clone for Mut<'a, T> +where + T: ?Sized, +{ + fn clone(&self) -> Self { + *self + } +} + +impl<'a, T> Mut<'a, T> +where + T: ?Sized, +{ + #[cfg(anyhow_no_ptr_addr_of)] + pub fn new(ptr: &'a mut T) -> Self { + Mut { + ptr: NonNull::from(ptr), + lifetime: PhantomData, + } + } + + pub fn cast(self) -> Mut<'a, U::Target> { + Mut { + ptr: self.ptr.cast(), + lifetime: PhantomData, + } + } + + #[cfg(not(anyhow_no_ptr_addr_of))] + pub fn by_ref(self) -> Ref<'a, T> { + Ref { + ptr: self.ptr, + lifetime: PhantomData, + } + } + + pub fn extend<'b>(self) -> Mut<'b, T> { + Mut { + ptr: self.ptr, + lifetime: PhantomData, + } + } + + pub unsafe fn deref_mut(self) -> &'a mut T { + unsafe { &mut *self.ptr.as_ptr() } + } +} + +impl<'a, T> Mut<'a, T> { + pub unsafe fn read(self) -> T { + unsafe { self.ptr.as_ptr().read() } + } +} + +// Force turbofish on all calls of `.cast::()`. +pub trait CastTo { + type Target; +} + +impl CastTo for T { + type Target = T; +} diff --git a/vendor/anyhow/src/wrapper.rs b/vendor/anyhow/src/wrapper.rs new file mode 100644 index 0000000..6f46779 --- /dev/null +++ b/vendor/anyhow/src/wrapper.rs @@ -0,0 +1,84 @@ +use crate::StdError; +use core::fmt::{self, Debug, Display}; + +#[cfg(any(feature = "std", not(anyhow_no_core_error)))] +use alloc::boxed::Box; + +#[cfg(error_generic_member_access)] +use core::error::Request; + +#[repr(transparent)] +pub struct MessageError(pub M); + +impl Debug for MessageError +where + M: Display + Debug, +{ + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + Debug::fmt(&self.0, f) + } +} + +impl Display for MessageError +where + M: Display + Debug, +{ + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + Display::fmt(&self.0, f) + } +} + +impl StdError for MessageError where M: Display + Debug + 'static {} + +#[repr(transparent)] +pub struct DisplayError(pub M); + +impl Debug for DisplayError +where + M: Display, +{ + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + Display::fmt(&self.0, f) + } +} + +impl Display for DisplayError +where + M: Display, +{ + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + Display::fmt(&self.0, f) + } +} + +impl StdError for DisplayError where M: Display + 'static {} + +#[cfg(any(feature = "std", not(anyhow_no_core_error)))] +#[repr(transparent)] +pub struct BoxedError(pub Box); + +#[cfg(any(feature = "std", not(anyhow_no_core_error)))] +impl Debug for BoxedError { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + Debug::fmt(&self.0, f) + } +} + +#[cfg(any(feature = "std", not(anyhow_no_core_error)))] +impl Display for BoxedError { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + Display::fmt(&self.0, f) + } +} + +#[cfg(any(feature = "std", not(anyhow_no_core_error)))] +impl StdError for BoxedError { + fn source(&self) -> Option<&(dyn StdError + 'static)> { + self.0.source() + } + + #[cfg(error_generic_member_access)] + fn provide<'a>(&'a self, request: &mut Request<'a>) { + self.0.provide(request); + } +} diff --git a/vendor/anyhow/tests/common/mod.rs b/vendor/anyhow/tests/common/mod.rs new file mode 100644 index 0000000..fc165a5 --- /dev/null +++ b/vendor/anyhow/tests/common/mod.rs @@ -0,0 +1,14 @@ +use anyhow::{bail, Result}; +use std::io; + +pub fn bail_literal() -> Result<()> { + bail!("oh no!"); +} + +pub fn bail_fmt() -> Result<()> { + bail!("{} {}!", "oh", "no"); +} + +pub fn bail_error() -> Result<()> { + bail!(io::Error::new(io::ErrorKind::Other, "oh no!")); +} diff --git a/vendor/anyhow/tests/compiletest.rs b/vendor/anyhow/tests/compiletest.rs new file mode 100644 index 0000000..23a6a06 --- /dev/null +++ b/vendor/anyhow/tests/compiletest.rs @@ -0,0 +1,7 @@ +#[rustversion::attr(not(nightly), ignore = "requires nightly")] +#[cfg_attr(miri, ignore = "incompatible with miri")] +#[test] +fn ui() { + let t = trybuild::TestCases::new(); + t.compile_fail("tests/ui/*.rs"); +} diff --git a/vendor/anyhow/tests/drop/mod.rs b/vendor/anyhow/tests/drop/mod.rs new file mode 100644 index 0000000..7da4bf5 --- /dev/null +++ b/vendor/anyhow/tests/drop/mod.rs @@ -0,0 +1,53 @@ +#![allow(clippy::module_name_repetitions)] + +use std::error::Error as StdError; +use std::fmt::{self, Display}; +use std::sync::atomic::{AtomicBool, Ordering}; +use std::sync::Arc; + +#[derive(Debug)] +pub struct Flag { + atomic: Arc, +} + +impl Flag { + pub fn new() -> Self { + Flag { + atomic: Arc::new(AtomicBool::new(false)), + } + } + + pub fn get(&self) -> bool { + self.atomic.load(Ordering::Relaxed) + } +} + +#[derive(Debug)] +pub struct DetectDrop { + has_dropped: Flag, +} + +impl DetectDrop { + pub fn new(has_dropped: &Flag) -> Self { + DetectDrop { + has_dropped: Flag { + atomic: Arc::clone(&has_dropped.atomic), + }, + } + } +} + +impl StdError for DetectDrop {} + +impl Display for DetectDrop { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "oh no!") + } +} + +impl Drop for DetectDrop { + fn drop(&mut self) { + let already_dropped = self.has_dropped.atomic.swap(true, Ordering::Relaxed); + assert!(!already_dropped); + } +} diff --git a/vendor/anyhow/tests/test_autotrait.rs b/vendor/anyhow/tests/test_autotrait.rs new file mode 100644 index 0000000..080b3b9 --- /dev/null +++ b/vendor/anyhow/tests/test_autotrait.rs @@ -0,0 +1,34 @@ +#![allow(clippy::extra_unused_type_parameters)] + +use anyhow::Error; +use std::panic::{RefUnwindSafe, UnwindSafe}; + +#[test] +fn test_send() { + fn assert_send() {} + assert_send::(); +} + +#[test] +fn test_sync() { + fn assert_sync() {} + assert_sync::(); +} + +#[test] +fn test_unwind_safe() { + fn assert_unwind_safe() {} + assert_unwind_safe::(); +} + +#[test] +fn test_ref_unwind_safe() { + fn assert_ref_unwind_safe() {} + assert_ref_unwind_safe::(); +} + +#[test] +fn test_unpin() { + fn assert_unpin() {} + assert_unpin::(); +} diff --git a/vendor/anyhow/tests/test_backtrace.rs b/vendor/anyhow/tests/test_backtrace.rs new file mode 100644 index 0000000..938c1c2 --- /dev/null +++ b/vendor/anyhow/tests/test_backtrace.rs @@ -0,0 +1,15 @@ +#![allow(clippy::let_underscore_untyped)] + +#[rustversion::not(nightly)] +#[ignore = "requires nightly"] +#[test] +fn test_backtrace() {} + +#[rustversion::nightly] +#[test] +fn test_backtrace() { + use anyhow::anyhow; + + let error = anyhow!("oh no!"); + let _ = error.backtrace(); +} diff --git a/vendor/anyhow/tests/test_boxed.rs b/vendor/anyhow/tests/test_boxed.rs new file mode 100644 index 0000000..fb1fb13 --- /dev/null +++ b/vendor/anyhow/tests/test_boxed.rs @@ -0,0 +1,45 @@ +#![allow( + // Clippy bug: https://github.com/rust-lang/rust-clippy/issues/7422 + clippy::nonstandard_macro_braces, +)] + +use anyhow::anyhow; +use std::error::Error as StdError; +use std::io; +use thiserror::Error; + +#[derive(Error, Debug)] +#[error("outer")] +struct MyError { + source: io::Error, +} + +#[test] +fn test_boxed_str() { + let error = Box::::from("oh no!"); + let error = anyhow!(error); + assert_eq!("oh no!", error.to_string()); + assert_eq!( + "oh no!", + error + .downcast_ref::>() + .unwrap() + .to_string() + ); +} + +#[test] +fn test_boxed_thiserror() { + let error = MyError { + source: io::Error::new(io::ErrorKind::Other, "oh no!"), + }; + let error = anyhow!(error); + assert_eq!("oh no!", error.source().unwrap().to_string()); +} + +#[test] +fn test_boxed_anyhow() { + let error = anyhow!("oh no!").context("it failed"); + let error = anyhow!(error); + assert_eq!("oh no!", error.source().unwrap().to_string()); +} diff --git a/vendor/anyhow/tests/test_chain.rs b/vendor/anyhow/tests/test_chain.rs new file mode 100644 index 0000000..c8b901a --- /dev/null +++ b/vendor/anyhow/tests/test_chain.rs @@ -0,0 +1,69 @@ +use anyhow::{anyhow, Chain, Error}; + +fn error() -> Error { + anyhow!({ 0 }).context(1).context(2).context(3) +} + +#[test] +fn test_iter() { + let e = error(); + let mut chain = e.chain(); + assert_eq!("3", chain.next().unwrap().to_string()); + assert_eq!("2", chain.next().unwrap().to_string()); + assert_eq!("1", chain.next().unwrap().to_string()); + assert_eq!("0", chain.next().unwrap().to_string()); + assert!(chain.next().is_none()); + assert!(chain.next_back().is_none()); +} + +#[test] +fn test_rev() { + let e = error(); + let mut chain = e.chain().rev(); + assert_eq!("0", chain.next().unwrap().to_string()); + assert_eq!("1", chain.next().unwrap().to_string()); + assert_eq!("2", chain.next().unwrap().to_string()); + assert_eq!("3", chain.next().unwrap().to_string()); + assert!(chain.next().is_none()); + assert!(chain.next_back().is_none()); +} + +#[test] +fn test_len() { + let e = error(); + let mut chain = e.chain(); + assert_eq!(4, chain.len()); + assert_eq!((4, Some(4)), chain.size_hint()); + assert_eq!("3", chain.next().unwrap().to_string()); + assert_eq!(3, chain.len()); + assert_eq!((3, Some(3)), chain.size_hint()); + assert_eq!("0", chain.next_back().unwrap().to_string()); + assert_eq!(2, chain.len()); + assert_eq!((2, Some(2)), chain.size_hint()); + assert_eq!("2", chain.next().unwrap().to_string()); + assert_eq!(1, chain.len()); + assert_eq!((1, Some(1)), chain.size_hint()); + assert_eq!("1", chain.next_back().unwrap().to_string()); + assert_eq!(0, chain.len()); + assert_eq!((0, Some(0)), chain.size_hint()); + assert!(chain.next().is_none()); +} + +#[test] +fn test_default() { + let mut c = Chain::default(); + assert!(c.next().is_none()); +} + +#[test] +#[allow(clippy::redundant_clone)] +fn test_clone() { + let e = error(); + let mut chain = e.chain().clone(); + assert_eq!("3", chain.next().unwrap().to_string()); + assert_eq!("2", chain.next().unwrap().to_string()); + assert_eq!("1", chain.next().unwrap().to_string()); + assert_eq!("0", chain.next().unwrap().to_string()); + assert!(chain.next().is_none()); + assert!(chain.next_back().is_none()); +} diff --git a/vendor/anyhow/tests/test_context.rs b/vendor/anyhow/tests/test_context.rs new file mode 100644 index 0000000..2053fc9 --- /dev/null +++ b/vendor/anyhow/tests/test_context.rs @@ -0,0 +1,172 @@ +#![allow( + // Clippy bug: https://github.com/rust-lang/rust-clippy/issues/7422 + clippy::nonstandard_macro_braces, +)] + +mod drop; + +use crate::drop::{DetectDrop, Flag}; +use anyhow::{Context, Error, Result}; +use std::fmt::{self, Display}; +use thiserror::Error; + +// https://github.com/dtolnay/anyhow/issues/18 +#[test] +fn test_inference() -> Result<()> { + let x = "1"; + let y: u32 = x.parse().context("...")?; + assert_eq!(y, 1); + Ok(()) +} + +macro_rules! context_type { + ($name:ident) => { + #[derive(Debug)] + struct $name { + message: &'static str, + #[allow(dead_code)] + drop: DetectDrop, + } + + impl Display for $name { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.write_str(self.message) + } + } + }; +} + +context_type!(HighLevel); +context_type!(MidLevel); + +#[derive(Error, Debug)] +#[error("{message}")] +struct LowLevel { + message: &'static str, + drop: DetectDrop, +} + +struct Dropped { + low: Flag, + mid: Flag, + high: Flag, +} + +impl Dropped { + fn none(&self) -> bool { + !self.low.get() && !self.mid.get() && !self.high.get() + } + + fn all(&self) -> bool { + self.low.get() && self.mid.get() && self.high.get() + } +} + +fn make_chain() -> (Error, Dropped) { + let dropped = Dropped { + low: Flag::new(), + mid: Flag::new(), + high: Flag::new(), + }; + + let low = LowLevel { + message: "no such file or directory", + drop: DetectDrop::new(&dropped.low), + }; + + // impl Context for Result + let mid = Err::<(), LowLevel>(low) + .context(MidLevel { + message: "failed to load config", + drop: DetectDrop::new(&dropped.mid), + }) + .unwrap_err(); + + // impl Context for Result + let high = Err::<(), Error>(mid) + .context(HighLevel { + message: "failed to start server", + drop: DetectDrop::new(&dropped.high), + }) + .unwrap_err(); + + (high, dropped) +} + +#[test] +fn test_downcast_ref() { + let (err, dropped) = make_chain(); + + assert!(!err.is::()); + assert!(err.downcast_ref::().is_none()); + + assert!(err.is::()); + let high = err.downcast_ref::().unwrap(); + assert_eq!(high.to_string(), "failed to start server"); + + assert!(err.is::()); + let mid = err.downcast_ref::().unwrap(); + assert_eq!(mid.to_string(), "failed to load config"); + + assert!(err.is::()); + let low = err.downcast_ref::().unwrap(); + assert_eq!(low.to_string(), "no such file or directory"); + + assert!(dropped.none()); + drop(err); + assert!(dropped.all()); +} + +#[test] +fn test_downcast_high() { + let (err, dropped) = make_chain(); + + let err = err.downcast::().unwrap(); + assert!(!dropped.high.get()); + assert!(dropped.low.get() && dropped.mid.get()); + + drop(err); + assert!(dropped.all()); +} + +#[test] +fn test_downcast_mid() { + let (err, dropped) = make_chain(); + + let err = err.downcast::().unwrap(); + assert!(!dropped.mid.get()); + assert!(dropped.low.get() && dropped.high.get()); + + drop(err); + assert!(dropped.all()); +} + +#[test] +fn test_downcast_low() { + let (err, dropped) = make_chain(); + + let err = err.downcast::().unwrap(); + assert!(!dropped.low.get()); + assert!(dropped.mid.get() && dropped.high.get()); + + drop(err); + assert!(dropped.all()); +} + +#[test] +fn test_unsuccessful_downcast() { + let (err, dropped) = make_chain(); + + let err = err.downcast::().unwrap_err(); + assert!(dropped.none()); + + drop(err); + assert!(dropped.all()); +} + +#[test] +fn test_root_cause() { + let (err, _) = make_chain(); + + assert_eq!(err.root_cause().to_string(), "no such file or directory"); +} diff --git a/vendor/anyhow/tests/test_convert.rs b/vendor/anyhow/tests/test_convert.rs new file mode 100644 index 0000000..6da171d --- /dev/null +++ b/vendor/anyhow/tests/test_convert.rs @@ -0,0 +1,46 @@ +#![allow(clippy::unnecessary_wraps)] + +mod drop; + +use self::drop::{DetectDrop, Flag}; +use anyhow::{Error, Result}; +use std::error::Error as StdError; + +#[test] +fn test_convert() { + let has_dropped = Flag::new(); + let error = Error::new(DetectDrop::new(&has_dropped)); + let box_dyn = Box::::from(error); + assert_eq!("oh no!", box_dyn.to_string()); + drop(box_dyn); + assert!(has_dropped.get()); +} + +#[test] +fn test_convert_send() { + let has_dropped = Flag::new(); + let error = Error::new(DetectDrop::new(&has_dropped)); + let box_dyn = Box::::from(error); + assert_eq!("oh no!", box_dyn.to_string()); + drop(box_dyn); + assert!(has_dropped.get()); +} + +#[test] +fn test_convert_send_sync() { + let has_dropped = Flag::new(); + let error = Error::new(DetectDrop::new(&has_dropped)); + let box_dyn = Box::::from(error); + assert_eq!("oh no!", box_dyn.to_string()); + drop(box_dyn); + assert!(has_dropped.get()); +} + +#[test] +fn test_question_mark() -> Result<(), Box> { + fn f() -> Result<()> { + Ok(()) + } + f()?; + Ok(()) +} diff --git a/vendor/anyhow/tests/test_downcast.rs b/vendor/anyhow/tests/test_downcast.rs new file mode 100644 index 0000000..b4470d5 --- /dev/null +++ b/vendor/anyhow/tests/test_downcast.rs @@ -0,0 +1,123 @@ +#![allow(clippy::assertions_on_result_states, clippy::wildcard_imports)] + +mod common; +mod drop; + +use self::common::*; +use self::drop::{DetectDrop, Flag}; +use anyhow::Error; +use std::error::Error as StdError; +use std::fmt::{self, Display}; +use std::io; + +#[test] +fn test_downcast() { + assert_eq!( + "oh no!", + bail_literal().unwrap_err().downcast::<&str>().unwrap(), + ); + assert_eq!( + "oh no!", + bail_fmt().unwrap_err().downcast::().unwrap(), + ); + assert_eq!( + "oh no!", + bail_error() + .unwrap_err() + .downcast::() + .unwrap() + .to_string(), + ); +} + +#[test] +fn test_downcast_ref() { + assert_eq!( + "oh no!", + *bail_literal().unwrap_err().downcast_ref::<&str>().unwrap(), + ); + assert_eq!( + "oh no!", + bail_fmt().unwrap_err().downcast_ref::().unwrap(), + ); + assert_eq!( + "oh no!", + bail_error() + .unwrap_err() + .downcast_ref::() + .unwrap() + .to_string(), + ); +} + +#[test] +fn test_downcast_mut() { + assert_eq!( + "oh no!", + *bail_literal().unwrap_err().downcast_mut::<&str>().unwrap(), + ); + assert_eq!( + "oh no!", + bail_fmt().unwrap_err().downcast_mut::().unwrap(), + ); + assert_eq!( + "oh no!", + bail_error() + .unwrap_err() + .downcast_mut::() + .unwrap() + .to_string(), + ); + + let mut bailed = bail_fmt().unwrap_err(); + *bailed.downcast_mut::().unwrap() = "clobber".to_string(); + assert_eq!(bailed.downcast_ref::().unwrap(), "clobber"); + assert_eq!(bailed.downcast_mut::().unwrap(), "clobber"); + assert_eq!(bailed.downcast::().unwrap(), "clobber"); +} + +#[test] +fn test_drop() { + let has_dropped = Flag::new(); + let error = Error::new(DetectDrop::new(&has_dropped)); + drop(error.downcast::().unwrap()); + assert!(has_dropped.get()); +} + +#[test] +fn test_as_ref() { + let error = bail_error().unwrap_err(); + let ref_dyn: &dyn StdError = error.as_ref(); + assert_eq!("oh no!", ref_dyn.to_string()); + let ref_dyn_send_sync: &(dyn StdError + Send + Sync) = error.as_ref(); + assert_eq!("oh no!", ref_dyn_send_sync.to_string()); +} + +#[test] +fn test_large_alignment() { + #[repr(align(64))] + #[derive(Debug)] + struct LargeAlignedError(&'static str); + + impl Display for LargeAlignedError { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.write_str(self.0) + } + } + + impl StdError for LargeAlignedError {} + + let error = Error::new(LargeAlignedError("oh no!")); + assert_eq!( + "oh no!", + error.downcast_ref::().unwrap().0 + ); +} + +#[test] +fn test_unsuccessful_downcast() { + let mut error = bail_error().unwrap_err(); + assert!(error.downcast_ref::<&str>().is_none()); + assert!(error.downcast_mut::<&str>().is_none()); + assert!(error.downcast::<&str>().is_err()); +} diff --git a/vendor/anyhow/tests/test_ensure.rs b/vendor/anyhow/tests/test_ensure.rs new file mode 100644 index 0000000..f41ad37 --- /dev/null +++ b/vendor/anyhow/tests/test_ensure.rs @@ -0,0 +1,741 @@ +#![allow( + clippy::bool_to_int_with_if, + clippy::char_lit_as_u8, + clippy::deref_addrof, + clippy::diverging_sub_expression, + clippy::erasing_op, + clippy::extra_unused_type_parameters, + clippy::if_same_then_else, + clippy::ifs_same_cond, + clippy::ignored_unit_patterns, + clippy::items_after_statements, + clippy::let_and_return, + clippy::let_underscore_untyped, + clippy::match_bool, + clippy::needless_else, + clippy::never_loop, + clippy::overly_complex_bool_expr, + clippy::redundant_closure_call, + clippy::redundant_pattern_matching, + clippy::too_many_lines, + clippy::unit_arg, + clippy::unnecessary_cast, + clippy::while_immutable_condition, + clippy::zero_ptr, + irrefutable_let_patterns +)] + +use self::Enum::Generic; +use anyhow::{anyhow, ensure, Chain, Error, Result}; +use std::fmt::{self, Debug}; +use std::iter; +use std::marker::{PhantomData, PhantomData as P}; +use std::mem; +use std::ops::Add; +use std::ptr; + +struct S; + +impl Add for S { + type Output = bool; + fn add(self, rhs: T) -> Self::Output { + let _ = rhs; + false + } +} + +trait Trait: Sized { + const V: usize = 0; + fn t(self, i: i32) -> i32 { + i + } +} + +impl Trait for T {} + +enum Enum { + #[allow(dead_code)] + Thing(PhantomData), + Generic, +} + +impl PartialEq for Enum { + fn eq(&self, rhs: &Self) -> bool { + mem::discriminant(self) == mem::discriminant(rhs) + } +} + +impl Debug for Enum { + fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("Generic") + } +} + +#[track_caller] +fn assert_err(result: impl FnOnce() -> Result, expected: &'static str) { + let actual = result().unwrap_err().to_string(); + + // In general different rustc versions will format the interpolated lhs and + // rhs $:expr fragment with insignificant differences in whitespace or + // punctuation, so we check the message in full against nightly and do just + // a cursory test on older toolchains. + if rustversion::cfg!(nightly) && !cfg!(miri) { + assert_eq!(actual, expected); + } else { + assert_eq!(actual.contains(" vs "), expected.contains(" vs ")); + } +} + +#[test] +fn test_recursion() { + // Must not blow the default #[recursion_limit], which is 128. + #[rustfmt::skip] + let test = || Ok(ensure!( + false | false | false | false | false | false | false | false | false | + false | false | false | false | false | false | false | false | false | + false | false | false | false | false | false | false | false | false | + false | false | false | false | false | false | false | false | false | + false | false | false | false | false | false | false | false | false | + false | false | false | false | false | false | false | false | false | + false | false | false | false | false | false | false | false | false + )); + + test().unwrap_err(); +} + +#[test] +fn test_low_precedence_control_flow() { + #[allow(unreachable_code)] + let test = || { + let val = loop { + // Break has lower precedence than the comparison operators so the + // expression here is `S + (break (1 == 1))`. It would be bad if the + // ensure macro partitioned this input into `(S + break 1) == (1)` + // because that means a different thing than what was written. + ensure!(S + break 1 == 1); + }; + Ok(val) + }; + + assert!(test().unwrap()); +} + +#[test] +fn test_low_precedence_binary_operator() { + // Must not partition as `false == (true && false)`. + let test = || Ok(ensure!(false == true && false)); + assert_err(test, "Condition failed: `false == true && false`"); + + // But outside the root level, it is fine. + let test = || Ok(ensure!(while false == true && false {} < ())); + assert_err( + test, + "Condition failed: `while false == true && false {} < ()` (() vs ())", + ); + + let a = 15; + let b = 3; + let test = || Ok(ensure!(a <= b || a - b <= 10)); + assert_err(test, "Condition failed: `a <= b || a - b <= 10`"); +} + +#[test] +fn test_high_precedence_binary_operator() { + let a = 15; + let b = 3; + let test = || Ok(ensure!(a - b <= 10)); + assert_err(test, "Condition failed: `a - b <= 10` (12 vs 10)"); +} + +#[test] +fn test_closure() { + // Must not partition as `(S + move) || (1 == 1)` by treating move as an + // identifier, nor as `(S + move || 1) == (1)` by misinterpreting the + // closure precedence. + let test = || Ok(ensure!(S + move || 1 == 1)); + assert_err(test, "Condition failed: `S + move || 1 == 1`"); + + let test = || Ok(ensure!(S + || 1 == 1)); + assert_err(test, "Condition failed: `S + || 1 == 1`"); + + // Must not partition as `S + ((move | ()) | 1) == 1` by treating those + // pipes as bitwise-or. + let test = || Ok(ensure!(S + move |()| 1 == 1)); + assert_err(test, "Condition failed: `S + move |()| 1 == 1`"); + + let test = || Ok(ensure!(S + |()| 1 == 1)); + assert_err(test, "Condition failed: `S + |()| 1 == 1`"); +} + +#[test] +fn test_unary() { + let mut x = &1; + let test = || Ok(ensure!(*x == 2)); + assert_err(test, "Condition failed: `*x == 2` (1 vs 2)"); + + let test = || Ok(ensure!(!x == 1)); + assert_err(test, "Condition failed: `!x == 1` (-2 vs 1)"); + + let test = || Ok(ensure!(-x == 1)); + assert_err(test, "Condition failed: `-x == 1` (-1 vs 1)"); + + let test = || Ok(ensure!(&x == &&2)); + assert_err(test, "Condition failed: `&x == &&2` (1 vs 2)"); + + let test = || Ok(ensure!(&mut x == *&&mut &2)); + assert_err(test, "Condition failed: `&mut x == *&&mut &2` (1 vs 2)"); +} + +#[test] +fn test_if() { + #[rustfmt::skip] + let test = || Ok(ensure!(if false {}.t(1) == 2)); + assert_err(test, "Condition failed: `if false {}.t(1) == 2` (1 vs 2)"); + + #[rustfmt::skip] + let test = || Ok(ensure!(if false {} else {}.t(1) == 2)); + assert_err( + test, + "Condition failed: `if false {} else {}.t(1) == 2` (1 vs 2)", + ); + + #[rustfmt::skip] + let test = || Ok(ensure!(if false {} else if false {}.t(1) == 2)); + assert_err( + test, + "Condition failed: `if false {} else if false {}.t(1) == 2` (1 vs 2)", + ); + + #[rustfmt::skip] + let test = || Ok(ensure!(if let 1 = 2 {}.t(1) == 2)); + assert_err( + test, + "Condition failed: `if let 1 = 2 {}.t(1) == 2` (1 vs 2)", + ); + + #[rustfmt::skip] + let test = || Ok(ensure!(if let 1 | 2 = 2 {}.t(1) == 2)); + assert_err( + test, + "Condition failed: `if let 1 | 2 = 2 {}.t(1) == 2` (1 vs 2)", + ); + + #[rustfmt::skip] + let test = || Ok(ensure!(if let | 1 | 2 = 2 {}.t(1) == 2)); + assert_err( + test, + "Condition failed: `if let | 1 | 2 = 2 {}.t(1) == 2` (1 vs 2)", + ); +} + +#[test] +fn test_loop() { + #[rustfmt::skip] + let test = || Ok(ensure!(1 + loop { break 1 } == 1)); + assert_err( + test, + "Condition failed: `1 + loop { break 1 } == 1` (2 vs 1)", + ); + + #[rustfmt::skip] + let test = || Ok(ensure!(1 + 'a: loop { break 'a 1 } == 1)); + assert_err( + test, + "Condition failed: `1 + 'a: loop { break 'a 1 } == 1` (2 vs 1)", + ); + + #[rustfmt::skip] + let test = || Ok(ensure!(while false {}.t(1) == 2)); + assert_err( + test, + "Condition failed: `while false {}.t(1) == 2` (1 vs 2)", + ); + + #[rustfmt::skip] + let test = || Ok(ensure!(while let None = Some(1) {}.t(1) == 2)); + assert_err( + test, + "Condition failed: `while let None = Some(1) {}.t(1) == 2` (1 vs 2)", + ); + + #[rustfmt::skip] + let test = || Ok(ensure!(for _x in iter::once(0) {}.t(1) == 2)); + assert_err( + test, + "Condition failed: `for _x in iter::once(0) {}.t(1) == 2` (1 vs 2)", + ); + + #[rustfmt::skip] + let test = || Ok(ensure!(for | _x in iter::once(0) {}.t(1) == 2)); + assert_err( + test, + "Condition failed: `for | _x in iter::once(0) {}.t(1) == 2` (1 vs 2)", + ); + + #[rustfmt::skip] + let test = || Ok(ensure!(for true | false in iter::empty() {}.t(1) == 2)); + assert_err( + test, + "Condition failed: `for true | false in iter::empty() {}.t(1) == 2` (1 vs 2)", + ); +} + +#[test] +fn test_match() { + #[rustfmt::skip] + let test = || Ok(ensure!(match 1 == 1 { true => 1, false => 0 } == 2)); + assert_err( + test, + "Condition failed: `match 1 == 1 { true => 1, false => 0 } == 2` (1 vs 2)", + ); +} + +#[test] +fn test_atom() { + let test = || Ok(ensure!([false, false].len() > 3)); + assert_err( + test, + "Condition failed: `[false, false].len() > 3` (2 vs 3)", + ); + + #[rustfmt::skip] + let test = || Ok(ensure!({ let x = 1; x } >= 3)); + assert_err(test, "Condition failed: `{ let x = 1; x } >= 3` (1 vs 3)"); + + let test = || Ok(ensure!(S + async { 1 } == true)); + assert_err( + test, + "Condition failed: `S + async { 1 } == true` (false vs true)", + ); + + let test = || Ok(ensure!(S + async move { 1 } == true)); + assert_err( + test, + "Condition failed: `S + async move { 1 } == true` (false vs true)", + ); + + let x = &1; + let test = || Ok(ensure!(S + unsafe { ptr::read(x) } == true)); + assert_err( + test, + "Condition failed: `S + unsafe { ptr::read(x) } == true` (false vs true)", + ); +} + +#[test] +fn test_path() { + let test = || Ok(ensure!(crate::S.t(1) == 2)); + assert_err(test, "Condition failed: `crate::S.t(1) == 2` (1 vs 2)"); + + let test = || Ok(ensure!(::anyhow::Error::root_cause.t(1) == 2)); + assert_err( + test, + "Condition failed: `::anyhow::Error::root_cause.t(1) == 2` (1 vs 2)", + ); + + let test = || Ok(ensure!(Error::msg::<&str>.t(1) == 2)); + assert_err( + test, + "Condition failed: `Error::msg::<&str>.t(1) == 2` (1 vs 2)", + ); + + #[rustfmt::skip] + let test = || Ok(ensure!(Error::msg::<&str,>.t(1) == 2)); + assert_err( + test, + "Condition failed: `Error::msg::<&str,>.t(1) == 2` (1 vs 2)", + ); + + let test = || Ok(ensure!(Error::msg::<::Owned>.t(1) == 2)); + assert_err( + test, + "Condition failed: `Error::msg::<::Owned>.t(1) == 2` (1 vs 2)", + ); + + let test = || Ok(ensure!(Chain::<'static>::new.t(1) == 2)); + assert_err( + test, + "Condition failed: `Chain::<'static>::new.t(1) == 2` (1 vs 2)", + ); + + #[rustfmt::skip] + let test = || Ok(ensure!(Chain::<'static,>::new.t(1) == 2)); + assert_err( + test, + "Condition failed: `Chain::<'static,>::new.t(1) == 2` (1 vs 2)", + ); + + fn f() {} + let test = || Ok(ensure!(f::<1>() != ())); + assert_err(test, "Condition failed: `f::<1>() != ()` (() vs ())"); + let test = || Ok(ensure!(f::<-1>() != ())); + assert_err(test, "Condition failed: `f::<-1>() != ()` (() vs ())"); + + fn g() {} + let test = || Ok(ensure!(g::() != ())); + assert_err(test, "Condition failed: `g::() != ()` (() vs ())"); + let test = || Ok(ensure!(g::() != ())); + assert_err(test, "Condition failed: `g::() != ()` (() vs ())"); + + #[derive(PartialOrd, PartialEq, Debug)] + enum E<'a, T> { + #[allow(dead_code)] + T(&'a T), + U, + } + + #[rustfmt::skip] + let test = || Ok(ensure!(E::U::<>>E::U::)); + assert_err(test, "Condition failed: `E::U::<> > E::U::` (U vs U)"); + + #[rustfmt::skip] + let test = || Ok(ensure!(E::U::>E::U)); + assert_err(test, "Condition failed: `E::U:: > E::U` (U vs U)"); + + #[rustfmt::skip] + let test = || Ok(ensure!(E::U::>E::U)); + assert_err(test, "Condition failed: `E::U:: > E::U` (U vs U)"); + + let test = || Ok(ensure!(Generic:: != Generic)); + assert_err( + test, + "Condition failed: `Generic:: != Generic` (Generic vs Generic)", + ); + + let test = || Ok(ensure!(Generic:: != Generic)); + assert_err( + test, + "Condition failed: `Generic:: != Generic` (Generic vs Generic)", + ); + + #[rustfmt::skip] + let test = || { + Ok(ensure!( + Generic:: != Generic + )) + }; + assert_err( + test, + "Condition failed: `Generic:: != Generic` (Generic vs Generic)", + ); +} + +#[test] +fn test_macro() { + let test = || Ok(ensure!(anyhow!("...").to_string().len() <= 1)); + assert_err( + test, + "Condition failed: `anyhow!(\"...\").to_string().len() <= 1` (3 vs 1)", + ); + + let test = || Ok(ensure!(vec![1].len() < 1)); + assert_err(test, "Condition failed: `vec![1].len() < 1` (1 vs 1)"); + + let test = || Ok(ensure!(stringify! {} != "")); + assert_err( + test, + "Condition failed: `stringify! {} != \"\"` (\"\" vs \"\")", + ); +} + +#[test] +fn test_trailer() { + let test = || Ok(ensure!((|| 1)() == 2)); + assert_err(test, "Condition failed: `(|| 1)() == 2` (1 vs 2)"); + + let test = || Ok(ensure!(b"hmm"[1] == b'c')); + assert_err(test, "Condition failed: `b\"hmm\"[1] == b'c'` (109 vs 99)"); + + let test = || Ok(ensure!(PhantomData:: {} != PhantomData)); + assert_err( + test, + "Condition failed: `PhantomData:: {} != PhantomData` (PhantomData vs PhantomData)", + ); + + let result = Ok::<_, Error>(1); + let test = || Ok(ensure!(result? == 2)); + assert_err(test, "Condition failed: `result? == 2` (1 vs 2)"); + + let test = || Ok(ensure!((2, 3).1 == 2)); + assert_err(test, "Condition failed: `(2, 3).1 == 2` (3 vs 2)"); + + #[rustfmt::skip] + let test = || Ok(ensure!((2, (3, 4)). 1.1 == 2)); + assert_err(test, "Condition failed: `(2, (3, 4)).1.1 == 2` (4 vs 2)"); + + let err = anyhow!(""); + let test = || Ok(ensure!(err.is::<&str>() == false)); + assert_err( + test, + "Condition failed: `err.is::<&str>() == false` (true vs false)", + ); + + let test = || Ok(ensure!(err.is::<::Owned>() == true)); + assert_err( + test, + "Condition failed: `err.is::<::Owned>() == true` (false vs true)", + ); +} + +#[test] +fn test_whitespace() { + #[derive(Debug)] + pub struct Point { + #[allow(dead_code)] + pub x: i32, + #[allow(dead_code)] + pub y: i32, + } + + let point = Point { x: 0, y: 0 }; + let test = || Ok(ensure!("" == format!("{:#?}", point))); + assert_err( + test, + "Condition failed: `\"\" == format!(\"{:#?}\", point)`", + ); +} + +#[test] +fn test_too_long() { + let test = || Ok(ensure!("" == "x".repeat(10))); + assert_err( + test, + "Condition failed: `\"\" == \"x\".repeat(10)` (\"\" vs \"xxxxxxxxxx\")", + ); + + let test = || Ok(ensure!("" == "x".repeat(80))); + assert_err(test, "Condition failed: `\"\" == \"x\".repeat(80)`"); +} + +#[test] +fn test_as() { + let test = || Ok(ensure!('\0' as u8 > 1)); + assert_err(test, "Condition failed: `'\\0' as u8 > 1` (0 vs 1)"); + + let test = || Ok(ensure!('\0' as ::std::primitive::u8 > 1)); + assert_err( + test, + "Condition failed: `'\\0' as ::std::primitive::u8 > 1` (0 vs 1)", + ); + + let test = || Ok(ensure!(&[0] as &[i32] == [1])); + assert_err( + test, + "Condition failed: `&[0] as &[i32] == [1]` ([0] vs [1])", + ); + + let test = || Ok(ensure!(0 as *const () as *mut _ == 1 as *mut ())); + assert_err( + test, + "Condition failed: `0 as *const () as *mut _ == 1 as *mut ()` (0x0 vs 0x1)", + ); + + let s = ""; + let test = || Ok(ensure!(s as &str != s)); + assert_err(test, "Condition failed: `s as &str != s` (\"\" vs \"\")"); + + let test = || Ok(ensure!(&s as &&str != &s)); + assert_err(test, "Condition failed: `&s as &&str != &s` (\"\" vs \"\")"); + + let test = || Ok(ensure!(s as &'static str != s)); + assert_err( + test, + "Condition failed: `s as &'static str != s` (\"\" vs \"\")", + ); + + let test = || Ok(ensure!(&s as &&'static str != &s)); + assert_err( + test, + "Condition failed: `&s as &&'static str != &s` (\"\" vs \"\")", + ); + + let m: &mut str = Default::default(); + let test = || Ok(ensure!(m as &mut str != s)); + assert_err( + test, + "Condition failed: `m as &mut str != s` (\"\" vs \"\")", + ); + + let test = || Ok(ensure!(&m as &&mut str != &s)); + assert_err( + test, + "Condition failed: `&m as &&mut str != &s` (\"\" vs \"\")", + ); + + let test = || Ok(ensure!(&m as &&'static mut str != &s)); + assert_err( + test, + "Condition failed: `&m as &&'static mut str != &s` (\"\" vs \"\")", + ); + + let f = || {}; + let test = || Ok(ensure!(f as fn() as usize * 0 != 0)); + assert_err( + test, + "Condition failed: `f as fn() as usize * 0 != 0` (0 vs 0)", + ); + + let test = || Ok(ensure!(f as fn() -> () as usize * 0 != 0)); + assert_err( + test, + "Condition failed: `f as fn() -> () as usize * 0 != 0` (0 vs 0)", + ); + + let test = || Ok(ensure!(f as for<'a> fn() as usize * 0 != 0)); + assert_err( + test, + "Condition failed: `f as for<'a> fn() as usize * 0 != 0` (0 vs 0)", + ); + + let test = || Ok(ensure!(f as unsafe fn() as usize * 0 != 0)); + assert_err( + test, + "Condition failed: `f as unsafe fn() as usize * 0 != 0` (0 vs 0)", + ); + + #[rustfmt::skip] + let test = || Ok(ensure!(f as extern "Rust" fn() as usize * 0 != 0)); + assert_err( + test, + "Condition failed: `f as extern \"Rust\" fn() as usize * 0 != 0` (0 vs 0)", + ); + + extern "C" fn extern_fn() {} + #[rustfmt::skip] + let test = || Ok(ensure!(extern_fn as extern fn() as usize * 0 != 0)); + assert_err( + test, + "Condition failed: `extern_fn as extern fn() as usize * 0 != 0` (0 vs 0)", + ); + + let f = || -> ! { panic!() }; + let test = || Ok(ensure!(f as fn() -> ! as usize * 0 != 0)); + assert_err( + test, + "Condition failed: `f as fn() -> ! as usize * 0 != 0` (0 vs 0)", + ); + + trait EqDebug: PartialEq + Debug { + type Assoc; + } + + impl EqDebug for S + where + S: PartialEq + Debug, + { + type Assoc = bool; + } + + let test = || Ok(ensure!(&0 as &dyn EqDebug != &0)); + assert_err( + test, + "Condition failed: `&0 as &dyn EqDebug != &0` (0 vs 0)", + ); + + let test = || { + Ok(ensure!( + PhantomData as PhantomData<::Owned> != PhantomData + )) + }; + assert_err( + test, + "Condition failed: `PhantomData as PhantomData<::Owned> != PhantomData` (PhantomData vs PhantomData)", + ); + + macro_rules! int { + (...) => { + u8 + }; + } + + let test = || Ok(ensure!(0 as int!(...) != 0)); + assert_err(test, "Condition failed: `0 as int!(...) != 0` (0 vs 0)"); + + let test = || Ok(ensure!(0 as int![...] != 0)); + assert_err(test, "Condition failed: `0 as int![...] != 0` (0 vs 0)"); + + let test = || Ok(ensure!(0 as int! {...} != 0)); + assert_err(test, "Condition failed: `0 as int! { ... } != 0` (0 vs 0)"); +} + +#[test] +fn test_pat() { + let test = || Ok(ensure!(if let ref mut _x @ 0 = 0 { 0 } else { 1 } == 1)); + assert_err( + test, + "Condition failed: `if let ref mut _x @ 0 = 0 { 0 } else { 1 } == 1` (0 vs 1)", + ); + + let test = || Ok(ensure!(if let -1..=1 = 0 { 0 } else { 1 } == 1)); + assert_err( + test, + "Condition failed: `if let -1..=1 = 0 { 0 } else { 1 } == 1` (0 vs 1)", + ); + + let test = || Ok(ensure!(if let &0 = &0 { 0 } else { 1 } == 1)); + assert_err( + test, + "Condition failed: `if let &0 = &0 { 0 } else { 1 } == 1` (0 vs 1)", + ); + + let test = || Ok(ensure!(if let &&0 = &&0 { 0 } else { 1 } == 1)); + assert_err( + test, + "Condition failed: `if let &&0 = &&0 { 0 } else { 1 } == 1` (0 vs 1)", + ); + + let test = || Ok(ensure!(if let &mut 0 = &mut 0 { 0 } else { 1 } == 1)); + assert_err( + test, + "Condition failed: `if let &mut 0 = &mut 0 { 0 } else { 1 } == 1` (0 vs 1)", + ); + + let test = || Ok(ensure!(if let &&mut 0 = &&mut 0 { 0 } else { 1 } == 1)); + assert_err( + test, + "Condition failed: `if let &&mut 0 = &&mut 0 { 0 } else { 1 } == 1` (0 vs 1)", + ); + + let test = || Ok(ensure!(if let (0, 1) = (0, 1) { 0 } else { 1 } == 1)); + assert_err( + test, + "Condition failed: `if let (0, 1) = (0, 1) { 0 } else { 1 } == 1` (0 vs 1)", + ); + + let test = || Ok(ensure!(if let [0] = b"\0" { 0 } else { 1 } == 1)); + assert_err( + test, + "Condition failed: `if let [0] = b\"\\0\" { 0 } else { 1 } == 1` (0 vs 1)", + ); + + let p = PhantomData::; + let test = || Ok(ensure!(if let P:: {} = p { 0 } else { 1 } == 1)); + assert_err( + test, + "Condition failed: `if let P:: {} = p { 0 } else { 1 } == 1` (0 vs 1)", + ); + + let test = || Ok(ensure!(if let ::std::marker::PhantomData = p {} != ())); + assert_err( + test, + "Condition failed: `if let ::std::marker::PhantomData = p {} != ()` (() vs ())", + ); + + let test = || Ok(ensure!(if let ::V = 0 { 0 } else { 1 } == 1)); + assert_err( + test, + "Condition failed: `if let ::V = 0 { 0 } else { 1 } == 1` (0 vs 1)", + ); + + let test = || Ok(ensure!(for _ in iter::once(()) {} != ())); + assert_err( + test, + "Condition failed: `for _ in iter::once(()) {} != ()` (() vs ())", + ); + + let test = || Ok(ensure!(if let stringify!(x) = "x" { 0 } else { 1 } == 1)); + assert_err( + test, + "Condition failed: `if let stringify!(x) = \"x\" { 0 } else { 1 } == 1` (0 vs 1)", + ); +} diff --git a/vendor/anyhow/tests/test_ffi.rs b/vendor/anyhow/tests/test_ffi.rs new file mode 100644 index 0000000..0321fc1 --- /dev/null +++ b/vendor/anyhow/tests/test_ffi.rs @@ -0,0 +1,18 @@ +#![deny(improper_ctypes, improper_ctypes_definitions)] + +use anyhow::anyhow; + +#[no_mangle] +pub extern "C" fn anyhow1(err: anyhow::Error) { + println!("{:?}", err); +} + +#[no_mangle] +pub extern "C" fn anyhow2(err: &mut Option) { + *err = Some(anyhow!("ffi error")); +} + +#[no_mangle] +pub extern "C" fn anyhow3() -> Option { + Some(anyhow!("ffi error")) +} diff --git a/vendor/anyhow/tests/test_fmt.rs b/vendor/anyhow/tests/test_fmt.rs new file mode 100644 index 0000000..8206f22 --- /dev/null +++ b/vendor/anyhow/tests/test_fmt.rs @@ -0,0 +1,93 @@ +use anyhow::{bail, Context, Result}; +use std::io; + +fn f() -> Result<()> { + bail!(io::Error::new(io::ErrorKind::PermissionDenied, "oh no!")); +} + +fn g() -> Result<()> { + f().context("f failed") +} + +fn h() -> Result<()> { + g().context("g failed") +} + +const EXPECTED_ALTDISPLAY_F: &str = "oh no!"; + +const EXPECTED_ALTDISPLAY_G: &str = "f failed: oh no!"; + +const EXPECTED_ALTDISPLAY_H: &str = "g failed: f failed: oh no!"; + +const EXPECTED_DEBUG_F: &str = "oh no!"; + +const EXPECTED_DEBUG_G: &str = "\ +f failed + +Caused by: + oh no!\ +"; + +const EXPECTED_DEBUG_H: &str = "\ +g failed + +Caused by: + 0: f failed + 1: oh no!\ +"; + +const EXPECTED_ALTDEBUG_F: &str = "\ +Custom { + kind: PermissionDenied, + error: \"oh no!\", +}\ +"; + +const EXPECTED_ALTDEBUG_G: &str = "\ +Error { + context: \"f failed\", + source: Custom { + kind: PermissionDenied, + error: \"oh no!\", + }, +}\ +"; + +const EXPECTED_ALTDEBUG_H: &str = "\ +Error { + context: \"g failed\", + source: Error { + context: \"f failed\", + source: Custom { + kind: PermissionDenied, + error: \"oh no!\", + }, + }, +}\ +"; + +#[test] +fn test_display() { + assert_eq!("g failed", h().unwrap_err().to_string()); +} + +#[test] +fn test_altdisplay() { + assert_eq!(EXPECTED_ALTDISPLAY_F, format!("{:#}", f().unwrap_err())); + assert_eq!(EXPECTED_ALTDISPLAY_G, format!("{:#}", g().unwrap_err())); + assert_eq!(EXPECTED_ALTDISPLAY_H, format!("{:#}", h().unwrap_err())); +} + +#[test] +fn test_debug() { + assert_eq!(EXPECTED_DEBUG_F, format!("{:?}", f().unwrap_err())); + assert_eq!(EXPECTED_DEBUG_G, format!("{:?}", g().unwrap_err())); + assert_eq!(EXPECTED_DEBUG_H, format!("{:?}", h().unwrap_err())); +} + +#[test] +fn test_altdebug() { + assert_eq!(EXPECTED_ALTDEBUG_F, format!("{:#?}", f().unwrap_err())); + assert_eq!(EXPECTED_ALTDEBUG_G, format!("{:#?}", g().unwrap_err())); + assert_eq!(EXPECTED_ALTDEBUG_H, format!("{:#?}", h().unwrap_err())); +} diff --git a/vendor/anyhow/tests/test_macros.rs b/vendor/anyhow/tests/test_macros.rs new file mode 100644 index 0000000..10740a9 --- /dev/null +++ b/vendor/anyhow/tests/test_macros.rs @@ -0,0 +1,96 @@ +#![allow( + clippy::assertions_on_result_states, + clippy::eq_op, + clippy::incompatible_msrv, // https://github.com/rust-lang/rust-clippy/issues/12257 + clippy::items_after_statements, + clippy::match_single_binding, + clippy::needless_pass_by_value, + clippy::shadow_unrelated, + clippy::wildcard_imports +)] + +mod common; + +use self::common::*; +use anyhow::{anyhow, ensure, Result}; +use std::cell::Cell; +use std::future; + +#[test] +fn test_messages() { + assert_eq!("oh no!", bail_literal().unwrap_err().to_string()); + assert_eq!("oh no!", bail_fmt().unwrap_err().to_string()); + assert_eq!("oh no!", bail_error().unwrap_err().to_string()); +} + +#[test] +fn test_ensure() { + let f = || { + ensure!(1 + 1 == 2, "This is correct"); + Ok(()) + }; + assert!(f().is_ok()); + + let v = 1; + let f = || { + ensure!(v + v == 2, "This is correct, v: {}", v); + Ok(()) + }; + assert!(f().is_ok()); + + let f = || { + ensure!(v + v == 1, "This is not correct, v: {}", v); + Ok(()) + }; + assert!(f().is_err()); + + let f = || { + ensure!(v + v == 1); + Ok(()) + }; + assert_eq!( + f().unwrap_err().to_string(), + "Condition failed: `v + v == 1` (2 vs 1)", + ); +} + +#[test] +fn test_ensure_nonbool() -> Result<()> { + struct Struct { + condition: bool, + } + + let s = Struct { condition: true }; + match &s { + Struct { condition } => ensure!(condition), // &bool + } + + Ok(()) +} + +#[test] +fn test_temporaries() { + fn require_send_sync(_: impl Send + Sync) {} + + require_send_sync(async { + // If anyhow hasn't dropped any temporary format_args it creates by the + // time it's done evaluating, those will stick around until the + // semicolon, which is on the other side of the await point, making the + // enclosing future non-Send. + future::ready(anyhow!("...")).await; + }); + + fn message(cell: Cell<&str>) -> &str { + cell.get() + } + + require_send_sync(async { + future::ready(anyhow!(message(Cell::new("...")))).await; + }); +} + +#[test] +fn test_brace_escape() { + let err = anyhow!("unterminated ${{..}} expression"); + assert_eq!("unterminated ${..} expression", err.to_string()); +} diff --git a/vendor/anyhow/tests/test_repr.rs b/vendor/anyhow/tests/test_repr.rs new file mode 100644 index 0000000..2976cd8 --- /dev/null +++ b/vendor/anyhow/tests/test_repr.rs @@ -0,0 +1,30 @@ +#![allow(clippy::extra_unused_type_parameters)] + +mod drop; + +use self::drop::{DetectDrop, Flag}; +use anyhow::Error; +use std::mem; + +#[test] +fn test_error_size() { + assert_eq!(mem::size_of::(), mem::size_of::()); +} + +#[test] +fn test_null_pointer_optimization() { + assert_eq!(mem::size_of::>(), mem::size_of::()); +} + +#[test] +fn test_autotraits() { + fn assert() {} + assert::(); +} + +#[test] +fn test_drop() { + let has_dropped = Flag::new(); + drop(Error::new(DetectDrop::new(&has_dropped))); + assert!(has_dropped.get()); +} diff --git a/vendor/anyhow/tests/test_source.rs b/vendor/anyhow/tests/test_source.rs new file mode 100644 index 0000000..018267d --- /dev/null +++ b/vendor/anyhow/tests/test_source.rs @@ -0,0 +1,62 @@ +use anyhow::anyhow; +use std::error::Error as StdError; +use std::fmt::{self, Display}; +use std::io; + +#[derive(Debug)] +enum TestError { + Io(io::Error), +} + +impl Display for TestError { + fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + match self { + TestError::Io(e) => Display::fmt(e, formatter), + } + } +} + +impl StdError for TestError { + fn source(&self) -> Option<&(dyn StdError + 'static)> { + match self { + TestError::Io(io) => Some(io), + } + } +} + +#[test] +fn test_literal_source() { + let error = anyhow!("oh no!"); + assert!(error.source().is_none()); +} + +#[test] +fn test_variable_source() { + let msg = "oh no!"; + let error = anyhow!(msg); + assert!(error.source().is_none()); + + let msg = msg.to_owned(); + let error = anyhow!(msg); + assert!(error.source().is_none()); +} + +#[test] +fn test_fmt_source() { + let error = anyhow!("{} {}!", "oh", "no"); + assert!(error.source().is_none()); +} + +#[test] +fn test_io_source() { + let io = io::Error::new(io::ErrorKind::Other, "oh no!"); + let error = anyhow!(TestError::Io(io)); + assert_eq!("oh no!", error.source().unwrap().to_string()); +} + +#[test] +fn test_anyhow_from_anyhow() { + let error = anyhow!("oh no!").context("context"); + let error = anyhow!(error); + assert_eq!("oh no!", error.source().unwrap().to_string()); +} diff --git a/vendor/anyhow/tests/ui/chained-comparison.rs b/vendor/anyhow/tests/ui/chained-comparison.rs new file mode 100644 index 0000000..4521b51 --- /dev/null +++ b/vendor/anyhow/tests/ui/chained-comparison.rs @@ -0,0 +1,8 @@ +use anyhow::{ensure, Result}; + +fn main() -> Result<()> { + // `ensure!` must not partition this into `(false) == (false == true)` + // because Rust doesn't ordinarily allow this form of expression. + ensure!(false == false == true); + Ok(()) +} diff --git a/vendor/anyhow/tests/ui/chained-comparison.stderr b/vendor/anyhow/tests/ui/chained-comparison.stderr new file mode 100644 index 0000000..2a4c665 --- /dev/null +++ b/vendor/anyhow/tests/ui/chained-comparison.stderr @@ -0,0 +1,10 @@ +error: comparison operators cannot be chained + --> tests/ui/chained-comparison.rs:6:19 + | +6 | ensure!(false == false == true); + | ^^ ^^ + | +help: split the comparison into two + | +6 | ensure!(false == false && false == true); + | ++++++++ diff --git a/vendor/anyhow/tests/ui/empty-ensure.rs b/vendor/anyhow/tests/ui/empty-ensure.rs new file mode 100644 index 0000000..139b743 --- /dev/null +++ b/vendor/anyhow/tests/ui/empty-ensure.rs @@ -0,0 +1,6 @@ +use anyhow::{ensure, Result}; + +fn main() -> Result<()> { + ensure!(); + Ok(()) +} diff --git a/vendor/anyhow/tests/ui/empty-ensure.stderr b/vendor/anyhow/tests/ui/empty-ensure.stderr new file mode 100644 index 0000000..bf0229a --- /dev/null +++ b/vendor/anyhow/tests/ui/empty-ensure.stderr @@ -0,0 +1,12 @@ +error: unexpected end of macro invocation + --> tests/ui/empty-ensure.rs:4:5 + | +4 | ensure!(); + | ^^^^^^^^^ missing tokens in macro arguments + | +note: while trying to match meta-variable `$cond:expr` + --> src/ensure.rs + | + | ($cond:expr $(,)?) => { + | ^^^^^^^^^^ + = note: this error originates in the macro `$crate::__parse_ensure` which comes from the expansion of the macro `ensure` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/vendor/anyhow/tests/ui/ensure-nonbool.rs b/vendor/anyhow/tests/ui/ensure-nonbool.rs new file mode 100644 index 0000000..c7df4e1 --- /dev/null +++ b/vendor/anyhow/tests/ui/ensure-nonbool.rs @@ -0,0 +1,40 @@ +use anyhow::{ensure, Result}; +use std::ops::{Deref, Not}; + +struct Bool(bool); + +struct DerefBool(bool); + +struct NotBool(bool); + +impl Deref for DerefBool { + type Target = bool; + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +impl Not for NotBool { + type Output = bool; + fn not(self) -> Self::Output { + !self.0 + } +} + +fn main() -> Result<()> { + ensure!("..."); + + let mut s = Bool(true); + match &mut s { + Bool(cond) => ensure!(cond), + } + + let db = DerefBool(true); + ensure!(db); + ensure!(&db); + + let nb = NotBool(true); + ensure!(nb); + + Ok(()) +} diff --git a/vendor/anyhow/tests/ui/ensure-nonbool.stderr b/vendor/anyhow/tests/ui/ensure-nonbool.stderr new file mode 100644 index 0000000..3fdb8e6 --- /dev/null +++ b/vendor/anyhow/tests/ui/ensure-nonbool.stderr @@ -0,0 +1,91 @@ +error[E0277]: the trait bound `&str: __private::not::Bool` is not satisfied + --> tests/ui/ensure-nonbool.rs:25:13 + | +25 | ensure!("..."); + | --------^^^^^- + | | | + | | the trait `__private::not::Bool` is not implemented for `&str` + | required by a bound introduced by this call + | + = help: the following other types implement trait `__private::not::Bool`: + &bool + bool +note: required by a bound in `anyhow::__private::not` + --> src/lib.rs + | + | pub fn not(cond: impl Bool) -> bool { + | ^^^^ required by this bound in `not` + +error[E0277]: the trait bound `&mut bool: __private::not::Bool` is not satisfied + --> tests/ui/ensure-nonbool.rs:29:31 + | +29 | Bool(cond) => ensure!(cond), + | --------^^^^- + | | | + | | the trait `__private::not::Bool` is not implemented for `&mut bool` + | required by a bound introduced by this call + | + = help: the following other types implement trait `__private::not::Bool`: + &bool + bool + = note: `__private::not::Bool` is implemented for `&bool`, but not for `&mut bool` +note: required by a bound in `anyhow::__private::not` + --> src/lib.rs + | + | pub fn not(cond: impl Bool) -> bool { + | ^^^^ required by this bound in `not` + +error[E0277]: the trait bound `DerefBool: __private::not::Bool` is not satisfied + --> tests/ui/ensure-nonbool.rs:33:13 + | +33 | ensure!(db); + | --------^^- + | | | + | | the trait `__private::not::Bool` is not implemented for `DerefBool` + | required by a bound introduced by this call + | + = help: the following other types implement trait `__private::not::Bool`: + &bool + bool +note: required by a bound in `anyhow::__private::not` + --> src/lib.rs + | + | pub fn not(cond: impl Bool) -> bool { + | ^^^^ required by this bound in `not` + +error[E0277]: the trait bound `&DerefBool: __private::not::Bool` is not satisfied + --> tests/ui/ensure-nonbool.rs:34:13 + | +34 | ensure!(&db); + | --------^^^- + | | | + | | the trait `__private::not::Bool` is not implemented for `&DerefBool` + | required by a bound introduced by this call + | +note: required by a bound in `anyhow::__private::not` + --> src/lib.rs + | + | pub fn not(cond: impl Bool) -> bool { + | ^^^^ required by this bound in `not` +help: consider dereferencing here + | +34 | ensure!(&*db); + | + + +error[E0277]: the trait bound `NotBool: __private::not::Bool` is not satisfied + --> tests/ui/ensure-nonbool.rs:37:13 + | +37 | ensure!(nb); + | --------^^- + | | | + | | the trait `__private::not::Bool` is not implemented for `NotBool` + | required by a bound introduced by this call + | + = help: the following other types implement trait `__private::not::Bool`: + &bool + bool +note: required by a bound in `anyhow::__private::not` + --> src/lib.rs + | + | pub fn not(cond: impl Bool) -> bool { + | ^^^^ required by this bound in `not` diff --git a/vendor/anyhow/tests/ui/must-use.rs b/vendor/anyhow/tests/ui/must-use.rs new file mode 100644 index 0000000..ea4e58f --- /dev/null +++ b/vendor/anyhow/tests/ui/must-use.rs @@ -0,0 +1,11 @@ +#![deny(unused_must_use)] + +use anyhow::anyhow; + +fn main() -> anyhow::Result<()> { + if true { + // meant to write bail! + anyhow!("it failed"); + } + Ok(()) +} diff --git a/vendor/anyhow/tests/ui/must-use.stderr b/vendor/anyhow/tests/ui/must-use.stderr new file mode 100644 index 0000000..e10bde4 --- /dev/null +++ b/vendor/anyhow/tests/ui/must-use.stderr @@ -0,0 +1,12 @@ +error: unused return value of `anyhow::__private::must_use` that must be used + --> tests/ui/must-use.rs:8:9 + | +8 | anyhow!("it failed"); + | ^^^^^^^^^^^^^^^^^^^^ + | +note: the lint level is defined here + --> tests/ui/must-use.rs:1:9 + | +1 | #![deny(unused_must_use)] + | ^^^^^^^^^^^^^^^ + = note: this error originates in the macro `anyhow` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/vendor/anyhow/tests/ui/no-impl.rs b/vendor/anyhow/tests/ui/no-impl.rs new file mode 100644 index 0000000..d2e89af --- /dev/null +++ b/vendor/anyhow/tests/ui/no-impl.rs @@ -0,0 +1,8 @@ +use anyhow::anyhow; + +#[derive(Debug)] +struct Error; + +fn main() { + let _ = anyhow!(Error); +} diff --git a/vendor/anyhow/tests/ui/no-impl.stderr b/vendor/anyhow/tests/ui/no-impl.stderr new file mode 100644 index 0000000..e06d70b --- /dev/null +++ b/vendor/anyhow/tests/ui/no-impl.stderr @@ -0,0 +1,32 @@ +error[E0599]: the method `anyhow_kind` exists for reference `&Error`, but its trait bounds were not satisfied + --> tests/ui/no-impl.rs:7:13 + | +4 | struct Error; + | ------------ doesn't satisfy `Error: Into`, `Error: anyhow::kind::TraitKind` or `Error: std::fmt::Display` +... +7 | let _ = anyhow!(Error); + | ^^^^^^^^^^^^^^ method cannot be called on `&Error` due to unsatisfied trait bounds + | + = note: the following trait bounds were not satisfied: + `Error: Into` + which is required by `Error: anyhow::kind::TraitKind` + `Error: std::fmt::Display` + which is required by `&Error: anyhow::kind::AdhocKind` + `&Error: Into` + which is required by `&Error: anyhow::kind::TraitKind` +note: the traits `Into` and `std::fmt::Display` must be implemented + --> $RUST/core/src/fmt/mod.rs + | + | pub trait Display { + | ^^^^^^^^^^^^^^^^^ + | + ::: $RUST/core/src/convert/mod.rs + | + | pub trait Into: Sized { + | ^^^^^^^^^^^^^^^^^^^^^^^^ + = help: items from traits can only be used if the trait is implemented and in scope + = note: the following traits define an item `anyhow_kind`, perhaps you need to implement one of them: + candidate #1: `anyhow::kind::AdhocKind` + candidate #2: `anyhow::kind::BoxedKind` + candidate #3: `anyhow::kind::TraitKind` + = note: this error originates in the macro `anyhow` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/vendor/anyhow/tests/ui/temporary-value.rs b/vendor/anyhow/tests/ui/temporary-value.rs new file mode 100644 index 0000000..803809b --- /dev/null +++ b/vendor/anyhow/tests/ui/temporary-value.rs @@ -0,0 +1,5 @@ +use anyhow::anyhow; + +fn main() { + let _ = anyhow!(&String::new()); +} diff --git a/vendor/anyhow/tests/ui/temporary-value.stderr b/vendor/anyhow/tests/ui/temporary-value.stderr new file mode 100644 index 0000000..dc27c49 --- /dev/null +++ b/vendor/anyhow/tests/ui/temporary-value.stderr @@ -0,0 +1,9 @@ +error[E0716]: temporary value dropped while borrowed + --> tests/ui/temporary-value.rs:4:22 + | +4 | let _ = anyhow!(&String::new()); + | ---------^^^^^^^^^^^^^- + | | | + | | creates a temporary value which is freed while still in use + | temporary value is freed at the end of this statement + | argument requires that borrow lasts for `'static` diff --git a/vendor/anyhow/tests/ui/wrong-interpolation.rs b/vendor/anyhow/tests/ui/wrong-interpolation.rs new file mode 100644 index 0000000..b870ca7 --- /dev/null +++ b/vendor/anyhow/tests/ui/wrong-interpolation.rs @@ -0,0 +1,5 @@ +use anyhow::{bail, Result}; + +fn main() -> Result<()> { + bail!("{} not found"); +} diff --git a/vendor/anyhow/tests/ui/wrong-interpolation.stderr b/vendor/anyhow/tests/ui/wrong-interpolation.stderr new file mode 100644 index 0000000..55a2964 --- /dev/null +++ b/vendor/anyhow/tests/ui/wrong-interpolation.stderr @@ -0,0 +1,5 @@ +error: 1 positional argument in format string, but no arguments were given + --> tests/ui/wrong-interpolation.rs:4:12 + | +4 | bail!("{} not found"); + | ^^ diff --git a/vendor/base64/.cargo-checksum.json b/vendor/base64/.cargo-checksum.json new file mode 100644 index 0000000..7411418 --- /dev/null +++ b/vendor/base64/.cargo-checksum.json @@ -0,0 +1 @@ +{"files":{"Cargo.lock":"cee37732975a1ffc1f956d3d05b6edf1baec72841cfabc384a21b02b3bfa0275","Cargo.toml":"52bee6a418e14918d37058fd15fccfd0f417a06fe4f9668b6f97866bf7f991e3","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"0dd882e53de11566d50f8e8e2d5a651bcf3fabee4987d70f306233cf39094ba7","README.md":"df01f5b4317d601e7de86743f9818aec9196abf9e298f5e47679b7a966ecd945","RELEASE-NOTES.md":"997a5193317a8bff266ecfe4f015ba070b782b6df7d3a1738b9b52584d57f9c6","benches/benchmarks.rs":"cebbcc8649e760e569c6be04f5e727aee2c2568ced7faab580fc0aa0d0426d26","clippy.toml":"b26be4d15ed059985ce6994f11817fd7562046f46e460a0dc64dbb71cfc246d1","examples/base64.rs":"b75ead2199a9b4389c69fe6f1ae988176a263b8fc84e7a4fea1d7e5a41592078","icon_CLion.svg":"cffa044ba75cb998ee3306991dc4a3755ec2f39ab95ddd4b74bc21988389020f","src/alphabet.rs":"5de2beb8fcccb078c61cac2c0477ebbde145122d6c10a0f7ea2e57e8159318e0","src/chunked_encoder.rs":"edfdbb9a4329b80fb2c769ada81e234e00839e0fa85faaa70bacf40ce12e951c","src/decode.rs":"b046a72d62eaac58dc42efcf7848d9d96d022f6594e851cf87074b77ce45c04a","src/display.rs":"31bf3e19274a0b80dd8948a81ea535944f756ef5b88736124c940f5fe1e8c71c","src/encode.rs":"44ddcc162f3fe9817b6e857dda0a3b9197b90a657e5f71c44aacabf5431ccf7d","src/engine/general_purpose/decode.rs":"d865b057e5788e7fefd189cf57ec913df263e6a0742dfa52513f587e14fa1a92","src/engine/general_purpose/decode_suffix.rs":"689688f7bf442b232d3b9f56a1b41c56d9393ace88556a165c224b93dd19b74e","src/engine/general_purpose/mod.rs":"901760a7f5721ec3bafad5fea6251f57de0f767ecb2e1e2fdfe64d661404ec34","src/engine/mod.rs":"5e4a6c0e86417f3b62350264ef383f91e9864390f7c315d786ecd8e9c920ee9f","src/engine/naive.rs":"70de29d909c3fe7918d2965782088b05047b8b6e30d1d2bf11ba073d3f8633ff","src/engine/tests.rs":"2cc8d1431f40f5b9c3ad8970e6fb73bba8be3f2317553dd026539f41908aaa19","src/lib.rs":"c4db7bd31ace78aec2ecd151cef3ad90dfdc76097ba12027bde79d3c82612f7c","src/prelude.rs":"c1587138e5301ac797c5c362cb3638649b33f79c20c16db6f38ad44330540752","src/read/decoder.rs":"00aaa0553a54fcf12762658c4e56663a9705cc30c07af30976291e6f69d78c3d","src/read/decoder_tests.rs":"66ec39bf6e86f21f4db1afd6c5cd63d4a4931ab896b9c38de25d99b803804bbf","src/read/mod.rs":"e0b714eda02d16b1ffa6f78fd09b2f963e01c881b1f7c17b39db4e904be5e746","src/tests.rs":"90cb9f8a1ccb7c4ddc4f8618208e0031fc97e0df0e5aa466d6a5cf45d25967d8","src/write/encoder.rs":"c889c853249220fe2ddaeb77ee6e2ee2945f7db88cd6658ef89ff71b81255ea8","src/write/encoder_string_writer.rs":"0326c9d120369b9bbc35697b5b9b141bed24283374c93d5af1052eb042e47799","src/write/encoder_tests.rs":"28695a485b17cf5db73656aae5d90127f726e02c6d70efd83e5ab53a4cc17b38","src/write/mod.rs":"73cd98dadc9d712b3fefd9449d97e825e097397441b90588e0051e4d3b0911b9","tests/encode.rs":"5309f4538b1df611436f7bfba7409c725161b6f841b1bbf8d9890ae185de7d88","tests/tests.rs":"78efcf0dc4bb6ae52f7a91fcad89e44e4dce578224c36b4e6c1c306459be8500"},"package":"72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6"} \ No newline at end of file diff --git a/vendor/base64/Cargo.toml b/vendor/base64/Cargo.toml new file mode 100644 index 0000000..e1b35fc --- /dev/null +++ b/vendor/base64/Cargo.toml @@ -0,0 +1,85 @@ +# 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] +edition = "2018" +rust-version = "1.48.0" +name = "base64" +version = "0.22.1" +authors = ["Marshall Pierce "] +description = "encodes and decodes base64 as bytes or utf8" +documentation = "https://docs.rs/base64" +readme = "README.md" +keywords = [ + "base64", + "utf8", + "encode", + "decode", + "no_std", +] +categories = ["encoding"] +license = "MIT OR Apache-2.0" +repository = "https://github.com/marshallpierce/rust-base64" + +[package.metadata.docs.rs] +rustdoc-args = ["--generate-link-to-definition"] + +[profile.bench] +debug = 2 + +[profile.test] +opt-level = 3 + +[[example]] +name = "base64" +required-features = ["std"] + +[[test]] +name = "tests" +required-features = ["alloc"] + +[[test]] +name = "encode" +required-features = ["alloc"] + +[[bench]] +name = "benchmarks" +harness = false +required-features = ["std"] + +[dev-dependencies.clap] +version = "3.2.25" +features = ["derive"] + +[dev-dependencies.criterion] +version = "0.4.0" + +[dev-dependencies.once_cell] +version = "1" + +[dev-dependencies.rand] +version = "0.8.5" +features = ["small_rng"] + +[dev-dependencies.rstest] +version = "0.13.0" + +[dev-dependencies.rstest_reuse] +version = "0.6.0" + +[dev-dependencies.strum] +version = "0.25" +features = ["derive"] + +[features] +alloc = [] +default = ["std"] +std = ["alloc"] diff --git a/vendor/base64/LICENSE-APACHE b/vendor/base64/LICENSE-APACHE new file mode 100644 index 0000000..16fe87b --- /dev/null +++ b/vendor/base64/LICENSE-APACHE @@ -0,0 +1,201 @@ + 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/base64/LICENSE-MIT b/vendor/base64/LICENSE-MIT new file mode 100644 index 0000000..7bc10f8 --- /dev/null +++ b/vendor/base64/LICENSE-MIT @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2015 Alice Maz + +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/base64/README.md b/vendor/base64/README.md new file mode 100644 index 0000000..f566756 --- /dev/null +++ b/vendor/base64/README.md @@ -0,0 +1,154 @@ +# [base64](https://crates.io/crates/base64) + +[![](https://img.shields.io/crates/v/base64.svg)](https://crates.io/crates/base64) [![Docs](https://docs.rs/base64/badge.svg)](https://docs.rs/base64) [![CircleCI](https://circleci.com/gh/marshallpierce/rust-base64/tree/master.svg?style=shield)](https://circleci.com/gh/marshallpierce/rust-base64/tree/master) [![codecov](https://codecov.io/gh/marshallpierce/rust-base64/branch/master/graph/badge.svg)](https://codecov.io/gh/marshallpierce/rust-base64) [![unsafe forbidden](https://img.shields.io/badge/unsafe-forbidden-success.svg)](https://github.com/rust-secure-code/safety-dance/) + + + +Made with CLion. Thanks to JetBrains for supporting open source! + +It's base64. What more could anyone want? + +This library's goals are to be *correct* and *fast*. It's thoroughly tested and widely used. It exposes functionality at +multiple levels of abstraction so you can choose the level of convenience vs performance that you want, +e.g. `decode_engine_slice` decodes into an existing `&mut [u8]` and is pretty fast (2.6GiB/s for a 3 KiB input), +whereas `decode_engine` allocates a new `Vec` and returns it, which might be more convenient in some cases, but is +slower (although still fast enough for almost any purpose) at 2.1 GiB/s. + +See the [docs](https://docs.rs/base64) for all the details. + +## FAQ + +### I need to decode base64 with whitespace/null bytes/other random things interspersed in it. What should I do? + +Remove non-base64 characters from your input before decoding. + +If you have a `Vec` of base64, [retain](https://doc.rust-lang.org/std/vec/struct.Vec.html#method.retain) can be used to +strip out whatever you need removed. + +If you have a `Read` (e.g. reading a file or network socket), there are various approaches. + +- Use [iter_read](https://crates.io/crates/iter-read) together with `Read`'s `bytes()` to filter out unwanted bytes. +- Implement `Read` with a `read()` impl that delegates to your actual `Read`, and then drops any bytes you don't want. + +### I need to line-wrap base64, e.g. for MIME/PEM. + +[line-wrap](https://crates.io/crates/line-wrap) does just that. + +### I want canonical base64 encoding/decoding. + +First, don't do this. You should no more expect Base64 to be canonical than you should expect compression algorithms to +produce canonical output across all usage in the wild (hint: they don't). +However, [people are drawn to their own destruction like moths to a flame](https://eprint.iacr.org/2022/361), so here we +are. + +There are two opportunities for non-canonical encoding (and thus, detection of the same during decoding): the final bits +of the last encoded token in two or three token suffixes, and the `=` token used to inflate the suffix to a full four +tokens. + +The trailing bits issue is unavoidable: with 6 bits available in each encoded token, 1 input byte takes 2 tokens, +with the second one having some bits unused. Same for two input bytes: 16 bits, but 3 tokens have 18 bits. Unless we +decide to stop shipping whole bytes around, we're stuck with those extra bits that a sneaky or buggy encoder might set +to 1 instead of 0. + +The `=` pad bytes, on the other hand, are entirely a self-own by the Base64 standard. They do not affect decoding other +than to provide an opportunity to say "that padding is incorrect". Exabytes of storage and transfer have no doubt been +wasted on pointless `=` bytes. Somehow we all seem to be quite comfortable with, say, hex-encoded data just stopping +when it's done rather than requiring a confirmation that the author of the encoder could count to four. Anyway, there +are two ways to make pad bytes predictable: require canonical padding to the next multiple of four bytes as per the RFC, +or, if you control all producers and consumers, save a few bytes by requiring no padding (especially applicable to the +url-safe alphabet). + +All `Engine` implementations must at a minimum support treating non-canonical padding of both types as an error, and +optionally may allow other behaviors. + +## Rust version compatibility + +The minimum supported Rust version is 1.48.0. + +# Contributing + +Contributions are very welcome. However, because this library is used widely, and in security-sensitive contexts, all +PRs will be carefully scrutinized. Beyond that, this sort of low level library simply needs to be 100% correct. Nobody +wants to chase bugs in encoding of any sort. + +All this means that it takes me a fair amount of time to review each PR, so it might take quite a while to carve out the +free time to give each PR the attention it deserves. I will get to everyone eventually! + +## Developing + +Benchmarks are in `benches/`. + +```bash +cargo bench +``` + +## no_std + +This crate supports no_std. By default the crate targets std via the `std` feature. You can deactivate +the `default-features` to target `core` instead. In that case you lose out on all the functionality revolving +around `std::io`, `std::error::Error`, and heap allocations. There is an additional `alloc` feature that you can activate +to bring back the support for heap allocations. + +## Profiling + +On Linux, you can use [perf](https://perf.wiki.kernel.org/index.php/Main_Page) for profiling. Then compile the +benchmarks with `cargo bench --no-run`. + +Run the benchmark binary with `perf` (shown here filtering to one particular benchmark, which will make the results +easier to read). `perf` is only available to the root user on most systems as it fiddles with event counters in your +CPU, so use `sudo`. We need to run the actual benchmark binary, hence the path into `target`. You can see the actual +full path with `cargo bench -v`; it will print out the commands it runs. If you use the exact path +that `bench` outputs, make sure you get the one that's for the benchmarks, not the tests. You may also want +to `cargo clean` so you have only one `benchmarks-` binary (they tend to accumulate). + +```bash +sudo perf record target/release/deps/benchmarks-* --bench decode_10mib_reuse +``` + +Then analyze the results, again with perf: + +```bash +sudo perf annotate -l +``` + +You'll see a bunch of interleaved rust source and assembly like this. The section with `lib.rs:327` is telling us that +4.02% of samples saw the `movzbl` aka bit shift as the active instruction. However, this percentage is not as exact as +it seems due to a phenomenon called *skid*. Basically, a consequence of how fancy modern CPUs are is that this sort of +instruction profiling is inherently inaccurate, especially in branch-heavy code. + +```text + lib.rs:322 0.70 : 10698: mov %rdi,%rax + 2.82 : 1069b: shr $0x38,%rax + : if morsel == decode_tables::INVALID_VALUE { + : bad_byte_index = input_index; + : break; + : }; + : accum = (morsel as u64) << 58; + lib.rs:327 4.02 : 1069f: movzbl (%r9,%rax,1),%r15d + : // fast loop of 8 bytes at a time + : while input_index < length_of_full_chunks { + : let mut accum: u64; + : + : let input_chunk = BigEndian::read_u64(&input_bytes[input_index..(input_index + 8)]); + : morsel = decode_table[(input_chunk >> 56) as usize]; + lib.rs:322 3.68 : 106a4: cmp $0xff,%r15 + : if morsel == decode_tables::INVALID_VALUE { + 0.00 : 106ab: je 1090e +``` + +## Fuzzing + +This uses [cargo-fuzz](https://github.com/rust-fuzz/cargo-fuzz). See `fuzz/fuzzers` for the available fuzzing scripts. +To run, use an invocation like these: + +```bash +cargo +nightly fuzz run roundtrip +cargo +nightly fuzz run roundtrip_no_pad +cargo +nightly fuzz run roundtrip_random_config -- -max_len=10240 +cargo +nightly fuzz run decode_random +``` + +## License + +This project is dual-licensed under MIT and Apache 2.0. + diff --git a/vendor/base64/RELEASE-NOTES.md b/vendor/base64/RELEASE-NOTES.md new file mode 100644 index 0000000..91b68a6 --- /dev/null +++ b/vendor/base64/RELEASE-NOTES.md @@ -0,0 +1,271 @@ +# 0.22.1 + +- Correct the symbols used for the predefined `alphabet::BIN_HEX`. + +# 0.22.0 + +- `DecodeSliceError::OutputSliceTooSmall` is now conservative rather than precise. That is, the error will only occur if the decoded output _cannot_ fit, meaning that `Engine::decode_slice` can now be used with exactly-sized output slices. As part of this, `Engine::internal_decode` now returns `DecodeSliceError` instead of `DecodeError`, but that is not expected to affect any external callers. +- `DecodeError::InvalidLength` now refers specifically to the _number of valid symbols_ being invalid (i.e. `len % 4 == 1`), rather than just the number of input bytes. This avoids confusing scenarios when based on interpretation you could make a case for either `InvalidLength` or `InvalidByte` being appropriate. +- Decoding is somewhat faster (5-10%) + +# 0.21.7 + +- Support getting an alphabet's contents as a str via `Alphabet::as_str()` + +# 0.21.6 + +- Improved introductory documentation and example + +# 0.21.5 + +- Add `Debug` and `Clone` impls for the general purpose Engine + +# 0.21.4 + +- Make `encoded_len` `const`, allowing the creation of arrays sized to encode compile-time-known data lengths + +# 0.21.3 + +- Implement `source` instead of `cause` on Error types +- Roll back MSRV to 1.48.0 so Debian can continue to live in a time warp +- Slightly faster chunked encoding for short inputs +- Decrease binary size + +# 0.21.2 + +- Rollback MSRV to 1.57.0 -- only dev dependencies need 1.60, not the main code + +# 0.21.1 + +- Remove the possibility of panicking during decoded length calculations +- `DecoderReader` no longer sometimes erroneously ignores + padding [#226](https://github.com/marshallpierce/rust-base64/issues/226) + +## Breaking changes + +- `Engine.internal_decode` return type changed +- Update MSRV to 1.60.0 + +# 0.21.0 + +## Migration + +### Functions + +| < 0.20 function | 0.21 equivalent | +|-------------------------|-------------------------------------------------------------------------------------| +| `encode()` | `engine::general_purpose::STANDARD.encode()` or `prelude::BASE64_STANDARD.encode()` | +| `encode_config()` | `engine.encode()` | +| `encode_config_buf()` | `engine.encode_string()` | +| `encode_config_slice()` | `engine.encode_slice()` | +| `decode()` | `engine::general_purpose::STANDARD.decode()` or `prelude::BASE64_STANDARD.decode()` | +| `decode_config()` | `engine.decode()` | +| `decode_config_buf()` | `engine.decode_vec()` | +| `decode_config_slice()` | `engine.decode_slice()` | + +The short-lived 0.20 functions were the 0.13 functions with `config` replaced with `engine`. + +### Padding + +If applicable, use the preset engines `engine::STANDARD`, `engine::STANDARD_NO_PAD`, `engine::URL_SAFE`, +or `engine::URL_SAFE_NO_PAD`. +The `NO_PAD` ones require that padding is absent when decoding, and the others require that +canonical padding is present . + +If you need the < 0.20 behavior that did not care about padding, or want to recreate < 0.20.0's predefined `Config`s +precisely, see the following table. + +| 0.13.1 Config | 0.20.0+ alphabet | `encode_padding` | `decode_padding_mode` | +|-----------------|------------------|------------------|-----------------------| +| STANDARD | STANDARD | true | Indifferent | +| STANDARD_NO_PAD | STANDARD | false | Indifferent | +| URL_SAFE | URL_SAFE | true | Indifferent | +| URL_SAFE_NO_PAD | URL_SAFE | false | Indifferent | + +# 0.21.0-rc.1 + +- Restore the ability to decode into a slice of precisely the correct length with `Engine.decode_slice_unchecked`. +- Add `Engine` as a `pub use` in `prelude`. + +# 0.21.0-beta.2 + +## Breaking changes + +- Re-exports of preconfigured engines in `engine` are removed in favor of `base64::prelude::...` that are better suited + to those who wish to `use` the entire path to a name. + +# 0.21.0-beta.1 + +## Breaking changes + +- `FastPortable` was only meant to be an interim name, and shouldn't have shipped in 0.20. It is now `GeneralPurpose` to + make its intended usage more clear. +- `GeneralPurpose` and its config are now `pub use`'d in the `engine` module for convenience. +- Change a few `from()` functions to be `new()`. `from()` causes confusing compiler errors because of confusion + with `From::from`, and is a little misleading because some of those invocations are not very cheap as one would + usually expect from a `from` call. +- `encode*` and `decode*` top level functions are now methods on `Engine`. +- `DEFAULT_ENGINE` was replaced by `engine::general_purpose::STANDARD` +- Predefined engine consts `engine::general_purpose::{STANDARD, STANDARD_NO_PAD, URL_SAFE, URL_SAFE_NO_PAD}` + - These are `pub use`d into `engine` as well +- The `*_slice` decode/encode functions now return an error instead of panicking when the output slice is too small + - As part of this, there isn't now a public way to decode into a slice _exactly_ the size needed for inputs that + aren't multiples of 4 tokens. If adding up to 2 bytes to always be a multiple of 3 bytes for the decode buffer is + a problem, file an issue. + +## Other changes + +- `decoded_len_estimate()` is provided to make it easy to size decode buffers correctly. + +# 0.20.0 + +## Breaking changes + +- Update MSRV to 1.57.0 +- Decoding can now either ignore padding, require correct padding, or require no padding. The default is to require + correct padding. + - The `NO_PAD` config now requires that padding be absent when decoding. + +## 0.20.0-alpha.1 + +### Breaking changes + +- Extended the `Config` concept into the `Engine` abstraction, allowing the user to pick different encoding / decoding + implementations. + - What was formerly the only algorithm is now the `FastPortable` engine, so named because it's portable (works on + any CPU) and relatively fast. + - This opens the door to a portable constant-time + implementation ([#153](https://github.com/marshallpierce/rust-base64/pull/153), + presumably `ConstantTimePortable`?) for security-sensitive applications that need side-channel resistance, and + CPU-specific SIMD implementations for more speed. + - Standard base64 per the RFC is available via `DEFAULT_ENGINE`. To use different alphabets or other settings ( + padding, etc), create your own engine instance. +- `CharacterSet` is now `Alphabet` (per the RFC), and allows creating custom alphabets. The corresponding tables that + were previously code-generated are now built dynamically. +- Since there are already multiple breaking changes, various functions are renamed to be more consistent and + discoverable. +- MSRV is now 1.47.0 to allow various things to use `const fn`. +- `DecoderReader` now owns its inner reader, and can expose it via `into_inner()`. For symmetry, `EncoderWriter` can do + the same with its writer. +- `encoded_len` is now public so you can size encode buffers precisely. + +# 0.13.1 + +- More precise decode buffer sizing, avoiding unnecessary allocation in `decode_config`. + +# 0.13.0 + +- Config methods are const +- Added `EncoderStringWriter` to allow encoding directly to a String +- `EncoderWriter` now owns its delegate writer rather than keeping a reference to it (though refs still work) + - As a consequence, it is now possible to extract the delegate writer from an `EncoderWriter` via `finish()`, which + returns `Result` instead of `Result<()>`. If you were calling `finish()` explicitly, you will now need to + use `let _ = foo.finish()` instead of just `foo.finish()` to avoid a warning about the unused value. +- When decoding input that has both an invalid length and an invalid symbol as the last byte, `InvalidByte` will be + emitted instead of `InvalidLength` to make the problem more obvious. + +# 0.12.2 + +- Add `BinHex` alphabet + +# 0.12.1 + +- Add `Bcrypt` alphabet + +# 0.12.0 + +- A `Read` implementation (`DecoderReader`) to let users transparently decoded data from a b64 input source +- IMAP's modified b64 alphabet +- Relaxed type restrictions to just `AsRef<[ut8]>` for main `encode*`/`decode*` functions +- A minor performance improvement in encoding + +# 0.11.0 + +- Minimum rust version 1.34.0 +- `no_std` is now supported via the two new features `alloc` and `std`. + +# 0.10.1 + +- Minimum rust version 1.27.2 +- Fix bug in streaming encoding ([#90](https://github.com/marshallpierce/rust-base64/pull/90)): if the underlying writer + didn't write all the bytes given to it, the remaining bytes would not be retried later. See the docs + on `EncoderWriter::write`. +- Make it configurable whether or not to return an error when decoding detects excess trailing bits. + +# 0.10.0 + +- Remove line wrapping. Line wrapping was never a great conceptual fit in this library, and other features (streaming + encoding, etc) either couldn't support it or could support only special cases of it with a great increase in + complexity. Line wrapping has been pulled out into a [line-wrap](https://crates.io/crates/line-wrap) crate, so it's + still available if you need it. + - `Base64Display` creation no longer uses a `Result` because it can't fail, which means its helper methods for + common + configs that `unwrap()` for you are no longer needed +- Add a streaming encoder `Write` impl to transparently base64 as you write. +- Remove the remaining `unsafe` code. +- Remove whitespace stripping to simplify `no_std` support. No out of the box configs use it, and it's trivial to do + yourself if needed: `filter(|b| !b" \n\t\r\x0b\x0c".contains(b)`. +- Detect invalid trailing symbols when decoding and return an error rather than silently ignoring them. + +# 0.9.3 + +- Update safemem + +# 0.9.2 + +- Derive `Clone` for `DecodeError`. + +# 0.9.1 + +- Add support for `crypt(3)`'s base64 variant. + +# 0.9.0 + +- `decode_config_slice` function for no-allocation decoding, analogous to `encode_config_slice` +- Decode performance optimization + +# 0.8.0 + +- `encode_config_slice` function for no-allocation encoding + +# 0.7.0 + +- `STANDARD_NO_PAD` config +- `Base64Display` heap-free wrapper for use in format strings, etc + +# 0.6.0 + +- Decode performance improvements +- Use `unsafe` in fewer places +- Added fuzzers + +# 0.5.2 + +- Avoid usize overflow when calculating length +- Better line wrapping performance + +# 0.5.1 + +- Temporarily disable line wrapping +- Add Apache 2.0 license + +# 0.5.0 + +- MIME support, including configurable line endings and line wrapping +- Removed `decode_ws` +- Renamed `Base64Error` to `DecodeError` + +# 0.4.1 + +- Allow decoding a `AsRef<[u8]>` instead of just a `&str` + +# 0.4.0 + +- Configurable padding +- Encode performance improvements + +# 0.3.0 + +- Added encode/decode functions that do not allocate their own storage +- Decode performance improvements +- Extraneous padding bytes are no longer ignored. Now, an error will be returned. diff --git a/vendor/base64/benches/benchmarks.rs b/vendor/base64/benches/benchmarks.rs new file mode 100644 index 0000000..8f04185 --- /dev/null +++ b/vendor/base64/benches/benchmarks.rs @@ -0,0 +1,238 @@ +#[macro_use] +extern crate criterion; + +use base64::{ + display, + engine::{general_purpose::STANDARD, Engine}, + write, +}; +use criterion::{black_box, Bencher, BenchmarkId, Criterion, Throughput}; +use rand::{Rng, SeedableRng}; +use std::io::{self, Read, Write}; + +fn do_decode_bench(b: &mut Bencher, &size: &usize) { + let mut v: Vec = Vec::with_capacity(size * 3 / 4); + fill(&mut v); + let encoded = STANDARD.encode(&v); + + b.iter(|| { + let orig = STANDARD.decode(&encoded); + black_box(&orig); + }); +} + +fn do_decode_bench_reuse_buf(b: &mut Bencher, &size: &usize) { + let mut v: Vec = Vec::with_capacity(size * 3 / 4); + fill(&mut v); + let encoded = STANDARD.encode(&v); + + let mut buf = Vec::new(); + b.iter(|| { + STANDARD.decode_vec(&encoded, &mut buf).unwrap(); + black_box(&buf); + buf.clear(); + }); +} + +fn do_decode_bench_slice(b: &mut Bencher, &size: &usize) { + let mut v: Vec = Vec::with_capacity(size * 3 / 4); + fill(&mut v); + let encoded = STANDARD.encode(&v); + + let mut buf = vec![0; size]; + b.iter(|| { + STANDARD.decode_slice(&encoded, &mut buf).unwrap(); + black_box(&buf); + }); +} + +fn do_decode_bench_stream(b: &mut Bencher, &size: &usize) { + let mut v: Vec = Vec::with_capacity(size * 3 / 4); + fill(&mut v); + let encoded = STANDARD.encode(&v); + + let mut buf = vec![0; size]; + buf.truncate(0); + + b.iter(|| { + let mut cursor = io::Cursor::new(&encoded[..]); + let mut decoder = base64::read::DecoderReader::new(&mut cursor, &STANDARD); + decoder.read_to_end(&mut buf).unwrap(); + buf.clear(); + black_box(&buf); + }); +} + +fn do_encode_bench(b: &mut Bencher, &size: &usize) { + let mut v: Vec = Vec::with_capacity(size); + fill(&mut v); + b.iter(|| { + let e = STANDARD.encode(&v); + black_box(&e); + }); +} + +fn do_encode_bench_display(b: &mut Bencher, &size: &usize) { + let mut v: Vec = Vec::with_capacity(size); + fill(&mut v); + b.iter(|| { + let e = format!("{}", display::Base64Display::new(&v, &STANDARD)); + black_box(&e); + }); +} + +fn do_encode_bench_reuse_buf(b: &mut Bencher, &size: &usize) { + let mut v: Vec = Vec::with_capacity(size); + fill(&mut v); + let mut buf = String::new(); + b.iter(|| { + STANDARD.encode_string(&v, &mut buf); + buf.clear(); + }); +} + +fn do_encode_bench_slice(b: &mut Bencher, &size: &usize) { + let mut v: Vec = Vec::with_capacity(size); + fill(&mut v); + // conservative estimate of encoded size + let mut buf = vec![0; v.len() * 2]; + b.iter(|| STANDARD.encode_slice(&v, &mut buf).unwrap()); +} + +fn do_encode_bench_stream(b: &mut Bencher, &size: &usize) { + let mut v: Vec = Vec::with_capacity(size); + fill(&mut v); + let mut buf = Vec::with_capacity(size * 2); + + b.iter(|| { + buf.clear(); + let mut stream_enc = write::EncoderWriter::new(&mut buf, &STANDARD); + stream_enc.write_all(&v).unwrap(); + stream_enc.flush().unwrap(); + }); +} + +fn do_encode_bench_string_stream(b: &mut Bencher, &size: &usize) { + let mut v: Vec = Vec::with_capacity(size); + fill(&mut v); + + b.iter(|| { + let mut stream_enc = write::EncoderStringWriter::new(&STANDARD); + stream_enc.write_all(&v).unwrap(); + stream_enc.flush().unwrap(); + let _ = stream_enc.into_inner(); + }); +} + +fn do_encode_bench_string_reuse_buf_stream(b: &mut Bencher, &size: &usize) { + let mut v: Vec = Vec::with_capacity(size); + fill(&mut v); + + let mut buf = String::new(); + b.iter(|| { + buf.clear(); + let mut stream_enc = write::EncoderStringWriter::from_consumer(&mut buf, &STANDARD); + stream_enc.write_all(&v).unwrap(); + stream_enc.flush().unwrap(); + let _ = stream_enc.into_inner(); + }); +} + +fn fill(v: &mut Vec) { + let cap = v.capacity(); + // weak randomness is plenty; we just want to not be completely friendly to the branch predictor + let mut r = rand::rngs::SmallRng::from_entropy(); + while v.len() < cap { + v.push(r.gen::()); + } +} + +const BYTE_SIZES: [usize; 5] = [3, 50, 100, 500, 3 * 1024]; + +// Benchmarks over these byte sizes take longer so we will run fewer samples to +// keep the benchmark runtime reasonable. +const LARGE_BYTE_SIZES: [usize; 3] = [3 * 1024 * 1024, 10 * 1024 * 1024, 30 * 1024 * 1024]; + +fn encode_benchmarks(c: &mut Criterion, label: &str, byte_sizes: &[usize]) { + let mut group = c.benchmark_group(label); + group + .warm_up_time(std::time::Duration::from_millis(500)) + .measurement_time(std::time::Duration::from_secs(3)); + + for size in byte_sizes { + group + .throughput(Throughput::Bytes(*size as u64)) + .bench_with_input(BenchmarkId::new("encode", size), size, do_encode_bench) + .bench_with_input( + BenchmarkId::new("encode_display", size), + size, + do_encode_bench_display, + ) + .bench_with_input( + BenchmarkId::new("encode_reuse_buf", size), + size, + do_encode_bench_reuse_buf, + ) + .bench_with_input( + BenchmarkId::new("encode_slice", size), + size, + do_encode_bench_slice, + ) + .bench_with_input( + BenchmarkId::new("encode_reuse_buf_stream", size), + size, + do_encode_bench_stream, + ) + .bench_with_input( + BenchmarkId::new("encode_string_stream", size), + size, + do_encode_bench_string_stream, + ) + .bench_with_input( + BenchmarkId::new("encode_string_reuse_buf_stream", size), + size, + do_encode_bench_string_reuse_buf_stream, + ); + } + + group.finish(); +} + +fn decode_benchmarks(c: &mut Criterion, label: &str, byte_sizes: &[usize]) { + let mut group = c.benchmark_group(label); + + for size in byte_sizes { + group + .warm_up_time(std::time::Duration::from_millis(500)) + .measurement_time(std::time::Duration::from_secs(3)) + .throughput(Throughput::Bytes(*size as u64)) + .bench_with_input(BenchmarkId::new("decode", size), size, do_decode_bench) + .bench_with_input( + BenchmarkId::new("decode_reuse_buf", size), + size, + do_decode_bench_reuse_buf, + ) + .bench_with_input( + BenchmarkId::new("decode_slice", size), + size, + do_decode_bench_slice, + ) + .bench_with_input( + BenchmarkId::new("decode_stream", size), + size, + do_decode_bench_stream, + ); + } + + group.finish(); +} + +fn bench(c: &mut Criterion) { + encode_benchmarks(c, "encode_small_input", &BYTE_SIZES[..]); + encode_benchmarks(c, "encode_large_input", &LARGE_BYTE_SIZES[..]); + decode_benchmarks(c, "decode_small_input", &BYTE_SIZES[..]); + decode_benchmarks(c, "decode_large_input", &LARGE_BYTE_SIZES[..]); +} + +criterion_group!(benches, bench); +criterion_main!(benches); diff --git a/vendor/base64/clippy.toml b/vendor/base64/clippy.toml new file mode 100644 index 0000000..11d46a7 --- /dev/null +++ b/vendor/base64/clippy.toml @@ -0,0 +1 @@ +msrv = "1.48.0" diff --git a/vendor/base64/examples/base64.rs b/vendor/base64/examples/base64.rs new file mode 100644 index 0000000..0c8aa3f --- /dev/null +++ b/vendor/base64/examples/base64.rs @@ -0,0 +1,81 @@ +use std::fs::File; +use std::io::{self, Read}; +use std::path::PathBuf; +use std::process; + +use base64::{alphabet, engine, read, write}; +use clap::Parser; + +#[derive(Clone, Debug, Parser, strum::EnumString, Default)] +#[strum(serialize_all = "kebab-case")] +enum Alphabet { + #[default] + Standard, + UrlSafe, +} + +/// Base64 encode or decode FILE (or standard input), to standard output. +#[derive(Debug, Parser)] +struct Opt { + /// Decode the base64-encoded input (default: encode the input as base64). + #[structopt(short = 'd', long = "decode")] + decode: bool, + + /// The encoding alphabet: "standard" (default) or "url-safe". + #[structopt(long = "alphabet")] + alphabet: Option, + + /// Omit padding characters while encoding, and reject them while decoding. + #[structopt(short = 'p', long = "no-padding")] + no_padding: bool, + + /// The file to encode or decode. + #[structopt(name = "FILE", parse(from_os_str))] + file: Option, +} + +fn main() { + let opt = Opt::parse(); + let stdin; + let mut input: Box = match opt.file { + None => { + stdin = io::stdin(); + Box::new(stdin.lock()) + } + Some(ref f) if f.as_os_str() == "-" => { + stdin = io::stdin(); + Box::new(stdin.lock()) + } + Some(f) => Box::new(File::open(f).unwrap()), + }; + + let alphabet = opt.alphabet.unwrap_or_default(); + let engine = engine::GeneralPurpose::new( + &match alphabet { + Alphabet::Standard => alphabet::STANDARD, + Alphabet::UrlSafe => alphabet::URL_SAFE, + }, + match opt.no_padding { + true => engine::general_purpose::NO_PAD, + false => engine::general_purpose::PAD, + }, + ); + + let stdout = io::stdout(); + let mut stdout = stdout.lock(); + let r = if opt.decode { + let mut decoder = read::DecoderReader::new(&mut input, &engine); + io::copy(&mut decoder, &mut stdout) + } else { + let mut encoder = write::EncoderWriter::new(&mut stdout, &engine); + io::copy(&mut input, &mut encoder) + }; + if let Err(e) = r { + eprintln!( + "Base64 {} failed with {}", + if opt.decode { "decode" } else { "encode" }, + e + ); + process::exit(1); + } +} diff --git a/vendor/base64/icon_CLion.svg b/vendor/base64/icon_CLion.svg new file mode 100644 index 0000000..e9edb04 --- /dev/null +++ b/vendor/base64/icon_CLion.svg @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + + + + + + + icon_CLion + + + + + + + + + + + + + diff --git a/vendor/base64/src/alphabet.rs b/vendor/base64/src/alphabet.rs new file mode 100644 index 0000000..b07bfdf --- /dev/null +++ b/vendor/base64/src/alphabet.rs @@ -0,0 +1,285 @@ +//! Provides [Alphabet] and constants for alphabets commonly used in the wild. + +use crate::PAD_BYTE; +use core::{convert, fmt}; +#[cfg(any(feature = "std", test))] +use std::error; + +const ALPHABET_SIZE: usize = 64; + +/// An alphabet defines the 64 ASCII characters (symbols) used for base64. +/// +/// Common alphabets are provided as constants, and custom alphabets +/// can be made via `from_str` or the `TryFrom` implementation. +/// +/// # Examples +/// +/// Building and using a custom Alphabet: +/// +/// ``` +/// let custom = base64::alphabet::Alphabet::new("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/").unwrap(); +/// +/// let engine = base64::engine::GeneralPurpose::new( +/// &custom, +/// base64::engine::general_purpose::PAD); +/// ``` +/// +/// Building a const: +/// +/// ``` +/// use base64::alphabet::Alphabet; +/// +/// static CUSTOM: Alphabet = { +/// // Result::unwrap() isn't const yet, but panic!() is OK +/// match Alphabet::new("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/") { +/// Ok(x) => x, +/// Err(_) => panic!("creation of alphabet failed"), +/// } +/// }; +/// ``` +/// +/// Building lazily: +/// +/// ``` +/// use base64::{ +/// alphabet::Alphabet, +/// engine::{general_purpose::GeneralPurpose, GeneralPurposeConfig}, +/// }; +/// use once_cell::sync::Lazy; +/// +/// static CUSTOM: Lazy = Lazy::new(|| +/// Alphabet::new("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/").unwrap() +/// ); +/// ``` +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct Alphabet { + pub(crate) symbols: [u8; ALPHABET_SIZE], +} + +impl Alphabet { + /// Performs no checks so that it can be const. + /// Used only for known-valid strings. + const fn from_str_unchecked(alphabet: &str) -> Self { + let mut symbols = [0_u8; ALPHABET_SIZE]; + let source_bytes = alphabet.as_bytes(); + + // a way to copy that's allowed in const fn + let mut index = 0; + while index < ALPHABET_SIZE { + symbols[index] = source_bytes[index]; + index += 1; + } + + Self { symbols } + } + + /// Create an `Alphabet` from a string of 64 unique printable ASCII bytes. + /// + /// The `=` byte is not allowed as it is used for padding. + pub const fn new(alphabet: &str) -> Result { + let bytes = alphabet.as_bytes(); + if bytes.len() != ALPHABET_SIZE { + return Err(ParseAlphabetError::InvalidLength); + } + + { + let mut index = 0; + while index < ALPHABET_SIZE { + let byte = bytes[index]; + + // must be ascii printable. 127 (DEL) is commonly considered printable + // for some reason but clearly unsuitable for base64. + if !(byte >= 32_u8 && byte <= 126_u8) { + return Err(ParseAlphabetError::UnprintableByte(byte)); + } + // = is assumed to be padding, so cannot be used as a symbol + if byte == PAD_BYTE { + return Err(ParseAlphabetError::ReservedByte(byte)); + } + + // Check for duplicates while staying within what const allows. + // It's n^2, but only over 64 hot bytes, and only once, so it's likely in the single digit + // microsecond range. + + let mut probe_index = 0; + while probe_index < ALPHABET_SIZE { + if probe_index == index { + probe_index += 1; + continue; + } + + let probe_byte = bytes[probe_index]; + + if byte == probe_byte { + return Err(ParseAlphabetError::DuplicatedByte(byte)); + } + + probe_index += 1; + } + + index += 1; + } + } + + Ok(Self::from_str_unchecked(alphabet)) + } + + /// Create a `&str` from the symbols in the `Alphabet` + pub fn as_str(&self) -> &str { + core::str::from_utf8(&self.symbols).unwrap() + } +} + +impl convert::TryFrom<&str> for Alphabet { + type Error = ParseAlphabetError; + + fn try_from(value: &str) -> Result { + Self::new(value) + } +} + +/// Possible errors when constructing an [Alphabet] from a `str`. +#[derive(Debug, Eq, PartialEq)] +pub enum ParseAlphabetError { + /// Alphabets must be 64 ASCII bytes + InvalidLength, + /// All bytes must be unique + DuplicatedByte(u8), + /// All bytes must be printable (in the range `[32, 126]`). + UnprintableByte(u8), + /// `=` cannot be used + ReservedByte(u8), +} + +impl fmt::Display for ParseAlphabetError { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + Self::InvalidLength => write!(f, "Invalid length - must be 64 bytes"), + Self::DuplicatedByte(b) => write!(f, "Duplicated byte: {:#04x}", b), + Self::UnprintableByte(b) => write!(f, "Unprintable byte: {:#04x}", b), + Self::ReservedByte(b) => write!(f, "Reserved byte: {:#04x}", b), + } + } +} + +#[cfg(any(feature = "std", test))] +impl error::Error for ParseAlphabetError {} + +/// The standard alphabet (with `+` and `/`) specified in [RFC 4648][]. +/// +/// [RFC 4648]: https://datatracker.ietf.org/doc/html/rfc4648#section-4 +pub const STANDARD: Alphabet = Alphabet::from_str_unchecked( + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/", +); + +/// The URL-safe alphabet (with `-` and `_`) specified in [RFC 4648][]. +/// +/// [RFC 4648]: https://datatracker.ietf.org/doc/html/rfc4648#section-5 +pub const URL_SAFE: Alphabet = Alphabet::from_str_unchecked( + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_", +); + +/// The `crypt(3)` alphabet (with `.` and `/` as the _first_ two characters). +/// +/// Not standardized, but folk wisdom on the net asserts that this alphabet is what crypt uses. +pub const CRYPT: Alphabet = Alphabet::from_str_unchecked( + "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz", +); + +/// The bcrypt alphabet. +pub const BCRYPT: Alphabet = Alphabet::from_str_unchecked( + "./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", +); + +/// The alphabet used in IMAP-modified UTF-7 (with `+` and `,`). +/// +/// See [RFC 3501](https://tools.ietf.org/html/rfc3501#section-5.1.3) +pub const IMAP_MUTF7: Alphabet = Alphabet::from_str_unchecked( + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+,", +); + +/// The alphabet used in BinHex 4.0 files. +/// +/// See [BinHex 4.0 Definition](http://files.stairways.com/other/binhex-40-specs-info.txt) +pub const BIN_HEX: Alphabet = Alphabet::from_str_unchecked( + "!\"#$%&'()*+,-012345689@ABCDEFGHIJKLMNPQRSTUVXYZ[`abcdefhijklmpqr", +); + +#[cfg(test)] +mod tests { + use crate::alphabet::*; + use core::convert::TryFrom as _; + + #[test] + fn detects_duplicate_start() { + assert_eq!( + ParseAlphabetError::DuplicatedByte(b'A'), + Alphabet::new("AACDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/") + .unwrap_err() + ); + } + + #[test] + fn detects_duplicate_end() { + assert_eq!( + ParseAlphabetError::DuplicatedByte(b'/'), + Alphabet::new("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789//") + .unwrap_err() + ); + } + + #[test] + fn detects_duplicate_middle() { + assert_eq!( + ParseAlphabetError::DuplicatedByte(b'Z'), + Alphabet::new("ABCDEFGHIJKLMNOPQRSTUVWXYZZbcdefghijklmnopqrstuvwxyz0123456789+/") + .unwrap_err() + ); + } + + #[test] + fn detects_length() { + assert_eq!( + ParseAlphabetError::InvalidLength, + Alphabet::new( + "xxxxxxxxxABCDEFGHIJKLMNOPQRSTUVWXYZZbcdefghijklmnopqrstuvwxyz0123456789+/", + ) + .unwrap_err() + ); + } + + #[test] + fn detects_padding() { + assert_eq!( + ParseAlphabetError::ReservedByte(b'='), + Alphabet::new("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+=") + .unwrap_err() + ); + } + + #[test] + fn detects_unprintable() { + // form feed + assert_eq!( + ParseAlphabetError::UnprintableByte(0xc), + Alphabet::new("\x0cBCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/") + .unwrap_err() + ); + } + + #[test] + fn same_as_unchecked() { + assert_eq!( + STANDARD, + Alphabet::try_from("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/") + .unwrap() + ); + } + + #[test] + fn str_same_as_input() { + let alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + let a = Alphabet::try_from(alphabet).unwrap(); + assert_eq!(alphabet, a.as_str()) + } +} diff --git a/vendor/base64/src/chunked_encoder.rs b/vendor/base64/src/chunked_encoder.rs new file mode 100644 index 0000000..817b339 --- /dev/null +++ b/vendor/base64/src/chunked_encoder.rs @@ -0,0 +1,172 @@ +use crate::{ + encode::add_padding, + engine::{Config, Engine}, +}; +#[cfg(any(feature = "alloc", test))] +use alloc::string::String; +#[cfg(any(feature = "alloc", test))] +use core::str; + +/// The output mechanism for ChunkedEncoder's encoded bytes. +pub trait Sink { + type Error; + + /// Handle a chunk of encoded base64 data (as UTF-8 bytes) + fn write_encoded_bytes(&mut self, encoded: &[u8]) -> Result<(), Self::Error>; +} + +/// A base64 encoder that emits encoded bytes in chunks without heap allocation. +pub struct ChunkedEncoder<'e, E: Engine + ?Sized> { + engine: &'e E, +} + +impl<'e, E: Engine + ?Sized> ChunkedEncoder<'e, E> { + pub fn new(engine: &'e E) -> ChunkedEncoder<'e, E> { + ChunkedEncoder { engine } + } + + pub fn encode(&self, bytes: &[u8], sink: &mut S) -> Result<(), S::Error> { + const BUF_SIZE: usize = 1024; + const CHUNK_SIZE: usize = BUF_SIZE / 4 * 3; + + let mut buf = [0; BUF_SIZE]; + for chunk in bytes.chunks(CHUNK_SIZE) { + let mut len = self.engine.internal_encode(chunk, &mut buf); + if chunk.len() != CHUNK_SIZE && self.engine.config().encode_padding() { + // Final, potentially partial, chunk. + // Only need to consider if padding is needed on a partial chunk since full chunk + // is a multiple of 3, which therefore won't be padded. + // Pad output to multiple of four bytes if required by config. + len += add_padding(len, &mut buf[len..]); + } + sink.write_encoded_bytes(&buf[..len])?; + } + + Ok(()) + } +} + +// A really simple sink that just appends to a string +#[cfg(any(feature = "alloc", test))] +pub(crate) struct StringSink<'a> { + string: &'a mut String, +} + +#[cfg(any(feature = "alloc", test))] +impl<'a> StringSink<'a> { + pub(crate) fn new(s: &mut String) -> StringSink { + StringSink { string: s } + } +} + +#[cfg(any(feature = "alloc", test))] +impl<'a> Sink for StringSink<'a> { + type Error = (); + + fn write_encoded_bytes(&mut self, s: &[u8]) -> Result<(), Self::Error> { + self.string.push_str(str::from_utf8(s).unwrap()); + + Ok(()) + } +} + +#[cfg(test)] +pub mod tests { + use rand::{ + distributions::{Distribution, Uniform}, + Rng, SeedableRng, + }; + + use crate::{ + alphabet::STANDARD, + engine::general_purpose::{GeneralPurpose, GeneralPurposeConfig, PAD}, + tests::random_engine, + }; + + use super::*; + + #[test] + fn chunked_encode_empty() { + assert_eq!("", chunked_encode_str(&[], PAD)); + } + + #[test] + fn chunked_encode_intermediate_fast_loop() { + // > 8 bytes input, will enter the pretty fast loop + assert_eq!("Zm9vYmFyYmF6cXV4", chunked_encode_str(b"foobarbazqux", PAD)); + } + + #[test] + fn chunked_encode_fast_loop() { + // > 32 bytes input, will enter the uber fast loop + assert_eq!( + "Zm9vYmFyYmF6cXV4cXV1eGNvcmdlZ3JhdWx0Z2FycGx5eg==", + chunked_encode_str(b"foobarbazquxquuxcorgegraultgarplyz", PAD) + ); + } + + #[test] + fn chunked_encode_slow_loop_only() { + // < 8 bytes input, slow loop only + assert_eq!("Zm9vYmFy", chunked_encode_str(b"foobar", PAD)); + } + + #[test] + fn chunked_encode_matches_normal_encode_random_string_sink() { + let helper = StringSinkTestHelper; + chunked_encode_matches_normal_encode_random(&helper); + } + + pub fn chunked_encode_matches_normal_encode_random(sink_test_helper: &S) { + let mut input_buf: Vec = Vec::new(); + let mut output_buf = String::new(); + let mut rng = rand::rngs::SmallRng::from_entropy(); + let input_len_range = Uniform::new(1, 10_000); + + for _ in 0..20_000 { + input_buf.clear(); + output_buf.clear(); + + let buf_len = input_len_range.sample(&mut rng); + for _ in 0..buf_len { + input_buf.push(rng.gen()); + } + + let engine = random_engine(&mut rng); + + let chunk_encoded_string = sink_test_helper.encode_to_string(&engine, &input_buf); + engine.encode_string(&input_buf, &mut output_buf); + + assert_eq!(output_buf, chunk_encoded_string, "input len={}", buf_len); + } + } + + fn chunked_encode_str(bytes: &[u8], config: GeneralPurposeConfig) -> String { + let mut s = String::new(); + + let mut sink = StringSink::new(&mut s); + let engine = GeneralPurpose::new(&STANDARD, config); + let encoder = ChunkedEncoder::new(&engine); + encoder.encode(bytes, &mut sink).unwrap(); + + s + } + + // An abstraction around sinks so that we can have tests that easily to any sink implementation + pub trait SinkTestHelper { + fn encode_to_string(&self, engine: &E, bytes: &[u8]) -> String; + } + + struct StringSinkTestHelper; + + impl SinkTestHelper for StringSinkTestHelper { + fn encode_to_string(&self, engine: &E, bytes: &[u8]) -> String { + let encoder = ChunkedEncoder::new(engine); + let mut s = String::new(); + let mut sink = StringSink::new(&mut s); + encoder.encode(bytes, &mut sink).unwrap(); + + s + } + } +} diff --git a/vendor/base64/src/decode.rs b/vendor/base64/src/decode.rs new file mode 100644 index 0000000..6df8aba --- /dev/null +++ b/vendor/base64/src/decode.rs @@ -0,0 +1,386 @@ +use crate::engine::{general_purpose::STANDARD, DecodeEstimate, Engine}; +#[cfg(any(feature = "alloc", test))] +use alloc::vec::Vec; +use core::fmt; +#[cfg(any(feature = "std", test))] +use std::error; + +/// Errors that can occur while decoding. +#[derive(Clone, Debug, PartialEq, Eq)] +pub enum DecodeError { + /// An invalid byte was found in the input. The offset and offending byte are provided. + /// + /// Padding characters (`=`) interspersed in the encoded form are invalid, as they may only + /// be present as the last 0-2 bytes of input. + /// + /// This error may also indicate that extraneous trailing input bytes are present, causing + /// otherwise valid padding to no longer be the last bytes of input. + InvalidByte(usize, u8), + /// The length of the input, as measured in valid base64 symbols, is invalid. + /// There must be 2-4 symbols in the last input quad. + InvalidLength(usize), + /// The last non-padding input symbol's encoded 6 bits have nonzero bits that will be discarded. + /// This is indicative of corrupted or truncated Base64. + /// Unlike [DecodeError::InvalidByte], which reports symbols that aren't in the alphabet, + /// this error is for symbols that are in the alphabet but represent nonsensical encodings. + InvalidLastSymbol(usize, u8), + /// The nature of the padding was not as configured: absent or incorrect when it must be + /// canonical, or present when it must be absent, etc. + InvalidPadding, +} + +impl fmt::Display for DecodeError { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match *self { + Self::InvalidByte(index, byte) => { + write!(f, "Invalid symbol {}, offset {}.", byte, index) + } + Self::InvalidLength(len) => write!(f, "Invalid input length: {}", len), + Self::InvalidLastSymbol(index, byte) => { + write!(f, "Invalid last symbol {}, offset {}.", byte, index) + } + Self::InvalidPadding => write!(f, "Invalid padding"), + } + } +} + +#[cfg(any(feature = "std", test))] +impl error::Error for DecodeError {} + +/// Errors that can occur while decoding into a slice. +#[derive(Clone, Debug, PartialEq, Eq)] +pub enum DecodeSliceError { + /// A [DecodeError] occurred + DecodeError(DecodeError), + /// The provided slice is too small. + OutputSliceTooSmall, +} + +impl fmt::Display for DecodeSliceError { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + Self::DecodeError(e) => write!(f, "DecodeError: {}", e), + Self::OutputSliceTooSmall => write!(f, "Output slice too small"), + } + } +} + +#[cfg(any(feature = "std", test))] +impl error::Error for DecodeSliceError { + fn source(&self) -> Option<&(dyn error::Error + 'static)> { + match self { + DecodeSliceError::DecodeError(e) => Some(e), + DecodeSliceError::OutputSliceTooSmall => None, + } + } +} + +impl From for DecodeSliceError { + fn from(e: DecodeError) -> Self { + DecodeSliceError::DecodeError(e) + } +} + +/// Decode base64 using the [`STANDARD` engine](STANDARD). +/// +/// See [Engine::decode]. +#[deprecated(since = "0.21.0", note = "Use Engine::decode")] +#[cfg(any(feature = "alloc", test))] +pub fn decode>(input: T) -> Result, DecodeError> { + STANDARD.decode(input) +} + +/// Decode from string reference as octets using the specified [Engine]. +/// +/// See [Engine::decode]. +///Returns a `Result` containing a `Vec`. +#[deprecated(since = "0.21.0", note = "Use Engine::decode")] +#[cfg(any(feature = "alloc", test))] +pub fn decode_engine>( + input: T, + engine: &E, +) -> Result, DecodeError> { + engine.decode(input) +} + +/// Decode from string reference as octets. +/// +/// See [Engine::decode_vec]. +#[cfg(any(feature = "alloc", test))] +#[deprecated(since = "0.21.0", note = "Use Engine::decode_vec")] +pub fn decode_engine_vec>( + input: T, + buffer: &mut Vec, + engine: &E, +) -> Result<(), DecodeError> { + engine.decode_vec(input, buffer) +} + +/// Decode the input into the provided output slice. +/// +/// See [Engine::decode_slice]. +#[deprecated(since = "0.21.0", note = "Use Engine::decode_slice")] +pub fn decode_engine_slice>( + input: T, + output: &mut [u8], + engine: &E, +) -> Result { + engine.decode_slice(input, output) +} + +/// Returns a conservative estimate of the decoded size of `encoded_len` base64 symbols (rounded up +/// to the next group of 3 decoded bytes). +/// +/// The resulting length will be a safe choice for the size of a decode buffer, but may have up to +/// 2 trailing bytes that won't end up being needed. +/// +/// # Examples +/// +/// ``` +/// use base64::decoded_len_estimate; +/// +/// assert_eq!(3, decoded_len_estimate(1)); +/// assert_eq!(3, decoded_len_estimate(2)); +/// assert_eq!(3, decoded_len_estimate(3)); +/// assert_eq!(3, decoded_len_estimate(4)); +/// // start of the next quad of encoded symbols +/// assert_eq!(6, decoded_len_estimate(5)); +/// ``` +pub fn decoded_len_estimate(encoded_len: usize) -> usize { + STANDARD + .internal_decoded_len_estimate(encoded_len) + .decoded_len_estimate() +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::{ + alphabet, + engine::{general_purpose, Config, GeneralPurpose}, + tests::{assert_encode_sanity, random_engine}, + }; + use rand::{ + distributions::{Distribution, Uniform}, + Rng, SeedableRng, + }; + + #[test] + fn decode_into_nonempty_vec_doesnt_clobber_existing_prefix() { + let mut orig_data = Vec::new(); + let mut encoded_data = String::new(); + let mut decoded_with_prefix = Vec::new(); + let mut decoded_without_prefix = Vec::new(); + let mut prefix = Vec::new(); + + let prefix_len_range = Uniform::new(0, 1000); + let input_len_range = Uniform::new(0, 1000); + + let mut rng = rand::rngs::SmallRng::from_entropy(); + + for _ in 0..10_000 { + orig_data.clear(); + encoded_data.clear(); + decoded_with_prefix.clear(); + decoded_without_prefix.clear(); + prefix.clear(); + + let input_len = input_len_range.sample(&mut rng); + + for _ in 0..input_len { + orig_data.push(rng.gen()); + } + + let engine = random_engine(&mut rng); + engine.encode_string(&orig_data, &mut encoded_data); + assert_encode_sanity(&encoded_data, engine.config().encode_padding(), input_len); + + let prefix_len = prefix_len_range.sample(&mut rng); + + // fill the buf with a prefix + for _ in 0..prefix_len { + prefix.push(rng.gen()); + } + + decoded_with_prefix.resize(prefix_len, 0); + decoded_with_prefix.copy_from_slice(&prefix); + + // decode into the non-empty buf + engine + .decode_vec(&encoded_data, &mut decoded_with_prefix) + .unwrap(); + // also decode into the empty buf + engine + .decode_vec(&encoded_data, &mut decoded_without_prefix) + .unwrap(); + + assert_eq!( + prefix_len + decoded_without_prefix.len(), + decoded_with_prefix.len() + ); + assert_eq!(orig_data, decoded_without_prefix); + + // append plain decode onto prefix + prefix.append(&mut decoded_without_prefix); + + assert_eq!(prefix, decoded_with_prefix); + } + } + + #[test] + fn decode_slice_doesnt_clobber_existing_prefix_or_suffix() { + do_decode_slice_doesnt_clobber_existing_prefix_or_suffix(|e, input, output| { + e.decode_slice(input, output).unwrap() + }) + } + + #[test] + fn decode_slice_unchecked_doesnt_clobber_existing_prefix_or_suffix() { + do_decode_slice_doesnt_clobber_existing_prefix_or_suffix(|e, input, output| { + e.decode_slice_unchecked(input, output).unwrap() + }) + } + + #[test] + fn decode_engine_estimation_works_for_various_lengths() { + let engine = GeneralPurpose::new(&alphabet::STANDARD, general_purpose::NO_PAD); + for num_prefix_quads in 0..100 { + for suffix in &["AA", "AAA", "AAAA"] { + let mut prefix = "AAAA".repeat(num_prefix_quads); + prefix.push_str(suffix); + // make sure no overflow (and thus a panic) occurs + let res = engine.decode(prefix); + assert!(res.is_ok()); + } + } + } + + #[test] + fn decode_slice_output_length_errors() { + for num_quads in 1..100 { + let input = "AAAA".repeat(num_quads); + let mut vec = vec![0; (num_quads - 1) * 3]; + assert_eq!( + DecodeSliceError::OutputSliceTooSmall, + STANDARD.decode_slice(&input, &mut vec).unwrap_err() + ); + vec.push(0); + assert_eq!( + DecodeSliceError::OutputSliceTooSmall, + STANDARD.decode_slice(&input, &mut vec).unwrap_err() + ); + vec.push(0); + assert_eq!( + DecodeSliceError::OutputSliceTooSmall, + STANDARD.decode_slice(&input, &mut vec).unwrap_err() + ); + vec.push(0); + // now it works + assert_eq!( + num_quads * 3, + STANDARD.decode_slice(&input, &mut vec).unwrap() + ); + } + } + + fn do_decode_slice_doesnt_clobber_existing_prefix_or_suffix< + F: Fn(&GeneralPurpose, &[u8], &mut [u8]) -> usize, + >( + call_decode: F, + ) { + let mut orig_data = Vec::new(); + let mut encoded_data = String::new(); + let mut decode_buf = Vec::new(); + let mut decode_buf_copy: Vec = Vec::new(); + + let input_len_range = Uniform::new(0, 1000); + + let mut rng = rand::rngs::SmallRng::from_entropy(); + + for _ in 0..10_000 { + orig_data.clear(); + encoded_data.clear(); + decode_buf.clear(); + decode_buf_copy.clear(); + + let input_len = input_len_range.sample(&mut rng); + + for _ in 0..input_len { + orig_data.push(rng.gen()); + } + + let engine = random_engine(&mut rng); + engine.encode_string(&orig_data, &mut encoded_data); + assert_encode_sanity(&encoded_data, engine.config().encode_padding(), input_len); + + // fill the buffer with random garbage, long enough to have some room before and after + for _ in 0..5000 { + decode_buf.push(rng.gen()); + } + + // keep a copy for later comparison + decode_buf_copy.extend(decode_buf.iter()); + + let offset = 1000; + + // decode into the non-empty buf + let decode_bytes_written = + call_decode(&engine, encoded_data.as_bytes(), &mut decode_buf[offset..]); + + assert_eq!(orig_data.len(), decode_bytes_written); + assert_eq!( + orig_data, + &decode_buf[offset..(offset + decode_bytes_written)] + ); + assert_eq!(&decode_buf_copy[0..offset], &decode_buf[0..offset]); + assert_eq!( + &decode_buf_copy[offset + decode_bytes_written..], + &decode_buf[offset + decode_bytes_written..] + ); + } + } +} + +#[allow(deprecated)] +#[cfg(test)] +mod coverage_gaming { + use super::*; + use std::error::Error; + + #[test] + fn decode_error() { + let _ = format!("{:?}", DecodeError::InvalidPadding.clone()); + let _ = format!( + "{} {} {} {}", + DecodeError::InvalidByte(0, 0), + DecodeError::InvalidLength(0), + DecodeError::InvalidLastSymbol(0, 0), + DecodeError::InvalidPadding, + ); + } + + #[test] + fn decode_slice_error() { + let _ = format!("{:?}", DecodeSliceError::OutputSliceTooSmall.clone()); + let _ = format!( + "{} {}", + DecodeSliceError::OutputSliceTooSmall, + DecodeSliceError::DecodeError(DecodeError::InvalidPadding) + ); + let _ = DecodeSliceError::OutputSliceTooSmall.source(); + let _ = DecodeSliceError::DecodeError(DecodeError::InvalidPadding).source(); + } + + #[test] + fn deprecated_fns() { + let _ = decode(""); + let _ = decode_engine("", &crate::prelude::BASE64_STANDARD); + let _ = decode_engine_vec("", &mut Vec::new(), &crate::prelude::BASE64_STANDARD); + let _ = decode_engine_slice("", &mut [], &crate::prelude::BASE64_STANDARD); + } + + #[test] + fn decoded_len_est() { + assert_eq!(3, decoded_len_estimate(4)); + } +} diff --git a/vendor/base64/src/display.rs b/vendor/base64/src/display.rs new file mode 100644 index 0000000..fc292f1 --- /dev/null +++ b/vendor/base64/src/display.rs @@ -0,0 +1,88 @@ +//! Enables base64'd output anywhere you might use a `Display` implementation, like a format string. +//! +//! ``` +//! use base64::{display::Base64Display, engine::general_purpose::STANDARD}; +//! +//! let data = vec![0x0, 0x1, 0x2, 0x3]; +//! let wrapper = Base64Display::new(&data, &STANDARD); +//! +//! assert_eq!("base64: AAECAw==", format!("base64: {}", wrapper)); +//! ``` + +use super::chunked_encoder::ChunkedEncoder; +use crate::engine::Engine; +use core::fmt::{Display, Formatter}; +use core::{fmt, str}; + +/// A convenience wrapper for base64'ing bytes into a format string without heap allocation. +pub struct Base64Display<'a, 'e, E: Engine> { + bytes: &'a [u8], + chunked_encoder: ChunkedEncoder<'e, E>, +} + +impl<'a, 'e, E: Engine> Base64Display<'a, 'e, E> { + /// Create a `Base64Display` with the provided engine. + pub fn new(bytes: &'a [u8], engine: &'e E) -> Base64Display<'a, 'e, E> { + Base64Display { + bytes, + chunked_encoder: ChunkedEncoder::new(engine), + } + } +} + +impl<'a, 'e, E: Engine> Display for Base64Display<'a, 'e, E> { + fn fmt(&self, formatter: &mut Formatter) -> Result<(), fmt::Error> { + let mut sink = FormatterSink { f: formatter }; + self.chunked_encoder.encode(self.bytes, &mut sink) + } +} + +struct FormatterSink<'a, 'b: 'a> { + f: &'a mut Formatter<'b>, +} + +impl<'a, 'b: 'a> super::chunked_encoder::Sink for FormatterSink<'a, 'b> { + type Error = fmt::Error; + + fn write_encoded_bytes(&mut self, encoded: &[u8]) -> Result<(), Self::Error> { + // Avoid unsafe. If max performance is needed, write your own display wrapper that uses + // unsafe here to gain about 10-15%. + self.f + .write_str(str::from_utf8(encoded).expect("base64 data was not utf8")) + } +} + +#[cfg(test)] +mod tests { + use super::super::chunked_encoder::tests::{ + chunked_encode_matches_normal_encode_random, SinkTestHelper, + }; + use super::*; + use crate::engine::general_purpose::STANDARD; + + #[test] + fn basic_display() { + assert_eq!( + "~$Zm9vYmFy#*", + format!("~${}#*", Base64Display::new(b"foobar", &STANDARD)) + ); + assert_eq!( + "~$Zm9vYmFyZg==#*", + format!("~${}#*", Base64Display::new(b"foobarf", &STANDARD)) + ); + } + + #[test] + fn display_encode_matches_normal_encode() { + let helper = DisplaySinkTestHelper; + chunked_encode_matches_normal_encode_random(&helper); + } + + struct DisplaySinkTestHelper; + + impl SinkTestHelper for DisplaySinkTestHelper { + fn encode_to_string(&self, engine: &E, bytes: &[u8]) -> String { + format!("{}", Base64Display::new(bytes, engine)) + } + } +} diff --git a/vendor/base64/src/encode.rs b/vendor/base64/src/encode.rs new file mode 100644 index 0000000..ae6d790 --- /dev/null +++ b/vendor/base64/src/encode.rs @@ -0,0 +1,492 @@ +#[cfg(any(feature = "alloc", test))] +use alloc::string::String; +use core::fmt; +#[cfg(any(feature = "std", test))] +use std::error; + +#[cfg(any(feature = "alloc", test))] +use crate::engine::general_purpose::STANDARD; +use crate::engine::{Config, Engine}; +use crate::PAD_BYTE; + +/// Encode arbitrary octets as base64 using the [`STANDARD` engine](STANDARD). +/// +/// See [Engine::encode]. +#[allow(unused)] +#[deprecated(since = "0.21.0", note = "Use Engine::encode")] +#[cfg(any(feature = "alloc", test))] +pub fn encode>(input: T) -> String { + STANDARD.encode(input) +} + +///Encode arbitrary octets as base64 using the provided `Engine` into a new `String`. +/// +/// See [Engine::encode]. +#[allow(unused)] +#[deprecated(since = "0.21.0", note = "Use Engine::encode")] +#[cfg(any(feature = "alloc", test))] +pub fn encode_engine>(input: T, engine: &E) -> String { + engine.encode(input) +} + +///Encode arbitrary octets as base64 into a supplied `String`. +/// +/// See [Engine::encode_string]. +#[allow(unused)] +#[deprecated(since = "0.21.0", note = "Use Engine::encode_string")] +#[cfg(any(feature = "alloc", test))] +pub fn encode_engine_string>( + input: T, + output_buf: &mut String, + engine: &E, +) { + engine.encode_string(input, output_buf) +} + +/// Encode arbitrary octets as base64 into a supplied slice. +/// +/// See [Engine::encode_slice]. +#[allow(unused)] +#[deprecated(since = "0.21.0", note = "Use Engine::encode_slice")] +pub fn encode_engine_slice>( + input: T, + output_buf: &mut [u8], + engine: &E, +) -> Result { + engine.encode_slice(input, output_buf) +} + +/// B64-encode and pad (if configured). +/// +/// This helper exists to avoid recalculating encoded_size, which is relatively expensive on short +/// inputs. +/// +/// `encoded_size` is the encoded size calculated for `input`. +/// +/// `output` must be of size `encoded_size`. +/// +/// All bytes in `output` will be written to since it is exactly the size of the output. +pub(crate) fn encode_with_padding( + input: &[u8], + output: &mut [u8], + engine: &E, + expected_encoded_size: usize, +) { + debug_assert_eq!(expected_encoded_size, output.len()); + + let b64_bytes_written = engine.internal_encode(input, output); + + let padding_bytes = if engine.config().encode_padding() { + add_padding(b64_bytes_written, &mut output[b64_bytes_written..]) + } else { + 0 + }; + + let encoded_bytes = b64_bytes_written + .checked_add(padding_bytes) + .expect("usize overflow when calculating b64 length"); + + debug_assert_eq!(expected_encoded_size, encoded_bytes); +} + +/// Calculate the base64 encoded length for a given input length, optionally including any +/// appropriate padding bytes. +/// +/// Returns `None` if the encoded length can't be represented in `usize`. This will happen for +/// input lengths in approximately the top quarter of the range of `usize`. +pub const fn encoded_len(bytes_len: usize, padding: bool) -> Option { + let rem = bytes_len % 3; + + let complete_input_chunks = bytes_len / 3; + // `?` is disallowed in const, and `let Some(_) = _ else` requires 1.65.0, whereas this + // messier syntax works on 1.48 + let complete_chunk_output = + if let Some(complete_chunk_output) = complete_input_chunks.checked_mul(4) { + complete_chunk_output + } else { + return None; + }; + + if rem > 0 { + if padding { + complete_chunk_output.checked_add(4) + } else { + let encoded_rem = match rem { + 1 => 2, + // only other possible remainder is 2 + // can't use a separate _ => unreachable!() in const fns in ancient rust versions + _ => 3, + }; + complete_chunk_output.checked_add(encoded_rem) + } + } else { + Some(complete_chunk_output) + } +} + +/// Write padding characters. +/// `unpadded_output_len` is the size of the unpadded but base64 encoded data. +/// `output` is the slice where padding should be written, of length at least 2. +/// +/// Returns the number of padding bytes written. +pub(crate) fn add_padding(unpadded_output_len: usize, output: &mut [u8]) -> usize { + let pad_bytes = (4 - (unpadded_output_len % 4)) % 4; + // for just a couple bytes, this has better performance than using + // .fill(), or iterating over mutable refs, which call memset() + #[allow(clippy::needless_range_loop)] + for i in 0..pad_bytes { + output[i] = PAD_BYTE; + } + + pad_bytes +} + +/// Errors that can occur while encoding into a slice. +#[derive(Clone, Debug, PartialEq, Eq)] +pub enum EncodeSliceError { + /// The provided slice is too small. + OutputSliceTooSmall, +} + +impl fmt::Display for EncodeSliceError { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + Self::OutputSliceTooSmall => write!(f, "Output slice too small"), + } + } +} + +#[cfg(any(feature = "std", test))] +impl error::Error for EncodeSliceError {} + +#[cfg(test)] +mod tests { + use super::*; + + use crate::{ + alphabet, + engine::general_purpose::{GeneralPurpose, NO_PAD, STANDARD}, + tests::{assert_encode_sanity, random_config, random_engine}, + }; + use rand::{ + distributions::{Distribution, Uniform}, + Rng, SeedableRng, + }; + use std::str; + + const URL_SAFE_NO_PAD_ENGINE: GeneralPurpose = GeneralPurpose::new(&alphabet::URL_SAFE, NO_PAD); + + #[test] + fn encoded_size_correct_standard() { + assert_encoded_length(0, 0, &STANDARD, true); + + assert_encoded_length(1, 4, &STANDARD, true); + assert_encoded_length(2, 4, &STANDARD, true); + assert_encoded_length(3, 4, &STANDARD, true); + + assert_encoded_length(4, 8, &STANDARD, true); + assert_encoded_length(5, 8, &STANDARD, true); + assert_encoded_length(6, 8, &STANDARD, true); + + assert_encoded_length(7, 12, &STANDARD, true); + assert_encoded_length(8, 12, &STANDARD, true); + assert_encoded_length(9, 12, &STANDARD, true); + + assert_encoded_length(54, 72, &STANDARD, true); + + assert_encoded_length(55, 76, &STANDARD, true); + assert_encoded_length(56, 76, &STANDARD, true); + assert_encoded_length(57, 76, &STANDARD, true); + + assert_encoded_length(58, 80, &STANDARD, true); + } + + #[test] + fn encoded_size_correct_no_pad() { + assert_encoded_length(0, 0, &URL_SAFE_NO_PAD_ENGINE, false); + + assert_encoded_length(1, 2, &URL_SAFE_NO_PAD_ENGINE, false); + assert_encoded_length(2, 3, &URL_SAFE_NO_PAD_ENGINE, false); + assert_encoded_length(3, 4, &URL_SAFE_NO_PAD_ENGINE, false); + + assert_encoded_length(4, 6, &URL_SAFE_NO_PAD_ENGINE, false); + assert_encoded_length(5, 7, &URL_SAFE_NO_PAD_ENGINE, false); + assert_encoded_length(6, 8, &URL_SAFE_NO_PAD_ENGINE, false); + + assert_encoded_length(7, 10, &URL_SAFE_NO_PAD_ENGINE, false); + assert_encoded_length(8, 11, &URL_SAFE_NO_PAD_ENGINE, false); + assert_encoded_length(9, 12, &URL_SAFE_NO_PAD_ENGINE, false); + + assert_encoded_length(54, 72, &URL_SAFE_NO_PAD_ENGINE, false); + + assert_encoded_length(55, 74, &URL_SAFE_NO_PAD_ENGINE, false); + assert_encoded_length(56, 75, &URL_SAFE_NO_PAD_ENGINE, false); + assert_encoded_length(57, 76, &URL_SAFE_NO_PAD_ENGINE, false); + + assert_encoded_length(58, 78, &URL_SAFE_NO_PAD_ENGINE, false); + } + + #[test] + fn encoded_size_overflow() { + assert_eq!(None, encoded_len(usize::MAX, true)); + } + + #[test] + fn encode_engine_string_into_nonempty_buffer_doesnt_clobber_prefix() { + let mut orig_data = Vec::new(); + let mut prefix = String::new(); + let mut encoded_data_no_prefix = String::new(); + let mut encoded_data_with_prefix = String::new(); + let mut decoded = Vec::new(); + + let prefix_len_range = Uniform::new(0, 1000); + let input_len_range = Uniform::new(0, 1000); + + let mut rng = rand::rngs::SmallRng::from_entropy(); + + for _ in 0..10_000 { + orig_data.clear(); + prefix.clear(); + encoded_data_no_prefix.clear(); + encoded_data_with_prefix.clear(); + decoded.clear(); + + let input_len = input_len_range.sample(&mut rng); + + for _ in 0..input_len { + orig_data.push(rng.gen()); + } + + let prefix_len = prefix_len_range.sample(&mut rng); + for _ in 0..prefix_len { + // getting convenient random single-byte printable chars that aren't base64 is + // annoying + prefix.push('#'); + } + encoded_data_with_prefix.push_str(&prefix); + + let engine = random_engine(&mut rng); + engine.encode_string(&orig_data, &mut encoded_data_no_prefix); + engine.encode_string(&orig_data, &mut encoded_data_with_prefix); + + assert_eq!( + encoded_data_no_prefix.len() + prefix_len, + encoded_data_with_prefix.len() + ); + assert_encode_sanity( + &encoded_data_no_prefix, + engine.config().encode_padding(), + input_len, + ); + assert_encode_sanity( + &encoded_data_with_prefix[prefix_len..], + engine.config().encode_padding(), + input_len, + ); + + // append plain encode onto prefix + prefix.push_str(&encoded_data_no_prefix); + + assert_eq!(prefix, encoded_data_with_prefix); + + engine + .decode_vec(&encoded_data_no_prefix, &mut decoded) + .unwrap(); + assert_eq!(orig_data, decoded); + } + } + + #[test] + fn encode_engine_slice_into_nonempty_buffer_doesnt_clobber_suffix() { + let mut orig_data = Vec::new(); + let mut encoded_data = Vec::new(); + let mut encoded_data_original_state = Vec::new(); + let mut decoded = Vec::new(); + + let input_len_range = Uniform::new(0, 1000); + + let mut rng = rand::rngs::SmallRng::from_entropy(); + + for _ in 0..10_000 { + orig_data.clear(); + encoded_data.clear(); + encoded_data_original_state.clear(); + decoded.clear(); + + let input_len = input_len_range.sample(&mut rng); + + for _ in 0..input_len { + orig_data.push(rng.gen()); + } + + // plenty of existing garbage in the encoded buffer + for _ in 0..10 * input_len { + encoded_data.push(rng.gen()); + } + + encoded_data_original_state.extend_from_slice(&encoded_data); + + let engine = random_engine(&mut rng); + + let encoded_size = encoded_len(input_len, engine.config().encode_padding()).unwrap(); + + assert_eq!( + encoded_size, + engine.encode_slice(&orig_data, &mut encoded_data).unwrap() + ); + + assert_encode_sanity( + str::from_utf8(&encoded_data[0..encoded_size]).unwrap(), + engine.config().encode_padding(), + input_len, + ); + + assert_eq!( + &encoded_data[encoded_size..], + &encoded_data_original_state[encoded_size..] + ); + + engine + .decode_vec(&encoded_data[0..encoded_size], &mut decoded) + .unwrap(); + assert_eq!(orig_data, decoded); + } + } + + #[test] + fn encode_to_slice_random_valid_utf8() { + let mut input = Vec::new(); + let mut output = Vec::new(); + + let input_len_range = Uniform::new(0, 1000); + + let mut rng = rand::rngs::SmallRng::from_entropy(); + + for _ in 0..10_000 { + input.clear(); + output.clear(); + + let input_len = input_len_range.sample(&mut rng); + + for _ in 0..input_len { + input.push(rng.gen()); + } + + let config = random_config(&mut rng); + let engine = random_engine(&mut rng); + + // fill up the output buffer with garbage + let encoded_size = encoded_len(input_len, config.encode_padding()).unwrap(); + for _ in 0..encoded_size { + output.push(rng.gen()); + } + + let orig_output_buf = output.clone(); + + let bytes_written = engine.internal_encode(&input, &mut output); + + // make sure the part beyond bytes_written is the same garbage it was before + assert_eq!(orig_output_buf[bytes_written..], output[bytes_written..]); + + // make sure the encoded bytes are UTF-8 + let _ = str::from_utf8(&output[0..bytes_written]).unwrap(); + } + } + + #[test] + fn encode_with_padding_random_valid_utf8() { + let mut input = Vec::new(); + let mut output = Vec::new(); + + let input_len_range = Uniform::new(0, 1000); + + let mut rng = rand::rngs::SmallRng::from_entropy(); + + for _ in 0..10_000 { + input.clear(); + output.clear(); + + let input_len = input_len_range.sample(&mut rng); + + for _ in 0..input_len { + input.push(rng.gen()); + } + + let engine = random_engine(&mut rng); + + // fill up the output buffer with garbage + let encoded_size = encoded_len(input_len, engine.config().encode_padding()).unwrap(); + for _ in 0..encoded_size + 1000 { + output.push(rng.gen()); + } + + let orig_output_buf = output.clone(); + + encode_with_padding(&input, &mut output[0..encoded_size], &engine, encoded_size); + + // make sure the part beyond b64 is the same garbage it was before + assert_eq!(orig_output_buf[encoded_size..], output[encoded_size..]); + + // make sure the encoded bytes are UTF-8 + let _ = str::from_utf8(&output[0..encoded_size]).unwrap(); + } + } + + #[test] + fn add_padding_random_valid_utf8() { + let mut output = Vec::new(); + + let mut rng = rand::rngs::SmallRng::from_entropy(); + + // cover our bases for length % 4 + for unpadded_output_len in 0..20 { + output.clear(); + + // fill output with random + for _ in 0..100 { + output.push(rng.gen()); + } + + let orig_output_buf = output.clone(); + + let bytes_written = add_padding(unpadded_output_len, &mut output); + + // make sure the part beyond bytes_written is the same garbage it was before + assert_eq!(orig_output_buf[bytes_written..], output[bytes_written..]); + + // make sure the encoded bytes are UTF-8 + let _ = str::from_utf8(&output[0..bytes_written]).unwrap(); + } + } + + fn assert_encoded_length( + input_len: usize, + enc_len: usize, + engine: &E, + padded: bool, + ) { + assert_eq!(enc_len, encoded_len(input_len, padded).unwrap()); + + let mut bytes: Vec = Vec::new(); + let mut rng = rand::rngs::SmallRng::from_entropy(); + + for _ in 0..input_len { + bytes.push(rng.gen()); + } + + let encoded = engine.encode(&bytes); + assert_encode_sanity(&encoded, padded, input_len); + + assert_eq!(enc_len, encoded.len()); + } + + #[test] + fn encode_imap() { + assert_eq!( + &GeneralPurpose::new(&alphabet::IMAP_MUTF7, NO_PAD).encode(b"\xFB\xFF"), + &GeneralPurpose::new(&alphabet::STANDARD, NO_PAD) + .encode(b"\xFB\xFF") + .replace('/', ",") + ); + } +} diff --git a/vendor/base64/src/engine/general_purpose/decode.rs b/vendor/base64/src/engine/general_purpose/decode.rs new file mode 100644 index 0000000..b55d3fc --- /dev/null +++ b/vendor/base64/src/engine/general_purpose/decode.rs @@ -0,0 +1,357 @@ +use crate::{ + engine::{general_purpose::INVALID_VALUE, DecodeEstimate, DecodeMetadata, DecodePaddingMode}, + DecodeError, DecodeSliceError, PAD_BYTE, +}; + +#[doc(hidden)] +pub struct GeneralPurposeEstimate { + /// input len % 4 + rem: usize, + conservative_decoded_len: usize, +} + +impl GeneralPurposeEstimate { + pub(crate) fn new(encoded_len: usize) -> Self { + let rem = encoded_len % 4; + Self { + rem, + conservative_decoded_len: (encoded_len / 4 + (rem > 0) as usize) * 3, + } + } +} + +impl DecodeEstimate for GeneralPurposeEstimate { + fn decoded_len_estimate(&self) -> usize { + self.conservative_decoded_len + } +} + +/// Helper to avoid duplicating num_chunks calculation, which is costly on short inputs. +/// Returns the decode metadata, or an error. +// We're on the fragile edge of compiler heuristics here. If this is not inlined, slow. If this is +// inlined(always), a different slow. plain ol' inline makes the benchmarks happiest at the moment, +// but this is fragile and the best setting changes with only minor code modifications. +#[inline] +pub(crate) fn decode_helper( + input: &[u8], + estimate: GeneralPurposeEstimate, + output: &mut [u8], + decode_table: &[u8; 256], + decode_allow_trailing_bits: bool, + padding_mode: DecodePaddingMode, +) -> Result { + let input_complete_nonterminal_quads_len = + complete_quads_len(input, estimate.rem, output.len(), decode_table)?; + + const UNROLLED_INPUT_CHUNK_SIZE: usize = 32; + const UNROLLED_OUTPUT_CHUNK_SIZE: usize = UNROLLED_INPUT_CHUNK_SIZE / 4 * 3; + + let input_complete_quads_after_unrolled_chunks_len = + input_complete_nonterminal_quads_len % UNROLLED_INPUT_CHUNK_SIZE; + + let input_unrolled_loop_len = + input_complete_nonterminal_quads_len - input_complete_quads_after_unrolled_chunks_len; + + // chunks of 32 bytes + for (chunk_index, chunk) in input[..input_unrolled_loop_len] + .chunks_exact(UNROLLED_INPUT_CHUNK_SIZE) + .enumerate() + { + let input_index = chunk_index * UNROLLED_INPUT_CHUNK_SIZE; + let chunk_output = &mut output[chunk_index * UNROLLED_OUTPUT_CHUNK_SIZE + ..(chunk_index + 1) * UNROLLED_OUTPUT_CHUNK_SIZE]; + + decode_chunk_8( + &chunk[0..8], + input_index, + decode_table, + &mut chunk_output[0..6], + )?; + decode_chunk_8( + &chunk[8..16], + input_index + 8, + decode_table, + &mut chunk_output[6..12], + )?; + decode_chunk_8( + &chunk[16..24], + input_index + 16, + decode_table, + &mut chunk_output[12..18], + )?; + decode_chunk_8( + &chunk[24..32], + input_index + 24, + decode_table, + &mut chunk_output[18..24], + )?; + } + + // remaining quads, except for the last possibly partial one, as it may have padding + let output_unrolled_loop_len = input_unrolled_loop_len / 4 * 3; + let output_complete_quad_len = input_complete_nonterminal_quads_len / 4 * 3; + { + let output_after_unroll = &mut output[output_unrolled_loop_len..output_complete_quad_len]; + + for (chunk_index, chunk) in input + [input_unrolled_loop_len..input_complete_nonterminal_quads_len] + .chunks_exact(4) + .enumerate() + { + let chunk_output = &mut output_after_unroll[chunk_index * 3..chunk_index * 3 + 3]; + + decode_chunk_4( + chunk, + input_unrolled_loop_len + chunk_index * 4, + decode_table, + chunk_output, + )?; + } + } + + super::decode_suffix::decode_suffix( + input, + input_complete_nonterminal_quads_len, + output, + output_complete_quad_len, + decode_table, + decode_allow_trailing_bits, + padding_mode, + ) +} + +/// Returns the length of complete quads, except for the last one, even if it is complete. +/// +/// Returns an error if the output len is not big enough for decoding those complete quads, or if +/// the input % 4 == 1, and that last byte is an invalid value other than a pad byte. +/// +/// - `input` is the base64 input +/// - `input_len_rem` is input len % 4 +/// - `output_len` is the length of the output slice +pub(crate) fn complete_quads_len( + input: &[u8], + input_len_rem: usize, + output_len: usize, + decode_table: &[u8; 256], +) -> Result { + debug_assert!(input.len() % 4 == input_len_rem); + + // detect a trailing invalid byte, like a newline, as a user convenience + if input_len_rem == 1 { + let last_byte = input[input.len() - 1]; + // exclude pad bytes; might be part of padding that extends from earlier in the input + if last_byte != PAD_BYTE && decode_table[usize::from(last_byte)] == INVALID_VALUE { + return Err(DecodeError::InvalidByte(input.len() - 1, last_byte).into()); + } + }; + + // skip last quad, even if it's complete, as it may have padding + let input_complete_nonterminal_quads_len = input + .len() + .saturating_sub(input_len_rem) + // if rem was 0, subtract 4 to avoid padding + .saturating_sub((input_len_rem == 0) as usize * 4); + debug_assert!( + input.is_empty() || (1..=4).contains(&(input.len() - input_complete_nonterminal_quads_len)) + ); + + // check that everything except the last quad handled by decode_suffix will fit + if output_len < input_complete_nonterminal_quads_len / 4 * 3 { + return Err(DecodeSliceError::OutputSliceTooSmall); + }; + Ok(input_complete_nonterminal_quads_len) +} + +/// Decode 8 bytes of input into 6 bytes of output. +/// +/// `input` is the 8 bytes to decode. +/// `index_at_start_of_input` is the offset in the overall input (used for reporting errors +/// accurately) +/// `decode_table` is the lookup table for the particular base64 alphabet. +/// `output` will have its first 6 bytes overwritten +// yes, really inline (worth 30-50% speedup) +#[inline(always)] +fn decode_chunk_8( + input: &[u8], + index_at_start_of_input: usize, + decode_table: &[u8; 256], + output: &mut [u8], +) -> Result<(), DecodeError> { + let morsel = decode_table[usize::from(input[0])]; + if morsel == INVALID_VALUE { + return Err(DecodeError::InvalidByte(index_at_start_of_input, input[0])); + } + let mut accum = u64::from(morsel) << 58; + + let morsel = decode_table[usize::from(input[1])]; + if morsel == INVALID_VALUE { + return Err(DecodeError::InvalidByte( + index_at_start_of_input + 1, + input[1], + )); + } + accum |= u64::from(morsel) << 52; + + let morsel = decode_table[usize::from(input[2])]; + if morsel == INVALID_VALUE { + return Err(DecodeError::InvalidByte( + index_at_start_of_input + 2, + input[2], + )); + } + accum |= u64::from(morsel) << 46; + + let morsel = decode_table[usize::from(input[3])]; + if morsel == INVALID_VALUE { + return Err(DecodeError::InvalidByte( + index_at_start_of_input + 3, + input[3], + )); + } + accum |= u64::from(morsel) << 40; + + let morsel = decode_table[usize::from(input[4])]; + if morsel == INVALID_VALUE { + return Err(DecodeError::InvalidByte( + index_at_start_of_input + 4, + input[4], + )); + } + accum |= u64::from(morsel) << 34; + + let morsel = decode_table[usize::from(input[5])]; + if morsel == INVALID_VALUE { + return Err(DecodeError::InvalidByte( + index_at_start_of_input + 5, + input[5], + )); + } + accum |= u64::from(morsel) << 28; + + let morsel = decode_table[usize::from(input[6])]; + if morsel == INVALID_VALUE { + return Err(DecodeError::InvalidByte( + index_at_start_of_input + 6, + input[6], + )); + } + accum |= u64::from(morsel) << 22; + + let morsel = decode_table[usize::from(input[7])]; + if morsel == INVALID_VALUE { + return Err(DecodeError::InvalidByte( + index_at_start_of_input + 7, + input[7], + )); + } + accum |= u64::from(morsel) << 16; + + output[..6].copy_from_slice(&accum.to_be_bytes()[..6]); + + Ok(()) +} + +/// Like [decode_chunk_8] but for 4 bytes of input and 3 bytes of output. +#[inline(always)] +fn decode_chunk_4( + input: &[u8], + index_at_start_of_input: usize, + decode_table: &[u8; 256], + output: &mut [u8], +) -> Result<(), DecodeError> { + let morsel = decode_table[usize::from(input[0])]; + if morsel == INVALID_VALUE { + return Err(DecodeError::InvalidByte(index_at_start_of_input, input[0])); + } + let mut accum = u32::from(morsel) << 26; + + let morsel = decode_table[usize::from(input[1])]; + if morsel == INVALID_VALUE { + return Err(DecodeError::InvalidByte( + index_at_start_of_input + 1, + input[1], + )); + } + accum |= u32::from(morsel) << 20; + + let morsel = decode_table[usize::from(input[2])]; + if morsel == INVALID_VALUE { + return Err(DecodeError::InvalidByte( + index_at_start_of_input + 2, + input[2], + )); + } + accum |= u32::from(morsel) << 14; + + let morsel = decode_table[usize::from(input[3])]; + if morsel == INVALID_VALUE { + return Err(DecodeError::InvalidByte( + index_at_start_of_input + 3, + input[3], + )); + } + accum |= u32::from(morsel) << 8; + + output[..3].copy_from_slice(&accum.to_be_bytes()[..3]); + + Ok(()) +} + +#[cfg(test)] +mod tests { + use super::*; + + use crate::engine::general_purpose::STANDARD; + + #[test] + fn decode_chunk_8_writes_only_6_bytes() { + let input = b"Zm9vYmFy"; // "foobar" + let mut output = [0_u8, 1, 2, 3, 4, 5, 6, 7]; + + decode_chunk_8(&input[..], 0, &STANDARD.decode_table, &mut output).unwrap(); + assert_eq!(&vec![b'f', b'o', b'o', b'b', b'a', b'r', 6, 7], &output); + } + + #[test] + fn decode_chunk_4_writes_only_3_bytes() { + let input = b"Zm9v"; // "foobar" + let mut output = [0_u8, 1, 2, 3]; + + decode_chunk_4(&input[..], 0, &STANDARD.decode_table, &mut output).unwrap(); + assert_eq!(&vec![b'f', b'o', b'o', 3], &output); + } + + #[test] + fn estimate_short_lengths() { + for (range, decoded_len_estimate) in [ + (0..=0, 0), + (1..=4, 3), + (5..=8, 6), + (9..=12, 9), + (13..=16, 12), + (17..=20, 15), + ] { + for encoded_len in range { + let estimate = GeneralPurposeEstimate::new(encoded_len); + assert_eq!(decoded_len_estimate, estimate.decoded_len_estimate()); + } + } + } + + #[test] + fn estimate_via_u128_inflation() { + // cover both ends of usize + (0..1000) + .chain(usize::MAX - 1000..=usize::MAX) + .for_each(|encoded_len| { + // inflate to 128 bit type to be able to safely use the easy formulas + let len_128 = encoded_len as u128; + + let estimate = GeneralPurposeEstimate::new(encoded_len); + assert_eq!( + (len_128 + 3) / 4 * 3, + estimate.conservative_decoded_len as u128 + ); + }) + } +} diff --git a/vendor/base64/src/engine/general_purpose/decode_suffix.rs b/vendor/base64/src/engine/general_purpose/decode_suffix.rs new file mode 100644 index 0000000..02aaf51 --- /dev/null +++ b/vendor/base64/src/engine/general_purpose/decode_suffix.rs @@ -0,0 +1,162 @@ +use crate::{ + engine::{general_purpose::INVALID_VALUE, DecodeMetadata, DecodePaddingMode}, + DecodeError, DecodeSliceError, PAD_BYTE, +}; + +/// Decode the last 0-4 bytes, checking for trailing set bits and padding per the provided +/// parameters. +/// +/// Returns the decode metadata representing the total number of bytes decoded, including the ones +/// indicated as already written by `output_index`. +pub(crate) fn decode_suffix( + input: &[u8], + input_index: usize, + output: &mut [u8], + mut output_index: usize, + decode_table: &[u8; 256], + decode_allow_trailing_bits: bool, + padding_mode: DecodePaddingMode, +) -> Result { + debug_assert!((input.len() - input_index) <= 4); + + // Decode any leftovers that might not be a complete input chunk of 4 bytes. + // Use a u32 as a stack-resident 4 byte buffer. + let mut morsels_in_leftover = 0; + let mut padding_bytes_count = 0; + // offset from input_index + let mut first_padding_offset: usize = 0; + let mut last_symbol = 0_u8; + let mut morsels = [0_u8; 4]; + + for (leftover_index, &b) in input[input_index..].iter().enumerate() { + // '=' padding + if b == PAD_BYTE { + // There can be bad padding bytes in a few ways: + // 1 - Padding with non-padding characters after it + // 2 - Padding after zero or one characters in the current quad (should only + // be after 2 or 3 chars) + // 3 - More than two characters of padding. If 3 or 4 padding chars + // are in the same quad, that implies it will be caught by #2. + // If it spreads from one quad to another, it will be an invalid byte + // in the first quad. + // 4 - Non-canonical padding -- 1 byte when it should be 2, etc. + // Per config, non-canonical but still functional non- or partially-padded base64 + // may be treated as an error condition. + + if leftover_index < 2 { + // Check for error #2. + // Either the previous byte was padding, in which case we would have already hit + // this case, or it wasn't, in which case this is the first such error. + debug_assert!( + leftover_index == 0 || (leftover_index == 1 && padding_bytes_count == 0) + ); + let bad_padding_index = input_index + leftover_index; + return Err(DecodeError::InvalidByte(bad_padding_index, b).into()); + } + + if padding_bytes_count == 0 { + first_padding_offset = leftover_index; + } + + padding_bytes_count += 1; + continue; + } + + // Check for case #1. + // To make '=' handling consistent with the main loop, don't allow + // non-suffix '=' in trailing chunk either. Report error as first + // erroneous padding. + if padding_bytes_count > 0 { + return Err( + DecodeError::InvalidByte(input_index + first_padding_offset, PAD_BYTE).into(), + ); + } + + last_symbol = b; + + // can use up to 8 * 6 = 48 bits of the u64, if last chunk has no padding. + // Pack the leftovers from left to right. + let morsel = decode_table[b as usize]; + if morsel == INVALID_VALUE { + return Err(DecodeError::InvalidByte(input_index + leftover_index, b).into()); + } + + morsels[morsels_in_leftover] = morsel; + morsels_in_leftover += 1; + } + + // If there was 1 trailing byte, and it was valid, and we got to this point without hitting + // an invalid byte, now we can report invalid length + if !input.is_empty() && morsels_in_leftover < 2 { + return Err(DecodeError::InvalidLength(input_index + morsels_in_leftover).into()); + } + + match padding_mode { + DecodePaddingMode::Indifferent => { /* everything we care about was already checked */ } + DecodePaddingMode::RequireCanonical => { + // allow empty input + if (padding_bytes_count + morsels_in_leftover) % 4 != 0 { + return Err(DecodeError::InvalidPadding.into()); + } + } + DecodePaddingMode::RequireNone => { + if padding_bytes_count > 0 { + // check at the end to make sure we let the cases of padding that should be InvalidByte + // get hit + return Err(DecodeError::InvalidPadding.into()); + } + } + } + + // When encoding 1 trailing byte (e.g. 0xFF), 2 base64 bytes ("/w") are needed. + // / is the symbol for 63 (0x3F, bottom 6 bits all set) and w is 48 (0x30, top 2 bits + // of bottom 6 bits set). + // When decoding two symbols back to one trailing byte, any final symbol higher than + // w would still decode to the original byte because we only care about the top two + // bits in the bottom 6, but would be a non-canonical encoding. So, we calculate a + // mask based on how many bits are used for just the canonical encoding, and optionally + // error if any other bits are set. In the example of one encoded byte -> 2 symbols, + // 2 symbols can technically encode 12 bits, but the last 4 are non-canonical, and + // useless since there are no more symbols to provide the necessary 4 additional bits + // to finish the second original byte. + + let leftover_bytes_to_append = morsels_in_leftover * 6 / 8; + // Put the up to 6 complete bytes as the high bytes. + // Gain a couple percent speedup from nudging these ORs to use more ILP with a two-way split. + let mut leftover_num = (u32::from(morsels[0]) << 26) + | (u32::from(morsels[1]) << 20) + | (u32::from(morsels[2]) << 14) + | (u32::from(morsels[3]) << 8); + + // if there are bits set outside the bits we care about, last symbol encodes trailing bits that + // will not be included in the output + let mask = !0_u32 >> (leftover_bytes_to_append * 8); + if !decode_allow_trailing_bits && (leftover_num & mask) != 0 { + // last morsel is at `morsels_in_leftover` - 1 + return Err(DecodeError::InvalidLastSymbol( + input_index + morsels_in_leftover - 1, + last_symbol, + ) + .into()); + } + + // Strangely, this approach benchmarks better than writing bytes one at a time, + // or copy_from_slice into output. + for _ in 0..leftover_bytes_to_append { + let hi_byte = (leftover_num >> 24) as u8; + leftover_num <<= 8; + *output + .get_mut(output_index) + .ok_or(DecodeSliceError::OutputSliceTooSmall)? = hi_byte; + output_index += 1; + } + + Ok(DecodeMetadata::new( + output_index, + if padding_bytes_count > 0 { + Some(input_index + first_padding_offset) + } else { + None + }, + )) +} diff --git a/vendor/base64/src/engine/general_purpose/mod.rs b/vendor/base64/src/engine/general_purpose/mod.rs new file mode 100644 index 0000000..6fe9580 --- /dev/null +++ b/vendor/base64/src/engine/general_purpose/mod.rs @@ -0,0 +1,352 @@ +//! Provides the [GeneralPurpose] engine and associated config types. +use crate::{ + alphabet, + alphabet::Alphabet, + engine::{Config, DecodeMetadata, DecodePaddingMode}, + DecodeSliceError, +}; +use core::convert::TryInto; + +pub(crate) mod decode; +pub(crate) mod decode_suffix; + +pub use decode::GeneralPurposeEstimate; + +pub(crate) const INVALID_VALUE: u8 = 255; + +/// A general-purpose base64 engine. +/// +/// - It uses no vector CPU instructions, so it will work on any system. +/// - It is reasonably fast (~2-3GiB/s). +/// - It is not constant-time, though, so it is vulnerable to timing side-channel attacks. For loading cryptographic keys, etc, it is suggested to use the forthcoming constant-time implementation. + +#[derive(Debug, Clone)] +pub struct GeneralPurpose { + encode_table: [u8; 64], + decode_table: [u8; 256], + config: GeneralPurposeConfig, +} + +impl GeneralPurpose { + /// Create a `GeneralPurpose` engine from an [Alphabet]. + /// + /// While not very expensive to initialize, ideally these should be cached + /// if the engine will be used repeatedly. + pub const fn new(alphabet: &Alphabet, config: GeneralPurposeConfig) -> Self { + Self { + encode_table: encode_table(alphabet), + decode_table: decode_table(alphabet), + config, + } + } +} + +impl super::Engine for GeneralPurpose { + type Config = GeneralPurposeConfig; + type DecodeEstimate = GeneralPurposeEstimate; + + fn internal_encode(&self, input: &[u8], output: &mut [u8]) -> usize { + let mut input_index: usize = 0; + + const BLOCKS_PER_FAST_LOOP: usize = 4; + const LOW_SIX_BITS: u64 = 0x3F; + + // we read 8 bytes at a time (u64) but only actually consume 6 of those bytes. Thus, we need + // 2 trailing bytes to be available to read.. + let last_fast_index = input.len().saturating_sub(BLOCKS_PER_FAST_LOOP * 6 + 2); + let mut output_index = 0; + + if last_fast_index > 0 { + while input_index <= last_fast_index { + // Major performance wins from letting the optimizer do the bounds check once, mostly + // on the output side + let input_chunk = + &input[input_index..(input_index + (BLOCKS_PER_FAST_LOOP * 6 + 2))]; + let output_chunk = + &mut output[output_index..(output_index + BLOCKS_PER_FAST_LOOP * 8)]; + + // Hand-unrolling for 32 vs 16 or 8 bytes produces yields performance about equivalent + // to unsafe pointer code on a Xeon E5-1650v3. 64 byte unrolling was slightly better for + // large inputs but significantly worse for 50-byte input, unsurprisingly. I suspect + // that it's a not uncommon use case to encode smallish chunks of data (e.g. a 64-byte + // SHA-512 digest), so it would be nice if that fit in the unrolled loop at least once. + // Plus, single-digit percentage performance differences might well be quite different + // on different hardware. + + let input_u64 = read_u64(&input_chunk[0..]); + + output_chunk[0] = self.encode_table[((input_u64 >> 58) & LOW_SIX_BITS) as usize]; + output_chunk[1] = self.encode_table[((input_u64 >> 52) & LOW_SIX_BITS) as usize]; + output_chunk[2] = self.encode_table[((input_u64 >> 46) & LOW_SIX_BITS) as usize]; + output_chunk[3] = self.encode_table[((input_u64 >> 40) & LOW_SIX_BITS) as usize]; + output_chunk[4] = self.encode_table[((input_u64 >> 34) & LOW_SIX_BITS) as usize]; + output_chunk[5] = self.encode_table[((input_u64 >> 28) & LOW_SIX_BITS) as usize]; + output_chunk[6] = self.encode_table[((input_u64 >> 22) & LOW_SIX_BITS) as usize]; + output_chunk[7] = self.encode_table[((input_u64 >> 16) & LOW_SIX_BITS) as usize]; + + let input_u64 = read_u64(&input_chunk[6..]); + + output_chunk[8] = self.encode_table[((input_u64 >> 58) & LOW_SIX_BITS) as usize]; + output_chunk[9] = self.encode_table[((input_u64 >> 52) & LOW_SIX_BITS) as usize]; + output_chunk[10] = self.encode_table[((input_u64 >> 46) & LOW_SIX_BITS) as usize]; + output_chunk[11] = self.encode_table[((input_u64 >> 40) & LOW_SIX_BITS) as usize]; + output_chunk[12] = self.encode_table[((input_u64 >> 34) & LOW_SIX_BITS) as usize]; + output_chunk[13] = self.encode_table[((input_u64 >> 28) & LOW_SIX_BITS) as usize]; + output_chunk[14] = self.encode_table[((input_u64 >> 22) & LOW_SIX_BITS) as usize]; + output_chunk[15] = self.encode_table[((input_u64 >> 16) & LOW_SIX_BITS) as usize]; + + let input_u64 = read_u64(&input_chunk[12..]); + + output_chunk[16] = self.encode_table[((input_u64 >> 58) & LOW_SIX_BITS) as usize]; + output_chunk[17] = self.encode_table[((input_u64 >> 52) & LOW_SIX_BITS) as usize]; + output_chunk[18] = self.encode_table[((input_u64 >> 46) & LOW_SIX_BITS) as usize]; + output_chunk[19] = self.encode_table[((input_u64 >> 40) & LOW_SIX_BITS) as usize]; + output_chunk[20] = self.encode_table[((input_u64 >> 34) & LOW_SIX_BITS) as usize]; + output_chunk[21] = self.encode_table[((input_u64 >> 28) & LOW_SIX_BITS) as usize]; + output_chunk[22] = self.encode_table[((input_u64 >> 22) & LOW_SIX_BITS) as usize]; + output_chunk[23] = self.encode_table[((input_u64 >> 16) & LOW_SIX_BITS) as usize]; + + let input_u64 = read_u64(&input_chunk[18..]); + + output_chunk[24] = self.encode_table[((input_u64 >> 58) & LOW_SIX_BITS) as usize]; + output_chunk[25] = self.encode_table[((input_u64 >> 52) & LOW_SIX_BITS) as usize]; + output_chunk[26] = self.encode_table[((input_u64 >> 46) & LOW_SIX_BITS) as usize]; + output_chunk[27] = self.encode_table[((input_u64 >> 40) & LOW_SIX_BITS) as usize]; + output_chunk[28] = self.encode_table[((input_u64 >> 34) & LOW_SIX_BITS) as usize]; + output_chunk[29] = self.encode_table[((input_u64 >> 28) & LOW_SIX_BITS) as usize]; + output_chunk[30] = self.encode_table[((input_u64 >> 22) & LOW_SIX_BITS) as usize]; + output_chunk[31] = self.encode_table[((input_u64 >> 16) & LOW_SIX_BITS) as usize]; + + output_index += BLOCKS_PER_FAST_LOOP * 8; + input_index += BLOCKS_PER_FAST_LOOP * 6; + } + } + + // Encode what's left after the fast loop. + + const LOW_SIX_BITS_U8: u8 = 0x3F; + + let rem = input.len() % 3; + let start_of_rem = input.len() - rem; + + // start at the first index not handled by fast loop, which may be 0. + + while input_index < start_of_rem { + let input_chunk = &input[input_index..(input_index + 3)]; + let output_chunk = &mut output[output_index..(output_index + 4)]; + + output_chunk[0] = self.encode_table[(input_chunk[0] >> 2) as usize]; + output_chunk[1] = self.encode_table + [((input_chunk[0] << 4 | input_chunk[1] >> 4) & LOW_SIX_BITS_U8) as usize]; + output_chunk[2] = self.encode_table + [((input_chunk[1] << 2 | input_chunk[2] >> 6) & LOW_SIX_BITS_U8) as usize]; + output_chunk[3] = self.encode_table[(input_chunk[2] & LOW_SIX_BITS_U8) as usize]; + + input_index += 3; + output_index += 4; + } + + if rem == 2 { + output[output_index] = self.encode_table[(input[start_of_rem] >> 2) as usize]; + output[output_index + 1] = + self.encode_table[((input[start_of_rem] << 4 | input[start_of_rem + 1] >> 4) + & LOW_SIX_BITS_U8) as usize]; + output[output_index + 2] = + self.encode_table[((input[start_of_rem + 1] << 2) & LOW_SIX_BITS_U8) as usize]; + output_index += 3; + } else if rem == 1 { + output[output_index] = self.encode_table[(input[start_of_rem] >> 2) as usize]; + output[output_index + 1] = + self.encode_table[((input[start_of_rem] << 4) & LOW_SIX_BITS_U8) as usize]; + output_index += 2; + } + + output_index + } + + fn internal_decoded_len_estimate(&self, input_len: usize) -> Self::DecodeEstimate { + GeneralPurposeEstimate::new(input_len) + } + + fn internal_decode( + &self, + input: &[u8], + output: &mut [u8], + estimate: Self::DecodeEstimate, + ) -> Result { + decode::decode_helper( + input, + estimate, + output, + &self.decode_table, + self.config.decode_allow_trailing_bits, + self.config.decode_padding_mode, + ) + } + + fn config(&self) -> &Self::Config { + &self.config + } +} + +/// Returns a table mapping a 6-bit index to the ASCII byte encoding of the index +pub(crate) const fn encode_table(alphabet: &Alphabet) -> [u8; 64] { + // the encode table is just the alphabet: + // 6-bit index lookup -> printable byte + let mut encode_table = [0_u8; 64]; + { + let mut index = 0; + while index < 64 { + encode_table[index] = alphabet.symbols[index]; + index += 1; + } + } + + encode_table +} + +/// Returns a table mapping base64 bytes as the lookup index to either: +/// - [INVALID_VALUE] for bytes that aren't members of the alphabet +/// - a byte whose lower 6 bits are the value that was encoded into the index byte +pub(crate) const fn decode_table(alphabet: &Alphabet) -> [u8; 256] { + let mut decode_table = [INVALID_VALUE; 256]; + + // Since the table is full of `INVALID_VALUE` already, we only need to overwrite + // the parts that are valid. + let mut index = 0; + while index < 64 { + // The index in the alphabet is the 6-bit value we care about. + // Since the index is in 0-63, it is safe to cast to u8. + decode_table[alphabet.symbols[index] as usize] = index as u8; + index += 1; + } + + decode_table +} + +#[inline] +fn read_u64(s: &[u8]) -> u64 { + u64::from_be_bytes(s[..8].try_into().unwrap()) +} + +/// Contains configuration parameters for base64 encoding and decoding. +/// +/// ``` +/// # use base64::engine::GeneralPurposeConfig; +/// let config = GeneralPurposeConfig::new() +/// .with_encode_padding(false); +/// // further customize using `.with_*` methods as needed +/// ``` +/// +/// The constants [PAD] and [NO_PAD] cover most use cases. +/// +/// To specify the characters used, see [Alphabet]. +#[derive(Clone, Copy, Debug)] +pub struct GeneralPurposeConfig { + encode_padding: bool, + decode_allow_trailing_bits: bool, + decode_padding_mode: DecodePaddingMode, +} + +impl GeneralPurposeConfig { + /// Create a new config with `padding` = `true`, `decode_allow_trailing_bits` = `false`, and + /// `decode_padding_mode = DecodePaddingMode::RequireCanonicalPadding`. + /// + /// This probably matches most people's expectations, but consider disabling padding to save + /// a few bytes unless you specifically need it for compatibility with some legacy system. + pub const fn new() -> Self { + Self { + // RFC states that padding must be applied by default + encode_padding: true, + decode_allow_trailing_bits: false, + decode_padding_mode: DecodePaddingMode::RequireCanonical, + } + } + + /// Create a new config based on `self` with an updated `padding` setting. + /// + /// If `padding` is `true`, encoding will append either 1 or 2 `=` padding characters as needed + /// to produce an output whose length is a multiple of 4. + /// + /// Padding is not needed for correct decoding and only serves to waste bytes, but it's in the + /// [spec](https://datatracker.ietf.org/doc/html/rfc4648#section-3.2). + /// + /// For new applications, consider not using padding if the decoders you're using don't require + /// padding to be present. + pub const fn with_encode_padding(self, padding: bool) -> Self { + Self { + encode_padding: padding, + ..self + } + } + + /// Create a new config based on `self` with an updated `decode_allow_trailing_bits` setting. + /// + /// Most users will not need to configure this. It's useful if you need to decode base64 + /// produced by a buggy encoder that has bits set in the unused space on the last base64 + /// character as per [forgiving-base64 decode](https://infra.spec.whatwg.org/#forgiving-base64-decode). + /// If invalid trailing bits are present and this is `true`, those bits will + /// be silently ignored, else `DecodeError::InvalidLastSymbol` will be emitted. + pub const fn with_decode_allow_trailing_bits(self, allow: bool) -> Self { + Self { + decode_allow_trailing_bits: allow, + ..self + } + } + + /// Create a new config based on `self` with an updated `decode_padding_mode` setting. + /// + /// Padding is not useful in terms of representing encoded data -- it makes no difference to + /// the decoder if padding is present or not, so if you have some un-padded input to decode, it + /// is perfectly fine to use `DecodePaddingMode::Indifferent` to prevent errors from being + /// emitted. + /// + /// However, since in practice + /// [people who learned nothing from BER vs DER seem to expect base64 to have one canonical encoding](https://eprint.iacr.org/2022/361), + /// the default setting is the stricter `DecodePaddingMode::RequireCanonicalPadding`. + /// + /// Or, if "canonical" in your circumstance means _no_ padding rather than padding to the + /// next multiple of four, there's `DecodePaddingMode::RequireNoPadding`. + pub const fn with_decode_padding_mode(self, mode: DecodePaddingMode) -> Self { + Self { + decode_padding_mode: mode, + ..self + } + } +} + +impl Default for GeneralPurposeConfig { + /// Delegates to [GeneralPurposeConfig::new]. + fn default() -> Self { + Self::new() + } +} + +impl Config for GeneralPurposeConfig { + fn encode_padding(&self) -> bool { + self.encode_padding + } +} + +/// A [GeneralPurpose] engine using the [alphabet::STANDARD] base64 alphabet and [PAD] config. +pub const STANDARD: GeneralPurpose = GeneralPurpose::new(&alphabet::STANDARD, PAD); + +/// A [GeneralPurpose] engine using the [alphabet::STANDARD] base64 alphabet and [NO_PAD] config. +pub const STANDARD_NO_PAD: GeneralPurpose = GeneralPurpose::new(&alphabet::STANDARD, NO_PAD); + +/// A [GeneralPurpose] engine using the [alphabet::URL_SAFE] base64 alphabet and [PAD] config. +pub const URL_SAFE: GeneralPurpose = GeneralPurpose::new(&alphabet::URL_SAFE, PAD); + +/// A [GeneralPurpose] engine using the [alphabet::URL_SAFE] base64 alphabet and [NO_PAD] config. +pub const URL_SAFE_NO_PAD: GeneralPurpose = GeneralPurpose::new(&alphabet::URL_SAFE, NO_PAD); + +/// Include padding bytes when encoding, and require that they be present when decoding. +/// +/// This is the standard per the base64 RFC, but consider using [NO_PAD] instead as padding serves +/// little purpose in practice. +pub const PAD: GeneralPurposeConfig = GeneralPurposeConfig::new(); + +/// Don't add padding when encoding, and require no padding when decoding. +pub const NO_PAD: GeneralPurposeConfig = GeneralPurposeConfig::new() + .with_encode_padding(false) + .with_decode_padding_mode(DecodePaddingMode::RequireNone); diff --git a/vendor/base64/src/engine/mod.rs b/vendor/base64/src/engine/mod.rs new file mode 100644 index 0000000..f2cc33f --- /dev/null +++ b/vendor/base64/src/engine/mod.rs @@ -0,0 +1,478 @@ +//! Provides the [Engine] abstraction and out of the box implementations. +#[cfg(any(feature = "alloc", test))] +use crate::chunked_encoder; +use crate::{ + encode::{encode_with_padding, EncodeSliceError}, + encoded_len, DecodeError, DecodeSliceError, +}; +#[cfg(any(feature = "alloc", test))] +use alloc::vec::Vec; + +#[cfg(any(feature = "alloc", test))] +use alloc::{string::String, vec}; + +pub mod general_purpose; + +#[cfg(test)] +mod naive; + +#[cfg(test)] +mod tests; + +pub use general_purpose::{GeneralPurpose, GeneralPurposeConfig}; + +/// An `Engine` provides low-level encoding and decoding operations that all other higher-level parts of the API use. Users of the library will generally not need to implement this. +/// +/// Different implementations offer different characteristics. The library currently ships with +/// [GeneralPurpose] that offers good speed and works on any CPU, with more choices +/// coming later, like a constant-time one when side channel resistance is called for, and vendor-specific vectorized ones for more speed. +/// +/// See [general_purpose::STANDARD_NO_PAD] if you just want standard base64. Otherwise, when possible, it's +/// recommended to store the engine in a `const` so that references to it won't pose any lifetime +/// issues, and to avoid repeating the cost of engine setup. +/// +/// Since almost nobody will need to implement `Engine`, docs for internal methods are hidden. +// When adding an implementation of Engine, include them in the engine test suite: +// - add an implementation of [engine::tests::EngineWrapper] +// - add the implementation to the `all_engines` macro +// All tests run on all engines listed in the macro. +pub trait Engine: Send + Sync { + /// The config type used by this engine + type Config: Config; + /// The decode estimate used by this engine + type DecodeEstimate: DecodeEstimate; + + /// This is not meant to be called directly; it is only for `Engine` implementors. + /// See the other `encode*` functions on this trait. + /// + /// Encode the `input` bytes into the `output` buffer based on the mapping in `encode_table`. + /// + /// `output` will be long enough to hold the encoded data. + /// + /// Returns the number of bytes written. + /// + /// No padding should be written; that is handled separately. + /// + /// Must not write any bytes into the output slice other than the encoded data. + #[doc(hidden)] + fn internal_encode(&self, input: &[u8], output: &mut [u8]) -> usize; + + /// This is not meant to be called directly; it is only for `Engine` implementors. + /// + /// As an optimization to prevent the decoded length from being calculated twice, it is + /// sometimes helpful to have a conservative estimate of the decoded size before doing the + /// decoding, so this calculation is done separately and passed to [Engine::decode()] as needed. + #[doc(hidden)] + fn internal_decoded_len_estimate(&self, input_len: usize) -> Self::DecodeEstimate; + + /// This is not meant to be called directly; it is only for `Engine` implementors. + /// See the other `decode*` functions on this trait. + /// + /// Decode `input` base64 bytes into the `output` buffer. + /// + /// `decode_estimate` is the result of [Engine::internal_decoded_len_estimate()], which is passed in to avoid + /// calculating it again (expensive on short inputs).` + /// + /// Each complete 4-byte chunk of encoded data decodes to 3 bytes of decoded data, but this + /// function must also handle the final possibly partial chunk. + /// If the input length is not a multiple of 4, or uses padding bytes to reach a multiple of 4, + /// the trailing 2 or 3 bytes must decode to 1 or 2 bytes, respectively, as per the + /// [RFC](https://tools.ietf.org/html/rfc4648#section-3.5). + /// + /// Decoding must not write any bytes into the output slice other than the decoded data. + /// + /// Non-canonical trailing bits in the final tokens or non-canonical padding must be reported as + /// errors unless the engine is configured otherwise. + #[doc(hidden)] + fn internal_decode( + &self, + input: &[u8], + output: &mut [u8], + decode_estimate: Self::DecodeEstimate, + ) -> Result; + + /// Returns the config for this engine. + fn config(&self) -> &Self::Config; + + /// Encode arbitrary octets as base64 using the provided `Engine`. + /// Returns a `String`. + /// + /// # Example + /// + /// ```rust + /// use base64::{Engine as _, engine::{self, general_purpose}, alphabet}; + /// + /// let b64 = general_purpose::STANDARD.encode(b"hello world~"); + /// println!("{}", b64); + /// + /// const CUSTOM_ENGINE: engine::GeneralPurpose = + /// engine::GeneralPurpose::new(&alphabet::URL_SAFE, general_purpose::NO_PAD); + /// + /// let b64_url = CUSTOM_ENGINE.encode(b"hello internet~"); + /// ``` + #[cfg(any(feature = "alloc", test))] + #[inline] + fn encode>(&self, input: T) -> String { + fn inner(engine: &E, input_bytes: &[u8]) -> String + where + E: Engine + ?Sized, + { + let encoded_size = encoded_len(input_bytes.len(), engine.config().encode_padding()) + .expect("integer overflow when calculating buffer size"); + + let mut buf = vec![0; encoded_size]; + + encode_with_padding(input_bytes, &mut buf[..], engine, encoded_size); + + String::from_utf8(buf).expect("Invalid UTF8") + } + + inner(self, input.as_ref()) + } + + /// Encode arbitrary octets as base64 into a supplied `String`. + /// Writes into the supplied `String`, which may allocate if its internal buffer isn't big enough. + /// + /// # Example + /// + /// ```rust + /// use base64::{Engine as _, engine::{self, general_purpose}, alphabet}; + /// const CUSTOM_ENGINE: engine::GeneralPurpose = + /// engine::GeneralPurpose::new(&alphabet::URL_SAFE, general_purpose::NO_PAD); + /// + /// fn main() { + /// let mut buf = String::new(); + /// general_purpose::STANDARD.encode_string(b"hello world~", &mut buf); + /// println!("{}", buf); + /// + /// buf.clear(); + /// CUSTOM_ENGINE.encode_string(b"hello internet~", &mut buf); + /// println!("{}", buf); + /// } + /// ``` + #[cfg(any(feature = "alloc", test))] + #[inline] + fn encode_string>(&self, input: T, output_buf: &mut String) { + fn inner(engine: &E, input_bytes: &[u8], output_buf: &mut String) + where + E: Engine + ?Sized, + { + let mut sink = chunked_encoder::StringSink::new(output_buf); + + chunked_encoder::ChunkedEncoder::new(engine) + .encode(input_bytes, &mut sink) + .expect("Writing to a String shouldn't fail"); + } + + inner(self, input.as_ref(), output_buf) + } + + /// Encode arbitrary octets as base64 into a supplied slice. + /// Writes into the supplied output buffer. + /// + /// This is useful if you wish to avoid allocation entirely (e.g. encoding into a stack-resident + /// or statically-allocated buffer). + /// + /// # Example + /// + #[cfg_attr(feature = "alloc", doc = "```")] + #[cfg_attr(not(feature = "alloc"), doc = "```ignore")] + /// use base64::{Engine as _, engine::general_purpose}; + /// let s = b"hello internet!"; + /// let mut buf = Vec::new(); + /// // make sure we'll have a slice big enough for base64 + padding + /// buf.resize(s.len() * 4 / 3 + 4, 0); + /// + /// let bytes_written = general_purpose::STANDARD.encode_slice(s, &mut buf).unwrap(); + /// + /// // shorten our vec down to just what was written + /// buf.truncate(bytes_written); + /// + /// assert_eq!(s, general_purpose::STANDARD.decode(&buf).unwrap().as_slice()); + /// ``` + #[inline] + fn encode_slice>( + &self, + input: T, + output_buf: &mut [u8], + ) -> Result { + fn inner( + engine: &E, + input_bytes: &[u8], + output_buf: &mut [u8], + ) -> Result + where + E: Engine + ?Sized, + { + let encoded_size = encoded_len(input_bytes.len(), engine.config().encode_padding()) + .expect("usize overflow when calculating buffer size"); + + if output_buf.len() < encoded_size { + return Err(EncodeSliceError::OutputSliceTooSmall); + } + + let b64_output = &mut output_buf[0..encoded_size]; + + encode_with_padding(input_bytes, b64_output, engine, encoded_size); + + Ok(encoded_size) + } + + inner(self, input.as_ref(), output_buf) + } + + /// Decode the input into a new `Vec`. + /// + /// # Example + /// + /// ```rust + /// use base64::{Engine as _, alphabet, engine::{self, general_purpose}}; + /// + /// let bytes = general_purpose::STANDARD + /// .decode("aGVsbG8gd29ybGR+Cg==").unwrap(); + /// println!("{:?}", bytes); + /// + /// // custom engine setup + /// let bytes_url = engine::GeneralPurpose::new( + /// &alphabet::URL_SAFE, + /// general_purpose::NO_PAD) + /// .decode("aGVsbG8gaW50ZXJuZXR-Cg").unwrap(); + /// println!("{:?}", bytes_url); + /// ``` + #[cfg(any(feature = "alloc", test))] + #[inline] + fn decode>(&self, input: T) -> Result, DecodeError> { + fn inner(engine: &E, input_bytes: &[u8]) -> Result, DecodeError> + where + E: Engine + ?Sized, + { + let estimate = engine.internal_decoded_len_estimate(input_bytes.len()); + let mut buffer = vec![0; estimate.decoded_len_estimate()]; + + let bytes_written = engine + .internal_decode(input_bytes, &mut buffer, estimate) + .map_err(|e| match e { + DecodeSliceError::DecodeError(e) => e, + DecodeSliceError::OutputSliceTooSmall => { + unreachable!("Vec is sized conservatively") + } + })? + .decoded_len; + + buffer.truncate(bytes_written); + + Ok(buffer) + } + + inner(self, input.as_ref()) + } + + /// Decode the `input` into the supplied `buffer`. + /// + /// Writes into the supplied `Vec`, which may allocate if its internal buffer isn't big enough. + /// Returns a `Result` containing an empty tuple, aka `()`. + /// + /// # Example + /// + /// ```rust + /// use base64::{Engine as _, alphabet, engine::{self, general_purpose}}; + /// const CUSTOM_ENGINE: engine::GeneralPurpose = + /// engine::GeneralPurpose::new(&alphabet::URL_SAFE, general_purpose::PAD); + /// + /// fn main() { + /// use base64::Engine; + /// let mut buffer = Vec::::new(); + /// // with the default engine + /// general_purpose::STANDARD + /// .decode_vec("aGVsbG8gd29ybGR+Cg==", &mut buffer,).unwrap(); + /// println!("{:?}", buffer); + /// + /// buffer.clear(); + /// + /// // with a custom engine + /// CUSTOM_ENGINE.decode_vec( + /// "aGVsbG8gaW50ZXJuZXR-Cg==", + /// &mut buffer, + /// ).unwrap(); + /// println!("{:?}", buffer); + /// } + /// ``` + #[cfg(any(feature = "alloc", test))] + #[inline] + fn decode_vec>( + &self, + input: T, + buffer: &mut Vec, + ) -> Result<(), DecodeError> { + fn inner(engine: &E, input_bytes: &[u8], buffer: &mut Vec) -> Result<(), DecodeError> + where + E: Engine + ?Sized, + { + let starting_output_len = buffer.len(); + let estimate = engine.internal_decoded_len_estimate(input_bytes.len()); + + let total_len_estimate = estimate + .decoded_len_estimate() + .checked_add(starting_output_len) + .expect("Overflow when calculating output buffer length"); + + buffer.resize(total_len_estimate, 0); + + let buffer_slice = &mut buffer.as_mut_slice()[starting_output_len..]; + + let bytes_written = engine + .internal_decode(input_bytes, buffer_slice, estimate) + .map_err(|e| match e { + DecodeSliceError::DecodeError(e) => e, + DecodeSliceError::OutputSliceTooSmall => { + unreachable!("Vec is sized conservatively") + } + })? + .decoded_len; + + buffer.truncate(starting_output_len + bytes_written); + + Ok(()) + } + + inner(self, input.as_ref(), buffer) + } + + /// Decode the input into the provided output slice. + /// + /// Returns the number of bytes written to the slice, or an error if `output` is smaller than + /// the estimated decoded length. + /// + /// This will not write any bytes past exactly what is decoded (no stray garbage bytes at the end). + /// + /// See [crate::decoded_len_estimate] for calculating buffer sizes. + /// + /// See [Engine::decode_slice_unchecked] for a version that panics instead of returning an error + /// if the output buffer is too small. + #[inline] + fn decode_slice>( + &self, + input: T, + output: &mut [u8], + ) -> Result { + fn inner( + engine: &E, + input_bytes: &[u8], + output: &mut [u8], + ) -> Result + where + E: Engine + ?Sized, + { + engine + .internal_decode( + input_bytes, + output, + engine.internal_decoded_len_estimate(input_bytes.len()), + ) + .map(|dm| dm.decoded_len) + } + + inner(self, input.as_ref(), output) + } + + /// Decode the input into the provided output slice. + /// + /// Returns the number of bytes written to the slice. + /// + /// This will not write any bytes past exactly what is decoded (no stray garbage bytes at the end). + /// + /// See [crate::decoded_len_estimate] for calculating buffer sizes. + /// + /// See [Engine::decode_slice] for a version that returns an error instead of panicking if the output + /// buffer is too small. + /// + /// # Panics + /// + /// Panics if the provided output buffer is too small for the decoded data. + #[inline] + fn decode_slice_unchecked>( + &self, + input: T, + output: &mut [u8], + ) -> Result { + fn inner(engine: &E, input_bytes: &[u8], output: &mut [u8]) -> Result + where + E: Engine + ?Sized, + { + engine + .internal_decode( + input_bytes, + output, + engine.internal_decoded_len_estimate(input_bytes.len()), + ) + .map(|dm| dm.decoded_len) + .map_err(|e| match e { + DecodeSliceError::DecodeError(e) => e, + DecodeSliceError::OutputSliceTooSmall => { + panic!("Output slice is too small") + } + }) + } + + inner(self, input.as_ref(), output) + } +} + +/// The minimal level of configuration that engines must support. +pub trait Config { + /// Returns `true` if padding should be added after the encoded output. + /// + /// Padding is added outside the engine's encode() since the engine may be used + /// to encode only a chunk of the overall output, so it can't always know when + /// the output is "done" and would therefore need padding (if configured). + // It could be provided as a separate parameter when encoding, but that feels like + // leaking an implementation detail to the user, and it's hopefully more convenient + // to have to only pass one thing (the engine) to any part of the API. + fn encode_padding(&self) -> bool; +} + +/// The decode estimate used by an engine implementation. Users do not need to interact with this; +/// it is only for engine implementors. +/// +/// Implementors may store relevant data here when constructing this to avoid having to calculate +/// them again during actual decoding. +pub trait DecodeEstimate { + /// Returns a conservative (err on the side of too big) estimate of the decoded length to use + /// for pre-allocating buffers, etc. + /// + /// The estimate must be no larger than the next largest complete triple of decoded bytes. + /// That is, the final quad of tokens to decode may be assumed to be complete with no padding. + fn decoded_len_estimate(&self) -> usize; +} + +/// Controls how pad bytes are handled when decoding. +/// +/// Each [Engine] must support at least the behavior indicated by +/// [DecodePaddingMode::RequireCanonical], and may support other modes. +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub enum DecodePaddingMode { + /// Canonical padding is allowed, but any fewer padding bytes than that is also allowed. + Indifferent, + /// Padding must be canonical (0, 1, or 2 `=` as needed to produce a 4 byte suffix). + RequireCanonical, + /// Padding must be absent -- for when you want predictable padding, without any wasted bytes. + RequireNone, +} + +/// Metadata about the result of a decode operation +#[derive(PartialEq, Eq, Debug)] +pub struct DecodeMetadata { + /// Number of decoded bytes output + pub(crate) decoded_len: usize, + /// Offset of the first padding byte in the input, if any + pub(crate) padding_offset: Option, +} + +impl DecodeMetadata { + pub(crate) fn new(decoded_bytes: usize, padding_index: Option) -> Self { + Self { + decoded_len: decoded_bytes, + padding_offset: padding_index, + } + } +} diff --git a/vendor/base64/src/engine/naive.rs b/vendor/base64/src/engine/naive.rs new file mode 100644 index 0000000..af509bf --- /dev/null +++ b/vendor/base64/src/engine/naive.rs @@ -0,0 +1,195 @@ +use crate::{ + alphabet::Alphabet, + engine::{ + general_purpose::{self, decode_table, encode_table}, + Config, DecodeEstimate, DecodeMetadata, DecodePaddingMode, Engine, + }, + DecodeError, DecodeSliceError, +}; +use std::ops::{BitAnd, BitOr, Shl, Shr}; + +/// Comparatively simple implementation that can be used as something to compare against in tests +pub struct Naive { + encode_table: [u8; 64], + decode_table: [u8; 256], + config: NaiveConfig, +} + +impl Naive { + const ENCODE_INPUT_CHUNK_SIZE: usize = 3; + const DECODE_INPUT_CHUNK_SIZE: usize = 4; + + pub const fn new(alphabet: &Alphabet, config: NaiveConfig) -> Self { + Self { + encode_table: encode_table(alphabet), + decode_table: decode_table(alphabet), + config, + } + } + + fn decode_byte_into_u32(&self, offset: usize, byte: u8) -> Result { + let decoded = self.decode_table[byte as usize]; + + if decoded == general_purpose::INVALID_VALUE { + return Err(DecodeError::InvalidByte(offset, byte)); + } + + Ok(decoded as u32) + } +} + +impl Engine for Naive { + type Config = NaiveConfig; + type DecodeEstimate = NaiveEstimate; + + fn internal_encode(&self, input: &[u8], output: &mut [u8]) -> usize { + // complete chunks first + + const LOW_SIX_BITS: u32 = 0x3F; + + let rem = input.len() % Self::ENCODE_INPUT_CHUNK_SIZE; + // will never underflow + let complete_chunk_len = input.len() - rem; + + let mut input_index = 0_usize; + let mut output_index = 0_usize; + if let Some(last_complete_chunk_index) = + complete_chunk_len.checked_sub(Self::ENCODE_INPUT_CHUNK_SIZE) + { + while input_index <= last_complete_chunk_index { + let chunk = &input[input_index..input_index + Self::ENCODE_INPUT_CHUNK_SIZE]; + + // populate low 24 bits from 3 bytes + let chunk_int: u32 = + (chunk[0] as u32).shl(16) | (chunk[1] as u32).shl(8) | (chunk[2] as u32); + // encode 4x 6-bit output bytes + output[output_index] = self.encode_table[chunk_int.shr(18) as usize]; + output[output_index + 1] = + self.encode_table[chunk_int.shr(12_u8).bitand(LOW_SIX_BITS) as usize]; + output[output_index + 2] = + self.encode_table[chunk_int.shr(6_u8).bitand(LOW_SIX_BITS) as usize]; + output[output_index + 3] = + self.encode_table[chunk_int.bitand(LOW_SIX_BITS) as usize]; + + input_index += Self::ENCODE_INPUT_CHUNK_SIZE; + output_index += 4; + } + } + + // then leftovers + if rem == 2 { + let chunk = &input[input_index..input_index + 2]; + + // high six bits of chunk[0] + output[output_index] = self.encode_table[chunk[0].shr(2) as usize]; + // bottom 2 bits of [0], high 4 bits of [1] + output[output_index + 1] = + self.encode_table[(chunk[0].shl(4_u8).bitor(chunk[1].shr(4_u8)) as u32) + .bitand(LOW_SIX_BITS) as usize]; + // bottom 4 bits of [1], with the 2 bottom bits as zero + output[output_index + 2] = + self.encode_table[(chunk[1].shl(2_u8) as u32).bitand(LOW_SIX_BITS) as usize]; + + output_index += 3; + } else if rem == 1 { + let byte = input[input_index]; + output[output_index] = self.encode_table[byte.shr(2) as usize]; + output[output_index + 1] = + self.encode_table[(byte.shl(4_u8) as u32).bitand(LOW_SIX_BITS) as usize]; + output_index += 2; + } + + output_index + } + + fn internal_decoded_len_estimate(&self, input_len: usize) -> Self::DecodeEstimate { + NaiveEstimate::new(input_len) + } + + fn internal_decode( + &self, + input: &[u8], + output: &mut [u8], + estimate: Self::DecodeEstimate, + ) -> Result { + let complete_nonterminal_quads_len = general_purpose::decode::complete_quads_len( + input, + estimate.rem, + output.len(), + &self.decode_table, + )?; + + const BOTTOM_BYTE: u32 = 0xFF; + + for (chunk_index, chunk) in input[..complete_nonterminal_quads_len] + .chunks_exact(4) + .enumerate() + { + let input_index = chunk_index * 4; + let output_index = chunk_index * 3; + + let decoded_int: u32 = self.decode_byte_into_u32(input_index, chunk[0])?.shl(18) + | self + .decode_byte_into_u32(input_index + 1, chunk[1])? + .shl(12) + | self.decode_byte_into_u32(input_index + 2, chunk[2])?.shl(6) + | self.decode_byte_into_u32(input_index + 3, chunk[3])?; + + output[output_index] = decoded_int.shr(16_u8).bitand(BOTTOM_BYTE) as u8; + output[output_index + 1] = decoded_int.shr(8_u8).bitand(BOTTOM_BYTE) as u8; + output[output_index + 2] = decoded_int.bitand(BOTTOM_BYTE) as u8; + } + + general_purpose::decode_suffix::decode_suffix( + input, + complete_nonterminal_quads_len, + output, + complete_nonterminal_quads_len / 4 * 3, + &self.decode_table, + self.config.decode_allow_trailing_bits, + self.config.decode_padding_mode, + ) + } + + fn config(&self) -> &Self::Config { + &self.config + } +} + +pub struct NaiveEstimate { + /// remainder from dividing input by `Naive::DECODE_CHUNK_SIZE` + rem: usize, + /// Length of input that is in complete `Naive::DECODE_CHUNK_SIZE`-length chunks + complete_chunk_len: usize, +} + +impl NaiveEstimate { + fn new(input_len: usize) -> Self { + let rem = input_len % Naive::DECODE_INPUT_CHUNK_SIZE; + let complete_chunk_len = input_len - rem; + + Self { + rem, + complete_chunk_len, + } + } +} + +impl DecodeEstimate for NaiveEstimate { + fn decoded_len_estimate(&self) -> usize { + ((self.complete_chunk_len / 4) + ((self.rem > 0) as usize)) * 3 + } +} + +#[derive(Clone, Copy, Debug)] +pub struct NaiveConfig { + pub encode_padding: bool, + pub decode_allow_trailing_bits: bool, + pub decode_padding_mode: DecodePaddingMode, +} + +impl Config for NaiveConfig { + fn encode_padding(&self) -> bool { + self.encode_padding + } +} diff --git a/vendor/base64/src/engine/tests.rs b/vendor/base64/src/engine/tests.rs new file mode 100644 index 0000000..72bbf4b --- /dev/null +++ b/vendor/base64/src/engine/tests.rs @@ -0,0 +1,1579 @@ +// rstest_reuse template functions have unused variables +#![allow(unused_variables)] + +use rand::{ + self, + distributions::{self, Distribution as _}, + rngs, Rng as _, SeedableRng as _, +}; +use rstest::rstest; +use rstest_reuse::{apply, template}; +use std::{collections, fmt, io::Read as _}; + +use crate::{ + alphabet::{Alphabet, STANDARD}, + encode::add_padding, + encoded_len, + engine::{ + general_purpose, naive, Config, DecodeEstimate, DecodeMetadata, DecodePaddingMode, Engine, + }, + read::DecoderReader, + tests::{assert_encode_sanity, random_alphabet, random_config}, + DecodeError, DecodeSliceError, PAD_BYTE, +}; + +// the case::foo syntax includes the "foo" in the generated test method names +#[template] +#[rstest(engine_wrapper, +case::general_purpose(GeneralPurposeWrapper {}), +case::naive(NaiveWrapper {}), +case::decoder_reader(DecoderReaderEngineWrapper {}), +)] +fn all_engines(engine_wrapper: E) {} + +/// Some decode tests don't make sense for use with `DecoderReader` as they are difficult to +/// reason about or otherwise inapplicable given how DecoderReader slice up its input along +/// chunk boundaries. +#[template] +#[rstest(engine_wrapper, +case::general_purpose(GeneralPurposeWrapper {}), +case::naive(NaiveWrapper {}), +)] +fn all_engines_except_decoder_reader(engine_wrapper: E) {} + +#[apply(all_engines)] +fn rfc_test_vectors_std_alphabet(engine_wrapper: E) { + let data = vec![ + ("", ""), + ("f", "Zg=="), + ("fo", "Zm8="), + ("foo", "Zm9v"), + ("foob", "Zm9vYg=="), + ("fooba", "Zm9vYmE="), + ("foobar", "Zm9vYmFy"), + ]; + + let engine = E::standard(); + let engine_no_padding = E::standard_unpadded(); + + for (orig, encoded) in &data { + let encoded_without_padding = encoded.trim_end_matches('='); + + // unpadded + { + let mut encode_buf = [0_u8; 8]; + let mut decode_buf = [0_u8; 6]; + + let encode_len = + engine_no_padding.internal_encode(orig.as_bytes(), &mut encode_buf[..]); + assert_eq!( + &encoded_without_padding, + &std::str::from_utf8(&encode_buf[0..encode_len]).unwrap() + ); + let decode_len = engine_no_padding + .decode_slice_unchecked(encoded_without_padding.as_bytes(), &mut decode_buf[..]) + .unwrap(); + assert_eq!(orig.len(), decode_len); + + assert_eq!( + orig, + &std::str::from_utf8(&decode_buf[0..decode_len]).unwrap() + ); + + // if there was any padding originally, the no padding engine won't decode it + if encoded.as_bytes().contains(&PAD_BYTE) { + assert_eq!( + Err(DecodeError::InvalidPadding), + engine_no_padding.decode(encoded) + ) + } + } + + // padded + { + let mut encode_buf = [0_u8; 8]; + let mut decode_buf = [0_u8; 6]; + + let encode_len = engine.internal_encode(orig.as_bytes(), &mut encode_buf[..]); + assert_eq!( + // doesn't have padding added yet + &encoded_without_padding, + &std::str::from_utf8(&encode_buf[0..encode_len]).unwrap() + ); + let pad_len = add_padding(encode_len, &mut encode_buf[encode_len..]); + assert_eq!(encoded.as_bytes(), &encode_buf[..encode_len + pad_len]); + + let decode_len = engine + .decode_slice_unchecked(encoded.as_bytes(), &mut decode_buf[..]) + .unwrap(); + assert_eq!(orig.len(), decode_len); + + assert_eq!( + orig, + &std::str::from_utf8(&decode_buf[0..decode_len]).unwrap() + ); + + // if there was (canonical) padding, and we remove it, the standard engine won't decode + if encoded.as_bytes().contains(&PAD_BYTE) { + assert_eq!( + Err(DecodeError::InvalidPadding), + engine.decode(encoded_without_padding) + ) + } + } + } +} + +#[apply(all_engines)] +fn roundtrip_random(engine_wrapper: E) { + let mut rng = seeded_rng(); + + let mut orig_data = Vec::::new(); + let mut encode_buf = Vec::::new(); + let mut decode_buf = Vec::::new(); + + let len_range = distributions::Uniform::new(1, 1_000); + + for _ in 0..10_000 { + let engine = E::random(&mut rng); + + orig_data.clear(); + encode_buf.clear(); + decode_buf.clear(); + + let (orig_len, _, encoded_len) = generate_random_encoded_data( + &engine, + &mut orig_data, + &mut encode_buf, + &mut rng, + &len_range, + ); + + // exactly the right size + decode_buf.resize(orig_len, 0); + + let dec_len = engine + .decode_slice_unchecked(&encode_buf[0..encoded_len], &mut decode_buf[..]) + .unwrap(); + + assert_eq!(orig_len, dec_len); + assert_eq!(&orig_data[..], &decode_buf[..dec_len]); + } +} + +#[apply(all_engines)] +fn encode_doesnt_write_extra_bytes(engine_wrapper: E) { + let mut rng = seeded_rng(); + + let mut orig_data = Vec::::new(); + let mut encode_buf = Vec::::new(); + let mut encode_buf_backup = Vec::::new(); + + let input_len_range = distributions::Uniform::new(0, 1000); + + for _ in 0..10_000 { + let engine = E::random(&mut rng); + let padded = engine.config().encode_padding(); + + orig_data.clear(); + encode_buf.clear(); + encode_buf_backup.clear(); + + let orig_len = fill_rand(&mut orig_data, &mut rng, &input_len_range); + + let prefix_len = 1024; + // plenty of prefix and suffix + fill_rand_len(&mut encode_buf, &mut rng, prefix_len * 2 + orig_len * 2); + encode_buf_backup.extend_from_slice(&encode_buf[..]); + + let expected_encode_len_no_pad = encoded_len(orig_len, false).unwrap(); + + let encoded_len_no_pad = + engine.internal_encode(&orig_data[..], &mut encode_buf[prefix_len..]); + assert_eq!(expected_encode_len_no_pad, encoded_len_no_pad); + + // no writes past what it claimed to write + assert_eq!(&encode_buf_backup[..prefix_len], &encode_buf[..prefix_len]); + assert_eq!( + &encode_buf_backup[(prefix_len + encoded_len_no_pad)..], + &encode_buf[(prefix_len + encoded_len_no_pad)..] + ); + + let encoded_data = &encode_buf[prefix_len..(prefix_len + encoded_len_no_pad)]; + assert_encode_sanity( + std::str::from_utf8(encoded_data).unwrap(), + // engines don't pad + false, + orig_len, + ); + + // pad so we can decode it in case our random engine requires padding + let pad_len = if padded { + add_padding( + encoded_len_no_pad, + &mut encode_buf[prefix_len + encoded_len_no_pad..], + ) + } else { + 0 + }; + + assert_eq!( + orig_data, + engine + .decode(&encode_buf[prefix_len..(prefix_len + encoded_len_no_pad + pad_len)],) + .unwrap() + ); + } +} + +#[apply(all_engines)] +fn encode_engine_slice_fits_into_precisely_sized_slice(engine_wrapper: E) { + let mut orig_data = Vec::new(); + let mut encoded_data = Vec::new(); + let mut decoded = Vec::new(); + + let input_len_range = distributions::Uniform::new(0, 1000); + + let mut rng = rngs::SmallRng::from_entropy(); + + for _ in 0..10_000 { + orig_data.clear(); + encoded_data.clear(); + decoded.clear(); + + let input_len = input_len_range.sample(&mut rng); + + for _ in 0..input_len { + orig_data.push(rng.gen()); + } + + let engine = E::random(&mut rng); + + let encoded_size = encoded_len(input_len, engine.config().encode_padding()).unwrap(); + + encoded_data.resize(encoded_size, 0); + + assert_eq!( + encoded_size, + engine.encode_slice(&orig_data, &mut encoded_data).unwrap() + ); + + assert_encode_sanity( + std::str::from_utf8(&encoded_data[0..encoded_size]).unwrap(), + engine.config().encode_padding(), + input_len, + ); + + engine + .decode_vec(&encoded_data[0..encoded_size], &mut decoded) + .unwrap(); + assert_eq!(orig_data, decoded); + } +} + +#[apply(all_engines)] +fn decode_doesnt_write_extra_bytes(engine_wrapper: E) +where + E: EngineWrapper, + <::Engine as Engine>::Config: fmt::Debug, +{ + let mut rng = seeded_rng(); + + let mut orig_data = Vec::::new(); + let mut encode_buf = Vec::::new(); + let mut decode_buf = Vec::::new(); + let mut decode_buf_backup = Vec::::new(); + + let len_range = distributions::Uniform::new(1, 1_000); + + for _ in 0..10_000 { + let engine = E::random(&mut rng); + + orig_data.clear(); + encode_buf.clear(); + decode_buf.clear(); + decode_buf_backup.clear(); + + let orig_len = fill_rand(&mut orig_data, &mut rng, &len_range); + encode_buf.resize(orig_len * 2 + 100, 0); + + let encoded_len = engine + .encode_slice(&orig_data[..], &mut encode_buf[..]) + .unwrap(); + encode_buf.truncate(encoded_len); + + // oversize decode buffer so we can easily tell if it writes anything more than + // just the decoded data + let prefix_len = 1024; + // plenty of prefix and suffix + fill_rand_len(&mut decode_buf, &mut rng, prefix_len * 2 + orig_len * 2); + decode_buf_backup.extend_from_slice(&decode_buf[..]); + + let dec_len = engine + .decode_slice_unchecked(&encode_buf, &mut decode_buf[prefix_len..]) + .unwrap(); + + assert_eq!(orig_len, dec_len); + assert_eq!( + &orig_data[..], + &decode_buf[prefix_len..prefix_len + dec_len] + ); + assert_eq!(&decode_buf_backup[..prefix_len], &decode_buf[..prefix_len]); + assert_eq!( + &decode_buf_backup[prefix_len + dec_len..], + &decode_buf[prefix_len + dec_len..] + ); + } +} + +#[apply(all_engines)] +fn decode_detect_invalid_last_symbol(engine_wrapper: E) { + // 0xFF -> "/w==", so all letters > w, 0-9, and '+', '/' should get InvalidLastSymbol + let engine = E::standard(); + + assert_eq!(Ok(vec![0x89, 0x85]), engine.decode("iYU=")); + assert_eq!(Ok(vec![0xFF]), engine.decode("/w==")); + + for (suffix, offset) in vec![ + // suffix, offset of bad byte from start of suffix + ("/x==", 1_usize), + ("/z==", 1_usize), + ("/0==", 1_usize), + ("/9==", 1_usize), + ("/+==", 1_usize), + ("//==", 1_usize), + // trailing 01 + ("iYV=", 2_usize), + // trailing 10 + ("iYW=", 2_usize), + // trailing 11 + ("iYX=", 2_usize), + ] { + for prefix_quads in 0..256 { + let mut encoded = "AAAA".repeat(prefix_quads); + encoded.push_str(suffix); + + assert_eq!( + Err(DecodeError::InvalidLastSymbol( + encoded.len() - 4 + offset, + suffix.as_bytes()[offset], + )), + engine.decode(encoded.as_str()) + ); + } + } +} + +#[apply(all_engines)] +fn decode_detect_1_valid_symbol_in_last_quad_invalid_length(engine_wrapper: E) { + for len in (0_usize..256).map(|len| len * 4 + 1) { + for mode in all_pad_modes() { + let mut input = vec![b'A'; len]; + + let engine = E::standard_with_pad_mode(true, mode); + + assert_eq!(Err(DecodeError::InvalidLength(len)), engine.decode(&input)); + // if we add padding, then the first pad byte in the quad is invalid because it should + // be the second symbol + for _ in 0..3 { + input.push(PAD_BYTE); + assert_eq!( + Err(DecodeError::InvalidByte(len, PAD_BYTE)), + engine.decode(&input) + ); + } + } + } +} + +#[apply(all_engines)] +fn decode_detect_1_invalid_byte_in_last_quad_invalid_byte(engine_wrapper: E) { + for prefix_len in (0_usize..256).map(|len| len * 4) { + for mode in all_pad_modes() { + let mut input = vec![b'A'; prefix_len]; + input.push(b'*'); + + let engine = E::standard_with_pad_mode(true, mode); + + assert_eq!( + Err(DecodeError::InvalidByte(prefix_len, b'*')), + engine.decode(&input) + ); + // adding padding doesn't matter + for _ in 0..3 { + input.push(PAD_BYTE); + assert_eq!( + Err(DecodeError::InvalidByte(prefix_len, b'*')), + engine.decode(&input) + ); + } + } + } +} + +#[apply(all_engines)] +fn decode_detect_invalid_last_symbol_every_possible_two_symbols( + engine_wrapper: E, +) { + let engine = E::standard(); + + let mut base64_to_bytes = collections::HashMap::new(); + + for b in 0_u8..=255 { + let mut b64 = vec![0_u8; 4]; + assert_eq!(2, engine.internal_encode(&[b], &mut b64[..])); + let _ = add_padding(2, &mut b64[2..]); + + assert!(base64_to_bytes.insert(b64, vec![b]).is_none()); + } + + // every possible combination of trailing symbols must either decode to 1 byte or get InvalidLastSymbol, with or without any leading chunks + + let mut prefix = Vec::new(); + for _ in 0..256 { + let mut clone = prefix.clone(); + + let mut symbols = [0_u8; 4]; + for &s1 in STANDARD.symbols.iter() { + symbols[0] = s1; + for &s2 in STANDARD.symbols.iter() { + symbols[1] = s2; + symbols[2] = PAD_BYTE; + symbols[3] = PAD_BYTE; + + // chop off previous symbols + clone.truncate(prefix.len()); + clone.extend_from_slice(&symbols[..]); + let decoded_prefix_len = prefix.len() / 4 * 3; + + match base64_to_bytes.get(&symbols[..]) { + Some(bytes) => { + let res = engine + .decode(&clone) + // remove prefix + .map(|decoded| decoded[decoded_prefix_len..].to_vec()); + + assert_eq!(Ok(bytes.clone()), res); + } + None => assert_eq!( + Err(DecodeError::InvalidLastSymbol(1, s2)), + engine.decode(&symbols[..]) + ), + } + } + } + + prefix.extend_from_slice(b"AAAA"); + } +} + +#[apply(all_engines)] +fn decode_detect_invalid_last_symbol_every_possible_three_symbols( + engine_wrapper: E, +) { + let engine = E::standard(); + + let mut base64_to_bytes = collections::HashMap::new(); + + let mut bytes = [0_u8; 2]; + for b1 in 0_u8..=255 { + bytes[0] = b1; + for b2 in 0_u8..=255 { + bytes[1] = b2; + let mut b64 = vec![0_u8; 4]; + assert_eq!(3, engine.internal_encode(&bytes, &mut b64[..])); + let _ = add_padding(3, &mut b64[3..]); + + let mut v = Vec::with_capacity(2); + v.extend_from_slice(&bytes[..]); + + assert!(base64_to_bytes.insert(b64, v).is_none()); + } + } + + // every possible combination of symbols must either decode to 2 bytes or get InvalidLastSymbol, with or without any leading chunks + + let mut prefix = Vec::new(); + let mut input = Vec::new(); + for _ in 0..256 { + input.clear(); + input.extend_from_slice(&prefix); + + let mut symbols = [0_u8; 4]; + for &s1 in STANDARD.symbols.iter() { + symbols[0] = s1; + for &s2 in STANDARD.symbols.iter() { + symbols[1] = s2; + for &s3 in STANDARD.symbols.iter() { + symbols[2] = s3; + symbols[3] = PAD_BYTE; + + // chop off previous symbols + input.truncate(prefix.len()); + input.extend_from_slice(&symbols[..]); + let decoded_prefix_len = prefix.len() / 4 * 3; + + match base64_to_bytes.get(&symbols[..]) { + Some(bytes) => { + let res = engine + .decode(&input) + // remove prefix + .map(|decoded| decoded[decoded_prefix_len..].to_vec()); + + assert_eq!(Ok(bytes.clone()), res); + } + None => assert_eq!( + Err(DecodeError::InvalidLastSymbol(2, s3)), + engine.decode(&symbols[..]) + ), + } + } + } + } + prefix.extend_from_slice(b"AAAA"); + } +} + +#[apply(all_engines)] +fn decode_invalid_trailing_bits_ignored_when_configured(engine_wrapper: E) { + let strict = E::standard(); + let forgiving = E::standard_allow_trailing_bits(); + + fn assert_tolerant_decode( + engine: &E, + input: &mut String, + b64_prefix_len: usize, + expected_decode_bytes: Vec, + data: &str, + ) { + let prefixed = prefixed_data(input, b64_prefix_len, data); + let decoded = engine.decode(prefixed); + // prefix is always complete chunks + let decoded_prefix_len = b64_prefix_len / 4 * 3; + assert_eq!( + Ok(expected_decode_bytes), + decoded.map(|v| v[decoded_prefix_len..].to_vec()) + ); + } + + let mut prefix = String::new(); + for _ in 0..256 { + let mut input = prefix.clone(); + + // example from https://github.com/marshallpierce/rust-base64/issues/75 + assert!(strict + .decode(prefixed_data(&mut input, prefix.len(), "/w==")) + .is_ok()); + assert!(strict + .decode(prefixed_data(&mut input, prefix.len(), "iYU=")) + .is_ok()); + // trailing 01 + assert_tolerant_decode(&forgiving, &mut input, prefix.len(), vec![255], "/x=="); + assert_tolerant_decode(&forgiving, &mut input, prefix.len(), vec![137, 133], "iYV="); + // trailing 10 + assert_tolerant_decode(&forgiving, &mut input, prefix.len(), vec![255], "/y=="); + assert_tolerant_decode(&forgiving, &mut input, prefix.len(), vec![137, 133], "iYW="); + // trailing 11 + assert_tolerant_decode(&forgiving, &mut input, prefix.len(), vec![255], "/z=="); + assert_tolerant_decode(&forgiving, &mut input, prefix.len(), vec![137, 133], "iYX="); + + prefix.push_str("AAAA"); + } +} + +#[apply(all_engines)] +fn decode_invalid_byte_error(engine_wrapper: E) { + let mut rng = seeded_rng(); + + let mut orig_data = Vec::::new(); + let mut encode_buf = Vec::::new(); + let mut decode_buf = Vec::::new(); + + let len_range = distributions::Uniform::new(1, 1_000); + + for _ in 0..100_000 { + let alphabet = random_alphabet(&mut rng); + let engine = E::random_alphabet(&mut rng, alphabet); + + orig_data.clear(); + encode_buf.clear(); + decode_buf.clear(); + + let (orig_len, encoded_len_just_data, encoded_len_with_padding) = + generate_random_encoded_data( + &engine, + &mut orig_data, + &mut encode_buf, + &mut rng, + &len_range, + ); + + // exactly the right size + decode_buf.resize(orig_len, 0); + + // replace one encoded byte with an invalid byte + let invalid_byte: u8 = loop { + let byte: u8 = rng.gen(); + + if alphabet.symbols.contains(&byte) || byte == PAD_BYTE { + continue; + } else { + break byte; + } + }; + + let invalid_range = distributions::Uniform::new(0, orig_len); + let invalid_index = invalid_range.sample(&mut rng); + encode_buf[invalid_index] = invalid_byte; + + assert_eq!( + Err(DecodeError::InvalidByte(invalid_index, invalid_byte)), + engine.decode_slice_unchecked( + &encode_buf[0..encoded_len_with_padding], + &mut decode_buf[..], + ) + ); + } +} + +/// Any amount of padding anywhere before the final non padding character = invalid byte at first +/// pad byte. +/// From this and [decode_padding_before_final_non_padding_char_error_invalid_byte_at_first_pad_non_canonical_padding_suffix_all_modes], +/// we know padding must extend contiguously to the end of the input. +#[apply(all_engines)] +fn decode_padding_before_final_non_padding_char_error_invalid_byte_at_first_pad_all_modes< + E: EngineWrapper, +>( + engine_wrapper: E, +) { + // Different amounts of padding, w/ offset from end for the last non-padding char. + // Only canonical padding, so Canonical mode will work. + let suffixes = &[("AA==", 2), ("AAA=", 1), ("AAAA", 0)]; + + for mode in pad_modes_allowing_padding() { + // We don't encode, so we don't care about encode padding. + let engine = E::standard_with_pad_mode(true, mode); + + decode_padding_before_final_non_padding_char_error_invalid_byte_at_first_pad( + engine, + suffixes.as_slice(), + ); + } +} + +/// See [decode_padding_before_final_non_padding_char_error_invalid_byte_at_first_pad_all_modes] +#[apply(all_engines)] +fn decode_padding_before_final_non_padding_char_error_invalid_byte_at_first_pad_non_canonical_padding_suffix< + E: EngineWrapper, +>( + engine_wrapper: E, +) { + // Different amounts of padding, w/ offset from end for the last non-padding char, and + // non-canonical padding. + let suffixes = [ + ("AA==", 2), + ("AA=", 1), + ("AA", 0), + ("AAA=", 1), + ("AAA", 0), + ("AAAA", 0), + ]; + + // We don't encode, so we don't care about encode padding. + // Decoding is indifferent so that we don't get caught by missing padding on the last quad + let engine = E::standard_with_pad_mode(true, DecodePaddingMode::Indifferent); + + decode_padding_before_final_non_padding_char_error_invalid_byte_at_first_pad( + engine, + suffixes.as_slice(), + ) +} + +fn decode_padding_before_final_non_padding_char_error_invalid_byte_at_first_pad( + engine: impl Engine, + suffixes: &[(&str, usize)], +) { + let mut rng = seeded_rng(); + + let prefix_quads_range = distributions::Uniform::from(0..=256); + + for _ in 0..100_000 { + for (suffix, suffix_offset) in suffixes.iter() { + let mut s = "AAAA".repeat(prefix_quads_range.sample(&mut rng)); + s.push_str(suffix); + let mut encoded = s.into_bytes(); + + // calculate a range to write padding into that leaves at least one non padding char + let last_non_padding_offset = encoded.len() - 1 - suffix_offset; + + // don't include last non padding char as it must stay not padding + let padding_end = rng.gen_range(0..last_non_padding_offset); + + // don't use more than 100 bytes of padding, but also use shorter lengths when + // padding_end is near the start of the encoded data to avoid biasing to padding + // the entire prefix on short lengths + let padding_len = rng.gen_range(1..=usize::min(100, padding_end + 1)); + let padding_start = padding_end.saturating_sub(padding_len); + + encoded[padding_start..=padding_end].fill(PAD_BYTE); + + // should still have non-padding before any final padding + assert_ne!(PAD_BYTE, encoded[last_non_padding_offset]); + assert_eq!( + Err(DecodeError::InvalidByte(padding_start, PAD_BYTE)), + engine.decode(&encoded), + "len: {}, input: {}", + encoded.len(), + String::from_utf8(encoded).unwrap() + ); + } + } +} + +/// Any amount of padding before final chunk that crosses over into final chunk with 1-4 bytes = +/// invalid byte at first pad byte. +/// From this we know the padding must start in the final chunk. +#[apply(all_engines)] +fn decode_padding_starts_before_final_chunk_error_invalid_byte_at_first_pad( + engine_wrapper: E, +) { + let mut rng = seeded_rng(); + + // must have at least one prefix quad + let prefix_quads_range = distributions::Uniform::from(1..256); + let suffix_pad_len_range = distributions::Uniform::from(1..=4); + // don't use no-padding mode, as the reader decode might decode a block that ends with + // valid padding, which should then be referenced when encountering the later invalid byte + for mode in pad_modes_allowing_padding() { + // we don't encode so we don't care about encode padding + let engine = E::standard_with_pad_mode(true, mode); + for _ in 0..100_000 { + let suffix_len = suffix_pad_len_range.sample(&mut rng); + // all 0 bits so we don't hit InvalidLastSymbol with the reader decoder + let mut encoded = "AAAA" + .repeat(prefix_quads_range.sample(&mut rng)) + .into_bytes(); + encoded.resize(encoded.len() + suffix_len, PAD_BYTE); + + // amount of padding must be long enough to extend back from suffix into previous + // quads + let padding_len = rng.gen_range(suffix_len + 1..encoded.len()); + // no non-padding after padding in this test, so padding goes to the end + let padding_start = encoded.len() - padding_len; + encoded[padding_start..].fill(PAD_BYTE); + + assert_eq!( + Err(DecodeError::InvalidByte(padding_start, PAD_BYTE)), + engine.decode(&encoded), + "suffix_len: {}, padding_len: {}, b64: {}", + suffix_len, + padding_len, + std::str::from_utf8(&encoded).unwrap() + ); + } + } +} + +/// 0-1 bytes of data before any amount of padding in final chunk = invalid byte, since padding +/// is not valid data (consistent with error for pad bytes in earlier chunks). +/// From this we know there must be 2-3 bytes of data before padding +#[apply(all_engines)] +fn decode_too_little_data_before_padding_error_invalid_byte(engine_wrapper: E) { + let mut rng = seeded_rng(); + + // want to test no prefix quad case, so start at 0 + let prefix_quads_range = distributions::Uniform::from(0_usize..256); + let suffix_data_len_range = distributions::Uniform::from(0_usize..=1); + for mode in all_pad_modes() { + // we don't encode so we don't care about encode padding + let engine = E::standard_with_pad_mode(true, mode); + for _ in 0..100_000 { + let suffix_data_len = suffix_data_len_range.sample(&mut rng); + let prefix_quad_len = prefix_quads_range.sample(&mut rng); + + // for all possible padding lengths + for padding_len in 1..=(4 - suffix_data_len) { + let mut encoded = "ABCD".repeat(prefix_quad_len).into_bytes(); + encoded.resize(encoded.len() + suffix_data_len, b'A'); + encoded.resize(encoded.len() + padding_len, PAD_BYTE); + + assert_eq!( + Err(DecodeError::InvalidByte( + prefix_quad_len * 4 + suffix_data_len, + PAD_BYTE, + )), + engine.decode(&encoded), + "input {} suffix data len {} pad len {}", + String::from_utf8(encoded).unwrap(), + suffix_data_len, + padding_len + ); + } + } + } +} + +// https://eprint.iacr.org/2022/361.pdf table 2, test 1 +#[apply(all_engines)] +fn decode_malleability_test_case_3_byte_suffix_valid(engine_wrapper: E) { + assert_eq!( + b"Hello".as_slice(), + &E::standard().decode("SGVsbG8=").unwrap() + ); +} + +// https://eprint.iacr.org/2022/361.pdf table 2, test 2 +#[apply(all_engines)] +fn decode_malleability_test_case_3_byte_suffix_invalid_trailing_symbol( + engine_wrapper: E, +) { + assert_eq!( + DecodeError::InvalidLastSymbol(6, 0x39), + E::standard().decode("SGVsbG9=").unwrap_err() + ); +} + +// https://eprint.iacr.org/2022/361.pdf table 2, test 3 +#[apply(all_engines)] +fn decode_malleability_test_case_3_byte_suffix_no_padding(engine_wrapper: E) { + assert_eq!( + DecodeError::InvalidPadding, + E::standard().decode("SGVsbG9").unwrap_err() + ); +} + +// https://eprint.iacr.org/2022/361.pdf table 2, test 4 +#[apply(all_engines)] +fn decode_malleability_test_case_2_byte_suffix_valid_two_padding_symbols( + engine_wrapper: E, +) { + assert_eq!( + b"Hell".as_slice(), + &E::standard().decode("SGVsbA==").unwrap() + ); +} + +// https://eprint.iacr.org/2022/361.pdf table 2, test 5 +#[apply(all_engines)] +fn decode_malleability_test_case_2_byte_suffix_short_padding(engine_wrapper: E) { + assert_eq!( + DecodeError::InvalidPadding, + E::standard().decode("SGVsbA=").unwrap_err() + ); +} + +// https://eprint.iacr.org/2022/361.pdf table 2, test 6 +#[apply(all_engines)] +fn decode_malleability_test_case_2_byte_suffix_no_padding(engine_wrapper: E) { + assert_eq!( + DecodeError::InvalidPadding, + E::standard().decode("SGVsbA").unwrap_err() + ); +} + +// https://eprint.iacr.org/2022/361.pdf table 2, test 7 +// DecoderReader pseudo-engine gets InvalidByte at 8 (extra padding) since it decodes the first +// two complete quads correctly. +#[apply(all_engines_except_decoder_reader)] +fn decode_malleability_test_case_2_byte_suffix_too_much_padding( + engine_wrapper: E, +) { + assert_eq!( + DecodeError::InvalidByte(6, PAD_BYTE), + E::standard().decode("SGVsbA====").unwrap_err() + ); +} + +/// Requires canonical padding -> accepts 2 + 2, 3 + 1, 4 + 0 final quad configurations +#[apply(all_engines)] +fn decode_pad_mode_requires_canonical_accepts_canonical(engine_wrapper: E) { + assert_all_suffixes_ok( + E::standard_with_pad_mode(true, DecodePaddingMode::RequireCanonical), + vec!["/w==", "iYU=", "AAAA"], + ); +} + +/// Requires canonical padding -> rejects 2 + 0-1, 3 + 0 final chunk configurations +#[apply(all_engines)] +fn decode_pad_mode_requires_canonical_rejects_non_canonical(engine_wrapper: E) { + let engine = E::standard_with_pad_mode(true, DecodePaddingMode::RequireCanonical); + + let suffixes = ["/w", "/w=", "iYU"]; + for num_prefix_quads in 0..256 { + for &suffix in suffixes.iter() { + let mut encoded = "AAAA".repeat(num_prefix_quads); + encoded.push_str(suffix); + + let res = engine.decode(&encoded); + + assert_eq!(Err(DecodeError::InvalidPadding), res); + } + } +} + +/// Requires no padding -> accepts 2 + 0, 3 + 0, 4 + 0 final chunk configuration +#[apply(all_engines)] +fn decode_pad_mode_requires_no_padding_accepts_no_padding(engine_wrapper: E) { + assert_all_suffixes_ok( + E::standard_with_pad_mode(true, DecodePaddingMode::RequireNone), + vec!["/w", "iYU", "AAAA"], + ); +} + +/// Requires no padding -> rejects 2 + 1-2, 3 + 1 final chunk configuration +#[apply(all_engines)] +fn decode_pad_mode_requires_no_padding_rejects_any_padding(engine_wrapper: E) { + let engine = E::standard_with_pad_mode(true, DecodePaddingMode::RequireNone); + + let suffixes = ["/w=", "/w==", "iYU="]; + for num_prefix_quads in 0..256 { + for &suffix in suffixes.iter() { + let mut encoded = "AAAA".repeat(num_prefix_quads); + encoded.push_str(suffix); + + let res = engine.decode(&encoded); + + assert_eq!(Err(DecodeError::InvalidPadding), res); + } + } +} + +/// Indifferent padding accepts 2 + 0-2, 3 + 0-1, 4 + 0 final chunk configuration +#[apply(all_engines)] +fn decode_pad_mode_indifferent_padding_accepts_anything(engine_wrapper: E) { + assert_all_suffixes_ok( + E::standard_with_pad_mode(true, DecodePaddingMode::Indifferent), + vec!["/w", "/w=", "/w==", "iYU", "iYU=", "AAAA"], + ); +} + +/// 1 trailing byte that's not padding is detected as invalid byte even though there's padding +/// in the middle of the input. This is essentially mandating the eager check for 1 trailing byte +/// to catch the \n suffix case. +// DecoderReader pseudo-engine can't handle DecodePaddingMode::RequireNone since it will decode +// a complete quad with padding in it before encountering the stray byte that makes it an invalid +// length +#[apply(all_engines_except_decoder_reader)] +fn decode_invalid_trailing_bytes_all_pad_modes_invalid_byte(engine_wrapper: E) { + for mode in all_pad_modes() { + do_invalid_trailing_byte(E::standard_with_pad_mode(true, mode), mode); + } +} + +#[apply(all_engines)] +fn decode_invalid_trailing_bytes_invalid_byte(engine_wrapper: E) { + // excluding no padding mode because the DecoderWrapper pseudo-engine will fail with + // InvalidPadding because it will decode the last complete quad with padding first + for mode in pad_modes_allowing_padding() { + do_invalid_trailing_byte(E::standard_with_pad_mode(true, mode), mode); + } +} +fn do_invalid_trailing_byte(engine: impl Engine, mode: DecodePaddingMode) { + for last_byte in [b'*', b'\n'] { + for num_prefix_quads in 0..256 { + let mut s: String = "ABCD".repeat(num_prefix_quads); + s.push_str("Cg=="); + let mut input = s.into_bytes(); + input.push(last_byte); + + // The case of trailing newlines is common enough to warrant a test for a good error + // message. + assert_eq!( + Err(DecodeError::InvalidByte( + num_prefix_quads * 4 + 4, + last_byte + )), + engine.decode(&input), + "mode: {:?}, input: {}", + mode, + String::from_utf8(input).unwrap() + ); + } + } +} + +/// When there's 1 trailing byte, but it's padding, it's only InvalidByte if there isn't padding +/// earlier. +#[apply(all_engines)] +fn decode_invalid_trailing_padding_as_invalid_byte_at_first_pad_byte( + engine_wrapper: E, +) { + // excluding no padding mode because the DecoderWrapper pseudo-engine will fail with + // InvalidPadding because it will decode the last complete quad with padding first + for mode in pad_modes_allowing_padding() { + do_invalid_trailing_padding_as_invalid_byte_at_first_padding( + E::standard_with_pad_mode(true, mode), + mode, + ); + } +} + +// DecoderReader pseudo-engine can't handle DecodePaddingMode::RequireNone since it will decode +// a complete quad with padding in it before encountering the stray byte that makes it an invalid +// length +#[apply(all_engines_except_decoder_reader)] +fn decode_invalid_trailing_padding_as_invalid_byte_at_first_byte_all_modes( + engine_wrapper: E, +) { + for mode in all_pad_modes() { + do_invalid_trailing_padding_as_invalid_byte_at_first_padding( + E::standard_with_pad_mode(true, mode), + mode, + ); + } +} +fn do_invalid_trailing_padding_as_invalid_byte_at_first_padding( + engine: impl Engine, + mode: DecodePaddingMode, +) { + for num_prefix_quads in 0..256 { + for (suffix, pad_offset) in [("AA===", 2), ("AAA==", 3), ("AAAA=", 4)] { + let mut s: String = "ABCD".repeat(num_prefix_quads); + s.push_str(suffix); + + assert_eq!( + // pad after `g`, not the last one + Err(DecodeError::InvalidByte( + num_prefix_quads * 4 + pad_offset, + PAD_BYTE + )), + engine.decode(&s), + "mode: {:?}, input: {}", + mode, + s + ); + } + } +} + +#[apply(all_engines)] +fn decode_into_slice_fits_in_precisely_sized_slice(engine_wrapper: E) { + let mut orig_data = Vec::new(); + let mut encoded_data = String::new(); + let mut decode_buf = Vec::new(); + + let input_len_range = distributions::Uniform::new(0, 1000); + let mut rng = rngs::SmallRng::from_entropy(); + + for _ in 0..10_000 { + orig_data.clear(); + encoded_data.clear(); + decode_buf.clear(); + + let input_len = input_len_range.sample(&mut rng); + + for _ in 0..input_len { + orig_data.push(rng.gen()); + } + + let engine = E::random(&mut rng); + engine.encode_string(&orig_data, &mut encoded_data); + assert_encode_sanity(&encoded_data, engine.config().encode_padding(), input_len); + + decode_buf.resize(input_len, 0); + // decode into the non-empty buf + let decode_bytes_written = engine + .decode_slice_unchecked(encoded_data.as_bytes(), &mut decode_buf[..]) + .unwrap(); + assert_eq!(orig_data.len(), decode_bytes_written); + assert_eq!(orig_data, decode_buf); + + // same for checked variant + decode_buf.clear(); + decode_buf.resize(input_len, 0); + // decode into the non-empty buf + let decode_bytes_written = engine + .decode_slice(encoded_data.as_bytes(), &mut decode_buf[..]) + .unwrap(); + assert_eq!(orig_data.len(), decode_bytes_written); + assert_eq!(orig_data, decode_buf); + } +} + +#[apply(all_engines)] +fn inner_decode_reports_padding_position(engine_wrapper: E) { + let mut b64 = String::new(); + let mut decoded = Vec::new(); + let engine = E::standard(); + + for pad_position in 1..10_000 { + b64.clear(); + decoded.clear(); + // plenty of room for original data + decoded.resize(pad_position, 0); + + for _ in 0..pad_position { + b64.push('A'); + } + // finish the quad with padding + for _ in 0..(4 - (pad_position % 4)) { + b64.push('='); + } + + let decode_res = engine.internal_decode( + b64.as_bytes(), + &mut decoded[..], + engine.internal_decoded_len_estimate(b64.len()), + ); + if pad_position % 4 < 2 { + // impossible padding + assert_eq!( + Err(DecodeSliceError::DecodeError(DecodeError::InvalidByte( + pad_position, + PAD_BYTE + ))), + decode_res + ); + } else { + let decoded_bytes = pad_position / 4 * 3 + + match pad_position % 4 { + 0 => 0, + 2 => 1, + 3 => 2, + _ => unreachable!(), + }; + assert_eq!( + Ok(DecodeMetadata::new(decoded_bytes, Some(pad_position))), + decode_res + ); + } + } +} + +#[apply(all_engines)] +fn decode_length_estimate_delta(engine_wrapper: E) { + for engine in [E::standard(), E::standard_unpadded()] { + for &padding in &[true, false] { + for orig_len in 0..1000 { + let encoded_len = encoded_len(orig_len, padding).unwrap(); + + let decoded_estimate = engine + .internal_decoded_len_estimate(encoded_len) + .decoded_len_estimate(); + assert!(decoded_estimate >= orig_len); + assert!( + decoded_estimate - orig_len < 3, + "estimate: {}, encoded: {}, orig: {}", + decoded_estimate, + encoded_len, + orig_len + ); + } + } + } +} + +#[apply(all_engines)] +fn estimate_via_u128_inflation(engine_wrapper: E) { + // cover both ends of usize + (0..1000) + .chain(usize::MAX - 1000..=usize::MAX) + .for_each(|encoded_len| { + // inflate to 128 bit type to be able to safely use the easy formulas + let len_128 = encoded_len as u128; + + let estimate = E::standard() + .internal_decoded_len_estimate(encoded_len) + .decoded_len_estimate(); + + // This check is a little too strict: it requires using the (len + 3) / 4 * 3 formula + // or equivalent, but until other engines come along that use a different formula + // requiring that we think more carefully about what the allowable criteria are, this + // will do. + assert_eq!( + ((len_128 + 3) / 4 * 3) as usize, + estimate, + "enc len {}", + encoded_len + ); + }) +} + +#[apply(all_engines)] +fn decode_slice_checked_fails_gracefully_at_all_output_lengths( + engine_wrapper: E, +) { + let mut rng = seeded_rng(); + for original_len in 0..1000 { + let mut original = vec![0; original_len]; + rng.fill(&mut original[..]); + + for mode in all_pad_modes() { + let engine = E::standard_with_pad_mode( + match mode { + DecodePaddingMode::Indifferent | DecodePaddingMode::RequireCanonical => true, + DecodePaddingMode::RequireNone => false, + }, + mode, + ); + + let encoded = engine.encode(&original); + let mut decode_buf = Vec::with_capacity(original_len); + for decode_buf_len in 0..original_len { + decode_buf.resize(decode_buf_len, 0); + assert_eq!( + DecodeSliceError::OutputSliceTooSmall, + engine + .decode_slice(&encoded, &mut decode_buf[..]) + .unwrap_err(), + "original len: {}, encoded len: {}, buf len: {}, mode: {:?}", + original_len, + encoded.len(), + decode_buf_len, + mode + ); + // internal method works the same + assert_eq!( + DecodeSliceError::OutputSliceTooSmall, + engine + .internal_decode( + encoded.as_bytes(), + &mut decode_buf[..], + engine.internal_decoded_len_estimate(encoded.len()) + ) + .unwrap_err() + ); + } + + decode_buf.resize(original_len, 0); + rng.fill(&mut decode_buf[..]); + assert_eq!( + original_len, + engine.decode_slice(&encoded, &mut decode_buf[..]).unwrap() + ); + assert_eq!(original, decode_buf); + } + } +} + +/// Returns a tuple of the original data length, the encoded data length (just data), and the length including padding. +/// +/// Vecs provided should be empty. +fn generate_random_encoded_data>( + engine: &E, + orig_data: &mut Vec, + encode_buf: &mut Vec, + rng: &mut R, + length_distribution: &D, +) -> (usize, usize, usize) { + let padding: bool = engine.config().encode_padding(); + + let orig_len = fill_rand(orig_data, rng, length_distribution); + let expected_encoded_len = encoded_len(orig_len, padding).unwrap(); + encode_buf.resize(expected_encoded_len, 0); + + let base_encoded_len = engine.internal_encode(&orig_data[..], &mut encode_buf[..]); + + let enc_len_with_padding = if padding { + base_encoded_len + add_padding(base_encoded_len, &mut encode_buf[base_encoded_len..]) + } else { + base_encoded_len + }; + + assert_eq!(expected_encoded_len, enc_len_with_padding); + + (orig_len, base_encoded_len, enc_len_with_padding) +} + +// fill to a random length +fn fill_rand>( + vec: &mut Vec, + rng: &mut R, + length_distribution: &D, +) -> usize { + let len = length_distribution.sample(rng); + for _ in 0..len { + vec.push(rng.gen()); + } + + len +} + +fn fill_rand_len(vec: &mut Vec, rng: &mut R, len: usize) { + for _ in 0..len { + vec.push(rng.gen()); + } +} + +fn prefixed_data<'i>(input_with_prefix: &'i mut String, prefix_len: usize, data: &str) -> &'i str { + input_with_prefix.truncate(prefix_len); + input_with_prefix.push_str(data); + input_with_prefix.as_str() +} + +/// A wrapper to make using engines in rstest fixtures easier. +/// The functions don't need to be instance methods, but rstest does seem +/// to want an instance, so instances are passed to test functions and then ignored. +trait EngineWrapper { + type Engine: Engine; + + /// Return an engine configured for RFC standard base64 + fn standard() -> Self::Engine; + + /// Return an engine configured for RFC standard base64, except with no padding appended on + /// encode, and required no padding on decode. + fn standard_unpadded() -> Self::Engine; + + /// Return an engine configured for RFC standard alphabet with the provided encode and decode + /// pad settings + fn standard_with_pad_mode(encode_pad: bool, decode_pad_mode: DecodePaddingMode) + -> Self::Engine; + + /// Return an engine configured for RFC standard base64 that allows invalid trailing bits + fn standard_allow_trailing_bits() -> Self::Engine; + + /// Return an engine configured with a randomized alphabet and config + fn random(rng: &mut R) -> Self::Engine; + + /// Return an engine configured with the specified alphabet and randomized config + fn random_alphabet(rng: &mut R, alphabet: &Alphabet) -> Self::Engine; +} + +struct GeneralPurposeWrapper {} + +impl EngineWrapper for GeneralPurposeWrapper { + type Engine = general_purpose::GeneralPurpose; + + fn standard() -> Self::Engine { + general_purpose::GeneralPurpose::new(&STANDARD, general_purpose::PAD) + } + + fn standard_unpadded() -> Self::Engine { + general_purpose::GeneralPurpose::new(&STANDARD, general_purpose::NO_PAD) + } + + fn standard_with_pad_mode( + encode_pad: bool, + decode_pad_mode: DecodePaddingMode, + ) -> Self::Engine { + general_purpose::GeneralPurpose::new( + &STANDARD, + general_purpose::GeneralPurposeConfig::new() + .with_encode_padding(encode_pad) + .with_decode_padding_mode(decode_pad_mode), + ) + } + + fn standard_allow_trailing_bits() -> Self::Engine { + general_purpose::GeneralPurpose::new( + &STANDARD, + general_purpose::GeneralPurposeConfig::new().with_decode_allow_trailing_bits(true), + ) + } + + fn random(rng: &mut R) -> Self::Engine { + let alphabet = random_alphabet(rng); + + Self::random_alphabet(rng, alphabet) + } + + fn random_alphabet(rng: &mut R, alphabet: &Alphabet) -> Self::Engine { + general_purpose::GeneralPurpose::new(alphabet, random_config(rng)) + } +} + +struct NaiveWrapper {} + +impl EngineWrapper for NaiveWrapper { + type Engine = naive::Naive; + + fn standard() -> Self::Engine { + naive::Naive::new( + &STANDARD, + naive::NaiveConfig { + encode_padding: true, + decode_allow_trailing_bits: false, + decode_padding_mode: DecodePaddingMode::RequireCanonical, + }, + ) + } + + fn standard_unpadded() -> Self::Engine { + naive::Naive::new( + &STANDARD, + naive::NaiveConfig { + encode_padding: false, + decode_allow_trailing_bits: false, + decode_padding_mode: DecodePaddingMode::RequireNone, + }, + ) + } + + fn standard_with_pad_mode( + encode_pad: bool, + decode_pad_mode: DecodePaddingMode, + ) -> Self::Engine { + naive::Naive::new( + &STANDARD, + naive::NaiveConfig { + encode_padding: encode_pad, + decode_allow_trailing_bits: false, + decode_padding_mode: decode_pad_mode, + }, + ) + } + + fn standard_allow_trailing_bits() -> Self::Engine { + naive::Naive::new( + &STANDARD, + naive::NaiveConfig { + encode_padding: true, + decode_allow_trailing_bits: true, + decode_padding_mode: DecodePaddingMode::RequireCanonical, + }, + ) + } + + fn random(rng: &mut R) -> Self::Engine { + let alphabet = random_alphabet(rng); + + Self::random_alphabet(rng, alphabet) + } + + fn random_alphabet(rng: &mut R, alphabet: &Alphabet) -> Self::Engine { + let mode = rng.gen(); + + let config = naive::NaiveConfig { + encode_padding: match mode { + DecodePaddingMode::Indifferent => rng.gen(), + DecodePaddingMode::RequireCanonical => true, + DecodePaddingMode::RequireNone => false, + }, + decode_allow_trailing_bits: rng.gen(), + decode_padding_mode: mode, + }; + + naive::Naive::new(alphabet, config) + } +} + +/// A pseudo-Engine that routes all decoding through [DecoderReader] +struct DecoderReaderEngine { + engine: E, +} + +impl From for DecoderReaderEngine { + fn from(value: E) -> Self { + Self { engine: value } + } +} + +impl Engine for DecoderReaderEngine { + type Config = E::Config; + type DecodeEstimate = E::DecodeEstimate; + + fn internal_encode(&self, input: &[u8], output: &mut [u8]) -> usize { + self.engine.internal_encode(input, output) + } + + fn internal_decoded_len_estimate(&self, input_len: usize) -> Self::DecodeEstimate { + self.engine.internal_decoded_len_estimate(input_len) + } + + fn internal_decode( + &self, + input: &[u8], + output: &mut [u8], + decode_estimate: Self::DecodeEstimate, + ) -> Result { + let mut reader = DecoderReader::new(input, &self.engine); + let mut buf = vec![0; input.len()]; + // to avoid effects like not detecting invalid length due to progressively growing + // the output buffer in read_to_end etc, read into a big enough buffer in one go + // to make behavior more consistent with normal engines + let _ = reader + .read(&mut buf) + .and_then(|len| { + buf.truncate(len); + // make sure we got everything + reader.read_to_end(&mut buf) + }) + .map_err(|io_error| { + *io_error + .into_inner() + .and_then(|inner| inner.downcast::().ok()) + .unwrap() + })?; + if output.len() < buf.len() { + return Err(DecodeSliceError::OutputSliceTooSmall); + } + output[..buf.len()].copy_from_slice(&buf); + Ok(DecodeMetadata::new( + buf.len(), + input + .iter() + .enumerate() + .filter(|(_offset, byte)| **byte == PAD_BYTE) + .map(|(offset, _byte)| offset) + .next(), + )) + } + + fn config(&self) -> &Self::Config { + self.engine.config() + } +} + +struct DecoderReaderEngineWrapper {} + +impl EngineWrapper for DecoderReaderEngineWrapper { + type Engine = DecoderReaderEngine; + + fn standard() -> Self::Engine { + GeneralPurposeWrapper::standard().into() + } + + fn standard_unpadded() -> Self::Engine { + GeneralPurposeWrapper::standard_unpadded().into() + } + + fn standard_with_pad_mode( + encode_pad: bool, + decode_pad_mode: DecodePaddingMode, + ) -> Self::Engine { + GeneralPurposeWrapper::standard_with_pad_mode(encode_pad, decode_pad_mode).into() + } + + fn standard_allow_trailing_bits() -> Self::Engine { + GeneralPurposeWrapper::standard_allow_trailing_bits().into() + } + + fn random(rng: &mut R) -> Self::Engine { + GeneralPurposeWrapper::random(rng).into() + } + + fn random_alphabet(rng: &mut R, alphabet: &Alphabet) -> Self::Engine { + GeneralPurposeWrapper::random_alphabet(rng, alphabet).into() + } +} + +fn seeded_rng() -> impl rand::Rng { + rngs::SmallRng::from_entropy() +} + +fn all_pad_modes() -> Vec { + vec![ + DecodePaddingMode::Indifferent, + DecodePaddingMode::RequireCanonical, + DecodePaddingMode::RequireNone, + ] +} + +fn pad_modes_allowing_padding() -> Vec { + vec![ + DecodePaddingMode::Indifferent, + DecodePaddingMode::RequireCanonical, + ] +} + +fn assert_all_suffixes_ok(engine: E, suffixes: Vec<&str>) { + for num_prefix_quads in 0..256 { + for &suffix in suffixes.iter() { + let mut encoded = "AAAA".repeat(num_prefix_quads); + encoded.push_str(suffix); + + let res = &engine.decode(&encoded); + assert!(res.is_ok()); + } + } +} diff --git a/vendor/base64/src/lib.rs b/vendor/base64/src/lib.rs new file mode 100644 index 0000000..579a722 --- /dev/null +++ b/vendor/base64/src/lib.rs @@ -0,0 +1,277 @@ +//! Correct, fast, and configurable [base64][] decoding and encoding. Base64 +//! transports binary data efficiently in contexts where only plain text is +//! allowed. +//! +//! [base64]: https://developer.mozilla.org/en-US/docs/Glossary/Base64 +//! +//! # Usage +//! +//! Use an [`Engine`] to decode or encode base64, configured with the base64 +//! alphabet and padding behavior best suited to your application. +//! +//! ## Engine setup +//! +//! There is more than one way to encode a stream of bytes as “base64”. +//! Different applications use different encoding +//! [alphabets][alphabet::Alphabet] and +//! [padding behaviors][engine::general_purpose::GeneralPurposeConfig]. +//! +//! ### Encoding alphabet +//! +//! Almost all base64 [alphabets][alphabet::Alphabet] use `A-Z`, `a-z`, and +//! `0-9`, which gives nearly 64 characters (26 + 26 + 10 = 62), but they differ +//! in their choice of their final 2. +//! +//! Most applications use the [standard][alphabet::STANDARD] alphabet specified +//! in [RFC 4648][rfc-alphabet]. If that’s all you need, you can get started +//! quickly by using the pre-configured +//! [`STANDARD`][engine::general_purpose::STANDARD] engine, which is also available +//! in the [`prelude`] module as shown here, if you prefer a minimal `use` +//! footprint. +//! +#![cfg_attr(feature = "alloc", doc = "```")] +#![cfg_attr(not(feature = "alloc"), doc = "```ignore")] +//! use base64::prelude::*; +//! +//! # fn main() -> Result<(), base64::DecodeError> { +//! assert_eq!(BASE64_STANDARD.decode(b"+uwgVQA=")?, b"\xFA\xEC\x20\x55\0"); +//! assert_eq!(BASE64_STANDARD.encode(b"\xFF\xEC\x20\x55\0"), "/+wgVQA="); +//! # Ok(()) +//! # } +//! ``` +//! +//! [rfc-alphabet]: https://datatracker.ietf.org/doc/html/rfc4648#section-4 +//! +//! Other common alphabets are available in the [`alphabet`] module. +//! +//! #### URL-safe alphabet +//! +//! The standard alphabet uses `+` and `/` as its two non-alphanumeric tokens, +//! which cannot be safely used in URL’s without encoding them as `%2B` and +//! `%2F`. +//! +//! To avoid that, some applications use a [“URL-safe” alphabet][alphabet::URL_SAFE], +//! which uses `-` and `_` instead. To use that alternative alphabet, use the +//! [`URL_SAFE`][engine::general_purpose::URL_SAFE] engine. This example doesn't +//! use [`prelude`] to show what a more explicit `use` would look like. +//! +#![cfg_attr(feature = "alloc", doc = "```")] +#![cfg_attr(not(feature = "alloc"), doc = "```ignore")] +//! use base64::{engine::general_purpose::URL_SAFE, Engine as _}; +//! +//! # fn main() -> Result<(), base64::DecodeError> { +//! assert_eq!(URL_SAFE.decode(b"-uwgVQA=")?, b"\xFA\xEC\x20\x55\0"); +//! assert_eq!(URL_SAFE.encode(b"\xFF\xEC\x20\x55\0"), "_-wgVQA="); +//! # Ok(()) +//! # } +//! ``` +//! +//! ### Padding characters +//! +//! Each base64 character represents 6 bits (2⁶ = 64) of the original binary +//! data, and every 3 bytes of input binary data will encode to 4 base64 +//! characters (8 bits × 3 = 6 bits × 4 = 24 bits). +//! +//! When the input is not an even multiple of 3 bytes in length, [canonical][] +//! base64 encoders insert padding characters at the end, so that the output +//! length is always a multiple of 4: +//! +//! [canonical]: https://datatracker.ietf.org/doc/html/rfc4648#section-3.5 +//! +#![cfg_attr(feature = "alloc", doc = "```")] +#![cfg_attr(not(feature = "alloc"), doc = "```ignore")] +//! use base64::{engine::general_purpose::STANDARD, Engine as _}; +//! +//! assert_eq!(STANDARD.encode(b""), ""); +//! assert_eq!(STANDARD.encode(b"f"), "Zg=="); +//! assert_eq!(STANDARD.encode(b"fo"), "Zm8="); +//! assert_eq!(STANDARD.encode(b"foo"), "Zm9v"); +//! ``` +//! +//! Canonical encoding ensures that base64 encodings will be exactly the same, +//! byte-for-byte, regardless of input length. But the `=` padding characters +//! aren’t necessary for decoding, and they may be omitted by using a +//! [`NO_PAD`][engine::general_purpose::NO_PAD] configuration: +//! +#![cfg_attr(feature = "alloc", doc = "```")] +#![cfg_attr(not(feature = "alloc"), doc = "```ignore")] +//! use base64::{engine::general_purpose::STANDARD_NO_PAD, Engine as _}; +//! +//! assert_eq!(STANDARD_NO_PAD.encode(b""), ""); +//! assert_eq!(STANDARD_NO_PAD.encode(b"f"), "Zg"); +//! assert_eq!(STANDARD_NO_PAD.encode(b"fo"), "Zm8"); +//! assert_eq!(STANDARD_NO_PAD.encode(b"foo"), "Zm9v"); +//! ``` +//! +//! The pre-configured `NO_PAD` engines will reject inputs containing padding +//! `=` characters. To encode without padding and still accept padding while +//! decoding, create an [engine][engine::general_purpose::GeneralPurpose] with +//! that [padding mode][engine::DecodePaddingMode]. +//! +#![cfg_attr(feature = "alloc", doc = "```")] +#![cfg_attr(not(feature = "alloc"), doc = "```ignore")] +//! # use base64::{engine::general_purpose::STANDARD_NO_PAD, Engine as _}; +//! assert_eq!(STANDARD_NO_PAD.decode(b"Zm8="), Err(base64::DecodeError::InvalidPadding)); +//! ``` +//! +//! ### Further customization +//! +//! Decoding and encoding behavior can be customized by creating an +//! [engine][engine::GeneralPurpose] with an [alphabet][alphabet::Alphabet] and +//! [padding configuration][engine::GeneralPurposeConfig]: +//! +#![cfg_attr(feature = "alloc", doc = "```")] +#![cfg_attr(not(feature = "alloc"), doc = "```ignore")] +//! use base64::{engine, alphabet, Engine as _}; +//! +//! // bizarro-world base64: +/ as the first symbols instead of the last +//! let alphabet = +//! alphabet::Alphabet::new("+/ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789") +//! .unwrap(); +//! +//! // a very weird config that encodes with padding but requires no padding when decoding...? +//! let crazy_config = engine::GeneralPurposeConfig::new() +//! .with_decode_allow_trailing_bits(true) +//! .with_encode_padding(true) +//! .with_decode_padding_mode(engine::DecodePaddingMode::RequireNone); +//! +//! let crazy_engine = engine::GeneralPurpose::new(&alphabet, crazy_config); +//! +//! let encoded = crazy_engine.encode(b"abc 123"); +//! +//! ``` +//! +//! ## Memory allocation +//! +//! The [decode][Engine::decode()] and [encode][Engine::encode()] engine methods +//! allocate memory for their results – `decode` returns a `Vec` and +//! `encode` returns a `String`. To instead decode or encode into a buffer that +//! you allocated, use one of the alternative methods: +//! +//! #### Decoding +//! +//! | Method | Output | Allocates memory | +//! | -------------------------- | ----------------------------- | ----------------------------- | +//! | [`Engine::decode`] | returns a new `Vec` | always | +//! | [`Engine::decode_vec`] | appends to provided `Vec` | if `Vec` lacks capacity | +//! | [`Engine::decode_slice`] | writes to provided `&[u8]` | never +//! +//! #### Encoding +//! +//! | Method | Output | Allocates memory | +//! | -------------------------- | ---------------------------- | ------------------------------ | +//! | [`Engine::encode`] | returns a new `String` | always | +//! | [`Engine::encode_string`] | appends to provided `String` | if `String` lacks capacity | +//! | [`Engine::encode_slice`] | writes to provided `&[u8]` | never | +//! +//! ## Input and output +//! +//! The `base64` crate can [decode][Engine::decode()] and +//! [encode][Engine::encode()] values in memory, or +//! [`DecoderReader`][read::DecoderReader] and +//! [`EncoderWriter`][write::EncoderWriter] provide streaming decoding and +//! encoding for any [readable][std::io::Read] or [writable][std::io::Write] +//! byte stream. +//! +//! #### Decoding +//! +#![cfg_attr(feature = "std", doc = "```")] +#![cfg_attr(not(feature = "std"), doc = "```ignore")] +//! # use std::io; +//! use base64::{engine::general_purpose::STANDARD, read::DecoderReader}; +//! +//! # fn main() -> Result<(), Box> { +//! let mut input = io::stdin(); +//! let mut decoder = DecoderReader::new(&mut input, &STANDARD); +//! io::copy(&mut decoder, &mut io::stdout())?; +//! # Ok(()) +//! # } +//! ``` +//! +//! #### Encoding +//! +#![cfg_attr(feature = "std", doc = "```")] +#![cfg_attr(not(feature = "std"), doc = "```ignore")] +//! # use std::io; +//! use base64::{engine::general_purpose::STANDARD, write::EncoderWriter}; +//! +//! # fn main() -> Result<(), Box> { +//! let mut output = io::stdout(); +//! let mut encoder = EncoderWriter::new(&mut output, &STANDARD); +//! io::copy(&mut io::stdin(), &mut encoder)?; +//! # Ok(()) +//! # } +//! ``` +//! +//! #### Display +//! +//! If you only need a base64 representation for implementing the +//! [`Display`][std::fmt::Display] trait, use +//! [`Base64Display`][display::Base64Display]: +//! +//! ``` +//! use base64::{display::Base64Display, engine::general_purpose::STANDARD}; +//! +//! let value = Base64Display::new(b"\0\x01\x02\x03", &STANDARD); +//! assert_eq!("base64: AAECAw==", format!("base64: {}", value)); +//! ``` +//! +//! # Panics +//! +//! If length calculations result in overflowing `usize`, a panic will result. + +#![cfg_attr(feature = "cargo-clippy", allow(clippy::cast_lossless))] +#![deny( + missing_docs, + trivial_casts, + trivial_numeric_casts, + unused_extern_crates, + unused_import_braces, + unused_results, + variant_size_differences +)] +#![forbid(unsafe_code)] +// Allow globally until https://github.com/rust-lang/rust-clippy/issues/8768 is resolved. +// The desired state is to allow it only for the rstest_reuse import. +#![allow(clippy::single_component_path_imports)] +#![cfg_attr(not(any(feature = "std", test)), no_std)] + +#[cfg(any(feature = "alloc", test))] +extern crate alloc; + +// has to be included at top level because of the way rstest_reuse defines its macros +#[cfg(test)] +use rstest_reuse; + +mod chunked_encoder; +pub mod display; +#[cfg(any(feature = "std", test))] +pub mod read; +#[cfg(any(feature = "std", test))] +pub mod write; + +pub mod engine; +pub use engine::Engine; + +pub mod alphabet; + +mod encode; +#[allow(deprecated)] +#[cfg(any(feature = "alloc", test))] +pub use crate::encode::{encode, encode_engine, encode_engine_string}; +#[allow(deprecated)] +pub use crate::encode::{encode_engine_slice, encoded_len, EncodeSliceError}; + +mod decode; +#[allow(deprecated)] +#[cfg(any(feature = "alloc", test))] +pub use crate::decode::{decode, decode_engine, decode_engine_vec}; +#[allow(deprecated)] +pub use crate::decode::{decode_engine_slice, decoded_len_estimate, DecodeError, DecodeSliceError}; + +pub mod prelude; + +#[cfg(test)] +mod tests; + +const PAD_BYTE: u8 = b'='; diff --git a/vendor/base64/src/prelude.rs b/vendor/base64/src/prelude.rs new file mode 100644 index 0000000..df5fdb4 --- /dev/null +++ b/vendor/base64/src/prelude.rs @@ -0,0 +1,20 @@ +//! Preconfigured engines for common use cases. +//! +//! These are re-exports of `const` engines in [crate::engine::general_purpose], renamed with a `BASE64_` +//! prefix for those who prefer to `use` the entire path to a name. +//! +//! # Examples +//! +#![cfg_attr(feature = "alloc", doc = "```")] +#![cfg_attr(not(feature = "alloc"), doc = "```ignore")] +//! use base64::prelude::{Engine as _, BASE64_STANDARD_NO_PAD}; +//! +//! assert_eq!("c29tZSBieXRlcw", &BASE64_STANDARD_NO_PAD.encode(b"some bytes")); +//! ``` + +pub use crate::engine::Engine; + +pub use crate::engine::general_purpose::STANDARD as BASE64_STANDARD; +pub use crate::engine::general_purpose::STANDARD_NO_PAD as BASE64_STANDARD_NO_PAD; +pub use crate::engine::general_purpose::URL_SAFE as BASE64_URL_SAFE; +pub use crate::engine::general_purpose::URL_SAFE_NO_PAD as BASE64_URL_SAFE_NO_PAD; diff --git a/vendor/base64/src/read/decoder.rs b/vendor/base64/src/read/decoder.rs new file mode 100644 index 0000000..781f6f8 --- /dev/null +++ b/vendor/base64/src/read/decoder.rs @@ -0,0 +1,335 @@ +use crate::{engine::Engine, DecodeError, DecodeSliceError, PAD_BYTE}; +use std::{cmp, fmt, io}; + +// This should be large, but it has to fit on the stack. +pub(crate) const BUF_SIZE: usize = 1024; + +// 4 bytes of base64 data encode 3 bytes of raw data (modulo padding). +const BASE64_CHUNK_SIZE: usize = 4; +const DECODED_CHUNK_SIZE: usize = 3; + +/// A `Read` implementation that decodes base64 data read from an underlying reader. +/// +/// # Examples +/// +/// ``` +/// use std::io::Read; +/// use std::io::Cursor; +/// use base64::engine::general_purpose; +/// +/// // use a cursor as the simplest possible `Read` -- in real code this is probably a file, etc. +/// let mut wrapped_reader = Cursor::new(b"YXNkZg=="); +/// let mut decoder = base64::read::DecoderReader::new( +/// &mut wrapped_reader, +/// &general_purpose::STANDARD); +/// +/// // handle errors as you normally would +/// let mut result = Vec::new(); +/// decoder.read_to_end(&mut result).unwrap(); +/// +/// assert_eq!(b"asdf", &result[..]); +/// +/// ``` +pub struct DecoderReader<'e, E: Engine, R: io::Read> { + engine: &'e E, + /// Where b64 data is read from + inner: R, + + /// Holds b64 data read from the delegate reader. + b64_buffer: [u8; BUF_SIZE], + /// The start of the pending buffered data in `b64_buffer`. + b64_offset: usize, + /// The amount of buffered b64 data after `b64_offset` in `b64_len`. + b64_len: usize, + /// Since the caller may provide us with a buffer of size 1 or 2 that's too small to copy a + /// decoded chunk in to, we have to be able to hang on to a few decoded bytes. + /// Technically we only need to hold 2 bytes, but then we'd need a separate temporary buffer to + /// decode 3 bytes into and then juggle copying one byte into the provided read buf and the rest + /// into here, which seems like a lot of complexity for 1 extra byte of storage. + decoded_chunk_buffer: [u8; DECODED_CHUNK_SIZE], + /// Index of start of decoded data in `decoded_chunk_buffer` + decoded_offset: usize, + /// Length of decoded data after `decoded_offset` in `decoded_chunk_buffer` + decoded_len: usize, + /// Input length consumed so far. + /// Used to provide accurate offsets in errors + input_consumed_len: usize, + /// offset of previously seen padding, if any + padding_offset: Option, +} + +// exclude b64_buffer as it's uselessly large +impl<'e, E: Engine, R: io::Read> fmt::Debug for DecoderReader<'e, E, R> { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.debug_struct("DecoderReader") + .field("b64_offset", &self.b64_offset) + .field("b64_len", &self.b64_len) + .field("decoded_chunk_buffer", &self.decoded_chunk_buffer) + .field("decoded_offset", &self.decoded_offset) + .field("decoded_len", &self.decoded_len) + .field("input_consumed_len", &self.input_consumed_len) + .field("padding_offset", &self.padding_offset) + .finish() + } +} + +impl<'e, E: Engine, R: io::Read> DecoderReader<'e, E, R> { + /// Create a new decoder that will read from the provided reader `r`. + pub fn new(reader: R, engine: &'e E) -> Self { + DecoderReader { + engine, + inner: reader, + b64_buffer: [0; BUF_SIZE], + b64_offset: 0, + b64_len: 0, + decoded_chunk_buffer: [0; DECODED_CHUNK_SIZE], + decoded_offset: 0, + decoded_len: 0, + input_consumed_len: 0, + padding_offset: None, + } + } + + /// Write as much as possible of the decoded buffer into the target buffer. + /// Must only be called when there is something to write and space to write into. + /// Returns a Result with the number of (decoded) bytes copied. + fn flush_decoded_buf(&mut self, buf: &mut [u8]) -> io::Result { + debug_assert!(self.decoded_len > 0); + debug_assert!(!buf.is_empty()); + + let copy_len = cmp::min(self.decoded_len, buf.len()); + debug_assert!(copy_len > 0); + debug_assert!(copy_len <= self.decoded_len); + + buf[..copy_len].copy_from_slice( + &self.decoded_chunk_buffer[self.decoded_offset..self.decoded_offset + copy_len], + ); + + self.decoded_offset += copy_len; + self.decoded_len -= copy_len; + + debug_assert!(self.decoded_len < DECODED_CHUNK_SIZE); + + Ok(copy_len) + } + + /// Read into the remaining space in the buffer after the current contents. + /// Must only be called when there is space to read into in the buffer. + /// Returns the number of bytes read. + fn read_from_delegate(&mut self) -> io::Result { + debug_assert!(self.b64_offset + self.b64_len < BUF_SIZE); + + let read = self + .inner + .read(&mut self.b64_buffer[self.b64_offset + self.b64_len..])?; + self.b64_len += read; + + debug_assert!(self.b64_offset + self.b64_len <= BUF_SIZE); + + Ok(read) + } + + /// Decode the requested number of bytes from the b64 buffer into the provided buffer. It's the + /// caller's responsibility to choose the number of b64 bytes to decode correctly. + /// + /// Returns a Result with the number of decoded bytes written to `buf`. + /// + /// # Panics + /// + /// panics if `buf` is too small + fn decode_to_buf(&mut self, b64_len_to_decode: usize, buf: &mut [u8]) -> io::Result { + debug_assert!(self.b64_len >= b64_len_to_decode); + debug_assert!(self.b64_offset + self.b64_len <= BUF_SIZE); + debug_assert!(!buf.is_empty()); + + let b64_to_decode = &self.b64_buffer[self.b64_offset..self.b64_offset + b64_len_to_decode]; + let decode_metadata = self + .engine + .internal_decode( + b64_to_decode, + buf, + self.engine.internal_decoded_len_estimate(b64_len_to_decode), + ) + .map_err(|dse| match dse { + DecodeSliceError::DecodeError(de) => { + match de { + DecodeError::InvalidByte(offset, byte) => { + match (byte, self.padding_offset) { + // if there was padding in a previous block of decoding that happened to + // be correct, and we now find more padding that happens to be incorrect, + // to be consistent with non-reader decodes, record the error at the first + // padding + (PAD_BYTE, Some(first_pad_offset)) => { + DecodeError::InvalidByte(first_pad_offset, PAD_BYTE) + } + _ => { + DecodeError::InvalidByte(self.input_consumed_len + offset, byte) + } + } + } + DecodeError::InvalidLength(len) => { + DecodeError::InvalidLength(self.input_consumed_len + len) + } + DecodeError::InvalidLastSymbol(offset, byte) => { + DecodeError::InvalidLastSymbol(self.input_consumed_len + offset, byte) + } + DecodeError::InvalidPadding => DecodeError::InvalidPadding, + } + } + DecodeSliceError::OutputSliceTooSmall => { + unreachable!("buf is sized correctly in calling code") + } + }) + .map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e))?; + + if let Some(offset) = self.padding_offset { + // we've already seen padding + if decode_metadata.decoded_len > 0 { + // we read more after already finding padding; report error at first padding byte + return Err(io::Error::new( + io::ErrorKind::InvalidData, + DecodeError::InvalidByte(offset, PAD_BYTE), + )); + } + } + + self.padding_offset = self.padding_offset.or(decode_metadata + .padding_offset + .map(|offset| self.input_consumed_len + offset)); + self.input_consumed_len += b64_len_to_decode; + self.b64_offset += b64_len_to_decode; + self.b64_len -= b64_len_to_decode; + + debug_assert!(self.b64_offset + self.b64_len <= BUF_SIZE); + + Ok(decode_metadata.decoded_len) + } + + /// Unwraps this `DecoderReader`, returning the base reader which it reads base64 encoded + /// input from. + /// + /// Because `DecoderReader` performs internal buffering, the state of the inner reader is + /// unspecified. This function is mainly provided because the inner reader type may provide + /// additional functionality beyond the `Read` implementation which may still be useful. + pub fn into_inner(self) -> R { + self.inner + } +} + +impl<'e, E: Engine, R: io::Read> io::Read for DecoderReader<'e, E, R> { + /// Decode input from the wrapped reader. + /// + /// Under non-error circumstances, this returns `Ok` with the value being the number of bytes + /// written in `buf`. + /// + /// Where possible, this function buffers base64 to minimize the number of read() calls to the + /// delegate reader. + /// + /// # Errors + /// + /// Any errors emitted by the delegate reader are returned. Decoding errors due to invalid + /// base64 are also possible, and will have `io::ErrorKind::InvalidData`. + fn read(&mut self, buf: &mut [u8]) -> io::Result { + if buf.is_empty() { + return Ok(0); + } + + // offset == BUF_SIZE when we copied it all last time + debug_assert!(self.b64_offset <= BUF_SIZE); + debug_assert!(self.b64_offset + self.b64_len <= BUF_SIZE); + debug_assert!(if self.b64_offset == BUF_SIZE { + self.b64_len == 0 + } else { + self.b64_len <= BUF_SIZE + }); + + debug_assert!(if self.decoded_len == 0 { + // can be = when we were able to copy the complete chunk + self.decoded_offset <= DECODED_CHUNK_SIZE + } else { + self.decoded_offset < DECODED_CHUNK_SIZE + }); + + // We shouldn't ever decode into decoded_buffer when we can't immediately write at least one + // byte into the provided buf, so the effective length should only be 3 momentarily between + // when we decode and when we copy into the target buffer. + debug_assert!(self.decoded_len < DECODED_CHUNK_SIZE); + debug_assert!(self.decoded_len + self.decoded_offset <= DECODED_CHUNK_SIZE); + + if self.decoded_len > 0 { + // we have a few leftover decoded bytes; flush that rather than pull in more b64 + self.flush_decoded_buf(buf) + } else { + let mut at_eof = false; + while self.b64_len < BASE64_CHUNK_SIZE { + // Copy any bytes we have to the start of the buffer. + self.b64_buffer + .copy_within(self.b64_offset..self.b64_offset + self.b64_len, 0); + self.b64_offset = 0; + + // then fill in more data + let read = self.read_from_delegate()?; + if read == 0 { + // we never read into an empty buf, so 0 => we've hit EOF + at_eof = true; + break; + } + } + + if self.b64_len == 0 { + debug_assert!(at_eof); + // we must be at EOF, and we have no data left to decode + return Ok(0); + }; + + debug_assert!(if at_eof { + // if we are at eof, we may not have a complete chunk + self.b64_len > 0 + } else { + // otherwise, we must have at least one chunk + self.b64_len >= BASE64_CHUNK_SIZE + }); + + debug_assert_eq!(0, self.decoded_len); + + if buf.len() < DECODED_CHUNK_SIZE { + // caller requested an annoyingly short read + // have to write to a tmp buf first to avoid double mutable borrow + let mut decoded_chunk = [0_u8; DECODED_CHUNK_SIZE]; + // if we are at eof, could have less than BASE64_CHUNK_SIZE, in which case we have + // to assume that these last few tokens are, in fact, valid (i.e. must be 2-4 b64 + // tokens, not 1, since 1 token can't decode to 1 byte). + let to_decode = cmp::min(self.b64_len, BASE64_CHUNK_SIZE); + + let decoded = self.decode_to_buf(to_decode, &mut decoded_chunk[..])?; + self.decoded_chunk_buffer[..decoded].copy_from_slice(&decoded_chunk[..decoded]); + + self.decoded_offset = 0; + self.decoded_len = decoded; + + // can be less than 3 on last block due to padding + debug_assert!(decoded <= 3); + + self.flush_decoded_buf(buf) + } else { + let b64_bytes_that_can_decode_into_buf = (buf.len() / DECODED_CHUNK_SIZE) + .checked_mul(BASE64_CHUNK_SIZE) + .expect("too many chunks"); + debug_assert!(b64_bytes_that_can_decode_into_buf >= BASE64_CHUNK_SIZE); + + let b64_bytes_available_to_decode = if at_eof { + self.b64_len + } else { + // only use complete chunks + self.b64_len - self.b64_len % 4 + }; + + let actual_decode_len = cmp::min( + b64_bytes_that_can_decode_into_buf, + b64_bytes_available_to_decode, + ); + self.decode_to_buf(actual_decode_len, buf) + } + } + } +} diff --git a/vendor/base64/src/read/decoder_tests.rs b/vendor/base64/src/read/decoder_tests.rs new file mode 100644 index 0000000..f343145 --- /dev/null +++ b/vendor/base64/src/read/decoder_tests.rs @@ -0,0 +1,487 @@ +use std::{ + cmp, + io::{self, Read as _}, + iter, +}; + +use rand::{Rng as _, RngCore as _}; + +use super::decoder::{DecoderReader, BUF_SIZE}; +use crate::{ + alphabet, + engine::{general_purpose::STANDARD, Engine, GeneralPurpose}, + tests::{random_alphabet, random_config, random_engine}, + DecodeError, PAD_BYTE, +}; + +#[test] +fn simple() { + let tests: &[(&[u8], &[u8])] = &[ + (&b"0"[..], &b"MA=="[..]), + (b"01", b"MDE="), + (b"012", b"MDEy"), + (b"0123", b"MDEyMw=="), + (b"01234", b"MDEyMzQ="), + (b"012345", b"MDEyMzQ1"), + (b"0123456", b"MDEyMzQ1Ng=="), + (b"01234567", b"MDEyMzQ1Njc="), + (b"012345678", b"MDEyMzQ1Njc4"), + (b"0123456789", b"MDEyMzQ1Njc4OQ=="), + ][..]; + + for (text_expected, base64data) in tests.iter() { + // Read n bytes at a time. + for n in 1..base64data.len() + 1 { + let mut wrapped_reader = io::Cursor::new(base64data); + let mut decoder = DecoderReader::new(&mut wrapped_reader, &STANDARD); + + // handle errors as you normally would + let mut text_got = Vec::new(); + let mut buffer = vec![0u8; n]; + while let Ok(read) = decoder.read(&mut buffer[..]) { + if read == 0 { + break; + } + text_got.extend_from_slice(&buffer[..read]); + } + + assert_eq!( + text_got, + *text_expected, + "\nGot: {}\nExpected: {}", + String::from_utf8_lossy(&text_got[..]), + String::from_utf8_lossy(text_expected) + ); + } + } +} + +// Make sure we error out on trailing junk. +#[test] +fn trailing_junk() { + let tests: &[&[u8]] = &[&b"MDEyMzQ1Njc4*!@#$%^&"[..], b"MDEyMzQ1Njc4OQ== "][..]; + + for base64data in tests.iter() { + // Read n bytes at a time. + for n in 1..base64data.len() + 1 { + let mut wrapped_reader = io::Cursor::new(base64data); + let mut decoder = DecoderReader::new(&mut wrapped_reader, &STANDARD); + + // handle errors as you normally would + let mut buffer = vec![0u8; n]; + let mut saw_error = false; + loop { + match decoder.read(&mut buffer[..]) { + Err(_) => { + saw_error = true; + break; + } + Ok(0) => break, + Ok(_len) => (), + } + } + + assert!(saw_error); + } + } +} + +#[test] +fn handles_short_read_from_delegate() { + let mut rng = rand::thread_rng(); + let mut bytes = Vec::new(); + let mut b64 = String::new(); + let mut decoded = Vec::new(); + + for _ in 0..10_000 { + bytes.clear(); + b64.clear(); + decoded.clear(); + + let size = rng.gen_range(0..(10 * BUF_SIZE)); + bytes.extend(iter::repeat(0).take(size)); + bytes.truncate(size); + rng.fill_bytes(&mut bytes[..size]); + assert_eq!(size, bytes.len()); + + let engine = random_engine(&mut rng); + engine.encode_string(&bytes[..], &mut b64); + + let mut wrapped_reader = io::Cursor::new(b64.as_bytes()); + let mut short_reader = RandomShortRead { + delegate: &mut wrapped_reader, + rng: &mut rng, + }; + + let mut decoder = DecoderReader::new(&mut short_reader, &engine); + + let decoded_len = decoder.read_to_end(&mut decoded).unwrap(); + assert_eq!(size, decoded_len); + assert_eq!(&bytes[..], &decoded[..]); + } +} + +#[test] +fn read_in_short_increments() { + let mut rng = rand::thread_rng(); + let mut bytes = Vec::new(); + let mut b64 = String::new(); + let mut decoded = Vec::new(); + + for _ in 0..10_000 { + bytes.clear(); + b64.clear(); + decoded.clear(); + + let size = rng.gen_range(0..(10 * BUF_SIZE)); + bytes.extend(iter::repeat(0).take(size)); + // leave room to play around with larger buffers + decoded.extend(iter::repeat(0).take(size * 3)); + + rng.fill_bytes(&mut bytes[..]); + assert_eq!(size, bytes.len()); + + let engine = random_engine(&mut rng); + + engine.encode_string(&bytes[..], &mut b64); + + let mut wrapped_reader = io::Cursor::new(&b64[..]); + let mut decoder = DecoderReader::new(&mut wrapped_reader, &engine); + + consume_with_short_reads_and_validate(&mut rng, &bytes[..], &mut decoded, &mut decoder); + } +} + +#[test] +fn read_in_short_increments_with_short_delegate_reads() { + let mut rng = rand::thread_rng(); + let mut bytes = Vec::new(); + let mut b64 = String::new(); + let mut decoded = Vec::new(); + + for _ in 0..10_000 { + bytes.clear(); + b64.clear(); + decoded.clear(); + + let size = rng.gen_range(0..(10 * BUF_SIZE)); + bytes.extend(iter::repeat(0).take(size)); + // leave room to play around with larger buffers + decoded.extend(iter::repeat(0).take(size * 3)); + + rng.fill_bytes(&mut bytes[..]); + assert_eq!(size, bytes.len()); + + let engine = random_engine(&mut rng); + + engine.encode_string(&bytes[..], &mut b64); + + let mut base_reader = io::Cursor::new(&b64[..]); + let mut decoder = DecoderReader::new(&mut base_reader, &engine); + let mut short_reader = RandomShortRead { + delegate: &mut decoder, + rng: &mut rand::thread_rng(), + }; + + consume_with_short_reads_and_validate( + &mut rng, + &bytes[..], + &mut decoded, + &mut short_reader, + ); + } +} + +#[test] +fn reports_invalid_last_symbol_correctly() { + let mut rng = rand::thread_rng(); + let mut bytes = Vec::new(); + let mut b64 = String::new(); + let mut b64_bytes = Vec::new(); + let mut decoded = Vec::new(); + let mut bulk_decoded = Vec::new(); + + for _ in 0..1_000 { + bytes.clear(); + b64.clear(); + b64_bytes.clear(); + + let size = rng.gen_range(1..(10 * BUF_SIZE)); + bytes.extend(iter::repeat(0).take(size)); + decoded.extend(iter::repeat(0).take(size)); + rng.fill_bytes(&mut bytes[..]); + assert_eq!(size, bytes.len()); + + let config = random_config(&mut rng); + let alphabet = random_alphabet(&mut rng); + // changing padding will cause invalid padding errors when we twiddle the last byte + let engine = GeneralPurpose::new(alphabet, config.with_encode_padding(false)); + engine.encode_string(&bytes[..], &mut b64); + b64_bytes.extend(b64.bytes()); + assert_eq!(b64_bytes.len(), b64.len()); + + // change the last character to every possible symbol. Should behave the same as bulk + // decoding whether invalid or valid. + for &s1 in alphabet.symbols.iter() { + decoded.clear(); + bulk_decoded.clear(); + + // replace the last + *b64_bytes.last_mut().unwrap() = s1; + let bulk_res = engine.decode_vec(&b64_bytes[..], &mut bulk_decoded); + + let mut wrapped_reader = io::Cursor::new(&b64_bytes[..]); + let mut decoder = DecoderReader::new(&mut wrapped_reader, &engine); + + let stream_res = decoder.read_to_end(&mut decoded).map(|_| ()).map_err(|e| { + e.into_inner() + .and_then(|e| e.downcast::().ok()) + }); + + assert_eq!(bulk_res.map_err(|e| Some(Box::new(e))), stream_res); + } + } +} + +#[test] +fn reports_invalid_byte_correctly() { + let mut rng = rand::thread_rng(); + let mut bytes = Vec::new(); + let mut b64 = String::new(); + let mut stream_decoded = Vec::new(); + let mut bulk_decoded = Vec::new(); + + for _ in 0..10_000 { + bytes.clear(); + b64.clear(); + stream_decoded.clear(); + bulk_decoded.clear(); + + let size = rng.gen_range(1..(10 * BUF_SIZE)); + bytes.extend(iter::repeat(0).take(size)); + rng.fill_bytes(&mut bytes[..size]); + assert_eq!(size, bytes.len()); + + let engine = GeneralPurpose::new(&alphabet::STANDARD, random_config(&mut rng)); + + engine.encode_string(&bytes[..], &mut b64); + // replace one byte, somewhere, with '*', which is invalid + let bad_byte_pos = rng.gen_range(0..b64.len()); + let mut b64_bytes = b64.bytes().collect::>(); + b64_bytes[bad_byte_pos] = b'*'; + + let mut wrapped_reader = io::Cursor::new(b64_bytes.clone()); + let mut decoder = DecoderReader::new(&mut wrapped_reader, &engine); + + let read_decode_err = decoder + .read_to_end(&mut stream_decoded) + .map_err(|e| { + let kind = e.kind(); + let inner = e + .into_inner() + .and_then(|e| e.downcast::().ok()); + inner.map(|i| (*i, kind)) + }) + .err() + .and_then(|o| o); + + let bulk_decode_err = engine.decode_vec(&b64_bytes[..], &mut bulk_decoded).err(); + + // it's tricky to predict where the invalid data's offset will be since if it's in the last + // chunk it will be reported at the first padding location because it's treated as invalid + // padding. So, we just check that it's the same as it is for decoding all at once. + assert_eq!( + bulk_decode_err.map(|e| (e, io::ErrorKind::InvalidData)), + read_decode_err + ); + } +} + +#[test] +fn internal_padding_error_with_short_read_concatenated_texts_invalid_byte_error() { + let mut rng = rand::thread_rng(); + let mut bytes = Vec::new(); + let mut b64 = String::new(); + let mut reader_decoded = Vec::new(); + let mut bulk_decoded = Vec::new(); + + // encodes with padding, requires that padding be present so we don't get InvalidPadding + // just because padding is there at all + let engine = STANDARD; + + for _ in 0..10_000 { + bytes.clear(); + b64.clear(); + reader_decoded.clear(); + bulk_decoded.clear(); + + // at least 2 bytes so there can be a split point between bytes + let size = rng.gen_range(2..(10 * BUF_SIZE)); + bytes.resize(size, 0); + rng.fill_bytes(&mut bytes[..size]); + + // Concatenate two valid b64s, yielding padding in the middle. + // This avoids scenarios that are challenging to assert on, like random padding location + // that might be InvalidLastSymbol when decoded at certain buffer sizes but InvalidByte + // when done all at once. + let split = loop { + // find a split point that will produce padding on the first part + let s = rng.gen_range(1..size); + if s % 3 != 0 { + // short enough to need padding + break s; + }; + }; + + engine.encode_string(&bytes[..split], &mut b64); + assert!(b64.contains('='), "split: {}, b64: {}", split, b64); + let bad_byte_pos = b64.find('=').unwrap(); + engine.encode_string(&bytes[split..], &mut b64); + let b64_bytes = b64.as_bytes(); + + // short read to make it plausible for padding to happen on a read boundary + let read_len = rng.gen_range(1..10); + let mut wrapped_reader = ShortRead { + max_read_len: read_len, + delegate: io::Cursor::new(&b64_bytes), + }; + + let mut decoder = DecoderReader::new(&mut wrapped_reader, &engine); + + let read_decode_err = decoder + .read_to_end(&mut reader_decoded) + .map_err(|e| { + *e.into_inner() + .and_then(|e| e.downcast::().ok()) + .unwrap() + }) + .unwrap_err(); + + let bulk_decode_err = engine.decode_vec(b64_bytes, &mut bulk_decoded).unwrap_err(); + + assert_eq!( + bulk_decode_err, + read_decode_err, + "read len: {}, bad byte pos: {}, b64: {}", + read_len, + bad_byte_pos, + std::str::from_utf8(b64_bytes).unwrap() + ); + assert_eq!( + DecodeError::InvalidByte( + split / 3 * 4 + + match split % 3 { + 1 => 2, + 2 => 3, + _ => unreachable!(), + }, + PAD_BYTE + ), + read_decode_err + ); + } +} + +#[test] +fn internal_padding_anywhere_error() { + let mut rng = rand::thread_rng(); + let mut bytes = Vec::new(); + let mut b64 = String::new(); + let mut reader_decoded = Vec::new(); + + // encodes with padding, requires that padding be present so we don't get InvalidPadding + // just because padding is there at all + let engine = STANDARD; + + for _ in 0..10_000 { + bytes.clear(); + b64.clear(); + reader_decoded.clear(); + + bytes.resize(10 * BUF_SIZE, 0); + rng.fill_bytes(&mut bytes[..]); + + // Just shove a padding byte in there somewhere. + // The specific error to expect is challenging to predict precisely because it + // will vary based on the position of the padding in the quad and the read buffer + // length, but SOMETHING should go wrong. + + engine.encode_string(&bytes[..], &mut b64); + let mut b64_bytes = b64.as_bytes().to_vec(); + // put padding somewhere other than the last quad + b64_bytes[rng.gen_range(0..bytes.len() - 4)] = PAD_BYTE; + + // short read to make it plausible for padding to happen on a read boundary + let read_len = rng.gen_range(1..10); + let mut wrapped_reader = ShortRead { + max_read_len: read_len, + delegate: io::Cursor::new(&b64_bytes), + }; + + let mut decoder = DecoderReader::new(&mut wrapped_reader, &engine); + + let result = decoder.read_to_end(&mut reader_decoded); + assert!(result.is_err()); + } +} + +fn consume_with_short_reads_and_validate( + rng: &mut rand::rngs::ThreadRng, + expected_bytes: &[u8], + decoded: &mut [u8], + short_reader: &mut R, +) { + let mut total_read = 0_usize; + loop { + assert!( + total_read <= expected_bytes.len(), + "tr {} size {}", + total_read, + expected_bytes.len() + ); + if total_read == expected_bytes.len() { + assert_eq!(expected_bytes, &decoded[..total_read]); + // should be done + assert_eq!(0, short_reader.read(&mut *decoded).unwrap()); + // didn't write anything + assert_eq!(expected_bytes, &decoded[..total_read]); + + break; + } + let decode_len = rng.gen_range(1..cmp::max(2, expected_bytes.len() * 2)); + + let read = short_reader + .read(&mut decoded[total_read..total_read + decode_len]) + .unwrap(); + total_read += read; + } +} + +/// Limits how many bytes a reader will provide in each read call. +/// Useful for shaking out code that may work fine only with typical input sources that always fill +/// the buffer. +struct RandomShortRead<'a, 'b, R: io::Read, N: rand::Rng> { + delegate: &'b mut R, + rng: &'a mut N, +} + +impl<'a, 'b, R: io::Read, N: rand::Rng> io::Read for RandomShortRead<'a, 'b, R, N> { + fn read(&mut self, buf: &mut [u8]) -> Result { + // avoid 0 since it means EOF for non-empty buffers + let effective_len = cmp::min(self.rng.gen_range(1..20), buf.len()); + + self.delegate.read(&mut buf[..effective_len]) + } +} + +struct ShortRead { + delegate: R, + max_read_len: usize, +} + +impl io::Read for ShortRead { + fn read(&mut self, buf: &mut [u8]) -> io::Result { + let len = self.max_read_len.max(buf.len()); + self.delegate.read(&mut buf[..len]) + } +} diff --git a/vendor/base64/src/read/mod.rs b/vendor/base64/src/read/mod.rs new file mode 100644 index 0000000..8560644 --- /dev/null +++ b/vendor/base64/src/read/mod.rs @@ -0,0 +1,6 @@ +//! Implementations of `io::Read` to transparently decode base64. +mod decoder; +pub use self::decoder::DecoderReader; + +#[cfg(test)] +mod decoder_tests; diff --git a/vendor/base64/src/tests.rs b/vendor/base64/src/tests.rs new file mode 100644 index 0000000..7083b54 --- /dev/null +++ b/vendor/base64/src/tests.rs @@ -0,0 +1,117 @@ +use std::str; + +use rand::{ + distributions, + distributions::{Distribution as _, Uniform}, + seq::SliceRandom, + Rng, SeedableRng, +}; + +use crate::{ + alphabet, + encode::encoded_len, + engine::{ + general_purpose::{GeneralPurpose, GeneralPurposeConfig}, + Config, DecodePaddingMode, Engine, + }, +}; + +#[test] +fn roundtrip_random_config_short() { + // exercise the slower encode/decode routines that operate on shorter buffers more vigorously + roundtrip_random_config(Uniform::new(0, 50), 10_000); +} + +#[test] +fn roundtrip_random_config_long() { + roundtrip_random_config(Uniform::new(0, 1000), 10_000); +} + +pub fn assert_encode_sanity(encoded: &str, padded: bool, input_len: usize) { + let input_rem = input_len % 3; + let expected_padding_len = if input_rem > 0 { + if padded { + 3 - input_rem + } else { + 0 + } + } else { + 0 + }; + + let expected_encoded_len = encoded_len(input_len, padded).unwrap(); + + assert_eq!(expected_encoded_len, encoded.len()); + + let padding_len = encoded.chars().filter(|&c| c == '=').count(); + + assert_eq!(expected_padding_len, padding_len); + + let _ = str::from_utf8(encoded.as_bytes()).expect("Base64 should be valid utf8"); +} + +fn roundtrip_random_config(input_len_range: Uniform, iterations: u32) { + let mut input_buf: Vec = Vec::new(); + let mut encoded_buf = String::new(); + let mut rng = rand::rngs::SmallRng::from_entropy(); + + for _ in 0..iterations { + input_buf.clear(); + encoded_buf.clear(); + + let input_len = input_len_range.sample(&mut rng); + + let engine = random_engine(&mut rng); + + for _ in 0..input_len { + input_buf.push(rng.gen()); + } + + engine.encode_string(&input_buf, &mut encoded_buf); + + assert_encode_sanity(&encoded_buf, engine.config().encode_padding(), input_len); + + assert_eq!(input_buf, engine.decode(&encoded_buf).unwrap()); + } +} + +pub fn random_config(rng: &mut R) -> GeneralPurposeConfig { + let mode = rng.gen(); + GeneralPurposeConfig::new() + .with_encode_padding(match mode { + DecodePaddingMode::Indifferent => rng.gen(), + DecodePaddingMode::RequireCanonical => true, + DecodePaddingMode::RequireNone => false, + }) + .with_decode_padding_mode(mode) + .with_decode_allow_trailing_bits(rng.gen()) +} + +impl distributions::Distribution for distributions::Standard { + fn sample(&self, rng: &mut R) -> DecodePaddingMode { + match rng.gen_range(0..=2) { + 0 => DecodePaddingMode::Indifferent, + 1 => DecodePaddingMode::RequireCanonical, + _ => DecodePaddingMode::RequireNone, + } + } +} + +pub fn random_alphabet(rng: &mut R) -> &'static alphabet::Alphabet { + ALPHABETS.choose(rng).unwrap() +} + +pub fn random_engine(rng: &mut R) -> GeneralPurpose { + let alphabet = random_alphabet(rng); + let config = random_config(rng); + GeneralPurpose::new(alphabet, config) +} + +const ALPHABETS: &[alphabet::Alphabet] = &[ + alphabet::URL_SAFE, + alphabet::STANDARD, + alphabet::CRYPT, + alphabet::BCRYPT, + alphabet::IMAP_MUTF7, + alphabet::BIN_HEX, +]; diff --git a/vendor/base64/src/write/encoder.rs b/vendor/base64/src/write/encoder.rs new file mode 100644 index 0000000..1c19bb4 --- /dev/null +++ b/vendor/base64/src/write/encoder.rs @@ -0,0 +1,407 @@ +use crate::engine::Engine; +use std::{ + cmp, fmt, io, + io::{ErrorKind, Result}, +}; + +pub(crate) const BUF_SIZE: usize = 1024; +/// The most bytes whose encoding will fit in `BUF_SIZE` +const MAX_INPUT_LEN: usize = BUF_SIZE / 4 * 3; +// 3 bytes of input = 4 bytes of base64, always (because we don't allow line wrapping) +const MIN_ENCODE_CHUNK_SIZE: usize = 3; + +/// A `Write` implementation that base64 encodes data before delegating to the wrapped writer. +/// +/// Because base64 has special handling for the end of the input data (padding, etc), there's a +/// `finish()` method on this type that encodes any leftover input bytes and adds padding if +/// appropriate. It's called automatically when deallocated (see the `Drop` implementation), but +/// any error that occurs when invoking the underlying writer will be suppressed. If you want to +/// handle such errors, call `finish()` yourself. +/// +/// # Examples +/// +/// ``` +/// use std::io::Write; +/// use base64::engine::general_purpose; +/// +/// // use a vec as the simplest possible `Write` -- in real code this is probably a file, etc. +/// let mut enc = base64::write::EncoderWriter::new(Vec::new(), &general_purpose::STANDARD); +/// +/// // handle errors as you normally would +/// enc.write_all(b"asdf").unwrap(); +/// +/// // could leave this out to be called by Drop, if you don't care +/// // about handling errors or getting the delegate writer back +/// let delegate = enc.finish().unwrap(); +/// +/// // base64 was written to the writer +/// assert_eq!(b"YXNkZg==", &delegate[..]); +/// +/// ``` +/// +/// # Panics +/// +/// Calling `write()` (or related methods) or `finish()` after `finish()` has completed without +/// error is invalid and will panic. +/// +/// # Errors +/// +/// Base64 encoding itself does not generate errors, but errors from the wrapped writer will be +/// returned as per the contract of `Write`. +/// +/// # Performance +/// +/// It has some minor performance loss compared to encoding slices (a couple percent). +/// It does not do any heap allocation. +/// +/// # Limitations +/// +/// Owing to the specification of the `write` and `flush` methods on the `Write` trait and their +/// implications for a buffering implementation, these methods may not behave as expected. In +/// particular, calling `write_all` on this interface may fail with `io::ErrorKind::WriteZero`. +/// See the documentation of the `Write` trait implementation for further details. +pub struct EncoderWriter<'e, E: Engine, W: io::Write> { + engine: &'e E, + /// Where encoded data is written to. It's an Option as it's None immediately before Drop is + /// called so that finish() can return the underlying writer. None implies that finish() has + /// been called successfully. + delegate: Option, + /// Holds a partial chunk, if any, after the last `write()`, so that we may then fill the chunk + /// with the next `write()`, encode it, then proceed with the rest of the input normally. + extra_input: [u8; MIN_ENCODE_CHUNK_SIZE], + /// How much of `extra` is occupied, in `[0, MIN_ENCODE_CHUNK_SIZE]`. + extra_input_occupied_len: usize, + /// Buffer to encode into. May hold leftover encoded bytes from a previous write call that the underlying writer + /// did not write last time. + output: [u8; BUF_SIZE], + /// How much of `output` is occupied with encoded data that couldn't be written last time + output_occupied_len: usize, + /// panic safety: don't write again in destructor if writer panicked while we were writing to it + panicked: bool, +} + +impl<'e, E: Engine, W: io::Write> fmt::Debug for EncoderWriter<'e, E, W> { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!( + f, + "extra_input: {:?} extra_input_occupied_len:{:?} output[..5]: {:?} output_occupied_len: {:?}", + self.extra_input, + self.extra_input_occupied_len, + &self.output[0..5], + self.output_occupied_len + ) + } +} + +impl<'e, E: Engine, W: io::Write> EncoderWriter<'e, E, W> { + /// Create a new encoder that will write to the provided delegate writer. + pub fn new(delegate: W, engine: &'e E) -> EncoderWriter<'e, E, W> { + EncoderWriter { + engine, + delegate: Some(delegate), + extra_input: [0u8; MIN_ENCODE_CHUNK_SIZE], + extra_input_occupied_len: 0, + output: [0u8; BUF_SIZE], + output_occupied_len: 0, + panicked: false, + } + } + + /// Encode all remaining buffered data and write it, including any trailing incomplete input + /// triples and associated padding. + /// + /// Once this succeeds, no further writes or calls to this method are allowed. + /// + /// This may write to the delegate writer multiple times if the delegate writer does not accept + /// all input provided to its `write` each invocation. + /// + /// If you don't care about error handling, it is not necessary to call this function, as the + /// equivalent finalization is done by the Drop impl. + /// + /// Returns the writer that this was constructed around. + /// + /// # Errors + /// + /// The first error that is not of `ErrorKind::Interrupted` will be returned. + pub fn finish(&mut self) -> Result { + // If we could consume self in finish(), we wouldn't have to worry about this case, but + // finish() is retryable in the face of I/O errors, so we can't consume here. + if self.delegate.is_none() { + panic!("Encoder has already had finish() called"); + }; + + self.write_final_leftovers()?; + + let writer = self.delegate.take().expect("Writer must be present"); + + Ok(writer) + } + + /// Write any remaining buffered data to the delegate writer. + fn write_final_leftovers(&mut self) -> Result<()> { + if self.delegate.is_none() { + // finish() has already successfully called this, and we are now in drop() with a None + // writer, so just no-op + return Ok(()); + } + + self.write_all_encoded_output()?; + + if self.extra_input_occupied_len > 0 { + let encoded_len = self + .engine + .encode_slice( + &self.extra_input[..self.extra_input_occupied_len], + &mut self.output[..], + ) + .expect("buffer is large enough"); + + self.output_occupied_len = encoded_len; + + self.write_all_encoded_output()?; + + // write succeeded, do not write the encoding of extra again if finish() is retried + self.extra_input_occupied_len = 0; + } + + Ok(()) + } + + /// Write as much of the encoded output to the delegate writer as it will accept, and store the + /// leftovers to be attempted at the next write() call. Updates `self.output_occupied_len`. + /// + /// # Errors + /// + /// Errors from the delegate writer are returned. In the case of an error, + /// `self.output_occupied_len` will not be updated, as errors from `write` are specified to mean + /// that no write took place. + fn write_to_delegate(&mut self, current_output_len: usize) -> Result<()> { + self.panicked = true; + let res = self + .delegate + .as_mut() + .expect("Writer must be present") + .write(&self.output[..current_output_len]); + self.panicked = false; + + res.map(|consumed| { + debug_assert!(consumed <= current_output_len); + + if consumed < current_output_len { + self.output_occupied_len = current_output_len.checked_sub(consumed).unwrap(); + // If we're blocking on I/O, the minor inefficiency of copying bytes to the + // start of the buffer is the least of our concerns... + // TODO Rotate moves more than we need to; copy_within now stable. + self.output.rotate_left(consumed); + } else { + self.output_occupied_len = 0; + } + }) + } + + /// Write all buffered encoded output. If this returns `Ok`, `self.output_occupied_len` is `0`. + /// + /// This is basically write_all for the remaining buffered data but without the undesirable + /// abort-on-`Ok(0)` behavior. + /// + /// # Errors + /// + /// Any error emitted by the delegate writer abort the write loop and is returned, unless it's + /// `Interrupted`, in which case the error is ignored and writes will continue. + fn write_all_encoded_output(&mut self) -> Result<()> { + while self.output_occupied_len > 0 { + let remaining_len = self.output_occupied_len; + match self.write_to_delegate(remaining_len) { + // try again on interrupts ala write_all + Err(ref e) if e.kind() == ErrorKind::Interrupted => {} + // other errors return + Err(e) => return Err(e), + // success no-ops because remaining length is already updated + Ok(_) => {} + }; + } + + debug_assert_eq!(0, self.output_occupied_len); + Ok(()) + } + + /// Unwraps this `EncoderWriter`, returning the base writer it writes base64 encoded output + /// to. + /// + /// Normally this method should not be needed, since `finish()` returns the inner writer if + /// it completes successfully. That will also ensure all data has been flushed, which the + /// `into_inner()` function does *not* do. + /// + /// Calling this method after `finish()` has completed successfully will panic, since the + /// writer has already been returned. + /// + /// This method may be useful if the writer implements additional APIs beyond the `Write` + /// trait. Note that the inner writer might be in an error state or have an incomplete + /// base64 string written to it. + pub fn into_inner(mut self) -> W { + self.delegate + .take() + .expect("Encoder has already had finish() called") + } +} + +impl<'e, E: Engine, W: io::Write> io::Write for EncoderWriter<'e, E, W> { + /// Encode input and then write to the delegate writer. + /// + /// Under non-error circumstances, this returns `Ok` with the value being the number of bytes + /// of `input` consumed. The value may be `0`, which interacts poorly with `write_all`, which + /// interprets `Ok(0)` as an error, despite it being allowed by the contract of `write`. See + /// for more on that. + /// + /// If the previous call to `write` provided more (encoded) data than the delegate writer could + /// accept in a single call to its `write`, the remaining data is buffered. As long as buffered + /// data is present, subsequent calls to `write` will try to write the remaining buffered data + /// to the delegate and return either `Ok(0)` -- and therefore not consume any of `input` -- or + /// an error. + /// + /// # Errors + /// + /// Any errors emitted by the delegate writer are returned. + fn write(&mut self, input: &[u8]) -> Result { + if self.delegate.is_none() { + panic!("Cannot write more after calling finish()"); + } + + if input.is_empty() { + return Ok(0); + } + + // The contract of `Write::write` places some constraints on this implementation: + // - a call to `write()` represents at most one call to a wrapped `Write`, so we can't + // iterate over the input and encode multiple chunks. + // - Errors mean that "no bytes were written to this writer", so we need to reset the + // internal state to what it was before the error occurred + + // before reading any input, write any leftover encoded output from last time + if self.output_occupied_len > 0 { + let current_len = self.output_occupied_len; + return self + .write_to_delegate(current_len) + // did not read any input + .map(|_| 0); + } + + debug_assert_eq!(0, self.output_occupied_len); + + // how many bytes, if any, were read into `extra` to create a triple to encode + let mut extra_input_read_len = 0; + let mut input = input; + + let orig_extra_len = self.extra_input_occupied_len; + + let mut encoded_size = 0; + // always a multiple of MIN_ENCODE_CHUNK_SIZE + let mut max_input_len = MAX_INPUT_LEN; + + // process leftover un-encoded input from last write + if self.extra_input_occupied_len > 0 { + debug_assert!(self.extra_input_occupied_len < 3); + if input.len() + self.extra_input_occupied_len >= MIN_ENCODE_CHUNK_SIZE { + // Fill up `extra`, encode that into `output`, and consume as much of the rest of + // `input` as possible. + // We could write just the encoding of `extra` by itself but then we'd have to + // return after writing only 4 bytes, which is inefficient if the underlying writer + // would make a syscall. + extra_input_read_len = MIN_ENCODE_CHUNK_SIZE - self.extra_input_occupied_len; + debug_assert!(extra_input_read_len > 0); + // overwrite only bytes that weren't already used. If we need to rollback extra_len + // (when the subsequent write errors), the old leading bytes will still be there. + self.extra_input[self.extra_input_occupied_len..MIN_ENCODE_CHUNK_SIZE] + .copy_from_slice(&input[0..extra_input_read_len]); + + let len = self.engine.internal_encode( + &self.extra_input[0..MIN_ENCODE_CHUNK_SIZE], + &mut self.output[..], + ); + debug_assert_eq!(4, len); + + input = &input[extra_input_read_len..]; + + // consider extra to be used up, since we encoded it + self.extra_input_occupied_len = 0; + // don't clobber where we just encoded to + encoded_size = 4; + // and don't read more than can be encoded + max_input_len = MAX_INPUT_LEN - MIN_ENCODE_CHUNK_SIZE; + + // fall through to normal encoding + } else { + // `extra` and `input` are non empty, but `|extra| + |input| < 3`, so there must be + // 1 byte in each. + debug_assert_eq!(1, input.len()); + debug_assert_eq!(1, self.extra_input_occupied_len); + + self.extra_input[self.extra_input_occupied_len] = input[0]; + self.extra_input_occupied_len += 1; + return Ok(1); + }; + } else if input.len() < MIN_ENCODE_CHUNK_SIZE { + // `extra` is empty, and `input` fits inside it + self.extra_input[0..input.len()].copy_from_slice(input); + self.extra_input_occupied_len = input.len(); + return Ok(input.len()); + }; + + // either 0 or 1 complete chunks encoded from extra + debug_assert!(encoded_size == 0 || encoded_size == 4); + debug_assert!( + // didn't encode extra input + MAX_INPUT_LEN == max_input_len + // encoded one triple + || MAX_INPUT_LEN == max_input_len + MIN_ENCODE_CHUNK_SIZE + ); + + // encode complete triples only + let input_complete_chunks_len = input.len() - (input.len() % MIN_ENCODE_CHUNK_SIZE); + let input_chunks_to_encode_len = cmp::min(input_complete_chunks_len, max_input_len); + debug_assert_eq!(0, max_input_len % MIN_ENCODE_CHUNK_SIZE); + debug_assert_eq!(0, input_chunks_to_encode_len % MIN_ENCODE_CHUNK_SIZE); + + encoded_size += self.engine.internal_encode( + &input[..(input_chunks_to_encode_len)], + &mut self.output[encoded_size..], + ); + + // not updating `self.output_occupied_len` here because if the below write fails, it should + // "never take place" -- the buffer contents we encoded are ignored and perhaps retried + // later, if the consumer chooses. + + self.write_to_delegate(encoded_size) + // no matter whether we wrote the full encoded buffer or not, we consumed the same + // input + .map(|_| extra_input_read_len + input_chunks_to_encode_len) + .map_err(|e| { + // in case we filled and encoded `extra`, reset extra_len + self.extra_input_occupied_len = orig_extra_len; + + e + }) + } + + /// Because this is usually treated as OK to call multiple times, it will *not* flush any + /// incomplete chunks of input or write padding. + /// # Errors + /// + /// The first error that is not of [`ErrorKind::Interrupted`] will be returned. + fn flush(&mut self) -> Result<()> { + self.write_all_encoded_output()?; + self.delegate + .as_mut() + .expect("Writer must be present") + .flush() + } +} + +impl<'e, E: Engine, W: io::Write> Drop for EncoderWriter<'e, E, W> { + fn drop(&mut self) { + if !self.panicked { + // like `BufWriter`, ignore errors during drop + let _ = self.write_final_leftovers(); + } + } +} diff --git a/vendor/base64/src/write/encoder_string_writer.rs b/vendor/base64/src/write/encoder_string_writer.rs new file mode 100644 index 0000000..9c02bcd --- /dev/null +++ b/vendor/base64/src/write/encoder_string_writer.rs @@ -0,0 +1,207 @@ +use super::encoder::EncoderWriter; +use crate::engine::Engine; +use std::io; + +/// A `Write` implementation that base64-encodes data using the provided config and accumulates the +/// resulting base64 utf8 `&str` in a [StrConsumer] implementation (typically `String`), which is +/// then exposed via `into_inner()`. +/// +/// # Examples +/// +/// Buffer base64 in a new String: +/// +/// ``` +/// use std::io::Write; +/// use base64::engine::general_purpose; +/// +/// let mut enc = base64::write::EncoderStringWriter::new(&general_purpose::STANDARD); +/// +/// enc.write_all(b"asdf").unwrap(); +/// +/// // get the resulting String +/// let b64_string = enc.into_inner(); +/// +/// assert_eq!("YXNkZg==", &b64_string); +/// ``` +/// +/// Or, append to an existing `String`, which implements `StrConsumer`: +/// +/// ``` +/// use std::io::Write; +/// use base64::engine::general_purpose; +/// +/// let mut buf = String::from("base64: "); +/// +/// let mut enc = base64::write::EncoderStringWriter::from_consumer( +/// &mut buf, +/// &general_purpose::STANDARD); +/// +/// enc.write_all(b"asdf").unwrap(); +/// +/// // release the &mut reference on buf +/// let _ = enc.into_inner(); +/// +/// assert_eq!("base64: YXNkZg==", &buf); +/// ``` +/// +/// # Performance +/// +/// Because it has to validate that the base64 is UTF-8, it is about 80% as fast as writing plain +/// bytes to a `io::Write`. +pub struct EncoderStringWriter<'e, E: Engine, S: StrConsumer> { + encoder: EncoderWriter<'e, E, Utf8SingleCodeUnitWriter>, +} + +impl<'e, E: Engine, S: StrConsumer> EncoderStringWriter<'e, E, S> { + /// Create a EncoderStringWriter that will append to the provided `StrConsumer`. + pub fn from_consumer(str_consumer: S, engine: &'e E) -> Self { + EncoderStringWriter { + encoder: EncoderWriter::new(Utf8SingleCodeUnitWriter { str_consumer }, engine), + } + } + + /// Encode all remaining buffered data, including any trailing incomplete input triples and + /// associated padding. + /// + /// Returns the base64-encoded form of the accumulated written data. + pub fn into_inner(mut self) -> S { + self.encoder + .finish() + .expect("Writing to a consumer should never fail") + .str_consumer + } +} + +impl<'e, E: Engine> EncoderStringWriter<'e, E, String> { + /// Create a EncoderStringWriter that will encode into a new `String` with the provided config. + pub fn new(engine: &'e E) -> Self { + EncoderStringWriter::from_consumer(String::new(), engine) + } +} + +impl<'e, E: Engine, S: StrConsumer> io::Write for EncoderStringWriter<'e, E, S> { + fn write(&mut self, buf: &[u8]) -> io::Result { + self.encoder.write(buf) + } + + fn flush(&mut self) -> io::Result<()> { + self.encoder.flush() + } +} + +/// An abstraction around consuming `str`s produced by base64 encoding. +pub trait StrConsumer { + /// Consume the base64 encoded data in `buf` + fn consume(&mut self, buf: &str); +} + +/// As for io::Write, `StrConsumer` is implemented automatically for `&mut S`. +impl StrConsumer for &mut S { + fn consume(&mut self, buf: &str) { + (**self).consume(buf); + } +} + +/// Pushes the str onto the end of the String +impl StrConsumer for String { + fn consume(&mut self, buf: &str) { + self.push_str(buf); + } +} + +/// A `Write` that only can handle bytes that are valid single-byte UTF-8 code units. +/// +/// This is safe because we only use it when writing base64, which is always valid UTF-8. +struct Utf8SingleCodeUnitWriter { + str_consumer: S, +} + +impl io::Write for Utf8SingleCodeUnitWriter { + fn write(&mut self, buf: &[u8]) -> io::Result { + // Because we expect all input to be valid utf-8 individual bytes, we can encode any buffer + // length + let s = std::str::from_utf8(buf).expect("Input must be valid UTF-8"); + + self.str_consumer.consume(s); + + Ok(buf.len()) + } + + fn flush(&mut self) -> io::Result<()> { + // no op + Ok(()) + } +} + +#[cfg(test)] +mod tests { + use crate::{ + engine::Engine, tests::random_engine, write::encoder_string_writer::EncoderStringWriter, + }; + use rand::Rng; + use std::cmp; + use std::io::Write; + + #[test] + fn every_possible_split_of_input() { + let mut rng = rand::thread_rng(); + let mut orig_data = Vec::::new(); + let mut normal_encoded = String::new(); + + let size = 5_000; + + for i in 0..size { + orig_data.clear(); + normal_encoded.clear(); + + orig_data.resize(size, 0); + rng.fill(&mut orig_data[..]); + + let engine = random_engine(&mut rng); + engine.encode_string(&orig_data, &mut normal_encoded); + + let mut stream_encoder = EncoderStringWriter::new(&engine); + // Write the first i bytes, then the rest + stream_encoder.write_all(&orig_data[0..i]).unwrap(); + stream_encoder.write_all(&orig_data[i..]).unwrap(); + + let stream_encoded = stream_encoder.into_inner(); + + assert_eq!(normal_encoded, stream_encoded); + } + } + #[test] + fn incremental_writes() { + let mut rng = rand::thread_rng(); + let mut orig_data = Vec::::new(); + let mut normal_encoded = String::new(); + + let size = 5_000; + + for _ in 0..size { + orig_data.clear(); + normal_encoded.clear(); + + orig_data.resize(size, 0); + rng.fill(&mut orig_data[..]); + + let engine = random_engine(&mut rng); + engine.encode_string(&orig_data, &mut normal_encoded); + + let mut stream_encoder = EncoderStringWriter::new(&engine); + // write small nibbles of data + let mut offset = 0; + while offset < size { + let nibble_size = cmp::min(rng.gen_range(0..=64), size - offset); + let len = stream_encoder + .write(&orig_data[offset..offset + nibble_size]) + .unwrap(); + offset += len; + } + + let stream_encoded = stream_encoder.into_inner(); + + assert_eq!(normal_encoded, stream_encoded); + } + } +} diff --git a/vendor/base64/src/write/encoder_tests.rs b/vendor/base64/src/write/encoder_tests.rs new file mode 100644 index 0000000..1f1a165 --- /dev/null +++ b/vendor/base64/src/write/encoder_tests.rs @@ -0,0 +1,554 @@ +use std::io::{Cursor, Write}; +use std::{cmp, io, str}; + +use rand::Rng; + +use crate::{ + alphabet::{STANDARD, URL_SAFE}, + engine::{ + general_purpose::{GeneralPurpose, NO_PAD, PAD}, + Engine, + }, + tests::random_engine, +}; + +use super::EncoderWriter; + +const URL_SAFE_ENGINE: GeneralPurpose = GeneralPurpose::new(&URL_SAFE, PAD); +const NO_PAD_ENGINE: GeneralPurpose = GeneralPurpose::new(&STANDARD, NO_PAD); + +#[test] +fn encode_three_bytes() { + let mut c = Cursor::new(Vec::new()); + { + let mut enc = EncoderWriter::new(&mut c, &URL_SAFE_ENGINE); + + let sz = enc.write(b"abc").unwrap(); + assert_eq!(sz, 3); + } + assert_eq!(&c.get_ref()[..], URL_SAFE_ENGINE.encode("abc").as_bytes()); +} + +#[test] +fn encode_nine_bytes_two_writes() { + let mut c = Cursor::new(Vec::new()); + { + let mut enc = EncoderWriter::new(&mut c, &URL_SAFE_ENGINE); + + let sz = enc.write(b"abcdef").unwrap(); + assert_eq!(sz, 6); + let sz = enc.write(b"ghi").unwrap(); + assert_eq!(sz, 3); + } + assert_eq!( + &c.get_ref()[..], + URL_SAFE_ENGINE.encode("abcdefghi").as_bytes() + ); +} + +#[test] +fn encode_one_then_two_bytes() { + let mut c = Cursor::new(Vec::new()); + { + let mut enc = EncoderWriter::new(&mut c, &URL_SAFE_ENGINE); + + let sz = enc.write(b"a").unwrap(); + assert_eq!(sz, 1); + let sz = enc.write(b"bc").unwrap(); + assert_eq!(sz, 2); + } + assert_eq!(&c.get_ref()[..], URL_SAFE_ENGINE.encode("abc").as_bytes()); +} + +#[test] +fn encode_one_then_five_bytes() { + let mut c = Cursor::new(Vec::new()); + { + let mut enc = EncoderWriter::new(&mut c, &URL_SAFE_ENGINE); + + let sz = enc.write(b"a").unwrap(); + assert_eq!(sz, 1); + let sz = enc.write(b"bcdef").unwrap(); + assert_eq!(sz, 5); + } + assert_eq!( + &c.get_ref()[..], + URL_SAFE_ENGINE.encode("abcdef").as_bytes() + ); +} + +#[test] +fn encode_1_2_3_bytes() { + let mut c = Cursor::new(Vec::new()); + { + let mut enc = EncoderWriter::new(&mut c, &URL_SAFE_ENGINE); + + let sz = enc.write(b"a").unwrap(); + assert_eq!(sz, 1); + let sz = enc.write(b"bc").unwrap(); + assert_eq!(sz, 2); + let sz = enc.write(b"def").unwrap(); + assert_eq!(sz, 3); + } + assert_eq!( + &c.get_ref()[..], + URL_SAFE_ENGINE.encode("abcdef").as_bytes() + ); +} + +#[test] +fn encode_with_padding() { + let mut c = Cursor::new(Vec::new()); + { + let mut enc = EncoderWriter::new(&mut c, &URL_SAFE_ENGINE); + + enc.write_all(b"abcd").unwrap(); + + enc.flush().unwrap(); + } + assert_eq!(&c.get_ref()[..], URL_SAFE_ENGINE.encode("abcd").as_bytes()); +} + +#[test] +fn encode_with_padding_multiple_writes() { + let mut c = Cursor::new(Vec::new()); + { + let mut enc = EncoderWriter::new(&mut c, &URL_SAFE_ENGINE); + + assert_eq!(1, enc.write(b"a").unwrap()); + assert_eq!(2, enc.write(b"bc").unwrap()); + assert_eq!(3, enc.write(b"def").unwrap()); + assert_eq!(1, enc.write(b"g").unwrap()); + + enc.flush().unwrap(); + } + assert_eq!( + &c.get_ref()[..], + URL_SAFE_ENGINE.encode("abcdefg").as_bytes() + ); +} + +#[test] +fn finish_writes_extra_byte() { + let mut c = Cursor::new(Vec::new()); + { + let mut enc = EncoderWriter::new(&mut c, &URL_SAFE_ENGINE); + + assert_eq!(6, enc.write(b"abcdef").unwrap()); + + // will be in extra + assert_eq!(1, enc.write(b"g").unwrap()); + + // 1 trailing byte = 2 encoded chars + let _ = enc.finish().unwrap(); + } + assert_eq!( + &c.get_ref()[..], + URL_SAFE_ENGINE.encode("abcdefg").as_bytes() + ); +} + +#[test] +fn write_partial_chunk_encodes_partial_chunk() { + let mut c = Cursor::new(Vec::new()); + { + let mut enc = EncoderWriter::new(&mut c, &NO_PAD_ENGINE); + + // nothing encoded yet + assert_eq!(2, enc.write(b"ab").unwrap()); + // encoded here + let _ = enc.finish().unwrap(); + } + assert_eq!(&c.get_ref()[..], NO_PAD_ENGINE.encode("ab").as_bytes()); + assert_eq!(3, c.get_ref().len()); +} + +#[test] +fn write_1_chunk_encodes_complete_chunk() { + let mut c = Cursor::new(Vec::new()); + { + let mut enc = EncoderWriter::new(&mut c, &NO_PAD_ENGINE); + + assert_eq!(3, enc.write(b"abc").unwrap()); + let _ = enc.finish().unwrap(); + } + assert_eq!(&c.get_ref()[..], NO_PAD_ENGINE.encode("abc").as_bytes()); + assert_eq!(4, c.get_ref().len()); +} + +#[test] +fn write_1_chunk_and_partial_encodes_only_complete_chunk() { + let mut c = Cursor::new(Vec::new()); + { + let mut enc = EncoderWriter::new(&mut c, &NO_PAD_ENGINE); + + // "d" not consumed since it's not a full chunk + assert_eq!(3, enc.write(b"abcd").unwrap()); + let _ = enc.finish().unwrap(); + } + assert_eq!(&c.get_ref()[..], NO_PAD_ENGINE.encode("abc").as_bytes()); + assert_eq!(4, c.get_ref().len()); +} + +#[test] +fn write_2_partials_to_exactly_complete_chunk_encodes_complete_chunk() { + let mut c = Cursor::new(Vec::new()); + { + let mut enc = EncoderWriter::new(&mut c, &NO_PAD_ENGINE); + + assert_eq!(1, enc.write(b"a").unwrap()); + assert_eq!(2, enc.write(b"bc").unwrap()); + let _ = enc.finish().unwrap(); + } + assert_eq!(&c.get_ref()[..], NO_PAD_ENGINE.encode("abc").as_bytes()); + assert_eq!(4, c.get_ref().len()); +} + +#[test] +fn write_partial_then_enough_to_complete_chunk_but_not_complete_another_chunk_encodes_complete_chunk_without_consuming_remaining( +) { + let mut c = Cursor::new(Vec::new()); + { + let mut enc = EncoderWriter::new(&mut c, &NO_PAD_ENGINE); + + assert_eq!(1, enc.write(b"a").unwrap()); + // doesn't consume "d" + assert_eq!(2, enc.write(b"bcd").unwrap()); + let _ = enc.finish().unwrap(); + } + assert_eq!(&c.get_ref()[..], NO_PAD_ENGINE.encode("abc").as_bytes()); + assert_eq!(4, c.get_ref().len()); +} + +#[test] +fn write_partial_then_enough_to_complete_chunk_and_another_chunk_encodes_complete_chunks() { + let mut c = Cursor::new(Vec::new()); + { + let mut enc = EncoderWriter::new(&mut c, &NO_PAD_ENGINE); + + assert_eq!(1, enc.write(b"a").unwrap()); + // completes partial chunk, and another chunk + assert_eq!(5, enc.write(b"bcdef").unwrap()); + let _ = enc.finish().unwrap(); + } + assert_eq!(&c.get_ref()[..], NO_PAD_ENGINE.encode("abcdef").as_bytes()); + assert_eq!(8, c.get_ref().len()); +} + +#[test] +fn write_partial_then_enough_to_complete_chunk_and_another_chunk_and_another_partial_chunk_encodes_only_complete_chunks( +) { + let mut c = Cursor::new(Vec::new()); + { + let mut enc = EncoderWriter::new(&mut c, &NO_PAD_ENGINE); + + assert_eq!(1, enc.write(b"a").unwrap()); + // completes partial chunk, and another chunk, with one more partial chunk that's not + // consumed + assert_eq!(5, enc.write(b"bcdefe").unwrap()); + let _ = enc.finish().unwrap(); + } + assert_eq!(&c.get_ref()[..], NO_PAD_ENGINE.encode("abcdef").as_bytes()); + assert_eq!(8, c.get_ref().len()); +} + +#[test] +fn drop_calls_finish_for_you() { + let mut c = Cursor::new(Vec::new()); + { + let mut enc = EncoderWriter::new(&mut c, &NO_PAD_ENGINE); + assert_eq!(1, enc.write(b"a").unwrap()); + } + assert_eq!(&c.get_ref()[..], NO_PAD_ENGINE.encode("a").as_bytes()); + assert_eq!(2, c.get_ref().len()); +} + +#[test] +fn every_possible_split_of_input() { + let mut rng = rand::thread_rng(); + let mut orig_data = Vec::::new(); + let mut stream_encoded = Vec::::new(); + let mut normal_encoded = String::new(); + + let size = 5_000; + + for i in 0..size { + orig_data.clear(); + stream_encoded.clear(); + normal_encoded.clear(); + + for _ in 0..size { + orig_data.push(rng.gen()); + } + + let engine = random_engine(&mut rng); + engine.encode_string(&orig_data, &mut normal_encoded); + + { + let mut stream_encoder = EncoderWriter::new(&mut stream_encoded, &engine); + // Write the first i bytes, then the rest + stream_encoder.write_all(&orig_data[0..i]).unwrap(); + stream_encoder.write_all(&orig_data[i..]).unwrap(); + } + + assert_eq!(normal_encoded, str::from_utf8(&stream_encoded).unwrap()); + } +} + +#[test] +fn encode_random_config_matches_normal_encode_reasonable_input_len() { + // choose up to 2 * buf size, so ~half the time it'll use a full buffer + do_encode_random_config_matches_normal_encode(super::encoder::BUF_SIZE * 2); +} + +#[test] +fn encode_random_config_matches_normal_encode_tiny_input_len() { + do_encode_random_config_matches_normal_encode(10); +} + +#[test] +fn retrying_writes_that_error_with_interrupted_works() { + let mut rng = rand::thread_rng(); + let mut orig_data = Vec::::new(); + let mut stream_encoded = Vec::::new(); + let mut normal_encoded = String::new(); + + for _ in 0..1_000 { + orig_data.clear(); + stream_encoded.clear(); + normal_encoded.clear(); + + let orig_len: usize = rng.gen_range(100..20_000); + for _ in 0..orig_len { + orig_data.push(rng.gen()); + } + + // encode the normal way + let engine = random_engine(&mut rng); + engine.encode_string(&orig_data, &mut normal_encoded); + + // encode via the stream encoder + { + let mut interrupt_rng = rand::thread_rng(); + let mut interrupting_writer = InterruptingWriter { + w: &mut stream_encoded, + rng: &mut interrupt_rng, + fraction: 0.8, + }; + + let mut stream_encoder = EncoderWriter::new(&mut interrupting_writer, &engine); + let mut bytes_consumed = 0; + while bytes_consumed < orig_len { + // use short inputs since we want to use `extra` a lot as that's what needs rollback + // when errors occur + let input_len: usize = cmp::min(rng.gen_range(0..10), orig_len - bytes_consumed); + + retry_interrupted_write_all( + &mut stream_encoder, + &orig_data[bytes_consumed..bytes_consumed + input_len], + ) + .unwrap(); + + bytes_consumed += input_len; + } + + loop { + let res = stream_encoder.finish(); + match res { + Ok(_) => break, + Err(e) => match e.kind() { + io::ErrorKind::Interrupted => continue, + _ => panic!("{:?}", e), // bail + }, + } + } + + assert_eq!(orig_len, bytes_consumed); + } + + assert_eq!(normal_encoded, str::from_utf8(&stream_encoded).unwrap()); + } +} + +#[test] +fn writes_that_only_write_part_of_input_and_sometimes_interrupt_produce_correct_encoded_data() { + let mut rng = rand::thread_rng(); + let mut orig_data = Vec::::new(); + let mut stream_encoded = Vec::::new(); + let mut normal_encoded = String::new(); + + for _ in 0..1_000 { + orig_data.clear(); + stream_encoded.clear(); + normal_encoded.clear(); + + let orig_len: usize = rng.gen_range(100..20_000); + for _ in 0..orig_len { + orig_data.push(rng.gen()); + } + + // encode the normal way + let engine = random_engine(&mut rng); + engine.encode_string(&orig_data, &mut normal_encoded); + + // encode via the stream encoder + { + let mut partial_rng = rand::thread_rng(); + let mut partial_writer = PartialInterruptingWriter { + w: &mut stream_encoded, + rng: &mut partial_rng, + full_input_fraction: 0.1, + no_interrupt_fraction: 0.1, + }; + + let mut stream_encoder = EncoderWriter::new(&mut partial_writer, &engine); + let mut bytes_consumed = 0; + while bytes_consumed < orig_len { + // use at most medium-length inputs to exercise retry logic more aggressively + let input_len: usize = cmp::min(rng.gen_range(0..100), orig_len - bytes_consumed); + + let res = + stream_encoder.write(&orig_data[bytes_consumed..bytes_consumed + input_len]); + + // retry on interrupt + match res { + Ok(len) => bytes_consumed += len, + Err(e) => match e.kind() { + io::ErrorKind::Interrupted => continue, + _ => { + panic!("should not see other errors"); + } + }, + } + } + + let _ = stream_encoder.finish().unwrap(); + + assert_eq!(orig_len, bytes_consumed); + } + + assert_eq!(normal_encoded, str::from_utf8(&stream_encoded).unwrap()); + } +} + +/// Retry writes until all the data is written or an error that isn't Interrupted is returned. +fn retry_interrupted_write_all(w: &mut W, buf: &[u8]) -> io::Result<()> { + let mut bytes_consumed = 0; + + while bytes_consumed < buf.len() { + let res = w.write(&buf[bytes_consumed..]); + + match res { + Ok(len) => bytes_consumed += len, + Err(e) => match e.kind() { + io::ErrorKind::Interrupted => continue, + _ => return Err(e), + }, + } + } + + Ok(()) +} + +fn do_encode_random_config_matches_normal_encode(max_input_len: usize) { + let mut rng = rand::thread_rng(); + let mut orig_data = Vec::::new(); + let mut stream_encoded = Vec::::new(); + let mut normal_encoded = String::new(); + + for _ in 0..1_000 { + orig_data.clear(); + stream_encoded.clear(); + normal_encoded.clear(); + + let orig_len: usize = rng.gen_range(100..20_000); + for _ in 0..orig_len { + orig_data.push(rng.gen()); + } + + // encode the normal way + let engine = random_engine(&mut rng); + engine.encode_string(&orig_data, &mut normal_encoded); + + // encode via the stream encoder + { + let mut stream_encoder = EncoderWriter::new(&mut stream_encoded, &engine); + let mut bytes_consumed = 0; + while bytes_consumed < orig_len { + let input_len: usize = + cmp::min(rng.gen_range(0..max_input_len), orig_len - bytes_consumed); + + // write a little bit of the data + stream_encoder + .write_all(&orig_data[bytes_consumed..bytes_consumed + input_len]) + .unwrap(); + + bytes_consumed += input_len; + } + + let _ = stream_encoder.finish().unwrap(); + + assert_eq!(orig_len, bytes_consumed); + } + + assert_eq!(normal_encoded, str::from_utf8(&stream_encoded).unwrap()); + } +} + +/// A `Write` implementation that returns Interrupted some fraction of the time, randomly. +struct InterruptingWriter<'a, W: 'a + Write, R: 'a + Rng> { + w: &'a mut W, + rng: &'a mut R, + /// In [0, 1]. If a random number in [0, 1] is `<= threshold`, `Write` methods will return + /// an `Interrupted` error + fraction: f64, +} + +impl<'a, W: Write, R: Rng> Write for InterruptingWriter<'a, W, R> { + fn write(&mut self, buf: &[u8]) -> io::Result { + if self.rng.gen_range(0.0..1.0) <= self.fraction { + return Err(io::Error::new(io::ErrorKind::Interrupted, "interrupted")); + } + + self.w.write(buf) + } + + fn flush(&mut self) -> io::Result<()> { + if self.rng.gen_range(0.0..1.0) <= self.fraction { + return Err(io::Error::new(io::ErrorKind::Interrupted, "interrupted")); + } + + self.w.flush() + } +} + +/// A `Write` implementation that sometimes will only write part of its input. +struct PartialInterruptingWriter<'a, W: 'a + Write, R: 'a + Rng> { + w: &'a mut W, + rng: &'a mut R, + /// In [0, 1]. If a random number in [0, 1] is `<= threshold`, `write()` will write all its + /// input. Otherwise, it will write a random substring + full_input_fraction: f64, + no_interrupt_fraction: f64, +} + +impl<'a, W: Write, R: Rng> Write for PartialInterruptingWriter<'a, W, R> { + fn write(&mut self, buf: &[u8]) -> io::Result { + if self.rng.gen_range(0.0..1.0) > self.no_interrupt_fraction { + return Err(io::Error::new(io::ErrorKind::Interrupted, "interrupted")); + } + + if self.rng.gen_range(0.0..1.0) <= self.full_input_fraction || buf.is_empty() { + // pass through the buf untouched + self.w.write(buf) + } else { + // only use a prefix of it + self.w + .write(&buf[0..(self.rng.gen_range(0..(buf.len() - 1)))]) + } + } + + fn flush(&mut self) -> io::Result<()> { + self.w.flush() + } +} diff --git a/vendor/base64/src/write/mod.rs b/vendor/base64/src/write/mod.rs new file mode 100644 index 0000000..2a617db --- /dev/null +++ b/vendor/base64/src/write/mod.rs @@ -0,0 +1,11 @@ +//! Implementations of `io::Write` to transparently handle base64. +mod encoder; +mod encoder_string_writer; + +pub use self::{ + encoder::EncoderWriter, + encoder_string_writer::{EncoderStringWriter, StrConsumer}, +}; + +#[cfg(test)] +mod encoder_tests; diff --git a/vendor/base64/tests/encode.rs b/vendor/base64/tests/encode.rs new file mode 100644 index 0000000..9d69447 --- /dev/null +++ b/vendor/base64/tests/encode.rs @@ -0,0 +1,77 @@ +use base64::{ + alphabet::URL_SAFE, engine::general_purpose::PAD, engine::general_purpose::STANDARD, *, +}; + +fn compare_encode(expected: &str, target: &[u8]) { + assert_eq!(expected, STANDARD.encode(target)); +} + +#[test] +fn encode_all_ascii() { + let ascii: Vec = (0..=127).collect(); + + compare_encode( + "AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vMDEyMzQ1Njc4OTo7P\ + D0+P0BBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWltcXV5fYGFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6e3x9fn8\ + =", + &ascii, + ); +} + +#[test] +fn encode_all_bytes() { + let bytes: Vec = (0..=255).collect(); + + compare_encode( + "AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vMDEyMzQ1Njc4OTo7P\ + D0+P0BBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWltcXV5fYGFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6e3x9fn\ + +AgYKDhIWGh4iJiouMjY6PkJGSk5SVlpeYmZqbnJ2en6ChoqOkpaanqKmqq6ytrq+wsbKztLW2t7i5uru8vb6\ + /wMHCw8TFxsfIycrLzM3Oz9DR0tPU1dbX2Nna29zd3t/g4eLj5OXm5+jp6uvs7e7v8PHy8/T19vf4+fr7/P3+/w==", + &bytes, + ); +} + +#[test] +fn encode_all_bytes_url() { + let bytes: Vec = (0..=255).collect(); + + assert_eq!( + "AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vMDEyMzQ1Njc4OTo7PD0\ + -P0BBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWltcXV5fYGFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6e3x9fn\ + -AgYKDhIWGh4iJiouMjY6PkJGSk5SVlpeYmZqbnJ2en6ChoqOkpaanqKmqq6ytrq\ + -wsbKztLW2t7i5uru8vb6_wMHCw8TFxsfIycrLzM3Oz9DR0tPU1dbX2Nna29zd3t_g4eLj5OXm5-jp6uvs7e7v8PHy\ + 8_T19vf4-fr7_P3-_w==", + &engine::GeneralPurpose::new(&URL_SAFE, PAD).encode(bytes) + ); +} + +#[test] +fn encoded_len_unpadded() { + assert_eq!(0, encoded_len(0, false).unwrap()); + assert_eq!(2, encoded_len(1, false).unwrap()); + assert_eq!(3, encoded_len(2, false).unwrap()); + assert_eq!(4, encoded_len(3, false).unwrap()); + assert_eq!(6, encoded_len(4, false).unwrap()); + assert_eq!(7, encoded_len(5, false).unwrap()); + assert_eq!(8, encoded_len(6, false).unwrap()); + assert_eq!(10, encoded_len(7, false).unwrap()); +} + +#[test] +fn encoded_len_padded() { + assert_eq!(0, encoded_len(0, true).unwrap()); + assert_eq!(4, encoded_len(1, true).unwrap()); + assert_eq!(4, encoded_len(2, true).unwrap()); + assert_eq!(4, encoded_len(3, true).unwrap()); + assert_eq!(8, encoded_len(4, true).unwrap()); + assert_eq!(8, encoded_len(5, true).unwrap()); + assert_eq!(8, encoded_len(6, true).unwrap()); + assert_eq!(12, encoded_len(7, true).unwrap()); +} +#[test] +fn encoded_len_overflow() { + let max_size = usize::MAX / 4 * 3 + 2; + assert_eq!(2, max_size % 3); + assert_eq!(Some(usize::MAX), encoded_len(max_size, false)); + assert_eq!(None, encoded_len(max_size + 1, false)); +} diff --git a/vendor/base64/tests/tests.rs b/vendor/base64/tests/tests.rs new file mode 100644 index 0000000..eceff40 --- /dev/null +++ b/vendor/base64/tests/tests.rs @@ -0,0 +1,161 @@ +use rand::{Rng, SeedableRng}; + +use base64::engine::{general_purpose::STANDARD, Engine}; +use base64::*; + +use base64::engine::general_purpose::{GeneralPurpose, NO_PAD}; + +// generate random contents of the specified length and test encode/decode roundtrip +fn roundtrip_random( + byte_buf: &mut Vec, + str_buf: &mut String, + engine: &E, + byte_len: usize, + approx_values_per_byte: u8, + max_rounds: u64, +) { + // let the short ones be short but don't let it get too crazy large + let num_rounds = calculate_number_of_rounds(byte_len, approx_values_per_byte, max_rounds); + let mut r = rand::rngs::SmallRng::from_entropy(); + let mut decode_buf = Vec::new(); + + for _ in 0..num_rounds { + byte_buf.clear(); + str_buf.clear(); + decode_buf.clear(); + while byte_buf.len() < byte_len { + byte_buf.push(r.gen::()); + } + + engine.encode_string(&byte_buf, str_buf); + engine.decode_vec(&str_buf, &mut decode_buf).unwrap(); + + assert_eq!(byte_buf, &decode_buf); + } +} + +fn calculate_number_of_rounds(byte_len: usize, approx_values_per_byte: u8, max: u64) -> u64 { + // don't overflow + let mut prod = approx_values_per_byte as u64; + + for _ in 0..byte_len { + if prod > max { + return max; + } + + prod = prod.saturating_mul(prod); + } + + prod +} + +#[test] +fn roundtrip_random_short_standard() { + let mut byte_buf: Vec = Vec::new(); + let mut str_buf = String::new(); + + for input_len in 0..40 { + roundtrip_random(&mut byte_buf, &mut str_buf, &STANDARD, input_len, 4, 10000); + } +} + +#[test] +fn roundtrip_random_with_fast_loop_standard() { + let mut byte_buf: Vec = Vec::new(); + let mut str_buf = String::new(); + + for input_len in 40..100 { + roundtrip_random(&mut byte_buf, &mut str_buf, &STANDARD, input_len, 4, 1000); + } +} + +#[test] +fn roundtrip_random_short_no_padding() { + let mut byte_buf: Vec = Vec::new(); + let mut str_buf = String::new(); + + let engine = GeneralPurpose::new(&alphabet::STANDARD, NO_PAD); + for input_len in 0..40 { + roundtrip_random(&mut byte_buf, &mut str_buf, &engine, input_len, 4, 10000); + } +} + +#[test] +fn roundtrip_random_no_padding() { + let mut byte_buf: Vec = Vec::new(); + let mut str_buf = String::new(); + + let engine = GeneralPurpose::new(&alphabet::STANDARD, NO_PAD); + + for input_len in 40..100 { + roundtrip_random(&mut byte_buf, &mut str_buf, &engine, input_len, 4, 1000); + } +} + +#[test] +fn roundtrip_decode_trailing_10_bytes() { + // This is a special case because we decode 8 byte blocks of input at a time as much as we can, + // ideally unrolled to 32 bytes at a time, in stages 1 and 2. Since we also write a u64's worth + // of bytes (8) to the output, we always write 2 garbage bytes that then will be overwritten by + // the NEXT block. However, if the next block only contains 2 bytes, it will decode to 1 byte, + // and therefore be too short to cover up the trailing 2 garbage bytes. Thus, we have stage 3 + // to handle that case. + + for num_quads in 0..25 { + let mut s: String = "ABCD".repeat(num_quads); + s.push_str("EFGHIJKLZg"); + + let engine = GeneralPurpose::new(&alphabet::STANDARD, NO_PAD); + let decoded = engine.decode(&s).unwrap(); + assert_eq!(num_quads * 3 + 7, decoded.len()); + + assert_eq!(s, engine.encode(&decoded)); + } +} + +#[test] +fn display_wrapper_matches_normal_encode() { + let mut bytes = Vec::::with_capacity(256); + + for i in 0..255 { + bytes.push(i); + } + bytes.push(255); + + assert_eq!( + STANDARD.encode(&bytes), + format!("{}", display::Base64Display::new(&bytes, &STANDARD)) + ); +} + +#[test] +fn encode_engine_slice_error_when_buffer_too_small() { + for num_triples in 1..100 { + let input = "AAA".repeat(num_triples); + let mut vec = vec![0; (num_triples - 1) * 4]; + assert_eq!( + EncodeSliceError::OutputSliceTooSmall, + STANDARD.encode_slice(&input, &mut vec).unwrap_err() + ); + vec.push(0); + assert_eq!( + EncodeSliceError::OutputSliceTooSmall, + STANDARD.encode_slice(&input, &mut vec).unwrap_err() + ); + vec.push(0); + assert_eq!( + EncodeSliceError::OutputSliceTooSmall, + STANDARD.encode_slice(&input, &mut vec).unwrap_err() + ); + vec.push(0); + assert_eq!( + EncodeSliceError::OutputSliceTooSmall, + STANDARD.encode_slice(&input, &mut vec).unwrap_err() + ); + vec.push(0); + assert_eq!( + num_triples * 4, + STANDARD.encode_slice(&input, &mut vec).unwrap() + ); + } +} diff --git a/vendor/bitflags/.cargo-checksum.json b/vendor/bitflags/.cargo-checksum.json new file mode 100644 index 0000000..9ed6cb2 --- /dev/null +++ b/vendor/bitflags/.cargo-checksum.json @@ -0,0 +1 @@ +{"files":{"CHANGELOG.md":"c98723b209ac4c66625e034b113a55a43a5c1c9e49c0e3b86123d0cd62bae573","CODE_OF_CONDUCT.md":"42634d0f6d922f49857175af991802822f7f920487aefa2ee250a50d12251a66","CONTRIBUTING.md":"6c9f96eacb20af877ae2d16f024904f3038b93448a8488e9dbcac0df7f6439a5","Cargo.lock":"d3e3bce47b94298f2de893a7d91035f2b73a887905a7ffd4ddb668efdd0aee20","Cargo.toml":"92e110c36340bda13f3b329a2aa24aede8bdcb7fa035806926f7ce438dde87f2","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"6485b8ed310d3f0340bf1ad1f47645069ce4069dcc6bb46c7d5c6faf41de1fdb","README.md":"e9b1329fee85868f1aa674d0505cd95b86a259e2a1762347e5af4a5abedd61d4","SECURITY.md":"68704c8128fa2e776ed7cbda741fbf61ad52f998a96350ee7ee4dbf64c6573bc","benches/parse.rs":"f1390d62322c6880d65bd931e183d49b313f287879a6bfaa36b1cb1921090b51","examples/custom_bits_type.rs":"e53b32051adc5d97860e0b48c8f3a301a041d73b4939c0d7caa5f0cfcc0b9739","examples/custom_derive.rs":"a404e8f606efdd1b43e0c365e4142ccc3dc3ba230127ddeea89cd8784bb55a1e","examples/fmt.rs":"87ba37a1fb8528570c74ea26d8e8948e1179c3d867b928bea1080880258e0a99","examples/macro_free.rs":"69e7f284b53b5214d51228a686e87f127b52a3b74711e45537ebfa5583a180e5","examples/serde.rs":"08b21b35d5c10fdca132fe0f36c8067bb44f559e96617a9257ab6316a20cbc75","spec.md":"fcdd939df30c59b0643be09027df664b71cbea9b9989185441482c5576160fed","src/example_generated.rs":"d018caf059f6ffc4c2403b771a6d76679fa5af03c329a91bd9252957df695e7f","src/external.rs":"734d3f470e6a669297d2df421ce3976fe613d8aa9c071d5ce6fe3ca890e5b815","src/external/arbitrary.rs":"fa8c9187028b9bc54856977b0914676f62101010e7a9450abd577fd78c89552f","src/external/bytemuck.rs":"3afcef382122867040fddd5e4153d633d1ed5596fe5d7dfac66a8e61c2513df5","src/external/serde.rs":"4a09db12534a20fe554a08dc5f1c8124b379292d41fa75628abcd2ca21587573","src/internal.rs":"645b13af0c7302258df61239073a4b8203d09f27b6c17f8a6f1f8c3e427f5334","src/iter.rs":"dbaa6437c1c044f689185ce3fafe43df8796bed19bbdd2c20334a52de5eeee73","src/lib.rs":"1feb0eea02f88491c99c7962b0ce6e66bdedea0ab0cac375d4c9c2d879248dc7","src/parser.rs":"4e788b29f5d0542c409a8b43c703bcb4a6c2a57c181cadd17f565f0abb39681e","src/public.rs":"78ba06e1a5830b36960adf9bd79aaf47d783b9b8a0f1fa33b0d7a340c15fd1d1","src/tests.rs":"b120c27ff0c67a819527de9d8171f1f4c5d37ba4009c54abeb869c70e6035f14","src/tests/all.rs":"e99a865cd4271a524c2fe95503e96d851b35990570aed6fb2e9dac7a14da31b6","src/tests/bits.rs":"3840c34b2ea5d1802404b9ce5bcc1d3fa6ccd8dfba2e29e6d07c605f817d90df","src/tests/complement.rs":"d0e6d4c3daf49e0a7438c9f1c1ac91fad1b37f258c03593f6cd6a695ee626f5e","src/tests/contains.rs":"58bb3cb8c86550e775d11134da1d4aca85c83f943ea454e3a5f222772c674a24","src/tests/difference.rs":"d0d2b96bb52658b8ac019210da74ca75a53e76622f668855142ea6e97c28cb0e","src/tests/empty.rs":"817d6e93ced7cb7576ff0e334aa1a44703f3f96871ff2c6bdcb8f207e6551f67","src/tests/eq.rs":"b816767680a029e9c163e37af074dd4e604c4a3e4936f829f0ca3774fd5f0e37","src/tests/extend.rs":"5fabb9fd0254c64da019149c24063fceff72da3eb4ad73b57c1cc4c04b008364","src/tests/flags.rs":"2f48d3a25db1cf66fe98c9959abc70875deb9f7b38b2c278dc70c46e0d4ec277","src/tests/fmt.rs":"a2d4148491f3202f030f63633eee941b741e3be29a68cf376f008dbe5cb11e5c","src/tests/from_bits.rs":"d94c65b88bf89961d0cfc1b3152a7f1acc285bae160a1628438effda11b8e2c1","src/tests/from_bits_retain.rs":"980591dfaf91e940f42d9a1ce890f237514dd59d458fc264abcf9ceabbc40677","src/tests/from_bits_truncate.rs":"d3406b5e107ebb6449b98a59eee6cc5d84f947d4aaee1ee7e80dc7202de179f0","src/tests/from_name.rs":"f4a055d1f3c86decef70ef8f3020cef5c4e229718c20b3d59d5a3abc3a8b1298","src/tests/insert.rs":"3fab5da800a6fc0654dfb5f859f95da65a507eb9fda8695083c2712266dff0b9","src/tests/intersection.rs":"baf1454c9e4eba552264870a556ee0032d9f2bb8cac361833d571235e0b52221","src/tests/intersects.rs":"c55e36179fd8bc636f04ea9bbce346dcaafe57915d13f1df28c5b83117dbd08e","src/tests/is_all.rs":"b2f11faa7c954bd85c8fb39999e0c37d983cf7895152bc13c7ddde106aa33b6d","src/tests/is_empty.rs":"11f21323cdca7ff92dd89e09de667dba69e8dce88e2d3e27ea68ace91d15d070","src/tests/iter.rs":"4ba121932b527e787b82745405c7c65c1084c242e2dda3290d475ec160d265e4","src/tests/parser.rs":"fa2fb8dedcf16601af609a5e21d9c5840c7f96a1e3a587f7f2ea3dc8387f7628","src/tests/remove.rs":"6e75f8508d2dc1a2cba89ef691f4387a665a4fd13853bb1dd0fd80c783b89947","src/tests/symmetric_difference.rs":"0a89f084f9de1dd5b1932fe72c3b10a3c93cbaa16832b3a31b6a85e3bbd3ba6e","src/tests/union.rs":"88f398ee4600bb1e59bf6d02d1f6ff33f5f853eab5a6c700bd8a683c6ee4651a","src/traits.rs":"b79d008daec546136fae4497966fc85a33663d86ea2d9213fd23b412d4d77b66"},"package":"b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de"} \ No newline at end of file diff --git a/vendor/bitflags/CHANGELOG.md b/vendor/bitflags/CHANGELOG.md new file mode 100644 index 0000000..f17d469 --- /dev/null +++ b/vendor/bitflags/CHANGELOG.md @@ -0,0 +1,553 @@ +# 2.6.0 + +## What's Changed +* Sync CHANGELOG.md with github release notes by @dextero in https://github.com/bitflags/bitflags/pull/402 +* Update error messages and zerocopy by @KodrAus in https://github.com/bitflags/bitflags/pull/403 +* Bump minimum declared versions of dependencies by @dextero in https://github.com/bitflags/bitflags/pull/404 +* chore(deps): bump serde_derive and bytemuck versions by @joshka in https://github.com/bitflags/bitflags/pull/405 +* add OSFF Scorecard workflow by @KodrAus in https://github.com/bitflags/bitflags/pull/396 +* Update stderr messages by @KodrAus in https://github.com/bitflags/bitflags/pull/408 +* Fix typo by @waywardmonkeys in https://github.com/bitflags/bitflags/pull/410 +* Allow specifying outer attributes in impl mode by @KodrAus in https://github.com/bitflags/bitflags/pull/411 + +## New Contributors +* @dextero made their first contribution in https://github.com/bitflags/bitflags/pull/402 +* @joshka made their first contribution in https://github.com/bitflags/bitflags/pull/405 +* @waywardmonkeys made their first contribution in https://github.com/bitflags/bitflags/pull/410 + +**Full Changelog**: https://github.com/bitflags/bitflags/compare/2.5.0...2.6.0 + +# 2.5.0 + +## What's Changed +* Derive `Debug` for `Flag` by @tgross35 in https://github.com/bitflags/bitflags/pull/398 +* Support truncating or strict-named variants of parsing and formatting by @KodrAus in https://github.com/bitflags/bitflags/pull/400 + +## New Contributors +* @tgross35 made their first contribution in https://github.com/bitflags/bitflags/pull/398 + +**Full Changelog**: https://github.com/bitflags/bitflags/compare/2.4.2...2.5.0 + +# 2.4.2 + +## What's Changed +* Cargo.toml: Anchor excludes to root of the package by @jamessan in https://github.com/bitflags/bitflags/pull/387 +* Update error messages by @KodrAus in https://github.com/bitflags/bitflags/pull/390 +* Add support for impl mode structs to be repr(packed) by @GnomedDev in https://github.com/bitflags/bitflags/pull/388 +* Remove old `unused_tuple_struct_fields` lint by @dtolnay in https://github.com/bitflags/bitflags/pull/393 +* Delete use of `local_inner_macros` by @dtolnay in https://github.com/bitflags/bitflags/pull/392 + +## New Contributors +* @jamessan made their first contribution in https://github.com/bitflags/bitflags/pull/387 +* @GnomedDev made their first contribution in https://github.com/bitflags/bitflags/pull/388 + +**Full Changelog**: https://github.com/bitflags/bitflags/compare/2.4.1...2.4.2 + +# 2.4.1 + +## What's Changed +* Allow some new pedantic clippy lints by @KodrAus in https://github.com/bitflags/bitflags/pull/380 + +**Full Changelog**: https://github.com/bitflags/bitflags/compare/2.4.0...2.4.1 + +# 2.4.0 + +## What's Changed +* Remove html_root_url by @eldruin in https://github.com/bitflags/bitflags/pull/368 +* Support unnamed flags by @KodrAus in https://github.com/bitflags/bitflags/pull/371 +* Update smoke test to verify all Clippy and rustc lints by @MitMaro in https://github.com/bitflags/bitflags/pull/374 +* Specify the behavior of bitflags by @KodrAus in https://github.com/bitflags/bitflags/pull/369 + +## New Contributors +* @eldruin made their first contribution in https://github.com/bitflags/bitflags/pull/368 +* @MitMaro made their first contribution in https://github.com/bitflags/bitflags/pull/374 + +**Full Changelog**: https://github.com/bitflags/bitflags/compare/2.3.3...2.4.0 + +# 2.3.3 + +## Changes to `-=` + +The `-=` operator was incorrectly changed to truncate bits that didn't correspond to valid flags in `2.3.0`. This has +been fixed up so it once again behaves the same as `-` and `difference`. + +## Changes to `!` + +The `!` operator previously called `Self::from_bits_truncate`, which would truncate any bits that only partially +overlapped with a valid flag. It will now use `bits & Self::all().bits()`, so any bits that overlap any bits +specified by any flag will be respected. This is unlikely to have any practical implications, but enables defining +a flag like `const ALL = !0` as a way to signal that any bit pattern is a known set of flags. + +## Changes to formatting + +Zero-valued flags will never be printed. You'll either get `0x0` for empty flags using debug formatting, or the +set of flags with zero-valued flags omitted for others. + +Composite flags will no longer be redundantly printed if there are extra bits to print at the end that don't correspond +to a valid flag. + +## What's Changed +* Fix up incorrect sub assign behavior and other cleanups by @KodrAus in https://github.com/bitflags/bitflags/pull/366 + +**Full Changelog**: https://github.com/bitflags/bitflags/compare/2.3.2...2.3.3 + +# 2.3.2 + +## What's Changed +* [doc] [src/lib.rs] delete redundant path prefix by @OccupyMars2025 in https://github.com/bitflags/bitflags/pull/361 + +## New Contributors +* @OccupyMars2025 made their first contribution in https://github.com/bitflags/bitflags/pull/361 + +**Full Changelog**: https://github.com/bitflags/bitflags/compare/2.3.1...2.3.2 + +# 2.3.1 + +## What's Changed +* Fix Self in flags value expressions by @KodrAus in https://github.com/bitflags/bitflags/pull/355 + +**Full Changelog**: https://github.com/bitflags/bitflags/compare/2.3.0...2.3.1 + +# 2.3.0 + +## Major changes + +### `BitFlags` trait deprecated in favor of `Flags` trait + +This release introduces the `Flags` trait and deprecates the `BitFlags` trait. These two traits are semver compatible so if you have public API code depending on `BitFlags` you can move to `Flags` without breaking end-users. This is possible because the `BitFlags` trait was never publicly implementable, so it now carries `Flags` as a supertrait. All implementations of `Flags` additionally implement `BitFlags`. + +The `Flags` trait is a publicly implementable version of the old `BitFlags` trait. The original `BitFlags` trait carried some macro baggage that made it difficult to implement, so a new `Flags` trait has been introduced as the _One True Trait_ for interacting with flags types generically. See the the `macro_free` and `custom_derive` examples for more details. + +### `Bits` trait publicly exposed + +The `Bits` trait for the underlying storage of flags values is also now publicly implementable. This lets you define your own exotic backing storage for flags. See the `custom_bits_type` example for more details. + +## What's Changed +* Use explicit hashes for actions steps by @KodrAus in https://github.com/bitflags/bitflags/pull/350 +* Support ejecting flags types from the bitflags macro by @KodrAus in https://github.com/bitflags/bitflags/pull/351 + +**Full Changelog**: https://github.com/bitflags/bitflags/compare/2.2.1...2.3.0 + +# 2.2.1 + +## What's Changed +* Refactor attribute filtering to apply per-flag by @KodrAus in https://github.com/bitflags/bitflags/pull/345 + +**Full Changelog**: https://github.com/bitflags/bitflags/compare/2.2.0...2.2.1 + +# 2.2.0 + +## What's Changed +* Create SECURITY.md by @KodrAus in https://github.com/bitflags/bitflags/pull/338 +* add docs to describe the behavior of multi-bit flags by @nicholasbishop in https://github.com/bitflags/bitflags/pull/340 +* Add support for bytemuck by @KodrAus in https://github.com/bitflags/bitflags/pull/336 +* Add a top-level macro for filtering attributes by @KodrAus in https://github.com/bitflags/bitflags/pull/341 + +## New Contributors +* @nicholasbishop made their first contribution in https://github.com/bitflags/bitflags/pull/340 + +**Full Changelog**: https://github.com/bitflags/bitflags/compare/2.1.0...2.2.0 + +# 2.1.0 + +## What's Changed +* Add docs for the internal Field0 and examples of formatting/parsing by @KodrAus in https://github.com/bitflags/bitflags/pull/328 +* Add support for arbitrary by @KodrAus in https://github.com/bitflags/bitflags/pull/324 +* Fix up missing docs for consts within consts by @KodrAus in https://github.com/bitflags/bitflags/pull/330 +* Ignore clippy lint in generated code by @Jake-Shadle in https://github.com/bitflags/bitflags/pull/331 + +## New Contributors +* @Jake-Shadle made their first contribution in https://github.com/bitflags/bitflags/pull/331 + +**Full Changelog**: https://github.com/bitflags/bitflags/compare/2.0.2...2.1.0 + +# 2.0.2 + +## What's Changed +* Fix up missing isize and usize Bits impls by @KodrAus in https://github.com/bitflags/bitflags/pull/321 + +**Full Changelog**: https://github.com/bitflags/bitflags/compare/2.0.1...2.0.2 + +# 2.0.1 + +## What's Changed +* Fix up some docs issues by @KodrAus in https://github.com/bitflags/bitflags/pull/309 +* Make empty_flag() const. by @tormeh in https://github.com/bitflags/bitflags/pull/313 +* Fix formatting of multi-bit flags with partial overlap by @KodrAus in https://github.com/bitflags/bitflags/pull/316 + +## New Contributors +* @tormeh made their first contribution in https://github.com/bitflags/bitflags/pull/313 + +**Full Changelog**: https://github.com/bitflags/bitflags/compare/2.0.0...2.0.1 + +# 2.0.0 + +## Major changes + +This release includes some major changes over `1.x`. If you use `bitflags!` types in your public API then upgrading this library may cause breakage in your downstream users. + +### ⚠️ Serialization + +You'll need to add the `serde` Cargo feature in order to `#[derive(Serialize, Deserialize)]` on your generated flags types: + +```rust +bitflags! { + #[derive(Serialize, Deserialize)] + #[serde(transparent)] + pub struct Flags: T { + .. + } +} +``` + +where `T` is the underlying bits type you're using, such as `u32`. + +The default serialization format with `serde` **has changed** if you `#[derive(Serialize, Deserialize)]` on your generated flags types. It will now use a formatted string for human-readable formats and the underlying bits type for compact formats. + +To keep the old format, see the https://github.com/KodrAus/bitflags-serde-legacy library. + +### ⚠️ Traits + +Generated flags types now derive fewer traits. If you need to maintain backwards compatibility, you can derive the following yourself: + +```rust +#[derive(PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Clone, Copy)] +``` + +### ⚠️ Methods + +The unsafe `from_bits_unchecked` method is now a safe `from_bits_retain` method. + +You can add the following method to your generated types to keep them compatible: + +```rust +#[deprecated = "use the safe `from_bits_retain` method instead"] +pub unsafe fn from_bits_unchecked(bits: T) -> Self { + Self::from_bits_retain(bits) +} +``` + +where `T` is the underlying bits type you're using, such as `u32`. + +### ⚠️ `.bits` field + +You can now use the `.bits()` method instead of the old `.bits`. + +The representation of generated flags types has changed from a struct with the single field `bits` to a newtype. + +## What's Changed +* Fix a typo and call out MSRV bump by @KodrAus in https://github.com/bitflags/bitflags/pull/259 +* BitFlags trait by @arturoc in https://github.com/bitflags/bitflags/pull/220 +* Add a hidden trait to discourage manual impls of BitFlags by @KodrAus in https://github.com/bitflags/bitflags/pull/261 +* Sanitize `Ok` by @konsumlamm in https://github.com/bitflags/bitflags/pull/266 +* Fix bug in `Debug` implementation by @konsumlamm in https://github.com/bitflags/bitflags/pull/268 +* Fix a typo in the generated documentation by @wackbyte in https://github.com/bitflags/bitflags/pull/271 +* Use SPDX license format by @atouchet in https://github.com/bitflags/bitflags/pull/272 +* serde tests fail in CI by @arturoc in https://github.com/bitflags/bitflags/pull/277 +* Fix beta test output by @KodrAus in https://github.com/bitflags/bitflags/pull/279 +* Add example to the README.md file by @tiaanl in https://github.com/bitflags/bitflags/pull/270 +* Iterator over all the enabled options by @arturoc in https://github.com/bitflags/bitflags/pull/278 +* from_bits_(truncate) fail with composite flags by @arturoc in https://github.com/bitflags/bitflags/pull/276 +* Add more platform coverage to CI by @KodrAus in https://github.com/bitflags/bitflags/pull/280 +* rework the way cfgs are handled by @KodrAus in https://github.com/bitflags/bitflags/pull/281 +* Split generated code into two types by @KodrAus in https://github.com/bitflags/bitflags/pull/282 +* expose bitflags iters using nameable types by @KodrAus in https://github.com/bitflags/bitflags/pull/286 +* Support creating flags from their names by @KodrAus in https://github.com/bitflags/bitflags/pull/287 +* Update README.md by @KodrAus in https://github.com/bitflags/bitflags/pull/288 +* Prepare for 2.0.0-rc.1 release by @KodrAus in https://github.com/bitflags/bitflags/pull/289 +* Add missing "if" to contains doc-comment in traits.rs by @rusty-snake in https://github.com/bitflags/bitflags/pull/291 +* Forbid unsafe_code by @fintelia in https://github.com/bitflags/bitflags/pull/294 +* serde: enable no-std support by @nim65s in https://github.com/bitflags/bitflags/pull/296 +* Add a parser for flags formatted as bar-separated-values by @KodrAus in https://github.com/bitflags/bitflags/pull/297 +* Prepare for 2.0.0-rc.2 release by @KodrAus in https://github.com/bitflags/bitflags/pull/299 +* Use strip_prefix instead of starts_with + slice by @QuinnPainter in https://github.com/bitflags/bitflags/pull/301 +* Fix up some clippy lints by @KodrAus in https://github.com/bitflags/bitflags/pull/302 +* Prepare for 2.0.0-rc.3 release by @KodrAus in https://github.com/bitflags/bitflags/pull/303 +* feat: Add minimum permissions to rust.yml workflow by @gabibguti in https://github.com/bitflags/bitflags/pull/305 + +## New Contributors +* @wackbyte made their first contribution in https://github.com/bitflags/bitflags/pull/271 +* @atouchet made their first contribution in https://github.com/bitflags/bitflags/pull/272 +* @tiaanl made their first contribution in https://github.com/bitflags/bitflags/pull/270 +* @rusty-snake made their first contribution in https://github.com/bitflags/bitflags/pull/291 +* @fintelia made their first contribution in https://github.com/bitflags/bitflags/pull/294 +* @nim65s made their first contribution in https://github.com/bitflags/bitflags/pull/296 +* @QuinnPainter made their first contribution in https://github.com/bitflags/bitflags/pull/301 +* @gabibguti made their first contribution in https://github.com/bitflags/bitflags/pull/305 + +**Full Changelog**: https://github.com/bitflags/bitflags/compare/1.3.2...2.0.0 + +# 2.0.0-rc.3 + +## What's Changed +* Use strip_prefix instead of starts_with + slice by @QuinnPainter in https://github.com/bitflags/bitflags/pull/301 +* Fix up some clippy lints by @KodrAus in https://github.com/bitflags/bitflags/pull/302 + +## New Contributors +* @QuinnPainter made their first contribution in https://github.com/bitflags/bitflags/pull/301 + +**Full Changelog**: https://github.com/bitflags/bitflags/compare/2.0.0-rc.2...2.0.0-rc.3 + +# 2.0.0-rc.2 + +## Changes to `serde` serialization + +**⚠️ NOTE ⚠️** This release changes the default serialization you'll get if you `#[derive(Serialize, Deserialize)]` +on your generated flags types. It will now use a formatted string for human-readable formats and the underlying bits +type for compact formats. + +To keep the old behavior, see the [`bitflags-serde-legacy`](https://github.com/KodrAus/bitflags-serde-legacy) library. + +## What's Changed + +* Add missing "if" to contains doc-comment in traits.rs by @rusty-snake in https://github.com/bitflags/bitflags/pull/291 +* Forbid unsafe_code by @fintelia in https://github.com/bitflags/bitflags/pull/294 +* serde: enable no-std support by @nim65s in https://github.com/bitflags/bitflags/pull/296 +* Add a parser for flags formatted as bar-separated-values by @KodrAus in https://github.com/bitflags/bitflags/pull/297 + +## New Contributors +* @rusty-snake made their first contribution in https://github.com/bitflags/bitflags/pull/291 +* @fintelia made their first contribution in https://github.com/bitflags/bitflags/pull/294 +* @nim65s made their first contribution in https://github.com/bitflags/bitflags/pull/296 + +**Full Changelog**: https://github.com/bitflags/bitflags/compare/2.0.0-rc.1...2.0.0-rc.2 + +# 2.0.0-rc.1 + +This is a big release including a few years worth of work on a new `BitFlags` trait, iteration, and better macro organization for future extensibility. + +## What's Changed +* Fix a typo and call out MSRV bump by @KodrAus in https://github.com/bitflags/bitflags/pull/259 +* BitFlags trait by @arturoc in https://github.com/bitflags/bitflags/pull/220 +* Add a hidden trait to discourage manual impls of BitFlags by @KodrAus in https://github.com/bitflags/bitflags/pull/261 +* Sanitize `Ok` by @konsumlamm in https://github.com/bitflags/bitflags/pull/266 +* Fix bug in `Debug` implementation by @konsumlamm in https://github.com/bitflags/bitflags/pull/268 +* Fix a typo in the generated documentation by @wackbyte in https://github.com/bitflags/bitflags/pull/271 +* Use SPDX license format by @atouchet in https://github.com/bitflags/bitflags/pull/272 +* serde tests fail in CI by @arturoc in https://github.com/bitflags/bitflags/pull/277 +* Fix beta test output by @KodrAus in https://github.com/bitflags/bitflags/pull/279 +* Add example to the README.md file by @tiaanl in https://github.com/bitflags/bitflags/pull/270 +* Iterator over all the enabled options by @arturoc in https://github.com/bitflags/bitflags/pull/278 +* from_bits_(truncate) fail with composite flags by @arturoc in https://github.com/bitflags/bitflags/pull/276 +* Add more platform coverage to CI by @KodrAus in https://github.com/bitflags/bitflags/pull/280 +* rework the way cfgs are handled by @KodrAus in https://github.com/bitflags/bitflags/pull/281 +* Split generated code into two types by @KodrAus in https://github.com/bitflags/bitflags/pull/282 +* expose bitflags iters using nameable types by @KodrAus in https://github.com/bitflags/bitflags/pull/286 +* Support creating flags from their names by @KodrAus in https://github.com/bitflags/bitflags/pull/287 +* Update README.md by @KodrAus in https://github.com/bitflags/bitflags/pull/288 + +## New Contributors +* @wackbyte made their first contribution in https://github.com/bitflags/bitflags/pull/271 +* @atouchet made their first contribution in https://github.com/bitflags/bitflags/pull/272 +* @tiaanl made their first contribution in https://github.com/bitflags/bitflags/pull/270 + +**Full Changelog**: https://github.com/bitflags/bitflags/compare/1.3.2...2.0.0-rc.1 + +# 1.3.2 + +- Allow `non_snake_case` in generated flags types ([#256]) + +[#256]: https://github.com/bitflags/bitflags/pull/256 + +# 1.3.1 + +- Revert unconditional `#[repr(transparent)]` ([#252]) + +[#252]: https://github.com/bitflags/bitflags/pull/252 + +# 1.3.0 (yanked) + +**This release bumps the Minimum Supported Rust Version to `1.46.0`** + +- Add `#[repr(transparent)]` ([#187]) + +- End `empty` doc comment with full stop ([#202]) + +- Fix typo in crate root docs ([#206]) + +- Document from_bits_unchecked unsafety ([#207]) + +- Let `is_all` ignore extra bits ([#211]) + +- Allows empty flag definition ([#225]) + +- Making crate accessible from std ([#227]) + +- Make `from_bits` a const fn ([#229]) + +- Allow multiple bitflags structs in one macro invocation ([#235]) + +- Add named functions to perform set operations ([#244]) + +- Fix typos in method docs ([#245]) + +- Modernization of the `bitflags` macro to take advantage of newer features and 2018 idioms ([#246]) + +- Fix regression (in an unreleased feature) and simplify tests ([#247]) + +- Use `Self` and fix bug when overriding `stringify!` ([#249]) + +[#187]: https://github.com/bitflags/bitflags/pull/187 +[#202]: https://github.com/bitflags/bitflags/pull/202 +[#206]: https://github.com/bitflags/bitflags/pull/206 +[#207]: https://github.com/bitflags/bitflags/pull/207 +[#211]: https://github.com/bitflags/bitflags/pull/211 +[#225]: https://github.com/bitflags/bitflags/pull/225 +[#227]: https://github.com/bitflags/bitflags/pull/227 +[#229]: https://github.com/bitflags/bitflags/pull/229 +[#235]: https://github.com/bitflags/bitflags/pull/235 +[#244]: https://github.com/bitflags/bitflags/pull/244 +[#245]: https://github.com/bitflags/bitflags/pull/245 +[#246]: https://github.com/bitflags/bitflags/pull/246 +[#247]: https://github.com/bitflags/bitflags/pull/247 +[#249]: https://github.com/bitflags/bitflags/pull/249 + +# 1.2.1 + +- Remove extraneous `#[inline]` attributes ([#194]) + +[#194]: https://github.com/bitflags/bitflags/pull/194 + +# 1.2.0 + +- Fix typo: {Lower, Upper}Exp - {Lower, Upper}Hex ([#183]) + +- Add support for "unknown" bits ([#188]) + +[#183]: https://github.com/rust-lang-nursery/bitflags/pull/183 +[#188]: https://github.com/rust-lang-nursery/bitflags/pull/188 + +# 1.1.0 + +This is a re-release of `1.0.5`, which was yanked due to a bug in the RLS. + +# 1.0.5 + +- Use compiletest_rs flags supported by stable toolchain ([#171]) + +- Put the user provided attributes first ([#173]) + +- Make bitflags methods `const` on newer compilers ([#175]) + +[#171]: https://github.com/rust-lang-nursery/bitflags/pull/171 +[#173]: https://github.com/rust-lang-nursery/bitflags/pull/173 +[#175]: https://github.com/rust-lang-nursery/bitflags/pull/175 + +# 1.0.4 + +- Support Rust 2018 style macro imports ([#165]) + + ```rust + use bitflags::bitflags; + ``` + +[#165]: https://github.com/rust-lang-nursery/bitflags/pull/165 + +# 1.0.3 + +- Improve zero value flag handling and documentation ([#157]) + +[#157]: https://github.com/rust-lang-nursery/bitflags/pull/157 + +# 1.0.2 + +- 30% improvement in compile time of bitflags crate ([#156]) + +- Documentation improvements ([#153]) + +- Implementation cleanup ([#149]) + +[#156]: https://github.com/rust-lang-nursery/bitflags/pull/156 +[#153]: https://github.com/rust-lang-nursery/bitflags/pull/153 +[#149]: https://github.com/rust-lang-nursery/bitflags/pull/149 + +# 1.0.1 +- Add support for `pub(restricted)` specifier on the bitflags struct ([#135]) +- Optimize performance of `all()` when called from a separate crate ([#136]) + +[#135]: https://github.com/rust-lang-nursery/bitflags/pull/135 +[#136]: https://github.com/rust-lang-nursery/bitflags/pull/136 + +# 1.0.0 +- **[breaking change]** Macro now generates [associated constants](https://doc.rust-lang.org/reference/items.html#associated-constants) ([#24]) + +- **[breaking change]** Minimum supported version is Rust **1.20**, due to usage of associated constants + +- After being broken in 0.9, the `#[deprecated]` attribute is now supported again ([#112]) + +- Other improvements to unit tests and documentation ([#106] and [#115]) + +[#24]: https://github.com/rust-lang-nursery/bitflags/pull/24 +[#106]: https://github.com/rust-lang-nursery/bitflags/pull/106 +[#112]: https://github.com/rust-lang-nursery/bitflags/pull/112 +[#115]: https://github.com/rust-lang-nursery/bitflags/pull/115 + +## How to update your code to use associated constants +Assuming the following structure definition: +```rust +bitflags! { + struct Something: u8 { + const FOO = 0b01, + const BAR = 0b10 + } +} +``` +In 0.9 and older you could do: +```rust +let x = FOO.bits | BAR.bits; +``` +Now you must use: +```rust +let x = Something::FOO.bits | Something::BAR.bits; +``` + +# 0.9.1 +- Fix the implementation of `Formatting` traits when other formatting traits were present in scope ([#105]) + +[#105]: https://github.com/rust-lang-nursery/bitflags/pull/105 + +# 0.9.0 +- **[breaking change]** Use struct keyword instead of flags to define bitflag types ([#84]) + +- **[breaking change]** Terminate const items with semicolons instead of commas ([#87]) + +- Implement the `Hex`, `Octal`, and `Binary` formatting traits ([#86]) + +- Printing an empty flag value with the `Debug` trait now prints "(empty)" instead of nothing ([#85]) + +- The `bitflags!` macro can now be used inside of a fn body, to define a type local to that function ([#74]) + +[#74]: https://github.com/rust-lang-nursery/bitflags/pull/74 +[#84]: https://github.com/rust-lang-nursery/bitflags/pull/84 +[#85]: https://github.com/rust-lang-nursery/bitflags/pull/85 +[#86]: https://github.com/rust-lang-nursery/bitflags/pull/86 +[#87]: https://github.com/rust-lang-nursery/bitflags/pull/87 + +# 0.8.2 +- Update feature flag used when building bitflags as a dependency of the Rust toolchain + +# 0.8.1 +- Allow bitflags to be used as a dependency of the Rust toolchain + +# 0.8.0 +- Add support for the experimental `i128` and `u128` integer types ([#57]) +- Add set method: `flags.set(SOME_FLAG, true)` or `flags.set(SOME_FLAG, false)` ([#55]) + This may break code that defines its own set method + +[#55]: https://github.com/rust-lang-nursery/bitflags/pull/55 +[#57]: https://github.com/rust-lang-nursery/bitflags/pull/57 + +# 0.7.1 +*(yanked)* + +# 0.7.0 +- Implement the Extend trait ([#49]) +- Allow definitions inside the `bitflags!` macro to refer to items imported from other modules ([#51]) + +[#49]: https://github.com/rust-lang-nursery/bitflags/pull/49 +[#51]: https://github.com/rust-lang-nursery/bitflags/pull/51 + +# 0.6.0 +- The `no_std` feature was removed as it is now the default +- The `assignment_operators` feature was remove as it is now enabled by default +- Some clippy suggestions have been applied diff --git a/vendor/bitflags/CODE_OF_CONDUCT.md b/vendor/bitflags/CODE_OF_CONDUCT.md new file mode 100644 index 0000000..f7add90 --- /dev/null +++ b/vendor/bitflags/CODE_OF_CONDUCT.md @@ -0,0 +1,73 @@ +# Contributor Covenant Code of Conduct + +## Our Pledge + +In the interest of fostering an open and welcoming environment, we as +contributors and maintainers pledge to making participation in our project and +our community a harassment-free experience for everyone, regardless of age, body +size, disability, ethnicity, gender identity and expression, level of experience, +education, socio-economic status, nationality, personal appearance, race, +religion, or sexual identity and orientation. + +## Our Standards + +Examples of behavior that contributes to creating a positive environment +include: + +* Using welcoming and inclusive language +* Being respectful of differing viewpoints and experiences +* Gracefully accepting constructive criticism +* Focusing on what is best for the community +* Showing empathy towards other community members + +Examples of unacceptable behavior by participants include: + +* The use of sexualized language or imagery and unwelcome sexual attention or + advances +* Trolling, insulting/derogatory comments, and personal or political attacks +* Public or private harassment +* Publishing others' private information, such as a physical or electronic + address, without explicit permission +* Other conduct which could reasonably be considered inappropriate in a + professional setting + +## Our Responsibilities + +Project maintainers are responsible for clarifying the standards of acceptable +behavior and are expected to take appropriate and fair corrective action in +response to any instances of unacceptable behavior. + +Project maintainers have the right and responsibility to remove, edit, or +reject comments, commits, code, wiki edits, issues, and other contributions +that are not aligned to this Code of Conduct, or to ban temporarily or +permanently any contributor for other behaviors that they deem inappropriate, +threatening, offensive, or harmful. + +## Scope + +This Code of Conduct applies both within project spaces and in public spaces +when an individual is representing the project or its community. Examples of +representing a project or community include using an official project e-mail +address, posting via an official social media account, or acting as an appointed +representative at an online or offline event. Representation of a project may be +further defined and clarified by project maintainers. + +## Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be +reported by contacting the project team at coc@senaite.org. All +complaints will be reviewed and investigated and will result in a response that +is deemed necessary and appropriate to the circumstances. The project team is +obligated to maintain confidentiality with regard to the reporter of an incident. +Further details of specific enforcement policies may be posted separately. + +Project maintainers who do not follow or enforce the Code of Conduct in good +faith may face temporary or permanent repercussions as determined by other +members of the project's leadership. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, +available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html + +[homepage]: https://www.contributor-covenant.org \ No newline at end of file diff --git a/vendor/bitflags/CONTRIBUTING.md b/vendor/bitflags/CONTRIBUTING.md new file mode 100644 index 0000000..5883363 --- /dev/null +++ b/vendor/bitflags/CONTRIBUTING.md @@ -0,0 +1,9 @@ +# Updating compile-fail test outputs + +`bitflags` uses the `trybuild` crate to integration test its macros. Since Rust error messages change frequently enough that `nightly` builds produce spurious failures, we only check the compiler output in `beta` builds. If you run: + +``` +TRYBUILD=overwrite cargo +beta test --all +``` + +it will run the tests and update the `trybuild` output files. diff --git a/vendor/bitflags/Cargo.toml b/vendor/bitflags/Cargo.toml new file mode 100644 index 0000000..54c4b82 --- /dev/null +++ b/vendor/bitflags/Cargo.toml @@ -0,0 +1,96 @@ +# 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] +edition = "2021" +rust-version = "1.56.0" +name = "bitflags" +version = "2.6.0" +authors = ["The Rust Project Developers"] +exclude = [ + "/tests", + "/.github", +] +description = """ +A macro to generate structures which behave like bitflags. +""" +homepage = "https://github.com/bitflags/bitflags" +documentation = "https://docs.rs/bitflags" +readme = "README.md" +keywords = [ + "bit", + "bitmask", + "bitflags", + "flags", +] +categories = ["no-std"] +license = "MIT OR Apache-2.0" +repository = "https://github.com/bitflags/bitflags" + +[package.metadata.docs.rs] +features = ["example_generated"] + +[dependencies.arbitrary] +version = "1.0" +optional = true + +[dependencies.bytemuck] +version = "1.12" +optional = true + +[dependencies.compiler_builtins] +version = "0.1.2" +optional = true + +[dependencies.core] +version = "1.0.0" +optional = true +package = "rustc-std-workspace-core" + +[dependencies.serde] +version = "1.0.103" +optional = true +default-features = false + +[dev-dependencies.arbitrary] +version = "1.0" +features = ["derive"] + +[dev-dependencies.bytemuck] +version = "1.12.2" +features = ["derive"] + +[dev-dependencies.rustversion] +version = "1.0" + +[dev-dependencies.serde_derive] +version = "1.0.103" + +[dev-dependencies.serde_json] +version = "1.0" + +[dev-dependencies.serde_test] +version = "1.0.19" + +[dev-dependencies.trybuild] +version = "1.0.18" + +[dev-dependencies.zerocopy] +version = "0.7" +features = ["derive"] + +[features] +example_generated = [] +rustc-dep-of-std = [ + "core", + "compiler_builtins", +] +std = [] diff --git a/vendor/bitflags/LICENSE-APACHE b/vendor/bitflags/LICENSE-APACHE new file mode 100644 index 0000000..16fe87b --- /dev/null +++ b/vendor/bitflags/LICENSE-APACHE @@ -0,0 +1,201 @@ + 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/bitflags/LICENSE-MIT b/vendor/bitflags/LICENSE-MIT new file mode 100644 index 0000000..39d4bdb --- /dev/null +++ b/vendor/bitflags/LICENSE-MIT @@ -0,0 +1,25 @@ +Copyright (c) 2014 The Rust Project Developers + +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/bitflags/README.md b/vendor/bitflags/README.md new file mode 100644 index 0000000..f2ad555 --- /dev/null +++ b/vendor/bitflags/README.md @@ -0,0 +1,77 @@ +bitflags +======== + +[![Rust](https://github.com/bitflags/bitflags/workflows/Rust/badge.svg)](https://github.com/bitflags/bitflags/actions) +[![Latest version](https://img.shields.io/crates/v/bitflags.svg)](https://crates.io/crates/bitflags) +[![Documentation](https://docs.rs/bitflags/badge.svg)](https://docs.rs/bitflags) +![License](https://img.shields.io/crates/l/bitflags.svg) + +`bitflags` generates flags enums with well-defined semantics and ergonomic end-user APIs. + +You can use `bitflags` to: + +- provide more user-friendly bindings to C APIs where flags may or may not be fully known in advance. +- generate efficient options types with string parsing and formatting support. + +You can't use `bitflags` to: + +- guarantee only bits corresponding to defined flags will ever be set. `bitflags` allows access to the underlying bits type so arbitrary bits may be set. +- define bitfields. `bitflags` only generates types where set bits denote the presence of some combination of flags. + +- [Documentation](https://docs.rs/bitflags) +- [Specification](https://github.com/bitflags/bitflags/blob/main/spec.md) +- [Release notes](https://github.com/bitflags/bitflags/releases) + +## Usage + +Add this to your `Cargo.toml`: + +```toml +[dependencies] +bitflags = "2.6.0" +``` + +and this to your source code: + +```rust +use bitflags::bitflags; +``` + +## Example + +Generate a flags structure: + +```rust +use bitflags::bitflags; + +// The `bitflags!` macro generates `struct`s that manage a set of flags. +bitflags! { + /// Represents a set of flags. + #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] + struct Flags: u32 { + /// The value `A`, at bit position `0`. + const A = 0b00000001; + /// The value `B`, at bit position `1`. + const B = 0b00000010; + /// The value `C`, at bit position `2`. + const C = 0b00000100; + + /// The combination of `A`, `B`, and `C`. + const ABC = Self::A.bits() | Self::B.bits() | Self::C.bits(); + } +} + +fn main() { + let e1 = Flags::A | Flags::C; + let e2 = Flags::B | Flags::C; + assert_eq!((e1 | e2), Flags::ABC); // union + assert_eq!((e1 & e2), Flags::C); // intersection + assert_eq!((e1 - e2), Flags::A); // set difference + assert_eq!(!e2, Flags::A); // set complement +} +``` + +## Rust Version Support + +The minimum supported Rust version is documented in the `Cargo.toml` file. +This may be bumped in minor releases as necessary. diff --git a/vendor/bitflags/SECURITY.md b/vendor/bitflags/SECURITY.md new file mode 100644 index 0000000..790ac5b --- /dev/null +++ b/vendor/bitflags/SECURITY.md @@ -0,0 +1,13 @@ +# Security Policy + +## Supported Versions + +Security updates are applied only to the latest release. + +## Reporting a Vulnerability + +If you have discovered a security vulnerability in this project, please report it privately. **Do not disclose it as a public issue.** This gives us time to work with you to fix the issue before public exposure, reducing the chance that the exploit will be used before a patch is released. + +Please disclose it at [security advisory](https://github.com/bitflags/bitflags/security/advisories/new). + +This project is maintained by a team of volunteers on a reasonable-effort basis. As such, please give us at least 90 days to work on a fix before public exposure. diff --git a/vendor/bitflags/benches/parse.rs b/vendor/bitflags/benches/parse.rs new file mode 100644 index 0000000..caa9203 --- /dev/null +++ b/vendor/bitflags/benches/parse.rs @@ -0,0 +1,96 @@ +#![feature(test)] + +extern crate test; + +use std::{ + fmt::{self, Display}, + str::FromStr, +}; + +bitflags::bitflags! { + struct Flags10: u32 { + const A = 0b0000_0000_0000_0001; + const B = 0b0000_0000_0000_0010; + const C = 0b0000_0000_0000_0100; + const D = 0b0000_0000_0000_1000; + const E = 0b0000_0000_0001_0000; + const F = 0b0000_0000_0010_0000; + const G = 0b0000_0000_0100_0000; + const H = 0b0000_0000_1000_0000; + const I = 0b0000_0001_0000_0000; + const J = 0b0000_0010_0000_0000; + } +} + +impl FromStr for Flags10 { + type Err = bitflags::parser::ParseError; + + fn from_str(flags: &str) -> Result { + Ok(Flags10(flags.parse()?)) + } +} + +impl Display for Flags10 { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + Display::fmt(&self.0, f) + } +} + +#[bench] +fn format_flags_1_present(b: &mut test::Bencher) { + b.iter(|| Flags10::J.to_string()) +} + +#[bench] +fn format_flags_5_present(b: &mut test::Bencher) { + b.iter(|| (Flags10::F | Flags10::G | Flags10::H | Flags10::I | Flags10::J).to_string()) +} + +#[bench] +fn format_flags_10_present(b: &mut test::Bencher) { + b.iter(|| { + (Flags10::A + | Flags10::B + | Flags10::C + | Flags10::D + | Flags10::E + | Flags10::F + | Flags10::G + | Flags10::H + | Flags10::I + | Flags10::J) + .to_string() + }) +} + +#[bench] +fn parse_flags_1_10(b: &mut test::Bencher) { + b.iter(|| { + let flags: Flags10 = "J".parse().unwrap(); + flags + }) +} + +#[bench] +fn parse_flags_5_10(b: &mut test::Bencher) { + b.iter(|| { + let flags: Flags10 = "F | G | H | I | J".parse().unwrap(); + flags + }) +} + +#[bench] +fn parse_flags_10_10(b: &mut test::Bencher) { + b.iter(|| { + let flags: Flags10 = "A | B | C | D | E | F | G | H | I | J".parse().unwrap(); + flags + }) +} + +#[bench] +fn parse_flags_1_10_hex(b: &mut test::Bencher) { + b.iter(|| { + let flags: Flags10 = "0xFF".parse().unwrap(); + flags + }) +} diff --git a/vendor/bitflags/examples/custom_bits_type.rs b/vendor/bitflags/examples/custom_bits_type.rs new file mode 100644 index 0000000..8924bfd --- /dev/null +++ b/vendor/bitflags/examples/custom_bits_type.rs @@ -0,0 +1,97 @@ +use std::ops::{BitAnd, BitOr, BitXor, Not}; + +use bitflags::{Bits, Flag, Flags}; + +// Define a custom container that can be used in flags types +// Note custom bits types can't be used in `bitflags!` +// without making the trait impls `const`. This is currently +// unstable +#[derive(Clone, Copy, Debug)] +pub struct CustomBits([bool; 3]); + +impl Bits for CustomBits { + const EMPTY: Self = CustomBits([false; 3]); + + const ALL: Self = CustomBits([true; 3]); +} + +impl PartialEq for CustomBits { + fn eq(&self, other: &Self) -> bool { + self.0 == other.0 + } +} + +impl BitAnd for CustomBits { + type Output = Self; + + fn bitand(self, other: Self) -> Self { + CustomBits([ + self.0[0] & other.0[0], + self.0[1] & other.0[1], + self.0[2] & other.0[2], + ]) + } +} + +impl BitOr for CustomBits { + type Output = Self; + + fn bitor(self, other: Self) -> Self { + CustomBits([ + self.0[0] | other.0[0], + self.0[1] | other.0[1], + self.0[2] | other.0[2], + ]) + } +} + +impl BitXor for CustomBits { + type Output = Self; + + fn bitxor(self, other: Self) -> Self { + CustomBits([ + self.0[0] & other.0[0], + self.0[1] & other.0[1], + self.0[2] & other.0[2], + ]) + } +} + +impl Not for CustomBits { + type Output = Self; + + fn not(self) -> Self { + CustomBits([!self.0[0], !self.0[1], !self.0[2]]) + } +} + +#[derive(Clone, Copy, Debug)] +pub struct CustomFlags(CustomBits); + +impl CustomFlags { + pub const A: Self = CustomFlags(CustomBits([true, false, false])); + pub const B: Self = CustomFlags(CustomBits([false, true, false])); + pub const C: Self = CustomFlags(CustomBits([false, false, true])); +} + +impl Flags for CustomFlags { + const FLAGS: &'static [Flag] = &[ + Flag::new("A", Self::A), + Flag::new("B", Self::B), + Flag::new("C", Self::C), + ]; + + type Bits = CustomBits; + + fn bits(&self) -> Self::Bits { + self.0 + } + + fn from_bits_retain(bits: Self::Bits) -> Self { + CustomFlags(bits) + } +} + +fn main() { + println!("{:?}", CustomFlags::A.union(CustomFlags::C)); +} diff --git a/vendor/bitflags/examples/custom_derive.rs b/vendor/bitflags/examples/custom_derive.rs new file mode 100644 index 0000000..4239ee4 --- /dev/null +++ b/vendor/bitflags/examples/custom_derive.rs @@ -0,0 +1,23 @@ +//! An example of implementing the `BitFlags` trait manually for a flags type. + +use std::str; + +use bitflags::bitflags; + +// Define a flags type outside of the `bitflags` macro as a newtype +// It can accept custom derives for libraries `bitflags` doesn't support natively +#[derive(zerocopy::AsBytes, zerocopy::FromBytes, zerocopy::FromZeroes)] +#[repr(transparent)] +pub struct ManualFlags(u32); + +// Next: use `impl Flags` instead of `struct Flags` +bitflags! { + impl ManualFlags: u32 { + const A = 0b00000001; + const B = 0b00000010; + const C = 0b00000100; + const ABC = Self::A.bits() | Self::B.bits() | Self::C.bits(); + } +} + +fn main() {} diff --git a/vendor/bitflags/examples/fmt.rs b/vendor/bitflags/examples/fmt.rs new file mode 100644 index 0000000..724b207 --- /dev/null +++ b/vendor/bitflags/examples/fmt.rs @@ -0,0 +1,49 @@ +//! An example of implementing Rust's standard formatting and parsing traits for flags types. + +use core::{fmt, str}; + +bitflags::bitflags! { + // You can `#[derive]` the `Debug` trait, but implementing it manually + // can produce output like `A | B` instead of `Flags(A | B)`. + // #[derive(Debug)] + #[derive(PartialEq, Eq)] + pub struct Flags: u32 { + const A = 1; + const B = 2; + const C = 4; + const D = 8; + } +} + +impl fmt::Debug for Flags { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + bitflags::parser::to_writer(self, f) + } +} + +impl fmt::Display for Flags { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + bitflags::parser::to_writer(self, f) + } +} + +impl str::FromStr for Flags { + type Err = bitflags::parser::ParseError; + + fn from_str(flags: &str) -> Result { + bitflags::parser::from_str(flags) + } +} + +fn main() -> Result<(), bitflags::parser::ParseError> { + let flags = Flags::A | Flags::B; + + println!("{}", flags); + + let formatted = flags.to_string(); + let parsed: Flags = formatted.parse()?; + + assert_eq!(flags, parsed); + + Ok(()) +} diff --git a/vendor/bitflags/examples/macro_free.rs b/vendor/bitflags/examples/macro_free.rs new file mode 100644 index 0000000..7563379 --- /dev/null +++ b/vendor/bitflags/examples/macro_free.rs @@ -0,0 +1,61 @@ +//! An example of implementing the `BitFlags` trait manually for a flags type. +//! +//! This example doesn't use any macros. + +use std::{fmt, str}; + +use bitflags::{Flag, Flags}; + +// First: Define your flags type. It just needs to be `Sized + 'static`. +pub struct ManualFlags(u32); + +// Not required: Define some constants for valid flags +impl ManualFlags { + pub const A: ManualFlags = ManualFlags(0b00000001); + pub const B: ManualFlags = ManualFlags(0b00000010); + pub const C: ManualFlags = ManualFlags(0b00000100); + pub const ABC: ManualFlags = ManualFlags(0b00000111); +} + +// Next: Implement the `BitFlags` trait, specifying your set of valid flags +// and iterators +impl Flags for ManualFlags { + const FLAGS: &'static [Flag] = &[ + Flag::new("A", Self::A), + Flag::new("B", Self::B), + Flag::new("C", Self::C), + ]; + + type Bits = u32; + + fn bits(&self) -> u32 { + self.0 + } + + fn from_bits_retain(bits: u32) -> Self { + Self(bits) + } +} + +// Not required: Add parsing support +impl str::FromStr for ManualFlags { + type Err = bitflags::parser::ParseError; + + fn from_str(input: &str) -> Result { + bitflags::parser::from_str(input) + } +} + +// Not required: Add formatting support +impl fmt::Display for ManualFlags { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + bitflags::parser::to_writer(self, f) + } +} + +fn main() { + println!( + "{}", + ManualFlags::A.union(ManualFlags::B).union(ManualFlags::C) + ); +} diff --git a/vendor/bitflags/examples/serde.rs b/vendor/bitflags/examples/serde.rs new file mode 100644 index 0000000..22eae2d --- /dev/null +++ b/vendor/bitflags/examples/serde.rs @@ -0,0 +1,36 @@ +//! An example of implementing `serde::Serialize` and `serde::Deserialize`. +//! The `#[serde(transparent)]` attribute is recommended to serialize directly +//! to the underlying bits type without wrapping it in a `serde` newtype. + +#[cfg(feature = "serde")] +fn main() { + use serde_derive::*; + + bitflags::bitflags! { + #[derive(Serialize, Deserialize, Debug, PartialEq, Eq)] + #[serde(transparent)] + pub struct Flags: u32 { + const A = 1; + const B = 2; + const C = 4; + const D = 8; + } + } + + let flags = Flags::A | Flags::B; + + let serialized = serde_json::to_string(&flags).unwrap(); + + println!("{:?} -> {}", flags, serialized); + + assert_eq!(serialized, r#""A | B""#); + + let deserialized: Flags = serde_json::from_str(&serialized).unwrap(); + + println!("{} -> {:?}", serialized, flags); + + assert_eq!(deserialized, flags); +} + +#[cfg(not(feature = "serde"))] +fn main() {} diff --git a/vendor/bitflags/spec.md b/vendor/bitflags/spec.md new file mode 100644 index 0000000..43dae1d --- /dev/null +++ b/vendor/bitflags/spec.md @@ -0,0 +1,552 @@ +# Bitflags + +`bitflags` generates flags enums with well-defined semantics and ergonomic end-user APIs. + +You can use `bitflags` to: + +- provide more user-friendly bindings to C APIs where flags may or may not be fully known in advance. +- generate efficient options types with string parsing and formatting support. + +You can't use `bitflags` to: + +- guarantee only bits corresponding to defined flags will ever be set. `bitflags` allows access to the underlying bits type so arbitrary bits may be set. +- define bitfields. `bitflags` only generates types where set bits denote the presence of some combination of flags. + +## Definitions + +This section formally defines the terminology and semantics of `bitflags`. It's organized so more fundamental concepts are introduced before those that build on them. It may be helpful to start from the bottom of the section and refer back up to concepts defined earlier. + +Examples use `bitflags` syntax with `u8` as the bits type. + +### Bits type + +A type that defines a fixed number of bits at specific locations. + +---- + +Bits types are typically fixed-width unsigned integers. For example, `u8` is a bits type that defines 8 bits; bit-0 through bit-7. + +### Bits value + +An instance of a bits type where each bit may be set (`1`) or unset (`0`). + +---- + +Some examples of bits values for the bits type `u8` are: + +```rust +0b0000_0000 +0b1111_1111 +0b1010_0101 +``` + +#### Equality + +Two bits values are equal if their bits are in the same configuration; set bits in one are set in the other, and unset bits in one are unset in the other. + +#### Operations + +Bits values define the bitwise operators and (`&`), or (`|`), exclusive-or (`^`), and negation (`!`) that apply to each of their bits. + +### Flag + +A set of bits in a bits type that may have a unique name. + +---- + +Bits are not required to be exclusive to a flag. Bits are not required to be contiguous. + +The following is a flag for `u8` with the name `A` that includes bit-0: + +```rust +const A = 0b0000_0001; +``` + +The following is a flag for `u8` with the name `B` that includes bit-0, and bit-5: + +```rust +const B = 0b0010_0001; +``` + +#### Named flag + +A flag with a name. + +---- + +The following is a named flag, where the name is `A`: + +```rust +const A = 0b0000_0001; +``` + +#### Unnamed flag + +A flag without a name. + +---- + +The following is an unnamed flag: + +```rust +const _ = 0b0000_0001; +``` + +#### Zero-bit flag + +A flag with a set of zero bits. + +---- + +The following is a zero-bit flag: + +```rust +const ZERO = 0b0000_0000; +``` + +#### Single-bit flag + +A flag with a set of one bit. + +---- + +The following are single-bit flags: + +```rust +const A = 0b0000_0001; +const B = 0b0000_0010; +``` + +#### Multi-bit flag + +A flag with a set of more than one bit. + +---- + +The following are multi-bit flags: + +```rust +const A = 0b0000_0011; +const B = 0b1111_1111; +``` + +### Flags type + +A set of defined flags over a specific bits type. + +#### Known bit + +A bit in any defined flag. + +---- + +In the following flags type: + +```rust +struct Flags { + const A = 0b0000_0001; + const B = 0b0000_0010; + const C = 0b0000_0100; +} +``` + +the known bits are: + +```rust +0b0000_0111 +``` + +#### Unknown bit + +A bit not in any defined flag. + +---- + +In the following flags type: + +```rust +struct Flags { + const A = 0b0000_0001; + const B = 0b0000_0010; + const C = 0b0000_0100; +} +``` + +the unknown bits are: + +```rust +0b1111_1000 +``` + +### Flags value + +An instance of a flags type using its specific bits value for storage. + +The flags value of a flag is one where each of its bits is set, and all others are unset. + +#### Contains + +Whether all set bits in a source flags value are also set in a target flags value. + +---- + +Given the flags value: + +```rust +0b0000_0011 +``` + +the following flags values are contained: + +```rust +0b0000_0000 +0b0000_0010 +0b0000_0001 +0b0000_0011 +``` + +but the following flags values are not contained: + +```rust +0b0000_1000 +0b0000_0110 +``` + +#### Intersects + +Whether any set bits in a source flags value are also set in a target flags value. + +---- + +Given the flags value: + +```rust +0b0000_0011 +``` + +the following flags intersect: + +```rust +0b0000_0010 +0b0000_0001 +0b1111_1111 +``` + +but the following flags values do not intersect: + +```rust +0b0000_0000 +0b1111_0000 +``` + +#### Empty + +Whether all bits in a flags value are unset. + +---- + +The following flags value is empty: + +```rust +0b0000_0000 +``` + +The following flags values are not empty: + +```rust +0b0000_0001 +0b0110_0000 +``` + +#### All + +Whether all defined flags are contained in a flags value. + +---- + +Given a flags type: + +```rust +struct Flags { + const A = 0b0000_0001; + const B = 0b0000_0010; +} +``` + +the following flags values all satisfy all: + +```rust +0b0000_0011 +0b1000_0011 +0b1111_1111 +``` + +### Operations + +Examples in this section all use the given flags type: + +```rust +struct Flags { + const A = 0b0000_0001; + const B = 0b0000_0010; + const C = 0b0000_1100; +} +``` + +#### Truncate + +Unset all unknown bits in a flags value. + +---- + +Given the flags value: + +```rust +0b1111_1111 +``` + +the result of truncation will be: + +```rust +0b0000_1111 +``` + +---- + +Truncating doesn't guarantee that a non-empty result will contain any defined flags. Given the following flags type: + +```rust +struct Flags { + const A = 0b0000_0101; +} +``` + +and the following flags value: + +```rust +0b0000_1110; +``` + +The result of truncation will be: + +```rust +0b0000_0100; +``` + +which intersects the flag `A`, but doesn't contain it. + +This behavior is possible even when only operating with flags values containing defined flags. Given the following flags type: + +```rust +struct Flags { + const A = 0b0000_0101; + const B = 0b0000_0001; +} +``` + +The result of `A ^ B` is `0b0000_0100`, which also doesn't contain any defined flag. + +---- + +If all known bits are in the set of at least one defined single-bit flag, then all operations that produce non-empty results will always contain defined flags. + +#### Union + +The bitwise or (`|`) of the bits in two flags values. + +---- + +The following are examples of the result of unioning flags values: + +```rust +0b0000_0001 | 0b0000_0010 = 0b0000_0011 +0b0000_0000 | 0b1111_1111 = 0b1111_1111 +``` + +#### Intersection + +The bitwise and (`&`) of the bits in two flags values. + +---- + +The following are examples of the result of intersecting flags values: + +```rust +0b0000_0001 & 0b0000_0010 = 0b0000_0000 +0b1111_1100 & 0b1111_0111 = 0b1111_0100 +0b1111_1111 & 0b1111_1111 = 0b1111_1111 +``` + +#### Symmetric difference + +The bitwise exclusive-or (`^`) of the bits in two flags values. + +---- + +The following are examples of the symmetric difference between two flags values: + +```rust +0b0000_0001 ^ 0b0000_0010 = 0b0000_0011 +0b0000_1111 ^ 0b0000_0011 = 0b0000_1100 +0b1100_0000 ^ 0b0011_0000 = 0b1111_0000 +``` + +#### Complement + +The bitwise negation (`!`) of the bits in a flags value, truncating the result. + +---- + +The following are examples of the complement of a flags value: + +```rust +!0b0000_0000 = 0b0000_1111 +!0b0000_1111 = 0b0000_0000 +!0b1111_1000 = 0b0000_0111 +``` + +#### Difference + +The bitwise union (`|`) of the bits in one flags value and the bitwise negation (`!`) of the bits in another. + +---- + +This operation is not equivalent to the intersection of one flags value with the complement of another (`&!`). +The former will truncate the result, where difference will not. + +---- + +The following are examples of the difference between two flags values: + +```rust +0b0000_0001 & !0b0000_0010 = 0b0000_0001 +0b0000_1101 & !0b0000_0011 = 0b0000_1100 +0b1111_1111 & !0b0000_0001 = 0b1111_1110 +``` + +### Iteration + +Yield the bits of a source flags value in a set of contained flags values. + +---- + +To be most useful, each yielded flags value should set exactly the bits of a defined flag contained in the source. Any known bits that aren't in the set of any contained flag should be yielded together as a final flags value. + +---- + +Given the following flags type: + +```rust +struct Flags { + const A = 0b0000_0001; + const B = 0b0000_0010; + const AB = 0b0000_0011; +} +``` + +and the following flags value: + +```rust +0b0000_1111 +``` + +When iterated it may yield a flags value for `A` and `B`, then a final flag with the unknown bits: + +```rust +0b0000_0001 +0b0000_0010 +0b0000_1100 +``` + +It may also yield a flags value for `AB`, then a final flag with the unknown bits: + +```rust +0b0000_0011 +0b0000_1100 +``` + +---- + +Given the following flags type: + +```rust +struct Flags { + const A = 0b0000_0011; +} +``` + +and the following flags value: + +```rust +0b0000_0001 +``` + +When iterated it will still yield a flags value for the known bit `0b0000_0001` even though it doesn't contain a flag. + +### Formatting + +Format and parse a flags value as text using the following grammar: + +- _Flags:_ (_Whitespace_ _Flag_ _Whitespace_)`|`* +- _Flag:_ _Name_ | _Hex Number_ +- _Name:_ The name of any defined flag +- _Hex Number_: `0x`([0-9a-fA-F])* +- _Whitespace_: (\s)* + +Flags values can be formatted as _Flags_ by iterating over them, formatting each yielded flags value as a _Flag_. Any yielded flags value that sets exactly the bits of a defined flag with a name should be formatted as a _Name_. Otherwise it must be formatted as a _Hex Number_. + +Formatting and parsing supports three modes: + +- **Retain**: Formatting and parsing roundtrips exactly the bits of the source flags value. This is the default behavior. +- **Truncate**: Flags values are truncated before formatting, and truncated after parsing. +- **Strict**: A _Flag_ may only be formatted and parsed as a _Name_. _Hex numbers_ are not allowed. A consequence of this is that unknown bits and any bits that aren't in a contained named flag will be ignored. This is recommended for flags values serialized across API boundaries, like web services. + +Text that is empty or whitespace is an empty flags value. + +---- + +Given the following flags type: + +```rust +struct Flags { + const A = 0b0000_0001; + const B = 0b0000_0010; + const AB = 0b0000_0011; + const C = 0b0000_1100; +} +``` + +The following are examples of how flags values can be formatted using any mode: + +```rust +0b0000_0000 = "" +0b0000_0001 = "A" +0b0000_0010 = "B" +0b0000_0011 = "A | B" +0b0000_0011 = "AB" +0b0000_1111 = "A | B | C" +``` + +Truncate mode will unset any unknown bits: + +```rust +0b1000_0000 = "" +0b1111_1111 = "A | B | C" +0b0000_1000 = "0x8" +``` + +Retain mode will include any unknown bits as a final _Flag_: + +```rust +0b1000_0000 = "0x80" +0b1111_1111 = "A | B | C | 0xf0" +0b0000_1000 = "0x8" +``` + +Strict mode will unset any unknown bits, as well as bits not contained in any defined named flags: + +```rust +0b1000_0000 = "" +0b1111_1111 = "A | B | C" +0b0000_1000 = "" +``` diff --git a/vendor/bitflags/src/example_generated.rs b/vendor/bitflags/src/example_generated.rs new file mode 100644 index 0000000..abb1118 --- /dev/null +++ b/vendor/bitflags/src/example_generated.rs @@ -0,0 +1,65 @@ +//! This module shows an example of code generated by the macro. **IT MUST NOT BE USED OUTSIDE THIS +//! CRATE**. +//! +//! Usually, when you call the `bitflags!` macro, only the `Flags` type would be visible. In this +//! example, the `Field0`, `Iter`, and `IterRaw` types are also exposed so that you can explore +//! their APIs. The `Field0` type can be accessed as `self.0` on an instance of `Flags`. + +__declare_public_bitflags! { + /// This is the same `Flags` struct defined in the [crate level example](../index.html#example). + /// Note that this struct is just for documentation purposes only, it must not be used outside + /// this crate. + pub struct Flags +} + +__declare_internal_bitflags! { + pub struct Field0: u32 +} + +__impl_internal_bitflags! { + Field0: u32, Flags { + // Field `A`. + /// + /// This flag has the value `0b00000001`. + const A = 0b00000001; + /// Field `B`. + /// + /// This flag has the value `0b00000010`. + const B = 0b00000010; + /// Field `C`. + /// + /// This flag has the value `0b00000100`. + const C = 0b00000100; + const ABC = Self::A.bits() | Self::B.bits() | Self::C.bits(); + } +} + +__impl_public_bitflags_forward! { + Flags: u32, Field0 +} + +__impl_public_bitflags_ops! { + Flags +} + +__impl_public_bitflags_iter! { + Flags: u32, Flags +} + +__impl_public_bitflags_consts! { + Flags: u32 { + /// Field `A`. + /// + /// This flag has the value `0b00000001`. + const A = 0b00000001; + /// Field `B`. + /// + /// This flag has the value `0b00000010`. + const B = 0b00000010; + /// Field `C`. + /// + /// This flag has the value `0b00000100`. + const C = 0b00000100; + const ABC = Self::A.bits() | Self::B.bits() | Self::C.bits(); + } +} diff --git a/vendor/bitflags/src/external.rs b/vendor/bitflags/src/external.rs new file mode 100644 index 0000000..716af83 --- /dev/null +++ b/vendor/bitflags/src/external.rs @@ -0,0 +1,262 @@ +//! Conditional trait implementations for external libraries. + +/* +How do I support a new external library? + +Let's say we want to add support for `my_library`. + +First, we create a module under `external`, like `serde` with any specialized code. +Ideally, any utilities in here should just work off the `Flags` trait and maybe a +few other assumed bounds. + +Next, re-export the library from the `__private` module here. + +Next, define a macro like so: + +```rust +#[macro_export] +#[doc(hidden)] +#[cfg(feature = "serde")] +macro_rules! __impl_external_bitflags_my_library { + ( + $InternalBitFlags:ident: $T:ty, $PublicBitFlags:ident { + $( + $(#[$inner:ident $($args:tt)*])* + const $Flag:tt; + )* + } + ) => { + // Implementation goes here + }; +} + +#[macro_export] +#[doc(hidden)] +#[cfg(not(feature = "my_library"))] +macro_rules! __impl_external_bitflags_my_library { + ( + $InternalBitFlags:ident: $T:ty, $PublicBitFlags:ident { + $( + $(#[$inner:ident $($args:tt)*])* + const $Flag:tt; + )* + } + ) => {}; +} +``` + +Note that the macro is actually defined twice; once for when the `my_library` feature +is available, and once for when it's not. This is because the `__impl_external_bitflags_my_library` +macro is called in an end-user's library, not in `bitflags`. In an end-user's library we don't +know whether or not a particular feature of `bitflags` is enabled, so we unconditionally call +the macro, where the body of that macro depends on the feature flag. + +Now, we add our macro call to the `__impl_external_bitflags` macro body: + +```rust +__impl_external_bitflags_my_library! { + $InternalBitFlags: $T, $PublicBitFlags { + $( + $(#[$inner $($args)*])* + const $Flag; + )* + } +} +``` +*/ + +pub(crate) mod __private { + #[cfg(feature = "serde")] + pub use serde; + + #[cfg(feature = "arbitrary")] + pub use arbitrary; + + #[cfg(feature = "bytemuck")] + pub use bytemuck; +} + +/// Implements traits from external libraries for the internal bitflags type. +#[macro_export] +#[doc(hidden)] +macro_rules! __impl_external_bitflags { + ( + $InternalBitFlags:ident: $T:ty, $PublicBitFlags:ident { + $( + $(#[$inner:ident $($args:tt)*])* + const $Flag:tt; + )* + } + ) => { + // Any new library traits impls should be added here + // Use `serde` as an example: generate code when the feature is available, + // and a no-op when it isn't + + $crate::__impl_external_bitflags_serde! { + $InternalBitFlags: $T, $PublicBitFlags { + $( + $(#[$inner $($args)*])* + const $Flag; + )* + } + } + + $crate::__impl_external_bitflags_arbitrary! { + $InternalBitFlags: $T, $PublicBitFlags { + $( + $(#[$inner $($args)*])* + const $Flag; + )* + } + } + + $crate::__impl_external_bitflags_bytemuck! { + $InternalBitFlags: $T, $PublicBitFlags { + $( + $(#[$inner $($args)*])* + const $Flag; + )* + } + } + }; +} + +#[cfg(feature = "serde")] +pub mod serde; + +/// Implement `Serialize` and `Deserialize` for the internal bitflags type. +#[macro_export] +#[doc(hidden)] +#[cfg(feature = "serde")] +macro_rules! __impl_external_bitflags_serde { + ( + $InternalBitFlags:ident: $T:ty, $PublicBitFlags:ident { + $( + $(#[$inner:ident $($args:tt)*])* + const $Flag:tt; + )* + } + ) => { + impl $crate::__private::serde::Serialize for $InternalBitFlags { + fn serialize( + &self, + serializer: S, + ) -> $crate::__private::core::result::Result { + $crate::serde::serialize( + &$PublicBitFlags::from_bits_retain(self.bits()), + serializer, + ) + } + } + + impl<'de> $crate::__private::serde::Deserialize<'de> for $InternalBitFlags { + fn deserialize>( + deserializer: D, + ) -> $crate::__private::core::result::Result { + let flags: $PublicBitFlags = $crate::serde::deserialize(deserializer)?; + + Ok(flags.0) + } + } + }; +} + +#[macro_export] +#[doc(hidden)] +#[cfg(not(feature = "serde"))] +macro_rules! __impl_external_bitflags_serde { + ( + $InternalBitFlags:ident: $T:ty, $PublicBitFlags:ident { + $( + $(#[$inner:ident $($args:tt)*])* + const $Flag:tt; + )* + } + ) => {}; +} + +#[cfg(feature = "arbitrary")] +pub mod arbitrary; + +#[cfg(feature = "bytemuck")] +mod bytemuck; + +/// Implement `Arbitrary` for the internal bitflags type. +#[macro_export] +#[doc(hidden)] +#[cfg(feature = "arbitrary")] +macro_rules! __impl_external_bitflags_arbitrary { + ( + $InternalBitFlags:ident: $T:ty, $PublicBitFlags:ident { + $( + $(#[$inner:ident $($args:tt)*])* + const $Flag:tt; + )* + } + ) => { + impl<'a> $crate::__private::arbitrary::Arbitrary<'a> for $InternalBitFlags { + fn arbitrary( + u: &mut $crate::__private::arbitrary::Unstructured<'a>, + ) -> $crate::__private::arbitrary::Result { + $crate::arbitrary::arbitrary::<$PublicBitFlags>(u).map(|flags| flags.0) + } + } + }; +} + +#[macro_export] +#[doc(hidden)] +#[cfg(not(feature = "arbitrary"))] +macro_rules! __impl_external_bitflags_arbitrary { + ( + $InternalBitFlags:ident: $T:ty, $PublicBitFlags:ident { + $( + $(#[$inner:ident $($args:tt)*])* + const $Flag:tt; + )* + } + ) => {}; +} + +/// Implement `Pod` and `Zeroable` for the internal bitflags type. +#[macro_export] +#[doc(hidden)] +#[cfg(feature = "bytemuck")] +macro_rules! __impl_external_bitflags_bytemuck { + ( + $InternalBitFlags:ident: $T:ty, $PublicBitFlags:ident { + $( + $(#[$inner:ident $($args:tt)*])* + const $Flag:tt; + )* + } + ) => { + // SAFETY: $InternalBitFlags is guaranteed to have the same ABI as $T, + // and $T implements Pod + unsafe impl $crate::__private::bytemuck::Pod for $InternalBitFlags where + $T: $crate::__private::bytemuck::Pod + { + } + + // SAFETY: $InternalBitFlags is guaranteed to have the same ABI as $T, + // and $T implements Zeroable + unsafe impl $crate::__private::bytemuck::Zeroable for $InternalBitFlags where + $T: $crate::__private::bytemuck::Zeroable + { + } + }; +} + +#[macro_export] +#[doc(hidden)] +#[cfg(not(feature = "bytemuck"))] +macro_rules! __impl_external_bitflags_bytemuck { + ( + $InternalBitFlags:ident: $T:ty, $PublicBitFlags:ident { + $( + $(#[$inner:ident $($args:tt)*])* + const $Flag:tt; + )* + } + ) => {}; +} diff --git a/vendor/bitflags/src/external/arbitrary.rs b/vendor/bitflags/src/external/arbitrary.rs new file mode 100644 index 0000000..ea76f0a --- /dev/null +++ b/vendor/bitflags/src/external/arbitrary.rs @@ -0,0 +1,33 @@ +//! Specialized fuzzing for flags types using `arbitrary`. + +use crate::Flags; + +/** +Generate some arbitrary flags value with only known bits set. +*/ +pub fn arbitrary<'a, B: Flags>(u: &mut arbitrary::Unstructured<'a>) -> arbitrary::Result +where + B::Bits: arbitrary::Arbitrary<'a>, +{ + B::from_bits(u.arbitrary()?).ok_or_else(|| arbitrary::Error::IncorrectFormat) +} + +#[cfg(test)] +mod tests { + use arbitrary::Arbitrary; + + bitflags! { + #[derive(Arbitrary)] + struct Color: u32 { + const RED = 0x1; + const GREEN = 0x2; + const BLUE = 0x4; + } + } + + #[test] + fn test_arbitrary() { + let mut unstructured = arbitrary::Unstructured::new(&[0_u8; 256]); + let _color = Color::arbitrary(&mut unstructured); + } +} diff --git a/vendor/bitflags/src/external/bytemuck.rs b/vendor/bitflags/src/external/bytemuck.rs new file mode 100644 index 0000000..a0cd68c --- /dev/null +++ b/vendor/bitflags/src/external/bytemuck.rs @@ -0,0 +1,19 @@ +#[cfg(test)] +mod tests { + use bytemuck::{Pod, Zeroable}; + + bitflags! { + #[derive(Pod, Zeroable, Clone, Copy)] + #[repr(transparent)] + struct Color: u32 { + const RED = 0x1; + const GREEN = 0x2; + const BLUE = 0x4; + } + } + + #[test] + fn test_bytemuck() { + assert_eq!(0x1, bytemuck::cast::(Color::RED)); + } +} diff --git a/vendor/bitflags/src/external/serde.rs b/vendor/bitflags/src/external/serde.rs new file mode 100644 index 0000000..be4f2ed --- /dev/null +++ b/vendor/bitflags/src/external/serde.rs @@ -0,0 +1,93 @@ +//! Specialized serialization for flags types using `serde`. + +use crate::{ + parser::{self, ParseHex, WriteHex}, + Flags, +}; +use core::{fmt, str}; +use serde::{ + de::{Error, Visitor}, + Deserialize, Deserializer, Serialize, Serializer, +}; + +/** +Serialize a set of flags as a human-readable string or their underlying bits. + +Any unknown bits will be retained. +*/ +pub fn serialize(flags: &B, serializer: S) -> Result +where + B::Bits: WriteHex + Serialize, +{ + // Serialize human-readable flags as a string like `"A | B"` + if serializer.is_human_readable() { + serializer.collect_str(&parser::AsDisplay(flags)) + } + // Serialize non-human-readable flags directly as the underlying bits + else { + flags.bits().serialize(serializer) + } +} + +/** +Deserialize a set of flags from a human-readable string or their underlying bits. + +Any unknown bits will be retained. +*/ +pub fn deserialize<'de, B: Flags, D: Deserializer<'de>>(deserializer: D) -> Result +where + B::Bits: ParseHex + Deserialize<'de>, +{ + if deserializer.is_human_readable() { + // Deserialize human-readable flags by parsing them from strings like `"A | B"` + struct FlagsVisitor(core::marker::PhantomData); + + impl<'de, B: Flags> Visitor<'de> for FlagsVisitor + where + B::Bits: ParseHex, + { + type Value = B; + + fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { + formatter.write_str("a string value of `|` separated flags") + } + + fn visit_str(self, flags: &str) -> Result { + parser::from_str(flags).map_err(|e| E::custom(e)) + } + } + + deserializer.deserialize_str(FlagsVisitor(Default::default())) + } else { + // Deserialize non-human-readable flags directly from the underlying bits + let bits = B::Bits::deserialize(deserializer)?; + + Ok(B::from_bits_retain(bits)) + } +} + +#[cfg(test)] +mod tests { + use serde_test::{assert_tokens, Configure, Token::*}; + bitflags! { + #[derive(serde_derive::Serialize, serde_derive::Deserialize, Debug, PartialEq, Eq)] + #[serde(transparent)] + struct SerdeFlags: u32 { + const A = 1; + const B = 2; + const C = 4; + const D = 8; + } + } + + #[test] + fn test_serde_bitflags_default() { + assert_tokens(&SerdeFlags::empty().readable(), &[Str("")]); + + assert_tokens(&SerdeFlags::empty().compact(), &[U32(0)]); + + assert_tokens(&(SerdeFlags::A | SerdeFlags::B).readable(), &[Str("A | B")]); + + assert_tokens(&(SerdeFlags::A | SerdeFlags::B).compact(), &[U32(1 | 2)]); + } +} diff --git a/vendor/bitflags/src/internal.rs b/vendor/bitflags/src/internal.rs new file mode 100644 index 0000000..87d01cc --- /dev/null +++ b/vendor/bitflags/src/internal.rs @@ -0,0 +1,125 @@ +//! Generate the internal `bitflags`-facing flags type. +//! +//! The code generated here is owned by `bitflags`, but still part of its public API. +//! Changes to the types generated here need to be considered like any other public API change. + +/// Declare the `bitflags`-facing bitflags struct. +/// +/// This type is part of the `bitflags` crate's public API, but not part of the user's. +#[macro_export] +#[doc(hidden)] +macro_rules! __declare_internal_bitflags { + ( + $vis:vis struct $InternalBitFlags:ident: $T:ty + ) => { + // NOTE: The ABI of this type is _guaranteed_ to be the same as `T` + // This is relied on by some external libraries like `bytemuck` to make + // its `unsafe` trait impls sound. + #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] + #[repr(transparent)] + $vis struct $InternalBitFlags($T); + }; +} + +/// Implement functions on the private (bitflags-facing) bitflags type. +/// +/// Methods and trait implementations can be freely added here without breaking end-users. +/// If we want to expose new functionality to `#[derive]`, this is the place to do it. +#[macro_export] +#[doc(hidden)] +macro_rules! __impl_internal_bitflags { + ( + $InternalBitFlags:ident: $T:ty, $PublicBitFlags:ident { + $( + $(#[$inner:ident $($args:tt)*])* + const $Flag:tt = $value:expr; + )* + } + ) => { + // NOTE: This impl is also used to prevent using bits types from non-primitive types + // in the `bitflags` macro. If this approach is changed, this guard will need to be + // retained somehow + impl $crate::__private::PublicFlags for $PublicBitFlags { + type Primitive = $T; + type Internal = $InternalBitFlags; + } + + impl $crate::__private::core::default::Default for $InternalBitFlags { + #[inline] + fn default() -> Self { + $InternalBitFlags::empty() + } + } + + impl $crate::__private::core::fmt::Debug for $InternalBitFlags { + fn fmt(&self, f: &mut $crate::__private::core::fmt::Formatter<'_>) -> $crate::__private::core::fmt::Result { + if self.is_empty() { + // If no flags are set then write an empty hex flag to avoid + // writing an empty string. In some contexts, like serialization, + // an empty string is preferable, but it may be unexpected in + // others for a format not to produce any output. + // + // We can remove this `0x0` and remain compatible with `FromStr`, + // because an empty string will still parse to an empty set of flags, + // just like `0x0` does. + $crate::__private::core::write!(f, "{:#x}", <$T as $crate::Bits>::EMPTY) + } else { + $crate::__private::core::fmt::Display::fmt(self, f) + } + } + } + + impl $crate::__private::core::fmt::Display for $InternalBitFlags { + fn fmt(&self, f: &mut $crate::__private::core::fmt::Formatter<'_>) -> $crate::__private::core::fmt::Result { + $crate::parser::to_writer(&$PublicBitFlags(*self), f) + } + } + + impl $crate::__private::core::str::FromStr for $InternalBitFlags { + type Err = $crate::parser::ParseError; + + fn from_str(s: &str) -> $crate::__private::core::result::Result { + $crate::parser::from_str::<$PublicBitFlags>(s).map(|flags| flags.0) + } + } + + impl $crate::__private::core::convert::AsRef<$T> for $InternalBitFlags { + fn as_ref(&self) -> &$T { + &self.0 + } + } + + impl $crate::__private::core::convert::From<$T> for $InternalBitFlags { + fn from(bits: $T) -> Self { + Self::from_bits_retain(bits) + } + } + + // The internal flags type offers a similar API to the public one + + $crate::__impl_public_bitflags! { + $InternalBitFlags: $T, $PublicBitFlags { + $( + $(#[$inner $($args)*])* + const $Flag = $value; + )* + } + } + + $crate::__impl_public_bitflags_ops! { + $InternalBitFlags + } + + $crate::__impl_public_bitflags_iter! { + $InternalBitFlags: $T, $PublicBitFlags + } + + impl $InternalBitFlags { + /// Returns a mutable reference to the raw value of the flags currently stored. + #[inline] + pub fn bits_mut(&mut self) -> &mut $T { + &mut self.0 + } + } + }; +} diff --git a/vendor/bitflags/src/iter.rs b/vendor/bitflags/src/iter.rs new file mode 100644 index 0000000..7f7ce55 --- /dev/null +++ b/vendor/bitflags/src/iter.rs @@ -0,0 +1,145 @@ +/*! +Yield the bits of a source flags value in a set of contained flags values. +*/ + +use crate::{Flag, Flags}; + +/** +An iterator over flags values. + +This iterator will yield flags values for contained, defined flags first, with any remaining bits yielded +as a final flags value. +*/ +pub struct Iter { + inner: IterNames, + done: bool, +} + +impl Iter { + pub(crate) fn new(flags: &B) -> Self { + Iter { + inner: IterNames::new(flags), + done: false, + } + } +} + +impl Iter { + // Used by the `bitflags` macro + #[doc(hidden)] + pub const fn __private_const_new(flags: &'static [Flag], source: B, remaining: B) -> Self { + Iter { + inner: IterNames::__private_const_new(flags, source, remaining), + done: false, + } + } +} + +impl Iterator for Iter { + type Item = B; + + fn next(&mut self) -> Option { + match self.inner.next() { + Some((_, flag)) => Some(flag), + None if !self.done => { + self.done = true; + + // After iterating through valid names, if there are any bits left over + // then return one final value that includes them. This makes `into_iter` + // and `from_iter` roundtrip + if !self.inner.remaining().is_empty() { + Some(B::from_bits_retain(self.inner.remaining.bits())) + } else { + None + } + } + None => None, + } + } +} + +/** +An iterator over flags values. + +This iterator only yields flags values for contained, defined, named flags. Any remaining bits +won't be yielded, but can be found with the [`IterNames::remaining`] method. +*/ +pub struct IterNames { + flags: &'static [Flag], + idx: usize, + source: B, + remaining: B, +} + +impl IterNames { + pub(crate) fn new(flags: &B) -> Self { + IterNames { + flags: B::FLAGS, + idx: 0, + remaining: B::from_bits_retain(flags.bits()), + source: B::from_bits_retain(flags.bits()), + } + } +} + +impl IterNames { + // Used by the bitflags macro + #[doc(hidden)] + pub const fn __private_const_new(flags: &'static [Flag], source: B, remaining: B) -> Self { + IterNames { + flags, + idx: 0, + remaining, + source, + } + } + + /// Get a flags value of any remaining bits that haven't been yielded yet. + /// + /// Once the iterator has finished, this method can be used to + /// check whether or not there are any bits that didn't correspond + /// to a contained, defined, named flag remaining. + pub fn remaining(&self) -> &B { + &self.remaining + } +} + +impl Iterator for IterNames { + type Item = (&'static str, B); + + fn next(&mut self) -> Option { + while let Some(flag) = self.flags.get(self.idx) { + // Short-circuit if our state is empty + if self.remaining.is_empty() { + return None; + } + + self.idx += 1; + + // Skip unnamed flags + if flag.name().is_empty() { + continue; + } + + let bits = flag.value().bits(); + + // If the flag is set in the original source _and_ it has bits that haven't + // been covered by a previous flag yet then yield it. These conditions cover + // two cases for multi-bit flags: + // + // 1. When flags partially overlap, such as `0b00000001` and `0b00000101`, we'll + // yield both flags. + // 2. When flags fully overlap, such as in convenience flags that are a shorthand for others, + // we won't yield both flags. + if self.source.contains(B::from_bits_retain(bits)) + && self.remaining.intersects(B::from_bits_retain(bits)) + { + self.remaining.remove(B::from_bits_retain(bits)); + + return Some((flag.name(), B::from_bits_retain(bits))); + } + } + + None + } +} diff --git a/vendor/bitflags/src/lib.rs b/vendor/bitflags/src/lib.rs new file mode 100644 index 0000000..a9a6aa4 --- /dev/null +++ b/vendor/bitflags/src/lib.rs @@ -0,0 +1,927 @@ +// Copyright 2014 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. + +/*! +Generate types for C-style flags with ergonomic APIs. + +# Getting started + +Add `bitflags` to your `Cargo.toml`: + +```toml +[dependencies.bitflags] +version = "2.6.0" +``` + +## Generating flags types + +Use the [`bitflags`] macro to generate flags types: + +```rust +use bitflags::bitflags; + +bitflags! { + pub struct Flags: u32 { + const A = 0b00000001; + const B = 0b00000010; + const C = 0b00000100; + } +} +``` + +See the docs for the `bitflags` macro for the full syntax. + +Also see the [`example_generated`](./example_generated/index.html) module for an example of what the `bitflags` macro generates for a flags type. + +### Externally defined flags + +If you're generating flags types for an external source, such as a C API, you can define +an extra unnamed flag as a mask of all bits the external source may ever set. Usually this would be all bits (`!0`): + +```rust +# use bitflags::bitflags; +bitflags! { + pub struct Flags: u32 { + const A = 0b00000001; + const B = 0b00000010; + const C = 0b00000100; + + // The source may set any bits + const _ = !0; + } +} +``` + +Why should you do this? Generated methods like `all` and truncating operators like `!` only consider +bits in defined flags. Adding an unnamed flag makes those methods consider additional bits, +without generating additional constants for them. It helps compatibility when the external source +may start setting additional bits at any time. The [known and unknown bits](#known-and-unknown-bits) +section has more details on this behavior. + +### Custom derives + +You can derive some traits on generated flags types if you enable Cargo features. The following +libraries are currently supported: + +- `serde`: Support `#[derive(Serialize, Deserialize)]`, using text for human-readable formats, +and a raw number for binary formats. +- `arbitrary`: Support `#[derive(Arbitrary)]`, only generating flags values with known bits. +- `bytemuck`: Support `#[derive(Pod, Zeroable)]`, for casting between flags values and their +underlying bits values. + +You can also define your own flags type outside of the [`bitflags`] macro and then use it to generate methods. +This can be useful if you need a custom `#[derive]` attribute for a library that `bitflags` doesn't +natively support: + +```rust +# use std::fmt::Debug as SomeTrait; +# use bitflags::bitflags; +#[derive(SomeTrait)] +pub struct Flags(u32); + +bitflags! { + impl Flags: u32 { + const A = 0b00000001; + const B = 0b00000010; + const C = 0b00000100; + } +} +``` + +### Adding custom methods + +The [`bitflags`] macro supports attributes on generated flags types within the macro itself, while +`impl` blocks can be added outside of it: + +```rust +# use bitflags::bitflags; +bitflags! { + // Attributes can be applied to flags types + #[repr(transparent)] + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + pub struct Flags: u32 { + const A = 0b00000001; + const B = 0b00000010; + const C = 0b00000100; + } +} + +// Impl blocks can be added to flags types +impl Flags { + pub fn as_u64(&self) -> u64 { + self.bits() as u64 + } +} +``` + +## Working with flags values + +Use generated constants and standard bitwise operators to interact with flags values: + +```rust +# use bitflags::bitflags; +# bitflags! { +# #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] +# pub struct Flags: u32 { +# const A = 0b00000001; +# const B = 0b00000010; +# const C = 0b00000100; +# } +# } +// union +let ab = Flags::A | Flags::B; + +// intersection +let a = ab & Flags::A; + +// difference +let b = ab - Flags::A; + +// complement +let c = !ab; +``` + +See the docs for the [`Flags`] trait for more details on operators and how they behave. + +# Formatting and parsing + +`bitflags` defines a text format that can be used to convert any flags value to and from strings. + +See the [`parser`] module for more details. + +# Specification + +The terminology and behavior of generated flags types is +[specified in the source repository](https://github.com/bitflags/bitflags/blob/main/spec.md). +Details are repeated in these docs where appropriate, but is exhaustively listed in the spec. Some +things are worth calling out explicitly here. + +## Flags types, flags values, flags + +The spec and these docs use consistent terminology to refer to things in the bitflags domain: + +- **Bits type**: A type that defines a fixed number of bits at specific locations. +- **Flag**: A set of bits in a bits type that may have a unique name. +- **Flags type**: A set of defined flags over a specific bits type. +- **Flags value**: An instance of a flags type using its specific bits value for storage. + +``` +# use bitflags::bitflags; +bitflags! { + struct FlagsType: u8 { +// -- Bits type +// --------- Flags type + const A = 1; +// ----- Flag + } +} + +let flag = FlagsType::A; +// ---- Flags value +``` + +## Known and unknown bits + +Any bits in a flag you define are called _known bits_. Any other bits are _unknown bits_. +In the following flags type: + +``` +# use bitflags::bitflags; +bitflags! { + struct Flags: u8 { + const A = 1; + const B = 1 << 1; + const C = 1 << 2; + } +} +``` + +The known bits are `0b0000_0111` and the unknown bits are `0b1111_1000`. + +`bitflags` doesn't guarantee that a flags value will only ever have known bits set, but some operators +will unset any unknown bits they encounter. In a future version of `bitflags`, all operators will +unset unknown bits. + +If you're using `bitflags` for flags types defined externally, such as from C, you probably want all +bits to be considered known, in case that external source changes. You can do this using an unnamed +flag, as described in [externally defined flags](#externally-defined-flags). + +## Zero-bit flags + +Flags with no bits set should be avoided because they interact strangely with [`Flags::contains`] +and [`Flags::intersects`]. A zero-bit flag is always contained, but is never intersected. The +names of zero-bit flags can be parsed, but are never formatted. + +## Multi-bit flags + +Flags that set multiple bits should be avoided unless each bit is also in a single-bit flag. +Take the following flags type as an example: + +``` +# use bitflags::bitflags; +bitflags! { + struct Flags: u8 { + const A = 1; + const B = 1 | 1 << 1; + } +} +``` + +The result of `Flags::A ^ Flags::B` is `0b0000_0010`, which doesn't correspond to either +`Flags::A` or `Flags::B` even though it's still a known bit. +*/ + +#![cfg_attr(not(any(feature = "std", test)), no_std)] +#![cfg_attr(not(test), forbid(unsafe_code))] +#![cfg_attr(test, allow(mixed_script_confusables))] + +#[doc(inline)] +pub use traits::{Bits, Flag, Flags}; + +pub mod iter; +pub mod parser; + +mod traits; + +#[doc(hidden)] +pub mod __private { + #[allow(unused_imports)] + // Easier than conditionally checking any optional external dependencies + pub use crate::{external::__private::*, traits::__private::*}; + + pub use core; +} + +#[allow(unused_imports)] +pub use external::*; + +#[allow(deprecated)] +pub use traits::BitFlags; + +/* +How does the bitflags crate work? + +This library generates a `struct` in the end-user's crate with a bunch of constants on it that represent flags. +The difference between `bitflags` and a lot of other libraries is that we don't actually control the generated `struct` in the end. +It's part of the end-user's crate, so it belongs to them. That makes it difficult to extend `bitflags` with new functionality +because we could end up breaking valid code that was already written. + +Our solution is to split the type we generate into two: the public struct owned by the end-user, and an internal struct owned by `bitflags` (us). +To give you an example, let's say we had a crate that called `bitflags!`: + +```rust +bitflags! { + pub struct MyFlags: u32 { + const A = 1; + const B = 2; + } +} +``` + +What they'd end up with looks something like this: + +```rust +pub struct MyFlags(::InternalBitFlags); + +const _: () = { + #[repr(transparent)] + #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] + pub struct MyInternalBitFlags { + bits: u32, + } + + impl PublicFlags for MyFlags { + type Internal = InternalBitFlags; + } +}; +``` + +If we want to expose something like a new trait impl for generated flags types, we add it to our generated `MyInternalBitFlags`, +and let `#[derive]` on `MyFlags` pick up that implementation, if an end-user chooses to add one. + +The public API is generated in the `__impl_public_flags!` macro, and the internal API is generated in +the `__impl_internal_flags!` macro. + +The macros are split into 3 modules: + +- `public`: where the user-facing flags types are generated. +- `internal`: where the `bitflags`-facing flags types are generated. +- `external`: where external library traits are implemented conditionally. +*/ + +/** +Generate a flags type. + +# `struct` mode + +A declaration that begins with `$vis struct` will generate a `struct` for a flags type, along with +methods and trait implementations for it. The body of the declaration defines flags as constants, +where each constant is a flags value of the generated flags type. + +## Examples + +Generate a flags type using `u8` as the bits type: + +``` +# use bitflags::bitflags; +bitflags! { + struct Flags: u8 { + const A = 1; + const B = 1 << 1; + const C = 0b0000_0100; + } +} +``` + +Flags types are private by default and accept standard visibility modifiers. Flags themselves +are always public: + +``` +# use bitflags::bitflags; +bitflags! { + pub struct Flags: u8 { + // Constants are always `pub` + const A = 1; + } +} +``` + +Flags may refer to other flags using their [`Flags::bits`] value: + +``` +# use bitflags::bitflags; +bitflags! { + struct Flags: u8 { + const A = 1; + const B = 1 << 1; + const AB = Flags::A.bits() | Flags::B.bits(); + } +} +``` + +A single `bitflags` invocation may include zero or more flags type declarations: + +``` +# use bitflags::bitflags; +bitflags! {} + +bitflags! { + struct Flags1: u8 { + const A = 1; + } + + struct Flags2: u8 { + const A = 1; + } +} +``` + +# `impl` mode + +A declaration that begins with `impl` will only generate methods and trait implementations for the +`struct` defined outside of the `bitflags` macro. + +The struct itself must be a newtype using the bits type as its field. + +The syntax for `impl` mode is identical to `struct` mode besides the starting token. + +## Examples + +Implement flags methods and traits for a custom flags type using `u8` as its underlying bits type: + +``` +# use bitflags::bitflags; +struct Flags(u8); + +bitflags! { + impl Flags: u8 { + const A = 1; + const B = 1 << 1; + const C = 0b0000_0100; + } +} +``` + +# Named and unnamed flags + +Constants in the body of a declaration are flags. The identifier of the constant is the name of +the flag. If the identifier is `_`, then the flag is unnamed. Unnamed flags don't appear in the +generated API, but affect how bits are truncated. + +## Examples + +Adding an unnamed flag that makes all bits known: + +``` +# use bitflags::bitflags; +bitflags! { + struct Flags: u8 { + const A = 1; + const B = 1 << 1; + + const _ = !0; + } +} +``` + +Flags types may define multiple unnamed flags: + +``` +# use bitflags::bitflags; +bitflags! { + struct Flags: u8 { + const _ = 1; + const _ = 1 << 1; + } +} +``` +*/ +#[macro_export] +macro_rules! bitflags { + ( + $(#[$outer:meta])* + $vis:vis struct $BitFlags:ident: $T:ty { + $( + $(#[$inner:ident $($args:tt)*])* + const $Flag:tt = $value:expr; + )* + } + + $($t:tt)* + ) => { + // Declared in the scope of the `bitflags!` call + // This type appears in the end-user's API + $crate::__declare_public_bitflags! { + $(#[$outer])* + $vis struct $BitFlags + } + + // Workaround for: https://github.com/bitflags/bitflags/issues/320 + $crate::__impl_public_bitflags_consts! { + $BitFlags: $T { + $( + $(#[$inner $($args)*])* + const $Flag = $value; + )* + } + } + + #[allow( + dead_code, + deprecated, + unused_doc_comments, + unused_attributes, + unused_mut, + unused_imports, + non_upper_case_globals, + clippy::assign_op_pattern, + clippy::indexing_slicing, + clippy::same_name_method, + clippy::iter_without_into_iter, + )] + const _: () = { + // Declared in a "hidden" scope that can't be reached directly + // These types don't appear in the end-user's API + $crate::__declare_internal_bitflags! { + $vis struct InternalBitFlags: $T + } + + $crate::__impl_internal_bitflags! { + InternalBitFlags: $T, $BitFlags { + $( + $(#[$inner $($args)*])* + const $Flag = $value; + )* + } + } + + // This is where new library trait implementations can be added + $crate::__impl_external_bitflags! { + InternalBitFlags: $T, $BitFlags { + $( + $(#[$inner $($args)*])* + const $Flag; + )* + } + } + + $crate::__impl_public_bitflags_forward! { + $BitFlags: $T, InternalBitFlags + } + + $crate::__impl_public_bitflags_ops! { + $BitFlags + } + + $crate::__impl_public_bitflags_iter! { + $BitFlags: $T, $BitFlags + } + }; + + $crate::bitflags! { + $($t)* + } + }; + ( + $(#[$outer:meta])* + impl $BitFlags:ident: $T:ty { + $( + $(#[$inner:ident $($args:tt)*])* + const $Flag:tt = $value:expr; + )* + } + + $($t:tt)* + ) => { + $crate::__impl_public_bitflags_consts! { + $BitFlags: $T { + $( + $(#[$inner $($args)*])* + const $Flag = $value; + )* + } + } + + #[allow( + dead_code, + deprecated, + unused_doc_comments, + unused_attributes, + unused_mut, + unused_imports, + non_upper_case_globals, + clippy::assign_op_pattern, + clippy::iter_without_into_iter, + )] + const _: () = { + $crate::__impl_public_bitflags! { + $(#[$outer])* + $BitFlags: $T, $BitFlags { + $( + $(#[$inner $($args)*])* + const $Flag = $value; + )* + } + } + + $crate::__impl_public_bitflags_ops! { + $BitFlags + } + + $crate::__impl_public_bitflags_iter! { + $BitFlags: $T, $BitFlags + } + }; + + $crate::bitflags! { + $($t)* + } + }; + () => {}; +} + +/// Implement functions on bitflags types. +/// +/// We need to be careful about adding new methods and trait implementations here because they +/// could conflict with items added by the end-user. +#[macro_export] +#[doc(hidden)] +macro_rules! __impl_bitflags { + ( + $(#[$outer:meta])* + $PublicBitFlags:ident: $T:ty { + fn empty() $empty:block + fn all() $all:block + fn bits($bits0:ident) $bits:block + fn from_bits($from_bits0:ident) $from_bits:block + fn from_bits_truncate($from_bits_truncate0:ident) $from_bits_truncate:block + fn from_bits_retain($from_bits_retain0:ident) $from_bits_retain:block + fn from_name($from_name0:ident) $from_name:block + fn is_empty($is_empty0:ident) $is_empty:block + fn is_all($is_all0:ident) $is_all:block + fn intersects($intersects0:ident, $intersects1:ident) $intersects:block + fn contains($contains0:ident, $contains1:ident) $contains:block + fn insert($insert0:ident, $insert1:ident) $insert:block + fn remove($remove0:ident, $remove1:ident) $remove:block + fn toggle($toggle0:ident, $toggle1:ident) $toggle:block + fn set($set0:ident, $set1:ident, $set2:ident) $set:block + fn intersection($intersection0:ident, $intersection1:ident) $intersection:block + fn union($union0:ident, $union1:ident) $union:block + fn difference($difference0:ident, $difference1:ident) $difference:block + fn symmetric_difference($symmetric_difference0:ident, $symmetric_difference1:ident) $symmetric_difference:block + fn complement($complement0:ident) $complement:block + } + ) => { + #[allow(dead_code, deprecated, unused_attributes)] + $(#[$outer])* + impl $PublicBitFlags { + /// Get a flags value with all bits unset. + #[inline] + pub const fn empty() -> Self { + $empty + } + + /// Get a flags value with all known bits set. + #[inline] + pub const fn all() -> Self { + $all + } + + /// Get the underlying bits value. + /// + /// The returned value is exactly the bits set in this flags value. + #[inline] + pub const fn bits(&self) -> $T { + let $bits0 = self; + $bits + } + + /// Convert from a bits value. + /// + /// This method will return `None` if any unknown bits are set. + #[inline] + pub const fn from_bits(bits: $T) -> $crate::__private::core::option::Option { + let $from_bits0 = bits; + $from_bits + } + + /// Convert from a bits value, unsetting any unknown bits. + #[inline] + pub const fn from_bits_truncate(bits: $T) -> Self { + let $from_bits_truncate0 = bits; + $from_bits_truncate + } + + /// Convert from a bits value exactly. + #[inline] + pub const fn from_bits_retain(bits: $T) -> Self { + let $from_bits_retain0 = bits; + $from_bits_retain + } + + /// Get a flags value with the bits of a flag with the given name set. + /// + /// This method will return `None` if `name` is empty or doesn't + /// correspond to any named flag. + #[inline] + pub fn from_name(name: &str) -> $crate::__private::core::option::Option { + let $from_name0 = name; + $from_name + } + + /// Whether all bits in this flags value are unset. + #[inline] + pub const fn is_empty(&self) -> bool { + let $is_empty0 = self; + $is_empty + } + + /// Whether all known bits in this flags value are set. + #[inline] + pub const fn is_all(&self) -> bool { + let $is_all0 = self; + $is_all + } + + /// Whether any set bits in a source flags value are also set in a target flags value. + #[inline] + pub const fn intersects(&self, other: Self) -> bool { + let $intersects0 = self; + let $intersects1 = other; + $intersects + } + + /// Whether all set bits in a source flags value are also set in a target flags value. + #[inline] + pub const fn contains(&self, other: Self) -> bool { + let $contains0 = self; + let $contains1 = other; + $contains + } + + /// The bitwise or (`|`) of the bits in two flags values. + #[inline] + pub fn insert(&mut self, other: Self) { + let $insert0 = self; + let $insert1 = other; + $insert + } + + /// The intersection of a source flags value with the complement of a target flags value (`&!`). + /// + /// This method is not equivalent to `self & !other` when `other` has unknown bits set. + /// `remove` won't truncate `other`, but the `!` operator will. + #[inline] + pub fn remove(&mut self, other: Self) { + let $remove0 = self; + let $remove1 = other; + $remove + } + + /// The bitwise exclusive-or (`^`) of the bits in two flags values. + #[inline] + pub fn toggle(&mut self, other: Self) { + let $toggle0 = self; + let $toggle1 = other; + $toggle + } + + /// Call `insert` when `value` is `true` or `remove` when `value` is `false`. + #[inline] + pub fn set(&mut self, other: Self, value: bool) { + let $set0 = self; + let $set1 = other; + let $set2 = value; + $set + } + + /// The bitwise and (`&`) of the bits in two flags values. + #[inline] + #[must_use] + pub const fn intersection(self, other: Self) -> Self { + let $intersection0 = self; + let $intersection1 = other; + $intersection + } + + /// The bitwise or (`|`) of the bits in two flags values. + #[inline] + #[must_use] + pub const fn union(self, other: Self) -> Self { + let $union0 = self; + let $union1 = other; + $union + } + + /// The intersection of a source flags value with the complement of a target flags value (`&!`). + /// + /// This method is not equivalent to `self & !other` when `other` has unknown bits set. + /// `difference` won't truncate `other`, but the `!` operator will. + #[inline] + #[must_use] + pub const fn difference(self, other: Self) -> Self { + let $difference0 = self; + let $difference1 = other; + $difference + } + + /// The bitwise exclusive-or (`^`) of the bits in two flags values. + #[inline] + #[must_use] + pub const fn symmetric_difference(self, other: Self) -> Self { + let $symmetric_difference0 = self; + let $symmetric_difference1 = other; + $symmetric_difference + } + + /// The bitwise negation (`!`) of the bits in a flags value, truncating the result. + #[inline] + #[must_use] + pub const fn complement(self) -> Self { + let $complement0 = self; + $complement + } + } + }; +} + +/// A macro that processed the input to `bitflags!` and shuffles attributes around +/// based on whether or not they're "expression-safe". +/// +/// This macro is a token-tree muncher that works on 2 levels: +/// +/// For each attribute, we explicitly match on its identifier, like `cfg` to determine +/// whether or not it should be considered expression-safe. +/// +/// If you find yourself with an attribute that should be considered expression-safe +/// and isn't, it can be added here. +#[macro_export] +#[doc(hidden)] +macro_rules! __bitflags_expr_safe_attrs { + // Entrypoint: Move all flags and all attributes into `unprocessed` lists + // where they'll be munched one-at-a-time + ( + $(#[$inner:ident $($args:tt)*])* + { $e:expr } + ) => { + $crate::__bitflags_expr_safe_attrs! { + expr: { $e }, + attrs: { + // All attributes start here + unprocessed: [$(#[$inner $($args)*])*], + // Attributes that are safe on expressions go here + processed: [], + }, + } + }; + // Process the next attribute on the current flag + // `cfg`: The next flag should be propagated to expressions + // NOTE: You can copy this rules block and replace `cfg` with + // your attribute name that should be considered expression-safe + ( + expr: { $e:expr }, + attrs: { + unprocessed: [ + // cfg matched here + #[cfg $($args:tt)*] + $($attrs_rest:tt)* + ], + processed: [$($expr:tt)*], + }, + ) => { + $crate::__bitflags_expr_safe_attrs! { + expr: { $e }, + attrs: { + unprocessed: [ + $($attrs_rest)* + ], + processed: [ + $($expr)* + // cfg added here + #[cfg $($args)*] + ], + }, + } + }; + // Process the next attribute on the current flag + // `$other`: The next flag should not be propagated to expressions + ( + expr: { $e:expr }, + attrs: { + unprocessed: [ + // $other matched here + #[$other:ident $($args:tt)*] + $($attrs_rest:tt)* + ], + processed: [$($expr:tt)*], + }, + ) => { + $crate::__bitflags_expr_safe_attrs! { + expr: { $e }, + attrs: { + unprocessed: [ + $($attrs_rest)* + ], + processed: [ + // $other not added here + $($expr)* + ], + }, + } + }; + // Once all attributes on all flags are processed, generate the actual code + ( + expr: { $e:expr }, + attrs: { + unprocessed: [], + processed: [$(#[$expr:ident $($exprargs:tt)*])*], + }, + ) => { + $(#[$expr $($exprargs)*])* + { $e } + } +} + +/// Implement a flag, which may be a wildcard `_`. +#[macro_export] +#[doc(hidden)] +macro_rules! __bitflags_flag { + ( + { + name: _, + named: { $($named:tt)* }, + unnamed: { $($unnamed:tt)* }, + } + ) => { + $($unnamed)* + }; + ( + { + name: $Flag:ident, + named: { $($named:tt)* }, + unnamed: { $($unnamed:tt)* }, + } + ) => { + $($named)* + }; +} + +#[macro_use] +mod public; +#[macro_use] +mod internal; +#[macro_use] +mod external; + +#[cfg(feature = "example_generated")] +pub mod example_generated; + +#[cfg(test)] +mod tests; diff --git a/vendor/bitflags/src/parser.rs b/vendor/bitflags/src/parser.rs new file mode 100644 index 0000000..34b432d --- /dev/null +++ b/vendor/bitflags/src/parser.rs @@ -0,0 +1,332 @@ +/*! +Parsing flags from text. + +Format and parse a flags value as text using the following grammar: + +- _Flags:_ (_Whitespace_ _Flag_ _Whitespace_)`|`* +- _Flag:_ _Name_ | _Hex Number_ +- _Name:_ The name of any defined flag +- _Hex Number_: `0x`([0-9a-fA-F])* +- _Whitespace_: (\s)* + +As an example, this is how `Flags::A | Flags::B | 0x0c` can be represented as text: + +```text +A | B | 0x0c +``` + +Alternatively, it could be represented without whitespace: + +```text +A|B|0x0C +``` + +Note that identifiers are *case-sensitive*, so the following is *not equivalent*: + +```text +a|b|0x0C +``` +*/ + +#![allow(clippy::let_unit_value)] + +use core::fmt::{self, Write}; + +use crate::{Bits, Flags}; + +/** +Write a flags value as text. + +Any bits that aren't part of a contained flag will be formatted as a hex number. +*/ +pub fn to_writer(flags: &B, mut writer: impl Write) -> Result<(), fmt::Error> +where + B::Bits: WriteHex, +{ + // A formatter for bitflags that produces text output like: + // + // A | B | 0xf6 + // + // The names of set flags are written in a bar-separated-format, + // followed by a hex number of any remaining bits that are set + // but don't correspond to any flags. + + // Iterate over known flag values + let mut first = true; + let mut iter = flags.iter_names(); + for (name, _) in &mut iter { + if !first { + writer.write_str(" | ")?; + } + + first = false; + writer.write_str(name)?; + } + + // Append any extra bits that correspond to flags to the end of the format + let remaining = iter.remaining().bits(); + if remaining != B::Bits::EMPTY { + if !first { + writer.write_str(" | ")?; + } + + writer.write_str("0x")?; + remaining.write_hex(writer)?; + } + + fmt::Result::Ok(()) +} + +#[cfg(feature = "serde")] +pub(crate) struct AsDisplay<'a, B>(pub(crate) &'a B); + +#[cfg(feature = "serde")] +impl<'a, B: Flags> fmt::Display for AsDisplay<'a, B> +where + B::Bits: WriteHex, +{ + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + to_writer(self.0, f) + } +} + +/** +Parse a flags value from text. + +This function will fail on any names that don't correspond to defined flags. +Unknown bits will be retained. +*/ +pub fn from_str(input: &str) -> Result +where + B::Bits: ParseHex, +{ + let mut parsed_flags = B::empty(); + + // If the input is empty then return an empty set of flags + if input.trim().is_empty() { + return Ok(parsed_flags); + } + + for flag in input.split('|') { + let flag = flag.trim(); + + // If the flag is empty then we've got missing input + if flag.is_empty() { + return Err(ParseError::empty_flag()); + } + + // If the flag starts with `0x` then it's a hex number + // Parse it directly to the underlying bits type + let parsed_flag = if let Some(flag) = flag.strip_prefix("0x") { + let bits = + ::parse_hex(flag).map_err(|_| ParseError::invalid_hex_flag(flag))?; + + B::from_bits_retain(bits) + } + // Otherwise the flag is a name + // The generated flags type will determine whether + // or not it's a valid identifier + else { + B::from_name(flag).ok_or_else(|| ParseError::invalid_named_flag(flag))? + }; + + parsed_flags.insert(parsed_flag); + } + + Ok(parsed_flags) +} + +/** +Write a flags value as text, ignoring any unknown bits. +*/ +pub fn to_writer_truncate(flags: &B, writer: impl Write) -> Result<(), fmt::Error> +where + B::Bits: WriteHex, +{ + to_writer(&B::from_bits_truncate(flags.bits()), writer) +} + +/** +Parse a flags value from text. + +This function will fail on any names that don't correspond to defined flags. +Unknown bits will be ignored. +*/ +pub fn from_str_truncate(input: &str) -> Result +where + B::Bits: ParseHex, +{ + Ok(B::from_bits_truncate(from_str::(input)?.bits())) +} + +/** +Write only the contained, defined, named flags in a flags value as text. +*/ +pub fn to_writer_strict(flags: &B, mut writer: impl Write) -> Result<(), fmt::Error> { + // This is a simplified version of `to_writer` that ignores + // any bits not corresponding to a named flag + + let mut first = true; + let mut iter = flags.iter_names(); + for (name, _) in &mut iter { + if !first { + writer.write_str(" | ")?; + } + + first = false; + writer.write_str(name)?; + } + + fmt::Result::Ok(()) +} + +/** +Parse a flags value from text. + +This function will fail on any names that don't correspond to defined flags. +This function will fail to parse hex values. +*/ +pub fn from_str_strict(input: &str) -> Result { + // This is a simplified version of `from_str` that ignores + // any bits not corresponding to a named flag + + let mut parsed_flags = B::empty(); + + // If the input is empty then return an empty set of flags + if input.trim().is_empty() { + return Ok(parsed_flags); + } + + for flag in input.split('|') { + let flag = flag.trim(); + + // If the flag is empty then we've got missing input + if flag.is_empty() { + return Err(ParseError::empty_flag()); + } + + // If the flag starts with `0x` then it's a hex number + // These aren't supported in the strict parser + if flag.starts_with("0x") { + return Err(ParseError::invalid_hex_flag("unsupported hex flag value")); + } + + let parsed_flag = B::from_name(flag).ok_or_else(|| ParseError::invalid_named_flag(flag))?; + + parsed_flags.insert(parsed_flag); + } + + Ok(parsed_flags) +} + +/** +Encode a value as a hex string. + +Implementors of this trait should not write the `0x` prefix. +*/ +pub trait WriteHex { + /// Write the value as hex. + fn write_hex(&self, writer: W) -> fmt::Result; +} + +/** +Parse a value from a hex string. +*/ +pub trait ParseHex { + /// Parse the value from hex. + fn parse_hex(input: &str) -> Result + where + Self: Sized; +} + +/// An error encountered while parsing flags from text. +#[derive(Debug)] +pub struct ParseError(ParseErrorKind); + +#[derive(Debug)] +#[allow(clippy::enum_variant_names)] +enum ParseErrorKind { + EmptyFlag, + InvalidNamedFlag { + #[cfg(not(feature = "std"))] + got: (), + #[cfg(feature = "std")] + got: String, + }, + InvalidHexFlag { + #[cfg(not(feature = "std"))] + got: (), + #[cfg(feature = "std")] + got: String, + }, +} + +impl ParseError { + /// An invalid hex flag was encountered. + pub fn invalid_hex_flag(flag: impl fmt::Display) -> Self { + let _flag = flag; + + let got = { + #[cfg(feature = "std")] + { + _flag.to_string() + } + }; + + ParseError(ParseErrorKind::InvalidHexFlag { got }) + } + + /// A named flag that doesn't correspond to any on the flags type was encountered. + pub fn invalid_named_flag(flag: impl fmt::Display) -> Self { + let _flag = flag; + + let got = { + #[cfg(feature = "std")] + { + _flag.to_string() + } + }; + + ParseError(ParseErrorKind::InvalidNamedFlag { got }) + } + + /// A hex or named flag wasn't found between separators. + pub const fn empty_flag() -> Self { + ParseError(ParseErrorKind::EmptyFlag) + } +} + +impl fmt::Display for ParseError { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match &self.0 { + ParseErrorKind::InvalidNamedFlag { got } => { + let _got = got; + + write!(f, "unrecognized named flag")?; + + #[cfg(feature = "std")] + { + write!(f, " `{}`", _got)?; + } + } + ParseErrorKind::InvalidHexFlag { got } => { + let _got = got; + + write!(f, "invalid hex flag")?; + + #[cfg(feature = "std")] + { + write!(f, " `{}`", _got)?; + } + } + ParseErrorKind::EmptyFlag => { + write!(f, "encountered empty flag")?; + } + } + + Ok(()) + } +} + +#[cfg(feature = "std")] +impl std::error::Error for ParseError {} diff --git a/vendor/bitflags/src/public.rs b/vendor/bitflags/src/public.rs new file mode 100644 index 0000000..feecdd6 --- /dev/null +++ b/vendor/bitflags/src/public.rs @@ -0,0 +1,578 @@ +//! Generate the user-facing flags type. +//! +//! The code here belongs to the end-user, so new trait implementations and methods can't be +//! added without potentially breaking users. + +/// Declare the user-facing bitflags struct. +/// +/// This type is guaranteed to be a newtype with a `bitflags`-facing type as its single field. +#[macro_export] +#[doc(hidden)] +macro_rules! __declare_public_bitflags { + ( + $(#[$outer:meta])* + $vis:vis struct $PublicBitFlags:ident + ) => { + $(#[$outer])* + $vis struct $PublicBitFlags(<$PublicBitFlags as $crate::__private::PublicFlags>::Internal); + }; +} + +/// Implement functions on the public (user-facing) bitflags type. +/// +/// We need to be careful about adding new methods and trait implementations here because they +/// could conflict with items added by the end-user. +#[macro_export] +#[doc(hidden)] +macro_rules! __impl_public_bitflags_forward { + ( + $(#[$outer:meta])* + $PublicBitFlags:ident: $T:ty, $InternalBitFlags:ident + ) => { + $crate::__impl_bitflags! { + $(#[$outer])* + $PublicBitFlags: $T { + fn empty() { + Self($InternalBitFlags::empty()) + } + + fn all() { + Self($InternalBitFlags::all()) + } + + fn bits(f) { + f.0.bits() + } + + fn from_bits(bits) { + match $InternalBitFlags::from_bits(bits) { + $crate::__private::core::option::Option::Some(bits) => $crate::__private::core::option::Option::Some(Self(bits)), + $crate::__private::core::option::Option::None => $crate::__private::core::option::Option::None, + } + } + + fn from_bits_truncate(bits) { + Self($InternalBitFlags::from_bits_truncate(bits)) + } + + fn from_bits_retain(bits) { + Self($InternalBitFlags::from_bits_retain(bits)) + } + + fn from_name(name) { + match $InternalBitFlags::from_name(name) { + $crate::__private::core::option::Option::Some(bits) => $crate::__private::core::option::Option::Some(Self(bits)), + $crate::__private::core::option::Option::None => $crate::__private::core::option::Option::None, + } + } + + fn is_empty(f) { + f.0.is_empty() + } + + fn is_all(f) { + f.0.is_all() + } + + fn intersects(f, other) { + f.0.intersects(other.0) + } + + fn contains(f, other) { + f.0.contains(other.0) + } + + fn insert(f, other) { + f.0.insert(other.0) + } + + fn remove(f, other) { + f.0.remove(other.0) + } + + fn toggle(f, other) { + f.0.toggle(other.0) + } + + fn set(f, other, value) { + f.0.set(other.0, value) + } + + fn intersection(f, other) { + Self(f.0.intersection(other.0)) + } + + fn union(f, other) { + Self(f.0.union(other.0)) + } + + fn difference(f, other) { + Self(f.0.difference(other.0)) + } + + fn symmetric_difference(f, other) { + Self(f.0.symmetric_difference(other.0)) + } + + fn complement(f) { + Self(f.0.complement()) + } + } + } + }; +} + +/// Implement functions on the public (user-facing) bitflags type. +/// +/// We need to be careful about adding new methods and trait implementations here because they +/// could conflict with items added by the end-user. +#[macro_export] +#[doc(hidden)] +macro_rules! __impl_public_bitflags { + ( + $(#[$outer:meta])* + $BitFlags:ident: $T:ty, $PublicBitFlags:ident { + $( + $(#[$inner:ident $($args:tt)*])* + const $Flag:tt = $value:expr; + )* + } + ) => { + $crate::__impl_bitflags! { + $(#[$outer])* + $BitFlags: $T { + fn empty() { + Self(<$T as $crate::Bits>::EMPTY) + } + + fn all() { + let mut truncated = <$T as $crate::Bits>::EMPTY; + let mut i = 0; + + $( + $crate::__bitflags_expr_safe_attrs!( + $(#[$inner $($args)*])* + {{ + let flag = <$PublicBitFlags as $crate::Flags>::FLAGS[i].value().bits(); + + truncated = truncated | flag; + i += 1; + }} + ); + )* + + let _ = i; + Self::from_bits_retain(truncated) + } + + fn bits(f) { + f.0 + } + + fn from_bits(bits) { + let truncated = Self::from_bits_truncate(bits).0; + + if truncated == bits { + $crate::__private::core::option::Option::Some(Self(bits)) + } else { + $crate::__private::core::option::Option::None + } + } + + fn from_bits_truncate(bits) { + Self(bits & Self::all().bits()) + } + + fn from_bits_retain(bits) { + Self(bits) + } + + fn from_name(name) { + $( + $crate::__bitflags_flag!({ + name: $Flag, + named: { + $crate::__bitflags_expr_safe_attrs!( + $(#[$inner $($args)*])* + { + if name == $crate::__private::core::stringify!($Flag) { + return $crate::__private::core::option::Option::Some(Self($PublicBitFlags::$Flag.bits())); + } + } + ); + }, + unnamed: {}, + }); + )* + + let _ = name; + $crate::__private::core::option::Option::None + } + + fn is_empty(f) { + f.bits() == <$T as $crate::Bits>::EMPTY + } + + fn is_all(f) { + // NOTE: We check against `Self::all` here, not `Self::Bits::ALL` + // because the set of all flags may not use all bits + Self::all().bits() | f.bits() == f.bits() + } + + fn intersects(f, other) { + f.bits() & other.bits() != <$T as $crate::Bits>::EMPTY + } + + fn contains(f, other) { + f.bits() & other.bits() == other.bits() + } + + fn insert(f, other) { + *f = Self::from_bits_retain(f.bits()).union(other); + } + + fn remove(f, other) { + *f = Self::from_bits_retain(f.bits()).difference(other); + } + + fn toggle(f, other) { + *f = Self::from_bits_retain(f.bits()).symmetric_difference(other); + } + + fn set(f, other, value) { + if value { + f.insert(other); + } else { + f.remove(other); + } + } + + fn intersection(f, other) { + Self::from_bits_retain(f.bits() & other.bits()) + } + + fn union(f, other) { + Self::from_bits_retain(f.bits() | other.bits()) + } + + fn difference(f, other) { + Self::from_bits_retain(f.bits() & !other.bits()) + } + + fn symmetric_difference(f, other) { + Self::from_bits_retain(f.bits() ^ other.bits()) + } + + fn complement(f) { + Self::from_bits_truncate(!f.bits()) + } + } + } + }; +} + +/// Implement iterators on the public (user-facing) bitflags type. +#[macro_export] +#[doc(hidden)] +macro_rules! __impl_public_bitflags_iter { + ( + $(#[$outer:meta])* + $BitFlags:ident: $T:ty, $PublicBitFlags:ident + ) => { + $(#[$outer])* + impl $BitFlags { + /// Yield a set of contained flags values. + /// + /// Each yielded flags value will correspond to a defined named flag. Any unknown bits + /// will be yielded together as a final flags value. + #[inline] + pub const fn iter(&self) -> $crate::iter::Iter<$PublicBitFlags> { + $crate::iter::Iter::__private_const_new( + <$PublicBitFlags as $crate::Flags>::FLAGS, + $PublicBitFlags::from_bits_retain(self.bits()), + $PublicBitFlags::from_bits_retain(self.bits()), + ) + } + + /// Yield a set of contained named flags values. + /// + /// This method is like [`iter`](#method.iter), except only yields bits in contained named flags. + /// Any unknown bits, or bits not corresponding to a contained flag will not be yielded. + #[inline] + pub const fn iter_names(&self) -> $crate::iter::IterNames<$PublicBitFlags> { + $crate::iter::IterNames::__private_const_new( + <$PublicBitFlags as $crate::Flags>::FLAGS, + $PublicBitFlags::from_bits_retain(self.bits()), + $PublicBitFlags::from_bits_retain(self.bits()), + ) + } + } + + $(#[$outer:meta])* + impl $crate::__private::core::iter::IntoIterator for $BitFlags { + type Item = $PublicBitFlags; + type IntoIter = $crate::iter::Iter<$PublicBitFlags>; + + fn into_iter(self) -> Self::IntoIter { + self.iter() + } + } + }; +} + +/// Implement traits on the public (user-facing) bitflags type. +#[macro_export] +#[doc(hidden)] +macro_rules! __impl_public_bitflags_ops { + ( + $(#[$outer:meta])* + $PublicBitFlags:ident + ) => { + + $(#[$outer])* + impl $crate::__private::core::fmt::Binary for $PublicBitFlags { + fn fmt( + &self, + f: &mut $crate::__private::core::fmt::Formatter, + ) -> $crate::__private::core::fmt::Result { + let inner = self.0; + $crate::__private::core::fmt::Binary::fmt(&inner, f) + } + } + + $(#[$outer])* + impl $crate::__private::core::fmt::Octal for $PublicBitFlags { + fn fmt( + &self, + f: &mut $crate::__private::core::fmt::Formatter, + ) -> $crate::__private::core::fmt::Result { + let inner = self.0; + $crate::__private::core::fmt::Octal::fmt(&inner, f) + } + } + + $(#[$outer])* + impl $crate::__private::core::fmt::LowerHex for $PublicBitFlags { + fn fmt( + &self, + f: &mut $crate::__private::core::fmt::Formatter, + ) -> $crate::__private::core::fmt::Result { + let inner = self.0; + $crate::__private::core::fmt::LowerHex::fmt(&inner, f) + } + } + + $(#[$outer])* + impl $crate::__private::core::fmt::UpperHex for $PublicBitFlags { + fn fmt( + &self, + f: &mut $crate::__private::core::fmt::Formatter, + ) -> $crate::__private::core::fmt::Result { + let inner = self.0; + $crate::__private::core::fmt::UpperHex::fmt(&inner, f) + } + } + + $(#[$outer])* + impl $crate::__private::core::ops::BitOr for $PublicBitFlags { + type Output = Self; + + /// The bitwise or (`|`) of the bits in two flags values. + #[inline] + fn bitor(self, other: $PublicBitFlags) -> Self { + self.union(other) + } + } + + $(#[$outer])* + impl $crate::__private::core::ops::BitOrAssign for $PublicBitFlags { + /// The bitwise or (`|`) of the bits in two flags values. + #[inline] + fn bitor_assign(&mut self, other: Self) { + self.insert(other); + } + } + + $(#[$outer])* + impl $crate::__private::core::ops::BitXor for $PublicBitFlags { + type Output = Self; + + /// The bitwise exclusive-or (`^`) of the bits in two flags values. + #[inline] + fn bitxor(self, other: Self) -> Self { + self.symmetric_difference(other) + } + } + + $(#[$outer])* + impl $crate::__private::core::ops::BitXorAssign for $PublicBitFlags { + /// The bitwise exclusive-or (`^`) of the bits in two flags values. + #[inline] + fn bitxor_assign(&mut self, other: Self) { + self.toggle(other); + } + } + + $(#[$outer])* + impl $crate::__private::core::ops::BitAnd for $PublicBitFlags { + type Output = Self; + + /// The bitwise and (`&`) of the bits in two flags values. + #[inline] + fn bitand(self, other: Self) -> Self { + self.intersection(other) + } + } + + $(#[$outer])* + impl $crate::__private::core::ops::BitAndAssign for $PublicBitFlags { + /// The bitwise and (`&`) of the bits in two flags values. + #[inline] + fn bitand_assign(&mut self, other: Self) { + *self = Self::from_bits_retain(self.bits()).intersection(other); + } + } + + $(#[$outer])* + impl $crate::__private::core::ops::Sub for $PublicBitFlags { + type Output = Self; + + /// The intersection of a source flags value with the complement of a target flags value (`&!`). + /// + /// This method is not equivalent to `self & !other` when `other` has unknown bits set. + /// `difference` won't truncate `other`, but the `!` operator will. + #[inline] + fn sub(self, other: Self) -> Self { + self.difference(other) + } + } + + $(#[$outer])* + impl $crate::__private::core::ops::SubAssign for $PublicBitFlags { + /// The intersection of a source flags value with the complement of a target flags value (`&!`). + /// + /// This method is not equivalent to `self & !other` when `other` has unknown bits set. + /// `difference` won't truncate `other`, but the `!` operator will. + #[inline] + fn sub_assign(&mut self, other: Self) { + self.remove(other); + } + } + + $(#[$outer])* + impl $crate::__private::core::ops::Not for $PublicBitFlags { + type Output = Self; + + /// The bitwise negation (`!`) of the bits in a flags value, truncating the result. + #[inline] + fn not(self) -> Self { + self.complement() + } + } + + $(#[$outer])* + impl $crate::__private::core::iter::Extend<$PublicBitFlags> for $PublicBitFlags { + /// The bitwise or (`|`) of the bits in each flags value. + fn extend>( + &mut self, + iterator: T, + ) { + for item in iterator { + self.insert(item) + } + } + } + + $(#[$outer])* + impl $crate::__private::core::iter::FromIterator<$PublicBitFlags> for $PublicBitFlags { + /// The bitwise or (`|`) of the bits in each flags value. + fn from_iter>( + iterator: T, + ) -> Self { + use $crate::__private::core::iter::Extend; + + let mut result = Self::empty(); + result.extend(iterator); + result + } + } + }; +} + +/// Implement constants on the public (user-facing) bitflags type. +#[macro_export] +#[doc(hidden)] +macro_rules! __impl_public_bitflags_consts { + ( + $(#[$outer:meta])* + $PublicBitFlags:ident: $T:ty { + $( + $(#[$inner:ident $($args:tt)*])* + const $Flag:tt = $value:expr; + )* + } + ) => { + $(#[$outer])* + impl $PublicBitFlags { + $( + $crate::__bitflags_flag!({ + name: $Flag, + named: { + $(#[$inner $($args)*])* + #[allow( + deprecated, + non_upper_case_globals, + )] + pub const $Flag: Self = Self::from_bits_retain($value); + }, + unnamed: {}, + }); + )* + } + + $(#[$outer])* + impl $crate::Flags for $PublicBitFlags { + const FLAGS: &'static [$crate::Flag<$PublicBitFlags>] = &[ + $( + $crate::__bitflags_flag!({ + name: $Flag, + named: { + $crate::__bitflags_expr_safe_attrs!( + $(#[$inner $($args)*])* + { + #[allow( + deprecated, + non_upper_case_globals, + )] + $crate::Flag::new($crate::__private::core::stringify!($Flag), $PublicBitFlags::$Flag) + } + ) + }, + unnamed: { + $crate::__bitflags_expr_safe_attrs!( + $(#[$inner $($args)*])* + { + #[allow( + deprecated, + non_upper_case_globals, + )] + $crate::Flag::new("", $PublicBitFlags::from_bits_retain($value)) + } + ) + }, + }), + )* + ]; + + type Bits = $T; + + fn bits(&self) -> $T { + $PublicBitFlags::bits(self) + } + + fn from_bits_retain(bits: $T) -> $PublicBitFlags { + $PublicBitFlags::from_bits_retain(bits) + } + } + }; +} diff --git a/vendor/bitflags/src/tests.rs b/vendor/bitflags/src/tests.rs new file mode 100644 index 0000000..ed52ad4 --- /dev/null +++ b/vendor/bitflags/src/tests.rs @@ -0,0 +1,131 @@ +mod all; +mod bits; +mod complement; +mod contains; +mod difference; +mod empty; +mod eq; +mod extend; +mod flags; +mod fmt; +mod from_bits; +mod from_bits_retain; +mod from_bits_truncate; +mod from_name; +mod insert; +mod intersection; +mod intersects; +mod is_all; +mod is_empty; +mod iter; +mod parser; +mod remove; +mod symmetric_difference; +mod union; + +bitflags! { + #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Copy)] + pub struct TestFlags: u8 { + /// 1 + const A = 1; + + /// 1 << 1 + const B = 1 << 1; + + /// 1 << 2 + const C = 1 << 2; + + /// 1 | (1 << 1) | (1 << 2) + const ABC = Self::A.bits() | Self::B.bits() | Self::C.bits(); + } + + #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Copy)] + pub struct TestFlagsInvert: u8 { + /// 1 | (1 << 1) | (1 << 2) + const ABC = Self::A.bits() | Self::B.bits() | Self::C.bits(); + + /// 1 + const A = 1; + + /// 1 << 1 + const B = 1 << 1; + + /// 1 << 2 + const C = 1 << 2; + } + + #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Copy)] + pub struct TestZero: u8 { + /// 0 + const ZERO = 0; + } + + #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Copy)] + pub struct TestZeroOne: u8 { + /// 0 + const ZERO = 0; + + /// 1 + const ONE = 1; + } + + #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Copy)] + pub struct TestUnicode: u8 { + /// 1 + const 一 = 1; + + /// 2 + const 二 = 1 << 1; + } + + #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Copy)] + pub struct TestEmpty: u8 {} + + #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Copy)] + pub struct TestOverlapping: u8 { + /// 1 | (1 << 1) + const AB = 1 | (1 << 1); + + /// (1 << 1) | (1 << 2) + const BC = (1 << 1) | (1 << 2); + } + + #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Copy)] + pub struct TestOverlappingFull: u8 { + /// 1 + const A = 1; + + /// 1 + const B = 1; + + /// 1 + const C = 1; + + /// 2 + const D = 1 << 1; + } + + #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Copy)] + pub struct TestExternal: u8 { + /// 1 + const A = 1; + + /// 1 << 1 + const B = 1 << 1; + + /// 1 << 2 + const C = 1 << 2; + + /// 1 | (1 << 1) | (1 << 2) + const ABC = Self::A.bits() | Self::B.bits() | Self::C.bits(); + + /// External + const _ = !0; + } + + #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Copy)] + pub struct TestExternalFull: u8 { + /// External + const _ = !0; + } +} diff --git a/vendor/bitflags/src/tests/all.rs b/vendor/bitflags/src/tests/all.rs new file mode 100644 index 0000000..cceb93a --- /dev/null +++ b/vendor/bitflags/src/tests/all.rs @@ -0,0 +1,23 @@ +use super::*; + +use crate::Flags; + +#[test] +fn cases() { + case(1 | 1 << 1 | 1 << 2, TestFlags::all); + + case(0, TestZero::all); + + case(0, TestEmpty::all); + + case(!0, TestExternal::all); +} + +#[track_caller] +fn case(expected: T::Bits, inherent: impl FnOnce() -> T) +where + ::Bits: std::fmt::Debug + PartialEq, +{ + assert_eq!(expected, inherent().bits(), "T::all()"); + assert_eq!(expected, T::all().bits(), "Flags::all()"); +} diff --git a/vendor/bitflags/src/tests/bits.rs b/vendor/bitflags/src/tests/bits.rs new file mode 100644 index 0000000..678f153 --- /dev/null +++ b/vendor/bitflags/src/tests/bits.rs @@ -0,0 +1,36 @@ +use super::*; + +use crate::Flags; + +#[test] +fn cases() { + case(0, TestFlags::empty(), TestFlags::bits); + + case(1, TestFlags::A, TestFlags::bits); + case(1 | 1 << 1 | 1 << 2, TestFlags::ABC, TestFlags::bits); + + case(!0, TestFlags::from_bits_retain(u8::MAX), TestFlags::bits); + case(1 << 3, TestFlags::from_bits_retain(1 << 3), TestFlags::bits); + + case(1 << 3, TestZero::from_bits_retain(1 << 3), TestZero::bits); + + case(1 << 3, TestEmpty::from_bits_retain(1 << 3), TestEmpty::bits); + + case( + 1 << 4 | 1 << 6, + TestExternal::from_bits_retain(1 << 4 | 1 << 6), + TestExternal::bits, + ); +} + +#[track_caller] +fn case( + expected: T::Bits, + value: T, + inherent: impl FnOnce(&T) -> T::Bits, +) where + T::Bits: std::fmt::Debug + PartialEq, +{ + assert_eq!(expected, inherent(&value), "{:?}.bits()", value); + assert_eq!(expected, Flags::bits(&value), "Flags::bits({:?})", value); +} diff --git a/vendor/bitflags/src/tests/complement.rs b/vendor/bitflags/src/tests/complement.rs new file mode 100644 index 0000000..ac7a421 --- /dev/null +++ b/vendor/bitflags/src/tests/complement.rs @@ -0,0 +1,53 @@ +use super::*; + +use crate::Flags; + +#[test] +fn cases() { + case(0, TestFlags::all(), TestFlags::complement); + case(0, TestFlags::from_bits_retain(!0), TestFlags::complement); + + case(1 | 1 << 1, TestFlags::C, TestFlags::complement); + case( + 1 | 1 << 1, + TestFlags::C | TestFlags::from_bits_retain(1 << 3), + TestFlags::complement, + ); + + case( + 1 | 1 << 1 | 1 << 2, + TestFlags::empty(), + TestFlags::complement, + ); + case( + 1 | 1 << 1 | 1 << 2, + TestFlags::from_bits_retain(1 << 3), + TestFlags::complement, + ); + + case(0, TestZero::empty(), TestZero::complement); + + case(0, TestEmpty::empty(), TestEmpty::complement); + + case(1 << 2, TestOverlapping::AB, TestOverlapping::complement); + + case(!0, TestExternal::empty(), TestExternal::complement); +} + +#[track_caller] +fn case + Copy>( + expected: T::Bits, + value: T, + inherent: impl FnOnce(T) -> T, +) where + T::Bits: std::fmt::Debug + PartialEq, +{ + assert_eq!(expected, inherent(value).bits(), "{:?}.complement()", value); + assert_eq!( + expected, + Flags::complement(value).bits(), + "Flags::complement({:?})", + value + ); + assert_eq!(expected, (!value).bits(), "!{:?}", value); +} diff --git a/vendor/bitflags/src/tests/contains.rs b/vendor/bitflags/src/tests/contains.rs new file mode 100644 index 0000000..12428dd --- /dev/null +++ b/vendor/bitflags/src/tests/contains.rs @@ -0,0 +1,108 @@ +use super::*; + +use crate::Flags; + +#[test] +fn cases() { + case( + TestFlags::empty(), + &[ + (TestFlags::empty(), true), + (TestFlags::A, false), + (TestFlags::B, false), + (TestFlags::C, false), + (TestFlags::from_bits_retain(1 << 3), false), + ], + TestFlags::contains, + ); + + case( + TestFlags::A, + &[ + (TestFlags::empty(), true), + (TestFlags::A, true), + (TestFlags::B, false), + (TestFlags::C, false), + (TestFlags::ABC, false), + (TestFlags::from_bits_retain(1 << 3), false), + (TestFlags::from_bits_retain(1 | (1 << 3)), false), + ], + TestFlags::contains, + ); + + case( + TestFlags::ABC, + &[ + (TestFlags::empty(), true), + (TestFlags::A, true), + (TestFlags::B, true), + (TestFlags::C, true), + (TestFlags::ABC, true), + (TestFlags::from_bits_retain(1 << 3), false), + ], + TestFlags::contains, + ); + + case( + TestFlags::from_bits_retain(1 << 3), + &[ + (TestFlags::empty(), true), + (TestFlags::A, false), + (TestFlags::B, false), + (TestFlags::C, false), + (TestFlags::from_bits_retain(1 << 3), true), + ], + TestFlags::contains, + ); + + case( + TestZero::ZERO, + &[(TestZero::ZERO, true)], + TestZero::contains, + ); + + case( + TestOverlapping::AB, + &[ + (TestOverlapping::AB, true), + (TestOverlapping::BC, false), + (TestOverlapping::from_bits_retain(1 << 1), true), + ], + TestOverlapping::contains, + ); + + case( + TestExternal::all(), + &[ + (TestExternal::A, true), + (TestExternal::B, true), + (TestExternal::C, true), + (TestExternal::from_bits_retain(1 << 5 | 1 << 7), true), + ], + TestExternal::contains, + ); +} + +#[track_caller] +fn case( + value: T, + inputs: &[(T, bool)], + mut inherent: impl FnMut(&T, T) -> bool, +) { + for (input, expected) in inputs { + assert_eq!( + *expected, + inherent(&value, *input), + "{:?}.contains({:?})", + value, + input + ); + assert_eq!( + *expected, + Flags::contains(&value, *input), + "Flags::contains({:?}, {:?})", + value, + input + ); + } +} diff --git a/vendor/bitflags/src/tests/difference.rs b/vendor/bitflags/src/tests/difference.rs new file mode 100644 index 0000000..6ce9c0b --- /dev/null +++ b/vendor/bitflags/src/tests/difference.rs @@ -0,0 +1,92 @@ +use super::*; + +use crate::Flags; + +#[test] +fn cases() { + case( + TestFlags::A | TestFlags::B, + &[ + (TestFlags::A, 1 << 1), + (TestFlags::B, 1), + (TestFlags::from_bits_retain(1 << 3), 1 | 1 << 1), + ], + TestFlags::difference, + ); + + case( + TestFlags::from_bits_retain(1 | 1 << 3), + &[ + (TestFlags::A, 1 << 3), + (TestFlags::from_bits_retain(1 << 3), 1), + ], + TestFlags::difference, + ); + + case( + TestExternal::from_bits_retain(!0), + &[(TestExternal::A, 0b1111_1110)], + TestExternal::difference, + ); + + assert_eq!( + 0b1111_1110, + (TestExternal::from_bits_retain(!0) & !TestExternal::A).bits() + ); + + assert_eq!( + 0b1111_1110, + (TestFlags::from_bits_retain(!0).difference(TestFlags::A)).bits() + ); + + // The `!` operator unsets bits that don't correspond to known flags + assert_eq!( + 1 << 1 | 1 << 2, + (TestFlags::from_bits_retain(!0) & !TestFlags::A).bits() + ); +} + +#[track_caller] +fn case + std::ops::SubAssign + Copy>( + value: T, + inputs: &[(T, T::Bits)], + mut inherent: impl FnMut(T, T) -> T, +) where + T::Bits: std::fmt::Debug + PartialEq + Copy, +{ + for (input, expected) in inputs { + assert_eq!( + *expected, + inherent(value, *input).bits(), + "{:?}.difference({:?})", + value, + input + ); + assert_eq!( + *expected, + Flags::difference(value, *input).bits(), + "Flags::difference({:?}, {:?})", + value, + input + ); + assert_eq!( + *expected, + (value - *input).bits(), + "{:?} - {:?}", + value, + input + ); + assert_eq!( + *expected, + { + let mut value = value; + value -= *input; + value + } + .bits(), + "{:?} -= {:?}", + value, + input, + ); + } +} diff --git a/vendor/bitflags/src/tests/empty.rs b/vendor/bitflags/src/tests/empty.rs new file mode 100644 index 0000000..57fb1c7 --- /dev/null +++ b/vendor/bitflags/src/tests/empty.rs @@ -0,0 +1,23 @@ +use super::*; + +use crate::Flags; + +#[test] +fn cases() { + case(0, TestFlags::empty); + + case(0, TestZero::empty); + + case(0, TestEmpty::empty); + + case(0, TestExternal::empty); +} + +#[track_caller] +fn case(expected: T::Bits, inherent: impl FnOnce() -> T) +where + ::Bits: std::fmt::Debug + PartialEq, +{ + assert_eq!(expected, inherent().bits(), "T::empty()"); + assert_eq!(expected, T::empty().bits(), "Flags::empty()"); +} diff --git a/vendor/bitflags/src/tests/eq.rs b/vendor/bitflags/src/tests/eq.rs new file mode 100644 index 0000000..9779af7 --- /dev/null +++ b/vendor/bitflags/src/tests/eq.rs @@ -0,0 +1,10 @@ +use super::*; + +#[test] +fn cases() { + assert_eq!(TestFlags::empty(), TestFlags::empty()); + assert_eq!(TestFlags::all(), TestFlags::all()); + + assert!(TestFlags::from_bits_retain(1) < TestFlags::from_bits_retain(2)); + assert!(TestFlags::from_bits_retain(2) > TestFlags::from_bits_retain(1)); +} diff --git a/vendor/bitflags/src/tests/extend.rs b/vendor/bitflags/src/tests/extend.rs new file mode 100644 index 0000000..869dc17 --- /dev/null +++ b/vendor/bitflags/src/tests/extend.rs @@ -0,0 +1,42 @@ +use super::*; + +#[test] +fn cases() { + let mut flags = TestFlags::empty(); + + flags.extend(TestFlags::A); + + assert_eq!(TestFlags::A, flags); + + flags.extend(TestFlags::A | TestFlags::B | TestFlags::C); + + assert_eq!(TestFlags::ABC, flags); + + flags.extend(TestFlags::from_bits_retain(1 << 5)); + + assert_eq!(TestFlags::ABC | TestFlags::from_bits_retain(1 << 5), flags); +} + +mod external { + use super::*; + + #[test] + fn cases() { + let mut flags = TestExternal::empty(); + + flags.extend(TestExternal::A); + + assert_eq!(TestExternal::A, flags); + + flags.extend(TestExternal::A | TestExternal::B | TestExternal::C); + + assert_eq!(TestExternal::ABC, flags); + + flags.extend(TestExternal::from_bits_retain(1 << 5)); + + assert_eq!( + TestExternal::ABC | TestExternal::from_bits_retain(1 << 5), + flags + ); + } +} diff --git a/vendor/bitflags/src/tests/flags.rs b/vendor/bitflags/src/tests/flags.rs new file mode 100644 index 0000000..7a625b3 --- /dev/null +++ b/vendor/bitflags/src/tests/flags.rs @@ -0,0 +1,46 @@ +use super::*; + +use crate::Flags; + +#[test] +fn cases() { + let flags = TestFlags::FLAGS + .iter() + .map(|flag| (flag.name(), flag.value().bits())) + .collect::>(); + + assert_eq!( + vec![ + ("A", 1u8), + ("B", 1 << 1), + ("C", 1 << 2), + ("ABC", 1 | 1 << 1 | 1 << 2), + ], + flags, + ); + + assert_eq!(0, TestEmpty::FLAGS.iter().count()); +} + +mod external { + use super::*; + + #[test] + fn cases() { + let flags = TestExternal::FLAGS + .iter() + .map(|flag| (flag.name(), flag.value().bits())) + .collect::>(); + + assert_eq!( + vec![ + ("A", 1u8), + ("B", 1 << 1), + ("C", 1 << 2), + ("ABC", 1 | 1 << 1 | 1 << 2), + ("", !0), + ], + flags, + ); + } +} diff --git a/vendor/bitflags/src/tests/fmt.rs b/vendor/bitflags/src/tests/fmt.rs new file mode 100644 index 0000000..ed45718 --- /dev/null +++ b/vendor/bitflags/src/tests/fmt.rs @@ -0,0 +1,97 @@ +use super::*; + +#[test] +fn cases() { + case(TestFlags::empty(), "TestFlags(0x0)", "0", "0", "0", "0"); + case(TestFlags::A, "TestFlags(A)", "1", "1", "1", "1"); + case( + TestFlags::all(), + "TestFlags(A | B | C)", + "7", + "7", + "7", + "111", + ); + case( + TestFlags::from_bits_retain(1 << 3), + "TestFlags(0x8)", + "8", + "8", + "10", + "1000", + ); + case( + TestFlags::A | TestFlags::from_bits_retain(1 << 3), + "TestFlags(A | 0x8)", + "9", + "9", + "11", + "1001", + ); + + case(TestZero::ZERO, "TestZero(0x0)", "0", "0", "0", "0"); + case( + TestZero::ZERO | TestZero::from_bits_retain(1), + "TestZero(0x1)", + "1", + "1", + "1", + "1", + ); + + case(TestZeroOne::ONE, "TestZeroOne(ONE)", "1", "1", "1", "1"); + + case( + TestOverlapping::from_bits_retain(1 << 1), + "TestOverlapping(0x2)", + "2", + "2", + "2", + "10", + ); + + case( + TestExternal::from_bits_retain(1 | 1 << 1 | 1 << 3), + "TestExternal(A | B | 0x8)", + "B", + "b", + "13", + "1011", + ); + + case( + TestExternal::all(), + "TestExternal(A | B | C | 0xf8)", + "FF", + "ff", + "377", + "11111111", + ); + + case( + TestExternalFull::all(), + "TestExternalFull(0xff)", + "FF", + "ff", + "377", + "11111111", + ); +} + +#[track_caller] +fn case< + T: std::fmt::Debug + std::fmt::UpperHex + std::fmt::LowerHex + std::fmt::Octal + std::fmt::Binary, +>( + value: T, + debug: &str, + uhex: &str, + lhex: &str, + oct: &str, + bin: &str, +) { + assert_eq!(debug, format!("{:?}", value)); + assert_eq!(uhex, format!("{:X}", value)); + assert_eq!(lhex, format!("{:x}", value)); + assert_eq!(oct, format!("{:o}", value)); + assert_eq!(bin, format!("{:b}", value)); +} diff --git a/vendor/bitflags/src/tests/from_bits.rs b/vendor/bitflags/src/tests/from_bits.rs new file mode 100644 index 0000000..dada9af --- /dev/null +++ b/vendor/bitflags/src/tests/from_bits.rs @@ -0,0 +1,45 @@ +use super::*; + +use crate::Flags; + +#[test] +fn cases() { + case(Some(0), 0, TestFlags::from_bits); + case(Some(1), 1, TestFlags::from_bits); + case( + Some(1 | 1 << 1 | 1 << 2), + 1 | 1 << 1 | 1 << 2, + TestFlags::from_bits, + ); + + case(None, 1 << 3, TestFlags::from_bits); + case(None, 1 | 1 << 3, TestFlags::from_bits); + + case(Some(1 | 1 << 1), 1 | 1 << 1, TestOverlapping::from_bits); + + case(Some(1 << 1), 1 << 1, TestOverlapping::from_bits); + + case(Some(1 << 5), 1 << 5, TestExternal::from_bits); +} + +#[track_caller] +fn case( + expected: Option, + input: T::Bits, + inherent: impl FnOnce(T::Bits) -> Option, +) where + ::Bits: std::fmt::Debug + PartialEq, +{ + assert_eq!( + expected, + inherent(input).map(|f| f.bits()), + "T::from_bits({:?})", + input + ); + assert_eq!( + expected, + T::from_bits(input).map(|f| f.bits()), + "Flags::from_bits({:?})", + input + ); +} diff --git a/vendor/bitflags/src/tests/from_bits_retain.rs b/vendor/bitflags/src/tests/from_bits_retain.rs new file mode 100644 index 0000000..1ae28a6 --- /dev/null +++ b/vendor/bitflags/src/tests/from_bits_retain.rs @@ -0,0 +1,38 @@ +use super::*; + +use crate::Flags; + +#[test] +fn cases() { + case(0, TestFlags::from_bits_retain); + case(1, TestFlags::from_bits_retain); + case(1 | 1 << 1 | 1 << 2, TestFlags::from_bits_retain); + + case(1 << 3, TestFlags::from_bits_retain); + case(1 | 1 << 3, TestFlags::from_bits_retain); + + case(1 | 1 << 1, TestOverlapping::from_bits_retain); + + case(1 << 1, TestOverlapping::from_bits_retain); + + case(1 << 5, TestExternal::from_bits_retain); +} + +#[track_caller] +fn case(input: T::Bits, inherent: impl FnOnce(T::Bits) -> T) +where + ::Bits: std::fmt::Debug + PartialEq, +{ + assert_eq!( + input, + inherent(input).bits(), + "T::from_bits_retain({:?})", + input + ); + assert_eq!( + input, + T::from_bits_retain(input).bits(), + "Flags::from_bits_retain({:?})", + input + ); +} diff --git a/vendor/bitflags/src/tests/from_bits_truncate.rs b/vendor/bitflags/src/tests/from_bits_truncate.rs new file mode 100644 index 0000000..e4f3e53 --- /dev/null +++ b/vendor/bitflags/src/tests/from_bits_truncate.rs @@ -0,0 +1,42 @@ +use super::*; + +use crate::Flags; + +#[test] +fn cases() { + case(0, 0, TestFlags::from_bits_truncate); + case(1, 1, TestFlags::from_bits_truncate); + case( + 1 | 1 << 1 | 1 << 2, + 1 | 1 << 1 | 1 << 2, + TestFlags::from_bits_truncate, + ); + + case(0, 1 << 3, TestFlags::from_bits_truncate); + case(1, 1 | 1 << 3, TestFlags::from_bits_truncate); + + case(1 | 1 << 1, 1 | 1 << 1, TestOverlapping::from_bits_truncate); + + case(1 << 1, 1 << 1, TestOverlapping::from_bits_truncate); + + case(1 << 5, 1 << 5, TestExternal::from_bits_truncate); +} + +#[track_caller] +fn case(expected: T::Bits, input: T::Bits, inherent: impl FnOnce(T::Bits) -> T) +where + ::Bits: std::fmt::Debug + PartialEq, +{ + assert_eq!( + expected, + inherent(input).bits(), + "T::from_bits_truncate({:?})", + input + ); + assert_eq!( + expected, + T::from_bits_truncate(input).bits(), + "Flags::from_bits_truncate({:?})", + input + ); +} diff --git a/vendor/bitflags/src/tests/from_name.rs b/vendor/bitflags/src/tests/from_name.rs new file mode 100644 index 0000000..1d9a4e4 --- /dev/null +++ b/vendor/bitflags/src/tests/from_name.rs @@ -0,0 +1,42 @@ +use super::*; + +use crate::Flags; + +#[test] +fn cases() { + case(Some(1), "A", TestFlags::from_name); + case(Some(1 << 1), "B", TestFlags::from_name); + case(Some(1 | 1 << 1 | 1 << 2), "ABC", TestFlags::from_name); + + case(None, "", TestFlags::from_name); + case(None, "a", TestFlags::from_name); + case(None, "0x1", TestFlags::from_name); + case(None, "A | B", TestFlags::from_name); + + case(Some(0), "ZERO", TestZero::from_name); + + case(Some(2), "二", TestUnicode::from_name); + + case(None, "_", TestExternal::from_name); + + case(None, "", TestExternal::from_name); +} + +#[track_caller] +fn case(expected: Option, input: &str, inherent: impl FnOnce(&str) -> Option) +where + ::Bits: std::fmt::Debug + PartialEq, +{ + assert_eq!( + expected, + inherent(input).map(|f| f.bits()), + "T::from_name({:?})", + input + ); + assert_eq!( + expected, + T::from_name(input).map(|f| f.bits()), + "Flags::from_name({:?})", + input + ); +} diff --git a/vendor/bitflags/src/tests/insert.rs b/vendor/bitflags/src/tests/insert.rs new file mode 100644 index 0000000..b18cd17 --- /dev/null +++ b/vendor/bitflags/src/tests/insert.rs @@ -0,0 +1,91 @@ +use super::*; + +use crate::Flags; + +#[test] +fn cases() { + case( + TestFlags::empty(), + &[ + (TestFlags::A, 1), + (TestFlags::A | TestFlags::B, 1 | 1 << 1), + (TestFlags::empty(), 0), + (TestFlags::from_bits_retain(1 << 3), 1 << 3), + ], + TestFlags::insert, + TestFlags::set, + ); + + case( + TestFlags::A, + &[ + (TestFlags::A, 1), + (TestFlags::empty(), 1), + (TestFlags::B, 1 | 1 << 1), + ], + TestFlags::insert, + TestFlags::set, + ); +} + +#[track_caller] +fn case( + value: T, + inputs: &[(T, T::Bits)], + mut inherent_insert: impl FnMut(&mut T, T), + mut inherent_set: impl FnMut(&mut T, T, bool), +) where + T::Bits: std::fmt::Debug + PartialEq + Copy, +{ + for (input, expected) in inputs { + assert_eq!( + *expected, + { + let mut value = value; + inherent_insert(&mut value, *input); + value + } + .bits(), + "{:?}.insert({:?})", + value, + input + ); + assert_eq!( + *expected, + { + let mut value = value; + Flags::insert(&mut value, *input); + value + } + .bits(), + "Flags::insert({:?}, {:?})", + value, + input + ); + + assert_eq!( + *expected, + { + let mut value = value; + inherent_set(&mut value, *input, true); + value + } + .bits(), + "{:?}.set({:?}, true)", + value, + input + ); + assert_eq!( + *expected, + { + let mut value = value; + Flags::set(&mut value, *input, true); + value + } + .bits(), + "Flags::set({:?}, {:?}, true)", + value, + input + ); + } +} diff --git a/vendor/bitflags/src/tests/intersection.rs b/vendor/bitflags/src/tests/intersection.rs new file mode 100644 index 0000000..10a8ae9 --- /dev/null +++ b/vendor/bitflags/src/tests/intersection.rs @@ -0,0 +1,79 @@ +use super::*; + +use crate::Flags; + +#[test] +fn cases() { + case( + TestFlags::empty(), + &[(TestFlags::empty(), 0), (TestFlags::all(), 0)], + TestFlags::intersection, + ); + + case( + TestFlags::all(), + &[ + (TestFlags::all(), 1 | 1 << 1 | 1 << 2), + (TestFlags::A, 1), + (TestFlags::from_bits_retain(1 << 3), 0), + ], + TestFlags::intersection, + ); + + case( + TestFlags::from_bits_retain(1 << 3), + &[(TestFlags::from_bits_retain(1 << 3), 1 << 3)], + TestFlags::intersection, + ); + + case( + TestOverlapping::AB, + &[(TestOverlapping::BC, 1 << 1)], + TestOverlapping::intersection, + ); +} + +#[track_caller] +fn case + std::ops::BitAndAssign + Copy>( + value: T, + inputs: &[(T, T::Bits)], + mut inherent: impl FnMut(T, T) -> T, +) where + T::Bits: std::fmt::Debug + PartialEq + Copy, +{ + for (input, expected) in inputs { + assert_eq!( + *expected, + inherent(value, *input).bits(), + "{:?}.intersection({:?})", + value, + input + ); + assert_eq!( + *expected, + Flags::intersection(value, *input).bits(), + "Flags::intersection({:?}, {:?})", + value, + input + ); + assert_eq!( + *expected, + (value & *input).bits(), + "{:?} & {:?}", + value, + input + ); + assert_eq!( + *expected, + { + let mut value = value; + value &= *input; + value + } + .bits(), + "{:?} &= {:?}", + value, + input, + ); + } +} diff --git a/vendor/bitflags/src/tests/intersects.rs b/vendor/bitflags/src/tests/intersects.rs new file mode 100644 index 0000000..fe90798 --- /dev/null +++ b/vendor/bitflags/src/tests/intersects.rs @@ -0,0 +1,91 @@ +use super::*; + +use crate::Flags; + +#[test] +fn cases() { + case( + TestFlags::empty(), + &[ + (TestFlags::empty(), false), + (TestFlags::A, false), + (TestFlags::B, false), + (TestFlags::C, false), + (TestFlags::from_bits_retain(1 << 3), false), + ], + TestFlags::intersects, + ); + + case( + TestFlags::A, + &[ + (TestFlags::empty(), false), + (TestFlags::A, true), + (TestFlags::B, false), + (TestFlags::C, false), + (TestFlags::ABC, true), + (TestFlags::from_bits_retain(1 << 3), false), + (TestFlags::from_bits_retain(1 | (1 << 3)), true), + ], + TestFlags::intersects, + ); + + case( + TestFlags::ABC, + &[ + (TestFlags::empty(), false), + (TestFlags::A, true), + (TestFlags::B, true), + (TestFlags::C, true), + (TestFlags::ABC, true), + (TestFlags::from_bits_retain(1 << 3), false), + ], + TestFlags::intersects, + ); + + case( + TestFlags::from_bits_retain(1 << 3), + &[ + (TestFlags::empty(), false), + (TestFlags::A, false), + (TestFlags::B, false), + (TestFlags::C, false), + (TestFlags::from_bits_retain(1 << 3), true), + ], + TestFlags::intersects, + ); + + case( + TestOverlapping::AB, + &[ + (TestOverlapping::AB, true), + (TestOverlapping::BC, true), + (TestOverlapping::from_bits_retain(1 << 1), true), + ], + TestOverlapping::intersects, + ); +} + +#[track_caller] +fn case( + value: T, + inputs: &[(T, bool)], + mut inherent: impl FnMut(&T, T) -> bool, +) { + for (input, expected) in inputs { + assert_eq!( + *expected, + inherent(&value, *input), + "{:?}.intersects({:?})", + value, + input + ); + assert_eq!( + *expected, + Flags::intersects(&value, *input), + "Flags::intersects({:?}, {:?})", + value, + input + ); + } +} diff --git a/vendor/bitflags/src/tests/is_all.rs b/vendor/bitflags/src/tests/is_all.rs new file mode 100644 index 0000000..382a458 --- /dev/null +++ b/vendor/bitflags/src/tests/is_all.rs @@ -0,0 +1,32 @@ +use super::*; + +use crate::Flags; + +#[test] +fn cases() { + case(false, TestFlags::empty(), TestFlags::is_all); + case(false, TestFlags::A, TestFlags::is_all); + + case(true, TestFlags::ABC, TestFlags::is_all); + + case( + true, + TestFlags::ABC | TestFlags::from_bits_retain(1 << 3), + TestFlags::is_all, + ); + + case(true, TestZero::empty(), TestZero::is_all); + + case(true, TestEmpty::empty(), TestEmpty::is_all); +} + +#[track_caller] +fn case(expected: bool, value: T, inherent: impl FnOnce(&T) -> bool) { + assert_eq!(expected, inherent(&value), "{:?}.is_all()", value); + assert_eq!( + expected, + Flags::is_all(&value), + "Flags::is_all({:?})", + value + ); +} diff --git a/vendor/bitflags/src/tests/is_empty.rs b/vendor/bitflags/src/tests/is_empty.rs new file mode 100644 index 0000000..92165f1 --- /dev/null +++ b/vendor/bitflags/src/tests/is_empty.rs @@ -0,0 +1,31 @@ +use super::*; + +use crate::Flags; + +#[test] +fn cases() { + case(true, TestFlags::empty(), TestFlags::is_empty); + + case(false, TestFlags::A, TestFlags::is_empty); + case(false, TestFlags::ABC, TestFlags::is_empty); + case( + false, + TestFlags::from_bits_retain(1 << 3), + TestFlags::is_empty, + ); + + case(true, TestZero::empty(), TestZero::is_empty); + + case(true, TestEmpty::empty(), TestEmpty::is_empty); +} + +#[track_caller] +fn case(expected: bool, value: T, inherent: impl FnOnce(&T) -> bool) { + assert_eq!(expected, inherent(&value), "{:?}.is_empty()", value); + assert_eq!( + expected, + Flags::is_empty(&value), + "Flags::is_empty({:?})", + value + ); +} diff --git a/vendor/bitflags/src/tests/iter.rs b/vendor/bitflags/src/tests/iter.rs new file mode 100644 index 0000000..54b1d27 --- /dev/null +++ b/vendor/bitflags/src/tests/iter.rs @@ -0,0 +1,209 @@ +use super::*; + +use crate::Flags; + +#[test] +#[cfg(not(miri))] // Very slow in miri +fn roundtrip() { + for a in 0u8..=255 { + for b in 0u8..=255 { + let f = TestFlags::from_bits_retain(a | b); + + assert_eq!(f, f.iter().collect::()); + assert_eq!( + TestFlags::from_bits_truncate(f.bits()), + f.iter_names().map(|(_, f)| f).collect::() + ); + + let f = TestExternal::from_bits_retain(a | b); + + assert_eq!(f, f.iter().collect::()); + } + } +} + +mod collect { + use super::*; + + #[test] + fn cases() { + assert_eq!(0, [].into_iter().collect::().bits()); + + assert_eq!(1, [TestFlags::A,].into_iter().collect::().bits()); + + assert_eq!( + 1 | 1 << 1 | 1 << 2, + [TestFlags::A, TestFlags::B | TestFlags::C,] + .into_iter() + .collect::() + .bits() + ); + + assert_eq!( + 1 | 1 << 3, + [ + TestFlags::from_bits_retain(1 << 3), + TestFlags::empty(), + TestFlags::A, + ] + .into_iter() + .collect::() + .bits() + ); + + assert_eq!( + 1 << 5 | 1 << 7, + [ + TestExternal::empty(), + TestExternal::from_bits_retain(1 << 5), + TestExternal::from_bits_retain(1 << 7), + ] + .into_iter() + .collect::() + .bits() + ); + } +} + +mod iter { + use super::*; + + #[test] + fn cases() { + case(&[], TestFlags::empty(), TestFlags::iter); + + case(&[1], TestFlags::A, TestFlags::iter); + case(&[1, 1 << 1], TestFlags::A | TestFlags::B, TestFlags::iter); + case( + &[1, 1 << 1, 1 << 3], + TestFlags::A | TestFlags::B | TestFlags::from_bits_retain(1 << 3), + TestFlags::iter, + ); + + case(&[1, 1 << 1, 1 << 2], TestFlags::ABC, TestFlags::iter); + case( + &[1, 1 << 1, 1 << 2, 1 << 3], + TestFlags::ABC | TestFlags::from_bits_retain(1 << 3), + TestFlags::iter, + ); + + case( + &[1 | 1 << 1 | 1 << 2], + TestFlagsInvert::ABC, + TestFlagsInvert::iter, + ); + + case(&[], TestZero::ZERO, TestZero::iter); + + case( + &[1, 1 << 1, 1 << 2, 0b1111_1000], + TestExternal::all(), + TestExternal::iter, + ); + } + + #[track_caller] + fn case + Copy>( + expected: &[T::Bits], + value: T, + inherent: impl FnOnce(&T) -> crate::iter::Iter, + ) where + T::Bits: std::fmt::Debug + PartialEq, + { + assert_eq!( + expected, + inherent(&value).map(|f| f.bits()).collect::>(), + "{:?}.iter()", + value + ); + assert_eq!( + expected, + Flags::iter(&value).map(|f| f.bits()).collect::>(), + "Flags::iter({:?})", + value + ); + assert_eq!( + expected, + value.into_iter().map(|f| f.bits()).collect::>(), + "{:?}.into_iter()", + value + ); + } +} + +mod iter_names { + use super::*; + + #[test] + fn cases() { + case(&[], TestFlags::empty(), TestFlags::iter_names); + + case(&[("A", 1)], TestFlags::A, TestFlags::iter_names); + case( + &[("A", 1), ("B", 1 << 1)], + TestFlags::A | TestFlags::B, + TestFlags::iter_names, + ); + case( + &[("A", 1), ("B", 1 << 1)], + TestFlags::A | TestFlags::B | TestFlags::from_bits_retain(1 << 3), + TestFlags::iter_names, + ); + + case( + &[("A", 1), ("B", 1 << 1), ("C", 1 << 2)], + TestFlags::ABC, + TestFlags::iter_names, + ); + case( + &[("A", 1), ("B", 1 << 1), ("C", 1 << 2)], + TestFlags::ABC | TestFlags::from_bits_retain(1 << 3), + TestFlags::iter_names, + ); + + case( + &[("ABC", 1 | 1 << 1 | 1 << 2)], + TestFlagsInvert::ABC, + TestFlagsInvert::iter_names, + ); + + case(&[], TestZero::ZERO, TestZero::iter_names); + + case( + &[("A", 1)], + TestOverlappingFull::A, + TestOverlappingFull::iter_names, + ); + case( + &[("A", 1), ("D", 1 << 1)], + TestOverlappingFull::A | TestOverlappingFull::D, + TestOverlappingFull::iter_names, + ); + } + + #[track_caller] + fn case( + expected: &[(&'static str, T::Bits)], + value: T, + inherent: impl FnOnce(&T) -> crate::iter::IterNames, + ) where + T::Bits: std::fmt::Debug + PartialEq, + { + assert_eq!( + expected, + inherent(&value) + .map(|(n, f)| (n, f.bits())) + .collect::>(), + "{:?}.iter_names()", + value + ); + assert_eq!( + expected, + Flags::iter_names(&value) + .map(|(n, f)| (n, f.bits())) + .collect::>(), + "Flags::iter_names({:?})", + value + ); + } +} diff --git a/vendor/bitflags/src/tests/parser.rs b/vendor/bitflags/src/tests/parser.rs new file mode 100644 index 0000000..fb27225 --- /dev/null +++ b/vendor/bitflags/src/tests/parser.rs @@ -0,0 +1,332 @@ +use super::*; + +use crate::{parser::*, Flags}; + +#[test] +#[cfg(not(miri))] // Very slow in miri +fn roundtrip() { + let mut s = String::new(); + + for a in 0u8..=255 { + for b in 0u8..=255 { + let f = TestFlags::from_bits_retain(a | b); + + s.clear(); + to_writer(&f, &mut s).unwrap(); + + assert_eq!(f, from_str::(&s).unwrap()); + } + } +} + +#[test] +#[cfg(not(miri))] // Very slow in miri +fn roundtrip_truncate() { + let mut s = String::new(); + + for a in 0u8..=255 { + for b in 0u8..=255 { + let f = TestFlags::from_bits_retain(a | b); + + s.clear(); + to_writer_truncate(&f, &mut s).unwrap(); + + assert_eq!( + TestFlags::from_bits_truncate(f.bits()), + from_str_truncate::(&s).unwrap() + ); + } + } +} + +#[test] +#[cfg(not(miri))] // Very slow in miri +fn roundtrip_strict() { + let mut s = String::new(); + + for a in 0u8..=255 { + for b in 0u8..=255 { + let f = TestFlags::from_bits_retain(a | b); + + s.clear(); + to_writer_strict(&f, &mut s).unwrap(); + + let mut strict = TestFlags::empty(); + for (_, flag) in f.iter_names() { + strict |= flag; + } + let f = strict; + + if let Ok(s) = from_str_strict::(&s) { + assert_eq!(f, s); + } + } + } +} + +mod from_str { + use super::*; + + #[test] + fn valid() { + assert_eq!(0, from_str::("").unwrap().bits()); + + assert_eq!(1, from_str::("A").unwrap().bits()); + assert_eq!(1, from_str::(" A ").unwrap().bits()); + assert_eq!( + 1 | 1 << 1 | 1 << 2, + from_str::("A | B | C").unwrap().bits() + ); + assert_eq!( + 1 | 1 << 1 | 1 << 2, + from_str::("A\n|\tB\r\n| C ").unwrap().bits() + ); + assert_eq!( + 1 | 1 << 1 | 1 << 2, + from_str::("A|B|C").unwrap().bits() + ); + + assert_eq!(1 << 3, from_str::("0x8").unwrap().bits()); + assert_eq!(1 | 1 << 3, from_str::("A | 0x8").unwrap().bits()); + assert_eq!( + 1 | 1 << 1 | 1 << 3, + from_str::("0x1 | 0x8 | B").unwrap().bits() + ); + + assert_eq!( + 1 | 1 << 1, + from_str::("一 | 二").unwrap().bits() + ); + } + + #[test] + fn invalid() { + assert!(from_str::("a") + .unwrap_err() + .to_string() + .starts_with("unrecognized named flag")); + assert!(from_str::("A & B") + .unwrap_err() + .to_string() + .starts_with("unrecognized named flag")); + + assert!(from_str::("0xg") + .unwrap_err() + .to_string() + .starts_with("invalid hex flag")); + assert!(from_str::("0xffffffffffff") + .unwrap_err() + .to_string() + .starts_with("invalid hex flag")); + } +} + +mod to_writer { + use super::*; + + #[test] + fn cases() { + assert_eq!("", write(TestFlags::empty())); + assert_eq!("A", write(TestFlags::A)); + assert_eq!("A | B | C", write(TestFlags::all())); + assert_eq!("0x8", write(TestFlags::from_bits_retain(1 << 3))); + assert_eq!( + "A | 0x8", + write(TestFlags::A | TestFlags::from_bits_retain(1 << 3)) + ); + + assert_eq!("", write(TestZero::ZERO)); + + assert_eq!("ABC", write(TestFlagsInvert::all())); + + assert_eq!("0x1", write(TestOverlapping::from_bits_retain(1))); + + assert_eq!("A", write(TestOverlappingFull::C)); + assert_eq!( + "A | D", + write(TestOverlappingFull::C | TestOverlappingFull::D) + ); + } + + fn write(value: F) -> String + where + F::Bits: crate::parser::WriteHex, + { + let mut s = String::new(); + + to_writer(&value, &mut s).unwrap(); + s + } +} + +mod from_str_truncate { + use super::*; + + #[test] + fn valid() { + assert_eq!(0, from_str_truncate::("").unwrap().bits()); + + assert_eq!(1, from_str_truncate::("A").unwrap().bits()); + assert_eq!(1, from_str_truncate::(" A ").unwrap().bits()); + assert_eq!( + 1 | 1 << 1 | 1 << 2, + from_str_truncate::("A | B | C").unwrap().bits() + ); + assert_eq!( + 1 | 1 << 1 | 1 << 2, + from_str_truncate::("A\n|\tB\r\n| C ") + .unwrap() + .bits() + ); + assert_eq!( + 1 | 1 << 1 | 1 << 2, + from_str_truncate::("A|B|C").unwrap().bits() + ); + + assert_eq!(0, from_str_truncate::("0x8").unwrap().bits()); + assert_eq!(1, from_str_truncate::("A | 0x8").unwrap().bits()); + assert_eq!( + 1 | 1 << 1, + from_str_truncate::("0x1 | 0x8 | B") + .unwrap() + .bits() + ); + + assert_eq!( + 1 | 1 << 1, + from_str_truncate::("一 | 二").unwrap().bits() + ); + } +} + +mod to_writer_truncate { + use super::*; + + #[test] + fn cases() { + assert_eq!("", write(TestFlags::empty())); + assert_eq!("A", write(TestFlags::A)); + assert_eq!("A | B | C", write(TestFlags::all())); + assert_eq!("", write(TestFlags::from_bits_retain(1 << 3))); + assert_eq!( + "A", + write(TestFlags::A | TestFlags::from_bits_retain(1 << 3)) + ); + + assert_eq!("", write(TestZero::ZERO)); + + assert_eq!("ABC", write(TestFlagsInvert::all())); + + assert_eq!("0x1", write(TestOverlapping::from_bits_retain(1))); + + assert_eq!("A", write(TestOverlappingFull::C)); + assert_eq!( + "A | D", + write(TestOverlappingFull::C | TestOverlappingFull::D) + ); + } + + fn write(value: F) -> String + where + F::Bits: crate::parser::WriteHex, + { + let mut s = String::new(); + + to_writer_truncate(&value, &mut s).unwrap(); + s + } +} + +mod from_str_strict { + use super::*; + + #[test] + fn valid() { + assert_eq!(0, from_str_strict::("").unwrap().bits()); + + assert_eq!(1, from_str_strict::("A").unwrap().bits()); + assert_eq!(1, from_str_strict::(" A ").unwrap().bits()); + assert_eq!( + 1 | 1 << 1 | 1 << 2, + from_str_strict::("A | B | C").unwrap().bits() + ); + assert_eq!( + 1 | 1 << 1 | 1 << 2, + from_str_strict::("A\n|\tB\r\n| C ") + .unwrap() + .bits() + ); + assert_eq!( + 1 | 1 << 1 | 1 << 2, + from_str_strict::("A|B|C").unwrap().bits() + ); + + assert_eq!( + 1 | 1 << 1, + from_str_strict::("一 | 二").unwrap().bits() + ); + } + + #[test] + fn invalid() { + assert!(from_str_strict::("a") + .unwrap_err() + .to_string() + .starts_with("unrecognized named flag")); + assert!(from_str_strict::("A & B") + .unwrap_err() + .to_string() + .starts_with("unrecognized named flag")); + + assert!(from_str_strict::("0x1") + .unwrap_err() + .to_string() + .starts_with("invalid hex flag")); + assert!(from_str_strict::("0xg") + .unwrap_err() + .to_string() + .starts_with("invalid hex flag")); + assert!(from_str_strict::("0xffffffffffff") + .unwrap_err() + .to_string() + .starts_with("invalid hex flag")); + } +} + +mod to_writer_strict { + use super::*; + + #[test] + fn cases() { + assert_eq!("", write(TestFlags::empty())); + assert_eq!("A", write(TestFlags::A)); + assert_eq!("A | B | C", write(TestFlags::all())); + assert_eq!("", write(TestFlags::from_bits_retain(1 << 3))); + assert_eq!( + "A", + write(TestFlags::A | TestFlags::from_bits_retain(1 << 3)) + ); + + assert_eq!("", write(TestZero::ZERO)); + + assert_eq!("ABC", write(TestFlagsInvert::all())); + + assert_eq!("", write(TestOverlapping::from_bits_retain(1))); + + assert_eq!("A", write(TestOverlappingFull::C)); + assert_eq!( + "A | D", + write(TestOverlappingFull::C | TestOverlappingFull::D) + ); + } + + fn write(value: F) -> String + where + F::Bits: crate::parser::WriteHex, + { + let mut s = String::new(); + + to_writer_strict(&value, &mut s).unwrap(); + s + } +} diff --git a/vendor/bitflags/src/tests/remove.rs b/vendor/bitflags/src/tests/remove.rs new file mode 100644 index 0000000..574b1ed --- /dev/null +++ b/vendor/bitflags/src/tests/remove.rs @@ -0,0 +1,100 @@ +use super::*; + +use crate::Flags; + +#[test] +fn cases() { + case( + TestFlags::empty(), + &[ + (TestFlags::A, 0), + (TestFlags::empty(), 0), + (TestFlags::from_bits_retain(1 << 3), 0), + ], + TestFlags::remove, + TestFlags::set, + ); + + case( + TestFlags::A, + &[ + (TestFlags::A, 0), + (TestFlags::empty(), 1), + (TestFlags::B, 1), + ], + TestFlags::remove, + TestFlags::set, + ); + + case( + TestFlags::ABC, + &[ + (TestFlags::A, 1 << 1 | 1 << 2), + (TestFlags::A | TestFlags::C, 1 << 1), + ], + TestFlags::remove, + TestFlags::set, + ); +} + +#[track_caller] +fn case( + value: T, + inputs: &[(T, T::Bits)], + mut inherent_remove: impl FnMut(&mut T, T), + mut inherent_set: impl FnMut(&mut T, T, bool), +) where + T::Bits: std::fmt::Debug + PartialEq + Copy, +{ + for (input, expected) in inputs { + assert_eq!( + *expected, + { + let mut value = value; + inherent_remove(&mut value, *input); + value + } + .bits(), + "{:?}.remove({:?})", + value, + input + ); + assert_eq!( + *expected, + { + let mut value = value; + Flags::remove(&mut value, *input); + value + } + .bits(), + "Flags::remove({:?}, {:?})", + value, + input + ); + + assert_eq!( + *expected, + { + let mut value = value; + inherent_set(&mut value, *input, false); + value + } + .bits(), + "{:?}.set({:?}, false)", + value, + input + ); + assert_eq!( + *expected, + { + let mut value = value; + Flags::set(&mut value, *input, false); + value + } + .bits(), + "Flags::set({:?}, {:?}, false)", + value, + input + ); + } +} diff --git a/vendor/bitflags/src/tests/symmetric_difference.rs b/vendor/bitflags/src/tests/symmetric_difference.rs new file mode 100644 index 0000000..75e9123 --- /dev/null +++ b/vendor/bitflags/src/tests/symmetric_difference.rs @@ -0,0 +1,110 @@ +use super::*; + +use crate::Flags; + +#[test] +fn cases() { + case( + TestFlags::empty(), + &[ + (TestFlags::empty(), 0), + (TestFlags::all(), 1 | 1 << 1 | 1 << 2), + (TestFlags::from_bits_retain(1 << 3), 1 << 3), + ], + TestFlags::symmetric_difference, + TestFlags::toggle, + ); + + case( + TestFlags::A, + &[ + (TestFlags::empty(), 1), + (TestFlags::A, 0), + (TestFlags::all(), 1 << 1 | 1 << 2), + ], + TestFlags::symmetric_difference, + TestFlags::toggle, + ); + + case( + TestFlags::A | TestFlags::B | TestFlags::from_bits_retain(1 << 3), + &[ + (TestFlags::ABC, 1 << 2 | 1 << 3), + (TestFlags::from_bits_retain(1 << 3), 1 | 1 << 1), + ], + TestFlags::symmetric_difference, + TestFlags::toggle, + ); +} + +#[track_caller] +fn case + std::ops::BitXorAssign + Copy>( + value: T, + inputs: &[(T, T::Bits)], + mut inherent_sym_diff: impl FnMut(T, T) -> T, + mut inherent_toggle: impl FnMut(&mut T, T), +) where + T::Bits: std::fmt::Debug + PartialEq + Copy, +{ + for (input, expected) in inputs { + assert_eq!( + *expected, + inherent_sym_diff(value, *input).bits(), + "{:?}.symmetric_difference({:?})", + value, + input + ); + assert_eq!( + *expected, + Flags::symmetric_difference(value, *input).bits(), + "Flags::symmetric_difference({:?}, {:?})", + value, + input + ); + assert_eq!( + *expected, + (value ^ *input).bits(), + "{:?} ^ {:?}", + value, + input + ); + assert_eq!( + *expected, + { + let mut value = value; + value ^= *input; + value + } + .bits(), + "{:?} ^= {:?}", + value, + input, + ); + + assert_eq!( + *expected, + { + let mut value = value; + inherent_toggle(&mut value, *input); + value + } + .bits(), + "{:?}.toggle({:?})", + value, + input, + ); + + assert_eq!( + *expected, + { + let mut value = value; + Flags::toggle(&mut value, *input); + value + } + .bits(), + "{:?}.toggle({:?})", + value, + input, + ); + } +} diff --git a/vendor/bitflags/src/tests/union.rs b/vendor/bitflags/src/tests/union.rs new file mode 100644 index 0000000..6190681 --- /dev/null +++ b/vendor/bitflags/src/tests/union.rs @@ -0,0 +1,71 @@ +use super::*; + +use crate::Flags; + +#[test] +fn cases() { + case( + TestFlags::empty(), + &[ + (TestFlags::A, 1), + (TestFlags::all(), 1 | 1 << 1 | 1 << 2), + (TestFlags::empty(), 0), + (TestFlags::from_bits_retain(1 << 3), 1 << 3), + ], + TestFlags::union, + ); + + case( + TestFlags::A | TestFlags::C, + &[ + (TestFlags::A | TestFlags::B, 1 | 1 << 1 | 1 << 2), + (TestFlags::A, 1 | 1 << 2), + ], + TestFlags::union, + ); +} + +#[track_caller] +fn case + std::ops::BitOrAssign + Copy>( + value: T, + inputs: &[(T, T::Bits)], + mut inherent: impl FnMut(T, T) -> T, +) where + T::Bits: std::fmt::Debug + PartialEq + Copy, +{ + for (input, expected) in inputs { + assert_eq!( + *expected, + inherent(value, *input).bits(), + "{:?}.union({:?})", + value, + input + ); + assert_eq!( + *expected, + Flags::union(value, *input).bits(), + "Flags::union({:?}, {:?})", + value, + input + ); + assert_eq!( + *expected, + (value | *input).bits(), + "{:?} | {:?}", + value, + input + ); + assert_eq!( + *expected, + { + let mut value = value; + value |= *input; + value + } + .bits(), + "{:?} |= {:?}", + value, + input, + ); + } +} diff --git a/vendor/bitflags/src/traits.rs b/vendor/bitflags/src/traits.rs new file mode 100644 index 0000000..3905d7d --- /dev/null +++ b/vendor/bitflags/src/traits.rs @@ -0,0 +1,431 @@ +use core::{ + fmt, + ops::{BitAnd, BitOr, BitXor, Not}, +}; + +use crate::{ + iter, + parser::{ParseError, ParseHex, WriteHex}, +}; + +/** +A defined flags value that may be named or unnamed. +*/ +#[derive(Debug)] +pub struct Flag { + name: &'static str, + value: B, +} + +impl Flag { + /** + Define a flag. + + If `name` is non-empty then the flag is named, otherwise it's unnamed. + */ + pub const fn new(name: &'static str, value: B) -> Self { + Flag { name, value } + } + + /** + Get the name of this flag. + + If the flag is unnamed then the returned string will be empty. + */ + pub const fn name(&self) -> &'static str { + self.name + } + + /** + Get the flags value of this flag. + */ + pub const fn value(&self) -> &B { + &self.value + } + + /** + Whether the flag is named. + + If [`Flag::name`] returns a non-empty string then this method will return `true`. + */ + pub const fn is_named(&self) -> bool { + !self.name.is_empty() + } + + /** + Whether the flag is unnamed. + + If [`Flag::name`] returns a non-empty string then this method will return `false`. + */ + pub const fn is_unnamed(&self) -> bool { + self.name.is_empty() + } +} + +/** +A set of defined flags using a bits type as storage. + +## Implementing `Flags` + +This trait is implemented by the [`bitflags`](macro.bitflags.html) macro: + +``` +use bitflags::bitflags; + +bitflags! { + struct MyFlags: u8 { + const A = 1; + const B = 1 << 1; + } +} +``` + +It can also be implemented manually: + +``` +use bitflags::{Flag, Flags}; + +struct MyFlags(u8); + +impl Flags for MyFlags { + const FLAGS: &'static [Flag] = &[ + Flag::new("A", MyFlags(1)), + Flag::new("B", MyFlags(1 << 1)), + ]; + + type Bits = u8; + + fn from_bits_retain(bits: Self::Bits) -> Self { + MyFlags(bits) + } + + fn bits(&self) -> Self::Bits { + self.0 + } +} +``` + +## Using `Flags` + +The `Flags` trait can be used generically to work with any flags types. In this example, +we can count the number of defined named flags: + +``` +# use bitflags::{bitflags, Flags}; +fn defined_flags() -> usize { + F::FLAGS.iter().filter(|f| f.is_named()).count() +} + +bitflags! { + struct MyFlags: u8 { + const A = 1; + const B = 1 << 1; + const C = 1 << 2; + + const _ = !0; + } +} + +assert_eq!(3, defined_flags::()); +``` +*/ +pub trait Flags: Sized + 'static { + /// The set of defined flags. + const FLAGS: &'static [Flag]; + + /// The underlying bits type. + type Bits: Bits; + + /// Get a flags value with all bits unset. + fn empty() -> Self { + Self::from_bits_retain(Self::Bits::EMPTY) + } + + /// Get a flags value with all known bits set. + fn all() -> Self { + let mut truncated = Self::Bits::EMPTY; + + for flag in Self::FLAGS.iter() { + truncated = truncated | flag.value().bits(); + } + + Self::from_bits_retain(truncated) + } + + /// Get the underlying bits value. + /// + /// The returned value is exactly the bits set in this flags value. + fn bits(&self) -> Self::Bits; + + /// Convert from a bits value. + /// + /// This method will return `None` if any unknown bits are set. + fn from_bits(bits: Self::Bits) -> Option { + let truncated = Self::from_bits_truncate(bits); + + if truncated.bits() == bits { + Some(truncated) + } else { + None + } + } + + /// Convert from a bits value, unsetting any unknown bits. + fn from_bits_truncate(bits: Self::Bits) -> Self { + Self::from_bits_retain(bits & Self::all().bits()) + } + + /// Convert from a bits value exactly. + fn from_bits_retain(bits: Self::Bits) -> Self; + + /// Get a flags value with the bits of a flag with the given name set. + /// + /// This method will return `None` if `name` is empty or doesn't + /// correspond to any named flag. + fn from_name(name: &str) -> Option { + // Don't parse empty names as empty flags + if name.is_empty() { + return None; + } + + for flag in Self::FLAGS { + if flag.name() == name { + return Some(Self::from_bits_retain(flag.value().bits())); + } + } + + None + } + + /// Yield a set of contained flags values. + /// + /// Each yielded flags value will correspond to a defined named flag. Any unknown bits + /// will be yielded together as a final flags value. + fn iter(&self) -> iter::Iter { + iter::Iter::new(self) + } + + /// Yield a set of contained named flags values. + /// + /// This method is like [`Flags::iter`], except only yields bits in contained named flags. + /// Any unknown bits, or bits not corresponding to a contained flag will not be yielded. + fn iter_names(&self) -> iter::IterNames { + iter::IterNames::new(self) + } + + /// Whether all bits in this flags value are unset. + fn is_empty(&self) -> bool { + self.bits() == Self::Bits::EMPTY + } + + /// Whether all known bits in this flags value are set. + fn is_all(&self) -> bool { + // NOTE: We check against `Self::all` here, not `Self::Bits::ALL` + // because the set of all flags may not use all bits + Self::all().bits() | self.bits() == self.bits() + } + + /// Whether any set bits in a source flags value are also set in a target flags value. + fn intersects(&self, other: Self) -> bool + where + Self: Sized, + { + self.bits() & other.bits() != Self::Bits::EMPTY + } + + /// Whether all set bits in a source flags value are also set in a target flags value. + fn contains(&self, other: Self) -> bool + where + Self: Sized, + { + self.bits() & other.bits() == other.bits() + } + + /// The bitwise or (`|`) of the bits in two flags values. + fn insert(&mut self, other: Self) + where + Self: Sized, + { + *self = Self::from_bits_retain(self.bits()).union(other); + } + + /// The intersection of a source flags value with the complement of a target flags value (`&!`). + /// + /// This method is not equivalent to `self & !other` when `other` has unknown bits set. + /// `remove` won't truncate `other`, but the `!` operator will. + fn remove(&mut self, other: Self) + where + Self: Sized, + { + *self = Self::from_bits_retain(self.bits()).difference(other); + } + + /// The bitwise exclusive-or (`^`) of the bits in two flags values. + fn toggle(&mut self, other: Self) + where + Self: Sized, + { + *self = Self::from_bits_retain(self.bits()).symmetric_difference(other); + } + + /// Call [`Flags::insert`] when `value` is `true` or [`Flags::remove`] when `value` is `false`. + fn set(&mut self, other: Self, value: bool) + where + Self: Sized, + { + if value { + self.insert(other); + } else { + self.remove(other); + } + } + + /// The bitwise and (`&`) of the bits in two flags values. + #[must_use] + fn intersection(self, other: Self) -> Self { + Self::from_bits_retain(self.bits() & other.bits()) + } + + /// The bitwise or (`|`) of the bits in two flags values. + #[must_use] + fn union(self, other: Self) -> Self { + Self::from_bits_retain(self.bits() | other.bits()) + } + + /// The intersection of a source flags value with the complement of a target flags value (`&!`). + /// + /// This method is not equivalent to `self & !other` when `other` has unknown bits set. + /// `difference` won't truncate `other`, but the `!` operator will. + #[must_use] + fn difference(self, other: Self) -> Self { + Self::from_bits_retain(self.bits() & !other.bits()) + } + + /// The bitwise exclusive-or (`^`) of the bits in two flags values. + #[must_use] + fn symmetric_difference(self, other: Self) -> Self { + Self::from_bits_retain(self.bits() ^ other.bits()) + } + + /// The bitwise negation (`!`) of the bits in a flags value, truncating the result. + #[must_use] + fn complement(self) -> Self { + Self::from_bits_truncate(!self.bits()) + } +} + +/** +A bits type that can be used as storage for a flags type. +*/ +pub trait Bits: + Clone + + Copy + + PartialEq + + BitAnd + + BitOr + + BitXor + + Not + + Sized + + 'static +{ + /// A value with all bits unset. + const EMPTY: Self; + + /// A value with all bits set. + const ALL: Self; +} + +// Not re-exported: prevent custom `Bits` impls being used in the `bitflags!` macro, +// or they may fail to compile based on crate features +pub trait Primitive {} + +macro_rules! impl_bits { + ($($u:ty, $i:ty,)*) => { + $( + impl Bits for $u { + const EMPTY: $u = 0; + const ALL: $u = <$u>::MAX; + } + + impl Bits for $i { + const EMPTY: $i = 0; + const ALL: $i = <$u>::MAX as $i; + } + + impl ParseHex for $u { + fn parse_hex(input: &str) -> Result { + <$u>::from_str_radix(input, 16).map_err(|_| ParseError::invalid_hex_flag(input)) + } + } + + impl ParseHex for $i { + fn parse_hex(input: &str) -> Result { + <$i>::from_str_radix(input, 16).map_err(|_| ParseError::invalid_hex_flag(input)) + } + } + + impl WriteHex for $u { + fn write_hex(&self, mut writer: W) -> fmt::Result { + write!(writer, "{:x}", self) + } + } + + impl WriteHex for $i { + fn write_hex(&self, mut writer: W) -> fmt::Result { + write!(writer, "{:x}", self) + } + } + + impl Primitive for $i {} + impl Primitive for $u {} + )* + } +} + +impl_bits! { + u8, i8, + u16, i16, + u32, i32, + u64, i64, + u128, i128, + usize, isize, +} + +/// A trait for referencing the `bitflags`-owned internal type +/// without exposing it publicly. +pub trait PublicFlags { + /// The type of the underlying storage. + type Primitive: Primitive; + + /// The type of the internal field on the generated flags type. + type Internal; +} + +#[doc(hidden)] +#[deprecated(note = "use the `Flags` trait instead")] +pub trait BitFlags: ImplementedByBitFlagsMacro + Flags { + /// An iterator over enabled flags in an instance of the type. + type Iter: Iterator; + + /// An iterator over the raw names and bits for enabled flags in an instance of the type. + type IterNames: Iterator; +} + +#[allow(deprecated)] +impl BitFlags for B { + type Iter = iter::Iter; + type IterNames = iter::IterNames; +} + +impl ImplementedByBitFlagsMacro for B {} + +/// A marker trait that signals that an implementation of `BitFlags` came from the `bitflags!` macro. +/// +/// There's nothing stopping an end-user from implementing this trait, but we don't guarantee their +/// manual implementations won't break between non-breaking releases. +#[doc(hidden)] +pub trait ImplementedByBitFlagsMacro {} + +pub(crate) mod __private { + pub use super::{ImplementedByBitFlagsMacro, PublicFlags}; +} diff --git a/vendor/cc/.cargo-checksum.json b/vendor/cc/.cargo-checksum.json new file mode 100644 index 0000000..383ee18 --- /dev/null +++ b/vendor/cc/.cargo-checksum.json @@ -0,0 +1 @@ +{"files":{"CHANGELOG.md":"4c2d7e4367b23e9232a1a08f93c6cd739d9c54394d8f6a58b1674101e7fd70ed","Cargo.toml":"8531bf0801327dae7536893352efc21e1864af5cbb854547c3850a4905a88f36","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"378f5840b258e2779c39418f3f2d7b2ba96f1c7917dd6be0713f88305dbda397","README.md":"f1ddbede208a5b78333a25dac0a7598e678e9b601a7d99a791069bddaf180dfe","clippy.toml":"aa7850db4350883c8f373bd0d6b4d19bf3b75f13c1c238e24368c109cb52fb1d","src/command_helpers.rs":"63742844930bd693e029fa93b734d21c64453c1d9c58f792b3363b28a4c0e86d","src/detect_compiler_family.c":"97ca4b021495611e828becea6187add37414186a16dfedd26c2947cbce6e8b2f","src/lib.rs":"68e35fadafc880de1f59c327f5bc1681837c1009089dcdf6815798e76bbcc39f","src/parallel/async_executor.rs":"4ce24435fff6b6555b43fee042c16bd65d4150d0346567f246b9190d85b45983","src/parallel/job_token.rs":"f4ed0a03d89a42bfd5527133d12b267af519b745f3f2b997ed293df15a2641b8","src/parallel/mod.rs":"55fb4c2d15e66677b2ed5ffa6d65ea161bcf1a1e1dc7910ee3bde06f2f67ab14","src/parallel/once_lock.rs":"d13e4cb82d6bca3297ca8671d83a40dd5affd7ac89191d733dd451867181bb02","src/parallel/stderr.rs":"74384d41198740a6fce0877f144262db09fb091225fa8fbfa771314bb11487c6","src/target_info.rs":"447d3083f24e10fe4c449925b349b3d14ab2ff103c0d9f942ea9b581873442e1","src/tempfile.rs":"ebafb5b0e5d08b0706916ed911d4245240e60c3e2d0c9a1630c520842988a2b3","src/tool.rs":"2e6550062e021f2b394388172bbb01e86fe6a94d2395bcb3c85a9e86690da1a9","src/utilities.rs":"a13bb0a351fcef72823485b1b5dc4f514c533fa4feac95deb66ed9e5fbfe7b53","src/windows/com.rs":"a2800ddb81215fff2bf618336f5c4ff8e8bdb746dd18b795873c7304b3f2a5e3","src/windows/find_tools.rs":"dd6b2450909cd8334a2aa2ce856bcc72a9654d92422267d6345d5fabfcbf57c5","src/windows/mod.rs":"34cfa201cfbcac7ccaa3ea5295d3e4200439af3cc5c6433baf81502596040a89","src/windows/registry.rs":"c521b72c825e8095843e73482ffa810ed066ad8bb9f86e6db0c5c143c171aba1","src/windows/setup_config.rs":"754439cbab492afd44c9755abcbec1a41c9b2c358131cee2df13c0e996dbbec8","src/windows/vs_instances.rs":"946527cf8fd32c3472f6a2884dcdec290763101097334c7478f9c24c3950db6b","src/windows/winapi.rs":"250d51c1826d1a2329e9889dd9f058cfce253dbf2a678b076147c6cdb5db046c","src/windows/windows_sys.rs":"e2714c8307bfa083b9745eb0e46cadd7f98d7b88abf45a7637172019324e34b8","src/windows/windows_targets.rs":"5b4648ebc22b028caca9f4b4bf8881fe2d094b7bec217264ba2e6e2c49d1ccee"},"package":"c2e7962b54006dcfcc61cb72735f4d89bb97061dd6a7ed882ec6b8ee53714c6f"} \ No newline at end of file diff --git a/vendor/cc/CHANGELOG.md b/vendor/cc/CHANGELOG.md new file mode 100644 index 0000000..bc0ebc1 --- /dev/null +++ b/vendor/cc/CHANGELOG.md @@ -0,0 +1,244 @@ +# Changelog +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## [Unreleased] + +## [1.1.31](https://github.com/rust-lang/cc-rs/compare/cc-v1.1.30...cc-v1.1.31) - 2024-10-19 + +### Other + +- Add comment explaining why cc does not rebuild on env PATH change ([#1247](https://github.com/rust-lang/cc-rs/pull/1247)) + +## [1.1.30](https://github.com/rust-lang/cc-rs/compare/cc-v1.1.29...cc-v1.1.30) - 2024-10-11 + +### Other + +- Don't pass -fPIC by default on wasm ([#1245](https://github.com/rust-lang/cc-rs/pull/1245)) + +## [1.1.29](https://github.com/rust-lang/cc-rs/compare/cc-v1.1.28...cc-v1.1.29) - 2024-10-11 + +### Other + +- Regenerate target info ([#1243](https://github.com/rust-lang/cc-rs/pull/1243)) + +## [1.1.28](https://github.com/rust-lang/cc-rs/compare/cc-v1.1.27...cc-v1.1.28) - 2024-10-06 + +### Other + +- Environment variables: For one accepting boolean, treat "0", "false" and empty env as false ([#1238](https://github.com/rust-lang/cc-rs/pull/1238)) + +## [1.1.27](https://github.com/rust-lang/cc-rs/compare/cc-v1.1.26...cc-v1.1.27) - 2024-10-06 + +### Other + +- Revert "Use debug version of MSVC runtime library on debug ([#1231](https://github.com/rust-lang/cc-rs/pull/1231))" ([#1237](https://github.com/rust-lang/cc-rs/pull/1237)) +- Disable `CC_ENABLE_DEBUG_OUTPUT` if it is set to "0" ([#1234](https://github.com/rust-lang/cc-rs/pull/1234)) + +## [1.1.26](https://github.com/rust-lang/cc-rs/compare/cc-v1.1.25...cc-v1.1.26) - 2024-10-06 + +### Other + +- Use debug version of MSVC runtime library on debug ([#1231](https://github.com/rust-lang/cc-rs/pull/1231)) + +## [1.1.25](https://github.com/rust-lang/cc-rs/compare/cc-v1.1.24...cc-v1.1.25) - 2024-10-05 + +### Other + +- Remove incorrect "lib" prefixes in CXXSTDLIB doc comments ([#1228](https://github.com/rust-lang/cc-rs/pull/1228)) + +## [1.1.24](https://github.com/rust-lang/cc-rs/compare/cc-v1.1.23...cc-v1.1.24) - 2024-10-01 + +### Other + +- Fix wasm32-wasip1-threads: shared-memory disallowed due to not compiled with 'atomics' or 'bulk-memory' features ([#1221](https://github.com/rust-lang/cc-rs/pull/1221)) +- Reduce the need for the host target triple ([#1224](https://github.com/rust-lang/cc-rs/pull/1224)) +- Add auto cancellation for CI jobs ([#1222](https://github.com/rust-lang/cc-rs/pull/1222)) + +## [1.1.23](https://github.com/rust-lang/cc-rs/compare/cc-v1.1.22...cc-v1.1.23) - 2024-09-30 + +### Other + +- Update doc for detecting changes/upgrades of compilers ([#1218](https://github.com/rust-lang/cc-rs/pull/1218)) + +## [1.1.22](https://github.com/rust-lang/cc-rs/compare/cc-v1.1.21...cc-v1.1.22) - 2024-09-27 + +### Other + +- Don't rerun if PATH changes ([#1215](https://github.com/rust-lang/cc-rs/pull/1215)) + +## [1.1.21](https://github.com/rust-lang/cc-rs/compare/cc-v1.1.20...cc-v1.1.21) - 2024-09-18 + +### Other + +- disable pic for targets that end in `-none` ([#1212](https://github.com/rust-lang/cc-rs/pull/1212)) + +## [1.1.20](https://github.com/rust-lang/cc-rs/compare/cc-v1.1.19...cc-v1.1.20) - 2024-09-17 + +### Other + +- Add buildcache as known Rust and C/C++ compiler wrapper ([#1209](https://github.com/rust-lang/cc-rs/pull/1209)) + +## [1.1.19](https://github.com/rust-lang/cc-rs/compare/cc-v1.1.18...cc-v1.1.19) - 2024-09-15 + +### Other + +- Add support arm64e-apple-darwin ([#1207](https://github.com/rust-lang/cc-rs/pull/1207)) + +## [1.1.18](https://github.com/rust-lang/cc-rs/compare/cc-v1.1.17...cc-v1.1.18) - 2024-09-07 + +### Other +- Fixed unsoundness in `StderrForwarder::forward_available` ([#1203](https://github.com/rust-lang/cc-rs/pull/1203)) + +## [1.1.17](https://github.com/rust-lang/cc-rs/compare/cc-v1.1.16...cc-v1.1.17) - 2024-09-06 + +### Fixed +- fix finding toolchains when invoked by msbuild ([#1201](https://github.com/rust-lang/cc-rs/pull/1201)) + +## [1.1.16](https://github.com/rust-lang/cc-rs/compare/cc-v1.1.15...cc-v1.1.16) - 2024-09-04 + +### Other +- Treat VxWorks wr-cc as a Gnu compiler ([#1198](https://github.com/rust-lang/cc-rs/pull/1198)) + +## [1.1.15](https://github.com/rust-lang/cc-rs/compare/cc-v1.1.14...cc-v1.1.15) - 2024-08-26 + +### Other +- Add -mfloat-abi=hard as a default argument when using any arm/thumb-none-eabihf target ([#1194](https://github.com/rust-lang/cc-rs/pull/1194)) + +## [1.1.14](https://github.com/rust-lang/cc-rs/compare/cc-v1.1.13...cc-v1.1.14) - 2024-08-23 + +### Other +- allow finding tools from path if VisualStudioDir is set + +## [1.1.13](https://github.com/rust-lang/cc-rs/compare/cc-v1.1.12...cc-v1.1.13) - 2024-08-16 + +### Other +- Fix detect family: should detect emscripten as clang, closes [#1185](https://github.com/rust-lang/cc-rs/pull/1185) ([#1186](https://github.com/rust-lang/cc-rs/pull/1186)) + +## [1.1.12](https://github.com/rust-lang/cc-rs/compare/cc-v1.1.11...cc-v1.1.12) - 2024-08-15 + +### Other +- improve docs ([#1183](https://github.com/rust-lang/cc-rs/pull/1183)) + +## [1.1.11](https://github.com/rust-lang/cc-rs/compare/cc-v1.1.10...cc-v1.1.11) - 2024-08-14 + +### Other +- Add support for parsing shell encoded `*FLAGS` ([#1181](https://github.com/rust-lang/cc-rs/pull/1181)) +- Replace vector of tuples with BTreeMap which already is sorted and free of duplicates ([#1177](https://github.com/rust-lang/cc-rs/pull/1177)) + +## [1.1.10](https://github.com/rust-lang/cc-rs/compare/cc-v1.1.9...cc-v1.1.10) - 2024-08-11 + +### Other +- Remap Windows targets triples to their LLVM counterparts ([#1176](https://github.com/rust-lang/cc-rs/pull/1176)) + +## [1.1.9](https://github.com/rust-lang/cc-rs/compare/cc-v1.1.8...cc-v1.1.9) - 2024-08-11 + +### Other +- Add custom CC wrapper to the wrapper whitelist ([#1175](https://github.com/rust-lang/cc-rs/pull/1175)) + +## [1.1.8](https://github.com/rust-lang/cc-rs/compare/cc-v1.1.7...cc-v1.1.8) - 2024-08-06 + +### Other +- Fix broken link in docs.rs ([#1173](https://github.com/rust-lang/cc-rs/pull/1173)) + +## [1.1.7](https://github.com/rust-lang/cc-rs/compare/cc-v1.1.6...cc-v1.1.7) - 2024-07-29 + +### Other +- add `.objects` ([#1166](https://github.com/rust-lang/cc-rs/pull/1166)) + +## [1.1.6](https://github.com/rust-lang/cc-rs/compare/cc-v1.1.5...cc-v1.1.6) - 2024-07-19 + +### Other +- Clippy fixes ([#1163](https://github.com/rust-lang/cc-rs/pull/1163)) + +## [1.1.5](https://github.com/rust-lang/cc-rs/compare/cc-v1.1.4...cc-v1.1.5) - 2024-07-15 + +### Other +- Fix cyclic compilation: Use vendored once_cell ([#1154](https://github.com/rust-lang/cc-rs/pull/1154)) + +## [1.1.4](https://github.com/rust-lang/cc-rs/compare/cc-v1.1.3...cc-v1.1.4) - 2024-07-14 + +### Other +- Support compiling on wasm targets (Supersede [#1068](https://github.com/rust-lang/cc-rs/pull/1068)) ([#1160](https://github.com/rust-lang/cc-rs/pull/1160)) + +## [1.1.3](https://github.com/rust-lang/cc-rs/compare/cc-v1.1.2...cc-v1.1.3) - 2024-07-14 + +### Other +- Reduce msrv to 1.63 ([#1158](https://github.com/rust-lang/cc-rs/pull/1158)) +- Revert "Use raw-dylib for windows-sys ([#1137](https://github.com/rust-lang/cc-rs/pull/1137))" ([#1157](https://github.com/rust-lang/cc-rs/pull/1157)) +- Fix typos ([#1152](https://github.com/rust-lang/cc-rs/pull/1152)) +- Fix `doc_lazy_continuation` lints ([#1153](https://github.com/rust-lang/cc-rs/pull/1153)) + +## [1.1.2](https://github.com/rust-lang/cc-rs/compare/cc-v1.1.1...cc-v1.1.2) - 2024-07-12 + +### Other +- Add empty `jobserver` feature. ([#1150](https://github.com/rust-lang/cc-rs/pull/1150)) + +## [1.1.1](https://github.com/rust-lang/cc-rs/compare/cc-v1.1.0...cc-v1.1.1) - 2024-07-12 + +### Other +- Fix is_flag_supported not respecting emit_rerun_if_env_changed ([#1147](https://github.com/rust-lang/cc-rs/pull/1147)) ([#1148](https://github.com/rust-lang/cc-rs/pull/1148)) + +## [1.1.0](https://github.com/rust-lang/cc-rs/compare/cc-v1.0.106...cc-v1.1.0) - 2024-07-08 + +### Added +- add cargo_output to eliminate last vestiges of stdout pollution ([#1141](https://github.com/rust-lang/cc-rs/pull/1141)) + +## [1.0.106](https://github.com/rust-lang/cc-rs/compare/cc-v1.0.105...cc-v1.0.106) - 2024-07-08 + +### Other +- Drop support for Visual Studio 12 (2013) ([#1046](https://github.com/rust-lang/cc-rs/pull/1046)) +- Use raw-dylib for windows-sys ([#1137](https://github.com/rust-lang/cc-rs/pull/1137)) +- Bump msrv to 1.67 ([#1143](https://github.com/rust-lang/cc-rs/pull/1143)) +- Bump msrv to 1.65 ([#1140](https://github.com/rust-lang/cc-rs/pull/1140)) +- Fix clippy warnings ([#1138](https://github.com/rust-lang/cc-rs/pull/1138)) + +## [1.0.105](https://github.com/rust-lang/cc-rs/compare/cc-v1.0.104...cc-v1.0.105) - 2024-07-07 + +### Other +- Regenerate windows sys bindings ([#1132](https://github.com/rust-lang/cc-rs/pull/1132)) +- Fix generate-windows-sys-bindings ([#1133](https://github.com/rust-lang/cc-rs/pull/1133)) +- Fix gen-windows-sys-binding ([#1130](https://github.com/rust-lang/cc-rs/pull/1130)) +- Fix gen-windows-sys-binding ([#1127](https://github.com/rust-lang/cc-rs/pull/1127)) +- Update windows-bindgen requirement from 0.57 to 0.58 ([#1123](https://github.com/rust-lang/cc-rs/pull/1123)) + +## [1.0.104](https://github.com/rust-lang/cc-rs/compare/cc-v1.0.103...cc-v1.0.104) - 2024-07-01 + +### Other +- Fixed link break about compile-time-requirements ([#1118](https://github.com/rust-lang/cc-rs/pull/1118)) + +## [1.0.103](https://github.com/rust-lang/cc-rs/compare/cc-v1.0.102...cc-v1.0.103) - 2024-06-30 + +### Other +- Fix compilation for wasm: env WASI_SYSROOT should be optional ([#1114](https://github.com/rust-lang/cc-rs/pull/1114)) + +## [1.0.102](https://github.com/rust-lang/cc-rs/compare/cc-v1.0.101...cc-v1.0.102) - 2024-06-29 + +### Other +- Fix invalid wasi targets compatibility ([#1105](https://github.com/rust-lang/cc-rs/pull/1105)) +- Speedup regenerate-target-info and regenerate-windows-sys ([#1110](https://github.com/rust-lang/cc-rs/pull/1110)) + +## [1.0.101](https://github.com/rust-lang/cc-rs/compare/cc-v1.0.100...cc-v1.0.101) - 2024-06-25 + +### Other +- Use `Build::getenv` instead of `env::var*` in anywhere that makes sense ([#1103](https://github.com/rust-lang/cc-rs/pull/1103)) + +## [1.0.100](https://github.com/rust-lang/cc-rs/compare/cc-v1.0.99...cc-v1.0.100) - 2024-06-23 + +### Other +- Update publish.yml to use release-plz ([#1101](https://github.com/rust-lang/cc-rs/pull/1101)) +- Accept `OsStr` instead of `str` for flags ([#1100](https://github.com/rust-lang/cc-rs/pull/1100)) +- Use `dep:` syntax to avoid implicit features. ([#1099](https://github.com/rust-lang/cc-rs/pull/1099)) +- Minor clippy fixes. ([#1098](https://github.com/rust-lang/cc-rs/pull/1098)) +- Fix WASI compilation for C++ ([#1083](https://github.com/rust-lang/cc-rs/pull/1083)) +- Regenerate windows sys bindings ([#1096](https://github.com/rust-lang/cc-rs/pull/1096)) +- Rename regenerate-windows-sys to regenerate-windows-sys.yml ([#1095](https://github.com/rust-lang/cc-rs/pull/1095)) +- Create regenerate-windows-sys.yml ([#1094](https://github.com/rust-lang/cc-rs/pull/1094)) +- Update windows-bindgen requirement from 0.56 to 0.57 ([#1091](https://github.com/rust-lang/cc-rs/pull/1091)) +- Eagerly close tempfile to fix [#1082](https://github.com/rust-lang/cc-rs/pull/1082) ([#1087](https://github.com/rust-lang/cc-rs/pull/1087)) +- Output msvc.exe in the output directory ([#1090](https://github.com/rust-lang/cc-rs/pull/1090)) +- Fix clippy warnings on Windows ([#1088](https://github.com/rust-lang/cc-rs/pull/1088)) +- Don't try to free DLL on drop ([#1089](https://github.com/rust-lang/cc-rs/pull/1089)) +- Fix panic safety issue in StderrForwarder ([#1079](https://github.com/rust-lang/cc-rs/pull/1079)) diff --git a/vendor/cc/Cargo.toml b/vendor/cc/Cargo.toml new file mode 100644 index 0000000..5d4957e --- /dev/null +++ b/vendor/cc/Cargo.toml @@ -0,0 +1,66 @@ +# 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] +edition = "2018" +rust-version = "1.63" +name = "cc" +version = "1.1.31" +authors = ["Alex Crichton "] +build = false +exclude = [ + "/.github", + "tests", + "src/bin", +] +autobins = false +autoexamples = false +autotests = false +autobenches = false +description = """ +A build-time dependency for Cargo build scripts to assist in invoking the native +C compiler to compile native C code into a static archive to be linked into Rust +code. +""" +homepage = "https://github.com/rust-lang/cc-rs" +documentation = "https://docs.rs/cc" +readme = "README.md" +keywords = ["build-dependencies"] +categories = ["development-tools::build-utils"] +license = "MIT OR Apache-2.0" +repository = "https://github.com/rust-lang/cc-rs" + +[lib] +name = "cc" +path = "src/lib.rs" + +[dependencies.jobserver] +version = "0.1.30" +optional = true +default-features = false + +[dependencies.shlex] +version = "1.3.0" + +[dev-dependencies.tempfile] +version = "3" + +[features] +jobserver = [] +parallel = [ + "dep:libc", + "dep:jobserver", +] + +[target."cfg(unix)".dependencies.libc] +version = "0.2.62" +optional = true +default-features = false diff --git a/vendor/cc/LICENSE-APACHE b/vendor/cc/LICENSE-APACHE new file mode 100644 index 0000000..16fe87b --- /dev/null +++ b/vendor/cc/LICENSE-APACHE @@ -0,0 +1,201 @@ + 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/LICENSE-MIT b/vendor/cc/LICENSE-MIT new file mode 100644 index 0000000..39e0ed6 --- /dev/null +++ b/vendor/cc/LICENSE-MIT @@ -0,0 +1,25 @@ +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/cc/README.md b/vendor/cc/README.md new file mode 100644 index 0000000..33d4bb4 --- /dev/null +++ b/vendor/cc/README.md @@ -0,0 +1,27 @@ +# cc-rs + +A library for [Cargo build scripts](https://doc.rust-lang.org/cargo/reference/build-scripts.html) +to compile a set of C/C++/assembly/CUDA files into a static archive for Cargo +to link into the crate being built. This crate does not compile code itself; +it calls out to the default compiler for the platform. This crate will +automatically detect situations such as cross compilation and +various environment variables and will build code appropriately. + +Refer to the [documentation](https://docs.rs/cc) for detailed usage instructions. + +## 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/clippy.toml b/vendor/cc/clippy.toml new file mode 100644 index 0000000..39e6cc6 --- /dev/null +++ b/vendor/cc/clippy.toml @@ -0,0 +1,5 @@ +disallowed-methods = [ + { path = "std::env::var_os", reason = "Please use Build::getenv" }, + { path = "std::env::var", reason = "Please use Build::getenv" }, +] +doc-valid-idents = ["AppleClang", "OpenBSD", ".."] diff --git a/vendor/cc/src/command_helpers.rs b/vendor/cc/src/command_helpers.rs new file mode 100644 index 0000000..9f83e38 --- /dev/null +++ b/vendor/cc/src/command_helpers.rs @@ -0,0 +1,491 @@ +//! Miscellaneous helpers for running commands + +use std::{ + collections::hash_map, + ffi::OsString, + fmt::Display, + fs, + hash::Hasher, + io::{self, Read, Write}, + path::Path, + process::{Child, ChildStderr, Command, Stdio}, + sync::{ + atomic::{AtomicBool, Ordering}, + Arc, + }, +}; + +use crate::{Error, ErrorKind, Object}; + +#[derive(Clone, Debug)] +pub(crate) struct CargoOutput { + pub(crate) metadata: bool, + pub(crate) warnings: bool, + pub(crate) debug: bool, + pub(crate) output: OutputKind, + checked_dbg_var: Arc, +} + +/// Different strategies for handling compiler output (to stdout) +#[derive(Clone, Debug)] +pub(crate) enum OutputKind { + /// Forward the output to this process' stdout ([`Stdio::inherit()`]) + Forward, + /// Discard the output ([`Stdio::null()`]) + Discard, + /// Capture the result (`[Stdio::piped()`]) + Capture, +} + +impl CargoOutput { + pub(crate) fn new() -> Self { + #[allow(clippy::disallowed_methods)] + Self { + metadata: true, + warnings: true, + output: OutputKind::Forward, + debug: match std::env::var_os("CC_ENABLE_DEBUG_OUTPUT") { + Some(v) => v != "0" && v != "false" && v != "", + None => false, + }, + checked_dbg_var: Arc::new(AtomicBool::new(false)), + } + } + + pub(crate) fn print_metadata(&self, s: &dyn Display) { + if self.metadata { + println!("{}", s); + } + } + + pub(crate) fn print_warning(&self, arg: &dyn Display) { + if self.warnings { + println!("cargo:warning={}", arg); + } + } + + pub(crate) fn print_debug(&self, arg: &dyn Display) { + if self.metadata && !self.checked_dbg_var.load(Ordering::Relaxed) { + self.checked_dbg_var.store(true, Ordering::Relaxed); + println!("cargo:rerun-if-env-changed=CC_ENABLE_DEBUG_OUTPUT"); + } + if self.debug { + println!("{}", arg); + } + } + + fn stdio_for_warnings(&self) -> Stdio { + if self.warnings { + Stdio::piped() + } else { + Stdio::null() + } + } + + fn stdio_for_output(&self) -> Stdio { + match self.output { + OutputKind::Capture => Stdio::piped(), + OutputKind::Forward => Stdio::inherit(), + OutputKind::Discard => Stdio::null(), + } + } +} + +pub(crate) struct StderrForwarder { + inner: Option<(ChildStderr, Vec)>, + #[cfg(feature = "parallel")] + is_non_blocking: bool, + #[cfg(feature = "parallel")] + bytes_available_failed: bool, + /// number of bytes buffered in inner + bytes_buffered: usize, +} + +const MIN_BUFFER_CAPACITY: usize = 100; + +impl StderrForwarder { + pub(crate) fn new(child: &mut Child) -> Self { + Self { + inner: child + .stderr + .take() + .map(|stderr| (stderr, Vec::with_capacity(MIN_BUFFER_CAPACITY))), + bytes_buffered: 0, + #[cfg(feature = "parallel")] + is_non_blocking: false, + #[cfg(feature = "parallel")] + bytes_available_failed: false, + } + } + + fn forward_available(&mut self) -> bool { + if let Some((stderr, buffer)) = self.inner.as_mut() { + loop { + // For non-blocking we check to see if there is data available, so we should try to + // read at least that much. For blocking, always read at least the minimum amount. + #[cfg(not(feature = "parallel"))] + let to_reserve = MIN_BUFFER_CAPACITY; + #[cfg(feature = "parallel")] + let to_reserve = if self.is_non_blocking && !self.bytes_available_failed { + match crate::parallel::stderr::bytes_available(stderr) { + #[cfg(windows)] + Ok(0) => break false, + #[cfg(unix)] + Ok(0) => { + // On Unix, depending on the implementation, we may sometimes get 0 in a + // loop (either there is data available or the pipe is broken), so + // continue with the non-blocking read anyway. + MIN_BUFFER_CAPACITY + } + #[cfg(windows)] + Err(_) => { + // On Windows, if we get an error then the pipe is broken, so flush + // the buffer and bail. + if !buffer.is_empty() { + write_warning(&buffer[..]); + } + self.inner = None; + break true; + } + #[cfg(unix)] + Err(_) => { + // On Unix, depending on the implementation, we may get spurious + // errors so make a note not to use bytes_available again and try + // the non-blocking read anyway. + self.bytes_available_failed = true; + MIN_BUFFER_CAPACITY + } + #[cfg(target_family = "wasm")] + Err(_) => panic!("bytes_available should always succeed on wasm"), + Ok(bytes_available) => MIN_BUFFER_CAPACITY.max(bytes_available), + } + } else { + MIN_BUFFER_CAPACITY + }; + if self.bytes_buffered + to_reserve > buffer.len() { + buffer.resize(self.bytes_buffered + to_reserve, 0); + } + + match stderr.read(&mut buffer[self.bytes_buffered..]) { + Err(err) if err.kind() == std::io::ErrorKind::WouldBlock => { + // No data currently, yield back. + break false; + } + Err(err) if err.kind() == std::io::ErrorKind::Interrupted => { + // Interrupted, try again. + continue; + } + Ok(bytes_read) if bytes_read != 0 => { + self.bytes_buffered += bytes_read; + let mut consumed = 0; + for line in buffer[..self.bytes_buffered].split_inclusive(|&b| b == b'\n') { + // Only forward complete lines, leave the rest in the buffer. + if let Some((b'\n', line)) = line.split_last() { + consumed += line.len() + 1; + write_warning(line); + } + } + if consumed > 0 && consumed < self.bytes_buffered { + // Remove the consumed bytes from buffer + buffer.copy_within(consumed.., 0); + } + self.bytes_buffered -= consumed; + } + res => { + // End of stream: flush remaining data and bail. + if self.bytes_buffered > 0 { + write_warning(&buffer[..self.bytes_buffered]); + } + if let Err(err) = res { + write_warning( + format!("Failed to read from child stderr: {err}").as_bytes(), + ); + } + self.inner.take(); + break true; + } + } + } + } else { + true + } + } + + #[cfg(feature = "parallel")] + pub(crate) fn set_non_blocking(&mut self) -> Result<(), Error> { + assert!(!self.is_non_blocking); + + #[cfg(unix)] + if let Some((stderr, _)) = self.inner.as_ref() { + crate::parallel::stderr::set_non_blocking(stderr)?; + } + + self.is_non_blocking = true; + Ok(()) + } + + #[cfg(feature = "parallel")] + fn forward_all(&mut self) { + while !self.forward_available() {} + } + + #[cfg(not(feature = "parallel"))] + fn forward_all(&mut self) { + let forward_result = self.forward_available(); + assert!(forward_result, "Should have consumed all data"); + } +} + +fn write_warning(line: &[u8]) { + let stdout = io::stdout(); + let mut stdout = stdout.lock(); + stdout.write_all(b"cargo:warning=").unwrap(); + stdout.write_all(line).unwrap(); + stdout.write_all(b"\n").unwrap(); +} + +fn wait_on_child( + cmd: &Command, + program: &Path, + child: &mut Child, + cargo_output: &CargoOutput, +) -> Result<(), Error> { + StderrForwarder::new(child).forward_all(); + + let status = match child.wait() { + Ok(s) => s, + Err(e) => { + return Err(Error::new( + ErrorKind::ToolExecError, + format!( + "Failed to wait on spawned child process, command {:?} with args {}: {}.", + cmd, + program.display(), + e + ), + )); + } + }; + + cargo_output.print_debug(&status); + + if status.success() { + Ok(()) + } else { + Err(Error::new( + ErrorKind::ToolExecError, + format!( + "Command {:?} with args {} did not execute successfully (status code {}).", + cmd, + program.display(), + status + ), + )) + } +} + +/// Find the destination object path for each file in the input source files, +/// and store them in the output Object. +pub(crate) fn objects_from_files(files: &[Arc], dst: &Path) -> Result, Error> { + let mut objects = Vec::with_capacity(files.len()); + for file in files { + let basename = file + .file_name() + .ok_or_else(|| { + Error::new( + ErrorKind::InvalidArgument, + "No file_name for object file path!", + ) + })? + .to_string_lossy(); + let dirname = file + .parent() + .ok_or_else(|| { + Error::new( + ErrorKind::InvalidArgument, + "No parent for object file path!", + ) + })? + .to_string_lossy(); + + // Hash the dirname. This should prevent conflicts if we have multiple + // object files with the same filename in different subfolders. + let mut hasher = hash_map::DefaultHasher::new(); + hasher.write(dirname.to_string().as_bytes()); + let obj = dst + .join(format!("{:016x}-{}", hasher.finish(), basename)) + .with_extension("o"); + + match obj.parent() { + Some(s) => fs::create_dir_all(s)?, + None => { + return Err(Error::new( + ErrorKind::InvalidArgument, + "dst is an invalid path with no parent", + )); + } + }; + + objects.push(Object::new(file.to_path_buf(), obj)); + } + + Ok(objects) +} + +pub(crate) fn run( + cmd: &mut Command, + program: impl AsRef, + cargo_output: &CargoOutput, +) -> Result<(), Error> { + let program = program.as_ref(); + + let mut child = spawn(cmd, program, cargo_output)?; + wait_on_child(cmd, program, &mut child, cargo_output) +} + +pub(crate) fn run_output( + cmd: &mut Command, + program: impl AsRef, + cargo_output: &CargoOutput, +) -> Result, Error> { + let program = program.as_ref(); + + // We specifically need the output to be captured, so override default + let mut captured_cargo_output = cargo_output.clone(); + captured_cargo_output.output = OutputKind::Capture; + let mut child = spawn(cmd, program, &captured_cargo_output)?; + + let mut stdout = vec![]; + child + .stdout + .take() + .unwrap() + .read_to_end(&mut stdout) + .unwrap(); + + // Don't care about this output, use the normal settings + wait_on_child(cmd, program, &mut child, cargo_output)?; + + Ok(stdout) +} + +pub(crate) fn spawn( + cmd: &mut Command, + program: &Path, + cargo_output: &CargoOutput, +) -> Result { + struct ResetStderr<'cmd>(&'cmd mut Command); + + impl Drop for ResetStderr<'_> { + fn drop(&mut self) { + // Reset stderr to default to release pipe_writer so that print thread will + // not block forever. + self.0.stderr(Stdio::inherit()); + } + } + + cargo_output.print_debug(&format_args!("running: {:?}", cmd)); + + let cmd = ResetStderr(cmd); + let child = cmd + .0 + .stderr(cargo_output.stdio_for_warnings()) + .stdout(cargo_output.stdio_for_output()) + .spawn(); + match child { + Ok(child) => Ok(child), + Err(ref e) if e.kind() == io::ErrorKind::NotFound => { + let extra = if cfg!(windows) { + " (see https://docs.rs/cc/latest/cc/#compile-time-requirements \ +for help)" + } else { + "" + }; + Err(Error::new( + ErrorKind::ToolNotFound, + format!( + "Failed to find tool. Is `{}` installed?{}", + program.display(), + extra + ), + )) + } + Err(e) => Err(Error::new( + ErrorKind::ToolExecError, + format!( + "Command {:?} with args {} failed to start: {:?}", + cmd.0, + program.display(), + e + ), + )), + } +} + +pub(crate) struct CmdAddOutputFileArgs { + pub(crate) cuda: bool, + pub(crate) is_assembler_msvc: bool, + pub(crate) msvc: bool, + pub(crate) clang: bool, + pub(crate) gnu: bool, + pub(crate) is_asm: bool, + pub(crate) is_arm: bool, +} + +pub(crate) fn command_add_output_file(cmd: &mut Command, dst: &Path, args: CmdAddOutputFileArgs) { + if args.is_assembler_msvc + || !(!args.msvc || args.clang || args.gnu || args.cuda || (args.is_asm && args.is_arm)) + { + let mut s = OsString::from("-Fo"); + s.push(dst); + cmd.arg(s); + } else { + cmd.arg("-o").arg(dst); + } +} + +#[cfg(feature = "parallel")] +pub(crate) fn try_wait_on_child( + cmd: &Command, + program: &Path, + child: &mut Child, + stdout: &mut dyn io::Write, + stderr_forwarder: &mut StderrForwarder, +) -> Result, Error> { + stderr_forwarder.forward_available(); + + match child.try_wait() { + Ok(Some(status)) => { + stderr_forwarder.forward_all(); + + let _ = writeln!(stdout, "{}", status); + + if status.success() { + Ok(Some(())) + } else { + Err(Error::new( + ErrorKind::ToolExecError, + format!( + "Command {:?} with args {} did not execute successfully (status code {}).", + cmd, + program.display(), + status + ), + )) + } + } + Ok(None) => Ok(None), + Err(e) => { + stderr_forwarder.forward_all(); + Err(Error::new( + ErrorKind::ToolExecError, + format!( + "Failed to wait on spawned child process, command {:?} with args {}: {}.", + cmd, + program.display(), + e + ), + )) + } + } +} diff --git a/vendor/cc/src/detect_compiler_family.c b/vendor/cc/src/detect_compiler_family.c new file mode 100644 index 0000000..601cee6 --- /dev/null +++ b/vendor/cc/src/detect_compiler_family.c @@ -0,0 +1,15 @@ +#ifdef __clang__ +#pragma message "clang" +#endif + +#ifdef __GNUC__ +#pragma message "gcc" +#endif + +#ifdef __EMSCRIPTEN__ +#pragma message "emscripten" +#endif + +#ifdef __VXWORKS__ +#pragma message "VxWorks" +#endif diff --git a/vendor/cc/src/lib.rs b/vendor/cc/src/lib.rs new file mode 100644 index 0000000..a7c4442 --- /dev/null +++ b/vendor/cc/src/lib.rs @@ -0,0 +1,4348 @@ +//! A library for [Cargo build scripts](https://doc.rust-lang.org/cargo/reference/build-scripts.html) +//! to compile a set of C/C++/assembly/CUDA files into a static archive for Cargo +//! to link into the crate being built. This crate does not compile code itself; +//! it calls out to the default compiler for the platform. This crate will +//! automatically detect situations such as cross compilation and +//! [various environment variables](#external-configuration-via-environment-variables) and will build code appropriately. +//! +//! # Example +//! +//! 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 +//! 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 "C" { +//! fn foo_function(); +//! fn bar_function(x: i32) -> i32; +//! } +//! +//! pub fn call() { +//! unsafe { +//! foo_function(); +//! bar_function(42); +//! } +//! } +//! +//! fn main() { +//! call(); +//! } +//! ``` +//! +//! 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. +//! * `CC_ENABLE_DEBUG_OUTPUT` - if set, compiler command invocations and exit codes will +//! be logged to stdout. This is useful for debugging build script issues, but can be +//! overly verbose for normal use. +//! * `CC_SHELL_ESCAPED_FLAGS` - if set, `*FLAGS` will be parsed as if they were shell +//! arguments (similar to `make` and `cmake`) rather than splitting them on each space. +//! For example, with `CFLAGS='a "b c"'`, the compiler will be invoked with 2 arguments - +//! `a` and `b c` - rather than 3: `a`, `"b` and `c"`. +//! * `CXX...` - see [C++ Support](#c-support). +//! +//! Furthermore, projects using this crate may specify custom environment variables +//! to be inspected, for example via the `Build::try_flags_from_environment` +//! function. Consult the project’s own documentation or its use of the `cc` crate +//! for any additional variables it may use. +//! +//! 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 Visual Studio to be installed. `cc-rs` attempts to locate it, and +//! if it fails, `cl.exe` is expected to be available in `PATH`. This 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](https://www.mingw-w64.org/) distribution. +//! 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/blob/master/INSTALL.md#building-on-windows +//! +//! # C++ support +//! +//! `cc-rs` supports C++ libraries compilation by using the `cpp` method on +//! `Build`: +//! +//! ```rust,no_run +//! cc::Build::new() +//! .cpp(true) // Switch to C++ library compilation. +//! .file("foo.cpp") +//! .compile("foo"); +//! ``` +//! +//! 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 +//! cc::Build::new() +//! .cpp(true) +//! .file("foo.cpp") +//! .cpp_link_stdlib("stdc++") // use libstdc++ +//! .compile("foo"); +//! ``` +//! 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`: +//! +//! ```rust,no_run +//! cc::Build::new() +//! // Switch to CUDA C++ library compilation using NVCC. +//! .cuda(true) +//! .cudart("static") +//! // 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") +//! // Generate code in parallel +//! .flag("-t0") +//! .file("bar.cu") +//! .compile("bar"); +//! ``` + +#![doc(html_root_url = "https://docs.rs/cc/1.0")] +#![deny(warnings)] +#![deny(missing_docs)] +#![deny(clippy::disallowed_methods)] +#![warn(clippy::doc_markdown)] + +use std::borrow::Cow; +use std::collections::HashMap; +use std::env; +use std::ffi::{OsStr, OsString}; +use std::fmt::{self, Display, Formatter}; +use std::fs; +use std::io::{self, Write}; +use std::path::{Component, Path, PathBuf}; +#[cfg(feature = "parallel")] +use std::process::Child; +use std::process::Command; +use std::sync::{Arc, RwLock}; + +use shlex::Shlex; + +#[cfg(feature = "parallel")] +mod parallel; +mod windows; +// Regardless of whether this should be in this crate's public API, +// it has been since 2015, so don't break it. +pub use windows::find_tools as windows_registry; + +mod command_helpers; +use command_helpers::*; + +mod tool; +pub use tool::Tool; +use tool::ToolFamily; + +mod target_info; +mod tempfile; + +mod utilities; +use utilities::*; + +#[derive(Debug, Eq, PartialEq, Hash)] +struct CompilerFlag { + compiler: Box, + flag: Box, +} + +type Env = Option>; + +/// 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<(Arc, Option>)>, + objects: Vec>, + flags: Vec>, + flags_supported: Vec>, + known_flag_support_status_cache: Arc>>, + ar_flags: Vec>, + asm_flags: Vec>, + no_default_flags: bool, + files: Vec>, + cpp: bool, + cpp_link_stdlib: Option>>, + cpp_set_stdlib: Option>, + cuda: bool, + cudart: Option>, + ccbin: bool, + std: Option>, + target: Option>, + /// The host compiler. + /// + /// Try to not access this directly, and instead prefer `cfg!(...)`. + host: Option>, + out_dir: Option>, + opt_level: Option>, + debug: Option, + force_frame_pointer: Option, + env: Vec<(Arc, Arc)>, + compiler: Option>, + archiver: Option>, + ranlib: Option>, + cargo_output: CargoOutput, + link_lib_modifiers: Vec>, + 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, Env>>>, + apple_sdk_root_cache: Arc, Arc>>>, + apple_versions_cache: Arc, Arc>>>, + emit_rerun_if_env_changed: bool, + cached_compiler_family: Arc, ToolFamily>>>, + shell_escaped_flags: Option, +} + +/// 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, + /// One of the function arguments failed validation. + InvalidArgument, + /// No known macro is defined for the compiler when discovering tool family + ToolFamilyMacroNotFound, + /// Invalid target + InvalidTarget, + #[cfg(feature = "parallel")] + /// jobserver helpthread failure + JobserverHelpThreadError, +} + +/// 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: Cow<'static, str>, +} + +impl Error { + fn new(kind: ErrorKind, message: impl Into>) -> Error { + Error { + kind, + message: message.into(), + } + } +} + +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 {} + +/// 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, 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_cache: Arc::new(RwLock::new(HashMap::new())), + ar_flags: Vec::new(), + asm_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, + cudart: None, + ccbin: true, + std: None, + target: None, + host: None, + out_dir: None, + opt_level: None, + debug: None, + force_frame_pointer: None, + env: Vec::new(), + compiler: None, + archiver: None, + ranlib: None, + cargo_output: CargoOutput::new(), + link_lib_modifiers: Vec::new(), + pic: None, + use_plt: None, + static_crt: None, + warnings: None, + extra_warnings: None, + warnings_into_errors: false, + env_cache: Arc::new(RwLock::new(HashMap::new())), + apple_sdk_root_cache: Arc::new(RwLock::new(HashMap::new())), + apple_versions_cache: Arc::new(RwLock::new(HashMap::new())), + emit_rerun_if_env_changed: true, + cached_compiler_family: Arc::default(), + shell_escaped_flags: None, + } + } + + /// 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().into()); + 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.into(), val.into().map(Into::into))); + self + } + + /// Add an arbitrary object file to link in + pub fn object>(&mut self, obj: P) -> &mut Build { + self.objects.push(obj.as_ref().into()); + self + } + + /// Add arbitrary object files to link in + pub fn objects

(&mut self, objs: P) -> &mut Build + where + P: IntoIterator, + P::Item: AsRef, + { + for obj in objs { + self.object(obj); + } + 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: impl AsRef) -> &mut Build { + self.flags.push(flag.as_ref().into()); + self + } + + /// Removes a compiler flag that was added by [`Build::flag`]. + /// + /// Will not remove flags added by other means (default flags, + /// flags from env, and so on). + /// + /// # Example + /// ``` + /// cc::Build::new() + /// .file("src/foo.c") + /// .flag("unwanted_flag") + /// .remove_flag("unwanted_flag"); + /// ``` + + pub fn remove_flag(&mut self, flag: &str) -> &mut Build { + self.flags.retain(|other_flag| &**other_flag != flag); + self + } + + /// Add a flag to the invocation of the ar + /// + /// # 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: impl AsRef) -> &mut Build { + self.ar_flags.push(flag.as_ref().into()); + self + } + + /// Add a flag that will only be used with assembly files. + /// + /// The flag will be applied to input files with either a `.s` or + /// `.asm` extension (case insensitive). + /// + /// # Example + /// + /// ```no_run + /// cc::Build::new() + /// .asm_flag("-Wa,-defsym,abc=1") + /// .file("src/foo.S") // The asm flag will be applied here + /// .file("src/bar.c") // The asm flag will not be applied here + /// .compile("foo"); + /// ``` + pub fn asm_flag(&mut self, flag: impl AsRef) -> &mut Build { + self.asm_flags.push(flag.as_ref().into()); + 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: impl AsRef) -> Result { + self.is_flag_supported_inner( + flag.as_ref(), + self.get_base_compiler()?.path(), + &self.get_target()?, + ) + } + + fn is_flag_supported_inner( + &self, + flag: &OsStr, + compiler_path: &Path, + target: &str, + ) -> Result { + let compiler_flag = CompilerFlag { + compiler: compiler_path.into(), + flag: flag.into(), + }; + + if let Some(is_supported) = self + .known_flag_support_status_cache + .read() + .unwrap() + .get(&compiler_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 mut compiler = { + let mut cfg = Build::new(); + cfg.flag(flag) + .compiler(compiler_path) + .cargo_metadata(self.cargo_output.metadata) + .target(target) + .opt_level(0) + .debug(false) + .cpp(self.cpp) + .cuda(self.cuda) + .emit_rerun_if_env_changed(self.emit_rerun_if_env_changed); + if let Some(host) = &self.host { + cfg.host(host); + } + 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()); + } + if compiler.is_like_clang() { + // Avoid reporting that the arg is unsupported just because the + // compiler complains that it wasn't used. + compiler.push_cc_arg("-Wno-unused-command-line-argument".into()); + } + + let mut cmd = compiler.to_command(); + let is_arm = target.contains("aarch64") || target.contains("arm"); + let clang = compiler.is_like_clang(); + let gnu = compiler.family == ToolFamily::Gnu; + command_add_output_file( + &mut cmd, + &obj, + CmdAddOutputFileArgs { + cuda: self.cuda, + is_assembler_msvc: false, + msvc: compiler.is_like_msvc(), + clang, + gnu, + is_asm: false, + is_arm, + }, + ); + + // Checking for compiler flags does not require linking + cmd.arg("-c"); + + cmd.arg(&src); + + let output = cmd.output()?; + let is_supported = output.status.success() && output.stderr.is_empty(); + + self.known_flag_support_status_cache + .write() + .unwrap() + .insert(compiler_flag, 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: impl AsRef) -> &mut Build { + self.flags_supported.push(flag.as_ref().into()); + self + } + + /// Add flags from the specified environment variable. + /// + /// Normally the `cc` crate will consult with the standard set of environment + /// variables (such as `CFLAGS` and `CXXFLAGS`) to construct the compiler invocation. Use of + /// this method provides additional levers for the end user to use when configuring the build + /// process. + /// + /// Just like the standard variables, this method will search for an environment variable with + /// appropriate target prefixes, when appropriate. + /// + /// # Examples + /// + /// This method is particularly beneficial in introducing the ability to specify crate-specific + /// flags. + /// + /// ```no_run + /// cc::Build::new() + /// .file("src/foo.c") + /// .try_flags_from_environment(concat!(env!("CARGO_PKG_NAME"), "_CFLAGS")) + /// .expect("the environment variable must be specified and UTF-8") + /// .compile("foo"); + /// ``` + /// + pub fn try_flags_from_environment(&mut self, environ_key: &str) -> Result<&mut Build, Error> { + let flags = self.envflags(environ_key)?; + self.flags.extend( + flags + .into_iter() + .map(|flag| Arc::from(OsString::from(flag).as_os_str())), + ); + Ok(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().into()); + 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 + } + + /// Get the files which will be compiled + pub fn get_files(&self) -> impl Iterator { + self.files.iter().map(AsRef::as_ref) + } + + /// Set C++ support. + /// + /// The other `cpp_*` options will only become active if this is set to + /// `true`. + /// + /// The name of the C++ standard library to link is decided by: + /// 1. If [`cpp_link_stdlib`](Build::cpp_link_stdlib) is set, use its value. + /// 2. Else if the `CXXSTDLIB` environment variable is set, use its value. + /// 3. Else the default is `c++` for OS X and BSDs, `c++_shared` for Android, + /// `None` for MSVC and `stdc++` for anything else. + pub fn cpp(&mut self, cpp: bool) -> &mut Build { + self.cpp = cpp; + self + } + + /// Set CUDA C++ support. + /// + /// Enabling CUDA will invoke the CUDA compiler, NVCC. While NVCC accepts + /// the most common compiler flags, e.g. `-std=c++17`, some project-specific + /// flags might have to be prefixed with "-Xcompiler" flag, for example as + /// `.flag("-Xcompiler").flag("-fpermissive")`. See the documentation for + /// `nvcc`, the CUDA compiler driver, at + /// for more information. + /// + /// 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.cudart = Some("static".into()); + } + self + } + + /// Link CUDA run-time. + /// + /// This option mimics the `--cudart` NVCC command-line option. Just like + /// the original it accepts `{none|shared|static}`, with default being + /// `static`. The method has to be invoked after `.cuda(true)`, or not + /// at all, if the default is right for the project. + pub fn cudart(&mut self, cudart: &str) -> &mut Build { + if self.cuda { + self.cudart = Some(cudart.into()); + } + self + } + + /// Set CUDA host compiler. + /// + /// By default, a `-ccbin` flag will be passed to NVCC to specify the + /// underlying host compiler. The value of `-ccbin` is the same as the + /// chosen C++ compiler. This is not always desired, because NVCC might + /// not support that compiler. In this case, you can remove the `-ccbin` + /// flag so that NVCC will choose the host compiler by itself. + pub fn ccbin(&mut self, ccbin: bool) -> &mut Build { + self.ccbin = ccbin; + self + } + + /// Specify the C or C++ language standard version. + /// + /// These values are common to modern versions of GCC, Clang and MSVC: + /// - `c11` for ISO/IEC 9899:2011 + /// - `c17` for ISO/IEC 9899:2018 + /// - `c++14` for ISO/IEC 14882:2014 + /// - `c++17` for ISO/IEC 14882:2017 + /// - `c++20` for ISO/IEC 14882:2020 + /// + /// Other values have less broad support, e.g. MSVC does not support `c++11` + /// (`c++14` is the minimum), `c89` (omit the flag instead) or `c99`. + /// + /// For compiling C++ code, you should also set `.cpp(true)`. + /// + /// The default is that no standard flag is passed to the compiler, so the + /// language version will be the compiler's default. + /// + /// # Example + /// + /// ```no_run + /// cc::Build::new() + /// .file("src/modern.cpp") + /// .cpp(true) + /// .std("c++17") + /// .compile("modern"); + /// ``` + pub fn std(&mut self, std: &str) -> &mut Build { + self.std = Some(std.into()); + 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. + /// + /// 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(Arc::from)); + 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 conjunction 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().map(Arc::from); + self.cpp_set_stdlib.clone_from(&cpp_set_stdlib); + self.cpp_link_stdlib = Some(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.into()); + 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.into()); + 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().into()); + 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.into()); + 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().into()); + 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().into()); + 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().into()); + self + } + + /// Configures the tool used to index 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 ranlib>(&mut self, ranlib: P) -> &mut Build { + self.ranlib = Some(ranlib.as_ref().into()); + 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` + /// - If `emit_rerun_if_env_changed` is not `false`, `rerun-if-env-changed=`*env* + /// + pub fn cargo_metadata(&mut self, cargo_metadata: bool) -> &mut Build { + self.cargo_output.metadata = cargo_metadata; + self + } + + /// Define whether compile warnings should be emitted for cargo. Defaults to + /// `true`. + /// + /// If disabled, compiler messages will not be printed. + /// Issues unrelated to the compilation will always produce cargo warnings regardless of this setting. + pub fn cargo_warnings(&mut self, cargo_warnings: bool) -> &mut Build { + self.cargo_output.warnings = cargo_warnings; + self + } + + /// Define whether debug information should be emitted for cargo. Defaults to whether + /// or not the environment variable `CC_ENABLE_DEBUG_OUTPUT` is set. + /// + /// If enabled, the compiler will emit debug information when generating object files, + /// such as the command invoked and the exit status. + pub fn cargo_debug(&mut self, cargo_debug: bool) -> &mut Build { + self.cargo_output.debug = cargo_debug; + self + } + + /// Define whether compiler output (to stdout) should be emitted. Defaults to `true` + /// (forward compiler stdout to this process' stdout) + /// + /// Some compilers emit errors to stdout, so if you *really* need stdout to be clean + /// you should also set this to `false`. + pub fn cargo_output(&mut self, cargo_output: bool) -> &mut Build { + self.cargo_output.output = if cargo_output { + OutputKind::Forward + } else { + OutputKind::Discard + }; + self + } + + /// Adds a native library modifier that will be added to the + /// `rustc-link-lib=static:MODIFIERS=LIBRARY_NAME` metadata line + /// emitted for cargo if `cargo_metadata` is enabled. + /// See + /// for the list of modifiers accepted by rustc. + pub fn link_lib_modifier(&mut self, link_lib_modifier: impl AsRef) -> &mut Build { + self.link_lib_modifiers + .push(link_lib_modifier.as_ref().into()); + 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 + } + + /// Define whether metadata should be emitted for cargo to detect environment + /// changes that should trigger a rebuild. + /// + /// NOTE that cc does not emit metadata to detect changes for `PATH`, since it could + /// be changed every comilation yet does not affect the result of compilation + /// (i.e. rust-analyzer adds temporary directory to `PATH`). + /// + /// cc in general, has no way detecting changes to compiler, as there are so many ways to + /// change it and sidestep the detection, for example the compiler might be wrapped in a script + /// so detecting change of the file, or using checksum won't work. + /// + /// We recommend users to decide for themselves, if they want rebuild if the compiler has been upgraded + /// or changed, and how to detect that. + /// + /// This has no effect if the `cargo_metadata` option is `false`. + /// + /// This option defaults to `true`. + pub fn emit_rerun_if_env_changed(&mut self, emit_rerun_if_env_changed: bool) -> &mut Build { + self.emit_rerun_if_env_changed = emit_rerun_if_env_changed; + 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 + } + + /// Configure whether *FLAGS variables are parsed using `shlex`, similarly to `make` and + /// `cmake`. + /// + /// This option defaults to `false`. + pub fn shell_escaped_flags(&mut self, shell_escaped_flags: bool) -> &mut Build { + self.shell_escaped_flags = Some(shell_escaped_flags); + 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().into(), b.as_ref().into())); + self + } + + /// Run the compiler, generating the file `output` + /// + /// This will return a result instead of panicking; see [`Self::compile()`] for + /// the complete description. + pub fn try_compile(&self, output: &str) -> Result<(), Error> { + let mut output_components = Path::new(output).components(); + match (output_components.next(), output_components.next()) { + (Some(Component::Normal(_)), None) => {} + _ => { + return Err(Error::new( + ErrorKind::InvalidArgument, + "argument of `compile` must be a single normal path component", + )); + } + } + + 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 objects = objects_from_files(&self.files, &dst)?; + + self.compile_objects(&objects)?; + self.assemble(lib_name, &dst.join(gnu_lib_name), &objects)?; + + let target = self.get_target()?; + if target.contains("msvc") { + let compiler = self.get_base_compiler()?; + let atlmfc_lib = compiler + .env() + .iter() + .find(|&(var, _)| var.as_os_str() == OsStr::new("LIB")) + .and_then(|(_, 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.cargo_output.print_metadata(&format_args!( + "cargo:rustc-link-search=native={}", + atlmfc_lib.display() + )); + } + } + + if self.link_lib_modifiers.is_empty() { + self.cargo_output + .print_metadata(&format_args!("cargo:rustc-link-lib=static={}", lib_name)); + } else { + self.cargo_output.print_metadata(&format_args!( + "cargo:rustc-link-lib=static:{}={}", + JoinOsStrs { + slice: &self.link_lib_modifiers, + delimiter: ',' + }, + lib_name + )); + } + self.cargo_output.print_metadata(&format_args!( + "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.cargo_output + .print_metadata(&format_args!("cargo:rustc-link-lib={}", stdlib.display())); + } + // Link c++ lib from WASI sysroot + if Build::is_wasi_target(target.as_ref()) { + if let Ok(wasi_sysroot) = self.wasi_sysroot() { + self.cargo_output.print_metadata(&format_args!( + "cargo:rustc-flags=-L {}/lib/{} -lstatic=c++ -lstatic=c++abi", + Path::new(&wasi_sysroot).display(), + target + )); + } + } + } + + let cudart = match &self.cudart { + Some(opt) => opt, // {none|shared|static} + None => "none", + }; + if cudart != "none" { + if let Some(nvcc) = self.which(&self.get_compiler().path, None) { + // Try to figure out the -L search path. If it fails, + // it's on user to specify one by passing it through + // RUSTFLAGS environment variable. + let mut libtst = false; + let mut libdir = nvcc; + libdir.pop(); // remove 'nvcc' + libdir.push(".."); + let target_arch = self.getenv_unwrap_str("CARGO_CFG_TARGET_ARCH")?; + if cfg!(target_os = "linux") { + libdir.push("targets"); + libdir.push(target_arch.to_owned() + "-linux"); + libdir.push("lib"); + libtst = true; + } else if cfg!(target_env = "msvc") { + libdir.push("lib"); + match target_arch.as_str() { + "x86_64" => { + libdir.push("x64"); + libtst = true; + } + "x86" => { + libdir.push("Win32"); + libtst = true; + } + _ => libtst = false, + } + } + if libtst && libdir.is_dir() { + self.cargo_output.print_metadata(&format_args!( + "cargo:rustc-link-search=native={}", + libdir.to_str().unwrap() + )); + } + + // And now the -l flag. + let lib = match cudart { + "shared" => "cudart", + "static" => "cudart_static", + bad => panic!("unsupported cudart option: {}", bad), + }; + self.cargo_output + .print_metadata(&format_args!("cargo:rustc-link-lib={}", lib)); + } + } + + Ok(()) + } + + /// Run the compiler, generating the file `output` + /// + /// # Library name + /// + /// The `output` string argument determines the file name for the compiled + /// library. The Rust compiler will create an assembly named "lib"+output+".a". + /// MSVC will create a file named output+".lib". + /// + /// The choice of `output` is close to arbitrary, but: + /// + /// - must be nonempty, + /// - must not contain a path separator (`/`), + /// - must be unique across all `compile` invocations made by the same build + /// script. + /// + /// If your build script compiles a single source file, the base name of + /// that source file would usually be reasonable: + /// + /// ```no_run + /// cc::Build::new().file("blobstore.c").compile("blobstore"); + /// ``` + /// + /// Compiling multiple source files, some people use their crate's name, or + /// their crate's name + "-cc". + /// + /// Otherwise, please use your imagination. + /// + /// For backwards compatibility, if `output` starts with "lib" *and* ends + /// with ".a", a second "lib" prefix and ".a" suffix do not get added on, + /// but this usage is deprecated; please omit `lib` and `.a` in the argument + /// that you pass. + /// + /// # 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); + } + } + + /// Run the compiler, generating intermediate files, but without linking + /// them into an archive file. + /// + /// This will return a list of compiled object files, in the same order + /// as they were passed in as `file`/`files` methods. + pub fn compile_intermediates(&self) -> Vec { + match self.try_compile_intermediates() { + Ok(v) => v, + Err(e) => fail(&e.message), + } + } + + /// Run the compiler, generating intermediate files, but without linking + /// them into an archive file. + /// + /// This will return a result instead of panicking; see `compile_intermediates()` for the complete description. + pub fn try_compile_intermediates(&self) -> Result, Error> { + let dst = self.get_out_dir()?; + let objects = objects_from_files(&self.files, &dst)?; + + self.compile_objects(&objects)?; + + Ok(objects.into_iter().map(|v| v.dst).collect()) + } + + #[cfg(feature = "parallel")] + fn compile_objects(&self, objs: &[Object]) -> Result<(), Error> { + use std::cell::Cell; + + use parallel::async_executor::{block_on, YieldOnce}; + + if objs.len() <= 1 { + for obj in objs { + let (mut cmd, name) = self.create_compile_object_cmd(obj)?; + run(&mut cmd, &name, &self.cargo_output)?; + } + + return Ok(()); + } + + // Limit our parallelism globally with a jobserver. + let mut tokens = parallel::job_token::ActiveJobTokenServer::new(); + + // 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 spawn the process to actually compile objects in + // parallel after we've acquired a token to perform some work + // + // 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 wait on all the processes and propagate the results of compilation. + + let pendings = Cell::new(Vec::<( + Command, + Cow<'static, Path>, + KillOnDrop, + parallel::job_token::JobToken, + )>::new()); + let is_disconnected = Cell::new(false); + let has_made_progress = Cell::new(false); + + let wait_future = async { + let mut error = None; + // Buffer the stdout + let mut stdout = io::BufWriter::with_capacity(128, io::stdout()); + + loop { + // If the other end of the pipe is already disconnected, then we're not gonna get any new jobs, + // so it doesn't make sense to reuse the tokens; in fact, + // releasing them as soon as possible (once we know that the other end is disconnected) is beneficial. + // Imagine that the last file built takes an hour to finish; in this scenario, + // by not releasing the tokens before that last file is done we would effectively block other processes from + // starting sooner - even though we only need one token for that last file, not N others that were acquired. + + let mut pendings_is_empty = false; + + cell_update(&pendings, |mut pendings| { + // Try waiting on them. + pendings.retain_mut(|(cmd, program, child, _token)| { + match try_wait_on_child( + cmd, + program, + &mut child.0, + &mut stdout, + &mut child.1, + ) { + Ok(Some(())) => { + // Task done, remove the entry + has_made_progress.set(true); + false + } + Ok(None) => true, // Task still not finished, keep the entry + Err(err) => { + // Task fail, remove the entry. + // Since we can only return one error, log the error to make + // sure users always see all the compilation failures. + has_made_progress.set(true); + + if self.cargo_output.warnings { + let _ = writeln!(stdout, "cargo:warning={}", err); + } + error = Some(err); + + false + } + } + }); + pendings_is_empty = pendings.is_empty(); + pendings + }); + + if pendings_is_empty && is_disconnected.get() { + break if let Some(err) = error { + Err(err) + } else { + Ok(()) + }; + } + + YieldOnce::default().await; + } + }; + let spawn_future = async { + for obj in objs { + let (mut cmd, program) = self.create_compile_object_cmd(obj)?; + let token = tokens.acquire().await?; + let mut child = spawn(&mut cmd, &program, &self.cargo_output)?; + let mut stderr_forwarder = StderrForwarder::new(&mut child); + stderr_forwarder.set_non_blocking()?; + + cell_update(&pendings, |mut pendings| { + pendings.push((cmd, program, KillOnDrop(child, stderr_forwarder), token)); + pendings + }); + + has_made_progress.set(true); + } + is_disconnected.set(true); + + Ok::<_, Error>(()) + }; + + return block_on(wait_future, spawn_future, &has_made_progress); + + struct KillOnDrop(Child, StderrForwarder); + + impl Drop for KillOnDrop { + fn drop(&mut self) { + let child = &mut self.0; + + child.kill().ok(); + } + } + + fn cell_update(cell: &Cell, f: F) + where + T: Default, + F: FnOnce(T) -> T, + { + let old = cell.take(); + let new = f(old); + cell.set(new); + } + } + + #[cfg(not(feature = "parallel"))] + fn compile_objects(&self, objs: &[Object]) -> Result<(), Error> { + for obj in objs { + let (mut cmd, name) = self.create_compile_object_cmd(obj)?; + run(&mut cmd, &name, &self.cargo_output)?; + } + + Ok(()) + } + + fn create_compile_object_cmd( + &self, + obj: &Object, + ) -> Result<(Command, Cow<'static, Path>), Error> { + let asm_ext = AsmFileExt::from_path(&obj.src); + let is_asm = asm_ext.is_some(); + let target = self.get_target()?; + let msvc = target.contains("msvc"); + let compiler = self.try_get_compiler()?; + let clang = compiler.is_like_clang(); + let gnu = compiler.family == ToolFamily::Gnu; + + let is_assembler_msvc = msvc && asm_ext == Some(AsmFileExt::DotAsm); + let (mut cmd, name) = if is_assembler_msvc { + let (cmd, name) = self.msvc_macro_assembler()?; + (cmd, Cow::Borrowed(Path::new(name))) + } else { + let mut cmd = compiler.to_command(); + for (a, 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.")) + .map(PathBuf::from) + .map(Cow::Owned)?, + ) + }; + let is_arm = target.contains("aarch64") || target.contains("arm"); + command_add_output_file( + &mut cmd, + &obj.dst, + CmdAddOutputFileArgs { + cuda: self.cuda, + is_assembler_msvc, + msvc: compiler.is_like_msvc(), + clang, + gnu, + is_asm, + is_arm, + }, + ); + // armasm and armasm64 don't requrie -c option + if !is_assembler_msvc || !is_arm { + cmd.arg("-c"); + } + if self.cuda && self.cuda_file_count() > 1 { + cmd.arg("--device-c"); + } + if is_asm { + cmd.args(self.asm_flags.iter().map(std::ops::Deref::deref)); + } + if compiler.family == (ToolFamily::Msvc { clang_cl: true }) && !is_assembler_msvc { + // #513: For `clang-cl`, separate flags/options from the input file. + // When cross-compiling macOS -> Windows, this avoids interpreting + // common `/Users/...` paths as the `/U` flag and triggering + // `-Wslash-u-filename` warning. + cmd.arg("--"); + } + cmd.arg(&obj.src); + if cfg!(target_os = "macos") { + self.fix_env_for_apple_os(&mut cmd)?; + } + + Ok((cmd, name)) + } + + /// This will return a result instead of panicking; see [`Self::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 (a, 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" + ); + + let is_asm = self + .files + .iter() + .map(std::ops::Deref::deref) + .find_map(AsmFileExt::from_path) + .is_some(); + + if compiler.family == (ToolFamily::Msvc { clang_cl: true }) && !is_asm { + // #513: For `clang-cl`, separate flags/options from the input file. + // When cross-compiling macOS -> Windows, this avoids interpreting + // common `/Users/...` paths as the `/U` flag and triggering + // `-Wslash-u-filename` warning. + cmd.arg("--"); + } + + cmd.args(self.files.iter().map(std::ops::Deref::deref)); + + let name = compiler + .path + .file_name() + .ok_or_else(|| Error::new(ErrorKind::IOError, "Failed to get compiler path."))?; + + run_output(&mut cmd, name, &self.cargo_output) + } + + /// 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 panicking; see + /// [`get_compiler()`](Self::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()?; + + // Disable default flag generation via `no_default_flags` or environment variable + let no_defaults = self.no_default_flags || self.getenv_boolean("CRATE_CC_NO_DEFAULTS"); + + if !no_defaults { + self.add_default_flags(&mut cmd, &target, &opt_level)?; + } + + if let Some(ref std) = self.std { + let separator = match cmd.family { + ToolFamily::Msvc { .. } => ':', + ToolFamily::Gnu | ToolFamily::Clang { .. } => '=', + }; + cmd.push_cc_arg(format!("-std{}{}", separator, std).into()); + } + + for directory in self.include_directories.iter() { + cmd.args.push("-I".into()); + cmd.args.push(directory.as_os_str().into()); + } + + if let Ok(flags) = self.envflags(if self.cpp { "CXXFLAGS" } else { "CFLAGS" }) { + for arg in flags { + cmd.push_cc_arg(arg.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(!self.has_flags()) { + let wflags = cmd.family.warnings_flags().into(); + cmd.push_cc_arg(wflags); + } + + if self.extra_warnings.unwrap_or(!self.has_flags()) { + 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_inner(flag, &cmd.path, &target) + .unwrap_or(false) + { + cmd.push_cc_arg((**flag).into()); + } + } + + for (key, 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"); + let features = features.as_deref().unwrap_or_default(); + if features.to_string_lossy().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.is_like_clang() { + cmd.push_opt_unless_duplicate("-Os".into()); + } else { + cmd.push_opt_unless_duplicate(format!("-O{}", opt_level).into()); + } + + if cmd.is_like_clang() && target.contains("windows") { + // Disambiguate mingw and msvc on Windows. Problem is that + // depending on the origin clang can default to a mismatchig + // run-time. + cmd.push_cc_arg(format!("--target={}", target).into()); + } + + if cmd.is_like_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") + && !target.contains("apple-watchos") + && !target.contains("apple-tvos") + && !target.contains("apple-visionos") + { + 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_else(|| { + !target.contains("windows") + && !target.contains("-none-") + && !target.ends_with("-none") + && !target.contains("uefi") + && !Build::is_wasi_target(target) + }) { + 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 Build::is_wasi_target(target) { + // WASI does not support exceptions yet. + // https://github.com/WebAssembly/exception-handling + cmd.push_cc_arg("-fno-exceptions".into()); + // Link clang sysroot + if let Ok(wasi_sysroot) = self.wasi_sysroot() { + cmd.push_cc_arg( + format!("--sysroot={}", Path::new(&wasi_sysroot).display()).into(), + ); + } + + if target.contains("threads") { + cmd.push_cc_arg("-pthread".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, self.get_dwarf_version()); + } + + if self.get_force_frame_pointer() { + let family = cmd.family; + family.add_force_frame_pointer(cmd); + } + + if !cmd.is_like_msvc() { + 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()); + } + } + + // Target flags + match cmd.family { + ToolFamily::Clang { .. } => { + if !(cmd.has_internal_target_arg + || (target.contains("android") + && android_clang_compiler_uses_target_arg_internally(&cmd.path))) + { + let (arch, rest) = target.split_once('-').ok_or_else(|| { + Error::new( + ErrorKind::InvalidTarget, + format!("Invalid target `{}`: no `-` in it", target), + ) + })?; + + 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) + { + cmd.args + .push(format!("--target={}-apple-ios-macabi", arch).into()); + } + } else if target.contains("ios-sim") { + if let Some(arch) = + map_darwin_target_from_rust_to_compiler_architecture(target) + { + let sdk_details = + apple_os_sdk_parts(AppleOs::Ios, &AppleArchSpec::Simulator("")); + let deployment_target = + self.apple_deployment_version(AppleOs::Ios, None, &sdk_details.sdk); + cmd.args.push( + format!( + "--target={}-apple-ios{}-simulator", + arch, deployment_target + ) + .into(), + ); + } + } else if target.contains("watchos-sim") { + if let Some(arch) = + map_darwin_target_from_rust_to_compiler_architecture(target) + { + let sdk_details = + apple_os_sdk_parts(AppleOs::WatchOs, &AppleArchSpec::Simulator("")); + let deployment_target = self.apple_deployment_version( + AppleOs::WatchOs, + None, + &sdk_details.sdk, + ); + cmd.args.push( + format!( + "--target={}-apple-watchos{}-simulator", + arch, deployment_target + ) + .into(), + ); + } + } else if target.contains("tvos-sim") || target.contains("x86_64-apple-tvos") { + if let Some(arch) = + map_darwin_target_from_rust_to_compiler_architecture(target) + { + let sdk_details = + apple_os_sdk_parts(AppleOs::TvOs, &AppleArchSpec::Simulator("")); + let deployment_target = self.apple_deployment_version( + AppleOs::TvOs, + None, + &sdk_details.sdk, + ); + cmd.args.push( + format!( + "--target={}-apple-tvos{}-simulator", + arch, deployment_target + ) + .into(), + ); + } + } else if target.contains("aarch64-apple-tvos") { + if let Some(arch) = + map_darwin_target_from_rust_to_compiler_architecture(target) + { + let sdk_details = + apple_os_sdk_parts(AppleOs::TvOs, &AppleArchSpec::Device("")); + let deployment_target = self.apple_deployment_version( + AppleOs::TvOs, + None, + &sdk_details.sdk, + ); + cmd.args.push( + format!("--target={}-apple-tvos{}", arch, deployment_target).into(), + ); + } + } else if target.contains("visionos-sim") { + if let Some(arch) = + map_darwin_target_from_rust_to_compiler_architecture(target) + { + let sdk_details = apple_os_sdk_parts( + AppleOs::VisionOS, + &AppleArchSpec::Simulator(""), + ); + let deployment_target = self.apple_deployment_version( + AppleOs::VisionOS, + None, + &sdk_details.sdk, + ); + cmd.args.push( + format!( + "--target={}-apple-xros{}-simulator", + arch, deployment_target + ) + .into(), + ); + } + } else if target.contains("visionos") { + if let Some(arch) = + map_darwin_target_from_rust_to_compiler_architecture(target) + { + let sdk_details = + apple_os_sdk_parts(AppleOs::VisionOS, &AppleArchSpec::Device("")); + let deployment_target = self.apple_deployment_version( + AppleOs::VisionOS, + None, + &sdk_details.sdk, + ); + cmd.args.push( + format!("--target={}-apple-xros{}", arch, deployment_target).into(), + ); + } + } else if let Ok(index) = target_info::RISCV_ARCH_MAPPING + .binary_search_by_key(&arch, |(arch, _)| arch) + { + cmd.args.push( + format!( + "--target={}-{}", + target_info::RISCV_ARCH_MAPPING[index].1, + rest + ) + .into(), + ); + } else if target.contains("uefi") { + if target.contains("x86_64") { + cmd.args.push("--target=x86_64-unknown-windows-gnu".into()); + } else if target.contains("i686") { + cmd.args.push("--target=i686-unknown-windows-gnu".into()) + } else if target.contains("aarch64") { + cmd.args.push("--target=aarch64-unknown-windows-gnu".into()) + } + } else if target.ends_with("-freebsd") { + // FreeBSD only supports C++11 and above when compiling against libc++ + // (available from FreeBSD 10 onwards). Under FreeBSD, clang uses libc++ by + // default on FreeBSD 10 and newer unless `--target` is manually passed to + // the compiler, in which case its default behavior differs: + // * If --target=xxx-unknown-freebsdX(.Y) is specified and X is greater than + // or equal to 10, clang++ uses libc++ + // * If --target=xxx-unknown-freebsd is specified (without a version), + // clang++ cannot assume libc++ is available and reverts to a default of + // libstdc++ (this behavior was changed in llvm 14). + // + // This breaks C++11 (or greater) builds if targeting FreeBSD with the + // generic xxx-unknown-freebsd triple on clang 13 or below *without* + // explicitly specifying that libc++ should be used. + // When cross-compiling, we can't infer from the rust/cargo target triple + // which major version of FreeBSD we are targeting, so we need to make sure + // that libc++ is used (unless the user has explicitly specified otherwise). + // There's no compelling reason to use a different approach when compiling + // natively. + if self.cpp && self.cpp_set_stdlib.is_none() { + cmd.push_cc_arg("-stdlib=libc++".into()); + } + + cmd.push_cc_arg(format!("--target={}", target).into()); + } else if let Ok(index) = target_info::WINDOWS_TRIPLE_MAPPING + .binary_search_by_key(&target, |(target, _)| target) + { + cmd.args.push( + format!( + "--target={}-{}", + target_info::WINDOWS_TRIPLE_MAPPING[index].1, + rest + ) + .into(), + ) + } else { + cmd.push_cc_arg(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()); + } else if target.contains("arm64ec") { + cmd.push_cc_arg("-arm64EC".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("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 target.contains("-kmc-solid_") { + cmd.args.push("-finput-charset=utf-8".into()); + } + + if self.static_flag.is_none() { + let features = self.getenv("CARGO_CFG_TARGET_FEATURE"); + let features = features.as_deref().unwrap_or_default(); + if features.to_string_lossy().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-") || target.contains("-kmc-solid_")) + { + cmd.args.push("-march=armv7-a".into()); + + if target.ends_with("eabihf") { + // lowest common denominator FPU + cmd.args.push("-mfpu=vfpv3-d16".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("arm") || target.starts_with("thumb")) + && target.ends_with("-none-eabihf") + { + cmd.args.push("-mfloat-abi=hard".into()) + } + if target.starts_with("thumb") { + cmd.args.push("-mthumb".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") { + // lowest common denominator FPU + // (see Cortex-R4 technical reference manual) + cmd.args.push("-mfpu=vfpv3-d16".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 arch.starts_with("64") { + if target.contains("linux") + | target.contains("freebsd") + | target.contains("netbsd") + | target.contains("linux") + { + cmd.args.push(("-march=rv64gc").into()); + cmd.args.push("-mabi=lp64d".into()); + } else { + cmd.args.push(("-march=rv".to_owned() + arch).into()); + cmd.args.push("-mabi=lp64".into()); + } + } else if arch.starts_with("32") { + if target.contains("linux") { + cmd.args.push(("-march=rv32gc").into()); + cmd.args.push("-mabi=ilp32d".into()); + } else { + cmd.args.push(("-march=rv".to_owned() + arch).into()); + cmd.args.push("-mabi=ilp32".into()); + } + } else { + cmd.args.push("-mcmodel=medany".into()); + } + } + } + } + } + + if target.contains("-apple-") { + self.apple_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()); + } + _ => { + self.cargo_output.print_warning(&format_args!("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.getenv_with_target_prefixes(flags_env_var_name); + flags_env_var_value.is_ok() + } + + fn msvc_macro_assembler(&self) -> Result<(Command, &'static str), 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 = self + .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") { + if self.get_debug() { + cmd.arg("-g"); + } + + for (key, value) in self.definitions.iter() { + cmd.arg("-PreDefine"); + if let Some(ref value) = *value { + if let Ok(i) = value.parse::() { + cmd.arg(format!("{} SETA {}", key, i)); + } else if value.starts_with('"') && value.ends_with('"') { + cmd.arg(format!("{} SETS {}", key, value)); + } else { + cmd.arg(format!("{} SETS \"{}\"", key, value)); + } + } else { + cmd.arg(format!("{} SETL {}", key, "{TRUE}")); + } + } + } else { + if self.get_debug() { + cmd.arg("-Zi"); + } + + for (key, 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"); + } + + Ok((cmd, tool)) + } + + 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.as_path()) + .chain(self.objects.iter().map(std::ops::Deref::deref)) + .collect(); + for chunk in objs.chunks(100) { + self.assemble_progressive(dst, chunk)?; + } + + if self.cuda && self.cuda_file_count() > 0 { + // Link the device-side code and add it to the target library, + // so that non-CUDA linker can link the final binary. + + let out_dir = self.get_out_dir()?; + let dlink = out_dir.join(lib_name.to_owned() + "_dlink.o"); + let mut nvcc = self.get_compiler().to_command(); + nvcc.arg("--device-link").arg("-o").arg(&dlink).arg(dst); + run(&mut nvcc, "nvcc", &self.cargo_output)?; + self.assemble_progressive(dst, &[dlink.as_path()])?; + } + + 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, _any_flags) = self.get_ar()?; + + // NOTE: We add `s` even if flags were passed using $ARFLAGS/ar_flag, because `s` + // here represents a _mode_, not an arbitrary flag. Further discussion of this choice + // can be seen in https://github.com/rust-lang/cc-rs/pull/763. + run(ar.arg("s").arg(dst), &cmd, &self.cargo_output)?; + } + + Ok(()) + } + + fn assemble_progressive(&self, dst: &Path, objs: &[&Path]) -> Result<(), Error> { + let target = self.get_target()?; + + let (mut cmd, program, any_flags) = self.get_ar()?; + if target.contains("msvc") && !program.to_string_lossy().contains("llvm-ar") { + // NOTE: -out: here is an I/O flag, and so must be included even if $ARFLAGS/ar_flag is + // in use. -nologo on the other hand is just a regular flag, and one that we'll skip if + // the caller has explicitly dictated the flags they want. See + // https://github.com/rust-lang/cc-rs/pull/763 for further discussion. + let mut out = OsString::from("-out:"); + out.push(dst); + cmd.arg(out); + if !any_flags { + cmd.arg("-nologo"); + } + // If the library file already exists, add the library 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, &self.cargo_output)?; + } else { + // 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! + cmd.env("ZERO_AR_DATE", "1"); + + // NOTE: We add cq here regardless of whether $ARFLAGS/ar_flag have been used because + // it dictates the _mode_ ar runs in, which the setter of $ARFLAGS/ar_flag can't + // dictate. See https://github.com/rust-lang/cc-rs/pull/763 for further discussion. + run( + cmd.arg("cq").arg(dst).args(objs), + &program, + &self.cargo_output, + )?; + } + + Ok(()) + } + + fn apple_flags(&self, cmd: &mut Tool) -> Result<(), Error> { + let target = self.get_target()?; + let os = if target.contains("-darwin") { + AppleOs::MacOs + } else if target.contains("-watchos") { + AppleOs::WatchOs + } else if target.contains("-tvos") { + AppleOs::TvOs + } else if target.contains("-visionos") { + AppleOs::VisionOS + } else { + AppleOs::Ios + }; + let is_mac = matches!(os, AppleOs::MacOs); + + let arch_str = target.split('-').nth(0).ok_or_else(|| { + Error::new( + ErrorKind::ArchitectureInvalid, + format!("Unknown architecture for {:?} target.", os), + ) + })?; + + let is_catalyst = match target.split('-').nth(3) { + Some(v) => v == "macabi", + None => false, + }; + + let is_arm_sim = match target.split('-').nth(3) { + Some(v) => v == "sim", + None => false, + }; + + let arch = if is_mac { + match arch_str { + "i686" => AppleArchSpec::Device("-m32"), + "x86_64" | "x86_64h" | "aarch64" | "arm64e" => AppleArchSpec::Device("-m64"), + _ => { + return Err(Error::new( + ErrorKind::ArchitectureInvalid, + "Unknown architecture for macOS target.", + )); + } + } + } else if is_catalyst { + match arch_str { + "arm64e" => AppleArchSpec::Catalyst("arm64e"), + "arm64" | "aarch64" => AppleArchSpec::Catalyst("arm64"), + "x86_64" | "x86_64h" => AppleArchSpec::Catalyst("-m64"), + _ => { + return Err(Error::new( + ErrorKind::ArchitectureInvalid, + "Unknown architecture for iOS target.", + )); + } + } + } else if is_arm_sim { + match arch_str { + "arm64" | "aarch64" => AppleArchSpec::Simulator("arm64"), + "x86_64" | "x86_64h" => AppleArchSpec::Simulator("-m64"), + _ => { + return Err(Error::new( + ErrorKind::ArchitectureInvalid, + "Unknown architecture for simulator target.", + )); + } + } + } else { + match arch_str { + "arm" | "armv7" | "thumbv7" => AppleArchSpec::Device("armv7"), + "armv7k" => AppleArchSpec::Device("armv7k"), + "armv7s" | "thumbv7s" => AppleArchSpec::Device("armv7s"), + "arm64e" => AppleArchSpec::Device("arm64e"), + "arm64" | "aarch64" => AppleArchSpec::Device("arm64"), + "arm64_32" => AppleArchSpec::Device("arm64_32"), + "i386" | "i686" => AppleArchSpec::Simulator("-m32"), + "x86_64" | "x86_64h" => AppleArchSpec::Simulator("-m64"), + _ => { + return Err(Error::new( + ErrorKind::ArchitectureInvalid, + format!("Unknown architecture for {:?} target.", os), + )); + } + } + }; + + let sdk_details = apple_os_sdk_parts(os, &arch); + let min_version = self.apple_deployment_version(os, Some(arch_str), &sdk_details.sdk); + + match arch { + AppleArchSpec::Device(_) if is_mac => { + cmd.args + .push(format!("-mmacosx-version-min={}", min_version).into()); + } + AppleArchSpec::Device(arch) => { + cmd.args.push("-arch".into()); + cmd.args.push(arch.into()); + // `-mxros-version-min` does not exist + // https://github.com/llvm/llvm-project/issues/88271 + if os != AppleOs::VisionOS { + cmd.args.push( + format!("-m{}os-version-min={}", sdk_details.sdk_prefix, min_version) + .into(), + ); + } + } + AppleArchSpec::Simulator(arch) => { + if arch.starts_with('-') { + // -m32 or -m64 + cmd.args.push(arch.into()); + } else { + cmd.args.push("-arch".into()); + cmd.args.push(arch.into()); + } + if os != AppleOs::VisionOS { + cmd.args.push( + format!( + "-m{}simulator-version-min={}", + sdk_details.sim_prefix, min_version + ) + .into(), + ); + } + } + AppleArchSpec::Catalyst(_) => {} + }; + + // AppleClang sometimes requires sysroot even for darwin + if cmd.is_xctoolchain_clang() || !target.ends_with("-darwin") { + self.cargo_output.print_metadata(&format_args!( + "Detecting {:?} SDK path for {}", + os, sdk_details.sdk + )); + let sdk_path = self.apple_sdk_root(&sdk_details.sdk)?; + + cmd.args.push("-isysroot".into()); + cmd.args.push(OsStr::new(&sdk_path).to_owned()); + + if let AppleArchSpec::Catalyst(_) = arch { + // Mac Catalyst uses the macOS SDK, but to compile against and + // link to iOS-specific frameworks, we should have the support + // library stubs in the include and library search path. + let ios_support = Path::new(&sdk_path).join("System/iOSSupport"); + + cmd.args.extend([ + // Header search path + OsString::from("-isystem"), + ios_support.join("usr/include").into(), + // Framework header search path + OsString::from("-iframework"), + ios_support.join("System/Library/Frameworks").into(), + // Library search path + { + let mut s = OsString::from("-L"); + s.push(ios_support.join("usr/lib")); + s + }, + // Framework linker search path + { + // Technically, we _could_ avoid emitting `-F`, as + // `-iframework` implies it, but let's keep it in for + // clarity. + let mut s = OsString::from("-F"); + s.push(ios_support.join("System/Library/Frameworks")); + s + }, + ]); + } + } + + Ok(()) + } + + fn cmd>(&self, prog: P) -> Command { + let mut cmd = Command::new(prog); + for (a, b) in self.env.iter() { + cmd.env(a, b); + } + cmd + } + + fn get_base_compiler(&self) -> Result { + let out_dir = self.get_out_dir().ok(); + let out_dir = out_dir.as_deref(); + + if let Some(c) = &self.compiler { + return Ok(Tool::new( + (**c).to_owned(), + &self.cached_compiler_family, + &self.cargo_output, + out_dir, + )); + } + let target = self.get_target()?; + let target = &*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 cfg!(target_os = "solaris") || cfg!(target_os = "illumos") { + gnu + } else { + traditional + }; + + let cl_exe = self.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( + tool, + driver_mode, + &self.cached_compiler_family, + &self.cargo_output, + out_dir, + ); + if let Some(cc_wrapper) = wrapper { + t.cc_wrapper_path = Some(Path::new(&cc_wrapper).to_owned()); + } + 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::with_family( + PathBuf::from("cmd"), + ToolFamily::Clang { zig_cc: false }, + ); + t.args.push("/c".into()); + t.args.push(format!("{}.bat", tool).into()); + Some(t) + } else { + Some(Tool::new( + PathBuf::from(tool), + &self.cached_compiler_family, + &self.cargo_output, + out_dir, + )) + } + } else { + None + } + }) + .or_else(|| cl_exe.clone()); + + let tool = match tool_opt { + Some(t) => t, + None => { + let compiler = if cfg!(windows) && target.contains("windows") { + if target.contains("msvc") { + msvc.to_string() + } else { + let cc = if target.contains("llvm") { clang } else { gnu }; + format!("{}.exe", cc) + } + } else if target.contains("apple-ios") + | target.contains("apple-watchos") + | target.contains("apple-tvos") + | target.contains("apple-visionos") + { + clang.to_string() + } else if target.contains("android") { + autodetect_android_compiler(target, gnu, clang) + } else if target.contains("cloudabi") { + format!("{}-{}", target, traditional) + } else if Build::is_wasi_target(target) { + if self.cpp { + "clang++".to_string() + } else { + "clang".to_string() + } + } else if target.contains("vxworks") { + if self.cpp { + "wr-c++".to_string() + } else { + "wr-cc".to_string() + } + } else if target.starts_with("armv7a-kmc-solid_") { + format!("arm-kmc-eabi-{}", gnu) + } else if target.starts_with("aarch64-kmc-solid_") { + format!("aarch64-kmc-elf-{}", gnu) + } else if self.get_is_cross_compile()? { + let prefix = self.prefix_for_target(target); + match prefix { + Some(prefix) => { + let cc = if target.contains("llvm") { clang } else { gnu }; + format!("{}-{}", prefix, cc) + } + None => default.to_string(), + } + } else { + default.to_string() + }; + + let mut t = Tool::new( + PathBuf::from(compiler), + &self.cached_compiler_family, + &self.cargo_output, + out_dir, + ); + if let Some(cc_wrapper) = self.rustc_wrapper_fallback() { + t.cc_wrapper_path = Some(Path::new(&cc_wrapper).to_owned()); + } + t + } + }; + + let mut tool = if self.cuda { + assert!( + tool.args.is_empty(), + "CUDA compilation currently assumes empty pre-existing args" + ); + let nvcc = match self.getenv_with_target_prefixes("NVCC") { + Err(_) => PathBuf::from("nvcc"), + Ok(nvcc) => PathBuf::from(&*nvcc), + }; + let mut nvcc_tool = Tool::with_features( + nvcc, + None, + self.cuda, + &self.cached_compiler_family, + &self.cargo_output, + out_dir, + ); + if self.ccbin { + 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 construct the + // `--target=` ourselves. + if cfg!(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.has_internal_target_arg = true; + 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.is_empty() + && target.contains("msvc") + { + for (k, v) in cl_exe.env.iter() { + tool.env.push((k.to_owned(), v.to_owned())); + } + } + } + + if target.contains("msvc") && tool.family == ToolFamily::Gnu { + self.cargo_output + .print_warning(&"GNU compiler is not supported for this target"); + } + + Ok(tool) + } + + /// Returns a fallback `cc_compiler_wrapper` by introspecting `RUSTC_WRAPPER` + fn rustc_wrapper_fallback(&self) -> 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) + const VALID_WRAPPERS: &[&str] = &["sccache", "cachepot", "buildcache"]; + + let rustc_wrapper = self.getenv("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) + } else { + None + } + } + + /// Returns compiler path, optional modifier name from whitelist, and arguments vec + fn env_tool(&self, name: &str) -> Option<(PathBuf, Option>, Vec)> { + let tool = self.getenv_with_target_prefixes(name).ok()?; + let tool = tool.to_string_lossy(); + let tool = tool.trim(); + + if tool.is_empty() { + 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(( + PathBuf::from(tool), + self.rustc_wrapper_fallback(), + 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 mut known_wrappers = vec![ + "ccache", + "distcc", + "sccache", + "icecc", + "cachepot", + "buildcache", + ]; + let custom_wrapper = self.getenv("CC_KNOWN_WRAPPER_CUSTOM"); + if custom_wrapper.is_some() { + known_wrappers.push(custom_wrapper.as_deref().unwrap().to_str().unwrap()); + } + + 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()?.to_str()?; + if known_wrappers.contains(&file_stem) { + if let Some(compiler) = parts.next() { + return Some(( + compiler.into(), + Some(Arc::::from(OsStr::new(&maybe_wrapper))), + parts.map(|s| s.to_string()).collect(), + )); + } + } + + Some(( + maybe_wrapper.into(), + 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 `c++` for OS X and BSDs, `c++_shared` for Android, + /// `None` for MSVC and `stdc++` for anything else. + fn get_cpp_link_stdlib(&self) -> Result>, Error> { + match &self.cpp_link_stdlib { + Some(s) => Ok(s.as_deref().map(Path::new).map(Cow::Borrowed)), + None => { + if let Ok(stdlib) = self.getenv_with_target_prefixes("CXXSTDLIB") { + if stdlib.is_empty() { + Ok(None) + } else { + Ok(Some(Cow::Owned(Path::new(&stdlib).to_owned()))) + } + } else { + let target = self.get_target()?; + if target.contains("msvc") { + Ok(None) + } else if target.contains("apple") + | target.contains("freebsd") + | target.contains("openbsd") + | target.contains("aix") + | target.contains("linux-ohos") + | target.contains("-wasi") + { + Ok(Some(Cow::Borrowed(Path::new("c++")))) + } else if target.contains("android") { + Ok(Some(Cow::Borrowed(Path::new("c++_shared")))) + } else { + Ok(Some(Cow::Borrowed(Path::new("stdc++")))) + } + } + } + } + } + + fn get_ar(&self) -> Result<(Command, PathBuf, bool), Error> { + self.try_get_archiver_and_flags() + } + + /// Get the archiver (ar) that's in use for this configuration. + /// + /// You can use [`Command::get_program`] to get just the path to the command. + /// + /// 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_archiver(&self) -> Command { + match self.try_get_archiver() { + Ok(tool) => tool, + Err(e) => fail(&e.message), + } + } + + /// Get the archiver that's in use for this configuration. + /// + /// This will return a result instead of panicking; + /// see [`Self::get_archiver`] for the complete description. + pub fn try_get_archiver(&self) -> Result { + Ok(self.try_get_archiver_and_flags()?.0) + } + + fn try_get_archiver_and_flags(&self) -> Result<(Command, PathBuf, bool), Error> { + let (mut cmd, name) = self.get_base_archiver()?; + let mut any_flags = false; + if let Ok(flags) = self.envflags("ARFLAGS") { + any_flags |= !flags.is_empty(); + cmd.args(flags); + } + for flag in &self.ar_flags { + any_flags = true; + cmd.arg(&**flag); + } + Ok((cmd, name, any_flags)) + } + + fn get_base_archiver(&self) -> Result<(Command, PathBuf), Error> { + if let Some(ref a) = self.archiver { + let archiver = &**a; + return Ok((self.cmd(archiver), archiver.into())); + } + + self.get_base_archiver_variant("AR", "ar") + } + + /// Get the ranlib that's in use for this configuration. + /// + /// You can use [`Command::get_program`] to get just the path to the command. + /// + /// 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_ranlib(&self) -> Command { + match self.try_get_ranlib() { + Ok(tool) => tool, + Err(e) => fail(&e.message), + } + } + + /// Get the ranlib that's in use for this configuration. + /// + /// This will return a result instead of panicking; + /// see [`Self::get_ranlib`] for the complete description. + pub fn try_get_ranlib(&self) -> Result { + let mut cmd = self.get_base_ranlib()?; + if let Ok(flags) = self.envflags("RANLIBFLAGS") { + cmd.args(flags); + } + Ok(cmd) + } + + fn get_base_ranlib(&self) -> Result { + if let Some(ref r) = self.ranlib { + return Ok(self.cmd(&**r)); + } + + Ok(self.get_base_archiver_variant("RANLIB", "ranlib")?.0) + } + + fn get_base_archiver_variant( + &self, + env: &str, + tool: &str, + ) -> Result<(Command, PathBuf), Error> { + let target = self.get_target()?; + let mut name = PathBuf::new(); + let tool_opt: Option = self + .env_tool(env) + .map(|(tool, _wrapper, args)| { + name.clone_from(&tool); + let mut cmd = self.cmd(tool); + cmd.args(args); + cmd + }) + .or_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"); + name = format!("em{}.bat", tool).into(); + cmd.arg("/c").arg(&name); + Some(cmd) + } else { + name = format!("em{}", tool).into(); + Some(self.cmd(&name)) + } + } else if target.starts_with("wasm32") { + // Formally speaking one should be able to use this approach, + // parsing -print-search-dirs output, to cover all clang targets, + // including Android SDKs and other cross-compilation scenarios... + // And even extend it to gcc targets by searching for "ar" instead + // of "llvm-ar"... + let compiler = self.get_base_compiler().ok()?; + if compiler.is_like_clang() { + name = format!("llvm-{}", tool).into(); + self.search_programs( + &mut self.cmd(&compiler.path), + &name, + &self.cargo_output, + ) + .map(|name| self.cmd(name)) + } else { + None + } + } else { + None + } + }); + + let default = tool.to_string(); + let tool = match tool_opt { + Some(t) => t, + None => { + if target.contains("android") { + name = format!("llvm-{}", tool).into(); + match Command::new(&name).arg("--version").status() { + Ok(status) if status.success() => (), + _ => name = format!("{}-{}", target.replace("armv7", "arm"), tool).into(), + } + self.cmd(&name) + } else if target.contains("msvc") { + // NOTE: There isn't really a ranlib on msvc, so arguably we should return + // `None` somehow here. But in general, callers will already have to be aware + // of not running ranlib on Windows anyway, so it feels okay to return lib.exe + // here. + + let compiler = self.get_base_compiler()?; + let mut lib = String::new(); + if compiler.family == (ToolFamily::Msvc { clang_cl: true }) { + // See if there is 'llvm-lib' next to 'clang-cl' + // Another possibility could be to see if there is 'clang' + // next to 'clang-cl' and use 'search_programs()' to locate + // 'llvm-lib'. This is because 'clang-cl' doesn't support + // the -print-search-dirs option. + if let Some(mut cmd) = self.which(&compiler.path, None) { + cmd.pop(); + cmd.push("llvm-lib.exe"); + if let Some(llvm_lib) = self.which(&cmd, None) { + llvm_lib.to_str().unwrap().clone_into(&mut lib); + } + } + } + + if lib.is_empty() { + name = PathBuf::from("lib.exe"); + let mut cmd = match self.windows_registry_find(&target, "lib.exe") { + Some(t) => t, + None => self.cmd("lib.exe"), + }; + if target.contains("arm64ec") { + cmd.arg("/machine:arm64ec"); + } + cmd + } else { + name = lib.into(); + self.cmd(&name) + } + } 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. + name = format!("g{}", tool).into(); + self.cmd(&name) + } else if self.get_is_cross_compile()? { + match self.prefix_for_target(&target) { + Some(p) => { + // GCC uses $target-gcc-ar, whereas binutils uses $target-ar -- try both. + // Prefer -ar if it exists, as builds of `-gcc-ar` have been observed to be + // outright broken (such as when targeting freebsd with `--disable-lto` + // toolchain where the archiver attempts to load the LTO plugin anyway but + // fails to find one). + // + // The same applies to ranlib. + let mut chosen = default; + for &infix in &["", "-gcc"] { + let target_p = format!("{}{}-{}", p, infix, tool); + if Command::new(&target_p).output().is_ok() { + chosen = target_p; + break; + } + } + name = chosen.into(); + self.cmd(&name) + } + None => { + name = default.into(); + self.cmd(&name) + } + } + } else { + name = default.into(); + self.cmd(&name) + } + } + }; + + Ok((tool, name)) + } + + fn prefix_for_target(&self, target: &str) -> Option> { + // CROSS_COMPILE is of the form: "arm-linux-gnueabi-" + self.getenv("CROSS_COMPILE") + .as_deref() + .map(|s| s.to_string_lossy().trim_end_matches('-').to_owned()) + .map(Cow::Owned) + .or_else(|| { + // Put aside RUSTC_LINKER's prefix to be used as second choice, after CROSS_COMPILE + self.getenv("RUSTC_LINKER").and_then(|var| { + var.to_string_lossy() + .strip_suffix("-gcc") + .map(str::to_string) + .map(Cow::Owned) + }) + }) + .or_else(|| { + match target { + // Note: there is no `aarch64-pc-windows-gnu` target, only `-gnullvm` + "aarch64-pc-windows-gnullvm" => Some("aarch64-w64-mingw32"), + "aarch64-uwp-windows-gnu" => Some("aarch64-w64-mingw32"), + "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-gnu" => self.find_working_gnu_prefix(&[ + "i686-linux-gnu", + "x86_64-linux-gnu", // transparently support gcc-multilib + ]), // explicit None if not found, so caller knows to fall back + "i686-unknown-linux-musl" => Some("musl"), + "i686-unknown-netbsd" => Some("i486--netbsdelf"), + "loongarch64-unknown-linux-gnu" => Some("loongarch64-linux-gnu"), + "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-esp-espidf" => Some("riscv32-esp-elf"), + "riscv32imac-unknown-none-elf" => self.find_working_gnu_prefix(&[ + "riscv32-unknown-elf", + "riscv64-unknown-elf", + "riscv-none-embed", + ]), + "riscv32imac-unknown-xous-elf" => self.find_working_gnu_prefix(&[ + "riscv32-unknown-elf", + "riscv64-unknown-elf", + "riscv-none-embed", + ]), + "riscv32imc-esp-espidf" => Some("riscv32-esp-elf"), + "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"), + "riscv64gc-unknown-netbsd" => Some("riscv64--netbsd"), + "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"), + "armv8r-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-pc-windows-gnullvm" => 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-gnu" => self.find_working_gnu_prefix(&[ + "x86_64-linux-gnu", // rustfmt wrap + ]), // explicit None if not found, so caller knows to fall back + "x86_64-unknown-linux-musl" => Some("musl"), + "x86_64-unknown-netbsd" => Some("x86_64--netbsd"), + _ => None, + } + .map(Cow::Borrowed) + }) + } + + /// 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. + self.getenv("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 + }) + }) + .copied() + // 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. + .or_else(|| prefixes.first().copied()) + } + + fn get_target(&self) -> Result, Error> { + match &self.target { + Some(t) => Ok(Cow::Borrowed(t)), + None => self.getenv_unwrap_str("TARGET").map(Cow::Owned), + } + } + + fn get_is_cross_compile(&self) -> Result { + let target = self.get_target()?; + let host: Cow<'_, str> = match &self.host { + Some(h) => Cow::Borrowed(h), + None => Cow::Owned(self.getenv_unwrap_str("HOST")?), + }; + Ok(host != target) + } + + fn get_opt_level(&self) -> Result, Error> { + match &self.opt_level { + Some(ol) => Ok(Cow::Borrowed(ol)), + None => self.getenv_unwrap_str("OPT_LEVEL").map(Cow::Owned), + } + } + + fn get_debug(&self) -> bool { + self.debug.unwrap_or_else(|| self.getenv_boolean("DEBUG")) + } + + fn get_shell_escaped_flags(&self) -> bool { + self.shell_escaped_flags + .unwrap_or_else(|| self.getenv_boolean("CC_SHELL_ESCAPED_FLAGS")) + } + + fn get_dwarf_version(&self) -> Option { + // Tentatively matches the DWARF version defaults as of rustc 1.62. + let target = self.get_target().ok()?; + if target.contains("android") + || target.contains("apple") + || target.contains("dragonfly") + || target.contains("freebsd") + || target.contains("netbsd") + || target.contains("openbsd") + || target.contains("windows-gnu") + { + Some(2) + } else if target.contains("linux") { + Some(4) + } else { + None + } + } + + fn get_force_frame_pointer(&self) -> bool { + self.force_frame_pointer.unwrap_or_else(|| self.get_debug()) + } + + fn get_out_dir(&self) -> Result, Error> { + match &self.out_dir { + Some(p) => Ok(Cow::Borrowed(&**p)), + None => self + .getenv("OUT_DIR") + .as_deref() + .map(PathBuf::from) + .map(Cow::Owned) + .ok_or_else(|| { + Error::new( + ErrorKind::EnvVarNotFound, + "Environment variable OUT_DIR not defined.", + ) + }), + } + } + + #[allow(clippy::disallowed_methods)] + fn getenv(&self, v: &str) -> Option> { + // Returns true for environment variables cargo sets for build scripts: + // https://doc.rust-lang.org/cargo/reference/environment-variables.html#environment-variables-cargo-sets-for-build-scripts + // + // This handles more of the vars than we actually use (it tries to check + // complete-ish set), just to avoid needing maintenance if/when new + // calls to `getenv`/`getenv_unwrap` are added. + fn provided_by_cargo(envvar: &str) -> bool { + match envvar { + v if v.starts_with("CARGO") || v.starts_with("RUSTC") => true, + "HOST" | "TARGET" | "RUSTDOC" | "OUT_DIR" | "OPT_LEVEL" | "DEBUG" | "PROFILE" + | "NUM_JOBS" | "RUSTFLAGS" => true, + _ => false, + } + } + if let Some(val) = self.env_cache.read().unwrap().get(v).cloned() { + return val; + } + // Excluding `PATH` prevents spurious rebuilds on Windows, see + // for details. + if self.emit_rerun_if_env_changed && !provided_by_cargo(v) && v != "PATH" { + self.cargo_output + .print_metadata(&format_args!("cargo:rerun-if-env-changed={}", v)); + } + let r = env::var_os(v).map(Arc::from); + self.cargo_output.print_metadata(&format_args!( + "{} = {}", + v, + OptionOsStrDisplay(r.as_deref()) + )); + self.env_cache.write().unwrap().insert(v.into(), r.clone()); + r + } + + /// get boolean flag that is either true or false + fn getenv_boolean(&self, v: &str) -> bool { + match self.getenv(v) { + Some(s) => &*s != "0" && &*s != "false" && !s.is_empty(), + None => false, + } + } + + fn getenv_unwrap(&self, v: &str) -> Result, Error> { + match self.getenv(v) { + Some(s) => Ok(s), + None => Err(Error::new( + ErrorKind::EnvVarNotFound, + format!("Environment variable {} not defined.", v), + )), + } + } + + fn getenv_unwrap_str(&self, v: &str) -> Result { + let env = self.getenv_unwrap(v)?; + env.to_str().map(String::from).ok_or_else(|| { + Error::new( + ErrorKind::EnvVarNotFound, + format!("Environment variable {} is not valid utf-8.", v), + ) + }) + } + + fn getenv_with_target_prefixes(&self, var_base: &str) -> Result, Error> { + let target = self.get_target()?; + let kind = if self.get_is_cross_compile()? { + "TARGET" + } else { + "HOST" + }; + 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) -> Result, Error> { + let env_os = self.getenv_with_target_prefixes(name)?; + let env = env_os.to_string_lossy(); + + if self.get_shell_escaped_flags() { + Ok(Shlex::new(&env).collect()) + } else { + Ok(env + .split_ascii_whitespace() + .map(ToString::to_string) + .collect()) + } + } + + fn fix_env_for_apple_os(&self, cmd: &mut Command) -> Result<(), Error> { + let target = self.get_target()?; + if cfg!(target_os = "macos") && target.contains("apple-darwin") { + // 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_inner(&self, sdk: &str) -> Result, Error> { + // Code copied from rustc's compiler/rustc_codegen_ssa/src/back/link.rs. + if let Some(sdkroot) = self.getenv("SDKROOT") { + let p = Path::new(&sdkroot); + let does_sdkroot_contain = |strings: &[&str]| { + let sdkroot_str = p.to_string_lossy(); + strings.iter().any(|s| sdkroot_str.contains(s)) + }; + match sdk { + // Ignore `SDKROOT` if it's clearly set for the wrong platform. + "appletvos" + if does_sdkroot_contain(&["TVSimulator.platform", "MacOSX.platform"]) => {} + "appletvsimulator" + if does_sdkroot_contain(&["TVOS.platform", "MacOSX.platform"]) => {} + "iphoneos" + if does_sdkroot_contain(&["iPhoneSimulator.platform", "MacOSX.platform"]) => {} + "iphonesimulator" + if does_sdkroot_contain(&["iPhoneOS.platform", "MacOSX.platform"]) => {} + "macosx10.15" + if does_sdkroot_contain(&["iPhoneOS.platform", "iPhoneSimulator.platform"]) => { + } + "watchos" + if does_sdkroot_contain(&["WatchSimulator.platform", "MacOSX.platform"]) => {} + "watchsimulator" + if does_sdkroot_contain(&["WatchOS.platform", "MacOSX.platform"]) => {} + "xros" if does_sdkroot_contain(&["XRSimulator.platform", "MacOSX.platform"]) => {} + "xrsimulator" if does_sdkroot_contain(&["XROS.platform", "MacOSX.platform"]) => {} + // Ignore `SDKROOT` if it's not a valid path. + _ if !p.is_absolute() || p == Path::new("/") || !p.exists() => {} + _ => return Ok(sdkroot), + } + } + + let sdk_path = run_output( + self.cmd("xcrun") + .arg("--show-sdk-path") + .arg("--sdk") + .arg(sdk), + "xcrun", + &self.cargo_output, + )?; + + let sdk_path = match String::from_utf8(sdk_path) { + Ok(p) => p, + Err(_) => { + return Err(Error::new( + ErrorKind::IOError, + "Unable to determine Apple SDK path.", + )); + } + }; + Ok(Arc::from(OsStr::new(sdk_path.trim()))) + } + + fn apple_sdk_root(&self, sdk: &str) -> Result, Error> { + if let Some(ret) = self + .apple_sdk_root_cache + .read() + .expect("apple_sdk_root_cache lock failed") + .get(sdk) + .cloned() + { + return Ok(ret); + } + let sdk_path = self.apple_sdk_root_inner(sdk)?; + self.apple_sdk_root_cache + .write() + .expect("apple_sdk_root_cache lock failed") + .insert(sdk.into(), sdk_path.clone()); + Ok(sdk_path) + } + + fn apple_deployment_version(&self, os: AppleOs, arch_str: Option<&str>, sdk: &str) -> Arc { + if let Some(ret) = self + .apple_versions_cache + .read() + .expect("apple_versions_cache lock failed") + .get(sdk) + .cloned() + { + return ret; + } + + let default_deployment_from_sdk = || -> Option> { + let version = run_output( + self.cmd("xcrun") + .arg("--show-sdk-version") + .arg("--sdk") + .arg(sdk), + "xcrun", + &self.cargo_output, + ) + .ok()?; + + Some(Arc::from(std::str::from_utf8(&version).ok()?.trim())) + }; + + let deployment_from_env = |name: &str| -> Option> { + // note that self.env isn't hit in production codepaths, its mostly just for tests which don't + // set the real env + self.env + .iter() + .find(|(k, _)| &**k == OsStr::new(name)) + .map(|(_, v)| v) + .cloned() + .or_else(|| self.getenv(name))? + .to_str() + .map(Arc::from) + }; + + // Determines if the acquired deployment target is too low to support modern C++ on some Apple platform. + // + // A long time ago they used libstdc++, but since macOS 10.9 and iOS 7 libc++ has been the library the SDKs provide to link against. + // If a `cc`` config wants to use C++, we round up to these versions as the baseline. + let maybe_cpp_version_baseline = |deployment_target_ver: Arc| -> Option> { + if !self.cpp { + return Some(deployment_target_ver); + } + + let mut deployment_target = deployment_target_ver + .split('.') + .map(|v| v.parse::().expect("integer version")); + + match os { + AppleOs::MacOs => { + let major = deployment_target.next().unwrap_or(0); + let minor = deployment_target.next().unwrap_or(0); + + // If below 10.9, we ignore it and let the SDK's target definitions handle it. + if major == 10 && minor < 9 { + self.cargo_output.print_warning(&format_args!( + "macOS deployment target ({}) too low, it will be increased", + deployment_target_ver + )); + return None; + } + } + AppleOs::Ios => { + let major = deployment_target.next().unwrap_or(0); + + // If below 10.7, we ignore it and let the SDK's target definitions handle it. + if major < 7 { + self.cargo_output.print_warning(&format_args!( + "iOS deployment target ({}) too low, it will be increased", + deployment_target_ver + )); + return None; + } + } + // watchOS, tvOS, visionOS, and others are all new enough that libc++ is their baseline. + _ => {} + } + + // If the deployment target met or exceeded the C++ baseline + Some(deployment_target_ver) + }; + + // The hardcoded minimums here are subject to change in a future compiler release, + // and only exist as last resort fallbacks. Don't consider them stable. + // `cc` doesn't use rustc's `--print deployment-target`` because the compiler's defaults + // don't align well with Apple's SDKs and other third-party libraries that require ~generally~ higher + // deployment targets. rustc isn't interested in those by default though so its fine to be different here. + // + // If no explicit target is passed, `cc` defaults to the current Xcode SDK's `DefaultDeploymentTarget` for better + // compatibility. This is also the crate's historical behavior and what has become a relied-on value. + // + // The ordering of env -> XCode SDK -> old rustc defaults is intentional for performance when using + // an explicit target. + let version: Arc = match os { + AppleOs::MacOs => deployment_from_env("MACOSX_DEPLOYMENT_TARGET") + .and_then(maybe_cpp_version_baseline) + .or_else(default_deployment_from_sdk) + .unwrap_or_else(|| { + if arch_str == Some("aarch64") { + "11.0".into() + } else { + let default: Arc = Arc::from("10.7"); + maybe_cpp_version_baseline(default.clone()).unwrap_or(default) + } + }), + + AppleOs::Ios => deployment_from_env("IPHONEOS_DEPLOYMENT_TARGET") + .and_then(maybe_cpp_version_baseline) + .or_else(default_deployment_from_sdk) + .unwrap_or_else(|| "7.0".into()), + + AppleOs::WatchOs => deployment_from_env("WATCHOS_DEPLOYMENT_TARGET") + .or_else(default_deployment_from_sdk) + .unwrap_or_else(|| "5.0".into()), + + AppleOs::TvOs => deployment_from_env("TVOS_DEPLOYMENT_TARGET") + .or_else(default_deployment_from_sdk) + .unwrap_or_else(|| "9.0".into()), + + AppleOs::VisionOS => deployment_from_env("XROS_DEPLOYMENT_TARGET") + .or_else(default_deployment_from_sdk) + .unwrap_or_else(|| "1.0".into()), + }; + + self.apple_versions_cache + .write() + .expect("apple_versions_cache lock failed") + .insert(sdk.into(), version.clone()); + + version + } + + fn wasi_sysroot(&self) -> Result, Error> { + if let Some(wasi_sysroot_path) = self.getenv("WASI_SYSROOT") { + Ok(wasi_sysroot_path) + } else { + Err(Error::new( + ErrorKind::EnvVarNotFound, + "Environment variable WASI_SYSROOT not defined. Download sysroot from GitHub & setup environment variable WASI_SYSROOT targeting the folder.", + )) + } + } + fn is_wasi_target(target: &str) -> bool { + const TARGETS: [&str; 7] = [ + "wasm32-wasi", + "wasm32-wasip1", + "wasm32-wasip1-threads", + "wasm32-wasip2", + "wasm32-wasi-threads", + "wasm32-unknown-wasi", + "wasm32-unknown-unknown", + ]; + TARGETS.contains(&target) + } + + fn cuda_file_count(&self) -> usize { + self.files + .iter() + .filter(|file| file.extension() == Some(OsStr::new("cu"))) + .count() + } + + fn which(&self, tool: &Path, path_entries: Option<&OsStr>) -> Option { + fn check_exe(mut exe: PathBuf) -> Option { + let exe_ext = std::env::consts::EXE_EXTENSION; + let check = + exe.exists() || (!exe_ext.is_empty() && exe.set_extension(exe_ext) && exe.exists()); + check.then_some(exe) + } + + // Loop through PATH entries searching for the |tool|. + let find_exe_in_path = |path_entries: &OsStr| -> Option { + env::split_paths(path_entries).find_map(|path_entry| check_exe(path_entry.join(tool))) + }; + + // If |tool| is not just one "word," assume it's an actual path... + if tool.components().count() > 1 { + check_exe(PathBuf::from(tool)) + } else { + path_entries + .and_then(find_exe_in_path) + .or_else(|| find_exe_in_path(&self.getenv("PATH")?)) + } + } + + /// search for |prog| on 'programs' path in '|cc| -print-search-dirs' output + fn search_programs( + &self, + cc: &mut Command, + prog: &Path, + cargo_output: &CargoOutput, + ) -> Option { + let search_dirs = run_output( + cc.arg("-print-search-dirs"), + "cc", + // this doesn't concern the compilation so we always want to show warnings. + cargo_output, + ) + .ok()?; + // clang driver appears to be forcing UTF-8 output even on Windows, + // hence from_utf8 is assumed to be usable in all cases. + let search_dirs = std::str::from_utf8(&search_dirs).ok()?; + for dirs in search_dirs.split(['\r', '\n']) { + if let Some(path) = dirs.strip_prefix("programs: =") { + return self.which(prog, Some(OsStr::new(path))); + } + } + None + } + + fn windows_registry_find(&self, target: &str, tool: &str) -> Option { + self.windows_registry_find_tool(target, tool) + .map(|c| c.to_command()) + } + + fn windows_registry_find_tool(&self, target: &str, tool: &str) -> Option { + struct BuildEnvGetter<'s>(&'s Build); + + impl windows_registry::EnvGetter for BuildEnvGetter<'_> { + fn get_env(&self, name: &str) -> Option { + self.0.getenv(name).map(windows_registry::Env::Arced) + } + } + + windows_registry::find_tool_inner(target, tool, &BuildEnvGetter(self)) + } +} + +impl Default for Build { + fn default() -> Build { + Build::new() + } +} + +fn fail(s: &str) -> ! { + eprintln!("\n\nerror occurred: {}\n\n", s); + std::process::exit(1); +} + +#[derive(Clone, Copy, PartialEq)] +enum AppleOs { + MacOs, + Ios, + WatchOs, + TvOs, + VisionOS, +} + +impl std::fmt::Debug for AppleOs { + fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { + match self { + AppleOs::MacOs => f.write_str("macOS"), + AppleOs::Ios => f.write_str("iOS"), + AppleOs::WatchOs => f.write_str("WatchOS"), + AppleOs::TvOs => f.write_str("AppleTVOS"), + AppleOs::VisionOS => f.write_str("visionOS"), + } + } +} + +struct AppleSdkTargetParts { + sdk_prefix: &'static str, + sim_prefix: &'static str, + sdk: Cow<'static, str>, +} + +fn apple_os_sdk_parts(os: AppleOs, arch: &AppleArchSpec) -> AppleSdkTargetParts { + let (sdk_prefix, sim_prefix) = match os { + AppleOs::MacOs => ("macosx", ""), + AppleOs::Ios => ("iphone", "ios-"), + AppleOs::WatchOs => ("watch", "watch"), + AppleOs::TvOs => ("appletv", "appletv"), + AppleOs::VisionOS => ("xr", "xr"), + }; + let sdk = match arch { + AppleArchSpec::Device(_) if os == AppleOs::MacOs => Cow::Borrowed("macosx"), + AppleArchSpec::Device(_) => format!("{}os", sdk_prefix).into(), + AppleArchSpec::Simulator(_) => format!("{}simulator", sdk_prefix).into(), + AppleArchSpec::Catalyst(_) => Cow::Borrowed("macosx"), + }; + + AppleSdkTargetParts { + sdk_prefix, + sim_prefix, + sdk, + } +} + +#[allow(dead_code)] +enum AppleArchSpec { + Device(&'static str), + Simulator(&'static str), + #[allow(dead_code)] + Catalyst(&'static str), +} + +// 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() { + if let Some(idx) = filename_str.rfind('-') { + return filename_str.split_at(idx).0.contains("android"); + } + } + } + false +} + +fn autodetect_android_compiler(target: &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 cfg!(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_64h") { + Some("x86_64h") + } else if target.contains("x86_64") { + Some("x86_64") + } else if target.contains("arm64e") { + Some("arm64e") + } else if target.contains("aarch64") { + Some("arm64") + } else if target.contains("i686") { + Some("i386") + } else if target.contains("powerpc") { + Some("ppc") + } else if target.contains("powerpc64") { + Some("ppc64") + } else { + None + } +} + +#[derive(Clone, Copy, PartialEq)] +enum AsmFileExt { + /// `.asm` files. On MSVC targets, we assume these should be passed to MASM + /// (`ml{,64}.exe`). + DotAsm, + /// `.s` or `.S` files, which do not have the special handling on MSVC targets. + DotS, +} + +impl AsmFileExt { + fn from_path(file: &Path) -> Option { + if let Some(ext) = file.extension() { + if let Some(ext) = ext.to_str() { + let ext = ext.to_lowercase(); + match &*ext { + "asm" => return Some(AsmFileExt::DotAsm), + "s" => return Some(AsmFileExt::DotS), + _ => return None, + } + } + } + None + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[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-i686-linux-android") + )); + assert!(!android_clang_compiler_uses_target_arg_internally( + &PathBuf::from("clang") + )); + assert!(!android_clang_compiler_uses_target_arg_internally( + &PathBuf::from("clang++") + )); + } +} diff --git a/vendor/cc/src/parallel/async_executor.rs b/vendor/cc/src/parallel/async_executor.rs new file mode 100644 index 0000000..9ebd1ad --- /dev/null +++ b/vendor/cc/src/parallel/async_executor.rs @@ -0,0 +1,118 @@ +use std::{ + cell::Cell, + future::Future, + pin::Pin, + ptr, + task::{Context, Poll, RawWaker, RawWakerVTable, Waker}, + thread, + time::Duration, +}; + +use crate::Error; + +const NOOP_WAKER_VTABLE: RawWakerVTable = RawWakerVTable::new( + // Cloning just returns a new no-op raw waker + |_| NOOP_RAW_WAKER, + // `wake` does nothing + |_| {}, + // `wake_by_ref` does nothing + |_| {}, + // Dropping does nothing as we don't allocate anything + |_| {}, +); +const NOOP_RAW_WAKER: RawWaker = RawWaker::new(ptr::null(), &NOOP_WAKER_VTABLE); + +#[derive(Default)] +pub(crate) struct YieldOnce(bool); + +impl Future for YieldOnce { + type Output = (); + + fn poll(self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<()> { + let flag = &mut std::pin::Pin::into_inner(self).0; + if !*flag { + *flag = true; + Poll::Pending + } else { + Poll::Ready(()) + } + } +} + +/// Execute the futures and return when they are all done. +/// +/// Here we use our own homebrew async executor since cc is used in the build +/// script of many popular projects, pulling in additional dependencies would +/// significantly slow down its compilation. +pub(crate) fn block_on( + mut fut1: Fut1, + mut fut2: Fut2, + has_made_progress: &Cell, +) -> Result<(), Error> +where + Fut1: Future>, + Fut2: Future>, +{ + // Shadows the future so that it can never be moved and is guaranteed + // to be pinned. + // + // The same trick used in `pin!` macro. + // + // TODO: Once MSRV is bumped to 1.68, replace this with `std::pin::pin!` + let mut fut1 = Some(unsafe { Pin::new_unchecked(&mut fut1) }); + let mut fut2 = Some(unsafe { Pin::new_unchecked(&mut fut2) }); + + // TODO: Once `Waker::noop` stablised and our MSRV is bumped to the version + // which it is stablised, replace this with `Waker::noop`. + let waker = unsafe { Waker::from_raw(NOOP_RAW_WAKER) }; + let mut context = Context::from_waker(&waker); + + let mut backoff_cnt = 0; + + loop { + has_made_progress.set(false); + + if let Some(fut) = fut2.as_mut() { + if let Poll::Ready(res) = fut.as_mut().poll(&mut context) { + fut2 = None; + res?; + } + } + + if let Some(fut) = fut1.as_mut() { + if let Poll::Ready(res) = fut.as_mut().poll(&mut context) { + fut1 = None; + res?; + } + } + + if fut1.is_none() && fut2.is_none() { + return Ok(()); + } + + if !has_made_progress.get() { + if backoff_cnt > 3 { + // We have yielded at least three times without making' + // any progress, so we will sleep for a while. + let duration = Duration::from_millis(100 * (backoff_cnt - 3).min(10)); + thread::sleep(duration); + } else { + // Given that we spawned a lot of compilation tasks, it is unlikely + // that OS cannot find other ready task to execute. + // + // If all of them are done, then we will yield them and spawn more, + // or simply return. + // + // Thus this will not be turned into a busy-wait loop and it will not + // waste CPU resource. + thread::yield_now(); + } + } + + backoff_cnt = if has_made_progress.get() { + 0 + } else { + backoff_cnt + 1 + }; + } +} diff --git a/vendor/cc/src/parallel/job_token.rs b/vendor/cc/src/parallel/job_token.rs new file mode 100644 index 0000000..2640cea --- /dev/null +++ b/vendor/cc/src/parallel/job_token.rs @@ -0,0 +1,273 @@ +use std::marker::PhantomData; + +use crate::Error; + +use super::once_lock::OnceLock; + +pub(crate) struct JobToken(PhantomData<()>); + +impl JobToken { + fn new() -> Self { + Self(PhantomData) + } +} + +impl Drop for JobToken { + fn drop(&mut self) { + match JobTokenServer::new() { + JobTokenServer::Inherited(jobserver) => jobserver.release_token_raw(), + JobTokenServer::InProcess(jobserver) => jobserver.release_token_raw(), + } + } +} + +enum JobTokenServer { + Inherited(inherited_jobserver::JobServer), + InProcess(inprocess_jobserver::JobServer), +} + +impl JobTokenServer { + /// This function returns a static reference to the jobserver because + /// - creating a jobserver from env is a bit fd-unsafe (e.g. the fd might + /// be closed by other jobserver users in the process) and better do it + /// at the start of the program. + /// - in case a jobserver cannot be created from env (e.g. it's not + /// present), we will create a global in-process only jobserver + /// that has to be static so that it will be shared by all cc + /// compilation. + fn new() -> &'static Self { + // TODO: Replace with a OnceLock once MSRV is 1.70 + static JOBSERVER: OnceLock = OnceLock::new(); + + JOBSERVER.get_or_init(|| { + unsafe { inherited_jobserver::JobServer::from_env() } + .map(Self::Inherited) + .unwrap_or_else(|| Self::InProcess(inprocess_jobserver::JobServer::new())) + }) + } +} + +pub(crate) enum ActiveJobTokenServer { + Inherited(inherited_jobserver::ActiveJobServer<'static>), + InProcess(&'static inprocess_jobserver::JobServer), +} + +impl ActiveJobTokenServer { + pub(crate) fn new() -> Self { + match JobTokenServer::new() { + JobTokenServer::Inherited(inherited_jobserver) => { + Self::Inherited(inherited_jobserver.enter_active()) + } + JobTokenServer::InProcess(inprocess_jobserver) => Self::InProcess(inprocess_jobserver), + } + } + + pub(crate) async fn acquire(&mut self) -> Result { + match self { + Self::Inherited(jobserver) => jobserver.acquire().await, + Self::InProcess(jobserver) => Ok(jobserver.acquire().await), + } + } +} + +mod inherited_jobserver { + use super::JobToken; + + use crate::{parallel::async_executor::YieldOnce, Error, ErrorKind}; + + use std::{ + io, mem, + sync::{mpsc, Mutex, MutexGuard, PoisonError}, + }; + + pub(super) struct JobServer { + /// Implicit token for this process which is obtained and will be + /// released in parent. Since JobTokens only give back what they got, + /// there should be at most one global implicit token in the wild. + /// + /// Since Rust does not execute any `Drop` for global variables, + /// we can't just put it back to jobserver and then re-acquire it at + /// the end of the process. + /// + /// Use `Mutex` to avoid race between acquire and release. + /// If an `AtomicBool` is used, then it's possible for: + /// - `release_token_raw`: Tries to set `global_implicit_token` to true, but it is already + /// set to `true`, continue to release it to jobserver + /// - `acquire` takes the global implicit token, set `global_implicit_token` to false + /// - `release_token_raw` now writes the token back into the jobserver, while + /// `global_implicit_token` is `false` + /// + /// If the program exits here, then cc effectively increases parallelism by one, which is + /// incorrect, hence we use a `Mutex` here. + global_implicit_token: Mutex, + inner: jobserver::Client, + } + + impl JobServer { + pub(super) unsafe fn from_env() -> Option { + jobserver::Client::from_env().map(|inner| Self { + inner, + global_implicit_token: Mutex::new(true), + }) + } + + fn get_global_implicit_token(&self) -> MutexGuard<'_, bool> { + self.global_implicit_token + .lock() + .unwrap_or_else(PoisonError::into_inner) + } + + /// All tokens except for the global implicit token will be put back into the jobserver + /// immediately and they cannot be cached, since Rust does not call `Drop::drop` on + /// global variables. + pub(super) fn release_token_raw(&self) { + let mut global_implicit_token = self.get_global_implicit_token(); + + if *global_implicit_token { + // There's already a global implicit token, so this token must + // be released back into jobserver. + // + // `release_raw` should not block + let _ = self.inner.release_raw(); + } else { + *global_implicit_token = true; + } + } + + pub(super) fn enter_active(&self) -> ActiveJobServer<'_> { + ActiveJobServer { + jobserver: self, + helper_thread: None, + } + } + } + + struct HelperThread { + inner: jobserver::HelperThread, + /// When rx is dropped, all the token stored within it will be dropped. + rx: mpsc::Receiver>, + } + + impl HelperThread { + fn new(jobserver: &JobServer) -> Result { + let (tx, rx) = mpsc::channel(); + + Ok(Self { + rx, + inner: jobserver.inner.clone().into_helper_thread(move |res| { + let _ = tx.send(res); + })?, + }) + } + } + + pub(crate) struct ActiveJobServer<'a> { + jobserver: &'a JobServer, + helper_thread: Option, + } + + impl<'a> ActiveJobServer<'a> { + pub(super) async fn acquire(&mut self) -> Result { + let mut has_requested_token = false; + + loop { + // Fast path + if mem::replace(&mut *self.jobserver.get_global_implicit_token(), false) { + break Ok(JobToken::new()); + } + + match self.jobserver.inner.try_acquire() { + Ok(Some(acquired)) => { + acquired.drop_without_releasing(); + break Ok(JobToken::new()); + } + Ok(None) => YieldOnce::default().await, + Err(err) if err.kind() == io::ErrorKind::Unsupported => { + // Fallback to creating a help thread with blocking acquire + let helper_thread = if let Some(thread) = self.helper_thread.as_ref() { + thread + } else { + self.helper_thread + .insert(HelperThread::new(self.jobserver)?) + }; + + match helper_thread.rx.try_recv() { + Ok(res) => { + let acquired = res?; + acquired.drop_without_releasing(); + break Ok(JobToken::new()); + } + Err(mpsc::TryRecvError::Disconnected) => break Err(Error::new( + ErrorKind::JobserverHelpThreadError, + "jobserver help thread has returned before ActiveJobServer is dropped", + )), + Err(mpsc::TryRecvError::Empty) => { + if !has_requested_token { + helper_thread.inner.request_token(); + has_requested_token = true; + } + YieldOnce::default().await + } + } + } + Err(err) => break Err(err.into()), + } + } + } + } +} + +mod inprocess_jobserver { + use super::JobToken; + + use crate::parallel::async_executor::YieldOnce; + + use std::{ + env::var, + sync::atomic::{ + AtomicU32, + Ordering::{AcqRel, Acquire}, + }, + }; + + pub(crate) struct JobServer(AtomicU32); + + impl JobServer { + pub(super) fn new() -> Self { + // 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; + // TODO: Use std::thread::available_parallelism as an upper bound + // when MSRV is bumped. + if let Ok(amt) = var("NUM_JOBS") { + if let Ok(amt) = amt.parse() { + parallelism = amt; + } + } + + Self(AtomicU32::new(parallelism)) + } + + pub(super) async fn acquire(&self) -> JobToken { + loop { + let res = self + .0 + .fetch_update(AcqRel, Acquire, |tokens| tokens.checked_sub(1)); + + if res.is_ok() { + break JobToken::new(); + } + + YieldOnce::default().await + } + } + + pub(super) fn release_token_raw(&self) { + self.0.fetch_add(1, AcqRel); + } + } +} diff --git a/vendor/cc/src/parallel/mod.rs b/vendor/cc/src/parallel/mod.rs new file mode 100644 index 0000000..70a56e7 --- /dev/null +++ b/vendor/cc/src/parallel/mod.rs @@ -0,0 +1,4 @@ +pub(crate) mod async_executor; +pub(crate) mod job_token; +pub(crate) mod once_lock; +pub(crate) mod stderr; diff --git a/vendor/cc/src/parallel/once_lock.rs b/vendor/cc/src/parallel/once_lock.rs new file mode 100644 index 0000000..c48dbb7 --- /dev/null +++ b/vendor/cc/src/parallel/once_lock.rs @@ -0,0 +1,47 @@ +use std::{ + cell::UnsafeCell, + marker::PhantomData, + mem::MaybeUninit, + panic::{RefUnwindSafe, UnwindSafe}, + sync::Once, +}; + +pub(crate) struct OnceLock { + once: Once, + value: UnsafeCell>, + _marker: PhantomData, +} + +impl OnceLock { + pub(crate) const fn new() -> Self { + Self { + once: Once::new(), + value: UnsafeCell::new(MaybeUninit::uninit()), + _marker: PhantomData, + } + } + + pub(crate) fn get_or_init(&self, f: impl FnOnce() -> T) -> &T { + self.once.call_once(|| { + unsafe { &mut *self.value.get() }.write(f()); + }); + unsafe { (&*self.value.get()).assume_init_ref() } + } +} + +unsafe impl Sync for OnceLock {} +unsafe impl Send for OnceLock {} + +impl RefUnwindSafe for OnceLock {} +impl UnwindSafe for OnceLock {} + +impl Drop for OnceLock { + #[inline] + fn drop(&mut self) { + if self.once.is_completed() { + // SAFETY: The cell is initialized and being dropped, so it can't + // be accessed again. + unsafe { self.value.get_mut().assume_init_drop() }; + } + } +} diff --git a/vendor/cc/src/parallel/stderr.rs b/vendor/cc/src/parallel/stderr.rs new file mode 100644 index 0000000..7018686 --- /dev/null +++ b/vendor/cc/src/parallel/stderr.rs @@ -0,0 +1,91 @@ +#![cfg_attr(target_family = "wasm", allow(unused))] +/// Helpers functions for [ChildStderr]. +use std::{convert::TryInto, process::ChildStderr}; + +use crate::{Error, ErrorKind}; + +#[cfg(all(not(unix), not(windows), not(target_family = "wasm")))] +compile_error!("Only unix and windows support non-blocking pipes! For other OSes, disable the parallel feature."); + +#[cfg(unix)] +fn get_flags(fd: std::os::unix::io::RawFd) -> Result { + let flags = unsafe { libc::fcntl(fd, libc::F_GETFL, 0) }; + if flags == -1 { + Err(Error::new( + ErrorKind::IOError, + format!( + "Failed to get flags for pipe {}: {}", + fd, + std::io::Error::last_os_error() + ), + )) + } else { + Ok(flags) + } +} + +#[cfg(unix)] +fn set_flags(fd: std::os::unix::io::RawFd, flags: std::os::raw::c_int) -> Result<(), Error> { + if unsafe { libc::fcntl(fd, libc::F_SETFL, flags) } == -1 { + Err(Error::new( + ErrorKind::IOError, + format!( + "Failed to set flags for pipe {}: {}", + fd, + std::io::Error::last_os_error() + ), + )) + } else { + Ok(()) + } +} + +#[cfg(unix)] +pub fn set_non_blocking(pipe: &impl std::os::unix::io::AsRawFd) -> Result<(), Error> { + // On Unix, switch the pipe to non-blocking mode. + // On Windows, we have a different way to be non-blocking. + let fd = pipe.as_raw_fd(); + + let flags = get_flags(fd)?; + set_flags(fd, flags | libc::O_NONBLOCK) +} + +pub fn bytes_available(stderr: &mut ChildStderr) -> Result { + let mut bytes_available = 0; + #[cfg(windows)] + { + use crate::windows::windows_sys::PeekNamedPipe; + use std::os::windows::io::AsRawHandle; + use std::ptr::null_mut; + if unsafe { + PeekNamedPipe( + stderr.as_raw_handle(), + null_mut(), + 0, + null_mut(), + &mut bytes_available, + null_mut(), + ) + } == 0 + { + return Err(Error::new( + ErrorKind::IOError, + format!( + "PeekNamedPipe failed with {}", + std::io::Error::last_os_error() + ), + )); + } + } + #[cfg(unix)] + { + use std::os::unix::io::AsRawFd; + if unsafe { libc::ioctl(stderr.as_raw_fd(), libc::FIONREAD, &mut bytes_available) } != 0 { + return Err(Error::new( + ErrorKind::IOError, + format!("ioctl failed with {}", std::io::Error::last_os_error()), + )); + } + } + Ok(bytes_available.try_into().unwrap()) +} diff --git a/vendor/cc/src/target_info.rs b/vendor/cc/src/target_info.rs new file mode 100644 index 0000000..085412a --- /dev/null +++ b/vendor/cc/src/target_info.rs @@ -0,0 +1,29 @@ +//! This file is generated code. Please edit the generator +//! in dev-tools/gen-target-info if you need to make changes. + +pub const RISCV_ARCH_MAPPING: &[(&str, &str)] = &[ + ("riscv32e", "riscv32"), + ("riscv32em", "riscv32"), + ("riscv32emc", "riscv32"), + ("riscv32gc", "riscv32"), + ("riscv32i", "riscv32"), + ("riscv32im", "riscv32"), + ("riscv32ima", "riscv32"), + ("riscv32imac", "riscv32"), + ("riscv32imafc", "riscv32"), + ("riscv32imc", "riscv32"), + ("riscv64gc", "riscv64"), + ("riscv64imac", "riscv64"), +]; +pub const WINDOWS_TRIPLE_MAPPING: &[(&str, &str)] = &[ + ("aarch64-pc-windows-gnullvm", "aarch64-pc-windows-gnu"), + ("aarch64-uwp-windows-msvc", "aarch64-pc-windows-msvc"), + ("i686-pc-windows-gnullvm", "i686-pc-windows-gnu"), + ("i686-uwp-windows-gnu", "i686-pc-windows-gnu"), + ("i686-uwp-windows-msvc", "i686-pc-windows-msvc"), + ("i686-win7-windows-msvc", "i686-pc-windows-msvc"), + ("thumbv7a-uwp-windows-msvc", "thumbv7a-pc-windows-msvc"), + ("x86_64-pc-windows-gnullvm", "x86_64-pc-windows-gnu"), + ("x86_64-uwp-windows-gnu", "x86_64-pc-windows-gnu"), + ("x86_64-uwp-windows-msvc", "x86_64-pc-windows-msvc"), +]; diff --git a/vendor/cc/src/tempfile.rs b/vendor/cc/src/tempfile.rs new file mode 100644 index 0000000..833e6f2 --- /dev/null +++ b/vendor/cc/src/tempfile.rs @@ -0,0 +1,86 @@ +#![cfg_attr(target_family = "wasm", allow(unused))] + +use std::{ + collections::hash_map::RandomState, + fs::{remove_file, File, OpenOptions}, + hash::{BuildHasher, Hasher}, + io, os, + path::{Path, PathBuf}, +}; + +#[cfg(not(any(unix, target_family = "wasm", windows)))] +compile_error!("Your system is not supported since cc cannot create named tempfile"); + +fn rand() -> u64 { + RandomState::new().build_hasher().finish() +} + +fn tmpname(suffix: &str) -> String { + format!("{}{}", rand(), suffix) +} + +fn create_named(path: &Path) -> io::Result { + let mut open_options = OpenOptions::new(); + + open_options.read(true).write(true).create_new(true); + + #[cfg(all(unix, not(target_os = "wasi")))] + ::mode(&mut open_options, 0o600); + + #[cfg(windows)] + ::custom_flags( + &mut open_options, + crate::windows::windows_sys::FILE_ATTRIBUTE_TEMPORARY, + ); + + open_options.open(path) +} + +pub(super) struct NamedTempfile { + path: PathBuf, + file: Option, +} + +impl NamedTempfile { + pub(super) fn new(base: &Path, suffix: &str) -> io::Result { + for _ in 0..10 { + let path = base.join(tmpname(suffix)); + match create_named(&path) { + Ok(file) => { + return Ok(Self { + file: Some(file), + path, + }) + } + Err(e) if e.kind() == io::ErrorKind::AlreadyExists => continue, + Err(e) => return Err(e), + }; + } + + Err(io::Error::new( + io::ErrorKind::AlreadyExists, + format!( + "too many temporary files exist in base `{}` with suffix `{}`", + base.display(), + suffix + ), + )) + } + + pub(super) fn path(&self) -> &Path { + &self.path + } + + pub(super) fn take_file(&mut self) -> Option { + self.file.take() + } +} + +impl Drop for NamedTempfile { + fn drop(&mut self) { + // On Windows you have to close all handle to it before + // removing the file. + self.file.take(); + let _ = remove_file(&self.path); + } +} diff --git a/vendor/cc/src/tool.rs b/vendor/cc/src/tool.rs new file mode 100644 index 0000000..c34bc2b --- /dev/null +++ b/vendor/cc/src/tool.rs @@ -0,0 +1,476 @@ +use std::{ + borrow::Cow, + collections::HashMap, + env, + ffi::{OsStr, OsString}, + io::Write, + path::{Path, PathBuf}, + process::Command, + sync::RwLock, +}; + +use crate::{ + command_helpers::{run_output, CargoOutput}, + run, + tempfile::NamedTempfile, + Error, ErrorKind, OutputKind, +}; + +/// 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)] +#[allow(missing_docs)] +pub struct Tool { + pub(crate) path: PathBuf, + pub(crate) cc_wrapper_path: Option, + pub(crate) cc_wrapper_args: Vec, + pub(crate) args: Vec, + pub(crate) env: Vec<(OsString, OsString)>, + pub(crate) family: ToolFamily, + pub(crate) cuda: bool, + pub(crate) removed_args: Vec, + pub(crate) has_internal_target_arg: bool, +} + +impl Tool { + pub(crate) fn new( + path: PathBuf, + cached_compiler_family: &RwLock, ToolFamily>>, + cargo_output: &CargoOutput, + out_dir: Option<&Path>, + ) -> Self { + Self::with_features( + path, + None, + false, + cached_compiler_family, + cargo_output, + out_dir, + ) + } + + pub(crate) fn with_clang_driver( + path: PathBuf, + clang_driver: Option<&str>, + cached_compiler_family: &RwLock, ToolFamily>>, + cargo_output: &CargoOutput, + out_dir: Option<&Path>, + ) -> Self { + Self::with_features( + path, + clang_driver, + false, + cached_compiler_family, + cargo_output, + out_dir, + ) + } + + /// Explicitly set the `ToolFamily`, skipping name-based detection. + pub(crate) fn with_family(path: PathBuf, family: ToolFamily) -> Self { + Self { + path, + cc_wrapper_path: None, + cc_wrapper_args: Vec::new(), + args: Vec::new(), + env: Vec::new(), + family, + cuda: false, + removed_args: Vec::new(), + has_internal_target_arg: false, + } + } + + pub(crate) fn with_features( + path: PathBuf, + clang_driver: Option<&str>, + cuda: bool, + cached_compiler_family: &RwLock, ToolFamily>>, + cargo_output: &CargoOutput, + out_dir: Option<&Path>, + ) -> Self { + fn is_zig_cc(path: &Path, cargo_output: &CargoOutput) -> bool { + run_output( + Command::new(path).arg("--version"), + path, + // tool detection issues should always be shown as warnings + cargo_output, + ) + .map(|o| String::from_utf8_lossy(&o).contains("ziglang")) + .unwrap_or_default() + } + + fn detect_family_inner( + path: &Path, + cargo_output: &CargoOutput, + out_dir: Option<&Path>, + ) -> Result { + let out_dir = out_dir + .map(Cow::Borrowed) + .unwrap_or_else(|| Cow::Owned(env::temp_dir())); + + // Ensure all the parent directories exist otherwise temp file creation + // will fail + std::fs::create_dir_all(&out_dir).map_err(|err| Error { + kind: ErrorKind::IOError, + message: format!("failed to create OUT_DIR '{}': {}", out_dir.display(), err) + .into(), + })?; + + let mut tmp = + NamedTempfile::new(&out_dir, "detect_compiler_family.c").map_err(|err| Error { + kind: ErrorKind::IOError, + message: format!( + "failed to create detect_compiler_family.c temp file in '{}': {}", + out_dir.display(), + err + ) + .into(), + })?; + let mut tmp_file = tmp.take_file().unwrap(); + tmp_file.write_all(include_bytes!("detect_compiler_family.c"))?; + // Close the file handle *now*, otherwise the compiler may fail to open it on Windows + // (#1082). The file stays on disk and its path remains valid until `tmp` is dropped. + tmp_file.flush()?; + tmp_file.sync_data()?; + drop(tmp_file); + + let stdout = run_output( + Command::new(path).arg("-E").arg(tmp.path()), + path, + // When expanding the file, the compiler prints a lot of information to stderr + // that it is not an error, but related to expanding itself. + // + // cc would have to disable warning here to prevent generation of too many warnings. + &{ + let mut cargo_output = cargo_output.clone(); + cargo_output.warnings = cargo_output.debug; + cargo_output + }, + )?; + let stdout = String::from_utf8_lossy(&stdout); + + cargo_output.print_debug(&stdout); + + // https://gitlab.kitware.com/cmake/cmake/-/blob/69a2eeb9dff5b60f2f1e5b425002a0fd45b7cadb/Modules/CMakeDetermineCompilerId.cmake#L267-271 + let accepts_cl_style_flags = run(Command::new(path).arg("-?"), path, &{ + // the errors are not errors! + let mut cargo_output = cargo_output.clone(); + cargo_output.warnings = cargo_output.debug; + cargo_output.output = OutputKind::Discard; + cargo_output + }) + .is_ok(); + + let clang = stdout.contains(r#""clang""#); + let gcc = stdout.contains(r#""gcc""#); + let emscripten = stdout.contains(r#""emscripten""#); + let vxworks = stdout.contains(r#""VxWorks""#); + + match (clang, accepts_cl_style_flags, gcc, emscripten, vxworks) { + (clang_cl, true, _, false, false) => Ok(ToolFamily::Msvc { clang_cl }), + (true, _, _, _, false) | (_, _, _, true, false) => Ok(ToolFamily::Clang { + zig_cc: is_zig_cc(path, cargo_output), + }), + (false, false, true, _, false) | (_, _, _, _, true) => Ok(ToolFamily::Gnu), + (false, false, false, false, false) => { + cargo_output.print_warning(&"Compiler family detection failed since it does not define `__clang__`, `__GNUC__`, `__EMSCRIPTEN__` or `__VXWORKS__`, also does not accept cl style flag `-?`, fallback to treating it as GNU"); + Err(Error::new( + ErrorKind::ToolFamilyMacroNotFound, + "Expects macro `__clang__`, `__GNUC__` or `__EMSCRIPTEN__`, `__VXWORKS__` or accepts cl style flag `-?`, but found none", + )) + } + } + } + let detect_family = |path: &Path| -> Result { + if let Some(family) = cached_compiler_family.read().unwrap().get(path) { + return Ok(*family); + } + + let family = detect_family_inner(path, cargo_output, out_dir)?; + cached_compiler_family + .write() + .unwrap() + .insert(path.into(), family); + Ok(family) + }; + + let family = detect_family(&path).unwrap_or_else(|e| { + cargo_output.print_warning(&format_args!( + "Compiler family detection failed due to error: {}", + e + )); + match path.file_name().map(OsStr::to_string_lossy) { + Some(fname) if fname.contains("clang-cl") => ToolFamily::Msvc { clang_cl: true }, + Some(fname) if fname.ends_with("cl") || fname == "cl.exe" => { + ToolFamily::Msvc { clang_cl: false } + } + Some(fname) if fname.contains("clang") => match clang_driver { + Some("cl") => ToolFamily::Msvc { clang_cl: true }, + _ => ToolFamily::Clang { + zig_cc: is_zig_cc(&path, cargo_output), + }, + }, + Some(fname) if fname.contains("zig") => ToolFamily::Clang { zig_cc: true }, + _ => ToolFamily::Gnu, + } + }); + + Tool { + path, + cc_wrapper_path: None, + cc_wrapper_args: Vec::new(), + args: Vec::new(), + env: Vec::new(), + family, + cuda, + removed_args: Vec::new(), + has_internal_target_arg: false, + } + } + + /// Add an argument to be stripped from the final command arguments. + pub(crate) fn remove_arg(&mut self, flag: OsString) { + self.removed_args.push(flag); + } + + /// Push an "exotic" flag to the end of the compiler's arguments list. + /// + /// Nvidia compiler accepts only the most common compiler flags like `-D`, + /// `-I`, `-c`, etc. Options meant specifically for the underlying + /// host C++ compiler have to be prefixed with `-Xcompiler`. + /// [Another possible future application for this function is passing + /// clang-specific flags to clang-cl, which otherwise accepts only + /// MSVC-specific options.] + pub(crate) fn push_cc_arg(&mut self, flag: OsString) { + if self.cuda { + self.args.push("-Xcompiler".into()); + } + self.args.push(flag); + } + + /// Checks if an argument or flag has already been specified or conflicts. + /// + /// Currently only checks optimization flags. + pub(crate) 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()) && chars.next() != Some('-') { + return false; + } + + // Check for existing optimization flags (-O, /O) + if chars.next() == Some('O') { + return self + .args() + .iter() + .any(|a| a.to_str().unwrap_or("").chars().nth(1) == Some('O')); + } + + // TODO Check for existing -m..., -m...=..., /arch:... flags + false + } + + /// Don't push optimization arg if it conflicts with existing args. + pub(crate) fn push_opt_unless_duplicate(&mut self, flag: OsString) { + if self.is_duplicate_opt_arg(&flag) { + eprintln!("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 (k, 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 { + matches!(self.family, ToolFamily::Clang { .. }) + } + + /// Whether the tool is AppleClang under .xctoolchain + #[cfg(target_vendor = "apple")] + pub(crate) fn is_xctoolchain_clang(&self) -> bool { + let path = self.path.to_string_lossy(); + path.contains(".xctoolchain/") + } + #[cfg(not(target_vendor = "apple"))] + pub(crate) fn is_xctoolchain_clang(&self) -> bool { + false + } + + /// Whether the tool is MSVC-like. + pub fn is_like_msvc(&self) -> bool { + matches!(self.family, ToolFamily::Msvc { .. }) + } +} + +/// 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)] +pub 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 { zig_cc: bool }, + /// 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 + pub(crate) fn add_debug_flags(&self, cmd: &mut Tool, dwarf_version: Option) { + match *self { + ToolFamily::Msvc { .. } => { + cmd.push_cc_arg("-Z7".into()); + } + ToolFamily::Gnu | ToolFamily::Clang { .. } => { + cmd.push_cc_arg( + dwarf_version + .map_or_else(|| "-g".into(), |v| format!("-gdwarf-{}", v)) + .into(), + ); + } + } + } + + /// What the flag to force frame pointers. + pub(crate) 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 + pub(crate) fn warnings_flags(&self) -> &'static str { + match *self { + ToolFamily::Msvc { .. } => "-W4", + ToolFamily::Gnu | ToolFamily::Clang { .. } => "-Wall", + } + } + + /// What the flags to enable extra warnings + pub(crate) 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 + pub(crate) fn warnings_to_errors_flag(&self) -> &'static str { + match *self { + ToolFamily::Msvc { .. } => "-WX", + ToolFamily::Gnu | ToolFamily::Clang { .. } => "-Werror", + } + } + + pub(crate) fn verbose_stderr(&self) -> bool { + matches!(*self, ToolFamily::Clang { .. }) + } +} diff --git a/vendor/cc/src/utilities.rs b/vendor/cc/src/utilities.rs new file mode 100644 index 0000000..073e617 --- /dev/null +++ b/vendor/cc/src/utilities.rs @@ -0,0 +1,45 @@ +use std::{ + ffi::OsStr, + fmt::{self, Write}, + path::Path, +}; + +pub(super) struct JoinOsStrs<'a, T> { + pub(super) slice: &'a [T], + pub(super) delimiter: char, +} + +impl fmt::Display for JoinOsStrs<'_, T> +where + T: AsRef, +{ + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + let len = self.slice.len(); + for (index, os_str) in self.slice.iter().enumerate() { + // TODO: Use OsStr::display once it is stablised, + // Path and OsStr has the same `Display` impl + write!(f, "{}", Path::new(os_str).display())?; + if index + 1 < len { + f.write_char(self.delimiter)?; + } + } + Ok(()) + } +} + +pub(super) struct OptionOsStrDisplay(pub(super) Option); + +impl fmt::Display for OptionOsStrDisplay +where + T: AsRef, +{ + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + // TODO: Use OsStr::display once it is stablised + // Path and OsStr has the same `Display` impl + if let Some(os_str) = self.0.as_ref() { + write!(f, "Some({})", Path::new(os_str).display()) + } else { + f.write_str("None") + } + } +} diff --git a/vendor/cc/src/windows/com.rs b/vendor/cc/src/windows/com.rs new file mode 100644 index 0000000..0391b5a --- /dev/null +++ b/vendor/cc/src/windows/com.rs @@ -0,0 +1,110 @@ +// 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. + +use crate::windows::{ + winapi::{IUnknown, Interface}, + windows_sys::{ + CoInitializeEx, SysFreeString, SysStringLen, BSTR, COINIT_MULTITHREADED, HRESULT, S_FALSE, + S_OK, + }, +}; +use std::{ + convert::TryInto, + ffi::OsString, + ops::Deref, + os::windows::ffi::OsStringExt, + ptr::{null, null_mut}, + slice::from_raw_parts, +}; + +pub fn initialize() -> Result<(), HRESULT> { + let err = unsafe { CoInitializeEx(null(), COINIT_MULTITHREADED.try_into().unwrap()) }; + if err != S_OK && err != S_FALSE { + // S_FALSE just means COM is already initialized + Err(err) + } else { + 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) + } + /// 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) }; + } +} diff --git a/vendor/cc/src/windows/find_tools.rs b/vendor/cc/src/windows/find_tools.rs new file mode 100644 index 0000000..54470f3 --- /dev/null +++ b/vendor/cc/src/windows/find_tools.rs @@ -0,0 +1,1191 @@ +// 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 looking for windows-specific tools: +//! 1. On Windows host, probe the Windows Registry if needed; +//! 2. On non-Windows host, check specified environment variables. + +#![allow(clippy::upper_case_acronyms)] + +use std::{ + env, + ffi::{OsStr, OsString}, + ops::Deref, + path::PathBuf, + process::Command, + sync::Arc, +}; + +use crate::Tool; +use crate::ToolFamily; + +const MSVC_FAMILY: ToolFamily = ToolFamily::Msvc { clang_cl: false }; + +#[derive(Copy, Clone)] +struct TargetArch<'a>(pub &'a str); + +impl PartialEq<&str> for TargetArch<'_> { + fn eq(&self, other: &&str) -> bool { + self.0 == *other + } +} + +impl<'a> From> for &'a str { + fn from(target: TargetArch<'a>) -> Self { + target.0 + } +} + +pub(crate) enum Env { + Owned(OsString), + Arced(Arc), +} + +impl AsRef for Env { + fn as_ref(&self) -> &OsStr { + self.deref() + } +} + +impl Deref for Env { + type Target = OsStr; + + fn deref(&self) -> &Self::Target { + match self { + Env::Owned(os_str) => os_str, + Env::Arced(os_str) => os_str, + } + } +} + +impl From for PathBuf { + fn from(env: Env) -> Self { + match env { + Env::Owned(os_str) => PathBuf::from(os_str), + Env::Arced(os_str) => PathBuf::from(os_str.deref()), + } + } +} + +pub(crate) trait EnvGetter { + fn get_env(&self, name: &'static str) -> Option; +} + +struct StdEnvGetter; + +impl EnvGetter for StdEnvGetter { + #[allow(clippy::disallowed_methods)] + fn get_env(&self, name: &'static str) -> Option { + env::var_os(name).map(Env::Owned) + } +} + +/// 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. +pub fn find_tool(target: &str, tool: &str) -> Option { + find_tool_inner(target, tool, &StdEnvGetter) +} + +pub(crate) fn find_tool_inner( + target: &str, + tool: &str, + env_getter: &dyn EnvGetter, +) -> Option { + // This logic is all tailored for MSVC, if we're not that then bail out + // early. + if !target.contains("msvc") { + return None; + } + + // Split the target to get the arch. + let target = TargetArch(target.split_once('-')?.0); + + // Looks like msbuild isn't located in the same location as other tools like + // cl.exe and lib.exe. + if tool.contains("msbuild") { + return impl_::find_msbuild(target, env_getter); + } + + // Looks like devenv isn't located in the same location as other tools like + // cl.exe and lib.exe. + if tool.contains("devenv") { + return impl_::find_devenv(target, env_getter); + } + + // 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. + + impl_::find_msvc_environment(tool, target, env_getter) + .or_else(|| impl_::find_msvc_15plus(tool, target, env_getter)) + .or_else(|| impl_::find_msvc_14(tool, target, env_getter)) +} + +/// A version of Visual Studio +#[derive(Debug, PartialEq, Eq, Copy, Clone)] +#[non_exhaustive] +pub enum VsVers { + /// Visual Studio 12 (2013) + #[deprecated( + note = "Visual Studio 12 is no longer supported. cc will never return this value." + )] + Vs12, + /// Visual Studio 14 (2015) + Vs14, + /// Visual Studio 15 (2017) + Vs15, + /// Visual Studio 16 (2019) + Vs16, + /// Visual Studio 17 (2022) + Vs17, +} + +/// Find the most recent installed version of Visual Studio +/// +/// This is used by the cmake crate to figure out the correct +/// generator. +#[allow(clippy::disallowed_methods)] +pub fn find_vs_version() -> Result { + fn has_msbuild_version(version: &str) -> bool { + impl_::has_msbuild_version(version, &StdEnvGetter) + } + + match std::env::var("VisualStudioVersion") { + Ok(version) => match &version[..] { + "17.0" => Ok(VsVers::Vs17), + "16.0" => Ok(VsVers::Vs16), + "15.0" => Ok(VsVers::Vs15), + "14.0" => Ok(VsVers::Vs14), + 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 presence of a specific registry key + // that indicates visual studio is installed. + if has_msbuild_version("17.0") { + Ok(VsVers::Vs17) + } else if has_msbuild_version("16.0") { + Ok(VsVers::Vs16) + } else if has_msbuild_version("15.0") { + Ok(VsVers::Vs15) + } else if has_msbuild_version("14.0") { + Ok(VsVers::Vs14) + } else { + Err("\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\ + " + .to_string()) + } + } + } +} + +/// Windows Implementation. +#[cfg(windows)] +mod impl_ { + use crate::windows::com; + use crate::windows::registry::{RegistryKey, LOCAL_MACHINE}; + use crate::windows::setup_config::SetupConfiguration; + use crate::windows::vs_instances::{VsInstances, VswhereInstance}; + use crate::windows::windows_sys::{ + GetMachineTypeAttributes, GetProcAddress, LoadLibraryA, UserEnabled, HMODULE, + IMAGE_FILE_MACHINE_AMD64, MACHINE_ATTRIBUTES, S_OK, + }; + 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 std::sync::atomic::{AtomicBool, Ordering}; + use std::sync::Once; + + use super::{EnvGetter, TargetArch, MSVC_FAMILY}; + use crate::Tool; + + struct MsvcTool { + tool: PathBuf, + libs: Vec, + path: Vec, + include: Vec, + } + + struct LibraryHandle(HMODULE); + + impl LibraryHandle { + fn new(name: &[u8]) -> Option { + let handle = unsafe { LoadLibraryA(name.as_ptr() as _) }; + (!handle.is_null()).then_some(Self(handle)) + } + + /// Get a function pointer to a function in the library. + /// # SAFETY + /// + /// The caller must ensure that the function signature matches the actual function. + /// The easiest way to do this is to add an entry to windows_sys_no_link.list and use the + /// generated function for `func_signature`. + /// + /// The function returned cannot be used after the handle is dropped. + unsafe fn get_proc_address(&self, name: &[u8]) -> Option { + let symbol = GetProcAddress(self.0, name.as_ptr() as _); + symbol.map(|symbol| mem::transmute_copy(&symbol)) + } + } + + type GetMachineTypeAttributesFuncType = + unsafe extern "system" fn(u16, *mut MACHINE_ATTRIBUTES) -> i32; + const _: () = { + // Ensure that our hand-written signature matches the actual function signature. + // We can't use `GetMachineTypeAttributes` outside of a const scope otherwise we'll end up statically linking to + // it, which will fail to load on older versions of Windows. + let _: GetMachineTypeAttributesFuncType = GetMachineTypeAttributes; + }; + + fn is_amd64_emulation_supported_inner() -> Option { + // GetMachineTypeAttributes is only available on Win11 22000+, so dynamically load it. + let kernel32 = LibraryHandle::new(b"kernel32.dll\0")?; + // SAFETY: GetMachineTypeAttributesFuncType is checked to match the real function signature. + let get_machine_type_attributes = unsafe { + kernel32 + .get_proc_address::(b"GetMachineTypeAttributes\0") + }?; + let mut attributes = Default::default(); + if unsafe { get_machine_type_attributes(IMAGE_FILE_MACHINE_AMD64, &mut attributes) } == S_OK + { + Some((attributes & UserEnabled) != 0) + } else { + Some(false) + } + } + + fn is_amd64_emulation_supported() -> bool { + // TODO: Replace with a OnceLock once MSRV is 1.70. + static LOAD_VALUE: Once = Once::new(); + static IS_SUPPORTED: AtomicBool = AtomicBool::new(false); + + // Using Relaxed ordering since the Once is providing synchronization. + LOAD_VALUE.call_once(|| { + IS_SUPPORTED.store( + is_amd64_emulation_supported_inner().unwrap_or(false), + Ordering::Relaxed, + ); + }); + IS_SUPPORTED.load(Ordering::Relaxed) + } + + impl MsvcTool { + fn new(tool: PathBuf) -> MsvcTool { + MsvcTool { + tool, + libs: Vec::new(), + path: Vec::new(), + include: Vec::new(), + } + } + + fn into_tool(self, env_getter: &dyn EnvGetter) -> Tool { + let MsvcTool { + tool, + libs, + path, + include, + } = self; + let mut tool = Tool::with_family(tool, MSVC_FAMILY); + add_env(&mut tool, "LIB", libs, env_getter); + add_env(&mut tool, "PATH", path, env_getter); + add_env(&mut tool, "INCLUDE", include, env_getter); + 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. + fn is_vscmd_target(target: TargetArch<'_>, env_getter: &dyn EnvGetter) -> Option { + let vscmd_arch = env_getter.get_env("VSCMD_ARG_TGT_ARCH")?; + // Convert the Rust target arch to its VS arch equivalent. + let arch = match target.into() { + "x86_64" => "x64", + "aarch64" | "arm64ec" => "arm64", + "i686" | "i586" => "x86", + "thumbv7a" => "arm", + // An unrecognized arch. + _ => return Some(false), + }; + Some(vscmd_arch.as_ref() == arch) + } + + /// Attempt to find the tool using environment variables set by vcvars. + pub(super) fn find_msvc_environment( + tool: &str, + target: TargetArch<'_>, + env_getter: &dyn EnvGetter, + ) -> Option { + // Early return if the environment isn't one that is known to have compiler toolsets in PATH + // `VCINSTALLDIR` is set from vcvarsall.bat (developer command prompt) + // `VSTEL_MSBuildProjectFullPath` is set by msbuild when invoking custom build steps + // NOTE: `VisualStudioDir` used to be used but this isn't set when invoking msbuild from the commandline + if env_getter.get_env("VCINSTALLDIR").is_none() + && env_getter.get_env("VSTEL_MSBuildProjectFullPath").is_none() + { + return None; + } + + // 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, env_getter) == Some(false) { + // We will only get here with versions 15+. + let vs_install_dir: PathBuf = env_getter.get_env("VSINSTALLDIR")?.into(); + tool_from_vs15plus_instance(tool, target, &vs_install_dir, env_getter) + } else { + // Fallback to simply using the current environment. + env_getter + .get_env("PATH") + .and_then(|path| { + env::split_paths(&path) + .map(|p| p.join(tool)) + .find(|p| p.exists()) + }) + .map(|path| Tool::with_family(path, MSVC_FAMILY)) + } + } + + fn find_msbuild_vs17(target: TargetArch<'_>, env_getter: &dyn EnvGetter) -> Option { + find_tool_in_vs16plus_path(r"MSBuild\Current\Bin\MSBuild.exe", target, "17", env_getter) + } + + #[allow(bare_trait_objects)] + fn vs16plus_instances( + target: TargetArch<'_>, + version: &'static str, + env_getter: &dyn EnvGetter, + ) -> Box> { + let instances = if let Some(instances) = vs15plus_instances(target, env_getter) { + instances + } else { + return Box::new(iter::empty()); + }; + Box::new(instances.into_iter().filter_map(move |instance| { + let installation_name = instance.installation_name()?; + if installation_name.starts_with(&format!("VisualStudio/{}.", version)) + || installation_name.starts_with(&format!("VisualStudioPreview/{}.", version)) + { + Some(instance.installation_path()?) + } else { + None + } + })) + } + + fn find_tool_in_vs16plus_path( + tool: &str, + target: TargetArch<'_>, + version: &'static str, + env_getter: &dyn EnvGetter, + ) -> Option { + vs16plus_instances(target, version, env_getter) + .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 == "x86_64" { + tool.env.push(("Platform".into(), "X64".into())); + } + if target == "aarch64" || target == "arm64ec" { + tool.env.push(("Platform".into(), "ARM64".into())); + } + Some(tool) + }) + .next() + } + + fn find_msbuild_vs16(target: TargetArch<'_>, env_getter: &dyn EnvGetter) -> Option { + find_tool_in_vs16plus_path(r"MSBuild\Current\Bin\MSBuild.exe", target, "16", env_getter) + } + + // 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: TargetArch<'_>, + env_getter: &dyn EnvGetter, + ) -> Option { + vs15plus_instances_using_com() + .or_else(|| vs15plus_instances_using_vswhere(target, env_getter)) + } + + 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: TargetArch<'_>, + env_getter: &dyn EnvGetter, + ) -> Option { + let program_files_path = env_getter + .get_env("ProgramFiles(x86)") + .or_else(|| env_getter.get_env("ProgramFiles"))?; + + let program_files_path = Path::new(program_files_path.as_ref()); + + let vswhere_path = + program_files_path.join(r"Microsoft Visual Studio\Installer\vswhere.exe"); + + if !vswhere_path.exists() { + return None; + } + + let tools_arch = match target.into() { + "i586" | "i686" | "x86_64" => Some("x86.x64"), + "arm" | "thumbv7a" => Some("ARM"), + "aarch64" | "arm64ec" => 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(super) fn find_msvc_15plus( + tool: &str, + target: TargetArch<'_>, + env_getter: &dyn EnvGetter, + ) -> Option { + let iter = vs15plus_instances(target, env_getter)?; + 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, env_getter)?; + 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/rust-lang/cc-rs/pull/331 + fn find_tool_in_vs15_path( + tool: &str, + target: TargetArch<'_>, + env_getter: &dyn EnvGetter, + ) -> Option { + let mut path = match vs15plus_instances(target, env_getter) { + Some(instances) => instances + .into_iter() + .filter_map(|instance| instance.installation_path()) + .map(|path| path.join(tool)) + .find(|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 == "x86_64" { + tool.env.push(("Platform".into(), "X64".into())); + } else if target == "aarch64" { + tool.env.push(("Platform".into(), "ARM64".into())); + } + tool + }) + } + + fn tool_from_vs15plus_instance( + tool: &str, + target: TargetArch<'_>, + instance_path: &Path, + env_getter: &dyn EnvGetter, + ) -> Option { + let (root_path, bin_path, host_dylib_path, lib_path, alt_lib_path, include_path) = + vs15plus_vc_paths(target, instance_path, env_getter)?; + 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); + if let Some(alt_lib_path) = alt_lib_path { + tool.libs.push(alt_lib_path); + } + tool.libs.push(lib_path); + tool.include.push(include_path); + + if let Some((atl_lib_path, atl_include_path)) = atl_paths(target, &root_path) { + tool.libs.push(atl_lib_path); + tool.include.push(atl_include_path); + } + + add_sdks(&mut tool, target, env_getter)?; + + Some(tool.into_tool(env_getter)) + } + + fn vs15plus_vc_paths( + target: TargetArch<'_>, + instance_path: &Path, + env_getter: &dyn EnvGetter, + ) -> Option<(PathBuf, PathBuf, PathBuf, PathBuf, Option, PathBuf)> { + let version = vs15plus_vc_read_version(instance_path)?; + + let hosts = match host_arch() { + X86 => &["X86"], + X86_64 => &["X64"], + // Starting with VS 17.4, there is a natively hosted compiler on ARM64: + // https://devblogs.microsoft.com/visualstudio/arm64-visual-studio-is-officially-here/ + // On older versions of VS, we use x64 if running under emulation is supported, + // otherwise use x86. + AARCH64 => { + if is_amd64_emulation_supported() { + &["ARM64", "X64", "X86"][..] + } else { + &["ARM64", "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); + // We use the first available host architecture that can build for the target + let (host_path, host) = hosts.iter().find_map(|&x| { + let candidate = path.join("bin").join(format!("Host{}", x)); + if candidate.join(target).exists() { + Some((candidate, x)) + } else { + None + } + })?; + // This is the path to the toolchain for a particular target, running + // on a given host + let bin_path = host_path.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 = host_path.join(host.to_lowercase()); + let lib_fragment = if use_spectre_mitigated_libs(env_getter) { + r"lib\spectre" + } else { + "lib" + }; + let lib_path = path.join(lib_fragment).join(target); + let alt_lib_path = (target == "arm64ec").then(|| path.join(lib_fragment).join("arm64ec")); + let include_path = path.join("include"); + Some(( + path, + bin_path, + host_dylib_path, + lib_path, + alt_lib_path, + include_path, + )) + } + + fn vs15plus_vc_read_version(dir: &Path) -> Option { + // Try to open the default version file. + let mut version_path: PathBuf = + dir.join(r"VC\Auxiliary\Build\Microsoft.VCToolsVersion.default.txt"); + let mut version_file = if let Ok(f) = File::open(&version_path) { + f + } else { + // If the default doesn't exist, search for other version files. + // These are in the form Microsoft.VCToolsVersion.v143.default.txt + // where `143` is any three decimal digit version number. + // This sorts versions by lexical order and selects the highest version. + let mut version_file = String::new(); + version_path.pop(); + for file in version_path.read_dir().ok()? { + let name = file.ok()?.file_name(); + let name = name.to_str()?; + if name.starts_with("Microsoft.VCToolsVersion.v") + && name.ends_with(".default.txt") + && name > &version_file + { + version_file.replace_range(.., name); + } + } + if version_file.is_empty() { + return None; + } + version_path.push(version_file); + File::open(version_path).ok()? + }; + + // Get the version string from the file we found. + let mut version = String::new(); + version_file.read_to_string(&mut version).ok()?; + version.truncate(version.trim_end().len()); + Some(version) + } + + fn use_spectre_mitigated_libs(env_getter: &dyn EnvGetter) -> bool { + env_getter + .get_env("VSCMD_ARG_VCVARS_SPECTRE") + .map(|env| env.as_ref() == "spectre") + .unwrap_or_default() + } + + fn atl_paths(target: TargetArch<'_>, 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(super) fn find_msvc_14( + tool: &str, + target: TargetArch<'_>, + env_getter: &dyn EnvGetter, + ) -> Option { + let vcdir = get_vc_dir("14.0")?; + let mut tool = get_tool(tool, &vcdir, target)?; + add_sdks(&mut tool, target, env_getter)?; + Some(tool.into_tool(env_getter)) + } + + fn add_sdks( + tool: &mut MsvcTool, + target: TargetArch<'_>, + env_getter: &dyn EnvGetter, + ) -> 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(env_getter) { + 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(()) + } + + fn add_env( + tool: &mut Tool, + env: &'static str, + paths: Vec, + env_getter: &dyn EnvGetter, + ) { + let prev = env_getter.get_env(env); + let prev = prev.as_ref().map(AsRef::as_ref).unwrap_or_default(); + 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: TargetArch<'_>) -> Option { + bin_subdir(target) + .into_iter() + .map(|(sub, host)| { + ( + path.join("bin").join(sub).join(tool), + path.join("bin").join(host), + ) + }) + .filter(|(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. + // Before doing that, we check the "WindowsSdkDir" and "WindowsSDKVersion" + // environment variables set by vcvars to use the environment sdk version + // if one is already configured. + fn get_sdk10_dir(env_getter: &dyn EnvGetter) -> Option<(PathBuf, String)> { + if let (Some(root), Some(version)) = ( + env_getter.get_env("WindowsSdkDir"), + env_getter + .get_env("WindowsSDKVersion") + .as_ref() + .and_then(|version| version.as_ref().to_str()), + ) { + return Some(( + PathBuf::from(root), + version.trim_end_matches('\\').to_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() + .find(|dir| dir.join("um").join("x64").join("kernel32.lib").is_file())?; + 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 targeting 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()) + } + + 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: TargetArch<'_>) -> Vec<(&'static str, &'static str)> { + match (target.into(), 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: TargetArch<'_>) -> Option<&'static str> { + match target.into() { + "i586" | "i686" => Some("x86"), + "x86_64" => Some("x64"), + "arm" | "thumbv7a" => Some("arm"), + "aarch64" | "arm64ec" => Some("arm64"), + _ => None, + } + } + + // MSVC's x86 libraries are not in a subfolder + fn vc_lib_subdir(target: TargetArch<'_>) -> Option<&'static str> { + match target.into() { + "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_start_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 + } + + #[inline(always)] + pub(super) fn has_msbuild_version(version: &str, env_getter: &dyn EnvGetter) -> bool { + match version { + "17.0" => { + find_msbuild_vs17(TargetArch("x86_64"), env_getter).is_some() + || find_msbuild_vs17(TargetArch("i686"), env_getter).is_some() + || find_msbuild_vs17(TargetArch("aarch64"), env_getter).is_some() + } + "16.0" => { + find_msbuild_vs16(TargetArch("x86_64"), env_getter).is_some() + || find_msbuild_vs16(TargetArch("i686"), env_getter).is_some() + || find_msbuild_vs16(TargetArch("aarch64"), env_getter).is_some() + } + "15.0" => { + find_msbuild_vs15(TargetArch("x86_64"), env_getter).is_some() + || find_msbuild_vs15(TargetArch("i686"), env_getter).is_some() + || find_msbuild_vs15(TargetArch("aarch64"), env_getter).is_some() + } + "14.0" => LOCAL_MACHINE + .open(&OsString::from(format!( + "SOFTWARE\\Microsoft\\MSBuild\\ToolsVersions\\{}", + version + ))) + .is_ok(), + _ => false, + } + } + + pub(super) fn find_devenv(target: TargetArch<'_>, env_getter: &dyn EnvGetter) -> Option { + find_devenv_vs15(target, env_getter) + } + + fn find_devenv_vs15(target: TargetArch<'_>, env_getter: &dyn EnvGetter) -> Option { + find_tool_in_vs15_path(r"Common7\IDE\devenv.exe", target, env_getter) + } + + // see http://stackoverflow.com/questions/328017/path-to-msbuild + pub(super) fn find_msbuild(target: TargetArch<'_>, env_getter: &dyn EnvGetter) -> Option { + // VS 15 (2017) changed how to locate msbuild + if let Some(r) = find_msbuild_vs17(target, env_getter) { + Some(r) + } else if let Some(r) = find_msbuild_vs16(target, env_getter) { + return Some(r); + } else if let Some(r) = find_msbuild_vs15(target, env_getter) { + return Some(r); + } else { + find_old_msbuild(target) + } + } + + fn find_msbuild_vs15(target: TargetArch<'_>, env_getter: &dyn EnvGetter) -> Option { + find_tool_in_vs15_path(r"MSBuild\15.0\Bin\MSBuild.exe", target, env_getter) + } + + fn find_old_msbuild(target: TargetArch<'_>) -> 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 == "x86_64" { + tool.env.push(("Platform".into(), "X64".into())); + } + tool + }) + } +} + +/// Non-Windows Implementation. +#[cfg(not(windows))] +mod impl_ { + use std::{env, ffi::OsStr}; + + use super::{EnvGetter, TargetArch, MSVC_FAMILY}; + use crate::Tool; + + /// Finding msbuild.exe tool under unix system is not currently supported. + /// Maybe can check it using an environment variable looks like `MSBUILD_BIN`. + #[inline(always)] + pub(super) fn find_msbuild(_target: TargetArch<'_>, _: &dyn EnvGetter) -> Option { + None + } + + // Finding devenv.exe tool under unix system is not currently supported. + // Maybe can check it using an environment variable looks like `DEVENV_BIN`. + #[inline(always)] + pub(super) fn find_devenv(_target: TargetArch<'_>, _: &dyn EnvGetter) -> Option { + None + } + + /// Attempt to find the tool using environment variables set by vcvars. + pub(super) fn find_msvc_environment( + tool: &str, + _target: TargetArch<'_>, + env_getter: &dyn EnvGetter, + ) -> Option { + // Early return if the environment doesn't contain a VC install. + let vc_install_dir = env_getter.get_env("VCINSTALLDIR")?; + let vs_install_dir = env_getter.get_env("VSINSTALLDIR")?; + + let get_tool = |install_dir: &OsStr| { + env::split_paths(install_dir) + .map(|p| p.join(tool)) + .find(|p| p.exists()) + .map(|path| Tool::with_family(path, MSVC_FAMILY)) + }; + + // Take the path of tool for the vc install directory. + get_tool(vc_install_dir.as_ref()) + // Take the path of tool for the vs install directory. + .or_else(|| get_tool(vs_install_dir.as_ref())) + // Take the path of tool for the current path environment. + .or_else(|| { + env_getter + .get_env("PATH") + .as_ref() + .map(|path| path.as_ref()) + .and_then(get_tool) + }) + } + + #[inline(always)] + pub(super) fn find_msvc_15plus( + _tool: &str, + _target: TargetArch<'_>, + _: &dyn EnvGetter, + ) -> Option { + None + } + + // For MSVC 14 we need to find the Universal CRT as well as either + // the Windows 10 SDK or Windows 8.1 SDK. + #[inline(always)] + pub(super) fn find_msvc_14( + _tool: &str, + _target: TargetArch<'_>, + _: &dyn EnvGetter, + ) -> Option { + None + } + + #[inline(always)] + pub(super) fn has_msbuild_version(_version: &str, _: &dyn EnvGetter) -> bool { + false + } +} diff --git a/vendor/cc/src/windows/mod.rs b/vendor/cc/src/windows/mod.rs new file mode 100644 index 0000000..ccf22b0 --- /dev/null +++ b/vendor/cc/src/windows/mod.rs @@ -0,0 +1,22 @@ +//! These modules are all glue to support reading the MSVC version from +//! the registry and from COM interfaces. + +// This is used in the crate's public API, so don't use #[cfg(windows)] +pub mod find_tools; + +#[cfg(windows)] +pub(crate) mod windows_sys; +#[cfg(windows)] +mod windows_targets; + +#[cfg(windows)] +mod registry; +#[cfg(windows)] +#[macro_use] +mod winapi; +#[cfg(windows)] +mod com; +#[cfg(windows)] +mod setup_config; +#[cfg(windows)] +mod vs_instances; diff --git a/vendor/cc/src/windows/registry.rs b/vendor/cc/src/windows/registry.rs new file mode 100644 index 0000000..8398303 --- /dev/null +++ b/vendor/cc/src/windows/registry.rs @@ -0,0 +1,191 @@ +// 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 crate::windows::windows_sys::{ + RegCloseKey, RegEnumKeyExW, RegOpenKeyExW, RegQueryValueExW, ERROR_NO_MORE_ITEMS, + ERROR_SUCCESS, HKEY, HKEY_LOCAL_MACHINE, KEY_READ, KEY_WOW64_32KEY, REG_SZ, +}; +use std::{ + ffi::{OsStr, OsString}, + io, + ops::RangeFrom, + os::windows::prelude::*, + ptr::null_mut, +}; + +/// Must never be `HKEY_PERFORMANCE_DATA`. +pub(crate) struct RegistryKey(Repr); + +#[allow(clippy::upper_case_acronyms)] +type DWORD = u32; + +struct OwnedKey(HKEY); + +/// Note: must not encode `HKEY_PERFORMANCE_DATA` or one of its subkeys. +enum Repr { + /// `HKEY_LOCAL_MACHINE`. + LocalMachine, + /// A subkey of `HKEY_LOCAL_MACHINE`. + Owned(OwnedKey), +} + +pub struct Iter<'a> { + idx: RangeFrom, + key: &'a RegistryKey, +} + +unsafe impl Sync for Repr {} +unsafe impl Send for Repr {} + +pub(crate) const LOCAL_MACHINE: RegistryKey = RegistryKey(Repr::LocalMachine); + +impl RegistryKey { + fn raw(&self) -> HKEY { + match self.0 { + Repr::LocalMachine => HKEY_LOCAL_MACHINE, + Repr::Owned(ref val) => val.0, + } + } + + /// Open a sub-key of `self`. + pub fn open(&self, key: &OsStr) -> io::Result { + let key = key.encode_wide().chain(Some(0)).collect::>(); + let mut ret = null_mut(); + let err = unsafe { + RegOpenKeyExW( + self.raw(), + key.as_ptr(), + 0, + KEY_READ | KEY_WOW64_32KEY, + &mut ret, + ) + }; + if err == ERROR_SUCCESS { + 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(), + null_mut(), + &mut kind, + null_mut(), + &mut len, + ); + if err != ERROR_SUCCESS { + 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 length + // passed in. + assert!(len % 2 == 0, "impossible wide string size: {} bytes", len); + let vlen = len as usize / 2; + // Defensively initialized, see comment about + // `HKEY_PERFORMANCE_DATA` below. + let mut v = vec![0u16; vlen]; + let err = RegQueryValueExW( + self.raw(), + name.as_ptr(), + null_mut(), + null_mut(), + v.as_mut_ptr() as *mut _, + &mut len, + ); + // We don't check for `ERROR_MORE_DATA` (which would if the value + // grew between the first and second call to `RegQueryValueExW`), + // both because it's extremely unlikely, and this is a bit more + // defensive more defensive against weird types of registry keys. + if err != ERROR_SUCCESS { + return Err(io::Error::from_raw_os_error(err as i32)); + } + // The length is allowed to change, but should still be even, as + // well as smaller. + assert!(len % 2 == 0, "impossible wide string size: {} bytes", len); + // If the length grew but returned a success code, it *probably* + // indicates we're `HKEY_PERFORMANCE_DATA` or a subkey(?). We + // consider this UB, since those keys write "undefined" or + // "unpredictable" values to len, and need to use a completely + // different loop structure. This should be impossible (and enforce + // it in the API to the best of our ability), but to mitigate the + // damage we do some smoke-checks on the len, and ensure `v` has + // been fully initialized (rather than trusting the result of + // `RegQueryValueExW`). + let actual_len = len as usize / 2; + assert!(actual_len <= v.len()); + v.truncate(actual_len); + // 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.is_empty() && 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, + null_mut(), + null_mut(), + null_mut(), + null_mut(), + ); + if ret == ERROR_NO_MORE_ITEMS { + None + } else if ret != ERROR_SUCCESS { + 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/windows/setup_config.rs b/vendor/cc/src/windows/setup_config.rs new file mode 100644 index 0000000..5739ecf --- /dev/null +++ b/vendor/cc/src/windows/setup_config.rs @@ -0,0 +1,283 @@ +// 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::windows::{ + com::{BStr, ComPtr}, + winapi::{ + IUnknown, IUnknownVtbl, Interface, LCID, LPCOLESTR, LPCWSTR, LPFILETIME, LPSAFEARRAY, + PULONGLONG, ULONG, + }, + windows_sys::{CoCreateInstance, BSTR, CLSCTX_ALL, HRESULT, S_FALSE}, +}; + +use std::{ + ffi::OsString, + ptr::{null, null_mut}, +}; + +// 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(); + 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(); + 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(); + 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(); + 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(); + 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/windows/vs_instances.rs b/vendor/cc/src/windows/vs_instances.rs new file mode 100644 index 0000000..3e6eeed --- /dev/null +++ b/vendor/cc/src/windows/vs_instances.rs @@ -0,0 +1,199 @@ +use std::borrow::Cow; +use std::collections::HashMap; +use std::convert::TryFrom; +use std::io::BufRead; +use std::path::PathBuf; + +use crate::windows::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() + .map_while(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/windows/winapi.rs b/vendor/cc/src/windows/winapi.rs new file mode 100644 index 0000000..09965da --- /dev/null +++ b/vendor/cc/src/windows/winapi.rs @@ -0,0 +1,146 @@ +// 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, clippy::upper_case_acronyms)] + +use std::os::raw; + +pub type wchar_t = u16; + +pub use crate::windows::windows_sys::{FILETIME, GUID, HRESULT, SAFEARRAY}; + +pub type REFIID = *const IID; +pub type IID = GUID; +pub type ULONG = raw::c_ulong; +pub type DWORD = u32; +pub type LPFILETIME = *mut FILETIME; +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 trait Interface { + fn uuidof() -> GUID; +} + +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::windows::winapi::GUID = $crate::windows::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::windows::winapi::Interface for $interface { + #[inline] + fn uuidof() -> $crate::windows::winapi::GUID { + $crate::windows::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/windows_sys.rs b/vendor/cc/src/windows/windows_sys.rs new file mode 100644 index 0000000..fd177e6 --- /dev/null +++ b/vendor/cc/src/windows/windows_sys.rs @@ -0,0 +1,121 @@ +// This file is autogenerated. +// +// To add bindings, edit windows_sys.lst then run: +// +// ``` +// cd generate-windows-sys/ +// cargo run +// ``` +// Bindings generated by `windows-bindgen` 0.58.0 + +#![allow( + non_snake_case, + non_upper_case_globals, + non_camel_case_types, + dead_code, + clippy::all +)] +windows_targets::link!("advapi32.dll" "system" fn RegCloseKey(hkey : HKEY) -> WIN32_ERROR); +windows_targets::link!("advapi32.dll" "system" fn RegEnumKeyExW(hkey : HKEY, dwindex : u32, lpname : PWSTR, lpcchname : *mut u32, lpreserved : *const u32, lpclass : PWSTR, lpcchclass : *mut u32, lpftlastwritetime : *mut FILETIME) -> WIN32_ERROR); +windows_targets::link!("advapi32.dll" "system" fn RegOpenKeyExW(hkey : HKEY, lpsubkey : PCWSTR, uloptions : u32, samdesired : REG_SAM_FLAGS, phkresult : *mut HKEY) -> WIN32_ERROR); +windows_targets::link!("advapi32.dll" "system" fn RegQueryValueExW(hkey : HKEY, lpvaluename : PCWSTR, lpreserved : *const u32, lptype : *mut REG_VALUE_TYPE, lpdata : *mut u8, lpcbdata : *mut u32) -> WIN32_ERROR); +windows_targets::link!("kernel32.dll" "system" fn FreeLibrary(hlibmodule : HMODULE) -> BOOL); +windows_targets::link!("kernel32.dll" "system" fn GetMachineTypeAttributes(machine : u16, machinetypeattributes : *mut MACHINE_ATTRIBUTES) -> HRESULT); +windows_targets::link!("kernel32.dll" "system" fn GetProcAddress(hmodule : HMODULE, lpprocname : PCSTR) -> FARPROC); +windows_targets::link!("kernel32.dll" "system" fn LoadLibraryA(lplibfilename : PCSTR) -> HMODULE); +windows_targets::link!("kernel32.dll" "system" fn OpenSemaphoreA(dwdesiredaccess : u32, binherithandle : BOOL, lpname : PCSTR) -> HANDLE); +windows_targets::link!("kernel32.dll" "system" fn PeekNamedPipe(hnamedpipe : HANDLE, lpbuffer : *mut core::ffi::c_void, nbuffersize : u32, lpbytesread : *mut u32, lptotalbytesavail : *mut u32, lpbytesleftthismessage : *mut u32) -> BOOL); +windows_targets::link!("kernel32.dll" "system" fn ReleaseSemaphore(hsemaphore : HANDLE, lreleasecount : i32, lppreviouscount : *mut i32) -> BOOL); +windows_targets::link!("kernel32.dll" "system" fn WaitForSingleObject(hhandle : HANDLE, dwmilliseconds : u32) -> WAIT_EVENT); +windows_targets::link!("ole32.dll" "system" fn CoCreateInstance(rclsid : *const GUID, punkouter : * mut core::ffi::c_void, dwclscontext : CLSCTX, riid : *const GUID, ppv : *mut *mut core::ffi::c_void) -> HRESULT); +windows_targets::link!("ole32.dll" "system" fn CoInitializeEx(pvreserved : *const core::ffi::c_void, dwcoinit : u32) -> HRESULT); +windows_targets::link!("oleaut32.dll" "system" fn SysFreeString(bstrstring : BSTR)); +windows_targets::link!("oleaut32.dll" "system" fn SysStringLen(pbstr : BSTR) -> u32); +pub type ADVANCED_FEATURE_FLAGS = u16; +pub type BOOL = i32; +pub type BSTR = *const u16; +pub type CLSCTX = u32; +pub const CLSCTX_ALL: CLSCTX = 23u32; +pub type COINIT = i32; +pub const COINIT_MULTITHREADED: COINIT = 0i32; +pub const ERROR_NO_MORE_ITEMS: WIN32_ERROR = 259u32; +pub const ERROR_SUCCESS: WIN32_ERROR = 0u32; +pub const FALSE: BOOL = 0i32; +pub type FARPROC = Option isize>; +#[repr(C)] +#[derive(Clone, Copy)] +pub struct FILETIME { + pub dwLowDateTime: u32, + pub dwHighDateTime: u32, +} +pub const FILE_ATTRIBUTE_TEMPORARY: FILE_FLAGS_AND_ATTRIBUTES = 256u32; +pub type FILE_FLAGS_AND_ATTRIBUTES = u32; +#[repr(C)] +#[derive(Clone, Copy)] +pub struct GUID { + pub data1: u32, + pub data2: u16, + pub data3: u16, + pub data4: [u8; 8], +} +impl GUID { + pub const fn from_u128(uuid: u128) -> Self { + Self { + data1: (uuid >> 96) as u32, + data2: (uuid >> 80 & 0xffff) as u16, + data3: (uuid >> 64 & 0xffff) as u16, + data4: (uuid as u64).to_be_bytes(), + } + } +} +pub type HANDLE = *mut core::ffi::c_void; +pub type HKEY = *mut core::ffi::c_void; +pub const HKEY_LOCAL_MACHINE: HKEY = -2147483646i32 as _; +pub type HMODULE = *mut core::ffi::c_void; +pub type HRESULT = i32; +pub type IMAGE_FILE_MACHINE = u16; +pub const IMAGE_FILE_MACHINE_AMD64: IMAGE_FILE_MACHINE = 34404u16; +pub const KEY_READ: REG_SAM_FLAGS = 131097u32; +pub const KEY_WOW64_32KEY: REG_SAM_FLAGS = 512u32; +pub type MACHINE_ATTRIBUTES = i32; +pub type PCSTR = *const u8; +pub type PCWSTR = *const u16; +pub type PWSTR = *mut u16; +pub type REG_SAM_FLAGS = u32; +pub const REG_SZ: REG_VALUE_TYPE = 1u32; +pub type REG_VALUE_TYPE = u32; +#[repr(C)] +#[derive(Clone, Copy)] +pub struct SAFEARRAY { + pub cDims: u16, + pub fFeatures: ADVANCED_FEATURE_FLAGS, + pub cbElements: u32, + pub cLocks: u32, + pub pvData: *mut core::ffi::c_void, + pub rgsabound: [SAFEARRAYBOUND; 1], +} +#[repr(C)] +#[derive(Clone, Copy)] +pub struct SAFEARRAYBOUND { + pub cElements: u32, + pub lLbound: i32, +} +pub const SEMAPHORE_MODIFY_STATE: SYNCHRONIZATION_ACCESS_RIGHTS = 2u32; +pub type SYNCHRONIZATION_ACCESS_RIGHTS = u32; +pub const S_FALSE: HRESULT = 0x1_u32 as _; +pub const S_OK: HRESULT = 0x0_u32 as _; +pub type THREAD_ACCESS_RIGHTS = u32; +pub const THREAD_SYNCHRONIZE: THREAD_ACCESS_RIGHTS = 1048576u32; +pub const UserEnabled: MACHINE_ATTRIBUTES = 1i32; +pub const WAIT_ABANDONED: WAIT_EVENT = 128u32; +pub type WAIT_EVENT = u32; +pub const WAIT_FAILED: WAIT_EVENT = 4294967295u32; +pub const WAIT_OBJECT_0: WAIT_EVENT = 0u32; +pub const WAIT_TIMEOUT: WAIT_EVENT = 258u32; +pub type WIN32_ERROR = u32; + +#[link(name = "advapi32")] +#[link(name = "ole32")] +#[link(name = "oleaut32")] +extern "C" {} +use super::windows_targets; diff --git a/vendor/cc/src/windows/windows_targets.rs b/vendor/cc/src/windows/windows_targets.rs new file mode 100644 index 0000000..d08affe --- /dev/null +++ b/vendor/cc/src/windows/windows_targets.rs @@ -0,0 +1,19 @@ +//! Provides the `link!` macro used by the generated windows bindings. +//! +//! This is a simple wrapper around an `extern` block with a `#[link]` attribute. +//! It's very roughly equivalent to the windows-targets crate. + +macro_rules! link_macro { + ($library:literal $abi:literal $($link_name:literal)? $(#[$doc:meta])? fn $($function:tt)*) => ( + // Note: the windows-targets crate uses a pre-built Windows.lib import library which we don't + // have in this repo. So instead we always link kernel32.lib and add the rest of the import + // libraries below by using an empty extern block. This works because extern blocks are not + // connected to the library given in the #[link] attribute. + #[link(name = "kernel32")] + extern $abi { + $(#[link_name=$link_name])? + pub fn $($function)*; + } + ) +} +pub(crate) use link_macro as link; diff --git a/vendor/cfg-if/.cargo-checksum.json b/vendor/cfg-if/.cargo-checksum.json new file mode 100644 index 0000000..93e07c1 --- /dev/null +++ b/vendor/cfg-if/.cargo-checksum.json @@ -0,0 +1 @@ +{"files":{"Cargo.toml":"5b2a8f6e5256957c029cf3a8912d51438e7faa5891c5c102c312f6d4599c1f00","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"378f5840b258e2779c39418f3f2d7b2ba96f1c7917dd6be0713f88305dbda397","README.md":"2406e83ee174e30aa67f8ab266836fa78545012b196395aff37c152321e2c713","src/lib.rs":"54b0f108b0dc48a077c52c0bcd22b64ef4de083e5e2b7d405e50ae4d78224f1b","tests/xcrate.rs":"c0734dae6e63beafcd60bf53546115a2320735b51035c9e2387fdf9301580934"},"package":"baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"} \ No newline at end of file diff --git a/vendor/cfg-if/Cargo.toml b/vendor/cfg-if/Cargo.toml new file mode 100644 index 0000000..13a32ba --- /dev/null +++ b/vendor/cfg-if/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 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 = "1.0.0" +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/LICENSE-APACHE b/vendor/cfg-if/LICENSE-APACHE new file mode 100644 index 0000000..16fe87b --- /dev/null +++ b/vendor/cfg-if/LICENSE-APACHE @@ -0,0 +1,201 @@ + 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/cfg-if/LICENSE-MIT b/vendor/cfg-if/LICENSE-MIT new file mode 100644 index 0000000..39e0ed6 --- /dev/null +++ b/vendor/cfg-if/LICENSE-MIT @@ -0,0 +1,25 @@ +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/README.md b/vendor/cfg-if/README.md new file mode 100644 index 0000000..50b5e3b --- /dev/null +++ b/vendor/cfg-if/README.md @@ -0,0 +1,47 @@ +# 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/src/lib.rs b/vendor/cfg-if/src/lib.rs new file mode 100644 index 0000000..52bbbe0 --- /dev/null +++ b/vendor/cfg-if/src/lib.rs @@ -0,0 +1,176 @@ +//! 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/tests/xcrate.rs b/vendor/cfg-if/tests/xcrate.rs new file mode 100644 index 0000000..e7b4a36 --- /dev/null +++ b/vendor/cfg-if/tests/xcrate.rs @@ -0,0 +1,14 @@ +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/foreign-types-shared/.cargo-checksum.json b/vendor/foreign-types-shared/.cargo-checksum.json new file mode 100644 index 0000000..2d6d891 --- /dev/null +++ b/vendor/foreign-types-shared/.cargo-checksum.json @@ -0,0 +1 @@ +{"files":{"Cargo.toml":"6b91ae600fe7b521537096b2269ab7bfd606f8a1fcd97749634dd03ba18daf53","LICENSE-APACHE":"c6596eb7be8581c18be736c846fb9173b69eccf6ef94c5135893ec56bd92ba08","LICENSE-MIT":"333ea3aaa3cadb819f4acd9f9153f9feee060a995ca8710f32bc5bd9a4b91734","src/lib.rs":"77aed289fd36258c273f033e766e572ee05330249083c017d045f0a75662f5df"},"package":"00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b"} \ No newline at end of file diff --git a/vendor/foreign-types-shared/Cargo.toml b/vendor/foreign-types-shared/Cargo.toml new file mode 100644 index 0000000..e2cb783 --- /dev/null +++ b/vendor/foreign-types-shared/Cargo.toml @@ -0,0 +1,21 @@ +# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO +# +# When uploading crates to the registry Cargo will automatically +# "normalize" Cargo.toml files for maximal compatibility +# with all versions of Cargo and also rewrite `path` dependencies +# to registry (e.g. crates.io) dependencies +# +# If you believe there's an error in this file please file an +# issue against the rust-lang/cargo repository. If you're +# editing this file be aware that the upstream Cargo.toml +# will likely look very different (and much more reasonable) + +[package] +name = "foreign-types-shared" +version = "0.1.1" +authors = ["Steven Fackler "] +description = "An internal crate used by foreign-types" +license = "MIT/Apache-2.0" +repository = "https://github.com/sfackler/foreign-types" + +[dependencies] diff --git a/vendor/foreign-types-shared/LICENSE-APACHE b/vendor/foreign-types-shared/LICENSE-APACHE new file mode 100644 index 0000000..8f71f43 --- /dev/null +++ b/vendor/foreign-types-shared/LICENSE-APACHE @@ -0,0 +1,202 @@ + 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/foreign-types-shared/LICENSE-MIT b/vendor/foreign-types-shared/LICENSE-MIT new file mode 100644 index 0000000..bb76d01 --- /dev/null +++ b/vendor/foreign-types-shared/LICENSE-MIT @@ -0,0 +1,19 @@ +Copyright (c) 2017 The foreign-types Developers + +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/foreign-types-shared/src/lib.rs b/vendor/foreign-types-shared/src/lib.rs new file mode 100644 index 0000000..cbebc33 --- /dev/null +++ b/vendor/foreign-types-shared/src/lib.rs @@ -0,0 +1,51 @@ +//! Internal crate used by foreign-types + +#![no_std] +#![warn(missing_docs)] +#![doc(html_root_url="https://docs.rs/foreign-types-shared/0.1")] + +use core::cell::UnsafeCell; + +/// An opaque type used to define `ForeignTypeRef` types. +/// +/// A type implementing `ForeignTypeRef` should simply be a newtype wrapper around this type. +pub struct Opaque(UnsafeCell<()>); + +/// A type implemented by wrappers over foreign types. +pub trait ForeignType: Sized { + /// The raw C type. + type CType; + + /// The type representing a reference to this type. + type Ref: ForeignTypeRef; + + /// Constructs an instance of this type from its raw type. + unsafe fn from_ptr(ptr: *mut Self::CType) -> Self; + + /// Returns a raw pointer to the wrapped value. + fn as_ptr(&self) -> *mut Self::CType; +} + +/// A trait implemented by types which reference borrowed foreign types. +pub trait ForeignTypeRef: Sized { + /// The raw C type. + type CType; + + /// Constructs a shared instance of this type from its raw type. + #[inline] + unsafe fn from_ptr<'a>(ptr: *mut Self::CType) -> &'a Self { + &*(ptr as *mut _) + } + + /// Constructs a mutable reference of this type from its raw type. + #[inline] + unsafe fn from_ptr_mut<'a>(ptr: *mut Self::CType) -> &'a mut Self { + &mut *(ptr as *mut _) + } + + /// Returns a raw pointer to the wrapped value. + #[inline] + fn as_ptr(&self) -> *mut Self::CType { + self as *const _ as *mut _ + } +} diff --git a/vendor/foreign-types/.cargo-checksum.json b/vendor/foreign-types/.cargo-checksum.json new file mode 100644 index 0000000..7e74bd5 --- /dev/null +++ b/vendor/foreign-types/.cargo-checksum.json @@ -0,0 +1 @@ +{"files":{"Cargo.toml":"1a667c28f60115423b68fea369255c2dcb129b8dce10f30e0e1da73d05f9adab","LICENSE-APACHE":"c6596eb7be8581c18be736c846fb9173b69eccf6ef94c5135893ec56bd92ba08","LICENSE-MIT":"333ea3aaa3cadb819f4acd9f9153f9feee060a995ca8710f32bc5bd9a4b91734","README.md":"6f3f1429f2724a481df811842f318d0d3b83160ada953fd869d4b685f7fd72e4","src/lib.rs":"4f0a33bf8ec94a57d1b71e50f1af8ca410985e447f69fdc9c680545b03ea4566"},"package":"f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1"} \ No newline at end of file diff --git a/vendor/foreign-types/Cargo.toml b/vendor/foreign-types/Cargo.toml new file mode 100644 index 0000000..6ff5567 --- /dev/null +++ b/vendor/foreign-types/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] +name = "foreign-types" +version = "0.3.2" +authors = ["Steven Fackler "] +description = "A framework for Rust wrappers over C APIs" +readme = "README.md" +license = "MIT/Apache-2.0" +repository = "https://github.com/sfackler/foreign-types" +[dependencies.foreign-types-shared] +version = "0.1" diff --git a/vendor/foreign-types/LICENSE-APACHE b/vendor/foreign-types/LICENSE-APACHE new file mode 100644 index 0000000..8f71f43 --- /dev/null +++ b/vendor/foreign-types/LICENSE-APACHE @@ -0,0 +1,202 @@ + 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/foreign-types/LICENSE-MIT b/vendor/foreign-types/LICENSE-MIT new file mode 100644 index 0000000..bb76d01 --- /dev/null +++ b/vendor/foreign-types/LICENSE-MIT @@ -0,0 +1,19 @@ +Copyright (c) 2017 The foreign-types Developers + +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/foreign-types/README.md b/vendor/foreign-types/README.md new file mode 100644 index 0000000..cd15965 --- /dev/null +++ b/vendor/foreign-types/README.md @@ -0,0 +1,23 @@ +# foreign-types + +[![CircleCI](https://circleci.com/gh/sfackler/foreign-types.svg?style=shield)](https://circleci.com/gh/sfackler/foreign-types) + +[Documentation](https://docs.rs/foreign-types) + +A framework for Rust wrappers over C APIs. + +## License + +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 the work 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/foreign-types/src/lib.rs b/vendor/foreign-types/src/lib.rs new file mode 100644 index 0000000..6ce9592 --- /dev/null +++ b/vendor/foreign-types/src/lib.rs @@ -0,0 +1,306 @@ +//! A framework for Rust wrappers over C APIs. +//! +//! Ownership is as important in C as it is in Rust, but the semantics are often implicit. In +//! particular, pointer-to-value is commonly used to pass C values both when transferring ownership +//! or a borrow. +//! +//! This crate provides a framework to define a Rust wrapper over these kinds of raw C APIs in a way +//! that allows ownership semantics to be expressed in an ergonomic manner. The framework takes a +//! dual-type approach similar to APIs in the standard library such as `PathBuf`/`Path` or `String`/ +//! `str`. One type represents an owned value and references to the other represent borrowed +//! values. +//! +//! # Examples +//! +//! ``` +//! use foreign_types::{ForeignType, ForeignTypeRef, Opaque}; +//! use std::ops::{Deref, DerefMut}; +//! +//! mod foo_sys { +//! pub enum FOO {} +//! +//! extern { +//! pub fn FOO_free(foo: *mut FOO); +//! } +//! } +//! +//! // The borrowed type is a newtype wrapper around an `Opaque` value. +//! // +//! // `FooRef` values never exist; we instead create references to `FooRef`s +//! // from raw C pointers. +//! pub struct FooRef(Opaque); +//! +//! impl ForeignTypeRef for FooRef { +//! type CType = foo_sys::FOO; +//! } +//! +//! // The owned type is simply a newtype wrapper around the raw C type. +//! // +//! // It dereferences to `FooRef`, so methods that do not require ownership +//! // should be defined there. +//! pub struct Foo(*mut foo_sys::FOO); +//! +//! impl Drop for Foo { +//! fn drop(&mut self) { +//! unsafe { foo_sys::FOO_free(self.0) } +//! } +//! } +//! +//! impl ForeignType for Foo { +//! type CType = foo_sys::FOO; +//! type Ref = FooRef; +//! +//! unsafe fn from_ptr(ptr: *mut foo_sys::FOO) -> Foo { +//! Foo(ptr) +//! } +//! +//! fn as_ptr(&self) -> *mut foo_sys::FOO { +//! self.0 +//! } +//! } +//! +//! impl Deref for Foo { +//! type Target = FooRef; +//! +//! fn deref(&self) -> &FooRef { +//! unsafe { FooRef::from_ptr(self.0) } +//! } +//! } +//! +//! impl DerefMut for Foo { +//! fn deref_mut(&mut self) -> &mut FooRef { +//! unsafe { FooRef::from_ptr_mut(self.0) } +//! } +//! } +//! ``` +//! +//! The `foreign_type!` macro can generate this boilerplate for you: +//! +//! ``` +//! #[macro_use] +//! extern crate foreign_types; +//! +//! mod foo_sys { +//! pub enum FOO {} +//! +//! extern { +//! pub fn FOO_free(foo: *mut FOO); +//! pub fn FOO_duplicate(foo: *mut FOO) -> *mut FOO; // Optional +//! } +//! } +//! +//! foreign_type! { +//! type CType = foo_sys::FOO; +//! fn drop = foo_sys::FOO_free; +//! fn clone = foo_sys::FOO_duplicate; // Optional +//! /// A Foo. +//! pub struct Foo; +//! /// A borrowed Foo. +//! pub struct FooRef; +//! } +//! +//! # fn main() {} +//! ``` +//! +//! If `fn clone` is specified, then it must take `CType` as an argument and return a copy of it as `CType`. +//! It will be used to implement `ToOwned` and `Clone`. +//! +//! `#[derive(…)] is permitted before the lines with `pub struct`. +//! `#[doc(hidden)]` before the `type CType` line will hide the `foreign_type!` implementations from documentation. +//! +//! Say we then have a separate type in our C API that contains a `FOO`: +//! +//! ``` +//! mod foo_sys { +//! pub enum FOO {} +//! pub enum BAR {} +//! +//! extern { +//! pub fn FOO_free(foo: *mut FOO); +//! pub fn BAR_free(bar: *mut BAR); +//! pub fn BAR_get_foo(bar: *mut BAR) -> *mut FOO; +//! } +//! } +//! ``` +//! +//! The documentation for the C library states that `BAR_get_foo` returns a reference into the `BAR` +//! passed to it, which translates into a reference in Rust. It also says that we're allowed to +//! modify the `FOO`, so we'll define a pair of accessor methods, one immutable and one mutable: +//! +//! ``` +//! #[macro_use] +//! extern crate foreign_types; +//! +//! use foreign_types::ForeignTypeRef; +//! +//! mod foo_sys { +//! pub enum FOO {} +//! pub enum BAR {} +//! +//! extern { +//! pub fn FOO_free(foo: *mut FOO); +//! pub fn BAR_free(bar: *mut BAR); +//! pub fn BAR_get_foo(bar: *mut BAR) -> *mut FOO; +//! } +//! } +//! +//! foreign_type! { +//! #[doc(hidden)] +//! type CType = foo_sys::FOO; +//! fn drop = foo_sys::FOO_free; +//! /// A Foo. +//! pub struct Foo; +//! /// A borrowed Foo. +//! pub struct FooRef; +//! } +//! +//! foreign_type! { +//! type CType = foo_sys::BAR; +//! fn drop = foo_sys::BAR_free; +//! /// A Foo. +//! pub struct Bar; +//! /// A borrowed Bar. +//! pub struct BarRef; +//! } +//! +//! impl BarRef { +//! fn foo(&self) -> &FooRef { +//! unsafe { FooRef::from_ptr(foo_sys::BAR_get_foo(self.as_ptr())) } +//! } +//! +//! fn foo_mut(&mut self) -> &mut FooRef { +//! unsafe { FooRef::from_ptr_mut(foo_sys::BAR_get_foo(self.as_ptr())) } +//! } +//! } +//! +//! # fn main() {} +//! ``` +#![no_std] +#![warn(missing_docs)] +#![doc(html_root_url="https://docs.rs/foreign-types/0.3")] +extern crate foreign_types_shared; + +#[doc(inline)] +pub use foreign_types_shared::*; + +/// A macro to easily define wrappers for foreign types. +/// +/// # Examples +/// +/// ``` +/// #[macro_use] +/// extern crate foreign_types; +/// +/// # mod openssl_sys { pub type SSL = (); pub unsafe fn SSL_free(_: *mut SSL) {} pub unsafe fn SSL_dup(x: *mut SSL) -> *mut SSL {x} } +/// foreign_type! { +/// type CType = openssl_sys::SSL; +/// fn drop = openssl_sys::SSL_free; +/// fn clone = openssl_sys::SSL_dup; +/// /// Documentation for the owned type. +/// pub struct Ssl; +/// /// Documentation for the borrowed type. +/// pub struct SslRef; +/// } +/// +/// # fn main() {} +/// ``` +#[macro_export] +macro_rules! foreign_type { + ( + $(#[$impl_attr:meta])* + type CType = $ctype:ty; + fn drop = $drop:expr; + $(fn clone = $clone:expr;)* + $(#[$owned_attr:meta])* + pub struct $owned:ident; + $(#[$borrowed_attr:meta])* + pub struct $borrowed:ident; + ) => { + $(#[$owned_attr])* + pub struct $owned(*mut $ctype); + + $(#[$impl_attr])* + impl $crate::ForeignType for $owned { + type CType = $ctype; + type Ref = $borrowed; + + #[inline] + unsafe fn from_ptr(ptr: *mut $ctype) -> $owned { + $owned(ptr) + } + + #[inline] + fn as_ptr(&self) -> *mut $ctype { + self.0 + } + } + + impl Drop for $owned { + #[inline] + fn drop(&mut self) { + unsafe { $drop(self.0) } + } + } + + $( + impl Clone for $owned { + #[inline] + fn clone(&self) -> $owned { + unsafe { + let handle: *mut $ctype = $clone(self.0); + $crate::ForeignType::from_ptr(handle) + } + } + } + + impl ::std::borrow::ToOwned for $borrowed { + type Owned = $owned; + #[inline] + fn to_owned(&self) -> $owned { + unsafe { + let handle: *mut $ctype = $clone($crate::ForeignTypeRef::as_ptr(self)); + $crate::ForeignType::from_ptr(handle) + } + } + } + )* + + impl ::std::ops::Deref for $owned { + type Target = $borrowed; + + #[inline] + fn deref(&self) -> &$borrowed { + unsafe { $crate::ForeignTypeRef::from_ptr(self.0) } + } + } + + impl ::std::ops::DerefMut for $owned { + #[inline] + fn deref_mut(&mut self) -> &mut $borrowed { + unsafe { $crate::ForeignTypeRef::from_ptr_mut(self.0) } + } + } + + impl ::std::borrow::Borrow<$borrowed> for $owned { + #[inline] + fn borrow(&self) -> &$borrowed { + &**self + } + } + + impl ::std::convert::AsRef<$borrowed> for $owned { + #[inline] + fn as_ref(&self) -> &$borrowed { + &**self + } + } + + $(#[$borrowed_attr])* + pub struct $borrowed($crate::Opaque); + + $(#[$impl_attr])* + impl $crate::ForeignTypeRef for $borrowed { + type CType = $ctype; + } + } +} diff --git a/vendor/itoa/.cargo-checksum.json b/vendor/itoa/.cargo-checksum.json new file mode 100644 index 0000000..ff584ba --- /dev/null +++ b/vendor/itoa/.cargo-checksum.json @@ -0,0 +1 @@ +{"files":{"Cargo.toml":"4b12156f19f1d3a10516ba0177197325f072340e40de4b6a376732fcef3105b2","LICENSE-APACHE":"62c7a1e35f56406896d7aa7ca52d0cc0d272ac022b5d2796e7d6905db8a3636a","LICENSE-MIT":"23f18e03dc49df91622fe2a76176497404e46ced8a715d9d2b67a7446571cca3","README.md":"48573443063fa4e0786c3b46f42b6efd1f171c6b73408a64afc1b34de89f31fe","benches/bench.rs":"636f3093bd461210ad3063289d455f90669c4a1be3273bcd30898de39f02c641","src/lib.rs":"22f02b06399d4c6849dac5a1b517d3e5736dd33edc3955101ee0be6afc8376eb","src/udiv128.rs":"d28c1872c37ee2185931babcb20a221b8706a5aa8abc4963419763888023ff17","tests/test.rs":"aa1e910573a1d847d39773b4a2e4c597a8d3810070332673df0f6864cab24807"},"package":"49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b"} \ No newline at end of file diff --git a/vendor/itoa/Cargo.toml b/vendor/itoa/Cargo.toml new file mode 100644 index 0000000..91fe913 --- /dev/null +++ b/vendor/itoa/Cargo.toml @@ -0,0 +1,43 @@ +# 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] +edition = "2018" +rust-version = "1.36" +name = "itoa" +version = "1.0.11" +authors = ["David Tolnay "] +exclude = [ + "performance.png", + "chart/**", +] +description = "Fast integer primitive to string conversion" +documentation = "https://docs.rs/itoa" +readme = "README.md" +keywords = ["integer"] +categories = [ + "value-formatting", + "no-std", + "no-std::no-alloc", +] +license = "MIT OR Apache-2.0" +repository = "https://github.com/dtolnay/itoa" + +[package.metadata.docs.rs] +rustdoc-args = ["--generate-link-to-definition"] +targets = ["x86_64-unknown-linux-gnu"] + +[lib] +doc-scrape-examples = false + +[dependencies.no-panic] +version = "0.1" +optional = true diff --git a/vendor/itoa/LICENSE-APACHE b/vendor/itoa/LICENSE-APACHE new file mode 100644 index 0000000..1b5ec8b --- /dev/null +++ b/vendor/itoa/LICENSE-APACHE @@ -0,0 +1,176 @@ + 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 diff --git a/vendor/itoa/LICENSE-MIT b/vendor/itoa/LICENSE-MIT new file mode 100644 index 0000000..31aa793 --- /dev/null +++ b/vendor/itoa/LICENSE-MIT @@ -0,0 +1,23 @@ +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/itoa/README.md b/vendor/itoa/README.md new file mode 100644 index 0000000..5728fb7 --- /dev/null +++ b/vendor/itoa/README.md @@ -0,0 +1,59 @@ +itoa +==== + +[github](https://github.com/dtolnay/itoa) +[crates.io](https://crates.io/crates/itoa) +[docs.rs](https://docs.rs/itoa) +[build status](https://github.com/dtolnay/itoa/actions?query=branch%3Amaster) + +This crate provides a fast conversion of integer primitives to decimal strings. +The implementation comes straight from [libcore] but avoids the performance +penalty of going through [`core::fmt::Formatter`]. + +See also [`ryu`] for printing floating point primitives. + +*Version requirement: rustc 1.36+* + +[libcore]: https://github.com/rust-lang/rust/blob/b8214dc6c6fc20d0a660fb5700dca9ebf51ebe89/src/libcore/fmt/num.rs#L201-L254 +[`core::fmt::Formatter`]: https://doc.rust-lang.org/std/fmt/struct.Formatter.html +[`ryu`]: https://github.com/dtolnay/ryu + +```toml +[dependencies] +itoa = "1.0" +``` + +
+ +## Example + +```rust +fn main() { + let mut buffer = itoa::Buffer::new(); + let printed = buffer.format(128u64); + assert_eq!(printed, "128"); +} +``` + +
+ +## Performance (lower is better) + +![performance](https://raw.githubusercontent.com/dtolnay/itoa/master/performance.png) + +
+ +#### License + + +Licensed under either of Apache License, Version +2.0 or MIT license at your option. + + +
+ + +Unless you explicitly state otherwise, any contribution intentionally submitted +for inclusion in this crate 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/itoa/benches/bench.rs b/vendor/itoa/benches/bench.rs new file mode 100644 index 0000000..acd2a0c --- /dev/null +++ b/vendor/itoa/benches/bench.rs @@ -0,0 +1,55 @@ +#![feature(test)] +#![allow(non_snake_case)] +#![allow(clippy::cast_lossless)] + +extern crate test; + +macro_rules! benches { + ($($name:ident($value:expr))*) => { + mod bench_itoa_format { + use test::{Bencher, black_box}; + + $( + #[bench] + fn $name(b: &mut Bencher) { + let mut buffer = itoa::Buffer::new(); + + b.iter(|| { + let printed = buffer.format(black_box($value)); + black_box(printed); + }); + } + )* + } + + mod bench_std_fmt { + use std::io::Write; + use test::{Bencher, black_box}; + + $( + #[bench] + fn $name(b: &mut Bencher) { + let mut buf = Vec::with_capacity(40); + + b.iter(|| { + buf.clear(); + write!(&mut buf, "{}", black_box($value)).unwrap(); + black_box(&buf); + }); + } + )* + } + } +} + +benches! { + bench_u64_0(0u64) + bench_u64_half(u32::max_value() as u64) + bench_u64_max(u64::max_value()) + + bench_i16_0(0i16) + bench_i16_min(i16::min_value()) + + bench_u128_0(0u128) + bench_u128_max(u128::max_value()) +} diff --git a/vendor/itoa/src/lib.rs b/vendor/itoa/src/lib.rs new file mode 100644 index 0000000..8d6721d --- /dev/null +++ b/vendor/itoa/src/lib.rs @@ -0,0 +1,309 @@ +//! [![github]](https://github.com/dtolnay/itoa) [![crates-io]](https://crates.io/crates/itoa) [![docs-rs]](https://docs.rs/itoa) +//! +//! [github]: https://img.shields.io/badge/github-8da0cb?style=for-the-badge&labelColor=555555&logo=github +//! [crates-io]: https://img.shields.io/badge/crates.io-fc8d62?style=for-the-badge&labelColor=555555&logo=rust +//! [docs-rs]: https://img.shields.io/badge/docs.rs-66c2a5?style=for-the-badge&labelColor=555555&logo=docs.rs +//! +//!
+//! +//! This crate provides a fast conversion of integer primitives to decimal +//! strings. The implementation comes straight from [libcore] but avoids the +//! performance penalty of going through [`core::fmt::Formatter`]. +//! +//! See also [`ryu`] for printing floating point primitives. +//! +//! [libcore]: https://github.com/rust-lang/rust/blob/b8214dc6c6fc20d0a660fb5700dca9ebf51ebe89/src/libcore/fmt/num.rs#L201-L254 +//! [`core::fmt::Formatter`]: https://doc.rust-lang.org/std/fmt/struct.Formatter.html +//! [`ryu`]: https://github.com/dtolnay/ryu +//! +//! # Example +//! +//! ``` +//! fn main() { +//! let mut buffer = itoa::Buffer::new(); +//! let printed = buffer.format(128u64); +//! assert_eq!(printed, "128"); +//! } +//! ``` +//! +//! # Performance (lower is better) +//! +//! ![performance](https://raw.githubusercontent.com/dtolnay/itoa/master/performance.png) + +#![doc(html_root_url = "https://docs.rs/itoa/1.0.11")] +#![no_std] +#![allow( + clippy::cast_lossless, + clippy::cast_possible_truncation, + clippy::expl_impl_clone_on_copy, + clippy::must_use_candidate, + clippy::needless_doctest_main, + clippy::unreadable_literal +)] + +mod udiv128; + +use core::mem::{self, MaybeUninit}; +use core::{ptr, slice, str}; +#[cfg(feature = "no-panic")] +use no_panic::no_panic; + +/// A correctly sized stack allocation for the formatted integer to be written +/// into. +/// +/// # Example +/// +/// ``` +/// let mut buffer = itoa::Buffer::new(); +/// let printed = buffer.format(1234); +/// assert_eq!(printed, "1234"); +/// ``` +pub struct Buffer { + bytes: [MaybeUninit; I128_MAX_LEN], +} + +impl Default for Buffer { + #[inline] + fn default() -> Buffer { + Buffer::new() + } +} + +impl Copy for Buffer {} + +impl Clone for Buffer { + #[inline] + #[allow(clippy::non_canonical_clone_impl)] // false positive https://github.com/rust-lang/rust-clippy/issues/11072 + fn clone(&self) -> Self { + Buffer::new() + } +} + +impl Buffer { + /// This is a cheap operation; you don't need to worry about reusing buffers + /// for efficiency. + #[inline] + #[cfg_attr(feature = "no-panic", no_panic)] + pub fn new() -> Buffer { + let bytes = [MaybeUninit::::uninit(); I128_MAX_LEN]; + Buffer { bytes } + } + + /// Print an integer into this buffer and return a reference to its string + /// representation within the buffer. + #[cfg_attr(feature = "no-panic", no_panic)] + pub fn format(&mut self, i: I) -> &str { + i.write(unsafe { + &mut *(&mut self.bytes as *mut [MaybeUninit; I128_MAX_LEN] + as *mut ::Buffer) + }) + } +} + +/// An integer that can be written into an [`itoa::Buffer`][Buffer]. +/// +/// This trait is sealed and cannot be implemented for types outside of itoa. +pub trait Integer: private::Sealed {} + +// Seal to prevent downstream implementations of the Integer trait. +mod private { + pub trait Sealed: Copy { + type Buffer: 'static; + fn write(self, buf: &mut Self::Buffer) -> &str; + } +} + +const DEC_DIGITS_LUT: &[u8] = b"\ + 0001020304050607080910111213141516171819\ + 2021222324252627282930313233343536373839\ + 4041424344454647484950515253545556575859\ + 6061626364656667686970717273747576777879\ + 8081828384858687888990919293949596979899"; + +// Adaptation of the original implementation at +// https://github.com/rust-lang/rust/blob/b8214dc6c6fc20d0a660fb5700dca9ebf51ebe89/src/libcore/fmt/num.rs#L188-L266 +macro_rules! impl_Integer { + ($($max_len:expr => $t:ident),* as $conv_fn:ident) => {$( + impl Integer for $t {} + + impl private::Sealed for $t { + type Buffer = [MaybeUninit; $max_len]; + + #[allow(unused_comparisons)] + #[inline] + #[cfg_attr(feature = "no-panic", no_panic)] + fn write(self, buf: &mut [MaybeUninit; $max_len]) -> &str { + let is_nonnegative = self >= 0; + let mut n = if is_nonnegative { + self as $conv_fn + } else { + // Convert negative number to positive by summing 1 to its two's complement. + (!(self as $conv_fn)).wrapping_add(1) + }; + let mut curr = buf.len() as isize; + let buf_ptr = buf.as_mut_ptr() as *mut u8; + let lut_ptr = DEC_DIGITS_LUT.as_ptr(); + + // Need at least 16 bits for the 4-digits-at-a-time to work. + if mem::size_of::<$t>() >= 2 { + // Eagerly decode 4 digits at a time. + while n >= 10000 { + let rem = (n % 10000) as isize; + n /= 10000; + + let d1 = (rem / 100) << 1; + let d2 = (rem % 100) << 1; + curr -= 4; + unsafe { + ptr::copy_nonoverlapping(lut_ptr.offset(d1), buf_ptr.offset(curr), 2); + ptr::copy_nonoverlapping(lut_ptr.offset(d2), buf_ptr.offset(curr + 2), 2); + } + } + } + + // If we reach here, numbers are <=9999 so at most 4 digits long. + let mut n = n as isize; // Possibly reduce 64-bit math. + + // Decode 2 more digits, if >2 digits. + if n >= 100 { + let d1 = (n % 100) << 1; + n /= 100; + curr -= 2; + unsafe { + ptr::copy_nonoverlapping(lut_ptr.offset(d1), buf_ptr.offset(curr), 2); + } + } + + // Decode last 1 or 2 digits. + if n < 10 { + curr -= 1; + unsafe { + *buf_ptr.offset(curr) = (n as u8) + b'0'; + } + } else { + let d1 = n << 1; + curr -= 2; + unsafe { + ptr::copy_nonoverlapping(lut_ptr.offset(d1), buf_ptr.offset(curr), 2); + } + } + + if !is_nonnegative { + curr -= 1; + unsafe { + *buf_ptr.offset(curr) = b'-'; + } + } + + let len = buf.len() - curr as usize; + let bytes = unsafe { slice::from_raw_parts(buf_ptr.offset(curr), len) }; + unsafe { str::from_utf8_unchecked(bytes) } + } + } + )*}; +} + +const I8_MAX_LEN: usize = 4; +const U8_MAX_LEN: usize = 3; +const I16_MAX_LEN: usize = 6; +const U16_MAX_LEN: usize = 5; +const I32_MAX_LEN: usize = 11; +const U32_MAX_LEN: usize = 10; +const I64_MAX_LEN: usize = 20; +const U64_MAX_LEN: usize = 20; + +impl_Integer!( + I8_MAX_LEN => i8, + U8_MAX_LEN => u8, + I16_MAX_LEN => i16, + U16_MAX_LEN => u16, + I32_MAX_LEN => i32, + U32_MAX_LEN => u32 + as u32); + +impl_Integer!(I64_MAX_LEN => i64, U64_MAX_LEN => u64 as u64); + +#[cfg(target_pointer_width = "16")] +impl_Integer!(I16_MAX_LEN => isize, U16_MAX_LEN => usize as u16); + +#[cfg(target_pointer_width = "32")] +impl_Integer!(I32_MAX_LEN => isize, U32_MAX_LEN => usize as u32); + +#[cfg(target_pointer_width = "64")] +impl_Integer!(I64_MAX_LEN => isize, U64_MAX_LEN => usize as u64); + +macro_rules! impl_Integer128 { + ($($max_len:expr => $t:ident),*) => {$( + impl Integer for $t {} + + impl private::Sealed for $t { + type Buffer = [MaybeUninit; $max_len]; + + #[allow(unused_comparisons)] + #[inline] + #[cfg_attr(feature = "no-panic", no_panic)] + fn write(self, buf: &mut [MaybeUninit; $max_len]) -> &str { + let is_nonnegative = self >= 0; + let n = if is_nonnegative { + self as u128 + } else { + // Convert negative number to positive by summing 1 to its two's complement. + (!(self as u128)).wrapping_add(1) + }; + let mut curr = buf.len() as isize; + let buf_ptr = buf.as_mut_ptr() as *mut u8; + + // Divide by 10^19 which is the highest power less than 2^64. + let (n, rem) = udiv128::udivmod_1e19(n); + let buf1 = unsafe { buf_ptr.offset(curr - U64_MAX_LEN as isize) as *mut [MaybeUninit; U64_MAX_LEN] }; + curr -= rem.write(unsafe { &mut *buf1 }).len() as isize; + + if n != 0 { + // Memset the base10 leading zeros of rem. + let target = buf.len() as isize - 19; + unsafe { + ptr::write_bytes(buf_ptr.offset(target), b'0', (curr - target) as usize); + } + curr = target; + + // Divide by 10^19 again. + let (n, rem) = udiv128::udivmod_1e19(n); + let buf2 = unsafe { buf_ptr.offset(curr - U64_MAX_LEN as isize) as *mut [MaybeUninit; U64_MAX_LEN] }; + curr -= rem.write(unsafe { &mut *buf2 }).len() as isize; + + if n != 0 { + // Memset the leading zeros. + let target = buf.len() as isize - 38; + unsafe { + ptr::write_bytes(buf_ptr.offset(target), b'0', (curr - target) as usize); + } + curr = target; + + // There is at most one digit left + // because u128::MAX / 10^19 / 10^19 is 3. + curr -= 1; + unsafe { + *buf_ptr.offset(curr) = (n as u8) + b'0'; + } + } + } + + if !is_nonnegative { + curr -= 1; + unsafe { + *buf_ptr.offset(curr) = b'-'; + } + } + + let len = buf.len() - curr as usize; + let bytes = unsafe { slice::from_raw_parts(buf_ptr.offset(curr), len) }; + unsafe { str::from_utf8_unchecked(bytes) } + } + } + )*}; +} + +const U128_MAX_LEN: usize = 39; +const I128_MAX_LEN: usize = 40; + +impl_Integer128!(I128_MAX_LEN => i128, U128_MAX_LEN => u128); diff --git a/vendor/itoa/src/udiv128.rs b/vendor/itoa/src/udiv128.rs new file mode 100644 index 0000000..0587047 --- /dev/null +++ b/vendor/itoa/src/udiv128.rs @@ -0,0 +1,48 @@ +#[cfg(feature = "no-panic")] +use no_panic::no_panic; + +/// Multiply unsigned 128 bit integers, return upper 128 bits of the result +#[inline] +#[cfg_attr(feature = "no-panic", no_panic)] +fn u128_mulhi(x: u128, y: u128) -> u128 { + let x_lo = x as u64; + let x_hi = (x >> 64) as u64; + let y_lo = y as u64; + let y_hi = (y >> 64) as u64; + + // handle possibility of overflow + let carry = (x_lo as u128 * y_lo as u128) >> 64; + let m = x_lo as u128 * y_hi as u128 + carry; + let high1 = m >> 64; + + let m_lo = m as u64; + let high2 = (x_hi as u128 * y_lo as u128 + m_lo as u128) >> 64; + + x_hi as u128 * y_hi as u128 + high1 + high2 +} + +/// Divide `n` by 1e19 and return quotient and remainder +/// +/// Integer division algorithm is based on the following paper: +/// +/// T. Granlund and P. Montgomery, “Division by Invariant Integers Using Multiplication” +/// in Proc. of the SIGPLAN94 Conference on Programming Language Design and +/// Implementation, 1994, pp. 61–72 +/// +#[inline] +#[cfg_attr(feature = "no-panic", no_panic)] +pub fn udivmod_1e19(n: u128) -> (u128, u64) { + let d = 10_000_000_000_000_000_000_u64; // 10^19 + + let quot = if n < 1 << 83 { + ((n >> 19) as u64 / (d >> 19)) as u128 + } else { + u128_mulhi(n, 156927543384667019095894735580191660403) >> 62 + }; + + let rem = (n - quot * d as u128) as u64; + debug_assert_eq!(quot, n / d as u128); + debug_assert_eq!(rem as u128, n % d as u128); + + (quot, rem) +} diff --git a/vendor/itoa/tests/test.rs b/vendor/itoa/tests/test.rs new file mode 100644 index 0000000..f8275d6 --- /dev/null +++ b/vendor/itoa/tests/test.rs @@ -0,0 +1,30 @@ +#![allow(non_snake_case)] +#![allow(clippy::cast_lossless)] + +macro_rules! test { + ($($name:ident($value:expr, $expected:expr))*) => { + $( + #[test] + fn $name() { + let mut buffer = itoa::Buffer::new(); + let s = buffer.format($value); + assert_eq!(s, $expected); + } + )* + } +} + +test! { + test_u64_0(0u64, "0") + test_u64_half(u32::max_value() as u64, "4294967295") + test_u64_max(u64::max_value(), "18446744073709551615") + test_i64_min(i64::min_value(), "-9223372036854775808") + + test_i16_0(0i16, "0") + test_i16_min(i16::min_value(), "-32768") + + test_u128_0(0u128, "0") + test_u128_max(u128::max_value(), "340282366920938463463374607431768211455") + test_i128_min(i128::min_value(), "-170141183460469231731687303715884105728") + test_i128_max(i128::max_value(), "170141183460469231731687303715884105727") +} diff --git a/vendor/libc/.cargo-checksum.json b/vendor/libc/.cargo-checksum.json new file mode 100644 index 0000000..7193bb9 --- /dev/null +++ b/vendor/libc/.cargo-checksum.json @@ -0,0 +1 @@ +{"files":{"CHANGELOG.md":"00a63505931433eba3839574cda42b8120c51d87848a48db84566249e80a4683","CONTRIBUTING.md":"a93fcda0a76e1975fcfb0aa2ba00c9b1864f9ae6062704a294d81a3688898e10","Cargo.toml":"cd5c96ca2c050e73f246b496d6744fd99193c049a9adbac875d731e15d118afe","LICENSE-APACHE":"62c7a1e35f56406896d7aa7ca52d0cc0d272ac022b5d2796e7d6905db8a3636a","LICENSE-MIT":"a8d47ff51ca256f56a8932dba07660672dbfe3004257ca8de708aac1415937a1","README.md":"dcd338c238d2eede49c8e5031dae41297248bc72038aa0b6a74c276b7af8e4c1","build.rs":"c06d45444ada13db1b9faaafe2c3e85fe8c8e35e9450cf33496d595fa401c01c","rustfmt.toml":"eaa2ea84fc1ba0359b77680804903e07bb38d257ab11986b95b158e460f787b2","src/fixed_width_ints.rs":"7f986e5f5e68d25ef04d386fd2f640e8be8f15427a8d4a458ea01d26b8dca0ca","src/fuchsia/aarch64.rs":"893fcec48142d273063ffd814dca33fbec92205fd39ada97075f85201d803996","src/fuchsia/align.rs":"ae1cf8f011a99737eabeb14ffff768e60f13b13363d7646744dbb0f443dab3d6","src/fuchsia/mod.rs":"a8e3ff551e5ff4247ab1faa1b7ca1e042046a619198e8b30fe183c6ef8485d65","src/fuchsia/no_align.rs":"303f3f1b255e0088b5715094353cf00476131d8e94e6aebb3f469557771c8b8a","src/fuchsia/riscv64.rs":"617cd75e79e0e20f664db764a4dc2a396d9fd11a4d95371acd91ed4811293b11","src/fuchsia/x86_64.rs":"93a3632b5cf67d2a6bcb7dc0a558605252d5fe689e0f38d8aa2ec5852255ac87","src/hermit.rs":"fb4a1781b64586a03b06f0837f6882ded37c01018c1d1012eea5f36e4593b87b","src/lib.rs":"7f57f05b3d9e1e14a666aabbd942cf5959e778966981e604087774d56eb059c8","src/macros.rs":"5f985b3de7b18833f866bf832b8ffb0430f0f70aa9a468b6a2c855c1bf9d33e4","src/psp.rs":"0a7d5121a8cc2903009f586c00e4ae2d6126d24eb90531dafaba6f59823aa6b2","src/sgx.rs":"16a95cdefc81c5ee00d8353a60db363c4cc3e0f75abcd5d0144723f2a306ed1b","src/solid/aarch64.rs":"a726e47f324adf73a4a0b67a2c183408d0cad105ae66acf36db37a42ab7f8707","src/solid/arm.rs":"e39a4f74ebbef3b97b8c95758ad741123d84ed3eb48d9cf4f1f4872097fc27fe","src/solid/mod.rs":"5f4151dca5132e4b4e4c23ab9737e12856dddbdc0ca3f7dbc004328ef3c8acde","src/switch.rs":"9da3dd39b3de45a7928789926e8572d00e1e11a39e6f7289a1349aadce90edba","src/teeos/mod.rs":"ecf8922923fb7541ef7b0813cdc5418b75be56247c4dbdbb7dca58a076f25b97","src/unix/aix/mod.rs":"91de34bf8237e4998e10f9274471d14fb9a31ac6f2ef6e44689066b8e280b3d3","src/unix/aix/powerpc64.rs":"cf374d81139d45f9d77c6a764f640bfbf7e0a5903689652c8296f8e10d55169b","src/unix/align.rs":"93e08ec488a0a86a518c3c64b02d4fd18a91bdc03f7103495709062f3e9efd15","src/unix/bsd/apple/b32/align.rs":"ec833a747866fe19ca2d9b4d3c9ff0385faba5edf4bd0d15fa68884c40b0e26c","src/unix/bsd/apple/b32/mod.rs":"b68a100ef6bcdac138e4381b34cebdb97f3cc04fc7282c5200776933576e26ab","src/unix/bsd/apple/b64/aarch64/align.rs":"2eaf0f561a32bdcbf4e0477c8895d5e7bcb5cdebd5fef7b4df2ca8e38e144d94","src/unix/bsd/apple/b64/aarch64/mod.rs":"44c217a4f263afe7a97435de9323d20a96c37836f899ca0925306d4b7e073c27","src/unix/bsd/apple/b64/align.rs":"ec833a747866fe19ca2d9b4d3c9ff0385faba5edf4bd0d15fa68884c40b0e26c","src/unix/bsd/apple/b64/mod.rs":"dbe5d2cfda9517615f1bcd5ebf65508555795fd659eb5f2a3ba3ac9948dfc795","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":"b29927e1da40142316427e72ec3bea9c672f143a166ab15b2e73a2c33bbf3d68","src/unix/bsd/freebsdlike/dragonfly/errno.rs":"8295b8bb0dfd38d2cdb4d9192cdeeb534cc6c3b208170e64615fa3e0edb3e578","src/unix/bsd/freebsdlike/dragonfly/mod.rs":"de68129961129d85c8252d1eea7960151c61d817789b502ba1bf004e269ec6cd","src/unix/bsd/freebsdlike/freebsd/aarch64.rs":"6c8e216385f53a4bf5f171749b57602fc34a4e4b160a44ca31c058cb0c8a2126","src/unix/bsd/freebsdlike/freebsd/arm.rs":"a8749458ac9fec3f3594280bb2c83cf90e78e46026a05c2a5b5af22c7c28867d","src/unix/bsd/freebsdlike/freebsd/freebsd11/b32.rs":"019329b53448b550d2ae07be672facc886f4108c6440cc19bcd6ce2f398d91a5","src/unix/bsd/freebsdlike/freebsd/freebsd11/b64.rs":"9808d152c1196aa647f1b0f0cf84dac8c930da7d7f897a44975545e3d9d17681","src/unix/bsd/freebsdlike/freebsd/freebsd11/mod.rs":"65ae22c58b30221320d74dd97ca020a13f556314f5cdf7b9f5adb9683ef73f70","src/unix/bsd/freebsdlike/freebsd/freebsd12/mod.rs":"b95173192cc528b51c455fcaa7c8578eb3356e76b55924157f05a9a60cad95d3","src/unix/bsd/freebsdlike/freebsd/freebsd12/x86_64.rs":"2df36a7f122f6d6e5753cfb4d22e915cc80f6bc91c0161b3daae55a481bfd052","src/unix/bsd/freebsdlike/freebsd/freebsd13/mod.rs":"04857783746abeecea95a03d812e11fe59049742ae7f52a8507f5208eb25d4bb","src/unix/bsd/freebsdlike/freebsd/freebsd13/x86_64.rs":"2df36a7f122f6d6e5753cfb4d22e915cc80f6bc91c0161b3daae55a481bfd052","src/unix/bsd/freebsdlike/freebsd/freebsd14/mod.rs":"c299bdf43fea4b5f083b77ca181401d6d8f1f1edfb36f9afe22548bf4b3422c9","src/unix/bsd/freebsdlike/freebsd/freebsd14/x86_64.rs":"e7b5863e222d6cc416b6b0fbe71690fad909e899b4c4ae810bbca117e4fcb650","src/unix/bsd/freebsdlike/freebsd/freebsd15/mod.rs":"293d185c686b6ae62038287e3af42cf958c32f7e0b4acbfc4b8da47e9b77b9f3","src/unix/bsd/freebsdlike/freebsd/freebsd15/x86_64.rs":"e7b5863e222d6cc416b6b0fbe71690fad909e899b4c4ae810bbca117e4fcb650","src/unix/bsd/freebsdlike/freebsd/mod.rs":"819c393d6368d067735b1c6f41acf59e83952d6927720e7ef09d62ff878ac9a8","src/unix/bsd/freebsdlike/freebsd/powerpc.rs":"45f2293fcfc76f936cd1a075f3b7eb1a37433f86acf22f34d4346e16f8162c37","src/unix/bsd/freebsdlike/freebsd/powerpc64.rs":"d650fb558023c2e79cba812ed76b25342c12c516de2245d8ecd2f1c4fc9bd6fc","src/unix/bsd/freebsdlike/freebsd/riscv64.rs":"fa4bed4c58cad24ba3395941c7fa6b11e089551a04714f9561078e400f5b2b62","src/unix/bsd/freebsdlike/freebsd/x86.rs":"9640d6be072b07b36917a2d475fb9e30dce68a607b645a5e9de5591bd56b7024","src/unix/bsd/freebsdlike/freebsd/x86_64/align.rs":"0e1f69a88fca1c32874b1daf5db3d446fefbe518dca497f096cc9168c39dde70","src/unix/bsd/freebsdlike/freebsd/x86_64/mod.rs":"e4d76219bec0621db07dec37de9be1a9b7fb38daa10ffc1a6adbdbc34e163435","src/unix/bsd/freebsdlike/mod.rs":"e6872f3d66b99905846d57034c1d3b6da939de7b357e891b017f8ae643f0e84b","src/unix/bsd/mod.rs":"c8dddc969aee356415d42fb2045802c7e402fb6b019dd007f0e4e25010f97edb","src/unix/bsd/netbsdlike/mod.rs":"3f6ca44e28bd09a1aef70c74aaa7ba9bc5086b89984f2290530f0d89944edafa","src/unix/bsd/netbsdlike/netbsd/aarch64.rs":"057ee877db7193ba0dc10801b9a6563ac6dbdb78376d6851a84cb12b30841759","src/unix/bsd/netbsdlike/netbsd/arm.rs":"949b55e4dee1c8c511f4f061a6a57ac876a6c0eabfaf5cc20e9ab40d8f41b2e0","src/unix/bsd/netbsdlike/netbsd/mips.rs":"88be18ac43ba224c77e78e4179b6761debc5e6c30a258fac56263809c7af4fbc","src/unix/bsd/netbsdlike/netbsd/mod.rs":"febeb36ab9e653e8916c5476c5560b4eb12ea19153bb74fb591e4166afa013eb","src/unix/bsd/netbsdlike/netbsd/powerpc.rs":"ee7ff5d89d0ed22f531237b5059aa669df93a3b5c489fa641465ace8d405bf41","src/unix/bsd/netbsdlike/netbsd/riscv64.rs":"1cbe2e5ed681cb1054b699da37daaf6c714267df7d332c90fc2a589b11579625","src/unix/bsd/netbsdlike/netbsd/sparc64.rs":"9489f4b3e4566f43bb12dfb92238960613dac7f6a45cc13068a8d152b902d7d9","src/unix/bsd/netbsdlike/netbsd/x86.rs":"20692320e36bfe028d1a34d16fe12ca77aa909cb02bda167376f98f1a09aefe7","src/unix/bsd/netbsdlike/netbsd/x86_64.rs":"532b76199d6c71ff996eade9f906c55a72c9aff489595d25a21e21878cfd740b","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":"fc947eb997567037feb46d0e1404abc20de63e10cc2f9800d155d7b64bcd875c","src/unix/bsd/netbsdlike/openbsd/powerpc.rs":"01580d261bc6447bb327a0d982181b7bdabfa066cee65a30373d3ced729ad307","src/unix/bsd/netbsdlike/openbsd/powerpc64.rs":"1dd5449dd1fd3d51e30ffdeeaece91d0aaf05c710e0ac699fecc5461cfa2c28e","src/unix/bsd/netbsdlike/openbsd/riscv64.rs":"1fe3332dc705a13e6242219970f5449d6d7a73e2e6c8537ab8e421d8a6f2e3ff","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":"b40054667bedbaed9c27768ec10628187c530f488067d4f9e0fd86afde92ac1a","src/unix/haiku/native.rs":"2b1f88c043777a915bb7218aa05a3647a0e0481ebff55a99e351c45dea2be8de","src/unix/haiku/x86_64.rs":"3ec3aeeb7ed208b8916f3e32d42bfd085ff5e16936a1a35d9a52789f043b7237","src/unix/hurd/align.rs":"03c79b2cd8270ebd0cf93cb475a8f1ff85b28175ea0de007ede17cad94a89b03","src/unix/hurd/b32.rs":"2ba90ed973f90366c36a6387833a3df42abfee9622d4a0352635937d4a89eaf4","src/unix/hurd/b64.rs":"d919b4aec9b3080ad24c125c57b2c8b2e483d72045f1554c429d14560355846f","src/unix/hurd/mod.rs":"5900f5d2caa62fadf2d3098344d0a2b7495c4a05fde4cc6c46b74c94429ffee5","src/unix/hurd/no_align.rs":"03c79b2cd8270ebd0cf93cb475a8f1ff85b28175ea0de007ede17cad94a89b03","src/unix/linux_like/android/b32/arm.rs":"a817ce1e9ab47c1de31f447697f4480ac18a8d2b8f261b25dbc3e01b346c10a3","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":"cdfd47d24e464575a737c9902d4ea8fe1c8e3af824f4e8258fc47d5c26e15437","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":"bb8522d0a482d3a1a83d57d7c8d7c7504ee1447b121898316d206df91f1b95b2","src/unix/linux_like/android/b64/mod.rs":"c6403d74a0233796b61db7c16b5da16c33b913653e5c0ef467f63b8a6299ab5a","src/unix/linux_like/android/b64/riscv64/align.rs":"0bf138f84e5327d8339bcd4adf071a6832b516445e597552c82bbd881095e3a8","src/unix/linux_like/android/b64/riscv64/mod.rs":"27497d6f43bb38b860c486f19104bb2dbaec554384dcc35f2286cf8a71f2ad4b","src/unix/linux_like/android/b64/x86_64/align.rs":"7169d07a9fd4716f7512719aec9fda5d8bed306dc0720ffc1b21696c9951e3c6","src/unix/linux_like/android/b64/x86_64/mod.rs":"1237ceeae9cfb035aaa67e102633612b369dca1bb88c3573a2700af1b54eff46","src/unix/linux_like/android/mod.rs":"66f047d4ead41af0987db997a7c53c7c726af8ae8302591094f79fd9113994a6","src/unix/linux_like/emscripten/align.rs":"86c95cbed7a7161b1f23ee06843e7b0e2340ad92b2cb86fe2a8ef3e0e8c36216","src/unix/linux_like/emscripten/lfs64.rs":"3776af30a758d765a88920ec4fde442ab89040da13d3b3625c7fbcb8a958559f","src/unix/linux_like/emscripten/mod.rs":"a90b1520ddc6d3a4f792f1d423a62e925efaa63ed169d6e35b1c9b940cb76681","src/unix/linux_like/emscripten/no_align.rs":"0128e4aa721a9902754828b61b5ec7d8a86619983ed1e0544a85d35b1051fad6","src/unix/linux_like/linux/align.rs":"c2b0beda8ffb03c2068f5f45aeb417030cc94a0294a2810d8dec6e87a65af8ba","src/unix/linux_like/linux/arch/generic/mod.rs":"3ab533349696d24505adb6bb9183d73fd5e3b17e2f90dd21478af2a47b4d6fa8","src/unix/linux_like/linux/arch/mips/mod.rs":"ca3db0e3ae852abf18f3588e40d5d64707fcc1829e08ddc5da1080e1a92c8851","src/unix/linux_like/linux/arch/mod.rs":"5bd5361f8a6ab4e18bbba6da9f92c164ae252b15a0ed10064812544aa1fdf198","src/unix/linux_like/linux/arch/powerpc/mod.rs":"0bc2d2667a00eca81f4abeb6d613a90848a947f51224103f83268928b8197629","src/unix/linux_like/linux/arch/sparc/mod.rs":"5e6777863e74a9e2aa9dc487f1059783dd211babc2b32d6bf676f311e49c55d6","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":"b8bf225aa589e52471eab5193c9270e1492b42232c09d16c6e01aeb29f102945","src/unix/linux_like/linux/gnu/b32/csky/align.rs":"3fed009dc9af3cc81be7087da9d2d7d1f39845e4497e290259c5cdbae25f039d","src/unix/linux_like/linux/gnu/b32/csky/mod.rs":"8729b68e433e94c2128e51a7db4fd555938e4be4dc64584c352b24a20d9c8e91","src/unix/linux_like/linux/gnu/b32/m68k/align.rs":"8faa92f77a9232c035418d45331774e64a9a841d99c91791570a203bf2b45bcb","src/unix/linux_like/linux/gnu/b32/m68k/mod.rs":"80956d3fef163ecf248828a6f38782dd8ae856d86b1bb5aac2de36032dbd8ea0","src/unix/linux_like/linux/gnu/b32/mips/align.rs":"429fb5e005cb7143602d430098b6ebfb7d360685b194f333dfd587472ae954ee","src/unix/linux_like/linux/gnu/b32/mips/mod.rs":"96e22350d5d132d917c743d6560464500652c67b52c3d0e8474494487df3365d","src/unix/linux_like/linux/gnu/b32/mod.rs":"b56625dd20dd48a8699034d349ef089c540c0ddcbf8a3481d598d101f8b40b78","src/unix/linux_like/linux/gnu/b32/powerpc.rs":"2cd0f4128eee4120275e1f0706729c28c32426c01adbc54dbc7104e72e9c6185","src/unix/linux_like/linux/gnu/b32/riscv32/align.rs":"d321491612be8d5c61b6ec2dc0111beb3a22e58803f99cd37543efe86621b119","src/unix/linux_like/linux/gnu/b32/riscv32/mod.rs":"887288a0a1cfff319d0e15edcdc4fcb31fd643ff41715ec5244c8f2413624169","src/unix/linux_like/linux/gnu/b32/sparc/align.rs":"21adbed27df73e2d1ed934aaf733a643003d7baf2bde9c48ea440895bcca6d41","src/unix/linux_like/linux/gnu/b32/sparc/mod.rs":"cc4342b949e4d796f304acd9dfe3f721a1c2f37fec16b42d3bb27dc94723af37","src/unix/linux_like/linux/gnu/b32/x86/align.rs":"e4bafdc4a519a7922a81b37a62bbfd1177a2f620890eef8f1fbc47162e9eb413","src/unix/linux_like/linux/gnu/b32/x86/mod.rs":"772b5f144ba8f7dd481e7956fa922c98e7173616fa4dc312f17a56702fdc7c6d","src/unix/linux_like/linux/gnu/b64/aarch64/align.rs":"fdf1c72375a2167699157e0dd825422690bb6719f7bc69515a2e5846d0431d7c","src/unix/linux_like/linux/gnu/b64/aarch64/fallback.rs":"832e7487249c1c0bb6e9911ce3f7d32ca22378e42392ab83c56915cbc59d8be3","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":"23c9aaf3a154d1ce6606791d9a9a93625f6a0d091097b18a63a01f451ce9da44","src/unix/linux_like/linux/gnu/b64/loongarch64/align.rs":"060aa33cc737966c691aab8511c5c5729e551458ce18d0e284e0d45f39beeb60","src/unix/linux_like/linux/gnu/b64/loongarch64/mod.rs":"10f025edecebc6e0ed8fdae4736ebe7564189741d5b910433f07c21fc12a94d8","src/unix/linux_like/linux/gnu/b64/mips64/align.rs":"7169d07a9fd4716f7512719aec9fda5d8bed306dc0720ffc1b21696c9951e3c6","src/unix/linux_like/linux/gnu/b64/mips64/mod.rs":"73532be4b5775acf9524c77feeefe1f6d1936ceffef908d01dd2586986520f2d","src/unix/linux_like/linux/gnu/b64/mod.rs":"6a160ef25439c4fecdb0e3bd0b818742263c791364da874d4febd3aa644ec8e2","src/unix/linux_like/linux/gnu/b64/powerpc64/align.rs":"e29c4868bbecfa4a6cd8a2ad06193f3bbc78a468cc1dc9df83f002f1268130d9","src/unix/linux_like/linux/gnu/b64/powerpc64/mod.rs":"a90c2641616c620e9d1fea87695ce046e14f9da2282bb93f761eeb4077c74741","src/unix/linux_like/linux/gnu/b64/riscv64/align.rs":"fe7e3c928d0367c37eb652686591801c3694a3558ebbbeb5c22be692265d07f2","src/unix/linux_like/linux/gnu/b64/riscv64/mod.rs":"dec86883731f7b8419bff35b125b40eefc927090c1510f6daf931726f7965c0b","src/unix/linux_like/linux/gnu/b64/s390x.rs":"6f5c788ba4a05ef8c2045c24dba160f2e3e7391d474fa0796de2915e3706ba3c","src/unix/linux_like/linux/gnu/b64/sparc64/align.rs":"e29c4868bbecfa4a6cd8a2ad06193f3bbc78a468cc1dc9df83f002f1268130d9","src/unix/linux_like/linux/gnu/b64/sparc64/mod.rs":"bed381c44cec2a5b50125f7e548ab487d4c829006c971d152a611b7141760052","src/unix/linux_like/linux/gnu/b64/x86_64/align.rs":"62e822478356db4a73b6bbd1b36d825b893939ab4b308ec11b0578bcc4b49769","src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs":"ba753a7997864baa04097de1176c2a2618ea8495b2342f43af81b39b4a0ba7eb","src/unix/linux_like/linux/gnu/b64/x86_64/not_x32.rs":"1901db260c5fbbe57ba13e034ba88d7780302b272c03cafd2963535d9d3b7b7e","src/unix/linux_like/linux/gnu/b64/x86_64/x32.rs":"46230160f3ec999bcdeeb6f363d1e930619e67a6a80652bdd12709ef71975c7d","src/unix/linux_like/linux/gnu/mod.rs":"e448e29b9d2f35ea9adccf24397365e5a9d680ef31e88680be9750242b5f797c","src/unix/linux_like/linux/gnu/no_align.rs":"9cd223135de75315840ff9c3fd5441ba1cb632b96b5c85a76f8316c86653db25","src/unix/linux_like/linux/mod.rs":"544d76a04c916d536e5e151e1ea5dedb70e4d7fa1074100f35639438fff7bf4e","src/unix/linux_like/linux/musl/b32/arm/align.rs":"3e8ac052c1043764776b54c93ba4260e061df998631737a897d9d47d54f7b80c","src/unix/linux_like/linux/musl/b32/arm/mod.rs":"3466888b7a46f2f63f5318762011e03634c2b3ecea5125e305ef5e16438062f1","src/unix/linux_like/linux/musl/b32/hexagon.rs":"d079cab42529f7dab699334d43168c74ff4aa0282f11040a8b7d274b65767a7a","src/unix/linux_like/linux/musl/b32/mips/align.rs":"429fb5e005cb7143602d430098b6ebfb7d360685b194f333dfd587472ae954ee","src/unix/linux_like/linux/musl/b32/mips/mod.rs":"e44043766f7cd26de7ffa4232654afb6feb03e58dbd5890717970887bd003151","src/unix/linux_like/linux/musl/b32/mod.rs":"31677597fd9544c4b1ec1477628288f6273fabbc06e38f33da862ad55f019ce1","src/unix/linux_like/linux/musl/b32/powerpc.rs":"98508bd9493f0f5858184be71595694bb2d0ab4bb1151a773ccc1bed33cb9b95","src/unix/linux_like/linux/musl/b32/riscv32/align.rs":"efd2accf33b87de7c7547903359a5da896edc33cd6c719552c7474b60d4a5d48","src/unix/linux_like/linux/musl/b32/riscv32/mod.rs":"3ee845d272f91a1908d5f421d7c353e1f14681bbdfef64410e408f4c14365a91","src/unix/linux_like/linux/musl/b32/x86/align.rs":"08e77fbd7435d7dec2ff56932433bece3f02e47ce810f89004a275a86d39cbe1","src/unix/linux_like/linux/musl/b32/x86/mod.rs":"25a7efca08ff96cc39b3da374b35e17eae13597a60ad854655949388ea3d4f64","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":"b35b8fd1771b1b07b6b045cf9fd5b46ba877e467199d18635dd8aab50823daa4","src/unix/linux_like/linux/musl/b64/loongarch64/align.rs":"060aa33cc737966c691aab8511c5c5729e551458ce18d0e284e0d45f39beeb60","src/unix/linux_like/linux/musl/b64/loongarch64/mod.rs":"3d9ef92e682a1789544a2bd20cad5a5623db9d7d9f5d0a3692bb0230af034165","src/unix/linux_like/linux/musl/b64/mips64.rs":"a968ef9c54fa22293085f318c8472c1754482df92cc500568dc33bd807d71ea6","src/unix/linux_like/linux/musl/b64/mod.rs":"20ceaf90a03c24a2eb154a5dffbfc9a538348404db5b554a3d8126021ba45509","src/unix/linux_like/linux/musl/b64/powerpc64.rs":"140e579800a67315f4cb8a42b22aa8157eae34ffe626e77e421b43c53c23b34d","src/unix/linux_like/linux/musl/b64/riscv64/align.rs":"fe7e3c928d0367c37eb652686591801c3694a3558ebbbeb5c22be692265d07f2","src/unix/linux_like/linux/musl/b64/riscv64/mod.rs":"c5944526d7e19cd43e9d14d119a1d98f8780db7ecbcc79e69d7b9348e596b520","src/unix/linux_like/linux/musl/b64/s390x.rs":"b48edee0693b5c59a5e24bd239469f430258a334d9914e57c39dae572214bb21","src/unix/linux_like/linux/musl/b64/x86_64/align.rs":"77309276ad7a42cbe59ca381f23590b7a143aded05555b34a5b307b808cbca6e","src/unix/linux_like/linux/musl/b64/x86_64/mod.rs":"af3532523b56aa4417e0f3b7a8f6c9138e65db594ec63aa4ea7bf34c7b728f2a","src/unix/linux_like/linux/musl/lfs64.rs":"3e4fb381f3a0756520bde0f1692d4fa45e4ae8133bf7d7c64b0e3fdd512f235f","src/unix/linux_like/linux/musl/mod.rs":"0a9d87bcae05265ad65269c41bafb621a1086d8cc2aa7d2b9c79bfe9ab85dd4e","src/unix/linux_like/linux/no_align.rs":"29a591dbbdd66e72666b4dfcb50b9dff33c1eefc4169e898c84c4b171e49d1a5","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":"8424edc59f5670d2ab82bda9fba828af8798bffc93cdb7d8b82a3f5d76eedb77","src/unix/linux_like/linux/uclibc/no_align.rs":"3f28637046524618adaa1012e26cb7ffe94b9396e6b518cccdc69d59f274d709","src/unix/linux_like/linux/uclibc/x86_64/l4re.rs":"8485b9182b7c67f7344fab377e7cc2a72afefd9ab63837c860514abba9728d76","src/unix/linux_like/linux/uclibc/x86_64/mod.rs":"e7197f0f68ece174c8ae42b2b9115893abfcdbe44a1a6ed98fb3cbd7bfe087e8","src/unix/linux_like/linux/uclibc/x86_64/other.rs":"42c3f71e58cabba373f6a55a623f3c31b85049eb64824c09c2b082b3b2d6a0a8","src/unix/linux_like/mod.rs":"863f628cbaa864911ffebc58e9fb788b6c6a9651955fc401ac1f40f20eb62505","src/unix/mod.rs":"a3544f9e681e84caac85ab44d1194887ce65724902c45a4451755b81491e40bf","src/unix/newlib/aarch64/mod.rs":"964c096288da836b53c0c71d7f3a97048d177da220a69314c5ce93ba330d72af","src/unix/newlib/align.rs":"28aaf87fafbc6b312622719d472d8cf65f9e5467d15339df5f73e66d8502b28a","src/unix/newlib/arm/mod.rs":"cf754f8b1197489fca01e881a4b4b146e814998e4b365f116fa1a102c00e6a4e","src/unix/newlib/espidf/mod.rs":"56e0c1366c930339ef757742088f99a3617197ec86336b34afa854982cd0efff","src/unix/newlib/generic.rs":"43651894e9beb0950c8e3caa4ba7deb149c7290fe6a0f33fbccb72ee8ce54229","src/unix/newlib/horizon/mod.rs":"6c1109cbf4809d25a6d88129445f82f137183422c6ed1d3faa3a775bce12d536","src/unix/newlib/mod.rs":"7f46ed8648b45bf93b5952ef2e1c0e198cab8542c6ffe517b4091c53fcb98a80","src/unix/newlib/no_align.rs":"e0743b2179495a9514bc3a4d1781e492878c4ec834ee0085d0891dd1712e82fb","src/unix/newlib/powerpc/mod.rs":"cc9e188711b9bf614323ad6c48e0d2e1a1ecc5d3bc64961ba451f29c6c22d2d8","src/unix/newlib/rtems/mod.rs":"6f6fd7daf9c4a60647d5eb2c117340467e1df93b012a5e1ccbc2f52ba1060c63","src/unix/newlib/vita/mod.rs":"ff1caf74bb0696fe15d60dbac598db4520cd538aa0f5989713d97d008eee6ad8","src/unix/no_align.rs":"7be3d17a22ca1f55ba1058d199fd45916f9be1a9669bfd99e0dea5525af07b84","src/unix/nto/aarch64.rs":"4709c9afdc8d583be876598e7c238499ee3e8da5bd2baa614d9c7dd414851555","src/unix/nto/mod.rs":"5eb045c352114f5d744d098acaf9e47a9223f6fccd43f36b9a3ba79b29af0eee","src/unix/nto/neutrino.rs":"799bff4ab01a6424db6c5a2b76aa5679826d41495f9d13c63485bf13bc80026b","src/unix/nto/x86_64.rs":"a3e18e93c2999da1cd7a6f748a4b60c07aefb73d8ea2aafec19a84cfb040bc8e","src/unix/nuttx/mod.rs":"4aaa15700c6ba8777f270864c02844f0c7ce7fbbbd84f9e1f7f80ff8033691f8","src/unix/redox/mod.rs":"0f12d756798211ddaa5f0d075eb723ece86426f2a726dcce7e2da7d27a631bec","src/unix/solarish/compat.rs":"00f1ee3faec9da69204e42f025f6735dd13d894071a154425dcc43ecbdd06e7f","src/unix/solarish/illumos.rs":"0f31604e9b9c60caa3ac0be8ff078cbde089b63add5b908ba218840e7156b7ca","src/unix/solarish/mod.rs":"eb1f663df0898486c91d155c825a21806705d6b736b3ffa0925b290995631c5b","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":"fdba79ee380a3e25c64137d76faf78718e06237fbe38fc3233d4ba900d9e0375","src/vxworks/powerpc.rs":"acb7968ce99fe3f4abdf39d98f8133d21a4fba435b8ef7084777cb181d788e88","src/vxworks/powerpc64.rs":"98f0afdc511cd02557e506c21fed6737585490a1dce7a9d4941d08c437762b99","src/vxworks/riscv32.rs":"552f007f38317620b23889cb7c49d1d115841252439060122f52f434fbc6e5ba","src/vxworks/riscv64.rs":"018d92be3ad628a129eff9f2f5dfbc0883d8b8e5f2fa917b900a7f98ed6b514a","src/vxworks/x86.rs":"552f007f38317620b23889cb7c49d1d115841252439060122f52f434fbc6e5ba","src/vxworks/x86_64.rs":"018d92be3ad628a129eff9f2f5dfbc0883d8b8e5f2fa917b900a7f98ed6b514a","src/wasi/mod.rs":"6b7d8bbcf668c85e37ae35fecf6088ad75a81b6d84f3e339fabc2f8dae4b12c9","src/wasi/p2.rs":"535987406f8a5abddba9e3e020865a1b148e11dee683ed28ccc553cfac9c5e1b","src/windows/gnu/align.rs":"b2c13ec1b9f3b39a75c452c80c951dff9d0215e31d77e883b4502afb31794647","src/windows/gnu/mod.rs":"3c8c7edb7cdf5d0c44af936db2a94869585c69dfabeef30571b4f4e38375767a","src/windows/mod.rs":"9fdc5e1c62c441abef7bc62a7343efb2041edc24db9ac0efc0f74df55b69e249","src/windows/msvc/mod.rs":"c068271e00fca6b62bc4bf44bcf142cfc38caeded9b6c4e01d1ceef3ccf986f4","src/xous.rs":"eb0675f25ba01f73072d2b70907fb8abb1148facefe5a20756c49250f3d65fae","tests/const_fn.rs":"cb75a1f0864f926aebe79118fc34d51a0d1ade2c20a394e7774c7e545f21f1f4"},"package":"8e9489c2807c139ffd9c1794f4af0ebe86a828db53ecdc7fea2111d0fed085d1"} \ No newline at end of file diff --git a/vendor/libc/CHANGELOG.md b/vendor/libc/CHANGELOG.md new file mode 100644 index 0000000..6cb8da6 --- /dev/null +++ b/vendor/libc/CHANGELOG.md @@ -0,0 +1,139 @@ +# Changelog + +## [Unreleased] + +## [0.2.161](https://github.com/rust-lang/libc/compare/0.2.160...0.2.161) - 2024-10-17 + +### Fixed + +- OpenBSD: fix `FNM_PATHNAME` and `FNM_NOESCAPE` values + +## [0.2.160](https://github.com/rust-lang/libc/compare/0.2.159...0.2.160) - 2024-10-17 + +### Added + +- Android: add `PR_GET_NAME` and `PR_SET_NAME` +- Apple: add `F_TRANSFEREXTENTS` +- Apple: add `mach_error_string` +- Apple: add additional `pthread` APIs +- Apple: add the `LOCAL_PEERTOKEN` socket option +- BSD: add `RTF_*`, `RTA_*`, `RTAX_*`, and `RTM_*` definitions +- Emscripten: add `AT_EACCESS` +- Emscripten: add `getgrgid`, `getgrnam`, `getgrnam_r` and `getgrgid_r` +- Emscripten: add `getpwnam_r` and `getpwuid_r` +- FreeBSD: add `POLLRDHUP` +- Haiku: add `arc4random` +- Illumos: add `ptsname_r` +- Linux: add `fanotify` interfaces +- Linux: add `tcp_info` +- Linux: add additional AF_PACKET options +- Linux: make Elf constants always available +- Musl x86: add `iopl` and `ioperm` +- Musl: add `posix_spawn` chdir functions +- Musl: add `utmpx.h` constants +- NetBSD: add `sysctlnametomib`, `CLOCK_THREAD_CPUTIME_ID` and `CLOCK_PROCESS_CPUTIME_ID` +- Nuttx: initial support +- RTEMS: add `getentropy` +- RTEMS: initial support +- Solarish: add `POLLRDHUP`, `POSIX_FADV_*`, `O_RSYNC`, and `posix_fallocate` +- Unix: add `fnmatch.h` +- VxWorks: add riscv64 support +- VxWorks: update constants related to the scheduler + +### Changed + +- Redox: change `ino_t` to be `c_ulonglong` + +### Fixed + +- ESP-IDF: fix mismatched constants and structs +- FreeBSD: fix `struct stat` on FreeBSD 12+ + +### Other + +- CI: Fix CI for FreeBSD 15 +- Docs: link to `windows-sys` + +## [0.2.159](https://github.com/rust-lang/libc/compare/0.2.158...0.2.159) - 2024-09-24 + +### Added + +- Android: add more `AT_*` constants in +- Apple: add missing `NOTE_*` constants in +- Hermit: add missing error numbers in +- Hurd: add `__timeval` for 64-bit support in +- Linux: add `epoll_pwait2` in +- Linux: add `mq_notify` in +- Linux: add missing `NFT_CT_*` constants in +- Linux: add the `fchmodat2` syscall in +- Linux: add the `mseal` syscall in +- OpenBSD: add `sendmmsg` and `recvmmsg` in +- Unix: add `IN6ADDR_ANY_INIT` and `IN6ADDR_LOOPBACK_INIT` in +- VxWorks: add `S_ISVTX` in +- VxWorks: add `vxCpuLib` and `taskLib` functions +- WASIp2: add definitions for `std::net` support in + +### Fixed + +- Correctly handle version checks when `clippy-driver` is used + +### Changed + +- EspIdf: change signal constants to c_int in +- HorizonOS: update network definitions in +- Linux: combine `ioctl` APIs in +- WASI: enable CI testing in +- WASIp2: enable CI testing in + +## [0.2.158](https://github.com/rust-lang/libc/compare/0.2.157...0.2.158) - 2024-08-19 + +### Other +- WASI: fix missing `Iterator` with `rustc-dep-of-std` in + +## [0.2.157](https://github.com/rust-lang/libc/compare/0.2.156...0.2.157) - 2024-08-17 + +### Added + +- Apple: add `_NSGetArgv`, `_NSGetArgc` and `_NSGetProgname` in +- Build: add `RUSTC_WRAPPER` support in +- FreeBSD: add `execvpe` support from 14.1 release in +- Fuchsia: add `SO_BINDTOIFINDEX` +- Linux: add `klogctl` in +- MacOS: add `fcntl` OFD commands in +- NetBSD: add `_lwp_park` in +- Solaris: add missing networking support in +- Unix: add `pthread_equal` in +- WASI: add `select`, `FD_SET`, `FD_ZERO`, `FD_ISSET ` in + +### Fixed +- TEEOS: fix octal notation for `O_*` constants in + +### Changed +- FreeBSD: always use freebsd12 when `rustc_dep_of_std` is set in + +## [0.2.156](https://github.com/rust-lang/libc/compare/v0.2.155...v0.2.156) - 2024-08-15 + +### Added +- Apple: add `F_ALLOCATEPERSIST` in +- Apple: add `os_sync_wait_on_address` and related definitions in +- BSD: generalise `IPV6_DONTFRAG` to all BSD targets in +- FreeBSD/DragonFly: add `IP_RECVTTL`/`IPV6_RECVHOPLIMIT` in +- Hurd: add `XATTR_CREATE`, `XATTR_REPLACE` in +- Linux GNU: `confstr` API and `_CS_*` in +- Linux musl: add `preadv2` and `pwritev2` (1.2.5 min.) in +- VxWorks: add the constant `SOMAXCONN` in +- VxWorks: add a few errnoLib related constants in + +### Fixed +- Solaris/illumos: Change `ifa_flags` type to u64 in +- QNX 7.0: Disable `libregex` in + +### Changed +- QNX NTO: update platform support in +- `addr_of!(EXTERN_STATIC)` is now considered safe in + +### Removed +- Apple: remove `rmx_state` in + +### Other +- Update or remove CI tests that have been failing diff --git a/vendor/libc/CONTRIBUTING.md b/vendor/libc/CONTRIBUTING.md new file mode 100644 index 0000000..b6f41cc --- /dev/null +++ b/vendor/libc/CONTRIBUTING.md @@ -0,0 +1,100 @@ +# Contributing to `libc` + +Welcome! If you are reading this document, it means you are interested in contributing +to the `libc` crate. + +## v0.2 changes + +If you want to add your changes to v0.2, please submit them to the `libc-0.2` branch. +If you want to add any breaking changes, it should be submitted to the main branch, +which has changes for v0.3. +We will support and make a new release for v0.2 until we make the first release of v0.3. + +## Adding an API + +Want to use an API which currently isn't bound in `libc`? It's quite easy to add +one! + +The internal structure of this crate is designed to minimize the number of +`#[cfg]` attributes in order to easily be able to add new items which apply +to all platforms in the future. As a result, the crate is organized +hierarchically based on platform. Each module has a number of `#[cfg]`'d +children, but only one is ever actually compiled. Each module then reexports all +the contents of its children. + +This means that for each platform that libc supports, the path from a +leaf module to the root will contain all bindings for the platform in question. +Consequently, this indicates where an API should be added! Adding an API at a +particular level in the hierarchy means that it is supported on all the child +platforms of that level. For example, when adding a Unix API it should be added +to `src/unix/mod.rs`, but when adding a Linux-only API it should be added to +`src/unix/linux_like/linux/mod.rs`. + +If you're not 100% sure at what level of the hierarchy an API should be added +at, fear not! This crate has CI support which tests any binding against all +platforms supported, so you'll see failures if an API is added at the wrong +level or has different signatures across platforms. + +New symbol(s) (i.e. functions, constants etc.) should also be added to the +symbols list(s) found in the `libc-test/semver` directory. These lists keep +track of what symbols are public in the libc crate and ensures they remain +available between changes to the crate. If the new symbol(s) are available on +all supported Unixes it should be added to `unix.txt` list1, +otherwise they should be added to the OS specific list(s). + +With that in mind, the steps for adding a new API are: + +1. Determine where in the module hierarchy your API should be added. +2. Add the API, including adding new symbol(s) to the semver lists. +3. Send a PR to this repo. +4. Wait for CI to pass, fixing errors. +5. Wait for a merge! + +1: Note that this list has nothing to do with any Unix or Posix +standard, it's just a list shared between all OSs that declare `#[cfg(unix)]`. + +## Test before you commit + +We have two automated tests running on [GitHub Actions](https://github.com/rust-lang/libc/actions): + +1. [`libc-test`](https://github.com/gnzlbg/ctest) + - `cd libc-test && cargo test` + - Use the `skip_*()` functions in `build.rs` if you really need a workaround. +2. Style checker + - [`sh ci/style.sh`](https://github.com/rust-lang/libc/blob/main/ci/style.sh) + +## Breaking change policy + +Sometimes an upstream adds a breaking change to their API e.g. removing outdated items, +changing the type signature, etc. And we probably should follow that change to build the +`libc` crate successfully. It's annoying to do the equivalent of semver-major versioning +for each such change. Instead, we mark the item as deprecated and do the actual change +after a certain period. The steps are: + +1. Add `#[deprecated(since = "", note="")]` attribute to the item. + - The `since` field should have a next version of `libc` + (e.g., if the current version is `0.2.1`, it should be `0.2.2`). + - The `note` field should have a reason to deprecate and a tracking issue to call for comments + (e.g., "We consider removing this as the upstream removed it. + 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 +platform in this crate, the next step is to get that sweet, sweet usage from +crates.io! The only next step is to bump the version of libc and then publish +it. If you'd like to get a release out ASAP you can follow these steps: + +1. 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!). +1. Once merged, the release will be tagged and published by one of the libc crate + maintainers. + +[example-pr]: https://github.com/rust-lang/libc/pull/2120 diff --git a/vendor/libc/Cargo.toml b/vendor/libc/Cargo.toml new file mode 100644 index 0000000..0b37bc5 --- /dev/null +++ b/vendor/libc/Cargo.toml @@ -0,0 +1,188 @@ +# 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 = "libc" +version = "0.2.161" +authors = ["The Rust Project Developers"] +build = "build.rs" +exclude = [ + "/ci/*", + "/.github/*", + "/.cirrus.yml", + "/triagebot.toml", +] +autobins = false +autoexamples = false +autotests = false +autobenches = false +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", +] +license = "MIT OR Apache-2.0" +repository = "https://github.com/rust-lang/libc" + +[package.metadata.docs.rs] +cargo-args = ["-Zbuild-std=core"] +default-target = "x86_64-unknown-linux-gnu" +features = [ + "const-extern-fn", + "extra_traits", +] +targets = [ + "aarch64-apple-darwin", + "aarch64-apple-ios", + "aarch64-linux-android", + "aarch64-pc-windows-msvc", + "aarch64-unknown-freebsd", + "aarch64-unknown-fuchsia", + "aarch64-unknown-hermit", + "aarch64-unknown-linux-gnu", + "aarch64-unknown-linux-musl", + "aarch64-unknown-netbsd", + "aarch64-unknown-openbsd", + "aarch64-wrs-vxworks", + "arm-linux-androideabi", + "arm-unknown-linux-gnueabi", + "arm-unknown-linux-gnueabihf", + "arm-unknown-linux-musleabi", + "arm-unknown-linux-musleabihf", + "armebv7r-none-eabi", + "armebv7r-none-eabihf", + "armv5te-unknown-linux-gnueabi", + "armv5te-unknown-linux-musleabi", + "armv7-linux-androideabi", + "armv7-unknown-linux-gnueabihf", + "armv7-unknown-linux-musleabihf", + "armv7-wrs-vxworks-eabihf", + "armv7r-none-eabi", + "armv7r-none-eabihf", + "i586-pc-windows-msvc", + "i586-unknown-linux-gnu", + "i586-unknown-linux-musl", + "i686-linux-android", + "i686-pc-windows-gnu", + "i686-pc-windows-msvc", + "i686-pc-windows-msvc", + "i686-unknown-freebsd", + "i686-unknown-haiku", + "i686-unknown-linux-gnu", + "i686-unknown-linux-musl", + "i686-unknown-netbsd", + "i686-unknown-openbsd", + "i686-wrs-vxworks", + "mips-unknown-linux-gnu", + "mips-unknown-linux-musl", + "mips64-unknown-linux-gnuabi64", + "mips64-unknown-linux-muslabi64", + "mips64el-unknown-linux-gnuabi64", + "mips64el-unknown-linux-muslabi64", + "mipsel-sony-psp", + "mipsel-unknown-linux-gnu", + "mipsel-unknown-linux-musl", + "nvptx64-nvidia-cuda", + "powerpc-unknown-linux-gnu", + "powerpc-unknown-linux-gnuspe", + "powerpc-unknown-netbsd", + "powerpc-wrs-vxworks", + "powerpc-wrs-vxworks-spe", + "powerpc64-unknown-freebsd", + "powerpc64-unknown-linux-gnu", + "powerpc64-wrs-vxworks", + "powerpc64le-unknown-linux-gnu", + "riscv32gc-unknown-linux-gnu", + "riscv32i-unknown-none-elf", + "riscv32imac-unknown-none-elf", + "riscv32imc-unknown-none-elf", + "riscv32-wrs-vxworks", + "riscv64gc-unknown-freebsd", + "riscv64gc-unknown-hermit", + "riscv64gc-unknown-linux-gnu", + "riscv64gc-unknown-linux-musl", + "riscv64gc-unknown-none-elf", + "riscv64imac-unknown-none-elf", + "riscv64-wrs-vxworks", + "s390x-unknown-linux-gnu", + "s390x-unknown-linux-musl", + "sparc-unknown-linux-gnu", + "sparc64-unknown-linux-gnu", + "sparc64-unknown-netbsd", + "sparcv9-sun-solaris", + "thumbv6m-none-eabi", + "thumbv7em-none-eabi", + "thumbv7em-none-eabihf", + "thumbv7m-none-eabi", + "thumbv7neon-linux-androideabi", + "thumbv7neon-unknown-linux-gnueabihf", + "wasm32-unknown-emscripten", + "wasm32-unknown-unknown", + "wasm32-wasi", + "x86_64-apple-darwin", + "x86_64-apple-ios", + "x86_64-fortanix-unknown-sgx", + "x86_64-linux-android", + "x86_64-pc-solaris", + "x86_64-pc-windows-gnu", + "x86_64-pc-windows-msvc", + "x86_64-unknown-dragonfly", + "x86_64-unknown-freebsd", + "x86_64-unknown-fuchsia", + "x86_64-unknown-haiku", + "x86_64-unknown-hermit", + "x86_64-unknown-illumos", + "x86_64-unknown-l4re-uclibc", + "x86_64-unknown-linux-gnu", + "x86_64-unknown-linux-gnux32", + "x86_64-unknown-linux-musl", + "x86_64-unknown-netbsd", + "x86_64-unknown-openbsd", + "x86_64-unknown-redox", + "x86_64-wrs-vxworks", +] + +[lib] +name = "libc" +path = "src/lib.rs" + +[[test]] +name = "const_fn" +path = "tests/const_fn.rs" + +[dependencies.rustc-std-workspace-core] +version = "1.0.0" +optional = true + +[features] +align = [] +const-extern-fn = [] +default = ["std"] +extra_traits = [] +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 new file mode 100644 index 0000000..1b5ec8b --- /dev/null +++ b/vendor/libc/LICENSE-APACHE @@ -0,0 +1,176 @@ + 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 diff --git a/vendor/libc/LICENSE-MIT b/vendor/libc/LICENSE-MIT new file mode 100644 index 0000000..7806181 --- /dev/null +++ b/vendor/libc/LICENSE-MIT @@ -0,0 +1,25 @@ +Copyright (c) 2014-2020 The Rust Project Developers + +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/libc/README.md b/vendor/libc/README.md new file mode 100644 index 0000000..3d5b5ec --- /dev/null +++ b/vendor/libc/README.md @@ -0,0 +1,122 @@ +# libc - Raw FFI bindings to platforms' system libraries + +[![GHA Status]][GitHub Actions] [![Cirrus CI Status]][Cirrus CI] [![Latest Version]][crates.io] [![Documentation]][docs.rs] ![License] + +`libc` provides all of the definitions necessary to easily interoperate with C +code (or "C-like" code) on each of the platforms that Rust supports. This +includes type definitions (e.g. `c_int`), constants (e.g. `EINVAL`) as well as +function headers (e.g. `malloc`). + +This crate exports all underlying platform types, functions, and constants under +the crate root, so all items are accessible as `libc::foo`. The types and values +of all the exported APIs match the platform that libc is compiled for. + +Windows API bindings are not included in this crate. If you are looking for WinAPI +bindings, consider using crates like [windows-sys]. + +More detailed information about the design of this library can be found in its +[associated RFC][rfc]. + +[rfc]: https://github.com/rust-lang/rfcs/blob/HEAD/text/1291-promote-libc.md +[windows-sys]: https://docs.rs/windows-sys + +## v0.3 Roadmap + +The main branch is now for v0.3 which has some breaking changes. + +For v0.2, please submit PRs to the `libc-0.2` branch instead. +We will stop making new v0.2 releases once we release v0.3 on crates.io. + +See the [tracking issue](https://github.com/rust-lang/libc/issues/3248) for details. + +## Usage + +Add the following to your `Cargo.toml`: + +```toml +[dependencies] +libc = "0.2" +``` + +## Features + +* `std`: by default `libc` links to the standard library. Disable this + feature to remove this dependency and be able to use `libc` in `#![no_std]` + crates. + +* `extra_traits`: all `struct`s implemented in `libc` are `Copy` and `Clone`. + This feature derives `Debug`, `Eq`, `Hash`, and `PartialEq`. + +* `const-extern-fn`: Changes some `extern fn`s into `const extern fn`s. + 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 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 | +|----------------------|---------| +| `union` | 1.19.0 | +| `const mem::size_of` | 1.24.0 | +| `repr(align)` | 1.25.0 | +| `extra_traits` | 1.25.0 | +| `core::ffi::c_void` | 1.30.0 | +| `repr(packed(N))` | 1.33.0 | +| `cfg(target_vendor)` | 1.33.0 | +| `const-extern-fn` | 1.62.0 | + +## Platform support + +You can see the platform(target)-specific docs on [docs.rs], select a platform you want to see. + +See +[`ci/build.sh`](https://github.com/rust-lang/libc/blob/HEAD/ci/build.sh) +for the platforms on which `libc` is guaranteed to build for each Rust +toolchain. The test-matrix at [GitHub Actions] and [Cirrus CI] show the +platforms in which `libc` tests are run. + +

+ +## License + +This project is licensed under either of + +* [Apache License, Version 2.0](https://www.apache.org/licenses/LICENSE-2.0) + ([LICENSE-APACHE](https://github.com/rust-lang/libc/blob/HEAD/LICENSE-APACHE)) + +* [MIT License](https://opensource.org/licenses/MIT) + ([LICENSE-MIT](https://github.com/rust-lang/libc/blob/HEAD/LICENSE-MIT)) + +at your option. + +## Contributing + +We welcome all people who want to contribute. Please see the [contributing +instructions] for more information. + +[contributing instructions]: https://github.com/rust-lang/libc/blob/HEAD/CONTRIBUTING.md + +Contributions in any form (issues, pull requests, etc.) to this project +must adhere to Rust's [Code of Conduct]. + +[Code of Conduct]: https://www.rust-lang.org/policies/code-of-conduct + +Unless you explicitly state otherwise, any contribution intentionally submitted +for inclusion in `libc` by you, as defined in the Apache-2.0 license, shall be +dual licensed as above, without any additional terms or conditions. + +[GitHub Actions]: https://github.com/rust-lang/libc/actions +[GHA Status]: https://github.com/rust-lang/libc/workflows/CI/badge.svg +[Cirrus CI]: https://cirrus-ci.com/github/rust-lang/libc +[Cirrus CI Status]: https://api.cirrus-ci.com/github/rust-lang/libc.svg +[crates.io]: https://crates.io/crates/libc +[Latest Version]: https://img.shields.io/crates/v/libc.svg +[Documentation]: https://docs.rs/libc/badge.svg +[docs.rs]: https://docs.rs/libc +[License]: https://img.shields.io/crates/l/libc.svg diff --git a/vendor/libc/build.rs b/vendor/libc/build.rs new file mode 100644 index 0000000..ea55185 --- /dev/null +++ b/vendor/libc/build.rs @@ -0,0 +1,339 @@ +use std::env; +use std::process::{Command, Output}; +use std::str; + +// 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] = &[ + "emscripten_new_stat_abi", + "espidf_time64", + "freebsd10", + "freebsd11", + "freebsd12", + "freebsd13", + "freebsd14", + "freebsd15", + "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", + "libc_ctest", +]; + +// Extra values to allow for check-cfg. +const CHECK_CFG_EXTRA: &'static [(&'static str, &'static [&'static str])] = &[ + ( + "target_os", + &[ + "switch", "aix", "ohos", "hurd", "rtems", "visionos", "nuttx", + ], + ), + ("target_env", &["illumos", "wasi", "aix", "ohos"]), + ( + "target_arch", + &["loongarch64", "mips32r6", "mips64r6", "csky"], + ), +]; + +fn main() { + // Avoid unnecessary re-building. + println!("cargo:rerun-if-changed=build.rs"); + + 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() || rustc_minor_ver >= 80; + + if env::var("CARGO_FEATURE_USE_STD").is_ok() { + println!( + "cargo:warning=\"libc's use_std cargo feature is deprecated since libc 0.2.55; \ + please consider using the `std` cargo feature instead\"" + ); + } + + // The ABI of libc used by std is backward compatible with FreeBSD 12. + // The ABI of libc from crates.io is backward compatible with FreeBSD 11. + // + // On CI, we detect the actual FreeBSD version and match its ABI exactly, + // running tests to ensure that the ABI is correct. + let which_freebsd = if libc_ci { + which_freebsd().unwrap_or(11) + } else if rustc_dep_of_std { + 12 + } else { + 11 + }; + match which_freebsd { + x if x < 10 => panic!("FreeBSD older than 10 is not supported"), + 10 => set_cfg("freebsd10"), + 11 => set_cfg("freebsd11"), + 12 => set_cfg("freebsd12"), + 13 => set_cfg("freebsd13"), + 14 => set_cfg("freebsd14"), + _ => set_cfg("freebsd15"), + } + + match emcc_version_code() { + Some(v) if (v >= 30142) => set_cfg("emscripten_new_stat_abi"), + // Non-Emscripten or version < 3.1.42. + Some(_) | None => (), + } + + // On CI: deny all warnings + if libc_ci { + set_cfg("libc_deny_warnings"); + } + + // Rust >= 1.15 supports private module use: + if rustc_minor_ver >= 15 || rustc_dep_of_std { + set_cfg("libc_priv_mod_use"); + } + + // Rust >= 1.19 supports unions: + if rustc_minor_ver >= 19 || rustc_dep_of_std { + set_cfg("libc_union"); + } + + // Rust >= 1.24 supports const mem::size_of: + if rustc_minor_ver >= 24 || rustc_dep_of_std { + set_cfg("libc_const_size_of"); + } + + // Rust >= 1.25 supports repr(align): + if rustc_minor_ver >= 25 || rustc_dep_of_std || align_cargo_feature { + 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 { + 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 { + 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 { + set_cfg("libc_thread_local"); + } + + // 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 { + if rustc_minor_ver >= 75 { + println!("cargo:rustc-check-cfg=cfg({})", cfg); + } else { + println!("cargo:rustc-check-cfg=values({})", cfg); + } + } + for &(name, values) in CHECK_CFG_EXTRA { + let values = values.join("\",\""); + if rustc_minor_ver >= 75 { + println!("cargo:rustc-check-cfg=cfg({},values(\"{}\"))", name, values); + } else { + println!("cargo:rustc-check-cfg=values({},\"{}\")", name, values); + } + } + } +} + +/// Run `rustc --version` and capture the output, adjusting arguments as needed if `clippy-driver` +/// is used instead. +fn rustc_version_cmd(is_clippy_driver: bool) -> Output { + let rustc = env::var_os("RUSTC").expect("Failed to get rustc version: missing RUSTC env"); + + let mut cmd = match env::var_os("RUSTC_WRAPPER") { + Some(ref wrapper) if wrapper.is_empty() => Command::new(rustc), + Some(wrapper) => { + let mut cmd = Command::new(wrapper); + cmd.arg(rustc); + if is_clippy_driver { + cmd.arg("--rustc"); + } + + cmd + } + None => Command::new(rustc), + }; + + cmd.arg("--version"); + + let output = cmd.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()) + ); + } + + output +} + +/// Return the minor version of `rustc`, as well as a bool indicating whether or not the version +/// is a nightly. +fn rustc_minor_nightly() -> (u32, bool) { + macro_rules! otry { + ($e:expr) => { + match $e { + Some(e) => e, + None => panic!("Failed to get rustc version"), + } + }; + } + + let mut output = rustc_version_cmd(false); + + if otry!(str::from_utf8(&output.stdout).ok()).starts_with("clippy") { + output = rustc_version_cmd(true); + } + + let version = otry!(str::from_utf8(&output.stdout).ok()); + + let mut pieces = version.split('.'); + + if pieces.next() != Some("rustc 1") { + panic!("Failed to get rustc version"); + } + + let minor = pieces.next(); + + // If `rustc` was built from a tarball, its version string + // will have neither a git hash nor a commit date + // (e.g. "rustc 1.39.0"). Treat this case as non-nightly, + // since a nightly build should either come from CI + // or a git checkout + let nightly_raw = otry!(pieces.next()).split('-').nth(1); + let nightly = nightly_raw + .map(|raw| raw.starts_with("dev") || raw.starts_with("nightly")) + .unwrap_or(false); + let minor = otry!(otry!(minor).parse().ok()); + + (minor, nightly) +} + +fn which_freebsd() -> Option { + let output = std::process::Command::new("freebsd-version").output().ok(); + if output.is_none() { + return None; + } + let output = output.unwrap(); + if !output.status.success() { + return None; + } + + let stdout = String::from_utf8(output.stdout).ok(); + if stdout.is_none() { + return None; + } + let stdout = stdout.unwrap(); + + match &stdout { + s if s.starts_with("10") => Some(10), + 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), + s if s.starts_with("15") => Some(15), + _ => None, + } +} + +fn emcc_version_code() -> Option { + let output = std::process::Command::new("emcc") + .arg("-dumpversion") + .output() + .ok(); + if output.is_none() { + return None; + } + let output = output.unwrap(); + if !output.status.success() { + return None; + } + + let stdout = String::from_utf8(output.stdout).ok(); + if stdout.is_none() { + return None; + } + let version = stdout.unwrap(); + + // Some Emscripten versions come with `-git` attached, so split the + // version string also on the `-` char. + let mut pieces = version.trim().split(|c| c == '.' || c == '-'); + + let major = pieces.next().and_then(|x| x.parse().ok()).unwrap_or(0); + let minor = pieces.next().and_then(|x| x.parse().ok()).unwrap_or(0); + let patch = pieces.next().and_then(|x| x.parse().ok()).unwrap_or(0); + + Some(major * 10000 + minor * 100 + patch) +} + +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/rustfmt.toml b/vendor/libc/rustfmt.toml new file mode 100644 index 0000000..dc85c99 --- /dev/null +++ b/vendor/libc/rustfmt.toml @@ -0,0 +1 @@ +error_on_line_overflow = true diff --git a/vendor/libc/src/fixed_width_ints.rs b/vendor/libc/src/fixed_width_ints.rs new file mode 100644 index 0000000..999de8f --- /dev/null +++ b/vendor/libc/src/fixed_width_ints.rs @@ -0,0 +1,99 @@ +//! This module contains type aliases for C's fixed-width integer types . +//! +//! These aliases are deprecated: use the Rust types instead. + +#[deprecated(since = "0.2.55", note = "Use i8 instead.")] +pub type int8_t = i8; +#[deprecated(since = "0.2.55", note = "Use i16 instead.")] +pub type int16_t = i16; +#[deprecated(since = "0.2.55", note = "Use i32 instead.")] +pub type int32_t = i32; +#[deprecated(since = "0.2.55", note = "Use i64 instead.")] +pub type int64_t = i64; +#[deprecated(since = "0.2.55", note = "Use u8 instead.")] +pub type uint8_t = u8; +#[deprecated(since = "0.2.55", note = "Use u16 instead.")] +pub type uint16_t = u16; +#[deprecated(since = "0.2.55", note = "Use u32 instead.")] +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 new file mode 100644 index 0000000..33e3934 --- /dev/null +++ b/vendor/libc/src/fuchsia/aarch64.rs @@ -0,0 +1,67 @@ +pub type c_char = u8; +pub type __u64 = ::c_ulonglong; +pub type wchar_t = u32; +pub type nlink_t = ::c_ulong; +pub type blksize_t = ::c_long; + +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, + __pad0: ::c_ulong, + pub st_size: ::off_t, + pub st_blksize: ::blksize_t, + __pad1: ::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_uint; 2], + } + + 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_uid: ::uid_t, + pub st_gid: ::gid_t, + pub st_rdev: ::dev_t, + __pad0: ::c_ulong, + pub st_size: ::off_t, + pub st_blksize: ::blksize_t, + __pad1: ::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_uint; 2], + } + + 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, + } +} + +// 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/align.rs b/vendor/libc/src/fuchsia/align.rs new file mode 100644 index 0000000..3409bf0 --- /dev/null +++ b/vendor/libc/src/fuchsia/align.rs @@ -0,0 +1,142 @@ +macro_rules! expand_align { + () => { + s! { + #[cfg_attr( + any( + target_pointer_width = "32", + target_arch = "x86_64" + ), + repr(align(4)))] + #[cfg_attr( + not(any( + target_pointer_width = "32", + target_arch = "x86_64" + )), + repr(align(8)))] + pub struct pthread_mutexattr_t { + size: [u8; ::__SIZEOF_PTHREAD_MUTEXATTR_T], + } + + #[cfg_attr(target_pointer_width = "32", + repr(align(4)))] + #[cfg_attr(target_pointer_width = "64", + repr(align(8)))] + pub struct pthread_rwlockattr_t { + size: [u8; ::__SIZEOF_PTHREAD_RWLOCKATTR_T], + } + + #[repr(align(4))] + pub struct pthread_condattr_t { + size: [u8; ::__SIZEOF_PTHREAD_CONDATTR_T], + } + } + + s_no_extra_traits! { + #[cfg_attr(all(target_pointer_width = "32", + any(target_arch = "arm", + target_arch = "x86_64")), + repr(align(4)))] + #[cfg_attr(any(target_pointer_width = "64", + not(any(target_arch = "arm", + target_arch = "x86_64"))), + repr(align(8)))] + pub struct pthread_mutex_t { + size: [u8; ::__SIZEOF_PTHREAD_MUTEX_T], + } + + #[cfg_attr(all(target_pointer_width = "32", + any(target_arch = "arm", + target_arch = "x86_64")), + repr(align(4)))] + #[cfg_attr(any(target_pointer_width = "64", + not(any(target_arch = "arm", + target_arch = "x86_64"))), + repr(align(8)))] + pub struct pthread_rwlock_t { + size: [u8; ::__SIZEOF_PTHREAD_RWLOCK_T], + } + + #[cfg_attr(target_pointer_width = "32", + repr(align(4)))] + #[cfg_attr(target_pointer_width = "64", + repr(align(8)))] + #[cfg_attr(target_arch = "x86", + repr(align(4)))] + #[cfg_attr(not(target_arch = "x86"), + repr(align(8)))] + pub struct pthread_cond_t { + size: [u8; ::__SIZEOF_PTHREAD_COND_T], + } + } + + cfg_if! { + if #[cfg(feature = "extra_traits")] { + impl PartialEq for pthread_cond_t { + fn eq(&self, other: &pthread_cond_t) -> bool { + self.size + .iter() + .zip(other.size.iter()) + .all(|(a,b)| a == b) + } + } + impl Eq for pthread_cond_t {} + impl ::fmt::Debug for pthread_cond_t { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("pthread_cond_t") + // FIXME: .field("size", &self.size) + .finish() + } + } + impl ::hash::Hash for pthread_cond_t { + fn hash(&self, state: &mut H) { + self.size.hash(state); + } + } + + impl PartialEq for pthread_mutex_t { + fn eq(&self, other: &pthread_mutex_t) -> bool { + self.size + .iter() + .zip(other.size.iter()) + .all(|(a,b)| a == b) + } + } + impl Eq for pthread_mutex_t {} + impl ::fmt::Debug for pthread_mutex_t { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("pthread_mutex_t") + // FIXME: .field("size", &self.size) + .finish() + } + } + impl ::hash::Hash for pthread_mutex_t { + fn hash(&self, state: &mut H) { + self.size.hash(state); + } + } + + impl PartialEq for pthread_rwlock_t { + fn eq(&self, other: &pthread_rwlock_t) -> bool { + self.size + .iter() + .zip(other.size.iter()) + .all(|(a,b)| a == b) + } + } + impl Eq for pthread_rwlock_t {} + impl ::fmt::Debug for pthread_rwlock_t { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("pthread_rwlock_t") + // FIXME: .field("size", &self.size) + .finish() + } + } + impl ::hash::Hash for pthread_rwlock_t { + fn hash(&self, state: &mut H) { + self.size.hash(state); + } + } + } + } + }; +} diff --git a/vendor/libc/src/fuchsia/mod.rs b/vendor/libc/src/fuchsia/mod.rs new file mode 100644 index 0000000..9414d16 --- /dev/null +++ b/vendor/libc/src/fuchsia/mod.rs @@ -0,0 +1,4394 @@ +//! Definitions found commonly among almost all Unix derivatives +//! +//! More functions and definitions can be found in the more specific modules +//! according to the platform in question. + +// PUB_TYPE + +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 locale_t = *mut ::c_void; + +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 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; +pub type sa_family_t = u16; +pub type pthread_key_t = ::c_uint; +pub type speed_t = ::c_uint; +pub type tcflag_t = ::c_uint; +pub type clockid_t = ::c_int; +pub type key_t = ::c_int; +pub type id_t = ::c_uint; +pub type useconds_t = u32; +pub type dev_t = u64; +pub type socklen_t = u32; +pub type pthread_t = c_ulong; +pub type mode_t = u32; +pub type ino64_t = u64; +pub type off64_t = i64; +pub type blkcnt64_t = i64; +pub type rlim64_t = u64; +pub type mqd_t = ::c_int; +pub type nfds_t = ::c_ulong; +pub type nl_item = ::c_int; +pub type idtype_t = ::c_uint; +pub type loff_t = ::c_longlong; + +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; + +pub type Elf32_Half = u16; +pub type Elf32_Word = u32; +pub type Elf32_Off = u32; +pub type Elf32_Addr = u32; + +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 clock_t = c_long; +pub type time_t = c_long; +pub type suseconds_t = c_long; +pub type ino_t = u64; +pub type off_t = i64; +pub type blkcnt_t = i64; + +pub type shmatt_t = ::c_ulong; +pub type msgqnum_t = ::c_ulong; +pub type msglen_t = ::c_ulong; +pub type fsblkcnt_t = ::c_ulonglong; +pub type fsfilcnt_t = ::c_ulonglong; +pub type rlim_t = ::c_ulonglong; + +pub type c_long = i64; +pub type c_ulong = u64; + +// FIXME: why are these uninhabited types? that seems... wrong? +// Presumably these should be `()` or an `extern type` (when that stabilizes). +#[cfg_attr(feature = "extra_traits", derive(Debug))] +pub enum timezone {} +impl ::Copy for timezone {} +impl ::Clone for timezone { + fn clone(&self) -> timezone { + *self + } +} +#[cfg_attr(feature = "extra_traits", derive(Debug))] +pub enum DIR {} +impl ::Copy for DIR {} +impl ::Clone for DIR { + fn clone(&self) -> DIR { + *self + } +} + +#[cfg_attr(feature = "extra_traits", derive(Debug))] +pub enum fpos64_t {} // FIXME: fill this out with a struct +impl ::Copy for fpos64_t {} +impl ::Clone for fpos64_t { + fn clone(&self) -> fpos64_t { + *self + } +} + +// PUB_STRUCT + +s! { + pub struct group { + pub gr_name: *mut ::c_char, + pub gr_passwd: *mut ::c_char, + pub gr_gid: ::gid_t, + pub gr_mem: *mut *mut ::c_char, + } + + pub struct utimbuf { + pub actime: time_t, + pub modtime: time_t, + } + + pub struct timeval { + pub tv_sec: time_t, + pub tv_usec: suseconds_t, + } + + pub struct timespec { + pub tv_sec: time_t, + pub tv_nsec: ::c_long, + } + + // FIXME: the rlimit and rusage related functions and types don't exist + // within zircon. Are there reasons for keeping them around? + pub struct rlimit { + pub rlim_cur: rlim_t, + pub rlim_max: rlim_t, + } + + pub struct rusage { + pub ru_utime: timeval, + pub ru_stime: timeval, + pub ru_maxrss: c_long, + #[cfg(all(target_arch = "x86_64", target_pointer_width = "32"))] + __pad1: u32, + pub ru_ixrss: c_long, + #[cfg(all(target_arch = "x86_64", target_pointer_width = "32"))] + __pad2: u32, + pub ru_idrss: c_long, + #[cfg(all(target_arch = "x86_64", target_pointer_width = "32"))] + __pad3: u32, + pub ru_isrss: c_long, + #[cfg(all(target_arch = "x86_64", target_pointer_width = "32"))] + __pad4: u32, + pub ru_minflt: c_long, + #[cfg(all(target_arch = "x86_64", target_pointer_width = "32"))] + __pad5: u32, + pub ru_majflt: c_long, + #[cfg(all(target_arch = "x86_64", target_pointer_width = "32"))] + __pad6: u32, + pub ru_nswap: c_long, + #[cfg(all(target_arch = "x86_64", target_pointer_width = "32"))] + __pad7: u32, + pub ru_inblock: c_long, + #[cfg(all(target_arch = "x86_64", target_pointer_width = "32"))] + __pad8: u32, + pub ru_oublock: c_long, + #[cfg(all(target_arch = "x86_64", target_pointer_width = "32"))] + __pad9: u32, + pub ru_msgsnd: c_long, + #[cfg(all(target_arch = "x86_64", target_pointer_width = "32"))] + __pad10: u32, + pub ru_msgrcv: c_long, + #[cfg(all(target_arch = "x86_64", target_pointer_width = "32"))] + __pad11: u32, + pub ru_nsignals: c_long, + #[cfg(all(target_arch = "x86_64", target_pointer_width = "32"))] + __pad12: u32, + pub ru_nvcsw: c_long, + #[cfg(all(target_arch = "x86_64", target_pointer_width = "32"))] + __pad13: u32, + pub ru_nivcsw: c_long, + #[cfg(all(target_arch = "x86_64", target_pointer_width = "32"))] + __pad14: u32, + } + + pub struct in_addr { + pub s_addr: in_addr_t, + } + + pub struct in6_addr { + pub s6_addr: [u8; 16], + } + + 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 ipv6_mreq { + pub ipv6mr_multiaddr: in6_addr, + pub ipv6mr_interface: ::c_uint, + } + + pub struct hostent { + pub h_name: *mut ::c_char, + pub h_aliases: *mut *mut ::c_char, + pub h_addrtype: ::c_int, + pub h_length: ::c_int, + pub h_addr_list: *mut *mut ::c_char, + } + + pub struct iovec { + pub iov_base: *mut ::c_void, + pub iov_len: ::size_t, + } + + pub struct pollfd { + pub fd: ::c_int, + pub events: ::c_short, + pub revents: ::c_short, + } + + pub struct winsize { + pub ws_row: ::c_ushort, + pub ws_col: ::c_ushort, + pub ws_xpixel: ::c_ushort, + pub ws_ypixel: ::c_ushort, + } + + pub struct linger { + pub l_onoff: ::c_int, + pub l_linger: ::c_int, + } + + pub struct sigval { + // Actually a union of an int and a void* + pub sival_ptr: *mut ::c_void + } + + // + pub struct itimerval { + pub it_interval: ::timeval, + pub it_value: ::timeval, + } + + // + pub struct tms { + pub tms_utime: ::clock_t, + pub tms_stime: ::clock_t, + pub tms_cutime: ::clock_t, + pub tms_cstime: ::clock_t, + } + + pub struct servent { + pub s_name: *mut ::c_char, + pub s_aliases: *mut *mut ::c_char, + pub s_port: ::c_int, + pub s_proto: *mut ::c_char, + } + + pub struct protoent { + pub p_name: *mut ::c_char, + pub p_aliases: *mut *mut ::c_char, + pub p_proto: ::c_int, + } + + pub struct aiocb { + pub aio_fildes: ::c_int, + pub aio_lio_opcode: ::c_int, + pub aio_reqprio: ::c_int, + pub aio_buf: *mut ::c_void, + pub aio_nbytes: ::size_t, + pub aio_sigevent: ::sigevent, + __td: *mut ::c_void, + __lock: [::c_int; 2], + __err: ::c_int, + __ret: ::ssize_t, + pub aio_offset: off_t, + __next: *mut ::c_void, + __prev: *mut ::c_void, + #[cfg(target_pointer_width = "32")] + __dummy4: [::c_char; 24], + #[cfg(target_pointer_width = "64")] + __dummy4: [::c_char; 16], + } + + pub struct sigaction { + pub sa_sigaction: ::sighandler_t, + pub sa_mask: ::sigset_t, + pub sa_flags: ::c_int, + pub sa_restorer: ::Option, + } + + pub struct termios { + pub c_iflag: ::tcflag_t, + pub c_oflag: ::tcflag_t, + pub c_cflag: ::tcflag_t, + pub c_lflag: ::tcflag_t, + pub c_line: ::cc_t, + pub c_cc: [::cc_t; ::NCCS], + pub __c_ispeed: ::speed_t, + pub __c_ospeed: ::speed_t, + } + + pub struct 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 ucred { + pub pid: ::pid_t, + pub uid: ::uid_t, + pub gid: ::gid_t, + } + + pub struct sockaddr { + pub sa_family: sa_family_t, + pub sa_data: [::c_char; 14], + } + + pub struct sockaddr_in { + pub sin_family: sa_family_t, + pub sin_port: ::in_port_t, + pub sin_addr: ::in_addr, + pub sin_zero: [u8; 8], + } + + 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 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_addr: *mut ::sockaddr, + + pub ai_canonname: *mut c_char, + + pub ai_next: *mut addrinfo, + } + + pub struct sockaddr_ll { + pub sll_family: ::c_ushort, + pub sll_protocol: ::c_ushort, + pub sll_ifindex: ::c_int, + pub sll_hatype: ::c_ushort, + pub sll_pkttype: ::c_uchar, + pub sll_halen: ::c_uchar, + pub sll_addr: [::c_uchar; 8] + } + + pub struct fd_set { + fds_bits: [::c_ulong; 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, + } + + pub struct sched_param { + pub sched_priority: ::c_int, + pub sched_ss_low_priority: ::c_int, + pub sched_ss_repl_period: ::timespec, + pub sched_ss_init_budget: ::timespec, + pub sched_ss_max_repl: ::c_int, + } + + 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 epoll_event { + pub events: u32, + pub u64: u64, + } + + 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_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 rlimit64 { + pub rlim_cur: rlim64_t, + pub rlim_max: rlim64_t, + } + + pub struct glob_t { + pub gl_pathc: ::size_t, + pub gl_pathv: *mut *mut c_char, + pub gl_offs: ::size_t, + pub gl_flags: ::c_int, + + __unused1: *mut ::c_void, + __unused2: *mut ::c_void, + __unused3: *mut ::c_void, + __unused4: *mut ::c_void, + __unused5: *mut ::c_void, + } + + 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_ifu: *mut ::sockaddr, // FIXME This should be a union + pub ifa_data: *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_gecos: *mut ::c_char, + pub pw_dir: *mut ::c_char, + pub pw_shell: *mut ::c_char, + } + + pub struct spwd { + pub sp_namp: *mut ::c_char, + pub sp_pwdp: *mut ::c_char, + pub sp_lstchg: ::c_long, + pub sp_min: ::c_long, + pub sp_max: ::c_long, + pub sp_warn: ::c_long, + pub sp_inact: ::c_long, + pub sp_expire: ::c_long, + pub sp_flag: ::c_ulong, + } + + 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, + #[cfg(target_endian = "little")] + pub f_fsid: ::c_ulong, + #[cfg(all(target_pointer_width = "32", not(target_arch = "x86_64")))] + __f_unused: ::c_int, + #[cfg(target_endian = "big")] + pub f_fsid: ::c_ulong, + pub f_flag: ::c_ulong, + pub f_namemax: ::c_ulong, + __f_spare: [::c_int; 6], + } + + pub struct dqblk { + pub dqb_bhardlimit: u64, + pub dqb_bsoftlimit: u64, + pub dqb_curspace: u64, + pub dqb_ihardlimit: u64, + pub dqb_isoftlimit: u64, + pub dqb_curinodes: u64, + pub dqb_btime: u64, + pub dqb_itime: u64, + pub dqb_valid: u32, + } + + pub struct signalfd_siginfo { + pub ssi_signo: u32, + pub ssi_errno: i32, + pub ssi_code: i32, + pub ssi_pid: u32, + pub ssi_uid: u32, + pub ssi_fd: i32, + pub ssi_tid: u32, + pub ssi_band: u32, + pub ssi_overrun: u32, + pub ssi_trapno: u32, + pub ssi_status: i32, + pub ssi_int: i32, + pub ssi_ptr: u64, + pub ssi_utime: u64, + pub ssi_stime: u64, + pub ssi_addr: u64, + pub ssi_addr_lsb: u16, + _pad2: u16, + pub ssi_syscall: i32, + pub ssi_call_addr: u64, + pub ssi_arch: u32, + _pad: [u8; 28], + } + + pub struct itimerspec { + pub it_interval: ::timespec, + pub it_value: ::timespec, + } + + pub struct fsid_t { + __val: [::c_int; 2], + } + + pub struct cpu_set_t { + #[cfg(all(target_pointer_width = "32", + not(target_arch = "x86_64")))] + bits: [u32; 32], + #[cfg(not(all(target_pointer_width = "32", + not(target_arch = "x86_64"))))] + bits: [u64; 16], + } + + pub struct if_nameindex { + pub if_index: ::c_uint, + pub if_name: *mut ::c_char, + } + + // System V IPC + pub struct msginfo { + pub msgpool: ::c_int, + pub msgmap: ::c_int, + pub msgmax: ::c_int, + pub msgmnb: ::c_int, + pub msgmni: ::c_int, + pub msgssz: ::c_int, + pub msgtql: ::c_int, + pub msgseg: ::c_ushort, + } + + pub struct mmsghdr { + pub msg_hdr: ::msghdr, + pub msg_len: ::c_uint, + } + + pub struct sembuf { + pub sem_num: ::c_ushort, + pub sem_op: ::c_short, + pub sem_flg: ::c_short, + } + + 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], + } + + pub struct dl_phdr_info { + #[cfg(target_pointer_width = "64")] + pub dlpi_addr: Elf64_Addr, + #[cfg(target_pointer_width = "32")] + pub dlpi_addr: Elf32_Addr, + + pub dlpi_name: *const ::c_char, + + #[cfg(target_pointer_width = "64")] + pub dlpi_phdr: *const Elf64_Phdr, + #[cfg(target_pointer_width = "32")] + pub dlpi_phdr: *const Elf32_Phdr, + + #[cfg(target_pointer_width = "64")] + pub dlpi_phnum: Elf64_Half, + #[cfg(target_pointer_width = "32")] + pub dlpi_phnum: Elf32_Half, + + pub dlpi_adds: ::c_ulonglong, + pub dlpi_subs: ::c_ulonglong, + pub dlpi_tls_modid: ::size_t, + pub dlpi_tls_data: *mut ::c_void, + } + + 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 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, + pub f_flag: ::c_ulong, + pub f_namemax: ::c_ulong, + __f_spare: [::c_int; 6], + } + + pub struct stack_t { + pub ss_sp: *mut ::c_void, + pub ss_flags: ::c_int, + pub ss_size: ::size_t + } + + pub struct pthread_attr_t { + __size: [u64; 7] + } + + pub struct sigset_t { + __val: [::c_ulong; 16], + } + + 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: ::c_ulong, + __pad1: ::c_ulong, + __pad2: ::c_ulong, + } + + pub struct msqid_ds { + pub msg_perm: ::ipc_perm, + pub msg_stime: ::time_t, + pub msg_rtime: ::time_t, + pub msg_ctime: ::time_t, + __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 statfs { + 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 msghdr { + pub msg_name: *mut ::c_void, + pub msg_namelen: ::socklen_t, + pub msg_iov: *mut ::iovec, + pub msg_iovlen: ::c_int, + __pad1: ::c_int, + pub msg_control: *mut ::c_void, + pub msg_controllen: ::socklen_t, + __pad2: ::socklen_t, + pub msg_flags: ::c_int, + } + + pub struct cmsghdr { + pub cmsg_len: ::socklen_t, + pub __pad1: ::c_int, + pub cmsg_level: ::c_int, + pub cmsg_type: ::c_int, + } + + pub struct sem_t { + __val: [::c_int; 8], + } + + pub struct siginfo_t { + pub si_signo: ::c_int, + pub si_errno: ::c_int, + pub si_code: ::c_int, + pub _pad: [::c_int; 29], + _align: [usize; 0], + } + + 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 in6_pktinfo { + pub ipi6_addr: ::in6_addr, + pub ipi6_ifindex: ::c_uint, + } +} + +s_no_extra_traits! { + pub struct sysinfo { + pub uptime: ::c_ulong, + pub loads: [::c_ulong; 3], + pub totalram: ::c_ulong, + pub freeram: ::c_ulong, + pub sharedram: ::c_ulong, + pub bufferram: ::c_ulong, + pub totalswap: ::c_ulong, + pub freeswap: ::c_ulong, + pub procs: ::c_ushort, + pub pad: ::c_ushort, + pub totalhigh: ::c_ulong, + pub freehigh: ::c_ulong, + pub mem_unit: ::c_uint, + pub __reserved: [::c_char; 256], + } + + pub struct sockaddr_un { + pub sun_family: sa_family_t, + pub sun_path: [::c_char; 108] + } + + pub struct sockaddr_storage { + pub ss_family: sa_family_t, + __ss_pad2: [u8; 128 - 2 - 8], + __ss_align: ::size_t, + } + + pub struct utsname { + pub sysname: [::c_char; 65], + pub nodename: [::c_char; 65], + pub release: [::c_char; 65], + pub version: [::c_char; 65], + pub machine: [::c_char; 65], + pub domainname: [::c_char; 65] + } + + pub struct dirent { + pub d_ino: ::ino_t, + pub d_off: ::off_t, + pub d_reclen: ::c_ushort, + pub d_type: ::c_uchar, + pub d_name: [::c_char; 256], + } + + pub struct dirent64 { + pub d_ino: ::ino64_t, + pub d_off: ::off64_t, + pub d_reclen: ::c_ushort, + pub d_type: ::c_uchar, + pub d_name: [::c_char; 256], + } + + // x32 compatibility + // See https://sourceware.org/bugzilla/show_bug.cgi?id=21279 + pub struct mq_attr { + #[cfg(all(target_arch = "x86_64", target_pointer_width = "32"))] + pub mq_flags: i64, + #[cfg(all(target_arch = "x86_64", target_pointer_width = "32"))] + pub mq_maxmsg: i64, + #[cfg(all(target_arch = "x86_64", target_pointer_width = "32"))] + pub mq_msgsize: i64, + #[cfg(all(target_arch = "x86_64", target_pointer_width = "32"))] + pub mq_curmsgs: i64, + #[cfg(all(target_arch = "x86_64", target_pointer_width = "32"))] + pad: [i64; 4], + + #[cfg(not(all(target_arch = "x86_64", target_pointer_width = "32")))] + pub mq_flags: ::c_long, + #[cfg(not(all(target_arch = "x86_64", target_pointer_width = "32")))] + pub mq_maxmsg: ::c_long, + #[cfg(not(all(target_arch = "x86_64", target_pointer_width = "32")))] + pub mq_msgsize: ::c_long, + #[cfg(not(all(target_arch = "x86_64", target_pointer_width = "32")))] + pub mq_curmsgs: ::c_long, + #[cfg(not(all(target_arch = "x86_64", target_pointer_width = "32")))] + pad: [::c_long; 4], + } + + pub struct sockaddr_nl { + pub nl_family: ::sa_family_t, + nl_pad: ::c_ushort, + pub nl_pid: u32, + pub nl_groups: u32 + } + + pub struct sigevent { + pub sigev_value: ::sigval, + pub sigev_signo: ::c_int, + pub sigev_notify: ::c_int, + pub sigev_notify_function: fn(::sigval), + pub sigev_notify_attributes: *mut pthread_attr_t, + pub __pad: [::c_char; 56 - 3 * 8 /* 8 == sizeof(long) */], + } +} + +cfg_if! { + if #[cfg(feature = "extra_traits")] { + impl PartialEq for sysinfo { + fn eq(&self, other: &sysinfo) -> bool { + self.uptime == other.uptime + && self.loads == other.loads + && self.totalram == other.totalram + && self.freeram == other.freeram + && self.sharedram == other.sharedram + && self.bufferram == other.bufferram + && self.totalswap == other.totalswap + && self.freeswap == other.freeswap + && self.procs == other.procs + && self.pad == other.pad + && self.totalhigh == other.totalhigh + && self.freehigh == other.freehigh + && self.mem_unit == other.mem_unit + && self + .__reserved + .iter() + .zip(other.__reserved.iter()) + .all(|(a,b)| a == b) + } + } + impl Eq for sysinfo {} + impl ::fmt::Debug for sysinfo { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("sysinfo") + .field("uptime", &self.uptime) + .field("loads", &self.loads) + .field("totalram", &self.totalram) + .field("freeram", &self.freeram) + .field("sharedram", &self.sharedram) + .field("bufferram", &self.bufferram) + .field("totalswap", &self.totalswap) + .field("freeswap", &self.freeswap) + .field("procs", &self.procs) + .field("pad", &self.pad) + .field("totalhigh", &self.totalhigh) + .field("freehigh", &self.freehigh) + .field("mem_unit", &self.mem_unit) + // FIXME: .field("__reserved", &self.__reserved) + .finish() + } + } + impl ::hash::Hash for sysinfo { + fn hash(&self, state: &mut H) { + self.uptime.hash(state); + self.loads.hash(state); + self.totalram.hash(state); + self.freeram.hash(state); + self.sharedram.hash(state); + self.bufferram.hash(state); + self.totalswap.hash(state); + self.freeswap.hash(state); + self.procs.hash(state); + self.pad.hash(state); + self.totalhigh.hash(state); + self.freehigh.hash(state); + self.mem_unit.hash(state); + self.__reserved.hash(state); + } + } + + impl PartialEq for sockaddr_un { + fn eq(&self, other: &sockaddr_un) -> bool { + self.sun_family == other.sun_family + && self + .sun_path + .iter() + .zip(other.sun_path.iter()) + .all(|(a,b)| a == b) + } + } + impl Eq for sockaddr_un {} + impl ::fmt::Debug for sockaddr_un { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("sockaddr_un") + .field("sun_family", &self.sun_family) + // FIXME: .field("sun_path", &self.sun_path) + .finish() + } + } + impl ::hash::Hash for sockaddr_un { + fn hash(&self, state: &mut H) { + self.sun_family.hash(state); + self.sun_path.hash(state); + } + } + + impl PartialEq for sockaddr_storage { + fn eq(&self, other: &sockaddr_storage) -> bool { + self.ss_family == other.ss_family + && self.__ss_align == other.__ss_align + && self + .__ss_pad2 + .iter() + .zip(other.__ss_pad2.iter()) + .all(|(a, b)| a == b) + } + } + impl Eq for sockaddr_storage {} + impl ::fmt::Debug for sockaddr_storage { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("sockaddr_storage") + .field("ss_family", &self.ss_family) + .field("__ss_align", &self.__ss_align) + // FIXME: .field("__ss_pad2", &self.__ss_pad2) + .finish() + } + } + impl ::hash::Hash for sockaddr_storage { + fn hash(&self, state: &mut H) { + self.ss_family.hash(state); + self.__ss_align.hash(state); + self.__ss_pad2.hash(state); + } + } + + impl PartialEq for utsname { + fn eq(&self, other: &utsname) -> bool { + self.sysname + .iter() + .zip(other.sysname.iter()) + .all(|(a,b)| a == b) + && self + .nodename + .iter() + .zip(other.nodename.iter()) + .all(|(a,b)| a == b) + && self + .release + .iter() + .zip(other.release.iter()) + .all(|(a,b)| a == b) + && self + .version + .iter() + .zip(other.version.iter()) + .all(|(a,b)| a == b) + && self + .machine + .iter() + .zip(other.machine.iter()) + .all(|(a,b)| a == b) + } + } + impl Eq for utsname {} + impl ::fmt::Debug for utsname { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("utsname") + // FIXME: .field("sysname", &self.sysname) + // FIXME: .field("nodename", &self.nodename) + // FIXME: .field("release", &self.release) + // FIXME: .field("version", &self.version) + // FIXME: .field("machine", &self.machine) + .finish() + } + } + impl ::hash::Hash for utsname { + fn hash(&self, state: &mut H) { + self.sysname.hash(state); + self.nodename.hash(state); + self.release.hash(state); + self.version.hash(state); + self.machine.hash(state); + } + } + + impl PartialEq for dirent { + fn eq(&self, other: &dirent) -> bool { + self.d_ino == other.d_ino + && self.d_off == other.d_off + && self.d_reclen == other.d_reclen + && self.d_type == other.d_type + && self + .d_name + .iter() + .zip(other.d_name.iter()) + .all(|(a,b)| a == b) + } + } + impl Eq for dirent {} + impl ::fmt::Debug for dirent { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("dirent") + .field("d_ino", &self.d_ino) + .field("d_off", &self.d_off) + .field("d_reclen", &self.d_reclen) + .field("d_type", &self.d_type) + // FIXME: .field("d_name", &self.d_name) + .finish() + } + } + impl ::hash::Hash for dirent { + fn hash(&self, state: &mut H) { + self.d_ino.hash(state); + self.d_off.hash(state); + self.d_reclen.hash(state); + self.d_type.hash(state); + self.d_name.hash(state); + } + } + + impl PartialEq for dirent64 { + fn eq(&self, other: &dirent64) -> bool { + self.d_ino == other.d_ino + && self.d_off == other.d_off + && self.d_reclen == other.d_reclen + && self.d_type == other.d_type + && self + .d_name + .iter() + .zip(other.d_name.iter()) + .all(|(a,b)| a == b) + } + } + impl Eq for dirent64 {} + impl ::fmt::Debug for dirent64 { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("dirent64") + .field("d_ino", &self.d_ino) + .field("d_off", &self.d_off) + .field("d_reclen", &self.d_reclen) + .field("d_type", &self.d_type) + // FIXME: .field("d_name", &self.d_name) + .finish() + } + } + impl ::hash::Hash for dirent64 { + fn hash(&self, state: &mut H) { + self.d_ino.hash(state); + self.d_off.hash(state); + self.d_reclen.hash(state); + self.d_type.hash(state); + self.d_name.hash(state); + } + } + + impl PartialEq for 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 sockaddr_nl { + fn eq(&self, other: &sockaddr_nl) -> bool { + self.nl_family == other.nl_family && + self.nl_pid == other.nl_pid && + self.nl_groups == other.nl_groups + } + } + impl Eq for sockaddr_nl {} + impl ::fmt::Debug for sockaddr_nl { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("sockaddr_nl") + .field("nl_family", &self.nl_family) + .field("nl_pid", &self.nl_pid) + .field("nl_groups", &self.nl_groups) + .finish() + } + } + impl ::hash::Hash for sockaddr_nl { + fn hash(&self, state: &mut H) { + self.nl_family.hash(state); + self.nl_pid.hash(state); + self.nl_groups.hash(state); + } + } + + impl PartialEq for sigevent { + fn eq(&self, other: &sigevent) -> bool { + self.sigev_value == other.sigev_value + && self.sigev_signo == other.sigev_signo + && self.sigev_notify == other.sigev_notify + && self.sigev_notify_function + == other.sigev_notify_function + && self.sigev_notify_attributes + == other.sigev_notify_attributes + } + } + impl Eq for sigevent {} + impl ::fmt::Debug for sigevent { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("sigevent") + .field("sigev_value", &self.sigev_value) + .field("sigev_signo", &self.sigev_signo) + .field("sigev_notify", &self.sigev_notify) + .field("sigev_notify_function", &self.sigev_notify_function) + .field("sigev_notify_attributes", + &self.sigev_notify_attributes) + .finish() + } + } + impl ::hash::Hash for sigevent { + fn hash(&self, state: &mut H) { + self.sigev_value.hash(state); + self.sigev_signo.hash(state); + self.sigev_notify.hash(state); + self.sigev_notify_function.hash(state); + self.sigev_notify_attributes.hash(state); + } + } + } +} + +// PUB_CONST + +pub const INT_MIN: c_int = -2147483648; +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; + +pub const FD_CLOEXEC: ::c_int = 0x1; + +pub const USRQUOTA: ::c_int = 0; +pub const GRPQUOTA: ::c_int = 1; + +pub const SIGIOT: ::c_int = 6; + +pub const S_ISUID: ::mode_t = 0o4000; +pub const S_ISGID: ::mode_t = 0o2000; +pub const S_ISVTX: ::mode_t = 0o1000; + +pub const IF_NAMESIZE: ::size_t = 16; +pub const IFNAMSIZ: ::size_t = IF_NAMESIZE; + +pub const LOG_EMERG: ::c_int = 0; +pub const LOG_ALERT: ::c_int = 1; +pub const LOG_CRIT: ::c_int = 2; +pub const LOG_ERR: ::c_int = 3; +pub const LOG_WARNING: ::c_int = 4; +pub const LOG_NOTICE: ::c_int = 5; +pub const LOG_INFO: ::c_int = 6; +pub const LOG_DEBUG: ::c_int = 7; + +pub const LOG_KERN: ::c_int = 0; +pub const LOG_USER: ::c_int = 1 << 3; +pub const LOG_MAIL: ::c_int = 2 << 3; +pub const LOG_DAEMON: ::c_int = 3 << 3; +pub const LOG_AUTH: ::c_int = 4 << 3; +pub const LOG_SYSLOG: ::c_int = 5 << 3; +pub const LOG_LPR: ::c_int = 6 << 3; +pub const LOG_NEWS: ::c_int = 7 << 3; +pub const LOG_UUCP: ::c_int = 8 << 3; +pub const LOG_LOCAL0: ::c_int = 16 << 3; +pub const LOG_LOCAL1: ::c_int = 17 << 3; +pub const LOG_LOCAL2: ::c_int = 18 << 3; +pub const LOG_LOCAL3: ::c_int = 19 << 3; +pub const LOG_LOCAL4: ::c_int = 20 << 3; +pub const LOG_LOCAL5: ::c_int = 21 << 3; +pub const LOG_LOCAL6: ::c_int = 22 << 3; +pub const LOG_LOCAL7: ::c_int = 23 << 3; + +pub const LOG_PID: ::c_int = 0x01; +pub const LOG_CONS: ::c_int = 0x02; +pub const LOG_ODELAY: ::c_int = 0x04; +pub const LOG_NDELAY: ::c_int = 0x08; +pub const LOG_NOWAIT: ::c_int = 0x10; + +pub const LOG_PRIMASK: ::c_int = 7; +pub const LOG_FACMASK: ::c_int = 0x3f8; + +pub const PRIO_PROCESS: ::c_int = 0; +pub const PRIO_PGRP: ::c_int = 1; +pub const PRIO_USER: ::c_int = 2; + +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; +pub const IPPROTO_UDP: ::c_int = 17; +pub const IPPROTO_IP: ::c_int = 0; +pub const IPPROTO_IPV6: ::c_int = 41; + +pub const INADDR_LOOPBACK: in_addr_t = 2130706433; +pub const INADDR_ANY: in_addr_t = 0; +pub const INADDR_BROADCAST: in_addr_t = 4294967295; +pub const INADDR_NONE: in_addr_t = 4294967295; + +pub const EXIT_FAILURE: ::c_int = 1; +pub const EXIT_SUCCESS: ::c_int = 0; +pub const RAND_MAX: ::c_int = 2147483647; +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; + +// Linux-specific fcntls +pub const F_SETLEASE: ::c_int = 1024; +pub const F_GETLEASE: ::c_int = 1025; +pub const F_NOTIFY: ::c_int = 1026; +pub const F_CANCELLK: ::c_int = 1029; +pub const F_DUPFD_CLOEXEC: ::c_int = 1030; +pub const F_SETPIPE_SZ: ::c_int = 1031; +pub const F_GETPIPE_SZ: ::c_int = 1032; +pub const F_ADD_SEALS: ::c_int = 1033; +pub const F_GET_SEALS: ::c_int = 1034; + +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; + +// FIXME(#235): Include file sealing fcntls once we have a way to verify them. + +pub const SIGTRAP: ::c_int = 5; + +pub const PTHREAD_CREATE_JOINABLE: ::c_int = 0; +pub const PTHREAD_CREATE_DETACHED: ::c_int = 1; + +pub const CLOCK_REALTIME: ::clockid_t = 0; +pub const CLOCK_MONOTONIC: ::clockid_t = 1; +pub const CLOCK_PROCESS_CPUTIME_ID: ::clockid_t = 2; +pub const CLOCK_THREAD_CPUTIME_ID: ::clockid_t = 3; +pub const CLOCK_MONOTONIC_RAW: ::clockid_t = 4; +pub const CLOCK_REALTIME_COARSE: ::clockid_t = 5; +pub const CLOCK_MONOTONIC_COARSE: ::clockid_t = 6; +pub const CLOCK_BOOTTIME: ::clockid_t = 7; +pub const CLOCK_REALTIME_ALARM: ::clockid_t = 8; +pub const CLOCK_BOOTTIME_ALARM: ::clockid_t = 9; +pub const CLOCK_SGI_CYCLE: ::clockid_t = 10; +pub const CLOCK_TAI: ::clockid_t = 11; +pub const TIMER_ABSTIME: ::c_int = 1; + +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 RUSAGE_SELF: ::c_int = 0; + +pub const O_RDONLY: ::c_int = 0; +pub const O_WRONLY: ::c_int = 1; +pub const O_RDWR: ::c_int = 2; + +pub const S_IFIFO: ::mode_t = 4096; +pub const S_IFCHR: ::mode_t = 8192; +pub const S_IFBLK: ::mode_t = 24576; +pub const S_IFDIR: ::mode_t = 16384; +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 = 61440; +pub const S_IRWXU: ::mode_t = 448; +pub const S_IXUSR: ::mode_t = 64; +pub const S_IWUSR: ::mode_t = 128; +pub const S_IRUSR: ::mode_t = 256; +pub const S_IRWXG: ::mode_t = 56; +pub const S_IXGRP: ::mode_t = 8; +pub const S_IWGRP: ::mode_t = 16; +pub const S_IRGRP: ::mode_t = 32; +pub const S_IRWXO: ::mode_t = 7; +pub const S_IXOTH: ::mode_t = 1; +pub const S_IWOTH: ::mode_t = 2; +pub const S_IROTH: ::mode_t = 4; +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; +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 = 0; +pub const PROT_READ: ::c_int = 1; +pub const PROT_WRITE: ::c_int = 2; +pub const PROT_EXEC: ::c_int = 4; + +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_ALL: ::c_int = 6; +pub const LC_CTYPE_MASK: ::c_int = 1 << LC_CTYPE; +pub const LC_NUMERIC_MASK: ::c_int = 1 << LC_NUMERIC; +pub const LC_TIME_MASK: ::c_int = 1 << LC_TIME; +pub const LC_COLLATE_MASK: ::c_int = 1 << LC_COLLATE; +pub const LC_MONETARY_MASK: ::c_int = 1 << LC_MONETARY; +pub const LC_MESSAGES_MASK: ::c_int = 1 << LC_MESSAGES; +// LC_ALL_MASK defined per platform + +pub const MAP_FILE: ::c_int = 0x0000; +pub const MAP_SHARED: ::c_int = 0x0001; +pub const MAP_PRIVATE: ::c_int = 0x0002; +pub const MAP_FIXED: ::c_int = 0x0010; + +pub const MAP_FAILED: *mut ::c_void = !0 as *mut ::c_void; + +// MS_ flags for msync(2) +pub const MS_ASYNC: ::c_int = 0x0001; +pub const MS_INVALIDATE: ::c_int = 0x0002; +pub const MS_SYNC: ::c_int = 0x0004; + +// MS_ flags for mount(2) +pub const MS_RDONLY: ::c_ulong = 0x01; +pub const MS_NOSUID: ::c_ulong = 0x02; +pub const MS_NODEV: ::c_ulong = 0x04; +pub const MS_NOEXEC: ::c_ulong = 0x08; +pub const MS_SYNCHRONOUS: ::c_ulong = 0x10; +pub const MS_REMOUNT: ::c_ulong = 0x20; +pub const MS_MANDLOCK: ::c_ulong = 0x40; +pub const MS_DIRSYNC: ::c_ulong = 0x80; +pub const MS_NOATIME: ::c_ulong = 0x0400; +pub const MS_NODIRATIME: ::c_ulong = 0x0800; +pub const MS_BIND: ::c_ulong = 0x1000; +pub const MS_MOVE: ::c_ulong = 0x2000; +pub const MS_REC: ::c_ulong = 0x4000; +pub const MS_SILENT: ::c_ulong = 0x8000; +pub const MS_POSIXACL: ::c_ulong = 0x010000; +pub const MS_UNBINDABLE: ::c_ulong = 0x020000; +pub const MS_PRIVATE: ::c_ulong = 0x040000; +pub const MS_SLAVE: ::c_ulong = 0x080000; +pub const MS_SHARED: ::c_ulong = 0x100000; +pub const MS_RELATIME: ::c_ulong = 0x200000; +pub const MS_KERNMOUNT: ::c_ulong = 0x400000; +pub const MS_I_VERSION: ::c_ulong = 0x800000; +pub const MS_STRICTATIME: ::c_ulong = 0x1000000; +pub const MS_ACTIVE: ::c_ulong = 0x40000000; +pub const MS_NOUSER: ::c_ulong = 0x80000000; +pub const MS_MGC_VAL: ::c_ulong = 0xc0ed0000; +pub const MS_MGC_MSK: ::c_ulong = 0xffff0000; +pub const MS_RMT_MASK: ::c_ulong = 0x800051; + +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 EWOULDBLOCK: ::c_int = EAGAIN; + +pub const SCM_RIGHTS: ::c_int = 0x01; +pub const SCM_CREDENTIALS: ::c_int = 0x02; + +pub const PROT_GROWSDOWN: ::c_int = 0x1000000; +pub const PROT_GROWSUP: ::c_int = 0x2000000; + +pub const MAP_TYPE: ::c_int = 0x000f; + +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 MADV_FREE: ::c_int = 8; +pub const MADV_REMOVE: ::c_int = 9; +pub const MADV_DONTFORK: ::c_int = 10; +pub const MADV_DOFORK: ::c_int = 11; +pub const MADV_MERGEABLE: ::c_int = 12; +pub const MADV_UNMERGEABLE: ::c_int = 13; +pub const MADV_HUGEPAGE: ::c_int = 14; +pub const MADV_NOHUGEPAGE: ::c_int = 15; +pub const MADV_DONTDUMP: ::c_int = 16; +pub const MADV_DODUMP: ::c_int = 17; +pub const MADV_HWPOISON: ::c_int = 100; +pub const MADV_SOFT_OFFLINE: ::c_int = 101; + +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_MASTER: ::c_int = 0x400; +pub const IFF_SLAVE: ::c_int = 0x800; +pub const IFF_MULTICAST: ::c_int = 0x1000; +pub const IFF_PORTSEL: ::c_int = 0x2000; +pub const IFF_AUTOMEDIA: ::c_int = 0x4000; +pub const IFF_DYNAMIC: ::c_int = 0x8000; +pub const IFF_TUN: ::c_int = 0x0001; +pub const IFF_TAP: ::c_int = 0x0002; +pub const IFF_NO_PI: ::c_int = 0x1000; + +pub const SOL_IP: ::c_int = 0; +pub const SOL_TCP: ::c_int = 6; +pub const SOL_UDP: ::c_int = 17; +pub const SOL_IPV6: ::c_int = 41; +pub const SOL_ICMPV6: ::c_int = 58; +pub const SOL_RAW: ::c_int = 255; +pub const SOL_DECNET: ::c_int = 261; +pub const SOL_X25: ::c_int = 262; +pub const SOL_PACKET: ::c_int = 263; +pub const SOL_ATM: ::c_int = 264; +pub const SOL_AAL: ::c_int = 265; +pub const SOL_IRDA: ::c_int = 266; +pub const SOL_NETBEUI: ::c_int = 267; +pub const SOL_LLC: ::c_int = 268; +pub const SOL_DCCP: ::c_int = 269; +pub const SOL_NETLINK: ::c_int = 270; +pub const SOL_TIPC: ::c_int = 271; + +pub const AF_UNSPEC: ::c_int = 0; +pub const AF_UNIX: ::c_int = 1; +pub const AF_LOCAL: ::c_int = 1; +pub const AF_INET: ::c_int = 2; +pub const AF_AX25: ::c_int = 3; +pub const AF_IPX: ::c_int = 4; +pub const AF_APPLETALK: ::c_int = 5; +pub const AF_NETROM: ::c_int = 6; +pub const AF_BRIDGE: ::c_int = 7; +pub const AF_ATMPVC: ::c_int = 8; +pub const AF_X25: ::c_int = 9; +pub const AF_INET6: ::c_int = 10; +pub const AF_ROSE: ::c_int = 11; +pub const AF_DECnet: ::c_int = 12; +pub const AF_NETBEUI: ::c_int = 13; +pub const AF_SECURITY: ::c_int = 14; +pub const AF_KEY: ::c_int = 15; +pub const AF_NETLINK: ::c_int = 16; +pub const AF_ROUTE: ::c_int = AF_NETLINK; +pub const AF_PACKET: ::c_int = 17; +pub const AF_ASH: ::c_int = 18; +pub const AF_ECONET: ::c_int = 19; +pub const AF_ATMSVC: ::c_int = 20; +pub const AF_RDS: ::c_int = 21; +pub const AF_SNA: ::c_int = 22; +pub const AF_IRDA: ::c_int = 23; +pub const AF_PPPOX: ::c_int = 24; +pub const AF_WANPIPE: ::c_int = 25; +pub const AF_LLC: ::c_int = 26; +pub const AF_CAN: ::c_int = 29; +pub const AF_TIPC: ::c_int = 30; +pub const AF_BLUETOOTH: ::c_int = 31; +pub const AF_IUCV: ::c_int = 32; +pub const AF_RXRPC: ::c_int = 33; +pub const AF_ISDN: ::c_int = 34; +pub const AF_PHONET: ::c_int = 35; +pub const AF_IEEE802154: ::c_int = 36; +pub const AF_CAIF: ::c_int = 37; +pub const AF_ALG: ::c_int = 38; + +pub const PF_UNSPEC: ::c_int = AF_UNSPEC; +pub const PF_UNIX: ::c_int = AF_UNIX; +pub const PF_LOCAL: ::c_int = AF_LOCAL; +pub const PF_INET: ::c_int = AF_INET; +pub const PF_AX25: ::c_int = AF_AX25; +pub const PF_IPX: ::c_int = AF_IPX; +pub const PF_APPLETALK: ::c_int = AF_APPLETALK; +pub const PF_NETROM: ::c_int = AF_NETROM; +pub const PF_BRIDGE: ::c_int = AF_BRIDGE; +pub const PF_ATMPVC: ::c_int = AF_ATMPVC; +pub const PF_X25: ::c_int = AF_X25; +pub const PF_INET6: ::c_int = AF_INET6; +pub const PF_ROSE: ::c_int = AF_ROSE; +pub const PF_DECnet: ::c_int = AF_DECnet; +pub const PF_NETBEUI: ::c_int = AF_NETBEUI; +pub const PF_SECURITY: ::c_int = AF_SECURITY; +pub const PF_KEY: ::c_int = AF_KEY; +pub const PF_NETLINK: ::c_int = AF_NETLINK; +pub const PF_ROUTE: ::c_int = AF_ROUTE; +pub const PF_PACKET: ::c_int = AF_PACKET; +pub const PF_ASH: ::c_int = AF_ASH; +pub const PF_ECONET: ::c_int = AF_ECONET; +pub const PF_ATMSVC: ::c_int = AF_ATMSVC; +pub const PF_RDS: ::c_int = AF_RDS; +pub const PF_SNA: ::c_int = AF_SNA; +pub const PF_IRDA: ::c_int = AF_IRDA; +pub const PF_PPPOX: ::c_int = AF_PPPOX; +pub const PF_WANPIPE: ::c_int = AF_WANPIPE; +pub const PF_LLC: ::c_int = AF_LLC; +pub const PF_CAN: ::c_int = AF_CAN; +pub const PF_TIPC: ::c_int = AF_TIPC; +pub const PF_BLUETOOTH: ::c_int = AF_BLUETOOTH; +pub const PF_IUCV: ::c_int = AF_IUCV; +pub const PF_RXRPC: ::c_int = AF_RXRPC; +pub const PF_ISDN: ::c_int = AF_ISDN; +pub const PF_PHONET: ::c_int = AF_PHONET; +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; +pub const MSG_CTRUNC: ::c_int = 8; +pub const MSG_TRUNC: ::c_int = 0x20; +pub const MSG_DONTWAIT: ::c_int = 0x40; +pub const MSG_EOR: ::c_int = 0x80; +pub const MSG_WAITALL: ::c_int = 0x100; +pub const MSG_FIN: ::c_int = 0x200; +pub const MSG_SYN: ::c_int = 0x400; +pub const MSG_CONFIRM: ::c_int = 0x800; +pub const MSG_RST: ::c_int = 0x1000; +pub const MSG_ERRQUEUE: ::c_int = 0x2000; +pub const MSG_NOSIGNAL: ::c_int = 0x4000; +pub const MSG_MORE: ::c_int = 0x8000; +pub const MSG_WAITFORONE: ::c_int = 0x10000; +pub const MSG_FASTOPEN: ::c_int = 0x20000000; +pub const MSG_CMSG_CLOEXEC: ::c_int = 0x40000000; + +pub const SCM_TIMESTAMP: ::c_int = SO_TIMESTAMP; + +pub const SOCK_RAW: ::c_int = 3; +pub const SOCK_RDM: ::c_int = 4; + +pub const IP_TOS: ::c_int = 1; +pub const IP_TTL: ::c_int = 2; +pub const IP_HDRINCL: ::c_int = 3; +pub const IP_RECVTOS: ::c_int = 13; +pub const IP_FREEBIND: ::c_int = 15; +pub const IP_TRANSPARENT: ::c_int = 19; +pub const IP_MULTICAST_IF: ::c_int = 32; +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 IPV6_UNICAST_HOPS: ::c_int = 16; +pub const IPV6_MULTICAST_IF: ::c_int = 17; +pub const IPV6_MULTICAST_HOPS: ::c_int = 18; +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; +pub const TCP_CORK: ::c_int = 3; +pub const TCP_KEEPIDLE: ::c_int = 4; +pub const TCP_KEEPINTVL: ::c_int = 5; +pub const TCP_KEEPCNT: ::c_int = 6; +pub const TCP_SYNCNT: ::c_int = 7; +pub const TCP_LINGER2: ::c_int = 8; +pub const TCP_DEFER_ACCEPT: ::c_int = 9; +pub const TCP_WINDOW_CLAMP: ::c_int = 10; +pub const TCP_INFO: ::c_int = 11; +pub const TCP_QUICKACK: ::c_int = 12; +pub const TCP_CONGESTION: ::c_int = 13; + +pub const SO_DEBUG: ::c_int = 1; + +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 = 1; +pub const LOCK_EX: ::c_int = 2; +pub const LOCK_NB: ::c_int = 4; +pub const LOCK_UN: ::c_int = 8; + +pub const SS_ONSTACK: ::c_int = 1; +pub const SS_DISABLE: ::c_int = 2; + +pub const PATH_MAX: ::c_int = 4096; + +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 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 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_DETACH: ::c_int = 0x2; +pub const MNT_EXPIRE: ::c_int = 0x4; + +pub const Q_GETFMT: ::c_int = 0x800004; +pub const Q_GETINFO: ::c_int = 0x800005; +pub const Q_SETINFO: ::c_int = 0x800006; +pub const QIF_BLIMITS: u32 = 1; +pub const QIF_SPACE: u32 = 2; +pub const QIF_ILIMITS: u32 = 4; +pub const QIF_INODES: u32 = 8; +pub const QIF_BTIME: u32 = 16; +pub const QIF_ITIME: u32 = 32; +pub const QIF_LIMITS: u32 = 5; +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; +pub const Q_GETQUOTA: ::c_int = 0x800007; +pub const Q_SETQUOTA: ::c_int = 0x800008; + +pub const TCIOFF: ::c_int = 2; +pub const TCION: ::c_int = 3; +pub const TCOOFF: ::c_int = 0; +pub const TCOON: ::c_int = 1; +pub const TCIFLUSH: ::c_int = 0; +pub const TCOFLUSH: ::c_int = 1; +pub const TCIOFLUSH: ::c_int = 2; +pub const NL0: ::c_int = 0x00000000; +pub const NL1: ::c_int = 0x00000100; +pub const TAB0: ::c_int = 0x00000000; +pub const CR0: ::c_int = 0x00000000; +pub const FF0: ::c_int = 0x00000000; +pub const BS0: ::c_int = 0x00000000; +pub const VT0: ::c_int = 0x00000000; +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 = 0x1; +pub const CS5: ::tcflag_t = 0x00000000; +pub const CRTSCTS: ::tcflag_t = 0x80000000; +pub const ECHO: ::tcflag_t = 0x00000008; +pub const OCRNL: ::tcflag_t = 0o000010; +pub const ONOCR: ::tcflag_t = 0o000020; +pub const ONLRET: ::tcflag_t = 0o000040; +pub const OFILL: ::tcflag_t = 0o000100; +pub const OFDEL: ::tcflag_t = 0o000200; + +pub const CLONE_VM: ::c_int = 0x100; +pub const CLONE_FS: ::c_int = 0x200; +pub const CLONE_FILES: ::c_int = 0x400; +pub const CLONE_SIGHAND: ::c_int = 0x800; +pub const CLONE_PTRACE: ::c_int = 0x2000; +pub const CLONE_VFORK: ::c_int = 0x4000; +pub const CLONE_PARENT: ::c_int = 0x8000; +pub const CLONE_THREAD: ::c_int = 0x10000; +pub const CLONE_NEWNS: ::c_int = 0x20000; +pub const CLONE_SYSVSEM: ::c_int = 0x40000; +pub const CLONE_SETTLS: ::c_int = 0x80000; +pub const CLONE_PARENT_SETTID: ::c_int = 0x100000; +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_NEWUTS: ::c_int = 0x04000000; +pub const CLONE_NEWIPC: ::c_int = 0x08000000; +pub const CLONE_NEWUSER: ::c_int = 0x10000000; +pub const CLONE_NEWPID: ::c_int = 0x20000000; +pub const CLONE_NEWNET: ::c_int = 0x40000000; +pub const CLONE_IO: ::c_int = 0x80000000; +pub const CLONE_NEWCGROUP: ::c_int = 0x02000000; + +pub const WNOHANG: ::c_int = 0x00000001; +pub const WUNTRACED: ::c_int = 0x00000002; +pub const WSTOPPED: ::c_int = WUNTRACED; +pub const WEXITED: ::c_int = 0x00000004; +pub const WCONTINUED: ::c_int = 0x00000008; +pub const WNOWAIT: ::c_int = 0x01000000; + +// ::Options set using PTRACE_SETOPTIONS. +pub const PTRACE_O_TRACESYSGOOD: ::c_int = 0x00000001; +pub const PTRACE_O_TRACEFORK: ::c_int = 0x00000002; +pub const PTRACE_O_TRACEVFORK: ::c_int = 0x00000004; +pub const PTRACE_O_TRACECLONE: ::c_int = 0x00000008; +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_EXITKILL: ::c_int = 0x00100000; +pub const PTRACE_O_SUSPEND_SECCOMP: ::c_int = 0x00200000; +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; +pub const PTRACE_EVENT_VFORK: ::c_int = 2; +pub const PTRACE_EVENT_CLONE: ::c_int = 3; +pub const PTRACE_EVENT_EXEC: ::c_int = 4; +pub const PTRACE_EVENT_VFORK_DONE: ::c_int = 5; +pub const PTRACE_EVENT_EXIT: ::c_int = 6; +pub const PTRACE_EVENT_SECCOMP: ::c_int = 7; +// PTRACE_EVENT_STOP was added to glibc in 2.26 +// pub const PTRACE_EVENT_STOP: ::c_int = 128; + +pub const __WNOTHREAD: ::c_int = 0x20000000; +pub const __WALL: ::c_int = 0x40000000; +pub const __WCLONE: ::c_int = 0x80000000; + +pub const SPLICE_F_MOVE: ::c_uint = 0x01; +pub const SPLICE_F_NONBLOCK: ::c_uint = 0x02; +pub const SPLICE_F_MORE: ::c_uint = 0x04; +pub const SPLICE_F_GIFT: ::c_uint = 0x08; + +pub const RTLD_LOCAL: ::c_int = 0; +pub const RTLD_LAZY: ::c_int = 1; + +pub const POSIX_FADV_NORMAL: ::c_int = 0; +pub const POSIX_FADV_RANDOM: ::c_int = 1; +pub const POSIX_FADV_SEQUENTIAL: ::c_int = 2; +pub const POSIX_FADV_WILLNEED: ::c_int = 3; + +pub const AT_FDCWD: ::c_int = -100; +pub const AT_SYMLINK_NOFOLLOW: ::c_int = 0x100; +pub const AT_REMOVEDIR: ::c_int = 0x200; +pub const AT_EACCESS: ::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 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 = 4096; + +pub const SI_LOAD_SHIFT: ::c_uint = 16; + +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 SIGEV_SIGNAL: ::c_int = 0; +pub const SIGEV_NONE: ::c_int = 1; +pub const SIGEV_THREAD: ::c_int = 2; + +pub const P_ALL: idtype_t = 0; +pub const P_PID: idtype_t = 1; +pub const P_PGID: idtype_t = 2; + +pub const UTIME_OMIT: c_long = 1073741822; +pub const UTIME_NOW: c_long = 1073741823; + +pub const POLLIN: ::c_short = 0x1; +pub const POLLPRI: ::c_short = 0x2; +pub const POLLOUT: ::c_short = 0x4; +pub const POLLERR: ::c_short = 0x8; +pub const POLLHUP: ::c_short = 0x10; +pub const POLLNVAL: ::c_short = 0x20; +pub const POLLRDNORM: ::c_short = 0x040; +pub const POLLRDBAND: ::c_short = 0x080; + +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 RUSAGE_THREAD: ::c_int = 1; +pub const RUSAGE_CHILDREN: ::c_int = -1; + +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; + +pub const FILENAME_MAX: ::c_uint = 4096; +pub const L_tmpnam: ::c_uint = 20; +pub const _PC_LINK_MAX: ::c_int = 0; +pub const _PC_MAX_CANON: ::c_int = 1; +pub const _PC_MAX_INPUT: ::c_int = 2; +pub const _PC_NAME_MAX: ::c_int = 3; +pub const _PC_PATH_MAX: ::c_int = 4; +pub const _PC_PIPE_BUF: ::c_int = 5; +pub const _PC_CHOWN_RESTRICTED: ::c_int = 6; +pub const _PC_NO_TRUNC: ::c_int = 7; +pub const _PC_VDISABLE: ::c_int = 8; +pub const _PC_SYNC_IO: ::c_int = 9; +pub const _PC_ASYNC_IO: ::c_int = 10; +pub const _PC_PRIO_IO: ::c_int = 11; +pub const _PC_SOCK_MAXBUF: ::c_int = 12; +pub const _PC_FILESIZEBITS: ::c_int = 13; +pub const _PC_REC_INCR_XFER_SIZE: ::c_int = 14; +pub const _PC_REC_MAX_XFER_SIZE: ::c_int = 15; +pub const _PC_REC_MIN_XFER_SIZE: ::c_int = 16; +pub const _PC_REC_XFER_ALIGN: ::c_int = 17; +pub const _PC_ALLOC_SIZE_MIN: ::c_int = 18; +pub const _PC_SYMLINK_MAX: ::c_int = 19; +pub const _PC_2_SYMLINKS: ::c_int = 20; + +pub const _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_STREAM_MAX: ::c_int = 5; +pub const _SC_TZNAME_MAX: ::c_int = 6; +pub const _SC_JOB_CONTROL: ::c_int = 7; +pub const _SC_SAVED_IDS: ::c_int = 8; +pub const _SC_REALTIME_SIGNALS: ::c_int = 9; +pub const _SC_PRIORITY_SCHEDULING: ::c_int = 10; +pub const _SC_TIMERS: ::c_int = 11; +pub const _SC_ASYNCHRONOUS_IO: ::c_int = 12; +pub const _SC_PRIORITIZED_IO: ::c_int = 13; +pub const _SC_SYNCHRONIZED_IO: ::c_int = 14; +pub const _SC_FSYNC: ::c_int = 15; +pub const _SC_MAPPED_FILES: ::c_int = 16; +pub const _SC_MEMLOCK: ::c_int = 17; +pub const _SC_MEMLOCK_RANGE: ::c_int = 18; +pub const _SC_MEMORY_PROTECTION: ::c_int = 19; +pub const _SC_MESSAGE_PASSING: ::c_int = 20; +pub const _SC_SEMAPHORES: ::c_int = 21; +pub const _SC_SHARED_MEMORY_OBJECTS: ::c_int = 22; +pub const _SC_AIO_LISTIO_MAX: ::c_int = 23; +pub const _SC_AIO_MAX: ::c_int = 24; +pub const _SC_AIO_PRIO_DELTA_MAX: ::c_int = 25; +pub const _SC_DELAYTIMER_MAX: ::c_int = 26; +pub const _SC_MQ_OPEN_MAX: ::c_int = 27; +pub const _SC_MQ_PRIO_MAX: ::c_int = 28; +pub const _SC_VERSION: ::c_int = 29; +pub const _SC_PAGESIZE: ::c_int = 30; +pub const _SC_PAGE_SIZE: ::c_int = _SC_PAGESIZE; +pub const _SC_RTSIG_MAX: ::c_int = 31; +pub const _SC_SEM_NSEMS_MAX: ::c_int = 32; +pub const _SC_SEM_VALUE_MAX: ::c_int = 33; +pub const _SC_SIGQUEUE_MAX: ::c_int = 34; +pub const _SC_TIMER_MAX: ::c_int = 35; +pub const _SC_BC_BASE_MAX: ::c_int = 36; +pub const _SC_BC_DIM_MAX: ::c_int = 37; +pub const _SC_BC_SCALE_MAX: ::c_int = 38; +pub const _SC_BC_STRING_MAX: ::c_int = 39; +pub const _SC_COLL_WEIGHTS_MAX: ::c_int = 40; +pub const _SC_EXPR_NEST_MAX: ::c_int = 42; +pub const _SC_LINE_MAX: ::c_int = 43; +pub const _SC_RE_DUP_MAX: ::c_int = 44; +pub const _SC_2_VERSION: ::c_int = 46; +pub const _SC_2_C_BIND: ::c_int = 47; +pub const _SC_2_C_DEV: ::c_int = 48; +pub const _SC_2_FORT_DEV: ::c_int = 49; +pub const _SC_2_FORT_RUN: ::c_int = 50; +pub const _SC_2_SW_DEV: ::c_int = 51; +pub const _SC_2_LOCALEDEF: ::c_int = 52; +pub const _SC_UIO_MAXIOV: ::c_int = 60; +pub const _SC_IOV_MAX: ::c_int = 60; +pub const _SC_THREADS: ::c_int = 67; +pub const _SC_THREAD_SAFE_FUNCTIONS: ::c_int = 68; +pub const _SC_GETGR_R_SIZE_MAX: ::c_int = 69; +pub const _SC_GETPW_R_SIZE_MAX: ::c_int = 70; +pub const _SC_LOGIN_NAME_MAX: ::c_int = 71; +pub const _SC_TTY_NAME_MAX: ::c_int = 72; +pub const _SC_THREAD_DESTRUCTOR_ITERATIONS: ::c_int = 73; +pub const _SC_THREAD_KEYS_MAX: ::c_int = 74; +pub const _SC_THREAD_STACK_MIN: ::c_int = 75; +pub const _SC_THREAD_THREADS_MAX: ::c_int = 76; +pub const _SC_THREAD_ATTR_STACKADDR: ::c_int = 77; +pub const _SC_THREAD_ATTR_STACKSIZE: ::c_int = 78; +pub const _SC_THREAD_PRIORITY_SCHEDULING: ::c_int = 79; +pub const _SC_THREAD_PRIO_INHERIT: ::c_int = 80; +pub const _SC_THREAD_PRIO_PROTECT: ::c_int = 81; +pub const _SC_THREAD_PROCESS_SHARED: ::c_int = 82; +pub const _SC_NPROCESSORS_CONF: ::c_int = 83; +pub const _SC_NPROCESSORS_ONLN: ::c_int = 84; +pub const _SC_PHYS_PAGES: ::c_int = 85; +pub const _SC_AVPHYS_PAGES: ::c_int = 86; +pub const _SC_ATEXIT_MAX: ::c_int = 87; +pub const _SC_PASS_MAX: ::c_int = 88; +pub const _SC_XOPEN_VERSION: ::c_int = 89; +pub const _SC_XOPEN_XCU_VERSION: ::c_int = 90; +pub const _SC_XOPEN_UNIX: ::c_int = 91; +pub const _SC_XOPEN_CRYPT: ::c_int = 92; +pub const _SC_XOPEN_ENH_I18N: ::c_int = 93; +pub const _SC_XOPEN_SHM: ::c_int = 94; +pub const _SC_2_CHAR_TERM: ::c_int = 95; +pub const _SC_2_UPE: ::c_int = 97; +pub const _SC_XOPEN_XPG2: ::c_int = 98; +pub const _SC_XOPEN_XPG3: ::c_int = 99; +pub const _SC_XOPEN_XPG4: ::c_int = 100; +pub const _SC_NZERO: ::c_int = 109; +pub const _SC_XBS5_ILP32_OFF32: ::c_int = 125; +pub const _SC_XBS5_ILP32_OFFBIG: ::c_int = 126; +pub const _SC_XBS5_LP64_OFF64: ::c_int = 127; +pub const _SC_XBS5_LPBIG_OFFBIG: ::c_int = 128; +pub const _SC_XOPEN_LEGACY: ::c_int = 129; +pub const _SC_XOPEN_REALTIME: ::c_int = 130; +pub const _SC_XOPEN_REALTIME_THREADS: ::c_int = 131; +pub const _SC_ADVISORY_INFO: ::c_int = 132; +pub const _SC_BARRIERS: ::c_int = 133; +pub const _SC_CLOCK_SELECTION: ::c_int = 137; +pub const _SC_CPUTIME: ::c_int = 138; +pub const _SC_THREAD_CPUTIME: ::c_int = 139; +pub const _SC_MONOTONIC_CLOCK: ::c_int = 149; +pub const _SC_READER_WRITER_LOCKS: ::c_int = 153; +pub const _SC_SPIN_LOCKS: ::c_int = 154; +pub const _SC_REGEXP: ::c_int = 155; +pub const _SC_SHELL: ::c_int = 157; +pub const _SC_SPAWN: ::c_int = 159; +pub const _SC_SPORADIC_SERVER: ::c_int = 160; +pub const _SC_THREAD_SPORADIC_SERVER: ::c_int = 161; +pub const _SC_TIMEOUTS: ::c_int = 164; +pub const _SC_TYPED_MEMORY_OBJECTS: ::c_int = 165; +pub const _SC_2_PBS: ::c_int = 168; +pub const _SC_2_PBS_ACCOUNTING: ::c_int = 169; +pub const _SC_2_PBS_LOCATE: ::c_int = 170; +pub const _SC_2_PBS_MESSAGE: ::c_int = 171; +pub const _SC_2_PBS_TRACK: ::c_int = 172; +pub const _SC_SYMLOOP_MAX: ::c_int = 173; +pub const _SC_STREAMS: ::c_int = 174; +pub const _SC_2_PBS_CHECKPOINT: ::c_int = 175; +pub const _SC_V6_ILP32_OFF32: ::c_int = 176; +pub const _SC_V6_ILP32_OFFBIG: ::c_int = 177; +pub const _SC_V6_LP64_OFF64: ::c_int = 178; +pub const _SC_V6_LPBIG_OFFBIG: ::c_int = 179; +pub const _SC_HOST_NAME_MAX: ::c_int = 180; +pub const _SC_TRACE: ::c_int = 181; +pub const _SC_TRACE_EVENT_FILTER: ::c_int = 182; +pub const _SC_TRACE_INHERIT: ::c_int = 183; +pub const _SC_TRACE_LOG: ::c_int = 184; +pub const _SC_IPV6: ::c_int = 235; +pub const _SC_RAW_SOCKETS: ::c_int = 236; +pub const _SC_V7_ILP32_OFF32: ::c_int = 237; +pub const _SC_V7_ILP32_OFFBIG: ::c_int = 238; +pub const _SC_V7_LP64_OFF64: ::c_int = 239; +pub const _SC_V7_LPBIG_OFFBIG: ::c_int = 240; +pub const _SC_SS_REPL_MAX: ::c_int = 241; +pub const _SC_TRACE_EVENT_NAME_MAX: ::c_int = 242; +pub const _SC_TRACE_NAME_MAX: ::c_int = 243; +pub const _SC_TRACE_SYS_MAX: ::c_int = 244; +pub const _SC_TRACE_USER_EVENT_MAX: ::c_int = 245; +pub const _SC_XOPEN_STREAMS: ::c_int = 246; +pub const _SC_THREAD_ROBUST_PRIO_INHERIT: ::c_int = 247; +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; + +pub const GLOB_ERR: ::c_int = 1 << 0; +pub const GLOB_MARK: ::c_int = 1 << 1; +pub const GLOB_NOSORT: ::c_int = 1 << 2; +pub const GLOB_DOOFFS: ::c_int = 1 << 3; +pub const GLOB_NOCHECK: ::c_int = 1 << 4; +pub const GLOB_APPEND: ::c_int = 1 << 5; +pub const GLOB_NOESCAPE: ::c_int = 1 << 6; + +pub const GLOB_NOSPACE: ::c_int = 1; +pub const GLOB_ABORTED: ::c_int = 2; +pub const GLOB_NOMATCH: ::c_int = 3; + +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 S_IEXEC: mode_t = 64; +pub const S_IWRITE: mode_t = 128; +pub const S_IREAD: mode_t = 256; + +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 IFF_LOWER_UP: ::c_int = 0x10000; +pub const IFF_DORMANT: ::c_int = 0x20000; +pub const IFF_ECHO: ::c_int = 0x40000; + +pub const ST_RDONLY: ::c_ulong = 1; +pub const ST_NOSUID: ::c_ulong = 2; +pub const ST_NODEV: ::c_ulong = 4; +pub const ST_NOEXEC: ::c_ulong = 8; +pub const ST_SYNCHRONOUS: ::c_ulong = 16; +pub const ST_MANDLOCK: ::c_ulong = 64; +pub const ST_WRITE: ::c_ulong = 128; +pub const ST_APPEND: ::c_ulong = 256; +pub const ST_IMMUTABLE: ::c_ulong = 512; +pub const ST_NOATIME: ::c_ulong = 1024; +pub const ST_NODIRATIME: ::c_ulong = 2048; + +pub const RTLD_NEXT: *mut ::c_void = -1i64 as *mut ::c_void; +pub const RTLD_DEFAULT: *mut ::c_void = 0i64 as *mut ::c_void; +pub const RTLD_NODELETE: ::c_int = 0x1000; +pub const RTLD_NOW: ::c_int = 0x2; + +pub const TCP_MD5SIG: ::c_int = 14; + +align_const! { + pub const PTHREAD_MUTEX_INITIALIZER: pthread_mutex_t = pthread_mutex_t { + size: [0; __SIZEOF_PTHREAD_MUTEX_T], + }; + pub const PTHREAD_COND_INITIALIZER: pthread_cond_t = pthread_cond_t { + size: [0; __SIZEOF_PTHREAD_COND_T], + }; + pub const PTHREAD_RWLOCK_INITIALIZER: pthread_rwlock_t = pthread_rwlock_t { + size: [0; __SIZEOF_PTHREAD_RWLOCK_T], + }; +} +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_PROCESS_PRIVATE: ::c_int = 0; +pub const PTHREAD_PROCESS_SHARED: ::c_int = 1; +pub const __SIZEOF_PTHREAD_COND_T: usize = 48; + +pub const RENAME_NOREPLACE: ::c_int = 1; +pub const RENAME_EXCHANGE: ::c_int = 2; +pub const RENAME_WHITEOUT: ::c_int = 4; + +pub const SCHED_OTHER: ::c_int = 0; +pub const SCHED_FIFO: ::c_int = 1; +pub const SCHED_RR: ::c_int = 2; +pub const SCHED_BATCH: ::c_int = 3; +pub const SCHED_IDLE: ::c_int = 5; + +// netinet/in.h +// NOTE: These are in addition to the constants defined in src/unix/mod.rs + +// IPPROTO_IP defined in src/unix/mod.rs +/// Hop-by-hop option header +pub const IPPROTO_HOPOPTS: ::c_int = 0; +// IPPROTO_ICMP defined in src/unix/mod.rs +/// group mgmt protocol +pub const IPPROTO_IGMP: ::c_int = 2; +/// for compatibility +pub const IPPROTO_IPIP: ::c_int = 4; +// IPPROTO_TCP defined in src/unix/mod.rs +/// exterior gateway protocol +pub const IPPROTO_EGP: ::c_int = 8; +/// pup +pub const IPPROTO_PUP: ::c_int = 12; +// IPPROTO_UDP defined in src/unix/mod.rs +/// xns idp +pub const IPPROTO_IDP: ::c_int = 22; +/// tp-4 w/ class negotiation +pub const IPPROTO_TP: ::c_int = 29; +/// DCCP +pub const IPPROTO_DCCP: ::c_int = 33; +// IPPROTO_IPV6 defined in src/unix/mod.rs +/// IP6 routing header +pub const IPPROTO_ROUTING: ::c_int = 43; +/// IP6 fragmentation header +pub const IPPROTO_FRAGMENT: ::c_int = 44; +/// resource reservation +pub const IPPROTO_RSVP: ::c_int = 46; +/// General Routing Encap. +pub const IPPROTO_GRE: ::c_int = 47; +/// IP6 Encap Sec. Payload +pub const IPPROTO_ESP: ::c_int = 50; +/// IP6 Auth Header +pub const IPPROTO_AH: ::c_int = 51; +// IPPROTO_ICMPV6 defined in src/unix/mod.rs +/// IP6 no next header +pub const IPPROTO_NONE: ::c_int = 59; +/// IP6 destination option +pub const IPPROTO_DSTOPTS: ::c_int = 60; +pub const IPPROTO_MTP: ::c_int = 92; +pub const IPPROTO_BEETPH: ::c_int = 94; +/// encapsulation header +pub const IPPROTO_ENCAP: ::c_int = 98; +/// Protocol indep. multicast +pub const IPPROTO_PIM: ::c_int = 103; +/// IP Payload Comp. Protocol +pub const IPPROTO_COMP: ::c_int = 108; +/// SCTP +pub const IPPROTO_SCTP: ::c_int = 132; +pub const IPPROTO_MH: ::c_int = 135; +pub const IPPROTO_UDPLITE: ::c_int = 136; +pub const IPPROTO_MPLS: ::c_int = 137; +/// raw IP packet +pub const IPPROTO_RAW: ::c_int = 255; +pub const IPPROTO_MAX: ::c_int = 256; + +pub const AF_IB: ::c_int = 27; +pub const AF_MPLS: ::c_int = 28; +pub const AF_NFC: ::c_int = 39; +pub const AF_VSOCK: ::c_int = 40; +pub const PF_IB: ::c_int = AF_IB; +pub const PF_MPLS: ::c_int = AF_MPLS; +pub const PF_NFC: ::c_int = AF_NFC; +pub const PF_VSOCK: ::c_int = AF_VSOCK; + +// 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 MSG_STAT: ::c_int = 11; +pub const MSG_INFO: ::c_int = 12; + +pub const MSG_NOERROR: ::c_int = 0o10000; +pub const MSG_EXCEPT: ::c_int = 0o20000; +pub const MSG_COPY: ::c_int = 0o40000; + +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_REMAP: ::c_int = 0o40000; +pub const SHM_EXEC: ::c_int = 0o100000; + +pub const SHM_LOCK: ::c_int = 11; +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; +pub const QFMT_VFS_V1: ::c_int = 4; + +pub const EFD_SEMAPHORE: ::c_int = 0x1; + +pub const LOG_NFACILITIES: ::c_int = 24; + +pub const SEM_FAILED: *mut ::sem_t = 0 as *mut sem_t; + +pub const RB_AUTOBOOT: ::c_int = 0x01234567u32 as i32; +pub const RB_HALT_SYSTEM: ::c_int = 0xcdef0123u32 as i32; +pub const RB_ENABLE_CAD: ::c_int = 0x89abcdefu32 as i32; +pub const RB_DISABLE_CAD: ::c_int = 0x00000000u32 as i32; +pub const RB_POWER_OFF: ::c_int = 0x4321fedcu32 as i32; +pub const RB_SW_SUSPEND: ::c_int = 0xd000fce2u32 as i32; +pub const RB_KEXEC: ::c_int = 0x45584543u32 as i32; + +pub const AI_PASSIVE: ::c_int = 0x0001; +pub const AI_CANONNAME: ::c_int = 0x0002; +pub const AI_NUMERICHOST: ::c_int = 0x0004; +pub const AI_V4MAPPED: ::c_int = 0x0008; +pub const AI_ALL: ::c_int = 0x0010; +pub const AI_ADDRCONFIG: ::c_int = 0x0020; + +pub const AI_NUMERICSERV: ::c_int = 0x0400; + +pub const EAI_BADFLAGS: ::c_int = -1; +pub const EAI_NONAME: ::c_int = -2; +pub const EAI_AGAIN: ::c_int = -3; +pub const EAI_FAIL: ::c_int = -4; +pub const EAI_FAMILY: ::c_int = -6; +pub const EAI_SOCKTYPE: ::c_int = -7; +pub const EAI_SERVICE: ::c_int = -8; +pub const EAI_MEMORY: ::c_int = -10; +pub const EAI_OVERFLOW: ::c_int = -12; + +pub const NI_NUMERICHOST: ::c_int = 1; +pub const NI_NUMERICSERV: ::c_int = 2; +pub const NI_NOFQDN: ::c_int = 4; +pub const NI_NAMEREQD: ::c_int = 8; +pub const NI_DGRAM: ::c_int = 16; + +pub const SYNC_FILE_RANGE_WAIT_BEFORE: ::c_uint = 1; +pub const SYNC_FILE_RANGE_WRITE: ::c_uint = 2; +pub const SYNC_FILE_RANGE_WAIT_AFTER: ::c_uint = 4; + +pub const EAI_SYSTEM: ::c_int = -11; + +pub const AIO_CANCELED: ::c_int = 0; +pub const AIO_NOTCANCELED: ::c_int = 1; +pub const AIO_ALLDONE: ::c_int = 2; +pub const LIO_READ: ::c_int = 0; +pub const LIO_WRITE: ::c_int = 1; +pub const LIO_NOP: ::c_int = 2; +pub const LIO_WAIT: ::c_int = 0; +pub const LIO_NOWAIT: ::c_int = 1; + +pub const MREMAP_MAYMOVE: ::c_int = 1; +pub const MREMAP_FIXED: ::c_int = 2; + +pub const PR_SET_PDEATHSIG: ::c_int = 1; +pub const PR_GET_PDEATHSIG: ::c_int = 2; + +pub const PR_GET_DUMPABLE: ::c_int = 3; +pub const PR_SET_DUMPABLE: ::c_int = 4; + +pub const PR_GET_UNALIGN: ::c_int = 5; +pub const PR_SET_UNALIGN: ::c_int = 6; +pub const PR_UNALIGN_NOPRINT: ::c_int = 1; +pub const PR_UNALIGN_SIGBUS: ::c_int = 2; + +pub const PR_GET_KEEPCAPS: ::c_int = 7; +pub const PR_SET_KEEPCAPS: ::c_int = 8; + +pub const PR_GET_FPEMU: ::c_int = 9; +pub const PR_SET_FPEMU: ::c_int = 10; +pub const PR_FPEMU_NOPRINT: ::c_int = 1; +pub const PR_FPEMU_SIGFPE: ::c_int = 2; + +pub const PR_GET_FPEXC: ::c_int = 11; +pub const PR_SET_FPEXC: ::c_int = 12; +pub const PR_FP_EXC_SW_ENABLE: ::c_int = 0x80; +pub const PR_FP_EXC_DIV: ::c_int = 0x010000; +pub const PR_FP_EXC_OVF: ::c_int = 0x020000; +pub const PR_FP_EXC_UND: ::c_int = 0x040000; +pub const PR_FP_EXC_RES: ::c_int = 0x080000; +pub const PR_FP_EXC_INV: ::c_int = 0x100000; +pub const PR_FP_EXC_DISABLED: ::c_int = 0; +pub const PR_FP_EXC_NONRECOV: ::c_int = 1; +pub const PR_FP_EXC_ASYNC: ::c_int = 2; +pub const PR_FP_EXC_PRECISE: ::c_int = 3; + +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; + +pub const PR_SET_NAME: ::c_int = 15; +pub const PR_GET_NAME: ::c_int = 16; + +pub const PR_GET_ENDIAN: ::c_int = 19; +pub const PR_SET_ENDIAN: ::c_int = 20; +pub const PR_ENDIAN_BIG: ::c_int = 0; +pub const PR_ENDIAN_LITTLE: ::c_int = 1; +pub const PR_ENDIAN_PPC_LITTLE: ::c_int = 2; + +pub const PR_GET_SECCOMP: ::c_int = 21; +pub const PR_SET_SECCOMP: ::c_int = 22; + +pub const PR_CAPBSET_READ: ::c_int = 23; +pub const PR_CAPBSET_DROP: ::c_int = 24; + +pub const PR_GET_TSC: ::c_int = 25; +pub const PR_SET_TSC: ::c_int = 26; +pub const PR_TSC_ENABLE: ::c_int = 1; +pub const PR_TSC_SIGSEGV: ::c_int = 2; + +pub const PR_GET_SECUREBITS: ::c_int = 27; +pub const PR_SET_SECUREBITS: ::c_int = 28; + +pub const PR_SET_TIMERSLACK: ::c_int = 29; +pub const PR_GET_TIMERSLACK: ::c_int = 30; + +pub const PR_TASK_PERF_EVENTS_DISABLE: ::c_int = 31; +pub const PR_TASK_PERF_EVENTS_ENABLE: ::c_int = 32; + +pub const PR_MCE_KILL: ::c_int = 33; +pub const PR_MCE_KILL_CLEAR: ::c_int = 0; +pub const PR_MCE_KILL_SET: ::c_int = 1; + +pub const PR_MCE_KILL_LATE: ::c_int = 0; +pub const PR_MCE_KILL_EARLY: ::c_int = 1; +pub const PR_MCE_KILL_DEFAULT: ::c_int = 2; + +pub const PR_MCE_KILL_GET: ::c_int = 34; + +pub const PR_SET_MM: ::c_int = 35; +pub const PR_SET_MM_START_CODE: ::c_int = 1; +pub const PR_SET_MM_END_CODE: ::c_int = 2; +pub const PR_SET_MM_START_DATA: ::c_int = 3; +pub const PR_SET_MM_END_DATA: ::c_int = 4; +pub const PR_SET_MM_START_STACK: ::c_int = 5; +pub const PR_SET_MM_START_BRK: ::c_int = 6; +pub const PR_SET_MM_BRK: ::c_int = 7; +pub const PR_SET_MM_ARG_START: ::c_int = 8; +pub const PR_SET_MM_ARG_END: ::c_int = 9; +pub const PR_SET_MM_ENV_START: ::c_int = 10; +pub const PR_SET_MM_ENV_END: ::c_int = 11; +pub const PR_SET_MM_AUXV: ::c_int = 12; +pub const PR_SET_MM_EXE_FILE: ::c_int = 13; +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; + +pub const PR_SET_NO_NEW_PRIVS: ::c_int = 38; +pub const PR_GET_NO_NEW_PRIVS: ::c_int = 39; + +pub const PR_GET_TID_ADDRESS: ::c_int = 40; + +pub const PR_SET_THP_DISABLE: ::c_int = 41; +pub const PR_GET_THP_DISABLE: ::c_int = 42; + +pub const PR_MPX_ENABLE_MANAGEMENT: ::c_int = 43; +pub const PR_MPX_DISABLE_MANAGEMENT: ::c_int = 44; + +pub const PR_SET_FP_MODE: ::c_int = 45; +pub const PR_GET_FP_MODE: ::c_int = 46; +pub const PR_FP_MODE_FR: ::c_int = 1 << 0; +pub const PR_FP_MODE_FRE: ::c_int = 1 << 1; + +pub const PR_CAP_AMBIENT: ::c_int = 47; +pub const PR_CAP_AMBIENT_IS_SET: ::c_int = 1; +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 ITIMER_REAL: ::c_int = 0; +pub const ITIMER_VIRTUAL: ::c_int = 1; +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 XATTR_CREATE: ::c_int = 0x1; +pub const XATTR_REPLACE: ::c_int = 0x2; + +pub const _POSIX_VDISABLE: ::cc_t = 0; + +pub const FALLOC_FL_KEEP_SIZE: ::c_int = 0x01; +pub const FALLOC_FL_PUNCH_HOLE: ::c_int = 0x02; +pub const FALLOC_FL_COLLAPSE_RANGE: ::c_int = 0x08; +pub const FALLOC_FL_ZERO_RANGE: ::c_int = 0x10; +pub const FALLOC_FL_INSERT_RANGE: ::c_int = 0x20; +pub const FALLOC_FL_UNSHARE_RANGE: ::c_int = 0x40; + +// On Linux, libc doesn't define this constant, libattr does instead. +// We still define it for Linux as it's defined by libc on other platforms, +// and it's mentioned in the man pages for getxattr and setxattr. +pub const ENOATTR: ::c_int = ::ENODATA; + +pub const SO_ORIGINAL_DST: ::c_int = 80; +pub const IUTF8: ::tcflag_t = 0x00004000; +pub const CMSPAR: ::tcflag_t = 0o10000000000; + +pub const MFD_CLOEXEC: ::c_uint = 0x0001; +pub const MFD_ALLOW_SEALING: ::c_uint = 0x0002; + +// 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; + +// Ethernet protocol IDs. +pub const ETH_P_LOOP: ::c_int = 0x0060; +pub const ETH_P_PUP: ::c_int = 0x0200; +pub const ETH_P_PUPAT: ::c_int = 0x0201; +pub const ETH_P_IP: ::c_int = 0x0800; +pub const ETH_P_X25: ::c_int = 0x0805; +pub const ETH_P_ARP: ::c_int = 0x0806; +pub const ETH_P_BPQ: ::c_int = 0x08FF; +pub const ETH_P_IEEEPUP: ::c_int = 0x0a00; +pub const ETH_P_IEEEPUPAT: ::c_int = 0x0a01; +pub const ETH_P_BATMAN: ::c_int = 0x4305; +pub const ETH_P_DEC: ::c_int = 0x6000; +pub const ETH_P_DNA_DL: ::c_int = 0x6001; +pub const ETH_P_DNA_RC: ::c_int = 0x6002; +pub const ETH_P_DNA_RT: ::c_int = 0x6003; +pub const ETH_P_LAT: ::c_int = 0x6004; +pub const ETH_P_DIAG: ::c_int = 0x6005; +pub const ETH_P_CUST: ::c_int = 0x6006; +pub const ETH_P_SCA: ::c_int = 0x6007; +pub const ETH_P_TEB: ::c_int = 0x6558; +pub const ETH_P_RARP: ::c_int = 0x8035; +pub const ETH_P_ATALK: ::c_int = 0x809B; +pub const ETH_P_AARP: ::c_int = 0x80F3; +pub const ETH_P_8021Q: ::c_int = 0x8100; +pub const ETH_P_IPX: ::c_int = 0x8137; +pub const ETH_P_IPV6: ::c_int = 0x86DD; +pub const ETH_P_PAUSE: ::c_int = 0x8808; +pub const ETH_P_SLOW: ::c_int = 0x8809; +pub const ETH_P_WCCP: ::c_int = 0x883E; +pub const ETH_P_MPLS_UC: ::c_int = 0x8847; +pub const ETH_P_MPLS_MC: ::c_int = 0x8848; +pub const ETH_P_ATMMPOA: ::c_int = 0x884c; +pub const ETH_P_PPP_DISC: ::c_int = 0x8863; +pub const ETH_P_PPP_SES: ::c_int = 0x8864; +pub const ETH_P_LINK_CTL: ::c_int = 0x886c; +pub const ETH_P_ATMFATE: ::c_int = 0x8884; +pub const ETH_P_PAE: ::c_int = 0x888E; +pub const ETH_P_AOE: ::c_int = 0x88A2; +pub const ETH_P_8021AD: ::c_int = 0x88A8; +pub const ETH_P_802_EX1: ::c_int = 0x88B5; +pub const ETH_P_TIPC: ::c_int = 0x88CA; +pub const ETH_P_8021AH: ::c_int = 0x88E7; +pub const ETH_P_MVRP: ::c_int = 0x88F5; +pub const ETH_P_1588: ::c_int = 0x88F7; +pub const ETH_P_PRP: ::c_int = 0x88FB; +pub const ETH_P_FCOE: ::c_int = 0x8906; +pub const ETH_P_TDLS: ::c_int = 0x890D; +pub const ETH_P_FIP: ::c_int = 0x8914; +pub const ETH_P_80221: ::c_int = 0x8917; +pub const ETH_P_LOOPBACK: ::c_int = 0x9000; +pub const ETH_P_QINQ1: ::c_int = 0x9100; +pub const ETH_P_QINQ2: ::c_int = 0x9200; +pub const ETH_P_QINQ3: ::c_int = 0x9300; +pub const ETH_P_EDSA: ::c_int = 0xDADA; +pub const ETH_P_AF_IUCV: ::c_int = 0xFBFB; + +pub const ETH_P_802_3_MIN: ::c_int = 0x0600; + +pub const ETH_P_802_3: ::c_int = 0x0001; +pub const ETH_P_AX25: ::c_int = 0x0002; +pub const ETH_P_ALL: ::c_int = 0x0003; +pub const ETH_P_802_2: ::c_int = 0x0004; +pub const ETH_P_SNAP: ::c_int = 0x0005; +pub const ETH_P_DDCMP: ::c_int = 0x0006; +pub const ETH_P_WAN_PPP: ::c_int = 0x0007; +pub const ETH_P_PPP_MP: ::c_int = 0x0008; +pub const ETH_P_LOCALTALK: ::c_int = 0x0009; +pub const ETH_P_CAN: ::c_int = 0x000C; +pub const ETH_P_CANFD: ::c_int = 0x000D; +pub const ETH_P_PPPTALK: ::c_int = 0x0010; +pub const ETH_P_TR_802_2: ::c_int = 0x0011; +pub const ETH_P_MOBITEX: ::c_int = 0x0015; +pub const ETH_P_CONTROL: ::c_int = 0x0016; +pub const ETH_P_IRDA: ::c_int = 0x0017; +pub const ETH_P_ECONET: ::c_int = 0x0018; +pub const ETH_P_HDLC: ::c_int = 0x0019; +pub const ETH_P_ARCNET: ::c_int = 0x001A; +pub const ETH_P_DSA: ::c_int = 0x001B; +pub const ETH_P_TRAILER: ::c_int = 0x001C; +pub const ETH_P_PHONET: ::c_int = 0x00F5; +pub const ETH_P_IEEE802154: ::c_int = 0x00F6; +pub const ETH_P_CAIF: ::c_int = 0x00F7; + +pub const SFD_CLOEXEC: ::c_int = 0x080000; + +pub const NCCS: usize = 32; + +pub const O_TRUNC: ::c_int = 0x00040000; +pub const O_NOATIME: ::c_int = 0x00002000; +pub const O_CLOEXEC: ::c_int = 0x00000100; +pub const O_TMPFILE: ::c_int = 0x00004000; + +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 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 EPOLL_CLOEXEC: ::c_int = 0x80000; + +pub const EFD_CLOEXEC: ::c_int = 0x80000; + +pub const BUFSIZ: ::c_uint = 1024; +pub const TMP_MAX: ::c_uint = 10000; +pub const FOPEN_MAX: ::c_uint = 1000; +pub const O_PATH: ::c_int = 0x00400000; +pub const O_EXEC: ::c_int = O_PATH; +pub const O_SEARCH: ::c_int = O_PATH; +pub const O_ACCMODE: ::c_int = 03 | O_SEARCH; +pub const O_NDELAY: ::c_int = O_NONBLOCK; +pub const NI_MAXHOST: ::socklen_t = 255; +pub const PTHREAD_STACK_MIN: ::size_t = 2048; +pub const POSIX_FADV_DONTNEED: ::c_int = 4; +pub const POSIX_FADV_NOREUSE: ::c_int = 5; + +pub const POSIX_MADV_DONTNEED: ::c_int = 4; + +pub const RLIM_INFINITY: ::rlim_t = !0; +pub const RLIMIT_RTTIME: ::c_int = 15; +#[deprecated(since = "0.2.64", note = "Not stable across OS versions")] +pub const RLIMIT_NLIMITS: ::c_int = 16; +#[allow(deprecated)] +#[deprecated(since = "0.2.64", note = "Not stable across OS versions")] +pub const RLIM_NLIMITS: ::c_int = RLIMIT_NLIMITS; + +pub const MAP_ANONYMOUS: ::c_int = MAP_ANON; + +pub const SOCK_DCCP: ::c_int = 6; +pub const SOCK_PACKET: ::c_int = 10; + +pub const TCP_COOKIE_TRANSACTIONS: ::c_int = 15; +pub const TCP_THIN_LINEAR_TIMEOUTS: ::c_int = 16; +pub const TCP_THIN_DUPACK: ::c_int = 17; +pub const TCP_USER_TIMEOUT: ::c_int = 18; +pub const TCP_REPAIR: ::c_int = 19; +pub const TCP_REPAIR_QUEUE: ::c_int = 20; +pub const TCP_QUEUE_SEQ: ::c_int = 21; +pub const TCP_REPAIR_OPTIONS: ::c_int = 22; +pub const TCP_FASTOPEN: ::c_int = 23; +pub const TCP_TIMESTAMP: ::c_int = 24; + +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 CPU_SETSIZE: ::c_int = 128; + +pub const PTRACE_TRACEME: ::c_int = 0; +pub const PTRACE_PEEKTEXT: ::c_int = 1; +pub const PTRACE_PEEKDATA: ::c_int = 2; +pub const PTRACE_PEEKUSER: ::c_int = 3; +pub const PTRACE_POKETEXT: ::c_int = 4; +pub const PTRACE_POKEDATA: ::c_int = 5; +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_GETFPREGS: ::c_int = 14; +pub const PTRACE_SETFPREGS: ::c_int = 15; +pub const PTRACE_ATTACH: ::c_int = 16; +pub const PTRACE_DETACH: ::c_int = 17; +pub const PTRACE_GETFPXREGS: ::c_int = 18; +pub const PTRACE_SETFPXREGS: ::c_int = 19; +pub const PTRACE_SYSCALL: ::c_int = 24; +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_SEIZE: ::c_int = 0x4206; +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 EFD_NONBLOCK: ::c_int = ::O_NONBLOCK; + +pub const SFD_NONBLOCK: ::c_int = ::O_NONBLOCK; + +pub const TCSANOW: ::c_int = 0; +pub const TCSADRAIN: ::c_int = 1; +pub const TCSAFLUSH: ::c_int = 2; + +pub const TIOCINQ: ::c_int = ::FIONREAD; + +pub const RTLD_GLOBAL: ::c_int = 0x100; +pub const RTLD_NOLOAD: ::c_int = 0x4; + +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 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 SO_BINDTODEVICE: ::c_int = 25; +pub const SO_TIMESTAMP: ::c_int = 29; +pub const SO_MARK: ::c_int = 36; +pub const SO_RXQ_OVFL: ::c_int = 40; +pub const SO_PEEK_OFF: ::c_int = 42; +pub const SO_BUSY_POLL: ::c_int = 46; +pub const SO_BINDTOIFINDEX: ::c_int = 62; + +pub const __SIZEOF_PTHREAD_RWLOCK_T: usize = 56; +pub const __SIZEOF_PTHREAD_MUTEX_T: usize = 40; + +pub const O_ASYNC: ::c_int = 0x00000400; + +pub const FIOCLEX: ::c_int = 0x5451; +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 O_APPEND: ::c_int = 0x00100000; +pub const O_CREAT: ::c_int = 0x00010000; +pub const O_EXCL: ::c_int = 0x00020000; +pub const O_NOCTTY: ::c_int = 0x00000200; +pub const O_NONBLOCK: ::c_int = 0x00000010; +pub const O_SYNC: ::c_int = 0x00000040 | O_DSYNC; +pub const O_RSYNC: ::c_int = O_SYNC; +pub const O_DSYNC: ::c_int = 0x00000020; + +pub const SOCK_CLOEXEC: ::c_int = 0o2000000; +pub const SOCK_NONBLOCK: ::c_int = 0o4000; + +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 SOCK_STREAM: ::c_int = 1; +pub const SOCK_DGRAM: ::c_int = 2; +pub const SOCK_SEQPACKET: ::c_int = 5; + +pub const SOL_SOCKET: ::c_int = 1; + +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 EDEADLOCK: ::c_int = EDEADLK; +pub const EMULTIHOP: ::c_int = 72; +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 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 ERFKILL: ::c_int = 132; +pub const EHWPOISON: ::c_int = 133; + +pub const SO_REUSEADDR: ::c_int = 2; +pub const SO_TYPE: ::c_int = 3; +pub const SO_ERROR: ::c_int = 4; +pub const SO_DONTROUTE: ::c_int = 5; +pub const SO_BROADCAST: ::c_int = 6; +pub const SO_SNDBUF: ::c_int = 7; +pub const SO_RCVBUF: ::c_int = 8; +pub const SO_KEEPALIVE: ::c_int = 9; +pub const SO_OOBINLINE: ::c_int = 10; +pub const SO_NO_CHECK: ::c_int = 11; +pub const SO_PRIORITY: ::c_int = 12; +pub const SO_LINGER: ::c_int = 13; +pub const SO_BSDCOMPAT: ::c_int = 14; +pub const SO_REUSEPORT: ::c_int = 15; +pub const SO_PASSCRED: ::c_int = 16; +pub const SO_PEERCRED: ::c_int = 17; +pub const SO_RCVLOWAT: ::c_int = 18; +pub const SO_SNDLOWAT: ::c_int = 19; +pub const SO_RCVTIMEO: ::c_int = 20; +pub const SO_SNDTIMEO: ::c_int = 21; +pub const SO_ACCEPTCONN: ::c_int = 30; +pub const SO_SNDBUFFORCE: ::c_int = 32; +pub const SO_RCVBUFFORCE: ::c_int = 33; +pub const SO_PROTOCOL: ::c_int = 38; +pub const SO_DOMAIN: ::c_int = 39; + +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 EXTPROC: ::tcflag_t = 0x00010000; + +pub const MAP_HUGETLB: ::c_int = 0x040000; + +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 VEOF: usize = 4; +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 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 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; + +pub const O_DIRECTORY: ::c_int = 0x00080000; +pub const O_DIRECT: ::c_int = 0x00000800; +pub const O_LARGEFILE: ::c_int = 0x00001000; +pub const O_NOFOLLOW: ::c_int = 0x00000080; + +pub const HUGETLB_FLAG_ENCODE_SHIFT: u32 = 26; +pub const MAP_HUGE_SHIFT: u32 = 26; + +// 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 + } +} + +// END_PUB_CONST + +f! { + pub fn FD_CLR(fd: ::c_int, set: *mut fd_set) -> () { + let fd = fd as usize; + let size = ::mem::size_of_val(&(*set).fds_bits[0]) * 8; + (*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 CPU_ZERO(cpuset: &mut cpu_set_t) -> () { + for slot in cpuset.bits.iter_mut() { + *slot = 0; + } + } + + pub fn CPU_SET(cpu: usize, cpuset: &mut cpu_set_t) -> () { + let size_in_bits + = 8 * ::mem::size_of_val(&cpuset.bits[0]); // 32, 64 etc + let (idx, offset) = (cpu / size_in_bits, cpu % size_in_bits); + cpuset.bits[idx] |= 1 << offset; + () + } + + pub fn CPU_CLR(cpu: usize, cpuset: &mut cpu_set_t) -> () { + let size_in_bits + = 8 * ::mem::size_of_val(&cpuset.bits[0]); // 32, 64 etc + let (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); + 0 != (cpuset.bits[idx] & (1 << offset)) + } + + pub fn CPU_EQUAL(set1: &cpu_set_t, set2: &cpu_set_t) -> bool { + set1.bits == set2.bits + } + + pub fn major(dev: ::dev_t) -> ::c_uint { + let mut major = 0; + major |= (dev & 0x00000000000fff00) >> 8; + major |= (dev & 0xfffff00000000000) >> 32; + major as ::c_uint + } + + pub fn minor(dev: ::dev_t) -> ::c_uint { + let mut minor = 0; + minor |= (dev & 0x00000000000000ff) >> 0; + minor |= (dev & 0x00000ffffff00000) >> 12; + minor as ::c_uint + } + + pub fn CMSG_DATA(cmsg: *const cmsghdr) -> *mut c_uchar { + cmsg.offset(1) as *mut c_uchar + } + + pub fn CMSG_NXTHDR(mhdr: *const msghdr, cmsg: *const cmsghdr) + -> *mut cmsghdr + { + if ((*cmsg).cmsg_len as ::size_t) < ::mem::size_of::() { + 0 as *mut cmsghdr + } else if __CMSG_NEXT(cmsg).add(::mem::size_of::()) + >= __MHDR_END(mhdr) { + 0 as *mut cmsghdr + } else { + __CMSG_NEXT(cmsg).cast() + } + } + + pub fn CMSG_FIRSTHDR(mhdr: *const msghdr) -> *mut cmsghdr { + if (*mhdr).msg_controllen as ::size_t >= ::mem::size_of::() { + (*mhdr).msg_control.cast() + } else { + 0 as *mut cmsghdr + } + } + + pub {const} fn CMSG_ALIGN(len: ::size_t) -> ::size_t { + (len + ::mem::size_of::<::size_t>() - 1) + & !(::mem::size_of::<::size_t>() - 1) + } + + pub {const} fn CMSG_SPACE(len: ::c_uint) -> ::c_uint { + (CMSG_ALIGN(len as ::size_t) + CMSG_ALIGN(::mem::size_of::())) + as ::c_uint + } + + pub {const} fn CMSG_LEN(len: ::c_uint) -> ::c_uint { + (CMSG_ALIGN(::mem::size_of::()) + len as ::size_t) as ::c_uint + } +} + +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 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 { + ((unsafe { (*cmsg).cmsg_len as ::size_t } + ::mem::size_of::<::c_long>() - 1) + & !(::mem::size_of::<::c_long>() - 1)) as ::ssize_t +} + +fn __CMSG_NEXT(cmsg: *const cmsghdr) -> *mut c_uchar { + (unsafe { cmsg.offset(__CMSG_LEN(cmsg)) }) as *mut c_uchar +} + +fn __MHDR_END(mhdr: *const msghdr) -> *mut c_uchar { + unsafe { (*mhdr).msg_control.offset((*mhdr).msg_controllen as isize) }.cast() +} + +// EXTERN_FN + +#[link(name = "c")] +#[link(name = "fdio")] +extern "C" {} + +#[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 {} // FIXME: fill this out with a struct +impl ::Copy for fpos_t {} +impl ::Clone for fpos_t { + fn clone(&self) -> fpos_t { + *self + } +} + +extern "C" { + 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; + pub fn fopen(filename: *const c_char, mode: *const c_char) -> *mut FILE; + pub fn freopen(filename: *const c_char, mode: *const c_char, file: *mut FILE) -> *mut FILE; + pub fn fflush(file: *mut FILE) -> c_int; + pub fn fclose(file: *mut FILE) -> c_int; + pub fn remove(filename: *const c_char) -> c_int; + pub fn rename(oldname: *const c_char, newname: *const c_char) -> c_int; + pub fn tmpfile() -> *mut FILE; + 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 getchar() -> c_int; + pub fn putchar(c: c_int) -> c_int; + pub fn fgetc(stream: *mut FILE) -> c_int; + pub fn fgets(buf: *mut c_char, n: c_int, stream: *mut FILE) -> *mut c_char; + pub fn fputc(c: c_int, stream: *mut FILE) -> c_int; + pub fn fputs(s: *const c_char, stream: *mut FILE) -> c_int; + pub fn puts(s: *const c_char) -> c_int; + pub fn ungetc(c: c_int, stream: *mut FILE) -> c_int; + pub fn fread(ptr: *mut c_void, size: size_t, nobj: size_t, stream: *mut FILE) -> size_t; + pub fn fwrite(ptr: *const c_void, size: size_t, nobj: size_t, stream: *mut FILE) -> size_t; + pub fn fseek(stream: *mut FILE, offset: c_long, whence: c_int) -> c_int; + pub fn ftell(stream: *mut FILE) -> c_long; + pub fn rewind(stream: *mut FILE); + pub fn fgetpos(stream: *mut FILE, ptr: *mut fpos_t) -> c_int; + pub fn fsetpos(stream: *mut FILE, ptr: *const fpos_t) -> c_int; + 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; + pub fn free(p: *mut c_void); + pub fn abort() -> !; + pub fn exit(status: c_int) -> !; + pub fn _exit(status: c_int) -> !; + pub fn atexit(cb: extern "C" fn()) -> c_int; + pub fn system(s: *const c_char) -> c_int; + pub fn getenv(s: *const c_char) -> *mut c_char; + + 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 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; + pub fn strncmp(cs: *const c_char, ct: *const c_char, n: size_t) -> c_int; + pub fn strcoll(cs: *const c_char, ct: *const c_char) -> c_int; + pub fn strchr(cs: *const c_char, c: c_int) -> *mut c_char; + pub fn strrchr(cs: *const c_char, c: c_int) -> *mut c_char; + pub fn strspn(cs: *const c_char, ct: *const c_char) -> size_t; + pub fn strcspn(cs: *const c_char, ct: *const c_char) -> size_t; + pub fn strdup(cs: *const c_char) -> *mut c_char; + pub fn strpbrk(cs: *const c_char, ct: *const c_char) -> *mut c_char; + pub fn strstr(cs: *const c_char, ct: *const c_char) -> *mut c_char; + pub fn strlen(cs: *const c_char) -> size_t; + pub fn strnlen(cs: *const c_char, maxlen: size_t) -> size_t; + 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 strxfrm(s: *mut c_char, ct: *const c_char, n: size_t) -> size_t; + pub fn wcslen(buf: *const wchar_t) -> size_t; + pub fn wcstombs(dest: *mut c_char, src: *const wchar_t, n: size_t) -> ::size_t; + + pub fn memchr(cx: *const c_void, c: c_int, n: size_t) -> *mut c_void; + pub fn wmemchr(cx: *const wchar_t, c: wchar_t, n: size_t) -> *mut wchar_t; + pub fn memcmp(cx: *const c_void, ct: *const c_void, n: size_t) -> c_int; + pub fn memcpy(dest: *mut c_void, src: *const c_void, n: size_t) -> *mut c_void; + pub fn memmove(dest: *mut c_void, src: *const c_void, n: size_t) -> *mut c_void; + 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 labs(i: c_long) -> c_long; + pub fn rand() -> c_int; + pub fn srand(seed: c_uint); + + pub fn getpwnam(name: *const ::c_char) -> *mut passwd; + pub fn getpwuid(uid: ::uid_t) -> *mut passwd; + + pub fn fprintf(stream: *mut ::FILE, format: *const ::c_char, ...) -> ::c_int; + pub fn printf(format: *const ::c_char, ...) -> ::c_int; + pub fn snprintf(s: *mut ::c_char, n: ::size_t, format: *const ::c_char, ...) -> ::c_int; + pub fn sprintf(s: *mut ::c_char, format: *const ::c_char, ...) -> ::c_int; + pub fn fscanf(stream: *mut ::FILE, format: *const ::c_char, ...) -> ::c_int; + pub fn scanf(format: *const ::c_char, ...) -> ::c_int; + pub fn sscanf(s: *const ::c_char, format: *const ::c_char, ...) -> ::c_int; + pub fn getchar_unlocked() -> ::c_int; + pub fn putchar_unlocked(c: ::c_int) -> ::c_int; + + pub fn socket(domain: ::c_int, ty: ::c_int, protocol: ::c_int) -> ::c_int; + pub fn connect(socket: ::c_int, address: *const sockaddr, len: socklen_t) -> ::c_int; + pub fn listen(socket: ::c_int, backlog: ::c_int) -> ::c_int; + pub fn accept(socket: ::c_int, address: *mut sockaddr, address_len: *mut socklen_t) -> ::c_int; + pub fn getpeername( + socket: ::c_int, + address: *mut sockaddr, + address_len: *mut socklen_t, + ) -> ::c_int; + pub fn getsockname( + socket: ::c_int, + address: *mut sockaddr, + address_len: *mut socklen_t, + ) -> ::c_int; + pub fn setsockopt( + socket: ::c_int, + level: ::c_int, + name: ::c_int, + value: *const ::c_void, + option_len: socklen_t, + ) -> ::c_int; + pub fn socketpair( + domain: ::c_int, + type_: ::c_int, + protocol: ::c_int, + socket_vector: *mut ::c_int, + ) -> ::c_int; + pub fn sendto( + socket: ::c_int, + buf: *const ::c_void, + len: ::size_t, + flags: ::c_int, + addr: *const sockaddr, + addrlen: socklen_t, + ) -> ::ssize_t; + pub fn shutdown(socket: ::c_int, how: ::c_int) -> ::c_int; + + pub fn chmod(path: *const c_char, mode: mode_t) -> ::c_int; + pub fn fchmod(fd: ::c_int, mode: mode_t) -> ::c_int; + + pub fn fstat(fildes: ::c_int, buf: *mut stat) -> ::c_int; + + pub fn mkdir(path: *const c_char, mode: mode_t) -> ::c_int; + + pub fn stat(path: *const c_char, buf: *mut stat) -> ::c_int; + + pub fn pclose(stream: *mut ::FILE) -> ::c_int; + pub fn fdopen(fd: ::c_int, mode: *const c_char) -> *mut ::FILE; + pub fn fileno(stream: *mut ::FILE) -> ::c_int; + + pub fn open(path: *const c_char, oflag: ::c_int, ...) -> ::c_int; + pub fn creat(path: *const c_char, mode: mode_t) -> ::c_int; + pub fn fcntl(fd: ::c_int, cmd: ::c_int, ...) -> ::c_int; + + pub fn opendir(dirname: *const c_char) -> *mut ::DIR; + pub fn readdir(dirp: *mut ::DIR) -> *mut ::dirent; + pub fn readdir_r(dirp: *mut ::DIR, entry: *mut ::dirent, result: *mut *mut ::dirent) + -> ::c_int; + pub fn closedir(dirp: *mut ::DIR) -> ::c_int; + pub fn rewinddir(dirp: *mut ::DIR); + + pub fn openat(dirfd: ::c_int, pathname: *const ::c_char, flags: ::c_int, ...) -> ::c_int; + pub fn fchmodat( + dirfd: ::c_int, + pathname: *const ::c_char, + mode: ::mode_t, + flags: ::c_int, + ) -> ::c_int; + pub fn fchown(fd: ::c_int, owner: ::uid_t, group: ::gid_t) -> ::c_int; + pub fn fchownat( + dirfd: ::c_int, + pathname: *const ::c_char, + owner: ::uid_t, + group: ::gid_t, + flags: ::c_int, + ) -> ::c_int; + pub fn fstatat( + dirfd: ::c_int, + pathname: *const ::c_char, + buf: *mut stat, + flags: ::c_int, + ) -> ::c_int; + pub fn linkat( + olddirfd: ::c_int, + oldpath: *const ::c_char, + newdirfd: ::c_int, + newpath: *const ::c_char, + flags: ::c_int, + ) -> ::c_int; + pub fn mkdirat(dirfd: ::c_int, pathname: *const ::c_char, mode: ::mode_t) -> ::c_int; + pub fn readlinkat( + dirfd: ::c_int, + pathname: *const ::c_char, + buf: *mut ::c_char, + bufsiz: ::size_t, + ) -> ::ssize_t; + pub fn renameat( + olddirfd: ::c_int, + oldpath: *const ::c_char, + newdirfd: ::c_int, + newpath: *const ::c_char, + ) -> ::c_int; + pub fn symlinkat( + target: *const ::c_char, + newdirfd: ::c_int, + linkpath: *const ::c_char, + ) -> ::c_int; + pub fn unlinkat(dirfd: ::c_int, pathname: *const ::c_char, flags: ::c_int) -> ::c_int; + + pub fn access(path: *const c_char, amode: ::c_int) -> ::c_int; + pub fn alarm(seconds: ::c_uint) -> ::c_uint; + pub fn chdir(dir: *const c_char) -> ::c_int; + pub fn chown(path: *const c_char, uid: uid_t, gid: gid_t) -> ::c_int; + pub fn lchown(path: *const c_char, uid: uid_t, gid: gid_t) -> ::c_int; + pub fn close(fd: ::c_int) -> ::c_int; + pub fn dup(fd: ::c_int) -> ::c_int; + pub fn dup2(src: ::c_int, dst: ::c_int) -> ::c_int; + pub fn execl(path: *const c_char, arg0: *const c_char, ...) -> ::c_int; + pub fn execle(path: *const ::c_char, arg0: *const ::c_char, ...) -> ::c_int; + pub fn execlp(file: *const ::c_char, arg0: *const ::c_char, ...) -> ::c_int; + pub fn execv(prog: *const c_char, argv: *const *const c_char) -> ::c_int; + pub fn execve( + prog: *const c_char, + argv: *const *const c_char, + envp: *const *const c_char, + ) -> ::c_int; + pub fn execvp(c: *const c_char, argv: *const *const c_char) -> ::c_int; + pub fn fork() -> pid_t; + pub fn fpathconf(filedes: ::c_int, name: ::c_int) -> c_long; + pub fn getcwd(buf: *mut c_char, size: ::size_t) -> *mut c_char; + pub fn getegid() -> gid_t; + pub fn geteuid() -> uid_t; + pub fn getgid() -> gid_t; + pub fn getgroups(ngroups_max: ::c_int, groups: *mut gid_t) -> ::c_int; + pub fn getlogin() -> *mut c_char; + pub fn getopt(argc: ::c_int, argv: *const *mut c_char, optstr: *const c_char) -> ::c_int; + pub fn getpgid(pid: pid_t) -> pid_t; + pub fn getpgrp() -> pid_t; + pub fn getpid() -> pid_t; + pub fn getppid() -> pid_t; + pub fn getuid() -> uid_t; + pub fn isatty(fd: ::c_int) -> ::c_int; + pub fn link(src: *const c_char, dst: *const c_char) -> ::c_int; + pub fn lseek(fd: ::c_int, offset: off_t, whence: ::c_int) -> off_t; + pub fn pathconf(path: *const c_char, name: ::c_int) -> c_long; + pub fn pause() -> ::c_int; + pub fn pipe(fds: *mut ::c_int) -> ::c_int; + pub fn posix_memalign(memptr: *mut *mut ::c_void, align: ::size_t, size: ::size_t) -> ::c_int; + pub fn read(fd: ::c_int, buf: *mut ::c_void, count: ::size_t) -> ::ssize_t; + pub fn rmdir(path: *const c_char) -> ::c_int; + pub fn seteuid(uid: uid_t) -> ::c_int; + pub fn setegid(gid: gid_t) -> ::c_int; + pub fn setgid(gid: gid_t) -> ::c_int; + 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 sleep(secs: ::c_uint) -> ::c_uint; + pub fn nanosleep(rqtp: *const timespec, rmtp: *mut timespec) -> ::c_int; + pub fn tcgetpgrp(fd: ::c_int) -> pid_t; + pub fn tcsetpgrp(fd: ::c_int, pgrp: ::pid_t) -> ::c_int; + pub fn ttyname(fd: ::c_int) -> *mut c_char; + pub fn unlink(c: *const c_char) -> ::c_int; + pub fn wait(status: *mut ::c_int) -> pid_t; + pub fn waitpid(pid: pid_t, status: *mut ::c_int, options: ::c_int) -> pid_t; + pub fn write(fd: ::c_int, buf: *const ::c_void, count: ::size_t) -> ::ssize_t; + pub fn pread(fd: ::c_int, buf: *mut ::c_void, count: ::size_t, offset: off_t) -> ::ssize_t; + pub fn pwrite(fd: ::c_int, buf: *const ::c_void, count: ::size_t, offset: off_t) -> ::ssize_t; + pub fn umask(mask: mode_t) -> mode_t; + + pub fn utime(file: *const c_char, buf: *const utimbuf) -> ::c_int; + + pub fn kill(pid: pid_t, sig: ::c_int) -> ::c_int; + + pub fn mlock(addr: *const ::c_void, len: ::size_t) -> ::c_int; + pub fn munlock(addr: *const ::c_void, len: ::size_t) -> ::c_int; + pub fn mlockall(flags: ::c_int) -> ::c_int; + pub fn munlockall() -> ::c_int; + + pub fn mmap( + addr: *mut ::c_void, + len: ::size_t, + prot: ::c_int, + flags: ::c_int, + fd: ::c_int, + offset: off_t, + ) -> *mut ::c_void; + pub fn munmap(addr: *mut ::c_void, len: ::size_t) -> ::c_int; + + pub fn if_nametoindex(ifname: *const c_char) -> ::c_uint; + pub fn if_indextoname(ifindex: ::c_uint, ifname: *mut ::c_char) -> *mut ::c_char; + + pub fn lstat(path: *const c_char, buf: *mut stat) -> ::c_int; + + pub fn fsync(fd: ::c_int) -> ::c_int; + + pub fn setenv(name: *const c_char, val: *const c_char, overwrite: ::c_int) -> ::c_int; + pub fn unsetenv(name: *const c_char) -> ::c_int; + + pub fn symlink(path1: *const c_char, path2: *const c_char) -> ::c_int; + + pub fn ftruncate(fd: ::c_int, length: off_t) -> ::c_int; + + pub fn signal(signum: ::c_int, handler: sighandler_t) -> sighandler_t; + + pub fn realpath(pathname: *const ::c_char, resolved: *mut ::c_char) -> *mut ::c_char; + + pub fn flock(fd: ::c_int, operation: ::c_int) -> ::c_int; + + pub fn gettimeofday(tp: *mut ::timeval, tz: *mut ::c_void) -> ::c_int; + pub fn times(buf: *mut ::tms) -> ::clock_t; + + pub fn pthread_self() -> ::pthread_t; + pub fn pthread_join(native: ::pthread_t, value: *mut *mut ::c_void) -> ::c_int; + pub fn pthread_exit(value: *mut ::c_void) -> !; + pub fn pthread_attr_init(attr: *mut ::pthread_attr_t) -> ::c_int; + pub fn pthread_attr_destroy(attr: *mut ::pthread_attr_t) -> ::c_int; + pub fn pthread_attr_getstacksize( + attr: *const ::pthread_attr_t, + stacksize: *mut ::size_t, + ) -> ::c_int; + pub fn pthread_attr_setstacksize(attr: *mut ::pthread_attr_t, stack_size: ::size_t) -> ::c_int; + pub fn pthread_attr_setdetachstate(attr: *mut ::pthread_attr_t, state: ::c_int) -> ::c_int; + pub fn pthread_detach(thread: ::pthread_t) -> ::c_int; + pub fn sched_yield() -> ::c_int; + pub fn pthread_key_create( + key: *mut pthread_key_t, + dtor: ::Option, + ) -> ::c_int; + pub fn pthread_key_delete(key: pthread_key_t) -> ::c_int; + pub fn pthread_getspecific(key: pthread_key_t) -> *mut ::c_void; + pub fn pthread_setspecific(key: pthread_key_t, value: *const ::c_void) -> ::c_int; + pub fn pthread_mutex_init( + lock: *mut pthread_mutex_t, + attr: *const pthread_mutexattr_t, + ) -> ::c_int; + pub fn pthread_mutex_destroy(lock: *mut pthread_mutex_t) -> ::c_int; + pub fn pthread_mutex_lock(lock: *mut pthread_mutex_t) -> ::c_int; + pub fn pthread_mutex_trylock(lock: *mut pthread_mutex_t) -> ::c_int; + pub fn pthread_mutex_unlock(lock: *mut pthread_mutex_t) -> ::c_int; + + pub fn pthread_mutexattr_init(attr: *mut pthread_mutexattr_t) -> ::c_int; + pub fn pthread_mutexattr_destroy(attr: *mut pthread_mutexattr_t) -> ::c_int; + pub fn pthread_mutexattr_settype(attr: *mut pthread_mutexattr_t, _type: ::c_int) -> ::c_int; + + pub fn pthread_cond_init(cond: *mut pthread_cond_t, attr: *const pthread_condattr_t) + -> ::c_int; + pub fn pthread_cond_wait(cond: *mut pthread_cond_t, lock: *mut pthread_mutex_t) -> ::c_int; + pub fn pthread_cond_timedwait( + cond: *mut pthread_cond_t, + lock: *mut pthread_mutex_t, + abstime: *const ::timespec, + ) -> ::c_int; + pub fn pthread_cond_signal(cond: *mut pthread_cond_t) -> ::c_int; + pub fn pthread_cond_broadcast(cond: *mut pthread_cond_t) -> ::c_int; + pub fn pthread_cond_destroy(cond: *mut pthread_cond_t) -> ::c_int; + pub fn pthread_condattr_init(attr: *mut pthread_condattr_t) -> ::c_int; + pub fn pthread_condattr_destroy(attr: *mut pthread_condattr_t) -> ::c_int; + pub fn pthread_rwlock_init( + lock: *mut pthread_rwlock_t, + attr: *const pthread_rwlockattr_t, + ) -> ::c_int; + pub fn pthread_rwlock_destroy(lock: *mut pthread_rwlock_t) -> ::c_int; + pub fn pthread_rwlock_rdlock(lock: *mut pthread_rwlock_t) -> ::c_int; + pub fn pthread_rwlock_tryrdlock(lock: *mut pthread_rwlock_t) -> ::c_int; + pub fn pthread_rwlock_wrlock(lock: *mut pthread_rwlock_t) -> ::c_int; + pub fn pthread_rwlock_trywrlock(lock: *mut pthread_rwlock_t) -> ::c_int; + pub fn pthread_rwlock_unlock(lock: *mut pthread_rwlock_t) -> ::c_int; + pub fn pthread_rwlockattr_init(attr: *mut pthread_rwlockattr_t) -> ::c_int; + pub fn pthread_rwlockattr_destroy(attr: *mut pthread_rwlockattr_t) -> ::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 strerror_r(errnum: ::c_int, buf: *mut c_char, buflen: ::size_t) -> ::c_int; + + pub fn getsockopt( + sockfd: ::c_int, + level: ::c_int, + optname: ::c_int, + optval: *mut ::c_void, + optlen: *mut ::socklen_t, + ) -> ::c_int; + pub fn raise(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; + pub fn dlopen(filename: *const ::c_char, flag: ::c_int) -> *mut ::c_void; + 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; + + pub fn getaddrinfo( + node: *const c_char, + service: *const c_char, + hints: *const addrinfo, + res: *mut *mut addrinfo, + ) -> ::c_int; + pub fn freeaddrinfo(res: *mut addrinfo); + pub fn gai_strerror(errcode: ::c_int) -> *const ::c_char; + pub fn res_init() -> ::c_int; + + pub fn gmtime_r(time_p: *const time_t, result: *mut tm) -> *mut tm; + pub fn localtime_r(time_p: *const time_t, result: *mut tm) -> *mut tm; + pub fn mktime(tm: *mut tm) -> time_t; + pub fn time(time: *mut time_t) -> time_t; + pub fn gmtime(time_p: *const time_t) -> *mut tm; + pub fn localtime(time_p: *const time_t) -> *mut tm; + + pub fn mknod(pathname: *const ::c_char, mode: ::mode_t, dev: ::dev_t) -> ::c_int; + pub fn uname(buf: *mut ::utsname) -> ::c_int; + pub fn gethostname(name: *mut ::c_char, len: ::size_t) -> ::c_int; + pub fn getservbyname(name: *const ::c_char, proto: *const ::c_char) -> *mut servent; + pub fn getprotobyname(name: *const ::c_char) -> *mut protoent; + pub fn getprotobynumber(proto: ::c_int) -> *mut protoent; + pub fn usleep(secs: ::c_uint) -> ::c_int; + pub fn send(socket: ::c_int, buf: *const ::c_void, len: ::size_t, flags: ::c_int) -> ::ssize_t; + pub fn recv(socket: ::c_int, buf: *mut ::c_void, len: ::size_t, flags: ::c_int) -> ::ssize_t; + pub fn putenv(string: *mut c_char) -> ::c_int; + pub fn poll(fds: *mut pollfd, nfds: nfds_t, timeout: ::c_int) -> ::c_int; + pub fn select( + nfds: ::c_int, + readfds: *mut fd_set, + writefds: *mut fd_set, + errorfds: *mut fd_set, + timeout: *mut timeval, + ) -> ::c_int; + pub fn setlocale(category: ::c_int, locale: *const ::c_char) -> *mut ::c_char; + pub fn localeconv() -> *mut lconv; + + pub fn sem_destroy(sem: *mut sem_t) -> ::c_int; + pub fn sem_wait(sem: *mut sem_t) -> ::c_int; + pub fn sem_trywait(sem: *mut sem_t) -> ::c_int; + pub fn sem_post(sem: *mut sem_t) -> ::c_int; + pub fn sem_init(sem: *mut sem_t, pshared: ::c_int, value: ::c_uint) -> ::c_int; + pub fn statvfs(path: *const c_char, buf: *mut statvfs) -> ::c_int; + pub fn fstatvfs(fd: ::c_int, buf: *mut statvfs) -> ::c_int; + + pub fn readlink(path: *const c_char, buf: *mut c_char, bufsz: ::size_t) -> ::ssize_t; + + pub fn sigemptyset(set: *mut sigset_t) -> ::c_int; + pub fn sigaddset(set: *mut sigset_t, signum: ::c_int) -> ::c_int; + pub fn sigfillset(set: *mut sigset_t) -> ::c_int; + pub fn sigdelset(set: *mut sigset_t, signum: ::c_int) -> ::c_int; + pub fn sigismember(set: *const sigset_t, signum: ::c_int) -> ::c_int; + + pub fn sigprocmask(how: ::c_int, set: *const sigset_t, oldset: *mut sigset_t) -> ::c_int; + pub fn sigpending(set: *mut sigset_t) -> ::c_int; + + pub fn timegm(tm: *mut ::tm) -> time_t; + + pub fn getsid(pid: pid_t) -> pid_t; + + pub fn sysconf(name: ::c_int) -> ::c_long; + + pub fn mkfifo(path: *const c_char, mode: mode_t) -> ::c_int; + + 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; + pub fn fseeko(stream: *mut ::FILE, offset: ::off_t, whence: ::c_int) -> ::c_int; + pub fn ftello(stream: *mut ::FILE) -> ::off_t; + pub fn tcdrain(fd: ::c_int) -> ::c_int; + pub fn cfgetispeed(termios: *const ::termios) -> ::speed_t; + pub fn cfgetospeed(termios: *const ::termios) -> ::speed_t; + pub fn cfmakeraw(termios: *mut ::termios); + pub fn cfsetispeed(termios: *mut ::termios, speed: ::speed_t) -> ::c_int; + pub fn cfsetospeed(termios: *mut ::termios, speed: ::speed_t) -> ::c_int; + pub fn cfsetspeed(termios: *mut ::termios, speed: ::speed_t) -> ::c_int; + pub fn tcgetattr(fd: ::c_int, termios: *mut ::termios) -> ::c_int; + pub fn tcsetattr(fd: ::c_int, optional_actions: ::c_int, termios: *const ::termios) -> ::c_int; + pub fn tcflow(fd: ::c_int, action: ::c_int) -> ::c_int; + pub fn tcflush(fd: ::c_int, action: ::c_int) -> ::c_int; + pub fn tcgetsid(fd: ::c_int) -> ::pid_t; + pub fn tcsendbreak(fd: ::c_int, duration: ::c_int) -> ::c_int; + pub fn mkstemp(template: *mut ::c_char) -> ::c_int; + pub fn mkdtemp(template: *mut ::c_char) -> *mut ::c_char; + + pub fn tmpnam(ptr: *mut ::c_char) -> *mut ::c_char; + + pub fn openlog(ident: *const ::c_char, logopt: ::c_int, facility: ::c_int); + pub fn closelog(); + pub fn setlogmask(maskpri: ::c_int) -> ::c_int; + pub fn syslog(priority: ::c_int, message: *const ::c_char, ...); + + pub fn grantpt(fd: ::c_int) -> ::c_int; + pub fn posix_openpt(flags: ::c_int) -> ::c_int; + pub fn ptsname(fd: ::c_int) -> *mut ::c_char; + pub fn unlockpt(fd: ::c_int) -> ::c_int; + + pub fn fdatasync(fd: ::c_int) -> ::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 dirfd(dirp: *mut ::DIR) -> ::c_int; + + pub fn pthread_getattr_np(native: ::pthread_t, attr: *mut ::pthread_attr_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: ::size_t, ptr: *const ::gid_t) -> ::c_int; + pub fn pipe2(fds: *mut ::c_int, flags: ::c_int) -> ::c_int; + 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 memrchr(cx: *const ::c_void, c: ::c_int, n: ::size_t) -> *mut ::c_void; + + 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 utimensat( + dirfd: ::c_int, + path: *const ::c_char, + times: *const ::timespec, + flag: ::c_int, + ) -> ::c_int; + pub fn duplocale(base: ::locale_t) -> ::locale_t; + pub fn freelocale(loc: ::locale_t); + 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 fdopendir(fd: ::c_int) -> *mut ::DIR; + + pub fn mknodat( + dirfd: ::c_int, + pathname: *const ::c_char, + mode: ::mode_t, + dev: dev_t, + ) -> ::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 accept4( + fd: ::c_int, + addr: *mut ::sockaddr, + len: *mut ::socklen_t, + flg: ::c_int, + ) -> ::c_int; + pub fn ptsname_r(fd: ::c_int, buf: *mut ::c_char, buflen: ::size_t) -> ::c_int; + 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; + pub fn brk(addr: *mut ::c_void) -> ::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 openpty( + amaster: *mut ::c_int, + aslave: *mut ::c_int, + name: *mut ::c_char, + termp: *const termios, + winp: *const ::winsize, + ) -> ::c_int; + pub fn execvpe( + file: *const ::c_char, + argv: *const *const ::c_char, + envp: *const *const ::c_char, + ) -> ::c_int; + pub fn fexecve( + fd: ::c_int, + argv: *const *const ::c_char, + envp: *const *const ::c_char, + ) -> ::c_int; + + pub fn ioctl(fd: ::c_int, request: ::c_int, ...) -> ::c_int; + + pub fn lutimes(file: *const ::c_char, times: *const ::timeval) -> ::c_int; + + pub fn setpwent(); + pub fn endpwent(); + pub fn getpwent() -> *mut passwd; + + 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; + 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 ftok(pathname: *const ::c_char, proj_id: ::c_int) -> ::key_t; + 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 semctl(semid: ::c_int, semnum: ::c_int, cmd: ::c_int, ...) -> ::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 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 mprotect(addr: *mut ::c_void, len: ::size_t, prot: ::c_int) -> ::c_int; + pub fn __errno_location() -> *mut ::c_int; + + pub fn fallocate(fd: ::c_int, mode: ::c_int, offset: ::off_t, len: ::off_t) -> ::c_int; + pub fn posix_fallocate(fd: ::c_int, offset: ::off_t, len: ::off_t) -> ::c_int; + pub fn readahead(fd: ::c_int, offset: ::off64_t, count: ::size_t) -> ::ssize_t; + 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_gettime(fd: ::c_int, curr_value: *mut itimerspec) -> ::c_int; + pub fn timerfd_settime( + fd: ::c_int, + flags: ::c_int, + new_value: *const itimerspec, + old_value: *mut itimerspec, + ) -> ::c_int; + pub fn pwritev(fd: ::c_int, iov: *const ::iovec, iovcnt: ::c_int, offset: ::off_t) + -> ::ssize_t; + pub fn preadv(fd: ::c_int, iov: *const ::iovec, iovcnt: ::c_int, offset: ::off_t) -> ::ssize_t; + pub fn quotactl( + cmd: ::c_int, + special: *const ::c_char, + id: ::c_int, + data: *mut ::c_char, + ) -> ::c_int; + pub fn dup3(oldfd: ::c_int, newfd: ::c_int, flags: ::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; + 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 nl_langinfo_l(item: ::nl_item, locale: ::locale_t) -> *mut ::c_char; + pub fn getnameinfo( + sa: *const ::sockaddr, + salen: ::socklen_t, + host: *mut ::c_char, + hostlen: ::socklen_t, + serv: *mut ::c_char, + servlen: ::socklen_t, + flags: ::c_int, + ) -> ::c_int; + pub fn reboot(how_to: ::c_int) -> ::c_int; + pub fn setfsgid(gid: ::gid_t) -> ::c_int; + pub fn setfsuid(uid: ::uid_t) -> ::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); + pub fn sync_file_range( + fd: ::c_int, + offset: ::off64_t, + nbytes: ::off64_t, + flags: ::c_uint, + ) -> ::c_int; + pub fn getifaddrs(ifap: *mut *mut ::ifaddrs) -> ::c_int; + pub fn freeifaddrs(ifa: *mut ::ifaddrs); + + 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 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 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 futimes(fd: ::c_int, 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; + + 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 getdomainname(name: *mut ::c_char, len: ::size_t) -> ::c_int; + pub fn setdomainname(name: *const ::c_char, len: ::size_t) -> ::c_int; + pub fn vhangup() -> ::c_int; + pub fn sendmmsg( + sockfd: ::c_int, + msgvec: *mut mmsghdr, + vlen: ::c_uint, + flags: ::c_int, + ) -> ::c_int; + pub fn recvmmsg( + sockfd: ::c_int, + msgvec: *mut mmsghdr, + vlen: ::c_uint, + flags: ::c_int, + timeout: *mut ::timespec, + ) -> ::c_int; + pub fn sync(); + pub fn syscall(num: ::c_long, ...) -> ::c_long; + pub fn sched_getaffinity(pid: ::pid_t, cpusetsize: ::size_t, cpuset: *mut cpu_set_t) + -> ::c_int; + pub fn sched_setaffinity( + pid: ::pid_t, + cpusetsize: ::size_t, + cpuset: *const cpu_set_t, + ) -> ::c_int; + pub fn umount(target: *const ::c_char) -> ::c_int; + pub fn sched_get_priority_max(policy: ::c_int) -> ::c_int; + pub fn tee(fd_in: ::c_int, fd_out: ::c_int, len: ::size_t, flags: ::c_uint) -> ::ssize_t; + pub fn settimeofday(tv: *const ::timeval, tz: *const ::timezone) -> ::c_int; + pub fn splice( + fd_in: ::c_int, + off_in: *mut ::loff_t, + fd_out: ::c_int, + off_out: *mut ::loff_t, + len: ::size_t, + flags: ::c_uint, + ) -> ::ssize_t; + pub fn eventfd(init: ::c_uint, flags: ::c_int) -> ::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 swapoff(puath: *const ::c_char) -> ::c_int; + pub fn vmsplice( + fd: ::c_int, + iov: *const ::iovec, + nr_segs: ::size_t, + flags: ::c_uint, + ) -> ::ssize_t; + pub fn mount( + src: *const ::c_char, + target: *const ::c_char, + fstype: *const ::c_char, + flags: ::c_ulong, + data: *const ::c_void, + ) -> ::c_int; + pub fn personality(persona: ::c_ulong) -> ::c_int; + pub fn sched_getparam(pid: ::pid_t, param: *mut ::sched_param) -> ::c_int; + pub fn ppoll( + fds: *mut ::pollfd, + nfds: nfds_t, + timeout: *const ::timespec, + sigmask: *const sigset_t, + ) -> ::c_int; + pub fn pthread_mutex_timedlock( + lock: *mut pthread_mutex_t, + abstime: *const ::timespec, + ) -> ::c_int; + pub fn clone( + cb: extern "C" fn(*mut ::c_void) -> ::c_int, + child_stack: *mut ::c_void, + flags: ::c_int, + arg: *mut ::c_void, + ... + ) -> ::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 pthread_attr_setguardsize(attr: *mut ::pthread_attr_t, guardsize: ::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 umount2(target: *const ::c_char, flags: ::c_int) -> ::c_int; + pub fn swapon(path: *const ::c_char, swapflags: ::c_int) -> ::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 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; + 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 setgrent(); + pub fn endgrent(); + pub fn getgrent() -> *mut ::group; + + pub fn getgrouplist( + user: *const ::c_char, + group: ::gid_t, + groups: *mut ::gid_t, + ngroups: *mut ::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 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 dl_iterate_phdr( + callback: ::Option< + unsafe extern "C" fn( + info: *mut ::dl_phdr_info, + size: ::size_t, + data: *mut ::c_void, + ) -> ::c_int, + >, + data: *mut ::c_void, + ) -> ::c_int; +} + +cfg_if! { + if #[cfg(target_arch = "aarch64")] { + mod aarch64; + pub use self::aarch64::*; + } 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 + } +} + +cfg_if! { + if #[cfg(libc_align)] { + #[macro_use] + mod align; + } else { + #[macro_use] + mod no_align; + } +} +expand_align!(); + +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/libc/src/fuchsia/no_align.rs b/vendor/libc/src/fuchsia/no_align.rs new file mode 100644 index 0000000..7ca90e0 --- /dev/null +++ b/vendor/libc/src/fuchsia/no_align.rs @@ -0,0 +1,129 @@ +macro_rules! expand_align { + () => { + s! { + pub struct pthread_mutexattr_t { + #[cfg(target_arch = "x86_64")] + __align: [::c_int; 0], + #[cfg(not(target_arch = "x86_64"))] + __align: [::c_long; 0], + size: [u8; ::__SIZEOF_PTHREAD_MUTEXATTR_T], + } + + pub struct pthread_rwlockattr_t { + __align: [::c_long; 0], + size: [u8; ::__SIZEOF_PTHREAD_RWLOCKATTR_T], + } + + pub struct pthread_condattr_t { + __align: [::c_int; 0], + size: [u8; ::__SIZEOF_PTHREAD_CONDATTR_T], + } + } + + s_no_extra_traits! { + pub struct pthread_mutex_t { + #[cfg(any(target_arch = "arm", + all(target_arch = "x86_64", + target_pointer_width = "32")))] + __align: [::c_long; 0], + #[cfg(not(any(target_arch = "arm", + all(target_arch = "x86_64", + target_pointer_width = "32"))))] + __align: [::c_longlong; 0], + size: [u8; ::__SIZEOF_PTHREAD_MUTEX_T], + } + + pub struct pthread_rwlock_t { + __align: [::c_long; 0], + __align: [::c_longlong; 0], + size: [u8; ::__SIZEOF_PTHREAD_RWLOCK_T], + } + + pub struct pthread_cond_t { + __align: [*const ::c_void; 0], + #[cfg(not(target_env = "musl"))] + __align: [::c_longlong; 0], + size: [u8; ::__SIZEOF_PTHREAD_COND_T], + } + } + + cfg_if! { + if #[cfg(feature = "extra_traits")] { + impl PartialEq for pthread_cond_t { + fn eq(&self, other: &pthread_cond_t) -> bool { + // Ignore __align field + self.size + .iter() + .zip(other.size.iter()) + .all(|(a,b)| a == b) + } + } + impl Eq for pthread_cond_t {} + impl ::fmt::Debug for pthread_cond_t { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("pthread_cond_t") + // Ignore __align field + // FIXME: .field("size", &self.size) + .finish() + } + } + impl ::hash::Hash for pthread_cond_t { + fn hash(&self, state: &mut H) { + // Ignore __align field + self.size.hash(state); + } + } + + impl PartialEq for pthread_mutex_t { + fn eq(&self, other: &pthread_mutex_t) -> bool { + // Ignore __align field + self.size + .iter() + .zip(other.size.iter()) + .all(|(a,b)| a == b) + } + } + impl Eq for pthread_mutex_t {} + impl ::fmt::Debug for pthread_mutex_t { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("pthread_mutex_t") + // Ignore __align field + // FIXME: .field("size", &self.size) + .finish() + } + } + impl ::hash::Hash for pthread_mutex_t { + fn hash(&self, state: &mut H) { + // Ignore __align field + self.size.hash(state); + } + } + + impl PartialEq for pthread_rwlock_t { + fn eq(&self, other: &pthread_rwlock_t) -> bool { + // Ignore __align field + self.size + .iter() + .zip(other.size.iter()) + .all(|(a,b)| a == b) + } + } + impl Eq for pthread_rwlock_t {} + impl ::fmt::Debug for pthread_rwlock_t { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("pthread_rwlock_t") + // Ignore __align field + // FIXME: .field("size", &self.size) + .finish() + } + } + impl ::hash::Hash for pthread_rwlock_t { + fn hash(&self, state: &mut H) { + // Ignore __align field + self.size.hash(state); + } + } + } + } + }; +} 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/fuchsia/x86_64.rs b/vendor/libc/src/fuchsia/x86_64.rs new file mode 100644 index 0000000..dca3c24 --- /dev/null +++ b/vendor/libc/src/fuchsia/x86_64.rs @@ -0,0 +1,152 @@ +pub type c_char = i8; +pub type wchar_t = i32; +pub type nlink_t = u64; +pub type blksize_t = ::c_long; +pub type __u64 = ::c_ulonglong; + +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], + } + + pub struct stat64 { + pub st_dev: ::dev_t, + pub st_ino: ::ino64_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: ::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, + __reserved: [::c_long; 3], + } + + pub struct mcontext_t { + __private: [u64; 32], + } + + 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_int, + __unused1: ::c_long, + __unused2: ::c_long + } +} + +s_no_extra_traits! { + 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, + __private: [u8; 512], + } +} + +cfg_if! { + if #[cfg(feature = "extra_traits")] { + impl PartialEq for ucontext_t { + fn eq(&self, other: &ucontext_t) -> bool { + self.uc_flags == other.uc_flags + && self.uc_link == other.uc_link + && self.uc_stack == other.uc_stack + && self.uc_mcontext == other.uc_mcontext + && self.uc_sigmask == other.uc_sigmask + && self + .__private + .iter() + .zip(other.__private.iter()) + .all(|(a,b)| a == b) + } + } + impl Eq for ucontext_t {} + impl ::fmt::Debug for ucontext_t { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("ucontext_t") + .field("uc_flags", &self.uc_flags) + .field("uc_link", &self.uc_link) + .field("uc_stack", &self.uc_stack) + .field("uc_mcontext", &self.uc_mcontext) + .field("uc_sigmask", &self.uc_sigmask) + // FIXME: .field("__private", &self.__private) + .finish() + } + } + impl ::hash::Hash for ucontext_t { + fn hash(&self, state: &mut H) { + self.uc_flags.hash(state); + self.uc_link.hash(state); + self.uc_stack.hash(state); + self.uc_mcontext.hash(state); + self.uc_sigmask.hash(state); + self.__private.hash(state); + } + } + } +} + +// offsets in user_regs_structs, from sys/reg.h +pub const R15: ::c_int = 0; +pub const R14: ::c_int = 1; +pub const R13: ::c_int = 2; +pub const R12: ::c_int = 3; +pub const RBP: ::c_int = 4; +pub const RBX: ::c_int = 5; +pub const R11: ::c_int = 6; +pub const R10: ::c_int = 7; +pub const R9: ::c_int = 8; +pub const R8: ::c_int = 9; +pub const RAX: ::c_int = 10; +pub const RCX: ::c_int = 11; +pub const RDX: ::c_int = 12; +pub const RSI: ::c_int = 13; +pub const RDI: ::c_int = 14; +pub const ORIG_RAX: ::c_int = 15; +pub const RIP: ::c_int = 16; +pub const CS: ::c_int = 17; +pub const EFLAGS: ::c_int = 18; +pub const RSP: ::c_int = 19; +pub const SS: ::c_int = 20; +pub const FS_BASE: ::c_int = 21; +pub const GS_BASE: ::c_int = 22; +pub const DS: ::c_int = 23; +pub const ES: ::c_int = 24; +pub const FS: ::c_int = 25; +pub const GS: ::c_int = 26; + +pub const MAP_32BIT: ::c_int = 0x0040; + +pub const SIGSTKSZ: ::size_t = 8192; +pub const MINSIGSTKSZ: ::size_t = 2048; diff --git a/vendor/libc/src/hermit.rs b/vendor/libc/src/hermit.rs new file mode 100644 index 0000000..77df54a --- /dev/null +++ b/vendor/libc/src/hermit.rs @@ -0,0 +1,580 @@ +//! Hermit C type definitions + +cfg_if! { + if #[cfg(any(target_arch = "aarch64", target_arch = "riscv64"))] { + pub type c_char = u8; + } else { + pub type c_char = i8; + } +} + +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_long = i64; +pub type c_ulong = u64; +pub type c_longlong = i64; +pub type c_ulonglong = u64; +pub type intmax_t = i64; +pub type uintmax_t = u64; +pub type intptr_t = isize; +pub type uintptr_t = usize; + +pub type c_float = f32; +pub type c_double = f64; + +pub type size_t = usize; +pub type ssize_t = isize; +pub type ptrdiff_t = isize; + +pub type clockid_t = i32; +pub type in_addr_t = u32; +pub type in_port_t = u16; +pub type mode_t = u32; +pub type nfds_t = usize; +pub type pid_t = i32; +pub type sa_family_t = u8; +pub type socklen_t = u32; +pub type time_t = i64; + +s! { + pub struct addrinfo { + pub ai_flags: i32, + pub ai_family: i32, + pub ai_socktype: i32, + pub ai_protocol: i32, + pub ai_addrlen: socklen_t, + pub ai_canonname: *mut c_char, + pub ai_addr: *mut sockaddr, + pub ai_next: *mut addrinfo, + } + + pub struct dirent64 { + pub d_ino: u64, + pub d_off: i64, + pub d_reclen: u16, + pub d_type: u8, + pub d_name: [c_char; 256], + } + + #[repr(align(4))] + pub struct in6_addr { + pub s6_addr: [u8; 16], + } + + pub struct in_addr { + pub s_addr: in_addr_t, + } + + pub struct iovec { + iov_base: *mut c_void, + iov_len: usize, + } + + pub struct pollfd { + pub fd: i32, + pub events: i16, + pub revents: i16, + } + + 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: [c_char; 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, + } + + pub struct sockaddr_storage { + pub ss_len: u8, + pub ss_family: sa_family_t, + __ss_pad1: [u8; 6], + __ss_align: i64, + __ss_pad2: [u8; 112], + } + + pub struct stat { + pub st_dev: u64, + pub st_ino: u64, + pub st_nlink: u64, + pub st_mode: mode_t, + pub st_uid: u32, + pub st_gid: u32, + pub st_rdev: u64, + pub st_size: u64, + pub st_blksize: i64, + pub st_blocks: i64, + pub st_atim: timespec, + pub st_mtim: timespec, + pub st_ctim: timespec, + } + + pub struct timespec { + pub tv_sec: time_t, + pub tv_nsec: i32, + } +} + +pub const AF_INET: i32 = 0; +pub const AF_INET6: i32 = 1; + +pub const CLOCK_REALTIME: clockid_t = 1; +pub const CLOCK_MONOTONIC: clockid_t = 4; + +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; +pub const DT_WHT: u8 = 14; + +pub const EAI_AGAIN: i32 = 2; +pub const EAI_BADFLAGS: i32 = 3; +pub const EAI_FAIL: i32 = 4; +pub const EAI_FAMILY: i32 = 5; +pub const EAI_MEMORY: i32 = 6; +pub const EAI_NODATA: i32 = 7; +pub const EAI_NONAME: i32 = 8; +pub const EAI_SERVICE: i32 = 9; +pub const EAI_SOCKTYPE: i32 = 10; +pub const EAI_SYSTEM: i32 = 11; +pub const EAI_OVERFLOW: i32 = 14; + +pub const EFD_SEMAPHORE: i16 = 0o1; +pub const EFD_NONBLOCK: i16 = 0o4000; +pub const EFD_CLOEXEC: i16 = 0o40000; + +pub const F_DUPFD: i32 = 0; +pub const F_GETFD: i32 = 1; +pub const F_SETFD: i32 = 2; +pub const F_GETFL: i32 = 3; +pub const F_SETFL: i32 = 4; + +pub const FD_CLOEXEC: i32 = 1; + +pub const FIONBIO: i32 = 0x8008667e; + +pub const FUTEX_RELATIVE_TIMEOUT: u32 = 1; + +pub const IP_TOS: i32 = 1; +pub const IP_TTL: i32 = 2; +pub const IP_ADD_MEMBERSHIP: i32 = 3; +pub const IP_DROP_MEMBERSHIP: i32 = 4; +pub const IP_MULTICAST_TTL: i32 = 5; +pub const IP_MULTICAST_LOOP: i32 = 7; + +pub const IPPROTO_IP: i32 = 0; +pub const IPPROTO_TCP: i32 = 6; +pub const IPPROTO_UDP: i32 = 17; +pub const IPPROTO_IPV6: i32 = 41; + +pub const IPV6_ADD_MEMBERSHIP: i32 = 12; +pub const IPV6_DROP_MEMBERSHIP: i32 = 13; +pub const IPV6_MULTICAST_LOOP: i32 = 19; +pub const IPV6_V6ONLY: i32 = 27; + +pub const MSG_PEEK: i32 = 1; + +pub const O_RDONLY: i32 = 0o0; +pub const O_WRONLY: i32 = 0o1; +pub const O_RDWR: i32 = 0o2; +pub const O_CREAT: i32 = 0o100; +pub const O_EXCL: i32 = 0o200; +pub const O_TRUNC: i32 = 0o1000; +pub const O_APPEND: i32 = 0o2000; +pub const O_NONBLOCK: i32 = 0o4000; +pub const O_DIRECTORY: i32 = 0o200000; + +pub const POLLIN: i16 = 0x1; +pub const POLLPRI: i16 = 0x2; +pub const POLLOUT: i16 = 0x4; +pub const POLLERR: i16 = 0x8; +pub const POLLHUP: i16 = 0x10; +pub const POLLNVAL: i16 = 0x20; +pub const POLLRDNORM: i16 = 0x040; +pub const POLLRDBAND: i16 = 0x080; +pub const POLLWRNORM: i16 = 0x0100; +pub const POLLWRBAND: i16 = 0x0200; +pub const POLLRDHUP: i16 = 0x2000; + +pub const S_IRWXU: mode_t = 0o0700; +pub const S_IRUSR: mode_t = 0o0400; +pub const S_IWUSR: mode_t = 0o0200; +pub const S_IXUSR: mode_t = 0o0100; +pub const S_IRWXG: mode_t = 0o0070; +pub const S_IRGRP: mode_t = 0o0040; +pub const S_IWGRP: mode_t = 0o0020; +pub const S_IXGRP: mode_t = 0o0010; +pub const S_IRWXO: mode_t = 0o0007; +pub const S_IROTH: mode_t = 0o0004; +pub const S_IWOTH: mode_t = 0o0002; +pub const S_IXOTH: mode_t = 0o0001; + +pub const S_IFMT: mode_t = 0o17_0000; +pub const S_IFSOCK: mode_t = 0o14_0000; +pub const S_IFLNK: mode_t = 0o12_0000; +pub const S_IFREG: mode_t = 0o10_0000; +pub const S_IFBLK: mode_t = 0o6_0000; +pub const S_IFDIR: mode_t = 0o4_0000; +pub const S_IFCHR: mode_t = 0o2_0000; +pub const S_IFIFO: mode_t = 0o1_0000; + +pub const SHUT_RD: i32 = 0; +pub const SHUT_WR: i32 = 1; +pub const SHUT_RDWR: i32 = 2; + +pub const SO_REUSEADDR: i32 = 0x0004; +pub const SO_KEEPALIVE: i32 = 0x0008; +pub const SO_BROADCAST: i32 = 0x0020; +pub const SO_LINGER: i32 = 0x0080; +pub const SO_SNDBUF: i32 = 0x1001; +pub const SO_RCVBUF: i32 = 0x1002; +pub const SO_SNDTIMEO: i32 = 0x1005; +pub const SO_RCVTIMEO: i32 = 0x1006; +pub const SO_ERROR: i32 = 0x1007; + +pub const SOCK_STREAM: i32 = 1; +pub const SOCK_DGRAM: i32 = 2; +pub const SOCK_NONBLOCK: i32 = 0o4000; +pub const SOCK_CLOEXEC: i32 = 0o40000; + +pub const SOL_SOCKET: i32 = 4095; + +pub const STDIN_FILENO: c_int = 0; +pub const STDOUT_FILENO: c_int = 1; +pub const STDERR_FILENO: c_int = 2; + +pub const TCP_NODELAY: i32 = 1; + +pub const EPERM: i32 = 1; +pub const ENOENT: i32 = 2; +pub const ESRCH: i32 = 3; +pub const EINTR: i32 = 4; +pub const EIO: i32 = 5; +pub const ENXIO: i32 = 6; +pub const E2BIG: i32 = 7; +pub const ENOEXEC: i32 = 8; +pub const EBADF: i32 = 9; +pub const ECHILD: i32 = 10; +pub const EAGAIN: i32 = 11; +pub const ENOMEM: i32 = 12; +pub const EACCES: i32 = 13; +pub const EFAULT: i32 = 14; +pub const ENOTBLK: i32 = 15; +pub const EBUSY: i32 = 16; +pub const EEXIST: i32 = 17; +pub const EXDEV: i32 = 18; +pub const ENODEV: i32 = 19; +pub const ENOTDIR: i32 = 20; +pub const EISDIR: i32 = 21; +pub const EINVAL: i32 = 22; +pub const ENFILE: i32 = 23; +pub const EMFILE: i32 = 24; +pub const ENOTTY: i32 = 25; +pub const ETXTBSY: i32 = 26; +pub const EFBIG: i32 = 27; +pub const ENOSPC: i32 = 28; +pub const ESPIPE: i32 = 29; +pub const EROFS: i32 = 30; +pub const EMLINK: i32 = 31; +pub const EPIPE: i32 = 32; +pub const EDOM: i32 = 33; +pub const ERANGE: i32 = 34; +pub const EDEADLK: i32 = 35; +pub const ENAMETOOLONG: i32 = 36; +pub const ENOLCK: i32 = 37; +pub const ENOSYS: i32 = 38; +pub const ENOTEMPTY: i32 = 39; +pub const ELOOP: i32 = 40; +pub const EWOULDBLOCK: i32 = EAGAIN; +pub const ENOMSG: i32 = 42; +pub const EIDRM: i32 = 43; +pub const ECHRNG: i32 = 44; +pub const EL2NSYNC: i32 = 45; +pub const EL3HLT: i32 = 46; +pub const EL3RST: i32 = 47; +pub const ELNRNG: i32 = 48; +pub const EUNATCH: i32 = 49; +pub const ENOCSI: i32 = 50; +pub const EL2HLT: i32 = 51; +pub const EBADE: i32 = 52; +pub const EBADR: i32 = 53; +pub const EXFULL: i32 = 54; +pub const ENOANO: i32 = 55; +pub const EBADRQC: i32 = 56; +pub const EBADSLT: i32 = 57; +pub const EDEADLOCK: i32 = EDEADLK; +pub const EBFONT: i32 = 59; +pub const ENOSTR: i32 = 60; +pub const ENODATA: i32 = 61; +pub const ETIME: i32 = 62; +pub const ENOSR: i32 = 63; +pub const ENONET: i32 = 64; +pub const ENOPKG: i32 = 65; +pub const EREMOTE: i32 = 66; +pub const ENOLINK: i32 = 67; +pub const EADV: i32 = 68; +pub const ESRMNT: i32 = 69; +pub const ECOMM: i32 = 70; +pub const EPROTO: i32 = 71; +pub const EMULTIHOP: i32 = 72; +pub const EDOTDOT: i32 = 73; +pub const EBADMSG: i32 = 74; +pub const EOVERFLOW: i32 = 75; +pub const ENOTUNIQ: i32 = 76; +pub const EBADFD: i32 = 77; +pub const EREMCHG: i32 = 78; +pub const ELIBACC: i32 = 79; +pub const ELIBBAD: i32 = 80; +pub const ELIBSCN: i32 = 81; +pub const ELIBMAX: i32 = 82; +pub const ELIBEXEC: i32 = 83; +pub const EILSEQ: i32 = 84; +pub const ERESTART: i32 = 85; +pub const ESTRPIPE: i32 = 86; +pub const EUSERS: i32 = 87; +pub const ENOTSOCK: i32 = 88; +pub const EDESTADDRREQ: i32 = 89; +pub const EMSGSIZE: i32 = 90; +pub const EPROTOTYPE: i32 = 91; +pub const ENOPROTOOPT: i32 = 92; +pub const EPROTONOSUPPORT: i32 = 93; +pub const ESOCKTNOSUPPORT: i32 = 94; +pub const EOPNOTSUPP: i32 = 95; +pub const EPFNOSUPPORT: i32 = 96; +pub const EAFNOSUPPORT: i32 = 97; +pub const EADDRINUSE: i32 = 98; +pub const EADDRNOTAVAIL: i32 = 99; +pub const ENETDOWN: i32 = 100; +pub const ENETUNREACH: i32 = 101; +pub const ENETRESET: i32 = 102; +pub const ECONNABORTED: i32 = 103; +pub const ECONNRESET: i32 = 104; +pub const ENOBUFS: i32 = 105; +pub const EISCONN: i32 = 106; +pub const ENOTCONN: i32 = 107; +pub const ESHUTDOWN: i32 = 108; +pub const ETOOMANYREFS: i32 = 109; +pub const ETIMEDOUT: i32 = 110; +pub const ECONNREFUSED: i32 = 111; +pub const EHOSTDOWN: i32 = 112; +pub const EHOSTUNREACH: i32 = 113; +pub const EALREADY: i32 = 114; +pub const EINPROGRESS: i32 = 115; +pub const ESTALE: i32 = 116; +pub const EUCLEAN: i32 = 117; +pub const ENOTNAM: i32 = 118; +pub const ENAVAIL: i32 = 119; +pub const EISNAM: i32 = 120; +pub const EREMOTEIO: i32 = 121; +pub const EDQUOT: i32 = 122; +pub const ENOMEDIUM: i32 = 123; +pub const EMEDIUMTYPE: i32 = 124; +pub const ECANCELED: i32 = 125; +pub const ENOKEY: i32 = 126; +pub const EKEYEXPIRED: i32 = 127; +pub const EKEYREVOKED: i32 = 128; +pub const EKEYREJECTED: i32 = 129; +pub const EOWNERDEAD: i32 = 130; +pub const ENOTRECOVERABLE: i32 = 131; +pub const ERFKILL: i32 = 132; +pub const EHWPOISON: i32 = 133; + +extern "C" { + #[link_name = "sys_alloc"] + pub fn alloc(size: usize, align: usize) -> *mut u8; + + #[link_name = "sys_alloc_zeroed"] + pub fn alloc_zeroed(size: usize, align: usize) -> *mut u8; + + #[link_name = "sys_realloc"] + pub fn realloc(ptr: *mut u8, size: usize, align: usize, new_size: usize) -> *mut u8; + + #[link_name = "sys_dealloc"] + pub fn dealloc(ptr: *mut u8, size: usize, align: usize); + + #[link_name = "sys_exit"] + pub fn exit(status: i32) -> !; + + #[link_name = "sys_abort"] + pub fn abort() -> !; + + #[link_name = "sys_errno"] + pub fn errno() -> i32; + + #[link_name = "sys_clock_gettime"] + pub fn clock_gettime(clockid: clockid_t, tp: *mut timespec) -> i32; + + #[link_name = "sys_nanosleep"] + pub fn nanosleep(req: *const timespec) -> i32; + + #[link_name = "sys_available_parallelism"] + pub fn available_parallelism() -> usize; + + #[link_name = "sys_futex_wait"] + pub fn futex_wait( + address: *mut u32, + expected: u32, + timeout: *const timespec, + flags: u32, + ) -> i32; + + #[link_name = "sys_futex_wake"] + pub fn futex_wake(address: *mut u32, count: i32) -> i32; + + #[link_name = "sys_stat"] + pub fn stat(path: *const c_char, stat: *mut stat) -> i32; + + #[link_name = "sys_fstat"] + pub fn fstat(fd: i32, stat: *mut stat) -> i32; + + #[link_name = "sys_lstat"] + pub fn lstat(path: *const c_char, stat: *mut stat) -> i32; + + #[link_name = "sys_open"] + pub fn open(path: *const c_char, flags: i32, mode: mode_t) -> i32; + + #[link_name = "sys_unlink"] + pub fn unlink(path: *const c_char) -> i32; + + #[link_name = "sys_mkdir"] + pub fn mkdir(path: *const c_char, mode: mode_t) -> i32; + + #[link_name = "sys_rmdir"] + pub fn rmdir(path: *const c_char) -> i32; + + #[link_name = "sys_read"] + pub fn read(fd: i32, buf: *mut u8, len: usize) -> isize; + + #[link_name = "sys_write"] + pub fn write(fd: i32, buf: *const u8, len: usize) -> isize; + + #[link_name = "sys_readv"] + pub fn readv(fd: i32, iov: *const iovec, iovcnt: usize) -> isize; + + #[link_name = "sys_writev"] + pub fn writev(fd: i32, iov: *const iovec, iovcnt: usize) -> isize; + + #[link_name = "sys_close"] + pub fn close(fd: i32) -> i32; + + #[link_name = "sys_dup"] + pub fn dup(fd: i32) -> i32; + + #[link_name = "sys_fcntl"] + pub fn fcntl(fd: i32, cmd: i32, arg: i32) -> i32; + + #[link_name = "sys_getdents64"] + pub fn getdents64(fd: i32, dirp: *mut dirent64, count: usize) -> isize; + + #[link_name = "sys_getaddrinfo"] + pub fn getaddrinfo( + nodename: *const c_char, + servname: *const c_char, + hints: *const addrinfo, + res: *mut *mut addrinfo, + ) -> i32; + + #[link_name = "sys_freeaddrinfo"] + pub fn freeaddrinfo(ai: *mut addrinfo); + + #[link_name = "sys_socket"] + pub fn socket(domain: i32, ty: i32, protocol: i32) -> i32; + + #[link_name = "sys_bind"] + pub fn bind(sockfd: i32, addr: *const sockaddr, addrlen: socklen_t) -> i32; + + #[link_name = "sys_listen"] + pub fn listen(sockfd: i32, backlog: i32) -> i32; + + #[link_name = "sys_accept"] + pub fn accept(sockfd: i32, addr: *mut sockaddr, addrlen: *mut socklen_t) -> i32; + + #[link_name = "sys_connect"] + pub fn connect(sockfd: i32, addr: *const sockaddr, addrlen: socklen_t) -> i32; + + #[link_name = "sys_recv"] + pub fn recv(sockfd: i32, buf: *mut u8, len: usize, flags: i32) -> isize; + + #[link_name = "sys_recvfrom"] + pub fn recvfrom( + sockfd: i32, + buf: *mut c_void, + len: usize, + flags: i32, + addr: *mut sockaddr, + addrlen: *mut socklen_t, + ) -> isize; + + #[link_name = "sys_send"] + pub fn send(sockfd: i32, buf: *const c_void, len: usize, flags: i32) -> isize; + + #[link_name = "sys_sendto"] + pub fn sendto( + sockfd: i32, + buf: *const c_void, + len: usize, + flags: i32, + to: *const sockaddr, + tolen: socklen_t, + ) -> isize; + + #[link_name = "sys_getpeername"] + pub fn getpeername(sockfd: i32, addr: *mut sockaddr, addrlen: *mut socklen_t) -> i32; + + #[link_name = "sys_getsockname"] + pub fn getsockname(sockfd: i32, addr: *mut sockaddr, addrlen: *mut socklen_t) -> i32; + + #[link_name = "sys_getsockopt"] + pub fn getsockopt( + sockfd: i32, + level: i32, + optname: i32, + optval: *mut c_void, + optlen: *mut socklen_t, + ) -> i32; + + #[link_name = "sys_setsockopt"] + pub fn setsockopt( + sockfd: i32, + level: i32, + optname: i32, + optval: *const c_void, + optlen: socklen_t, + ) -> i32; + + #[link_name = "sys_ioctl"] + pub fn ioctl(sockfd: i32, cmd: i32, argp: *mut c_void) -> i32; + + #[link_name = "sys_shutdown"] + pub fn shutdown(sockfd: i32, how: i32) -> i32; + + #[link_name = "sys_eventfd"] + pub fn eventfd(initval: u64, flags: i16) -> i32; + + #[link_name = "sys_poll"] + pub fn poll(fds: *mut pollfd, nfds: nfds_t, timeout: i32) -> i32; +} + +pub use ffi::c_void; diff --git a/vendor/libc/src/lib.rs b/vendor/libc/src/lib.rs new file mode 100644 index 0000000..764d8e4 --- /dev/null +++ b/vendor/libc/src/lib.rs @@ -0,0 +1,169 @@ +//! libc - Raw FFI bindings to platforms' system libraries +#![crate_name = "libc"] +#![crate_type = "rlib"] +#![allow( + renamed_and_removed_lints, // Keep this order. + unknown_lints, // Keep this order. + bad_style, + overflowing_literals, + improper_ctypes, + // This lint is renamed but we run CI for old stable rustc so should be here. + redundant_semicolon, + redundant_semicolons, + unused_macros, + unused_macro_rules, + // FIXME: temporarily allow dead_code to fix CI: + // - https://github.com/rust-lang/libc/issues/3740 + // - https://github.com/rust-lang/rust/pull/126456 + dead_code, +)] +#![cfg_attr(libc_deny_warnings, deny(warnings))] +// Attributes needed when building as part of the standard library +#![cfg_attr(feature = "rustc-dep-of-std", feature(link_cfg, no_core))] +#![cfg_attr(libc_thread_local, feature(thread_local))] +// Enable extra lints: +#![cfg_attr(feature = "extra_traits", deny(missing_debug_implementations))] +#![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(libc_const_extern_fn_unstable, feature(const_extern_fn))] + +#[macro_use] +mod macros; + +cfg_if! { + if #[cfg(feature = "rustc-dep-of-std")] { + extern crate rustc_std_workspace_core as core; + #[allow(unused_imports)] + use core::iter; + #[allow(unused_imports)] + use core::ops; + #[allow(unused_imports)] + use core::option; + } +} + +cfg_if! { + if #[cfg(libc_priv_mod_use)] { + #[cfg(libc_core_cvoid)] + #[allow(unused_imports)] + use core::ffi; + #[allow(unused_imports)] + use core::fmt; + #[allow(unused_imports)] + use core::hash; + #[allow(unused_imports)] + use core::num; + #[allow(unused_imports)] + use core::mem; + #[doc(hidden)] + #[allow(unused_imports)] + use core::clone::Clone; + #[doc(hidden)] + #[allow(unused_imports)] + use core::marker::{Copy, Send, Sync}; + #[doc(hidden)] + #[allow(unused_imports)] + use core::option::Option; + } else { + #[doc(hidden)] + #[allow(unused_imports)] + pub use core::fmt; + #[doc(hidden)] + #[allow(unused_imports)] + pub use core::hash; + #[doc(hidden)] + #[allow(unused_imports)] + pub use core::num; + #[doc(hidden)] + #[allow(unused_imports)] + pub use core::mem; + #[doc(hidden)] + #[allow(unused_imports)] + pub use core::clone::Clone; + #[doc(hidden)] + #[allow(unused_imports)] + pub use core::marker::{Copy, Send, Sync}; + #[doc(hidden)] + #[allow(unused_imports)] + pub use core::option::Option; + } +} + +cfg_if! { + if #[cfg(windows)] { + mod fixed_width_ints; + pub use fixed_width_ints::*; + + mod windows; + pub use windows::*; + } else if #[cfg(target_os = "fuchsia")] { + mod fixed_width_ints; + pub use fixed_width_ints::*; + + mod fuchsia; + pub use fuchsia::*; + } else if #[cfg(target_os = "switch")] { + mod fixed_width_ints; + pub use fixed_width_ints::*; + + mod switch; + pub use switch::*; + } else if #[cfg(target_os = "psp")] { + mod fixed_width_ints; + pub use fixed_width_ints::*; + + mod psp; + pub use psp::*; + } else if #[cfg(target_os = "vxworks")] { + mod fixed_width_ints; + pub use fixed_width_ints::*; + + 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::*; + + mod unix; + pub use unix::*; + } else if #[cfg(target_os = "hermit")] { + mod fixed_width_ints; + pub use fixed_width_ints::*; + + mod hermit; + pub use hermit::*; + } else if #[cfg(target_os = "teeos")] { + mod fixed_width_ints; + pub use fixed_width_ints::*; + + mod teeos; + pub use teeos::*; + } else if #[cfg(all(target_env = "sgx", target_vendor = "fortanix"))] { + mod fixed_width_ints; + pub use fixed_width_ints::*; + + mod sgx; + pub use sgx::*; + } else if #[cfg(any(target_env = "wasi", target_os = "wasi"))] { + mod fixed_width_ints; + pub use fixed_width_ints::*; + + 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 new file mode 100644 index 0000000..beb8002 --- /dev/null +++ b/vendor/libc/src/macros.rs @@ -0,0 +1,349 @@ +/// A macro for defining #[cfg] if-else statements. +/// +/// This 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. +macro_rules! cfg_if { + // match if/else chains with a final `else` + ($( + if #[cfg($($meta:meta),*)] { $($it:item)* } + ) else * else { + $($it2:item)* + }) => { + cfg_if! { + @__items + () ; + $( ( ($($meta),*) ($($it)*) ), )* + ( () ($($it2)*) ), + } + }; + + // match if/else chains lacking a final `else` + ( + if #[cfg($($i_met:meta),*)] { $($i_it:item)* } + $( + else if #[cfg($($e_met:meta),*)] { $($e_it:item)* } + )* + ) => { + cfg_if! { + @__items + () ; + ( ($($i_met),*) ($($i_it)*) ), + $( ( ($($e_met),*) ($($e_it)*) ), )* + ( () () ), + } + }; + + // Internal and recursive macro to emit all the items + // + // Collects all the negated `cfg`s in a list at the beginning and after the + // semicolon is all the remaining items + (@__items ($($not:meta,)*) ; ) => {}; + (@__items ($($not:meta,)*) ; ( ($($m:meta),*) ($($it:item)*) ), + $($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_if! { @__apply cfg(all($($m,)* not(any($($not),*)))), $($it)* } + + // 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. + cfg_if! { @__items ($($not,)* $($m,)*) ; $($rest)* } + }; + + // Internal macro to Apply a cfg attribute to a list of items + (@__apply $m:meta, $($it:item)*) => { + $(#[$m] $it)* + }; +} + +macro_rules! s { + ($($(#[$attr:meta])* pub $t:ident $i:ident { $($field:tt)* })*) => ($( + s!(it: $(#[$attr])* pub $t $i { $($field)* }); + )*); + (it: $(#[$attr:meta])* pub union $i:ident { $($field:tt)* }) => ( + compile_error!("unions cannot derive extra traits, use s_no_extra_traits instead"); + ); + (it: $(#[$attr:meta])* pub struct $i:ident { $($field:tt)* }) => ( + __item! { + #[repr(C)] + #[cfg_attr(feature = "extra_traits", derive(Debug, Eq, Hash, PartialEq))] + #[allow(deprecated)] + $(#[$attr])* + pub struct $i { $($field)* } + } + #[allow(deprecated)] + impl ::Copy for $i {} + #[allow(deprecated)] + impl ::Clone for $i { + fn clone(&self) -> $i { *self } + } + ); +} + +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)* }); + )*); + (it: $(#[$attr:meta])* pub union $i:ident { $($field:tt)* }) => ( + cfg_if! { + if #[cfg(libc_union)] { + __item! { + #[repr(C)] + $(#[$attr])* + pub union $i { $($field)* } + } + + impl ::Copy for $i {} + impl ::Clone for $i { + fn clone(&self) -> $i { *self } + } + } + } + ); + (it: $(#[$attr:meta])* pub struct $i:ident { $($field:tt)* }) => ( + __item! { + #[repr(C)] + $(#[$attr])* + pub struct $i { $($field)* } + } + #[allow(deprecated)] + impl ::Copy for $i {} + #[allow(deprecated)] + impl ::Clone for $i { + fn clone(&self) -> $i { *self } + } + ); +} + +macro_rules! missing { + ($($(#[$attr:meta])* pub enum $i:ident {})*) => ($( + $(#[$attr])* #[allow(missing_copy_implementations)] pub enum $i { } + )*); +} + +macro_rules! e { + ($($(#[$attr:meta])* pub enum $i:ident { $($field:tt)* })*) => ($( + __item! { + #[cfg_attr(feature = "extra_traits", derive(Debug, Eq, Hash, PartialEq))] + $(#[$attr])* + pub enum $i { $($field)* } + } + impl ::Copy for $i {} + impl ::Clone for $i { + fn clone(&self) -> $i { *self } + } + )*); +} + +macro_rules! s_paren { + ($($(#[$attr:meta])* pub struct $i:ident ( $($field:tt)* ); )* ) => ($( + __item! { + #[cfg_attr(feature = "extra_traits", derive(Debug, Eq, Hash, PartialEq))] + $(#[$attr])* + pub struct $i ( $($field)* ); + } + impl ::Copy for $i {} + impl ::Clone for $i { + fn clone(&self) -> $i { *self } + } + )*); +} + +// This is a pretty horrible hack to allow us to conditionally mark +// some functions as 'const', without requiring users of this macro +// to care about the "const-extern-fn" feature. +// +// When 'const-extern-fn' is enabled, we emit the captured 'const' keyword +// in the expanded function. +// +// When 'const-extern-fn' is disabled, we always emit a plain 'pub unsafe extern fn'. +// Note that the expression matched by the macro is exactly the same - this allows +// users of this macro to work whether or not 'const-extern-fn' is enabled +// +// Unfortunately, we need to duplicate most of this macro between the 'cfg_if' blocks. +// This is because 'const unsafe extern fn' won't even parse on older compilers, +// so we need to avoid emitting it at all of 'const-extern-fn'. +// +// Specifically, moving the 'cfg_if' into the macro body will *not* work. +// Doing so would cause the '#[cfg(feature = "const-extern-fn")]' to be emitted +// into user code. The 'cfg' gate will not stop Rust from trying to parse the +// 'pub const unsafe extern fn', so users would get a compiler error even when +// the 'const-extern-fn' feature is disabled +// +// Note that users of this macro need to place 'const' in a weird position +// (after the closing ')' for the arguments, but before the return type). +// This was the only way I could satisfy the following two requirements: +// 1. Avoid ambiguity errors from 'macro_rules!' (which happen when writing '$foo:ident fn' +// 2. Allow users of this macro to mix 'pub fn foo' and 'pub const fn bar' within the same +// 'f!' block +cfg_if! { + if #[cfg(libc_const_extern_fn)] { + macro_rules! f { + ($($(#[$attr:meta])* pub $({$constness:ident})* fn $i:ident( + $($arg:ident: $argty:ty),* + ) -> $ret:ty { + $($body:stmt);* + })*) => ($( + #[inline] + $(#[$attr])* + pub $($constness)* unsafe extern fn $i($($arg: $argty),* + ) -> $ret { + $($body);* + } + )*) + } + + macro_rules! safe_f { + ($($(#[$attr:meta])* pub $({$constness:ident})* fn $i:ident( + $($arg:ident: $argty:ty),* + ) -> $ret:ty { + $($body:stmt);* + })*) => ($( + #[inline] + $(#[$attr])* + pub $($constness)* extern fn $i($($arg: $argty),* + ) -> $ret { + $($body);* + } + )*) + } + + macro_rules! const_fn { + ($($(#[$attr:meta])* $({$constness:ident})* fn $i:ident( + $($arg:ident: $argty:ty),* + ) -> $ret:ty { + $($body:stmt);* + })*) => ($( + #[inline] + $(#[$attr])* + $($constness)* fn $i($($arg: $argty),* + ) -> $ret { + $($body);* + } + )*) + } + + } else { + macro_rules! f { + ($($(#[$attr:meta])* pub $({$constness:ident})* fn $i:ident( + $($arg:ident: $argty:ty),* + ) -> $ret:ty { + $($body:stmt);* + })*) => ($( + #[inline] + $(#[$attr])* + pub unsafe extern fn $i($($arg: $argty),* + ) -> $ret { + $($body);* + } + )*) + } + + macro_rules! safe_f { + ($($(#[$attr:meta])* pub $({$constness:ident})* fn $i:ident( + $($arg:ident: $argty:ty),* + ) -> $ret:ty { + $($body:stmt);* + })*) => ($( + #[inline] + $(#[$attr])* + pub extern fn $i($($arg: $argty),* + ) -> $ret { + $($body);* + } + )*) + } + + macro_rules! const_fn { + ($($(#[$attr:meta])* $({$constness:ident})* fn $i:ident( + $($arg:ident: $argty:ty),* + ) -> $ret:ty { + $($body:stmt);* + })*) => ($( + #[inline] + $(#[$attr])* + fn $i($($arg: $argty),* + ) -> $ret { + $($body);* + } + )*) + } + } +} + +macro_rules! __item { + ($i:item) => { + $i + }; +} + +macro_rules! align_const { + ($($(#[$attr:meta])* + pub const $name:ident : $t1:ty + = $t2:ident { $($field:tt)* };)*) => ($( + #[cfg(libc_align)] + $(#[$attr])* + pub const $name : $t1 = $t2 { + $($field)* + }; + #[cfg(not(libc_align))] + $(#[$attr])* + pub const $name : $t1 = $t2 { + $($field)* + __align: [], + }; + )*) +} + +// 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 `mach2` crate instead", + )] + #[allow(deprecated)] + pub const $id: $ty = $expr; + }; + ($(pub const $id:ident: $ty:ty = $expr:expr;)*) => { + $( + deprecated_mach!( + pub const $id: $ty = $expr; + ); + )* + }; + (pub type $id:ident = $ty:ty;) => { + #[deprecated( + since = "0.2.55", + note = "Use the `mach2` crate instead", + )] + #[allow(deprecated)] + pub type $id = $ty; + }; + ($(pub type $id:ident = $ty:ty;)*) => { + $( + deprecated_mach!( + pub type $id = $ty; + ); + )* + } +} + +#[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/psp.rs b/vendor/libc/src/psp.rs new file mode 100644 index 0000000..a4ca029 --- /dev/null +++ b/vendor/libc/src/psp.rs @@ -0,0 +1,4177 @@ +//! PSP C type definitions +//! +//! These type declarations are not enough, as they must be ultimately resolved +//! by the linker. Crates that use these definitions must, somewhere in the +//! crate graph, include a stub provider crate such as the `psp` crate. + +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 c_char = u8; +pub type c_long = i64; +pub type c_ulong = u64; + +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, + } + } +} + +pub type SceKernelVTimerHandler = unsafe extern "C" fn( + uid: SceUid, + arg1: *mut SceKernelSysClock, + arg2: *mut SceKernelSysClock, + arg3: *mut c_void, +) -> u32; + +pub type SceKernelVTimerHandlerWide = + unsafe extern "C" fn(uid: SceUid, arg1: i64, arg2: i64, arg3: *mut c_void) -> u32; + +pub type SceKernelThreadEventHandler = + unsafe extern "C" fn(mask: i32, thid: SceUid, common: *mut c_void) -> i32; + +pub type SceKernelAlarmHandler = unsafe extern "C" fn(common: *mut c_void) -> u32; + +pub type SceKernelCallbackFunction = + unsafe extern "C" fn(arg1: i32, arg2: i32, arg: *mut c_void) -> i32; + +pub type SceKernelThreadEntry = unsafe extern "C" fn(args: usize, argp: *mut c_void) -> i32; + +pub type PowerCallback = extern "C" fn(unknown: i32, power_info: i32); + +pub type IoPermissions = i32; + +pub type UmdCallback = fn(unknown: i32, event: i32) -> i32; + +pub type SceMpegRingbufferCb = + ::Option i32>; + +pub type GuCallback = ::Option; +pub type GuSwapBuffersCallback = + ::Option; + +pub type SceNetAdhocctlHandler = + ::Option; + +pub type AdhocMatchingCallback = ::Option< + unsafe extern "C" fn( + matching_id: i32, + event: i32, + mac: *mut u8, + opt_len: i32, + opt_data: *mut c_void, + ), +>; + +pub type SceNetApctlHandler = ::Option< + unsafe extern "C" fn(oldState: i32, newState: i32, event: i32, error: i32, pArg: *mut c_void), +>; + +pub type HttpMallocFunction = ::Option *mut c_void>; +pub type HttpReallocFunction = + ::Option *mut c_void>; +pub type HttpFreeFunction = ::Option; +pub type HttpPasswordCB = ::Option< + unsafe extern "C" fn( + request: i32, + auth_type: HttpAuthType, + realm: *const u8, + username: *mut u8, + password: *mut u8, + need_entity: i32, + entity_body: *mut *mut u8, + entity_size: *mut usize, + save: *mut i32, + ) -> i32, +>; + +pub type socklen_t = u32; + +e! { + #[repr(u32)] + pub enum AudioFormat { + Stereo = 0, + Mono = 0x10, + } + + #[repr(u32)] + pub enum DisplayMode { + Lcd = 0, + } + + #[repr(u32)] + pub enum DisplayPixelFormat { + Psm5650 = 0, + Psm5551 = 1, + Psm4444 = 2, + Psm8888 = 3, + } + + #[repr(u32)] + pub enum DisplaySetBufSync { + Immediate = 0, + NextFrame = 1, + } + + #[repr(i32)] + pub enum AudioOutputFrequency { + Khz48 = 48000, + Khz44_1 = 44100, + Khz32 = 32000, + Khz24 = 24000, + Khz22_05 = 22050, + Khz16 = 16000, + Khz12 = 12000, + Khz11_025 = 11025, + Khz8 = 8000, + } + + #[repr(i32)] + pub enum AudioInputFrequency { + Khz44_1 = 44100, + Khz22_05 = 22050, + Khz11_025 = 11025, + } + + #[repr(u32)] + pub enum CtrlMode { + Digital = 0, + Analog, + } + + #[repr(i32)] + pub enum GeMatrixType { + Bone0 = 0, + Bone1, + Bone2, + Bone3, + Bone4, + Bone5, + Bone6, + Bone7, + World, + View, + Projection, + TexGen, + } + + #[repr(i32)] + pub enum GeListState { + Done = 0, + Queued, + DrawingDone, + StallReached, + CancelDone, + } + + #[repr(u8)] + pub enum GeCommand { + Nop = 0, + Vaddr = 0x1, + Iaddr = 0x2, + Prim = 0x4, + Bezier = 0x5, + Spline = 0x6, + BoundingBox = 0x7, + Jump = 0x8, + BJump = 0x9, + Call = 0xa, + Ret = 0xb, + End = 0xc, + Signal = 0xe, + Finish = 0xf, + Base = 0x10, + VertexType = 0x12, + OffsetAddr = 0x13, + Origin = 0x14, + Region1 = 0x15, + Region2 = 0x16, + LightingEnable = 0x17, + LightEnable0 = 0x18, + LightEnable1 = 0x19, + LightEnable2 = 0x1a, + LightEnable3 = 0x1b, + DepthClampEnable = 0x1c, + CullFaceEnable = 0x1d, + TextureMapEnable = 0x1e, + FogEnable = 0x1f, + DitherEnable = 0x20, + AlphaBlendEnable = 0x21, + AlphaTestEnable = 0x22, + ZTestEnable = 0x23, + StencilTestEnable = 0x24, + AntiAliasEnable = 0x25, + PatchCullEnable = 0x26, + ColorTestEnable = 0x27, + LogicOpEnable = 0x28, + BoneMatrixNumber = 0x2a, + BoneMatrixData = 0x2b, + MorphWeight0 = 0x2c, + MorphWeight1 = 0x2d, + MorphWeight2 = 0x2e, + MorphWeight3 = 0x2f, + MorphWeight4 = 0x30, + MorphWeight5 = 0x31, + MorphWeight6 = 0x32, + MorphWeight7 = 0x33, + PatchDivision = 0x36, + PatchPrimitive = 0x37, + PatchFacing = 0x38, + WorldMatrixNumber = 0x3a, + WorldMatrixData = 0x3b, + ViewMatrixNumber = 0x3c, + ViewMatrixData = 0x3d, + ProjMatrixNumber = 0x3e, + ProjMatrixData = 0x3f, + TGenMatrixNumber = 0x40, + TGenMatrixData = 0x41, + ViewportXScale = 0x42, + ViewportYScale = 0x43, + ViewportZScale = 0x44, + ViewportXCenter = 0x45, + ViewportYCenter = 0x46, + ViewportZCenter = 0x47, + TexScaleU = 0x48, + TexScaleV = 0x49, + TexOffsetU = 0x4a, + TexOffsetV = 0x4b, + OffsetX = 0x4c, + OffsetY = 0x4d, + ShadeMode = 0x50, + ReverseNormal = 0x51, + MaterialUpdate = 0x53, + MaterialEmissive = 0x54, + MaterialAmbient = 0x55, + MaterialDiffuse = 0x56, + MaterialSpecular = 0x57, + MaterialAlpha = 0x58, + MaterialSpecularCoef = 0x5b, + AmbientColor = 0x5c, + AmbientAlpha = 0x5d, + LightMode = 0x5e, + LightType0 = 0x5f, + LightType1 = 0x60, + LightType2 = 0x61, + LightType3 = 0x62, + Light0X = 0x63, + Light0Y, + Light0Z, + Light1X, + Light1Y, + Light1Z, + Light2X, + Light2Y, + Light2Z, + Light3X, + Light3Y, + Light3Z, + Light0DirectionX = 0x6f, + Light0DirectionY, + Light0DirectionZ, + Light1DirectionX, + Light1DirectionY, + Light1DirectionZ, + Light2DirectionX, + Light2DirectionY, + Light2DirectionZ, + Light3DirectionX, + Light3DirectionY, + Light3DirectionZ, + Light0ConstantAtten = 0x7b, + Light0LinearAtten, + Light0QuadtraticAtten, + Light1ConstantAtten, + Light1LinearAtten, + Light1QuadtraticAtten, + Light2ConstantAtten, + Light2LinearAtten, + Light2QuadtraticAtten, + Light3ConstantAtten, + Light3LinearAtten, + Light3QuadtraticAtten, + Light0ExponentAtten = 0x87, + Light1ExponentAtten, + Light2ExponentAtten, + Light3ExponentAtten, + Light0CutoffAtten = 0x8b, + Light1CutoffAtten, + Light2CutoffAtten, + Light3CutoffAtten, + Light0Ambient = 0x8f, + Light0Diffuse, + Light0Specular, + Light1Ambient, + Light1Diffuse, + Light1Specular, + Light2Ambient, + Light2Diffuse, + Light2Specular, + Light3Ambient, + Light3Diffuse, + Light3Specular, + Cull = 0x9b, + FrameBufPtr = 0x9c, + FrameBufWidth = 0x9d, + ZBufPtr = 0x9e, + ZBufWidth = 0x9f, + TexAddr0 = 0xa0, + TexAddr1, + TexAddr2, + TexAddr3, + TexAddr4, + TexAddr5, + TexAddr6, + TexAddr7, + TexBufWidth0 = 0xa8, + TexBufWidth1, + TexBufWidth2, + TexBufWidth3, + TexBufWidth4, + TexBufWidth5, + TexBufWidth6, + TexBufWidth7, + ClutAddr = 0xb0, + ClutAddrUpper = 0xb1, + TransferSrc, + TransferSrcW, + TransferDst, + TransferDstW, + TexSize0 = 0xb8, + TexSize1, + TexSize2, + TexSize3, + TexSize4, + TexSize5, + TexSize6, + TexSize7, + TexMapMode = 0xc0, + TexShadeLs = 0xc1, + TexMode = 0xc2, + TexFormat = 0xc3, + LoadClut = 0xc4, + ClutFormat = 0xc5, + TexFilter = 0xc6, + TexWrap = 0xc7, + TexLevel = 0xc8, + TexFunc = 0xc9, + TexEnvColor = 0xca, + TexFlush = 0xcb, + TexSync = 0xcc, + Fog1 = 0xcd, + Fog2 = 0xce, + FogColor = 0xcf, + TexLodSlope = 0xd0, + FramebufPixFormat = 0xd2, + ClearMode = 0xd3, + Scissor1 = 0xd4, + Scissor2 = 0xd5, + MinZ = 0xd6, + MaxZ = 0xd7, + ColorTest = 0xd8, + ColorRef = 0xd9, + ColorTestmask = 0xda, + AlphaTest = 0xdb, + StencilTest = 0xdc, + StencilOp = 0xdd, + ZTest = 0xde, + BlendMode = 0xdf, + BlendFixedA = 0xe0, + BlendFixedB = 0xe1, + Dith0 = 0xe2, + Dith1, + Dith2, + Dith3, + LogicOp = 0xe6, + ZWriteDisable = 0xe7, + MaskRgb = 0xe8, + MaskAlpha = 0xe9, + TransferStart = 0xea, + TransferSrcPos = 0xeb, + TransferDstPos = 0xec, + TransferSize = 0xee, + Vscx = 0xf0, + Vscy = 0xf1, + Vscz = 0xf2, + Vtcs = 0xf3, + Vtct = 0xf4, + Vtcq = 0xf5, + Vcv = 0xf6, + Vap = 0xf7, + Vfc = 0xf8, + Vscv = 0xf9, + + Unknown03 = 0x03, + Unknown0D = 0x0d, + Unknown11 = 0x11, + Unknown29 = 0x29, + Unknown34 = 0x34, + Unknown35 = 0x35, + Unknown39 = 0x39, + Unknown4E = 0x4e, + Unknown4F = 0x4f, + Unknown52 = 0x52, + Unknown59 = 0x59, + Unknown5A = 0x5a, + UnknownB6 = 0xb6, + UnknownB7 = 0xb7, + UnknownD1 = 0xd1, + UnknownED = 0xed, + UnknownEF = 0xef, + UnknownFA = 0xfa, + UnknownFB = 0xfb, + UnknownFC = 0xfc, + UnknownFD = 0xfd, + UnknownFE = 0xfe, + NopFF = 0xff, + } + + #[repr(i32)] + pub enum SceSysMemPartitionId { + SceKernelUnknownPartition = 0, + SceKernelPrimaryKernelPartition = 1, + SceKernelPrimaryUserPartition = 2, + SceKernelOtherKernelPartition1 = 3, + SceKernelOtherKernelPartition2 = 4, + SceKernelVshellPARTITION = 5, + SceKernelScUserPartition = 6, + SceKernelMeUserPartition = 7, + SceKernelExtendedScKernelPartition = 8, + SceKernelExtendedSc2KernelPartition = 9, + SceKernelExtendedMeKernelPartition = 10, + SceKernelVshellKernelPartition = 11, + SceKernelExtendedKernelPartition = 12, + } + + #[repr(i32)] + pub enum SceSysMemBlockTypes { + Low = 0, + High, + Addr, + } + + #[repr(u32)] + pub enum Interrupt { + Gpio = 4, + Ata = 5, + Umd = 6, + Mscm0 = 7, + Wlan = 8, + Audio = 10, + I2c = 12, + Sircs = 14, + Systimer0 = 15, + Systimer1 = 16, + Systimer2 = 17, + Systimer3 = 18, + Thread0 = 19, + Nand = 20, + Dmacplus = 21, + Dma0 = 22, + Dma1 = 23, + Memlmd = 24, + Ge = 25, + Vblank = 30, + Mecodec = 31, + Hpremote = 36, + Mscm1 = 60, + Mscm2 = 61, + Thread1 = 65, + Interrupt = 66, + } + + #[repr(u32)] + pub enum SubInterrupt { + Gpio = Interrupt::Gpio as u32, + Ata = Interrupt::Ata as u32, + Umd = Interrupt::Umd as u32, + Dmacplus = Interrupt::Dmacplus as u32, + Ge = Interrupt::Ge as u32, + Display = Interrupt::Vblank as u32, + } + + #[repr(u32)] + pub enum SceKernelIdListType { + Thread = 1, + Semaphore = 2, + EventFlag = 3, + Mbox = 4, + Vpl = 5, + Fpl = 6, + Mpipe = 7, + Callback = 8, + ThreadEventHandler = 9, + Alarm = 10, + VTimer = 11, + SleepThread = 64, + DelayThread = 65, + SuspendThread = 66, + DormantThread = 67, + } + + #[repr(i32)] + pub enum UsbCamResolution { + Px160_120 = 0, + Px176_144 = 1, + Px320_240 = 2, + Px352_288 = 3, + Px640_480 = 4, + Px1024_768 = 5, + Px1280_960 = 6, + Px480_272 = 7, + Px360_272 = 8, + } + + #[repr(i32)] + pub enum UsbCamResolutionEx { + Px160_120 = 0, + Px176_144 = 1, + Px320_240 = 2, + Px352_288 = 3, + Px360_272 = 4, + Px480_272 = 5, + Px640_480 = 6, + Px1024_768 = 7, + Px1280_960 = 8, + } + + #[repr(i32)] + pub enum UsbCamDelay { + NoDelay = 0, + Delay10Sec = 1, + Delay20Sec = 2, + Delay30Sec = 3, + } + + #[repr(i32)] + pub enum UsbCamFrameRate { + Fps3_75 = 0, + Fps5 = 1, + Fps7_5 = 2, + Fps10 = 3, + Fps15 = 4, + Fps20 = 5, + Fps30 = 6, + Fps60 = 7, + } + + #[repr(i32)] + pub enum UsbCamWb { + Auto = 0, + Daylight = 1, + Fluorescent = 2, + Incadescent = 3, + } + + #[repr(i32)] + pub enum UsbCamEffectMode { + Normal = 0, + Negative = 1, + Blackwhite = 2, + Sepia = 3, + Blue = 4, + Red = 5, + Green = 6, + } + + #[repr(i32)] + pub enum UsbCamEvLevel { + Pos2_0 = 0, + Pos1_7 = 1, + Pos1_5 = 2, + Pos1_3 = 3, + Pos1_0 = 4, + Pos0_7 = 5, + Pos0_5 = 6, + Pos0_3 = 7, + Zero = 8, + Neg0_3, + Neg0_5, + Neg0_7, + Neg1_0, + Neg1_3, + Neg1_5, + Neg1_7, + Neg2_0, + } + + #[repr(i32)] + pub enum RtcCheckValidError { + InvalidYear = -1, + InvalidMonth = -2, + InvalidDay = -3, + InvalidHour = -4, + InvalidMinutes = -5, + InvalidSeconds = -6, + InvalidMicroseconds = -7, + } + + #[repr(u32)] + pub enum PowerTick { + All = 0, + Suspend = 1, + Display = 6, + } + + #[repr(u32)] + pub enum IoAssignPerms { + RdWr = 0, + RdOnly = 1, + } + + #[repr(u32)] + pub enum IoWhence { + Set = 0, + Cur = 1, + End = 2, + } + + #[repr(u32)] + pub enum UmdType { + Game = 0x10, + Video = 0x20, + Audio = 0x40, + } + + #[repr(u32)] + pub enum GuPrimitive { + Points = 0, + Lines = 1, + LineStrip = 2, + Triangles = 3, + TriangleStrip = 4, + TriangleFan = 5, + Sprites = 6, + } + + #[repr(u32)] + pub enum PatchPrimitive { + Points = 0, + LineStrip = 2, + TriangleStrip = 4, + } + + #[repr(u32)] + pub enum GuState { + AlphaTest = 0, + DepthTest = 1, + ScissorTest = 2, + StencilTest = 3, + Blend = 4, + CullFace = 5, + Dither = 6, + Fog = 7, + ClipPlanes = 8, + Texture2D = 9, + Lighting = 10, + Light0 = 11, + Light1 = 12, + Light2 = 13, + Light3 = 14, + LineSmooth = 15, + PatchCullFace = 16, + ColorTest = 17, + ColorLogicOp = 18, + FaceNormalReverse = 19, + PatchFace = 20, + Fragment2X = 21, + } + + #[repr(u32)] + pub enum MatrixMode { + Projection = 0, + View = 1, + Model = 2, + Texture = 3, + } + + #[repr(u32)] + pub enum TexturePixelFormat { + Psm5650 = 0, + Psm5551 = 1, + Psm4444 = 2, + Psm8888 = 3, + PsmT4 = 4, + PsmT8 = 5, + PsmT16 = 6, + PsmT32 = 7, + PsmDxt1 = 8, + PsmDxt3 = 9, + PsmDxt5 = 10, + } + + #[repr(u32)] + pub enum SplineMode { + FillFill = 0, + OpenFill = 1, + FillOpen = 2, + OpenOpen = 3, + } + + #[repr(u32)] + pub enum ShadingModel { + Flat = 0, + Smooth = 1, + } + + #[repr(u32)] + pub enum LogicalOperation { + Clear = 0, + And = 1, + AndReverse = 2, + Copy = 3, + AndInverted = 4, + Noop = 5, + Xor = 6, + Or = 7, + Nor = 8, + Equiv = 9, + Inverted = 10, + OrReverse = 11, + CopyInverted = 12, + OrInverted = 13, + Nand = 14, + Set = 15, + } + + #[repr(u32)] + pub enum TextureFilter { + Nearest = 0, + Linear = 1, + NearestMipmapNearest = 4, + LinearMipmapNearest = 5, + NearestMipmapLinear = 6, + LinearMipmapLinear = 7, + } + + #[repr(u32)] + pub enum TextureMapMode { + TextureCoords = 0, + TextureMatrix = 1, + EnvironmentMap = 2, + } + + #[repr(u32)] + pub enum TextureLevelMode { + Auto = 0, + Const = 1, + Slope = 2, + } + + #[repr(u32)] + pub enum TextureProjectionMapMode { + Position = 0, + Uv = 1, + NormalizedNormal = 2, + Normal = 3, + } + + #[repr(u32)] + pub enum GuTexWrapMode { + Repeat = 0, + Clamp = 1, + } + + #[repr(u32)] + pub enum FrontFaceDirection { + Clockwise = 0, + CounterClockwise = 1, + } + + #[repr(u32)] + pub enum AlphaFunc { + Never = 0, + Always, + Equal, + NotEqual, + Less, + LessOrEqual, + Greater, + GreaterOrEqual, + } + + #[repr(u32)] + pub enum StencilFunc { + Never = 0, + Always, + Equal, + NotEqual, + Less, + LessOrEqual, + Greater, + GreaterOrEqual, + } + + #[repr(u32)] + pub enum ColorFunc { + Never = 0, + Always, + Equal, + NotEqual, + } + + #[repr(u32)] + pub enum DepthFunc { + Never = 0, + Always, + Equal, + NotEqual, + Less, + LessOrEqual, + Greater, + GreaterOrEqual, + } + + #[repr(u32)] + pub enum TextureEffect { + Modulate = 0, + Decal = 1, + Blend = 2, + Replace = 3, + Add = 4, + } + + #[repr(u32)] + pub enum TextureColorComponent { + Rgb = 0, + Rgba = 1, + } + + #[repr(u32)] + pub enum MipmapLevel { + None = 0, + Level1, + Level2, + Level3, + Level4, + Level5, + Level6, + Level7, + } + + #[repr(u32)] + pub enum BlendOp { + Add = 0, + Subtract = 1, + ReverseSubtract = 2, + Min = 3, + Max = 4, + Abs = 5, + } + + #[repr(u32)] + pub enum BlendSrc { + SrcColor = 0, + OneMinusSrcColor = 1, + SrcAlpha = 2, + OneMinusSrcAlpha = 3, + Fix = 10, + } + + #[repr(u32)] + pub enum BlendDst { + DstColor = 0, + OneMinusDstColor = 1, + DstAlpha = 4, + OneMinusDstAlpha = 5, + Fix = 10, + } + + #[repr(u32)] + pub enum StencilOperation { + Keep = 0, + Zero = 1, + Replace = 2, + Invert = 3, + Incr = 4, + Decr = 5, + } + + #[repr(u32)] + pub enum LightMode { + SingleColor = 0, + SeparateSpecularColor = 1, + } + + #[repr(u32)] + pub enum LightType { + Directional = 0, + Pointlight = 1, + Spotlight = 2, + } + + #[repr(u32)] + pub enum GuContextType { + Direct = 0, + Call = 1, + Send = 2, + } + + #[repr(u32)] + pub enum GuQueueMode { + Tail = 0, + Head = 1, + } + + #[repr(u32)] + pub enum GuSyncMode { + Finish = 0, + Signal = 1, + Done = 2, + List = 3, + Send = 4, + } + + #[repr(u32)] + pub enum GuSyncBehavior { + Wait = 0, + NoWait = 1, + } + + #[repr(u32)] + pub enum GuCallbackId { + Signal = 1, + Finish = 4, + } + + #[repr(u32)] + pub enum SignalBehavior { + Suspend = 1, + Continue = 2, + } + + #[repr(u32)] + pub enum ClutPixelFormat { + Psm5650 = 0, + Psm5551 = 1, + Psm4444 = 2, + Psm8888 = 3, + } + + #[repr(C)] + pub enum KeyType { + Directory = 1, + Integer = 2, + String = 3, + Bytes = 4, + } + + #[repr(u32)] + pub enum UtilityMsgDialogMode { + Error, + Text, + } + + #[repr(u32)] + pub enum UtilityMsgDialogPressed { + Unknown1, + Yes, + No, + Back, + } + + #[repr(u32)] + pub enum UtilityDialogButtonAccept { + Circle, + Cross, + } + + #[repr(u32)] + pub enum SceUtilityOskInputLanguage { + Default, + Japanese, + English, + French, + Spanish, + German, + Italian, + Dutch, + Portugese, + Russian, + Korean, + } + + #[repr(u32)] + pub enum SceUtilityOskInputType { + All, + LatinDigit, + LatinSymbol, + LatinLowercase = 4, + LatinUppercase = 8, + JapaneseDigit = 0x100, + JapaneseSymbol = 0x200, + JapaneseLowercase = 0x400, + JapaneseUppercase = 0x800, + JapaneseHiragana = 0x1000, + JapaneseHalfWidthKatakana = 0x2000, + JapaneseKatakana = 0x4000, + JapaneseKanji = 0x8000, + RussianLowercase = 0x10000, + RussianUppercase = 0x20000, + Korean = 0x40000, + Url = 0x80000, + } + + #[repr(u32)] + pub enum SceUtilityOskState { + None, + Initializing, + Initialized, + Visible, + Quit, + Finished, + } + + #[repr(u32)] + pub enum SceUtilityOskResult { + Unchanged, + Cancelled, + Changed, + } + + #[repr(u32)] + pub enum SystemParamLanguage { + Japanese, + English, + French, + Spanish, + German, + Italian, + Dutch, + Portugese, + Russian, + Korean, + ChineseTraditional, + ChineseSimplified, + } + + #[repr(u32)] + pub enum SystemParamId { + StringNickname = 1, + AdhocChannel, + WlanPowerSave, + DateFormat, + TimeFormat, + Timezone, + DaylightSavings, + Language, + Unknown, + } + + #[repr(u32)] + pub enum SystemParamAdhocChannel { + ChannelAutomatic = 0, + Channel1 = 1, + Channel6 = 6, + Channel11 = 11, + } + + #[repr(u32)] + pub enum SystemParamWlanPowerSaveState { + Off, + On, + } + + #[repr(u32)] + pub enum SystemParamDateFormat { + YYYYMMDD, + MMDDYYYY, + DDMMYYYY, + } + + #[repr(u32)] + pub enum SystemParamTimeFormat { + Hour24, + Hour12, + } + + #[repr(u32)] + pub enum SystemParamDaylightSavings { + Std, + Dst, + } + + #[repr(u32)] + pub enum AvModule { + AvCodec, + SasCore, + Atrac3Plus, + MpegBase, + Mp3, + Vaudio, + Aac, + G729, + } + + #[repr(u32)] + pub enum Module { + NetCommon = 0x100, + NetAdhoc, + NetInet, + NetParseUri, + NetHttp, + NetSsl, + + UsbPspCm = 0x200, + UsbMic, + UsbCam, + UsbGps, + + AvCodec = 0x300, + AvSascore, + AvAtrac3Plus, + AvMpegBase, + AvMp3, + AvVaudio, + AvAac, + AvG729, + + NpCommon = 0x400, + NpService, + NpMatching2, + NpDrm = 0x500, + + Irda = 0x600, + } + + #[repr(u32)] + pub enum NetModule { + NetCommon = 1, + NetAdhoc, + NetInet, + NetParseUri, + NetHttp, + NetSsl, + } + + #[repr(u32)] + pub enum UsbModule { + UsbPspCm = 1, + UsbAcc, + UsbMic, + UsbCam, + UsbGps, + } + + #[repr(u32)] + pub enum NetParam { + Name, + Ssid, + Secure, + WepKey, + IsStaticIp, + Ip, + NetMask, + Route, + ManualDns, + PrimaryDns, + SecondaryDns, + ProxyUser, + ProxyPass, + UseProxy, + ProxyServer, + ProxyPort, + Unknown1, + Unknown2, + } + + #[repr(u32)] + pub enum UtilityNetconfAction { + ConnectAP, + DisplayStatus, + ConnectAdhoc, + } + + #[repr(u32)] + pub enum UtilitySavedataMode { + AutoLoad, + AutoSave, + Load, + Save, + ListLoad, + ListSave, + ListDelete, + Delete, + } + + #[repr(u32)] + pub enum UtilitySavedataFocus { + Unknown1, + FirstList, + LastList, + Latest, + Oldest, + Unknown2, + Unknown3, + FirstEmpty, + LastEmpty, + } + + #[repr(u32)] + pub enum UtilityGameSharingMode { + Single = 1, + Multiple, + } + + #[repr(u32)] + pub enum UtilityGameSharingDataType { + File = 1, + Memory, + } + + #[repr(u32)] + pub enum UtilityHtmlViewerInterfaceMode { + Full, + Limited, + None, + } + + #[repr(u32)] + pub enum UtilityHtmlViewerCookieMode { + Disabled = 0, + Enabled, + Confirm, + Default, + } + + #[repr(u32)] + pub enum UtilityHtmlViewerTextSize { + Large, + Normal, + Small, + } + + #[repr(u32)] + pub enum UtilityHtmlViewerDisplayMode { + Normal, + Fit, + SmartFit, + } + + #[repr(u32)] + pub enum UtilityHtmlViewerConnectMode { + Last, + ManualOnce, + ManualAll, + } + + #[repr(u32)] + pub enum UtilityHtmlViewerDisconnectMode { + Enable, + Disable, + Confirm, + } + + #[repr(u32)] + pub enum ScePspnetAdhocPtpState { + Closed, + Listen, + SynSent, + SynReceived, + Established, + } + + #[repr(u32)] + pub enum AdhocMatchingMode { + Host = 1, + Client, + Ptp, + } + + #[repr(u32)] + pub enum ApctlState { + Disconnected, + Scanning, + Joining, + GettingIp, + GotIp, + EapAuth, + KeyExchange, + } + + #[repr(u32)] + pub enum ApctlEvent { + ConnectRequest, + ScanRequest, + ScanComplete, + Established, + GetIp, + DisconnectRequest, + Error, + Info, + EapAuth, + KeyExchange, + Reconnect, + } + + #[repr(u32)] + pub enum ApctlInfo { + ProfileName, + Bssid, + Ssid, + SsidLength, + SecurityType, + Strength, + Channel, + PowerSave, + Ip, + SubnetMask, + Gateway, + PrimaryDns, + SecondaryDns, + UseProxy, + ProxyUrl, + ProxyPort, + EapType, + StartBrowser, + Wifisp, + } + + #[repr(u32)] + pub enum ApctlInfoSecurityType { + None, + Wep, + Wpa, + } + + #[repr(u32)] + pub enum HttpMethod { + Get, + Post, + Head, + } + + #[repr(u32)] + pub enum HttpAuthType { + Basic, + Digest, + } +} + +s_paren! { + #[repr(transparent)] + pub struct SceUid(pub i32); + + #[repr(transparent)] + #[allow(dead_code)] + pub struct SceMpeg(*mut *mut c_void); + + #[repr(transparent)] + #[allow(dead_code)] + pub struct SceMpegStream(*mut c_void); + + #[repr(transparent)] + pub struct Mp3Handle(pub i32); + + #[repr(transparent)] + #[allow(dead_code)] + pub struct RegHandle(u32); +} + +s! { + pub struct sockaddr { + pub sa_len: u8, + pub sa_family: u8, + pub sa_data: [u8;14], + } + + pub struct in_addr { + pub s_addr: u32, + } + + pub struct AudioInputParams { + pub unknown1: i32, + pub gain: i32, + pub unknown2: i32, + pub unknown3: i32, + pub unknown4: i32, + pub unknown5: i32, + } + + pub struct Atrac3BufferInfo { + pub puc_write_position_first_buf: *mut u8, + pub ui_writable_byte_first_buf: u32, + pub ui_min_write_byte_first_buf: u32, + pub ui_read_position_first_buf: u32, + pub puc_write_position_second_buf: *mut u8, + pub ui_writable_byte_second_buf: u32, + pub ui_min_write_byte_second_buf: u32, + pub ui_read_position_second_buf: u32, + } + + pub struct SceCtrlData { + pub timestamp: u32, + pub buttons: i32, + pub lx: u8, + pub ly: u8, + pub rsrv: [u8; 6], + } + + pub struct SceCtrlLatch { + pub ui_make: u32, + pub ui_break: u32, + pub ui_press: u32, + pub ui_release: u32, + } + + pub struct GeStack { + pub stack: [u32; 8], + } + + pub struct GeCallbackData { + pub signal_func: ::Option, + pub signal_arg: *mut c_void, + pub finish_func: ::Option, + pub finish_arg: *mut c_void, + } + + pub struct GeListArgs { + pub size: u32, + pub context: *mut GeContext, + pub num_stacks: u32, + pub stacks: *mut GeStack, + } + + pub struct GeBreakParam { + pub buf: [u32; 4], + } + + pub struct SceKernelLoadExecParam { + pub size: usize, + pub args: usize, + pub argp: *mut c_void, + pub key: *const u8, + } + + pub struct timeval { + pub tv_sec: i32, + pub tv_usec: i32, + } + + pub struct timezone { + pub tz_minutes_west: i32, + pub tz_dst_time: i32, + } + + pub struct IntrHandlerOptionParam { + size: i32, + entry: u32, + common: u32, + gp: u32, + intr_code: u16, + sub_count: u16, + intr_level: u16, + enabled: u16, + calls: u32, + field_1c: u32, + total_clock_lo: u32, + total_clock_hi: u32, + min_clock_lo: u32, + min_clock_hi: u32, + max_clock_lo: u32, + max_clock_hi: u32, + } + + pub struct SceKernelLMOption { + pub size: usize, + pub m_pid_text: SceUid, + pub m_pid_data: SceUid, + pub flags: u32, + pub position: u8, + pub access: u8, + pub c_reserved: [u8; 2usize], + } + + pub struct SceKernelSMOption { + pub size: usize, + pub m_pid_stack: SceUid, + pub stack_size: usize, + pub priority: i32, + pub attribute: u32, + } + + pub struct SceKernelModuleInfo { + pub size: usize, + pub n_segment: u8, + pub reserved: [u8; 3usize], + pub segment_addr: [i32; 4usize], + pub segment_size: [i32; 4usize], + pub entry_addr: u32, + pub gp_value: u32, + pub text_addr: u32, + pub text_size: u32, + pub data_size: u32, + pub bss_size: u32, + pub attribute: u16, + pub version: [u8; 2usize], + pub name: [u8; 28usize], + } + + pub struct DebugProfilerRegs { + pub enable: u32, + pub systemck: u32, + pub cpuck: u32, + pub internal: u32, + pub memory: u32, + pub copz: u32, + pub vfpu: u32, + pub sleep: u32, + pub bus_access: u32, + pub uncached_load: u32, + pub uncached_store: u32, + pub cached_load: u32, + pub cached_store: u32, + pub i_miss: u32, + pub d_miss: u32, + pub d_writeback: u32, + pub cop0_inst: u32, + pub fpu_inst: u32, + pub vfpu_inst: u32, + pub local_bus: u32, + } + + pub struct SceKernelSysClock { + pub low: u32, + pub hi: u32, + } + + pub struct SceKernelThreadOptParam { + pub size: usize, + pub stack_mpid: SceUid, + } + + pub struct SceKernelThreadInfo { + pub size: usize, + pub name: [u8; 32], + pub attr: u32, + pub status: i32, + pub entry: SceKernelThreadEntry, + pub stack: *mut c_void, + pub stack_size: i32, + pub gp_reg: *mut c_void, + pub init_priority: i32, + pub current_priority: i32, + pub wait_type: i32, + pub wait_id: SceUid, + pub wakeup_count: i32, + pub exit_status: i32, + pub run_clocks: SceKernelSysClock, + pub intr_preempt_count: u32, + pub thread_preempt_count: u32, + pub release_count: u32, + } + + pub struct SceKernelThreadRunStatus { + pub size: usize, + pub status: i32, + pub current_priority: i32, + pub wait_type: i32, + pub wait_id: i32, + pub wakeup_count: i32, + pub run_clocks: SceKernelSysClock, + pub intr_preempt_count: u32, + pub thread_preempt_count: u32, + pub release_count: u32, + } + + pub struct SceKernelSemaOptParam { + pub size: usize, + } + + pub struct SceKernelSemaInfo { + pub size: usize, + pub name: [u8; 32], + pub attr: u32, + pub init_count: i32, + pub current_count: i32, + pub max_count: i32, + pub num_wait_threads: i32, + } + + pub struct SceKernelEventFlagInfo { + pub size: usize, + pub name: [u8; 32], + pub attr: u32, + pub init_pattern: u32, + pub current_pattern: u32, + pub num_wait_threads: i32, + } + + pub struct SceKernelEventFlagOptParam { + pub size: usize, + } + + pub struct SceKernelMbxOptParam { + pub size: usize, + } + + pub struct SceKernelMbxInfo { + pub size: usize, + pub name: [u8; 32usize], + pub attr: u32, + pub num_wait_threads: i32, + pub num_messages: i32, + pub first_message: *mut c_void, + } + + pub struct SceKernelVTimerInfo { + pub size: usize, + pub name: [u8; 32], + pub active: i32, + pub base: SceKernelSysClock, + pub current: SceKernelSysClock, + pub schedule: SceKernelSysClock, + pub handler: SceKernelVTimerHandler, + pub common: *mut c_void, + } + + pub struct SceKernelThreadEventHandlerInfo { + pub size: usize, + pub name: [u8; 32], + pub thread_id: SceUid, + pub mask: i32, + pub handler: SceKernelThreadEventHandler, + pub common: *mut c_void, + } + + pub struct SceKernelAlarmInfo { + pub size: usize, + pub schedule: SceKernelSysClock, + pub handler: SceKernelAlarmHandler, + pub common: *mut c_void, + } + + pub struct SceKernelSystemStatus { + pub size: usize, + pub status: u32, + pub idle_clocks: SceKernelSysClock, + pub comes_out_of_idle_count: u32, + pub thread_switch_count: u32, + pub vfpu_switch_count: u32, + } + + pub struct SceKernelMppInfo { + pub size: usize, + pub name: [u8; 32], + pub attr: u32, + pub buf_size: i32, + pub free_size: i32, + pub num_send_wait_threads: i32, + pub num_receive_wait_threads: i32, + } + + pub struct SceKernelVplOptParam { + pub size: usize, + } + + pub struct SceKernelVplInfo { + pub size: usize, + pub name: [u8; 32], + pub attr: u32, + pub pool_size: i32, + pub free_size: i32, + pub num_wait_threads: i32, + } + + pub struct SceKernelFplOptParam { + pub size: usize, + } + + pub struct SceKernelFplInfo { + pub size: usize, + pub name: [u8; 32usize], + pub attr: u32, + pub block_size: i32, + pub num_blocks: i32, + pub free_blocks: i32, + pub num_wait_threads: i32, + } + + pub struct SceKernelVTimerOptParam { + pub size: usize, + } + + pub struct SceKernelCallbackInfo { + pub size: usize, + pub name: [u8; 32usize], + pub thread_id: SceUid, + pub callback: SceKernelCallbackFunction, + pub common: *mut c_void, + pub notify_count: i32, + pub notify_arg: i32, + } + + pub struct UsbCamSetupStillParam { + pub size: i32, + pub resolution: UsbCamResolution, + pub jpeg_size: i32, + pub reverse_flags: i32, + pub delay: UsbCamDelay, + pub comp_level: i32, + } + + pub struct UsbCamSetupStillExParam { + pub size: i32, + pub unk: u32, + pub resolution: UsbCamResolutionEx, + pub jpeg_size: i32, + pub comp_level: i32, + pub unk2: u32, + pub unk3: u32, + pub flip: i32, + pub mirror: i32, + pub delay: UsbCamDelay, + pub unk4: [u32; 5usize], + } + + pub struct UsbCamSetupVideoParam { + pub size: i32, + pub resolution: UsbCamResolution, + pub framerate: UsbCamFrameRate, + pub white_balance: UsbCamWb, + pub saturation: i32, + pub brightness: i32, + pub contrast: i32, + pub sharpness: i32, + pub effect_mode: UsbCamEffectMode, + pub frame_size: i32, + pub unk: u32, + pub evl_evel: UsbCamEvLevel, + } + + pub struct UsbCamSetupVideoExParam { + pub size: i32, + pub unk: u32, + pub resolution: UsbCamResolutionEx, + pub framerate: UsbCamFrameRate, + pub unk2: u32, + pub unk3: u32, + pub white_balance: UsbCamWb, + pub saturation: i32, + pub brightness: i32, + pub contrast: i32, + pub sharpness: i32, + pub unk4: u32, + pub unk5: u32, + pub unk6: [u32; 3usize], + pub effect_mode: UsbCamEffectMode, + pub unk7: u32, + pub unk8: u32, + pub unk9: u32, + pub unk10: u32, + pub unk11: u32, + pub frame_size: i32, + pub unk12: u32, + pub ev_level: UsbCamEvLevel, + } + + pub struct ScePspDateTime { + pub year: u16, + pub month: u16, + pub day: u16, + pub hour: u16, + pub minutes: u16, + pub seconds: u16, + pub microseconds: u32, + } + + pub struct SceIoStat { + pub st_mode: i32, + pub st_attr: i32, + pub st_size: i64, + pub st_ctime: ScePspDateTime, + pub st_atime: ScePspDateTime, + pub st_mtime: ScePspDateTime, + pub st_private: [u32; 6usize], + } + + pub struct UmdInfo { + pub size: u32, + pub type_: UmdType, + } + + pub struct SceMpegRingbuffer { + pub packets: i32, + pub unk0: u32, + pub unk1: u32, + pub unk2: u32, + pub unk3: u32, + pub data: *mut c_void, + pub callback: SceMpegRingbufferCb, + pub cb_param: *mut c_void, + pub unk4: u32, + pub unk5: u32, + pub sce_mpeg: *mut c_void, + } + + pub struct SceMpegAu { + pub pts_msb: u32, + pub pts: u32, + pub dts_msb: u32, + pub dts: u32, + pub es_buffer: u32, + pub au_size: u32, + } + + pub struct SceMpegAvcMode { + pub unk0: i32, + pub pixel_format: super::DisplayPixelFormat, + } + + #[repr(align(64))] + pub struct SceMpegLLI { + pub src: *mut c_void, + pub dst: *mut c_void, + pub next: *mut c_void, + pub size: i32, + } + + #[repr(align(64))] + pub struct SceMpegYCrCbBuffer { + pub frame_buffer_height16: i32, + pub frame_buffer_width16: i32, + pub unknown: i32, + pub unknown2: i32, + pub y_buffer: *mut c_void, + pub y_buffer2: *mut c_void, + pub cr_buffer: *mut c_void, + pub cb_buffer: *mut c_void, + pub cr_buffer2: *mut c_void, + pub cb_buffer2: *mut c_void, + + pub frame_height: i32, + pub frame_width: i32, + pub frame_buffer_width: i32, + pub unknown3: [i32; 11usize], + } + + pub struct ScePspSRect { + pub x: i16, + pub y: i16, + pub w: i16, + pub h: i16, + } + + pub struct ScePspIRect { + pub x: i32, + pub y: i32, + pub w: i32, + pub h: i32, + } + + pub struct ScePspL64Rect { + pub x: u64, + pub y: u64, + pub w: u64, + pub h: u64, + } + + pub struct ScePspSVector2 { + pub x: i16, + pub y: i16, + } + + pub struct ScePspIVector2 { + pub x: i32, + pub y: i32, + } + + pub struct ScePspL64Vector2 { + pub x: u64, + pub y: u64, + } + + pub struct ScePspSVector3 { + pub x: i16, + pub y: i16, + pub z: i16, + } + + pub struct ScePspIVector3 { + pub x: i32, + pub y: i32, + pub z: i32, + } + + pub struct ScePspL64Vector3 { + pub x: u64, + pub y: u64, + pub z: u64, + } + + pub struct ScePspSVector4 { + pub x: i16, + pub y: i16, + pub z: i16, + pub w: i16, + } + + pub struct ScePspIVector4 { + pub x: i32, + pub y: i32, + pub z: i32, + pub w: i32, + } + + pub struct ScePspL64Vector4 { + pub x: u64, + pub y: u64, + pub z: u64, + pub w: u64, + } + + pub struct ScePspIMatrix2 { + pub x: ScePspIVector2, + pub y: ScePspIVector2, + } + + pub struct ScePspIMatrix3 { + pub x: ScePspIVector3, + pub y: ScePspIVector3, + pub z: ScePspIVector3, + } + + #[repr(align(16))] + pub struct ScePspIMatrix4 { + pub x: ScePspIVector4, + pub y: ScePspIVector4, + pub z: ScePspIVector4, + pub w: ScePspIVector4, + } + + pub struct ScePspIMatrix4Unaligned { + pub x: ScePspIVector4, + pub y: ScePspIVector4, + pub z: ScePspIVector4, + pub w: ScePspIVector4, + } + + pub struct SceMp3InitArg { + pub mp3_stream_start: u32, + pub unk1: u32, + pub mp3_stream_end: u32, + pub unk2: u32, + pub mp3_buf: *mut c_void, + pub mp3_buf_size: i32, + pub pcm_buf: *mut c_void, + pub pcm_buf_size: i32, + } + + pub struct OpenPSID { + pub data: [u8; 16usize], + } + + pub struct UtilityDialogCommon { + pub size: u32, + pub language: SystemParamLanguage, + pub button_accept: UtilityDialogButtonAccept, + pub graphics_thread: i32, + pub access_thread: i32, + pub font_thread: i32, + pub sound_thread: i32, + pub result: i32, + pub reserved: [i32; 4usize], + } + + pub struct UtilityNetconfAdhoc { + pub name: [u8; 8usize], + pub timeout: u32, + } + + pub struct UtilityNetconfData { + pub base: UtilityDialogCommon, + pub action: UtilityNetconfAction, + pub adhocparam: *mut UtilityNetconfAdhoc, + pub hotspot: i32, + pub hotspot_connected: i32, + pub wifisp: i32, + } + + pub struct UtilitySavedataFileData { + pub buf: *mut c_void, + pub buf_size: usize, + pub size: usize, + pub unknown: i32, + } + + pub struct UtilitySavedataListSaveNewData { + pub icon0: UtilitySavedataFileData, + pub title: *mut u8, + } + + pub struct UtilityGameSharingParams { + pub base: UtilityDialogCommon, + pub unknown1: i32, + pub unknown2: i32, + pub name: [u8; 8usize], + pub unknown3: i32, + pub unknown4: i32, + pub unknown5: i32, + pub result: i32, + pub filepath: *mut u8, + pub mode: UtilityGameSharingMode, + pub datatype: UtilityGameSharingDataType, + pub data: *mut c_void, + pub datasize: u32, + } + + pub struct UtilityHtmlViewerParam { + pub base: UtilityDialogCommon, + pub memaddr: *mut c_void, + pub memsize: u32, + pub unknown1: i32, + pub unknown2: i32, + pub initialurl: *mut u8, + pub numtabs: u32, + pub interfacemode: UtilityHtmlViewerInterfaceMode, + pub options: i32, + pub dldirname: *mut u8, + pub dlfilename: *mut u8, + pub uldirname: *mut u8, + pub ulfilename: *mut u8, + pub cookiemode: UtilityHtmlViewerCookieMode, + pub unknown3: u32, + pub homeurl: *mut u8, + pub textsize: UtilityHtmlViewerTextSize, + pub displaymode: UtilityHtmlViewerDisplayMode, + pub connectmode: UtilityHtmlViewerConnectMode, + pub disconnectmode: UtilityHtmlViewerDisconnectMode, + pub memused: u32, + pub unknown4: [i32; 10usize], + } + + pub struct SceUtilityOskData { + pub unk_00: i32, + pub unk_04: i32, + pub language: SceUtilityOskInputLanguage, + pub unk_12: i32, + pub inputtype: SceUtilityOskInputType, + pub lines: i32, + pub unk_24: i32, + pub desc: *mut u16, + pub intext: *mut u16, + pub outtextlength: i32, + pub outtext: *mut u16, + pub result: SceUtilityOskResult, + pub outtextlimit: i32, + } + + pub struct SceUtilityOskParams { + pub base: UtilityDialogCommon, + pub datacount: i32, + pub data: *mut SceUtilityOskData, + pub state: SceUtilityOskState, + pub unk_60: i32, + } + + pub struct SceNetMallocStat { + pub pool: i32, + pub maximum: i32, + pub free: i32, + } + + pub struct SceNetAdhocctlAdhocId { + pub unknown: i32, + pub adhoc_id: [u8; 9usize], + pub unk: [u8; 3usize], + } + + pub struct SceNetAdhocctlScanInfo { + pub next: *mut SceNetAdhocctlScanInfo, + pub channel: i32, + pub name: [u8; 8usize], + pub bssid: [u8; 6usize], + pub unknown: [u8; 2usize], + pub unknown2: i32, + } + + pub struct SceNetAdhocctlGameModeInfo { + pub count: i32, + pub macs: [[u8; 6usize]; 16usize], + } + + pub struct SceNetAdhocPtpStat { + pub next: *mut SceNetAdhocPtpStat, + pub ptp_id: i32, + pub mac: [u8; 6usize], + pub peermac: [u8; 6usize], + pub port: u16, + pub peerport: u16, + pub sent_data: u32, + pub rcvd_data: u32, + pub state: ScePspnetAdhocPtpState, + } + + pub struct SceNetAdhocPdpStat { + pub next: *mut SceNetAdhocPdpStat, + pub pdp_id: i32, + pub mac: [u8; 6usize], + pub port: u16, + pub rcvd_data: u32, + } + + pub struct AdhocPoolStat { + pub size: i32, + pub maxsize: i32, + pub freesize: i32, + } +} + +s_no_extra_traits! { + #[allow(missing_debug_implementations)] + pub struct GeContext { + pub context: [u32; 512], + } + + #[allow(missing_debug_implementations)] + pub struct SceKernelUtilsSha1Context { + pub h: [u32; 5usize], + pub us_remains: u16, + pub us_computed: u16, + pub ull_total_len: u64, + pub buf: [u8; 64usize], + } + + #[allow(missing_debug_implementations)] + pub struct SceKernelUtilsMt19937Context { + pub count: u32, + pub state: [u32; 624usize], + } + + #[allow(missing_debug_implementations)] + pub struct SceKernelUtilsMd5Context { + pub h: [u32; 4usize], + pub pad: u32, + pub us_remains: u16, + pub us_computed: u16, + pub ull_total_len: u64, + pub buf: [u8; 64usize], + } + + #[allow(missing_debug_implementations)] + pub struct SceIoDirent { + pub d_stat: SceIoStat, + pub d_name: [u8; 256usize], + pub d_private: *mut c_void, + pub dummy: i32, + } + + #[cfg_attr(feature = "extra_traits", derive(Debug))] + pub struct ScePspFRect { + pub x: f32, + pub y: f32, + pub w: f32, + pub h: f32, + } + + #[repr(align(16))] + #[cfg_attr(feature = "extra_traits", derive(Debug))] + pub struct ScePspFVector3 { + pub x: f32, + pub y: f32, + pub z: f32, + } + + #[repr(align(16))] + #[cfg_attr(feature = "extra_traits", derive(Debug))] + pub struct ScePspFVector4 { + pub x: f32, + pub y: f32, + pub z: f32, + pub w: f32, + } + + #[cfg_attr(feature = "extra_traits", derive(Debug))] + pub struct ScePspFVector4Unaligned { + pub x: f32, + pub y: f32, + pub z: f32, + pub w: f32, + } + + #[cfg_attr(feature = "extra_traits", derive(Debug))] + pub struct ScePspFVector2 { + pub x: f32, + pub y: f32, + } + + #[cfg_attr(feature = "extra_traits", derive(Debug))] + pub struct ScePspFMatrix2 { + pub x: ScePspFVector2, + pub y: ScePspFVector2, + } + + #[cfg_attr(feature = "extra_traits", derive(Debug))] + pub struct ScePspFMatrix3 { + pub x: ScePspFVector3, + pub y: ScePspFVector3, + pub z: ScePspFVector3, + } + + #[cfg_attr(feature = "extra_traits", derive(Debug))] + #[repr(align(16))] + pub struct ScePspFMatrix4 { + pub x: ScePspFVector4, + pub y: ScePspFVector4, + pub z: ScePspFVector4, + pub w: ScePspFVector4, + } + + #[allow(missing_debug_implementations)] + pub struct ScePspFMatrix4Unaligned { + pub x: ScePspFVector4, + pub y: ScePspFVector4, + pub z: ScePspFVector4, + pub w: ScePspFVector4, + } + + #[allow(missing_debug_implementations)] + pub union ScePspVector3 { + pub fv: ScePspFVector3, + pub iv: ScePspIVector3, + pub f: [f32; 3usize], + pub i: [i32; 3usize], + } + + #[allow(missing_debug_implementations)] + pub union ScePspVector4 { + pub fv: ScePspFVector4, + pub iv: ScePspIVector4, + pub qw: u128, + pub f: [f32; 4usize], + pub i: [i32; 4usize], + } + + #[allow(missing_debug_implementations)] + pub union ScePspMatrix2 { + pub fm: ScePspFMatrix2, + pub im: ScePspIMatrix2, + pub fv: [ScePspFVector2; 2usize], + pub iv: [ScePspIVector2; 2usize], + pub v: [ScePspVector2; 2usize], + pub f: [[f32; 2usize]; 2usize], + pub i: [[i32; 2usize]; 2usize], + } + + #[allow(missing_debug_implementations)] + pub union ScePspMatrix3 { + pub fm: ScePspFMatrix3, + pub im: ScePspIMatrix3, + pub fv: [ScePspFVector3; 3usize], + pub iv: [ScePspIVector3; 3usize], + pub v: [ScePspVector3; 3usize], + pub f: [[f32; 3usize]; 3usize], + pub i: [[i32; 3usize]; 3usize], + } + + #[allow(missing_debug_implementations)] + pub union ScePspVector2 { + pub fv: ScePspFVector2, + pub iv: ScePspIVector2, + pub f: [f32; 2usize], + pub i: [i32; 2usize], + } + + #[allow(missing_debug_implementations)] + pub union ScePspMatrix4 { + pub fm: ScePspFMatrix4, + pub im: ScePspIMatrix4, + pub fv: [ScePspFVector4; 4usize], + pub iv: [ScePspIVector4; 4usize], + pub v: [ScePspVector4; 4usize], + pub f: [[f32; 4usize]; 4usize], + pub i: [[i32; 4usize]; 4usize], + } + + #[allow(missing_debug_implementations)] + pub struct Key { + pub key_type: KeyType, + pub name: [u8; 256usize], + pub name_len: u32, + pub unk2: u32, + pub unk3: u32, + } + + #[allow(missing_debug_implementations)] + pub struct UtilityMsgDialogParams { + pub base: UtilityDialogCommon, + pub unknown: i32, + pub mode: UtilityMsgDialogMode, + pub error_value: u32, + pub message: [u8; 512usize], + pub options: i32, + pub button_pressed: UtilityMsgDialogPressed, + } + + #[allow(missing_debug_implementations)] + pub union UtilityNetData { + pub as_uint: u32, + pub as_string: [u8; 128usize], + } + + #[allow(missing_debug_implementations)] + pub struct UtilitySavedataSFOParam { + pub title: [u8; 128usize], + pub savedata_title: [u8; 128usize], + pub detail: [u8; 1024usize], + pub parental_level: u8, + pub unknown: [u8; 3usize], + } + + #[allow(missing_debug_implementations)] + pub struct SceUtilitySavedataParam { + pub base: UtilityDialogCommon, + pub mode: UtilitySavedataMode, + pub unknown1: i32, + pub overwrite: i32, + pub game_name: [u8; 13usize], + pub reserved: [u8; 3usize], + pub save_name: [u8; 20usize], + pub save_name_list: *mut [u8; 20usize], + pub file_name: [u8; 13usize], + pub reserved1: [u8; 3usize], + pub data_buf: *mut c_void, + pub data_buf_size: usize, + pub data_size: usize, + pub sfo_param: UtilitySavedataSFOParam, + pub icon0_file_data: UtilitySavedataFileData, + pub icon1_file_data: UtilitySavedataFileData, + pub pic1_file_data: UtilitySavedataFileData, + pub snd0_file_data: UtilitySavedataFileData, + pub new_data: *mut UtilitySavedataListSaveNewData, + pub focus: UtilitySavedataFocus, + pub unknown2: [i32; 4usize], + pub key: [u8; 16], + pub unknown3: [u8; 20], + } + + #[allow(missing_debug_implementations)] + pub struct SceNetAdhocctlPeerInfo { + pub next: *mut SceNetAdhocctlPeerInfo, + pub nickname: [u8; 128usize], + pub mac: [u8; 6usize], + pub unknown: [u8; 6usize], + pub timestamp: u32, + } + + #[allow(missing_debug_implementations)] + pub struct SceNetAdhocctlParams { + pub channel: i32, + pub name: [u8; 8usize], + pub bssid: [u8; 6usize], + pub nickname: [u8; 128usize], + } + + #[cfg_attr(feature = "extra_traits", allow(missing_debug_implementations))] + pub union SceNetApctlInfo { + pub name: [u8; 64usize], + pub bssid: [u8; 6usize], + pub ssid: [u8; 32usize], + pub ssid_length: u32, + pub security_type: u32, + pub strength: u8, + pub channel: u8, + pub power_save: u8, + pub ip: [u8; 16usize], + pub sub_net_mask: [u8; 16usize], + pub gateway: [u8; 16usize], + pub primary_dns: [u8; 16usize], + pub secondary_dns: [u8; 16usize], + pub use_proxy: u32, + pub proxy_url: [u8; 128usize], + pub proxy_port: u16, + pub eap_type: u32, + pub start_browser: u32, + pub wifisp: u32, + } +} + +pub const INT_MIN: c_int = -2147483648; +pub const INT_MAX: c_int = 2147483647; + +pub const AUDIO_VOLUME_MAX: u32 = 0x8000; +pub const AUDIO_CHANNEL_MAX: u32 = 8; +pub const AUDIO_NEXT_CHANNEL: i32 = -1; +pub const AUDIO_SAMPLE_MIN: u32 = 64; +pub const AUDIO_SAMPLE_MAX: u32 = 65472; + +pub const PSP_CTRL_SELECT: i32 = 0x000001; +pub const PSP_CTRL_START: i32 = 0x000008; +pub const PSP_CTRL_UP: i32 = 0x000010; +pub const PSP_CTRL_RIGHT: i32 = 0x000020; +pub const PSP_CTRL_DOWN: i32 = 0x000040; +pub const PSP_CTRL_LEFT: i32 = 0x000080; +pub const PSP_CTRL_LTRIGGER: i32 = 0x000100; +pub const PSP_CTRL_RTRIGGER: i32 = 0x000200; +pub const PSP_CTRL_TRIANGLE: i32 = 0x001000; +pub const PSP_CTRL_CIRCLE: i32 = 0x002000; +pub const PSP_CTRL_CROSS: i32 = 0x004000; +pub const PSP_CTRL_SQUARE: i32 = 0x008000; +pub const PSP_CTRL_HOME: i32 = 0x010000; +pub const PSP_CTRL_HOLD: i32 = 0x020000; +pub const PSP_CTRL_NOTE: i32 = 0x800000; +pub const PSP_CTRL_SCREEN: i32 = 0x400000; +pub const PSP_CTRL_VOLUP: i32 = 0x100000; +pub const PSP_CTRL_VOLDOWN: i32 = 0x200000; +pub const PSP_CTRL_WLAN_UP: i32 = 0x040000; +pub const PSP_CTRL_REMOTE: i32 = 0x080000; +pub const PSP_CTRL_DISC: i32 = 0x1000000; +pub const PSP_CTRL_MS: i32 = 0x2000000; + +pub const USB_CAM_PID: i32 = 0x282; +pub const USB_BUS_DRIVER_NAME: &str = "USBBusDriver"; +pub const USB_CAM_DRIVER_NAME: &str = "USBCamDriver"; +pub const USB_CAM_MIC_DRIVER_NAME: &str = "USBCamMicDriver"; +pub const USB_STOR_DRIVER_NAME: &str = "USBStor_Driver"; + +pub const ACTIVATED: i32 = 0x200; +pub const CONNECTED: i32 = 0x020; +pub const ESTABLISHED: i32 = 0x002; + +pub const USB_CAM_FLIP: i32 = 1; +pub const USB_CAM_MIRROR: i32 = 0x100; + +pub const THREAD_ATTR_VFPU: i32 = 0x00004000; +pub const THREAD_ATTR_USER: i32 = 0x80000000; +pub const THREAD_ATTR_USBWLAN: i32 = 0xa0000000; +pub const THREAD_ATTR_VSH: i32 = 0xc0000000; +pub const THREAD_ATTR_SCRATCH_SRAM: i32 = 0x00008000; +pub const THREAD_ATTR_NO_FILLSTACK: i32 = 0x00100000; +pub const THREAD_ATTR_CLEAR_STACK: i32 = 0x00200000; + +pub const EVENT_WAIT_MULTIPLE: i32 = 0x200; + +pub const EVENT_WAIT_AND: i32 = 0; +pub const EVENT_WAIT_OR: i32 = 1; +pub const EVENT_WAIT_CLEAR: i32 = 0x20; + +pub const POWER_INFO_POWER_SWITCH: i32 = 0x80000000; +pub const POWER_INFO_HOLD_SWITCH: i32 = 0x40000000; +pub const POWER_INFO_STANDBY: i32 = 0x00080000; +pub const POWER_INFO_RESUME_COMPLETE: i32 = 0x00040000; +pub const POWER_INFO_RESUMING: i32 = 0x00020000; +pub const POWER_INFO_SUSPENDING: i32 = 0x00010000; +pub const POWER_INFO_AC_POWER: i32 = 0x00001000; +pub const POWER_INFO_BATTERY_LOW: i32 = 0x00000100; +pub const POWER_INFO_BATTERY_EXIST: i32 = 0x00000080; +pub const POWER_INFO_BATTERY_POWER: i32 = 0x0000007; + +pub const FIO_S_IFLNK: i32 = 0x4000; +pub const FIO_S_IFDIR: i32 = 0x1000; +pub const FIO_S_IFREG: i32 = 0x2000; +pub const FIO_S_ISUID: i32 = 0x0800; +pub const FIO_S_ISGID: i32 = 0x0400; +pub const FIO_S_ISVTX: i32 = 0x0200; +pub const FIO_S_IRUSR: i32 = 0x0100; +pub const FIO_S_IWUSR: i32 = 0x0080; +pub const FIO_S_IXUSR: i32 = 0x0040; +pub const FIO_S_IRGRP: i32 = 0x0020; +pub const FIO_S_IWGRP: i32 = 0x0010; +pub const FIO_S_IXGRP: i32 = 0x0008; +pub const FIO_S_IROTH: i32 = 0x0004; +pub const FIO_S_IWOTH: i32 = 0x0002; +pub const FIO_S_IXOTH: i32 = 0x0001; + +pub const FIO_SO_IFLNK: i32 = 0x0008; +pub const FIO_SO_IFDIR: i32 = 0x0010; +pub const FIO_SO_IFREG: i32 = 0x0020; +pub const FIO_SO_IROTH: i32 = 0x0004; +pub const FIO_SO_IWOTH: i32 = 0x0002; +pub const FIO_SO_IXOTH: i32 = 0x0001; + +pub const PSP_O_RD_ONLY: i32 = 0x0001; +pub const PSP_O_WR_ONLY: i32 = 0x0002; +pub const PSP_O_RD_WR: i32 = 0x0003; +pub const PSP_O_NBLOCK: i32 = 0x0004; +pub const PSP_O_DIR: i32 = 0x0008; +pub const PSP_O_APPEND: i32 = 0x0100; +pub const PSP_O_CREAT: i32 = 0x0200; +pub const PSP_O_TRUNC: i32 = 0x0400; +pub const PSP_O_EXCL: i32 = 0x0800; +pub const PSP_O_NO_WAIT: i32 = 0x8000; + +pub const UMD_NOT_PRESENT: i32 = 0x01; +pub const UMD_PRESENT: i32 = 0x02; +pub const UMD_CHANGED: i32 = 0x04; +pub const UMD_INITING: i32 = 0x08; +pub const UMD_INITED: i32 = 0x10; +pub const UMD_READY: i32 = 0x20; + +pub const PLAY_PAUSE: i32 = 0x1; +pub const FORWARD: i32 = 0x4; +pub const BACK: i32 = 0x8; +pub const VOL_UP: i32 = 0x10; +pub const VOL_DOWN: i32 = 0x20; +pub const HOLD: i32 = 0x80; + +pub const GU_PI: f32 = 3.141593; + +pub const GU_TEXTURE_8BIT: i32 = 1; +pub const GU_TEXTURE_16BIT: i32 = 2; +pub const GU_TEXTURE_32BITF: i32 = 3; +pub const GU_COLOR_5650: i32 = 4 << 2; +pub const GU_COLOR_5551: i32 = 5 << 2; +pub const GU_COLOR_4444: i32 = 6 << 2; +pub const GU_COLOR_8888: i32 = 7 << 2; +pub const GU_NORMAL_8BIT: i32 = 1 << 5; +pub const GU_NORMAL_16BIT: i32 = 2 << 5; +pub const GU_NORMAL_32BITF: i32 = 3 << 5; +pub const GU_VERTEX_8BIT: i32 = 1 << 7; +pub const GU_VERTEX_16BIT: i32 = 2 << 7; +pub const GU_VERTEX_32BITF: i32 = 3 << 7; +pub const GU_WEIGHT_8BIT: i32 = 1 << 9; +pub const GU_WEIGHT_16BIT: i32 = 2 << 9; +pub const GU_WEIGHT_32BITF: i32 = 3 << 9; +pub const GU_INDEX_8BIT: i32 = 1 << 11; +pub const GU_INDEX_16BIT: i32 = 2 << 11; +pub const GU_WEIGHTS1: i32 = (((1 - 1) & 7) << 14) as i32; +pub const GU_WEIGHTS2: i32 = (((2 - 1) & 7) << 14) as i32; +pub const GU_WEIGHTS3: i32 = (((3 - 1) & 7) << 14) as i32; +pub const GU_WEIGHTS4: i32 = (((4 - 1) & 7) << 14) as i32; +pub const GU_WEIGHTS5: i32 = (((5 - 1) & 7) << 14) as i32; +pub const GU_WEIGHTS6: i32 = (((6 - 1) & 7) << 14) as i32; +pub const GU_WEIGHTS7: i32 = (((7 - 1) & 7) << 14) as i32; +pub const GU_WEIGHTS8: i32 = (((8 - 1) & 7) << 14) as i32; +pub const GU_VERTICES1: i32 = (((1 - 1) & 7) << 18) as i32; +pub const GU_VERTICES2: i32 = (((2 - 1) & 7) << 18) as i32; +pub const GU_VERTICES3: i32 = (((3 - 1) & 7) << 18) as i32; +pub const GU_VERTICES4: i32 = (((4 - 1) & 7) << 18) as i32; +pub const GU_VERTICES5: i32 = (((5 - 1) & 7) << 18) as i32; +pub const GU_VERTICES6: i32 = (((6 - 1) & 7) << 18) as i32; +pub const GU_VERTICES7: i32 = (((7 - 1) & 7) << 18) as i32; +pub const GU_VERTICES8: i32 = (((8 - 1) & 7) << 18) as i32; +pub const GU_TRANSFORM_2D: i32 = 1 << 23; +pub const GU_TRANSFORM_3D: i32 = 0; + +pub const GU_COLOR_BUFFER_BIT: i32 = 1; +pub const GU_STENCIL_BUFFER_BIT: i32 = 2; +pub const GU_DEPTH_BUFFER_BIT: i32 = 4; +pub const GU_FAST_CLEAR_BIT: i32 = 16; + +pub const GU_AMBIENT: i32 = 1; +pub const GU_DIFFUSE: i32 = 2; +pub const GU_SPECULAR: i32 = 4; +pub const GU_UNKNOWN_LIGHT_COMPONENT: i32 = 8; + +pub const SYSTEM_REGISTRY: [u8; 7] = *b"/system"; +pub const REG_KEYNAME_SIZE: u32 = 27; + +pub const UTILITY_MSGDIALOG_ERROR: i32 = 0; +pub const UTILITY_MSGDIALOG_TEXT: i32 = 1; +pub const UTILITY_MSGDIALOG_YES_NO_BUTTONS: i32 = 0x10; +pub const UTILITY_MSGDIALOG_DEFAULT_NO: i32 = 0x100; + +pub const UTILITY_HTMLVIEWER_OPEN_SCE_START_PAGE: i32 = 0x000001; +pub const UTILITY_HTMLVIEWER_DISABLE_STARTUP_LIMITS: i32 = 0x000002; +pub const UTILITY_HTMLVIEWER_DISABLE_EXIT_DIALOG: i32 = 0x000004; +pub const UTILITY_HTMLVIEWER_DISABLE_CURSOR: i32 = 0x000008; +pub const UTILITY_HTMLVIEWER_DISABLE_DOWNLOAD_COMPLETE_DIALOG: i32 = 0x000010; +pub const UTILITY_HTMLVIEWER_DISABLE_DOWNLOAD_START_DIALOG: i32 = 0x000020; +pub const UTILITY_HTMLVIEWER_DISABLE_DOWNLOAD_DESTINATION_DIALOG: i32 = 0x000040; +pub const UTILITY_HTMLVIEWER_LOCK_DOWNLOAD_DESTINATION_DIALOG: i32 = 0x000080; +pub const UTILITY_HTMLVIEWER_DISABLE_TAB_DISPLAY: i32 = 0x000100; +pub const UTILITY_HTMLVIEWER_ENABLE_ANALOG_HOLD: i32 = 0x000200; +pub const UTILITY_HTMLVIEWER_ENABLE_FLASH: i32 = 0x000400; +pub const UTILITY_HTMLVIEWER_DISABLE_LRTRIGGER: i32 = 0x000800; + +extern "C" { + pub fn sceAudioChReserve(channel: i32, sample_count: i32, format: AudioFormat) -> i32; + pub fn sceAudioChRelease(channel: i32) -> i32; + pub fn sceAudioOutput(channel: i32, vol: i32, buf: *mut c_void) -> i32; + pub fn sceAudioOutputBlocking(channel: i32, vol: i32, buf: *mut c_void) -> i32; + pub fn sceAudioOutputPanned( + channel: i32, + left_vol: i32, + right_vol: i32, + buf: *mut c_void, + ) -> i32; + pub fn sceAudioOutputPannedBlocking( + channel: i32, + left_vol: i32, + right_vol: i32, + buf: *mut c_void, + ) -> i32; + pub fn sceAudioGetChannelRestLen(channel: i32) -> i32; + pub fn sceAudioGetChannelRestLength(channel: i32) -> i32; + pub fn sceAudioSetChannelDataLen(channel: i32, sample_count: i32) -> i32; + pub fn sceAudioChangeChannelConfig(channel: i32, format: AudioFormat) -> i32; + pub fn sceAudioChangeChannelVolume(channel: i32, left_vol: i32, right_vol: i32) -> i32; + pub fn sceAudioOutput2Reserve(sample_count: i32) -> i32; + pub fn sceAudioOutput2Release() -> i32; + pub fn sceAudioOutput2ChangeLength(sample_count: i32) -> i32; + pub fn sceAudioOutput2OutputBlocking(vol: i32, buf: *mut c_void) -> i32; + pub fn sceAudioOutput2GetRestSample() -> i32; + pub fn sceAudioSRCChReserve( + sample_count: i32, + freq: AudioOutputFrequency, + channels: i32, + ) -> i32; + pub fn sceAudioSRCChRelease() -> i32; + pub fn sceAudioSRCOutputBlocking(vol: i32, buf: *mut c_void) -> i32; + pub fn sceAudioInputInit(unknown1: i32, gain: i32, unknown2: i32) -> i32; + pub fn sceAudioInputInitEx(params: *mut AudioInputParams) -> i32; + pub fn sceAudioInputBlocking(sample_count: i32, freq: AudioInputFrequency, buf: *mut c_void); + pub fn sceAudioInput(sample_count: i32, freq: AudioInputFrequency, buf: *mut c_void); + pub fn sceAudioGetInputLength() -> i32; + pub fn sceAudioWaitInputEnd() -> i32; + pub fn sceAudioPollInputEnd() -> i32; + + pub fn sceAtracGetAtracID(ui_codec_type: u32) -> i32; + pub fn sceAtracSetDataAndGetID(buf: *mut c_void, bufsize: usize) -> i32; + pub fn sceAtracDecodeData( + atrac_id: i32, + out_samples: *mut u16, + out_n: *mut i32, + out_end: *mut i32, + out_remain_frame: *mut i32, + ) -> i32; + pub fn sceAtracGetRemainFrame(atrac_id: i32, out_remain_frame: *mut i32) -> i32; + pub fn sceAtracGetStreamDataInfo( + atrac_id: i32, + write_pointer: *mut *mut u8, + available_bytes: *mut u32, + read_offset: *mut u32, + ) -> i32; + pub fn sceAtracAddStreamData(atrac_id: i32, bytes_to_add: u32) -> i32; + pub fn sceAtracGetBitrate(atrac_id: i32, out_bitrate: *mut i32) -> i32; + pub fn sceAtracSetLoopNum(atrac_id: i32, nloops: i32) -> i32; + pub fn sceAtracReleaseAtracID(atrac_id: i32) -> i32; + pub fn sceAtracGetNextSample(atrac_id: i32, out_n: *mut i32) -> i32; + pub fn sceAtracGetMaxSample(atrac_id: i32, out_max: *mut i32) -> i32; + pub fn sceAtracGetBufferInfoForReseting( + atrac_id: i32, + ui_sample: u32, + pbuffer_info: *mut Atrac3BufferInfo, + ) -> i32; + pub fn sceAtracGetChannel(atrac_id: i32, pui_channel: *mut u32) -> i32; + pub fn sceAtracGetInternalErrorInfo(atrac_id: i32, pi_result: *mut i32) -> i32; + pub fn sceAtracGetLoopStatus( + atrac_id: i32, + pi_loop_num: *mut i32, + pui_loop_status: *mut u32, + ) -> i32; + pub fn sceAtracGetNextDecodePosition(atrac_id: i32, pui_sample_position: *mut u32) -> i32; + pub fn sceAtracGetSecondBufferInfo( + atrac_id: i32, + pui_position: *mut u32, + pui_data_byte: *mut u32, + ) -> i32; + pub fn sceAtracGetSoundSample( + atrac_id: i32, + pi_end_sample: *mut i32, + pi_loop_start_sample: *mut i32, + pi_loop_end_sample: *mut i32, + ) -> i32; + pub fn sceAtracResetPlayPosition( + atrac_id: i32, + ui_sample: u32, + ui_write_byte_first_buf: u32, + ui_write_byte_second_buf: u32, + ) -> i32; + pub fn sceAtracSetData(atrac_id: i32, puc_buffer_addr: *mut u8, ui_buffer_byte: u32) -> i32; + pub fn sceAtracSetHalfwayBuffer( + atrac_id: i32, + puc_buffer_addr: *mut u8, + ui_read_byte: u32, + ui_buffer_byte: u32, + ) -> i32; + pub fn sceAtracSetHalfwayBufferAndGetID( + puc_buffer_addr: *mut u8, + ui_read_byte: u32, + ui_buffer_byte: u32, + ) -> i32; + pub fn sceAtracSetSecondBuffer( + atrac_id: i32, + puc_second_buffer_addr: *mut u8, + ui_second_buffer_byte: u32, + ) -> i32; + + pub fn sceCtrlSetSamplingCycle(cycle: i32) -> i32; + pub fn sceCtrlGetSamplingCycle(pcycle: *mut i32) -> i32; + pub fn sceCtrlSetSamplingMode(mode: CtrlMode) -> i32; + pub fn sceCtrlGetSamplingMode(pmode: *mut i32) -> i32; + pub fn sceCtrlPeekBufferPositive(pad_data: *mut SceCtrlData, count: i32) -> i32; + pub fn sceCtrlPeekBufferNegative(pad_data: *mut SceCtrlData, count: i32) -> i32; + pub fn sceCtrlReadBufferPositive(pad_data: *mut SceCtrlData, count: i32) -> i32; + pub fn sceCtrlReadBufferNegative(pad_data: *mut SceCtrlData, count: i32) -> i32; + pub fn sceCtrlPeekLatch(latch_data: *mut SceCtrlLatch) -> i32; + pub fn sceCtrlReadLatch(latch_data: *mut SceCtrlLatch) -> i32; + pub fn sceCtrlSetIdleCancelThreshold(idlereset: i32, idleback: i32) -> i32; + pub fn sceCtrlGetIdleCancelThreshold(idlereset: *mut i32, idleback: *mut i32) -> i32; + + pub fn sceDisplaySetMode(mode: DisplayMode, width: usize, height: usize) -> u32; + pub fn sceDisplayGetMode(pmode: *mut i32, pwidth: *mut i32, pheight: *mut i32) -> i32; + pub fn sceDisplaySetFrameBuf( + top_addr: *const u8, + buffer_width: usize, + pixel_format: DisplayPixelFormat, + sync: DisplaySetBufSync, + ) -> u32; + pub fn sceDisplayGetFrameBuf( + top_addr: *mut *mut c_void, + buffer_width: *mut usize, + pixel_format: *mut DisplayPixelFormat, + sync: DisplaySetBufSync, + ) -> i32; + pub fn sceDisplayGetVcount() -> u32; + pub fn sceDisplayWaitVblank() -> i32; + pub fn sceDisplayWaitVblankCB() -> i32; + pub fn sceDisplayWaitVblankStart() -> i32; + pub fn sceDisplayWaitVblankStartCB() -> i32; + pub fn sceDisplayGetAccumulatedHcount() -> i32; + pub fn sceDisplayGetCurrentHcount() -> i32; + pub fn sceDisplayGetFramePerSec() -> f32; + pub fn sceDisplayIsForeground() -> i32; + pub fn sceDisplayIsVblank() -> i32; + + pub fn sceGeEdramGetSize() -> u32; + pub fn sceGeEdramGetAddr() -> *mut u8; + pub fn sceGeEdramSetAddrTranslation(width: i32) -> i32; + pub fn sceGeGetCmd(cmd: i32) -> u32; + pub fn sceGeGetMtx(type_: GeMatrixType, matrix: *mut c_void) -> i32; + pub fn sceGeGetStack(stack_id: i32, stack: *mut GeStack) -> i32; + pub fn sceGeSaveContext(context: *mut GeContext) -> i32; + pub fn sceGeRestoreContext(context: *const GeContext) -> i32; + pub fn sceGeListEnQueue( + list: *const c_void, + stall: *mut c_void, + cbid: i32, + arg: *mut GeListArgs, + ) -> i32; + pub fn sceGeListEnQueueHead( + list: *const c_void, + stall: *mut c_void, + cbid: i32, + arg: *mut GeListArgs, + ) -> i32; + pub fn sceGeListDeQueue(qid: i32) -> i32; + pub fn sceGeListUpdateStallAddr(qid: i32, stall: *mut c_void) -> i32; + pub fn sceGeListSync(qid: i32, sync_type: i32) -> GeListState; + pub fn sceGeDrawSync(sync_type: i32) -> GeListState; + pub fn sceGeBreak(mode: i32, p_param: *mut GeBreakParam) -> i32; + pub fn sceGeContinue() -> i32; + pub fn sceGeSetCallback(cb: *mut GeCallbackData) -> i32; + pub fn sceGeUnsetCallback(cbid: i32) -> i32; + + pub fn sceKernelExitGame(); + pub fn sceKernelRegisterExitCallback(id: SceUid) -> i32; + pub fn sceKernelLoadExec(file: *const u8, param: *mut SceKernelLoadExecParam) -> i32; + + pub fn sceKernelAllocPartitionMemory( + partition: SceSysMemPartitionId, + name: *const u8, + type_: SceSysMemBlockTypes, + size: u32, + addr: *mut c_void, + ) -> SceUid; + pub fn sceKernelGetBlockHeadAddr(blockid: SceUid) -> *mut c_void; + pub fn sceKernelFreePartitionMemory(blockid: SceUid) -> i32; + pub fn sceKernelTotalFreeMemSize() -> usize; + pub fn sceKernelMaxFreeMemSize() -> usize; + pub fn sceKernelDevkitVersion() -> u32; + pub fn sceKernelSetCompiledSdkVersion(version: u32) -> i32; + pub fn sceKernelGetCompiledSdkVersion() -> u32; + + pub fn sceKernelLibcTime(t: *mut i32) -> i32; + pub fn sceKernelLibcClock() -> u32; + pub fn sceKernelLibcGettimeofday(tp: *mut timeval, tzp: *mut timezone) -> i32; + pub fn sceKernelDcacheWritebackAll(); + pub fn sceKernelDcacheWritebackInvalidateAll(); + pub fn sceKernelDcacheWritebackRange(p: *const c_void, size: u32); + pub fn sceKernelDcacheWritebackInvalidateRange(p: *const c_void, size: u32); + pub fn sceKernelDcacheInvalidateRange(p: *const c_void, size: u32); + pub fn sceKernelIcacheInvalidateAll(); + pub fn sceKernelIcacheInvalidateRange(p: *const c_void, size: u32); + pub fn sceKernelUtilsMt19937Init(ctx: *mut SceKernelUtilsMt19937Context, seed: u32) -> i32; + pub fn sceKernelUtilsMt19937UInt(ctx: *mut SceKernelUtilsMt19937Context) -> u32; + pub fn sceKernelUtilsMd5Digest(data: *mut u8, size: u32, digest: *mut u8) -> i32; + pub fn sceKernelUtilsMd5BlockInit(ctx: *mut SceKernelUtilsMd5Context) -> i32; + pub fn sceKernelUtilsMd5BlockUpdate( + ctx: *mut SceKernelUtilsMd5Context, + data: *mut u8, + size: u32, + ) -> i32; + pub fn sceKernelUtilsMd5BlockResult(ctx: *mut SceKernelUtilsMd5Context, digest: *mut u8) + -> i32; + pub fn sceKernelUtilsSha1Digest(data: *mut u8, size: u32, digest: *mut u8) -> i32; + pub fn sceKernelUtilsSha1BlockInit(ctx: *mut SceKernelUtilsSha1Context) -> i32; + pub fn sceKernelUtilsSha1BlockUpdate( + ctx: *mut SceKernelUtilsSha1Context, + data: *mut u8, + size: u32, + ) -> i32; + pub fn sceKernelUtilsSha1BlockResult( + ctx: *mut SceKernelUtilsSha1Context, + digest: *mut u8, + ) -> i32; + + pub fn sceKernelRegisterSubIntrHandler( + int_no: i32, + no: i32, + handler: *mut c_void, + arg: *mut c_void, + ) -> i32; + pub fn sceKernelReleaseSubIntrHandler(int_no: i32, no: i32) -> i32; + pub fn sceKernelEnableSubIntr(int_no: i32, no: i32) -> i32; + pub fn sceKernelDisableSubIntr(int_no: i32, no: i32) -> i32; + pub fn QueryIntrHandlerInfo( + intr_code: SceUid, + sub_intr_code: SceUid, + data: *mut IntrHandlerOptionParam, + ) -> i32; + + pub fn sceKernelCpuSuspendIntr() -> u32; + pub fn sceKernelCpuResumeIntr(flags: u32); + pub fn sceKernelCpuResumeIntrWithSync(flags: u32); + pub fn sceKernelIsCpuIntrSuspended(flags: u32) -> i32; + pub fn sceKernelIsCpuIntrEnable() -> i32; + + pub fn sceKernelLoadModule( + path: *const u8, + flags: i32, + option: *mut SceKernelLMOption, + ) -> SceUid; + pub fn sceKernelLoadModuleMs( + path: *const u8, + flags: i32, + option: *mut SceKernelLMOption, + ) -> SceUid; + pub fn sceKernelLoadModuleByID( + fid: SceUid, + flags: i32, + option: *mut SceKernelLMOption, + ) -> SceUid; + pub fn sceKernelLoadModuleBufferUsbWlan( + buf_size: usize, + buf: *mut c_void, + flags: i32, + option: *mut SceKernelLMOption, + ) -> SceUid; + pub fn sceKernelStartModule( + mod_id: SceUid, + arg_size: usize, + argp: *mut c_void, + status: *mut i32, + option: *mut SceKernelSMOption, + ) -> i32; + pub fn sceKernelStopModule( + mod_id: SceUid, + arg_size: usize, + argp: *mut c_void, + status: *mut i32, + option: *mut SceKernelSMOption, + ) -> i32; + pub fn sceKernelUnloadModule(mod_id: SceUid) -> i32; + pub fn sceKernelSelfStopUnloadModule(unknown: i32, arg_size: usize, argp: *mut c_void) -> i32; + pub fn sceKernelStopUnloadSelfModule( + arg_size: usize, + argp: *mut c_void, + status: *mut i32, + option: *mut SceKernelSMOption, + ) -> i32; + pub fn sceKernelQueryModuleInfo(mod_id: SceUid, info: *mut SceKernelModuleInfo) -> i32; + pub fn sceKernelGetModuleIdList( + read_buf: *mut SceUid, + read_buf_size: i32, + id_count: *mut i32, + ) -> i32; + + pub fn sceKernelVolatileMemLock(unk: i32, ptr: *mut *mut c_void, size: *mut i32) -> i32; + pub fn sceKernelVolatileMemTryLock(unk: i32, ptr: *mut *mut c_void, size: *mut i32) -> i32; + pub fn sceKernelVolatileMemUnlock(unk: i32) -> i32; + + pub fn sceKernelStdin() -> SceUid; + pub fn sceKernelStdout() -> SceUid; + pub fn sceKernelStderr() -> SceUid; + + pub fn sceKernelGetThreadmanIdType(uid: SceUid) -> SceKernelIdListType; + pub fn sceKernelCreateThread( + name: *const u8, + entry: SceKernelThreadEntry, + init_priority: i32, + stack_size: i32, + attr: i32, + option: *mut SceKernelThreadOptParam, + ) -> SceUid; + pub fn sceKernelDeleteThread(thid: SceUid) -> i32; + pub fn sceKernelStartThread(id: SceUid, arg_len: usize, arg_p: *mut c_void) -> i32; + pub fn sceKernelExitThread(status: i32) -> i32; + pub fn sceKernelExitDeleteThread(status: i32) -> i32; + pub fn sceKernelTerminateThread(thid: SceUid) -> i32; + pub fn sceKernelTerminateDeleteThread(thid: SceUid) -> i32; + pub fn sceKernelSuspendDispatchThread() -> i32; + pub fn sceKernelResumeDispatchThread(state: i32) -> i32; + pub fn sceKernelSleepThread() -> i32; + pub fn sceKernelSleepThreadCB() -> i32; + pub fn sceKernelWakeupThread(thid: SceUid) -> i32; + pub fn sceKernelCancelWakeupThread(thid: SceUid) -> i32; + pub fn sceKernelSuspendThread(thid: SceUid) -> i32; + pub fn sceKernelResumeThread(thid: SceUid) -> i32; + pub fn sceKernelWaitThreadEnd(thid: SceUid, timeout: *mut u32) -> i32; + pub fn sceKernelWaitThreadEndCB(thid: SceUid, timeout: *mut u32) -> i32; + pub fn sceKernelDelayThread(delay: u32) -> i32; + pub fn sceKernelDelayThreadCB(delay: u32) -> i32; + pub fn sceKernelDelaySysClockThread(delay: *mut SceKernelSysClock) -> i32; + pub fn sceKernelDelaySysClockThreadCB(delay: *mut SceKernelSysClock) -> i32; + pub fn sceKernelChangeCurrentThreadAttr(unknown: i32, attr: i32) -> i32; + pub fn sceKernelChangeThreadPriority(thid: SceUid, priority: i32) -> i32; + pub fn sceKernelRotateThreadReadyQueue(priority: i32) -> i32; + pub fn sceKernelReleaseWaitThread(thid: SceUid) -> i32; + pub fn sceKernelGetThreadId() -> i32; + pub fn sceKernelGetThreadCurrentPriority() -> i32; + pub fn sceKernelGetThreadExitStatus(thid: SceUid) -> i32; + pub fn sceKernelCheckThreadStack() -> i32; + pub fn sceKernelGetThreadStackFreeSize(thid: SceUid) -> i32; + pub fn sceKernelReferThreadStatus(thid: SceUid, info: *mut SceKernelThreadInfo) -> i32; + pub fn sceKernelReferThreadRunStatus( + thid: SceUid, + status: *mut SceKernelThreadRunStatus, + ) -> i32; + pub fn sceKernelCreateSema( + name: *const u8, + attr: u32, + init_val: i32, + max_val: i32, + option: *mut SceKernelSemaOptParam, + ) -> SceUid; + pub fn sceKernelDeleteSema(sema_id: SceUid) -> i32; + pub fn sceKernelSignalSema(sema_id: SceUid, signal: i32) -> i32; + pub fn sceKernelWaitSema(sema_id: SceUid, signal: i32, timeout: *mut u32) -> i32; + pub fn sceKernelWaitSemaCB(sema_id: SceUid, signal: i32, timeout: *mut u32) -> i32; + pub fn sceKernelPollSema(sema_id: SceUid, signal: i32) -> i32; + pub fn sceKernelReferSemaStatus(sema_id: SceUid, info: *mut SceKernelSemaInfo) -> i32; + pub fn sceKernelCreateEventFlag( + name: *const u8, + attr: i32, + bits: i32, + opt: *mut SceKernelEventFlagOptParam, + ) -> SceUid; + pub fn sceKernelSetEventFlag(ev_id: SceUid, bits: u32) -> i32; + pub fn sceKernelClearEventFlag(ev_id: SceUid, bits: u32) -> i32; + pub fn sceKernelPollEventFlag(ev_id: SceUid, bits: u32, wait: i32, out_bits: *mut u32) -> i32; + pub fn sceKernelWaitEventFlag( + ev_id: SceUid, + bits: u32, + wait: i32, + out_bits: *mut u32, + timeout: *mut u32, + ) -> i32; + pub fn sceKernelWaitEventFlagCB( + ev_id: SceUid, + bits: u32, + wait: i32, + out_bits: *mut u32, + timeout: *mut u32, + ) -> i32; + pub fn sceKernelDeleteEventFlag(ev_id: SceUid) -> i32; + pub fn sceKernelReferEventFlagStatus(event: SceUid, status: *mut SceKernelEventFlagInfo) + -> i32; + pub fn sceKernelCreateMbx( + name: *const u8, + attr: u32, + option: *mut SceKernelMbxOptParam, + ) -> SceUid; + pub fn sceKernelDeleteMbx(mbx_id: SceUid) -> i32; + pub fn sceKernelSendMbx(mbx_id: SceUid, message: *mut c_void) -> i32; + pub fn sceKernelReceiveMbx(mbx_id: SceUid, message: *mut *mut c_void, timeout: *mut u32) + -> i32; + pub fn sceKernelReceiveMbxCB( + mbx_id: SceUid, + message: *mut *mut c_void, + timeout: *mut u32, + ) -> i32; + pub fn sceKernelPollMbx(mbx_id: SceUid, pmessage: *mut *mut c_void) -> i32; + pub fn sceKernelCancelReceiveMbx(mbx_id: SceUid, num: *mut i32) -> i32; + pub fn sceKernelReferMbxStatus(mbx_id: SceUid, info: *mut SceKernelMbxInfo) -> i32; + pub fn sceKernelSetAlarm( + clock: u32, + handler: SceKernelAlarmHandler, + common: *mut c_void, + ) -> SceUid; + pub fn sceKernelSetSysClockAlarm( + clock: *mut SceKernelSysClock, + handler: *mut SceKernelAlarmHandler, + common: *mut c_void, + ) -> SceUid; + pub fn sceKernelCancelAlarm(alarm_id: SceUid) -> i32; + pub fn sceKernelReferAlarmStatus(alarm_id: SceUid, info: *mut SceKernelAlarmInfo) -> i32; + pub fn sceKernelCreateCallback( + name: *const u8, + func: SceKernelCallbackFunction, + arg: *mut c_void, + ) -> SceUid; + pub fn sceKernelReferCallbackStatus(cb: SceUid, status: *mut SceKernelCallbackInfo) -> i32; + pub fn sceKernelDeleteCallback(cb: SceUid) -> i32; + pub fn sceKernelNotifyCallback(cb: SceUid, arg2: i32) -> i32; + pub fn sceKernelCancelCallback(cb: SceUid) -> i32; + pub fn sceKernelGetCallbackCount(cb: SceUid) -> i32; + pub fn sceKernelCheckCallback() -> i32; + pub fn sceKernelGetThreadmanIdList( + type_: SceKernelIdListType, + read_buf: *mut SceUid, + read_buf_size: i32, + id_count: *mut i32, + ) -> i32; + pub fn sceKernelReferSystemStatus(status: *mut SceKernelSystemStatus) -> i32; + pub fn sceKernelCreateMsgPipe( + name: *const u8, + part: i32, + attr: i32, + unk1: *mut c_void, + opt: *mut c_void, + ) -> SceUid; + pub fn sceKernelDeleteMsgPipe(uid: SceUid) -> i32; + pub fn sceKernelSendMsgPipe( + uid: SceUid, + message: *mut c_void, + size: u32, + unk1: i32, + unk2: *mut c_void, + timeout: *mut u32, + ) -> i32; + pub fn sceKernelSendMsgPipeCB( + uid: SceUid, + message: *mut c_void, + size: u32, + unk1: i32, + unk2: *mut c_void, + timeout: *mut u32, + ) -> i32; + pub fn sceKernelTrySendMsgPipe( + uid: SceUid, + message: *mut c_void, + size: u32, + unk1: i32, + unk2: *mut c_void, + ) -> i32; + pub fn sceKernelReceiveMsgPipe( + uid: SceUid, + message: *mut c_void, + size: u32, + unk1: i32, + unk2: *mut c_void, + timeout: *mut u32, + ) -> i32; + pub fn sceKernelReceiveMsgPipeCB( + uid: SceUid, + message: *mut c_void, + size: u32, + unk1: i32, + unk2: *mut c_void, + timeout: *mut u32, + ) -> i32; + pub fn sceKernelTryReceiveMsgPipe( + uid: SceUid, + message: *mut c_void, + size: u32, + unk1: i32, + unk2: *mut c_void, + ) -> i32; + pub fn sceKernelCancelMsgPipe(uid: SceUid, send: *mut i32, recv: *mut i32) -> i32; + pub fn sceKernelReferMsgPipeStatus(uid: SceUid, info: *mut SceKernelMppInfo) -> i32; + pub fn sceKernelCreateVpl( + name: *const u8, + part: i32, + attr: i32, + size: u32, + opt: *mut SceKernelVplOptParam, + ) -> SceUid; + pub fn sceKernelDeleteVpl(uid: SceUid) -> i32; + pub fn sceKernelAllocateVpl( + uid: SceUid, + size: u32, + data: *mut *mut c_void, + timeout: *mut u32, + ) -> i32; + pub fn sceKernelAllocateVplCB( + uid: SceUid, + size: u32, + data: *mut *mut c_void, + timeout: *mut u32, + ) -> i32; + pub fn sceKernelTryAllocateVpl(uid: SceUid, size: u32, data: *mut *mut c_void) -> i32; + pub fn sceKernelFreeVpl(uid: SceUid, data: *mut c_void) -> i32; + pub fn sceKernelCancelVpl(uid: SceUid, num: *mut i32) -> i32; + pub fn sceKernelReferVplStatus(uid: SceUid, info: *mut SceKernelVplInfo) -> i32; + pub fn sceKernelCreateFpl( + name: *const u8, + part: i32, + attr: i32, + size: u32, + blocks: u32, + opt: *mut SceKernelFplOptParam, + ) -> i32; + pub fn sceKernelDeleteFpl(uid: SceUid) -> i32; + pub fn sceKernelAllocateFpl(uid: SceUid, data: *mut *mut c_void, timeout: *mut u32) -> i32; + pub fn sceKernelAllocateFplCB(uid: SceUid, data: *mut *mut c_void, timeout: *mut u32) -> i32; + pub fn sceKernelTryAllocateFpl(uid: SceUid, data: *mut *mut c_void) -> i32; + pub fn sceKernelFreeFpl(uid: SceUid, data: *mut c_void) -> i32; + pub fn sceKernelCancelFpl(uid: SceUid, pnum: *mut i32) -> i32; + pub fn sceKernelReferFplStatus(uid: SceUid, info: *mut SceKernelFplInfo) -> i32; + pub fn sceKernelUSec2SysClock(usec: u32, clock: *mut SceKernelSysClock) -> i32; + pub fn sceKernelUSec2SysClockWide(usec: u32) -> i64; + pub fn sceKernelSysClock2USec( + clock: *mut SceKernelSysClock, + low: *mut u32, + high: *mut u32, + ) -> i32; + pub fn sceKernelSysClock2USecWide(clock: i64, low: *mut u32, high: *mut u32) -> i32; + pub fn sceKernelGetSystemTime(time: *mut SceKernelSysClock) -> i32; + pub fn sceKernelGetSystemTimeWide() -> i64; + pub fn sceKernelGetSystemTimeLow() -> u32; + pub fn sceKernelCreateVTimer(name: *const u8, opt: *mut SceKernelVTimerOptParam) -> SceUid; + pub fn sceKernelDeleteVTimer(uid: SceUid) -> i32; + pub fn sceKernelGetVTimerBase(uid: SceUid, base: *mut SceKernelSysClock) -> i32; + pub fn sceKernelGetVTimerBaseWide(uid: SceUid) -> i64; + pub fn sceKernelGetVTimerTime(uid: SceUid, time: *mut SceKernelSysClock) -> i32; + pub fn sceKernelGetVTimerTimeWide(uid: SceUid) -> i64; + pub fn sceKernelSetVTimerTime(uid: SceUid, time: *mut SceKernelSysClock) -> i32; + pub fn sceKernelSetVTimerTimeWide(uid: SceUid, time: i64) -> i64; + pub fn sceKernelStartVTimer(uid: SceUid) -> i32; + pub fn sceKernelStopVTimer(uid: SceUid) -> i32; + pub fn sceKernelSetVTimerHandler( + uid: SceUid, + time: *mut SceKernelSysClock, + handler: SceKernelVTimerHandler, + common: *mut c_void, + ) -> i32; + pub fn sceKernelSetVTimerHandlerWide( + uid: SceUid, + time: i64, + handler: SceKernelVTimerHandlerWide, + common: *mut c_void, + ) -> i32; + pub fn sceKernelCancelVTimerHandler(uid: SceUid) -> i32; + pub fn sceKernelReferVTimerStatus(uid: SceUid, info: *mut SceKernelVTimerInfo) -> i32; + pub fn sceKernelRegisterThreadEventHandler( + name: *const u8, + thread_id: SceUid, + mask: i32, + handler: SceKernelThreadEventHandler, + common: *mut c_void, + ) -> SceUid; + pub fn sceKernelReleaseThreadEventHandler(uid: SceUid) -> i32; + pub fn sceKernelReferThreadEventHandlerStatus( + uid: SceUid, + info: *mut SceKernelThreadEventHandlerInfo, + ) -> i32; + pub fn sceKernelReferThreadProfiler() -> *mut DebugProfilerRegs; + pub fn sceKernelReferGlobalProfiler() -> *mut DebugProfilerRegs; + + pub fn sceUsbStart(driver_name: *const u8, size: i32, args: *mut c_void) -> i32; + pub fn sceUsbStop(driver_name: *const u8, size: i32, args: *mut c_void) -> i32; + pub fn sceUsbActivate(pid: u32) -> i32; + pub fn sceUsbDeactivate(pid: u32) -> i32; + pub fn sceUsbGetState() -> i32; + pub fn sceUsbGetDrvState(driver_name: *const u8) -> i32; +} + +extern "C" { + pub fn sceUsbCamSetupStill(param: *mut UsbCamSetupStillParam) -> i32; + pub fn sceUsbCamSetupStillEx(param: *mut UsbCamSetupStillExParam) -> i32; + pub fn sceUsbCamStillInputBlocking(buf: *mut u8, size: usize) -> i32; + pub fn sceUsbCamStillInput(buf: *mut u8, size: usize) -> i32; + pub fn sceUsbCamStillWaitInputEnd() -> i32; + pub fn sceUsbCamStillPollInputEnd() -> i32; + pub fn sceUsbCamStillCancelInput() -> i32; + pub fn sceUsbCamStillGetInputLength() -> i32; + pub fn sceUsbCamSetupVideo( + param: *mut UsbCamSetupVideoParam, + work_area: *mut c_void, + work_area_size: i32, + ) -> i32; + pub fn sceUsbCamSetupVideoEx( + param: *mut UsbCamSetupVideoExParam, + work_area: *mut c_void, + work_area_size: i32, + ) -> i32; + pub fn sceUsbCamStartVideo() -> i32; + pub fn sceUsbCamStopVideo() -> i32; + pub fn sceUsbCamReadVideoFrameBlocking(buf: *mut u8, size: usize) -> i32; + pub fn sceUsbCamReadVideoFrame(buf: *mut u8, size: usize) -> i32; + pub fn sceUsbCamWaitReadVideoFrameEnd() -> i32; + pub fn sceUsbCamPollReadVideoFrameEnd() -> i32; + pub fn sceUsbCamGetReadVideoFrameSize() -> i32; + pub fn sceUsbCamSetSaturation(saturation: i32) -> i32; + pub fn sceUsbCamSetBrightness(brightness: i32) -> i32; + pub fn sceUsbCamSetContrast(contrast: i32) -> i32; + pub fn sceUsbCamSetSharpness(sharpness: i32) -> i32; + pub fn sceUsbCamSetImageEffectMode(effect_mode: UsbCamEffectMode) -> i32; + pub fn sceUsbCamSetEvLevel(exposure_level: UsbCamEvLevel) -> i32; + pub fn sceUsbCamSetReverseMode(reverse_flags: i32) -> i32; + pub fn sceUsbCamSetZoom(zoom: i32) -> i32; + pub fn sceUsbCamGetSaturation(saturation: *mut i32) -> i32; + pub fn sceUsbCamGetBrightness(brightness: *mut i32) -> i32; + pub fn sceUsbCamGetContrast(contrast: *mut i32) -> i32; + pub fn sceUsbCamGetSharpness(sharpness: *mut i32) -> i32; + pub fn sceUsbCamGetImageEffectMode(effect_mode: *mut UsbCamEffectMode) -> i32; + pub fn sceUsbCamGetEvLevel(exposure_level: *mut UsbCamEvLevel) -> i32; + pub fn sceUsbCamGetReverseMode(reverse_flags: *mut i32) -> i32; + pub fn sceUsbCamGetZoom(zoom: *mut i32) -> i32; + pub fn sceUsbCamAutoImageReverseSW(on: i32) -> i32; + pub fn sceUsbCamGetAutoImageReverseState() -> i32; + pub fn sceUsbCamGetLensDirection() -> i32; + + pub fn sceUsbstorBootRegisterNotify(event_flag: SceUid) -> i32; + pub fn sceUsbstorBootUnregisterNotify(event_flag: u32) -> i32; + pub fn sceUsbstorBootSetCapacity(size: u32) -> i32; + + pub fn scePowerRegisterCallback(slot: i32, cbid: SceUid) -> i32; + pub fn scePowerUnregisterCallback(slot: i32) -> i32; + pub fn scePowerIsPowerOnline() -> i32; + pub fn scePowerIsBatteryExist() -> i32; + pub fn scePowerIsBatteryCharging() -> i32; + pub fn scePowerGetBatteryChargingStatus() -> i32; + pub fn scePowerIsLowBattery() -> i32; + pub fn scePowerGetBatteryLifePercent() -> i32; + pub fn scePowerGetBatteryLifeTime() -> i32; + pub fn scePowerGetBatteryTemp() -> i32; + pub fn scePowerGetBatteryElec() -> i32; + pub fn scePowerGetBatteryVolt() -> i32; + pub fn scePowerSetCpuClockFrequency(cpufreq: i32) -> i32; + pub fn scePowerSetBusClockFrequency(busfreq: i32) -> i32; + pub fn scePowerGetCpuClockFrequency() -> i32; + pub fn scePowerGetCpuClockFrequencyInt() -> i32; + pub fn scePowerGetCpuClockFrequencyFloat() -> f32; + pub fn scePowerGetBusClockFrequency() -> i32; + pub fn scePowerGetBusClockFrequencyInt() -> i32; + pub fn scePowerGetBusClockFrequencyFloat() -> f32; + pub fn scePowerSetClockFrequency(pllfreq: i32, cpufreq: i32, busfreq: i32) -> i32; + pub fn scePowerLock(unknown: i32) -> i32; + pub fn scePowerUnlock(unknown: i32) -> i32; + pub fn scePowerTick(t: PowerTick) -> i32; + pub fn scePowerGetIdleTimer() -> i32; + pub fn scePowerIdleTimerEnable(unknown: i32) -> i32; + pub fn scePowerIdleTimerDisable(unknown: i32) -> i32; + pub fn scePowerRequestStandby() -> i32; + pub fn scePowerRequestSuspend() -> i32; + + pub fn sceWlanDevIsPowerOn() -> i32; + pub fn sceWlanGetSwitchState() -> i32; + pub fn sceWlanGetEtherAddr(ether_addr: *mut u8) -> i32; + + pub fn sceWlanDevAttach() -> i32; + pub fn sceWlanDevDetach() -> i32; + + pub fn sceRtcGetTickResolution() -> u32; + pub fn sceRtcGetCurrentTick(tick: *mut u64) -> i32; + pub fn sceRtcGetCurrentClock(tm: *mut ScePspDateTime, tz: i32) -> i32; + pub fn sceRtcGetCurrentClockLocalTime(tm: *mut ScePspDateTime) -> i32; + pub fn sceRtcConvertUtcToLocalTime(tick_utc: *const u64, tick_local: *mut u64) -> i32; + pub fn sceRtcConvertLocalTimeToUTC(tick_local: *const u64, tick_utc: *mut u64) -> i32; + pub fn sceRtcIsLeapYear(year: i32) -> i32; + pub fn sceRtcGetDaysInMonth(year: i32, month: i32) -> i32; + pub fn sceRtcGetDayOfWeek(year: i32, month: i32, day: i32) -> i32; + pub fn sceRtcCheckValid(date: *const ScePspDateTime) -> i32; + pub fn sceRtcSetTick(date: *mut ScePspDateTime, tick: *const u64) -> i32; + pub fn sceRtcGetTick(date: *const ScePspDateTime, tick: *mut u64) -> i32; + pub fn sceRtcCompareTick(tick1: *const u64, tick2: *const u64) -> i32; + pub fn sceRtcTickAddTicks(dest_tick: *mut u64, src_tick: *const u64, num_ticks: u64) -> i32; + pub fn sceRtcTickAddMicroseconds(dest_tick: *mut u64, src_tick: *const u64, num_ms: u64) + -> i32; + pub fn sceRtcTickAddSeconds(dest_tick: *mut u64, src_tick: *const u64, num_seconds: u64) + -> i32; + pub fn sceRtcTickAddMinutes(dest_tick: *mut u64, src_tick: *const u64, num_minutes: u64) + -> i32; + pub fn sceRtcTickAddHours(dest_tick: *mut u64, src_tick: *const u64, num_hours: u64) -> i32; + pub fn sceRtcTickAddDays(dest_tick: *mut u64, src_tick: *const u64, num_days: u64) -> i32; + pub fn sceRtcTickAddWeeks(dest_tick: *mut u64, src_tick: *const u64, num_weeks: u64) -> i32; + pub fn sceRtcTickAddMonths(dest_tick: *mut u64, src_tick: *const u64, num_months: u64) -> i32; + pub fn sceRtcTickAddYears(dest_tick: *mut u64, src_tick: *const u64, num_years: u64) -> i32; + pub fn sceRtcSetTime_t(date: *mut ScePspDateTime, time: u32) -> i32; + pub fn sceRtcGetTime_t(date: *const ScePspDateTime, time: *mut u32) -> i32; + pub fn sceRtcSetTime64_t(date: *mut ScePspDateTime, time: u64) -> i32; + pub fn sceRtcGetTime64_t(date: *const ScePspDateTime, time: *mut u64) -> i32; + pub fn sceRtcSetDosTime(date: *mut ScePspDateTime, dos_time: u32) -> i32; + pub fn sceRtcGetDosTime(date: *mut ScePspDateTime, dos_time: u32) -> i32; + pub fn sceRtcSetWin32FileTime(date: *mut ScePspDateTime, time: *mut u64) -> i32; + pub fn sceRtcGetWin32FileTime(date: *mut ScePspDateTime, time: *mut u64) -> i32; + pub fn sceRtcParseDateTime(dest_tick: *mut u64, date_string: *const u8) -> i32; + pub fn sceRtcFormatRFC3339( + psz_date_time: *mut char, + p_utc: *const u64, + time_zone_minutes: i32, + ) -> i32; + pub fn sceRtcFormatRFC3339LocalTime(psz_date_time: *mut char, p_utc: *const u64) -> i32; + pub fn sceRtcParseRFC3339(p_utc: *mut u64, psz_date_time: *const u8) -> i32; + pub fn sceRtcFormatRFC2822( + psz_date_time: *mut char, + p_utc: *const u64, + time_zone_minutes: i32, + ) -> i32; + pub fn sceRtcFormatRFC2822LocalTime(psz_date_time: *mut char, p_utc: *const u64) -> i32; + + pub fn sceIoOpen(file: *const u8, flags: i32, permissions: IoPermissions) -> SceUid; + pub fn sceIoOpenAsync(file: *const u8, flags: i32, permissions: IoPermissions) -> SceUid; + pub fn sceIoClose(fd: SceUid) -> i32; + pub fn sceIoCloseAsync(fd: SceUid) -> i32; + pub fn sceIoRead(fd: SceUid, data: *mut c_void, size: u32) -> i32; + pub fn sceIoReadAsync(fd: SceUid, data: *mut c_void, size: u32) -> i32; + pub fn sceIoWrite(fd: SceUid, data: *const c_void, size: usize) -> i32; + pub fn sceIoWriteAsync(fd: SceUid, data: *const c_void, size: u32) -> i32; + pub fn sceIoLseek(fd: SceUid, offset: i64, whence: IoWhence) -> i64; + pub fn sceIoLseekAsync(fd: SceUid, offset: i64, whence: IoWhence) -> i32; + pub fn sceIoLseek32(fd: SceUid, offset: i32, whence: IoWhence) -> i32; + pub fn sceIoLseek32Async(fd: SceUid, offset: i32, whence: IoWhence) -> i32; + pub fn sceIoRemove(file: *const u8) -> i32; + pub fn sceIoMkdir(dir: *const u8, mode: IoPermissions) -> i32; + pub fn sceIoRmdir(path: *const u8) -> i32; + pub fn sceIoChdir(path: *const u8) -> i32; + pub fn sceIoRename(oldname: *const u8, newname: *const u8) -> i32; + pub fn sceIoDopen(dirname: *const u8) -> SceUid; + pub fn sceIoDread(fd: SceUid, dir: *mut SceIoDirent) -> i32; + pub fn sceIoDclose(fd: SceUid) -> i32; + pub fn sceIoDevctl( + dev: *const u8, + cmd: u32, + indata: *mut c_void, + inlen: i32, + outdata: *mut c_void, + outlen: i32, + ) -> i32; + pub fn sceIoAssign( + dev1: *const u8, + dev2: *const u8, + dev3: *const u8, + mode: IoAssignPerms, + unk1: *mut c_void, + unk2: i32, + ) -> i32; + pub fn sceIoUnassign(dev: *const u8) -> i32; + pub fn sceIoGetstat(file: *const u8, stat: *mut SceIoStat) -> i32; + pub fn sceIoChstat(file: *const u8, stat: *mut SceIoStat, bits: i32) -> i32; + pub fn sceIoIoctl( + fd: SceUid, + cmd: u32, + indata: *mut c_void, + inlen: i32, + outdata: *mut c_void, + outlen: i32, + ) -> i32; + pub fn sceIoIoctlAsync( + fd: SceUid, + cmd: u32, + indata: *mut c_void, + inlen: i32, + outdata: *mut c_void, + outlen: i32, + ) -> i32; + pub fn sceIoSync(device: *const u8, unk: u32) -> i32; + pub fn sceIoWaitAsync(fd: SceUid, res: *mut i64) -> i32; + pub fn sceIoWaitAsyncCB(fd: SceUid, res: *mut i64) -> i32; + pub fn sceIoPollAsync(fd: SceUid, res: *mut i64) -> i32; + pub fn sceIoGetAsyncStat(fd: SceUid, poll: i32, res: *mut i64) -> i32; + pub fn sceIoCancel(fd: SceUid) -> i32; + pub fn sceIoGetDevType(fd: SceUid) -> i32; + pub fn sceIoChangeAsyncPriority(fd: SceUid, pri: i32) -> i32; + pub fn sceIoSetAsyncCallback(fd: SceUid, cb: SceUid, argp: *mut c_void) -> i32; + + pub fn sceJpegInitMJpeg() -> i32; + pub fn sceJpegFinishMJpeg() -> i32; + pub fn sceJpegCreateMJpeg(width: i32, height: i32) -> i32; + pub fn sceJpegDeleteMJpeg() -> i32; + pub fn sceJpegDecodeMJpeg(jpeg_buf: *mut u8, size: usize, rgba: *mut c_void, unk: u32) -> i32; + + pub fn sceUmdCheckMedium() -> i32; + pub fn sceUmdGetDiscInfo(info: *mut UmdInfo) -> i32; + pub fn sceUmdActivate(unit: i32, drive: *const u8) -> i32; + pub fn sceUmdDeactivate(unit: i32, drive: *const u8) -> i32; + pub fn sceUmdWaitDriveStat(state: i32) -> i32; + pub fn sceUmdWaitDriveStatWithTimer(state: i32, timeout: u32) -> i32; + pub fn sceUmdWaitDriveStatCB(state: i32, timeout: u32) -> i32; + pub fn sceUmdCancelWaitDriveStat() -> i32; + pub fn sceUmdGetDriveStat() -> i32; + pub fn sceUmdGetErrorStat() -> i32; + pub fn sceUmdRegisterUMDCallBack(cbid: i32) -> i32; + pub fn sceUmdUnRegisterUMDCallBack(cbid: i32) -> i32; + pub fn sceUmdReplacePermit() -> i32; + pub fn sceUmdReplaceProhibit() -> i32; + + pub fn sceMpegInit() -> i32; + pub fn sceMpegFinish(); + pub fn sceMpegRingbufferQueryMemSize(packets: i32) -> i32; + pub fn sceMpegRingbufferConstruct( + ringbuffer: *mut SceMpegRingbuffer, + packets: i32, + data: *mut c_void, + size: i32, + callback: SceMpegRingbufferCb, + cb_param: *mut c_void, + ) -> i32; + pub fn sceMpegRingbufferDestruct(ringbuffer: *mut SceMpegRingbuffer); + pub fn sceMpegRingbufferAvailableSize(ringbuffer: *mut SceMpegRingbuffer) -> i32; + pub fn sceMpegRingbufferPut( + ringbuffer: *mut SceMpegRingbuffer, + num_packets: i32, + available: i32, + ) -> i32; + pub fn sceMpegQueryMemSize(unk: i32) -> i32; + pub fn sceMpegCreate( + handle: SceMpeg, + data: *mut c_void, + size: i32, + ringbuffer: *mut SceMpegRingbuffer, + frame_width: i32, + unk1: i32, + unk2: i32, + ) -> i32; + pub fn sceMpegDelete(handle: SceMpeg); + pub fn sceMpegQueryStreamOffset(handle: SceMpeg, buffer: *mut c_void, offset: *mut i32) -> i32; + pub fn sceMpegQueryStreamSize(buffer: *mut c_void, size: *mut i32) -> i32; + pub fn sceMpegRegistStream(handle: SceMpeg, stream_id: i32, unk: i32) -> SceMpegStream; + pub fn sceMpegUnRegistStream(handle: SceMpeg, stream: SceMpegStream); + pub fn sceMpegFlushAllStream(handle: SceMpeg) -> i32; + pub fn sceMpegMallocAvcEsBuf(handle: SceMpeg) -> *mut c_void; + pub fn sceMpegFreeAvcEsBuf(handle: SceMpeg, buf: *mut c_void); + pub fn sceMpegQueryAtracEsSize(handle: SceMpeg, es_size: *mut i32, out_size: *mut i32) -> i32; + pub fn sceMpegInitAu(handle: SceMpeg, es_buffer: *mut c_void, au: *mut SceMpegAu) -> i32; + pub fn sceMpegGetAvcAu( + handle: SceMpeg, + stream: SceMpegStream, + au: *mut SceMpegAu, + unk: *mut i32, + ) -> i32; + pub fn sceMpegAvcDecodeMode(handle: SceMpeg, mode: *mut SceMpegAvcMode) -> i32; + pub fn sceMpegAvcDecode( + handle: SceMpeg, + au: *mut SceMpegAu, + iframe_width: i32, + buffer: *mut c_void, + init: *mut i32, + ) -> i32; + pub fn sceMpegAvcDecodeStop( + handle: SceMpeg, + frame_width: i32, + buffer: *mut c_void, + status: *mut i32, + ) -> i32; + pub fn sceMpegGetAtracAu( + handle: SceMpeg, + stream: SceMpegStream, + au: *mut SceMpegAu, + unk: *mut c_void, + ) -> i32; + pub fn sceMpegAtracDecode( + handle: SceMpeg, + au: *mut SceMpegAu, + buffer: *mut c_void, + init: i32, + ) -> i32; + + pub fn sceMpegBaseYCrCbCopyVme(yuv_buffer: *mut c_void, buffer: *mut i32, type_: i32) -> i32; + pub fn sceMpegBaseCscInit(width: i32) -> i32; + pub fn sceMpegBaseCscVme( + rgb_buffer: *mut c_void, + rgb_buffer2: *mut c_void, + width: i32, + y_cr_cb_buffer: *mut SceMpegYCrCbBuffer, + ) -> i32; + pub fn sceMpegbase_BEA18F91(lli: *mut SceMpegLLI) -> i32; + + pub fn sceHprmPeekCurrentKey(key: *mut i32) -> i32; + pub fn sceHprmPeekLatch(latch: *mut [u32; 4]) -> i32; + pub fn sceHprmReadLatch(latch: *mut [u32; 4]) -> i32; + pub fn sceHprmIsHeadphoneExist() -> i32; + pub fn sceHprmIsRemoteExist() -> i32; + pub fn sceHprmIsMicrophoneExist() -> i32; + + pub fn sceGuDepthBuffer(zbp: *mut c_void, zbw: i32); + pub fn sceGuDispBuffer(width: i32, height: i32, dispbp: *mut c_void, dispbw: i32); + pub fn sceGuDrawBuffer(psm: DisplayPixelFormat, fbp: *mut c_void, fbw: i32); + pub fn sceGuDrawBufferList(psm: DisplayPixelFormat, fbp: *mut c_void, fbw: i32); + pub fn sceGuDisplay(state: bool) -> bool; + pub fn sceGuDepthFunc(function: DepthFunc); + pub fn sceGuDepthMask(mask: i32); + pub fn sceGuDepthOffset(offset: i32); + pub fn sceGuDepthRange(near: i32, far: i32); + pub fn sceGuFog(near: f32, far: f32, color: u32); + pub fn sceGuInit(); + pub fn sceGuTerm(); + pub fn sceGuBreak(mode: i32); + pub fn sceGuContinue(); + pub fn sceGuSetCallback(signal: GuCallbackId, callback: GuCallback) -> GuCallback; + pub fn sceGuSignal(behavior: SignalBehavior, signal: i32); + pub fn sceGuSendCommandf(cmd: GeCommand, argument: f32); + pub fn sceGuSendCommandi(cmd: GeCommand, argument: i32); + pub fn sceGuGetMemory(size: i32) -> *mut c_void; + pub fn sceGuStart(context_type: GuContextType, list: *mut c_void); + pub fn sceGuFinish() -> i32; + pub fn sceGuFinishId(id: u32) -> i32; + pub fn sceGuCallList(list: *const c_void); + pub fn sceGuCallMode(mode: i32); + pub fn sceGuCheckList() -> i32; + pub fn sceGuSendList(mode: GuQueueMode, list: *const c_void, context: *mut GeContext); + pub fn sceGuSwapBuffers() -> *mut c_void; + pub fn sceGuSync(mode: GuSyncMode, behavior: GuSyncBehavior) -> GeListState; + pub fn sceGuDrawArray( + prim: GuPrimitive, + vtype: i32, + count: i32, + indices: *const c_void, + vertices: *const c_void, + ); + pub fn sceGuBeginObject( + vtype: i32, + count: i32, + indices: *const c_void, + vertices: *const c_void, + ); + pub fn sceGuEndObject(); + pub fn sceGuSetStatus(state: GuState, status: i32); + pub fn sceGuGetStatus(state: GuState) -> bool; + pub fn sceGuSetAllStatus(status: i32); + pub fn sceGuGetAllStatus() -> i32; + pub fn sceGuEnable(state: GuState); + pub fn sceGuDisable(state: GuState); + pub fn sceGuLight(light: i32, type_: LightType, components: i32, position: &ScePspFVector3); + pub fn sceGuLightAtt(light: i32, atten0: f32, atten1: f32, atten2: f32); + pub fn sceGuLightColor(light: i32, component: i32, color: u32); + pub fn sceGuLightMode(mode: LightMode); + pub fn sceGuLightSpot(light: i32, direction: &ScePspFVector3, exponent: f32, cutoff: f32); + pub fn sceGuClear(flags: i32); + pub fn sceGuClearColor(color: u32); + pub fn sceGuClearDepth(depth: u32); + pub fn sceGuClearStencil(stencil: u32); + pub fn sceGuPixelMask(mask: u32); + pub fn sceGuColor(color: u32); + pub fn sceGuColorFunc(func: ColorFunc, color: u32, mask: u32); + pub fn sceGuColorMaterial(components: i32); + pub fn sceGuAlphaFunc(func: AlphaFunc, value: i32, mask: i32); + pub fn sceGuAmbient(color: u32); + pub fn sceGuAmbientColor(color: u32); + pub fn sceGuBlendFunc(op: BlendOp, src: BlendSrc, dest: BlendDst, src_fix: u32, dest_fix: u32); + pub fn sceGuMaterial(components: i32, color: u32); + pub fn sceGuModelColor(emissive: u32, ambient: u32, diffuse: u32, specular: u32); + pub fn sceGuStencilFunc(func: StencilFunc, ref_: i32, mask: i32); + pub fn sceGuStencilOp(fail: StencilOperation, zfail: StencilOperation, zpass: StencilOperation); + pub fn sceGuSpecular(power: f32); + pub fn sceGuFrontFace(order: FrontFaceDirection); + pub fn sceGuLogicalOp(op: LogicalOperation); + pub fn sceGuSetDither(matrix: &ScePspIMatrix4); + pub fn sceGuShadeModel(mode: ShadingModel); + pub fn sceGuCopyImage( + psm: DisplayPixelFormat, + sx: i32, + sy: i32, + width: i32, + height: i32, + srcw: i32, + src: *mut c_void, + dx: i32, + dy: i32, + destw: i32, + dest: *mut c_void, + ); + pub fn sceGuTexEnvColor(color: u32); + pub fn sceGuTexFilter(min: TextureFilter, mag: TextureFilter); + pub fn sceGuTexFlush(); + pub fn sceGuTexFunc(tfx: TextureEffect, tcc: TextureColorComponent); + pub fn sceGuTexImage( + mipmap: MipmapLevel, + width: i32, + height: i32, + tbw: i32, + tbp: *const c_void, + ); + pub fn sceGuTexLevelMode(mode: TextureLevelMode, bias: f32); + pub fn sceGuTexMapMode(mode: TextureMapMode, a1: u32, a2: u32); + pub fn sceGuTexMode(tpsm: TexturePixelFormat, maxmips: i32, a2: i32, swizzle: i32); + pub fn sceGuTexOffset(u: f32, v: f32); + pub fn sceGuTexProjMapMode(mode: TextureProjectionMapMode); + pub fn sceGuTexScale(u: f32, v: f32); + pub fn sceGuTexSlope(slope: f32); + pub fn sceGuTexSync(); + pub fn sceGuTexWrap(u: GuTexWrapMode, v: GuTexWrapMode); + pub fn sceGuClutLoad(num_blocks: i32, cbp: *const c_void); + pub fn sceGuClutMode(cpsm: ClutPixelFormat, shift: u32, mask: u32, a3: u32); + pub fn sceGuOffset(x: u32, y: u32); + pub fn sceGuScissor(x: i32, y: i32, w: i32, h: i32); + pub fn sceGuViewport(cx: i32, cy: i32, width: i32, height: i32); + pub fn sceGuDrawBezier( + v_type: i32, + u_count: i32, + v_count: i32, + indices: *const c_void, + vertices: *const c_void, + ); + pub fn sceGuPatchDivide(ulevel: u32, vlevel: u32); + pub fn sceGuPatchFrontFace(a0: u32); + pub fn sceGuPatchPrim(prim: PatchPrimitive); + pub fn sceGuDrawSpline( + v_type: i32, + u_count: i32, + v_count: i32, + u_edge: i32, + v_edge: i32, + indices: *const c_void, + vertices: *const c_void, + ); + pub fn sceGuSetMatrix(type_: MatrixMode, matrix: &ScePspFMatrix4); + pub fn sceGuBoneMatrix(index: u32, matrix: &ScePspFMatrix4); + pub fn sceGuMorphWeight(index: i32, weight: f32); + pub fn sceGuDrawArrayN( + primitive_type: GuPrimitive, + v_type: i32, + count: i32, + a3: i32, + indices: *const c_void, + vertices: *const c_void, + ); + + pub fn sceGumDrawArray( + prim: GuPrimitive, + v_type: i32, + count: i32, + indices: *const c_void, + vertices: *const c_void, + ); + pub fn sceGumDrawArrayN( + prim: GuPrimitive, + v_type: i32, + count: i32, + a3: i32, + indices: *const c_void, + vertices: *const c_void, + ); + pub fn sceGumDrawBezier( + v_type: i32, + u_count: i32, + v_count: i32, + indices: *const c_void, + vertices: *const c_void, + ); + pub fn sceGumDrawSpline( + v_type: i32, + u_count: i32, + v_count: i32, + u_edge: i32, + v_edge: i32, + indices: *const c_void, + vertices: *const c_void, + ); + pub fn sceGumFastInverse(); + pub fn sceGumFullInverse(); + pub fn sceGumLoadIdentity(); + pub fn sceGumLoadMatrix(m: &ScePspFMatrix4); + pub fn sceGumLookAt(eye: &ScePspFVector3, center: &ScePspFVector3, up: &ScePspFVector3); + pub fn sceGumMatrixMode(mode: MatrixMode); + pub fn sceGumMultMatrix(m: &ScePspFMatrix4); + pub fn sceGumOrtho(left: f32, right: f32, bottom: f32, top: f32, near: f32, far: f32); + pub fn sceGumPerspective(fovy: f32, aspect: f32, near: f32, far: f32); + pub fn sceGumPopMatrix(); + pub fn sceGumPushMatrix(); + pub fn sceGumRotateX(angle: f32); + pub fn sceGumRotateY(angle: f32); + pub fn sceGumRotateZ(angle: f32); + pub fn sceGumRotateXYZ(v: &ScePspFVector3); + pub fn sceGumRotateZYX(v: &ScePspFVector3); + pub fn sceGumScale(v: &ScePspFVector3); + pub fn sceGumStoreMatrix(m: &mut ScePspFMatrix4); + pub fn sceGumTranslate(v: &ScePspFVector3); + pub fn sceGumUpdateMatrix(); + + pub fn sceMp3ReserveMp3Handle(args: *mut SceMp3InitArg) -> i32; + pub fn sceMp3ReleaseMp3Handle(handle: Mp3Handle) -> i32; + pub fn sceMp3InitResource() -> i32; + pub fn sceMp3TermResource() -> i32; + pub fn sceMp3Init(handle: Mp3Handle) -> i32; + pub fn sceMp3Decode(handle: Mp3Handle, dst: *mut *mut i16) -> i32; + pub fn sceMp3GetInfoToAddStreamData( + handle: Mp3Handle, + dst: *mut *mut u8, + to_write: *mut i32, + src_pos: *mut i32, + ) -> i32; + pub fn sceMp3NotifyAddStreamData(handle: Mp3Handle, size: i32) -> i32; + pub fn sceMp3CheckStreamDataNeeded(handle: Mp3Handle) -> i32; + pub fn sceMp3SetLoopNum(handle: Mp3Handle, loop_: i32) -> i32; + pub fn sceMp3GetLoopNum(handle: Mp3Handle) -> i32; + pub fn sceMp3GetSumDecodedSample(handle: Mp3Handle) -> i32; + pub fn sceMp3GetMaxOutputSample(handle: Mp3Handle) -> i32; + pub fn sceMp3GetSamplingRate(handle: Mp3Handle) -> i32; + pub fn sceMp3GetBitRate(handle: Mp3Handle) -> i32; + pub fn sceMp3GetMp3ChannelNum(handle: Mp3Handle) -> i32; + pub fn sceMp3ResetPlayPosition(handle: Mp3Handle) -> i32; + + pub fn sceRegOpenRegistry(reg: *mut Key, mode: i32, handle: *mut RegHandle) -> i32; + pub fn sceRegFlushRegistry(handle: RegHandle) -> i32; + pub fn sceRegCloseRegistry(handle: RegHandle) -> i32; + pub fn sceRegOpenCategory( + handle: RegHandle, + name: *const u8, + mode: i32, + dir_handle: *mut RegHandle, + ) -> i32; + pub fn sceRegRemoveCategory(handle: RegHandle, name: *const u8) -> i32; + pub fn sceRegCloseCategory(dir_handle: RegHandle) -> i32; + pub fn sceRegFlushCategory(dir_handle: RegHandle) -> i32; + pub fn sceRegGetKeyInfo( + dir_handle: RegHandle, + name: *const u8, + key_handle: *mut RegHandle, + type_: *mut KeyType, + size: *mut usize, + ) -> i32; + pub fn sceRegGetKeyInfoByName( + dir_handle: RegHandle, + name: *const u8, + type_: *mut KeyType, + size: *mut usize, + ) -> i32; + pub fn sceRegGetKeyValue( + dir_handle: RegHandle, + key_handle: RegHandle, + buf: *mut c_void, + size: usize, + ) -> i32; + pub fn sceRegGetKeyValueByName( + dir_handle: RegHandle, + name: *const u8, + buf: *mut c_void, + size: usize, + ) -> i32; + pub fn sceRegSetKeyValue( + dir_handle: RegHandle, + name: *const u8, + buf: *const c_void, + size: usize, + ) -> i32; + pub fn sceRegGetKeysNum(dir_handle: RegHandle, num: *mut i32) -> i32; + pub fn sceRegGetKeys(dir_handle: RegHandle, buf: *mut u8, num: i32) -> i32; + pub fn sceRegCreateKey(dir_handle: RegHandle, name: *const u8, type_: i32, size: usize) -> i32; + pub fn sceRegRemoveRegistry(key: *mut Key) -> i32; + + pub fn sceOpenPSIDGetOpenPSID(openpsid: *mut OpenPSID) -> i32; + + pub fn sceUtilityMsgDialogInitStart(params: *mut UtilityMsgDialogParams) -> i32; + pub fn sceUtilityMsgDialogShutdownStart(); + pub fn sceUtilityMsgDialogGetStatus() -> i32; + pub fn sceUtilityMsgDialogUpdate(n: i32); + pub fn sceUtilityMsgDialogAbort() -> i32; + pub fn sceUtilityNetconfInitStart(data: *mut UtilityNetconfData) -> i32; + pub fn sceUtilityNetconfShutdownStart() -> i32; + pub fn sceUtilityNetconfUpdate(unknown: i32) -> i32; + pub fn sceUtilityNetconfGetStatus() -> i32; + pub fn sceUtilityCheckNetParam(id: i32) -> i32; + pub fn sceUtilityGetNetParam(conf: i32, param: NetParam, data: *mut UtilityNetData) -> i32; + pub fn sceUtilitySavedataInitStart(params: *mut SceUtilitySavedataParam) -> i32; + pub fn sceUtilitySavedataGetStatus() -> i32; + pub fn sceUtilitySavedataShutdownStart() -> i32; + pub fn sceUtilitySavedataUpdate(unknown: i32); + pub fn sceUtilityGameSharingInitStart(params: *mut UtilityGameSharingParams) -> i32; + pub fn sceUtilityGameSharingShutdownStart(); + pub fn sceUtilityGameSharingGetStatus() -> i32; + pub fn sceUtilityGameSharingUpdate(n: i32); + pub fn sceUtilityHtmlViewerInitStart(params: *mut UtilityHtmlViewerParam) -> i32; + pub fn sceUtilityHtmlViewerShutdownStart() -> i32; + pub fn sceUtilityHtmlViewerUpdate(n: i32) -> i32; + pub fn sceUtilityHtmlViewerGetStatus() -> i32; + pub fn sceUtilitySetSystemParamInt(id: SystemParamId, value: i32) -> i32; + pub fn sceUtilitySetSystemParamString(id: SystemParamId, str: *const u8) -> i32; + pub fn sceUtilityGetSystemParamInt(id: SystemParamId, value: *mut i32) -> i32; + pub fn sceUtilityGetSystemParamString(id: SystemParamId, str: *mut u8, len: i32) -> i32; + pub fn sceUtilityOskInitStart(params: *mut SceUtilityOskParams) -> i32; + pub fn sceUtilityOskShutdownStart() -> i32; + pub fn sceUtilityOskUpdate(n: i32) -> i32; + pub fn sceUtilityOskGetStatus() -> i32; + pub fn sceUtilityLoadNetModule(module: NetModule) -> i32; + pub fn sceUtilityUnloadNetModule(module: NetModule) -> i32; + pub fn sceUtilityLoadAvModule(module: AvModule) -> i32; + pub fn sceUtilityUnloadAvModule(module: AvModule) -> i32; + pub fn sceUtilityLoadUsbModule(module: UsbModule) -> i32; + pub fn sceUtilityUnloadUsbModule(module: UsbModule) -> i32; + pub fn sceUtilityLoadModule(module: Module) -> i32; + pub fn sceUtilityUnloadModule(module: Module) -> i32; + pub fn sceUtilityCreateNetParam(conf: i32) -> i32; + pub fn sceUtilitySetNetParam(param: NetParam, val: *const c_void) -> i32; + pub fn sceUtilityCopyNetParam(src: i32, dest: i32) -> i32; + pub fn sceUtilityDeleteNetParam(conf: i32) -> i32; + + pub fn sceNetInit( + poolsize: i32, + calloutprio: i32, + calloutstack: i32, + netintrprio: i32, + netintrstack: i32, + ) -> i32; + pub fn sceNetTerm() -> i32; + pub fn sceNetFreeThreadinfo(thid: i32) -> i32; + pub fn sceNetThreadAbort(thid: i32) -> i32; + pub fn sceNetEtherStrton(name: *mut u8, mac: *mut u8); + pub fn sceNetEtherNtostr(mac: *mut u8, name: *mut u8); + pub fn sceNetGetLocalEtherAddr(mac: *mut u8) -> i32; + pub fn sceNetGetMallocStat(stat: *mut SceNetMallocStat) -> i32; + + pub fn sceNetAdhocctlInit( + stacksize: i32, + priority: i32, + adhoc_id: *mut SceNetAdhocctlAdhocId, + ) -> i32; + pub fn sceNetAdhocctlTerm() -> i32; + pub fn sceNetAdhocctlConnect(name: *const u8) -> i32; + pub fn sceNetAdhocctlDisconnect() -> i32; + pub fn sceNetAdhocctlGetState(event: *mut i32) -> i32; + pub fn sceNetAdhocctlCreate(name: *const u8) -> i32; + pub fn sceNetAdhocctlJoin(scaninfo: *mut SceNetAdhocctlScanInfo) -> i32; + pub fn sceNetAdhocctlGetAdhocId(id: *mut SceNetAdhocctlAdhocId) -> i32; + pub fn sceNetAdhocctlCreateEnterGameMode( + name: *const u8, + unknown: i32, + num: i32, + macs: *mut u8, + timeout: u32, + unknown2: i32, + ) -> i32; + pub fn sceNetAdhocctlJoinEnterGameMode( + name: *const u8, + hostmac: *mut u8, + timeout: u32, + unknown: i32, + ) -> i32; + pub fn sceNetAdhocctlGetGameModeInfo(gamemodeinfo: *mut SceNetAdhocctlGameModeInfo) -> i32; + pub fn sceNetAdhocctlExitGameMode() -> i32; + pub fn sceNetAdhocctlGetPeerList(length: *mut i32, buf: *mut c_void) -> i32; + pub fn sceNetAdhocctlGetPeerInfo( + mac: *mut u8, + size: i32, + peerinfo: *mut SceNetAdhocctlPeerInfo, + ) -> i32; + pub fn sceNetAdhocctlScan() -> i32; + pub fn sceNetAdhocctlGetScanInfo(length: *mut i32, buf: *mut c_void) -> i32; + pub fn sceNetAdhocctlAddHandler(handler: SceNetAdhocctlHandler, unknown: *mut c_void) -> i32; + pub fn sceNetAdhocctlDelHandler(id: i32) -> i32; + pub fn sceNetAdhocctlGetNameByAddr(mac: *mut u8, nickname: *mut u8) -> i32; + pub fn sceNetAdhocctlGetAddrByName( + nickname: *mut u8, + length: *mut i32, + buf: *mut c_void, + ) -> i32; + pub fn sceNetAdhocctlGetParameter(params: *mut SceNetAdhocctlParams) -> i32; + + pub fn sceNetAdhocInit() -> i32; + pub fn sceNetAdhocTerm() -> i32; + pub fn sceNetAdhocPdpCreate(mac: *mut u8, port: u16, buf_size: u32, unk1: i32) -> i32; + pub fn sceNetAdhocPdpDelete(id: i32, unk1: i32) -> i32; + pub fn sceNetAdhocPdpSend( + id: i32, + dest_mac_addr: *mut u8, + port: u16, + data: *mut c_void, + len: u32, + timeout: u32, + nonblock: i32, + ) -> i32; + pub fn sceNetAdhocPdpRecv( + id: i32, + src_mac_addr: *mut u8, + port: *mut u16, + data: *mut c_void, + data_length: *mut c_void, + timeout: u32, + nonblock: i32, + ) -> i32; + pub fn sceNetAdhocGetPdpStat(size: *mut i32, stat: *mut SceNetAdhocPdpStat) -> i32; + pub fn sceNetAdhocGameModeCreateMaster(data: *mut c_void, size: i32) -> i32; + pub fn sceNetAdhocGameModeCreateReplica(mac: *mut u8, data: *mut c_void, size: i32) -> i32; + pub fn sceNetAdhocGameModeUpdateMaster() -> i32; + pub fn sceNetAdhocGameModeUpdateReplica(id: i32, unk1: i32) -> i32; + pub fn sceNetAdhocGameModeDeleteMaster() -> i32; + pub fn sceNetAdhocGameModeDeleteReplica(id: i32) -> i32; + pub fn sceNetAdhocPtpOpen( + srcmac: *mut u8, + srcport: u16, + destmac: *mut u8, + destport: u16, + buf_size: u32, + delay: u32, + count: i32, + unk1: i32, + ) -> i32; + pub fn sceNetAdhocPtpConnect(id: i32, timeout: u32, nonblock: i32) -> i32; + pub fn sceNetAdhocPtpListen( + srcmac: *mut u8, + srcport: u16, + buf_size: u32, + delay: u32, + count: i32, + queue: i32, + unk1: i32, + ) -> i32; + pub fn sceNetAdhocPtpAccept( + id: i32, + mac: *mut u8, + port: *mut u16, + timeout: u32, + nonblock: i32, + ) -> i32; + pub fn sceNetAdhocPtpSend( + id: i32, + data: *mut c_void, + data_size: *mut i32, + timeout: u32, + nonblock: i32, + ) -> i32; + pub fn sceNetAdhocPtpRecv( + id: i32, + data: *mut c_void, + data_size: *mut i32, + timeout: u32, + nonblock: i32, + ) -> i32; + pub fn sceNetAdhocPtpFlush(id: i32, timeout: u32, nonblock: i32) -> i32; + pub fn sceNetAdhocPtpClose(id: i32, unk1: i32) -> i32; + pub fn sceNetAdhocGetPtpStat(size: *mut i32, stat: *mut SceNetAdhocPtpStat) -> i32; +} + +extern "C" { + pub fn sceNetAdhocMatchingInit(memsize: i32) -> i32; + pub fn sceNetAdhocMatchingTerm() -> i32; + pub fn sceNetAdhocMatchingCreate( + mode: AdhocMatchingMode, + max_peers: i32, + port: u16, + buf_size: i32, + hello_delay: u32, + ping_delay: u32, + init_count: i32, + msg_delay: u32, + callback: AdhocMatchingCallback, + ) -> i32; + pub fn sceNetAdhocMatchingDelete(matching_id: i32) -> i32; + pub fn sceNetAdhocMatchingStart( + matching_id: i32, + evth_pri: i32, + evth_stack: i32, + inth_pri: i32, + inth_stack: i32, + opt_len: i32, + opt_data: *mut c_void, + ) -> i32; + pub fn sceNetAdhocMatchingStop(matching_id: i32) -> i32; + pub fn sceNetAdhocMatchingSelectTarget( + matching_id: i32, + mac: *mut u8, + opt_len: i32, + opt_data: *mut c_void, + ) -> i32; + pub fn sceNetAdhocMatchingCancelTarget(matching_id: i32, mac: *mut u8) -> i32; + pub fn sceNetAdhocMatchingCancelTargetWithOpt( + matching_id: i32, + mac: *mut u8, + opt_len: i32, + opt_data: *mut c_void, + ) -> i32; + pub fn sceNetAdhocMatchingSendData( + matching_id: i32, + mac: *mut u8, + data_len: i32, + data: *mut c_void, + ) -> i32; + pub fn sceNetAdhocMatchingAbortSendData(matching_id: i32, mac: *mut u8) -> i32; + pub fn sceNetAdhocMatchingSetHelloOpt( + matching_id: i32, + opt_len: i32, + opt_data: *mut c_void, + ) -> i32; + pub fn sceNetAdhocMatchingGetHelloOpt( + matching_id: i32, + opt_len: *mut i32, + opt_data: *mut c_void, + ) -> i32; + pub fn sceNetAdhocMatchingGetMembers( + matching_id: i32, + length: *mut i32, + buf: *mut c_void, + ) -> i32; + pub fn sceNetAdhocMatchingGetPoolMaxAlloc() -> i32; + pub fn sceNetAdhocMatchingGetPoolStat(poolstat: *mut AdhocPoolStat) -> i32; +} + +extern "C" { + pub fn sceNetApctlInit(stack_size: i32, init_priority: i32) -> i32; + pub fn sceNetApctlTerm() -> i32; + pub fn sceNetApctlGetInfo(code: ApctlInfo, pinfo: *mut SceNetApctlInfo) -> i32; + pub fn sceNetApctlAddHandler(handler: SceNetApctlHandler, parg: *mut c_void) -> i32; + pub fn sceNetApctlDelHandler(handler_id: i32) -> i32; + pub fn sceNetApctlConnect(conn_index: i32) -> i32; + pub fn sceNetApctlDisconnect() -> i32; + pub fn sceNetApctlGetState(pstate: *mut ApctlState) -> i32; + + pub fn sceNetInetInit() -> i32; + pub fn sceNetInetTerm() -> i32; + pub fn sceNetInetAccept(s: i32, addr: *mut sockaddr, addr_len: *mut socklen_t) -> i32; + pub fn sceNetInetBind(s: i32, my_addr: *const sockaddr, addr_len: socklen_t) -> i32; + pub fn sceNetInetConnect(s: i32, serv_addr: *const sockaddr, addr_len: socklen_t) -> i32; + pub fn sceNetInetGetsockopt( + s: i32, + level: i32, + opt_name: i32, + opt_val: *mut c_void, + optl_en: *mut socklen_t, + ) -> i32; + pub fn sceNetInetListen(s: i32, backlog: i32) -> i32; + pub fn sceNetInetRecv(s: i32, buf: *mut c_void, len: usize, flags: i32) -> usize; + pub fn sceNetInetRecvfrom( + s: i32, + buf: *mut c_void, + flags: usize, + arg1: i32, + from: *mut sockaddr, + from_len: *mut socklen_t, + ) -> usize; + pub fn sceNetInetSend(s: i32, buf: *const c_void, len: usize, flags: i32) -> usize; + pub fn sceNetInetSendto( + s: i32, + buf: *const c_void, + len: usize, + flags: i32, + to: *const sockaddr, + to_len: socklen_t, + ) -> usize; + pub fn sceNetInetSetsockopt( + s: i32, + level: i32, + opt_name: i32, + opt_val: *const c_void, + opt_len: socklen_t, + ) -> i32; + pub fn sceNetInetShutdown(s: i32, how: i32) -> i32; + pub fn sceNetInetSocket(domain: i32, type_: i32, protocol: i32) -> i32; + pub fn sceNetInetClose(s: i32) -> i32; + pub fn sceNetInetGetErrno() -> i32; + + pub fn sceSslInit(unknown1: i32) -> i32; + pub fn sceSslEnd() -> i32; + pub fn sceSslGetUsedMemoryMax(memory: *mut u32) -> i32; + pub fn sceSslGetUsedMemoryCurrent(memory: *mut u32) -> i32; + + pub fn sceHttpInit(unknown1: u32) -> i32; + pub fn sceHttpEnd() -> i32; + pub fn sceHttpCreateTemplate(agent: *mut u8, unknown1: i32, unknown2: i32) -> i32; + pub fn sceHttpDeleteTemplate(templateid: i32) -> i32; + pub fn sceHttpCreateConnection( + templateid: i32, + host: *mut u8, + unknown1: *mut u8, + port: u16, + unknown2: i32, + ) -> i32; + pub fn sceHttpCreateConnectionWithURL(templateid: i32, url: *const u8, unknown1: i32) -> i32; + pub fn sceHttpDeleteConnection(connection_id: i32) -> i32; + pub fn sceHttpCreateRequest( + connection_id: i32, + method: HttpMethod, + path: *mut u8, + content_length: u64, + ) -> i32; + pub fn sceHttpCreateRequestWithURL( + connection_id: i32, + method: HttpMethod, + url: *mut u8, + content_length: u64, + ) -> i32; + pub fn sceHttpDeleteRequest(request_id: i32) -> i32; + pub fn sceHttpSendRequest(request_id: i32, data: *mut c_void, data_size: u32) -> i32; + pub fn sceHttpAbortRequest(request_id: i32) -> i32; + pub fn sceHttpReadData(request_id: i32, data: *mut c_void, data_size: u32) -> i32; + pub fn sceHttpGetContentLength(request_id: i32, content_length: *mut u64) -> i32; + pub fn sceHttpGetStatusCode(request_id: i32, status_code: *mut i32) -> i32; + pub fn sceHttpSetResolveTimeOut(id: i32, timeout: u32) -> i32; + pub fn sceHttpSetResolveRetry(id: i32, count: i32) -> i32; + pub fn sceHttpSetConnectTimeOut(id: i32, timeout: u32) -> i32; + pub fn sceHttpSetSendTimeOut(id: i32, timeout: u32) -> i32; + pub fn sceHttpSetRecvTimeOut(id: i32, timeout: u32) -> i32; + pub fn sceHttpEnableKeepAlive(id: i32) -> i32; + pub fn sceHttpDisableKeepAlive(id: i32) -> i32; + pub fn sceHttpEnableRedirect(id: i32) -> i32; + pub fn sceHttpDisableRedirect(id: i32) -> i32; + pub fn sceHttpEnableCookie(id: i32) -> i32; + pub fn sceHttpDisableCookie(id: i32) -> i32; + pub fn sceHttpSaveSystemCookie() -> i32; + pub fn sceHttpLoadSystemCookie() -> i32; + pub fn sceHttpAddExtraHeader(id: i32, name: *mut u8, value: *mut u8, unknown1: i32) -> i32; + pub fn sceHttpDeleteHeader(id: i32, name: *const u8) -> i32; + pub fn sceHttpsInit(unknown1: i32, unknown2: i32, unknown3: i32, unknown4: i32) -> i32; + pub fn sceHttpsEnd() -> i32; + pub fn sceHttpsLoadDefaultCert(unknown1: i32, unknown2: i32) -> i32; + pub fn sceHttpDisableAuth(id: i32) -> i32; + pub fn sceHttpDisableCache(id: i32) -> i32; + pub fn sceHttpEnableAuth(id: i32) -> i32; + pub fn sceHttpEnableCache(id: i32) -> i32; + pub fn sceHttpEndCache() -> i32; + pub fn sceHttpGetAllHeader(request: i32, header: *mut *mut u8, header_size: *mut u32) -> i32; + pub fn sceHttpGetNetworkErrno(request: i32, err_num: *mut i32) -> i32; + pub fn sceHttpGetProxy( + id: i32, + activate_flag: *mut i32, + mode: *mut i32, + proxy_host: *mut u8, + len: usize, + proxy_port: *mut u16, + ) -> i32; + pub fn sceHttpInitCache(max_size: usize) -> i32; + pub fn sceHttpSetAuthInfoCB(id: i32, cbfunc: HttpPasswordCB) -> i32; + pub fn sceHttpSetProxy( + id: i32, + activate_flag: i32, + mode: i32, + new_proxy_host: *const u8, + new_proxy_port: u16, + ) -> i32; + pub fn sceHttpSetResHeaderMaxSize(id: i32, header_size: u32) -> i32; + pub fn sceHttpSetMallocFunction( + malloc_func: HttpMallocFunction, + free_func: HttpFreeFunction, + realloc_func: HttpReallocFunction, + ) -> i32; + + pub fn sceNetResolverInit() -> i32; + pub fn sceNetResolverCreate(rid: *mut i32, buf: *mut c_void, buf_length: u32) -> i32; + pub fn sceNetResolverDelete(rid: i32) -> i32; + pub fn sceNetResolverStartNtoA( + rid: i32, + hostname: *const u8, + addr: *mut in_addr, + timeout: u32, + retry: i32, + ) -> i32; + pub fn sceNetResolverStartAtoN( + rid: i32, + addr: *const in_addr, + hostname: *mut u8, + hostname_len: u32, + timeout: u32, + retry: i32, + ) -> i32; + pub fn sceNetResolverStop(rid: i32) -> i32; + pub fn sceNetResolverTerm() -> i32; +} diff --git a/vendor/libc/src/sgx.rs b/vendor/libc/src/sgx.rs new file mode 100644 index 0000000..7da6269 --- /dev/null +++ b/vendor/libc/src/sgx.rs @@ -0,0 +1,47 @@ +//! SGX C types definition + +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 c_char = i8; +pub type c_long = i64; +pub type c_ulong = u64; + +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/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/switch.rs b/vendor/libc/src/switch.rs new file mode 100644 index 0000000..030ab20 --- /dev/null +++ b/vendor/libc/src/switch.rs @@ -0,0 +1,49 @@ +//! Switch 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/libc/src/teeos/mod.rs b/vendor/libc/src/teeos/mod.rs new file mode 100644 index 0000000..4f1fef1 --- /dev/null +++ b/vendor/libc/src/teeos/mod.rs @@ -0,0 +1,1385 @@ +//! Libc bindings for teeos +//! +//! Apparently the loader just dynamically links it anyway, but fails +//! when linking is explicitly requested. +#![allow(non_camel_case_types)] +#![allow(non_snake_case)] + +// only supported on Rust > 1.59, so we can directly reexport c_void from core. +pub use core::ffi::c_void; + +use Option; + +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_bool = i32; + +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 pid_t = c_int; + +// aarch64 specifc +pub type c_char = u8; + +pub type wchar_t = u32; + +pub type c_long = i64; + +pub type c_ulong = u64; + +#[repr(align(16))] +pub struct _CLongDouble(pub u128); + +// long double in C means A float point value, which has 128bit length. +// but some bit maybe not used, so the really length of long double could be 80(x86) or 128(power pc/IEEE) +// this is different from f128(not stable and not included default) in Rust, so we use u128 for FFI(Rust to C). +// this is unstable and will couse to memfault/data abort. +pub type c_longdouble = _CLongDouble; + +pub type pthread_t = c_ulong; + +pub type pthread_key_t = c_uint; + +pub type pthread_spinlock_t = c_int; + +pub type off_t = i64; + +pub type time_t = c_long; + +pub type clock_t = c_long; + +pub type clockid_t = c_int; + +pub type suseconds_t = c_long; + +pub type once_fn = extern "C" fn() -> c_void; + +pub type pthread_once_t = c_int; + +pub type va_list = *mut c_char; + +pub type wint_t = c_uint; + +pub type wctype_t = c_ulong; + +pub type cmpfunc = extern "C" fn(x: *const c_void, y: *const c_void) -> c_int; + +#[repr(align(8))] +#[repr(C)] +pub struct pthread_cond_t { + #[doc(hidden)] + size: [u8; __SIZEOF_PTHREAD_COND_T], +} + +#[repr(align(8))] +#[repr(C)] +pub struct pthread_mutex_t { + #[doc(hidden)] + size: [u8; __SIZEOF_PTHREAD_MUTEX_T], +} + +#[repr(align(4))] +#[repr(C)] +pub struct pthread_mutexattr_t { + #[doc(hidden)] + size: [u8; __SIZEOF_PTHREAD_MUTEXATTR_T], +} + +#[repr(align(4))] +#[repr(C)] +pub struct pthread_condattr_t { + #[doc(hidden)] + size: [u8; __SIZEOF_PTHREAD_CONDATTR_T], +} + +#[repr(C)] +pub struct pthread_attr_t { + __size: [u64; 7], +} + +#[repr(C)] +pub struct cpu_set_t { + bits: [c_ulong; 128 / core::mem::size_of::()], +} + +#[repr(C)] +pub struct timespec { + pub tv_sec: time_t, + pub tv_nsec: c_long, +} + +#[repr(C)] +pub struct timeval { + pub tv_sec: time_t, + pub tv_usec: suseconds_t, +} + +#[repr(C)] +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(C)] +pub struct mbstate_t { + pub __opaque1: c_uint, + pub __opaque2: c_uint, +} + +#[repr(C)] +pub struct sem_t { + pub __val: [c_int; 4 * core::mem::size_of::() / core::mem::size_of::()], +} + +#[repr(C)] +pub struct div_t { + pub quot: c_int, + pub rem: c_int, +} + +// fcntl +pub const O_CREAT: u32 = 0o100; + +pub const O_EXCL: u32 = 0o200; + +pub const O_NOCTTY: u32 = 0o400; + +pub const O_TRUNC: u32 = 0o1000; + +pub const O_APPEND: u32 = 0o2000; + +pub const O_NONBLOCK: u32 = 0o4000; + +pub const O_DSYNC: u32 = 0o10000; + +pub const O_SYNC: u32 = 0o4010000; + +pub const O_RSYNC: u32 = 0o4010000; + +pub const O_DIRECTORY: u32 = 0o200000; + +pub const O_NOFOLLOW: u32 = 0o400000; + +pub const O_CLOEXEC: u32 = 0o2000000; + +pub const O_ASYNC: u32 = 0o20000; + +pub const O_DIRECT: u32 = 0o40000; + +pub const O_LARGEFILE: u32 = 0o100000; + +pub const O_NOATIME: u32 = 0o1000000; + +pub const O_PATH: u32 = 0o10000000; + +pub const O_TMPFILE: u32 = 0o20200000; + +pub const O_NDELAY: u32 = O_NONBLOCK; + +pub const F_DUPFD: u32 = 0; + +pub const F_GETFD: u32 = 1; + +pub const F_SETFD: u32 = 2; + +pub const F_GETFL: u32 = 3; + +pub const F_SETFL: u32 = 4; + +pub const F_SETOWN: u32 = 8; + +pub const F_GETOWN: u32 = 9; + +pub const F_SETSIG: u32 = 10; + +pub const F_GETSIG: u32 = 11; + +pub const F_GETLK: u32 = 12; + +pub const F_SETLK: u32 = 13; + +pub const F_SETLKW: u32 = 14; + +pub const F_SETOWN_EX: u32 = 15; + +pub const F_GETOWN_EX: u32 = 16; + +pub const F_GETOWNER_UIDS: u32 = 17; + +// mman +pub const MAP_FAILED: u64 = 0xffffffffffffffff; + +pub const MAP_FIXED_NOREPLACE: u32 = 0x100000; + +pub const MAP_SHARED_VALIDATE: u32 = 0x03; + +pub const MAP_SHARED: u32 = 0x01; + +pub const MAP_PRIVATE: u32 = 0x02; + +pub const MAP_TYPE: u32 = 0x0f; + +pub const MAP_FIXED: u32 = 0x10; + +pub const MAP_ANON: u32 = 0x20; + +pub const MAP_ANONYMOUS: u32 = MAP_ANON; + +pub const MAP_NORESERVE: u32 = 0x4000; + +pub const MAP_GROWSDOWN: u32 = 0x0100; + +pub const MAP_DENYWRITE: u32 = 0x0800; + +pub const MAP_EXECUTABLE: u32 = 0x1000; + +pub const MAP_LOCKED: u32 = 0x2000; + +pub const MAP_POPULATE: u32 = 0x8000; + +pub const MAP_NONBLOCK: u32 = 0x10000; + +pub const MAP_STACK: u32 = 0x20000; + +pub const MAP_HUGETLB: u32 = 0x40000; + +pub const MAP_SYNC: u32 = 0x80000; + +pub const MAP_FILE: u32 = 0; + +pub const MAP_HUGE_SHIFT: u32 = 26; + +pub const MAP_HUGE_MASK: u32 = 0x3f; + +pub const MAP_HUGE_16KB: u32 = 14 << 26; + +pub const MAP_HUGE_64KB: u32 = 16 << 26; + +pub const MAP_HUGE_512KB: u32 = 19 << 26; + +pub const MAP_HUGE_1MB: u32 = 20 << 26; + +pub const MAP_HUGE_2MB: u32 = 21 << 26; + +pub const MAP_HUGE_8MB: u32 = 23 << 26; + +pub const MAP_HUGE_16MB: u32 = 24 << 26; + +pub const MAP_HUGE_32MB: u32 = 25 << 26; + +pub const MAP_HUGE_256MB: u32 = 28 << 26; + +pub const MAP_HUGE_512MB: u32 = 29 << 26; + +pub const MAP_HUGE_1GB: u32 = 30 << 26; + +pub const MAP_HUGE_2GB: u32 = 31 << 26; + +pub const MAP_HUGE_16GB: u32 = 34u32 << 26; + +pub const PROT_NONE: u32 = 0; + +pub const PROT_READ: u32 = 1; + +pub const PROT_WRITE: u32 = 2; + +pub const PROT_EXEC: u32 = 4; + +pub const PROT_GROWSDOWN: u32 = 0x01000000; + +pub const PROT_GROWSUP: u32 = 0x02000000; + +pub const MS_ASYNC: u32 = 1; + +pub const MS_INVALIDATE: u32 = 2; + +pub const MS_SYNC: u32 = 4; + +pub const MCL_CURRENT: u32 = 1; + +pub const MCL_FUTURE: u32 = 2; + +pub const MCL_ONFAULT: u32 = 4; + +pub const POSIX_MADV_NORMAL: u32 = 0; + +pub const POSIX_MADV_RANDOM: u32 = 1; + +pub const POSIX_MADV_SEQUENTIAL: u32 = 2; + +pub const POSIX_MADV_WILLNEED: u32 = 3; + +pub const POSIX_MADV_DONTNEED: u32 = 4; + +// wctype +pub const WCTYPE_ALNUM: u64 = 1; + +pub const WCTYPE_ALPHA: u64 = 2; + +pub const WCTYPE_BLANK: u64 = 3; + +pub const WCTYPE_CNTRL: u64 = 4; + +pub const WCTYPE_DIGIT: u64 = 5; + +pub const WCTYPE_GRAPH: u64 = 6; + +pub const WCTYPE_LOWER: u64 = 7; + +pub const WCTYPE_PRINT: u64 = 8; + +pub const WCTYPE_PUNCT: u64 = 9; + +pub const WCTYPE_SPACE: u64 = 10; + +pub const WCTYPE_UPPER: u64 = 11; + +pub const WCTYPE_XDIGIT: u64 = 12; + +// locale +pub const LC_CTYPE: i32 = 0; + +pub const LC_NUMERIC: i32 = 1; + +pub const LC_TIME: i32 = 2; + +pub const LC_COLLATE: i32 = 3; + +pub const LC_MONETARY: i32 = 4; + +pub const LC_MESSAGES: i32 = 5; + +pub const LC_ALL: i32 = 6; + +// pthread +pub const __SIZEOF_PTHREAD_COND_T: usize = 48; + +pub const __SIZEOF_PTHREAD_MUTEX_T: usize = 40; + +pub const __SIZEOF_PTHREAD_MUTEXATTR_T: usize = 4; + +pub const __SIZEOF_PTHREAD_CONDATTR_T: usize = 4; + +// 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 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 EPROTONOSUPPOR: c_int = 93; + +pub const ESOCKTNOSUPPOR: 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 ERFKILL: c_int = 132; + +pub const EHWPOISON: c_int = 133; + +// pthread_attr.h +pub const TEESMP_THREAD_ATTR_CA_WILDCARD: c_int = 0; + +pub const TEESMP_THREAD_ATTR_CA_INHERIT: c_int = -1; + +pub const TEESMP_THREAD_ATTR_TASK_ID_INHERIT: c_int = -1; + +pub const TEESMP_THREAD_ATTR_HAS_SHADOW: c_int = 0x1; + +pub const TEESMP_THREAD_ATTR_NO_SHADOW: c_int = 0x0; + +// unistd.h +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_STREAM_MAX: c_int = 5; + +pub const _SC_TZNAME_MAX: c_int = 6; + +pub const _SC_JOB_CONTROL: c_int = 7; + +pub const _SC_SAVED_IDS: c_int = 8; + +pub const _SC_REALTIME_SIGNALS: c_int = 9; + +pub const _SC_PRIORITY_SCHEDULING: c_int = 10; + +pub const _SC_TIMERS: c_int = 11; + +pub const _SC_ASYNCHRONOUS_IO: c_int = 12; + +pub const _SC_PRIORITIZED_IO: c_int = 13; + +pub const _SC_SYNCHRONIZED_IO: c_int = 14; + +pub const _SC_FSYNC: c_int = 15; + +pub const _SC_MAPPED_FILES: c_int = 16; + +pub const _SC_MEMLOCK: c_int = 17; + +pub const _SC_MEMLOCK_RANGE: c_int = 18; + +pub const _SC_MEMORY_PROTECTION: c_int = 19; + +pub const _SC_MESSAGE_PASSING: c_int = 20; + +pub const _SC_SEMAPHORES: c_int = 21; + +pub const _SC_SHARED_MEMORY_OBJECTS: c_int = 22; + +pub const _SC_AIO_LISTIO_MAX: c_int = 23; + +pub const _SC_AIO_MAX: c_int = 24; + +pub const _SC_AIO_PRIO_DELTA_MAX: c_int = 25; + +pub const _SC_DELAYTIMER_MAX: c_int = 26; + +pub const _SC_MQ_OPEN_MAX: c_int = 27; + +pub const _SC_MQ_PRIO_MAX: c_int = 28; + +pub const _SC_VERSION: c_int = 29; + +pub const _SC_PAGE_SIZE: c_int = 30; + +pub const _SC_PAGESIZE: c_int = 30; /* !! */ + +pub const _SC_RTSIG_MAX: c_int = 31; + +pub const _SC_SEM_NSEMS_MAX: c_int = 32; + +pub const _SC_SEM_VALUE_MAX: c_int = 33; + +pub const _SC_SIGQUEUE_MAX: c_int = 34; + +pub const _SC_TIMER_MAX: c_int = 35; + +pub const _SC_BC_BASE_MAX: c_int = 36; + +pub const _SC_BC_DIM_MAX: c_int = 37; + +pub const _SC_BC_SCALE_MAX: c_int = 38; + +pub const _SC_BC_STRING_MAX: c_int = 39; + +pub const _SC_COLL_WEIGHTS_MAX: c_int = 40; + +pub const _SC_EXPR_NEST_MAX: c_int = 42; + +pub const _SC_LINE_MAX: c_int = 43; + +pub const _SC_RE_DUP_MAX: c_int = 44; + +pub const _SC_2_VERSION: c_int = 46; + +pub const _SC_2_C_BIND: c_int = 47; + +pub const _SC_2_C_DEV: c_int = 48; + +pub const _SC_2_FORT_DEV: c_int = 49; + +pub const _SC_2_FORT_RUN: c_int = 50; + +pub const _SC_2_SW_DEV: c_int = 51; + +pub const _SC_2_LOCALEDEF: c_int = 52; + +pub const _SC_UIO_MAXIOV: c_int = 60; /* !! */ + +pub const _SC_IOV_MAX: c_int = 60; + +pub const _SC_THREADS: c_int = 67; + +pub const _SC_THREAD_SAFE_FUNCTIONS: c_int = 68; + +pub const _SC_GETGR_R_SIZE_MAX: c_int = 69; + +pub const _SC_GETPW_R_SIZE_MAX: c_int = 70; + +pub const _SC_LOGIN_NAME_MAX: c_int = 71; + +pub const _SC_TTY_NAME_MAX: c_int = 72; + +pub const _SC_THREAD_DESTRUCTOR_ITERATIONS: c_int = 73; + +pub const _SC_THREAD_KEYS_MAX: c_int = 74; + +pub const _SC_THREAD_STACK_MIN: c_int = 75; + +pub const _SC_THREAD_THREADS_MAX: c_int = 76; + +pub const _SC_THREAD_ATTR_STACKADDR: c_int = 77; + +pub const _SC_THREAD_ATTR_STACKSIZE: c_int = 78; + +pub const _SC_THREAD_PRIORITY_SCHEDULING: c_int = 79; + +pub const _SC_THREAD_PRIO_INHERIT: c_int = 80; + +pub const _SC_THREAD_PRIO_PROTECT: c_int = 81; + +pub const _SC_THREAD_PROCESS_SHARED: c_int = 82; + +pub const _SC_NPROCESSORS_CONF: c_int = 83; + +pub const _SC_NPROCESSORS_ONLN: c_int = 84; + +pub const _SC_PHYS_PAGES: c_int = 85; + +pub const _SC_AVPHYS_PAGES: c_int = 86; + +pub const _SC_ATEXIT_MAX: c_int = 87; + +pub const _SC_PASS_MAX: c_int = 88; + +pub const _SC_XOPEN_VERSION: c_int = 89; + +pub const _SC_XOPEN_XCU_VERSION: c_int = 90; + +pub const _SC_XOPEN_UNIX: c_int = 91; + +pub const _SC_XOPEN_CRYPT: c_int = 92; + +pub const _SC_XOPEN_ENH_I18N: c_int = 93; + +pub const _SC_XOPEN_SHM: c_int = 94; + +pub const _SC_2_CHAR_TERM: c_int = 95; + +pub const _SC_2_UPE: c_int = 97; + +pub const _SC_XOPEN_XPG2: c_int = 98; + +pub const _SC_XOPEN_XPG3: c_int = 99; + +pub const _SC_XOPEN_XPG4: c_int = 100; + +pub const _SC_NZERO: c_int = 109; + +pub const _SC_XBS5_ILP32_OFF32: c_int = 125; + +pub const _SC_XBS5_ILP32_OFFBIG: c_int = 126; + +pub const _SC_XBS5_LP64_OFF64: c_int = 127; + +pub const _SC_XBS5_LPBIG_OFFBIG: c_int = 128; + +pub const _SC_XOPEN_LEGACY: c_int = 129; + +pub const _SC_XOPEN_REALTIME: c_int = 130; + +pub const _SC_XOPEN_REALTIME_THREADS: c_int = 131; + +pub const _SC_ADVISORY_INFO: c_int = 132; + +pub const _SC_BARRIERS: c_int = 133; + +pub const _SC_CLOCK_SELECTION: c_int = 137; + +pub const _SC_CPUTIME: c_int = 138; + +pub const _SC_THREAD_CPUTIME: c_int = 139; + +pub const _SC_MONOTONIC_CLOCK: c_int = 149; + +pub const _SC_READER_WRITER_LOCKS: c_int = 153; + +pub const _SC_SPIN_LOCKS: c_int = 154; + +pub const _SC_REGEXP: c_int = 155; + +pub const _SC_SHELL: c_int = 157; + +pub const _SC_SPAWN: c_int = 159; + +pub const _SC_SPORADIC_SERVER: c_int = 160; + +pub const _SC_THREAD_SPORADIC_SERVER: c_int = 161; + +pub const _SC_TIMEOUTS: c_int = 164; + +pub const _SC_TYPED_MEMORY_OBJECTS: c_int = 165; + +pub const _SC_2_PBS: c_int = 168; + +pub const _SC_2_PBS_ACCOUNTING: c_int = 169; + +pub const _SC_2_PBS_LOCATE: c_int = 170; + +pub const _SC_2_PBS_MESSAGE: c_int = 171; + +pub const _SC_2_PBS_TRACK: c_int = 172; + +pub const _SC_SYMLOOP_MAX: c_int = 173; + +pub const _SC_STREAMS: c_int = 174; + +pub const _SC_2_PBS_CHECKPOINT: c_int = 175; + +pub const _SC_V6_ILP32_OFF32: c_int = 176; + +pub const _SC_V6_ILP32_OFFBIG: c_int = 177; + +pub const _SC_V6_LP64_OFF64: c_int = 178; + +pub const _SC_V6_LPBIG_OFFBIG: c_int = 179; + +pub const _SC_HOST_NAME_MAX: c_int = 180; + +pub const _SC_TRACE: c_int = 181; + +pub const _SC_TRACE_EVENT_FILTER: c_int = 182; + +pub const _SC_TRACE_INHERIT: c_int = 183; + +pub const _SC_TRACE_LOG: c_int = 184; + +pub const _SC_IPV6: c_int = 235; + +pub const _SC_RAW_SOCKETS: c_int = 236; + +pub const _SC_V7_ILP32_OFF32: c_int = 237; + +pub const _SC_V7_ILP32_OFFBIG: c_int = 238; + +pub const _SC_V7_LP64_OFF64: c_int = 239; + +pub const _SC_V7_LPBIG_OFFBIG: c_int = 240; + +pub const _SC_SS_REPL_MAX: c_int = 241; + +pub const _SC_TRACE_EVENT_NAME_MAX: c_int = 242; + +pub const _SC_TRACE_NAME_MAX: c_int = 243; + +pub const _SC_TRACE_SYS_MAX: c_int = 244; + +pub const _SC_TRACE_USER_EVENT_MAX: c_int = 245; + +pub const _SC_XOPEN_STREAMS: c_int = 246; + +pub const _SC_THREAD_ROBUST_PRIO_INHERIT: c_int = 247; + +pub const _SC_THREAD_ROBUST_PRIO_PROTECT: c_int = 248; + +// limits.h +pub const PTHREAD_KEYS_MAX: c_int = 128; + +pub const PTHREAD_STACK_MIN: c_int = 2048; + +pub const PTHREAD_DESTRUCTOR_ITERATIONS: c_int = 4; + +pub const SEM_VALUE_MAX: c_int = 0x7fffffff; + +pub const SEM_NSEMS_MAX: c_int = 256; + +pub const DELAYTIMER_MAX: c_int = 0x7fffffff; + +pub const MQ_PRIO_MAX: c_int = 32768; + +pub const LOGIN_NAME_MAX: c_int = 256; + +// time.h +pub const CLOCK_REALTIME: clockid_t = 0; + +pub const CLOCK_MONOTONIC: clockid_t = 1; + +pub const PTHREAD_MUTEX_INITIALIZER: pthread_mutex_t = pthread_mutex_t { + size: [0; __SIZEOF_PTHREAD_MUTEX_T], +}; + +pub const PTHREAD_COND_INITIALIZER: pthread_cond_t = pthread_cond_t { + size: [0; __SIZEOF_PTHREAD_COND_T], +}; + +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; + +extern "C" { + // ---- ALLOC ----------------------------------------------------------------------------- + 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; + + pub fn aligned_alloc(align: size_t, len: size_t) -> *mut c_void; + + pub fn free(p: *mut c_void); + + pub fn posix_memalign(memptr: *mut *mut c_void, align: size_t, size: size_t) -> c_int; + + pub fn memchr(cx: *const c_void, c: c_int, n: size_t) -> *mut c_void; + + pub fn wmemchr(cx: *const wchar_t, c: wchar_t, n: size_t) -> *mut wchar_t; + + pub fn memcmp(cx: *const c_void, ct: *const c_void, n: size_t) -> c_int; + + pub fn memcpy(dest: *mut c_void, src: *const c_void, n: size_t) -> *mut c_void; + + pub fn memmove(dest: *mut c_void, src: *const c_void, n: size_t) -> *mut c_void; + + pub fn memset(dest: *mut c_void, c: c_int, n: size_t) -> *mut c_void; + + // ----- PTHREAD --------------------------------------------------------------------------- + pub fn pthread_self() -> pthread_t; + + pub fn pthread_join(native: pthread_t, value: *mut *mut c_void) -> c_int; + + // detach or pthread_attr_setdetachstate must not be called! + //pub fn pthread_detach(thread: pthread_t) -> c_int; + + pub fn pthread_exit(value: *mut c_void) -> !; + + pub fn pthread_attr_init(attr: *mut pthread_attr_t) -> c_int; + + pub fn pthread_attr_destroy(attr: *mut pthread_attr_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 pthread_attr_setstacksize(attr: *mut pthread_attr_t, stack_size: size_t) -> c_int; + + pub fn pthread_attr_getstacksize(attr: *const pthread_attr_t, size: *mut size_t) -> c_int; + + pub fn pthread_attr_settee( + attr: *mut pthread_attr_t, + ca: c_int, + task_id: c_int, + shadow: c_int, + ) -> c_int; + + // C-TA API do not include this interface, but TA can use. + pub fn sched_yield() -> c_int; + + pub fn pthread_key_create( + key: *mut pthread_key_t, + dtor: Option, + ) -> c_int; + + pub fn pthread_key_delete(key: pthread_key_t) -> c_int; + + pub fn pthread_getspecific(key: pthread_key_t) -> *mut c_void; + + pub fn pthread_setspecific(key: pthread_key_t, value: *const c_void) -> c_int; + + pub fn pthread_mutex_destroy(lock: *mut pthread_mutex_t) -> c_int; + + pub fn pthread_mutex_init( + lock: *mut pthread_mutex_t, + attr: *const pthread_mutexattr_t, + ) -> c_int; + + pub fn pthread_mutex_lock(lock: *mut pthread_mutex_t) -> c_int; + + pub fn pthread_mutex_trylock(lock: *mut pthread_mutex_t) -> c_int; + + pub fn pthread_mutex_unlock(lock: *mut pthread_mutex_t) -> c_int; + + pub fn pthread_mutexattr_destroy(attr: *mut pthread_mutexattr_t) -> c_int; + + pub fn pthread_mutexattr_init(attr: *mut pthread_mutexattr_t) -> c_int; + + pub fn pthread_mutexattr_settype(attr: *mut pthread_mutexattr_t, _type: c_int) -> c_int; + + pub fn pthread_mutexattr_setpshared(attr: *mut pthread_mutexattr_t, pshared: c_int) -> c_int; + + pub fn pthread_cond_broadcast(cond: *mut pthread_cond_t) -> c_int; + + pub fn pthread_cond_destroy(cond: *mut pthread_cond_t) -> c_int; + + pub fn pthread_cond_init(cond: *mut pthread_cond_t, attr: *const pthread_condattr_t) -> c_int; + + pub fn pthread_cond_signal(cond: *mut pthread_cond_t) -> c_int; + + pub fn pthread_cond_wait(cond: *mut pthread_cond_t, lock: *mut pthread_mutex_t) -> c_int; + + pub fn pthread_cond_timedwait( + cond: *mut pthread_cond_t, + lock: *mut pthread_mutex_t, + abstime: *const ::timespec, + ) -> ::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 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_setschedprio(native: pthread_t, priority: c_int) -> c_int; + + pub fn pthread_once(pot: *mut pthread_once_t, f: Option) -> c_int; + + pub fn pthread_equal(p1: pthread_t, p2: pthread_t) -> c_int; + + pub fn pthread_mutexattr_setprotocol(a: *mut pthread_mutexattr_t, protocol: c_int) -> c_int; + + pub fn pthread_attr_setstack( + attr: *mut pthread_attr_t, + stack: *mut c_void, + size: size_t, + ) -> c_int; + + pub fn pthread_setaffinity_np(td: pthread_t, size: size_t, set: *const cpu_set_t) -> c_int; + + pub fn pthread_getaffinity_np(td: pthread_t, size: size_t, set: *mut cpu_set_t) -> c_int; + + // stdio.h + pub fn printf(fmt: *const c_char, ...) -> c_int; + + pub fn scanf(fmt: *const c_char, ...) -> c_int; + + pub fn snprintf(s: *mut c_char, n: size_t, fmt: *const c_char, ...) -> c_int; + + pub fn sprintf(s: *mut c_char, fmt: *const c_char, ...) -> c_int; + + pub fn vsnprintf(s: *mut c_char, n: size_t, fmt: *const c_char, ap: va_list) -> c_int; + + pub fn vsprintf(s: *mut c_char, fmt: *const c_char, ap: va_list) -> c_int; + + // Not available. + //pub fn pthread_setname_np(thread: pthread_t, name: *const c_char) -> c_int; + + pub fn abort() -> !; + + // Not available. + //pub fn prctl(op: c_int, ...) -> c_int; + + pub fn sched_getaffinity(pid: pid_t, cpusetsize: size_t, cpuset: *mut cpu_set_t) -> c_int; + + pub fn sched_setaffinity(pid: pid_t, cpusetsize: size_t, cpuset: *const cpu_set_t) -> c_int; + + // sysconf is currently only implemented as a stub. + pub fn sysconf(name: c_int) -> c_long; + + // mman.h + pub fn mmap( + addr: *mut c_void, + len: size_t, + prot: c_int, + flags: c_int, + fd: c_int, + offset: off_t, + ) -> *mut c_void; + pub fn munmap(addr: *mut c_void, len: size_t) -> c_int; + + // errno.h + pub fn __errno_location() -> *mut c_int; + + pub fn strerror(e: c_int) -> *mut c_char; + + // time.h + pub fn clock_gettime(clock_id: clockid_t, tp: *mut timespec) -> c_int; + + // unistd + pub fn getpid() -> pid_t; + + // time + pub fn gettimeofday(tv: *mut timeval, tz: *mut c_void) -> c_int; + + pub fn strftime( + restrict: *mut c_char, + sz: size_t, + _restrict: *const c_char, + __restrict: *const tm, + ) -> size_t; + + pub fn time(t: *mut time_t) -> time_t; + + // sem + 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, valp: *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, flags: c_int, ...) -> *mut sem_t; + + pub fn sem_post(sem: *mut sem_t) -> c_int; + + pub fn sem_unlink(name: *const c_char) -> c_int; + + pub fn sem_wait(sem: *mut sem_t) -> c_int; + + // locale + pub fn setlocale(cat: c_int, name: *const c_char) -> *mut c_char; + + pub fn strcoll(l: *const c_char, r: *const c_char) -> c_int; + + pub fn strxfrm(dest: *mut c_char, src: *const c_char, n: size_t) -> size_t; + + pub fn strtod(s: *const c_char, p: *mut *mut c_char) -> c_double; + + // multibyte + pub fn mbrtowc(wc: *mut wchar_t, src: *const c_char, n: size_t, st: *mut mbstate_t) -> size_t; + + pub fn wcrtomb(s: *mut c_char, wc: wchar_t, st: *mut mbstate_t) -> size_t; + + pub fn wctob(c: wint_t) -> c_int; + + // prng + pub fn srandom(seed: c_uint); + + pub fn initstate(seed: c_uint, state: *mut c_char, size: size_t) -> *mut c_char; + + pub fn setstate(state: *mut c_char) -> *mut c_char; + + pub fn random() -> c_long; + + // string + pub fn strchr(s: *const c_char, c: c_int) -> *mut c_char; + + pub fn strlen(cs: *const c_char) -> size_t; + + pub fn strcmp(l: *const c_char, r: *const c_char) -> c_int; + + pub fn strcpy(dest: *mut c_char, src: *const c_char) -> *mut c_char; + + pub fn strncmp(_l: *const c_char, r: *const c_char, n: size_t) -> c_int; + + pub fn strncpy(dest: *mut c_char, src: *const c_char, n: size_t) -> *mut c_char; + + pub fn strnlen(cs: *const c_char, n: size_t) -> size_t; + + pub fn strrchr(s: *const c_char, c: c_int) -> *mut c_char; + + pub fn strstr(h: *const c_char, n: *const c_char) -> *mut c_char; + + pub fn wcschr(s: *const wchar_t, c: wchar_t) -> *mut wchar_t; + + pub fn wcslen(s: *const wchar_t) -> size_t; + + // ctype + pub fn isalpha(c: c_int) -> c_int; + + pub fn isascii(c: c_int) -> c_int; + + pub fn isdigit(c: c_int) -> c_int; + + pub fn islower(c: c_int) -> c_int; + + pub fn isprint(c: c_int) -> c_int; + + pub fn isspace(c: c_int) -> c_int; + + pub fn iswctype(wc: wint_t, ttype: wctype_t) -> c_int; + + pub fn iswdigit(wc: wint_t) -> c_int; + + pub fn iswlower(wc: wint_t) -> c_int; + + pub fn iswspace(wc: wint_t) -> c_int; + + pub fn iswupper(wc: wint_t) -> c_int; + + pub fn towupper(wc: wint_t) -> wint_t; + + pub fn towlower(wc: wint_t) -> wint_t; + + // cmath + pub fn atan(x: c_double) -> c_double; + + pub fn ceil(x: c_double) -> c_double; + + pub fn ceilf(x: c_float) -> c_float; + + pub fn exp(x: c_double) -> c_double; + + pub fn fabs(x: c_double) -> c_double; + + pub fn floor(x: c_double) -> c_double; + + pub fn frexp(x: c_double, e: *mut c_int) -> c_double; + + pub fn log(x: c_double) -> c_double; + + pub fn log2(x: c_double) -> c_double; + + pub fn pow(x: c_double, y: c_double) -> c_double; + + pub fn roundf(x: c_float) -> c_float; + + pub fn scalbn(x: c_double, n: c_int) -> c_double; + + pub fn sqrt(x: c_double) -> c_double; + + // stdlib + pub fn abs(x: c_int) -> 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 bsearch( + key: *const c_void, + base: *const c_void, + nel: size_t, + width: size_t, + cmp: cmpfunc, + ) -> *mut c_void; + + pub fn div(num: c_int, den: c_int) -> div_t; + + pub fn ecvt(x: c_double, n: c_int, dp: *mut c_int, sign: *mut c_int) -> *mut c_char; + + pub fn imaxabs(a: intmax_t) -> intmax_t; + + pub fn llabs(a: c_longlong) -> c_longlong; + + pub fn qsort(base: *mut c_void, nel: size_t, width: size_t, cmp: cmpfunc); + + pub fn strtoul(s: *const c_char, p: *mut *mut c_char, base: c_int) -> c_ulong; + + pub fn strtol(s: *const c_char, p: *mut *mut c_char, base: c_int) -> c_long; + + pub fn wcstod(s: *const wchar_t, p: *mut *mut wchar_t) -> c_double; +} + +pub fn errno() -> c_int { + unsafe { *__errno_location() } +} + +pub fn CPU_COUNT_S(size: usize, cpuset: &cpu_set_t) -> c_int { + let mut s: u32 = 0; + let size_of_mask = core::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(core::mem::size_of::(), cpuset) +} diff --git a/vendor/libc/src/unix/aix/mod.rs b/vendor/libc/src/unix/aix/mod.rs new file mode 100644 index 0000000..c072ae5 --- /dev/null +++ b/vendor/libc/src/unix/aix/mod.rs @@ -0,0 +1,3363 @@ +pub type c_char = u8; +pub type caddr_t = *mut ::c_char; +pub type clockid_t = ::c_longlong; +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_BARRIER_SERIAL_THREAD: ::c_int = -1; +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; +#[deprecated(since = "0.2.64", note = "Not stable across OS versions")] +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 {const} 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_setguardsize(attr: *mut ::pthread_attr_t, guardsize: ::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, + servlen: ::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 stat64at( + dirfd: ::c_int, + path: *const ::c_char, + buf: *mut stat64, + flags: ::c_int, + ) -> ::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/align.rs b/vendor/libc/src/unix/align.rs new file mode 100644 index 0000000..2e7c954 --- /dev/null +++ b/vendor/libc/src/unix/align.rs @@ -0,0 +1,14 @@ +s! { + #[repr(align(4))] + pub struct in6_addr { + pub s6_addr: [u8; 16], + } +} + +pub const IN6ADDR_LOOPBACK_INIT: in6_addr = in6_addr { + s6_addr: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], +}; + +pub const IN6ADDR_ANY_INIT: in6_addr = in6_addr { + s6_addr: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], +}; diff --git a/vendor/libc/src/unix/bsd/apple/b32/align.rs b/vendor/libc/src/unix/bsd/apple/b32/align.rs new file mode 100644 index 0000000..ca1fe1c --- /dev/null +++ b/vendor/libc/src/unix/bsd/apple/b32/align.rs @@ -0,0 +1,7 @@ +s_no_extra_traits! { + #[allow(missing_debug_implementations)] + #[repr(align(16))] + pub struct max_align_t { + priv_: [f64; 2] + } +} diff --git a/vendor/libc/src/unix/bsd/apple/b32/mod.rs b/vendor/libc/src/unix/bsd/apple/b32/mod.rs new file mode 100644 index 0000000..4e45459 --- /dev/null +++ b/vendor/libc/src/unix/bsd/apple/b32/mod.rs @@ -0,0 +1,154 @@ +//! 32-bit specific Apple (ios/darwin) definitions + +pub type c_long = i32; +pub type c_ulong = u32; +pub type boolean_t = ::c_int; + +s! { + pub struct if_data { + 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: u32, + pub ifi_ipackets: u32, + pub ifi_ierrors: u32, + pub ifi_opackets: u32, + pub ifi_oerrors: u32, + pub ifi_collisions: u32, + pub ifi_ibytes: u32, + pub ifi_obytes: u32, + pub ifi_imcasts: u32, + pub ifi_omcasts: u32, + pub ifi_iqdrops: u32, + pub ifi_noproto: u32, + pub ifi_recvtiming: u32, + pub ifi_xmittiming: u32, + pub ifi_lastchange: ::timeval, + pub ifi_unused2: u32, + pub ifi_hwassist: u32, + pub ifi_reserved1: u32, + pub ifi_reserved2: u32, + } + + pub struct bpf_hdr { + pub bh_tstamp: ::timeval, + pub bh_caplen: u32, + 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! { + pub struct pthread_attr_t { + __sig: c_long, + __opaque: [::c_char; 36] + } + + pub struct pthread_once_t { + __sig: c_long, + __opaque: [::c_char; ::__PTHREAD_ONCE_SIZE__], + } +} + +cfg_if! { + if #[cfg(feature = "extra_traits")] { + impl PartialEq for pthread_attr_t { + fn eq(&self, other: &pthread_attr_t) -> bool { + self.__sig == other.__sig + && self.__opaque + .iter() + .zip(other.__opaque.iter()) + .all(|(a,b)| a == b) + } + } + impl Eq for pthread_attr_t {} + impl ::fmt::Debug for pthread_attr_t { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("pthread_attr_t") + .field("__sig", &self.__sig) + // FIXME: .field("__opaque", &self.__opaque) + .finish() + } + } + impl ::hash::Hash for pthread_attr_t { + fn hash(&self, state: &mut H) { + self.__sig.hash(state); + self.__opaque.hash(state); + } + } + impl PartialEq for pthread_once_t { + fn eq(&self, other: &pthread_once_t) -> bool { + self.__sig == other.__sig + && self.__opaque + .iter() + .zip(other.__opaque.iter()) + .all(|(a,b)| a == b) + } + } + impl Eq for pthread_once_t {} + impl ::fmt::Debug for pthread_once_t { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("pthread_once_t") + .field("__sig", &self.__sig) + .finish() + } + } + impl ::hash::Hash for pthread_once_t { + fn hash(&self, state: &mut H) { + self.__sig.hash(state); + self.__opaque.hash(state); + } + } + } +} + +#[doc(hidden)] +#[deprecated(since = "0.2.55")] +pub const NET_RT_MAXID: ::c_int = 10; + +pub const __PTHREAD_MUTEX_SIZE__: usize = 40; +pub const __PTHREAD_COND_SIZE__: usize = 24; +pub const __PTHREAD_CONDATTR_SIZE__: usize = 4; +pub const __PTHREAD_ONCE_SIZE__: usize = 4; +pub const __PTHREAD_RWLOCK_SIZE__: usize = 124; +pub const __PTHREAD_RWLOCKATTR_SIZE__: usize = 12; + +pub const TIOCTIMESTAMP: ::c_ulong = 0x40087459; +pub const TIOCDCDTIMESTAMP: ::c_ulong = 0x40087458; + +pub const BIOCSETF: ::c_ulong = 0x80084267; +pub const BIOCSRTIMEOUT: ::c_ulong = 0x8008426d; +pub const BIOCGRTIMEOUT: ::c_ulong = 0x4008426e; +pub const BIOCSETFNR: ::c_ulong = 0x8008427e; + +const _PTHREAD_ONCE_SIG_INIT: c_long = 0x30B1BCBA; +pub const PTHREAD_ONCE_INIT: ::pthread_once_t = ::pthread_once_t { + __sig: _PTHREAD_ONCE_SIG_INIT, + __opaque: [0; 4], +}; + +extern "C" { + pub fn exchangedata( + path1: *const ::c_char, + path2: *const ::c_char, + options: ::c_ulong, + ) -> ::c_int; +} + +cfg_if! { + if #[cfg(libc_align)] { + mod align; + pub use self::align::*; + } +} diff --git a/vendor/libc/src/unix/bsd/apple/b64/aarch64/align.rs b/vendor/libc/src/unix/bsd/apple/b64/aarch64/align.rs new file mode 100644 index 0000000..131e15b --- /dev/null +++ b/vendor/libc/src/unix/bsd/apple/b64/aarch64/align.rs @@ -0,0 +1,55 @@ +pub type mcontext_t = *mut __darwin_mcontext64; + +s_no_extra_traits! { + #[allow(missing_debug_implementations)] + pub struct max_align_t { + priv_: f64 + } +} + +s! { + pub struct ucontext_t { + pub uc_onstack: ::c_int, + pub uc_sigmask: ::sigset_t, + pub uc_stack: ::stack_t, + pub uc_link: *mut ::ucontext_t, + pub uc_mcsize: usize, + pub uc_mcontext: mcontext_t, + } + + pub struct __darwin_mcontext64 { + pub __es: __darwin_arm_exception_state64, + pub __ss: __darwin_arm_thread_state64, + pub __ns: __darwin_arm_neon_state64, + } + + pub struct __darwin_arm_exception_state64 { + pub __far: u64, + pub __esr: u32, + pub __exception: u32, + } + + pub struct __darwin_arm_thread_state64 { + pub __x: [u64; 29], + pub __fp: u64, + pub __lr: u64, + pub __sp: u64, + pub __pc: u64, + pub __cpsr: u32, + pub __pad: u32, + } + + // 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 new file mode 100644 index 0000000..79e9ac8 --- /dev/null +++ b/vendor/libc/src/unix/bsd/apple/b64/aarch64/mod.rs @@ -0,0 +1,14 @@ +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; + pub use self::align::*; + } +} diff --git a/vendor/libc/src/unix/bsd/apple/b64/align.rs b/vendor/libc/src/unix/bsd/apple/b64/align.rs new file mode 100644 index 0000000..ca1fe1c --- /dev/null +++ b/vendor/libc/src/unix/bsd/apple/b64/align.rs @@ -0,0 +1,7 @@ +s_no_extra_traits! { + #[allow(missing_debug_implementations)] + #[repr(align(16))] + pub struct max_align_t { + priv_: [f64; 2] + } +} diff --git a/vendor/libc/src/unix/bsd/apple/b64/mod.rs b/vendor/libc/src/unix/bsd/apple/b64/mod.rs new file mode 100644 index 0000000..2206210 --- /dev/null +++ b/vendor/libc/src/unix/bsd/apple/b64/mod.rs @@ -0,0 +1,159 @@ +//! 64-bit specific Apple (ios/darwin) definitions + +pub type c_long = i64; +pub type c_ulong = u64; + +s! { + pub struct timeval32 { + pub tv_sec: i32, + pub tv_usec: i32, + } + + pub struct if_data { + 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: u32, + pub ifi_ipackets: u32, + pub ifi_ierrors: u32, + pub ifi_opackets: u32, + pub ifi_oerrors: u32, + pub ifi_collisions: u32, + pub ifi_ibytes: u32, + pub ifi_obytes: u32, + pub ifi_imcasts: u32, + pub ifi_omcasts: u32, + pub ifi_iqdrops: u32, + pub ifi_noproto: u32, + pub ifi_recvtiming: u32, + pub ifi_xmittiming: u32, + pub ifi_lastchange: timeval32, + pub ifi_unused2: u32, + pub ifi_hwassist: u32, + pub ifi_reserved1: u32, + pub ifi_reserved2: u32, + } + + pub struct bpf_hdr { + pub bh_tstamp: ::timeval32, + pub bh_caplen: u32, + pub bh_datalen: u32, + pub bh_hdrlen: ::c_ushort, + } +} + +s_no_extra_traits! { + pub struct pthread_attr_t { + __sig: c_long, + __opaque: [::c_char; 56] + } + + pub struct pthread_once_t { + __sig: c_long, + __opaque: [::c_char; __PTHREAD_ONCE_SIZE__], + } +} + +cfg_if! { + if #[cfg(feature = "extra_traits")] { + impl PartialEq for pthread_attr_t { + fn eq(&self, other: &pthread_attr_t) -> bool { + self.__sig == other.__sig + && self.__opaque + .iter() + .zip(other.__opaque.iter()) + .all(|(a,b)| a == b) + } + } + impl Eq for pthread_attr_t {} + impl ::fmt::Debug for pthread_attr_t { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("pthread_attr_t") + .field("__sig", &self.__sig) + // FIXME: .field("__opaque", &self.__opaque) + .finish() + } + } + impl ::hash::Hash for pthread_attr_t { + fn hash(&self, state: &mut H) { + self.__sig.hash(state); + self.__opaque.hash(state); + } + } + impl PartialEq for pthread_once_t { + fn eq(&self, other: &pthread_once_t) -> bool { + self.__sig == other.__sig + && self.__opaque + .iter() + .zip(other.__opaque.iter()) + .all(|(a,b)| a == b) + } + } + impl Eq for pthread_once_t {} + impl ::fmt::Debug for pthread_once_t { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("pthread_once_t") + .field("__sig", &self.__sig) + .finish() + } + } + impl ::hash::Hash for pthread_once_t { + fn hash(&self, state: &mut H) { + self.__sig.hash(state); + self.__opaque.hash(state); + } + } + } +} + +#[doc(hidden)] +#[deprecated(since = "0.2.55")] +pub const NET_RT_MAXID: ::c_int = 11; + +pub const __PTHREAD_MUTEX_SIZE__: usize = 56; +pub const __PTHREAD_COND_SIZE__: usize = 40; +pub const __PTHREAD_CONDATTR_SIZE__: usize = 8; +pub const __PTHREAD_ONCE_SIZE__: usize = 8; +pub const __PTHREAD_RWLOCK_SIZE__: usize = 192; +pub const __PTHREAD_RWLOCKATTR_SIZE__: usize = 16; + +pub const TIOCTIMESTAMP: ::c_ulong = 0x40107459; +pub const TIOCDCDTIMESTAMP: ::c_ulong = 0x40107458; + +pub const BIOCSETF: ::c_ulong = 0x80104267; +pub const BIOCSRTIMEOUT: ::c_ulong = 0x8010426d; +pub const BIOCGRTIMEOUT: ::c_ulong = 0x4010426e; +pub const BIOCSETFNR: ::c_ulong = 0x8010427e; + +const _PTHREAD_ONCE_SIG_INIT: c_long = 0x30B1BCBA; +pub const PTHREAD_ONCE_INIT: ::pthread_once_t = ::pthread_once_t { + __sig: _PTHREAD_ONCE_SIG_INIT, + __opaque: [0; 8], +}; + +extern "C" { + pub fn exchangedata( + path1: *const ::c_char, + path2: *const ::c_char, + options: ::c_uint, + ) -> ::c_int; +} + +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 { + // Unknown target_arch + } +} diff --git a/vendor/libc/src/unix/bsd/apple/b64/x86_64/align.rs b/vendor/libc/src/unix/bsd/apple/b64/x86_64/align.rs new file mode 100644 index 0000000..ca1fe1c --- /dev/null +++ b/vendor/libc/src/unix/bsd/apple/b64/x86_64/align.rs @@ -0,0 +1,7 @@ +s_no_extra_traits! { + #[allow(missing_debug_implementations)] + #[repr(align(16))] + pub struct max_align_t { + priv_: [f64; 2] + } +} 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 new file mode 100644 index 0000000..653650c --- /dev/null +++ b/vendor/libc/src/unix/bsd/apple/b64/x86_64/mod.rs @@ -0,0 +1,180 @@ +pub type boolean_t = ::c_uint; +pub type mcontext_t = *mut __darwin_mcontext64; + +s! { + pub struct ucontext_t { + pub uc_onstack: ::c_int, + pub uc_sigmask: ::sigset_t, + pub uc_stack: ::stack_t, + pub uc_link: *mut ::ucontext_t, + pub uc_mcsize: usize, + pub uc_mcontext: mcontext_t, + } + + pub struct __darwin_mcontext64 { + pub __es: __darwin_x86_exception_state64, + pub __ss: __darwin_x86_thread_state64, + pub __fs: __darwin_x86_float_state64, + } + + pub struct __darwin_x86_exception_state64 { + pub __trapno: u16, + pub __cpu: u16, + pub __err: u32, + pub __faultvaddr: u64, + } + + pub struct __darwin_x86_thread_state64 { + pub __rax: u64, + pub __rbx: u64, + pub __rcx: u64, + pub __rdx: u64, + pub __rdi: u64, + pub __rsi: u64, + pub __rbp: u64, + pub __rsp: u64, + pub __r8: u64, + pub __r9: u64, + pub __r10: u64, + pub __r11: u64, + pub __r12: u64, + pub __r13: u64, + pub __r14: u64, + pub __r15: u64, + pub __rip: u64, + pub __rflags: u64, + pub __cs: u64, + pub __fs: u64, + pub __gs: u64, + } + + pub struct __darwin_x86_float_state64 { + pub __fpu_reserved: [::c_int; 2], + __fpu_fcw: ::c_short, + __fpu_fsw: ::c_short, + pub __fpu_ftw: u8, + pub __fpu_rsrv1: u8, + pub __fpu_fop: u16, + pub __fpu_ip: u32, + pub __fpu_cs: u16, + pub __fpu_rsrv2: u16, + pub __fpu_dp: u32, + pub __fpu_ds: u16, + pub __fpu_rsrv3: u16, + pub __fpu_mxcsr: u32, + pub __fpu_mxcsrmask: u32, + pub __fpu_stmm0: __darwin_mmst_reg, + pub __fpu_stmm1: __darwin_mmst_reg, + pub __fpu_stmm2: __darwin_mmst_reg, + pub __fpu_stmm3: __darwin_mmst_reg, + pub __fpu_stmm4: __darwin_mmst_reg, + pub __fpu_stmm5: __darwin_mmst_reg, + pub __fpu_stmm6: __darwin_mmst_reg, + pub __fpu_stmm7: __darwin_mmst_reg, + pub __fpu_xmm0: __darwin_xmm_reg, + pub __fpu_xmm1: __darwin_xmm_reg, + pub __fpu_xmm2: __darwin_xmm_reg, + pub __fpu_xmm3: __darwin_xmm_reg, + pub __fpu_xmm4: __darwin_xmm_reg, + pub __fpu_xmm5: __darwin_xmm_reg, + pub __fpu_xmm6: __darwin_xmm_reg, + pub __fpu_xmm7: __darwin_xmm_reg, + pub __fpu_xmm8: __darwin_xmm_reg, + pub __fpu_xmm9: __darwin_xmm_reg, + pub __fpu_xmm10: __darwin_xmm_reg, + pub __fpu_xmm11: __darwin_xmm_reg, + pub __fpu_xmm12: __darwin_xmm_reg, + pub __fpu_xmm13: __darwin_xmm_reg, + pub __fpu_xmm14: __darwin_xmm_reg, + pub __fpu_xmm15: __darwin_xmm_reg, + // this field is actually [u8; 96], but defining it with a bigger type + // allows us to auto-implement traits for it since the length of the + // array is less than 32 + __fpu_rsrv4: [u32; 24], + pub __fpu_reserved1: ::c_int, + } + + pub struct __darwin_mmst_reg { + pub __mmst_reg: [::c_char; 10], + pub __mmst_rsrv: [::c_char; 6], + } + + 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! { + if #[cfg(libc_align)] { + mod align; + pub use self::align::*; + } +} 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 new file mode 100644 index 0000000..0017403 --- /dev/null +++ b/vendor/libc/src/unix/bsd/apple/mod.rs @@ -0,0 +1,6630 @@ +//! Apple (ios/darwin)-specific definitions +//! +//! This covers *-apple-* triples currently +pub type c_char = i8; +pub type wchar_t = i32; +pub type clock_t = c_ulong; +pub type time_t = c_long; +pub type suseconds_t = i32; +pub type dev_t = i32; +pub type ino_t = u64; +pub type mode_t = u16; +pub type nlink_t = u16; +pub type blksize_t = i32; +pub type rlim_t = u64; +pub type pthread_key_t = c_ulong; +pub type sigset_t = u32; +pub type clockid_t = ::c_uint; +pub type fsblkcnt_t = ::c_uint; +pub type fsfilcnt_t = ::c_uint; +pub type speed_t = ::c_ulong; +pub type tcflag_t = ::c_ulong; +pub type nl_item = ::c_int; +pub type id_t = ::c_uint; +pub type sem_t = ::c_int; +pub type idtype_t = ::c_uint; +pub type integer_t = ::c_int; +pub type cpu_type_t = integer_t; +pub type cpu_subtype_t = integer_t; +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; +pub type key_t = ::c_int; +pub type shmatt_t = ::c_ushort; + +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_error_t = ::kern_return_t; +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; + +pub type processor_cpu_load_info_t = *mut processor_cpu_load_info; +pub type processor_cpu_load_info_data_t = processor_cpu_load_info; +pub type processor_basic_info_t = *mut processor_basic_info; +pub type processor_basic_info_data_t = processor_basic_info; +pub type processor_set_basic_info_data_t = processor_set_basic_info; +pub type processor_set_basic_info_t = *mut processor_set_basic_info; +pub type processor_set_load_info_data_t = processor_set_load_info; +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 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; +pub type thread_throughput_qos_t = integer_t; +pub type thread_standard_policy_data_t = thread_standard_policy; +pub type thread_standard_policy_t = *mut thread_standard_policy; +pub type thread_extended_policy_data_t = thread_extended_policy; +pub type thread_extended_policy_t = *mut thread_extended_policy; +pub type thread_time_constraint_policy_data_t = thread_time_constraint_policy; +pub type thread_time_constraint_policy_t = *mut thread_time_constraint_policy; +pub type thread_precedence_policy_data_t = thread_precedence_policy; +pub type thread_precedence_policy_t = *mut thread_precedence_policy; +pub type thread_affinity_policy_data_t = thread_affinity_policy; +pub type thread_affinity_policy_t = *mut thread_affinity_policy; +pub type thread_background_policy_data_t = thread_background_policy; +pub type thread_background_policy_t = *mut thread_background_policy; +pub type thread_latency_qos_policy_data_t = thread_latency_qos_policy; +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_clockid_t = u32; + +pub type os_sync_wait_on_address_flags_t = u32; +pub type os_sync_wake_by_address_flags_t = u32; + +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 copyfile_callback_t = ::Option< + extern "C" fn( + ::c_int, + ::c_int, + copyfile_state_t, + *const ::c_char, + *const ::c_char, + *mut ::c_void, + ) -> ::c_int, +>; + +pub type attrgroup_t = u32; +pub type vol_capabilities_set_t = [u32; 4]; + +deprecated_mach! { + pub type mach_timebase_info_data_t = mach_timebase_info; +} + +#[cfg_attr(feature = "extra_traits", derive(Debug))] +pub enum timezone {} +impl ::Copy for timezone {} +impl ::Clone for timezone { + fn clone(&self) -> timezone { + *self + } +} + +#[cfg_attr(feature = "extra_traits", derive(Debug))] +#[repr(u32)] +pub enum qos_class_t { + QOS_CLASS_USER_INTERACTIVE = 0x21, + QOS_CLASS_USER_INITIATED = 0x19, + QOS_CLASS_DEFAULT = 0x15, + QOS_CLASS_UTILITY = 0x11, + QOS_CLASS_BACKGROUND = 0x09, + QOS_CLASS_UNSPECIFIED = 0x00, +} +impl ::Copy for qos_class_t {} +impl ::Clone for qos_class_t { + fn clone(&self) -> qos_class_t { + *self + } +} + +#[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, + pub aio_buf: *mut ::c_void, + pub aio_nbytes: ::size_t, + pub aio_reqprio: ::c_int, + pub aio_sigevent: sigevent, + pub aio_lio_opcode: ::c_int + } + + pub struct glob_t { + pub gl_pathc: ::size_t, + __unused1: ::c_int, + pub gl_offs: ::size_t, + __unused2: ::c_int, + pub gl_pathv: *mut *mut ::c_char, + + __unused3: *mut ::c_void, + + __unused4: *mut ::c_void, + __unused5: *mut ::c_void, + __unused6: *mut ::c_void, + __unused7: *mut ::c_void, + __unused8: *mut ::c_void, + } + + 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, + } + + #[deprecated( + since = "0.2.55", + note = "Use the `mach2` crate instead", + )] + pub struct mach_timebase_info { + pub numer: u32, + pub denom: u32, + } + + pub struct stat { + pub st_dev: dev_t, + pub st_mode: mode_t, + pub st_nlink: nlink_t, + pub st_ino: ino_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_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: u32, + pub st_gen: u32, + pub st_lspare: i32, + pub st_qspare: [i64; 2], + } + + pub struct pthread_mutexattr_t { + __sig: ::c_long, + __opaque: [u8; 8], + } + + pub struct pthread_condattr_t { + __sig: ::c_long, + __opaque: [u8; __PTHREAD_CONDATTR_SIZE__], + } + + pub struct pthread_rwlockattr_t { + __sig: ::c_long, + __opaque: [u8; __PTHREAD_RWLOCKATTR_SIZE__], + } + + 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, + //Requires it to be union for tests + //pub si_value: ::sigval, + _pad: [usize; 9], + } + + pub struct sigaction { + // FIXME: this field is actually a union + pub sa_sigaction: ::sighandler_t, + pub sa_mask: sigset_t, + pub sa_flags: ::c_int, + } + + pub struct stack_t { + pub ss_sp: *mut ::c_void, + pub ss_size: ::size_t, + pub ss_flags: ::c_int, + } + + pub struct fstore_t { + pub fst_flags: ::c_uint, + pub fst_posmode: ::c_int, + pub fst_offset: ::off_t, + pub fst_length: ::off_t, + pub fst_bytesalloc: ::off_t, + } + + pub struct fpunchhole_t { + pub fp_flags: ::c_uint, /* unused */ + pub reserved: ::c_uint, /* (to maintain 8-byte alignment) */ + pub fp_offset: ::off_t, /* IN: start of the region */ + pub fp_length: ::off_t, /* IN: size of the region */ + } + + pub struct ftrimactivefile_t { + pub fta_offset: ::off_t, + pub fta_length: ::off_t, + } + + pub struct fspecread_t { + pub fsr_flags: ::c_uint, + pub reserved: ::c_uint, + pub fsr_offset: ::off_t, + pub fsr_length: ::off_t, + } + + pub struct radvisory { + pub ra_offset: ::off_t, + pub ra_count: ::c_int, + } + + 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 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 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: [::c_char; 8], + } + + pub struct kevent64_s { + pub ident: u64, + pub filter: i16, + pub flags: u16, + pub fflags: u32, + pub data: i64, + pub udata: u64, + pub ext: [u64; 2], + } + + pub struct dqblk { + pub dqb_bhardlimit: u64, + pub dqb_bsoftlimit: u64, + pub dqb_curbytes: u64, + pub dqb_ihardlimit: u32, + pub dqb_isoftlimit: u32, + pub dqb_curinodes: u32, + pub dqb_btime: u32, + pub dqb_itime: u32, + pub dqb_id: u32, + pub dqb_spare: [u32; 4], + } + + pub struct if_msghdr { + 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_data: if_data, + } + + pub struct ifa_msghdr { + pub ifam_msglen: ::c_ushort, + pub ifam_version: ::c_uchar, + pub ifam_type: ::c_uchar, + pub ifam_addrs: ::c_int, + pub ifam_flags: ::c_int, + pub ifam_index: ::c_ushort, + pub ifam_metric: ::c_int, + } + + pub struct ifma_msghdr { + pub ifmam_msglen: ::c_ushort, + pub ifmam_version: ::c_uchar, + pub ifmam_type: ::c_uchar, + pub ifmam_addrs: ::c_int, + pub ifmam_flags: ::c_int, + pub ifmam_index: ::c_ushort, + } + + pub struct ifma_msghdr2 { + pub ifmam_msglen: ::c_ushort, + pub ifmam_version: ::c_uchar, + pub ifmam_type: ::c_uchar, + pub ifmam_addrs: ::c_int, + pub ifmam_flags: ::c_int, + pub ifmam_index: ::c_ushort, + pub ifmam_refcount: i32, + } + + pub struct rt_metrics { + pub rmx_locks: u32, + pub rmx_mtu: u32, + pub rmx_hopcount: u32, + pub rmx_expire: i32, + pub rmx_recvpipe: u32, + pub rmx_sendpipe: u32, + pub rmx_ssthresh: u32, + pub rmx_rtt: u32, + pub rmx_rttvar: u32, + pub rmx_pksent: u32, + /// This field does not exist anymore, the u32 is now part of a resized + /// `rmx_filler` array. + pub rmx_state: u32, + pub rmx_filler: [u32; 3], + } + + pub struct rt_msghdr { + pub rtm_msglen: ::c_ushort, + pub rtm_version: ::c_uchar, + pub rtm_type: ::c_uchar, + pub rtm_index: ::c_ushort, + pub rtm_flags: ::c_int, + pub rtm_addrs: ::c_int, + pub rtm_pid: ::pid_t, + pub rtm_seq: ::c_int, + pub rtm_errno: ::c_int, + pub rtm_use: ::c_int, + pub rtm_inits: u32, + pub rtm_rmx: rt_metrics, + } + + pub struct rt_msghdr2 { + pub rtm_msglen: ::c_ushort, + pub rtm_version: ::c_uchar, + pub rtm_type: ::c_uchar, + pub rtm_index: ::c_ushort, + pub rtm_flags: ::c_int, + pub rtm_addrs: ::c_int, + pub rtm_refcnt: i32, + pub rtm_parentflags: ::c_int, + pub rtm_reserved: ::c_int, + pub rtm_use: ::c_int, + pub rtm_inits: u32, + pub rtm_rmx: rt_metrics, + } + + 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 c_ispeed: ::speed_t, + pub c_ospeed: ::speed_t, + } + + pub struct flock { + pub l_start: ::off_t, + pub l_len: ::off_t, + pub l_pid: ::pid_t, + pub l_type: ::c_short, + pub l_whence: ::c_short, + } + + pub struct sf_hdtr { + pub headers: *mut ::iovec, + pub hdr_cnt: ::c_int, + pub trailers: *mut ::iovec, + pub trl_cnt: ::c_int, + } + + 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 proc_taskinfo { + pub pti_virtual_size: u64, + pub pti_resident_size: u64, + pub pti_total_user: u64, + pub pti_total_system: u64, + pub pti_threads_user: u64, + pub pti_threads_system: u64, + pub pti_policy: i32, + pub pti_faults: i32, + pub pti_pageins: i32, + pub pti_cow_faults: i32, + pub pti_messages_sent: i32, + pub pti_messages_received: i32, + pub pti_syscalls_mach: i32, + pub pti_syscalls_unix: i32, + pub pti_csw: i32, + pub pti_threadnum: i32, + pub pti_numrunning: i32, + pub pti_priority: i32, + } + + pub struct proc_bsdinfo { + pub pbi_flags: u32, + pub pbi_status: u32, + pub pbi_xstatus: u32, + pub pbi_pid: u32, + pub pbi_ppid: u32, + pub pbi_uid: ::uid_t, + pub pbi_gid: ::gid_t, + pub pbi_ruid: ::uid_t, + pub pbi_rgid: ::gid_t, + pub pbi_svuid: ::uid_t, + pub pbi_svgid: ::gid_t, + pub rfu_1: u32, + pub pbi_comm: [::c_char; MAXCOMLEN], + pub pbi_name: [::c_char; 32], // MAXCOMLEN * 2, but macro isn't happy... + pub pbi_nfiles: u32, + pub pbi_pgid: u32, + pub pbi_pjobc: u32, + pub e_tdev: u32, + pub e_tpgid: u32, + pub pbi_nice: i32, + pub pbi_start_tvsec: u64, + pub pbi_start_tvusec: u64, + } + + pub struct proc_taskallinfo { + pub pbsd: proc_bsdinfo, + pub ptinfo: proc_taskinfo, + } + + pub struct xsw_usage { + pub xsu_total: u64, + pub xsu_avail: u64, + pub xsu_used: u64, + pub xsu_pagesize: u32, + pub xsu_encrypted: ::boolean_t, + } + + pub struct xucred { + pub cr_version: ::c_uint, + pub cr_uid: ::uid_t, + pub cr_ngroups: ::c_short, + pub cr_groups: [::gid_t;16] + } + + #[deprecated( + since = "0.2.55", + note = "Use the `mach2` crate instead", + )] + pub struct mach_header { + pub magic: u32, + pub cputype: cpu_type_t, + pub cpusubtype: cpu_subtype_t, + pub filetype: u32, + pub ncmds: u32, + pub sizeofcmds: u32, + pub flags: u32, + } + + #[deprecated( + since = "0.2.55", + note = "Use the `mach2` crate instead", + )] + pub struct mach_header_64 { + pub magic: u32, + pub cputype: cpu_type_t, + pub cpusubtype: cpu_subtype_t, + pub filetype: u32, + pub ncmds: u32, + pub sizeofcmds: u32, + pub flags: u32, + pub reserved: u32, + } + + pub struct segment_command { + pub cmd: u32, + pub cmdsize: u32, + pub segname: [::c_char; 16], + pub vmaddr: u32, + pub vmsize: u32, + pub fileoff: u32, + pub filesize: u32, + pub maxprot: vm_prot_t, + pub initprot: vm_prot_t, + pub nsects: u32, + pub flags: u32, + } + + pub struct segment_command_64 { + pub cmd: u32, + pub cmdsize: u32, + pub segname: [::c_char; 16], + pub vmaddr: u64, + pub vmsize: u64, + pub fileoff: u64, + pub filesize: u64, + pub maxprot: vm_prot_t, + pub initprot: vm_prot_t, + pub nsects: u32, + pub flags: u32, + } + + pub struct load_command { + pub cmd: u32, + pub cmdsize: u32, + } + + 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; 12], + } + + pub struct sockaddr_inarp { + pub sin_len: ::c_uchar, + pub sin_family: ::c_uchar, + pub sin_port: ::c_ushort, + pub sin_addr: ::in_addr, + pub sin_srcaddr: ::in_addr, + pub sin_tos: ::c_ushort, + pub sin_other: ::c_ushort, + } + + pub struct sockaddr_ctl { + pub sc_len: ::c_uchar, + pub sc_family: ::c_uchar, + pub ss_sysaddr: u16, + pub sc_id: u32, + pub sc_unit: u32, + pub sc_reserved: [u32; 5], + } + + pub struct in_pktinfo { + pub ipi_ifindex: ::c_uint, + pub ipi_spec_dst: ::in_addr, + pub ipi_addr: ::in_addr, + } + + pub struct in6_pktinfo { + pub ipi6_addr: ::in6_addr, + pub ipi6_ifindex: ::c_uint, + } + + // sys/ipc.h: + + 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 _key: ::key_t, + } + + // sys/sem.h + + pub struct sembuf { + pub sem_num: ::c_ushort, + pub sem_op: ::c_short, + pub sem_flg: ::c_short, + } + + // sys/shm.h + + 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 in_addr { + 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; ::IFNAMSIZ], + } + + // sys/socket.h + + pub struct sa_endpoints_t { + pub sae_srcif: ::c_uint, // optional source interface + pub sae_srcaddr: *const ::sockaddr, // optional source address + pub sae_srcaddrlen: ::socklen_t, // size of source address + pub sae_dstaddr: *const ::sockaddr, // destination address + pub sae_dstaddrlen: ::socklen_t, // size of destination address + } + + 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 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 struct ntptimeval { + pub time: ::timespec, + pub maxerror: ::c_long, + pub esterror: ::c_long, + pub tai: ::c_long, + pub time_state: ::c_int, + } + + pub struct thread_standard_policy { + pub no_data: natural_t, + } + + pub struct thread_extended_policy { + pub timeshare: boolean_t, + } + + pub struct thread_time_constraint_policy { + pub period: u32, + pub computation: u32, + pub constraint: u32, + pub preemptible: boolean_t, + } + + pub struct thread_precedence_policy { + pub importance: integer_t, + } + + pub struct thread_affinity_policy { + pub affinity_tag: integer_t, + } + + pub struct thread_background_policy { + pub priority: integer_t, + } + + pub struct thread_latency_qos_policy { + pub thread_latency_qos_tier: thread_latency_qos_t, + } + + pub struct thread_throughput_qos_policy { + pub thread_throughput_qos_tier: thread_throughput_qos_t, + } + + // malloc/malloc.h + pub struct malloc_statistics_t { + pub blocks_in_use: ::c_uint, + pub size_in_use: ::size_t, + pub max_size_in_use: ::size_t, + pub size_allocated: ::size_t, + } + + pub struct mstats { + pub bytes_total: ::size_t, + pub chunks_used: ::size_t, + pub bytes_used: ::size_t, + 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, + } + + #[cfg_attr(libc_packedN, repr(packed(4)))] + pub struct ifconf { + pub ifc_len: ::c_int, + #[cfg(libc_union)] + pub ifc_ifcu: __c_anonymous_ifc_ifcu, + #[cfg(not(libc_union))] + pub ifc_ifcu: *mut ifreq, + } + + #[cfg_attr(libc_align, repr(align(8)))] + pub struct tcp_connection_info { + pub tcpi_state: u8, + pub tcpi_snd_wscale: u8, + pub tcpi_rcv_wscale: u8, + __pad1: u8, + pub tcpi_options: u32, + pub tcpi_flags: u32, + pub tcpi_rto: u32, + pub tcpi_maxseg: u32, + pub tcpi_snd_ssthresh: u32, + pub tcpi_snd_cwnd: u32, + pub tcpi_snd_wnd: u32, + pub tcpi_snd_sbbytes: u32, + pub tcpi_rcv_wnd: u32, + pub tcpi_rttcur: u32, + pub tcpi_srtt: u32, + pub tcpi_rttvar: u32, + pub tcpi_tfo_cookie_req: u32, + pub tcpi_tfo_cookie_rcv: u32, + pub tcpi_tfo_syn_loss: u32, + pub tcpi_tfo_syn_data_sent: u32, + pub tcpi_tfo_syn_data_acked: u32, + pub tcpi_tfo_syn_data_rcv: u32, + pub tcpi_tfo_cookie_req_rcv: u32, + pub tcpi_tfo_cookie_sent: u32, + pub tcpi_tfo_cookie_invalid: u32, + pub tcpi_tfo_cookie_wrong: u32, + pub tcpi_tfo_no_cookie_rcv: u32, + pub tcpi_tfo_heuristics_disable: u32, + pub tcpi_tfo_send_blackhole: u32, + pub tcpi_tfo_recv_blackhole: u32, + pub tcpi_tfo_onebyte_proxy: u32, + __pad2: u32, + pub tcpi_txpackets: u64, + pub tcpi_txbytes: u64, + pub tcpi_txretransmitbytes: u64, + pub tcpi_rxpackets: u64, + pub tcpi_rxbytes: u64, + pub tcpi_rxoutoforderbytes: u64, + pub tcpi_rxretransmitpackets: u64, + } +} + +s_no_extra_traits! { + #[cfg_attr(libc_packedN, repr(packed(4)))] + pub struct kevent { + pub ident: ::uintptr_t, + pub filter: i16, + pub flags: u16, + pub fflags: u32, + pub data: ::intptr_t, + pub udata: *mut ::c_void, + } + + #[cfg_attr(libc_packedN, repr(packed(4)))] + pub struct semid_ds { + // Note the manpage shows different types than the system header. + pub sem_perm: ipc_perm, + pub sem_base: i32, + pub sem_nsems: ::c_ushort, + pub sem_otime: ::time_t, + pub sem_pad1: i32, + pub sem_ctime: ::time_t, + pub sem_pad2: i32, + pub sem_pad3: [i32; 4], + } + + #[cfg_attr(libc_packedN, repr(packed(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, // FIXME: 64-bit wrong align => wrong offset + pub shm_dtime: ::time_t, // FIXME: 64-bit wrong align => wrong offset + pub shm_ctime: ::time_t, // FIXME: 64-bit wrong align => wrong offset + // FIXME: 64-bit wrong align => wrong offset: + pub shm_internal: *mut ::c_void, + } + + pub struct proc_threadinfo { + 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], + } + + pub struct statfs { + pub f_bsize: u32, + pub f_iosize: i32, + 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_owner: ::uid_t, + pub f_type: u32, + pub f_flags: u32, + pub f_fssubtype: u32, + pub f_fstypename: [::c_char; 16], + pub f_mntonname: [::c_char; 1024], + pub f_mntfromname: [::c_char; 1024], + pub f_flags_ext: u32, + pub f_reserved: [u32; 7], + } + + pub struct dirent { + pub d_ino: u64, + pub d_seekoff: u64, + pub d_reclen: u16, + pub d_namlen: u16, + pub d_type: u8, + pub d_name: [::c_char; 1024], + } + + pub struct pthread_rwlock_t { + __sig: ::c_long, + __opaque: [u8; __PTHREAD_RWLOCK_SIZE__], + } + + pub struct pthread_mutex_t { + __sig: ::c_long, + __opaque: [u8; __PTHREAD_MUTEX_SIZE__], + } + + pub struct pthread_cond_t { + __sig: ::c_long, + __opaque: [u8; __PTHREAD_COND_SIZE__], + } + + pub struct sockaddr_storage { + pub ss_len: u8, + pub ss_family: ::sa_family_t, + __ss_pad1: [u8; 6], + __ss_align: i64, + __ss_pad2: [u8; 112], + } + + pub struct utmpx { + pub ut_user: [::c_char; _UTX_USERSIZE], + pub ut_id: [::c_char; _UTX_IDSIZE], + pub ut_line: [::c_char; _UTX_LINESIZE], + pub ut_pid: ::pid_t, + pub ut_type: ::c_short, + pub ut_tv: ::timeval, + pub ut_host: [::c_char; _UTX_HOSTSIZE], + ut_pad: [u32; 16], + } + + pub struct sigevent { + pub sigev_notify: ::c_int, + pub sigev_signo: ::c_int, + pub sigev_value: ::sigval, + __unused1: *mut ::c_void, //actually a function pointer + pub sigev_notify_attributes: *mut ::pthread_attr_t + } + + pub struct processor_cpu_load_info { + pub cpu_ticks: [::c_uint; CPU_STATE_MAX as usize], + } + + pub struct processor_basic_info { + pub cpu_type: cpu_type_t, + pub cpu_subtype: cpu_subtype_t, + pub running: ::boolean_t, + pub slot_num: ::c_int, + pub is_master: ::boolean_t, + } + + pub struct processor_set_basic_info { + pub processor_count: ::c_int, + pub default_policy: ::c_int, + } + + pub struct processor_set_load_info { + pub task_count: ::c_int, + pub thread_count: ::c_int, + 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, + } + + #[cfg_attr(libc_packedN, repr(packed(1)))] + pub struct sockaddr_vm { + pub svm_len: ::c_uchar, + pub svm_family: ::sa_family_t, + pub svm_reserved1: ::c_ushort, + pub svm_port: ::c_uint, + pub svm_cid: ::c_uint, + } + + pub struct ifdevmtu { + pub ifdm_current: ::c_int, + pub ifdm_min: ::c_int, + pub ifdm_max: ::c_int, + } + + #[cfg(libc_union)] + pub union __c_anonymous_ifk_data { + pub ifk_ptr: *mut ::c_void, + pub ifk_value: ::c_int, + } + + #[cfg_attr(libc_packedN, repr(packed(4)))] + pub struct ifkpi { + pub ifk_module_id: ::c_uint, + pub ifk_type: ::c_uint, + #[cfg(libc_union)] + pub ifk_data: __c_anonymous_ifk_data, + } + + #[cfg(libc_union)] + pub union __c_anonymous_ifr_ifru { + pub ifru_addr: ::sockaddr, + pub ifru_dstaddr: ::sockaddr, + pub ifru_broadaddr: ::sockaddr, + pub ifru_flags: ::c_short, + pub ifru_metrics: ::c_int, + pub ifru_mtu: ::c_int, + pub ifru_phys: ::c_int, + pub ifru_media: ::c_int, + pub ifru_intval: ::c_int, + pub ifru_data: *mut ::c_char, + pub ifru_devmtu: ifdevmtu, + pub ifru_kpi: ifkpi, + pub ifru_wake_flags: u32, + pub ifru_route_refcnt: u32, + pub ifru_cap: [::c_int; 2], + pub ifru_functional_type: u32, + } + + pub struct ifreq { + 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: *mut ::c_char, + pub ifcu_req: *mut ifreq, + } +} + +impl siginfo_t { + pub unsafe fn si_addr(&self) -> *mut ::c_void { + self.si_addr + } + + pub unsafe fn si_value(&self) -> ::sigval { + #[repr(C)] + struct siginfo_timer { + _si_signo: ::c_int, + _si_errno: ::c_int, + _si_code: ::c_int, + _si_pid: ::pid_t, + _si_uid: ::uid_t, + _si_status: ::c_int, + _si_addr: *mut ::c_void, + si_value: ::sigval, + } + + (*(self as *const siginfo_t as *const siginfo_timer)).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(libc_union)] { + s_no_extra_traits! { + pub union semun { + pub val: ::c_int, + pub buf: *mut semid_ds, + pub array: *mut ::c_ushort, + } + } + + cfg_if! { + if #[cfg(feature = "extra_traits")] { + impl PartialEq for semun { + fn eq(&self, other: &semun) -> bool { + unsafe { self.val == other.val } + } + } + impl Eq for semun {} + impl ::fmt::Debug for semun { + fn fmt(&self, f: &mut ::fmt::Formatter) + -> ::fmt::Result { + f.debug_struct("semun") + .field("val", unsafe { &self.val }) + .finish() + } + } + impl ::hash::Hash for semun { + fn hash(&self, state: &mut H) { + unsafe { self.val.hash(state) }; + } + } + } + } + } +} + +cfg_if! { + if #[cfg(feature = "extra_traits")] { + impl PartialEq for kevent { + fn eq(&self, other: &kevent) -> bool { + self.ident == other.ident + && self.filter == other.filter + && self.flags == other.flags + && self.fflags == other.fflags + && self.data == other.data + && self.udata == other.udata + } + } + impl Eq for kevent {} + impl ::fmt::Debug for kevent { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + let ident = self.ident; + let filter = self.filter; + let flags = self.flags; + let fflags = self.fflags; + let data = self.data; + let udata = self.udata; + f.debug_struct("kevent") + .field("ident", &ident) + .field("filter", &filter) + .field("flags", &flags) + .field("fflags", &fflags) + .field("data", &data) + .field("udata", &udata) + .finish() + } + } + impl ::hash::Hash for kevent { + fn hash(&self, state: &mut H) { + let ident = self.ident; + let filter = self.filter; + let flags = self.flags; + let fflags = self.fflags; + let data = self.data; + let udata = self.udata; + ident.hash(state); + filter.hash(state); + flags.hash(state); + fflags.hash(state); + data.hash(state); + udata.hash(state); + } + } + + impl PartialEq for semid_ds { + fn eq(&self, other: &semid_ds) -> bool { + let sem_perm = self.sem_perm; + let sem_pad3 = self.sem_pad3; + let other_sem_perm = other.sem_perm; + let other_sem_pad3 = other.sem_pad3; + sem_perm == other_sem_perm + && self.sem_base == other.sem_base + && self.sem_nsems == other.sem_nsems + && self.sem_otime == other.sem_otime + && self.sem_pad1 == other.sem_pad1 + && self.sem_ctime == other.sem_ctime + && self.sem_pad2 == other.sem_pad2 + && sem_pad3 == other_sem_pad3 + } + } + impl Eq for semid_ds {} + impl ::fmt::Debug for semid_ds { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + let sem_perm = self.sem_perm; + let sem_base = self.sem_base; + let sem_nsems = self.sem_nsems; + let sem_otime = self.sem_otime; + let sem_pad1 = self.sem_pad1; + let sem_ctime = self.sem_ctime; + let sem_pad2 = self.sem_pad2; + let sem_pad3 = self.sem_pad3; + f.debug_struct("semid_ds") + .field("sem_perm", &sem_perm) + .field("sem_base", &sem_base) + .field("sem_nsems", &sem_nsems) + .field("sem_otime", &sem_otime) + .field("sem_pad1", &sem_pad1) + .field("sem_ctime", &sem_ctime) + .field("sem_pad2", &sem_pad2) + .field("sem_pad3", &sem_pad3) + .finish() + } + } + impl ::hash::Hash for semid_ds { + fn hash(&self, state: &mut H) { + let sem_perm = self.sem_perm; + let sem_base = self.sem_base; + let sem_nsems = self.sem_nsems; + let sem_otime = self.sem_otime; + let sem_pad1 = self.sem_pad1; + let sem_ctime = self.sem_ctime; + let sem_pad2 = self.sem_pad2; + let sem_pad3 = self.sem_pad3; + sem_perm.hash(state); + sem_base.hash(state); + sem_nsems.hash(state); + sem_otime.hash(state); + sem_pad1.hash(state); + sem_ctime.hash(state); + sem_pad2.hash(state); + sem_pad3.hash(state); + } + } + + impl PartialEq for shmid_ds { + fn eq(&self, other: &shmid_ds) -> bool { + let shm_perm = self.shm_perm; + let other_shm_perm = other.shm_perm; + shm_perm == other_shm_perm + && self.shm_segsz == other.shm_segsz + && self.shm_lpid == other.shm_lpid + && self.shm_cpid == other.shm_cpid + && self.shm_nattch == other.shm_nattch + && self.shm_atime == other.shm_atime + && self.shm_dtime == other.shm_dtime + && self.shm_ctime == other.shm_ctime + && self.shm_internal == other.shm_internal + } + } + impl Eq for shmid_ds {} + impl ::fmt::Debug for shmid_ds { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + let shm_perm = self.shm_perm; + let shm_segsz = self.shm_segsz; + let shm_lpid = self.shm_lpid; + let shm_cpid = self.shm_cpid; + let shm_nattch = self.shm_nattch; + let shm_atime = self.shm_atime; + let shm_dtime = self.shm_dtime; + let shm_ctime = self.shm_ctime; + let shm_internal = self.shm_internal; + f.debug_struct("shmid_ds") + .field("shm_perm", &shm_perm) + .field("shm_segsz", &shm_segsz) + .field("shm_lpid", &shm_lpid) + .field("shm_cpid", &shm_cpid) + .field("shm_nattch", &shm_nattch) + .field("shm_atime", &shm_atime) + .field("shm_dtime", &shm_dtime) + .field("shm_ctime", &shm_ctime) + .field("shm_internal", &shm_internal) + .finish() + } + } + impl ::hash::Hash for shmid_ds { + fn hash(&self, state: &mut H) { + let shm_perm = self.shm_perm; + let shm_segsz = self.shm_segsz; + let shm_lpid = self.shm_lpid; + let shm_cpid = self.shm_cpid; + let shm_nattch = self.shm_nattch; + let shm_atime = self.shm_atime; + let shm_dtime = self.shm_dtime; + let shm_ctime = self.shm_ctime; + let shm_internal = self.shm_internal; + shm_perm.hash(state); + shm_segsz.hash(state); + shm_lpid.hash(state); + shm_cpid.hash(state); + shm_nattch.hash(state); + shm_atime.hash(state); + shm_dtime.hash(state); + shm_ctime.hash(state); + shm_internal.hash(state); + } + } + + impl PartialEq for proc_threadinfo { + fn eq(&self, other: &proc_threadinfo) -> bool { + self.pth_user_time == other.pth_user_time + && 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 proc_threadinfo {} + impl ::fmt::Debug for proc_threadinfo { + 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 proc_threadinfo { + 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 statfs { + fn eq(&self, other: &statfs) -> bool { + self.f_bsize == other.f_bsize + && self.f_iosize == other.f_iosize + && self.f_blocks == other.f_blocks + && self.f_bfree == other.f_bfree + && self.f_bavail == other.f_bavail + && self.f_files == other.f_files + && self.f_ffree == other.f_ffree + && self.f_fsid == other.f_fsid + && self.f_owner == other.f_owner + && self.f_flags == other.f_flags + && self.f_fssubtype == other.f_fssubtype + && self.f_fstypename == other.f_fstypename + && self.f_type == other.f_type + && self + .f_mntonname + .iter() + .zip(other.f_mntonname.iter()) + .all(|(a,b)| a == b) + && self + .f_mntfromname + .iter() + .zip(other.f_mntfromname.iter()) + .all(|(a,b)| a == b) + && self.f_reserved == other.f_reserved + } + } + + impl Eq for statfs {} + impl ::fmt::Debug for statfs { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("statfs") + .field("f_bsize", &self.f_bsize) + .field("f_iosize", &self.f_iosize) + .field("f_blocks", &self.f_blocks) + .field("f_bfree", &self.f_bfree) + .field("f_bavail", &self.f_bavail) + .field("f_files", &self.f_files) + .field("f_ffree", &self.f_ffree) + .field("f_fsid", &self.f_fsid) + .field("f_owner", &self.f_owner) + .field("f_flags", &self.f_flags) + .field("f_fssubtype", &self.f_fssubtype) + .field("f_fstypename", &self.f_fstypename) + .field("f_type", &self.f_type) + // FIXME: .field("f_mntonname", &self.f_mntonname) + // FIXME: .field("f_mntfromname", &self.f_mntfromname) + .field("f_reserved", &self.f_reserved) + .finish() + } + } + + impl ::hash::Hash for statfs { + fn hash(&self, state: &mut H) { + self.f_bsize.hash(state); + self.f_iosize.hash(state); + self.f_blocks.hash(state); + self.f_bfree.hash(state); + self.f_bavail.hash(state); + self.f_files.hash(state); + self.f_ffree.hash(state); + self.f_fsid.hash(state); + self.f_owner.hash(state); + self.f_flags.hash(state); + self.f_fssubtype.hash(state); + self.f_fstypename.hash(state); + self.f_type.hash(state); + self.f_mntonname.hash(state); + self.f_mntfromname.hash(state); + self.f_reserved.hash(state); + } + } + + impl PartialEq for dirent { + fn eq(&self, other: &dirent) -> bool { + self.d_ino == other.d_ino + && self.d_seekoff == other.d_seekoff + && self.d_reclen == other.d_reclen + && self.d_namlen == other.d_namlen + && self.d_type == other.d_type + && self + .d_name + .iter() + .zip(other.d_name.iter()) + .all(|(a,b)| a == b) + } + } + impl Eq for dirent {} + impl ::fmt::Debug for dirent { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("dirent") + .field("d_ino", &self.d_ino) + .field("d_seekoff", &self.d_seekoff) + .field("d_reclen", &self.d_reclen) + .field("d_namlen", &self.d_namlen) + .field("d_type", &self.d_type) + // FIXME: .field("d_name", &self.d_name) + .finish() + } + } + impl ::hash::Hash for dirent { + fn hash(&self, state: &mut H) { + self.d_ino.hash(state); + self.d_seekoff.hash(state); + self.d_reclen.hash(state); + self.d_namlen.hash(state); + self.d_type.hash(state); + self.d_name.hash(state); + } + } + impl PartialEq for pthread_rwlock_t { + fn eq(&self, other: &pthread_rwlock_t) -> bool { + self.__sig == other.__sig + && self. + __opaque + .iter() + .zip(other.__opaque.iter()) + .all(|(a,b)| a == b) + } + } + impl Eq for pthread_rwlock_t {} + impl ::fmt::Debug for pthread_rwlock_t { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("pthread_rwlock_t") + .field("__sig", &self.__sig) + // FIXME: .field("__opaque", &self.__opaque) + .finish() + } + } + impl ::hash::Hash for pthread_rwlock_t { + fn hash(&self, state: &mut H) { + self.__sig.hash(state); + self.__opaque.hash(state); + } + } + + impl PartialEq for pthread_mutex_t { + fn eq(&self, other: &pthread_mutex_t) -> bool { + self.__sig == other.__sig + && self. + __opaque + .iter() + .zip(other.__opaque.iter()) + .all(|(a,b)| a == b) + } + } + + impl Eq for pthread_mutex_t {} + + impl ::fmt::Debug for pthread_mutex_t { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("pthread_mutex_t") + .field("__sig", &self.__sig) + // FIXME: .field("__opaque", &self.__opaque) + .finish() + } + } + + impl ::hash::Hash for pthread_mutex_t { + fn hash(&self, state: &mut H) { + self.__sig.hash(state); + self.__opaque.hash(state); + } + } + + impl PartialEq for pthread_cond_t { + fn eq(&self, other: &pthread_cond_t) -> bool { + self.__sig == other.__sig + && self. + __opaque + .iter() + .zip(other.__opaque.iter()) + .all(|(a,b)| a == b) + } + } + + impl Eq for pthread_cond_t {} + + impl ::fmt::Debug for pthread_cond_t { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("pthread_cond_t") + .field("__sig", &self.__sig) + // FIXME: .field("__opaque", &self.__opaque) + .finish() + } + } + + impl ::hash::Hash for pthread_cond_t { + fn hash(&self, state: &mut H) { + self.__sig.hash(state); + self.__opaque.hash(state); + } + } + + impl PartialEq for sockaddr_storage { + fn eq(&self, other: &sockaddr_storage) -> bool { + self.ss_len == other.ss_len + && self.ss_family == other.ss_family + && self + .__ss_pad1 + .iter() + .zip(other.__ss_pad1.iter()) + .all(|(a, b)| a == b) + && self.__ss_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 utmpx { + fn eq(&self, other: &utmpx) -> bool { + self.ut_user + .iter() + .zip(other.ut_user.iter()) + .all(|(a,b)| a == b) + && self.ut_id == other.ut_id + && self.ut_line == other.ut_line + && self.ut_pid == other.ut_pid + && self.ut_type == other.ut_type + && self.ut_tv == other.ut_tv + && self + .ut_host + .iter() + .zip(other.ut_host.iter()) + .all(|(a,b)| a == b) + && self.ut_pad == other.ut_pad + } + } + + impl Eq for utmpx {} + + impl ::fmt::Debug for utmpx { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("utmpx") + // FIXME: .field("ut_user", &self.ut_user) + .field("ut_id", &self.ut_id) + .field("ut_line", &self.ut_line) + .field("ut_pid", &self.ut_pid) + .field("ut_type", &self.ut_type) + .field("ut_tv", &self.ut_tv) + // FIXME: .field("ut_host", &self.ut_host) + .field("ut_pad", &self.ut_pad) + .finish() + } + } + + impl ::hash::Hash for utmpx { + fn hash(&self, state: &mut H) { + self.ut_user.hash(state); + self.ut_id.hash(state); + self.ut_line.hash(state); + self.ut_pid.hash(state); + self.ut_type.hash(state); + self.ut_tv.hash(state); + self.ut_host.hash(state); + self.ut_pad.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_attributes + == other.sigev_notify_attributes + } + } + + 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_attributes", + &self.sigev_notify_attributes) + .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_attributes.hash(state); + } + } + + impl PartialEq for processor_cpu_load_info { + fn eq(&self, other: &processor_cpu_load_info) -> bool { + self.cpu_ticks == other.cpu_ticks + } + } + impl Eq for processor_cpu_load_info {} + impl ::fmt::Debug for processor_cpu_load_info { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("processor_cpu_load_info") + .field("cpu_ticks", &self.cpu_ticks) + .finish() + } + } + impl ::hash::Hash for processor_cpu_load_info { + fn hash(&self, state: &mut H) { + self.cpu_ticks.hash(state); + } + } + + impl PartialEq for processor_basic_info { + fn eq(&self, other: &processor_basic_info) -> bool { + self.cpu_type == other.cpu_type + && self.cpu_subtype == other.cpu_subtype + && self.running == other.running + && self.slot_num == other.slot_num + && self.is_master == other.is_master + } + } + impl Eq for processor_basic_info {} + impl ::fmt::Debug for processor_basic_info { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("processor_basic_info") + .field("cpu_type", &self.cpu_type) + .field("cpu_subtype", &self.cpu_subtype) + .field("running", &self.running) + .field("slot_num", &self.slot_num) + .field("is_master", &self.is_master) + .finish() + } + } + impl ::hash::Hash for processor_basic_info { + fn hash(&self, state: &mut H) { + self.cpu_type.hash(state); + self.cpu_subtype.hash(state); + self.running.hash(state); + self.slot_num.hash(state); + self.is_master.hash(state); + } + } + + impl PartialEq for processor_set_basic_info { + fn eq(&self, other: &processor_set_basic_info) -> bool { + self.processor_count == other.processor_count + && self.default_policy == other.default_policy + } + } + impl Eq for processor_set_basic_info {} + impl ::fmt::Debug for processor_set_basic_info { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("processor_set_basic_info") + .field("processor_count", &self.processor_count) + .field("default_policy", &self.default_policy) + .finish() + } + } + impl ::hash::Hash for processor_set_basic_info { + fn hash(&self, state: &mut H) { + self.processor_count.hash(state); + self.default_policy.hash(state); + } + } + + impl PartialEq for processor_set_load_info { + fn eq(&self, other: &processor_set_load_info) -> bool { + self.task_count == other.task_count + && self.thread_count == other.thread_count + && self.load_average == other.load_average + && self.mach_factor == other.mach_factor + } + } + impl Eq for processor_set_load_info {} + impl ::fmt::Debug for processor_set_load_info { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("processor_set_load_info") + .field("task_count", &self.task_count) + .field("thread_count", &self.thread_count) + .field("load_average", &self.load_average) + .field("mach_factor", &self.mach_factor) + .finish() + } + } + impl ::hash::Hash for processor_set_load_info { + fn hash(&self, state: &mut H) { + self.task_count.hash(state); + self.thread_count.hash(state); + self.load_average.hash(state); + 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); + } + } + + impl PartialEq for sockaddr_vm { + fn eq(&self, other: &sockaddr_vm) -> bool { + self.svm_len == other.svm_len + && self.svm_family == other.svm_family + && self.svm_reserved1 == other.svm_reserved1 + && self.svm_port == other.svm_port + && self.svm_cid == other.svm_cid + } + } + + impl Eq for sockaddr_vm {} + + impl ::fmt::Debug for sockaddr_vm { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + let svm_len = self.svm_len; + let svm_family = self.svm_family; + let svm_reserved1 = self.svm_reserved1; + let svm_port = self.svm_port; + let svm_cid = self.svm_cid; + + f.debug_struct("sockaddr_vm") + .field("svm_len",&svm_len) + .field("svm_family",&svm_family) + .field("svm_reserved1",&svm_reserved1) + .field("svm_port",&svm_port) + .field("svm_cid",&svm_cid) + .finish() + } + } + + impl ::hash::Hash for sockaddr_vm { + fn hash(&self, state: &mut H) { + let svm_len = self.svm_len; + let svm_family = self.svm_family; + let svm_reserved1 = self.svm_reserved1; + let svm_port = self.svm_port; + let svm_cid = self.svm_cid; + + svm_len.hash(state); + svm_family.hash(state); + svm_reserved1.hash(state); + svm_port.hash(state); + svm_cid.hash(state); + } + } + + impl PartialEq for ifdevmtu { + fn eq(&self, other: &ifdevmtu) -> bool { + self.ifdm_current == other.ifdm_current + && self.ifdm_min == other.ifdm_min + && self.ifdm_max == other.ifdm_max + } + } + + impl Eq for ifdevmtu {} + + impl ::fmt::Debug for ifdevmtu { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("ifdevmtu") + .field("ifdm_current", &self.ifdm_current) + .field("ifdm_min", &self.ifdm_min) + .field("ifdm_max", &self.ifdm_max) + .finish() + } + } + + impl ::hash::Hash for ifdevmtu { + fn hash(&self, state: &mut H) { + self.ifdm_current.hash(state); + self.ifdm_min.hash(state); + self.ifdm_max.hash(state); + } + } + + #[cfg(libc_union)] + impl PartialEq for __c_anonymous_ifk_data { + fn eq(&self, other: &__c_anonymous_ifk_data) -> bool { + unsafe { + self.ifk_ptr == other.ifk_ptr + && self.ifk_value == other.ifk_value + } + } + } + + #[cfg(libc_union)] + impl Eq for __c_anonymous_ifk_data {} + + #[cfg(libc_union)] + impl ::fmt::Debug for __c_anonymous_ifk_data { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("__c_anonymous_ifk_data") + .field("ifk_ptr", unsafe { &self.ifk_ptr }) + .field("ifk_value", unsafe { &self.ifk_value }) + .finish() + } + } + #[cfg(libc_union)] + impl ::hash::Hash for __c_anonymous_ifk_data { + fn hash(&self, state: &mut H) { + unsafe { + self.ifk_ptr.hash(state); + self.ifk_value.hash(state); + } + } + } + + impl PartialEq for ifkpi { + fn eq(&self, other: &ifkpi) -> bool { + self.ifk_module_id == other.ifk_module_id + && self.ifk_type == other.ifk_type + } + } + + impl Eq for ifkpi {} + + impl ::fmt::Debug for ifkpi { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("ifkpi") + .field("ifk_module_id", &self.ifk_module_id) + .field("ifk_type", &self.ifk_type) + .finish() + } + } + + impl ::hash::Hash for ifkpi { + fn hash(&self, state: &mut H) { + self.ifk_module_id.hash(state); + self.ifk_type.hash(state); + } + } + + #[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_flags == other.ifru_flags + && self.ifru_metrics == other.ifru_metrics + && self.ifru_mtu == other.ifru_mtu + && self.ifru_phys == other.ifru_phys + && self.ifru_media == other.ifru_media + && self.ifru_intval == other.ifru_intval + && self.ifru_data == other.ifru_data + && self.ifru_devmtu == other.ifru_devmtu + && self.ifru_kpi == other.ifru_kpi + && self.ifru_wake_flags == other.ifru_wake_flags + && self.ifru_route_refcnt == other.ifru_route_refcnt + && self.ifru_cap.iter().zip(other.ifru_cap.iter()).all(|(a,b)| a == b) + && self.ifru_functional_type == other.ifru_functional_type + } + } + } + + #[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("__c_anonymous_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_flags", unsafe { &self.ifru_flags }) + .field("ifru_metrics", unsafe { &self.ifru_metrics }) + .field("ifru_mtu", unsafe { &self.ifru_mtu }) + .field("ifru_phys", unsafe { &self.ifru_phys }) + .field("ifru_media", unsafe { &self.ifru_media }) + .field("ifru_intval", unsafe { &self.ifru_intval }) + .field("ifru_data", unsafe { &self.ifru_data }) + .field("ifru_devmtu", unsafe { &self.ifru_devmtu }) + .field("ifru_kpi", unsafe { &self.ifru_kpi }) + .field("ifru_wake_flags", unsafe { &self.ifru_wake_flags }) + .field("ifru_route_refcnt", unsafe { &self.ifru_route_refcnt }) + .field("ifru_cap", unsafe { &self.ifru_cap }) + .field("ifru_functional_type", unsafe { &self.ifru_functional_type }) + .finish() + } + } + + #[cfg(libc_union)] + impl ::hash::Hash for __c_anonymous_ifr_ifru { + fn hash(&self, state: &mut H) { + unsafe { + self.ifru_addr.hash(state); + self.ifru_dstaddr.hash(state); + self.ifru_broadaddr.hash(state); + self.ifru_flags.hash(state); + self.ifru_metrics.hash(state); + self.ifru_mtu.hash(state); + self.ifru_phys.hash(state); + self.ifru_media.hash(state); + self.ifru_intval.hash(state); + self.ifru_data.hash(state); + self.ifru_devmtu.hash(state); + self.ifru_kpi.hash(state); + self.ifru_wake_flags.hash(state); + self.ifru_route_refcnt.hash(state); + self.ifru_cap.hash(state); + self.ifru_functional_type.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) }; + } + } + } +} + +pub const _UTX_USERSIZE: usize = 256; +pub const _UTX_LINESIZE: usize = 32; +pub const _UTX_IDSIZE: usize = 4; +pub const _UTX_HOSTSIZE: usize = 256; + +pub const EMPTY: ::c_short = 0; +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; +pub const SIGNATURE: ::c_short = 10; +pub const SHUTDOWN_TIME: ::c_short = 11; + +pub const LC_COLLATE_MASK: ::c_int = 1 << 0; +pub const LC_CTYPE_MASK: ::c_int = 1 << 1; +pub const LC_MESSAGES_MASK: ::c_int = 1 << 2; +pub const LC_MONETARY_MASK: ::c_int = 1 << 3; +pub const LC_NUMERIC_MASK: ::c_int = 1 << 4; +pub const LC_TIME_MASK: ::c_int = 1 << 5; +pub const LC_ALL_MASK: ::c_int = LC_COLLATE_MASK + | LC_CTYPE_MASK + | LC_MESSAGES_MASK + | LC_MONETARY_MASK + | LC_NUMERIC_MASK + | LC_TIME_MASK; + +pub const CODESET: ::nl_item = 0; +pub const D_T_FMT: ::nl_item = 1; +pub const D_FMT: ::nl_item = 2; +pub const T_FMT: ::nl_item = 3; +pub const T_FMT_AMPM: ::nl_item = 4; +pub const AM_STR: ::nl_item = 5; +pub const PM_STR: ::nl_item = 6; + +pub const DAY_1: ::nl_item = 7; +pub const DAY_2: ::nl_item = 8; +pub const DAY_3: ::nl_item = 9; +pub const DAY_4: ::nl_item = 10; +pub const DAY_5: ::nl_item = 11; +pub const DAY_6: ::nl_item = 12; +pub const DAY_7: ::nl_item = 13; + +pub const ABDAY_1: ::nl_item = 14; +pub const ABDAY_2: ::nl_item = 15; +pub const ABDAY_3: ::nl_item = 16; +pub const ABDAY_4: ::nl_item = 17; +pub const ABDAY_5: ::nl_item = 18; +pub const ABDAY_6: ::nl_item = 19; +pub const ABDAY_7: ::nl_item = 20; + +pub const MON_1: ::nl_item = 21; +pub const MON_2: ::nl_item = 22; +pub const MON_3: ::nl_item = 23; +pub const MON_4: ::nl_item = 24; +pub const MON_5: ::nl_item = 25; +pub const MON_6: ::nl_item = 26; +pub const MON_7: ::nl_item = 27; +pub const MON_8: ::nl_item = 28; +pub const MON_9: ::nl_item = 29; +pub const MON_10: ::nl_item = 30; +pub const MON_11: ::nl_item = 31; +pub const MON_12: ::nl_item = 32; + +pub const ABMON_1: ::nl_item = 33; +pub const ABMON_2: ::nl_item = 34; +pub const ABMON_3: ::nl_item = 35; +pub const ABMON_4: ::nl_item = 36; +pub const ABMON_5: ::nl_item = 37; +pub const ABMON_6: ::nl_item = 38; +pub const ABMON_7: ::nl_item = 39; +pub const ABMON_8: ::nl_item = 40; +pub const ABMON_9: ::nl_item = 41; +pub const ABMON_10: ::nl_item = 42; +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; + +pub const ERA: ::nl_item = 45; +pub const ERA_D_FMT: ::nl_item = 46; +pub const ERA_D_T_FMT: ::nl_item = 47; +pub const ERA_T_FMT: ::nl_item = 48; +pub const ALT_DIGITS: ::nl_item = 49; + +pub const RADIXCHAR: ::nl_item = 50; +pub const THOUSEP: ::nl_item = 51; + +pub const YESEXPR: ::nl_item = 52; +pub const NOEXPR: ::nl_item = 53; + +pub const YESSTR: ::nl_item = 54; +pub const NOSTR: ::nl_item = 55; + +pub const CRNCYSTR: ::nl_item = 56; + +pub const D_MD_ORDER: ::nl_item = 57; + +pub const EXIT_FAILURE: ::c_int = 1; +pub const EXIT_SUCCESS: ::c_int = 0; +pub const RAND_MAX: ::c_int = 2147483647; +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; +pub const BUFSIZ: ::c_uint = 1024; +pub const FOPEN_MAX: ::c_uint = 20; +pub const FILENAME_MAX: ::c_uint = 1024; +pub const L_tmpnam: ::c_uint = 1024; +pub const TMP_MAX: ::c_uint = 308915776; +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 = 7; +pub const _PC_NO_TRUNC: ::c_int = 8; +pub const _PC_VDISABLE: ::c_int = 9; +pub const _PC_NAME_CHARS_MAX: ::c_int = 10; +pub const _PC_CASE_SENSITIVE: ::c_int = 11; +pub const _PC_CASE_PRESERVING: ::c_int = 12; +pub const _PC_EXTENDED_SECURITY_NP: ::c_int = 13; +pub const _PC_AUTH_OPAQUE_NP: ::c_int = 14; +pub const _PC_2_SYMLINKS: ::c_int = 15; +pub const _PC_ALLOC_SIZE_MIN: ::c_int = 16; +pub const _PC_ASYNC_IO: ::c_int = 17; +pub const _PC_FILESIZEBITS: ::c_int = 18; +pub const _PC_PRIO_IO: ::c_int = 19; +pub const _PC_REC_INCR_XFER_SIZE: ::c_int = 20; +pub const _PC_REC_MAX_XFER_SIZE: ::c_int = 21; +pub const _PC_REC_MIN_XFER_SIZE: ::c_int = 22; +pub const _PC_REC_XFER_ALIGN: ::c_int = 23; +pub const _PC_SYMLINK_MAX: ::c_int = 24; +pub const _PC_SYNC_IO: ::c_int = 25; +pub const _PC_XATTR_SIZE_BITS: ::c_int = 26; +pub const _PC_MIN_HOLE_SIZE: ::c_int = 27; +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 O_EXEC: ::c_int = 0x40000000; +pub const O_SEARCH: ::c_int = O_EXEC | O_DIRECTORY; +pub const S_IFIFO: mode_t = 4096; +pub const S_IFCHR: mode_t = 8192; +pub const S_IFBLK: mode_t = 24576; +pub const S_IFDIR: mode_t = 16384; +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 = 61440; +pub const S_IEXEC: mode_t = 64; +pub const S_IWRITE: mode_t = 128; +pub const S_IREAD: mode_t = 256; +pub const S_IRWXU: mode_t = 448; +pub const S_IXUSR: mode_t = 64; +pub const S_IWUSR: mode_t = 128; +pub const S_IRUSR: mode_t = 256; +pub const S_IRWXG: mode_t = 56; +pub const S_IXGRP: mode_t = 8; +pub const S_IWGRP: mode_t = 16; +pub const S_IRGRP: mode_t = 32; +pub const S_IRWXO: mode_t = 7; +pub const S_IXOTH: mode_t = 1; +pub const S_IWOTH: mode_t = 2; +pub const S_IROTH: mode_t = 4; +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; +pub const STDIN_FILENO: ::c_int = 0; +pub const STDOUT_FILENO: ::c_int = 1; +pub const STDERR_FILENO: ::c_int = 2; +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_GETLK: ::c_int = 7; +pub const F_SETLK: ::c_int = 8; +pub const F_SETLKW: ::c_int = 9; +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 SIGPIPE: ::c_int = 13; +pub const SIGALRM: ::c_int = 14; +pub const SIGTERM: ::c_int = 15; + +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 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_READ_U: ::c_int = 3; +pub const PT_WRITE_I: ::c_int = 4; +pub const PT_WRITE_D: ::c_int = 5; +pub const PT_WRITE_U: ::c_int = 6; +pub const PT_CONTINUE: ::c_int = 7; +pub const PT_KILL: ::c_int = 8; +pub const PT_STEP: ::c_int = 9; +pub const PT_ATTACH: ::c_int = 10; +pub const PT_DETACH: ::c_int = 11; +pub const PT_SIGEXC: ::c_int = 12; +pub const PT_THUPDATE: ::c_int = 13; +pub const PT_ATTACHEXC: ::c_int = 14; + +pub const PT_FORCEQUOTA: ::c_int = 30; +pub const PT_DENY_ATTACH: ::c_int = 31; +pub const PT_FIRSTMACH: ::c_int = 32; + +pub const MAP_FILE: ::c_int = 0x0000; +pub const MAP_SHARED: ::c_int = 0x0001; +pub const MAP_PRIVATE: ::c_int = 0x0002; +pub const MAP_FIXED: ::c_int = 0x0010; +pub const MAP_ANON: ::c_int = 0x1000; +pub const MAP_ANONYMOUS: ::c_int = MAP_ANON; + +pub const CPU_STATE_USER: ::c_int = 0; +pub const CPU_STATE_SYSTEM: ::c_int = 1; +pub const CPU_STATE_IDLE: ::c_int = 2; +pub const CPU_STATE_NICE: ::c_int = 3; +pub const CPU_STATE_MAX: ::c_int = 4; + +pub const PROCESSOR_BASIC_INFO: ::c_int = 1; +pub const PROCESSOR_CPU_LOAD_INFO: ::c_int = 2; +pub const PROCESSOR_PM_REGS_INFO: ::c_int = 0x10000001; +pub const PROCESSOR_TEMPERATURE: ::c_int = 0x10000002; +pub const PROCESSOR_SET_LOAD_INFO: ::c_int = 4; +pub const PROCESSOR_SET_BASIC_INFO: ::c_int = 5; + +deprecated_mach! { + pub const VM_FLAGS_FIXED: ::c_int = 0x0000; + pub const VM_FLAGS_ANYWHERE: ::c_int = 0x0001; + pub const VM_FLAGS_PURGABLE: ::c_int = 0x0002; + pub const VM_FLAGS_RANDOM_ADDR: ::c_int = 0x0008; + pub const VM_FLAGS_NO_CACHE: ::c_int = 0x0010; + pub const VM_FLAGS_RESILIENT_CODESIGN: ::c_int = 0x0020; + pub const VM_FLAGS_RESILIENT_MEDIA: ::c_int = 0x0040; + pub const VM_FLAGS_OVERWRITE: ::c_int = 0x4000; + pub const VM_FLAGS_SUPERPAGE_MASK: ::c_int = 0x70000; + pub const VM_FLAGS_RETURN_DATA_ADDR: ::c_int = 0x100000; + pub const VM_FLAGS_RETURN_4K_DATA_ADDR: ::c_int = 0x800000; + pub const VM_FLAGS_ALIAS_MASK: ::c_int = 0xFF000000; + pub const VM_FLAGS_USER_ALLOCATE: ::c_int = 0xff07401f; + pub const VM_FLAGS_USER_MAP: ::c_int = 0xff97401f; + pub const VM_FLAGS_USER_REMAP: ::c_int = VM_FLAGS_FIXED | + VM_FLAGS_ANYWHERE | + VM_FLAGS_RANDOM_ADDR | + VM_FLAGS_OVERWRITE | + VM_FLAGS_RETURN_DATA_ADDR | + VM_FLAGS_RESILIENT_CODESIGN; + + pub const VM_FLAGS_SUPERPAGE_SHIFT: ::c_int = 16; + pub const SUPERPAGE_NONE: ::c_int = 0; + pub const SUPERPAGE_SIZE_ANY: ::c_int = 1; + pub const VM_FLAGS_SUPERPAGE_NONE: ::c_int = SUPERPAGE_NONE << + VM_FLAGS_SUPERPAGE_SHIFT; + pub const VM_FLAGS_SUPERPAGE_SIZE_ANY: ::c_int = SUPERPAGE_SIZE_ANY << + VM_FLAGS_SUPERPAGE_SHIFT; + pub const SUPERPAGE_SIZE_2MB: ::c_int = 2; + pub const VM_FLAGS_SUPERPAGE_SIZE_2MB: ::c_int = SUPERPAGE_SIZE_2MB << + VM_FLAGS_SUPERPAGE_SHIFT; + + pub const VM_MEMORY_MALLOC: ::c_int = 1; + pub const VM_MEMORY_MALLOC_SMALL: ::c_int = 2; + pub const VM_MEMORY_MALLOC_LARGE: ::c_int = 3; + pub const VM_MEMORY_MALLOC_HUGE: ::c_int = 4; + pub const VM_MEMORY_SBRK: ::c_int = 5; + pub const VM_MEMORY_REALLOC: ::c_int = 6; + pub const VM_MEMORY_MALLOC_TINY: ::c_int = 7; + pub const VM_MEMORY_MALLOC_LARGE_REUSABLE: ::c_int = 8; + pub const VM_MEMORY_MALLOC_LARGE_REUSED: ::c_int = 9; + pub const VM_MEMORY_ANALYSIS_TOOL: ::c_int = 10; + pub const VM_MEMORY_MALLOC_NANO: ::c_int = 11; + pub const VM_MEMORY_MACH_MSG: ::c_int = 20; + pub const VM_MEMORY_IOKIT: ::c_int = 21; + pub const VM_MEMORY_STACK: ::c_int = 30; + pub const VM_MEMORY_GUARD: ::c_int = 31; + pub const VM_MEMORY_SHARED_PMAP: ::c_int = 32; + pub const VM_MEMORY_DYLIB: ::c_int = 33; + pub const VM_MEMORY_OBJC_DISPATCHERS: ::c_int = 34; + pub const VM_MEMORY_UNSHARED_PMAP: ::c_int = 35; + pub const VM_MEMORY_APPKIT: ::c_int = 40; + pub const VM_MEMORY_FOUNDATION: ::c_int = 41; + pub const VM_MEMORY_COREGRAPHICS: ::c_int = 42; + pub const VM_MEMORY_CORESERVICES: ::c_int = 43; + pub const VM_MEMORY_CARBON: ::c_int = VM_MEMORY_CORESERVICES; + pub const VM_MEMORY_JAVA: ::c_int = 44; + pub const VM_MEMORY_COREDATA: ::c_int = 45; + pub const VM_MEMORY_COREDATA_OBJECTIDS: ::c_int = 46; + pub const VM_MEMORY_ATS: ::c_int = 50; + pub const VM_MEMORY_LAYERKIT: ::c_int = 51; + pub const VM_MEMORY_CGIMAGE: ::c_int = 52; + pub const VM_MEMORY_TCMALLOC: ::c_int = 53; + pub const VM_MEMORY_COREGRAPHICS_DATA: ::c_int = 54; + pub const VM_MEMORY_COREGRAPHICS_SHARED: ::c_int = 55; + pub const VM_MEMORY_COREGRAPHICS_FRAMEBUFFERS: ::c_int = 56; + pub const VM_MEMORY_COREGRAPHICS_BACKINGSTORES: ::c_int = 57; + pub const VM_MEMORY_COREGRAPHICS_XALLOC: ::c_int = 58; + pub const VM_MEMORY_COREGRAPHICS_MISC: ::c_int = VM_MEMORY_COREGRAPHICS; + pub const VM_MEMORY_DYLD: ::c_int = 60; + pub const VM_MEMORY_DYLD_MALLOC: ::c_int = 61; + pub const VM_MEMORY_SQLITE: ::c_int = 62; + pub const VM_MEMORY_JAVASCRIPT_CORE: ::c_int = 63; + pub const VM_MEMORY_JAVASCRIPT_JIT_EXECUTABLE_ALLOCATOR: ::c_int = 64; + pub const VM_MEMORY_JAVASCRIPT_JIT_REGISTER_FILE: ::c_int = 65; + pub const VM_MEMORY_GLSL: ::c_int = 66; + pub const VM_MEMORY_OPENCL: ::c_int = 67; + pub const VM_MEMORY_COREIMAGE: ::c_int = 68; + pub const VM_MEMORY_WEBCORE_PURGEABLE_BUFFERS: ::c_int = 69; + pub const VM_MEMORY_IMAGEIO: ::c_int = 70; + pub const VM_MEMORY_COREPROFILE: ::c_int = 71; + pub const VM_MEMORY_ASSETSD: ::c_int = 72; + pub const VM_MEMORY_OS_ALLOC_ONCE: ::c_int = 73; + pub const VM_MEMORY_LIBDISPATCH: ::c_int = 74; + pub const VM_MEMORY_ACCELERATE: ::c_int = 75; + pub const VM_MEMORY_COREUI: ::c_int = 76; + pub const VM_MEMORY_COREUIFILE: ::c_int = 77; + pub const VM_MEMORY_GENEALOGY: ::c_int = 78; + pub const VM_MEMORY_RAWCAMERA: ::c_int = 79; + pub const VM_MEMORY_CORPSEINFO: ::c_int = 80; + pub const VM_MEMORY_ASL: ::c_int = 81; + pub const VM_MEMORY_SWIFT_RUNTIME: ::c_int = 82; + pub const VM_MEMORY_SWIFT_METADATA: ::c_int = 83; + pub const VM_MEMORY_DHMM: ::c_int = 84; + pub const VM_MEMORY_SCENEKIT: ::c_int = 86; + pub const VM_MEMORY_SKYWALK: ::c_int = 87; + pub const VM_MEMORY_APPLICATION_SPECIFIC_1: ::c_int = 240; + pub const VM_MEMORY_APPLICATION_SPECIFIC_16: ::c_int = 255; +} + +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 MS_ASYNC: ::c_int = 0x0001; +pub const MS_INVALIDATE: ::c_int = 0x0002; +pub const MS_SYNC: ::c_int = 0x0010; + +pub const MS_KILLPAGES: ::c_int = 0x0004; +pub const MS_DEACTIVATE: ::c_int = 0x0008; + +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 EDEADLK: ::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 EAGAIN: ::c_int = 35; +pub const EWOULDBLOCK: ::c_int = EAGAIN; +pub const EINPROGRESS: ::c_int = 36; +pub const EALREADY: ::c_int = 37; +pub const ENOTSOCK: ::c_int = 38; +pub const EDESTADDRREQ: ::c_int = 39; +pub const EMSGSIZE: ::c_int = 40; +pub const EPROTOTYPE: ::c_int = 41; +pub const ENOPROTOOPT: ::c_int = 42; +pub const EPROTONOSUPPORT: ::c_int = 43; +pub const ESOCKTNOSUPPORT: ::c_int = 44; +pub const ENOTSUP: ::c_int = 45; +pub const EPFNOSUPPORT: ::c_int = 46; +pub const EAFNOSUPPORT: ::c_int = 47; +pub const EADDRINUSE: ::c_int = 48; +pub const EADDRNOTAVAIL: ::c_int = 49; +pub const ENETDOWN: ::c_int = 50; +pub const ENETUNREACH: ::c_int = 51; +pub const ENETRESET: ::c_int = 52; +pub const ECONNABORTED: ::c_int = 53; +pub const ECONNRESET: ::c_int = 54; +pub const ENOBUFS: ::c_int = 55; +pub const EISCONN: ::c_int = 56; +pub const ENOTCONN: ::c_int = 57; +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 ELOOP: ::c_int = 62; +pub const ENAMETOOLONG: ::c_int = 63; +pub const EHOSTDOWN: ::c_int = 64; +pub const EHOSTUNREACH: ::c_int = 65; +pub const ENOTEMPTY: ::c_int = 66; +pub const EPROCLIM: ::c_int = 67; +pub const EUSERS: ::c_int = 68; +pub const EDQUOT: ::c_int = 69; +pub const ESTALE: ::c_int = 70; +pub const EREMOTE: ::c_int = 71; +pub const EBADRPC: ::c_int = 72; +pub const ERPCMISMATCH: ::c_int = 73; +pub const EPROGUNAVAIL: ::c_int = 74; +pub const EPROGMISMATCH: ::c_int = 75; +pub const EPROCUNAVAIL: ::c_int = 76; +pub const ENOLCK: ::c_int = 77; +pub const ENOSYS: ::c_int = 78; +pub const EFTYPE: ::c_int = 79; +pub const EAUTH: ::c_int = 80; +pub const ENEEDAUTH: ::c_int = 81; +pub const EPWROFF: ::c_int = 82; +pub const EDEVERR: ::c_int = 83; +pub const EOVERFLOW: ::c_int = 84; +pub const EBADEXEC: ::c_int = 85; +pub const EBADARCH: ::c_int = 86; +pub const ESHLIBVERS: ::c_int = 87; +pub const EBADMACHO: ::c_int = 88; +pub const ECANCELED: ::c_int = 89; +pub const EIDRM: ::c_int = 90; +pub const ENOMSG: ::c_int = 91; +pub const EILSEQ: ::c_int = 92; +pub const ENOATTR: ::c_int = 93; +pub const EBADMSG: ::c_int = 94; +pub const EMULTIHOP: ::c_int = 95; +pub const ENODATA: ::c_int = 96; +pub const ENOLINK: ::c_int = 97; +pub const ENOSR: ::c_int = 98; +pub const ENOSTR: ::c_int = 99; +pub const EPROTO: ::c_int = 100; +pub const ETIME: ::c_int = 101; +pub const EOPNOTSUPP: ::c_int = 102; +pub const ENOPOLICY: ::c_int = 103; +pub const ENOTRECOVERABLE: ::c_int = 104; +pub const EOWNERDEAD: ::c_int = 105; +pub const EQFULL: ::c_int = 106; +pub const ELAST: ::c_int = 106; + +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 = 14; + +pub const F_DUPFD: ::c_int = 0; +pub const F_DUPFD_CLOEXEC: ::c_int = 67; +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_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; +// See https://github.com/apple/darwin-xnu/blob/main/bsd/sys/fcntl.h +pub const F_OFD_SETLK: ::c_int = 90; /* Acquire or release open file description lock */ +pub const F_OFD_SETLKW: ::c_int = 91; /* (as F_OFD_SETLK but blocking if conflicting lock) */ +pub const F_OFD_GETLK: ::c_int = 92; /* Examine OFD lock */ +pub const F_PUNCHHOLE: ::c_int = 99; +pub const F_TRIM_ACTIVE_FILE: ::c_int = 100; +pub const F_SPECULATIVE_READ: ::c_int = 101; +pub const F_GETPATH_NOFIRMLINK: ::c_int = 102; +pub const F_TRANSFEREXTENTS: ::c_int = 110; + +pub const F_ALLOCATECONTIG: ::c_uint = 0x02; +pub const F_ALLOCATEALL: ::c_uint = 0x04; +pub const F_ALLOCATEPERSIST: ::c_uint = 0x08; + +pub const F_PEOFPOSMODE: ::c_int = 3; +pub const F_VOLPOSMODE: ::c_int = 4; + +pub const AT_FDCWD: ::c_int = -2; +pub const AT_EACCESS: ::c_int = 0x0010; +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; +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 TIOCEXCL: ::c_int = 0x2000740d; +pub const TIOCNXCL: ::c_int = 0x2000740e; +pub const TIOCFLUSH: ::c_ulong = 0x80047410; +pub const TIOCGETD: ::c_ulong = 0x4004741a; +pub const TIOCSETD: ::c_ulong = 0x8004741b; +pub const TIOCIXON: ::c_uint = 0x20007481; +pub const TIOCIXOFF: ::c_uint = 0x20007480; +pub const TIOCSDTR: ::c_uint = 0x20007479; +pub const TIOCCDTR: ::c_uint = 0x20007478; +pub const TIOCGPGRP: ::c_ulong = 0x40047477; +pub const TIOCSPGRP: ::c_ulong = 0x80047476; +pub const TIOCOUTQ: ::c_ulong = 0x40047473; +pub const TIOCSTI: ::c_ulong = 0x80017472; +pub const TIOCNOTTY: ::c_uint = 0x20007471; +pub const TIOCPKT: ::c_ulong = 0x80047470; +pub const TIOCPKT_DATA: ::c_int = 0x0; +pub const TIOCPKT_FLUSHREAD: ::c_int = 0x1; +pub const TIOCPKT_FLUSHWRITE: ::c_int = 0x2; +pub const TIOCPKT_STOP: ::c_int = 0x4; +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 TIOCSTOP: ::c_uint = 0x2000746f; +pub const TIOCSTART: ::c_uint = 0x2000746e; +pub const TIOCMSET: ::c_ulong = 0x8004746d; +pub const TIOCMBIS: ::c_ulong = 0x8004746c; +pub const TIOCMBIC: ::c_ulong = 0x8004746b; +pub const TIOCMGET: ::c_ulong = 0x4004746a; +pub const TIOCREMOTE: ::c_ulong = 0x80047469; +pub const TIOCGWINSZ: ::c_ulong = 0x40087468; +pub const TIOCSWINSZ: ::c_ulong = 0x80087467; +pub const TIOCUCNTL: ::c_ulong = 0x80047466; +pub const TIOCSTAT: ::c_uint = 0x20007465; +pub const TIOCSCONS: ::c_uint = 0x20007463; +pub const TIOCCONS: ::c_ulong = 0x80047462; +pub const TIOCSCTTY: ::c_uint = 0x20007461; +pub const TIOCEXT: ::c_ulong = 0x80047460; +pub const TIOCSIG: ::c_uint = 0x2000745f; +pub const TIOCDRAIN: ::c_uint = 0x2000745e; +pub const TIOCMSDTRWAIT: ::c_ulong = 0x8004745b; +pub const TIOCMGDTRWAIT: ::c_ulong = 0x4004745a; +pub const TIOCSDRAINWAIT: ::c_ulong = 0x80047457; +pub const TIOCGDRAINWAIT: ::c_ulong = 0x40047456; +pub const TIOCDSIMICROCODE: ::c_uint = 0x20007455; +pub const TIOCPTYGRANT: ::c_uint = 0x20007454; +pub const TIOCPTYGNAME: ::c_uint = 0x40807453; +pub const TIOCPTYUNLK: ::c_uint = 0x20007452; + +pub const BIOCGRSIG: ::c_ulong = 0x40044272; +pub const BIOCSRSIG: ::c_ulong = 0x80044273; +pub const BIOCSDLT: ::c_ulong = 0x80044278; +pub const BIOCGSEESENT: ::c_ulong = 0x40044276; +pub const BIOCSSEESENT: ::c_ulong = 0x80044277; +pub const BIOCGDLTLIST: ::c_ulong = 0xc00c4279; + +pub const FIODTYPE: ::c_ulong = 0x4004667a; + +pub const B0: speed_t = 0; +pub const B50: speed_t = 50; +pub const B75: speed_t = 75; +pub const B110: speed_t = 110; +pub const B134: speed_t = 134; +pub const B150: speed_t = 150; +pub const B200: speed_t = 200; +pub const B300: speed_t = 300; +pub const B600: speed_t = 600; +pub const B1200: speed_t = 1200; +pub const B1800: speed_t = 1800; +pub const B2400: speed_t = 2400; +pub const B4800: speed_t = 4800; +pub const B9600: speed_t = 9600; +pub const B19200: speed_t = 19200; +pub const B38400: speed_t = 38400; +pub const B7200: speed_t = 7200; +pub const B14400: speed_t = 14400; +pub const B28800: speed_t = 28800; +pub const B57600: speed_t = 57600; +pub const B76800: speed_t = 76800; +pub const B115200: speed_t = 115200; +pub const B230400: speed_t = 230400; +pub const EXTA: speed_t = 19200; +pub const EXTB: speed_t = 38400; + +pub const SIGTRAP: ::c_int = 5; + +pub const GLOB_APPEND: ::c_int = 0x0001; +pub const GLOB_DOOFFS: ::c_int = 0x0002; +pub const GLOB_ERR: ::c_int = 0x0004; +pub const GLOB_MARK: ::c_int = 0x0008; +pub const GLOB_NOCHECK: ::c_int = 0x0010; +pub const GLOB_NOSORT: ::c_int = 0x0020; +pub const GLOB_NOESCAPE: ::c_int = 0x2000; + +pub const GLOB_NOSPACE: ::c_int = -1; +pub const GLOB_ABORTED: ::c_int = -2; +pub const GLOB_NOMATCH: ::c_int = -3; + +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_MADV_DONTNEED: ::c_int = 4; + +pub const _SC_IOV_MAX: ::c_int = 56; +pub const _SC_GETGR_R_SIZE_MAX: ::c_int = 70; +pub const _SC_GETPW_R_SIZE_MAX: ::c_int = 71; +pub const _SC_LOGIN_NAME_MAX: ::c_int = 73; +pub const _SC_MQ_PRIO_MAX: ::c_int = 75; +pub const _SC_THREAD_ATTR_STACKADDR: ::c_int = 82; +pub const _SC_THREAD_ATTR_STACKSIZE: ::c_int = 83; +pub const _SC_THREAD_DESTRUCTOR_ITERATIONS: ::c_int = 85; +pub const _SC_THREAD_KEYS_MAX: ::c_int = 86; +pub const _SC_THREAD_PRIO_INHERIT: ::c_int = 87; +pub const _SC_THREAD_PRIO_PROTECT: ::c_int = 88; +pub const _SC_THREAD_PRIORITY_SCHEDULING: ::c_int = 89; +pub const _SC_THREAD_PROCESS_SHARED: ::c_int = 90; +pub const _SC_THREAD_SAFE_FUNCTIONS: ::c_int = 91; +pub const _SC_THREAD_STACK_MIN: ::c_int = 93; +pub const _SC_THREAD_THREADS_MAX: ::c_int = 94; +pub const _SC_THREADS: ::c_int = 96; +pub const _SC_TTY_NAME_MAX: ::c_int = 101; +pub const _SC_ATEXIT_MAX: ::c_int = 107; +pub const _SC_XOPEN_CRYPT: ::c_int = 108; +pub const _SC_XOPEN_ENH_I18N: ::c_int = 109; +pub const _SC_XOPEN_LEGACY: ::c_int = 110; +pub const _SC_XOPEN_REALTIME: ::c_int = 111; +pub const _SC_XOPEN_REALTIME_THREADS: ::c_int = 112; +pub const _SC_XOPEN_SHM: ::c_int = 113; +pub const _SC_XOPEN_UNIX: ::c_int = 115; +pub const _SC_XOPEN_VERSION: ::c_int = 116; +pub const _SC_XOPEN_XCU_VERSION: ::c_int = 121; +pub const _SC_PHYS_PAGES: ::c_int = 200; + +pub const PTHREAD_PROCESS_PRIVATE: ::c_int = 2; +pub const PTHREAD_PROCESS_SHARED: ::c_int = 1; +pub const PTHREAD_CREATE_JOINABLE: ::c_int = 1; +pub const PTHREAD_CREATE_DETACHED: ::c_int = 2; +pub const PTHREAD_INHERIT_SCHED: ::c_int = 1; +pub const PTHREAD_EXPLICIT_SCHED: ::c_int = 2; +pub const PTHREAD_CANCEL_ENABLE: ::c_int = 0x01; +pub const PTHREAD_CANCEL_DISABLE: ::c_int = 0x00; +pub const PTHREAD_CANCEL_DEFERRED: ::c_int = 0x02; +pub const PTHREAD_CANCEL_ASYNCHRONOUS: ::c_int = 0x00; +pub const PTHREAD_CANCELED: *mut ::c_void = 1 as *mut ::c_void; +pub const PTHREAD_SCOPE_SYSTEM: ::c_int = 1; +pub const PTHREAD_SCOPE_PROCESS: ::c_int = 2; +pub const PTHREAD_PRIO_NONE: ::c_int = 0; +pub const PTHREAD_PRIO_INHERIT: ::c_int = 1; +pub const PTHREAD_PRIO_PROTECT: ::c_int = 2; + +#[cfg(target_arch = "aarch64")] +pub const PTHREAD_STACK_MIN: ::size_t = 16384; +#[cfg(not(target_arch = "aarch64"))] +pub const PTHREAD_STACK_MIN: ::size_t = 8192; + +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_AS: ::c_int = 5; +pub const RLIMIT_RSS: ::c_int = RLIMIT_AS; +pub const RLIMIT_MEMLOCK: ::c_int = 6; +pub const RLIMIT_NPROC: ::c_int = 7; +pub const RLIMIT_NOFILE: ::c_int = 8; +#[deprecated(since = "0.2.64", note = "Not stable across OS versions")] +pub const RLIM_NLIMITS: ::c_int = 9; +pub const _RLIMIT_POSIX_FLAG: ::c_int = 0x1000; + +pub const RLIM_INFINITY: rlim_t = 0x7fff_ffff_ffff_ffff; + +pub const RUSAGE_SELF: ::c_int = 0; +pub const RUSAGE_CHILDREN: ::c_int = -1; + +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 MADV_FREE: ::c_int = 5; +pub const MADV_ZERO_WIRED_PAGES: ::c_int = 6; +pub const MADV_FREE_REUSABLE: ::c_int = 7; +pub const MADV_FREE_REUSE: ::c_int = 8; +pub const MADV_CAN_REUSE: ::c_int = 9; + +pub const MINCORE_INCORE: ::c_int = 0x1; +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 CTLIOCGINFO: c_ulong = 0xc0644e03; + +// +// sys/netinet/in.h +// Protocols (RFC 1700) +// NOTE: These are in addition to the constants defined in src/unix/mod.rs + +// IPPROTO_IP defined in src/unix/mod.rs +/// IP6 hop-by-hop options +pub const IPPROTO_HOPOPTS: ::c_int = 0; +// IPPROTO_ICMP defined in src/unix/mod.rs +/// group mgmt protocol +pub const IPPROTO_IGMP: ::c_int = 2; +/// gateway2 (deprecated) +pub const IPPROTO_GGP: ::c_int = 3; +/// for compatibility +pub const IPPROTO_IPIP: ::c_int = 4; +// IPPROTO_TCP defined in src/unix/mod.rs +/// Stream protocol II. +pub const IPPROTO_ST: ::c_int = 7; +/// exterior gateway protocol +pub const IPPROTO_EGP: ::c_int = 8; +/// private interior gateway +pub const IPPROTO_PIGP: ::c_int = 9; +/// BBN RCC Monitoring +pub const IPPROTO_RCCMON: ::c_int = 10; +/// network voice protocol +pub const IPPROTO_NVPII: ::c_int = 11; +/// pup +pub const IPPROTO_PUP: ::c_int = 12; +/// Argus +pub const IPPROTO_ARGUS: ::c_int = 13; +/// EMCON +pub const IPPROTO_EMCON: ::c_int = 14; +/// Cross Net Debugger +pub const IPPROTO_XNET: ::c_int = 15; +/// Chaos +pub const IPPROTO_CHAOS: ::c_int = 16; +// IPPROTO_UDP defined in src/unix/mod.rs +/// Multiplexing +pub const IPPROTO_MUX: ::c_int = 18; +/// DCN Measurement Subsystems +pub const IPPROTO_MEAS: ::c_int = 19; +/// Host Monitoring +pub const IPPROTO_HMP: ::c_int = 20; +/// Packet Radio Measurement +pub const IPPROTO_PRM: ::c_int = 21; +/// xns idp +pub const IPPROTO_IDP: ::c_int = 22; +/// Trunk-1 +pub const IPPROTO_TRUNK1: ::c_int = 23; +/// Trunk-2 +pub const IPPROTO_TRUNK2: ::c_int = 24; +/// Leaf-1 +pub const IPPROTO_LEAF1: ::c_int = 25; +/// Leaf-2 +pub const IPPROTO_LEAF2: ::c_int = 26; +/// Reliable Data +pub const IPPROTO_RDP: ::c_int = 27; +/// Reliable Transaction +pub const IPPROTO_IRTP: ::c_int = 28; +/// tp-4 w/ class negotiation +pub const IPPROTO_TP: ::c_int = 29; +/// Bulk Data Transfer +pub const IPPROTO_BLT: ::c_int = 30; +/// Network Services +pub const IPPROTO_NSP: ::c_int = 31; +/// Merit Internodal +pub const IPPROTO_INP: ::c_int = 32; +/// Sequential Exchange +pub const IPPROTO_SEP: ::c_int = 33; +/// Third Party Connect +pub const IPPROTO_3PC: ::c_int = 34; +/// InterDomain Policy Routing +pub const IPPROTO_IDPR: ::c_int = 35; +/// XTP +pub const IPPROTO_XTP: ::c_int = 36; +/// Datagram Delivery +pub const IPPROTO_DDP: ::c_int = 37; +/// Control Message Transport +pub const IPPROTO_CMTP: ::c_int = 38; +/// TP++ Transport +pub const IPPROTO_TPXX: ::c_int = 39; +/// IL transport protocol +pub const IPPROTO_IL: ::c_int = 40; +// IPPROTO_IPV6 defined in src/unix/mod.rs +/// Source Demand Routing +pub const IPPROTO_SDRP: ::c_int = 42; +/// IP6 routing header +pub const IPPROTO_ROUTING: ::c_int = 43; +/// IP6 fragmentation header +pub const IPPROTO_FRAGMENT: ::c_int = 44; +/// InterDomain Routing +pub const IPPROTO_IDRP: ::c_int = 45; +/// resource reservation +pub const IPPROTO_RSVP: ::c_int = 46; +/// General Routing Encap. +pub const IPPROTO_GRE: ::c_int = 47; +/// Mobile Host Routing +pub const IPPROTO_MHRP: ::c_int = 48; +/// BHA +pub const IPPROTO_BHA: ::c_int = 49; +/// IP6 Encap Sec. Payload +pub const IPPROTO_ESP: ::c_int = 50; +/// IP6 Auth Header +pub const IPPROTO_AH: ::c_int = 51; +/// Integ. Net Layer Security +pub const IPPROTO_INLSP: ::c_int = 52; +/// IP with encryption +pub const IPPROTO_SWIPE: ::c_int = 53; +/// Next Hop Resolution +pub const IPPROTO_NHRP: ::c_int = 54; +/* 55-57: Unassigned */ +// IPPROTO_ICMPV6 defined in src/unix/mod.rs +/// IP6 no next header +pub const IPPROTO_NONE: ::c_int = 59; +/// IP6 destination option +pub const IPPROTO_DSTOPTS: ::c_int = 60; +/// any host internal protocol +pub const IPPROTO_AHIP: ::c_int = 61; +/// CFTP +pub const IPPROTO_CFTP: ::c_int = 62; +/// "hello" routing protocol +pub const IPPROTO_HELLO: ::c_int = 63; +/// SATNET/Backroom EXPAK +pub const IPPROTO_SATEXPAK: ::c_int = 64; +/// Kryptolan +pub const IPPROTO_KRYPTOLAN: ::c_int = 65; +/// Remote Virtual Disk +pub const IPPROTO_RVD: ::c_int = 66; +/// Pluribus Packet Core +pub const IPPROTO_IPPC: ::c_int = 67; +/// Any distributed FS +pub const IPPROTO_ADFS: ::c_int = 68; +/// Satnet Monitoring +pub const IPPROTO_SATMON: ::c_int = 69; +/// VISA Protocol +pub const IPPROTO_VISA: ::c_int = 70; +/// Packet Core Utility +pub const IPPROTO_IPCV: ::c_int = 71; +/// Comp. Prot. Net. Executive +pub const IPPROTO_CPNX: ::c_int = 72; +/// Comp. Prot. HeartBeat +pub const IPPROTO_CPHB: ::c_int = 73; +/// Wang Span Network +pub const IPPROTO_WSN: ::c_int = 74; +/// Packet Video Protocol +pub const IPPROTO_PVP: ::c_int = 75; +/// BackRoom SATNET Monitoring +pub const IPPROTO_BRSATMON: ::c_int = 76; +/// Sun net disk proto (temp.) +pub const IPPROTO_ND: ::c_int = 77; +/// WIDEBAND Monitoring +pub const IPPROTO_WBMON: ::c_int = 78; +/// WIDEBAND EXPAK +pub const IPPROTO_WBEXPAK: ::c_int = 79; +/// ISO cnlp +pub const IPPROTO_EON: ::c_int = 80; +/// VMTP +pub const IPPROTO_VMTP: ::c_int = 81; +/// Secure VMTP +pub const IPPROTO_SVMTP: ::c_int = 82; +/// Banyon VINES +pub const IPPROTO_VINES: ::c_int = 83; +/// TTP +pub const IPPROTO_TTP: ::c_int = 84; +/// NSFNET-IGP +pub const IPPROTO_IGP: ::c_int = 85; +/// dissimilar gateway prot. +pub const IPPROTO_DGP: ::c_int = 86; +/// TCF +pub const IPPROTO_TCF: ::c_int = 87; +/// Cisco/GXS IGRP +pub const IPPROTO_IGRP: ::c_int = 88; +/// OSPFIGP +pub const IPPROTO_OSPFIGP: ::c_int = 89; +/// Strite RPC protocol +pub const IPPROTO_SRPC: ::c_int = 90; +/// Locus Address Resoloution +pub const IPPROTO_LARP: ::c_int = 91; +/// Multicast Transport +pub const IPPROTO_MTP: ::c_int = 92; +/// AX.25 Frames +pub const IPPROTO_AX25: ::c_int = 93; +/// IP encapsulated in IP +pub const IPPROTO_IPEIP: ::c_int = 94; +/// Mobile Int.ing control +pub const IPPROTO_MICP: ::c_int = 95; +/// Semaphore Comm. security +pub const IPPROTO_SCCSP: ::c_int = 96; +/// Ethernet IP encapsulation +pub const IPPROTO_ETHERIP: ::c_int = 97; +/// encapsulation header +pub const IPPROTO_ENCAP: ::c_int = 98; +/// any private encr. scheme +pub const IPPROTO_APES: ::c_int = 99; +/// GMTP +pub const IPPROTO_GMTP: ::c_int = 100; + +/* 101-254: Partly Unassigned */ +/// Protocol Independent Mcast +pub const IPPROTO_PIM: ::c_int = 103; +/// payload compression (IPComp) +pub const IPPROTO_IPCOMP: ::c_int = 108; +/// PGM +pub const IPPROTO_PGM: ::c_int = 113; +/// SCTP +pub const IPPROTO_SCTP: ::c_int = 132; + +/* 255: Reserved */ +/* BSD Private, local use, namespace incursion */ +/// divert pseudo-protocol +pub const IPPROTO_DIVERT: ::c_int = 254; +/// raw IP packet +pub const IPPROTO_RAW: ::c_int = 255; +pub const IPPROTO_MAX: ::c_int = 256; +/// last return value of *_input(), meaning "all job for this pkt is done". +pub const IPPROTO_DONE: ::c_int = 257; + +pub const AF_UNSPEC: ::c_int = 0; +pub const AF_LOCAL: ::c_int = 1; +pub const AF_UNIX: ::c_int = AF_LOCAL; +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_ISO: ::c_int = 7; +pub const AF_OSI: ::c_int = AF_ISO; +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 AF_HYLINK: ::c_int = 15; +pub const AF_APPLETALK: ::c_int = 16; +pub const AF_ROUTE: ::c_int = 17; +pub const AF_LINK: ::c_int = 18; +pub const pseudo_AF_XTP: ::c_int = 19; +pub const AF_COIP: ::c_int = 20; +pub const AF_CNT: ::c_int = 21; +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; +pub const AF_INET6: ::c_int = 30; +pub const AF_NATM: ::c_int = 31; +pub const AF_SYSTEM: ::c_int = 32; +pub const AF_NETBIOS: ::c_int = 33; +pub const AF_PPP: ::c_int = 34; +pub const pseudo_AF_HDRCMPLT: ::c_int = 35; +pub const AF_IEEE80211: ::c_int = 37; +pub const AF_UTUN: ::c_int = 38; +pub const AF_VSOCK: ::c_int = 40; +pub const AF_SYS_CONTROL: ::c_int = 2; + +pub const SYSPROTO_EVENT: ::c_int = 1; +pub const SYSPROTO_CONTROL: ::c_int = 2; + +pub const PF_UNSPEC: ::c_int = AF_UNSPEC; +pub const PF_LOCAL: ::c_int = AF_LOCAL; +pub const PF_UNIX: ::c_int = PF_LOCAL; +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 = pseudo_AF_XTP; +pub const PF_COIP: ::c_int = AF_COIP; +pub const PF_CNT: ::c_int = AF_CNT; +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; +pub const PF_NATM: ::c_int = AF_NATM; +pub const PF_SYSTEM: ::c_int = AF_SYSTEM; +pub const PF_NETBIOS: ::c_int = AF_NETBIOS; +pub const PF_PPP: ::c_int = AF_PPP; +pub const PF_VSOCK: ::c_int = AF_VSOCK; + +pub const NET_RT_DUMP: ::c_int = 1; +pub const NET_RT_FLAGS: ::c_int = 2; +pub const NET_RT_IFLIST: ::c_int = 3; + +pub const SOMAXCONN: ::c_int = 128; + +pub const SOCK_MAXADDRLEN: ::c_int = 255; + +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_SEQPACKET: ::c_int = 5; +pub const IP_TTL: ::c_int = 4; +pub const IP_HDRINCL: ::c_int = 2; +pub const IP_RECVDSTADDR: ::c_int = 7; +pub const IP_ADD_MEMBERSHIP: ::c_int = 12; +pub const IP_DROP_MEMBERSHIP: ::c_int = 13; +pub const IP_RECVIF: ::c_int = 20; +pub const IP_RECVTTL: ::c_int = 24; +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; +pub const IPV6_RECVTCLASS: ::c_int = 35; +pub const IPV6_TCLASS: ::c_int = 36; +pub const IPV6_RECVHOPLIMIT: ::c_int = 37; +pub const IPV6_PKTINFO: ::c_int = 46; +pub const IPV6_HOPLIMIT: ::c_int = 47; +pub const IPV6_RECVPKTINFO: ::c_int = 61; +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; +pub const TCP_KEEPALIVE: ::c_int = 0x10; +pub const TCP_KEEPINTVL: ::c_int = 0x101; +pub const TCP_KEEPCNT: ::c_int = 0x102; +/// Enable/Disable TCP Fastopen on this socket +pub const TCP_FASTOPEN: ::c_int = 0x105; +pub const TCP_CONNECTION_INFO: ::c_int = 0x106; + +pub const SOL_LOCAL: ::c_int = 0; + +/// Retrieve peer credentials. +pub const LOCAL_PEERCRED: ::c_int = 0x001; +/// Retrieve peer PID. +pub const LOCAL_PEERPID: ::c_int = 0x002; +/// Retrieve effective peer PID. +pub const LOCAL_PEEREPID: ::c_int = 0x003; +/// Retrieve peer UUID. +pub const LOCAL_PEERUUID: ::c_int = 0x004; +/// Retrieve effective peer UUID. +pub const LOCAL_PEEREUUID: ::c_int = 0x005; +/// Retrieve peer audit token. +pub const LOCAL_PEERTOKEN: ::c_int = 0x006; + +pub const SOL_SOCKET: ::c_int = 0xffff; + +pub const SO_DEBUG: ::c_int = 0x01; +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_TIMESTAMP: ::c_int = 0x0400; +pub const SO_TIMESTAMP_MONOTONIC: ::c_int = 0x0800; +pub const SO_DONTTRUNC: ::c_int = 0x2000; +pub const SO_WANTMORE: ::c_int = 0x4000; +pub const SO_WANTOOBFLAG: ::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 SO_LABEL: ::c_int = 0x1010; +pub const SO_PEERLABEL: ::c_int = 0x1011; +pub const SO_NREAD: ::c_int = 0x1020; +pub const SO_NKE: ::c_int = 0x1021; +pub const SO_NOSIGPIPE: ::c_int = 0x1022; +pub const SO_NOADDRERR: ::c_int = 0x1023; +pub const SO_NWRITE: ::c_int = 0x1024; +pub const SO_REUSESHAREUID: ::c_int = 0x1025; +pub const SO_NOTIFYCONFLICT: ::c_int = 0x1026; +pub const SO_LINGER_SEC: ::c_int = 0x1080; +pub const SO_RANDOMPORT: ::c_int = 0x1082; +pub const SO_NP_EXTENSIONS: ::c_int = 0x1083; + +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_DONTWAIT: ::c_int = 0x80; +pub const MSG_EOF: ::c_int = 0x100; +pub const MSG_FLUSH: ::c_int = 0x400; +pub const MSG_HOLD: ::c_int = 0x800; +pub const MSG_SEND: ::c_int = 0x1000; +pub const MSG_HAVEMORE: ::c_int = 0x2000; +pub const MSG_RCVMORE: ::c_int = 0x4000; +pub const MSG_NEEDSA: ::c_int = 0x10000; +pub const MSG_NOSIGNAL: ::c_int = 0x80000; + +pub const SCM_TIMESTAMP: ::c_int = 0x02; +pub const SCM_CREDS: ::c_int = 0x03; + +// https://github.com/aosm/xnu/blob/HEAD/bsd/net/if.h#L140-L156 +pub const IFF_UP: ::c_int = 0x1; // interface is up +pub const IFF_BROADCAST: ::c_int = 0x2; // broadcast address valid +pub const IFF_DEBUG: ::c_int = 0x4; // turn on debugging +pub const IFF_LOOPBACK: ::c_int = 0x8; // is a loopback net +pub const IFF_POINTOPOINT: ::c_int = 0x10; // interface is point-to-point link +pub const IFF_NOTRAILERS: ::c_int = 0x20; // obsolete: avoid use of trailers +pub const IFF_RUNNING: ::c_int = 0x40; // resources allocated +pub const IFF_NOARP: ::c_int = 0x80; // no address resolution protocol +pub const IFF_PROMISC: ::c_int = 0x100; // receive all packets +pub const IFF_ALLMULTI: ::c_int = 0x200; // receive all multicast packets +pub const IFF_OACTIVE: ::c_int = 0x400; // transmission in progress +pub const IFF_SIMPLEX: ::c_int = 0x800; // 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; // supports multicast + +pub const SHUT_RD: ::c_int = 0; +pub const SHUT_WR: ::c_int = 1; +pub const SHUT_RDWR: ::c_int = 2; + +pub const SAE_ASSOCID_ANY: ::sae_associd_t = 0; +/// ((sae_associd_t)(-1ULL)) +pub const SAE_ASSOCID_ALL: ::sae_associd_t = 0xffffffff; + +pub const SAE_CONNID_ANY: ::sae_connid_t = 0; +/// ((sae_connid_t)(-1ULL)) +pub const SAE_CONNID_ALL: ::sae_connid_t = 0xffffffff; + +// connectx() flag parameters + +/// resume connect() on read/write +pub const CONNECT_RESUME_ON_READ_WRITE: ::c_uint = 0x1; +/// data is idempotent +pub const CONNECT_DATA_IDEMPOTENT: ::c_uint = 0x2; +/// data includes security that replaces the TFO-cookie +pub const CONNECT_DATA_AUTHENTICATED: ::c_uint = 0x4; + +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; + +pub const MAP_COPY: ::c_int = 0x0002; +pub const MAP_RENAME: ::c_int = 0x0020; +pub const MAP_NORESERVE: ::c_int = 0x0040; +pub const MAP_NOEXTEND: ::c_int = 0x0100; +pub const MAP_HASSEMAPHORE: ::c_int = 0x0200; +pub const MAP_NOCACHE: ::c_int = 0x0400; +pub const MAP_JIT: ::c_int = 0x0800; + +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_BC_BASE_MAX: ::c_int = 9; +pub const _SC_BC_DIM_MAX: ::c_int = 10; +pub const _SC_BC_SCALE_MAX: ::c_int = 11; +pub const _SC_BC_STRING_MAX: ::c_int = 12; +pub const _SC_COLL_WEIGHTS_MAX: ::c_int = 13; +pub const _SC_EXPR_NEST_MAX: ::c_int = 14; +pub const _SC_LINE_MAX: ::c_int = 15; +pub const _SC_RE_DUP_MAX: ::c_int = 16; +pub const _SC_2_VERSION: ::c_int = 17; +pub const _SC_2_C_BIND: ::c_int = 18; +pub const _SC_2_C_DEV: ::c_int = 19; +pub const _SC_2_CHAR_TERM: ::c_int = 20; +pub const _SC_2_FORT_DEV: ::c_int = 21; +pub const _SC_2_FORT_RUN: ::c_int = 22; +pub const _SC_2_LOCALEDEF: ::c_int = 23; +pub const _SC_2_SW_DEV: ::c_int = 24; +pub const _SC_2_UPE: ::c_int = 25; +pub const _SC_STREAM_MAX: ::c_int = 26; +pub const _SC_TZNAME_MAX: ::c_int = 27; +pub const _SC_ASYNCHRONOUS_IO: ::c_int = 28; +pub const _SC_PAGESIZE: ::c_int = 29; +pub const _SC_MEMLOCK: ::c_int = 30; +pub const _SC_MEMLOCK_RANGE: ::c_int = 31; +pub const _SC_MEMORY_PROTECTION: ::c_int = 32; +pub const _SC_MESSAGE_PASSING: ::c_int = 33; +pub const _SC_PRIORITIZED_IO: ::c_int = 34; +pub const _SC_PRIORITY_SCHEDULING: ::c_int = 35; +pub const _SC_REALTIME_SIGNALS: ::c_int = 36; +pub const _SC_SEMAPHORES: ::c_int = 37; +pub const _SC_FSYNC: ::c_int = 38; +pub const _SC_SHARED_MEMORY_OBJECTS: ::c_int = 39; +pub const _SC_SYNCHRONIZED_IO: ::c_int = 40; +pub const _SC_TIMERS: ::c_int = 41; +pub const _SC_AIO_LISTIO_MAX: ::c_int = 42; +pub const _SC_AIO_MAX: ::c_int = 43; +pub const _SC_AIO_PRIO_DELTA_MAX: ::c_int = 44; +pub const _SC_DELAYTIMER_MAX: ::c_int = 45; +pub const _SC_MQ_OPEN_MAX: ::c_int = 46; +pub const _SC_MAPPED_FILES: ::c_int = 47; +pub const _SC_RTSIG_MAX: ::c_int = 48; +pub const _SC_SEM_NSEMS_MAX: ::c_int = 49; +pub const _SC_SEM_VALUE_MAX: ::c_int = 50; +pub const _SC_SIGQUEUE_MAX: ::c_int = 51; +pub const _SC_TIMER_MAX: ::c_int = 52; +pub const _SC_NPROCESSORS_CONF: ::c_int = 57; +pub const _SC_NPROCESSORS_ONLN: ::c_int = 58; +pub const _SC_2_PBS: ::c_int = 59; +pub const _SC_2_PBS_ACCOUNTING: ::c_int = 60; +pub const _SC_2_PBS_CHECKPOINT: ::c_int = 61; +pub const _SC_2_PBS_LOCATE: ::c_int = 62; +pub const _SC_2_PBS_MESSAGE: ::c_int = 63; +pub const _SC_2_PBS_TRACK: ::c_int = 64; +pub const _SC_ADVISORY_INFO: ::c_int = 65; +pub const _SC_BARRIERS: ::c_int = 66; +pub const _SC_CLOCK_SELECTION: ::c_int = 67; +pub const _SC_CPUTIME: ::c_int = 68; +pub const _SC_FILE_LOCKING: ::c_int = 69; +pub const _SC_HOST_NAME_MAX: ::c_int = 72; +pub const _SC_MONOTONIC_CLOCK: ::c_int = 74; +pub const _SC_READER_WRITER_LOCKS: ::c_int = 76; +pub const _SC_REGEXP: ::c_int = 77; +pub const _SC_SHELL: ::c_int = 78; +pub const _SC_SPAWN: ::c_int = 79; +pub const _SC_SPIN_LOCKS: ::c_int = 80; +pub const _SC_SPORADIC_SERVER: ::c_int = 81; +pub const _SC_THREAD_CPUTIME: ::c_int = 84; +pub const _SC_THREAD_SPORADIC_SERVER: ::c_int = 92; +pub const _SC_TIMEOUTS: ::c_int = 95; +pub const _SC_TRACE: ::c_int = 97; +pub const _SC_TRACE_EVENT_FILTER: ::c_int = 98; +pub const _SC_TRACE_INHERIT: ::c_int = 99; +pub const _SC_TRACE_LOG: ::c_int = 100; +pub const _SC_TYPED_MEMORY_OBJECTS: ::c_int = 102; +pub const _SC_V6_ILP32_OFF32: ::c_int = 103; +pub const _SC_V6_ILP32_OFFBIG: ::c_int = 104; +pub const _SC_V6_LP64_OFF64: ::c_int = 105; +pub const _SC_V6_LPBIG_OFFBIG: ::c_int = 106; +pub const _SC_IPV6: ::c_int = 118; +pub const _SC_RAW_SOCKETS: ::c_int = 119; +pub const _SC_SYMLOOP_MAX: ::c_int = 120; +pub const _SC_PAGE_SIZE: ::c_int = _SC_PAGESIZE; +pub const _SC_XOPEN_STREAMS: ::c_int = 114; +pub const _SC_XBS5_ILP32_OFF32: ::c_int = 122; +pub const _SC_XBS5_ILP32_OFFBIG: ::c_int = 123; +pub const _SC_XBS5_LP64_OFF64: ::c_int = 124; +pub const _SC_XBS5_LPBIG_OFFBIG: ::c_int = 125; +pub const _SC_SS_REPL_MAX: ::c_int = 126; +pub const _SC_TRACE_EVENT_NAME_MAX: ::c_int = 127; +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; +pub const PTHREAD_MUTEX_RECURSIVE: ::c_int = 2; +pub const PTHREAD_MUTEX_DEFAULT: ::c_int = PTHREAD_MUTEX_NORMAL; +pub const _PTHREAD_MUTEX_SIG_init: ::c_long = 0x32AAABA7; +pub const _PTHREAD_COND_SIG_init: ::c_long = 0x3CB0B1BB; +pub const _PTHREAD_RWLOCK_SIG_init: ::c_long = 0x2DA8B3B4; +pub const PTHREAD_MUTEX_INITIALIZER: pthread_mutex_t = pthread_mutex_t { + __sig: _PTHREAD_MUTEX_SIG_init, + __opaque: [0; __PTHREAD_MUTEX_SIZE__], +}; +pub const PTHREAD_COND_INITIALIZER: pthread_cond_t = pthread_cond_t { + __sig: _PTHREAD_COND_SIG_init, + __opaque: [0; __PTHREAD_COND_SIZE__], +}; +pub const PTHREAD_RWLOCK_INITIALIZER: pthread_rwlock_t = pthread_rwlock_t { + __sig: _PTHREAD_RWLOCK_SIG_init, + __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; + +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; +pub const EVFILT_VNODE: i16 = -4; +pub const EVFILT_PROC: i16 = -5; +pub const EVFILT_SIGNAL: i16 = -6; +pub const EVFILT_TIMER: i16 = -7; +pub const EVFILT_MACHPORT: i16 = -8; +pub const EVFILT_FS: i16 = -9; +pub const EVFILT_USER: i16 = -10; +pub const EVFILT_VM: i16 = -12; + +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_ONESHOT: u16 = 0x10; +pub const EV_CLEAR: u16 = 0x20; +pub const EV_RECEIPT: u16 = 0x40; +pub const EV_DISPATCH: u16 = 0x80; +pub const EV_FLAG0: u16 = 0x1000; +pub const EV_POLL: u16 = 0x1000; +pub const EV_FLAG1: u16 = 0x2000; +pub const EV_OOBAND: u16 = 0x2000; +pub const EV_ERROR: u16 = 0x4000; +pub const EV_EOF: u16 = 0x8000; +pub const EV_SYSFLAGS: u16 = 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; +pub const NOTE_EXTEND: u32 = 0x00000004; +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_NONE: u32 = 0x00000080; +pub const NOTE_EXIT: u32 = 0x80000000; +pub const NOTE_FORK: u32 = 0x40000000; +pub const NOTE_EXEC: u32 = 0x20000000; +#[doc(hidden)] +#[deprecated(since = "0.2.49", note = "Deprecated since MacOSX 10.9")] +pub const NOTE_REAP: u32 = 0x10000000; +pub const NOTE_SIGNAL: u32 = 0x08000000; +pub const NOTE_EXITSTATUS: u32 = 0x04000000; +pub const NOTE_EXIT_DETAIL: u32 = 0x02000000; +pub const NOTE_PDATAMASK: u32 = 0x000fffff; +pub const NOTE_PCTRLMASK: u32 = 0xfff00000; +#[doc(hidden)] +#[deprecated(since = "0.2.49", note = "Deprecated since MacOSX 10.9")] +pub const NOTE_EXIT_REPARENTED: u32 = 0x00080000; +pub const NOTE_EXIT_DETAIL_MASK: u32 = 0x00070000; +pub const NOTE_EXIT_DECRYPTFAIL: u32 = 0x00010000; +pub const NOTE_EXIT_MEMORY: u32 = 0x00020000; +pub const NOTE_EXIT_CSERROR: u32 = 0x00040000; +pub const NOTE_VM_PRESSURE: u32 = 0x80000000; +pub const NOTE_VM_PRESSURE_TERMINATE: u32 = 0x40000000; +pub const NOTE_VM_PRESSURE_SUDDEN_TERMINATE: u32 = 0x20000000; +pub const NOTE_VM_ERROR: u32 = 0x10000000; +pub const NOTE_SECONDS: u32 = 0x00000001; +pub const NOTE_USECONDS: u32 = 0x00000002; +pub const NOTE_NSECONDS: u32 = 0x00000004; +pub const NOTE_ABSOLUTE: u32 = 0x00000008; +pub const NOTE_LEEWAY: u32 = 0x00000010; +pub const NOTE_CRITICAL: u32 = 0x00000020; +pub const NOTE_BACKGROUND: u32 = 0x00000040; +pub const NOTE_MACH_CONTINUOUS_TIME: u32 = 0x00000080; +pub const NOTE_MACHTIME: u32 = 0x00000100; +pub const NOTE_TRACK: u32 = 0x00000001; +pub const NOTE_TRACKERR: u32 = 0x00000002; +pub const NOTE_CHILD: u32 = 0x00000004; + +pub const OCRNL: ::tcflag_t = 0x00000010; +pub const ONOCR: ::tcflag_t = 0x00000020; +pub const ONLRET: ::tcflag_t = 0x00000040; +pub const OFILL: ::tcflag_t = 0x00000080; +pub const NLDLY: ::tcflag_t = 0x00000300; +pub const TABDLY: ::tcflag_t = 0x00000c04; +pub const CRDLY: ::tcflag_t = 0x00003000; +pub const FFDLY: ::tcflag_t = 0x00004000; +pub const BSDLY: ::tcflag_t = 0x00008000; +pub const VTDLY: ::tcflag_t = 0x00010000; +pub const OFDEL: ::tcflag_t = 0x00020000; + +pub const NL0: ::tcflag_t = 0x00000000; +pub const NL1: ::tcflag_t = 0x00000100; +pub const TAB0: ::tcflag_t = 0x00000000; +pub const TAB1: ::tcflag_t = 0x00000400; +pub const TAB2: ::tcflag_t = 0x00000800; +pub const CR0: ::tcflag_t = 0x00000000; +pub const CR1: ::tcflag_t = 0x00001000; +pub const CR2: ::tcflag_t = 0x00002000; +pub const CR3: ::tcflag_t = 0x00003000; +pub const FF0: ::tcflag_t = 0x00000000; +pub const FF1: ::tcflag_t = 0x00004000; +pub const BS0: ::tcflag_t = 0x00000000; +pub const BS1: ::tcflag_t = 0x00008000; +pub const TAB3: ::tcflag_t = 0x00000004; +pub const VT0: ::tcflag_t = 0x00000000; +pub const VT1: ::tcflag_t = 0x00010000; +pub const IUTF8: ::tcflag_t = 0x00004000; +pub const CRTSCTS: ::tcflag_t = 0x00030000; + +pub const NI_MAXHOST: ::socklen_t = 1025; +pub const NI_MAXSERV: ::socklen_t = 32; +pub const NI_NOFQDN: ::c_int = 0x00000001; +pub const NI_NUMERICHOST: ::c_int = 0x00000002; +pub const NI_NAMEREQD: ::c_int = 0x00000004; +pub const NI_NUMERICSERV: ::c_int = 0x00000008; +pub const NI_NUMERICSCOPE: ::c_int = 0x00000100; +pub const NI_DGRAM: ::c_int = 0x00000010; + +pub const Q_GETQUOTA: ::c_int = 0x300; +pub const Q_SETQUOTA: ::c_int = 0x400; + +pub const RENAME_SWAP: ::c_uint = 0x00000002; +pub const RENAME_EXCL: ::c_uint = 0x00000004; + +pub const RTLD_LOCAL: ::c_int = 0x4; +pub const RTLD_FIRST: ::c_int = 0x100; +pub const RTLD_NODELETE: ::c_int = 0x80; +pub const RTLD_NOLOAD: ::c_int = 0x10; +pub const RTLD_GLOBAL: ::c_int = 0x8; +pub const RTLD_MAIN_ONLY: *mut ::c_void = -5isize as *mut ::c_void; + +pub const _WSTOPPED: ::c_int = 0o177; + +pub const LOG_NETINFO: ::c_int = 12 << 3; +pub const LOG_REMOTEAUTH: ::c_int = 13 << 3; +pub const LOG_INSTALL: ::c_int = 14 << 3; +pub const LOG_RAS: ::c_int = 15 << 3; +pub const LOG_LAUNCHD: ::c_int = 24 << 3; +pub const LOG_NFACILITIES: ::c_int = 25; + +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_QUAD: ::c_int = 4; +pub const CTLTYPE_OPAQUE: ::c_int = 5; +pub const CTLTYPE_STRUCT: ::c_int = CTLTYPE_OPAQUE; +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_NOLOCK: ::c_int = 0x20000000; +pub const CTLFLAG_ANYBODY: ::c_int = 0x10000000; +pub const CTLFLAG_SECURE: ::c_int = 0x08000000; +pub const CTLFLAG_MASKED: ::c_int = 0x04000000; +pub const CTLFLAG_NOAUTO: ::c_int = 0x02000000; +pub const CTLFLAG_KERN: ::c_int = 0x01000000; +pub const CTLFLAG_LOCKED: ::c_int = 0x00800000; +pub const CTLFLAG_OID2: ::c_int = 0x00400000; +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_MAXID: ::c_int = 9; +pub const KERN_OSTYPE: ::c_int = 1; +pub const KERN_OSRELEASE: ::c_int = 2; +pub const KERN_OSREV: ::c_int = 3; +pub const KERN_VERSION: ::c_int = 4; +pub const KERN_MAXVNODES: ::c_int = 5; +pub const KERN_MAXPROC: ::c_int = 6; +pub const KERN_MAXFILES: ::c_int = 7; +pub const KERN_ARGMAX: ::c_int = 8; +pub const KERN_SECURELVL: ::c_int = 9; +pub const KERN_HOSTNAME: ::c_int = 10; +pub const KERN_HOSTID: ::c_int = 11; +pub const KERN_CLOCKRATE: ::c_int = 12; +pub const KERN_VNODE: ::c_int = 13; +pub const KERN_PROC: ::c_int = 14; +pub const KERN_FILE: ::c_int = 15; +pub const KERN_PROF: ::c_int = 16; +pub const KERN_POSIX1: ::c_int = 17; +pub const KERN_NGROUPS: ::c_int = 18; +pub const KERN_JOB_CONTROL: ::c_int = 19; +pub const KERN_SAVED_IDS: ::c_int = 20; +pub const KERN_BOOTTIME: ::c_int = 21; +pub const KERN_NISDOMAINNAME: ::c_int = 22; +pub const KERN_DOMAINNAME: ::c_int = KERN_NISDOMAINNAME; +pub const KERN_MAXPARTITIONS: ::c_int = 23; +pub const KERN_KDEBUG: ::c_int = 24; +pub const KERN_UPDATEINTERVAL: ::c_int = 25; +pub const KERN_OSRELDATE: ::c_int = 26; +pub const KERN_NTP_PLL: ::c_int = 27; +pub const KERN_BOOTFILE: ::c_int = 28; +pub const KERN_MAXFILESPERPROC: ::c_int = 29; +pub const KERN_MAXPROCPERUID: ::c_int = 30; +pub const KERN_DUMPDEV: ::c_int = 31; +pub const KERN_IPC: ::c_int = 32; +pub const KERN_DUMMY: ::c_int = 33; +pub const KERN_PS_STRINGS: ::c_int = 34; +pub const KERN_USRSTACK32: ::c_int = 35; +pub const KERN_LOGSIGEXIT: ::c_int = 36; +pub const KERN_SYMFILE: ::c_int = 37; +pub const KERN_PROCARGS: ::c_int = 38; +pub const KERN_NETBOOT: ::c_int = 40; +pub const KERN_SYSV: ::c_int = 42; +pub const KERN_AFFINITY: ::c_int = 43; +pub const KERN_TRANSLATE: ::c_int = 44; +pub const KERN_CLASSIC: ::c_int = KERN_TRANSLATE; +pub const KERN_EXEC: ::c_int = 45; +pub const KERN_CLASSICHANDLER: ::c_int = KERN_EXEC; +pub const KERN_AIOMAX: ::c_int = 46; +pub const KERN_AIOPROCMAX: ::c_int = 47; +pub const KERN_AIOTHREADS: ::c_int = 48; +pub const KERN_COREFILE: ::c_int = 50; +pub const KERN_COREDUMP: ::c_int = 51; +pub const KERN_SUGID_COREDUMP: ::c_int = 52; +pub const KERN_PROCDELAYTERM: ::c_int = 53; +pub const KERN_SHREG_PRIVATIZABLE: ::c_int = 54; +pub const KERN_LOW_PRI_WINDOW: ::c_int = 56; +pub const KERN_LOW_PRI_DELAY: ::c_int = 57; +pub const KERN_POSIX: ::c_int = 58; +pub const KERN_USRSTACK64: ::c_int = 59; +pub const KERN_NX_PROTECTION: ::c_int = 60; +pub const KERN_TFP: ::c_int = 61; +pub const KERN_PROCNAME: ::c_int = 62; +pub const KERN_THALTSTACK: ::c_int = 63; +pub const KERN_SPECULATIVE_READS: ::c_int = 64; +pub const KERN_OSVERSION: ::c_int = 65; +pub const KERN_SAFEBOOT: ::c_int = 66; +pub const KERN_RAGEVNODE: ::c_int = 68; +pub const KERN_TTY: ::c_int = 69; +pub const KERN_CHECKOPENEVT: ::c_int = 70; +pub const KERN_THREADNAME: ::c_int = 71; +pub const KERN_MAXID: ::c_int = 72; +pub const KERN_RAGE_PROC: ::c_int = 1; +pub const KERN_RAGE_THREAD: ::c_int = 2; +pub const KERN_UNRAGE_PROC: ::c_int = 3; +pub const KERN_UNRAGE_THREAD: ::c_int = 4; +pub const KERN_OPENEVT_PROC: ::c_int = 1; +pub const KERN_UNOPENEVT_PROC: ::c_int = 2; +pub const KERN_TFP_POLICY: ::c_int = 1; +pub const KERN_TFP_POLICY_DENY: ::c_int = 0; +pub const KERN_TFP_POLICY_DEFAULT: ::c_int = 2; +pub const KERN_KDEFLAGS: ::c_int = 1; +pub const KERN_KDDFLAGS: ::c_int = 2; +pub const KERN_KDENABLE: ::c_int = 3; +pub const KERN_KDSETBUF: ::c_int = 4; +pub const KERN_KDGETBUF: ::c_int = 5; +pub const KERN_KDSETUP: ::c_int = 6; +pub const KERN_KDREMOVE: ::c_int = 7; +pub const KERN_KDSETREG: ::c_int = 8; +pub const KERN_KDGETREG: ::c_int = 9; +pub const KERN_KDREADTR: ::c_int = 10; +pub const KERN_KDPIDTR: ::c_int = 11; +pub const KERN_KDTHRMAP: ::c_int = 12; +pub const KERN_KDPIDEX: ::c_int = 14; +pub const KERN_KDSETRTCDEC: ::c_int = 15; +pub const KERN_KDGETENTROPY: ::c_int = 16; +pub const KERN_KDWRITETR: ::c_int = 17; +pub const KERN_KDWRITEMAP: ::c_int = 18; +#[doc(hidden)] +#[deprecated(since = "0.2.49", note = "Removed in MacOSX 10.12")] +pub const KERN_KDENABLE_BG_TRACE: ::c_int = 19; +#[doc(hidden)] +#[deprecated(since = "0.2.49", note = "Removed in MacOSX 10.12")] +pub const KERN_KDDISABLE_BG_TRACE: ::c_int = 20; +pub const KERN_KDREADCURTHRMAP: ::c_int = 21; +pub const KERN_KDSET_TYPEFILTER: ::c_int = 22; +pub const KERN_KDBUFWAIT: ::c_int = 23; +pub const KERN_KDCPUMAP: ::c_int = 24; +pub const KERN_PROC_ALL: ::c_int = 0; +pub const KERN_PROC_PID: ::c_int = 1; +pub const KERN_PROC_PGRP: ::c_int = 2; +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_PROC_RUID: ::c_int = 6; +pub const KERN_PROC_LCID: ::c_int = 7; +pub const KERN_SUCCESS: ::c_int = 0; +pub const KERN_INVALID_ADDRESS: ::c_int = 1; +pub const KERN_PROTECTION_FAILURE: ::c_int = 2; +pub const KERN_NO_SPACE: ::c_int = 3; +pub const KERN_INVALID_ARGUMENT: ::c_int = 4; +pub const KERN_FAILURE: ::c_int = 5; +pub const KERN_RESOURCE_SHORTAGE: ::c_int = 6; +pub const KERN_NOT_RECEIVER: ::c_int = 7; +pub const KERN_NO_ACCESS: ::c_int = 8; +pub const KERN_MEMORY_FAILURE: ::c_int = 9; +pub const KERN_MEMORY_ERROR: ::c_int = 10; +pub const KERN_ALREADY_IN_SET: ::c_int = 11; +pub const KERN_NOT_IN_SET: ::c_int = 12; +pub const KERN_NAME_EXISTS: ::c_int = 13; +pub const KERN_ABORTED: ::c_int = 14; +pub const KERN_INVALID_NAME: ::c_int = 15; +pub const KERN_INVALID_TASK: ::c_int = 16; +pub const KERN_INVALID_RIGHT: ::c_int = 17; +pub const KERN_INVALID_VALUE: ::c_int = 18; +pub const KERN_UREFS_OVERFLOW: ::c_int = 19; +pub const KERN_INVALID_CAPABILITY: ::c_int = 20; +pub const KERN_RIGHT_EXISTS: ::c_int = 21; +pub const KERN_INVALID_HOST: ::c_int = 22; +pub const KERN_MEMORY_PRESENT: ::c_int = 23; +pub const KERN_MEMORY_DATA_MOVED: ::c_int = 24; +pub const KERN_MEMORY_RESTART_COPY: ::c_int = 25; +pub const KERN_INVALID_PROCESSOR_SET: ::c_int = 26; +pub const KERN_POLICY_LIMIT: ::c_int = 27; +pub const KERN_INVALID_POLICY: ::c_int = 28; +pub const KERN_INVALID_OBJECT: ::c_int = 29; +pub const KERN_ALREADY_WAITING: ::c_int = 30; +pub const KERN_DEFAULT_SET: ::c_int = 31; +pub const KERN_EXCEPTION_PROTECTED: ::c_int = 32; +pub const KERN_INVALID_LEDGER: ::c_int = 33; +pub const KERN_INVALID_MEMORY_CONTROL: ::c_int = 34; +pub const KERN_INVALID_SECURITY: ::c_int = 35; +pub const KERN_NOT_DEPRESSED: ::c_int = 36; +pub const KERN_TERMINATED: ::c_int = 37; +pub const KERN_LOCK_SET_DESTROYED: ::c_int = 38; +pub const KERN_LOCK_UNSTABLE: ::c_int = 39; +pub const KERN_LOCK_OWNED: ::c_int = 40; +pub const KERN_LOCK_OWNED_SELF: ::c_int = 41; +pub const KERN_SEMAPHORE_DESTROYED: ::c_int = 42; +pub const KERN_RPC_SERVER_TERMINATED: ::c_int = 43; +pub const KERN_RPC_TERMINATE_ORPHAN: ::c_int = 44; +pub const KERN_RPC_CONTINUE_ORPHAN: ::c_int = 45; +pub const KERN_NOT_SUPPORTED: ::c_int = 46; +pub const KERN_NODE_DOWN: ::c_int = 47; +pub const KERN_NOT_WAITING: ::c_int = 48; +pub const KERN_OPERATION_TIMED_OUT: ::c_int = 49; +pub const KERN_CODESIGN_ERROR: ::c_int = 50; +pub const KERN_POLICY_STATIC: ::c_int = 51; +pub const KERN_INSUFFICIENT_BUFFER_SIZE: ::c_int = 52; +pub const KIPC_MAXSOCKBUF: ::c_int = 1; +pub const KIPC_SOCKBUF_WASTE: ::c_int = 2; +pub const KIPC_SOMAXCONN: ::c_int = 3; +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 KIPC_MBSTAT: ::c_int = 8; +pub const KIPC_NMBCLUSTERS: ::c_int = 9; +pub const KIPC_SOQLIMITCOMPAT: ::c_int = 10; +pub const VM_METER: ::c_int = 1; +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; +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_DISKSTATS: ::c_int = 9; +pub const HW_EPOCH: ::c_int = 10; +pub const HW_FLOATINGPT: ::c_int = 11; +pub const HW_MACHINE_ARCH: ::c_int = 12; +pub const HW_VECTORUNIT: ::c_int = 13; +pub const HW_BUS_FREQ: ::c_int = 14; +pub const HW_CPU_FREQ: ::c_int = 15; +pub const HW_CACHELINE: ::c_int = 16; +pub const HW_L1ICACHESIZE: ::c_int = 17; +pub const HW_L1DCACHESIZE: ::c_int = 18; +pub const HW_L2SETTINGS: ::c_int = 19; +pub const HW_L2CACHESIZE: ::c_int = 20; +pub const HW_L3SETTINGS: ::c_int = 21; +pub const HW_L3CACHESIZE: ::c_int = 22; +pub const HW_TB_FREQ: ::c_int = 23; +pub const HW_MEMSIZE: ::c_int = 24; +pub const HW_AVAILCPU: ::c_int = 25; +pub const HW_TARGET: ::c_int = 26; +pub const HW_PRODUCT: ::c_int = 27; +pub const HW_MAXID: ::c_int = 28; +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_MAXID: ::c_int = 21; +pub const CTL_DEBUG_NAME: ::c_int = 0; +pub const CTL_DEBUG_VALUE: ::c_int = 1; +pub const CTL_DEBUG_MAXID: ::c_int = 20; + +pub const PRIO_DARWIN_THREAD: ::c_int = 3; +pub const PRIO_DARWIN_PROCESS: ::c_int = 4; +pub const PRIO_DARWIN_BG: ::c_int = 0x1000; +pub const PRIO_DARWIN_NONUI: ::c_int = 0x1001; + +pub const SEM_FAILED: *mut sem_t = -1isize 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 = 0x00001000; +pub const AI_MASK: ::c_int = + AI_PASSIVE | AI_CANONNAME | AI_NUMERICHOST | AI_NUMERICSERV | AI_ADDRCONFIG; +pub const AI_ALL: ::c_int = 0x00000100; +pub const AI_V4MAPPED_CFG: ::c_int = 0x00000200; +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; +pub const AI_UNUSABLE: ::c_int = 0x10000000; + +pub const SIGEV_NONE: ::c_int = 0; +pub const SIGEV_SIGNAL: ::c_int = 1; +pub const SIGEV_THREAD: ::c_int = 3; + +pub const AIO_CANCELED: ::c_int = 2; +pub const AIO_NOTCANCELED: ::c_int = 4; +pub const AIO_ALLDONE: ::c_int = 1; +#[deprecated( + since = "0.2.64", + note = "Can vary at runtime. Use sysconf(3) instead" +)] +pub const AIO_LISTIO_MAX: ::c_int = 16; +pub const LIO_NOP: ::c_int = 0; +pub const LIO_WRITE: ::c_int = 2; +pub const LIO_READ: ::c_int = 1; +pub const LIO_WAIT: ::c_int = 2; +pub const LIO_NOWAIT: ::c_int = 1; + +pub const WEXITED: ::c_int = 0x00000004; +pub const WSTOPPED: ::c_int = 0x00000008; +pub const WCONTINUED: ::c_int = 0x00000010; +pub const WNOWAIT: ::c_int = 0x00000020; + +pub const P_ALL: idtype_t = 0; +pub const P_PID: idtype_t = 1; +pub const P_PGID: idtype_t = 2; + +pub const UTIME_OMIT: c_long = -2; +pub const UTIME_NOW: c_long = -1; + +pub const XATTR_NOFOLLOW: ::c_int = 0x0001; +pub const XATTR_CREATE: ::c_int = 0x0002; +pub const XATTR_REPLACE: ::c_int = 0x0004; +pub const XATTR_NOSECURITY: ::c_int = 0x0008; +pub const XATTR_NODEFAULT: ::c_int = 0x0010; +pub const XATTR_SHOWCOMPRESSION: ::c_int = 0x0020; + +pub const NET_RT_IFLIST2: ::c_int = 0x0006; + +// net/route.h +pub const RTF_DELCLONE: ::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_NOIFREF: ::c_int = 0x2000; +pub const RTF_PRCLONING: ::c_int = 0x10000; +pub const RTF_WASCLONED: ::c_int = 0x20000; +pub const RTF_PROTO3: ::c_int = 0x40000; +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_IFSCOPE: ::c_int = 0x1000000; +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; + +// Message types +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_NEWMADDR: ::c_int = 0xf; +pub const RTM_DELMADDR: ::c_int = 0x10; +pub const RTM_IFINFO2: ::c_int = 0x12; +pub const RTM_NEWMADDR2: ::c_int = 0x13; +pub const RTM_GET2: ::c_int = 0x14; + +// Bitmask values for rtm_inits and rmx_locks. +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 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; + +pub const XUCRED_VERSION: ::c_uint = 0; + +pub const LC_SEGMENT: u32 = 0x1; +pub const LC_SEGMENT_64: u32 = 0x19; + +pub const MH_MAGIC: u32 = 0xfeedface; +pub const MH_MAGIC_64: u32 = 0xfeedfacf; + +// net/if_utun.h +pub const UTUN_OPT_FLAGS: ::c_int = 1; +pub const UTUN_OPT_IFNAME: ::c_int = 2; + +// net/bpf.h +pub const DLT_NULL: ::c_uint = 0; // no link-layer encapsulation +pub const DLT_EN10MB: ::c_uint = 1; // Ethernet (10Mb) +pub const DLT_EN3MB: ::c_uint = 2; // Experimental Ethernet (3Mb) +pub const DLT_AX25: ::c_uint = 3; // Amateur Radio AX.25 +pub const DLT_PRONET: ::c_uint = 4; // Proteon ProNET Token Ring +pub const DLT_CHAOS: ::c_uint = 5; // Chaos +pub const DLT_IEEE802: ::c_uint = 6; // IEEE 802 Networks +pub const DLT_ARCNET: ::c_uint = 7; // ARCNET +pub const DLT_SLIP: ::c_uint = 8; // Serial Line IP +pub const DLT_PPP: ::c_uint = 9; // Point-to-point Protocol +pub const DLT_FDDI: ::c_uint = 10; // FDDI +pub const DLT_ATM_RFC1483: ::c_uint = 11; // LLC/SNAP encapsulated atm +pub const DLT_RAW: ::c_uint = 12; // raw IP +pub const DLT_LOOP: ::c_uint = 108; + +// https://github.com/apple/darwin-xnu/blob/HEAD/bsd/net/bpf.h#L100 +// sizeof(i32) +pub const BPF_ALIGNMENT: ::c_int = 4; + +// sys/mount.h +pub const MNT_NODEV: ::c_int = 0x00000010; +pub const MNT_UNION: ::c_int = 0x00000020; +pub const MNT_CPROTECT: ::c_int = 0x00000080; + +// MAC labeled / "quarantined" flag +pub const MNT_QUARANTINE: ::c_int = 0x00000400; + +// Flags set by internal operations. +pub const MNT_LOCAL: ::c_int = 0x00001000; +pub const MNT_QUOTA: ::c_int = 0x00002000; +pub const MNT_ROOTFS: ::c_int = 0x00004000; +pub const MNT_DOVOLFS: ::c_int = 0x00008000; + +pub const MNT_DONTBROWSE: ::c_int = 0x00100000; +pub const MNT_IGNORE_OWNERSHIP: ::c_int = 0x00200000; +pub const MNT_AUTOMOUNTED: ::c_int = 0x00400000; +pub const MNT_JOURNALED: ::c_int = 0x00800000; +pub const MNT_NOUSERXATTR: ::c_int = 0x01000000; +pub const MNT_DEFWRITE: ::c_int = 0x02000000; +pub const MNT_MULTILABEL: ::c_int = 0x04000000; +pub const MNT_NOATIME: ::c_int = 0x10000000; +pub const MNT_SNAPSHOT: ::c_int = 0x40000000; + +// External filesystem command modifier flags. +pub const MNT_NOBLOCK: ::c_int = 0x00020000; + +// sys/spawn.h: +pub const POSIX_SPAWN_RESETIDS: ::c_int = 0x0001; +pub const POSIX_SPAWN_SETPGROUP: ::c_int = 0x0002; +pub const POSIX_SPAWN_SETSIGDEF: ::c_int = 0x0004; +pub const POSIX_SPAWN_SETSIGMASK: ::c_int = 0x0008; +pub const POSIX_SPAWN_SETEXEC: ::c_int = 0x0040; +pub const POSIX_SPAWN_START_SUSPENDED: ::c_int = 0x0080; +pub const POSIX_SPAWN_CLOEXEC_DEFAULT: ::c_int = 0x4000; + +// sys/ipc.h: +pub const IPC_CREAT: ::c_int = 0x200; +pub const IPC_EXCL: ::c_int = 0x400; +pub const IPC_NOWAIT: ::c_int = 0x800; +pub const IPC_PRIVATE: key_t = 0; + +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 = 0x100; +pub const IPC_W: ::c_int = 0x80; +pub const IPC_M: ::c_int = 0x1000; + +// 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 SHM_RDONLY: ::c_int = 0x1000; +pub const SHM_RND: ::c_int = 0x2000; +#[cfg(target_arch = "aarch64")] +pub const SHMLBA: ::c_int = 16 * 1024; +#[cfg(not(target_arch = "aarch64"))] +pub const SHMLBA: ::c_int = 4096; +pub const SHM_R: ::c_int = IPC_R; +pub const SHM_W: ::c_int = IPC_W; + +// 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 UF_COMPRESSED: ::c_uint = 0x00000020; +pub const UF_TRACKED: ::c_uint = 0x00000040; +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; +pub const UF_HIDDEN: ::c_uint = 0x00008000; + +// +pub const NTP_API: ::c_int = 4; +pub const MAXPHASE: ::c_long = 500000000; +pub const MAXFREQ: ::c_long = 500000; +pub const MINSEC: ::c_int = 256; +pub const MAXSEC: ::c_int = 2048; +pub const NANOSECOND: ::c_long = 1000000000; +pub const SCALE_PPM: ::c_int = 65; +pub const MAXTC: ::c_int = 10; +pub const MOD_OFFSET: ::c_uint = 0x0001; +pub const MOD_FREQUENCY: ::c_uint = 0x0002; +pub const MOD_MAXERROR: ::c_uint = 0x0004; +pub const MOD_ESTERROR: ::c_uint = 0x0008; +pub const MOD_STATUS: ::c_uint = 0x0010; +pub const MOD_TIMECONST: ::c_uint = 0x0020; +pub const MOD_PPSMAX: ::c_uint = 0x0040; +pub const MOD_TAI: ::c_uint = 0x0080; +pub const MOD_MICRO: ::c_uint = 0x1000; +pub const MOD_NANO: ::c_uint = 0x2000; +pub const MOD_CLKB: ::c_uint = 0x4000; +pub const MOD_CLKA: ::c_uint = 0x8000; +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 MNT_WAIT: ::c_int = 1; +pub const MNT_NOWAIT: ::c_int = 2; + +// +pub const THREAD_STANDARD_POLICY: ::c_int = 1; +pub const THREAD_STANDARD_POLICY_COUNT: ::c_int = 0; +pub const THREAD_EXTENDED_POLICY: ::c_int = 1; +pub const THREAD_TIME_CONSTRAINT_POLICY: ::c_int = 2; +pub const THREAD_PRECEDENCE_POLICY: ::c_int = 3; +pub const THREAD_AFFINITY_POLICY: ::c_int = 4; +pub const THREAD_AFFINITY_TAG_NULL: ::c_int = 0; +pub const THREAD_BACKGROUND_POLICY: ::c_int = 5; +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 COPYFILE_STATE_SRC_FD: ::c_int = 1; +pub const COPYFILE_STATE_SRC_FILENAME: ::c_int = 2; +pub const COPYFILE_STATE_DST_FD: ::c_int = 3; +pub const COPYFILE_STATE_DST_FILENAME: ::c_int = 4; +pub const COPYFILE_STATE_QUARANTINE: ::c_int = 5; +pub const COPYFILE_STATE_STATUS_CB: ::c_int = 6; +pub const COPYFILE_STATE_STATUS_CTX: ::c_int = 7; +pub const COPYFILE_STATE_COPIED: ::c_int = 8; +pub const COPYFILE_STATE_XATTRNAME: ::c_int = 9; +pub const COPYFILE_STATE_WAS_CLONED: ::c_int = 10; +pub const COPYFILE_STATE_SRC_BSIZE: ::c_int = 11; +pub const COPYFILE_STATE_DST_BSIZE: ::c_int = 12; +pub const COPYFILE_STATE_BSIZE: ::c_int = 13; + +// +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; + +// os/clock.h +pub const OS_CLOCK_MACH_ABSOLUTE_TIME: os_clockid_t = 32; + +// os/os_sync_wait_on_address.h +pub const OS_SYNC_WAIT_ON_ADDRESS_NONE: os_sync_wait_on_address_flags_t = 0x00000000; +pub const OS_SYNC_WAIT_ON_ADDRESS_SHARED: os_sync_wait_on_address_flags_t = 0x00000001; +pub const OS_SYNC_WAKE_BY_ADDRESS_NONE: os_sync_wake_by_address_flags_t = 0x00000000; +pub const OS_SYNC_WAKE_BY_ADDRESS_SHARED: os_sync_wake_by_address_flags_t = 0x00000001; + +// +/// Process being created by fork. +pub const SIDL: u32 = 1; +/// Currently runnable. +pub const SRUN: u32 = 2; +/// Sleeping on an address. +pub const SSLEEP: u32 = 3; +/// Process debugging or suspension. +pub const SSTOP: u32 = 4; +/// Awaiting collection by parent. +pub const SZOMB: u32 = 5; + +// sys/vsock.h +pub const VMADDR_CID_ANY: ::c_uint = 0xFFFFFFFF; +pub const VMADDR_CID_HYPERVISOR: ::c_uint = 0; +pub const VMADDR_CID_RESERVED: ::c_uint = 1; +pub const VMADDR_CID_HOST: ::c_uint = 2; +pub const VMADDR_PORT_ANY: ::c_uint = 0xFFFFFFFF; + +cfg_if! { + if #[cfg(libc_const_extern_fn)] { + const fn __DARWIN_ALIGN32(p: usize) -> usize { + const __DARWIN_ALIGNBYTES32: usize = ::mem::size_of::() - 1; + p + __DARWIN_ALIGNBYTES32 & !__DARWIN_ALIGNBYTES32 + } + } else if #[cfg(libc_const_size_of)] { + fn __DARWIN_ALIGN32(p: usize) -> usize { + 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; + pub const THREAD_TIME_CONSTRAINT_POLICY_COUNT: mach_msg_type_number_t = + (::mem::size_of::() / + ::mem::size_of::()) as mach_msg_type_number_t; + pub const THREAD_PRECEDENCE_POLICY_COUNT: mach_msg_type_number_t = + (::mem::size_of::() / ::mem::size_of::()) + as mach_msg_type_number_t; + pub const THREAD_AFFINITY_POLICY_COUNT: mach_msg_type_number_t = + (::mem::size_of::() / ::mem::size_of::()) + as mach_msg_type_number_t; + pub const THREAD_BACKGROUND_POLICY_COUNT: mach_msg_type_number_t = + (::mem::size_of::() / ::mem::size_of::()) + as mach_msg_type_number_t; + pub const THREAD_LATENCY_QOS_POLICY_COUNT: mach_msg_type_number_t = + (::mem::size_of::() / ::mem::size_of::()) + as mach_msg_type_number_t; + 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 { + 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; + pub const THREAD_AFFINITY_POLICY_COUNT: mach_msg_type_number_t = 1; + 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; + } +} + +f! { + pub fn CMSG_NXTHDR(mhdr: *const ::msghdr, + cmsg: *const ::cmsghdr) -> *mut ::cmsghdr { + if cmsg.is_null() { + return ::CMSG_FIRSTHDR(mhdr); + }; + let cmsg_len = (*cmsg).cmsg_len as usize; + let next = cmsg as usize + __DARWIN_ALIGN32(cmsg_len as usize); + let max = (*mhdr).msg_control as usize + + (*mhdr).msg_controllen as usize; + if next + __DARWIN_ALIGN32(::mem::size_of::<::cmsghdr>()) > max { + 0 as *mut ::cmsghdr + } else { + next as *mut ::cmsghdr + } + } + + pub fn CMSG_DATA(cmsg: *const ::cmsghdr) -> *mut ::c_uchar { + (cmsg as *mut ::c_uchar) + .offset(__DARWIN_ALIGN32(::mem::size_of::<::cmsghdr>()) as isize) + } + + pub {const} fn CMSG_SPACE(length: ::c_uint) -> ::c_uint { + (__DARWIN_ALIGN32(::mem::size_of::<::cmsghdr>()) + + __DARWIN_ALIGN32(length as usize)) + as ::c_uint + } + + pub {const} fn CMSG_LEN(length: ::c_uint) -> ::c_uint { + (__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! { + pub {const} fn WSTOPSIG(status: ::c_int) -> ::c_int { + status >> 8 + } + + pub {const} fn _WSTATUS(status: ::c_int) -> ::c_int { + status & 0x7f + } + + pub {const} fn WIFCONTINUED(status: ::c_int) -> bool { + _WSTATUS(status) == _WSTOPPED && WSTOPSIG(status) == 0x13 + } + + pub {const} fn WIFSIGNALED(status: ::c_int) -> bool { + _WSTATUS(status) != _WSTOPPED && _WSTATUS(status) != 0 + } + + pub {const} fn WIFSTOPPED(status: ::c_int) -> bool { + _WSTATUS(status) == _WSTOPPED && WSTOPSIG(status) != 0x13 + } +} + +extern "C" { + pub fn setgrent(); + #[doc(hidden)] + #[deprecated(since = "0.2.49", note = "Deprecated in MacOSX 10.5")] + #[cfg_attr(not(target_arch = "aarch64"), link_name = "daemon$1050")] + pub fn daemon(nochdir: ::c_int, noclose: ::c_int) -> ::c_int; + #[doc(hidden)] + #[deprecated(since = "0.2.49", note = "Deprecated in MacOSX 10.10")] + pub fn sem_destroy(sem: *mut sem_t) -> ::c_int; + #[doc(hidden)] + #[deprecated(since = "0.2.49", note = "Deprecated in MacOSX 10.10")] + pub fn sem_init(sem: *mut sem_t, pshared: ::c_int, value: ::c_uint) -> ::c_int; + pub fn aio_read(aiocbp: *mut aiocb) -> ::c_int; + pub fn aio_write(aiocbp: *mut aiocb) -> ::c_int; + pub fn aio_fsync(op: ::c_int, aiocbp: *mut aiocb) -> ::c_int; + pub fn aio_error(aiocbp: *const aiocb) -> ::c_int; + pub fn aio_return(aiocbp: *mut aiocb) -> ::ssize_t; + #[cfg_attr( + all(target_os = "macos", target_arch = "x86"), + link_name = "aio_suspend$UNIX2003" + )] + pub fn aio_suspend( + aiocb_list: *const *const aiocb, + nitems: ::c_int, + timeout: *const ::timespec, + ) -> ::c_int; + pub fn aio_cancel(fd: ::c_int, aiocbp: *mut aiocb) -> ::c_int; + pub fn chflags(path: *const ::c_char, flags: ::c_uint) -> ::c_int; + 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, + nitems: ::c_int, + sevp: *mut sigevent, + ) -> ::c_int; + + pub fn dirfd(dirp: *mut ::DIR) -> ::c_int; + + pub fn lutimes(file: *const ::c_char, times: *const ::timeval) -> ::c_int; + + pub fn gettimeofday(tp: *mut ::timeval, tz: *mut ::c_void) -> ::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 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 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, + host: *mut ::c_char, + hostlen: ::socklen_t, + serv: *mut ::c_char, + servlen: ::socklen_t, + flags: ::c_int, + ) -> ::c_int; + pub fn mincore(addr: *const ::c_void, len: ::size_t, vec: *mut ::c_char) -> ::c_int; + pub fn sysctlnametomib( + name: *const ::c_char, + mibp: *mut ::c_int, + sizep: *mut ::size_t, + ) -> ::c_int; + #[cfg_attr( + all(target_os = "macos", target_arch = "x86"), + link_name = "mprotect$UNIX2003" + )] + pub fn mprotect(addr: *mut ::c_void, len: ::size_t, prot: ::c_int) -> ::c_int; + pub fn semget(key: key_t, nsems: ::c_int, semflg: ::c_int) -> ::c_int; + #[cfg_attr( + all(target_os = "macos", target_arch = "x86"), + link_name = "semctl$UNIX2003" + )] + 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 shm_open(name: *const ::c_char, oflag: ::c_int, ...) -> ::c_int; + pub fn ftok(pathname: *const c_char, proj_id: ::c_int) -> key_t; + 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; + #[cfg_attr( + all(target_os = "macos", target_arch = "x86"), + link_name = "shmctl$UNIX2003" + )] + 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 sysctl( + name: *mut ::c_int, + namelen: ::c_uint, + oldp: *mut ::c_void, + oldlenp: *mut ::size_t, + newp: *mut ::c_void, + newlen: ::size_t, + ) -> ::c_int; + pub fn sysctlbyname( + name: *const ::c_char, + oldp: *mut ::c_void, + oldlenp: *mut ::size_t, + newp: *mut ::c_void, + newlen: ::size_t, + ) -> ::c_int; + #[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 `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_once( + once_control: *mut ::pthread_once_t, + init_routine: ::Option, + ) -> ::c_int; + pub fn pthread_attr_getinheritsched( + attr: *const ::pthread_attr_t, + inheritsched: *mut ::c_int, + ) -> ::c_int; + pub fn pthread_attr_getschedpolicy( + attr: *const ::pthread_attr_t, + policy: *mut ::c_int, + ) -> ::c_int; + pub fn pthread_attr_getscope( + attr: *const ::pthread_attr_t, + contentionscope: *mut ::c_int, + ) -> ::c_int; + pub fn pthread_attr_getstackaddr( + attr: *const ::pthread_attr_t, + stackaddr: *mut *mut ::c_void, + ) -> ::c_int; + pub fn pthread_attr_getdetachstate( + attr: *const ::pthread_attr_t, + detachstate: *mut ::c_int, + ) -> ::c_int; + pub fn pthread_attr_setinheritsched( + attr: *mut ::pthread_attr_t, + inheritsched: ::c_int, + ) -> ::c_int; + pub fn pthread_attr_setschedpolicy(attr: *mut ::pthread_attr_t, policy: ::c_int) -> ::c_int; + pub fn pthread_attr_setscope(attr: *mut ::pthread_attr_t, contentionscope: ::c_int) -> ::c_int; + pub fn pthread_attr_setstackaddr( + attr: *mut ::pthread_attr_t, + stackaddr: *mut ::c_void, + ) -> ::c_int; + 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; + pub fn pthread_condattr_getpshared( + 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, + ) -> ::c_int; + pub fn pthread_mutexattr_getpshared( + attr: *const pthread_mutexattr_t, + pshared: *mut ::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_threadid_np(thread: ::pthread_t, thread_id: *mut u64) -> ::c_int; + pub fn pthread_attr_set_qos_class_np( + attr: *mut pthread_attr_t, + class: qos_class_t, + priority: ::c_int, + ) -> ::c_int; + pub fn pthread_attr_get_qos_class_np( + attr: *mut pthread_attr_t, + class: *mut qos_class_t, + priority: *mut ::c_int, + ) -> ::c_int; + pub fn pthread_set_qos_class_self_np(class: qos_class_t, priority: ::c_int) -> ::c_int; + pub fn pthread_get_qos_class_np( + thread: ::pthread_t, + 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; + + // Available starting with macOS 14.4. + pub fn os_sync_wait_on_address( + addr: *mut ::c_void, + value: u64, + size: ::size_t, + flags: os_sync_wait_on_address_flags_t, + ) -> ::c_int; + pub fn os_sync_wait_on_address_with_deadline( + addr: *mut ::c_void, + value: u64, + size: ::size_t, + flags: os_sync_wait_on_address_flags_t, + clockid: os_clockid_t, + deadline: u64, + ) -> ::c_int; + pub fn os_sync_wait_on_address_with_timeout( + addr: *mut ::c_void, + value: u64, + size: ::size_t, + flags: os_sync_wait_on_address_flags_t, + clockid: os_clockid_t, + timeout_ns: u64, + ) -> ::c_int; + pub fn os_sync_wake_by_address_any( + addr: *mut ::c_void, + size: ::size_t, + flags: os_sync_wake_by_address_flags_t, + ) -> ::c_int; + pub fn os_sync_wake_by_address_all( + addr: *mut ::c_void, + size: ::size_t, + flags: os_sync_wake_by_address_flags_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, + policy_info: thread_policy_t, + count: mach_msg_type_number_t, + ) -> kern_return_t; + pub fn thread_policy_get( + thread: thread_t, + flavor: thread_policy_flavor_t, + policy_info: thread_policy_t, + 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" + )] + pub fn statfs(path: *const ::c_char, buf: *mut statfs) -> ::c_int; + #[cfg_attr( + all(target_os = "macos", not(target_arch = "aarch64")), + link_name = "fstatfs$INODE64" + )] + pub fn fstatfs(fd: ::c_int, buf: *mut statfs) -> ::c_int; + pub fn kevent( + kq: ::c_int, + changelist: *const ::kevent, + nchanges: ::c_int, + eventlist: *mut ::kevent, + nevents: ::c_int, + timeout: *const ::timespec, + ) -> ::c_int; + pub fn kevent64( + kq: ::c_int, + changelist: *const ::kevent64_s, + nchanges: ::c_int, + eventlist: *mut ::kevent64_s, + nevents: ::c_int, + flags: ::c_uint, + timeout: *const ::timespec, + ) -> ::c_int; + pub fn mount( + src: *const ::c_char, + target: *const ::c_char, + 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, + cmd: ::c_int, + id: ::c_int, + data: *mut ::c_char, + ) -> ::c_int; + pub fn sethostname(name: *const ::c_char, len: ::c_int) -> ::c_int; + pub fn sendfile( + fd: ::c_int, + s: ::c_int, + offset: ::off_t, + len: *mut ::off_t, + hdtr: *mut ::sf_hdtr, + flags: ::c_int, + ) -> ::c_int; + pub fn futimens(fd: ::c_int, times: *const ::timespec) -> ::c_int; + pub fn utimensat( + dirfd: ::c_int, + path: *const ::c_char, + times: *const ::timespec, + flag: ::c_int, + ) -> ::c_int; + 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 duplocale(base: ::locale_t) -> ::locale_t; + pub fn freelocale(loc: ::locale_t) -> ::c_int; + pub fn localeconv_l(loc: ::locale_t) -> *mut lconv; + 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 querylocale(mask: ::c_int, loc: ::locale_t) -> *const ::c_char; + 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 getdomainname(name: *mut ::c_char, len: ::c_int) -> ::c_int; + pub fn setdomainname(name: *const ::c_char, len: ::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 getxattr( + path: *const ::c_char, + name: *const ::c_char, + value: *mut ::c_void, + size: ::size_t, + position: u32, + flags: ::c_int, + ) -> ::ssize_t; + pub fn fgetxattr( + filedes: ::c_int, + name: *const ::c_char, + value: *mut ::c_void, + size: ::size_t, + position: u32, + flags: ::c_int, + ) -> ::ssize_t; + pub fn setxattr( + path: *const ::c_char, + name: *const ::c_char, + value: *const ::c_void, + size: ::size_t, + position: u32, + flags: ::c_int, + ) -> ::c_int; + pub fn fsetxattr( + filedes: ::c_int, + name: *const ::c_char, + value: *const ::c_void, + size: ::size_t, + position: u32, + flags: ::c_int, + ) -> ::c_int; + pub fn listxattr( + path: *const ::c_char, + list: *mut ::c_char, + size: ::size_t, + flags: ::c_int, + ) -> ::ssize_t; + pub fn flistxattr( + filedes: ::c_int, + list: *mut ::c_char, + size: ::size_t, + flags: ::c_int, + ) -> ::ssize_t; + pub fn removexattr(path: *const ::c_char, name: *const ::c_char, flags: ::c_int) -> ::c_int; + pub fn renamex_np(from: *const ::c_char, to: *const ::c_char, flags: ::c_uint) -> ::c_int; + pub fn renameatx_np( + fromfd: ::c_int, + from: *const ::c_char, + tofd: ::c_int, + to: *const ::c_char, + flags: ::c_uint, + ) -> ::c_int; + pub fn fremovexattr(filedes: ::c_int, name: *const ::c_char, flags: ::c_int) -> ::c_int; + + pub fn getgrouplist( + name: *const ::c_char, + basegid: ::c_int, + groups: *mut ::c_int, + ngroups: *mut ::c_int, + ) -> ::c_int; + pub fn initgroups(user: *const ::c_char, basegroup: ::c_int) -> ::c_int; + + #[cfg_attr( + all(target_os = "macos", target_arch = "x86"), + link_name = "waitid$UNIX2003" + )] + pub fn waitid(idtype: idtype_t, id: id_t, infop: *mut ::siginfo_t, options: ::c_int) + -> ::c_int; + 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 `mach2` crate instead")] + pub fn _dyld_image_count() -> u32; + #[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 `mach2` crate instead")] + pub fn _dyld_get_image_vmaddr_slide(image_index: u32) -> ::intptr_t; + #[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( + 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_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_getbinpref_np( + attr: *const posix_spawnattr_t, + count: ::size_t, + pref: *mut ::cpu_type_t, + ocount: *mut ::size_t, + ) -> ::c_int; + pub fn posix_spawnattr_setbinpref_np( + attr: *mut posix_spawnattr_t, + count: ::size_t, + pref: *mut ::cpu_type_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; + 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 uname(buf: *mut ::utsname) -> ::c_int; + + pub fn connectx( + socket: ::c_int, + endpoints: *const sa_endpoints_t, + associd: sae_associd_t, + flags: ::c_uint, + iov: *const ::iovec, + iovcnt: ::c_uint, + len: *mut ::size_t, + connid: *mut sae_connid_t, + ) -> ::c_int; + pub fn disconnectx(socket: ::c_int, associd: sae_associd_t, connid: sae_connid_t) -> ::c_int; + + pub fn ntp_adjtime(buf: *mut timex) -> ::c_int; + pub fn ntp_gettime(buf: *mut ntptimeval) -> ::c_int; + + #[cfg_attr( + all(target_os = "macos", not(target_arch = "aarch64")), + link_name = "getmntinfo$INODE64" + )] + pub fn getmntinfo(mntbufp: *mut *mut statfs, flags: ::c_int) -> ::c_int; + #[cfg_attr( + all(target_os = "macos", not(target_arch = "aarch64")), + link_name = "getfsstat$INODE64" + )] + pub fn getfsstat(mntbufp: *mut statfs, bufsize: ::c_int, flags: ::c_int) -> ::c_int; + + // Copy-on-write functions. + // According to the man page `flags` is an `int` but in the header + // this is a `uint32_t`. + pub fn clonefile(src: *const ::c_char, dst: *const ::c_char, flags: u32) -> ::c_int; + pub fn clonefileat( + src_dirfd: ::c_int, + src: *const ::c_char, + dst_dirfd: ::c_int, + dst: *const ::c_char, + flags: u32, + ) -> ::c_int; + pub fn fclonefileat( + srcfd: ::c_int, + dst_dirfd: ::c_int, + dst: *const ::c_char, + 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; + pub fn copyfile_state_free(s: copyfile_state_t) -> ::c_int; + pub fn copyfile_state_alloc() -> copyfile_state_t; + pub fn copyfile_state_get(s: copyfile_state_t, flags: u32, dst: *mut ::c_void) -> ::c_int; + pub fn copyfile_state_set(s: copyfile_state_t, flags: u32, src: *const ::c_void) -> ::c_int; + + pub fn mach_error_string(error_value: ::mach_error_t) -> *mut ::c_char; + + // 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; + // Added in macOS 10.5 + pub fn memset_pattern4(b: *mut ::c_void, pattern4: *const ::c_void, len: ::size_t); + 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, + typeinfo: u32, + buffer: *mut ::c_void, + buffersize: ::c_int, + ) -> ::c_int; + pub fn proc_listallpids(buffer: *mut ::c_void, buffersize: ::c_int) -> ::c_int; + pub fn proc_listpgrppids( + pgrpid: ::pid_t, + buffer: *mut ::c_void, + buffersize: ::c_int, + ) -> ::c_int; + pub fn proc_listchildpids(ppid: ::pid_t, buffer: *mut ::c_void, buffersize: ::c_int) + -> ::c_int; + pub fn proc_pidinfo( + pid: ::c_int, + flavor: ::c_int, + arg: u64, + buffer: *mut ::c_void, + buffersize: ::c_int, + ) -> ::c_int; + pub fn proc_pidfdinfo( + pid: ::c_int, + fd: ::c_int, + flavor: ::c_int, + buffer: *mut ::c_void, + buffersize: ::c_int, + ) -> ::c_int; + pub fn proc_pidfileportinfo( + pid: ::c_int, + fileport: u32, + flavor: ::c_int, + buffer: *mut ::c_void, + buffersize: ::c_int, + ) -> ::c_int; + pub fn proc_pidpath(pid: ::c_int, buffer: *mut ::c_void, buffersize: u32) -> ::c_int; + pub fn proc_name(pid: ::c_int, buffer: *mut ::c_void, buffersize: u32) -> ::c_int; + pub fn proc_regionfilename( + pid: ::c_int, + address: u64, + 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, minor: *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 getentropy(buf: *mut ::c_void, buflen: ::size_t) -> ::c_int; + + pub fn _NSGetExecutablePath(buf: *mut ::c_char, bufsize: *mut u32) -> ::c_int; + + // crt_externs.h + pub fn _NSGetArgv() -> *mut *mut *mut ::c_char; + pub fn _NSGetArgc() -> *mut ::c_int; + pub fn _NSGetEnviron() -> *mut *mut *mut ::c_char; + pub fn _NSGetProgname() -> *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_allocate( + target_task: vm_map_t, + address: *mut vm_address_t, + size: vm_size_t, + flags: ::c_int, + ) -> ::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 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 freadlink(fd: ::c_int, buf: *mut ::c_char, size: ::size_t) -> ::c_int; + pub fn execvP( + file: *const ::c_char, + search_path: *const ::c_char, + argv: *const *mut ::c_char, + ) -> ::c_int; +} + +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", target_os = "tvos", target_os = "visionos"))] { + extern "C" { + pub fn memmem( + haystack: *const ::c_void, + haystacklen: ::size_t, + 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; + } + } +} + +// 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( + 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; +} + +cfg_if! { + if #[cfg(target_pointer_width = "32")] { + mod b32; + pub use self::b32::*; + } 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/errno.rs b/vendor/libc/src/unix/bsd/freebsdlike/dragonfly/errno.rs new file mode 100644 index 0000000..5fe6bb8 --- /dev/null +++ b/vendor/libc/src/unix/bsd/freebsdlike/dragonfly/errno.rs @@ -0,0 +1,13 @@ +// DragonFlyBSD's __error function is declared with "static inline", so it must +// be implemented in the libc crate, as a pointer to a static thread_local. +f! { + #[deprecated(since = "0.2.77", note = "Use `__errno_location()` instead")] + pub fn __error() -> *mut ::c_int { + &mut errno + } +} + +extern "C" { + #[thread_local] + pub static mut errno: ::c_int; +} diff --git a/vendor/libc/src/unix/bsd/freebsdlike/dragonfly/mod.rs b/vendor/libc/src/unix/bsd/freebsdlike/dragonfly/mod.rs new file mode 100644 index 0000000..9b3b872 --- /dev/null +++ b/vendor/libc/src/unix/bsd/freebsdlike/dragonfly/mod.rs @@ -0,0 +1,1745 @@ +pub type dev_t = u32; +pub type c_char = i8; +pub type wchar_t = i32; +pub type clock_t = u64; +pub type ino_t = u64; +pub type lwpid_t = i32; +pub type nlink_t = u32; +pub type blksize_t = i64; +pub type clockid_t = ::c_ulong; + +pub type c_long = i64; +pub type c_ulong = u64; +pub type time_t = i64; +pub type suseconds_t = i64; + +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; + +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 {} +impl ::Copy for sem {} +impl ::Clone for sem { + fn clone(&self) -> sem { + *self + } +} + +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, + pub filter: ::c_short, + pub flags: ::c_ushort, + pub fflags: ::c_uint, + pub data: ::intptr_t, + pub udata: *mut ::c_void, + } + + pub struct exit_status { + pub e_termination: u16, + pub e_exit: u16 + } + + pub struct aiocb { + pub aio_fildes: ::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_reqprio: ::c_int, + _aio_val: ::c_int, + _aio_err: ::c_int + } + + 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; 6], + } + + 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 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_owner: ::uid_t, + pub f_type: ::c_uint, + pub f_syncreads: u64, + pub f_syncwrites: u64, + pub f_asyncreads: u64, + pub f_asyncwrites: u64, + pub f_fsid_uuid: ::uuid_t, + pub f_uid_uuid: ::uuid_t, + } + + pub struct stat { + pub st_ino: ::ino_t, + pub st_nlink: ::nlink_t, + pub st_dev: ::dev_t, + pub st_mode: ::mode_t, + pub st_padding1: u16, + 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: i64, + pub __old_st_blksize: u32, + pub st_flags: u32, + pub st_gen: u32, + pub st_lspare: i32, + pub st_blksize: i64, + pub st_qspare2: i64, + } + + pub struct if_data { + pub ifi_type: ::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_mtu: ::c_ulong, + pub ifi_metric: ::c_ulong, + pub ifi_link_state: ::c_ulong, + pub ifi_baudrate: u64, + pub ifi_ipackets: ::c_ulong, + pub ifi_ierrors: ::c_ulong, + pub ifi_opackets: ::c_ulong, + pub ifi_oerrors: ::c_ulong, + pub ifi_collisions: ::c_ulong, + pub ifi_ibytes: ::c_ulong, + pub ifi_obytes: ::c_ulong, + pub ifi_imcasts: ::c_ulong, + pub ifi_omcasts: ::c_ulong, + pub ifi_iqdrops: ::c_ulong, + pub ifi_noproto: ::c_ulong, + pub ifi_hwassist: ::c_ulong, + pub ifi_oqdrops: ::c_ulong, + pub ifi_lastchange: ::timeval, + } + + pub struct if_msghdr { + 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_data: if_data, + } + + 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; 12], + pub sdl_rcf: ::c_ushort, + pub sdl_route: [::c_ushort; 16], + } + + pub struct xucred { + pub cr_version: ::c_uint, + pub cr_uid: ::uid_t, + pub cr_ngroups: ::c_short, + pub cr_groups: [::gid_t; 16], + __cr_unused1: *mut ::c_void, + } + + pub struct stack_t { + pub ss_sp: *mut ::c_void, + pub ss_size: ::size_t, + pub ss_flags: ::c_int, + } + + 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! { + pub struct utmpx { + pub ut_name: [::c_char; 32], + pub ut_id: [::c_char; 4], + + pub ut_line: [::c_char; 32], + pub ut_host: [::c_char; 256], + + pub ut_unused: [u8; 16], + pub ut_session: u16, + pub ut_type: u16, + pub ut_pid: ::pid_t, + ut_exit: exit_status, + ut_ss: ::sockaddr_storage, + pub ut_tv: ::timeval, + pub ut_unused2: [u8; 16], + } + + pub struct 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, + pub d_type: u8, + __unused1: u8, + __unused2: u32, + pub d_name: [::c_char; 256], + } + + pub struct statfs { + __spare2: ::c_long, + pub f_bsize: ::c_long, + pub f_iosize: ::c_long, + pub f_blocks: ::c_long, + pub f_bfree: ::c_long, + pub f_bavail: ::c_long, + pub f_files: ::c_long, + pub f_ffree: ::c_long, + pub f_fsid: ::fsid_t, + pub f_owner: ::uid_t, + pub f_type: ::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; 80], + pub f_syncreads: ::c_long, + pub f_asyncreads: ::c_long, + __spares1: ::c_short, + pub f_mntfromname: [::c_char; 80], + __spares2: ::c_short, + __spare: [::c_long; 2], + } + + pub struct sigevent { + pub sigev_notify: ::c_int, + // The union is 8-byte in size, so it is aligned at a 8-byte offset. + #[cfg(target_pointer_width = "64")] + __unused1: ::c_int, + pub sigev_signo: ::c_int, //actually a union + // pad the union + #[cfg(target_pointer_width = "64")] + __unused2: ::c_int, + pub sigev_value: ::sigval, + __unused3: *mut ::c_void //actually a function pointer + } + + pub struct mcontext_t { + pub mc_onstack: register_t, + pub mc_rdi: register_t, + pub mc_rsi: register_t, + pub mc_rdx: register_t, + pub mc_rcx: register_t, + pub mc_r8: register_t, + pub mc_r9: register_t, + pub mc_rax: register_t, + pub mc_rbx: register_t, + pub mc_rbp: register_t, + pub mc_r10: register_t, + pub mc_r11: register_t, + pub mc_r12: register_t, + pub mc_r13: register_t, + pub mc_r14: register_t, + pub mc_r15: register_t, + pub mc_xflags: register_t, + pub mc_trapno: register_t, + pub mc_addr: register_t, + pub mc_flags: register_t, + pub mc_err: register_t, + pub mc_rip: register_t, + pub mc_cs: register_t, + pub mc_rflags: register_t, + pub mc_rsp: register_t, + pub mc_ss: register_t, + pub mc_len: ::c_uint, + pub mc_fpformat: ::c_uint, + pub mc_ownedfp: ::c_uint, + __reserved: ::c_uint, + __unused: [::c_uint; 8], + pub mc_fpregs: [[::c_uint; 8]; 32], + } + + 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_cofunc: ::Option, + pub uc_arg: *mut ::c_void, + __pad: [::c_int; 4], + } +} + +cfg_if! { + if #[cfg(feature = "extra_traits")] { + impl PartialEq for utmpx { + fn eq(&self, other: &utmpx) -> bool { + self.ut_name == other.ut_name + && self.ut_id == other.ut_id + && self.ut_line == other.ut_line + && self + .ut_host + .iter() + .zip(other.ut_host.iter()) + .all(|(a,b)| a == b) + && self.ut_unused == other.ut_unused + && self.ut_session == other.ut_session + && self.ut_type == other.ut_type + && self.ut_pid == other.ut_pid + && self.ut_exit == other.ut_exit + && self.ut_ss == other.ut_ss + && self.ut_tv == other.ut_tv + && self.ut_unused2 == other.ut_unused2 + } + } + impl Eq for utmpx {} + impl ::fmt::Debug for utmpx { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("utmpx") + .field("ut_name", &self.ut_name) + .field("ut_id", &self.ut_id) + .field("ut_line", &self.ut_line) + // FIXME: .field("ut_host", &self.ut_host) + .field("ut_unused", &self.ut_unused) + .field("ut_session", &self.ut_session) + .field("ut_type", &self.ut_type) + .field("ut_pid", &self.ut_pid) + .field("ut_exit", &self.ut_exit) + .field("ut_ss", &self.ut_ss) + .field("ut_tv", &self.ut_tv) + .field("ut_unused2", &self.ut_unused2) + .finish() + } + } + impl ::hash::Hash for utmpx { + fn hash(&self, state: &mut H) { + self.ut_name.hash(state); + self.ut_id.hash(state); + self.ut_line.hash(state); + self.ut_host.hash(state); + self.ut_unused.hash(state); + self.ut_session.hash(state); + self.ut_type.hash(state); + self.ut_pid.hash(state); + self.ut_exit.hash(state); + self.ut_ss.hash(state); + self.ut_tv.hash(state); + self.ut_unused2.hash(state); + } + } + impl PartialEq for 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 { + self.d_fileno == other.d_fileno + && self.d_namlen == other.d_namlen + && self.d_type == other.d_type + // Ignore __unused1 + // Ignore __unused2 + && self + .d_name + .iter() + .zip(other.d_name.iter()) + .all(|(a,b)| a == b) + } + } + impl Eq for dirent {} + impl ::fmt::Debug for dirent { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("dirent") + .field("d_fileno", &self.d_fileno) + .field("d_namlen", &self.d_namlen) + .field("d_type", &self.d_type) + // Ignore __unused1 + // Ignore __unused2 + // FIXME: .field("d_name", &self.d_name) + .finish() + } + } + impl ::hash::Hash for dirent { + fn hash(&self, state: &mut H) { + self.d_fileno.hash(state); + self.d_namlen.hash(state); + self.d_type.hash(state); + // Ignore __unused1 + // Ignore __unused2 + self.d_name.hash(state); + } + } + + impl PartialEq for statfs { + fn eq(&self, other: &statfs) -> bool { + self.f_bsize == other.f_bsize + && self.f_iosize == other.f_iosize + && self.f_blocks == other.f_blocks + && self.f_bfree == other.f_bfree + && self.f_bavail == other.f_bavail + && self.f_files == other.f_files + && self.f_ffree == other.f_ffree + && self.f_fsid == other.f_fsid + && self.f_owner == other.f_owner + && self.f_type == other.f_type + && self.f_flags == other.f_flags + && self.f_syncwrites == other.f_syncwrites + && self.f_asyncwrites == other.f_asyncwrites + && self.f_fstypename == other.f_fstypename + && self + .f_mntonname + .iter() + .zip(other.f_mntonname.iter()) + .all(|(a,b)| a == b) + && self.f_syncreads == other.f_syncreads + && self.f_asyncreads == other.f_asyncreads + && self + .f_mntfromname + .iter() + .zip(other.f_mntfromname.iter()) + .all(|(a,b)| a == b) + } + } + impl Eq for statfs {} + impl ::fmt::Debug for statfs { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("statfs") + .field("f_bsize", &self.f_bsize) + .field("f_iosize", &self.f_iosize) + .field("f_blocks", &self.f_blocks) + .field("f_bfree", &self.f_bfree) + .field("f_bavail", &self.f_bavail) + .field("f_files", &self.f_files) + .field("f_ffree", &self.f_ffree) + .field("f_fsid", &self.f_fsid) + .field("f_owner", &self.f_owner) + .field("f_type", &self.f_type) + .field("f_flags", &self.f_flags) + .field("f_syncwrites", &self.f_syncwrites) + .field("f_asyncwrites", &self.f_asyncwrites) + // FIXME: .field("f_mntonname", &self.f_mntonname) + .field("f_syncreads", &self.f_syncreads) + .field("f_asyncreads", &self.f_asyncreads) + // FIXME: .field("f_mntfromname", &self.f_mntfromname) + .finish() + } + } + impl ::hash::Hash for statfs { + fn hash(&self, state: &mut H) { + self.f_bsize.hash(state); + self.f_iosize.hash(state); + self.f_blocks.hash(state); + self.f_bfree.hash(state); + self.f_bavail.hash(state); + self.f_files.hash(state); + self.f_ffree.hash(state); + self.f_fsid.hash(state); + self.f_owner.hash(state); + self.f_type.hash(state); + self.f_flags.hash(state); + self.f_syncwrites.hash(state); + self.f_asyncwrites.hash(state); + self.f_fstypename.hash(state); + self.f_mntonname.hash(state); + self.f_syncreads.hash(state); + self.f_asyncreads.hash(state); + self.f_mntfromname.hash(state); + } + } + + 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 + } + } + 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) + .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); + } + } + impl PartialEq for mcontext_t { + fn eq(&self, other: &mcontext_t) -> bool { + self.mc_onstack == other.mc_onstack && + self.mc_rdi == other.mc_rdi && + self.mc_rsi == other.mc_rsi && + self.mc_rdx == other.mc_rdx && + self.mc_rcx == other.mc_rcx && + self.mc_r8 == other.mc_r8 && + self.mc_r9 == other.mc_r9 && + self.mc_rax == other.mc_rax && + self.mc_rbx == other.mc_rbx && + self.mc_rbp == other.mc_rbp && + self.mc_r10 == other.mc_r10 && + self.mc_r11 == other.mc_r11 && + self.mc_r12 == other.mc_r12 && + self.mc_r13 == other.mc_r13 && + self.mc_r14 == other.mc_r14 && + self.mc_r15 == other.mc_r15 && + self.mc_xflags == other.mc_xflags && + self.mc_trapno == other.mc_trapno && + self.mc_addr == other.mc_addr && + self.mc_flags == other.mc_flags && + self.mc_err == other.mc_err && + self.mc_rip == other.mc_rip && + self.mc_cs == other.mc_cs && + self.mc_rflags == other.mc_rflags && + self.mc_rsp == other.mc_rsp && + 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_fpregs.iter().zip(other.mc_fpregs.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_rdi", &self.mc_rdi) + .field("mc_rsi", &self.mc_rsi) + .field("mc_rdx", &self.mc_rdx) + .field("mc_rcx", &self.mc_rcx) + .field("mc_r8", &self.mc_r8) + .field("mc_r9", &self.mc_r9) + .field("mc_rax", &self.mc_rax) + .field("mc_rbx", &self.mc_rbx) + .field("mc_rbp", &self.mc_rbp) + .field("mc_r10", &self.mc_r10) + .field("mc_r11", &self.mc_r11) + .field("mc_r12", &self.mc_r12) + .field("mc_r13", &self.mc_r13) + .field("mc_r14", &self.mc_r14) + .field("mc_r15", &self.mc_r15) + .field("mc_xflags", &self.mc_xflags) + .field("mc_trapno", &self.mc_trapno) + .field("mc_addr", &self.mc_addr) + .field("mc_flags", &self.mc_flags) + .field("mc_err", &self.mc_err) + .field("mc_rip", &self.mc_rip) + .field("mc_cs", &self.mc_cs) + .field("mc_rflags", &self.mc_rflags) + .field("mc_rsp", &self.mc_rsp) + .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_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 + && self.uc_mcontext == other.uc_mcontext + && self.uc_link == other.uc_link + && self.uc_stack == other.uc_stack + && self.uc_cofunc == other.uc_cofunc + && self.uc_arg == other.uc_arg + } + } + 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_sigmask", &self.uc_sigmask) + .field("uc_mcontext", &self.uc_mcontext) + .field("uc_link", &self.uc_link) + .field("uc_stack", &self.uc_stack) + .field("uc_cofunc", &self.uc_cofunc) + .field("uc_arg", &self.uc_arg) + .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; +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; +#[deprecated(since = "0.2.64", note = "Not stable across OS versions")] +pub const RLIM_NLIMITS: ::rlim_t = 12; + +pub const Q_GETQUOTA: ::c_int = 0x300; +pub const Q_SETQUOTA: ::c_int = 0x400; + +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_P1003_1B: ::c_int = 9; +pub const CTL_LWKT: ::c_int = 10; +pub const CTL_MAXID: ::c_int = 11; +pub const KERN_OSTYPE: ::c_int = 1; +pub const KERN_OSRELEASE: ::c_int = 2; +pub const KERN_OSREV: ::c_int = 3; +pub const KERN_VERSION: ::c_int = 4; +pub const KERN_MAXVNODES: ::c_int = 5; +pub const KERN_MAXPROC: ::c_int = 6; +pub const KERN_MAXFILES: ::c_int = 7; +pub const KERN_ARGMAX: ::c_int = 8; +pub const KERN_SECURELVL: ::c_int = 9; +pub const KERN_HOSTNAME: ::c_int = 10; +pub const KERN_HOSTID: ::c_int = 11; +pub const KERN_CLOCKRATE: ::c_int = 12; +pub const KERN_VNODE: ::c_int = 13; +pub const KERN_PROC: ::c_int = 14; +pub const KERN_FILE: ::c_int = 15; +pub const KERN_PROF: ::c_int = 16; +pub const KERN_POSIX1: ::c_int = 17; +pub const KERN_NGROUPS: ::c_int = 18; +pub const KERN_JOB_CONTROL: ::c_int = 19; +pub const KERN_SAVED_IDS: ::c_int = 20; +pub const KERN_BOOTTIME: ::c_int = 21; +pub const KERN_NISDOMAINNAME: ::c_int = 22; +pub const KERN_UPDATEINTERVAL: ::c_int = 23; +pub const KERN_OSRELDATE: ::c_int = 24; +pub const KERN_NTP_PLL: ::c_int = 25; +pub const KERN_BOOTFILE: ::c_int = 26; +pub const KERN_MAXFILESPERPROC: ::c_int = 27; +pub const KERN_MAXPROCPERUID: ::c_int = 28; +pub const KERN_DUMPDEV: ::c_int = 29; +pub const KERN_IPC: ::c_int = 30; +pub const KERN_DUMMY: ::c_int = 31; +pub const KERN_PS_STRINGS: ::c_int = 32; +pub const KERN_USRSTACK: ::c_int = 33; +pub const KERN_LOGSIGEXIT: ::c_int = 34; +pub const KERN_IOV_MAX: ::c_int = 35; +pub const KERN_MAXPOSIXLOCKSPERUID: ::c_int = 36; +pub const KERN_MAXID: ::c_int = 37; +pub const KERN_PROC_ALL: ::c_int = 0; +pub const KERN_PROC_PID: ::c_int = 1; +pub const KERN_PROC_PGRP: ::c_int = 2; +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_PROC_RUID: ::c_int = 6; +pub const KERN_PROC_ARGS: ::c_int = 7; +pub const KERN_PROC_CWD: ::c_int = 8; +pub const KERN_PROC_PATHNAME: ::c_int = 9; +pub const KERN_PROC_FLAGMASK: ::c_int = 0x10; +pub const KERN_PROC_FLAG_LWP: ::c_int = 0x10; +pub const KIPC_MAXSOCKBUF: ::c_int = 1; +pub const KIPC_SOCKBUF_WASTE: ::c_int = 2; +pub const KIPC_SOMAXCONN: ::c_int = 3; +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 KIPC_MBSTAT: ::c_int = 8; +pub const KIPC_NMBCLUSTERS: ::c_int = 9; +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_DISKSTATS: ::c_int = 9; +pub const HW_FLOATINGPT: ::c_int = 10; +pub const HW_MACHINE_ARCH: ::c_int = 11; +pub const HW_MACHINE_PLATFORM: ::c_int = 12; +pub const HW_SENSORS: ::c_int = 13; +pub const HW_MAXID: ::c_int = 14; +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_MAXID: ::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; +pub const CTL_P1003_1B_MEMLOCK_RANGE: ::c_int = 4; +pub const CTL_P1003_1B_MEMORY_PROTECTION: ::c_int = 5; +pub const CTL_P1003_1B_MESSAGE_PASSING: ::c_int = 6; +pub const CTL_P1003_1B_PRIORITIZED_IO: ::c_int = 7; +pub const CTL_P1003_1B_PRIORITY_SCHEDULING: ::c_int = 8; +pub const CTL_P1003_1B_REALTIME_SIGNALS: ::c_int = 9; +pub const CTL_P1003_1B_SEMAPHORES: ::c_int = 10; +pub const CTL_P1003_1B_FSYNC: ::c_int = 11; +pub const CTL_P1003_1B_SHARED_MEMORY_OBJECTS: ::c_int = 12; +pub const CTL_P1003_1B_SYNCHRONIZED_IO: ::c_int = 13; +pub const CTL_P1003_1B_TIMERS: ::c_int = 14; +pub const CTL_P1003_1B_AIO_LISTIO_MAX: ::c_int = 15; +pub const CTL_P1003_1B_AIO_MAX: ::c_int = 16; +pub const CTL_P1003_1B_AIO_PRIO_DELTA_MAX: ::c_int = 17; +pub const CTL_P1003_1B_DELAYTIMER_MAX: ::c_int = 18; +pub const CTL_P1003_1B_UNUSED1: ::c_int = 19; +pub const CTL_P1003_1B_PAGESIZE: ::c_int = 20; +pub const CTL_P1003_1B_RTSIG_MAX: ::c_int = 21; +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 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; +pub const EVFILT_VNODE: i16 = -4; +pub const EVFILT_PROC: i16 = -5; +pub const EVFILT_SIGNAL: i16 = -6; +pub const EVFILT_TIMER: i16 = -7; +pub const EVFILT_EXCEPT: i16 = -8; +pub const EVFILT_USER: i16 = -9; +pub const EVFILT_FS: i16 = -10; + +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_ONESHOT: u16 = 0x10; +pub const EV_CLEAR: u16 = 0x20; +pub const EV_RECEIPT: u16 = 0x40; +pub const EV_DISPATCH: u16 = 0x80; +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; +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_OOB: u32 = 0x00000002; +pub const NOTE_DELETE: u32 = 0x00000001; +pub const NOTE_WRITE: u32 = 0x00000002; +pub const NOTE_EXTEND: u32 = 0x00000004; +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_EXIT: u32 = 0x80000000; +pub const NOTE_FORK: u32 = 0x40000000; +pub const NOTE_EXEC: u32 = 0x20000000; +pub const NOTE_PDATAMASK: u32 = 0x000fffff; +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 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/HEAD/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 +pub const IFF_DEBUG: ::c_int = 0x4; // turn on debugging +pub const IFF_LOOPBACK: ::c_int = 0x8; // is a loopback net +pub const IFF_POINTOPOINT: ::c_int = 0x10; // interface is point-to-point link +pub const IFF_SMART: ::c_int = 0x20; // interface manages own routes +pub const IFF_RUNNING: ::c_int = 0x40; // resources allocated +pub const IFF_NOARP: ::c_int = 0x80; // no address resolution protocol +pub const IFF_PROMISC: ::c_int = 0x100; // receive all packets +pub const IFF_ALLMULTI: ::c_int = 0x200; // receive all multicast packets +pub const IFF_OACTIVE_COMPAT: ::c_int = 0x400; // was transmission in progress +pub const IFF_SIMPLEX: ::c_int = 0x800; // 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; // supports multicast + // was interface is in polling mode +pub const IFF_POLLING_COMPAT: ::c_int = 0x10000; +pub const IFF_PPROMISC: ::c_int = 0x20000; // user-requested promisc mode +pub const IFF_MONITOR: ::c_int = 0x40000; // user-requested monitor mode +pub const IFF_STATICARP: ::c_int = 0x80000; // static ARP +pub const IFF_NPOLLING: ::c_int = 0x100000; // interface is in polling mode +pub const IFF_IDIRECT: ::c_int = 0x200000; // direct input + +// +// sys/netinet/in.h +// Protocols (RFC 1700) +// NOTE: These are in addition to the constants defined in src/unix/mod.rs + +// IPPROTO_IP defined in src/unix/mod.rs +/// IP6 hop-by-hop options +pub const IPPROTO_HOPOPTS: ::c_int = 0; +// IPPROTO_ICMP defined in src/unix/mod.rs +/// group mgmt protocol +pub const IPPROTO_IGMP: ::c_int = 2; +/// gateway^2 (deprecated) +pub const IPPROTO_GGP: ::c_int = 3; +/// for compatibility +pub const IPPROTO_IPIP: ::c_int = 4; +// IPPROTO_TCP defined in src/unix/mod.rs +/// Stream protocol II. +pub const IPPROTO_ST: ::c_int = 7; +/// exterior gateway protocol +pub const IPPROTO_EGP: ::c_int = 8; +/// private interior gateway +pub const IPPROTO_PIGP: ::c_int = 9; +/// BBN RCC Monitoring +pub const IPPROTO_RCCMON: ::c_int = 10; +/// network voice protocol +pub const IPPROTO_NVPII: ::c_int = 11; +/// pup +pub const IPPROTO_PUP: ::c_int = 12; +/// Argus +pub const IPPROTO_ARGUS: ::c_int = 13; +/// EMCON +pub const IPPROTO_EMCON: ::c_int = 14; +/// Cross Net Debugger +pub const IPPROTO_XNET: ::c_int = 15; +/// Chaos +pub const IPPROTO_CHAOS: ::c_int = 16; +// IPPROTO_UDP defined in src/unix/mod.rs +/// Multiplexing +pub const IPPROTO_MUX: ::c_int = 18; +/// DCN Measurement Subsystems +pub const IPPROTO_MEAS: ::c_int = 19; +/// Host Monitoring +pub const IPPROTO_HMP: ::c_int = 20; +/// Packet Radio Measurement +pub const IPPROTO_PRM: ::c_int = 21; +/// xns idp +pub const IPPROTO_IDP: ::c_int = 22; +/// Trunk-1 +pub const IPPROTO_TRUNK1: ::c_int = 23; +/// Trunk-2 +pub const IPPROTO_TRUNK2: ::c_int = 24; +/// Leaf-1 +pub const IPPROTO_LEAF1: ::c_int = 25; +/// Leaf-2 +pub const IPPROTO_LEAF2: ::c_int = 26; +/// Reliable Data +pub const IPPROTO_RDP: ::c_int = 27; +/// Reliable Transaction +pub const IPPROTO_IRTP: ::c_int = 28; +/// tp-4 w/ class negotiation +pub const IPPROTO_TP: ::c_int = 29; +/// Bulk Data Transfer +pub const IPPROTO_BLT: ::c_int = 30; +/// Network Services +pub const IPPROTO_NSP: ::c_int = 31; +/// Merit Internodal +pub const IPPROTO_INP: ::c_int = 32; +/// Sequential Exchange +pub const IPPROTO_SEP: ::c_int = 33; +/// Third Party Connect +pub const IPPROTO_3PC: ::c_int = 34; +/// InterDomain Policy Routing +pub const IPPROTO_IDPR: ::c_int = 35; +/// XTP +pub const IPPROTO_XTP: ::c_int = 36; +/// Datagram Delivery +pub const IPPROTO_DDP: ::c_int = 37; +/// Control Message Transport +pub const IPPROTO_CMTP: ::c_int = 38; +/// TP++ Transport +pub const IPPROTO_TPXX: ::c_int = 39; +/// IL transport protocol +pub const IPPROTO_IL: ::c_int = 40; +// IPPROTO_IPV6 defined in src/unix/mod.rs +/// Source Demand Routing +pub const IPPROTO_SDRP: ::c_int = 42; +/// IP6 routing header +pub const IPPROTO_ROUTING: ::c_int = 43; +/// IP6 fragmentation header +pub const IPPROTO_FRAGMENT: ::c_int = 44; +/// InterDomain Routing +pub const IPPROTO_IDRP: ::c_int = 45; +/// resource reservation +pub const IPPROTO_RSVP: ::c_int = 46; +/// General Routing Encap. +pub const IPPROTO_GRE: ::c_int = 47; +/// Mobile Host Routing +pub const IPPROTO_MHRP: ::c_int = 48; +/// BHA +pub const IPPROTO_BHA: ::c_int = 49; +/// IP6 Encap Sec. Payload +pub const IPPROTO_ESP: ::c_int = 50; +/// IP6 Auth Header +pub const IPPROTO_AH: ::c_int = 51; +/// Integ. Net Layer Security +pub const IPPROTO_INLSP: ::c_int = 52; +/// IP with encryption +pub const IPPROTO_SWIPE: ::c_int = 53; +/// Next Hop Resolution +pub const IPPROTO_NHRP: ::c_int = 54; +/// IP Mobility +pub const IPPROTO_MOBILE: ::c_int = 55; +/// Transport Layer Security +pub const IPPROTO_TLSP: ::c_int = 56; +/// SKIP +pub const IPPROTO_SKIP: ::c_int = 57; +// IPPROTO_ICMPV6 defined in src/unix/mod.rs +/// IP6 no next header +pub const IPPROTO_NONE: ::c_int = 59; +/// IP6 destination option +pub const IPPROTO_DSTOPTS: ::c_int = 60; +/// any host internal protocol +pub const IPPROTO_AHIP: ::c_int = 61; +/// CFTP +pub const IPPROTO_CFTP: ::c_int = 62; +/// "hello" routing protocol +pub const IPPROTO_HELLO: ::c_int = 63; +/// SATNET/Backroom EXPAK +pub const IPPROTO_SATEXPAK: ::c_int = 64; +/// Kryptolan +pub const IPPROTO_KRYPTOLAN: ::c_int = 65; +/// Remote Virtual Disk +pub const IPPROTO_RVD: ::c_int = 66; +/// Pluribus Packet Core +pub const IPPROTO_IPPC: ::c_int = 67; +/// Any distributed FS +pub const IPPROTO_ADFS: ::c_int = 68; +/// Satnet Monitoring +pub const IPPROTO_SATMON: ::c_int = 69; +/// VISA Protocol +pub const IPPROTO_VISA: ::c_int = 70; +/// Packet Core Utility +pub const IPPROTO_IPCV: ::c_int = 71; +/// Comp. Prot. Net. Executive +pub const IPPROTO_CPNX: ::c_int = 72; +/// Comp. Prot. HeartBeat +pub const IPPROTO_CPHB: ::c_int = 73; +/// Wang Span Network +pub const IPPROTO_WSN: ::c_int = 74; +/// Packet Video Protocol +pub const IPPROTO_PVP: ::c_int = 75; +/// BackRoom SATNET Monitoring +pub const IPPROTO_BRSATMON: ::c_int = 76; +/// Sun net disk proto (temp.) +pub const IPPROTO_ND: ::c_int = 77; +/// WIDEBAND Monitoring +pub const IPPROTO_WBMON: ::c_int = 78; +/// WIDEBAND EXPAK +pub const IPPROTO_WBEXPAK: ::c_int = 79; +/// ISO cnlp +pub const IPPROTO_EON: ::c_int = 80; +/// VMTP +pub const IPPROTO_VMTP: ::c_int = 81; +/// Secure VMTP +pub const IPPROTO_SVMTP: ::c_int = 82; +/// Banyon VINES +pub const IPPROTO_VINES: ::c_int = 83; +/// TTP +pub const IPPROTO_TTP: ::c_int = 84; +/// NSFNET-IGP +pub const IPPROTO_IGP: ::c_int = 85; +/// dissimilar gateway prot. +pub const IPPROTO_DGP: ::c_int = 86; +/// TCF +pub const IPPROTO_TCF: ::c_int = 87; +/// Cisco/GXS IGRP +pub const IPPROTO_IGRP: ::c_int = 88; +/// OSPFIGP +pub const IPPROTO_OSPFIGP: ::c_int = 89; +/// Strite RPC protocol +pub const IPPROTO_SRPC: ::c_int = 90; +/// Locus Address Resoloution +pub const IPPROTO_LARP: ::c_int = 91; +/// Multicast Transport +pub const IPPROTO_MTP: ::c_int = 92; +/// AX.25 Frames +pub const IPPROTO_AX25: ::c_int = 93; +/// IP encapsulated in IP +pub const IPPROTO_IPEIP: ::c_int = 94; +/// Mobile Int.ing control +pub const IPPROTO_MICP: ::c_int = 95; +/// Semaphore Comm. security +pub const IPPROTO_SCCSP: ::c_int = 96; +/// Ethernet IP encapsulation +pub const IPPROTO_ETHERIP: ::c_int = 97; +/// encapsulation header +pub const IPPROTO_ENCAP: ::c_int = 98; +/// any private encr. scheme +pub const IPPROTO_APES: ::c_int = 99; +/// GMTP +pub const IPPROTO_GMTP: ::c_int = 100; +/// payload compression (IPComp) +pub const IPPROTO_IPCOMP: ::c_int = 108; + +/* 101-254: Partly Unassigned */ +/// Protocol Independent Mcast +pub const IPPROTO_PIM: ::c_int = 103; +/// CARP +pub const IPPROTO_CARP: ::c_int = 112; +/// PGM +pub const IPPROTO_PGM: ::c_int = 113; +/// PFSYNC +pub const IPPROTO_PFSYNC: ::c_int = 240; + +/* 255: Reserved */ +/* BSD Private, local use, namespace incursion, no longer used */ +/// divert pseudo-protocol +pub const IPPROTO_DIVERT: ::c_int = 254; +pub const IPPROTO_MAX: ::c_int = 256; +/// last return value of *_input(), meaning "all job for this pkt is done". +pub const IPPROTO_DONE: ::c_int = 257; + +/// Used by RSS: the layer3 protocol is unknown +pub const IPPROTO_UNKNOWN: ::c_int = 258; + +// sys/netinet/tcp.h +pub const TCP_SIGNATURE_ENABLE: ::c_int = 16; +pub const TCP_KEEPINIT: ::c_int = 32; +pub const TCP_FASTKEEP: ::c_int = 128; + +pub const AF_BLUETOOTH: ::c_int = 33; +pub const AF_MPLS: ::c_int = 34; +pub const AF_IEEE80211: ::c_int = 35; + +pub const PF_BLUETOOTH: ::c_int = AF_BLUETOOTH; + +pub const NET_RT_DUMP: ::c_int = 1; +pub const NET_RT_FLAGS: ::c_int = 2; +pub const NET_RT_IFLIST: ::c_int = 3; +pub const NET_RT_MAXID: ::c_int = 4; + +pub const SOMAXOPT_SIZE: ::c_int = 65536; + +pub const MSG_UNUSED09: ::c_int = 0x00000200; +pub const MSG_NOSIGNAL: ::c_int = 0x00000400; +pub const MSG_SYNC: ::c_int = 0x00000800; +pub const MSG_CMSG_CLOEXEC: ::c_int = 0x00001000; +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; +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; +pub const SIGNATURE: ::c_short = 10; +pub const DOWNTIME: ::c_short = 11; +// utmpx database types +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; +pub const LC_MONETARY_MASK: ::c_int = 1 << 2; +pub const LC_NUMERIC_MASK: ::c_int = 1 << 3; +pub const LC_TIME_MASK: ::c_int = 1 << 4; +pub const LC_MESSAGES_MASK: ::c_int = 1 << 5; +pub const LC_ALL_MASK: ::c_int = LC_COLLATE_MASK + | LC_CTYPE_MASK + | LC_MESSAGES_MASK + | LC_MONETARY_MASK + | LC_NUMERIC_MASK + | LC_TIME_MASK; + +pub const TIOCSIG: ::c_ulong = 0x2000745f; +pub const BTUARTDISC: ::c_int = 0x7; +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; + +// Constants used by "at" family of system calls. +pub const AT_FDCWD: ::c_int = 0xFFFAFDCD; // invalid file descriptor +pub const AT_SYMLINK_NOFOLLOW: ::c_int = 1; +pub const AT_REMOVEDIR: ::c_int = 2; +pub const AT_EACCESS: ::c_int = 4; +pub const AT_SYMLINK_FOLLOW: ::c_int = 8; + +pub const VCHECKPT: usize = 19; + +pub const _PC_2_SYMLINKS: ::c_int = 22; +pub const _PC_TIMESTAMP_RESOLUTION: ::c_int = 23; + +pub const _SC_V7_ILP32_OFF32: ::c_int = 122; +pub const _SC_V7_ILP32_OFFBIG: ::c_int = 123; +pub const _SC_V7_LP64_OFF64: ::c_int = 124; +pub const _SC_V7_LPBIG_OFFBIG: ::c_int = 125; +pub const _SC_THREAD_ROBUST_PRIO_INHERIT: ::c_int = 126; +pub const _SC_THREAD_ROBUST_PRIO_PROTECT: ::c_int = 127; + +pub const WCONTINUED: ::c_int = 0x4; +pub const WSTOPPED: ::c_int = 0x2; +pub const WNOWAIT: ::c_int = 0x8; +pub const WEXITED: ::c_int = 0x10; +pub const WTRAPPED: ::c_int = 0x20; + +// Similar to FreeBSD, only the standardized ones are exposed. +// There are more. +pub const P_PID: idtype_t = 0; +pub const P_PGID: idtype_t = 2; +pub const P_ALL: idtype_t = 7; + +// Values for struct rtprio (type_ field) +pub const RTP_PRIO_REALTIME: ::c_ushort = 0; +pub const RTP_PRIO_NORMAL: ::c_ushort = 1; +pub const RTP_PRIO_IDLE: ::c_ushort = 2; +pub const RTP_PRIO_THREAD: ::c_ushort = 3; + +// Flags for chflags(2) +pub const UF_NOHISTORY: ::c_ulong = 0x00000040; +pub const UF_CACHE: ::c_ulong = 0x00000080; +pub const UF_XLINK: ::c_ulong = 0x00000100; +pub const SF_NOHISTORY: ::c_ulong = 0x00400000; +pub const SF_CACHE: ::c_ulong = 0x00800000; +pub const SF_XLINK: ::c_ulong = 0x01000000; + +// timespec constants +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; + +pub const RB_PAUSE: ::c_int = 0x40000; +pub const RB_VIDEO: ::c_int = 0x20000000; + +// net/route.h +pub const RTF_CLONING: ::c_int = 0x100; +pub const RTF_PRCLONING: ::c_int = 0x10000; +pub const RTF_WASCLONED: ::c_int = 0x20000; +pub const RTF_MPLSOPS: ::c_int = 0x1000000; + +pub const RTM_VERSION: ::c_int = 7; + +pub const RTAX_MPLS1: ::c_int = 8; +pub const RTAX_MPLS2: ::c_int = 9; +pub const RTAX_MPLS3: ::c_int = 10; +pub const RTAX_MAX: ::c_int = 11; + +const_fn! { + {const} fn _CMSG_ALIGN(n: usize) -> usize { + (n + (::mem::size_of::<::c_long>() - 1)) & !(::mem::size_of::<::c_long>() - 1) + } +} + +f! { + pub fn CMSG_DATA(cmsg: *const ::cmsghdr) -> *mut ::c_uchar { + (cmsg as *mut ::c_uchar) + .offset(_CMSG_ALIGN(::mem::size_of::<::cmsghdr>()) as isize) + } + + pub {const} fn CMSG_LEN(length: ::c_uint) -> ::c_uint { + (_CMSG_ALIGN(::mem::size_of::<::cmsghdr>()) + length as usize) + as ::c_uint + } + + pub fn CMSG_NXTHDR(mhdr: *const ::msghdr, cmsg: *const ::cmsghdr) + -> *mut ::cmsghdr + { + let next = cmsg as usize + _CMSG_ALIGN((*cmsg).cmsg_len as usize) + + _CMSG_ALIGN(::mem::size_of::<::cmsghdr>()); + let max = (*mhdr).msg_control as usize + + (*mhdr).msg_controllen as usize; + if next <= max { + (cmsg as usize + _CMSG_ALIGN((*cmsg).cmsg_len as usize)) + as *mut ::cmsghdr + } else { + 0 as *mut ::cmsghdr + } + } + + pub {const} fn CMSG_SPACE(length: ::c_uint) -> ::c_uint { + (_CMSG_ALIGN(::mem::size_of::<::cmsghdr>()) + + _CMSG_ALIGN(length as usize)) as ::c_uint + } + + pub fn CPU_ZERO(cpuset: &mut cpu_set_t) -> () { + for slot in cpuset.ary.iter_mut() { + *slot = 0; + } + } + + pub fn CPU_SET(cpu: usize, cpuset: &mut cpu_set_t) -> () { + let (idx, offset) = ((cpu >> 6) & 3, cpu & 63); + cpuset.ary[idx] |= 1 << offset; + () + } + + pub fn CPU_CLR(cpu: usize, cpuset: &mut cpu_set_t) -> () { + let (idx, offset) = ((cpu >> 6) & 3, cpu & 63); + cpuset.ary[idx] &= !(1 << offset); + () + } + + 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) + } + + pub fn major(dev: ::dev_t) -> ::c_int { + ((dev >> 8) & 0xff) as ::c_int + } + + pub fn minor(dev: ::dev_t) -> ::c_int { + (dev & 0xffff00ff) as ::c_int + } +} + +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" { + pub fn __errno_location() -> *mut ::c_int; + pub fn setgrent(); + pub fn mprotect(addr: *mut ::c_void, len: ::size_t, prot: ::c_int) -> ::c_int; + + pub fn setutxdb(_type: ::c_uint, file: *mut ::c_char) -> ::c_int; + + 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, + infop: *mut ::siginfo_t, + options: ::c_int, + ) -> ::c_int; + + pub fn freelocale(loc: ::locale_t); + + pub fn lwp_rtprio( + function: ::c_int, + pid: ::pid_t, + lwpid: lwpid_t, + rtp: *mut super::rtprio, + ) -> ::c_int; + + 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 uname(buf: *mut ::utsname) -> ::c_int; + pub fn memmem( + haystack: *const ::c_void, + haystacklen: ::size_t, + 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; + pub fn getmntinfo(mntbufp: *mut *mut ::statfs, flags: ::c_int) -> ::c_int; + pub fn getmntvinfo( + mntbufp: *mut *mut ::statfs, + mntvbufp: *mut *mut ::statvfs, + flags: ::c_int, + ) -> ::c_int; +} + +#[link(name = "rt")] +extern "C" { + 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_return(aiocbp: *mut aiocb) -> ::ssize_t; + pub fn aio_suspend( + aiocb_list: *const *const aiocb, + nitems: ::c_int, + timeout: *const ::timespec, + ) -> ::c_int; + pub fn aio_write(aiocbp: *mut aiocb) -> ::c_int; + pub fn lio_listio( + mode: ::c_int, + aiocb_list: *const *mut aiocb, + 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! { + if #[cfg(libc_thread_local)] { + mod errno; + pub use self::errno::*; + } +} diff --git a/vendor/libc/src/unix/bsd/freebsdlike/freebsd/aarch64.rs b/vendor/libc/src/unix/bsd/freebsdlike/freebsd/aarch64.rs new file mode 100644 index 0000000..e8be881 --- /dev/null +++ b/vendor/libc/src/unix/bsd/freebsdlike/freebsd/aarch64.rs @@ -0,0 +1,146 @@ +pub type c_char = u8; +pub type c_long = i64; +pub type c_ulong = u64; +pub type wchar_t = u32; +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)] { + #[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_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/arm.rs b/vendor/libc/src/unix/bsd/freebsdlike/freebsd/arm.rs new file mode 100644 index 0000000..8ff500c --- /dev/null +++ b/vendor/libc/src/unix/bsd/freebsdlike/freebsd/arm.rs @@ -0,0 +1,20 @@ +pub type c_char = u8; +pub type c_long = i32; +pub type c_ulong = u32; +pub type wchar_t = u32; +pub type time_t = i64; +pub type suseconds_t = i32; +pub type register_t = i32; + +// 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 = 4096; // 1024 * 4 diff --git a/vendor/libc/src/unix/bsd/freebsdlike/freebsd/freebsd11/b32.rs b/vendor/libc/src/unix/bsd/freebsdlike/freebsd/freebsd11/b32.rs new file mode 100644 index 0000000..5c11565 --- /dev/null +++ b/vendor/libc/src/unix/bsd/freebsdlike/freebsd/freebsd11/b32.rs @@ -0,0 +1,33 @@ +#[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_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, + __unused: [u8; 8], +} + +impl ::Copy for ::stat {} +impl ::Clone for ::stat { + fn clone(&self) -> ::stat { + *self + } +} diff --git a/vendor/libc/src/unix/bsd/freebsdlike/freebsd/freebsd11/b64.rs b/vendor/libc/src/unix/bsd/freebsdlike/freebsd/freebsd11/b64.rs new file mode 100644 index 0000000..f32128f --- /dev/null +++ b/vendor/libc/src/unix/bsd/freebsdlike/freebsd/freebsd11/b64.rs @@ -0,0 +1,32 @@ +#[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_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, +} + +impl ::Copy for ::stat {} +impl ::Clone for ::stat { + fn clone(&self) -> ::stat { + *self + } +} diff --git a/vendor/libc/src/unix/bsd/freebsdlike/freebsd/freebsd11/mod.rs b/vendor/libc/src/unix/bsd/freebsdlike/freebsd/freebsd11/mod.rs new file mode 100644 index 0000000..e416ebf --- /dev/null +++ b/vendor/libc/src/unix/bsd/freebsdlike/freebsd/freebsd11/mod.rs @@ -0,0 +1,489 @@ +// APIs that were changed after FreeBSD 11 + +// The type of `nlink_t` changed from `u16` to `u64` in FreeBSD 12: +pub type nlink_t = u16; +// Type of `dev_t` changed from `u32` to `u64` in FreeBSD 12: +pub type dev_t = u32; +// Type of `ino_t` changed from `__uint32_t` to `__uint64_t` in FreeBSD 12: +pub type ino_t = u32; + +s! { + pub struct kevent { + pub ident: ::uintptr_t, + pub filter: ::c_short, + pub flags: ::c_ushort, + pub fflags: ::c_uint, + pub data: ::intptr_t, + pub udata: *mut ::c_void, + } + + pub struct shmid_ds { + pub shm_perm: ::ipc_perm, + pub shm_segsz: ::size_t, + pub shm_lpid: ::pid_t, + pub shm_cpid: ::pid_t, + // Type of shm_nattc changed from `int` to `shmatt_t` (aka `unsigned + // int`) in FreeBSD 12: + pub shm_nattch: ::c_int, + pub shm_atime: ::time_t, + 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! { + pub struct dirent { + pub d_fileno: ::ino_t, + pub d_reclen: u16, + pub d_type: u8, + // Type of `d_namlen` changed from `char` to `u16` in FreeBSD 12: + pub d_namlen: u8, + 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], + // Array length changed from 88 to 1024 in FreeBSD 12: + pub f_mntfromname: [::c_char; 88], + // 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! { + 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_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_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_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_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_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 + } +} + +f! { + pub fn major(dev: ::dev_t) -> ::c_int { + ((dev >> 8) & 0xff) as ::c_int + } + + pub fn minor(dev: ::dev_t) -> ::c_int { + (dev & 0xffff00ff) as ::c_int + } +} + +extern "C" { + // Return type ::c_int was removed in FreeBSD 12 + pub fn setgrent() -> ::c_int; + + // Type of `addr` argument changed from `const void*` to `void*` + // in FreeBSD 12 + pub fn mprotect(addr: *const ::c_void, len: ::size_t, prot: ::c_int) -> ::c_int; + + // Return type ::c_int was removed in FreeBSD 12 + pub fn freelocale(loc: ::locale_t) -> ::c_int; + + // Return type ::c_int changed to ::ssize_t in FreeBSD 12: + pub fn msgrcv( + msqid: ::c_int, + msgp: *mut ::c_void, + msgsz: ::size_t, + msgtyp: ::c_long, + msgflg: ::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(target_pointer_width = "64")] { + mod b64; + pub use self::b64::*; + } else { + mod b32; + pub use self::b32::*; + } +} diff --git a/vendor/libc/src/unix/bsd/freebsdlike/freebsd/freebsd12/mod.rs b/vendor/libc/src/unix/bsd/freebsdlike/freebsd/freebsd12/mod.rs new file mode 100644 index 0000000..c4431a6 --- /dev/null +++ b/vendor/libc/src/unix/bsd/freebsdlike/freebsd/freebsd12/mod.rs @@ -0,0 +1,530 @@ +// APIs in FreeBSD 12 that have changed since 11. + +pub type nlink_t = u64; +pub type dev_t = u64; +pub type ino_t = u64; +pub type shmatt_t = ::c_uint; + +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 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, + } + + 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, + #[cfg(target_arch = "x86")] + st_atim_ext: i32, + pub st_atime: ::time_t, + pub st_atime_nsec: ::c_long, + #[cfg(target_arch = "x86")] + st_mtim_ext: i32, + pub st_mtime: ::time_t, + pub st_mtime_nsec: ::c_long, + #[cfg(target_arch = "x86")] + st_ctim_ext: i32, + pub st_ctime: ::time_t, + pub st_ctime_nsec: ::c_long, + #[cfg(target_arch = "x86")] + st_btim_ext: i32, + 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], + } +} + +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_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 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 + } +} + +f! { + pub fn major(dev: ::dev_t) -> ::c_int { + (((dev >> 32) & 0xffffff00) | ((dev >> 8) & 0xff)) as ::c_int + } + + pub fn minor(dev: ::dev_t) -> ::c_int { + (((dev >> 24) & 0xff00) | (dev & 0xffff00ff)) as ::c_int + } +} + +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 dirname(path: *mut ::c_char) -> *mut ::c_char; + pub fn basename(path: *mut ::c_char) -> *mut ::c_char; +} + +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 new file mode 100644 index 0000000..118404e --- /dev/null +++ b/vendor/libc/src/unix/bsd/freebsdlike/freebsd/freebsd13/mod.rs @@ -0,0 +1,571 @@ +// APIs in FreeBSD 13 that have changed since 11. + +pub type nlink_t = u64; +pub type dev_t = u64; +pub type ino_t = u64; +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, + } + + 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, + #[cfg(target_arch = "x86")] + st_atim_ext: i32, + pub st_atime: ::time_t, + pub st_atime_nsec: ::c_long, + #[cfg(target_arch = "x86")] + st_mtim_ext: i32, + pub st_mtime: ::time_t, + pub st_mtime_nsec: ::c_long, + #[cfg(target_arch = "x86")] + st_ctim_ext: i32, + pub st_ctime: ::time_t, + pub st_ctime_nsec: ::c_long, + #[cfg(target_arch = "x86")] + st_btim_ext: i32, + 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], + } +} + +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 = 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 + } +} + +f! { + pub fn major(dev: ::dev_t) -> ::c_int { + (((dev >> 32) & 0xffffff00) | ((dev >> 8) & 0xff)) as ::c_int + } + + pub fn minor(dev: ::dev_t) -> ::c_int { + (((dev >> 24) & 0xff00) | (dev & 0xffff00ff)) as ::c_int + } +} + +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(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/mod.rs b/vendor/libc/src/unix/bsd/freebsdlike/freebsd/freebsd14/mod.rs new file mode 100644 index 0000000..e624dd7 --- /dev/null +++ b/vendor/libc/src/unix/bsd/freebsdlike/freebsd/freebsd14/mod.rs @@ -0,0 +1,571 @@ +// APIs in FreeBSD 14 that have changed since 11. + +pub type nlink_t = u64; +pub type dev_t = u64; +pub type ino_t = u64; +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, + } + + 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, + #[cfg(target_arch = "x86")] + st_atim_ext: i32, + pub st_atime: ::time_t, + pub st_atime_nsec: ::c_long, + #[cfg(target_arch = "x86")] + st_mtim_ext: i32, + pub st_mtime: ::time_t, + pub st_mtime_nsec: ::c_long, + #[cfg(target_arch = "x86")] + st_ctim_ext: i32, + pub st_ctime: ::time_t, + pub st_ctime_nsec: ::c_long, + #[cfg(target_arch = "x86")] + st_btim_ext: i32, + 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], + } +} + +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 + } +} + +f! { + pub fn major(dev: ::dev_t) -> ::c_int { + (((dev >> 32) & 0xffffff00) | ((dev >> 8) & 0xff)) as ::c_int + } + + pub fn minor(dev: ::dev_t) -> ::c_int { + (((dev >> 24) & 0xff00) | (dev & 0xffff00ff)) as ::c_int + } +} + +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(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..01d0b43 --- /dev/null +++ b/vendor/libc/src/unix/bsd/freebsdlike/freebsd/freebsd14/x86_64.rs @@ -0,0 +1,12 @@ +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; +pub const PROC_LA_CTL: ::c_int = ::PROC_PROCCTL_MD_MIN + 2; +pub const PROC_LA_STATUS: ::c_int = ::PROC_PROCCTL_MD_MIN + 3; +pub const PROC_LA_CTL_LA48_ON_EXEC: ::c_int = 1; +pub const PROC_LA_CTL_LA57_ON_EXEC: ::c_int = 2; +pub const PROC_LA_CTL_DEFAULT_ON_EXEC: ::c_int = 3; +pub const PROC_LA_STATUS_LA48: ::c_int = 0x01000000; +pub const PROC_LA_STATUS_LA57: ::c_int = 0x02000000; diff --git a/vendor/libc/src/unix/bsd/freebsdlike/freebsd/freebsd15/mod.rs b/vendor/libc/src/unix/bsd/freebsdlike/freebsd/freebsd15/mod.rs new file mode 100644 index 0000000..a299af7 --- /dev/null +++ b/vendor/libc/src/unix/bsd/freebsdlike/freebsd/freebsd15/mod.rs @@ -0,0 +1,571 @@ +// APIs in FreeBSD 15 that have changed since 11. + +pub type nlink_t = u64; +pub type dev_t = u64; +pub type ino_t = u64; +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, + } + + 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, + #[cfg(target_arch = "x86")] + st_atim_ext: i32, + pub st_atime: ::time_t, + pub st_atime_nsec: ::c_long, + #[cfg(target_arch = "x86")] + st_mtim_ext: i32, + pub st_mtime: ::time_t, + pub st_mtime_nsec: ::c_long, + #[cfg(target_arch = "x86")] + st_ctim_ext: i32, + pub st_ctime: ::time_t, + pub st_ctime_nsec: ::c_long, + #[cfg(target_arch = "x86")] + st_btim_ext: i32, + 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], + } +} + +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 + } +} + +f! { + pub fn major(dev: ::dev_t) -> ::c_int { + (((dev >> 32) & 0xffffff00) | ((dev >> 8) & 0xff)) as ::c_int + } + + pub fn minor(dev: ::dev_t) -> ::c_int { + (((dev >> 24) & 0xff00) | (dev & 0xffff00ff)) as ::c_int + } +} + +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(target_arch = "x86_64")] { + mod x86_64; + pub use self::x86_64::*; + } +} diff --git a/vendor/libc/src/unix/bsd/freebsdlike/freebsd/freebsd15/x86_64.rs b/vendor/libc/src/unix/bsd/freebsdlike/freebsd/freebsd15/x86_64.rs new file mode 100644 index 0000000..01d0b43 --- /dev/null +++ b/vendor/libc/src/unix/bsd/freebsdlike/freebsd/freebsd15/x86_64.rs @@ -0,0 +1,12 @@ +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; +pub const PROC_LA_CTL: ::c_int = ::PROC_PROCCTL_MD_MIN + 2; +pub const PROC_LA_STATUS: ::c_int = ::PROC_PROCCTL_MD_MIN + 3; +pub const PROC_LA_CTL_LA48_ON_EXEC: ::c_int = 1; +pub const PROC_LA_CTL_LA57_ON_EXEC: ::c_int = 2; +pub const PROC_LA_CTL_DEFAULT_ON_EXEC: ::c_int = 3; +pub const PROC_LA_STATUS_LA48: ::c_int = 0x01000000; +pub const PROC_LA_STATUS_LA57: ::c_int = 0x02000000; diff --git a/vendor/libc/src/unix/bsd/freebsdlike/freebsd/mod.rs b/vendor/libc/src/unix/bsd/freebsdlike/freebsd/mod.rs new file mode 100644 index 0000000..a15987d --- /dev/null +++ b/vendor/libc/src/unix/bsd/freebsdlike/freebsd/mod.rs @@ -0,0 +1,5953 @@ +pub type fflags_t = u32; +pub type clock_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 msglen_t = ::c_ulong; +pub type msgqnum_t = ::c_ulong; + +pub type cpulevel_t = ::c_int; +pub type cpuwhich_t = ::c_int; + +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; + +pub type eventfd_t = u64; + +#[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, + pub aio_offset: ::off_t, + pub aio_buf: *mut ::c_void, + pub aio_nbytes: ::size_t, + __unused1: [::c_int; 2], + __unused2: *mut ::c_void, + pub aio_lio_opcode: ::c_int, + pub aio_reqprio: ::c_int, + // unused 3 through 5 are the __aiocb_private structure + __unused3: ::c_long, + __unused4: ::c_long, + __unused5: *mut ::c_void, + pub aio_sigevent: sigevent + } + + pub struct jail { + pub version: u32, + pub path: *mut ::c_char, + pub hostname: *mut ::c_char, + pub jailname: *mut ::c_char, + pub ip4s: ::c_uint, + pub ip6s: ::c_uint, + pub ip4: *mut ::in_addr, + pub ip6: *mut ::in6_addr, + } + + pub struct statvfs { + pub f_bavail: ::fsblkcnt_t, + pub f_bfree: ::fsblkcnt_t, + pub f_blocks: ::fsblkcnt_t, + pub f_favail: ::fsfilcnt_t, + pub f_ffree: ::fsfilcnt_t, + pub f_files: ::fsfilcnt_t, + pub f_bsize: ::c_ulong, + pub f_flag: ::c_ulong, + pub f_frsize: ::c_ulong, + pub f_fsid: ::c_ulong, + pub f_namemax: ::c_ulong, + } + + // internal structure has changed over time + pub struct _sem { + data: [u32; 4], + } + pub struct sembuf { + pub sem_num: ::c_ushort, + pub sem_op: ::c_short, + pub sem_flg: ::c_short, + } + + pub struct msqid_ds { + pub msg_perm: ::ipc_perm, + __unused1: *mut ::c_void, + __unused2: *mut ::c_void, + 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, + pub msg_rtime: ::time_t, + pub msg_ctime: ::time_t, + } + + pub struct stack_t { + pub ss_sp: *mut ::c_void, + pub ss_size: ::size_t, + pub ss_flags: ::c_int, + } + + pub struct mmsghdr { + pub msg_hdr: ::msghdr, + pub msg_len: ::ssize_t, + } + + 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 ptrace_vm_entry { + pub pve_entry: ::c_int, + pub pve_timestamp: ::c_int, + pub pve_start: ::c_ulong, + pub pve_end: ::c_ulong, + pub pve_offset: ::c_ulong, + pub pve_prot: ::c_uint, + pub pve_pathlen: ::c_uint, + pub pve_fileid: ::c_long, + pub pve_fsid: u32, + 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(all(any(freebsd15, freebsd14), target_pointer_width = "64"))] + __bits: [::c_long; 16], + #[cfg(all(any(freebsd15, freebsd14), target_pointer_width = "32"))] + __bits: [::c_long; 32], + #[cfg(all(not(any(freebsd15, freebsd14)), target_pointer_width = "64"))] + __bits: [::c_long; 4], + #[cfg(all(not(any(freebsd15, freebsd14)), target_pointer_width = "32"))] + __bits: [::c_long; 8], + } + + 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, freebsd15))] + pub sendq: ::c_uint, + #[cfg(any(freebsd12, freebsd13, freebsd14, freebsd15))] + 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, + #[cfg(not(libc_union))] + pub ifc_ifcu: *mut ifreq, + } + + 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, + } + + // Note: this structure will change in a backwards-incompatible way in + // FreeBSD 15. + 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(any(freebsd15, freebsd14))] + pub tcpi_delivered_ce: u32, + #[cfg(any(freebsd15, freebsd14))] + pub tcpi_received_ce: u32, + #[cfg(any(freebsd15, freebsd14))] + pub __tcpi_delivered_e1_bytes: u32, + #[cfg(any(freebsd15, freebsd14))] + pub __tcpi_delivered_e0_bytes: u32, + #[cfg(any(freebsd15, freebsd14))] + pub __tcpi_delivered_ce_bytes: u32, + #[cfg(any(freebsd15, freebsd14))] + pub __tcpi_received_e1_bytes: u32, + #[cfg(any(freebsd15, freebsd14))] + pub __tcpi_received_e0_bytes: u32, + #[cfg(any(freebsd15, freebsd14))] + pub __tcpi_received_ce_bytes: u32, + #[cfg(any(freebsd15, freebsd14))] + pub tcpi_total_tlp: u32, + #[cfg(any(freebsd15, freebsd14))] + pub tcpi_total_tlp_bytes: u64, + #[cfg(any(freebsd15, freebsd14))] + pub tcpi_snd_una: u32, + #[cfg(any(freebsd15, freebsd14))] + pub tcpi_snd_max: u32, + #[cfg(any(freebsd15, freebsd14))] + pub tcpi_rcv_numsacks: u32, + #[cfg(any(freebsd15, freebsd14))] + pub tcpi_rcv_adv: u32, + #[cfg(any(freebsd15, freebsd14))] + pub tcpi_dupacks: u32, + #[cfg(freebsd14)] + pub __tcpi_pad: [u32; 10], + #[cfg(freebsd15)] + pub __tcpi_pad: [u32; 14], + #[cfg(not(any(freebsd15, 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! { + 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], + pub __ut_spare: [::c_char; 64], + } + + #[cfg(libc_union)] + pub union __c_anonymous_cr_pid { + __cr_unused: *mut ::c_void, + pub cr_pid: ::pid_t, + } + + pub struct xucred { + pub cr_version: ::c_uint, + pub cr_uid: ::uid_t, + pub cr_ngroups: ::c_short, + pub cr_groups: [::gid_t; 16], + #[cfg(libc_union)] + pub cr_pid__c_anonymous_union: __c_anonymous_cr_pid, + #[cfg(not(libc_union))] + __cr_unused1: *mut ::c_void, + } + + 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; 46], + } + + pub struct mq_attr { + pub mq_flags: ::c_long, + pub mq_maxmsg: ::c_long, + pub mq_msgsize: ::c_long, + pub mq_curmsgs: ::c_long, + __reserved: [::c_long; 4] + } + + pub struct sigevent { + pub sigev_notify: ::c_int, + pub sigev_signo: ::c_int, + pub sigev_value: ::sigval, + //The rest of the structure is actually a union. We expose only + //sigev_notify_thread_id because it's the most useful union member. + pub sigev_notify_thread_id: ::lwpid_t, + #[cfg(target_pointer_width = "64")] + __unused1: ::c_int, + __unused2: [::c_long; 7] + } + + pub struct ptsstat { + #[cfg(any(freebsd12, freebsd13, freebsd14, freebsd15))] + pub dev: u64, + #[cfg(not(any(freebsd12, freebsd13, freebsd14, freebsd15)))] + 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, + } + + 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! { + 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 sctp_error_missing_param {} + impl ::fmt::Debug for sctp_error_missing_param { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + 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 sctp_error_missing_param { + fn hash(&self, state: &mut H) { + {self.cause}.hash(state); + {self.num_missing_params}.hash(state); + {self.tpe}.hash(state); + } + } + + 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} + } + } + 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("sctp_error_stale_cookie") + .field("cause", &{self.cause}) + .field("stale_time", &{self.stale_time}) + .finish() + } + } + impl ::hash::Hash for sctp_error_stale_cookie { + fn hash(&self, state: &mut H) { + {self.cause}.hash(state); + {self.stale_time}.hash(state); + } + } + + 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); + } + } + + impl PartialEq for sctp_error_unresolv_addr { + fn eq(&self, other: &sctp_error_unresolv_addr) -> bool { + return {self.cause} == {other.cause} + } + } + impl Eq for sctp_error_unresolv_addr {} + impl ::fmt::Debug for sctp_error_unresolv_addr { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("sctp_error_unresolv_addr") + .field("cause", &{self.cause}) + .finish() + } + } + impl ::hash::Hash for sctp_error_unresolv_addr { + fn hash(&self, state: &mut H) { + {self.cause}.hash(state); + } + } + + 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 sctp_error_unrecognized_chunk {} + impl ::fmt::Debug for sctp_error_unrecognized_chunk { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("sctp_error_unrecognized_chunk") + .field("cause", &{self.cause}) + .field("ch", &{self.ch}) + .finish() + } + } + impl ::hash::Hash for sctp_error_unrecognized_chunk { + fn hash(&self, state: &mut H) { + {self.cause}.hash(state); + {self.ch}.hash(state); + } + } + + 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 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("sctp_error_no_user_data") + .field("cause", &{self.cause}) + .field("tsn", &{self.tsn}) + .finish() + } + } + impl ::hash::Hash for sctp_error_no_user_data { + fn hash(&self, state: &mut H) { + {self.cause}.hash(state); + {self.tsn}.hash(state); + } + } + + 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 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("sctp_error_invalid_hmac") + .field("cause", &{self.cause}) + .field("hmac_id", &{self.hmac_id}) + .finish() + } + } + impl ::hash::Hash for sctp_error_auth_invalid_hmac { + fn hash(&self, state: &mut H) { + {self.cause}.hash(state); + {self.hmac_id}.hash(state); + } + } + + 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); + } + } + } +} + +#[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/caprights.h +pub const CAP_RIGHTS_VERSION_00: i32 = 0; +pub const CAP_RIGHTS_VERSION: i32 = CAP_RIGHTS_VERSION_00; + +// sys/capsicum.h +macro_rules! cap_right { + ($idx:expr, $bit:expr) => { + ((1u64 << (57 + ($idx))) | ($bit)) + }; +} +pub const CAP_READ: u64 = cap_right!(0, 0x0000000000000001u64); +pub const CAP_WRITE: u64 = cap_right!(0, 0x0000000000000002u64); +pub const CAP_SEEK_TELL: u64 = cap_right!(0, 0x0000000000000004u64); +pub const CAP_SEEK: u64 = CAP_SEEK_TELL | 0x0000000000000008u64; +pub const CAP_PREAD: u64 = CAP_SEEK | CAP_READ; +pub const CAP_PWRITE: u64 = CAP_SEEK | CAP_WRITE; +pub const CAP_MMAP: u64 = cap_right!(0, 0x0000000000000010u64); +pub const CAP_MMAP_R: u64 = CAP_MMAP | CAP_SEEK | CAP_READ; +pub const CAP_MMAP_W: u64 = CAP_MMAP | CAP_SEEK | CAP_WRITE; +pub const CAP_MMAP_X: u64 = CAP_MMAP | CAP_SEEK | 0x0000000000000020u64; +pub const CAP_MMAP_RW: u64 = CAP_MMAP_R | CAP_MMAP_W; +pub const CAP_MMAP_RX: u64 = CAP_MMAP_R | CAP_MMAP_X; +pub const CAP_MMAP_WX: u64 = CAP_MMAP_W | CAP_MMAP_X; +pub const CAP_MMAP_RWX: u64 = CAP_MMAP_R | CAP_MMAP_W | CAP_MMAP_X; +pub const CAP_CREATE: u64 = cap_right!(0, 0x0000000000000040u64); +pub const CAP_FEXECVE: u64 = cap_right!(0, 0x0000000000000080u64); +pub const CAP_FSYNC: u64 = cap_right!(0, 0x0000000000000100u64); +pub const CAP_FTRUNCATE: u64 = cap_right!(0, 0x0000000000000200u64); +pub const CAP_LOOKUP: u64 = cap_right!(0, 0x0000000000000400u64); +pub const CAP_FCHDIR: u64 = cap_right!(0, 0x0000000000000800u64); +pub const CAP_FCHFLAGS: u64 = cap_right!(0, 0x0000000000001000u64); +pub const CAP_CHFLAGSAT: u64 = CAP_FCHFLAGS | CAP_LOOKUP; +pub const CAP_FCHMOD: u64 = cap_right!(0, 0x0000000000002000u64); +pub const CAP_FCHMODAT: u64 = CAP_FCHMOD | CAP_LOOKUP; +pub const CAP_FCHOWN: u64 = cap_right!(0, 0x0000000000004000u64); +pub const CAP_FCHOWNAT: u64 = CAP_FCHOWN | CAP_LOOKUP; +pub const CAP_FCNTL: u64 = cap_right!(0, 0x0000000000008000u64); +pub const CAP_FLOCK: u64 = cap_right!(0, 0x0000000000010000u64); +pub const CAP_FPATHCONF: u64 = cap_right!(0, 0x0000000000020000u64); +pub const CAP_FSCK: u64 = cap_right!(0, 0x0000000000040000u64); +pub const CAP_FSTAT: u64 = cap_right!(0, 0x0000000000080000u64); +pub const CAP_FSTATAT: u64 = CAP_FSTAT | CAP_LOOKUP; +pub const CAP_FSTATFS: u64 = cap_right!(0, 0x0000000000100000u64); +pub const CAP_FUTIMES: u64 = cap_right!(0, 0x0000000000200000u64); +pub const CAP_FUTIMESAT: u64 = CAP_FUTIMES | CAP_LOOKUP; +// Note: this was named CAP_LINKAT prior to FreeBSD 11.0. +pub const CAP_LINKAT_TARGET: u64 = CAP_LOOKUP | 0x0000000000400000u64; +pub const CAP_MKDIRAT: u64 = CAP_LOOKUP | 0x0000000000800000u64; +pub const CAP_MKFIFOAT: u64 = CAP_LOOKUP | 0x0000000001000000u64; +pub const CAP_MKNODAT: u64 = CAP_LOOKUP | 0x0000000002000000u64; +// Note: this was named CAP_RENAMEAT prior to FreeBSD 11.0. +pub const CAP_RENAMEAT_SOURCE: u64 = CAP_LOOKUP | 0x0000000004000000u64; +pub const CAP_SYMLINKAT: u64 = CAP_LOOKUP | 0x0000000008000000u64; +pub const CAP_UNLINKAT: u64 = CAP_LOOKUP | 0x0000000010000000u64; +pub const CAP_ACCEPT: u64 = cap_right!(0, 0x0000000020000000u64); +pub const CAP_BIND: u64 = cap_right!(0, 0x0000000040000000u64); +pub const CAP_CONNECT: u64 = cap_right!(0, 0x0000000080000000u64); +pub const CAP_GETPEERNAME: u64 = cap_right!(0, 0x0000000100000000u64); +pub const CAP_GETSOCKNAME: u64 = cap_right!(0, 0x0000000200000000u64); +pub const CAP_GETSOCKOPT: u64 = cap_right!(0, 0x0000000400000000u64); +pub const CAP_LISTEN: u64 = cap_right!(0, 0x0000000800000000u64); +pub const CAP_PEELOFF: u64 = cap_right!(0, 0x0000001000000000u64); +pub const CAP_RECV: u64 = CAP_READ; +pub const CAP_SEND: u64 = CAP_WRITE; +pub const CAP_SETSOCKOPT: u64 = cap_right!(0, 0x0000002000000000u64); +pub const CAP_SHUTDOWN: u64 = cap_right!(0, 0x0000004000000000u64); +pub const CAP_BINDAT: u64 = CAP_LOOKUP | 0x0000008000000000u64; +pub const CAP_CONNECTAT: u64 = CAP_LOOKUP | 0x0000010000000000u64; +pub const CAP_LINKAT_SOURCE: u64 = CAP_LOOKUP | 0x0000020000000000u64; +pub const CAP_RENAMEAT_TARGET: u64 = CAP_LOOKUP | 0x0000040000000000u64; +pub const CAP_SOCK_CLIENT: u64 = CAP_CONNECT + | CAP_GETPEERNAME + | CAP_GETSOCKNAME + | CAP_GETSOCKOPT + | CAP_PEELOFF + | CAP_RECV + | CAP_SEND + | CAP_SETSOCKOPT + | CAP_SHUTDOWN; +pub const CAP_SOCK_SERVER: u64 = CAP_ACCEPT + | CAP_BIND + | CAP_GETPEERNAME + | CAP_GETSOCKNAME + | CAP_GETSOCKOPT + | CAP_LISTEN + | CAP_PEELOFF + | CAP_RECV + | CAP_SEND + | CAP_SETSOCKOPT + | CAP_SHUTDOWN; +pub const CAP_ALL0: u64 = cap_right!(0, 0x000007FFFFFFFFFFu64); +pub const CAP_UNUSED0_44: u64 = cap_right!(0, 0x0000080000000000u64); +pub const CAP_UNUSED0_57: u64 = cap_right!(0, 0x0100000000000000u64); +pub const CAP_MAC_GET: u64 = cap_right!(1, 0x0000000000000001u64); +pub const CAP_MAC_SET: u64 = cap_right!(1, 0x0000000000000002u64); +pub const CAP_SEM_GETVALUE: u64 = cap_right!(1, 0x0000000000000004u64); +pub const CAP_SEM_POST: u64 = cap_right!(1, 0x0000000000000008u64); +pub const CAP_SEM_WAIT: u64 = cap_right!(1, 0x0000000000000010u64); +pub const CAP_EVENT: u64 = cap_right!(1, 0x0000000000000020u64); +pub const CAP_KQUEUE_EVENT: u64 = cap_right!(1, 0x0000000000000040u64); +pub const CAP_IOCTL: u64 = cap_right!(1, 0x0000000000000080u64); +pub const CAP_TTYHOOK: u64 = cap_right!(1, 0x0000000000000100u64); +pub const CAP_PDGETPID: u64 = cap_right!(1, 0x0000000000000200u64); +pub const CAP_PDWAIT: u64 = cap_right!(1, 0x0000000000000400u64); +pub const CAP_PDKILL: u64 = cap_right!(1, 0x0000000000000800u64); +pub const CAP_EXTATTR_DELETE: u64 = cap_right!(1, 0x0000000000001000u64); +pub const CAP_EXTATTR_GET: u64 = cap_right!(1, 0x0000000000002000u64); +pub const CAP_EXTATTR_LIST: u64 = cap_right!(1, 0x0000000000004000u64); +pub const CAP_EXTATTR_SET: u64 = cap_right!(1, 0x0000000000008000u64); +pub const CAP_ACL_CHECK: u64 = cap_right!(1, 0x0000000000010000u64); +pub const CAP_ACL_DELETE: u64 = cap_right!(1, 0x0000000000020000u64); +pub const CAP_ACL_GET: u64 = cap_right!(1, 0x0000000000040000u64); +pub const CAP_ACL_SET: u64 = cap_right!(1, 0x0000000000080000u64); +pub const CAP_KQUEUE_CHANGE: u64 = cap_right!(1, 0x0000000000100000u64); +pub const CAP_KQUEUE: u64 = CAP_KQUEUE_EVENT | CAP_KQUEUE_CHANGE; +pub const CAP_ALL1: u64 = cap_right!(1, 0x00000000001FFFFFu64); +pub const CAP_UNUSED1_22: u64 = cap_right!(1, 0x0000000000200000u64); +pub const CAP_UNUSED1_57: u64 = cap_right!(1, 0x0100000000000000u64); +pub const CAP_FCNTL_GETFL: u32 = 1 << 3; +pub const CAP_FCNTL_SETFL: u32 = 1 << 4; +pub const CAP_FCNTL_GETOWN: u32 = 1 << 5; +pub const CAP_FCNTL_SETOWN: u32 = 1 << 6; + +// sys/devicestat.h +pub const DEVSTAT_N_TRANS_FLAGS: ::c_int = 4; +pub const DEVSTAT_NAME_LEN: ::c_int = 16; + +// sys/cpuset.h +cfg_if! { + if #[cfg(any(freebsd15, freebsd14))] { + pub const CPU_SETSIZE: ::c_int = 1024; + } else { + pub const CPU_SETSIZE: ::c_int = 256; + } +} + +pub const SIGEV_THREAD_ID: ::c_int = 4; + +pub const EXTATTR_NAMESPACE_EMPTY: ::c_int = 0; +pub const EXTATTR_NAMESPACE_USER: ::c_int = 1; +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; +pub const SF_SYNC: ::c_int = 0x00000004; +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; +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; +pub const NI_NAMEREQD: ::c_int = 0x00000004; +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_ALIGNMENT_SHIFT: ::c_int = 24; +pub const MAP_ALIGNMENT_MASK: ::c_int = 0xff << MAP_ALIGNMENT_SHIFT; +pub const MAP_ALIGNED_SUPER: ::c_int = 1 << MAP_ALIGNMENT_SHIFT; + +pub const POSIX_FADV_NORMAL: ::c_int = 0; +pub const POSIX_FADV_RANDOM: ::c_int = 1; +pub const POSIX_FADV_SEQUENTIAL: ::c_int = 2; +pub const POSIX_FADV_WILLNEED: ::c_int = 3; +pub const POSIX_FADV_DONTNEED: ::c_int = 4; +pub const POSIX_FADV_NOREUSE: ::c_int = 5; + +pub const POLLINIGNEOF: ::c_short = 0x2000; +pub const POLLRDHUP: ::c_short = 0x4000; + +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_SIGNAL: i16 = -6; +pub const EVFILT_TIMER: i16 = -7; +pub const EVFILT_PROCDESC: i16 = -8; +pub const EVFILT_FS: i16 = -9; +pub const EVFILT_LIO: i16 = -10; +pub const EVFILT_USER: i16 = -11; +pub const EVFILT_SENDFILE: i16 = -12; +pub const EVFILT_EMPTY: i16 = -13; + +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_FLAG2: u16 = 0x4000; + +pub const EV_EOF: u16 = 0x8000; +pub const EV_ERROR: u16 = 0x4000; + +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_FILE_POLL: u32 = 0x00000002; +pub const NOTE_DELETE: u32 = 0x00000001; +pub const NOTE_WRITE: u32 = 0x00000002; +pub const NOTE_EXTEND: u32 = 0x00000004; +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; +pub const NOTE_PDATAMASK: u32 = 0x000fffff; +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_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; + +#[doc(hidden)] +#[deprecated( + since = "0.2.72", + note = "CTL_UNSPEC is deprecated. Use CTL_SYSCTL instead" +)] +pub const CTL_UNSPEC: ::c_int = 0; +pub const CTL_SYSCTL: ::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_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; +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; +pub const KERN_VERSION: ::c_int = 4; +pub const KERN_MAXVNODES: ::c_int = 5; +pub const KERN_MAXPROC: ::c_int = 6; +pub const KERN_MAXFILES: ::c_int = 7; +pub const KERN_ARGMAX: ::c_int = 8; +pub const KERN_SECURELVL: ::c_int = 9; +pub const KERN_HOSTNAME: ::c_int = 10; +pub const KERN_HOSTID: ::c_int = 11; +pub const KERN_CLOCKRATE: ::c_int = 12; +pub const KERN_VNODE: ::c_int = 13; +pub const KERN_PROC: ::c_int = 14; +pub const KERN_FILE: ::c_int = 15; +pub const KERN_PROF: ::c_int = 16; +pub const KERN_POSIX1: ::c_int = 17; +pub const KERN_NGROUPS: ::c_int = 18; +pub const KERN_JOB_CONTROL: ::c_int = 19; +pub const KERN_SAVED_IDS: ::c_int = 20; +pub const KERN_BOOTTIME: ::c_int = 21; +pub const KERN_NISDOMAINNAME: ::c_int = 22; +pub const KERN_UPDATEINTERVAL: ::c_int = 23; +pub const KERN_OSRELDATE: ::c_int = 24; +pub const KERN_NTP_PLL: ::c_int = 25; +pub const KERN_BOOTFILE: ::c_int = 26; +pub const KERN_MAXFILESPERPROC: ::c_int = 27; +pub const KERN_MAXPROCPERUID: ::c_int = 28; +pub const KERN_DUMPDEV: ::c_int = 29; +pub const KERN_IPC: ::c_int = 30; +pub const KERN_DUMMY: ::c_int = 31; +pub const KERN_PS_STRINGS: ::c_int = 32; +pub const KERN_USRSTACK: ::c_int = 33; +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; +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_PROC_RUID: ::c_int = 6; +pub const KERN_PROC_ARGS: ::c_int = 7; +pub const KERN_PROC_PROC: ::c_int = 8; +pub const KERN_PROC_SV_NAME: ::c_int = 9; +pub const KERN_PROC_RGID: ::c_int = 10; +pub const KERN_PROC_GID: ::c_int = 11; +pub const KERN_PROC_PATHNAME: ::c_int = 12; +pub const KERN_PROC_OVMMAP: ::c_int = 13; +pub const KERN_PROC_OFILEDESC: ::c_int = 14; +pub const KERN_PROC_KSTACK: ::c_int = 15; +pub const KERN_PROC_INC_THREAD: ::c_int = 0x10; +pub const KERN_PROC_VMMAP: ::c_int = 32; +pub const KERN_PROC_FILEDESC: ::c_int = 33; +pub const KERN_PROC_GROUPS: ::c_int = 34; +pub const KERN_PROC_ENV: ::c_int = 35; +pub const KERN_PROC_AUXV: ::c_int = 36; +pub const KERN_PROC_RLIMIT: ::c_int = 37; +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; +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; +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_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; +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_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; +pub const CTL_P1003_1B_MEMLOCK_RANGE: ::c_int = 4; +pub const CTL_P1003_1B_MEMORY_PROTECTION: ::c_int = 5; +pub const CTL_P1003_1B_MESSAGE_PASSING: ::c_int = 6; +pub const CTL_P1003_1B_PRIORITIZED_IO: ::c_int = 7; +pub const CTL_P1003_1B_PRIORITY_SCHEDULING: ::c_int = 8; +pub const CTL_P1003_1B_REALTIME_SIGNALS: ::c_int = 9; +pub const CTL_P1003_1B_SEMAPHORES: ::c_int = 10; +pub const CTL_P1003_1B_FSYNC: ::c_int = 11; +pub const CTL_P1003_1B_SHARED_MEMORY_OBJECTS: ::c_int = 12; +pub const CTL_P1003_1B_SYNCHRONIZED_IO: ::c_int = 13; +pub const CTL_P1003_1B_TIMERS: ::c_int = 14; +pub const CTL_P1003_1B_AIO_LISTIO_MAX: ::c_int = 15; +pub const CTL_P1003_1B_AIO_MAX: ::c_int = 16; +pub const CTL_P1003_1B_AIO_PRIO_DELTA_MAX: ::c_int = 17; +pub const CTL_P1003_1B_DELAYTIMER_MAX: ::c_int = 18; +pub const CTL_P1003_1B_MQ_OPEN_MAX: ::c_int = 19; +pub const CTL_P1003_1B_PAGESIZE: ::c_int = 20; +pub const CTL_P1003_1B_RTSIG_MAX: ::c_int = 21; +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_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; +pub const JAIL_UPDATE: ::c_int = 0x02; +pub const JAIL_ATTACH: ::c_int = 0x04; +pub const JAIL_DYING: ::c_int = 0x08; +pub const JAIL_SET_MASK: ::c_int = 0x0f; +pub const JAIL_GET_MASK: ::c_int = 0x08; +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_BINTIME: ::c_int = 0x04; +pub const SCM_REALTIME: ::c_int = 0x05; +pub const SCM_MONOTONIC: ::c_int = 0x06; +pub const SCM_TIME_INFO: ::c_int = 0x07; +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; +pub const SO_REUSEPORT_LB: ::c_int = 0x10000; +pub const SO_LABEL: ::c_int = 0x1009; +pub const SO_PEERLABEL: ::c_int = 0x1010; +pub const SO_LISTENQLIMIT: ::c_int = 0x1011; +pub const SO_LISTENQLEN: ::c_int = 0x1012; +pub const SO_LISTENINCQLEN: ::c_int = 0x1013; +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; +pub const PT_CLEARSTEP: ::c_int = 16; +pub const PT_SETSTEP: ::c_int = 17; +pub const PT_SUSPEND: ::c_int = 18; +pub const PT_RESUME: ::c_int = 19; +pub const PT_TO_SCE: ::c_int = 20; +pub const PT_TO_SCX: ::c_int = 21; +pub const PT_SYSCALL: ::c_int = 22; +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; +pub const PT_SETFPREGS: ::c_int = 36; +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; +pub const PTRACE_SCE: ::c_int = 0x0002; +pub const PTRACE_SCX: ::c_int = 0x0004; +pub const PTRACE_SYSCALL: ::c_int = PTRACE_SCE | PTRACE_SCX; +pub const PTRACE_FORK: ::c_int = 0x0008; +pub const PTRACE_LWP: ::c_int = 0x0010; +pub const PTRACE_VFORK: ::c_int = 0x0020; +pub const PTRACE_DEFAULT: ::c_int = PTRACE_EXEC; + +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 +#[deprecated(since = "0.2.149", note = "Removed in FreeBSD 14")] +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 +#[deprecated(since = "0.2.149", note = "Removed in FreeBSD 14")] +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; + +pub const dot3ChipSetWesternDigital83C690: ::c_int = 1; +pub const dot3ChipSetWesternDigital83C790: ::c_int = 2; + +// sys/netinet/in.h +// Protocols (RFC 1700) +// NOTE: These are in addition to the constants defined in src/unix/mod.rs + +// IPPROTO_IP defined in src/unix/mod.rs +/// IP6 hop-by-hop options +pub const IPPROTO_HOPOPTS: ::c_int = 0; +// IPPROTO_ICMP defined in src/unix/mod.rs +/// group mgmt protocol +pub const IPPROTO_IGMP: ::c_int = 2; +/// gateway^2 (deprecated) +pub const IPPROTO_GGP: ::c_int = 3; +/// for compatibility +pub const IPPROTO_IPIP: ::c_int = 4; +// IPPROTO_TCP defined in src/unix/mod.rs +/// Stream protocol II. +pub const IPPROTO_ST: ::c_int = 7; +/// exterior gateway protocol +pub const IPPROTO_EGP: ::c_int = 8; +/// private interior gateway +pub const IPPROTO_PIGP: ::c_int = 9; +/// BBN RCC Monitoring +pub const IPPROTO_RCCMON: ::c_int = 10; +/// network voice protocol +pub const IPPROTO_NVPII: ::c_int = 11; +/// pup +pub const IPPROTO_PUP: ::c_int = 12; +/// Argus +pub const IPPROTO_ARGUS: ::c_int = 13; +/// EMCON +pub const IPPROTO_EMCON: ::c_int = 14; +/// Cross Net Debugger +pub const IPPROTO_XNET: ::c_int = 15; +/// Chaos +pub const IPPROTO_CHAOS: ::c_int = 16; +// IPPROTO_UDP defined in src/unix/mod.rs +/// Multiplexing +pub const IPPROTO_MUX: ::c_int = 18; +/// DCN Measurement Subsystems +pub const IPPROTO_MEAS: ::c_int = 19; +/// Host Monitoring +pub const IPPROTO_HMP: ::c_int = 20; +/// Packet Radio Measurement +pub const IPPROTO_PRM: ::c_int = 21; +/// xns idp +pub const IPPROTO_IDP: ::c_int = 22; +/// Trunk-1 +pub const IPPROTO_TRUNK1: ::c_int = 23; +/// Trunk-2 +pub const IPPROTO_TRUNK2: ::c_int = 24; +/// Leaf-1 +pub const IPPROTO_LEAF1: ::c_int = 25; +/// Leaf-2 +pub const IPPROTO_LEAF2: ::c_int = 26; +/// Reliable Data +pub const IPPROTO_RDP: ::c_int = 27; +/// Reliable Transaction +pub const IPPROTO_IRTP: ::c_int = 28; +/// tp-4 w/ class negotiation +pub const IPPROTO_TP: ::c_int = 29; +/// Bulk Data Transfer +pub const IPPROTO_BLT: ::c_int = 30; +/// Network Services +pub const IPPROTO_NSP: ::c_int = 31; +/// Merit Internodal +pub const IPPROTO_INP: ::c_int = 32; +#[doc(hidden)] +#[deprecated( + since = "0.2.72", + note = "IPPROTO_SEP is deprecated. Use IPPROTO_DCCP instead" +)] +pub const IPPROTO_SEP: ::c_int = 33; +/// Datagram Congestion Control Protocol +pub const IPPROTO_DCCP: ::c_int = 33; +/// Third Party Connect +pub const IPPROTO_3PC: ::c_int = 34; +/// InterDomain Policy Routing +pub const IPPROTO_IDPR: ::c_int = 35; +/// XTP +pub const IPPROTO_XTP: ::c_int = 36; +/// Datagram Delivery +pub const IPPROTO_DDP: ::c_int = 37; +/// Control Message Transport +pub const IPPROTO_CMTP: ::c_int = 38; +/// TP++ Transport +pub const IPPROTO_TPXX: ::c_int = 39; +/// IL transport protocol +pub const IPPROTO_IL: ::c_int = 40; +// IPPROTO_IPV6 defined in src/unix/mod.rs +/// Source Demand Routing +pub const IPPROTO_SDRP: ::c_int = 42; +/// IP6 routing header +pub const IPPROTO_ROUTING: ::c_int = 43; +/// IP6 fragmentation header +pub const IPPROTO_FRAGMENT: ::c_int = 44; +/// InterDomain Routing +pub const IPPROTO_IDRP: ::c_int = 45; +/// resource reservation +pub const IPPROTO_RSVP: ::c_int = 46; +/// General Routing Encap. +pub const IPPROTO_GRE: ::c_int = 47; +/// Mobile Host Routing +pub const IPPROTO_MHRP: ::c_int = 48; +/// BHA +pub const IPPROTO_BHA: ::c_int = 49; +/// IP6 Encap Sec. Payload +pub const IPPROTO_ESP: ::c_int = 50; +/// IP6 Auth Header +pub const IPPROTO_AH: ::c_int = 51; +/// Integ. Net Layer Security +pub const IPPROTO_INLSP: ::c_int = 52; +/// IP with encryption +pub const IPPROTO_SWIPE: ::c_int = 53; +/// Next Hop Resolution +pub const IPPROTO_NHRP: ::c_int = 54; +/// IP Mobility +pub const IPPROTO_MOBILE: ::c_int = 55; +/// Transport Layer Security +pub const IPPROTO_TLSP: ::c_int = 56; +/// SKIP +pub const IPPROTO_SKIP: ::c_int = 57; +// IPPROTO_ICMPV6 defined in src/unix/mod.rs +/// IP6 no next header +pub const IPPROTO_NONE: ::c_int = 59; +/// IP6 destination option +pub const IPPROTO_DSTOPTS: ::c_int = 60; +/// any host internal protocol +pub const IPPROTO_AHIP: ::c_int = 61; +/// CFTP +pub const IPPROTO_CFTP: ::c_int = 62; +/// "hello" routing protocol +pub const IPPROTO_HELLO: ::c_int = 63; +/// SATNET/Backroom EXPAK +pub const IPPROTO_SATEXPAK: ::c_int = 64; +/// Kryptolan +pub const IPPROTO_KRYPTOLAN: ::c_int = 65; +/// Remote Virtual Disk +pub const IPPROTO_RVD: ::c_int = 66; +/// Pluribus Packet Core +pub const IPPROTO_IPPC: ::c_int = 67; +/// Any distributed FS +pub const IPPROTO_ADFS: ::c_int = 68; +/// Satnet Monitoring +pub const IPPROTO_SATMON: ::c_int = 69; +/// VISA Protocol +pub const IPPROTO_VISA: ::c_int = 70; +/// Packet Core Utility +pub const IPPROTO_IPCV: ::c_int = 71; +/// Comp. Prot. Net. Executive +pub const IPPROTO_CPNX: ::c_int = 72; +/// Comp. Prot. HeartBeat +pub const IPPROTO_CPHB: ::c_int = 73; +/// Wang Span Network +pub const IPPROTO_WSN: ::c_int = 74; +/// Packet Video Protocol +pub const IPPROTO_PVP: ::c_int = 75; +/// BackRoom SATNET Monitoring +pub const IPPROTO_BRSATMON: ::c_int = 76; +/// Sun net disk proto (temp.) +pub const IPPROTO_ND: ::c_int = 77; +/// WIDEBAND Monitoring +pub const IPPROTO_WBMON: ::c_int = 78; +/// WIDEBAND EXPAK +pub const IPPROTO_WBEXPAK: ::c_int = 79; +/// ISO cnlp +pub const IPPROTO_EON: ::c_int = 80; +/// VMTP +pub const IPPROTO_VMTP: ::c_int = 81; +/// Secure VMTP +pub const IPPROTO_SVMTP: ::c_int = 82; +/// Banyon VINES +pub const IPPROTO_VINES: ::c_int = 83; +/// TTP +pub const IPPROTO_TTP: ::c_int = 84; +/// NSFNET-IGP +pub const IPPROTO_IGP: ::c_int = 85; +/// dissimilar gateway prot. +pub const IPPROTO_DGP: ::c_int = 86; +/// TCF +pub const IPPROTO_TCF: ::c_int = 87; +/// Cisco/GXS IGRP +pub const IPPROTO_IGRP: ::c_int = 88; +/// OSPFIGP +pub const IPPROTO_OSPFIGP: ::c_int = 89; +/// Strite RPC protocol +pub const IPPROTO_SRPC: ::c_int = 90; +/// Locus Address Resoloution +pub const IPPROTO_LARP: ::c_int = 91; +/// Multicast Transport +pub const IPPROTO_MTP: ::c_int = 92; +/// AX.25 Frames +pub const IPPROTO_AX25: ::c_int = 93; +/// IP encapsulated in IP +pub const IPPROTO_IPEIP: ::c_int = 94; +/// Mobile Int.ing control +pub const IPPROTO_MICP: ::c_int = 95; +/// Semaphore Comm. security +pub const IPPROTO_SCCSP: ::c_int = 96; +/// Ethernet IP encapsulation +pub const IPPROTO_ETHERIP: ::c_int = 97; +/// encapsulation header +pub const IPPROTO_ENCAP: ::c_int = 98; +/// any private encr. scheme +pub const IPPROTO_APES: ::c_int = 99; +/// GMTP +pub const IPPROTO_GMTP: ::c_int = 100; +/// payload compression (IPComp) +pub const IPPROTO_IPCOMP: ::c_int = 108; +/// SCTP +pub const IPPROTO_SCTP: ::c_int = 132; +/// IPv6 Mobility Header +pub const IPPROTO_MH: ::c_int = 135; +/// UDP-Lite +pub const IPPROTO_UDPLITE: ::c_int = 136; +/// IP6 Host Identity Protocol +pub const IPPROTO_HIP: ::c_int = 139; +/// IP6 Shim6 Protocol +pub const IPPROTO_SHIM6: ::c_int = 140; + +/* 101-254: Partly Unassigned */ +/// Protocol Independent Mcast +pub const IPPROTO_PIM: ::c_int = 103; +/// CARP +pub const IPPROTO_CARP: ::c_int = 112; +/// PGM +pub const IPPROTO_PGM: ::c_int = 113; +/// MPLS-in-IP +pub const IPPROTO_MPLS: ::c_int = 137; +/// PFSYNC +pub const IPPROTO_PFSYNC: ::c_int = 240; + +/* 255: Reserved */ +/* BSD Private, local use, namespace incursion, no longer used */ +/// OLD divert pseudo-proto +pub const IPPROTO_OLD_DIVERT: ::c_int = 254; +pub const IPPROTO_MAX: ::c_int = 256; +/// last return value of *_input(), meaning "all job for this pkt is done". +pub const IPPROTO_DONE: ::c_int = 257; + +/* Only used internally, so can be outside the range of valid IP protocols. */ +/// divert pseudo-protocol +pub const IPPROTO_DIVERT: ::c_int = 258; +/// SeND pseudo-protocol +pub const IPPROTO_SEND: ::c_int = 259; + +// sys/netinet/TCP.h +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; +#[deprecated(since = "0.2.160", note = "Removed in FreeBSD 15")] +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; +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; +pub const IPV6_ORIGDSTADDR: ::c_int = 72; +pub const IPV6_RECVORIGDSTADDR: ::c_int = IPV6_ORIGDSTADDR; + +pub const PF_SLOW: ::c_int = AF_SLOW; +pub const PF_SCLUSTER: ::c_int = AF_SCLUSTER; +pub const PF_ARP: ::c_int = AF_ARP; +pub const PF_BLUETOOTH: ::c_int = AF_BLUETOOTH; +pub const PF_IEEE80211: ::c_int = AF_IEEE80211; +pub const PF_INET_SDP: ::c_int = AF_INET_SDP; +pub const PF_INET6_SDP: ::c_int = AF_INET6_SDP; + +pub const NET_RT_DUMP: ::c_int = 1; +pub const NET_RT_FLAGS: ::c_int = 2; +pub const NET_RT_IFLIST: ::c_int = 3; +pub const NET_RT_IFMALIST: ::c_int = 4; +pub const NET_RT_IFLISTL: ::c_int = 5; + +// System V IPC +pub const IPC_INFO: ::c_int = 3; +pub const MSG_NOERROR: ::c_int = 0o10000; +pub const SHM_LOCK: ::c_int = 11; +pub const SHM_UNLOCK: ::c_int = 12; +pub const SHM_STAT: ::c_int = 13; +pub const SHM_INFO: ::c_int = 14; +pub const SHM_ANON: *mut ::c_char = 1 as *mut ::c_char; + +// The *_MAXID constants never should've been used outside of the +// FreeBSD base system. And with the exception of CTL_P1003_1B_MAXID, +// they were all removed in svn r262489. They remain here for backwards +// compatibility only, and are scheduled to be removed in libc 1.0.0. +#[doc(hidden)] +#[deprecated(since = "0.2.54", note = "Removed in FreeBSD 11")] +pub const CTL_MAXID: ::c_int = 10; +#[doc(hidden)] +#[deprecated(since = "0.2.54", note = "Removed in FreeBSD 11")] +pub const KERN_MAXID: ::c_int = 38; +#[doc(hidden)] +#[deprecated(since = "0.2.54", note = "Removed in FreeBSD 11")] +pub const HW_MAXID: ::c_int = 13; +#[doc(hidden)] +#[deprecated(since = "0.2.54", note = "Removed in FreeBSD 11")] +pub const USER_MAXID: ::c_int = 21; +#[doc(hidden)] +#[deprecated(since = "0.2.74", note = "Removed in FreeBSD 13")] +pub const CTL_P1003_1B_MAXID: ::c_int = 26; + +pub const MSG_NOTIFICATION: ::c_int = 0x00002000; +pub const MSG_NBIO: ::c_int = 0x00004000; +pub const MSG_COMPAT: ::c_int = 0x00008000; +pub const MSG_CMSG_CLOEXEC: ::c_int = 0x00040000; +pub const MSG_NOSIGNAL: ::c_int = 0x20000; +pub const MSG_WAITFORONE: ::c_int = 0x00080000; + +// 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 SHUTDOWN_TIME: ::c_short = 8; +// utmp database types +pub const UTXDB_ACTIVE: ::c_int = 0; +pub const UTXDB_LASTLOGIN: ::c_int = 1; +pub const UTXDB_LOG: ::c_int = 2; + +pub const LC_COLLATE_MASK: ::c_int = 1 << 0; +pub const LC_CTYPE_MASK: ::c_int = 1 << 1; +pub const LC_MONETARY_MASK: ::c_int = 1 << 2; +pub const LC_NUMERIC_MASK: ::c_int = 1 << 3; +pub const LC_TIME_MASK: ::c_int = 1 << 4; +pub const LC_MESSAGES_MASK: ::c_int = 1 << 5; +pub const LC_ALL_MASK: ::c_int = LC_COLLATE_MASK + | LC_CTYPE_MASK + | LC_MESSAGES_MASK + | LC_MONETARY_MASK + | LC_NUMERIC_MASK + | LC_TIME_MASK; + +pub const WSTOPPED: ::c_int = 2; // same as WUNTRACED +pub const WCONTINUED: ::c_int = 4; +pub const WNOWAIT: ::c_int = 8; +pub const WEXITED: ::c_int = 16; +pub const WTRAPPED: ::c_int = 32; + +// FreeBSD defines a great many more of these, we only expose the +// standardized ones. +pub const P_PID: idtype_t = 0; +pub const P_PGID: idtype_t = 2; +pub const P_ALL: idtype_t = 7; + +pub const UTIME_OMIT: c_long = -2; +pub const UTIME_NOW: c_long = -1; + +pub const B460800: ::speed_t = 460800; +pub const B921600: ::speed_t = 921600; + +pub const AT_FDCWD: ::c_int = -100; +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 AT_CANARY: ::c_int = 16; +pub const AT_OSRELDATE: ::c_int = 18; +pub const AT_NCPUS: ::c_int = 19; +pub const AT_PAGESIZES: ::c_int = 20; +pub const AT_TIMEKEEP: ::c_int = 22; +pub const AT_HWCAP: ::c_int = 25; +pub const AT_HWCAP2: ::c_int = 26; +pub const AT_USRSTACKBASE: ::c_int = 35; +pub const AT_USRSTACKLIM: ::c_int = 36; + +pub const TABDLY: ::tcflag_t = 0x00000004; +pub const TAB0: ::tcflag_t = 0x00000000; +pub const TAB3: ::tcflag_t = 0x00000004; + +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; +pub const PD_ALLOWED_AT_FORK: ::c_int = PD_DAEMON | PD_CLOEXEC; + +// Values for struct rtprio (type_ field) +pub const RTP_PRIO_REALTIME: ::c_ushort = 2; +pub const RTP_PRIO_NORMAL: ::c_ushort = 3; +pub const RTP_PRIO_IDLE: ::c_ushort = 4; + +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; + +// Flags for chflags(2) +pub const UF_SYSTEM: ::c_ulong = 0x00000080; +pub const UF_SPARSE: ::c_ulong = 0x00000100; +pub const UF_OFFLINE: ::c_ulong = 0x00000200; +pub const UF_REPARSE: ::c_ulong = 0x00000400; +pub const UF_ARCHIVE: ::c_ulong = 0x00000800; +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_RDAHEAD: ::c_int = 16; +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 realhostname* api +pub const HOSTNAME_FOUND: ::c_int = 0; +pub const HOSTNAME_INCORRECTNAME: ::c_int = 1; +pub const HOSTNAME_INVALIDADDR: ::c_int = 2; +pub const HOSTNAME_INVALIDNAME: ::c_int = 3; + +// For rfork +pub const RFFDG: ::c_int = 4; +pub const RFPROC: ::c_int = 16; +pub const RFMEM: ::c_int = 32; +pub const RFNOWAIT: ::c_int = 64; +pub const RFCFDG: ::c_int = 4096; +pub const RFTHREAD: ::c_int = 8192; +pub const RFSIGSHARE: ::c_int = 16384; +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; + +// net/route.h +pub const RTF_LLDATA: ::c_int = 0x400; +pub const RTF_FIXEDMTU: ::c_int = 0x80000; + +pub const RTM_VERSION: ::c_int = 5; + +pub const RTAX_MAX: ::c_int = 8; + +// 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; + +pub const KENV_DUMP_LOADER: ::c_int = 4; +pub const KENV_DUMP_STATIC: ::c_int = 5; + +pub const RB_PAUSE: ::c_int = 0x100000; +pub const RB_REROOT: ::c_int = 0x200000; +pub const RB_POWERCYCLE: ::c_int = 0x400000; +pub const RB_PROBE: ::c_int = 0x10000000; +pub const RB_MULTIPLE: ::c_int = 0x20000000; + +// sys/time.h +pub const CLOCK_BOOTTIME: ::clockid_t = ::CLOCK_UPTIME; +pub const CLOCK_REALTIME_COARSE: ::clockid_t = ::CLOCK_REALTIME_FAST; +pub const CLOCK_MONOTONIC_COARSE: ::clockid_t = ::CLOCK_MONOTONIC_FAST; + +// sys/timerfd.h + +pub const TFD_NONBLOCK: ::c_int = ::O_NONBLOCK; +pub const TFD_CLOEXEC: ::c_int = O_CLOEXEC; +pub const TFD_TIMER_ABSTIME: ::c_int = 0x01; +pub const TFD_TIMER_CANCEL_ON_SET: ::c_int = 0x02; + +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 + } +} + +f! { + pub fn CMSG_DATA(cmsg: *const ::cmsghdr) -> *mut ::c_uchar { + (cmsg as *mut ::c_uchar) + .offset(_ALIGN(::mem::size_of::<::cmsghdr>()) as isize) + } + + pub {const} fn CMSG_LEN(length: ::c_uint) -> ::c_uint { + _ALIGN(::mem::size_of::<::cmsghdr>()) as ::c_uint + length + } + + pub fn CMSG_NXTHDR(mhdr: *const ::msghdr, cmsg: *const ::cmsghdr) + -> *mut ::cmsghdr + { + if cmsg.is_null() { + return ::CMSG_FIRSTHDR(mhdr); + }; + let next = cmsg as usize + _ALIGN((*cmsg).cmsg_len as usize) + + _ALIGN(::mem::size_of::<::cmsghdr>()); + let max = (*mhdr).msg_control as usize + + (*mhdr).msg_controllen as usize; + if next > max { + 0 as *mut ::cmsghdr + } else { + (cmsg as usize + _ALIGN((*cmsg).cmsg_len as usize)) + as *mut ::cmsghdr + } + } + + pub {const} fn CMSG_SPACE(length: ::c_uint) -> ::c_uint { + (_ALIGN(::mem::size_of::<::cmsghdr>()) + _ALIGN(length as usize)) + 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 + } else { + 0 + }; + ::mem::size_of::() + ::mem::size_of::<::gid_t>() * ngrps + } + + pub fn uname(buf: *mut ::utsname) -> ::c_int { + __xuname(256, buf as *mut ::c_void) + } + + pub fn CPU_ZERO(cpuset: &mut cpuset_t) -> () { + for slot in cpuset.__bits.iter_mut() { + *slot = 0; + } + } + + pub fn CPU_FILL(cpuset: &mut cpuset_t) -> () { + for slot in cpuset.__bits.iter_mut() { + *slot = !0; + } + } + + pub fn CPU_SET(cpu: usize, cpuset: &mut cpuset_t) -> () { + 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 = 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: &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 + } + + pub fn PROT_MAX(x: ::c_int) -> ::c_int { + x << 16 + } + + pub fn PROT_MAX_EXTRACT(x: ::c_int) -> ::c_int { + (x >> 16) & (::PROT_READ | ::PROT_WRITE | ::PROT_EXEC) + } +} + +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, + nitems: ::c_int, + 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, + attrnamespace: ::c_int, + attrname: *const ::c_char, + ) -> ::c_int; + pub fn extattr_delete_file( + path: *const ::c_char, + attrnamespace: ::c_int, + attrname: *const ::c_char, + ) -> ::c_int; + pub fn extattr_delete_link( + path: *const ::c_char, + attrnamespace: ::c_int, + attrname: *const ::c_char, + ) -> ::c_int; + pub fn extattr_get_fd( + fd: ::c_int, + attrnamespace: ::c_int, + attrname: *const ::c_char, + data: *mut ::c_void, + nbytes: ::size_t, + ) -> ::ssize_t; + pub fn extattr_get_file( + path: *const ::c_char, + attrnamespace: ::c_int, + attrname: *const ::c_char, + data: *mut ::c_void, + nbytes: ::size_t, + ) -> ::ssize_t; + pub fn extattr_get_link( + path: *const ::c_char, + attrnamespace: ::c_int, + attrname: *const ::c_char, + data: *mut ::c_void, + nbytes: ::size_t, + ) -> ::ssize_t; + 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_set_fd( + fd: ::c_int, + attrnamespace: ::c_int, + attrname: *const ::c_char, + data: *const ::c_void, + nbytes: ::size_t, + ) -> ::ssize_t; + pub fn extattr_set_file( + path: *const ::c_char, + attrnamespace: ::c_int, + attrname: *const ::c_char, + data: *const ::c_void, + nbytes: ::size_t, + ) -> ::ssize_t; + pub fn extattr_set_link( + path: *const ::c_char, + attrnamespace: ::c_int, + attrname: *const ::c_char, + data: *const ::c_void, + 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; + pub fn jail_get(iov: *mut ::iovec, niov: ::c_uint, flags: ::c_int) -> ::c_int; + pub fn jail_set(iov: *mut ::iovec, niov: ::c_uint, flags: ::c_int) -> ::c_int; + + pub fn lio_listio( + mode: ::c_int, + aiocb_list: *const *mut aiocb, + nitems: ::c_int, + sevp: *mut sigevent, + ) -> ::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 getutxuser(user: *const ::c_char) -> *mut utmpx; + pub fn setutxdb(_type: ::c_int, file: *const ::c_char) -> ::c_int; + + pub fn aio_waitcomplete(iocbp: *mut *mut aiocb, timeout: *mut ::timespec) -> ::ssize_t; + pub fn mq_getfd_np(mqd: ::mqd_t) -> ::c_int; + + pub fn waitid( + idtype: idtype_t, + id: ::id_t, + 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( + msqid: ::c_int, + msgp: *const ::c_void, + msgsz: ::size_t, + msgflg: ::c_int, + ) -> ::c_int; + pub fn cfmakesane(termios: *mut ::termios); + + pub fn pdfork(fdp: *mut ::c_int, flags: ::c_int) -> ::pid_t; + pub fn pdgetpid(fd: ::c_int, pidp: *mut ::pid_t) -> ::c_int; + pub fn pdkill(fd: ::c_int, signum: ::c_int) -> ::c_int; + + pub fn rtprio_thread(function: ::c_int, lwpid: ::lwpid_t, rtp: *mut super::rtprio) -> ::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 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; + #[cfg_attr(all(target_os = "freebsd", freebsd11), link_name = "fstatfs@FBSD_1.0")] + pub fn fstatfs(fd: ::c_int, buf: *mut statfs) -> ::c_int; + + pub fn dup3(src: ::c_int, dst: ::c_int, flags: ::c_int) -> ::c_int; + pub fn __xuname(nmln: ::c_int, buf: *mut ::c_void) -> ::c_int; + + pub fn sendmmsg( + sockfd: ::c_int, + msgvec: *mut ::mmsghdr, + vlen: ::size_t, + flags: ::c_int, + ) -> ::ssize_t; + pub fn recvmmsg( + sockfd: ::c_int, + msgvec: *mut ::mmsghdr, + vlen: ::size_t, + flags: ::c_int, + timeout: *const ::timespec, + ) -> ::ssize_t; + pub fn memmem( + haystack: *const ::c_void, + haystacklen: ::size_t, + needle: *const ::c_void, + 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( + level: cpulevel_t, + which: cpuwhich_t, + id: ::id_t, + setsize: ::size_t, + mask: *mut cpuset_t, + ) -> ::c_int; + pub fn cpuset_setaffinity( + level: cpulevel_t, + which: cpuwhich_t, + id: ::id_t, + 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; + pub fn cap_rights_is_valid(rights: *const cap_rights_t) -> bool; + pub fn cap_rights_limit(fd: ::c_int, rights: *const cap_rights_t) -> ::c_int; + pub fn cap_rights_merge(dst: *mut cap_rights_t, src: *const cap_rights_t) -> *mut cap_rights_t; + 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_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 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 eventfd_read(fd: ::c_int, value: *mut eventfd_t) -> ::c_int; + pub fn eventfd_write(fd: ::c_int, value: eventfd_t) -> ::c_int; + + pub fn fdatasync(fd: ::c_int) -> ::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; + + pub fn timerfd_create(clockid: ::c_int, 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, + flags: ::c_int, + new_value: *const itimerspec, + old_value: *mut itimerspec, + ) -> ::c_int; + pub fn closefrom(lowfd: ::c_int); + pub fn close_range(lowfd: ::c_uint, highfd: ::c_uint, flags: ::c_int) -> ::c_int; + + pub fn execvpe( + file: *const ::c_char, + argv: *const *const ::c_char, + envp: *const *const ::c_char, + ) -> ::c_int; +} + +#[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")] +extern "C" { + pub fn extattr_namespace_to_string( + attrnamespace: ::c_int, + string: *mut *mut ::c_char, + ) -> ::c_int; + pub fn extattr_string_to_namespace( + string: *const ::c_char, + attrnamespace: *mut ::c_int, + ) -> ::c_int; + pub fn realhostname(host: *mut ::c_char, hsize: ::size_t, ip: *const ::in_addr) -> ::c_int; + pub fn realhostname_sa( + host: *mut ::c_char, + hsize: ::size_t, + 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(freebsd15)] { + mod freebsd15; + pub use self::freebsd15::*; + } else if #[cfg(freebsd14)] { + mod freebsd14; + pub use self::freebsd14::*; + } else if #[cfg(freebsd13)] { + mod freebsd13; + pub use self::freebsd13::*; + } else if #[cfg(freebsd12)] { + mod freebsd12; + pub use self::freebsd12::*; + } else if #[cfg(any(freebsd10, freebsd11))] { + mod freebsd11; + pub use self::freebsd11::*; + } else { + // Unknown freebsd version + } +} + +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")] { + mod aarch64; + pub use self::aarch64::*; + } else if #[cfg(target_arch = "arm")] { + mod arm; + pub use self::arm::*; + } 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..f84062b --- /dev/null +++ b/vendor/libc/src/unix/bsd/freebsdlike/freebsd/powerpc.rs @@ -0,0 +1,21 @@ +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; + +// 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/powerpc64.rs b/vendor/libc/src/unix/bsd/freebsdlike/freebsd/powerpc64.rs new file mode 100644 index 0000000..69cf4c5 --- /dev/null +++ b/vendor/libc/src/unix/bsd/freebsdlike/freebsd/powerpc64.rs @@ -0,0 +1,21 @@ +pub type c_char = u8; +pub type c_long = i64; +pub type c_ulong = u64; +pub type wchar_t = i32; +pub type time_t = i64; +pub type suseconds_t = i64; +pub type register_t = i64; + +// 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 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 new file mode 100644 index 0000000..31a660e --- /dev/null +++ b/vendor/libc/src/unix/bsd/freebsdlike/freebsd/x86.rs @@ -0,0 +1,178 @@ +pub type c_char = i8; +pub type c_long = i32; +pub type c_ulong = u32; +pub type wchar_t = i32; +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 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 +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 = 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 + +pub const KINFO_FILE_SIZE: ::c_int = 1392; diff --git a/vendor/libc/src/unix/bsd/freebsdlike/freebsd/x86_64/align.rs b/vendor/libc/src/unix/bsd/freebsdlike/freebsd/x86_64/align.rs new file mode 100644 index 0000000..3a016a0 --- /dev/null +++ b/vendor/libc/src/unix/bsd/freebsdlike/freebsd/x86_64/align.rs @@ -0,0 +1,197 @@ +use {c_long, register_t}; + +s_no_extra_traits! { + #[allow(missing_debug_implementations)] + #[repr(align(16))] + pub struct max_align_t { + priv_: [f64; 4] + } + + #[repr(align(16))] + pub struct mcontext_t { + pub mc_onstack: register_t, + pub mc_rdi: register_t, + pub mc_rsi: register_t, + pub mc_rdx: register_t, + pub mc_rcx: register_t, + pub mc_r8: register_t, + pub mc_r9: register_t, + pub mc_rax: register_t, + pub mc_rbx: register_t, + pub mc_rbp: register_t, + pub mc_r10: register_t, + pub mc_r11: register_t, + pub mc_r12: register_t, + pub mc_r13: register_t, + pub mc_r14: register_t, + pub mc_r15: register_t, + pub mc_trapno: u32, + pub mc_fs: u16, + pub mc_gs: u16, + pub mc_addr: register_t, + pub mc_flags: u32, + pub mc_es: u16, + pub mc_ds: u16, + pub mc_err: register_t, + pub mc_rip: register_t, + pub mc_cs: register_t, + pub mc_rflags: register_t, + pub mc_rsp: register_t, + pub mc_ss: register_t, + pub mc_len: c_long, + pub mc_fpformat: c_long, + pub mc_ownedfp: c_long, + pub mc_fpstate: [c_long; 64], + pub mc_fsbase: register_t, + pub mc_gsbase: register_t, + pub mc_xfpustate: register_t, + pub mc_xfpustate_len: register_t, + pub mc_spare: [c_long; 4], + } +} + +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_rdi == other.mc_rdi && + self.mc_rsi == other.mc_rsi && + self.mc_rdx == other.mc_rdx && + self.mc_rcx == other.mc_rcx && + self.mc_r8 == other.mc_r8 && + self.mc_r9 == other.mc_r9 && + self.mc_rax == other.mc_rax && + self.mc_rbx == other.mc_rbx && + self.mc_rbp == other.mc_rbp && + self.mc_r10 == other.mc_r10 && + self.mc_r11 == other.mc_r11 && + self.mc_r12 == other.mc_r12 && + self.mc_r13 == other.mc_r13 && + self.mc_r14 == other.mc_r14 && + self.mc_r15 == other.mc_r15 && + self.mc_trapno == other.mc_trapno && + self.mc_fs == other.mc_fs && + self.mc_gs == other.mc_gs && + self.mc_addr == other.mc_addr && + self.mc_flags == other.mc_flags && + self.mc_es == other.mc_es && + self.mc_ds == other.mc_ds && + self.mc_err == other.mc_err && + self.mc_rip == other.mc_rip && + self.mc_cs == other.mc_cs && + self.mc_rflags == other.mc_rflags && + self.mc_rsp == other.mc_rsp && + 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_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_spare == other.mc_spare + } + } + 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_rdi", &self.mc_rdi) + .field("mc_rsi", &self.mc_rsi) + .field("mc_rdx", &self.mc_rdx) + .field("mc_rcx", &self.mc_rcx) + .field("mc_r8", &self.mc_r8) + .field("mc_r9", &self.mc_r9) + .field("mc_rax", &self.mc_rax) + .field("mc_rbx", &self.mc_rbx) + .field("mc_rbp", &self.mc_rbp) + .field("mc_r10", &self.mc_r10) + .field("mc_r11", &self.mc_r11) + .field("mc_r12", &self.mc_r12) + .field("mc_r13", &self.mc_r13) + .field("mc_r14", &self.mc_r14) + .field("mc_r15", &self.mc_r15) + .field("mc_trapno", &self.mc_trapno) + .field("mc_fs", &self.mc_fs) + .field("mc_gs", &self.mc_gs) + .field("mc_addr", &self.mc_addr) + .field("mc_flags", &self.mc_flags) + .field("mc_es", &self.mc_es) + .field("mc_ds", &self.mc_ds) + .field("mc_err", &self.mc_err) + .field("mc_rip", &self.mc_rip) + .field("mc_cs", &self.mc_cs) + .field("mc_rflags", &self.mc_rflags) + .field("mc_rsp", &self.mc_rsp) + .field("mc_ss", &self.mc_ss) + .field("mc_len", &self.mc_len) + .field("mc_fpformat", &self.mc_fpformat) + .field("mc_ownedfp", &self.mc_ownedfp) + // FIXME: .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_spare", &self.mc_spare) + .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_r12.hash(state); + self.mc_r13.hash(state); + self.mc_r14.hash(state); + self.mc_r15.hash(state); + self.mc_trapno.hash(state); + self.mc_fs.hash(state); + self.mc_gs.hash(state); + self.mc_addr.hash(state); + self.mc_flags.hash(state); + self.mc_es.hash(state); + self.mc_ds.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_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_spare.hash(state); + } + } + } +} + +s! { + 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], + } +} 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 new file mode 100644 index 0000000..fb45979 --- /dev/null +++ b/vendor/libc/src/unix/bsd/freebsdlike/freebsd/x86_64/mod.rs @@ -0,0 +1,273 @@ +pub type c_char = i8; +pub type c_long = i64; +pub type c_ulong = u64; +pub type wchar_t = i32; +pub type time_t = i64; +pub type suseconds_t = i64; +pub type register_t = i64; + +s! { + pub struct reg32 { + pub r_fs: u32, + pub r_es: u32, + pub r_ds: u32, + pub r_edi: u32, + pub r_esi: u32, + pub r_ebp: u32, + pub r_isp: u32, + pub r_ebx: u32, + pub r_edx: u32, + pub r_ecx: u32, + pub r_eax: u32, + pub r_trapno: u32, + pub r_err: u32, + pub r_eip: u32, + pub r_cs: u32, + pub r_eflags: u32, + pub r_esp: u32, + pub r_ss: u32, + pub r_gs: u32, + } + + pub struct reg { + pub r_r15: i64, + pub r_r14: i64, + pub r_r13: i64, + pub r_r12: i64, + pub r_r11: i64, + pub r_r10: i64, + pub r_r9: i64, + pub r_r8: i64, + pub r_rdi: i64, + pub r_rsi: i64, + pub r_rbp: i64, + pub r_rbx: i64, + pub r_rdx: i64, + pub r_rcx: i64, + pub r_rax: i64, + pub r_trapno: u32, + pub r_fs: u16, + pub r_gs: u16, + pub r_err: u32, + pub r_es: u16, + pub r_ds: u16, + pub r_rip: i64, + pub r_cs: i64, + pub r_rflags: i64, + pub r_rsp: i64, + pub r_ss: i64, + } +} + +s_no_extra_traits! { + pub struct fpreg32 { + pub fpr_env: [u32; 7], + pub fpr_acc: [[u8; 10]; 8], + pub fpr_ex_sw: u32, + pub fpr_pad: [u8; 64], + } + + pub struct fpreg { + pub fpr_env: [u64; 4], + pub fpr_acc: [[u8; 16]; 8], + pub fpr_xacc: [[u8; 16]; 16], + pub fpr_spare: [u64; 12], + } + + pub struct xmmreg { + pub xmm_env: [u32; 8], + pub xmm_acc: [[u8; 16]; 8], + 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, + } +} + +cfg_if! { + if #[cfg(feature = "extra_traits")] { + impl PartialEq for fpreg32 { + fn eq(&self, other: &fpreg32) -> bool { + self.fpr_env == other.fpr_env && + self.fpr_acc == other.fpr_acc && + self.fpr_ex_sw == other.fpr_ex_sw && + self.fpr_pad + .iter() + .zip(other.fpr_pad.iter()) + .all(|(a,b)| a == b) + } + } + impl Eq for fpreg32 {} + impl ::fmt::Debug for fpreg32 { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("fpreg32") + .field("fpr_env", &&self.fpr_env[..]) + .field("fpr_acc", &self.fpr_acc) + .field("fpr_ex_sw", &self.fpr_ex_sw) + .field("fpr_pad", &&self.fpr_pad[..]) + .finish() + } + } + impl ::hash::Hash for fpreg32 { + fn hash(&self, state: &mut H) { + self.fpr_env.hash(state); + self.fpr_acc.hash(state); + self.fpr_ex_sw.hash(state); + self.fpr_pad.hash(state); + } + } + + impl PartialEq for fpreg { + fn eq(&self, other: &fpreg) -> bool { + self.fpr_env == other.fpr_env && + self.fpr_acc == other.fpr_acc && + self.fpr_xacc == other.fpr_xacc && + self.fpr_spare == other.fpr_spare + } + } + impl Eq for fpreg {} + impl ::fmt::Debug for fpreg { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("fpreg") + .field("fpr_env", &self.fpr_env) + .field("fpr_acc", &self.fpr_acc) + .field("fpr_xacc", &self.fpr_xacc) + .field("fpr_spare", &self.fpr_spare) + .finish() + } + } + impl ::hash::Hash for fpreg { + fn hash(&self, state: &mut H) { + self.fpr_env.hash(state); + self.fpr_acc.hash(state); + self.fpr_xacc.hash(state); + self.fpr_spare.hash(state); + } + } + + impl PartialEq for xmmreg { + fn eq(&self, other: &xmmreg) -> bool { + self.xmm_env == other.xmm_env && + self.xmm_acc == other.xmm_acc && + self.xmm_reg == other.xmm_reg && + self.xmm_pad + .iter() + .zip(other.xmm_pad.iter()) + .all(|(a,b)| a == b) + } + } + impl Eq for xmmreg {} + impl ::fmt::Debug for xmmreg { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("xmmreg") + .field("xmm_env", &self.xmm_env) + .field("xmm_acc", &self.xmm_acc) + .field("xmm_reg", &self.xmm_reg) + .field("xmm_pad", &&self.xmm_pad[..]) + .finish() + } + } + impl ::hash::Hash for xmmreg { + fn hash(&self, state: &mut H) { + self.xmm_env.hash(state); + self.xmm_acc.hash(state); + self.xmm_reg.hash(state); + 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() + } + } + } +} + +// 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 MAP_32BIT: ::c_int = 0x00080000; +pub const MINSIGSTKSZ: ::size_t = 2048; // 512 * 4 + +pub const _MC_HASSEGS: u32 = 0x1; +pub const _MC_HASBASES: u32 = 0x2; +pub const _MC_HASFPXSTATE: u32 = 0x4; +pub const _MC_FLAG_MASK: u32 = _MC_HASSEGS | _MC_HASBASES | _MC_HASFPXSTATE; + +pub const _MC_FPFMT_NODEV: c_long = 0x10000; +pub const _MC_FPFMT_XMM: c_long = 0x10002; +pub const _MC_FPOWNED_NONE: c_long = 0x20000; +pub const _MC_FPOWNED_FPU: c_long = 0x20001; +pub const _MC_FPOWNED_PCB: c_long = 0x20002; + +pub const KINFO_FILE_SIZE: ::c_int = 1392; + +cfg_if! { + if #[cfg(libc_align)] { + mod align; + pub use self::align::*; + } +} diff --git a/vendor/libc/src/unix/bsd/freebsdlike/mod.rs b/vendor/libc/src/unix/bsd/freebsdlike/mod.rs new file mode 100644 index 0000000..86ade55 --- /dev/null +++ b/vendor/libc/src/unix/bsd/freebsdlike/mod.rs @@ -0,0 +1,1947 @@ +pub type mode_t = u16; +pub type pthread_attr_t = *mut ::c_void; +pub type rlim_t = i64; +pub type pthread_mutex_t = *mut ::c_void; +pub type pthread_mutexattr_t = *mut ::c_void; +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_key_t = ::c_int; +pub type tcflag_t = ::c_uint; +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 + +pub type Elf32_Addr = u32; +pub type Elf32_Half = u16; +pub type Elf32_Lword = u64; +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_Lword = u64; +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 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; + type Elf_Half = Elf64_Half; + type Elf_Phdr = Elf64_Phdr; + } else if #[cfg(target_pointer_width = "32")] { + type Elf_Addr = Elf32_Addr; + type Elf_Half = Elf32_Half; + type Elf_Phdr = Elf32_Phdr; + } +} + +// link.h + +#[cfg_attr(feature = "extra_traits", derive(Debug))] +pub enum timezone {} +impl ::Copy for timezone {} +impl ::Clone for timezone { + fn clone(&self) -> timezone { + *self + } +} + +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 + } +} + +s! { + pub struct in_addr { + pub s_addr: ::in_addr_t, + } + + pub struct ip_mreq { + pub imr_multiaddr: in_addr, + pub imr_interface: in_addr, + } + + pub struct 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, + pub gl_offs: ::size_t, + pub gl_flags: ::c_int, + pub gl_pathv: *mut *mut ::c_char, + __unused3: *mut ::c_void, + __unused4: *mut ::c_void, + __unused5: *mut ::c_void, + __unused6: *mut ::c_void, + __unused7: *mut ::c_void, + __unused8: *mut ::c_void, + } + + 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 sigset_t { + bits: [u32; 4], + } + + 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_value: ::sigval, + _pad1: ::c_long, + _pad2: [::c_int; 7], + } + + pub struct sigaction { + pub sa_sigaction: ::sighandler_t, + pub sa_flags: ::c_int, + pub sa_mask: sigset_t, + } + + pub struct sched_param { + pub sched_priority: ::c_int, + } + + 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 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: [::c_char; 8], + } + + 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 c_ispeed: ::speed_t, + pub c_ospeed: ::speed_t, + } + + pub struct flock { + pub l_start: ::off_t, + pub l_len: ::off_t, + pub l_pid: ::pid_t, + pub l_type: ::c_short, + pub l_whence: ::c_short, + #[cfg(not(target_os = "dragonfly"))] + pub l_sysid: ::c_int, + } + + pub struct sf_hdtr { + pub headers: *mut ::iovec, + pub hdr_cnt: ::c_int, + pub trailers: *mut ::iovec, + pub trl_cnt: ::c_int, + } + + 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 cmsgcred { + pub cmcred_pid: ::pid_t, + pub cmcred_uid: ::uid_t, + pub cmcred_euid: ::uid_t, + pub cmcred_gid: ::gid_t, + pub cmcred_ngroups: ::c_short, + pub cmcred_groups: [::gid_t; CMGROUP_MAX], + } + + pub struct rtprio { + pub type_: ::c_ushort, + pub prio: ::c_ushort, + } + + pub struct in6_pktinfo { + pub ipi6_addr: ::in6_addr, + pub ipi6_ifindex: ::c_uint, + } + + 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 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 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 struct ntptimeval { + pub time: ::timespec, + pub maxerror: ::c_long, + pub esterror: ::c_long, + pub tai: ::c_long, + 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, + pub piod_addr: *mut ::c_void, + pub piod_len: ::size_t, + } + + // bpf.h + + pub struct bpf_program { + pub bf_len: ::c_uint, + pub bf_insns: *mut bpf_insn, + } + + pub struct bpf_stat { + pub bs_recv: ::c_uint, + pub bs_drop: ::c_uint, + } + + 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: ::c_ushort, + } + + pub struct bpf_insn { + pub code: ::c_ushort, + pub jt: ::c_uchar, + pub jf: ::c_uchar, + pub k: u32, + } + + pub struct bpf_dltlist { + bfl_len: ::c_uint, + bfl_list: *mut ::c_uint, + } + + // elf.h + + 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, + } + + // link.h + + 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, + pub dlpi_adds: ::c_ulonglong, + pub dlpi_subs: ::c_ulonglong, + 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! { + pub struct sockaddr_storage { + pub ss_len: u8, + pub ss_family: ::sa_family_t, + __ss_pad1: [u8; 6], + __ss_align: i64, + __ss_pad2: [u8; 112], + } +} + +cfg_if! { + if #[cfg(feature = "extra_traits")] { + impl PartialEq for sockaddr_storage { + fn eq(&self, other: &sockaddr_storage) -> bool { + self.ss_len == other.ss_len + && self.ss_family == other.ss_family + && self.__ss_pad1 == other.__ss_pad1 + && self.__ss_align == other.__ss_align + && self + .__ss_pad2 + .iter() + .zip(other.__ss_pad2.iter()) + .all(|(a, b)| a == b) + } + } + impl Eq for sockaddr_storage {} + impl ::fmt::Debug for sockaddr_storage { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("sockaddr_storage") + .field("ss_len", &self.ss_len) + .field("ss_family", &self.ss_family) + .field("__ss_pad1", &self.__ss_pad1) + .field("__ss_align", &self.__ss_align) + // FIXME: .field("__ss_pad2", &self.__ss_pad2) + .finish() + } + } + impl ::hash::Hash for sockaddr_storage { + fn hash(&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); + } + } + } +} + +// Non-public helper constant +cfg_if! { + if #[cfg(all(not(libc_const_size_of), target_pointer_width = "32"))] { + const SIZEOF_LONG: usize = 4; + } else if #[cfg(all(not(libc_const_size_of), target_pointer_width = "64"))] { + const SIZEOF_LONG: usize = 8; + } else if #[cfg(libc_const_size_of)] { + const SIZEOF_LONG: usize = ::mem::size_of::<::c_long>(); + } +} + +#[deprecated( + since = "0.2.64", + note = "Can vary at runtime. Use sysconf(3) instead" +)] +pub const AIO_LISTIO_MAX: ::c_int = 16; +pub const AIO_CANCELED: ::c_int = 1; +pub const AIO_NOTCANCELED: ::c_int = 2; +pub const AIO_ALLDONE: ::c_int = 3; +pub const LIO_NOP: ::c_int = 0; +pub const LIO_WRITE: ::c_int = 1; +pub const LIO_READ: ::c_int = 2; +pub const LIO_WAIT: ::c_int = 1; +pub const LIO_NOWAIT: ::c_int = 0; + +pub const SIGEV_NONE: ::c_int = 0; +pub const SIGEV_SIGNAL: ::c_int = 1; +pub const SIGEV_THREAD: ::c_int = 2; +pub const SIGEV_KEVENT: ::c_int = 3; + +pub const CODESET: ::nl_item = 0; +pub const D_T_FMT: ::nl_item = 1; +pub const D_FMT: ::nl_item = 2; +pub const T_FMT: ::nl_item = 3; +pub const T_FMT_AMPM: ::nl_item = 4; +pub const AM_STR: ::nl_item = 5; +pub const PM_STR: ::nl_item = 6; + +pub const DAY_1: ::nl_item = 7; +pub const DAY_2: ::nl_item = 8; +pub const DAY_3: ::nl_item = 9; +pub const DAY_4: ::nl_item = 10; +pub const DAY_5: ::nl_item = 11; +pub const DAY_6: ::nl_item = 12; +pub const DAY_7: ::nl_item = 13; + +pub const ABDAY_1: ::nl_item = 14; +pub const ABDAY_2: ::nl_item = 15; +pub const ABDAY_3: ::nl_item = 16; +pub const ABDAY_4: ::nl_item = 17; +pub const ABDAY_5: ::nl_item = 18; +pub const ABDAY_6: ::nl_item = 19; +pub const ABDAY_7: ::nl_item = 20; + +pub const MON_1: ::nl_item = 21; +pub const MON_2: ::nl_item = 22; +pub const MON_3: ::nl_item = 23; +pub const MON_4: ::nl_item = 24; +pub const MON_5: ::nl_item = 25; +pub const MON_6: ::nl_item = 26; +pub const MON_7: ::nl_item = 27; +pub const MON_8: ::nl_item = 28; +pub const MON_9: ::nl_item = 29; +pub const MON_10: ::nl_item = 30; +pub const MON_11: ::nl_item = 31; +pub const MON_12: ::nl_item = 32; + +pub const ABMON_1: ::nl_item = 33; +pub const ABMON_2: ::nl_item = 34; +pub const ABMON_3: ::nl_item = 35; +pub const ABMON_4: ::nl_item = 36; +pub const ABMON_5: ::nl_item = 37; +pub const ABMON_6: ::nl_item = 38; +pub const ABMON_7: ::nl_item = 39; +pub const ABMON_8: ::nl_item = 40; +pub const ABMON_9: ::nl_item = 41; +pub const ABMON_10: ::nl_item = 42; +pub const ABMON_11: ::nl_item = 43; +pub const ABMON_12: ::nl_item = 44; + +pub const ERA: ::nl_item = 45; +pub const ERA_D_FMT: ::nl_item = 46; +pub const ERA_D_T_FMT: ::nl_item = 47; +pub const ERA_T_FMT: ::nl_item = 48; +pub const ALT_DIGITS: ::nl_item = 49; + +pub const RADIXCHAR: ::nl_item = 50; +pub const THOUSEP: ::nl_item = 51; + +pub const YESEXPR: ::nl_item = 52; +pub const NOEXPR: ::nl_item = 53; + +pub const YESSTR: ::nl_item = 54; +pub const NOSTR: ::nl_item = 55; + +pub const CRNCYSTR: ::nl_item = 56; + +pub const D_MD_ORDER: ::nl_item = 57; + +pub const ALTMON_1: ::nl_item = 58; +pub const ALTMON_2: ::nl_item = 59; +pub const ALTMON_3: ::nl_item = 60; +pub const ALTMON_4: ::nl_item = 61; +pub const ALTMON_5: ::nl_item = 62; +pub const ALTMON_6: ::nl_item = 63; +pub const ALTMON_7: ::nl_item = 64; +pub const ALTMON_8: ::nl_item = 65; +pub const ALTMON_9: ::nl_item = 66; +pub const ALTMON_10: ::nl_item = 67; +pub const ALTMON_11: ::nl_item = 68; +pub const ALTMON_12: ::nl_item = 69; + +pub const EXIT_FAILURE: ::c_int = 1; +pub const EXIT_SUCCESS: ::c_int = 0; +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_DATA: ::c_int = 3; +pub const SEEK_HOLE: ::c_int = 4; +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 L_tmpnam: ::c_uint = 1024; +pub const TMP_MAX: ::c_uint = 308915776; + +pub const O_NOCTTY: ::c_int = 32768; +pub const O_DIRECT: ::c_int = 0x00010000; + +pub const S_IFIFO: mode_t = 4096; +pub const S_IFCHR: mode_t = 8192; +pub const S_IFBLK: mode_t = 24576; +pub const S_IFDIR: mode_t = 16384; +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 = 61440; +pub const S_IEXEC: mode_t = 64; +pub const S_IWRITE: mode_t = 128; +pub const S_IREAD: mode_t = 256; +pub const S_IRWXU: mode_t = 448; +pub const S_IXUSR: mode_t = 64; +pub const S_IWUSR: mode_t = 128; +pub const S_IRUSR: mode_t = 256; +pub const S_IRWXG: mode_t = 56; +pub const S_IXGRP: mode_t = 8; +pub const S_IWGRP: mode_t = 16; +pub const S_IRGRP: mode_t = 32; +pub const S_IRWXO: mode_t = 7; +pub const S_IXOTH: mode_t = 1; +pub const S_IWOTH: mode_t = 2; +pub const S_IROTH: mode_t = 4; +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; +pub const STDIN_FILENO: ::c_int = 0; +pub const STDOUT_FILENO: ::c_int = 1; +pub const STDERR_FILENO: ::c_int = 2; +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 = 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; +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 SIGPIPE: ::c_int = 13; +pub const SIGALRM: ::c_int = 14; +pub const SIGTERM: ::c_int = 15; + +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 = 0x0000; +pub const MAP_SHARED: ::c_int = 0x0001; +pub const MAP_PRIVATE: ::c_int = 0x0002; +pub const MAP_FIXED: ::c_int = 0x0010; +pub const MAP_ANON: ::c_int = 0x1000; +pub const MAP_ANONYMOUS: ::c_int = MAP_ANON; + +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; + +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 EDEADLK: ::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 EAGAIN: ::c_int = 35; +pub const EWOULDBLOCK: ::c_int = 35; +pub const EINPROGRESS: ::c_int = 36; +pub const EALREADY: ::c_int = 37; +pub const ENOTSOCK: ::c_int = 38; +pub const EDESTADDRREQ: ::c_int = 39; +pub const EMSGSIZE: ::c_int = 40; +pub const EPROTOTYPE: ::c_int = 41; +pub const ENOPROTOOPT: ::c_int = 42; +pub const EPROTONOSUPPORT: ::c_int = 43; +pub const ESOCKTNOSUPPORT: ::c_int = 44; +pub const EOPNOTSUPP: ::c_int = 45; +pub const ENOTSUP: ::c_int = EOPNOTSUPP; +pub const EPFNOSUPPORT: ::c_int = 46; +pub const EAFNOSUPPORT: ::c_int = 47; +pub const EADDRINUSE: ::c_int = 48; +pub const EADDRNOTAVAIL: ::c_int = 49; +pub const ENETDOWN: ::c_int = 50; +pub const ENETUNREACH: ::c_int = 51; +pub const ENETRESET: ::c_int = 52; +pub const ECONNABORTED: ::c_int = 53; +pub const ECONNRESET: ::c_int = 54; +pub const ENOBUFS: ::c_int = 55; +pub const EISCONN: ::c_int = 56; +pub const ENOTCONN: ::c_int = 57; +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 ELOOP: ::c_int = 62; +pub const ENAMETOOLONG: ::c_int = 63; +pub const EHOSTDOWN: ::c_int = 64; +pub const EHOSTUNREACH: ::c_int = 65; +pub const ENOTEMPTY: ::c_int = 66; +pub const EPROCLIM: ::c_int = 67; +pub const EUSERS: ::c_int = 68; +pub const EDQUOT: ::c_int = 69; +pub const ESTALE: ::c_int = 70; +pub const EREMOTE: ::c_int = 71; +pub const EBADRPC: ::c_int = 72; +pub const ERPCMISMATCH: ::c_int = 73; +pub const EPROGUNAVAIL: ::c_int = 74; +pub const EPROGMISMATCH: ::c_int = 75; +pub const EPROCUNAVAIL: ::c_int = 76; +pub const ENOLCK: ::c_int = 77; +pub const ENOSYS: ::c_int = 78; +pub const EFTYPE: ::c_int = 79; +pub const EAUTH: ::c_int = 80; +pub const ENEEDAUTH: ::c_int = 81; +pub const EIDRM: ::c_int = 82; +pub const ENOMSG: ::c_int = 83; +pub const EOVERFLOW: ::c_int = 84; +pub const ECANCELED: ::c_int = 85; +pub const EILSEQ: ::c_int = 86; +pub const ENOATTR: ::c_int = 87; +pub const EDOOFUS: ::c_int = 88; +pub const EBADMSG: ::c_int = 89; +pub const EMULTIHOP: ::c_int = 90; +pub const ENOLINK: ::c_int = 91; +pub const EPROTO: ::c_int = 92; + +pub const POLLSTANDARD: ::c_short = ::POLLIN + | ::POLLPRI + | ::POLLOUT + | ::POLLRDNORM + | ::POLLRDBAND + | ::POLLWRBAND + | ::POLLERR + | ::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; +pub const EAI_FAMILY: ::c_int = 5; +pub const EAI_MEMORY: ::c_int = 6; +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 = 14; + +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 SIGTRAP: ::c_int = 5; + +pub const GLOB_APPEND: ::c_int = 0x0001; +pub const GLOB_DOOFFS: ::c_int = 0x0002; +pub const GLOB_ERR: ::c_int = 0x0004; +pub const GLOB_MARK: ::c_int = 0x0008; +pub const GLOB_NOCHECK: ::c_int = 0x0010; +pub const GLOB_NOSORT: ::c_int = 0x0020; +pub const GLOB_NOESCAPE: ::c_int = 0x2000; + +pub const GLOB_NOSPACE: ::c_int = -1; +pub const GLOB_ABORTED: ::c_int = -2; +pub const GLOB_NOMATCH: ::c_int = -3; + +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_MADV_DONTNEED: ::c_int = 4; + +pub const PTHREAD_BARRIER_SERIAL_THREAD: ::c_int = -1; +pub const PTHREAD_PROCESS_PRIVATE: ::c_int = 0; +pub const PTHREAD_PROCESS_SHARED: ::c_int = 1; +pub const PTHREAD_CREATE_JOINABLE: ::c_int = 0; +pub const PTHREAD_CREATE_DETACHED: ::c_int = 1; + +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_MEMLOCK: ::c_int = 6; +pub const RLIMIT_NPROC: ::c_int = 7; +pub const RLIMIT_NOFILE: ::c_int = 8; +pub const RLIMIT_SBSIZE: ::c_int = 9; +pub const RLIMIT_VMEM: ::c_int = 10; +pub const RLIMIT_AS: ::c_int = RLIMIT_VMEM; +pub const RLIM_INFINITY: rlim_t = 0x7fff_ffff_ffff_ffff; + +pub const RUSAGE_SELF: ::c_int = 0; +pub const RUSAGE_CHILDREN: ::c_int = -1; + +pub const CLOCK_REALTIME: ::clockid_t = 0; +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_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_MONOTONIC_PRECISE: ::clockid_t = 11; +pub const CLOCK_MONOTONIC_FAST: ::clockid_t = 12; +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; + +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 MADV_FREE: ::c_int = 5; +pub const MADV_NOSYNC: ::c_int = 6; +pub const MADV_AUTOSYNC: ::c_int = 7; +pub const MADV_NOCORE: ::c_int = 8; +pub const MADV_CORE: ::c_int = 9; + +pub const MINCORE_INCORE: ::c_int = 0x1; +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 AF_UNSPEC: ::c_int = 0; +pub const AF_LOCAL: ::c_int = 1; +pub const AF_UNIX: ::c_int = AF_LOCAL; +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_NETBIOS: ::c_int = 6; +pub const AF_ISO: ::c_int = 7; +pub const AF_OSI: ::c_int = AF_ISO; +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 AF_HYLINK: ::c_int = 15; +pub const AF_APPLETALK: ::c_int = 16; +pub const AF_ROUTE: ::c_int = 17; +pub const AF_LINK: ::c_int = 18; +pub const pseudo_AF_XTP: ::c_int = 19; +pub const AF_COIP: ::c_int = 20; +pub const AF_CNT: ::c_int = 21; +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_ISDN: ::c_int = 26; +pub const AF_E164: ::c_int = AF_ISDN; +pub const pseudo_AF_KEY: ::c_int = 27; +pub const AF_INET6: ::c_int = 28; +pub const AF_NATM: ::c_int = 29; +pub const AF_ATM: ::c_int = 30; +pub const pseudo_AF_HDRCMPLT: ::c_int = 31; +pub const AF_NETGRAPH: ::c_int = 32; + +pub const PF_UNSPEC: ::c_int = AF_UNSPEC; +pub const PF_LOCAL: ::c_int = AF_LOCAL; +pub const PF_UNIX: ::c_int = PF_LOCAL; +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_NETBIOS: ::c_int = AF_NETBIOS; +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 = pseudo_AF_XTP; +pub const PF_COIP: ::c_int = AF_COIP; +pub const PF_CNT: ::c_int = AF_CNT; +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_ISDN: ::c_int = AF_ISDN; +pub const PF_KEY: ::c_int = pseudo_AF_KEY; +pub const PF_INET6: ::c_int = AF_INET6; +pub const PF_NATM: ::c_int = AF_NATM; +pub const PF_ATM: ::c_int = AF_ATM; +pub const PF_NETGRAPH: ::c_int = AF_NETGRAPH; + +pub const PIOD_READ_D: ::c_int = 1; +pub const PIOD_WRITE_D: ::c_int = 2; +pub const PIOD_READ_I: ::c_int = 3; +pub const PIOD_WRITE_I: ::c_int = 4; + +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_ATTACH: ::c_int = 10; +pub const PT_DETACH: ::c_int = 11; +pub const PT_IO: ::c_int = 12; + +pub const SOMAXCONN: ::c_int = 128; + +pub const MSG_OOB: ::c_int = 0x00000001; +pub const MSG_PEEK: ::c_int = 0x00000002; +pub const MSG_DONTROUTE: ::c_int = 0x00000004; +pub const MSG_EOR: ::c_int = 0x00000008; +pub const MSG_TRUNC: ::c_int = 0x00000010; +pub const MSG_CTRUNC: ::c_int = 0x00000020; +pub const MSG_WAITALL: ::c_int = 0x00000040; +pub const MSG_DONTWAIT: ::c_int = 0x00000080; +pub const MSG_EOF: ::c_int = 0x00000100; + +pub const SCM_TIMESTAMP: ::c_int = 0x02; +pub const SCM_CREDS: ::c_int = 0x03; + +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_SEQPACKET: ::c_int = 5; +pub const SOCK_CLOEXEC: ::c_int = 0x10000000; +pub const SOCK_NONBLOCK: ::c_int = 0x20000000; +pub const SOCK_MAXADDRLEN: ::c_int = 255; +pub const IP_TTL: ::c_int = 4; +pub const IP_HDRINCL: ::c_int = 2; +pub const IP_RECVDSTADDR: ::c_int = 7; +pub const IP_SENDSRCADDR: ::c_int = IP_RECVDSTADDR; +pub const IP_ADD_MEMBERSHIP: ::c_int = 12; +pub const IP_DROP_MEMBERSHIP: ::c_int = 13; +pub const IP_RECVIF: ::c_int = 20; +pub const IP_RECVTTL: ::c_int = 65; +pub const IPV6_RECVHOPLIMIT: ::c_int = 37; +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_RECVPKTINFO: ::c_int = 36; +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 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; +pub const TCP_KEEPIDLE: ::c_int = 256; +pub const TCP_KEEPINTVL: ::c_int = 512; +pub const TCP_KEEPCNT: ::c_int = 1024; + +pub const SOL_SOCKET: ::c_int = 0xffff; +pub const SO_DEBUG: ::c_int = 0x01; +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_TIMESTAMP: ::c_int = 0x0400; +pub const SO_NOSIGPIPE: ::c_int = 0x0800; +pub const SO_ACCEPTFILTER: ::c_int = 0x1000; +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 LOCAL_PEERCRED: ::c_int = 1; + +// net/route.h +pub const RTF_XRESOLVE: ::c_int = 0x200; +pub const RTF_LLINFO: ::c_int = 0x400; +pub const RTF_PROTO3: ::c_int = 0x40000; +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 RTM_LOCK: ::c_int = 0x8; +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_NEWMADDR: ::c_int = 0xf; +pub const RTM_DELMADDR: ::c_int = 0x10; +pub const RTM_IFANNOUNCE: ::c_int = 0x11; +pub const RTM_IEEE80211: ::c_int = 0x12; + +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 = 1; +pub const LOCK_EX: ::c_int = 2; +pub const LOCK_NB: ::c_int = 4; +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, unused in DragonFlyBSD" +)] +pub const MAP_RENAME: ::c_int = 0x0020; +#[doc(hidden)] +#[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; +pub const MAP_NOSYNC: ::c_int = 0x0800; +pub const MAP_NOCORE: ::c_int = 0x020000; + +pub const IPPROTO_RAW: ::c_int = 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 = 7; +pub const _PC_NO_TRUNC: ::c_int = 8; +pub const _PC_VDISABLE: ::c_int = 9; +pub const _PC_ALLOC_SIZE_MIN: ::c_int = 10; +pub const _PC_FILESIZEBITS: ::c_int = 12; +pub const _PC_REC_INCR_XFER_SIZE: ::c_int = 14; +pub const _PC_REC_MAX_XFER_SIZE: ::c_int = 15; +pub const _PC_REC_MIN_XFER_SIZE: ::c_int = 16; +pub const _PC_REC_XFER_ALIGN: ::c_int = 17; +pub const _PC_SYMLINK_MAX: ::c_int = 18; +pub const _PC_MIN_HOLE_SIZE: ::c_int = 21; +pub const _PC_ASYNC_IO: ::c_int = 53; +pub const _PC_PRIO_IO: ::c_int = 54; +pub const _PC_SYNC_IO: ::c_int = 55; +pub const _PC_ACL_EXTENDED: ::c_int = 59; +pub const _PC_ACL_PATH_MAX: ::c_int = 60; +pub const _PC_CAP_PRESENT: ::c_int = 61; +pub const _PC_INF_PRESENT: ::c_int = 62; +pub const _PC_MAC_PRESENT: ::c_int = 63; + +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_BC_BASE_MAX: ::c_int = 9; +pub const _SC_BC_DIM_MAX: ::c_int = 10; +pub const _SC_BC_SCALE_MAX: ::c_int = 11; +pub const _SC_BC_STRING_MAX: ::c_int = 12; +pub const _SC_COLL_WEIGHTS_MAX: ::c_int = 13; +pub const _SC_EXPR_NEST_MAX: ::c_int = 14; +pub const _SC_LINE_MAX: ::c_int = 15; +pub const _SC_RE_DUP_MAX: ::c_int = 16; +pub const _SC_2_VERSION: ::c_int = 17; +pub const _SC_2_C_BIND: ::c_int = 18; +pub const _SC_2_C_DEV: ::c_int = 19; +pub const _SC_2_CHAR_TERM: ::c_int = 20; +pub const _SC_2_FORT_DEV: ::c_int = 21; +pub const _SC_2_FORT_RUN: ::c_int = 22; +pub const _SC_2_LOCALEDEF: ::c_int = 23; +pub const _SC_2_SW_DEV: ::c_int = 24; +pub const _SC_2_UPE: ::c_int = 25; +pub const _SC_STREAM_MAX: ::c_int = 26; +pub const _SC_TZNAME_MAX: ::c_int = 27; +pub const _SC_ASYNCHRONOUS_IO: ::c_int = 28; +pub const _SC_MAPPED_FILES: ::c_int = 29; +pub const _SC_MEMLOCK: ::c_int = 30; +pub const _SC_MEMLOCK_RANGE: ::c_int = 31; +pub const _SC_MEMORY_PROTECTION: ::c_int = 32; +pub const _SC_MESSAGE_PASSING: ::c_int = 33; +pub const _SC_PRIORITIZED_IO: ::c_int = 34; +pub const _SC_PRIORITY_SCHEDULING: ::c_int = 35; +pub const _SC_REALTIME_SIGNALS: ::c_int = 36; +pub const _SC_SEMAPHORES: ::c_int = 37; +pub const _SC_FSYNC: ::c_int = 38; +pub const _SC_SHARED_MEMORY_OBJECTS: ::c_int = 39; +pub const _SC_SYNCHRONIZED_IO: ::c_int = 40; +pub const _SC_TIMERS: ::c_int = 41; +pub const _SC_AIO_LISTIO_MAX: ::c_int = 42; +pub const _SC_AIO_MAX: ::c_int = 43; +pub const _SC_AIO_PRIO_DELTA_MAX: ::c_int = 44; +pub const _SC_DELAYTIMER_MAX: ::c_int = 45; +pub const _SC_MQ_OPEN_MAX: ::c_int = 46; +pub const _SC_PAGESIZE: ::c_int = 47; +pub const _SC_PAGE_SIZE: ::c_int = _SC_PAGESIZE; +pub const _SC_RTSIG_MAX: ::c_int = 48; +pub const _SC_SEM_NSEMS_MAX: ::c_int = 49; +pub const _SC_SEM_VALUE_MAX: ::c_int = 50; +pub const _SC_SIGQUEUE_MAX: ::c_int = 51; +pub const _SC_TIMER_MAX: ::c_int = 52; +pub const _SC_IOV_MAX: ::c_int = 56; +pub const _SC_NPROCESSORS_CONF: ::c_int = 57; +pub const _SC_2_PBS: ::c_int = 59; +pub const _SC_2_PBS_ACCOUNTING: ::c_int = 60; +pub const _SC_2_PBS_CHECKPOINT: ::c_int = 61; +pub const _SC_2_PBS_LOCATE: ::c_int = 62; +pub const _SC_2_PBS_MESSAGE: ::c_int = 63; +pub const _SC_2_PBS_TRACK: ::c_int = 64; +pub const _SC_ADVISORY_INFO: ::c_int = 65; +pub const _SC_BARRIERS: ::c_int = 66; +pub const _SC_CLOCK_SELECTION: ::c_int = 67; +pub const _SC_CPUTIME: ::c_int = 68; +pub const _SC_FILE_LOCKING: ::c_int = 69; +pub const _SC_NPROCESSORS_ONLN: ::c_int = 58; +pub const _SC_GETGR_R_SIZE_MAX: ::c_int = 70; +pub const _SC_GETPW_R_SIZE_MAX: ::c_int = 71; +pub const _SC_HOST_NAME_MAX: ::c_int = 72; +pub const _SC_LOGIN_NAME_MAX: ::c_int = 73; +pub const _SC_MONOTONIC_CLOCK: ::c_int = 74; +pub const _SC_MQ_PRIO_MAX: ::c_int = 75; +pub const _SC_READER_WRITER_LOCKS: ::c_int = 76; +pub const _SC_REGEXP: ::c_int = 77; +pub const _SC_SHELL: ::c_int = 78; +pub const _SC_SPAWN: ::c_int = 79; +pub const _SC_SPIN_LOCKS: ::c_int = 80; +pub const _SC_SPORADIC_SERVER: ::c_int = 81; +pub const _SC_THREAD_ATTR_STACKADDR: ::c_int = 82; +pub const _SC_THREAD_ATTR_STACKSIZE: ::c_int = 83; +pub const _SC_THREAD_DESTRUCTOR_ITERATIONS: ::c_int = 85; +pub const _SC_THREAD_KEYS_MAX: ::c_int = 86; +pub const _SC_THREAD_PRIO_INHERIT: ::c_int = 87; +pub const _SC_THREAD_PRIO_PROTECT: ::c_int = 88; +pub const _SC_THREAD_PRIORITY_SCHEDULING: ::c_int = 89; +pub const _SC_THREAD_PROCESS_SHARED: ::c_int = 90; +pub const _SC_THREAD_SAFE_FUNCTIONS: ::c_int = 91; +pub const _SC_THREAD_SPORADIC_SERVER: ::c_int = 92; +pub const _SC_THREAD_STACK_MIN: ::c_int = 93; +pub const _SC_THREAD_THREADS_MAX: ::c_int = 94; +pub const _SC_TIMEOUTS: ::c_int = 95; +pub const _SC_THREADS: ::c_int = 96; +pub const _SC_TRACE: ::c_int = 97; +pub const _SC_TRACE_EVENT_FILTER: ::c_int = 98; +pub const _SC_TRACE_INHERIT: ::c_int = 99; +pub const _SC_TRACE_LOG: ::c_int = 100; +pub const _SC_TTY_NAME_MAX: ::c_int = 101; +pub const _SC_TYPED_MEMORY_OBJECTS: ::c_int = 102; +pub const _SC_V6_ILP32_OFF32: ::c_int = 103; +pub const _SC_V6_ILP32_OFFBIG: ::c_int = 104; +pub const _SC_V6_LP64_OFF64: ::c_int = 105; +pub const _SC_V6_LPBIG_OFFBIG: ::c_int = 106; +pub const _SC_ATEXIT_MAX: ::c_int = 107; +pub const _SC_XOPEN_CRYPT: ::c_int = 108; +pub const _SC_XOPEN_ENH_I18N: ::c_int = 109; +pub const _SC_XOPEN_LEGACY: ::c_int = 110; +pub const _SC_XOPEN_REALTIME: ::c_int = 111; +pub const _SC_XOPEN_REALTIME_THREADS: ::c_int = 112; +pub const _SC_XOPEN_SHM: ::c_int = 113; +pub const _SC_XOPEN_STREAMS: ::c_int = 114; +pub const _SC_XOPEN_UNIX: ::c_int = 115; +pub const _SC_XOPEN_VERSION: ::c_int = 116; +pub const _SC_XOPEN_XCU_VERSION: ::c_int = 117; +pub const _SC_IPV6: ::c_int = 118; +pub const _SC_RAW_SOCKETS: ::c_int = 119; +pub const _SC_SYMLOOP_MAX: ::c_int = 120; +pub const _SC_PHYS_PAGES: ::c_int = 121; + +pub const PTHREAD_MUTEX_INITIALIZER: pthread_mutex_t = 0 as *mut _; +pub const PTHREAD_COND_INITIALIZER: pthread_cond_t = 0 as *mut _; +pub const PTHREAD_RWLOCK_INITIALIZER: pthread_rwlock_t = 0 as *mut _; +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_MUTEX_DEFAULT: ::c_int = PTHREAD_MUTEX_ERRORCHECK; + +pub const SCHED_FIFO: ::c_int = 1; +pub const SCHED_OTHER: ::c_int = 2; +pub const SCHED_RR: ::c_int = 3; + +pub const FD_SETSIZE: usize = 1024; + +pub const ST_NOSUID: ::c_ulong = 2; + +pub const NI_MAXHOST: ::size_t = 1025; + +pub const XUCRED_VERSION: ::c_uint = 0; + +pub const RTLD_LOCAL: ::c_int = 0; +pub const RTLD_NODELETE: ::c_int = 0x1000; +pub const RTLD_NOLOAD: ::c_int = 0x2000; +pub const RTLD_GLOBAL: ::c_int = 0x100; + +pub const LOG_NTP: ::c_int = 12 << 3; +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_ulong = 0x2000740d; +pub const TIOCNXCL: ::c_ulong = 0x2000740e; +pub const TIOCFLUSH: ::c_ulong = 0x80047410; +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_ulong = 0x4004741a; +pub const TIOCSETD: ::c_ulong = 0x8004741b; +pub const TIOCGDRAINWAIT: ::c_ulong = 0x40047456; +pub const TIOCSDRAINWAIT: ::c_ulong = 0x80047457; +pub const TIOCTIMESTAMP: ::c_ulong = 0x40107459; +pub const TIOCMGDTRWAIT: ::c_ulong = 0x4004745a; +pub const TIOCMSDTRWAIT: ::c_ulong = 0x8004745b; +pub const TIOCDRAIN: ::c_ulong = 0x2000745e; +pub const TIOCEXT: ::c_ulong = 0x80047460; +pub const TIOCSCTTY: ::c_ulong = 0x20007461; +pub const TIOCCONS: ::c_ulong = 0x80047462; +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_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; +pub const TIOCM_ST: ::c_int = 0x8; +pub const TIOCM_SR: ::c_int = 0x10; +pub const TIOCM_CTS: ::c_int = 0x20; +pub const TIOCM_RI: ::c_int = 0x80; +pub const TIOCM_DSR: ::c_int = 0x100; +pub const TIOCM_CD: ::c_int = 0x40; +pub const TIOCM_CAR: ::c_int = 0x40; +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_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; +pub const TIOCPKT_FLUSHWRITE: ::c_int = 0x2; +pub const TIOCPKT_STOP: ::c_int = 0x4; +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_ulong = 0x20007471; +pub const TIOCSTI: ::c_ulong = 0x80017472; +pub const TIOCOUTQ: ::c_ulong = 0x40047473; +pub const TIOCSPGRP: ::c_ulong = 0x80047476; +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; +pub const NETGRAPHDISC: ::c_int = 0x6; + +pub const BIOCGRSIG: ::c_ulong = 0x40044272; +pub const BIOCSRSIG: ::c_ulong = 0x80044273; +pub const BIOCSDLT: ::c_ulong = 0x80044278; +pub const BIOCGSEESENT: ::c_ulong = 0x40044276; +pub const BIOCSSEESENT: ::c_ulong = 0x80044277; +pub const BIOCSETF: ::c_ulong = 0x80104267; +pub const BIOCGDLTLIST: ::c_ulong = 0xc0104279; +pub const BIOCSRTIMEOUT: ::c_ulong = 0x8010426d; +pub const BIOCGRTIMEOUT: ::c_ulong = 0x4010426e; + +pub const FIODTYPE: ::c_ulong = 0x4004667a; +pub const FIOGETLBA: ::c_ulong = 0x40046679; + +pub const B0: speed_t = 0; +pub const B50: speed_t = 50; +pub const B75: speed_t = 75; +pub const B110: speed_t = 110; +pub const B134: speed_t = 134; +pub const B150: speed_t = 150; +pub const B200: speed_t = 200; +pub const B300: speed_t = 300; +pub const B600: speed_t = 600; +pub const B1200: speed_t = 1200; +pub const B1800: speed_t = 1800; +pub const B2400: speed_t = 2400; +pub const B4800: speed_t = 4800; +pub const B9600: speed_t = 9600; +pub const B19200: speed_t = 19200; +pub const B38400: speed_t = 38400; +pub const B7200: speed_t = 7200; +pub const B14400: speed_t = 14400; +pub const B28800: speed_t = 28800; +pub const B57600: speed_t = 57600; +pub const B76800: speed_t = 76800; +pub const B115200: speed_t = 115200; +pub const B230400: speed_t = 230400; +pub const EXTA: speed_t = 19200; +pub const EXTB: speed_t = 38400; + +pub const SEM_FAILED: *mut sem_t = 0 as *mut sem_t; + +pub const CRTSCTS: ::tcflag_t = 0x00030000; +pub const CCTS_OFLOW: ::tcflag_t = 0x00010000; +pub const CRTS_IFLOW: ::tcflag_t = 0x00020000; +pub const CDTR_IFLOW: ::tcflag_t = 0x00040000; +pub const CDSR_OFLOW: ::tcflag_t = 0x00080000; +pub const CCAR_OFLOW: ::tcflag_t = 0x00100000; +pub const VERASE2: usize = 7; +pub const OCRNL: ::tcflag_t = 0x10; +pub const ONOCR: ::tcflag_t = 0x20; +pub const ONLRET: ::tcflag_t = 0x40; + +pub const CMGROUP_MAX: usize = 16; + +pub const EUI64_LEN: usize = 8; + +// https://github.com/freebsd/freebsd/blob/HEAD/sys/net/bpf.h +pub const BPF_ALIGNMENT: usize = SIZEOF_LONG; + +// Values for rtprio struct (prio field) and syscall (function argument) +pub const RTP_PRIO_MIN: ::c_ushort = 0; +pub const RTP_PRIO_MAX: ::c_ushort = 31; +pub const RTP_LOOKUP: ::c_int = 0; +pub const RTP_SET: ::c_int = 1; + +// 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 UF_NOUNLINK: ::c_ulong = 0x00000010; +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 SF_NOUNLINK: ::c_ulong = 0x00100000; + +pub const TIMER_ABSTIME: ::c_int = 1; + +// +pub const NTP_API: ::c_int = 4; +pub const MAXPHASE: ::c_long = 500000000; +pub const MAXFREQ: ::c_long = 500000; +pub const MINSEC: ::c_int = 256; +pub const MAXSEC: ::c_int = 2048; +pub const NANOSECOND: ::c_long = 1000000000; +pub const SCALE_PPM: ::c_int = 65; +pub const MAXTC: ::c_int = 10; +pub const MOD_OFFSET: ::c_uint = 0x0001; +pub const MOD_FREQUENCY: ::c_uint = 0x0002; +pub const MOD_MAXERROR: ::c_uint = 0x0004; +pub const MOD_ESTERROR: ::c_uint = 0x0008; +pub const MOD_STATUS: ::c_uint = 0x0010; +pub const MOD_TIMECONST: ::c_uint = 0x0020; +pub const MOD_PPSMAX: ::c_uint = 0x0040; +pub const MOD_TAI: ::c_uint = 0x0080; +pub const MOD_MICRO: ::c_uint = 0x1000; +pub const MOD_NANO: ::c_uint = 0x2000; +pub const MOD_CLKB: ::c_uint = 0x4000; +pub const MOD_CLKA: ::c_uint = 0x8000; +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 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; + +pub const KENV_GET: ::c_int = 0; +pub const KENV_SET: ::c_int = 1; +pub const KENV_UNSET: ::c_int = 2; +pub const KENV_DUMP: ::c_int = 3; +pub const KENV_MNAMELEN: ::c_int = 128; +pub const KENV_MVALLEN: ::c_int = 128; + +pub const RB_ASKNAME: ::c_int = 0x001; +pub const RB_SINGLE: ::c_int = 0x002; +pub const RB_NOSYNC: ::c_int = 0x004; +pub const RB_HALT: ::c_int = 0x008; +pub const RB_INITNAME: ::c_int = 0x010; +pub const RB_DFLTROOT: ::c_int = 0x020; +pub const RB_KDB: ::c_int = 0x040; +pub const RB_RDONLY: ::c_int = 0x080; +pub const RB_DUMP: ::c_int = 0x100; +pub const RB_MINIROOT: ::c_int = 0x200; +pub const RB_VERBOSE: ::c_int = 0x800; +pub const RB_SERIAL: ::c_int = 0x1000; +pub const RB_CDROM: ::c_int = 0x2000; +pub const RB_POWEROFF: ::c_int = 0x4000; +pub const RB_GDB: ::c_int = 0x8000; +pub const RB_MUTE: ::c_int = 0x10000; +pub const RB_SELFTEST: ::c_int = 0x20000; + +// For getrandom() +pub const GRND_NONBLOCK: ::c_uint = 0x1; +pub const GRND_RANDOM: ::c_uint = 0x2; +pub const GRND_INSECURE: ::c_uint = 0x4; + +safe_f! { + pub {const} fn WIFCONTINUED(status: ::c_int) -> bool { + status == 0x13 + } + + pub {const} fn WSTOPSIG(status: ::c_int) -> ::c_int { + status >> 8 + } + + pub {const} fn WIFSTOPPED(status: ::c_int) -> bool { + (status & 0o177) == 0o177 + } +} + +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 daemon(nochdir: ::c_int, noclose: ::c_int) -> ::c_int; + pub fn gettimeofday(tp: *mut ::timeval, tz: *mut ::timezone) -> ::c_int; + pub fn accept4( + s: ::c_int, + addr: *mut ::sockaddr, + addrlen: *mut ::socklen_t, + flags: ::c_int, + ) -> ::c_int; + pub fn chflags(path: *const ::c_char, flags: ::c_ulong) -> ::c_int; + pub fn chflagsat( + fd: ::c_int, + path: *const ::c_char, + flags: ::c_ulong, + atflag: ::c_int, + ) -> ::c_int; + + pub fn clock_nanosleep( + clk_id: ::clockid_t, + flags: ::c_int, + rqtp: *const ::timespec, + rmtp: *mut ::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_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( + grp: *mut ::group, + buf: *mut ::c_char, + buflen: ::size_t, + result: *mut *mut ::group, + ) -> ::c_int; + pub fn getpwent_r( + pwd: *mut ::passwd, + buf: *mut ::c_char, + buflen: ::size_t, + result: *mut *mut ::passwd, + ) -> ::c_int; + pub fn getgrouplist( + name: *const ::c_char, + basegid: ::gid_t, + groups: *mut ::gid_t, + ngroups: *mut ::c_int, + ) -> ::c_int; + pub fn getnameinfo( + sa: *const ::sockaddr, + salen: ::socklen_t, + host: *mut ::c_char, + hostlen: ::size_t, + serv: *mut ::c_char, + servlen: ::size_t, + 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; + pub fn initgroups(name: *const ::c_char, basegid: ::gid_t) -> ::c_int; + #[cfg_attr( + all(target_os = "freebsd", any(freebsd11, freebsd10)), + link_name = "kevent@FBSD_1.0" + )] + pub fn kevent( + kq: ::c_int, + changelist: *const ::kevent, + nchanges: ::c_int, + eventlist: *mut ::kevent, + nevents: ::c_int, + timeout: *const ::timespec, + ) -> ::c_int; + pub fn lchflags(path: *const ::c_char, flags: ::c_ulong) -> ::c_int; + pub fn lutimes(file: *const ::c_char, times: *const ::timeval) -> ::c_int; + pub fn memrchr(cx: *const ::c_void, c: ::c_int, n: ::size_t) -> *mut ::c_void; + pub fn mkfifoat(dirfd: ::c_int, pathname: *const ::c_char, mode: ::mode_t) -> ::c_int; + #[cfg_attr( + all(target_os = "freebsd", any(freebsd11, freebsd10)), + link_name = "mknodat@FBSD_1.1" + )] + pub fn mknodat( + dirfd: ::c_int, + pathname: *const ::c_char, + mode: ::mode_t, + dev: dev_t, + ) -> ::c_int; + pub fn malloc_usable_size(ptr: *const ::c_void) -> ::size_t; + pub fn mincore(addr: *const ::c_void, len: ::size_t, vec: *mut ::c_char) -> ::c_int; + 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, + timeout: *const ::timespec, + sigmask: *const sigset_t, + ) -> ::c_int; + pub fn preadv(fd: ::c_int, iov: *const ::iovec, iovcnt: ::c_int, offset: ::off_t) -> ::ssize_t; + pub fn pthread_attr_get_np(tid: ::pthread_t, attr: *mut ::pthread_attr_t) -> ::c_int; + pub fn pthread_attr_getguardsize( + attr: *const ::pthread_attr_t, + guardsize: *mut ::size_t, + ) -> ::c_int; + pub fn pthread_attr_setguardsize(attr: *mut ::pthread_attr_t, guardsize: ::size_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 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_main_np() -> ::c_int; + pub fn pthread_mutex_timedlock( + lock: *mut pthread_mutex_t, + abstime: *const ::timespec, + ) -> ::c_int; + pub fn pthread_mutexattr_getpshared( + attr: *const pthread_mutexattr_t, + pshared: *mut ::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 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_getname_np( + thread: ::pthread_t, + buffer: *mut ::c_char, + length: ::size_t, + ) -> ::c_int; + pub fn pthread_setname_np(thread: ::pthread_t, name: *const ::c_char) -> ::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 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, + policy: ::c_int, + param: *const ::sched_param, + ) -> ::c_int; + pub fn sem_getvalue(sem: *mut sem_t, sval: *mut ::c_int) -> ::c_int; + pub fn sem_timedwait(sem: *mut sem_t, abstime: *const ::timespec) -> ::c_int; + pub fn sendfile( + fd: ::c_int, + s: ::c_int, + offset: ::off_t, + nbytes: ::size_t, + hdtr: *mut ::sf_hdtr, + sbytes: *mut ::off_t, + flags: ::c_int, + ) -> ::c_int; + pub fn setdomainname(name: *const ::c_char, len: ::c_int) -> ::c_int; + pub fn sethostname(name: *const ::c_char, len: ::c_int) -> ::c_int; + pub fn setpriority(which: ::c_int, who: ::c_int, prio: ::c_int) -> ::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 settimeofday(tv: *const ::timeval, tz: *const ::timezone) -> ::c_int; + pub fn setutxent(); + pub fn shm_open(name: *const ::c_char, oflag: ::c_int, mode: ::mode_t) -> ::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 sysctl( + name: *const ::c_int, + namelen: ::c_uint, + oldp: *mut ::c_void, + oldlenp: *mut ::size_t, + newp: *const ::c_void, + newlen: ::size_t, + ) -> ::c_int; + pub fn sysctlbyname( + name: *const ::c_char, + oldp: *mut ::c_void, + oldlenp: *mut ::size_t, + newp: *const ::c_void, + newlen: ::size_t, + ) -> ::c_int; + pub fn sysctlnametomib( + name: *const ::c_char, + mibp: *mut ::c_int, + sizep: *mut ::size_t, + ) -> ::c_int; + pub fn uselocale(loc: ::locale_t) -> ::locale_t; + pub fn utimensat( + dirfd: ::c_int, + path: *const ::c_char, + times: *const ::timespec, + flag: ::c_int, + ) -> ::c_int; + + pub fn ntp_adjtime(buf: *mut timex) -> ::c_int; + pub fn ntp_gettime(buf: *mut ntptimeval) -> ::c_int; + + // #include + 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 iconv_open(tocode: *const ::c_char, fromcode: *const ::c_char) -> iconv_t; + 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; + + // Added in `FreeBSD` 11.0 + // Added in `DragonFly BSD` 5.4 + 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; + + pub fn kenv( + action: ::c_int, + name: *const ::c_char, + value: *mut ::c_char, + len: ::c_int, + ) -> ::c_int; + pub fn reboot(howto: ::c_int) -> ::c_int; + + pub fn exect( + path: *const ::c_char, + argv: *const *mut ::c_char, + envp: *const *mut ::c_char, + ) -> ::c_int; + pub fn execvP( + file: *const ::c_char, + search_path: *const ::c_char, + argv: *const *mut ::c_char, + ) -> ::c_int; +} + +#[link(name = "rt")] +extern "C" { + 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 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; +} + +#[link(name = "util")] +extern "C" { + 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 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! { + if #[cfg(target_os = "freebsd")] { + mod freebsd; + pub use self::freebsd::*; + } else if #[cfg(target_os = "dragonfly")] { + mod dragonfly; + pub use self::dragonfly::*; + } else { + // ... + } +} diff --git a/vendor/libc/src/unix/bsd/mod.rs b/vendor/libc/src/unix/bsd/mod.rs new file mode 100644 index 0000000..b49a838 --- /dev/null +++ b/vendor/libc/src/unix/bsd/mod.rs @@ -0,0 +1,977 @@ +pub type off_t = i64; +pub type useconds_t = u32; +pub type blkcnt_t = i64; +pub type socklen_t = u32; +pub type sa_family_t = u8; +pub type pthread_t = ::uintptr_t; +pub type nfds_t = ::c_uint; +pub type regoff_t = off_t; + +s! { + pub struct sockaddr { + pub sa_len: u8, + pub sa_family: sa_family_t, + pub sa_data: [::c_char; 14], + } + + 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, + } + + 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_change: ::time_t, + pub pw_class: *mut ::c_char, + pub pw_gecos: *mut ::c_char, + pub pw_dir: *mut ::c_char, + pub pw_shell: *mut ::c_char, + pub pw_expire: ::time_t, + + #[cfg(not(any(target_os = "macos", + target_os = "ios", + target_os = "tvos", + target_os = "watchos", + target_os = "visionos", + target_os = "netbsd", + target_os = "openbsd")))] + pub pw_fields: ::c_int, + } + + 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, + #[cfg(target_os = "netbsd")] + pub ifa_addrflags: ::c_uint + } + + pub struct fd_set { + #[cfg(all(target_pointer_width = "64", + any(target_os = "freebsd", target_os = "dragonfly")))] + fds_bits: [i64; FD_SETSIZE / 64], + #[cfg(not(all(target_pointer_width = "64", + any(target_os = "freebsd", target_os = "dragonfly"))))] + fds_bits: [i32; FD_SETSIZE / 32], + } + + 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, + } + + 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 fsid_t { + __fsid_val: [i32; 2], + } + + pub struct if_nameindex { + pub if_index: ::c_uint, + pub if_name: *mut ::c_char, + } + + pub struct regex_t { + __re_magic: ::c_int, + __re_nsub: ::size_t, + __re_endp: *const ::c_char, + __re_g: *mut ::c_void, + } + + pub struct regmatch_t { + 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! { + pub struct sockaddr_un { + pub sun_len: u8, + pub sun_family: sa_family_t, + pub sun_path: [c_char; 104] + } + + pub struct utsname { + #[cfg(not(target_os = "dragonfly"))] + pub sysname: [::c_char; 256], + #[cfg(target_os = "dragonfly")] + pub sysname: [::c_char; 32], + #[cfg(not(target_os = "dragonfly"))] + pub nodename: [::c_char; 256], + #[cfg(target_os = "dragonfly")] + pub nodename: [::c_char; 32], + #[cfg(not(target_os = "dragonfly"))] + pub release: [::c_char; 256], + #[cfg(target_os = "dragonfly")] + pub release: [::c_char; 32], + #[cfg(not(target_os = "dragonfly"))] + pub version: [::c_char; 256], + #[cfg(target_os = "dragonfly")] + pub version: [::c_char; 32], + #[cfg(not(target_os = "dragonfly"))] + pub machine: [::c_char; 256], + #[cfg(target_os = "dragonfly")] + pub machine: [::c_char; 32], + } + +} + +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); + } + } + } +} + +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 FIOCLEX: ::c_ulong = 0x20006601; +pub const FIONCLEX: ::c_ulong = 0x20006602; +pub const FIONREAD: ::c_ulong = 0x4004667f; +pub const FIONBIO: ::c_ulong = 0x8004667e; +pub const FIOASYNC: ::c_ulong = 0x8004667d; +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; + +pub const SA_ONSTACK: ::c_int = 0x0001; +pub const SA_SIGINFO: ::c_int = 0x0040; +pub const SA_RESTART: ::c_int = 0x0002; +pub const SA_RESETHAND: ::c_int = 0x0004; +pub const SA_NOCLDSTOP: ::c_int = 0x0008; +pub const SA_NODEFER: ::c_int = 0x0010; +pub const SA_NOCLDWAIT: ::c_int = 0x0020; + +pub const SS_ONSTACK: ::c_int = 1; +pub const SS_DISABLE: ::c_int = 4; + +pub const SIGCHLD: ::c_int = 20; +pub const SIGBUS: ::c_int = 10; +pub const SIGUSR1: ::c_int = 30; +pub const SIGUSR2: ::c_int = 31; +pub const SIGCONT: ::c_int = 19; +pub const SIGSTOP: ::c_int = 17; +pub const SIGTSTP: ::c_int = 18; +pub const SIGURG: ::c_int = 16; +pub const SIGIO: ::c_int = 23; +pub const SIGSYS: ::c_int = 12; +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 SIGINFO: ::c_int = 29; + +pub const SIG_SETMASK: ::c_int = 3; +pub const SIG_BLOCK: ::c_int = 0x1; +pub const SIG_UNBLOCK: ::c_int = 0x2; + +pub const IP_TOS: ::c_int = 3; +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 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_V6ONLY: ::c_int = 27; +pub const IPV6_DONTFRAG: ::c_int = 62; + +pub const IPTOS_ECN_NOTECT: 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 ST_RDONLY: ::c_ulong = 1; + +pub const SCM_RIGHTS: ::c_int = 0x01; + +pub const NCCS: usize = 20; + +pub const O_ACCMODE: ::c_int = 0x3; +pub const O_RDONLY: ::c_int = 0; +pub const O_WRONLY: ::c_int = 1; +pub const O_RDWR: ::c_int = 2; +pub const O_APPEND: ::c_int = 8; +pub const O_CREAT: ::c_int = 512; +pub const O_TRUNC: ::c_int = 1024; +pub const O_EXCL: ::c_int = 2048; +pub const O_ASYNC: ::c_int = 0x40; +pub const O_SYNC: ::c_int = 0x80; +pub const O_NONBLOCK: ::c_int = 0x4; +pub const O_NOFOLLOW: ::c_int = 0x100; +pub const O_SHLOCK: ::c_int = 0x10; +pub const O_EXLOCK: ::c_int = 0x20; +pub const O_FSYNC: ::c_int = O_SYNC; +pub const O_NDELAY: ::c_int = O_NONBLOCK; + +pub const F_GETOWN: ::c_int = 5; +pub const F_SETOWN: ::c_int = 6; + +pub const F_RDLCK: ::c_short = 1; +pub const F_UNLCK: ::c_short = 2; +pub const F_WRLCK: ::c_short = 3; + +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; +pub const Q_QUOTAOFF: ::c_int = 0x200; + +pub const TCIOFF: ::c_int = 3; +pub const TCION: ::c_int = 4; +pub const TCOOFF: ::c_int = 1; +pub const TCOON: ::c_int = 2; +pub const TCIFLUSH: ::c_int = 1; +pub const TCOFLUSH: ::c_int = 2; +pub const TCIOFLUSH: ::c_int = 3; +pub const TCSANOW: ::c_int = 0; +pub const TCSADRAIN: ::c_int = 1; +pub const TCSAFLUSH: ::c_int = 2; +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 VINTR: usize = 8; +pub const VQUIT: usize = 9; +pub const VSUSP: usize = 10; +pub const VDSUSP: usize = 11; +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 VSTATUS: usize = 18; +pub const _POSIX_VDISABLE: ::cc_t = 0xff; +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 = 0x00000200; +pub const IXOFF: ::tcflag_t = 0x00000400; +pub const IXANY: ::tcflag_t = 0x00000800; +pub const IMAXBEL: ::tcflag_t = 0x00002000; +pub const OPOST: ::tcflag_t = 0x1; +pub const ONLCR: ::tcflag_t = 0x2; +pub const OXTABS: ::tcflag_t = 0x4; +pub const ONOEOT: ::tcflag_t = 0x8; +pub const CIGNORE: ::tcflag_t = 0x00000001; +pub const CSIZE: ::tcflag_t = 0x00000300; +pub const CS5: ::tcflag_t = 0x00000000; +pub const CS6: ::tcflag_t = 0x00000100; +pub const CS7: ::tcflag_t = 0x00000200; +pub const CS8: ::tcflag_t = 0x00000300; +pub const CSTOPB: ::tcflag_t = 0x00000400; +pub const CREAD: ::tcflag_t = 0x00000800; +pub const PARENB: ::tcflag_t = 0x00001000; +pub const PARODD: ::tcflag_t = 0x00002000; +pub const HUPCL: ::tcflag_t = 0x00004000; +pub const CLOCAL: ::tcflag_t = 0x00008000; +pub const ECHOKE: ::tcflag_t = 0x00000001; +pub const ECHOE: ::tcflag_t = 0x00000002; +pub const ECHOK: ::tcflag_t = 0x00000004; +pub const ECHO: ::tcflag_t = 0x00000008; +pub const ECHONL: ::tcflag_t = 0x00000010; +pub const ECHOPRT: ::tcflag_t = 0x00000020; +pub const ECHOCTL: ::tcflag_t = 0x00000040; +pub const ISIG: ::tcflag_t = 0x00000080; +pub const ICANON: ::tcflag_t = 0x00000100; +pub const ALTWERASE: ::tcflag_t = 0x00000200; +pub const IEXTEN: ::tcflag_t = 0x00000400; +pub const EXTPROC: ::tcflag_t = 0x00000800; +pub const TOSTOP: ::tcflag_t = 0x00400000; +pub const FLUSHO: ::tcflag_t = 0x00800000; +pub const NOKERNINFO: ::tcflag_t = 0x02000000; +pub const PENDIN: ::tcflag_t = 0x20000000; +pub const NOFLSH: ::tcflag_t = 0x80000000; +pub const MDMBUF: ::tcflag_t = 0x00100000; + +pub const WNOHANG: ::c_int = 0x00000001; +pub const WUNTRACED: ::c_int = 0x00000002; + +pub const RTLD_LAZY: ::c_int = 0x1; +pub const RTLD_NOW: ::c_int = 0x2; +pub const RTLD_NEXT: *mut ::c_void = -1isize as *mut ::c_void; +pub const RTLD_DEFAULT: *mut ::c_void = -2isize as *mut ::c_void; +pub const RTLD_SELF: *mut ::c_void = -3isize as *mut ::c_void; + +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 TCP_NODELAY: ::c_int = 1; +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; +pub const CLD_TRAPPED: ::c_int = 4; +pub const CLD_STOPPED: ::c_int = 5; +pub const CLD_CONTINUED: ::c_int = 6; + +pub const POLLIN: ::c_short = 0x1; +pub const POLLPRI: ::c_short = 0x2; +pub const POLLOUT: ::c_short = 0x4; +pub const POLLERR: ::c_short = 0x8; +pub const POLLHUP: ::c_short = 0x10; +pub const POLLNVAL: ::c_short = 0x20; +pub const POLLRDNORM: ::c_short = 0x040; +pub const POLLWRNORM: ::c_short = 0x004; +pub const POLLRDBAND: ::c_short = 0x080; +pub const POLLWRBAND: ::c_short = 0x100; + +pub const BIOCGBLEN: ::c_ulong = 0x40044266; +pub const BIOCSBLEN: ::c_ulong = 0xc0044266; +pub const BIOCFLUSH: ::c_uint = 0x20004268; +pub const BIOCPROMISC: ::c_uint = 0x20004269; +pub const BIOCGDLT: ::c_ulong = 0x4004426a; +pub const BIOCGETIF: ::c_ulong = 0x4020426b; +pub const BIOCSETIF: ::c_ulong = 0x8020426c; +pub const BIOCGSTATS: ::c_ulong = 0x4008426f; +pub const BIOCIMMEDIATE: ::c_ulong = 0x80044270; +pub const BIOCVERSION: ::c_ulong = 0x40044271; +pub const BIOCGHDRCMPLT: ::c_ulong = 0x40044274; +pub const BIOCSHDRCMPLT: ::c_ulong = 0x80044275; +pub const SIOCGIFADDR: ::c_ulong = 0xc0206921; + +pub const REG_BASIC: ::c_int = 0o0000; +pub const REG_EXTENDED: ::c_int = 0o0001; +pub const REG_ICASE: ::c_int = 0o0002; +pub const REG_NOSUB: ::c_int = 0o0004; +pub const REG_NEWLINE: ::c_int = 0o0010; +pub const REG_NOSPEC: ::c_int = 0o0020; +pub const REG_PEND: ::c_int = 0o0040; +pub const REG_DUMP: ::c_int = 0o0200; + +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_EMPTY: ::c_int = 14; +pub const REG_ASSERT: ::c_int = 15; +pub const REG_INVARG: ::c_int = 16; +pub const REG_ATOI: ::c_int = 255; +pub const REG_ITOA: ::c_int = 0o0400; + +pub const REG_NOTBOL: ::c_int = 0o00001; +pub const REG_NOTEOL: ::c_int = 0o00002; +pub const REG_STARTEND: ::c_int = 0o00004; +pub const REG_TRACE: ::c_int = 0o00400; +pub const REG_LARGE: ::c_int = 0o01000; +pub const REG_BACKR: ::c_int = 0o02000; + +pub const TIOCCBRK: ::c_uint = 0x2000747a; +pub const TIOCSBRK: ::c_uint = 0x2000747b; + +pub const PRIO_PROCESS: ::c_int = 0; +pub const PRIO_PGRP: ::c_int = 1; +pub const PRIO_USER: ::c_int = 2; + +pub const ITIMER_REAL: ::c_int = 0; +pub const ITIMER_VIRTUAL: ::c_int = 1; +pub const ITIMER_PROF: ::c_int = 2; + +// net/route.h + +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_STATIC: ::c_int = 0x800; +pub const RTF_BLACKHOLE: ::c_int = 0x1000; +pub const RTF_PROTO2: ::c_int = 0x4000; +pub const RTF_PROTO1: ::c_int = 0x8000; + +// Message types +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; + +// Bitmask values for rtm_addrs. +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; + +// Index offsets for sockaddr array for alternate internal encoding. +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; + +f! { + pub fn CMSG_FIRSTHDR(mhdr: *const ::msghdr) -> *mut ::cmsghdr { + if (*mhdr).msg_controllen as usize >= ::mem::size_of::<::cmsghdr>() { + (*mhdr).msg_control as *mut ::cmsghdr + } else { + 0 as *mut ::cmsghdr + } + } + + pub fn FD_CLR(fd: ::c_int, set: *mut fd_set) -> () { + let bits = ::mem::size_of_val(&(*set).fds_bits[0]) * 8; + let fd = fd as usize; + (*set).fds_bits[fd / bits] &= !(1 << (fd % bits)); + return + } + + pub fn FD_ISSET(fd: ::c_int, set: *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 + } + + pub fn FD_SET(fd: ::c_int, set: *mut fd_set) -> () { + let bits = ::mem::size_of_val(&(*set).fds_bits[0]) * 8; + let fd = fd as usize; + (*set).fds_bits[fd / bits] |= 1 << (fd % bits); + return + } + + pub fn FD_ZERO(set: *mut fd_set) -> () { + for slot in (*set).fds_bits.iter_mut() { + *slot = 0; + } + } +} + +safe_f! { + pub {const} fn WTERMSIG(status: ::c_int) -> ::c_int { + status & 0o177 + } + + pub {const} fn WIFEXITED(status: ::c_int) -> bool { + (status & 0o177) == 0 + } + + pub {const} fn WEXITSTATUS(status: ::c_int) -> ::c_int { + status >> 8 + } + + pub {const} fn WCOREDUMP(status: ::c_int) -> bool { + (status & 0o200) != 0 + } + + pub {const} fn QCMD(cmd: ::c_int, type_: ::c_int) -> ::c_int { + (cmd << 8) | (type_ & 0x00ff) + } +} + +extern "C" { + #[cfg_attr( + all(target_os = "macos", target_arch = "x86"), + link_name = "getrlimit$UNIX2003" + )] + pub fn getrlimit(resource: ::c_int, rlim: *mut ::rlimit) -> ::c_int; + #[cfg_attr( + all(target_os = "macos", target_arch = "x86"), + link_name = "setrlimit$UNIX2003" + )] + pub fn setrlimit(resource: ::c_int, rlim: *const ::rlimit) -> ::c_int; + + pub fn strerror_r(errnum: ::c_int, buf: *mut c_char, buflen: ::size_t) -> ::c_int; + pub fn abs(i: ::c_int) -> ::c_int; + pub fn labs(i: ::c_long) -> ::c_long; + #[cfg_attr( + all(target_os = "freebsd", any(freebsd12, freebsd11, freebsd10)), + link_name = "rand@FBSD_1.0" + )] + pub fn rand() -> ::c_int; + #[cfg_attr( + all(target_os = "freebsd", any(freebsd12, freebsd11, freebsd10)), + link_name = "srand@FBSD_1.0" + )] + pub fn srand(seed: ::c_uint); + + pub fn getifaddrs(ifap: *mut *mut ::ifaddrs) -> ::c_int; + pub fn freeifaddrs(ifa: *mut ::ifaddrs); + pub fn setgroups(ngroups: ::c_int, ptr: *const ::gid_t) -> ::c_int; + pub fn setlogin(name: *const ::c_char) -> ::c_int; + pub fn ioctl(fd: ::c_int, request: ::c_ulong, ...) -> ::c_int; + pub fn kqueue() -> ::c_int; + pub fn unmount(target: *const ::c_char, arg: ::c_int) -> ::c_int; + pub fn syscall(num: ::c_int, ...) -> ::c_int; + #[cfg_attr(target_os = "netbsd", link_name = "__getpwent50")] + pub fn getpwent() -> *mut passwd; + pub fn setpwent(); + pub fn endpwent(); + pub fn endgrent(); + pub fn getgrent() -> *mut ::group; + + pub fn getprogname() -> *const ::c_char; + pub fn setprogname(name: *const ::c_char); + pub fn getloadavg(loadavg: *mut ::c_double, nelem: ::c_int) -> ::c_int; + pub fn if_nameindex() -> *mut if_nameindex; + pub fn if_freenameindex(ptr: *mut if_nameindex); + + pub fn getpeereid(socket: ::c_int, euid: *mut ::uid_t, egid: *mut ::gid_t) -> ::c_int; + + #[cfg_attr( + all(target_os = "macos", not(target_arch = "aarch64")), + link_name = "glob$INODE64" + )] + #[cfg_attr(target_os = "netbsd", link_name = "__glob30")] + #[cfg_attr( + all(target_os = "freebsd", any(freebsd11, freebsd10)), + link_name = "glob@FBSD_1.0" + )] + pub fn glob( + pattern: *const ::c_char, + flags: ::c_int, + errfunc: ::Option ::c_int>, + pglob: *mut ::glob_t, + ) -> ::c_int; + #[cfg_attr(target_os = "netbsd", link_name = "__globfree30")] + #[cfg_attr( + all(target_os = "freebsd", any(freebsd11, freebsd10)), + link_name = "globfree@FBSD_1.0" + )] + 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; + + #[cfg_attr( + all(target_os = "macos", target_arch = "x86_64"), + link_name = "seekdir$INODE64" + )] + #[cfg_attr( + all(target_os = "macos", target_arch = "x86"), + link_name = "seekdir$INODE64$UNIX2003" + )] + pub fn seekdir(dirp: *mut ::DIR, loc: ::c_long); + + #[cfg_attr( + all(target_os = "macos", target_arch = "x86_64"), + link_name = "telldir$INODE64" + )] + #[cfg_attr( + all(target_os = "macos", target_arch = "x86"), + link_name = "telldir$INODE64$UNIX2003" + )] + pub fn telldir(dirp: *mut ::DIR) -> ::c_long; + pub fn madvise(addr: *mut ::c_void, len: ::size_t, advice: ::c_int) -> ::c_int; + + #[cfg_attr( + all(target_os = "macos", target_arch = "x86"), + link_name = "msync$UNIX2003" + )] + #[cfg_attr(target_os = "netbsd", link_name = "__msync13")] + pub fn msync(addr: *mut ::c_void, len: ::size_t, flags: ::c_int) -> ::c_int; + + #[cfg_attr( + all(target_os = "macos", target_arch = "x86"), + link_name = "recvfrom$UNIX2003" + )] + 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; + #[cfg_attr(target_os = "netbsd", link_name = "__futimes50")] + pub fn futimes(fd: ::c_int, times: *const ::timeval) -> ::c_int; + pub fn nl_langinfo(item: ::nl_item) -> *mut ::c_char; + + #[cfg_attr( + all(target_os = "macos", target_arch = "x86"), + link_name = "bind$UNIX2003" + )] + pub fn bind(socket: ::c_int, address: *const ::sockaddr, address_len: ::socklen_t) -> ::c_int; + + #[cfg_attr( + all(target_os = "macos", target_arch = "x86"), + link_name = "writev$UNIX2003" + )] + pub fn writev(fd: ::c_int, iov: *const ::iovec, iovcnt: ::c_int) -> ::ssize_t; + #[cfg_attr( + all(target_os = "macos", target_arch = "x86"), + link_name = "readv$UNIX2003" + )] + pub fn readv(fd: ::c_int, iov: *const ::iovec, iovcnt: ::c_int) -> ::ssize_t; + + #[cfg_attr( + all(target_os = "macos", target_arch = "x86"), + link_name = "sendmsg$UNIX2003" + )] + pub fn sendmsg(fd: ::c_int, msg: *const ::msghdr, flags: ::c_int) -> ::ssize_t; + #[cfg_attr( + all(target_os = "macos", target_arch = "x86"), + link_name = "recvmsg$UNIX2003" + )] + pub fn recvmsg(fd: ::c_int, msg: *mut ::msghdr, flags: ::c_int) -> ::ssize_t; + + pub fn sync(); + pub fn getgrgid_r( + gid: ::gid_t, + grp: *mut ::group, + buf: *mut ::c_char, + buflen: ::size_t, + result: *mut *mut ::group, + ) -> ::c_int; + #[cfg_attr( + all(target_os = "macos", target_arch = "x86"), + link_name = "sigaltstack$UNIX2003" + )] + #[cfg_attr(target_os = "netbsd", link_name = "__sigaltstack14")] + pub fn sigaltstack(ss: *const stack_t, oss: *mut stack_t) -> ::c_int; + pub fn sigsuspend(mask: *const ::sigset_t) -> ::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; + #[cfg_attr( + all(target_os = "macos", target_arch = "x86"), + link_name = "pthread_sigmask$UNIX2003" + )] + 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; + #[cfg_attr( + all(target_os = "macos", target_arch = "x86"), + link_name = "pthread_cancel$UNIX2003" + )] + 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( + name: *const ::c_char, + pwd: *mut passwd, + buf: *mut ::c_char, + buflen: ::size_t, + result: *mut *mut passwd, + ) -> ::c_int; + #[cfg_attr(target_os = "netbsd", link_name = "__getpwuid_r50")] + pub fn getpwuid_r( + uid: ::uid_t, + pwd: *mut passwd, + buf: *mut ::c_char, + buflen: ::size_t, + result: *mut *mut passwd, + ) -> ::c_int; + #[cfg_attr( + all(target_os = "macos", target_arch = "x86"), + link_name = "sigwait$UNIX2003" + )] + 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; + #[cfg_attr( + all(target_os = "macos", target_arch = "x86"), + link_name = "popen$UNIX2003" + )] + 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 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 acct(filename: *const ::c_char) -> ::c_int; + #[cfg_attr( + all(target_os = "macos", target_arch = "x86"), + link_name = "wait4$UNIX2003" + )] + #[cfg_attr( + all(target_os = "freebsd", any(freebsd12, freebsd11, freebsd10)), + link_name = "wait4@FBSD_1.0" + )] + pub fn wait4( + pid: ::pid_t, + status: *mut ::c_int, + options: ::c_int, + rusage: *mut ::rusage, + ) -> ::pid_t; + #[cfg_attr( + all(target_os = "macos", target_arch = "x86"), + link_name = "getitimer$UNIX2003" + )] + pub fn getitimer(which: ::c_int, curr_value: *mut ::itimerval) -> ::c_int; + #[cfg_attr( + all(target_os = "macos", target_arch = "x86"), + link_name = "setitimer$UNIX2003" + )] + 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 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; + + pub fn strftime( + buf: *mut ::c_char, + maxsize: ::size_t, + format: *const ::c_char, + timeptr: *const ::tm, + ) -> ::size_t; + pub fn strftime_l( + buf: *mut ::c_char, + maxsize: ::size_t, + format: *const ::c_char, + timeptr: *const ::tm, + locale: ::locale_t, + ) -> ::size_t; +} + +cfg_if! { + if #[cfg(any(target_os = "macos", target_os = "ios", target_os = "tvos", target_os = "watchos", target_os = "visionos"))] { + mod apple; + pub use self::apple::*; + } else if #[cfg(any(target_os = "openbsd", target_os = "netbsd"))] { + mod netbsdlike; + pub use self::netbsdlike::*; + } else if #[cfg(any(target_os = "freebsd", target_os = "dragonfly"))] { + mod freebsdlike; + pub use self::freebsdlike::*; + } else { + // Unknown target_os + } +} diff --git a/vendor/libc/src/unix/bsd/netbsdlike/mod.rs b/vendor/libc/src/unix/bsd/netbsdlike/mod.rs new file mode 100644 index 0000000..dcd3582 --- /dev/null +++ b/vendor/libc/src/unix/bsd/netbsdlike/mod.rs @@ -0,0 +1,882 @@ +pub type wchar_t = i32; +pub type time_t = i64; +pub type mode_t = u32; +pub type nlink_t = u32; +pub type ino_t = u64; +pub type pthread_key_t = ::c_int; +pub type rlim_t = u64; +pub type speed_t = ::c_uint; +pub type tcflag_t = ::c_uint; +pub type nl_item = c_long; +pub type clockid_t = ::c_int; +pub type id_t = u32; +pub type sem_t = *mut sem; +pub type key_t = c_long; + +#[cfg_attr(feature = "extra_traits", derive(Debug))] +pub enum timezone {} +impl ::Copy for timezone {} +impl ::Clone for timezone { + fn clone(&self) -> timezone { + *self + } +} +#[cfg_attr(feature = "extra_traits", derive(Debug))] +pub enum sem {} +impl ::Copy for sem {} +impl ::Clone for sem { + fn clone(&self) -> sem { + *self + } +} + +s! { + pub struct sched_param { + pub sched_priority: ::c_int, + } + + pub struct sigaction { + pub sa_sigaction: ::sighandler_t, + pub sa_mask: ::sigset_t, + pub sa_flags: ::c_int, + } + + pub struct stack_t { + pub ss_sp: *mut ::c_void, + pub ss_size: ::size_t, + pub ss_flags: ::c_int, + } + + pub struct in6_pktinfo { + pub ipi6_addr: ::in6_addr, + pub ipi6_ifindex: ::c_uint, + } + + 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 c_ispeed: ::c_int, + pub c_ospeed: ::c_int, + } + + pub struct flock { + pub l_start: ::off_t, + pub l_len: ::off_t, + pub l_pid: ::pid_t, + pub l_type: ::c_short, + pub l_whence: ::c_short, + } + + pub struct ipc_perm { + pub cuid: ::uid_t, + pub cgid: ::gid_t, + pub uid: ::uid_t, + pub gid: ::gid_t, + pub mode: ::mode_t, + #[cfg(target_os = "openbsd")] + pub seq: ::c_ushort, + #[cfg(target_os = "netbsd")] + pub _seq: ::c_ushort, + #[cfg(target_os = "openbsd")] + pub key: ::key_t, + #[cfg(target_os = "netbsd")] + pub _key: ::key_t, + } + + pub struct ptrace_io_desc { + pub piod_op: ::c_int, + pub piod_offs: *mut ::c_void, + pub piod_addr: *mut ::c_void, + pub piod_len: ::size_t, + } + + pub struct mmsghdr { + pub msg_hdr: ::msghdr, + pub msg_len: ::c_uint, + } +} + +pub const D_T_FMT: ::nl_item = 0; +pub const D_FMT: ::nl_item = 1; +pub const T_FMT: ::nl_item = 2; +pub const T_FMT_AMPM: ::nl_item = 3; +pub const AM_STR: ::nl_item = 4; +pub const PM_STR: ::nl_item = 5; + +pub const DAY_1: ::nl_item = 6; +pub const DAY_2: ::nl_item = 7; +pub const DAY_3: ::nl_item = 8; +pub const DAY_4: ::nl_item = 9; +pub const DAY_5: ::nl_item = 10; +pub const DAY_6: ::nl_item = 11; +pub const DAY_7: ::nl_item = 12; + +pub const ABDAY_1: ::nl_item = 13; +pub const ABDAY_2: ::nl_item = 14; +pub const ABDAY_3: ::nl_item = 15; +pub const ABDAY_4: ::nl_item = 16; +pub const ABDAY_5: ::nl_item = 17; +pub const ABDAY_6: ::nl_item = 18; +pub const ABDAY_7: ::nl_item = 19; + +pub const MON_1: ::nl_item = 20; +pub const MON_2: ::nl_item = 21; +pub const MON_3: ::nl_item = 22; +pub const MON_4: ::nl_item = 23; +pub const MON_5: ::nl_item = 24; +pub const MON_6: ::nl_item = 25; +pub const MON_7: ::nl_item = 26; +pub const MON_8: ::nl_item = 27; +pub const MON_9: ::nl_item = 28; +pub const MON_10: ::nl_item = 29; +pub const MON_11: ::nl_item = 30; +pub const MON_12: ::nl_item = 31; + +pub const ABMON_1: ::nl_item = 32; +pub const ABMON_2: ::nl_item = 33; +pub const ABMON_3: ::nl_item = 34; +pub const ABMON_4: ::nl_item = 35; +pub const ABMON_5: ::nl_item = 36; +pub const ABMON_6: ::nl_item = 37; +pub const ABMON_7: ::nl_item = 38; +pub const ABMON_8: ::nl_item = 39; +pub const ABMON_9: ::nl_item = 40; +pub const ABMON_10: ::nl_item = 41; +pub const ABMON_11: ::nl_item = 42; +pub const ABMON_12: ::nl_item = 43; + +pub const RADIXCHAR: ::nl_item = 44; +pub const THOUSEP: ::nl_item = 45; +pub const YESSTR: ::nl_item = 46; +pub const YESEXPR: ::nl_item = 47; +pub const NOSTR: ::nl_item = 48; +pub const NOEXPR: ::nl_item = 49; +pub const CRNCYSTR: ::nl_item = 50; + +pub const CODESET: ::nl_item = 51; + +pub const EXIT_FAILURE: ::c_int = 1; +pub const EXIT_SUCCESS: ::c_int = 0; +pub const RAND_MAX: ::c_int = 2147483647; +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 L_tmpnam: ::c_uint = 1024; +pub const O_NOCTTY: ::c_int = 32768; +pub const S_IFIFO: mode_t = 4096; +pub const S_IFCHR: mode_t = 8192; +pub const S_IFBLK: mode_t = 24576; +pub const S_IFDIR: mode_t = 16384; +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 = 61440; +pub const S_IEXEC: mode_t = 64; +pub const S_IWRITE: mode_t = 128; +pub const S_IREAD: mode_t = 256; +pub const S_IRWXU: mode_t = 448; +pub const S_IXUSR: mode_t = 64; +pub const S_IWUSR: mode_t = 128; +pub const S_IRUSR: mode_t = 256; +pub const S_IRWXG: mode_t = 56; +pub const S_IXGRP: mode_t = 8; +pub const S_IWGRP: mode_t = 16; +pub const S_IRGRP: mode_t = 32; +pub const S_IRWXO: mode_t = 7; +pub const S_IXOTH: mode_t = 1; +pub const S_IWOTH: mode_t = 2; +pub const S_IROTH: mode_t = 4; +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; +pub const STDIN_FILENO: ::c_int = 0; +pub const STDOUT_FILENO: ::c_int = 1; +pub const STDERR_FILENO: ::c_int = 2; +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_GETLK: ::c_int = 7; +pub const F_SETLK: ::c_int = 8; +pub const F_SETLKW: ::c_int = 9; +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 SIGPIPE: ::c_int = 13; +pub const SIGALRM: ::c_int = 14; +pub const SIGTERM: ::c_int = 15; + +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 = 0x0000; +pub const MAP_SHARED: ::c_int = 0x0001; +pub const MAP_PRIVATE: ::c_int = 0x0002; +pub const MAP_FIXED: ::c_int = 0x0010; +pub const MAP_ANON: ::c_int = 0x1000; +pub const MAP_ANONYMOUS: ::c_int = MAP_ANON; + +pub const MAP_FAILED: *mut ::c_void = !0 as *mut ::c_void; + +pub const IPC_CREAT: ::c_int = 0o001000; +pub const IPC_EXCL: ::c_int = 0o002000; +pub const IPC_NOWAIT: ::c_int = 0o004000; + +pub const IPC_PRIVATE: ::key_t = 0; + +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; + +pub const MS_ASYNC: ::c_int = 0x0001; + +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 EDEADLK: ::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 EAGAIN: ::c_int = 35; +pub const EWOULDBLOCK: ::c_int = 35; +pub const EINPROGRESS: ::c_int = 36; +pub const EALREADY: ::c_int = 37; +pub const ENOTSOCK: ::c_int = 38; +pub const EDESTADDRREQ: ::c_int = 39; +pub const EMSGSIZE: ::c_int = 40; +pub const EPROTOTYPE: ::c_int = 41; +pub const ENOPROTOOPT: ::c_int = 42; +pub const EPROTONOSUPPORT: ::c_int = 43; +pub const ESOCKTNOSUPPORT: ::c_int = 44; +pub const EOPNOTSUPP: ::c_int = 45; +pub const EPFNOSUPPORT: ::c_int = 46; +pub const EAFNOSUPPORT: ::c_int = 47; +pub const EADDRINUSE: ::c_int = 48; +pub const EADDRNOTAVAIL: ::c_int = 49; +pub const ENETDOWN: ::c_int = 50; +pub const ENETUNREACH: ::c_int = 51; +pub const ENETRESET: ::c_int = 52; +pub const ECONNABORTED: ::c_int = 53; +pub const ECONNRESET: ::c_int = 54; +pub const ENOBUFS: ::c_int = 55; +pub const EISCONN: ::c_int = 56; +pub const ENOTCONN: ::c_int = 57; +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 ELOOP: ::c_int = 62; +pub const ENAMETOOLONG: ::c_int = 63; +pub const EHOSTDOWN: ::c_int = 64; +pub const EHOSTUNREACH: ::c_int = 65; +pub const ENOTEMPTY: ::c_int = 66; +pub const EPROCLIM: ::c_int = 67; +pub const EUSERS: ::c_int = 68; +pub const EDQUOT: ::c_int = 69; +pub const ESTALE: ::c_int = 70; +pub const EREMOTE: ::c_int = 71; +pub const EBADRPC: ::c_int = 72; +pub const ERPCMISMATCH: ::c_int = 73; +pub const EPROGUNAVAIL: ::c_int = 74; +pub const EPROGMISMATCH: ::c_int = 75; +pub const EPROCUNAVAIL: ::c_int = 76; +pub const ENOLCK: ::c_int = 77; +pub const ENOSYS: ::c_int = 78; +pub const EFTYPE: ::c_int = 79; +pub const EAUTH: ::c_int = 80; +pub const ENEEDAUTH: ::c_int = 81; + +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 SIGTRAP: ::c_int = 5; + +pub const GLOB_APPEND: ::c_int = 0x0001; +pub const GLOB_DOOFFS: ::c_int = 0x0002; +pub const GLOB_ERR: ::c_int = 0x0004; +pub const GLOB_MARK: ::c_int = 0x0008; +pub const GLOB_NOCHECK: ::c_int = 0x0010; +pub const GLOB_NOSORT: ::c_int = 0x0020; +pub const GLOB_NOESCAPE: ::c_int = 0x1000; + +pub const GLOB_NOSPACE: ::c_int = -1; +pub const GLOB_ABORTED: ::c_int = -2; +pub const GLOB_NOMATCH: ::c_int = -3; +pub const GLOB_NOSYS: ::c_int = -4; + +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_MADV_DONTNEED: ::c_int = 4; + +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 PTHREAD_CREATE_JOINABLE: ::c_int = 0; +pub const PTHREAD_CREATE_DETACHED: ::c_int = 1; + +pub const PIOD_READ_D: ::c_int = 1; +pub const PIOD_WRITE_D: ::c_int = 2; +pub const PIOD_READ_I: ::c_int = 3; +pub const PIOD_WRITE_I: ::c_int = 4; +pub const PIOD_READ_AUXV: ::c_int = 5; + +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_ATTACH: ::c_int = 9; +pub const PT_DETACH: ::c_int = 10; +pub const PT_IO: ::c_int = 11; + +// http://man.openbsd.org/OpenBSD-current/man2/clock_getres.2 +// The man page says clock_gettime(3) can accept various values as clockid_t but +// http://fxr.watson.org/fxr/source/kern/kern_time.c?v=OPENBSD;im=excerpts#L161 +// the implementation rejects anything other than the below two +// +// http://netbsd.gw.com/cgi-bin/man-cgi?clock_gettime +// https://github.com/jsonn/src/blob/HEAD/sys/kern/subr_time.c#L222 +// Basically the same goes for NetBSD +pub const CLOCK_REALTIME: ::clockid_t = 0; +pub const CLOCK_MONOTONIC: ::clockid_t = 3; + +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_MEMLOCK: ::c_int = 6; +pub const RLIMIT_NPROC: ::c_int = 7; +pub const RLIMIT_NOFILE: ::c_int = 8; + +pub const RLIM_INFINITY: rlim_t = 0x7fff_ffff_ffff_ffff; +pub const RLIM_SAVED_MAX: rlim_t = RLIM_INFINITY; +pub const RLIM_SAVED_CUR: rlim_t = RLIM_INFINITY; + +pub const RUSAGE_SELF: ::c_int = 0; +pub const RUSAGE_CHILDREN: ::c_int = -1; + +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 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; +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_ISO: ::c_int = 7; +pub const AF_OSI: ::c_int = AF_ISO; +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 AF_HYLINK: ::c_int = 15; +pub const AF_APPLETALK: ::c_int = 16; +pub const AF_LINK: ::c_int = 18; +pub const pseudo_AF_XTP: ::c_int = 19; +pub const AF_COIP: ::c_int = 20; +pub const AF_CNT: ::c_int = 21; +pub const pseudo_AF_RTIP: ::c_int = 22; +pub const AF_IPX: ::c_int = 23; +pub const AF_INET6: ::c_int = 24; +pub const pseudo_AF_PIP: ::c_int = 25; +pub const AF_ISDN: ::c_int = 26; +pub const AF_E164: ::c_int = AF_ISDN; +pub const AF_NATM: ::c_int = 27; + +pub const PF_UNSPEC: ::c_int = AF_UNSPEC; +pub const PF_LOCAL: ::c_int = AF_LOCAL; +pub const PF_UNIX: ::c_int = PF_LOCAL; +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_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_LINK: ::c_int = AF_LINK; +pub const PF_XTP: ::c_int = pseudo_AF_XTP; +pub const PF_COIP: ::c_int = AF_COIP; +pub const PF_CNT: ::c_int = AF_CNT; +pub const PF_IPX: ::c_int = AF_IPX; +pub const PF_INET6: ::c_int = AF_INET6; +pub const PF_RTIP: ::c_int = pseudo_AF_RTIP; +pub const PF_PIP: ::c_int = pseudo_AF_PIP; +pub const PF_ISDN: ::c_int = AF_ISDN; +pub const PF_NATM: ::c_int = AF_NATM; + +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_SEQPACKET: ::c_int = 5; +pub const IP_TTL: ::c_int = 4; +pub const IP_HDRINCL: ::c_int = 2; +pub const IP_ADD_MEMBERSHIP: ::c_int = 12; +pub const IP_DROP_MEMBERSHIP: ::c_int = 13; +pub const IPV6_RECVPKTINFO: ::c_int = 36; +pub const IPV6_PKTINFO: ::c_int = 46; +pub const IPV6_RECVTCLASS: ::c_int = 57; +pub const IPV6_TCLASS: ::c_int = 61; + +pub const SOL_SOCKET: ::c_int = 0xffff; +pub const SO_DEBUG: ::c_int = 0x01; +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_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_ERROR: ::c_int = 0x1007; +pub const SO_TYPE: ::c_int = 0x1008; + +pub const SOMAXCONN: ::c_int = 128; + +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_DONTWAIT: ::c_int = 0x80; +pub const MSG_BCAST: ::c_int = 0x100; +pub const MSG_MCAST: ::c_int = 0x200; +pub const MSG_NOSIGNAL: ::c_int = 0x400; +pub const MSG_CMSG_CLOEXEC: ::c_int = 0x800; + +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 = 1; +pub const LOCK_EX: ::c_int = 2; +pub const LOCK_NB: ::c_int = 4; +pub const LOCK_UN: ::c_int = 8; + +pub const IPPROTO_RAW: ::c_int = 255; + +pub const _SC_ARG_MAX: ::c_int = 1; +pub const _SC_CHILD_MAX: ::c_int = 2; +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_BC_BASE_MAX: ::c_int = 9; +pub const _SC_BC_DIM_MAX: ::c_int = 10; +pub const _SC_BC_SCALE_MAX: ::c_int = 11; +pub const _SC_BC_STRING_MAX: ::c_int = 12; +pub const _SC_COLL_WEIGHTS_MAX: ::c_int = 13; +pub const _SC_EXPR_NEST_MAX: ::c_int = 14; +pub const _SC_LINE_MAX: ::c_int = 15; +pub const _SC_RE_DUP_MAX: ::c_int = 16; +pub const _SC_2_VERSION: ::c_int = 17; +pub const _SC_2_C_BIND: ::c_int = 18; +pub const _SC_2_C_DEV: ::c_int = 19; +pub const _SC_2_CHAR_TERM: ::c_int = 20; +pub const _SC_2_FORT_DEV: ::c_int = 21; +pub const _SC_2_FORT_RUN: ::c_int = 22; +pub const _SC_2_LOCALEDEF: ::c_int = 23; +pub const _SC_2_SW_DEV: ::c_int = 24; +pub const _SC_2_UPE: ::c_int = 25; +pub const _SC_STREAM_MAX: ::c_int = 26; +pub const _SC_TZNAME_MAX: ::c_int = 27; +pub const _SC_PAGESIZE: ::c_int = 28; +pub const _SC_PAGE_SIZE: ::c_int = _SC_PAGESIZE; +pub const _SC_FSYNC: ::c_int = 29; +pub const _SC_XOPEN_SHM: ::c_int = 30; + +pub const Q_GETQUOTA: ::c_int = 0x300; +pub const Q_SETQUOTA: ::c_int = 0x400; + +pub const RTLD_GLOBAL: ::c_int = 0x100; + +pub const LOG_NFACILITIES: ::c_int = 24; + +pub const HW_NCPU: ::c_int = 3; + +pub const B0: speed_t = 0; +pub const B50: speed_t = 50; +pub const B75: speed_t = 75; +pub const B110: speed_t = 110; +pub const B134: speed_t = 134; +pub const B150: speed_t = 150; +pub const B200: speed_t = 200; +pub const B300: speed_t = 300; +pub const B600: speed_t = 600; +pub const B1200: speed_t = 1200; +pub const B1800: speed_t = 1800; +pub const B2400: speed_t = 2400; +pub const B4800: speed_t = 4800; +pub const B9600: speed_t = 9600; +pub const B19200: speed_t = 19200; +pub const B38400: speed_t = 38400; +pub const B7200: speed_t = 7200; +pub const B14400: speed_t = 14400; +pub const B28800: speed_t = 28800; +pub const B57600: speed_t = 57600; +pub const B76800: speed_t = 76800; +pub const B115200: speed_t = 115200; +pub const B230400: speed_t = 230400; +pub const EXTA: speed_t = 19200; +pub const EXTB: speed_t = 38400; + +pub const SEM_FAILED: *mut sem_t = 0 as *mut sem_t; + +pub const CRTSCTS: ::tcflag_t = 0x00010000; +pub const CRTS_IFLOW: ::tcflag_t = CRTSCTS; +pub const CCTS_OFLOW: ::tcflag_t = CRTSCTS; +pub const OCRNL: ::tcflag_t = 0x10; + +pub const TIOCEXCL: ::c_ulong = 0x2000740d; +pub const TIOCNXCL: ::c_ulong = 0x2000740e; +pub const TIOCFLUSH: ::c_ulong = 0x80047410; +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_ulong = 0x4004741a; +pub const TIOCSETD: ::c_ulong = 0x8004741b; +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 TIOCSTART: ::c_ulong = 0x2000746e; +pub const TIOCSTOP: ::c_ulong = 0x2000746f; +pub const TIOCSCTTY: ::c_ulong = 0x20007461; +pub const TIOCGWINSZ: ::c_ulong = 0x40087468; +pub const TIOCSWINSZ: ::c_ulong = 0x80087467; +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_RNG: ::c_int = 0o0200; +pub const TIOCM_DSR: ::c_int = 0o0400; +pub const TIOCM_CD: ::c_int = TIOCM_CAR; +pub const TIOCM_RI: ::c_int = TIOCM_RNG; + +pub const TIMER_ABSTIME: ::c_int = 1; + +// sys/reboot.h + +pub const RB_AUTOBOOT: ::c_int = 0; + +pub const TCP_INFO: ::c_int = 9; + +#[link(name = "util")] +extern "C" { + pub fn setgrent(); + pub fn sem_destroy(sem: *mut sem_t) -> ::c_int; + pub fn sem_init(sem: *mut sem_t, pshared: ::c_int, value: ::c_uint) -> ::c_int; + + pub fn daemon(nochdir: ::c_int, noclose: ::c_int) -> ::c_int; + pub fn accept4( + s: ::c_int, + addr: *mut ::sockaddr, + addrlen: *mut ::socklen_t, + flags: ::c_int, + ) -> ::c_int; + pub fn mincore(addr: *mut ::c_void, len: ::size_t, vec: *mut ::c_char) -> ::c_int; + #[cfg_attr(target_os = "netbsd", link_name = "__clock_getres50")] + pub fn clock_getres(clk_id: ::clockid_t, tp: *mut ::timespec) -> ::c_int; + #[cfg_attr(target_os = "netbsd", link_name = "__clock_gettime50")] + pub fn clock_gettime(clk_id: ::clockid_t, tp: *mut ::timespec) -> ::c_int; + #[cfg_attr(target_os = "netbsd", link_name = "__clock_settime50")] + pub fn clock_settime(clk_id: ::clockid_t, tp: *const ::timespec) -> ::c_int; + pub fn __errno() -> *mut ::c_int; + pub fn shm_open(name: *const ::c_char, oflag: ::c_int, mode: ::mode_t) -> ::c_int; + pub fn memrchr(cx: *const ::c_void, c: ::c_int, n: ::size_t) -> *mut ::c_void; + 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 pwritev(fd: ::c_int, iov: *const ::iovec, iovcnt: ::c_int, offset: ::off_t) + -> ::ssize_t; + pub fn preadv(fd: ::c_int, iov: *const ::iovec, iovcnt: ::c_int, offset: ::off_t) -> ::ssize_t; + pub fn futimens(fd: ::c_int, times: *const ::timespec) -> ::c_int; + pub fn utimensat( + dirfd: ::c_int, + path: *const ::c_char, + times: *const ::timespec, + flag: ::c_int, + ) -> ::c_int; + pub fn fdatasync(fd: ::c_int) -> ::c_int; + 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; + + pub fn mknodat( + dirfd: ::c_int, + pathname: *const ::c_char, + mode: ::mode_t, + dev: dev_t, + ) -> ::c_int; + pub fn mkfifoat(dirfd: ::c_int, pathname: *const ::c_char, mode: ::mode_t) -> ::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 pthread_condattr_setclock( + attr: *mut pthread_condattr_t, + clock_id: ::clockid_t, + ) -> ::c_int; + pub fn sethostname(name: *const ::c_char, len: ::size_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_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( + 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 getdomainname(name: *mut ::c_char, len: ::size_t) -> ::c_int; + pub fn setdomainname(name: *const ::c_char, len: ::size_t) -> ::c_int; + pub fn uname(buf: *mut ::utsname) -> ::c_int; + + 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 execvpe( + file: *const ::c_char, + argv: *const *const ::c_char, + envp: *const *const ::c_char, + ) -> ::c_int; + pub fn waitid( + idtype: idtype_t, + id: ::id_t, + infop: *mut ::siginfo_t, + options: ::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_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; +} + +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; + + pub fn sendmmsg( + sockfd: ::c_int, + mmsg: *mut ::mmsghdr, + vlen: ::c_uint, + flags: ::c_int, + ) -> ::c_int; + pub fn recvmmsg( + sockfd: ::c_int, + mmsg: *mut ::mmsghdr, + vlen: ::c_uint, + flags: ::c_int, + timeout: *mut ::timespec, + ) -> ::c_int; +} + +cfg_if! { + if #[cfg(target_os = "netbsd")] { + mod netbsd; + pub use self::netbsd::*; + } else if #[cfg(target_os = "openbsd")] { + mod openbsd; + pub use self::openbsd::*; + } else { + // Unknown target_os + } +} diff --git a/vendor/libc/src/unix/bsd/netbsdlike/netbsd/aarch64.rs b/vendor/libc/src/unix/bsd/netbsdlike/netbsd/aarch64.rs new file mode 100644 index 0000000..45bca47 --- /dev/null +++ b/vendor/libc/src/unix/bsd/netbsdlike/netbsd/aarch64.rs @@ -0,0 +1,162 @@ +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)] { + #[doc(hidden)] + pub const _ALIGNBYTES: usize = ::mem::size_of::<::c_int>() - 1; + } else { + #[doc(hidden)] + pub const _ALIGNBYTES: usize = 4 - 1; + } +} + +pub const PT_GETREGS: ::c_int = PT_FIRSTMACH + 0; +pub const PT_SETREGS: ::c_int = PT_FIRSTMACH + 1; +pub const PT_GETFPREGS: ::c_int = PT_FIRSTMACH + 2; +pub const PT_SETFPREGS: ::c_int = PT_FIRSTMACH + 3; + +pub const _REG_R0: ::c_int = 0; +pub const _REG_R1: ::c_int = 1; +pub const _REG_R2: ::c_int = 2; +pub const _REG_R3: ::c_int = 3; +pub const _REG_R4: ::c_int = 4; +pub const _REG_R5: ::c_int = 5; +pub const _REG_R6: ::c_int = 6; +pub const _REG_R7: ::c_int = 7; +pub const _REG_R8: ::c_int = 8; +pub const _REG_R9: ::c_int = 9; +pub const _REG_R10: ::c_int = 10; +pub const _REG_R11: ::c_int = 11; +pub const _REG_R12: ::c_int = 12; +pub const _REG_R13: ::c_int = 13; +pub const _REG_R14: ::c_int = 14; +pub const _REG_R15: ::c_int = 15; +pub const _REG_CPSR: ::c_int = 16; +pub const _REG_X0: ::c_int = 0; +pub const _REG_X1: ::c_int = 1; +pub const _REG_X2: ::c_int = 2; +pub const _REG_X3: ::c_int = 3; +pub const _REG_X4: ::c_int = 4; +pub const _REG_X5: ::c_int = 5; +pub const _REG_X6: ::c_int = 6; +pub const _REG_X7: ::c_int = 7; +pub const _REG_X8: ::c_int = 8; +pub const _REG_X9: ::c_int = 9; +pub const _REG_X10: ::c_int = 10; +pub const _REG_X11: ::c_int = 11; +pub const _REG_X12: ::c_int = 12; +pub const _REG_X13: ::c_int = 13; +pub const _REG_X14: ::c_int = 14; +pub const _REG_X15: ::c_int = 15; +pub const _REG_X16: ::c_int = 16; +pub const _REG_X17: ::c_int = 17; +pub const _REG_X18: ::c_int = 18; +pub const _REG_X19: ::c_int = 19; +pub const _REG_X20: ::c_int = 20; +pub const _REG_X21: ::c_int = 21; +pub const _REG_X22: ::c_int = 22; +pub const _REG_X23: ::c_int = 23; +pub const _REG_X24: ::c_int = 24; +pub const _REG_X25: ::c_int = 25; +pub const _REG_X26: ::c_int = 26; +pub const _REG_X27: ::c_int = 27; +pub const _REG_X28: ::c_int = 28; +pub const _REG_X29: ::c_int = 29; +pub const _REG_X30: ::c_int = 30; +pub const _REG_X31: ::c_int = 31; +pub const _REG_ELR: ::c_int = 32; +pub const _REG_SPSR: ::c_int = 33; +pub const _REG_TIPDR: ::c_int = 34; + +pub const _REG_RV: ::c_int = _REG_X0; +pub const _REG_FP: ::c_int = _REG_X29; +pub const _REG_LR: ::c_int = _REG_X30; +pub const _REG_SP: ::c_int = _REG_X31; +pub const _REG_PC: ::c_int = _REG_ELR; diff --git a/vendor/libc/src/unix/bsd/netbsdlike/netbsd/arm.rs b/vendor/libc/src/unix/bsd/netbsdlike/netbsd/arm.rs new file mode 100644 index 0000000..b5000d3 --- /dev/null +++ b/vendor/libc/src/unix/bsd/netbsdlike/netbsd/arm.rs @@ -0,0 +1,81 @@ +use PT_FIRSTMACH; + +pub type c_long = i32; +pub type c_ulong = u32; +pub type c_char = u8; +pub type __cpu_simple_lock_nv_t = ::c_int; + +// 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; + } +} + +pub const PT_GETREGS: ::c_int = PT_FIRSTMACH + 1; +pub const PT_SETREGS: ::c_int = PT_FIRSTMACH + 2; +pub const PT_GETFPREGS: ::c_int = PT_FIRSTMACH + 3; +pub const PT_SETFPREGS: ::c_int = PT_FIRSTMACH + 4; + +pub const _REG_R0: ::c_int = 0; +pub const _REG_R1: ::c_int = 1; +pub const _REG_R2: ::c_int = 2; +pub const _REG_R3: ::c_int = 3; +pub const _REG_R4: ::c_int = 4; +pub const _REG_R5: ::c_int = 5; +pub const _REG_R6: ::c_int = 6; +pub const _REG_R7: ::c_int = 7; +pub const _REG_R8: ::c_int = 8; +pub const _REG_R9: ::c_int = 9; +pub const _REG_R10: ::c_int = 10; +pub const _REG_R11: ::c_int = 11; +pub const _REG_R12: ::c_int = 12; +pub const _REG_R13: ::c_int = 13; +pub const _REG_R14: ::c_int = 14; +pub const _REG_R15: ::c_int = 15; +pub const _REG_CPSR: ::c_int = 16; +pub const _REG_X0: ::c_int = 0; +pub const _REG_X1: ::c_int = 1; +pub const _REG_X2: ::c_int = 2; +pub const _REG_X3: ::c_int = 3; +pub const _REG_X4: ::c_int = 4; +pub const _REG_X5: ::c_int = 5; +pub const _REG_X6: ::c_int = 6; +pub const _REG_X7: ::c_int = 7; +pub const _REG_X8: ::c_int = 8; +pub const _REG_X9: ::c_int = 9; +pub const _REG_X10: ::c_int = 10; +pub const _REG_X11: ::c_int = 11; +pub const _REG_X12: ::c_int = 12; +pub const _REG_X13: ::c_int = 13; +pub const _REG_X14: ::c_int = 14; +pub const _REG_X15: ::c_int = 15; +pub const _REG_X16: ::c_int = 16; +pub const _REG_X17: ::c_int = 17; +pub const _REG_X18: ::c_int = 18; +pub const _REG_X19: ::c_int = 19; +pub const _REG_X20: ::c_int = 20; +pub const _REG_X21: ::c_int = 21; +pub const _REG_X22: ::c_int = 22; +pub const _REG_X23: ::c_int = 23; +pub const _REG_X24: ::c_int = 24; +pub const _REG_X25: ::c_int = 25; +pub const _REG_X26: ::c_int = 26; +pub const _REG_X27: ::c_int = 27; +pub const _REG_X28: ::c_int = 28; +pub const _REG_X29: ::c_int = 29; +pub const _REG_X30: ::c_int = 30; +pub const _REG_X31: ::c_int = 31; +pub const _REG_ELR: ::c_int = 32; +pub const _REG_SPSR: ::c_int = 33; +pub const _REG_TIPDR: ::c_int = 34; + +pub const _REG_RV: ::c_int = _REG_R0; +pub const _REG_FP: ::c_int = _REG_R11; +pub const _REG_LR: ::c_int = _REG_R13; +pub const _REG_SP: ::c_int = _REG_R14; +pub const _REG_PC: ::c_int = _REG_R15; diff --git a/vendor/libc/src/unix/bsd/netbsdlike/netbsd/mips.rs b/vendor/libc/src/unix/bsd/netbsdlike/netbsd/mips.rs new file mode 100644 index 0000000..a536254 --- /dev/null +++ b/vendor/libc/src/unix/bsd/netbsdlike/netbsd/mips.rs @@ -0,0 +1,21 @@ +use PT_FIRSTMACH; + +pub type c_long = i32; +pub type c_ulong = u32; +pub type c_char = i8; +pub type __cpu_simple_lock_nv_t = ::c_int; + +cfg_if! { + if #[cfg(libc_const_size_of)] { + #[doc(hidden)] + pub const _ALIGNBYTES: usize = ::mem::size_of::<::c_longlong>() - 1; + } else { + #[doc(hidden)] + pub const _ALIGNBYTES: usize = 8 - 1; + } +} + +pub const PT_GETREGS: ::c_int = PT_FIRSTMACH + 1; +pub const PT_SETREGS: ::c_int = PT_FIRSTMACH + 2; +pub const PT_GETFPREGS: ::c_int = PT_FIRSTMACH + 3; +pub const PT_SETFPREGS: ::c_int = PT_FIRSTMACH + 4; diff --git a/vendor/libc/src/unix/bsd/netbsdlike/netbsd/mod.rs b/vendor/libc/src/unix/bsd/netbsdlike/netbsd/mod.rs new file mode 100644 index 0000000..da96d09 --- /dev/null +++ b/vendor/libc/src/unix/bsd/netbsdlike/netbsd/mod.rs @@ -0,0 +1,3179 @@ +pub type clock_t = ::c_uint; +pub type suseconds_t = ::c_int; +pub type dev_t = u64; +pub type blksize_t = i32; +pub type fsblkcnt_t = u64; +pub type fsfilcnt_t = u64; +pub type idtype_t = ::c_int; +pub type mqd_t = ::c_int; +type __pthread_spin_t = __cpu_simple_lock_nv_t; +pub type vm_size_t = ::uintptr_t; // FIXME: deprecated since long time +pub type lwpid_t = ::c_uint; +pub type shmatt_t = ::c_uint; +pub type cpuid_t = ::c_ulong; +pub type cpuset_t = _cpuset; +pub type pthread_spin_t = ::c_uchar; +pub type timer_t = ::c_int; + +// elf.h + +pub type Elf32_Addr = u32; +pub type Elf32_Half = u16; +pub type Elf32_Lword = u64; +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_Lword = u64; +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 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; + type Elf_Half = Elf64_Half; + type Elf_Phdr = Elf64_Phdr; + } else if #[cfg(target_pointer_width = "32")] { + type Elf_Addr = Elf32_Addr; + type Elf_Half = Elf32_Half; + type Elf_Phdr = Elf32_Phdr; + } +} + +impl siginfo_t { + pub unsafe fn si_addr(&self) -> *mut ::c_void { + self.si_addr + } + + pub unsafe fn si_code(&self) -> ::c_int { + self.si_code + } + + pub unsafe fn si_errno(&self) -> ::c_int { + self.si_errno + } + + pub unsafe fn si_pid(&self) -> ::pid_t { + #[repr(C)] + struct siginfo_timer { + _si_signo: ::c_int, + _si_errno: ::c_int, + _si_code: ::c_int, + __pad1: ::c_int, + _pid: ::pid_t, + } + (*(self as *const siginfo_t as *const siginfo_timer))._pid + } + + pub unsafe fn si_uid(&self) -> ::uid_t { + #[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, + } + (*(self as *const siginfo_t as *const siginfo_timer))._uid + } + + pub unsafe fn si_value(&self) -> ::sigval { + #[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, + } + (*(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! { + pub struct aiocb { + pub aio_offset: ::off_t, + pub aio_buf: *mut ::c_void, + pub aio_nbytes: ::size_t, + pub aio_fildes: ::c_int, + pub aio_lio_opcode: ::c_int, + pub aio_reqprio: ::c_int, + pub aio_sigevent: ::sigevent, + _state: ::c_int, + _errno: ::c_int, + _retval: ::ssize_t + } + + pub struct glob_t { + pub gl_pathc: ::size_t, + pub gl_matchc: ::size_t, + pub gl_offs: ::size_t, + pub gl_flags: ::c_int, + pub gl_pathv: *mut *mut ::c_char, + + __unused3: *mut ::c_void, + + __unused4: *mut ::c_void, + __unused5: *mut ::c_void, + __unused6: *mut ::c_void, + __unused7: *mut ::c_void, + __unused8: *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 itimerspec { + pub it_interval: ::timespec, + pub it_value: ::timespec, + } + + pub struct sigset_t { + __bits: [u32; 4], + } + + pub struct stat { + pub st_dev: ::dev_t, + pub st_mode: ::mode_t, + pub st_ino: ::ino_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_atimensec: ::c_long, + pub st_mtime: ::time_t, + pub st_mtimensec: ::c_long, + pub st_ctime: ::time_t, + pub st_ctimensec: ::c_long, + pub st_birthtime: ::time_t, + pub st_birthtimensec: ::c_long, + pub st_size: ::off_t, + pub st_blocks: ::blkcnt_t, + pub st_blksize: ::blksize_t, + pub st_flags: u32, + pub st_gen: u32, + pub st_spare: [u32; 2], + } + + 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 siginfo_t { + pub si_signo: ::c_int, + pub si_code: ::c_int, + pub si_errno: ::c_int, + __pad1: ::c_int, + pub si_addr: *mut ::c_void, + __pad2: [u64; 13], + } + + pub struct pthread_attr_t { + pta_magic: ::c_uint, + pta_flags: ::c_int, + pta_private: *mut ::c_void, + } + + pub struct pthread_mutex_t { + ptm_magic: ::c_uint, + ptm_errorcheck: __pthread_spin_t, + #[cfg(any(target_arch = "sparc", target_arch = "sparc64", + target_arch = "x86", target_arch = "x86_64"))] + ptm_pad1: [u8; 3], + // actually a union with a non-unused, 0-initialized field + ptm_unused: __pthread_spin_t, + #[cfg(any(target_arch = "sparc", target_arch = "sparc64", + target_arch = "x86", target_arch = "x86_64"))] + ptm_pad2: [u8; 3], + ptm_owner: ::pthread_t, + ptm_waiters: *mut u8, + ptm_recursed: ::c_uint, + ptm_spare2: *mut ::c_void, + } + + pub struct pthread_mutexattr_t { + ptma_magic: ::c_uint, + ptma_private: *mut ::c_void, + } + + pub struct pthread_rwlockattr_t { + ptra_magic: ::c_uint, + ptra_private: *mut ::c_void, + } + + pub struct pthread_cond_t { + ptc_magic: ::c_uint, + ptc_lock: __pthread_spin_t, + ptc_waiters_first: *mut u8, + ptc_waiters_last: *mut u8, + ptc_mutex: *mut ::pthread_mutex_t, + ptc_private: *mut ::c_void, + } + + pub struct pthread_condattr_t { + ptca_magic: ::c_uint, + ptca_private: *mut ::c_void, + } + + pub struct pthread_rwlock_t { + ptr_magic: ::c_uint, + ptr_interlock: __pthread_spin_t, + ptr_rblocked_first: *mut u8, + ptr_rblocked_last: *mut u8, + ptr_wblocked_first: *mut u8, + ptr_wblocked_last: *mut u8, + ptr_nreaders: ::c_uint, + ptr_owner: ::pthread_t, + 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, + pub flags: u32, + pub fflags: u32, + pub data: i64, + pub udata: ::intptr_t, /* FIXME: NetBSD 10.0 will finally have same layout as other BSD */ + } + + pub struct dqblk { + pub dqb_bhardlimit: u32, + pub dqb_bsoftlimit: u32, + pub dqb_curblocks: u32, + pub dqb_ihardlimit: u32, + pub dqb_isoftlimit: u32, + pub dqb_curinodes: u32, + pub dqb_btime: i32, + pub dqb_itime: i32, + } + + 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: *const ::c_void, + } + + 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 if_data { + pub ifi_type: ::c_uchar, + pub ifi_addrlen: ::c_uchar, + pub ifi_hdrlen: ::c_uchar, + pub ifi_link_state: ::c_int, + pub ifi_mtu: u64, + pub ifi_metric: u64, + 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_lastchange: ::timespec, + } + + pub struct if_msghdr { + 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_data: if_data, + } + + pub struct sockcred { + 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 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, + pub unp_egid: ::gid_t, + } + + pub struct sockaddr_dl { + pub sdl_len: ::c_uchar, + pub sdl_family: ::c_uchar, + pub sdl_index: ::c_ushort, + pub sdl_type: u8, + pub sdl_nlen: u8, + pub sdl_alen: u8, + pub sdl_slen: u8, + pub sdl_data: [::c_char; 12], + } + + pub struct __exit_status { + pub e_termination: u16, + pub e_exit: u16, + } + + 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 utmp { + pub ut_line: [::c_char; UT_LINESIZE], + pub ut_name: [::c_char; UT_NAMESIZE], + pub ut_host: [::c_char; UT_HOSTSIZE], + pub ut_time: ::time_t + } + + pub struct lastlog { + pub ll_line: [::c_char; UT_LINESIZE], + pub ll_host: [::c_char; UT_HOSTSIZE], + pub ll_time: ::time_t + } + + 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 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 struct ntptimeval { + pub time: ::timespec, + pub maxerror: ::c_long, + pub esterror: ::c_long, + pub tai: ::c_long, + pub time_state: ::c_int, + } + + // elf.h + + 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 Aux32Info { + pub a_type: Elf32_Word, + pub a_v: Elf32_Word, + } + + pub struct Aux64Info { + pub a_type: Elf64_Word, + pub a_v: Elf64_Xword, + } + + // link.h + + 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, + pub dlpi_adds: ::c_ulonglong, + pub dlpi_subs: ::c_ulonglong, + pub dlpi_tls_modid: usize, + pub dlpi_tls_data: *mut ::c_void, + } + + pub struct _cpuset { + bits: [u32; 0] + } + + pub struct accept_filter_arg { + 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! { + + pub struct utmpx { + pub ut_name: [::c_char; _UTX_USERSIZE], + pub ut_id: [::c_char; _UTX_IDSIZE], + pub ut_line: [::c_char; _UTX_LINESIZE], + pub ut_host: [::c_char; _UTX_HOSTSIZE], + pub ut_session: u16, + pub ut_type: u16, + pub ut_pid: ::pid_t, + pub ut_exit: __exit_status, // FIXME: when anonymous struct are supported + pub ut_ss: sockaddr_storage, + pub ut_tv: ::timeval, + pub ut_pad: [u8; _UTX_PADSIZE], + } + + 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 in_pktinfo { + pub ipi_addr: ::in_addr, + pub ipi_ifindex: ::c_uint, + } + + 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 in_addr { + pub s_addr: ::in_addr_t, + } + + pub struct ip_mreq { + pub imr_multiaddr: in_addr, + pub imr_interface: in_addr, + } + + pub struct sockaddr_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 dirent { + pub d_fileno: ::ino_t, + pub d_reclen: u16, + pub d_namlen: u16, + pub d_type: u8, + pub d_name: [::c_char; 512], + } + + pub struct statvfs { + pub f_flag: ::c_ulong, + pub f_bsize: ::c_ulong, + pub f_frsize: ::c_ulong, + pub f_iosize: ::c_ulong, + + pub f_blocks: ::fsblkcnt_t, + pub f_bfree: ::fsblkcnt_t, + pub f_bavail: ::fsblkcnt_t, + pub f_bresvd: ::fsblkcnt_t, + + pub f_files: ::fsfilcnt_t, + pub f_ffree: ::fsfilcnt_t, + pub f_favail: ::fsfilcnt_t, + pub f_fresvd: ::fsfilcnt_t, + + pub f_syncreads: u64, + pub f_syncwrites: u64, + + pub f_asyncreads: u64, + pub f_asyncwrites: u64, + + pub f_fsidx: ::fsid_t, + pub f_fsid: ::c_ulong, + pub f_namemax: ::c_ulong, + pub f_owner: ::uid_t, + + pub f_spare: [u32; 4], + + pub f_fstypename: [::c_char; 32], + pub f_mntonname: [::c_char; 1024], + pub f_mntfromname: [::c_char; 1024], + } + + pub struct sockaddr_storage { + pub ss_len: u8, + pub ss_family: ::sa_family_t, + __ss_pad1: [u8; 6], + __ss_pad2: i64, + __ss_pad3: [u8; 112], + } + + pub struct sigevent { + pub sigev_notify: ::c_int, + pub sigev_signo: ::c_int, + pub sigev_value: ::sigval, + __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! { + if #[cfg(feature = "extra_traits")] { + impl PartialEq for utmpx { + fn eq(&self, other: &utmpx) -> bool { + self.ut_type == other.ut_type + && self.ut_pid == other.ut_pid + && self.ut_name == other.ut_name + && self.ut_line == other.ut_line + && self.ut_id == other.ut_id + && self.ut_exit == other.ut_exit + && self.ut_session == other.ut_session + && self.ut_tv == other.ut_tv + && self.ut_ss == other.ut_ss + && self + .ut_pad + .iter() + .zip(other.ut_pad.iter()) + .all(|(a,b)| a == b) + && self + .ut_host + .iter() + .zip(other.ut_host.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_name", &self.ut_name) + .field("ut_id", &self.ut_id) + .field("ut_line", &self.ut_line) + // FIXME .field("ut_host", &self.ut_host) + .field("ut_session", &self.ut_session) + .field("ut_type", &self.ut_type) + .field("ut_pid", &self.ut_pid) + .field("ut_exit", &self.ut_exit) + .field("ut_ss", &self.ut_ss) + .field("ut_tv", &self.ut_tv) + // FIXME .field("ut_pad", &self.ut_pad) + .finish() + } + } + + impl ::hash::Hash for utmpx { + fn hash(&self, state: &mut H) { + self.ut_name.hash(state); + self.ut_type.hash(state); + self.ut_pid.hash(state); + self.ut_line.hash(state); + self.ut_id.hash(state); + self.ut_host.hash(state); + self.ut_exit.hash(state); + self.ut_session.hash(state); + self.ut_tv.hash(state); + self.ut_ss.hash(state); + self.ut_pad.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_ss == other.ll_ss + && self + .ll_host + .iter() + .zip(other.ll_host.iter()) + .all(|(a,b)| a == b) + } + } + + 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) + // FIXME.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 in_pktinfo { + fn eq(&self, other: &in_pktinfo) -> bool { + self.ipi_addr == other.ipi_addr + && self.ipi_ifindex == other.ipi_ifindex + } + } + impl Eq for in_pktinfo {} + impl ::fmt::Debug for in_pktinfo { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("in_pktinfo") + .field("ipi_addr", &self.ipi_addr) + .field("ipi_ifindex", &self.ipi_ifindex) + .finish() + } + } + impl ::hash::Hash for in_pktinfo { + fn hash(&self, state: &mut H) { + self.ipi_addr.hash(state); + self.ipi_ifindex.hash(state); + } + } + + impl PartialEq for arphdr { + fn eq(&self, other: &arphdr) -> bool { + self.ar_hrd == other.ar_hrd + && self.ar_pro == other.ar_pro + && self.ar_hln == other.ar_hln + && self.ar_pln == other.ar_pln + && self.ar_op == other.ar_op + } + } + impl Eq for arphdr {} + impl ::fmt::Debug for arphdr { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + let ar_hrd = self.ar_hrd; + let ar_pro = self.ar_pro; + let ar_op = self.ar_op; + f.debug_struct("arphdr") + .field("ar_hrd", &ar_hrd) + .field("ar_pro", &ar_pro) + .field("ar_hln", &self.ar_hln) + .field("ar_pln", &self.ar_pln) + .field("ar_op", &ar_op) + .finish() + } + } + impl ::hash::Hash for arphdr { + fn hash(&self, state: &mut H) { + let ar_hrd = self.ar_hrd; + let ar_pro = self.ar_pro; + let ar_op = self.ar_op; + ar_hrd.hash(state); + ar_pro.hash(state); + self.ar_hln.hash(state); + self.ar_pln.hash(state); + ar_op.hash(state); + } + } + + impl PartialEq for in_addr { + fn eq(&self, other: &in_addr) -> bool { + self.s_addr == other.s_addr + } + } + impl Eq for in_addr {} + impl ::fmt::Debug for in_addr { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + let s_addr = self.s_addr; + f.debug_struct("in_addr") + .field("s_addr", &s_addr) + .finish() + } + } + impl ::hash::Hash for in_addr { + fn hash(&self, state: &mut H) { + let s_addr = self.s_addr; + s_addr.hash(state); + } + } + + impl PartialEq for ip_mreq { + fn eq(&self, other: &ip_mreq) -> bool { + self.imr_multiaddr == other.imr_multiaddr + && self.imr_interface == other.imr_interface + } + } + impl Eq for ip_mreq {} + impl ::fmt::Debug for ip_mreq { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("ip_mreq") + .field("imr_multiaddr", &self.imr_multiaddr) + .field("imr_interface", &self.imr_interface) + .finish() + } + } + impl ::hash::Hash for ip_mreq { + fn hash(&self, state: &mut H) { + self.imr_multiaddr.hash(state); + self.imr_interface.hash(state); + } + } + + impl PartialEq for sockaddr_in { + fn eq(&self, other: &sockaddr_in) -> bool { + self.sin_len == other.sin_len + && self.sin_family == other.sin_family + && self.sin_port == other.sin_port + && self.sin_addr == other.sin_addr + && self.sin_zero == other.sin_zero + } + } + impl Eq for sockaddr_in {} + impl ::fmt::Debug for sockaddr_in { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("sockaddr_in") + .field("sin_len", &self.sin_len) + .field("sin_family", &self.sin_family) + .field("sin_port", &self.sin_port) + .field("sin_addr", &self.sin_addr) + .field("sin_zero", &self.sin_zero) + .finish() + } + } + impl ::hash::Hash for sockaddr_in { + fn hash(&self, state: &mut H) { + self.sin_len.hash(state); + self.sin_family.hash(state); + self.sin_port.hash(state); + self.sin_addr.hash(state); + self.sin_zero.hash(state); + } + } + + impl PartialEq for dirent { + fn eq(&self, other: &dirent) -> bool { + self.d_fileno == other.d_fileno + && self.d_reclen == other.d_reclen + && self.d_namlen == other.d_namlen + && self.d_type == other.d_type + && self + .d_name + .iter() + .zip(other.d_name.iter()) + .all(|(a,b)| a == b) + } + } + impl Eq for dirent {} + impl ::fmt::Debug for dirent { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("dirent") + .field("d_fileno", &self.d_fileno) + .field("d_reclen", &self.d_reclen) + .field("d_namlen", &self.d_namlen) + .field("d_type", &self.d_type) + // FIXME: .field("d_name", &self.d_name) + .finish() + } + } + impl ::hash::Hash for dirent { + fn hash(&self, state: &mut H) { + self.d_fileno.hash(state); + self.d_reclen.hash(state); + self.d_namlen.hash(state); + self.d_type.hash(state); + self.d_name.hash(state); + } + } + + impl PartialEq for statvfs { + fn eq(&self, other: &statvfs) -> bool { + self.f_flag == other.f_flag + && self.f_bsize == other.f_bsize + && self.f_frsize == other.f_frsize + && self.f_iosize == other.f_iosize + && self.f_blocks == other.f_blocks + && self.f_bfree == other.f_bfree + && self.f_bavail == other.f_bavail + && self.f_bresvd == other.f_bresvd + && self.f_files == other.f_files + && self.f_ffree == other.f_ffree + && self.f_favail == other.f_favail + && self.f_fresvd == other.f_fresvd + && self.f_syncreads == other.f_syncreads + && self.f_syncwrites == other.f_syncwrites + && self.f_asyncreads == other.f_asyncreads + && self.f_asyncwrites == other.f_asyncwrites + && self.f_fsidx == other.f_fsidx + && self.f_fsid == other.f_fsid + && self.f_namemax == other.f_namemax + && self.f_owner == other.f_owner + && self.f_spare == other.f_spare + && self.f_fstypename == other.f_fstypename + && self + .f_mntonname + .iter() + .zip(other.f_mntonname.iter()) + .all(|(a,b)| a == b) + && self + .f_mntfromname + .iter() + .zip(other.f_mntfromname.iter()) + .all(|(a,b)| a == b) + } + } + impl Eq for statvfs {} + impl ::fmt::Debug for statvfs { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("statvfs") + .field("f_flag", &self.f_flag) + .field("f_bsize", &self.f_bsize) + .field("f_frsize", &self.f_frsize) + .field("f_iosize", &self.f_iosize) + .field("f_blocks", &self.f_blocks) + .field("f_bfree", &self.f_bfree) + .field("f_bavail", &self.f_bavail) + .field("f_bresvd", &self.f_bresvd) + .field("f_files", &self.f_files) + .field("f_ffree", &self.f_ffree) + .field("f_favail", &self.f_favail) + .field("f_fresvd", &self.f_fresvd) + .field("f_syncreads", &self.f_syncreads) + .field("f_syncwrites", &self.f_syncwrites) + .field("f_asyncreads", &self.f_asyncreads) + .field("f_asyncwrites", &self.f_asyncwrites) + .field("f_fsidx", &self.f_fsidx) + .field("f_fsid", &self.f_fsid) + .field("f_namemax", &self.f_namemax) + .field("f_owner", &self.f_owner) + .field("f_spare", &self.f_spare) + .field("f_fstypename", &self.f_fstypename) + // FIXME: .field("f_mntonname", &self.f_mntonname) + // FIXME: .field("f_mntfromname", &self.f_mntfromname) + .finish() + } + } + impl ::hash::Hash for statvfs { + fn hash(&self, state: &mut H) { + self.f_flag.hash(state); + self.f_bsize.hash(state); + self.f_frsize.hash(state); + self.f_iosize.hash(state); + self.f_blocks.hash(state); + self.f_bfree.hash(state); + self.f_bavail.hash(state); + self.f_bresvd.hash(state); + self.f_files.hash(state); + self.f_ffree.hash(state); + self.f_favail.hash(state); + self.f_fresvd.hash(state); + self.f_syncreads.hash(state); + self.f_syncwrites.hash(state); + self.f_asyncreads.hash(state); + self.f_asyncwrites.hash(state); + self.f_fsidx.hash(state); + self.f_fsid.hash(state); + self.f_namemax.hash(state); + self.f_owner.hash(state); + self.f_spare.hash(state); + self.f_fstypename.hash(state); + self.f_mntonname.hash(state); + self.f_mntfromname.hash(state); + } + } + + impl PartialEq for sockaddr_storage { + fn eq(&self, other: &sockaddr_storage) -> bool { + self.ss_len == other.ss_len + && self.ss_family == other.ss_family + && self.__ss_pad1 == other.__ss_pad1 + && self.__ss_pad2 == other.__ss_pad2 + && self + .__ss_pad3 + .iter() + .zip(other.__ss_pad3.iter()) + .all(|(a,b)| a == b) + } + } + impl Eq for sockaddr_storage {} + impl ::fmt::Debug for sockaddr_storage { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("sockaddr_storage") + .field("ss_len", &self.ss_len) + .field("ss_family", &self.ss_family) + .field("__ss_pad1", &self.__ss_pad1) + .field("__ss_pad2", &self.__ss_pad2) + // FIXME: .field("__ss_pad3", &self.__ss_pad3) + .finish() + } + } + impl ::hash::Hash for sockaddr_storage { + fn hash(&self, state: &mut H) { + self.ss_len.hash(state); + self.ss_family.hash(state); + self.__ss_pad1.hash(state); + self.__ss_pad2.hash(state); + self.__ss_pad3.hash(state); + } + } + + impl PartialEq for 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_attributes + == other.sigev_notify_attributes + } + } + 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_attributes", + &self.sigev_notify_attributes) + .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_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); + } + } + } + } +} + +pub const AT_FDCWD: ::c_int = -100; +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_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; + +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; +pub const LC_ALL_MASK: ::c_int = !0; + +pub const ERA: ::nl_item = 52; +pub const ERA_D_FMT: ::nl_item = 53; +pub const ERA_D_T_FMT: ::nl_item = 54; +pub const ERA_T_FMT: ::nl_item = 55; +pub const ALT_DIGITS: ::nl_item = 56; + +pub const O_CLOEXEC: ::c_int = 0x400000; +pub const O_ALT_IO: ::c_int = 0x40000; +pub const O_NOSIGPIPE: ::c_int = 0x1000000; +pub const O_SEARCH: ::c_int = 0x800000; +pub const O_DIRECTORY: ::c_int = 0x200000; +pub const O_DIRECT: ::c_int = 0x00080000; +pub const O_RSYNC: ::c_int = 0x00020000; + +pub const MS_SYNC: ::c_int = 0x4; +pub const MS_INVALIDATE: ::c_int = 0x2; + +// Here because they are not present on OpenBSD +// (https://github.com/openbsd/src/blob/HEAD/sys/sys/resource.h) +pub const RLIMIT_SBSIZE: ::c_int = 9; +pub const RLIMIT_AS: ::c_int = 10; +pub const RLIMIT_NTHR: ::c_int = 11; + +#[deprecated(since = "0.2.64", note = "Not stable across OS versions")] +pub const RLIM_NLIMITS: ::c_int = 12; + +pub const EIDRM: ::c_int = 82; +pub const ENOMSG: ::c_int = 83; +pub const EOVERFLOW: ::c_int = 84; +pub const EILSEQ: ::c_int = 85; +pub const ENOTSUP: ::c_int = 86; +pub const ECANCELED: ::c_int = 87; +pub const EBADMSG: ::c_int = 88; +pub const ENODATA: ::c_int = 89; +pub const ENOSR: ::c_int = 90; +pub const ENOSTR: ::c_int = 91; +pub const ETIME: ::c_int = 92; +pub const ENOATTR: ::c_int = 93; +pub const EMULTIHOP: ::c_int = 94; +pub const ENOLINK: ::c_int = 95; +pub const EPROTO: ::c_int = 96; +pub const EOWNERDEAD: ::c_int = 97; +pub const ENOTRECOVERABLE: ::c_int = 98; +#[deprecated( + since = "0.2.143", + note = "This value will always match the highest defined error number \ + and thus is not stable. \ + See #3040 for more info." +)] +pub const ELAST: ::c_int = 98; + +pub const F_DUPFD_CLOEXEC: ::c_int = 12; +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; +pub const IP_RECVIF: ::c_int = 20; +pub const IP_PKTINFO: ::c_int = 25; +pub const IP_RECVPKTINFO: ::c_int = 26; +pub const IPV6_JOIN_GROUP: ::c_int = 12; +pub const IPV6_LEAVE_GROUP: ::c_int = 13; + +pub const TCP_KEEPIDLE: ::c_int = 3; +pub const TCP_KEEPINTVL: ::c_int = 5; +pub const TCP_KEEPCNT: ::c_int = 6; +pub const TCP_KEEPINIT: ::c_int = 7; +pub const TCP_MD5SIG: ::c_int = 0x10; +pub const TCP_CONGCTL: ::c_int = 0x20; + +pub const SOCK_CONN_DGRAM: ::c_int = 6; +pub const SOCK_DCCP: ::c_int = SOCK_CONN_DGRAM; +pub const SOCK_NOSIGPIPE: ::c_int = 0x40000000; +pub const SOCK_FLAGS_MASK: ::c_int = 0xf0000000; + +pub const SO_SNDTIMEO: ::c_int = 0x100b; +pub const SO_RCVTIMEO: ::c_int = 0x100c; +pub const SO_NOSIGPIPE: ::c_int = 0x0800; +pub const SO_ACCEPTFILTER: ::c_int = 0x1000; +pub const SO_TIMESTAMP: ::c_int = 0x2000; +pub const SO_OVERFLOWED: ::c_int = 0x1009; +pub const SO_NOHEADER: ::c_int = 0x100a; + +// http://cvsweb.netbsd.org/bsdweb.cgi/src/sys/sys/un.h?annotate +pub const LOCAL_OCREDS: ::c_int = 0x0001; // pass credentials to receiver +pub const LOCAL_CONNWAIT: ::c_int = 0x0002; // connects block until accepted +pub const LOCAL_PEEREID: ::c_int = 0x0003; // get peer identification +pub const LOCAL_CREDS: ::c_int = 0x0004; // pass credentials to receiver + +// https://github.com/NetBSD/src/blob/trunk/sys/net/if.h#L373 +pub const IFF_UP: ::c_int = 0x0001; // interface is up +pub const IFF_BROADCAST: ::c_int = 0x0002; // broadcast address valid +pub const IFF_DEBUG: ::c_int = 0x0004; // turn on debugging +pub const IFF_LOOPBACK: ::c_int = 0x0008; // is a loopback net +pub const IFF_POINTOPOINT: ::c_int = 0x0010; // interface is point-to-point link +pub const IFF_NOTRAILERS: ::c_int = 0x0020; // avoid use of trailers +pub const IFF_RUNNING: ::c_int = 0x0040; // resources allocated +pub const IFF_NOARP: ::c_int = 0x0080; // no address resolution protocol +pub const IFF_PROMISC: ::c_int = 0x0100; // receive all packets +pub const IFF_ALLMULTI: ::c_int = 0x0200; // receive all multicast packets +pub const IFF_OACTIVE: ::c_int = 0x0400; // transmission in progress +pub const IFF_SIMPLEX: ::c_int = 0x0800; // 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_MULTICAST: ::c_int = 0x8000; // supports multicast + +// sys/netinet/in.h +// Protocols (RFC 1700) +// NOTE: These are in addition to the constants defined in src/unix/mod.rs + +// IPPROTO_IP defined in src/unix/mod.rs +/// Hop-by-hop option header +pub const IPPROTO_HOPOPTS: ::c_int = 0; +// IPPROTO_ICMP defined in src/unix/mod.rs +/// group mgmt protocol +pub const IPPROTO_IGMP: ::c_int = 2; +/// gateway^2 (deprecated) +pub const IPPROTO_GGP: ::c_int = 3; +/// for compatibility +pub const IPPROTO_IPIP: ::c_int = 4; +// IPPROTO_TCP defined in src/unix/mod.rs +/// exterior gateway protocol +pub const IPPROTO_EGP: ::c_int = 8; +/// pup +pub const IPPROTO_PUP: ::c_int = 12; +// IPPROTO_UDP defined in src/unix/mod.rs +/// xns idp +pub const IPPROTO_IDP: ::c_int = 22; +/// tp-4 w/ class negotiation +pub const IPPROTO_TP: ::c_int = 29; +/// DCCP +pub const IPPROTO_DCCP: ::c_int = 33; +// IPPROTO_IPV6 defined in src/unix/mod.rs +/// IP6 routing header +pub const IPPROTO_ROUTING: ::c_int = 43; +/// IP6 fragmentation header +pub const IPPROTO_FRAGMENT: ::c_int = 44; +/// resource reservation +pub const IPPROTO_RSVP: ::c_int = 46; +/// General Routing Encap. +pub const IPPROTO_GRE: ::c_int = 47; +/// IP6 Encap Sec. Payload +pub const IPPROTO_ESP: ::c_int = 50; +/// IP6 Auth Header +pub const IPPROTO_AH: ::c_int = 51; +/// IP Mobility RFC 2004 +pub const IPPROTO_MOBILE: ::c_int = 55; +/// IPv6 ICMP +pub const IPPROTO_IPV6_ICMP: ::c_int = 58; +// IPPROTO_ICMPV6 defined in src/unix/mod.rs +/// IP6 no next header +pub const IPPROTO_NONE: ::c_int = 59; +/// IP6 destination option +pub const IPPROTO_DSTOPTS: ::c_int = 60; +/// ISO cnlp +pub const IPPROTO_EON: ::c_int = 80; +/// Ethernet-in-IP +pub const IPPROTO_ETHERIP: ::c_int = 97; +/// encapsulation header +pub const IPPROTO_ENCAP: ::c_int = 98; +/// Protocol indep. multicast +pub const IPPROTO_PIM: ::c_int = 103; +/// IP Payload Comp. Protocol +pub const IPPROTO_IPCOMP: ::c_int = 108; +/// VRRP RFC 2338 +pub const IPPROTO_VRRP: ::c_int = 112; +/// Common Address Resolution Protocol +pub const IPPROTO_CARP: ::c_int = 112; +/// L2TPv3 +pub const IPPROTO_L2TP: ::c_int = 115; +/// SCTP +pub const IPPROTO_SCTP: ::c_int = 132; +/// PFSYNC +pub const IPPROTO_PFSYNC: ::c_int = 240; +pub const IPPROTO_MAX: ::c_int = 256; + +/// last return value of *_input(), meaning "all job for this pkt is done". +pub const IPPROTO_DONE: ::c_int = 257; + +/// sysctl placeholder for (FAST_)IPSEC +pub const CTL_IPPROTO_IPSEC: ::c_int = 258; + +pub const AF_OROUTE: ::c_int = 17; +pub const AF_ARP: ::c_int = 28; +pub const pseudo_AF_KEY: ::c_int = 29; +pub const pseudo_AF_HDRCMPLT: ::c_int = 30; +pub const AF_BLUETOOTH: ::c_int = 31; +pub const AF_IEEE80211: ::c_int = 32; +pub const AF_MPLS: ::c_int = 33; +pub const AF_ROUTE: ::c_int = 34; +pub const NET_RT_DUMP: ::c_int = 1; +pub const NET_RT_FLAGS: ::c_int = 2; +pub const NET_RT_OOOIFLIST: ::c_int = 3; +pub const NET_RT_OOIFLIST: ::c_int = 4; +pub const NET_RT_OIFLIST: ::c_int = 5; +pub const NET_RT_IFLIST: ::c_int = 6; +pub const NET_RT_MAXID: ::c_int = 7; + +pub const PF_OROUTE: ::c_int = AF_OROUTE; +pub const PF_ARP: ::c_int = AF_ARP; +pub const PF_KEY: ::c_int = pseudo_AF_KEY; +pub const PF_BLUETOOTH: ::c_int = AF_BLUETOOTH; +pub const PF_MPLS: ::c_int = AF_MPLS; +pub const PF_ROUTE: ::c_int = AF_ROUTE; + +pub const MSG_NBIO: ::c_int = 0x1000; +pub const MSG_WAITFORONE: ::c_int = 0x2000; +pub const MSG_NOTIFICATION: ::c_int = 0x4000; + +pub const SCM_TIMESTAMP: ::c_int = 0x08; +pub const SCM_CREDS: ::c_int = 0x10; + +pub const O_DSYNC: ::c_int = 0x10000; + +pub const MAP_RENAME: ::c_int = 0x20; +pub const MAP_NORESERVE: ::c_int = 0x40; +pub const MAP_HASSEMAPHORE: ::c_int = 0x200; +pub const MAP_TRYFIXED: ::c_int = 0x400; +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; + +pub const DCCP_TYPE_REQUEST: ::c_int = 0; +pub const DCCP_TYPE_RESPONSE: ::c_int = 1; +pub const DCCP_TYPE_DATA: ::c_int = 2; +pub const DCCP_TYPE_ACK: ::c_int = 3; +pub const DCCP_TYPE_DATAACK: ::c_int = 4; +pub const DCCP_TYPE_CLOSEREQ: ::c_int = 5; +pub const DCCP_TYPE_CLOSE: ::c_int = 6; +pub const DCCP_TYPE_RESET: ::c_int = 7; +pub const DCCP_TYPE_MOVE: ::c_int = 8; + +pub const DCCP_FEATURE_CC: ::c_int = 1; +pub const DCCP_FEATURE_ECN: ::c_int = 2; +pub const DCCP_FEATURE_ACKRATIO: ::c_int = 3; +pub const DCCP_FEATURE_ACKVECTOR: ::c_int = 4; +pub const DCCP_FEATURE_MOBILITY: ::c_int = 5; +pub const DCCP_FEATURE_LOSSWINDOW: ::c_int = 6; +pub const DCCP_FEATURE_CONN_NONCE: ::c_int = 8; +pub const DCCP_FEATURE_IDENTREG: ::c_int = 7; + +pub const DCCP_OPT_PADDING: ::c_int = 0; +pub const DCCP_OPT_DATA_DISCARD: ::c_int = 1; +pub const DCCP_OPT_SLOW_RECV: ::c_int = 2; +pub const DCCP_OPT_BUF_CLOSED: ::c_int = 3; +pub const DCCP_OPT_CHANGE_L: ::c_int = 32; +pub const DCCP_OPT_CONFIRM_L: ::c_int = 33; +pub const DCCP_OPT_CHANGE_R: ::c_int = 34; +pub const DCCP_OPT_CONFIRM_R: ::c_int = 35; +pub const DCCP_OPT_INIT_COOKIE: ::c_int = 36; +pub const DCCP_OPT_NDP_COUNT: ::c_int = 37; +pub const DCCP_OPT_ACK_VECTOR0: ::c_int = 38; +pub const DCCP_OPT_ACK_VECTOR1: ::c_int = 39; +pub const DCCP_OPT_RECV_BUF_DROPS: ::c_int = 40; +pub const DCCP_OPT_TIMESTAMP: ::c_int = 41; +pub const DCCP_OPT_TIMESTAMP_ECHO: ::c_int = 42; +pub const DCCP_OPT_ELAPSEDTIME: ::c_int = 43; +pub const DCCP_OPT_DATACHECKSUM: ::c_int = 44; + +pub const DCCP_REASON_UNSPEC: ::c_int = 0; +pub const DCCP_REASON_CLOSED: ::c_int = 1; +pub const DCCP_REASON_INVALID: ::c_int = 2; +pub const DCCP_REASON_OPTION_ERR: ::c_int = 3; +pub const DCCP_REASON_FEA_ERR: ::c_int = 4; +pub const DCCP_REASON_CONN_REF: ::c_int = 5; +pub const DCCP_REASON_BAD_SNAME: ::c_int = 6; +pub const DCCP_REASON_BAD_COOKIE: ::c_int = 7; +pub const DCCP_REASON_INV_MOVE: ::c_int = 8; +pub const DCCP_REASON_UNANSW_CH: ::c_int = 10; +pub const DCCP_REASON_FRUITLESS_NEG: ::c_int = 11; + +pub const DCCP_CCID: ::c_int = 1; +pub const DCCP_CSLEN: ::c_int = 2; +pub const DCCP_MAXSEG: ::c_int = 4; +pub const DCCP_SERVICE: ::c_int = 8; + +pub const DCCP_NDP_LIMIT: ::c_int = 16; +pub const DCCP_SEQ_NUM_LIMIT: ::c_int = 16777216; +pub const DCCP_MAX_OPTIONS: ::c_int = 32; +pub const DCCP_MAX_PKTS: ::c_int = 100; + +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 = 7; +pub const _PC_NO_TRUNC: ::c_int = 8; +pub const _PC_VDISABLE: ::c_int = 9; +pub const _PC_SYNC_IO: ::c_int = 10; +pub const _PC_FILESIZEBITS: ::c_int = 11; +pub const _PC_SYMLINK_MAX: ::c_int = 12; +pub const _PC_2_SYMLINKS: ::c_int = 13; +pub const _PC_ACL_EXTENDED: ::c_int = 14; +pub const _PC_MIN_HOLE_SIZE: ::c_int = 15; + +pub const _SC_SYNCHRONIZED_IO: ::c_int = 31; +pub const _SC_IOV_MAX: ::c_int = 32; +pub const _SC_MAPPED_FILES: ::c_int = 33; +pub const _SC_MEMLOCK: ::c_int = 34; +pub const _SC_MEMLOCK_RANGE: ::c_int = 35; +pub const _SC_MEMORY_PROTECTION: ::c_int = 36; +pub const _SC_LOGIN_NAME_MAX: ::c_int = 37; +pub const _SC_MONOTONIC_CLOCK: ::c_int = 38; +pub const _SC_CLK_TCK: ::c_int = 39; +pub const _SC_ATEXIT_MAX: ::c_int = 40; +pub const _SC_THREADS: ::c_int = 41; +pub const _SC_SEMAPHORES: ::c_int = 42; +pub const _SC_BARRIERS: ::c_int = 43; +pub const _SC_TIMERS: ::c_int = 44; +pub const _SC_SPIN_LOCKS: ::c_int = 45; +pub const _SC_READER_WRITER_LOCKS: ::c_int = 46; +pub const _SC_GETGR_R_SIZE_MAX: ::c_int = 47; +pub const _SC_GETPW_R_SIZE_MAX: ::c_int = 48; +pub const _SC_CLOCK_SELECTION: ::c_int = 49; +pub const _SC_ASYNCHRONOUS_IO: ::c_int = 50; +pub const _SC_AIO_LISTIO_MAX: ::c_int = 51; +pub const _SC_AIO_MAX: ::c_int = 52; +pub const _SC_MESSAGE_PASSING: ::c_int = 53; +pub const _SC_MQ_OPEN_MAX: ::c_int = 54; +pub const _SC_MQ_PRIO_MAX: ::c_int = 55; +pub const _SC_PRIORITY_SCHEDULING: ::c_int = 56; +pub const _SC_THREAD_DESTRUCTOR_ITERATIONS: ::c_int = 57; +pub const _SC_THREAD_KEYS_MAX: ::c_int = 58; +pub const _SC_THREAD_STACK_MIN: ::c_int = 59; +pub const _SC_THREAD_THREADS_MAX: ::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 = 63; +pub const _SC_THREAD_PRIO_INHERIT: ::c_int = 64; +pub const _SC_THREAD_PRIO_PROTECT: ::c_int = 65; +pub const _SC_THREAD_PROCESS_SHARED: ::c_int = 66; +pub const _SC_THREAD_SAFE_FUNCTIONS: ::c_int = 67; +pub const _SC_TTY_NAME_MAX: ::c_int = 68; +pub const _SC_HOST_NAME_MAX: ::c_int = 69; +pub const _SC_PASS_MAX: ::c_int = 70; +pub const _SC_REGEXP: ::c_int = 71; +pub const _SC_SHELL: ::c_int = 72; +pub const _SC_SYMLOOP_MAX: ::c_int = 73; +pub const _SC_V6_ILP32_OFF32: ::c_int = 74; +pub const _SC_V6_ILP32_OFFBIG: ::c_int = 75; +pub const _SC_V6_LP64_OFF64: ::c_int = 76; +pub const _SC_V6_LPBIG_OFFBIG: ::c_int = 77; +pub const _SC_2_PBS: ::c_int = 80; +pub const _SC_2_PBS_ACCOUNTING: ::c_int = 81; +pub const _SC_2_PBS_CHECKPOINT: ::c_int = 82; +pub const _SC_2_PBS_LOCATE: ::c_int = 83; +pub const _SC_2_PBS_MESSAGE: ::c_int = 84; +pub const _SC_2_PBS_TRACK: ::c_int = 85; +pub const _SC_SPAWN: ::c_int = 86; +pub const _SC_SHARED_MEMORY_OBJECTS: ::c_int = 87; +pub const _SC_TIMER_MAX: ::c_int = 88; +pub const _SC_SEM_NSEMS_MAX: ::c_int = 89; +pub const _SC_CPUTIME: ::c_int = 90; +pub const _SC_THREAD_CPUTIME: ::c_int = 91; +pub const _SC_DELAYTIMER_MAX: ::c_int = 92; +// These two variables will be supported in NetBSD 8.0 +// pub const _SC_SIGQUEUE_MAX : ::c_int = 93; +// pub const _SC_REALTIME_SIGNALS : ::c_int = 94; +pub const _SC_PHYS_PAGES: ::c_int = 121; +pub const _SC_NPROCESSORS_CONF: ::c_int = 1001; +pub const _SC_NPROCESSORS_ONLN: ::c_int = 1002; +pub const _SC_SCHED_RT_TS: ::c_int = 2001; +pub const _SC_SCHED_PRI_MIN: ::c_int = 2002; +pub const _SC_SCHED_PRI_MAX: ::c_int = 2003; + +pub const FD_SETSIZE: usize = 0x100; + +pub const ST_NOSUID: ::c_ulong = 8; + +pub const BIOCGRSIG: ::c_ulong = 0x40044272; +pub const BIOCSRSIG: ::c_ulong = 0x80044273; +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 MNT_WAIT: ::c_int = 1; +pub const MNT_NOWAIT: ::c_int = 2; +pub const MNT_LAZY: ::c_int = 3; + +// +pub const CLOCK_PROCESS_CPUTIME_ID: ::clockid_t = 2; +pub const CLOCK_THREAD_CPUTIME_ID: ::clockid_t = 4; +pub const NTP_API: ::c_int = 4; +pub const MAXPHASE: ::c_long = 500000000; +pub const MAXFREQ: ::c_long = 500000; +pub const MINSEC: ::c_int = 256; +pub const MAXSEC: ::c_int = 2048; +pub const NANOSECOND: ::c_long = 1000000000; +pub const SCALE_PPM: ::c_int = 65; +pub const MAXTC: ::c_int = 10; +pub const MOD_OFFSET: ::c_uint = 0x0001; +pub const MOD_FREQUENCY: ::c_uint = 0x0002; +pub const MOD_MAXERROR: ::c_uint = 0x0004; +pub const MOD_ESTERROR: ::c_uint = 0x0008; +pub const MOD_STATUS: ::c_uint = 0x0010; +pub const MOD_TIMECONST: ::c_uint = 0x0020; +pub const MOD_PPSMAX: ::c_uint = 0x0040; +pub const MOD_TAI: ::c_uint = 0x0080; +pub const MOD_MICRO: ::c_uint = 0x1000; +pub const MOD_NANO: ::c_uint = 0x2000; +pub const MOD_CLKB: ::c_uint = 0x4000; +pub const MOD_CLKA: ::c_uint = 0x8000; +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 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"))] { + pub const PTHREAD_MUTEX_INITIALIZER: pthread_mutex_t + = pthread_mutex_t { + ptm_magic: 0x33330003, + ptm_errorcheck: 0, + ptm_pad1: [0; 3], + ptm_unused: 0, + ptm_pad2: [0; 3], + ptm_waiters: 0 as *mut _, + ptm_owner: 0, + ptm_recursed: 0, + ptm_spare2: 0 as *mut _, + }; + } else { + pub const PTHREAD_MUTEX_INITIALIZER: pthread_mutex_t + = pthread_mutex_t { + ptm_magic: 0x33330003, + ptm_errorcheck: 0, + ptm_unused: 0, + ptm_waiters: 0 as *mut _, + ptm_owner: 0, + ptm_recursed: 0, + ptm_spare2: 0 as *mut _, + }; + } +} + +pub const PTHREAD_COND_INITIALIZER: pthread_cond_t = pthread_cond_t { + ptc_magic: 0x55550005, + ptc_lock: 0, + ptc_waiters_first: 0 as *mut _, + ptc_waiters_last: 0 as *mut _, + ptc_mutex: 0 as *mut _, + ptc_private: 0 as *mut _, +}; +pub const PTHREAD_RWLOCK_INITIALIZER: pthread_rwlock_t = pthread_rwlock_t { + ptr_magic: 0x99990009, + ptr_interlock: 0, + ptr_rblocked_first: 0 as *mut _, + ptr_rblocked_last: 0 as *mut _, + ptr_wblocked_first: 0 as *mut _, + ptr_wblocked_last: 0 as *mut _, + ptr_nreaders: 0, + ptr_owner: 0, + ptr_private: 0 as *mut _, +}; +pub const PTHREAD_MUTEX_NORMAL: ::c_int = 0; +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; +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; +pub const EV_ENABLE: u32 = 0x4; +pub const EV_DISABLE: u32 = 0x8; +pub const EV_ONESHOT: u32 = 0x10; +pub const EV_CLEAR: u32 = 0x20; +pub const EV_RECEIPT: u32 = 0x40; +pub const EV_DISPATCH: u32 = 0x80; +pub const EV_FLAG1: u32 = 0x2000; +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; +pub const NOTE_EXTEND: u32 = 0x00000004; +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_EXIT: u32 = 0x80000000; +pub const NOTE_FORK: u32 = 0x40000000; +pub const NOTE_EXEC: u32 = 0x20000000; +pub const NOTE_PDATAMASK: u32 = 0x000fffff; +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; + +pub const NI_NOFQDN: ::c_int = 0x00000001; +pub const NI_NUMERICHOST: ::c_int = 0x000000002; +pub const NI_NAMEREQD: ::c_int = 0x000000004; +pub const NI_NUMERICSERV: ::c_int = 0x000000008; +pub const NI_DGRAM: ::c_int = 0x00000010; +pub const NI_WITHSCOPEID: ::c_int = 0x00000020; +pub const NI_NUMERICSCOPE: ::c_int = 0x00000040; + +pub const RTLD_NOLOAD: ::c_int = 0x2000; +pub const RTLD_LOCAL: ::c_int = 0x200; + +pub const CTL_MAXNAME: ::c_int = 12; +pub const SYSCTL_NAMELEN: ::c_int = 32; +pub const SYSCTL_DEFSIZE: ::c_int = 8; +pub const CTLTYPE_NODE: ::c_int = 1; +pub const CTLTYPE_INT: ::c_int = 2; +pub const CTLTYPE_STRING: ::c_int = 3; +pub const CTLTYPE_QUAD: ::c_int = 4; +pub const CTLTYPE_STRUCT: ::c_int = 5; +pub const CTLTYPE_BOOL: ::c_int = 6; +pub const CTLFLAG_READONLY: ::c_int = 0x00000000; +pub const CTLFLAG_READWRITE: ::c_int = 0x00000070; +pub const CTLFLAG_ANYWRITE: ::c_int = 0x00000080; +pub const CTLFLAG_PRIVATE: ::c_int = 0x00000100; +pub const CTLFLAG_PERMANENT: ::c_int = 0x00000200; +pub const CTLFLAG_OWNDATA: ::c_int = 0x00000400; +pub const CTLFLAG_IMMEDIATE: ::c_int = 0x00000800; +pub const CTLFLAG_HEX: ::c_int = 0x00001000; +pub const CTLFLAG_ROOT: ::c_int = 0x00002000; +pub const CTLFLAG_ANYNUMBER: ::c_int = 0x00004000; +pub const CTLFLAG_HIDDEN: ::c_int = 0x00008000; +pub const CTLFLAG_ALIAS: ::c_int = 0x00010000; +pub const CTLFLAG_MMAP: ::c_int = 0x00020000; +pub const CTLFLAG_OWNDESC: ::c_int = 0x00040000; +pub const CTLFLAG_UNSIGNED: ::c_int = 0x00080000; +pub const SYSCTL_VERS_MASK: ::c_int = 0xff000000; +pub const SYSCTL_VERS_0: ::c_int = 0x00000000; +pub const SYSCTL_VERS_1: ::c_int = 0x01000000; +pub const SYSCTL_VERSION: ::c_int = SYSCTL_VERS_1; +pub const CTL_EOL: ::c_int = -1; +pub const CTL_QUERY: ::c_int = -2; +pub const CTL_CREATE: ::c_int = -3; +pub const CTL_CREATESYM: ::c_int = -4; +pub const CTL_DESTROY: ::c_int = -5; +pub const CTL_MMAP: ::c_int = -6; +pub const CTL_DESCRIBE: ::c_int = -7; +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_DDB: ::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 KERN_OSTYPE: ::c_int = 1; +pub const KERN_OSRELEASE: ::c_int = 2; +pub const KERN_OSREV: ::c_int = 3; +pub const KERN_VERSION: ::c_int = 4; +pub const KERN_MAXVNODES: ::c_int = 5; +pub const KERN_MAXPROC: ::c_int = 6; +pub const KERN_MAXFILES: ::c_int = 7; +pub const KERN_ARGMAX: ::c_int = 8; +pub const KERN_SECURELVL: ::c_int = 9; +pub const KERN_HOSTNAME: ::c_int = 10; +pub const KERN_HOSTID: ::c_int = 11; +pub const KERN_CLOCKRATE: ::c_int = 12; +pub const KERN_VNODE: ::c_int = 13; +pub const KERN_PROC: ::c_int = 14; +pub const KERN_FILE: ::c_int = 15; +pub const KERN_PROF: ::c_int = 16; +pub const KERN_POSIX1: ::c_int = 17; +pub const KERN_NGROUPS: ::c_int = 18; +pub const KERN_JOB_CONTROL: ::c_int = 19; +pub const KERN_SAVED_IDS: ::c_int = 20; +pub const KERN_OBOOTTIME: ::c_int = 21; +pub const KERN_DOMAINNAME: ::c_int = 22; +pub const KERN_MAXPARTITIONS: ::c_int = 23; +pub const KERN_RAWPARTITION: ::c_int = 24; +pub const KERN_NTPTIME: ::c_int = 25; +pub const KERN_TIMEX: ::c_int = 26; +pub const KERN_AUTONICETIME: ::c_int = 27; +pub const KERN_AUTONICEVAL: ::c_int = 28; +pub const KERN_RTC_OFFSET: ::c_int = 29; +pub const KERN_ROOT_DEVICE: ::c_int = 30; +pub const KERN_MSGBUFSIZE: ::c_int = 31; +pub const KERN_FSYNC: ::c_int = 32; +pub const KERN_OLDSYSVMSG: ::c_int = 33; +pub const KERN_OLDSYSVSEM: ::c_int = 34; +pub const KERN_OLDSYSVSHM: ::c_int = 35; +pub const KERN_OLDSHORTCORENAME: ::c_int = 36; +pub const KERN_SYNCHRONIZED_IO: ::c_int = 37; +pub const KERN_IOV_MAX: ::c_int = 38; +pub const KERN_MBUF: ::c_int = 39; +pub const KERN_MAPPED_FILES: ::c_int = 40; +pub const KERN_MEMLOCK: ::c_int = 41; +pub const KERN_MEMLOCK_RANGE: ::c_int = 42; +pub const KERN_MEMORY_PROTECTION: ::c_int = 43; +pub const KERN_LOGIN_NAME_MAX: ::c_int = 44; +pub const KERN_DEFCORENAME: ::c_int = 45; +pub const KERN_LOGSIGEXIT: ::c_int = 46; +pub const KERN_PROC2: ::c_int = 47; +pub const KERN_PROC_ARGS: ::c_int = 48; +pub const KERN_FSCALE: ::c_int = 49; +pub const KERN_CCPU: ::c_int = 50; +pub const KERN_CP_TIME: ::c_int = 51; +pub const KERN_OLDSYSVIPC_INFO: ::c_int = 52; +pub const KERN_MSGBUF: ::c_int = 53; +pub const KERN_CONSDEV: ::c_int = 54; +pub const KERN_MAXPTYS: ::c_int = 55; +pub const KERN_PIPE: ::c_int = 56; +pub const KERN_MAXPHYS: ::c_int = 57; +pub const KERN_SBMAX: ::c_int = 58; +pub const KERN_TKSTAT: ::c_int = 59; +pub const KERN_MONOTONIC_CLOCK: ::c_int = 60; +pub const KERN_URND: ::c_int = 61; +pub const KERN_LABELSECTOR: ::c_int = 62; +pub const KERN_LABELOFFSET: ::c_int = 63; +pub const KERN_LWP: ::c_int = 64; +pub const KERN_FORKFSLEEP: ::c_int = 65; +pub const KERN_POSIX_THREADS: ::c_int = 66; +pub const KERN_POSIX_SEMAPHORES: ::c_int = 67; +pub const KERN_POSIX_BARRIERS: ::c_int = 68; +pub const KERN_POSIX_TIMERS: ::c_int = 69; +pub const KERN_POSIX_SPIN_LOCKS: ::c_int = 70; +pub const KERN_POSIX_READER_WRITER_LOCKS: ::c_int = 71; +pub const KERN_DUMP_ON_PANIC: ::c_int = 72; +pub const KERN_SOMAXKVA: ::c_int = 73; +pub const KERN_ROOT_PARTITION: ::c_int = 74; +pub const KERN_DRIVERS: ::c_int = 75; +pub const KERN_BUF: ::c_int = 76; +pub const KERN_FILE2: ::c_int = 77; +pub const KERN_VERIEXEC: ::c_int = 78; +pub const KERN_CP_ID: ::c_int = 79; +pub const KERN_HARDCLOCK_TICKS: ::c_int = 80; +pub const KERN_ARND: ::c_int = 81; +pub const KERN_SYSVIPC: ::c_int = 82; +pub const KERN_BOOTTIME: ::c_int = 83; +pub const KERN_EVCNT: ::c_int = 84; +pub const KERN_MAXID: ::c_int = 85; +pub const KERN_PROC_ALL: ::c_int = 0; +pub const KERN_PROC_PID: ::c_int = 1; +pub const KERN_PROC_PGRP: ::c_int = 2; +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_PROC_RUID: ::c_int = 6; +pub const KERN_PROC_GID: ::c_int = 7; +pub const KERN_PROC_RGID: ::c_int = 8; +pub const KERN_PROC_ARGV: ::c_int = 1; +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; +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 = 14; + +pub const AIO_CANCELED: ::c_int = 1; +pub const AIO_NOTCANCELED: ::c_int = 2; +pub const AIO_ALLDONE: ::c_int = 3; +pub const LIO_NOP: ::c_int = 0; +pub const LIO_WRITE: ::c_int = 1; +pub const LIO_READ: ::c_int = 2; +pub const LIO_WAIT: ::c_int = 1; +pub const LIO_NOWAIT: ::c_int = 0; + +pub const SIGEV_NONE: ::c_int = 0; +pub const SIGEV_SIGNAL: ::c_int = 1; +pub const SIGEV_THREAD: ::c_int = 2; + +pub const WSTOPPED: ::c_int = 0x00000002; // same as WUNTRACED +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; + +pub const UTIME_OMIT: c_long = 1073741822; +pub const UTIME_NOW: c_long = 1073741823; + +pub const B460800: ::speed_t = 460800; +pub const B921600: ::speed_t = 921600; + +pub const ONOCR: ::tcflag_t = 0x20; +pub const ONLRET: ::tcflag_t = 0x40; +pub const CDTRCTS: ::tcflag_t = 0x00020000; +pub const CHWFLOW: ::tcflag_t = ::MDMBUF | ::CRTSCTS | ::CDTRCTS; + +// pub const _PATH_UTMPX: &[::c_char; 14] = b"/var/run/utmpx"; +// pub const _PATH_WTMPX: &[::c_char; 14] = b"/var/log/wtmpx"; +// pub const _PATH_LASTLOGX: &[::c_char; 17] = b"/var/log/lastlogx"; +// pub const _PATH_UTMP_UPDATE: &[::c_char; 24] = b"/usr/libexec/utmp_update"; +pub const UT_NAMESIZE: usize = 8; +pub const UT_LINESIZE: usize = 8; +pub const UT_HOSTSIZE: usize = 16; +pub const _UTX_USERSIZE: usize = 32; +pub const _UTX_LINESIZE: usize = 32; +pub const _UTX_PADSIZE: usize = 40; +pub const _UTX_IDSIZE: usize = 4; +pub const _UTX_HOSTSIZE: usize = 256; +pub const EMPTY: u16 = 0; +pub const RUN_LVL: u16 = 1; +pub const BOOT_TIME: u16 = 2; +pub const OLD_TIME: u16 = 3; +pub const NEW_TIME: u16 = 4; +pub const INIT_PROCESS: u16 = 5; +pub const LOGIN_PROCESS: u16 = 6; +pub const USER_PROCESS: u16 = 7; +pub const DEAD_PROCESS: u16 = 8; +pub const ACCOUNTING: u16 = 9; +pub const SIGNATURE: u16 = 10; +pub const DOWN_TIME: u16 = 11; + +pub const SOCK_CLOEXEC: ::c_int = 0x10000000; +pub const SOCK_NONBLOCK: ::c_int = 0x20000000; + +// Uncomment on next NetBSD release +// pub const FIOSEEKDATA: ::c_ulong = 0xc0086661; +// pub const FIOSEEKHOLE: ::c_ulong = 0xc0086662; +pub const OFIOGETBMAP: ::c_ulong = 0xc004667a; +pub const FIOGETBMAP: ::c_ulong = 0xc008667a; +pub const FIONWRITE: ::c_ulong = 0x40046679; +pub const FIONSPACE: ::c_ulong = 0x40046678; +pub const FIBMAP: ::c_ulong = 0xc008667a; + +pub const SIGSTKSZ: ::size_t = 40960; + +pub const REG_ENOSYS: ::c_int = 17; + +pub const PT_DUMPCORE: ::c_int = 12; +pub const PT_LWPINFO: ::c_int = 13; +pub const PT_SYSCALL: ::c_int = 14; +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_RETURNERROR: ::c_int = 0x40; + +// Flags for chflags(2) +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; + +// 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; + +// sys/reboot.h +pub const RB_ASKNAME: ::c_int = 0x000000001; +pub const RB_SINGLE: ::c_int = 0x000000002; +pub const RB_NOSYNC: ::c_int = 0x000000004; +pub const RB_HALT: ::c_int = 0x000000008; +pub const RB_INITNAME: ::c_int = 0x000000010; +pub const RB_KDB: ::c_int = 0x000000040; +pub const RB_RDONLY: ::c_int = 0x000000080; +pub const RB_DUMP: ::c_int = 0x000000100; +pub const RB_MINIROOT: ::c_int = 0x000000200; +pub const RB_STRING: ::c_int = 0x000000400; +pub const RB_POWERDOWN: ::c_int = RB_HALT | 0x000000800; +pub const RB_USERCONF: ::c_int = 0x000001000; + +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 + } + } +} + +// net/route.h +pub const RTF_MASK: ::c_int = 0x80; +pub const RTF_CONNECTED: ::c_int = 0x100; +pub const RTF_ANNOUNCE: ::c_int = 0x20000; +pub const RTF_SRC: ::c_int = 0x10000; +pub const RTF_LOCAL: ::c_int = 0x40000; +pub const RTF_BROADCAST: ::c_int = 0x80000; +pub const RTF_UPDATING: ::c_int = 0x100000; +pub const RTF_DONTCHANGEIFA: ::c_int = 0x200000; + +pub const RTM_VERSION: ::c_int = 4; +pub const RTM_LOCK: ::c_int = 0x8; +pub const RTM_IFANNOUNCE: ::c_int = 0x10; +pub const RTM_IEEE80211: ::c_int = 0x11; +pub const RTM_SETGATE: ::c_int = 0x12; +pub const RTM_LLINFO_UPD: ::c_int = 0x13; +pub const RTM_IFINFO: ::c_int = 0x14; +pub const RTM_OCHGADDR: ::c_int = 0x15; +pub const RTM_NEWADDR: ::c_int = 0x16; +pub const RTM_DELADDR: ::c_int = 0x17; +pub const RTM_CHGADDR: ::c_int = 0x18; + +pub const RTA_TAG: ::c_int = 0x100; + +pub const RTAX_TAG: ::c_int = 8; +pub const RTAX_MAX: ::c_int = 9; + +const_fn! { + {const} fn _ALIGN(p: usize) -> usize { + (p + _ALIGNBYTES) & !_ALIGNBYTES + } +} + +f! { + pub fn CMSG_DATA(cmsg: *const ::cmsghdr) -> *mut ::c_uchar { + (cmsg as *mut ::c_uchar) + .offset(_ALIGN(::mem::size_of::<::cmsghdr>()) as isize) + } + + pub {const} fn CMSG_LEN(length: ::c_uint) -> ::c_uint { + _ALIGN(::mem::size_of::<::cmsghdr>()) as ::c_uint + length + } + + pub fn CMSG_NXTHDR(mhdr: *const ::msghdr, cmsg: *const ::cmsghdr) + -> *mut ::cmsghdr + { + if cmsg.is_null() { + return ::CMSG_FIRSTHDR(mhdr); + }; + let next = cmsg as usize + _ALIGN((*cmsg).cmsg_len as usize) + + _ALIGN(::mem::size_of::<::cmsghdr>()); + let max = (*mhdr).msg_control as usize + + (*mhdr).msg_controllen as usize; + if next > max { + 0 as *mut ::cmsghdr + } else { + (cmsg as usize + _ALIGN((*cmsg).cmsg_len as usize)) + as *mut ::cmsghdr + } + } + + pub {const} fn CMSG_SPACE(length: ::c_uint) -> ::c_uint { + (_ALIGN(::mem::size_of::<::cmsghdr>()) + _ALIGN(length as usize)) + as ::c_uint + } + + // dirfd() is a macro on netbsd to access + // the first field of the struct where dirp points to: + // http://cvsweb.netbsd.org/bsdweb.cgi/src/include/dirent.h?rev=1.36 + pub fn dirfd(dirp: *mut ::DIR) -> ::c_int { + *(dirp as *const ::c_int) + } + + pub fn SOCKCREDSIZE(ngrps: usize) -> usize { + let ngrps = if ngrps > 0 { + ngrps - 1 + } else { + 0 + }; + ::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 + } + + pub fn major(dev: ::dev_t) -> ::c_int { + (((dev as u32) & 0x000fff00) >> 8) as ::c_int + } + + pub fn minor(dev: ::dev_t) -> ::c_int { + let mut res = 0; + res |= ((dev as u32) & 0xfff00000) >> 12; + res |= (dev as u32) & 0x000000ff; + res as ::c_int + } +} + +safe_f! { + pub {const} fn WSTOPSIG(status: ::c_int) -> ::c_int { + status >> 8 + } + + pub {const} fn WIFSIGNALED(status: ::c_int) -> bool { + (status & 0o177) != 0o177 && (status & 0o177) != 0 + } + + pub {const} fn WIFSTOPPED(status: ::c_int) -> bool { + (status & 0o177) == 0o177 + } + + 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" { + pub fn ntp_adjtime(buf: *mut timex) -> ::c_int; + pub fn ntp_gettime(buf: *mut ntptimeval) -> ::c_int; + pub fn clock_nanosleep( + clk_id: ::clockid_t, + flags: ::c_int, + rqtp: *const ::timespec, + rmtp: *mut ::timespec, + ) -> ::c_int; + + pub fn reallocarr(ptr: *mut ::c_void, number: ::size_t, size: ::size_t) -> ::c_int; + + pub fn chflags(path: *const ::c_char, flags: ::c_ulong) -> ::c_int; + 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 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, + attrname: *const ::c_char, + ) -> ::c_int; + pub fn extattr_delete_file( + path: *const ::c_char, + attrnamespace: ::c_int, + attrname: *const ::c_char, + ) -> ::c_int; + pub fn extattr_delete_link( + path: *const ::c_char, + attrnamespace: ::c_int, + attrname: *const ::c_char, + ) -> ::c_int; + pub fn extattr_get_fd( + fd: ::c_int, + attrnamespace: ::c_int, + attrname: *const ::c_char, + data: *mut ::c_void, + nbytes: ::size_t, + ) -> ::ssize_t; + pub fn extattr_get_file( + path: *const ::c_char, + attrnamespace: ::c_int, + attrname: *const ::c_char, + data: *mut ::c_void, + nbytes: ::size_t, + ) -> ::ssize_t; + pub fn extattr_get_link( + path: *const ::c_char, + attrnamespace: ::c_int, + attrname: *const ::c_char, + data: *mut ::c_void, + nbytes: ::size_t, + ) -> ::ssize_t; + pub fn extattr_namespace_to_string( + attrnamespace: ::c_int, + string: *mut *mut ::c_char, + ) -> ::c_int; + pub fn extattr_set_fd( + fd: ::c_int, + attrnamespace: ::c_int, + attrname: *const ::c_char, + data: *const ::c_void, + nbytes: ::size_t, + ) -> ::c_int; + pub fn extattr_set_file( + path: *const ::c_char, + attrnamespace: ::c_int, + attrname: *const ::c_char, + data: *const ::c_void, + nbytes: ::size_t, + ) -> ::c_int; + pub fn extattr_set_link( + path: *const ::c_char, + attrnamespace: ::c_int, + attrname: *const ::c_char, + data: *const ::c_void, + nbytes: ::size_t, + ) -> ::c_int; + pub fn extattr_string_to_namespace( + string: *const ::c_char, + 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"] + pub fn gettimeofday(tp: *mut ::timeval, tz: *mut ::c_void) -> ::c_int; + pub fn getnameinfo( + sa: *const ::sockaddr, + salen: ::socklen_t, + host: *mut ::c_char, + hostlen: ::socklen_t, + serv: *mut ::c_char, + servlen: ::socklen_t, + flags: ::c_int, + ) -> ::c_int; + pub fn mprotect(addr: *mut ::c_void, len: ::size_t, prot: ::c_int) -> ::c_int; + pub fn sysctl( + name: *const ::c_int, + namelen: ::c_uint, + oldp: *mut ::c_void, + oldlenp: *mut ::size_t, + newp: *const ::c_void, + newlen: ::size_t, + ) -> ::c_int; + pub fn sysctlbyname( + name: *const ::c_char, + oldp: *mut ::c_void, + oldlenp: *mut ::size_t, + newp: *const ::c_void, + newlen: ::size_t, + ) -> ::c_int; + pub fn sysctlnametomib( + sname: *const ::c_char, + name: *mut ::c_int, + namelenp: *mut ::size_t, + ) -> ::c_int; + #[link_name = "__kevent50"] + pub fn kevent( + kq: ::c_int, + changelist: *const ::kevent, + nchanges: ::size_t, + eventlist: *mut ::kevent, + nevents: ::size_t, + timeout: *const ::timespec, + ) -> ::c_int; + #[link_name = "__mount50"] + pub fn mount( + src: *const ::c_char, + target: *const ::c_char, + flags: ::c_int, + data: *mut ::c_void, + size: ::size_t, + ) -> ::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_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_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; + #[link_name = "__mq_timedreceive50"] + 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; + #[link_name = "__mq_timedsend50"] + 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 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, + arg: *const ::c_void, + ) -> ::c_int; + pub fn pthread_attr_get_np(thread: ::pthread_t, attr: *mut ::pthread_attr_t) -> ::c_int; + pub fn pthread_getattr_np(native: ::pthread_t, attr: *mut ::pthread_attr_t) -> ::c_int; + pub fn pthread_attr_getguardsize( + attr: *const ::pthread_attr_t, + guardsize: *mut ::size_t, + ) -> ::c_int; + pub fn pthread_attr_setguardsize(attr: *mut ::pthread_attr_t, guardsize: ::size_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 pthread_getaffinity_np( + thread: ::pthread_t, + size: ::size_t, + set: *mut cpuset_t, + ) -> ::c_int; + pub fn pthread_setaffinity_np( + thread: ::pthread_t, + 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; + pub fn _cpuset_set(cpu: cpuid_t, set: *mut cpuset_t) -> ::c_int; + pub fn _cpuset_isset(cpu: cpuid_t, set: *const cpuset_t) -> ::c_int; + pub fn _cpuset_size(set: *const cpuset_t) -> ::size_t; + pub fn _cpuset_zero(set: *mut cpuset_t); + #[link_name = "__sigtimedwait50"] + 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 duplocale(base: ::locale_t) -> ::locale_t; + pub fn freelocale(loc: ::locale_t); + pub fn localeconv_l(loc: ::locale_t) -> *mut lconv; + pub fn newlocale(mask: ::c_int, locale: *const ::c_char, base: ::locale_t) -> ::locale_t; + #[link_name = "__settimeofday50"] + pub fn settimeofday(tv: *const ::timeval, tz: *const ::c_void) -> ::c_int; + + pub fn dup3(src: ::c_int, dst: ::c_int, flags: ::c_int) -> ::c_int; + + pub fn kqueue1(flags: ::c_int) -> ::c_int; + + pub fn _lwp_self() -> lwpid_t; + pub fn memmem( + haystack: *const ::c_void, + haystacklen: ::size_t, + needle: *const ::c_void, + needlelen: ::size_t, + ) -> *mut ::c_void; + + // link.h + + 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; + + // dlfcn.h + + pub fn _dlauxinfo() -> *mut ::c_void; + + pub fn iconv_open(tocode: *const ::c_char, fromcode: *const ::c_char) -> iconv_t; + 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 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; + + pub fn setproctitle(fmt: *const ::c_char, ...); + pub fn mremap( + oldp: *mut ::c_void, + oldsize: ::size_t, + newp: *mut ::c_void, + 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 getrandom(buf: *mut ::c_void, buflen: ::size_t, flags: ::c_uint) -> ::ssize_t; + + pub fn reboot(mode: ::c_int, bootstr: *mut ::c_char) -> ::c_int; + + #[link_name = "___lwp_park60"] + pub fn _lwp_park( + clock: ::clockid_t, + flags: ::c_int, + ts: *const ::timespec, + unpark: ::lwpid_t, + hint: *const ::c_void, + unparkhint: *mut ::c_void, + ) -> ::c_int; + pub fn _lwp_unpark(lwp: ::lwpid_t, hint: *const ::c_void) -> ::c_int; + pub fn _lwp_unpark_all( + targets: *const ::lwpid_t, + ntargets: ::size_t, + hint: *const ::c_void, + ) -> ::c_int; +} + +#[link(name = "rt")] +extern "C" { + pub fn aio_read(aiocbp: *mut aiocb) -> ::c_int; + pub fn aio_write(aiocbp: *mut aiocb) -> ::c_int; + pub fn aio_fsync(op: ::c_int, aiocbp: *mut aiocb) -> ::c_int; + pub fn aio_error(aiocbp: *const aiocb) -> ::c_int; + pub fn aio_return(aiocbp: *mut aiocb) -> ::ssize_t; + #[link_name = "__aio_suspend50"] + pub fn aio_suspend( + aiocb_list: *const *const aiocb, + nitems: ::c_int, + timeout: *const ::timespec, + ) -> ::c_int; + pub fn aio_cancel(fd: ::c_int, aiocbp: *mut aiocb) -> ::c_int; + pub fn lio_listio( + mode: ::c_int, + aiocb_list: *const *mut aiocb, + nitems: ::c_int, + sevp: *mut sigevent, + ) -> ::c_int; +} + +#[link(name = "util")] +extern "C" { + #[cfg_attr(target_os = "netbsd", link_name = "__getpwent_r50")] + pub fn getpwent_r( + pwd: *mut ::passwd, + buf: *mut ::c_char, + buflen: ::size_t, + result: *mut *mut ::passwd, + ) -> ::c_int; + pub fn getgrent_r( + grp: *mut ::group, + buf: *mut ::c_char, + buflen: ::size_t, + result: *mut *mut ::group, + ) -> ::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 utmpxname(file: *const ::c_char) -> ::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 getutmp(ux: *const utmpx, u: *mut utmp); + pub fn getutmpx(u: *const utmp, ux: *mut utmpx); + + pub fn utpname(file: *const ::c_char) -> ::c_int; + pub fn setutent(); + pub fn endutent(); + pub fn getutent() -> *mut utmp; + + pub fn efopen(p: *const ::c_char, m: *const ::c_char) -> ::FILE; + 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; +} + +#[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; + pub fn backtrace_symbols_fd_fmt( + addrlist: *const *mut ::c_void, + len: ::size_t, + fd: ::c_int, + fmt: *const ::c_char, + ) -> ::c_int; +} + +cfg_if! { + if #[cfg(libc_union)] { + extern { + // these functions use statvfs: + pub fn getmntinfo(mntbufp: *mut *mut ::statvfs, flags: ::c_int) -> ::c_int; + pub fn getvfsstat(buf: *mut statvfs, bufsize: ::size_t, flags: ::c_int) -> ::c_int; + } + } +} + +cfg_if! { + 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 = "powerpc")] { + mod powerpc; + pub use self::powerpc::*; + } else if #[cfg(target_arch = "sparc64")] { + mod sparc64; + pub use self::sparc64::*; + } else if #[cfg(target_arch = "x86_64")] { + mod x86_64; + pub use self::x86_64::*; + } else if #[cfg(target_arch = "x86")] { + mod x86; + pub use self::x86::*; + } else if #[cfg(target_arch = "mips")] { + mod mips; + pub use self::mips::*; + } else if #[cfg(target_arch = "riscv64")] { + mod riscv64; + pub use self::riscv64::*; + } else { + // Unknown target_arch + } +} diff --git a/vendor/libc/src/unix/bsd/netbsdlike/netbsd/powerpc.rs b/vendor/libc/src/unix/bsd/netbsdlike/netbsd/powerpc.rs new file mode 100644 index 0000000..e12fd5e --- /dev/null +++ b/vendor/libc/src/unix/bsd/netbsdlike/netbsd/powerpc.rs @@ -0,0 +1,21 @@ +use PT_FIRSTMACH; + +pub type c_long = i32; +pub type c_ulong = u32; +pub type c_char = u8; +pub type __cpu_simple_lock_nv_t = ::c_int; + +// 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 PT_STEP: ::c_int = PT_FIRSTMACH + 0; +pub const PT_GETREGS: ::c_int = PT_FIRSTMACH + 1; +pub const PT_SETREGS: ::c_int = PT_FIRSTMACH + 2; diff --git a/vendor/libc/src/unix/bsd/netbsdlike/netbsd/riscv64.rs b/vendor/libc/src/unix/bsd/netbsdlike/netbsd/riscv64.rs new file mode 100644 index 0000000..bc09149 --- /dev/null +++ b/vendor/libc/src/unix/bsd/netbsdlike/netbsd/riscv64.rs @@ -0,0 +1,21 @@ +use PT_FIRSTMACH; + +pub type c_long = i64; +pub type c_ulong = u64; +pub type c_char = u8; +pub type __cpu_simple_lock_nv_t = ::c_int; + +cfg_if! { + if #[cfg(libc_const_size_of)] { + #[doc(hidden)] + pub const _ALIGNBYTES: usize = ::mem::size_of::<::c_long>() - 1; + } else { + #[doc(hidden)] + pub const _ALIGNBYTES: usize = 8 - 1; + } +} + +pub const PT_GETREGS: ::c_int = PT_FIRSTMACH + 0; +pub const PT_SETREGS: ::c_int = PT_FIRSTMACH + 1; +pub const PT_GETFPREGS: ::c_int = PT_FIRSTMACH + 2; +pub const PT_SETFPREGS: ::c_int = PT_FIRSTMACH + 3; diff --git a/vendor/libc/src/unix/bsd/netbsdlike/netbsd/sparc64.rs b/vendor/libc/src/unix/bsd/netbsdlike/netbsd/sparc64.rs new file mode 100644 index 0000000..6a86759 --- /dev/null +++ b/vendor/libc/src/unix/bsd/netbsdlike/netbsd/sparc64.rs @@ -0,0 +1,8 @@ +pub type c_long = i64; +pub type c_ulong = u64; +pub type c_char = i8; +pub type __cpu_simple_lock_nv_t = ::c_uchar; + +// should be pub(crate), but that requires Rust 1.18.0 +#[doc(hidden)] +pub const _ALIGNBYTES: usize = 0xf; diff --git a/vendor/libc/src/unix/bsd/netbsdlike/netbsd/x86.rs b/vendor/libc/src/unix/bsd/netbsdlike/netbsd/x86.rs new file mode 100644 index 0000000..daa89a1 --- /dev/null +++ b/vendor/libc/src/unix/bsd/netbsdlike/netbsd/x86.rs @@ -0,0 +1,15 @@ +pub type c_long = i32; +pub type c_ulong = u32; +pub type c_char = i8; +pub type __cpu_simple_lock_nv_t = ::c_uchar; + +// 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; + } +} diff --git a/vendor/libc/src/unix/bsd/netbsdlike/netbsd/x86_64.rs b/vendor/libc/src/unix/bsd/netbsdlike/netbsd/x86_64.rs new file mode 100644 index 0000000..ba25907 --- /dev/null +++ b/vendor/libc/src/unix/bsd/netbsdlike/netbsd/x86_64.rs @@ -0,0 +1,67 @@ +use PT_FIRSTMACH; + +pub type c_long = i64; +pub type c_ulong = u64; +pub type c_char = i8; +pub type c___greg_t = u64; +pub type __cpu_simple_lock_nv_t = ::c_uchar; + +s! { + pub struct mcontext_t { + pub __gregs: [c___greg_t; 26], + pub _mc_tlsbase: c___greg_t, + pub __fpregs: [[::c_char;32]; 16], + } + + 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, + } +} + +// 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 PT_STEP: ::c_int = PT_FIRSTMACH + 0; +pub const PT_GETREGS: ::c_int = PT_FIRSTMACH + 1; +pub const PT_SETREGS: ::c_int = PT_FIRSTMACH + 2; +pub const PT_GETFPREGS: ::c_int = PT_FIRSTMACH + 3; +pub const PT_SETFPREGS: ::c_int = PT_FIRSTMACH + 4; + +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; diff --git a/vendor/libc/src/unix/bsd/netbsdlike/openbsd/aarch64.rs b/vendor/libc/src/unix/bsd/netbsdlike/openbsd/aarch64.rs new file mode 100644 index 0000000..2bc82e4 --- /dev/null +++ b/vendor/libc/src/unix/bsd/netbsdlike/openbsd/aarch64.rs @@ -0,0 +1,30 @@ +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! { + 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/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 new file mode 100644 index 0000000..259f9e0 --- /dev/null +++ b/vendor/libc/src/unix/bsd/netbsdlike/openbsd/mod.rs @@ -0,0 +1,2265 @@ +use unix::bsd::O_SYNC; + +pub type clock_t = i64; +pub type suseconds_t = ::c_long; +pub type dev_t = i32; +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; +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 + +pub type Elf32_Addr = u32; +pub type Elf32_Half = u16; +pub type Elf32_Lword = u64; +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_Lword = u64; +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; + +// search.h + +pub type ENTRY = entry; +pub type ACTION = ::c_uint; + +// spawn.h +pub type posix_spawnattr_t = *mut ::c_void; +pub type posix_spawn_file_actions_t = *mut ::c_void; + +cfg_if! { + if #[cfg(target_pointer_width = "64")] { + type Elf_Addr = Elf64_Addr; + type Elf_Half = Elf64_Half; + type Elf_Phdr = Elf64_Phdr; + } else if #[cfg(target_pointer_width = "32")] { + type Elf_Addr = Elf32_Addr; + type Elf_Half = Elf32_Half; + type Elf_Phdr = Elf32_Phdr; + } +} + +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, + pub gl_offs: ::size_t, + pub gl_flags: ::c_int, + pub gl_pathv: *mut *mut ::c_char, + __unused1: *mut ::c_void, + __unused2: *mut ::c_void, + __unused3: *mut ::c_void, + __unused4: *mut ::c_void, + __unused5: *mut ::c_void, + __unused6: *mut ::c_void, + __unused7: *mut ::c_void, + } + + pub struct lconv { + pub decimal_point: *mut ::c_char, + pub thousands_sep: *mut ::c_char, + 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_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 ufs_args { + pub fspec: *mut ::c_char, + pub export_info: export_args, + } + + pub struct mfs_args { + pub fspec: *mut ::c_char, + pub export_info: export_args, + // https://github.com/openbsd/src/blob/HEAD/sys/sys/types.h#L134 + pub base: *mut ::c_char, + pub size: ::c_ulong, + } + + pub struct iso_args { + pub fspec: *mut ::c_char, + pub export_info: export_args, + pub flags: ::c_int, + pub sess: ::c_int, + } + + pub struct nfs_args { + pub version: ::c_int, + pub addr: *mut ::sockaddr, + pub addrlen: ::c_int, + pub sotype: ::c_int, + pub proto: ::c_int, + pub fh: *mut ::c_uchar, + pub fhsize: ::c_int, + pub flags: ::c_int, + pub wsize: ::c_int, + pub rsize: ::c_int, + pub readdirsize: ::c_int, + pub timeo: ::c_int, + pub retrans: ::c_int, + pub maxgrouplist: ::c_int, + pub readahead: ::c_int, + pub leaseterm: ::c_int, + pub deadthresh: ::c_int, + pub hostname: *mut ::c_char, + pub acregmin: ::c_int, + pub acregmax: ::c_int, + pub acdirmin: ::c_int, + pub acdirmax: ::c_int, + } + + pub struct msdosfs_args { + pub fspec: *mut ::c_char, + pub export_info: export_args, + pub uid: ::uid_t, + pub gid: ::gid_t, + pub mask: ::mode_t, + pub flags: ::c_int, + } + + pub struct ntfs_args { + pub fspec: *mut ::c_char, + pub export_info: export_args, + pub uid: ::uid_t, + pub gid: ::gid_t, + pub mode: ::mode_t, + pub flag: ::c_ulong, + } + + pub struct udf_args { + pub fspec: *mut ::c_char, + pub lastblock: u32, + } + + pub struct tmpfs_args { + pub ta_version: ::c_int, + pub ta_nodes_max: ::ino_t, + pub ta_size_max: ::off_t, + pub ta_root_uid: ::uid_t, + pub ta_root_gid: ::gid_t, + pub ta_root_mode: ::mode_t, + } + + pub struct fusefs_args { + pub name: *mut ::c_char, + pub fd: ::c_int, + pub max_read: ::c_int, + pub allow_other: ::c_int, + } + + pub struct xucred { + pub cr_uid: ::uid_t, + pub cr_gid: ::gid_t, + pub cr_ngroups: ::c_short, + //https://github.com/openbsd/src/blob/HEAD/sys/sys/syslimits.h#L44 + pub cr_groups: [::gid_t; 16], + } + + pub struct export_args { + pub ex_flags: ::c_int, + pub ex_root: ::uid_t, + pub ex_anon: xucred, + pub ex_addr: *mut ::sockaddr, + pub ex_addrlen: ::c_int, + pub ex_mask: *mut ::sockaddr, + pub ex_masklen: ::c_int, + } + + pub struct ip_mreq { + pub imr_multiaddr: in_addr, + pub imr_interface: in_addr, + } + + pub struct in_addr { + pub s_addr: ::in_addr_t, + } + + 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 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, + pub flags: ::c_ushort, + pub fflags: ::c_uint, + pub data: i64, + pub udata: *mut ::c_void, + } + + pub struct stat { + pub st_mode: ::mode_t, + pub st_dev: ::dev_t, + pub st_ino: ::ino_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: u32, + pub st_gen: u32, + pub st_birthtime: ::time_t, + pub st_birthtime_nsec: ::c_long, + } + + 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 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_addr: *mut ::sockaddr, + pub ai_canonname: *mut ::c_char, + pub ai_next: *mut ::addrinfo, + } + + 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 if_data { + pub ifi_type: ::c_uchar, + pub ifi_addrlen: ::c_uchar, + pub ifi_hdrlen: ::c_uchar, + pub ifi_link_state: ::c_uchar, + pub ifi_mtu: u32, + pub ifi_metric: u32, + pub ifi_rdomain: 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_oqdrops: u64, + pub ifi_noproto: u64, + pub ifi_capabilities: u32, + pub ifi_lastchange: ::timeval, + } + + pub struct if_msghdr { + pub ifm_msglen: ::c_ushort, + pub ifm_version: ::c_uchar, + pub ifm_type: ::c_uchar, + pub ifm_hdrlen: ::c_ushort, + pub ifm_index: ::c_ushort, + pub ifm_tableid: ::c_ushort, + pub ifm_pad1: ::c_uchar, + pub ifm_pad2: ::c_uchar, + pub ifm_addrs: ::c_int, + pub ifm_flags: ::c_int, + pub ifm_xflags: ::c_int, + pub ifm_data: if_data, + } + + 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; 24], + } + + pub struct sockpeercred { + pub uid: ::uid_t, + pub gid: ::gid_t, + pub pid: ::pid_t, + } + + 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 shmid_ds { + pub shm_perm: ::ipc_perm, + pub shm_segsz: ::c_int, + pub shm_lpid: ::pid_t, + pub shm_cpid: ::pid_t, + pub shm_nattch: ::c_short, + pub shm_atime: ::time_t, + __shm_atimensec: c_long, + pub shm_dtime: ::time_t, + __shm_dtimensec: c_long, + pub shm_ctime: ::time_t, + __shm_ctimensec: c_long, + pub shm_internal: *mut ::c_void, + } + + // elf.h + 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, + } + + // link.h + + 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, + } + + // 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, + } + + pub struct ifreq { + 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 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 tcpi_snd_wscale: u8, + pub tcpi_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_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_rttmin: u32, + pub tcpi_max_sndwnd: u32, + pub tcpi_rcv_adv: u32, + pub tcpi_rcv_up: u32, + pub tcpi_snd_una: u32, + pub tcpi_snd_up: u32, + pub tcpi_snd_wl1: u32, + pub tcpi_snd_wl2: u32, + pub tcpi_snd_max: u32, + pub tcpi_ts_recent: u32, + pub tcpi_ts_recent_age: u32, + pub tcpi_rfbuf_cnt: u32, + pub tcpi_rfbuf_ts: u32, + pub tcpi_so_rcv_sb_cc: u32, + pub tcpi_so_rcv_sb_hiwat: u32, + pub tcpi_so_rcv_sb_lowat: u32, + pub tcpi_so_rcv_sb_wat: u32, + pub tcpi_so_snd_sb_cc: u32, + pub tcpi_so_snd_sb_hiwat: u32, + pub tcpi_so_snd_sb_lowat: u32, + pub tcpi_so_snd_sb_wat: u32, + } +} + +impl siginfo_t { + pub unsafe fn si_addr(&self) -> *mut ::c_char { + self.si_addr + } + + pub unsafe fn si_code(&self) -> ::c_int { + self.si_code + } + + pub unsafe fn si_errno(&self) -> ::c_int { + self.si_errno + } + + pub unsafe fn si_pid(&self) -> ::pid_t { + #[repr(C)] + struct siginfo_timer { + _si_signo: ::c_int, + _si_code: ::c_int, + _si_errno: ::c_int, + _pad: [::c_int; SI_PAD], + _pid: ::pid_t, + } + (*(self as *const siginfo_t as *const siginfo_timer))._pid + } + + pub unsafe fn si_uid(&self) -> ::uid_t { + #[repr(C)] + struct siginfo_timer { + _si_signo: ::c_int, + _si_code: ::c_int, + _si_errno: ::c_int, + _pad: [::c_int; SI_PAD], + _pid: ::pid_t, + _uid: ::uid_t, + } + (*(self as *const siginfo_t as *const siginfo_timer))._uid + } + + pub unsafe fn si_value(&self) -> ::sigval { + #[repr(C)] + struct siginfo_timer { + _si_signo: ::c_int, + _si_code: ::c_int, + _si_errno: ::c_int, + _pad: [::c_int; SI_PAD], + _pid: ::pid_t, + _uid: ::uid_t, + value: ::sigval, + } + (*(self as *const siginfo_t as *const siginfo_timer)).value + } +} + +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, + pub d_namlen: u8, + __d_padding: [u8; 4], + pub d_name: [::c_char; 256], + } + + pub struct sockaddr_storage { + pub ss_len: u8, + pub ss_family: ::sa_family_t, + __ss_pad1: [u8; 6], + __ss_pad2: i64, + __ss_pad3: [u8; 240], + } + + pub struct siginfo_t { + pub si_signo: ::c_int, + pub si_code: ::c_int, + pub si_errno: ::c_int, + pub si_addr: *mut ::c_char, + #[cfg(target_pointer_width = "32")] + __pad: [u8; 112], + #[cfg(target_pointer_width = "64")] + __pad: [u8; 108], + } + + pub struct lastlog { + ll_time: ::time_t, + ll_line: [::c_char; UT_LINESIZE], + ll_host: [::c_char; UT_HOSTSIZE], + } + + pub struct utmp { + pub ut_line: [::c_char; UT_LINESIZE], + pub ut_name: [::c_char; UT_NAMESIZE], + pub ut_host: [::c_char; UT_HOSTSIZE], + pub ut_time: ::time_t, + } + + pub union mount_info { + pub ufs_args: ufs_args, + pub mfs_args: mfs_args, + pub nfs_args: nfs_args, + pub iso_args: iso_args, + pub msdosfs_args: msdosfs_args, + pub ntfs_args: ntfs_args, + pub tmpfs_args: tmpfs_args, + align: [::c_char; 160], + } + + #[cfg(libc_union)] + pub union __c_anonymous_ifr_ifru { + pub ifru_addr: ::sockaddr, + pub ifru_dstaddr: ::sockaddr, + pub ifru_broadaddr: ::sockaddr, + pub ifru_flags: ::c_short, + pub ifru_metric: ::c_int, + pub ifru_vnetid: i64, + pub ifru_media: u64, + pub ifru_data: ::caddr_t, + pub ifru_index: ::c_uint, + } +} + +cfg_if! { + if #[cfg(feature = "extra_traits")] { + impl PartialEq for dirent { + fn eq(&self, other: &dirent) -> bool { + self.d_fileno == other.d_fileno + && self.d_off == other.d_off + && self.d_reclen == other.d_reclen + && self.d_type == other.d_type + && self.d_namlen == other.d_namlen + && self + .d_name + .iter() + .zip(other.d_name.iter()) + .all(|(a,b)| a == b) + } + } + + impl Eq for dirent {} + + impl ::fmt::Debug for dirent { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("dirent") + .field("d_fileno", &self.d_fileno) + .field("d_off", &self.d_off) + .field("d_reclen", &self.d_reclen) + .field("d_type", &self.d_type) + .field("d_namlen", &self.d_namlen) + // FIXME: .field("d_name", &self.d_name) + .finish() + } + } + + impl ::hash::Hash for dirent { + fn hash(&self, state: &mut H) { + self.d_fileno.hash(state); + self.d_off.hash(state); + self.d_reclen.hash(state); + self.d_type.hash(state); + self.d_namlen.hash(state); + self.d_name.hash(state); + } + } + + impl PartialEq for sockaddr_storage { + fn eq(&self, other: &sockaddr_storage) -> bool { + self.ss_len == other.ss_len + && self.ss_family == other.ss_family + } + } + + impl Eq for sockaddr_storage {} + + impl ::fmt::Debug for sockaddr_storage { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("sockaddr_storage") + .field("ss_len", &self.ss_len) + .field("ss_family", &self.ss_family) + .finish() + } + } + + impl ::hash::Hash for sockaddr_storage { + fn hash(&self, state: &mut H) { + self.ss_len.hash(state); + self.ss_family.hash(state); + } + } + + impl PartialEq for siginfo_t { + fn eq(&self, other: &siginfo_t) -> bool { + self.si_signo == other.si_signo + && self.si_code == other.si_code + && self.si_errno == other.si_errno + && self.si_addr == other.si_addr + } + } + + impl Eq for siginfo_t {} + + impl ::fmt::Debug for siginfo_t { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("siginfo_t") + .field("si_signo", &self.si_signo) + .field("si_code", &self.si_code) + .field("si_errno", &self.si_errno) + .field("si_addr", &self.si_addr) + .finish() + } + } + + impl ::hash::Hash for siginfo_t { + fn hash(&self, state: &mut H) { + self.si_signo.hash(state); + self.si_code.hash(state); + self.si_errno.hash(state); + self.si_addr.hash(state); + } + } + + impl PartialEq for lastlog { + fn eq(&self, other: &lastlog) -> bool { + self.ll_time == other.ll_time + && self + .ll_line + .iter() + .zip(other.ll_line.iter()) + .all(|(a,b)| a == b) + && self + .ll_host + .iter() + .zip(other.ll_host.iter()) + .all(|(a,b)| a == b) + } + } + + impl Eq for lastlog {} + + impl ::fmt::Debug for lastlog { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("lastlog") + .field("ll_time", &self.ll_time) + // FIXME: .field("ll_line", &self.ll_line) + // FIXME: .field("ll_host", &self.ll_host) + .finish() + } + } + + impl ::hash::Hash for lastlog { + fn hash(&self, state: &mut H) { + self.ll_time.hash(state); + self.ll_line.hash(state); + self.ll_host.hash(state); + } + } + + impl PartialEq for utmp { + fn eq(&self, other: &utmp) -> bool { + self.ut_time == other.ut_time + && self + .ut_line + .iter() + .zip(other.ut_line.iter()) + .all(|(a,b)| a == b) + && self + .ut_name + .iter() + .zip(other.ut_name.iter()) + .all(|(a,b)| a == b) + && self + .ut_host + .iter() + .zip(other.ut_host.iter()) + .all(|(a,b)| a == b) + } + } + + impl Eq for utmp {} + + impl ::fmt::Debug for utmp { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("utmp") + // FIXME: .field("ut_line", &self.ut_line) + // FIXME: .field("ut_name", &self.ut_name) + // FIXME: .field("ut_host", &self.ut_host) + .field("ut_time", &self.ut_time) + .finish() + } + } + + impl ::hash::Hash for utmp { + fn hash(&self, state: &mut H) { + self.ut_line.hash(state); + self.ut_name.hash(state); + self.ut_host.hash(state); + self.ut_time.hash(state); + } + } + + impl PartialEq for mount_info { + fn eq(&self, other: &mount_info) -> bool { + unsafe { + self.align + .iter() + .zip(other.align.iter()) + .all(|(a,b)| a == b) + } + } + } + + impl Eq for mount_info { } + + impl ::fmt::Debug for mount_info { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("mount_info") + // FIXME: .field("align", &self.align) + .finish() + } + } + + impl ::hash::Hash for mount_info { + fn hash(&self, state: &mut H) { + unsafe { self.align.hash(state) }; + } + } + + #[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_flags == other.ifru_flags + && self.ifru_metric == other.ifru_metric + && self.ifru_vnetid == other.ifru_vnetid + && self.ifru_media == other.ifru_media + && self.ifru_data == other.ifru_data + && self.ifru_index == other.ifru_index + } + } + } + + #[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("__c_anonymous_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_flags", unsafe { &self.ifru_flags }) + .field("ifru_metric", unsafe { &self.ifru_metric }) + .field("ifru_vnetid", unsafe { &self.ifru_vnetid }) + .field("ifru_media", unsafe { &self.ifru_media }) + .field("ifru_data", unsafe { &self.ifru_data }) + .field("ifru_index", unsafe { &self.ifru_index }) + .finish() + } + } + + #[cfg(libc_union)] + impl ::hash::Hash for __c_anonymous_ifr_ifru { + fn hash(&self, state: &mut H) { + unsafe { + self.ifru_addr.hash(state); + self.ifru_dstaddr.hash(state); + self.ifru_broadaddr.hash(state); + self.ifru_flags.hash(state); + self.ifru_metric.hash(state); + self.ifru_vnetid.hash(state); + self.ifru_media.hash(state); + self.ifru_data.hash(state); + self.ifru_index.hash(state); + } + } + } + } +} + +cfg_if! { + if #[cfg(libc_union)] { + s_no_extra_traits! { + // This type uses the union mount_info: + pub struct statfs { + pub f_flags: u32, + pub f_bsize: u32, + pub f_iosize: u32, + pub f_blocks: u64, + pub f_bfree: u64, + pub f_bavail: i64, + pub f_files: u64, + pub f_ffree: u64, + pub f_favail: i64, + pub f_syncwrites: u64, + pub f_syncreads: u64, + pub f_asyncwrites: u64, + pub f_asyncreads: u64, + pub f_fsid: ::fsid_t, + pub f_namemax: u32, + pub f_owner: ::uid_t, + pub f_ctime: u64, + pub f_fstypename: [::c_char; 16], + pub f_mntonname: [::c_char; 90], + pub f_mntfromname: [::c_char; 90], + pub f_mntfromspec: [::c_char; 90], + pub mount_info: mount_info, + } + } + + cfg_if! { + if #[cfg(feature = "extra_traits")] { + impl PartialEq for statfs { + fn eq(&self, other: &statfs) -> bool { + self.f_flags == other.f_flags + && self.f_bsize == other.f_bsize + && self.f_iosize == other.f_iosize + && self.f_blocks == other.f_blocks + && self.f_bfree == other.f_bfree + && self.f_bavail == other.f_bavail + && self.f_files == other.f_files + && self.f_ffree == other.f_ffree + && self.f_favail == other.f_favail + && self.f_syncwrites == other.f_syncwrites + && self.f_syncreads == other.f_syncreads + && self.f_asyncwrites == other.f_asyncwrites + && self.f_asyncreads == other.f_asyncreads + && self.f_fsid == other.f_fsid + && self.f_namemax == other.f_namemax + && self.f_owner == other.f_owner + && self.f_ctime == other.f_ctime + && self.f_fstypename + .iter() + .zip(other.f_fstypename.iter()) + .all(|(a,b)| a == b) + && self.f_mntonname + .iter() + .zip(other.f_mntonname.iter()) + .all(|(a,b)| a == b) + && self.f_mntfromname + .iter() + .zip(other.f_mntfromname.iter()) + .all(|(a,b)| a == b) + && self.f_mntfromspec + .iter() + .zip(other.f_mntfromspec.iter()) + .all(|(a,b)| a == b) + && self.mount_info == other.mount_info + } + } + + impl Eq for statfs { } + + impl ::fmt::Debug for statfs { + fn fmt(&self, f: &mut ::fmt::Formatter) + -> ::fmt::Result { + f.debug_struct("statfs") + .field("f_flags", &self.f_flags) + .field("f_bsize", &self.f_bsize) + .field("f_iosize", &self.f_iosize) + .field("f_blocks", &self.f_blocks) + .field("f_bfree", &self.f_bfree) + .field("f_bavail", &self.f_bavail) + .field("f_files", &self.f_files) + .field("f_ffree", &self.f_ffree) + .field("f_favail", &self.f_favail) + .field("f_syncwrites", &self.f_syncwrites) + .field("f_syncreads", &self.f_syncreads) + .field("f_asyncwrites", &self.f_asyncwrites) + .field("f_asyncreads", &self.f_asyncreads) + .field("f_fsid", &self.f_fsid) + .field("f_namemax", &self.f_namemax) + .field("f_owner", &self.f_owner) + .field("f_ctime", &self.f_ctime) + // FIXME: .field("f_fstypename", &self.f_fstypename) + // FIXME: .field("f_mntonname", &self.f_mntonname) + // FIXME: .field("f_mntfromname", &self.f_mntfromname) + // FIXME: .field("f_mntfromspec", &self.f_mntfromspec) + .field("mount_info", &self.mount_info) + .finish() + } + } + + impl ::hash::Hash for statfs { + fn hash(&self, state: &mut H) { + self.f_flags.hash(state); + self.f_bsize.hash(state); + self.f_iosize.hash(state); + self.f_blocks.hash(state); + self.f_bfree.hash(state); + self.f_bavail.hash(state); + self.f_files.hash(state); + self.f_ffree.hash(state); + self.f_favail.hash(state); + self.f_syncwrites.hash(state); + self.f_syncreads.hash(state); + self.f_asyncwrites.hash(state); + self.f_asyncreads.hash(state); + self.f_fsid.hash(state); + self.f_namemax.hash(state); + self.f_owner.hash(state); + self.f_ctime.hash(state); + self.f_fstypename.hash(state); + self.f_mntonname.hash(state); + self.f_mntfromname.hash(state); + self.f_mntfromspec.hash(state); + self.mount_info.hash(state); + } + } + } + } + } +} + +pub const UT_NAMESIZE: usize = 32; +pub const UT_LINESIZE: usize = 8; +pub const UT_HOSTSIZE: usize = 256; + +pub const O_CLOEXEC: ::c_int = 0x10000; +pub const O_DIRECTORY: ::c_int = 0x20000; +pub const O_RSYNC: ::c_int = O_SYNC; + +pub const MS_SYNC: ::c_int = 0x0002; +pub const MS_INVALIDATE: ::c_int = 0x0004; + +pub const POLLNORM: ::c_short = ::POLLRDNORM; + +pub const ENOATTR: ::c_int = 83; +pub const EILSEQ: ::c_int = 84; +pub const EOVERFLOW: ::c_int = 87; +pub const ECANCELED: ::c_int = 88; +pub const EIDRM: ::c_int = 89; +pub const ENOMSG: ::c_int = 90; +pub const ENOTSUP: ::c_int = 91; +pub const EBADMSG: ::c_int = 92; +pub const ENOTRECOVERABLE: ::c_int = 93; +pub const EOWNERDEAD: ::c_int = 94; +pub const EPROTO: ::c_int = 95; +pub const ELAST: ::c_int = 95; + +pub const F_DUPFD_CLOEXEC: ::c_int = 10; + +pub const UTIME_OMIT: c_long = -1; +pub const UTIME_NOW: c_long = -2; + +pub const AT_FDCWD: ::c_int = -100; +pub const AT_EACCESS: ::c_int = 0x01; +pub const AT_SYMLINK_NOFOLLOW: ::c_int = 0x02; +pub const AT_SYMLINK_FOLLOW: ::c_int = 0x04; +pub const AT_REMOVEDIR: ::c_int = 0x08; + +#[deprecated(since = "0.2.64", note = "Not stable across OS versions")] +pub const RLIM_NLIMITS: ::c_int = 9; + +pub const SO_TIMESTAMP: ::c_int = 0x0800; +pub const SO_SNDTIMEO: ::c_int = 0x1005; +pub const SO_RCVTIMEO: ::c_int = 0x1006; +pub const SO_BINDANY: ::c_int = 0x1000; +pub const SO_NETPROC: ::c_int = 0x1020; +pub const SO_RTABLE: ::c_int = 0x1021; +pub const SO_PEERCRED: ::c_int = 0x1022; +pub const SO_SPLICE: ::c_int = 0x1023; +pub const SO_DOMAIN: ::c_int = 0x1024; +pub const SO_PROTOCOL: ::c_int = 0x1025; + +// sys/netinet/in.h +// Protocols (RFC 1700) +// NOTE: These are in addition to the constants defined in src/unix/mod.rs + +// IPPROTO_IP defined in src/unix/mod.rs +/// Hop-by-hop option header +pub const IPPROTO_HOPOPTS: ::c_int = 0; +// IPPROTO_ICMP defined in src/unix/mod.rs +/// group mgmt protocol +pub const IPPROTO_IGMP: ::c_int = 2; +/// gateway^2 (deprecated) +pub const IPPROTO_GGP: ::c_int = 3; +/// for compatibility +pub const IPPROTO_IPIP: ::c_int = 4; +// IPPROTO_TCP defined in src/unix/mod.rs +/// exterior gateway protocol +pub const IPPROTO_EGP: ::c_int = 8; +/// pup +pub const IPPROTO_PUP: ::c_int = 12; +// IPPROTO_UDP defined in src/unix/mod.rs +/// xns idp +pub const IPPROTO_IDP: ::c_int = 22; +/// tp-4 w/ class negotiation +pub const IPPROTO_TP: ::c_int = 29; +// IPPROTO_IPV6 defined in src/unix/mod.rs +/// IP6 routing header +pub const IPPROTO_ROUTING: ::c_int = 43; +/// IP6 fragmentation header +pub const IPPROTO_FRAGMENT: ::c_int = 44; +/// resource reservation +pub const IPPROTO_RSVP: ::c_int = 46; +/// General Routing Encap. +pub const IPPROTO_GRE: ::c_int = 47; +/// IP6 Encap Sec. Payload +pub const IPPROTO_ESP: ::c_int = 50; +/// IP6 Auth Header +pub const IPPROTO_AH: ::c_int = 51; +/// IP Mobility RFC 2004 +pub const IPPROTO_MOBILE: ::c_int = 55; +// IPPROTO_ICMPV6 defined in src/unix/mod.rs +/// IP6 no next header +pub const IPPROTO_NONE: ::c_int = 59; +/// IP6 destination option +pub const IPPROTO_DSTOPTS: ::c_int = 60; +/// ISO cnlp +pub const IPPROTO_EON: ::c_int = 80; +/// Ethernet-in-IP +pub const IPPROTO_ETHERIP: ::c_int = 97; +/// encapsulation header +pub const IPPROTO_ENCAP: ::c_int = 98; +/// Protocol indep. multicast +pub const IPPROTO_PIM: ::c_int = 103; +/// IP Payload Comp. Protocol +pub const IPPROTO_IPCOMP: ::c_int = 108; +/// CARP +pub const IPPROTO_CARP: ::c_int = 112; +/// unicast MPLS packet +pub const IPPROTO_MPLS: ::c_int = 137; +/// PFSYNC +pub const IPPROTO_PFSYNC: ::c_int = 240; +pub const IPPROTO_MAX: ::c_int = 256; + +// Only used internally, so it can be outside the range of valid IP protocols +pub const IPPROTO_DIVERT: ::c_int = 258; + +pub const IP_RECVDSTADDR: ::c_int = 7; +pub const IP_SENDSRCADDR: ::c_int = IP_RECVDSTADDR; +pub const IP_RECVIF: ::c_int = 30; + +// sys/netinet/in.h +pub const TCP_MD5SIG: ::c_int = 0x04; +pub const TCP_NOPUSH: ::c_int = 0x10; + +pub const MSG_WAITFORONE: ::c_int = 0x1000; + +pub const AF_ECMA: ::c_int = 8; +pub const AF_ROUTE: ::c_int = 17; +pub const AF_ENCAP: ::c_int = 28; +pub const AF_SIP: ::c_int = 29; +pub const AF_KEY: ::c_int = 30; +pub const pseudo_AF_HDRCMPLT: ::c_int = 31; +pub const AF_BLUETOOTH: ::c_int = 32; +pub const AF_MPLS: ::c_int = 33; +pub const pseudo_AF_PFLOW: ::c_int = 34; +pub const pseudo_AF_PIPEX: ::c_int = 35; +pub const NET_RT_DUMP: ::c_int = 1; +pub const NET_RT_FLAGS: ::c_int = 2; +pub const NET_RT_IFLIST: ::c_int = 3; +pub const NET_RT_STATS: ::c_int = 4; +pub const NET_RT_TABLE: ::c_int = 5; +pub const NET_RT_IFNAMES: ::c_int = 6; +#[doc(hidden)] +#[deprecated( + since = "0.2.95", + note = "Possibly increasing over the releases and might not be so used in the field" +)] +pub const NET_RT_MAXID: ::c_int = 7; + +pub const IPV6_JOIN_GROUP: ::c_int = 12; +pub const IPV6_LEAVE_GROUP: ::c_int = 13; + +pub const PF_ROUTE: ::c_int = AF_ROUTE; +pub const PF_ECMA: ::c_int = AF_ECMA; +pub const PF_ENCAP: ::c_int = AF_ENCAP; +pub const PF_SIP: ::c_int = AF_SIP; +pub const PF_KEY: ::c_int = AF_KEY; +pub const PF_BPF: ::c_int = pseudo_AF_HDRCMPLT; +pub const PF_BLUETOOTH: ::c_int = AF_BLUETOOTH; +pub const PF_MPLS: ::c_int = AF_MPLS; +pub const PF_PFLOW: ::c_int = pseudo_AF_PFLOW; +pub const PF_PIPEX: ::c_int = pseudo_AF_PIPEX; + +pub const SCM_TIMESTAMP: ::c_int = 0x04; + +pub const O_DSYNC: ::c_int = 128; + +pub const MAP_RENAME: ::c_int = 0x0000; +pub const MAP_NORESERVE: ::c_int = 0x0000; +pub const MAP_HASSEMAPHORE: ::c_int = 0x0000; +pub const MAP_TRYFIXED: ::c_int = 0; + +pub const EIPSEC: ::c_int = 82; +pub const ENOMEDIUM: ::c_int = 85; +pub const EMEDIUMTYPE: ::c_int = 86; + +pub const EAI_BADFLAGS: ::c_int = -1; +pub const EAI_NONAME: ::c_int = -2; +pub const EAI_AGAIN: ::c_int = -3; +pub const EAI_FAIL: ::c_int = -4; +pub const EAI_NODATA: ::c_int = -5; +pub const EAI_FAMILY: ::c_int = -6; +pub const EAI_SOCKTYPE: ::c_int = -7; +pub const EAI_SERVICE: ::c_int = -8; +pub const EAI_MEMORY: ::c_int = -10; +pub const EAI_SYSTEM: ::c_int = -11; +pub const EAI_OVERFLOW: ::c_int = -14; + +pub const RUSAGE_THREAD: ::c_int = 1; + +pub const MAP_COPY: ::c_int = 0x0002; +pub const MAP_NOEXTEND: ::c_int = 0x0000; + +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 = 7; +pub const _PC_NO_TRUNC: ::c_int = 8; +pub const _PC_VDISABLE: ::c_int = 9; +pub const _PC_2_SYMLINKS: ::c_int = 10; +pub const _PC_ALLOC_SIZE_MIN: ::c_int = 11; +pub const _PC_ASYNC_IO: ::c_int = 12; +pub const _PC_FILESIZEBITS: ::c_int = 13; +pub const _PC_PRIO_IO: ::c_int = 14; +pub const _PC_REC_INCR_XFER_SIZE: ::c_int = 15; +pub const _PC_REC_MAX_XFER_SIZE: ::c_int = 16; +pub const _PC_REC_MIN_XFER_SIZE: ::c_int = 17; +pub const _PC_REC_XFER_ALIGN: ::c_int = 18; +pub const _PC_SYMLINK_MAX: ::c_int = 19; +pub const _PC_SYNC_IO: ::c_int = 20; +pub const _PC_TIMESTAMP_RESOLUTION: ::c_int = 21; + +pub const _SC_CLK_TCK: ::c_int = 3; +pub const _SC_SEM_NSEMS_MAX: ::c_int = 31; +pub const _SC_SEM_VALUE_MAX: ::c_int = 32; +pub const _SC_HOST_NAME_MAX: ::c_int = 33; +pub const _SC_MONOTONIC_CLOCK: ::c_int = 34; +pub const _SC_2_PBS: ::c_int = 35; +pub const _SC_2_PBS_ACCOUNTING: ::c_int = 36; +pub const _SC_2_PBS_CHECKPOINT: ::c_int = 37; +pub const _SC_2_PBS_LOCATE: ::c_int = 38; +pub const _SC_2_PBS_MESSAGE: ::c_int = 39; +pub const _SC_2_PBS_TRACK: ::c_int = 40; +pub const _SC_ADVISORY_INFO: ::c_int = 41; +pub const _SC_AIO_LISTIO_MAX: ::c_int = 42; +pub const _SC_AIO_MAX: ::c_int = 43; +pub const _SC_AIO_PRIO_DELTA_MAX: ::c_int = 44; +pub const _SC_ASYNCHRONOUS_IO: ::c_int = 45; +pub const _SC_ATEXIT_MAX: ::c_int = 46; +pub const _SC_BARRIERS: ::c_int = 47; +pub const _SC_CLOCK_SELECTION: ::c_int = 48; +pub const _SC_CPUTIME: ::c_int = 49; +pub const _SC_DELAYTIMER_MAX: ::c_int = 50; +pub const _SC_IOV_MAX: ::c_int = 51; +pub const _SC_IPV6: ::c_int = 52; +pub const _SC_MAPPED_FILES: ::c_int = 53; +pub const _SC_MEMLOCK: ::c_int = 54; +pub const _SC_MEMLOCK_RANGE: ::c_int = 55; +pub const _SC_MEMORY_PROTECTION: ::c_int = 56; +pub const _SC_MESSAGE_PASSING: ::c_int = 57; +pub const _SC_MQ_OPEN_MAX: ::c_int = 58; +pub const _SC_MQ_PRIO_MAX: ::c_int = 59; +pub const _SC_PRIORITIZED_IO: ::c_int = 60; +pub const _SC_PRIORITY_SCHEDULING: ::c_int = 61; +pub const _SC_RAW_SOCKETS: ::c_int = 62; +pub const _SC_READER_WRITER_LOCKS: ::c_int = 63; +pub const _SC_REALTIME_SIGNALS: ::c_int = 64; +pub const _SC_REGEXP: ::c_int = 65; +pub const _SC_RTSIG_MAX: ::c_int = 66; +pub const _SC_SEMAPHORES: ::c_int = 67; +pub const _SC_SHARED_MEMORY_OBJECTS: ::c_int = 68; +pub const _SC_SHELL: ::c_int = 69; +pub const _SC_SIGQUEUE_MAX: ::c_int = 70; +pub const _SC_SPAWN: ::c_int = 71; +pub const _SC_SPIN_LOCKS: ::c_int = 72; +pub const _SC_SPORADIC_SERVER: ::c_int = 73; +pub const _SC_SS_REPL_MAX: ::c_int = 74; +pub const _SC_SYNCHRONIZED_IO: ::c_int = 75; +pub const _SC_SYMLOOP_MAX: ::c_int = 76; +pub const _SC_THREAD_ATTR_STACKADDR: ::c_int = 77; +pub const _SC_THREAD_ATTR_STACKSIZE: ::c_int = 78; +pub const _SC_THREAD_CPUTIME: ::c_int = 79; +pub const _SC_THREAD_DESTRUCTOR_ITERATIONS: ::c_int = 80; +pub const _SC_THREAD_KEYS_MAX: ::c_int = 81; +pub const _SC_THREAD_PRIO_INHERIT: ::c_int = 82; +pub const _SC_THREAD_PRIO_PROTECT: ::c_int = 83; +pub const _SC_THREAD_PRIORITY_SCHEDULING: ::c_int = 84; +pub const _SC_THREAD_PROCESS_SHARED: ::c_int = 85; +pub const _SC_THREAD_ROBUST_PRIO_INHERIT: ::c_int = 86; +pub const _SC_THREAD_ROBUST_PRIO_PROTECT: ::c_int = 87; +pub const _SC_THREAD_SPORADIC_SERVER: ::c_int = 88; +pub const _SC_THREAD_STACK_MIN: ::c_int = 89; +pub const _SC_THREAD_THREADS_MAX: ::c_int = 90; +pub const _SC_THREADS: ::c_int = 91; +pub const _SC_TIMEOUTS: ::c_int = 92; +pub const _SC_TIMER_MAX: ::c_int = 93; +pub const _SC_TIMERS: ::c_int = 94; +pub const _SC_TRACE: ::c_int = 95; +pub const _SC_TRACE_EVENT_FILTER: ::c_int = 96; +pub const _SC_TRACE_EVENT_NAME_MAX: ::c_int = 97; +pub const _SC_TRACE_INHERIT: ::c_int = 98; +pub const _SC_TRACE_LOG: ::c_int = 99; +pub const _SC_GETGR_R_SIZE_MAX: ::c_int = 100; +pub const _SC_GETPW_R_SIZE_MAX: ::c_int = 101; +pub const _SC_LOGIN_NAME_MAX: ::c_int = 102; +pub const _SC_THREAD_SAFE_FUNCTIONS: ::c_int = 103; +pub const _SC_TRACE_NAME_MAX: ::c_int = 104; +pub const _SC_TRACE_SYS_MAX: ::c_int = 105; +pub const _SC_TRACE_USER_EVENT_MAX: ::c_int = 106; +pub const _SC_TTY_NAME_MAX: ::c_int = 107; +pub const _SC_TYPED_MEMORY_OBJECTS: ::c_int = 108; +pub const _SC_V6_ILP32_OFF32: ::c_int = 109; +pub const _SC_V6_ILP32_OFFBIG: ::c_int = 110; +pub const _SC_V6_LP64_OFF64: ::c_int = 111; +pub const _SC_V6_LPBIG_OFFBIG: ::c_int = 112; +pub const _SC_V7_ILP32_OFF32: ::c_int = 113; +pub const _SC_V7_ILP32_OFFBIG: ::c_int = 114; +pub const _SC_V7_LP64_OFF64: ::c_int = 115; +pub const _SC_V7_LPBIG_OFFBIG: ::c_int = 116; +pub const _SC_XOPEN_CRYPT: ::c_int = 117; +pub const _SC_XOPEN_ENH_I18N: ::c_int = 118; +pub const _SC_XOPEN_LEGACY: ::c_int = 119; +pub const _SC_XOPEN_REALTIME: ::c_int = 120; +pub const _SC_XOPEN_REALTIME_THREADS: ::c_int = 121; +pub const _SC_XOPEN_STREAMS: ::c_int = 122; +pub const _SC_XOPEN_UNIX: ::c_int = 123; +pub const _SC_XOPEN_UUCP: ::c_int = 124; +pub const _SC_XOPEN_VERSION: ::c_int = 125; +pub const _SC_PHYS_PAGES: ::c_int = 500; +pub const _SC_AVPHYS_PAGES: ::c_int = 501; +pub const _SC_NPROCESSORS_CONF: ::c_int = 502; +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 _; +pub const PTHREAD_COND_INITIALIZER: pthread_cond_t = 0 as *mut _; +pub const PTHREAD_RWLOCK_INITIALIZER: pthread_rwlock_t = 0 as *mut _; + +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_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_SIGNAL: i16 = -6; +pub const EVFILT_TIMER: i16 = -7; +pub const EVFILT_DEVICE: i16 = -8; +pub const EVFILT_EXCEPT: i16 = -9; + +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_ONESHOT: u16 = 0x10; +pub const EV_CLEAR: u16 = 0x20; +pub const EV_RECEIPT: u16 = 0x40; +pub const EV_DISPATCH: u16 = 0x80; +pub const EV_FLAG1: u16 = 0x2000; +pub const EV_ERROR: u16 = 0x4000; +pub const EV_EOF: u16 = 0x8000; + +#[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; +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_TRUNCATE: u32 = 0x00000080; +pub const NOTE_EXIT: u32 = 0x80000000; +pub const NOTE_FORK: u32 = 0x40000000; +pub const NOTE_EXEC: u32 = 0x20000000; +pub const NOTE_PDATAMASK: u32 = 0x000fffff; +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; +pub const NI_NAMEREQD: ::c_int = 8; +pub const NI_DGRAM: ::c_int = 16; + +pub const NI_MAXHOST: ::size_t = 256; + +pub const RTLD_LOCAL: ::c_int = 0; + +pub const CTL_MAXNAME: ::c_int = 12; + +pub const CTLTYPE_NODE: ::c_int = 1; +pub const CTLTYPE_INT: ::c_int = 2; +pub const CTLTYPE_STRING: ::c_int = 3; +pub const CTLTYPE_QUAD: ::c_int = 4; +pub const CTLTYPE_STRUCT: ::c_int = 5; + +pub const CTL_UNSPEC: ::c_int = 0; +pub const CTL_KERN: ::c_int = 1; +pub const CTL_VM: ::c_int = 2; +pub const CTL_FS: ::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_DDB: ::c_int = 9; +pub const CTL_VFS: ::c_int = 10; +pub const CTL_MAXID: ::c_int = 11; + +pub const HW_NCPUONLINE: ::c_int = 25; + +pub const KERN_OSTYPE: ::c_int = 1; +pub const KERN_OSRELEASE: ::c_int = 2; +pub const KERN_OSREV: ::c_int = 3; +pub const KERN_VERSION: ::c_int = 4; +pub const KERN_MAXVNODES: ::c_int = 5; +pub const KERN_MAXPROC: ::c_int = 6; +pub const KERN_MAXFILES: ::c_int = 7; +pub const KERN_ARGMAX: ::c_int = 8; +pub const KERN_SECURELVL: ::c_int = 9; +pub const KERN_HOSTNAME: ::c_int = 10; +pub const KERN_HOSTID: ::c_int = 11; +pub const KERN_CLOCKRATE: ::c_int = 12; +pub const KERN_PROF: ::c_int = 16; +pub const KERN_POSIX1: ::c_int = 17; +pub const KERN_NGROUPS: ::c_int = 18; +pub const KERN_JOB_CONTROL: ::c_int = 19; +pub const KERN_SAVED_IDS: ::c_int = 20; +pub const KERN_BOOTTIME: ::c_int = 21; +pub const KERN_DOMAINNAME: ::c_int = 22; +pub const KERN_MAXPARTITIONS: ::c_int = 23; +pub const KERN_RAWPARTITION: ::c_int = 24; +pub const KERN_MAXTHREAD: ::c_int = 25; +pub const KERN_NTHREADS: ::c_int = 26; +pub const KERN_OSVERSION: ::c_int = 27; +pub const KERN_SOMAXCONN: ::c_int = 28; +pub const KERN_SOMINCONN: ::c_int = 29; +#[deprecated(since = "0.2.71", note = "Removed in OpenBSD 6.0")] +pub const KERN_USERMOUNT: ::c_int = 30; +pub const KERN_NOSUIDCOREDUMP: ::c_int = 32; +pub const KERN_FSYNC: ::c_int = 33; +pub const KERN_SYSVMSG: ::c_int = 34; +pub const KERN_SYSVSEM: ::c_int = 35; +pub const KERN_SYSVSHM: ::c_int = 36; +#[deprecated(since = "0.2.71", note = "Removed in OpenBSD 6.0")] +pub const KERN_ARND: ::c_int = 37; +pub const KERN_MSGBUFSIZE: ::c_int = 38; +pub const KERN_MALLOCSTATS: ::c_int = 39; +pub const KERN_CPTIME: ::c_int = 40; +pub const KERN_NCHSTATS: ::c_int = 41; +pub const KERN_FORKSTAT: ::c_int = 42; +pub const KERN_NSELCOLL: ::c_int = 43; +pub const KERN_TTY: ::c_int = 44; +pub const KERN_CCPU: ::c_int = 45; +pub const KERN_FSCALE: ::c_int = 46; +pub const KERN_NPROCS: ::c_int = 47; +pub const KERN_MSGBUF: ::c_int = 48; +pub const KERN_POOL: ::c_int = 49; +pub const KERN_STACKGAPRANDOM: ::c_int = 50; +pub const KERN_SYSVIPC_INFO: ::c_int = 51; +pub const KERN_SPLASSERT: ::c_int = 54; +pub const KERN_PROC_ARGS: ::c_int = 55; +pub const KERN_NFILES: ::c_int = 56; +pub const KERN_TTYCOUNT: ::c_int = 57; +pub const KERN_NUMVNODES: ::c_int = 58; +pub const KERN_MBSTAT: ::c_int = 59; +pub const KERN_SEMINFO: ::c_int = 61; +pub const KERN_SHMINFO: ::c_int = 62; +pub const KERN_INTRCNT: ::c_int = 63; +pub const KERN_WATCHDOG: ::c_int = 64; +pub const KERN_PROC: ::c_int = 66; +pub const KERN_MAXCLUSTERS: ::c_int = 67; +pub const KERN_EVCOUNT: ::c_int = 68; +pub const KERN_TIMECOUNTER: ::c_int = 69; +pub const KERN_MAXLOCKSPERUID: ::c_int = 70; +pub const KERN_CPTIME2: ::c_int = 71; +pub const KERN_CACHEPCT: ::c_int = 72; +pub const KERN_FILE: ::c_int = 73; +pub const KERN_CONSDEV: ::c_int = 75; +pub const KERN_NETLIVELOCKS: ::c_int = 76; +pub const KERN_POOL_DEBUG: ::c_int = 77; +pub const KERN_PROC_CWD: ::c_int = 78; +pub const KERN_PROC_NOBROADCASTKILL: ::c_int = 79; +pub const KERN_PROC_VMMAP: ::c_int = 80; +pub const KERN_GLOBAL_PTRACE: ::c_int = 81; +pub const KERN_CONSBUFSIZE: ::c_int = 82; +pub const KERN_CONSBUF: ::c_int = 83; +pub const KERN_AUDIO: ::c_int = 84; +pub const KERN_CPUSTATS: ::c_int = 85; +pub const KERN_PFSTATUS: ::c_int = 86; +pub const KERN_TIMEOUT_STATS: ::c_int = 87; +#[deprecated( + since = "0.2.95", + note = "Possibly increasing over the releases and might not be so used in the field" +)] +pub const KERN_MAXID: ::c_int = 88; + +pub const KERN_PROC_ALL: ::c_int = 0; +pub const KERN_PROC_PID: ::c_int = 1; +pub const KERN_PROC_PGRP: ::c_int = 2; +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_PROC_RUID: ::c_int = 6; +pub const KERN_PROC_KTHREAD: ::c_int = 7; +pub const KERN_PROC_SHOW_THREADS: ::c_int = 0x40000000; + +pub const KERN_SYSVIPC_MSG_INFO: ::c_int = 1; +pub const KERN_SYSVIPC_SEM_INFO: ::c_int = 2; +pub const KERN_SYSVIPC_SHM_INFO: ::c_int = 3; + +pub const KERN_PROC_ARGV: ::c_int = 1; +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 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 = 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; +pub const ONLRET: ::tcflag_t = 0x80; + +//https://github.com/openbsd/src/blob/HEAD/sys/sys/mount.h +pub const ISOFSMNT_NORRIP: ::c_int = 0x1; // disable Rock Ridge Ext +pub const ISOFSMNT_GENS: ::c_int = 0x2; // enable generation numbers +pub const ISOFSMNT_EXTATT: ::c_int = 0x4; // enable extended attr +pub const ISOFSMNT_NOJOLIET: ::c_int = 0x8; // disable Joliet Ext +pub const ISOFSMNT_SESS: ::c_int = 0x10; // use iso_args.sess + +pub const NFS_ARGSVERSION: ::c_int = 4; // change when nfs_args changes + +pub const NFSMNT_RESVPORT: ::c_int = 0; // always use reserved ports +pub const NFSMNT_SOFT: ::c_int = 0x1; // soft mount (hard is default) +pub const NFSMNT_WSIZE: ::c_int = 0x2; // set write size +pub const NFSMNT_RSIZE: ::c_int = 0x4; // set read size +pub const NFSMNT_TIMEO: ::c_int = 0x8; // set initial timeout +pub const NFSMNT_RETRANS: ::c_int = 0x10; // set number of request retries +pub const NFSMNT_MAXGRPS: ::c_int = 0x20; // set maximum grouplist size +pub const NFSMNT_INT: ::c_int = 0x40; // allow interrupts on hard mount +pub const NFSMNT_NOCONN: ::c_int = 0x80; // Don't Connect the socket +pub const NFSMNT_NQNFS: ::c_int = 0x100; // Use Nqnfs protocol +pub const NFSMNT_NFSV3: ::c_int = 0x200; // Use NFS Version 3 protocol +pub const NFSMNT_KERB: ::c_int = 0x400; // Use Kerberos authentication +pub const NFSMNT_DUMBTIMR: ::c_int = 0x800; // Don't estimate rtt dynamically +pub const NFSMNT_LEASETERM: ::c_int = 0x1000; // set lease term (nqnfs) +pub const NFSMNT_READAHEAD: ::c_int = 0x2000; // set read ahead +pub const NFSMNT_DEADTHRESH: ::c_int = 0x4000; // set dead server retry thresh +pub const NFSMNT_NOAC: ::c_int = 0x8000; // disable attribute cache +pub const NFSMNT_RDIRPLUS: ::c_int = 0x10000; // Use Readdirplus for V3 +pub const NFSMNT_READDIRSIZE: ::c_int = 0x20000; // Set readdir size + +/* Flags valid only in mount syscall arguments */ +pub const NFSMNT_ACREGMIN: ::c_int = 0x40000; // acregmin field valid +pub const NFSMNT_ACREGMAX: ::c_int = 0x80000; // acregmax field valid +pub const NFSMNT_ACDIRMIN: ::c_int = 0x100000; // acdirmin field valid +pub const NFSMNT_ACDIRMAX: ::c_int = 0x200000; // acdirmax field valid + +/* Flags valid only in kernel */ +pub const NFSMNT_INTERNAL: ::c_int = 0xfffc0000; // Bits set internally +pub const NFSMNT_HASWRITEVERF: ::c_int = 0x40000; // Has write verifier for V3 +pub const NFSMNT_GOTPATHCONF: ::c_int = 0x80000; // Got the V3 pathconf info +pub const NFSMNT_GOTFSINFO: ::c_int = 0x100000; // Got the V3 fsinfo +pub const NFSMNT_MNTD: ::c_int = 0x200000; // Mnt server for mnt point +pub const NFSMNT_DISMINPROG: ::c_int = 0x400000; // Dismount in progress +pub const NFSMNT_DISMNT: ::c_int = 0x800000; // Dismounted +pub const NFSMNT_SNDLOCK: ::c_int = 0x1000000; // Send socket lock +pub const NFSMNT_WANTSND: ::c_int = 0x2000000; // Want above +pub const NFSMNT_RCVLOCK: ::c_int = 0x4000000; // Rcv socket lock +pub const NFSMNT_WANTRCV: ::c_int = 0x8000000; // Want above +pub const NFSMNT_WAITAUTH: ::c_int = 0x10000000; // Wait for authentication +pub const NFSMNT_HASAUTH: ::c_int = 0x20000000; // Has authenticator +pub const NFSMNT_WANTAUTH: ::c_int = 0x40000000; // Wants an authenticator +pub const NFSMNT_AUTHERR: ::c_int = 0x80000000; // Authentication error + +pub const MSDOSFSMNT_SHORTNAME: ::c_int = 0x1; // Force old DOS short names only +pub const MSDOSFSMNT_LONGNAME: ::c_int = 0x2; // Force Win'95 long names +pub const MSDOSFSMNT_NOWIN95: ::c_int = 0x4; // Completely ignore Win95 entries + +pub const NTFS_MFLAG_CASEINS: ::c_int = 0x1; +pub const NTFS_MFLAG_ALLNAMES: ::c_int = 0x2; + +pub const TMPFS_ARGS_VERSION: ::c_int = 1; + +const SI_MAXSZ: ::size_t = 128; +const SI_PAD: ::size_t = (SI_MAXSZ / ::mem::size_of::<::c_int>()) - 3; + +pub const MAP_STACK: ::c_int = 0x4000; +pub const MAP_CONCEAL: ::c_int = 0x8000; + +// https://github.com/openbsd/src/blob/HEAD/sys/net/if.h#L187 +pub const IFF_UP: ::c_int = 0x1; // interface is up +pub const IFF_BROADCAST: ::c_int = 0x2; // broadcast address valid +pub const IFF_DEBUG: ::c_int = 0x4; // turn on debugging +pub const IFF_LOOPBACK: ::c_int = 0x8; // is a loopback net +pub const IFF_POINTOPOINT: ::c_int = 0x10; // interface is point-to-point link +pub const IFF_STATICARP: ::c_int = 0x20; // only static ARP +pub const IFF_RUNNING: ::c_int = 0x40; // resources allocated +pub const IFF_NOARP: ::c_int = 0x80; // no address resolution protocol +pub const IFF_PROMISC: ::c_int = 0x100; // receive all packets +pub const IFF_ALLMULTI: ::c_int = 0x200; // receive all multicast packets +pub const IFF_OACTIVE: ::c_int = 0x400; // transmission in progress +pub const IFF_SIMPLEX: ::c_int = 0x800; // 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_MULTICAST: ::c_int = 0x8000; // supports multicast + +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; +pub const SOCK_NONBLOCK: ::c_int = 0x4000; +pub const SOCK_DNS: ::c_int = 0x1000; + +pub const BIOCGRSIG: ::c_ulong = 0x40044273; +pub const BIOCSRSIG: ::c_ulong = 0x80044272; +pub const BIOCSDLT: ::c_ulong = 0x8004427a; + +pub const PTRACE_FORK: ::c_int = 0x0002; + +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/exec_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_LOOS: u32 = 0x60000000; +pub const PT_HIOS: u32 = 0x6fffffff; +pub const PT_LOPROC: u32 = 0x70000000; +pub const PT_HIPROC: u32 = 0x7fffffff; + +pub const PT_GNU_EH_FRAME: u32 = 0x6474e550; +pub const PT_GNU_RELRO: u32 = 0x6474e552; + +// sys/exec_elf.h - Legal values for p_flags (segment flags). +pub const PF_X: u32 = 0x1; +pub const PF_W: u32 = 0x2; +pub const PF_R: u32 = 0x4; +pub const PF_MASKOS: u32 = 0x0ff00000; +pub const PF_MASKPROC: u32 = 0xf0000000; + +// 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; + +// sys/reboot.h +pub const RB_ASKNAME: ::c_int = 0x00001; +pub const RB_SINGLE: ::c_int = 0x00002; +pub const RB_NOSYNC: ::c_int = 0x00004; +pub const RB_HALT: ::c_int = 0x00008; +pub const RB_INITNAME: ::c_int = 0x00010; +pub const RB_KDB: ::c_int = 0x00040; +pub const RB_RDONLY: ::c_int = 0x00080; +pub const RB_DUMP: ::c_int = 0x00100; +pub const RB_MINIROOT: ::c_int = 0x00200; +pub const RB_CONFIG: ::c_int = 0x00400; +pub const RB_TIMEBAD: ::c_int = 0x00800; +pub const RB_POWERDOWN: ::c_int = 0x01000; +pub const RB_SERCONS: ::c_int = 0x02000; +pub const RB_USERREQ: ::c_int = 0x04000; +pub const RB_RESET: ::c_int = 0x08000; +pub const RB_GOODRANDOM: ::c_int = 0x10000; +pub const RB_UNHIBERNATE: ::c_int = 0x20000; + +// net/route.h +pub const RTF_CLONING: ::c_int = 0x100; +pub const RTF_MULTICAST: ::c_int = 0x200; +pub const RTF_LLINFO: ::c_int = 0x400; +pub const RTF_PROTO3: ::c_int = 0x2000; +pub const RTF_ANNOUNCE: ::c_int = ::RTF_PROTO2; + +pub const RTF_CLONED: ::c_int = 0x10000; +pub const RTF_CACHED: ::c_int = 0x20000; +pub const RTF_MPATH: ::c_int = 0x40000; +pub const RTF_MPLS: ::c_int = 0x100000; +pub const RTF_LOCAL: ::c_int = 0x200000; +pub const RTF_BROADCAST: ::c_int = 0x400000; +pub const RTF_CONNECTED: ::c_int = 0x800000; +pub const RTF_BFD: ::c_int = 0x1000000; +pub const RTF_FMASK: ::c_int = ::RTF_LLINFO + | ::RTF_PROTO1 + | ::RTF_PROTO2 + | ::RTF_PROTO3 + | ::RTF_BLACKHOLE + | ::RTF_REJECT + | ::RTF_STATIC + | ::RTF_MPLS + | ::RTF_BFD; + +pub const RTM_VERSION: ::c_int = 5; +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_IFANNOUNCE: ::c_int = 0xf; +pub const RTM_DESYNC: ::c_int = 0x10; +pub const RTM_INVALIDATE: ::c_int = 0x11; +pub const RTM_BFD: ::c_int = 0x12; +pub const RTM_PROPOSAL: ::c_int = 0x13; +pub const RTM_CHGADDRATTR: ::c_int = 0x14; +pub const RTM_80211INFO: ::c_int = 0x15; +pub const RTM_SOURCE: ::c_int = 0x16; + +pub const RTA_SRC: ::c_int = 0x100; +pub const RTA_SRCMASK: ::c_int = 0x200; +pub const RTA_LABEL: ::c_int = 0x400; +pub const RTA_BFD: ::c_int = 0x800; +pub const RTA_DNS: ::c_int = 0x1000; +pub const RTA_STATIC: ::c_int = 0x2000; +pub const RTA_SEARCH: ::c_int = 0x4000; + +pub const RTAX_SRC: ::c_int = 8; +pub const RTAX_SRCMASK: ::c_int = 9; +pub const RTAX_LABEL: ::c_int = 10; +pub const RTAX_BFD: ::c_int = 11; +pub const RTAX_DNS: ::c_int = 12; +pub const RTAX_STATIC: ::c_int = 13; +pub const RTAX_SEARCH: ::c_int = 14; +pub const RTAX_MAX: ::c_int = 15; + +const_fn! { + {const} fn _ALIGN(p: usize) -> usize { + (p + _ALIGNBYTES) & !_ALIGNBYTES + } +} + +f! { + pub fn CMSG_DATA(cmsg: *const ::cmsghdr) -> *mut ::c_uchar { + (cmsg as *mut ::c_uchar) + .offset(_ALIGN(::mem::size_of::<::cmsghdr>()) as isize) + } + + pub {const} fn CMSG_LEN(length: ::c_uint) -> ::c_uint { + _ALIGN(::mem::size_of::<::cmsghdr>()) as ::c_uint + length + } + + pub fn CMSG_NXTHDR(mhdr: *const ::msghdr, cmsg: *const ::cmsghdr) + -> *mut ::cmsghdr + { + if cmsg.is_null() { + return ::CMSG_FIRSTHDR(mhdr); + }; + let next = cmsg as usize + _ALIGN((*cmsg).cmsg_len as usize) + + _ALIGN(::mem::size_of::<::cmsghdr>()); + let max = (*mhdr).msg_control as usize + + (*mhdr).msg_controllen as usize; + if next > max { + 0 as *mut ::cmsghdr + } else { + (cmsg as usize + _ALIGN((*cmsg).cmsg_len as usize)) + as *mut ::cmsghdr + } + } + + pub {const} fn CMSG_SPACE(length: ::c_uint) -> ::c_uint { + (_ALIGN(::mem::size_of::<::cmsghdr>()) + _ALIGN(length as usize)) + as ::c_uint + } + + pub fn major(dev: ::dev_t) -> ::c_uint{ + ((dev as ::c_uint) >> 8) & 0xff + } + + pub fn minor(dev: ::dev_t) -> ::c_uint { + let dev = dev as ::c_uint; + let mut res = 0; + res |= (dev) & 0xff; + res |= ((dev) & 0xffff0000) >> 8; + + res + } +} + +safe_f! { + pub {const} fn WSTOPSIG(status: ::c_int) -> ::c_int { + status >> 8 + } + + pub {const} fn WIFSIGNALED(status: ::c_int) -> bool { + (status & 0o177) != 0o177 && (status & 0o177) != 0 + } + + pub {const} fn WIFSTOPPED(status: ::c_int) -> bool { + (status & 0xff) == 0o177 + } + + 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" { + pub fn gettimeofday(tp: *mut ::timeval, tz: *mut ::timezone) -> ::c_int; + pub fn settimeofday(tp: *const ::timeval, tz: *const ::timezone) -> ::c_int; + pub fn pledge(promises: *const ::c_char, execpromises: *const ::c_char) -> ::c_int; + pub fn unveil(path: *const ::c_char, permissions: *const ::c_char) -> ::c_int; + pub fn strtonum( + nptr: *const ::c_char, + minval: ::c_longlong, + maxval: ::c_longlong, + errstr: *mut *const ::c_char, + ) -> ::c_longlong; + pub fn dup3(src: ::c_int, dst: ::c_int, flags: ::c_int) -> ::c_int; + pub fn chflags(path: *const ::c_char, flags: ::c_uint) -> ::c_int; + pub fn fchflags(fd: ::c_int, flags: ::c_uint) -> ::c_int; + pub fn chflagsat( + fd: ::c_int, + path: *const ::c_char, + flags: ::c_uint, + atflag: ::c_int, + ) -> ::c_int; + pub fn dirfd(dirp: *mut ::DIR) -> ::c_int; + pub fn getnameinfo( + sa: *const ::sockaddr, + salen: ::socklen_t, + host: *mut ::c_char, + hostlen: ::size_t, + serv: *mut ::c_char, + 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, + nchanges: ::c_int, + eventlist: *mut ::kevent, + nevents: ::c_int, + 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, + ) -> ::c_int; + pub fn pthread_attr_setguardsize(attr: *mut ::pthread_attr_t, guardsize: ::size_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 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, + oldp: *mut ::c_void, + oldlenp: *mut ::size_t, + newp: *mut ::c_void, + newlen: ::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, + needle: *const ::c_void, + needlelen: ::size_t, + ) -> *mut ::c_void; + // #include + 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 uselocale(loc: ::locale_t) -> ::locale_t; + pub fn freelocale(loc: ::locale_t); + pub fn newlocale(mask: ::c_int, locale: *const ::c_char, base: ::locale_t) -> ::locale_t; + pub fn duplocale(base: ::locale_t) -> ::locale_t; + + // Added in `OpenBSD` 5.5 + 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; + + pub fn reboot(mode: ::c_int) -> ::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! { + if #[cfg(libc_union)] { + extern { + // 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 = "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..35f1672 --- /dev/null +++ b/vendor/libc/src/unix/bsd/netbsdlike/openbsd/riscv64.rs @@ -0,0 +1,35 @@ +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_ra: ::c_long, + pub sc_sp: ::c_long, + pub sc_gp: ::c_long, + pub sc_tp: ::c_long, + pub sc_t: [::c_long; 7], + pub sc_s: [::c_long; 12], + pub sc_a: [::c_long; 8], + pub sc_sepc: ::c_long, + pub sc_f: [::c_long; 32], + pub sc_fcsr: ::c_long, + pub sc_cookie: ::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_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/sparc64.rs b/vendor/libc/src/unix/bsd/netbsdlike/openbsd/sparc64.rs new file mode 100644 index 0000000..070fc93 --- /dev/null +++ b/vendor/libc/src/unix/bsd/netbsdlike/openbsd/sparc64.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 = 0xf; + +pub const _MAX_PAGE_SHIFT: u32 = 13; diff --git a/vendor/libc/src/unix/bsd/netbsdlike/openbsd/x86.rs b/vendor/libc/src/unix/bsd/netbsdlike/openbsd/x86.rs new file mode 100644 index 0000000..e87d0ff --- /dev/null +++ b/vendor/libc/src/unix/bsd/netbsdlike/openbsd/x86.rs @@ -0,0 +1,16 @@ +pub type c_long = i32; +pub type c_ulong = u32; +pub type c_char = i8; + +// 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 _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 new file mode 100644 index 0000000..60dab00 --- /dev/null +++ b/vendor/libc/src/unix/bsd/netbsdlike/openbsd/x86_64.rs @@ -0,0 +1,130 @@ +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! { + 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; + +pub const PT_STEP: ::c_int = PT_FIRSTMACH + 0; +pub const PT_GETREGS: ::c_int = PT_FIRSTMACH + 1; +pub const PT_SETREGS: ::c_int = PT_FIRSTMACH + 2; +pub const PT_GETFPREGS: ::c_int = PT_FIRSTMACH + 3; +pub const PT_SETFPREGS: ::c_int = PT_FIRSTMACH + 4; diff --git a/vendor/libc/src/unix/haiku/b32.rs b/vendor/libc/src/unix/haiku/b32.rs new file mode 100644 index 0000000..073ae9d --- /dev/null +++ b/vendor/libc/src/unix/haiku/b32.rs @@ -0,0 +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 new file mode 100644 index 0000000..4569180 --- /dev/null +++ b/vendor/libc/src/unix/haiku/b64.rs @@ -0,0 +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 new file mode 100644 index 0000000..3a226e6 --- /dev/null +++ b/vendor/libc/src/unix/haiku/mod.rs @@ -0,0 +1,2186 @@ +pub type rlim_t = ::uintptr_t; +pub type sa_family_t = u8; +pub type pthread_key_t = ::c_int; +pub type nfds_t = ::c_ulong; +pub type tcflag_t = ::c_uint; +pub type speed_t = ::c_uchar; +pub type c_char = i8; +pub type clock_t = i32; +pub type clockid_t = i32; +pub type suseconds_t = i32; +pub type wchar_t = i32; +pub type off_t = i64; +pub type ino_t = i64; +pub type blkcnt_t = i64; +pub type blksize_t = i32; +pub type dev_t = i32; +pub type mode_t = u32; +pub type nlink_t = i32; +pub type useconds_t = u32; +pub type socklen_t = u32; +pub type pthread_t = ::uintptr_t; +pub type pthread_condattr_t = ::uintptr_t; +pub type pthread_mutexattr_t = ::uintptr_t; +pub type pthread_rwlockattr_t = ::uintptr_t; +pub type sigset_t = u64; +pub type fsblkcnt_t = i64; +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_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 {} +impl ::Copy for timezone {} +impl ::Clone for timezone { + fn clone(&self) -> timezone { + *self + } +} + +impl siginfo_t { + pub unsafe fn si_addr(&self) -> *mut ::c_void { + self.si_addr + } + + 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 + } +} + +s! { + pub struct in_addr { + pub s_addr: ::in_addr_t, + } + + pub struct ip_mreq { + pub imr_multiaddr: in_addr, + pub imr_interface: in_addr, + } + + pub struct sockaddr { + pub sa_len: u8, + pub sa_family: sa_family_t, + pub sa_data: [u8; 30], + } + + 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; 24], + } + + pub struct sockaddr_in6 { + pub sin6_len: u8, + pub sin6_family: u8, + pub sin6_port: u16, + pub sin6_flowinfo: u32, + pub sin6_addr: ::in6_addr, + pub sin6_scope_id: u32, + } + + 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 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], + } + + 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_int, + pub tm_zone: *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 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_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 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 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 termios { + pub c_iflag: ::tcflag_t, + pub c_oflag: ::tcflag_t, + pub c_cflag: ::tcflag_t, + pub c_lflag: ::tcflag_t, + pub c_line: ::c_char, + pub c_ispeed: ::speed_t, + pub c_ospeed: ::speed_t, + pub c_cc: [::cc_t; ::NCCS], + } + + 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 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_size: off_t, + pub st_rdev: dev_t, + pub st_blksize: blksize_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_crtime: time_t, + pub st_crtime_nsec: c_long, + pub st_type: u32, + pub st_blocks: blkcnt_t, + } + + pub struct glob_t { + pub gl_pathc: ::size_t, + __unused1: ::size_t, + pub gl_offs: ::size_t, + __unused2: ::size_t, + pub gl_pathv: *mut *mut c_char, + + __unused3: *mut ::c_void, + __unused4: *mut ::c_void, + __unused5: *mut ::c_void, + __unused6: *mut ::c_void, + __unused7: *mut ::c_void, + __unused8: *mut ::c_void, + } + + pub struct pthread_mutex_t { + flags: u32, + lock: i32, + unused: i32, + owner: i32, + owner_count: i32, + } + + pub struct pthread_cond_t { + flags: u32, + unused: i32, + mutex: *mut ::c_void, + waiter_count: i32, + lock: i32, + } + + pub struct pthread_rwlock_t { + flags: u32, + owner: i32, + lock_sem: i32, // this is actually a union + lock_count: i32, + reader_count: i32, + writer_count: i32, + 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, + pub pw_uid: ::uid_t, + pub pw_gid: ::gid_t, + pub pw_dir: *mut ::c_char, + pub pw_shell: *mut ::c_char, + pub pw_gecos: *mut ::c_char, + } + + 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 struct stack_t { + pub ss_sp: *mut ::c_void, + pub ss_size: ::size_t, + pub ss_flags: ::c_int, + } + + pub struct siginfo_t { + pub si_signo: ::c_int, + pub si_code: ::c_int, + pub si_errno: ::c_int, + pub si_pid: ::pid_t, + pub si_uid: ::uid_t, + pub si_addr: *mut ::c_void, + pub si_status: ::c_int, + pub si_band: c_long, + pub sigval: *mut ::c_void, + } + + pub struct sigaction { + pub sa_sigaction: ::sighandler_t, //actually a union with sa_handler + pub sa_mask: ::sigset_t, + pub sa_flags: ::c_int, + sa_userdata: *mut ::c_void, + } + + pub struct sem_t { + pub type_: i32, + 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! { + pub struct sockaddr_un { + pub sun_len: u8, + pub sun_family: sa_family_t, + pub sun_path: [::c_char; 126] + } + pub struct sockaddr_storage { + pub ss_len: u8, + pub ss_family: sa_family_t, + __ss_pad1: [u8; 6], + __ss_pad2: u64, + __ss_pad3: [u8; 112], + } + pub struct dirent { + pub d_dev: dev_t, + pub d_pdev: dev_t, + pub d_ino: ino_t, + pub d_pino: i64, + pub d_reclen: ::c_ushort, + pub d_name: [::c_char; 1024], // Max length is _POSIX_PATH_MAX + } + + pub struct sigevent { + pub sigev_notify: ::c_int, + pub sigev_signo: ::c_int, + pub sigev_value: ::sigval, + __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 + && 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 sockaddr_storage { + fn eq(&self, other: &sockaddr_storage) -> bool { + self.ss_len == other.ss_len + && self.ss_family == other.ss_family + && self + .__ss_pad1 + .iter() + .zip(other.__ss_pad1.iter()) + .all(|(a, b)| a == b) + && self.__ss_pad2 == other.__ss_pad2 + && self + .__ss_pad3 + .iter() + .zip(other.__ss_pad3.iter()) + .all(|(a, b)| a == b) + } + } + impl Eq for sockaddr_storage {} + impl ::fmt::Debug for sockaddr_storage { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("sockaddr_storage") + .field("ss_len", &self.ss_len) + .field("ss_family", &self.ss_family) + .field("__ss_pad1", &self.__ss_pad1) + .field("__ss_pad2", &self.__ss_pad2) + // FIXME: .field("__ss_pad3", &self.__ss_pad3) + .finish() + } + } + impl ::hash::Hash for sockaddr_storage { + fn hash(&self, state: &mut H) { + self.ss_len.hash(state); + self.ss_family.hash(state); + self.__ss_pad1.hash(state); + self.__ss_pad2.hash(state); + self.__ss_pad3.hash(state); + } + } + + impl PartialEq for dirent { + fn eq(&self, other: &dirent) -> bool { + self.d_dev == other.d_dev + && self.d_pdev == other.d_pdev + && self.d_ino == other.d_ino + && self.d_pino == other.d_pino + && self.d_reclen == other.d_reclen + && self + .d_name + .iter() + .zip(other.d_name.iter()) + .all(|(a,b)| a == b) + } + } + impl Eq for dirent {} + impl ::fmt::Debug for dirent { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("dirent") + .field("d_dev", &self.d_dev) + .field("d_pdev", &self.d_pdev) + .field("d_ino", &self.d_ino) + .field("d_pino", &self.d_pino) + .field("d_reclen", &self.d_reclen) + // FIXME: .field("d_name", &self.d_name) + .finish() + } + } + impl ::hash::Hash for dirent { + fn hash(&self, state: &mut H) { + self.d_dev.hash(state); + self.d_pdev.hash(state); + self.d_ino.hash(state); + self.d_pino.hash(state); + self.d_reclen.hash(state); + self.d_name.hash(state); + } + } + + 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_attributes + == other.sigev_notify_attributes + } + } + 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_attributes", + &self.sigev_notify_attributes) + .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_attributes.hash(state); + } + } + } +} + +pub const EXIT_FAILURE: ::c_int = 1; +pub const EXIT_SUCCESS: ::c_int = 0; +pub const RAND_MAX: ::c_int = 2147483647; +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; + +pub const F_DUPFD: ::c_int = 0x0001; +pub const F_GETFD: ::c_int = 0x0002; +pub const F_SETFD: ::c_int = 0x0004; +pub const F_GETFL: ::c_int = 0x0008; +pub const F_SETFL: ::c_int = 0x0010; +pub const F_GETLK: ::c_int = 0x0020; +pub const F_SETLK: ::c_int = 0x0080; +pub const F_SETLKW: ::c_int = 0x0100; +pub const F_DUPFD_CLOEXEC: ::c_int = 0x0200; + +pub const F_RDLCK: ::c_int = 0x0040; +pub const F_UNLCK: ::c_int = 0x0200; +pub const F_WRLCK: ::c_int = 0x0400; + +pub const AT_FDCWD: ::c_int = -100; +pub const AT_SYMLINK_NOFOLLOW: ::c_int = 0x01; +pub const AT_SYMLINK_FOLLOW: ::c_int = 0x02; +pub const AT_REMOVEDIR: ::c_int = 0x04; +pub const AT_EACCESS: ::c_int = 0x08; + +pub const POLLIN: ::c_short = 0x0001; +pub const POLLOUT: ::c_short = 0x0002; +pub const POLLRDNORM: ::c_short = POLLIN; +pub const POLLWRNORM: ::c_short = POLLOUT; +pub const POLLRDBAND: ::c_short = 0x0008; +pub const POLLWRBAND: ::c_short = 0x0010; +pub const POLLPRI: ::c_short = 0x0020; +pub const POLLERR: ::c_short = 0x0004; +pub const POLLHUP: ::c_short = 0x0080; +pub const POLLNVAL: ::c_short = 0x1000; + +pub const PTHREAD_CREATE_JOINABLE: ::c_int = 0; +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; +pub const RLIMIT_DATA: ::c_int = 2; +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; +#[deprecated(since = "0.2.64", note = "Not stable across OS versions")] +pub const RLIM_NLIMITS: ::c_int = 8; + +pub const RUSAGE_SELF: ::c_int = 0; + +pub const RTLD_LAZY: ::c_int = 0; + +pub const NCCS: usize = 11; + +pub const O_RDONLY: ::c_int = 0x0000; +pub const O_WRONLY: ::c_int = 0x0001; +pub const O_RDWR: ::c_int = 0x0002; +pub const O_ACCMODE: ::c_int = 0x0003; + +pub const O_EXCL: ::c_int = 0x0100; +pub const O_CREAT: ::c_int = 0x0200; +pub const O_TRUNC: ::c_int = 0x0400; +pub const O_NOCTTY: ::c_int = 0x1000; +pub const O_NOTRAVERSE: ::c_int = 0x2000; + +pub const O_CLOEXEC: ::c_int = 0x00000040; +pub const O_NONBLOCK: ::c_int = 0x00000080; +pub const O_APPEND: ::c_int = 0x00000800; +pub const O_SYNC: ::c_int = 0x00010000; +pub const O_RSYNC: ::c_int = 0x00020000; +pub const O_DSYNC: ::c_int = 0x00040000; +pub const O_NOFOLLOW: ::c_int = 0x00080000; +pub const O_NOCACHE: ::c_int = 0x00100000; +pub const O_DIRECTORY: ::c_int = 0x00200000; + +pub const S_IFIFO: ::mode_t = 4096; +pub const S_IFCHR: ::mode_t = 8192; +pub const S_IFBLK: ::mode_t = 24576; +pub const S_IFDIR: ::mode_t = 16384; +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 = 61440; + +pub const S_IRWXU: ::mode_t = 0o00700; +pub const S_IRUSR: ::mode_t = 0o00400; +pub const S_IWUSR: ::mode_t = 0o00200; +pub const S_IXUSR: ::mode_t = 0o00100; +pub const S_IRWXG: ::mode_t = 0o00070; +pub const S_IRGRP: ::mode_t = 0o00040; +pub const S_IWGRP: ::mode_t = 0o00020; +pub const S_IXGRP: ::mode_t = 0o00010; +pub const S_IRWXO: ::mode_t = 0o00007; +pub const S_IROTH: ::mode_t = 0o00004; +pub const S_IWOTH: ::mode_t = 0o00002; +pub const S_IXOTH: ::mode_t = 0o00001; + +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; +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 SIGCHLD: ::c_int = 5; +pub const SIGABRT: ::c_int = 6; +pub const SIGPIPE: ::c_int = 7; +pub const SIGFPE: ::c_int = 8; +pub const SIGKILL: ::c_int = 9; +pub const SIGSTOP: ::c_int = 10; +pub const SIGSEGV: ::c_int = 11; +pub const SIGCONT: ::c_int = 12; +pub const SIGTSTP: ::c_int = 13; +pub const SIGALRM: ::c_int = 14; +pub const SIGTERM: ::c_int = 15; +pub const SIGTTIN: ::c_int = 16; +pub const SIGTTOU: ::c_int = 17; +pub const SIGUSR1: ::c_int = 18; +pub const SIGUSR2: ::c_int = 19; +pub const SIGWINCH: ::c_int = 20; +pub const SIGKILLTHR: ::c_int = 21; +pub const SIGTRAP: ::c_int = 22; +pub const SIGPOLL: ::c_int = 23; +pub const SIGPROF: ::c_int = 24; +pub const SIGSYS: ::c_int = 25; +pub const SIGURG: ::c_int = 26; +pub const SIGVTALRM: ::c_int = 27; +pub const SIGXCPU: ::c_int = 28; +pub const SIGXFSZ: ::c_int = 29; +pub const SIGBUS: ::c_int = 30; + +pub const SIG_BLOCK: ::c_int = 1; +pub const SIG_UNBLOCK: ::c_int = 2; +pub const SIG_SETMASK: ::c_int = 3; + +pub const SIGEV_NONE: ::c_int = 0; +pub const SIGEV_SIGNAL: ::c_int = 1; +pub const SIGEV_THREAD: ::c_int = 2; + +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 = 14; + +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 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; + +// FIXME: Haiku does not have MAP_FILE, but library/std/os.rs requires it +pub const MAP_FILE: ::c_int = 0x00; +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; + +pub const MS_ASYNC: ::c_int = 0x01; +pub const MS_INVALIDATE: ::c_int = 0x04; +pub const MS_SYNC: ::c_int = 0x02; + +pub const E2BIG: ::c_int = -2147454975; +pub const ECHILD: ::c_int = -2147454974; +pub const EDEADLK: ::c_int = -2147454973; +pub const EFBIG: ::c_int = -2147454972; +pub const EMLINK: ::c_int = -2147454971; +pub const ENFILE: ::c_int = -2147454970; +pub const ENODEV: ::c_int = -2147454969; +pub const ENOLCK: ::c_int = -2147454968; +pub const ENOSYS: ::c_int = -2147454967; +pub const ENOTTY: ::c_int = -2147454966; +pub const ENXIO: ::c_int = -2147454965; +pub const ESPIPE: ::c_int = -2147454964; +pub const ESRCH: ::c_int = -2147454963; +pub const EFPOS: ::c_int = -2147454962; +pub const ESIGPARM: ::c_int = -2147454961; +pub const EDOM: ::c_int = -2147454960; +pub const ERANGE: ::c_int = -2147454959; +pub const EPROTOTYPE: ::c_int = -2147454958; +pub const EPROTONOSUPPORT: ::c_int = -2147454957; +pub const EPFNOSUPPORT: ::c_int = -2147454956; +pub const EAFNOSUPPORT: ::c_int = -2147454955; +pub const EADDRINUSE: ::c_int = -2147454954; +pub const EADDRNOTAVAIL: ::c_int = -2147454953; +pub const ENETDOWN: ::c_int = -2147454952; +pub const ENETUNREACH: ::c_int = -2147454951; +pub const ENETRESET: ::c_int = -2147454950; +pub const ECONNABORTED: ::c_int = -2147454949; +pub const ECONNRESET: ::c_int = -2147454948; +pub const EISCONN: ::c_int = -2147454947; +pub const ENOTCONN: ::c_int = -2147454946; +pub const ESHUTDOWN: ::c_int = -2147454945; +pub const ECONNREFUSED: ::c_int = -2147454944; +pub const EHOSTUNREACH: ::c_int = -2147454943; +pub const ENOPROTOOPT: ::c_int = -2147454942; +pub const ENOBUFS: ::c_int = -2147454941; +pub const EINPROGRESS: ::c_int = -2147454940; +pub const EALREADY: ::c_int = -2147454939; +pub const EILSEQ: ::c_int = -2147454938; +pub const ENOMSG: ::c_int = -2147454937; +pub const ESTALE: ::c_int = -2147454936; +pub const EOVERFLOW: ::c_int = -2147454935; +pub const EMSGSIZE: ::c_int = -2147454934; +pub const EOPNOTSUPP: ::c_int = -2147454933; +pub const ENOTSOCK: ::c_int = -2147454932; +pub const EHOSTDOWN: ::c_int = -2147454931; +pub const EBADMSG: ::c_int = -2147454930; +pub const ECANCELED: ::c_int = -2147454929; +pub const EDESTADDRREQ: ::c_int = -2147454928; +pub const EDQUOT: ::c_int = -2147454927; +pub const EIDRM: ::c_int = -2147454926; +pub const EMULTIHOP: ::c_int = -2147454925; +pub const ENODATA: ::c_int = -2147454924; +pub const ENOLINK: ::c_int = -2147454923; +pub const ENOSR: ::c_int = -2147454922; +pub const ENOSTR: ::c_int = -2147454921; +pub const ENOTSUP: ::c_int = -2147454920; +pub const EPROTO: ::c_int = -2147454919; +pub const ETIME: ::c_int = -2147454918; +pub const ETXTBSY: ::c_int = -2147454917; +pub const ENOATTR: ::c_int = -2147454916; + +// INT_MIN +pub const ENOMEM: ::c_int = -2147483648; + +// POSIX errors that can be mapped to BeOS error codes +pub const EACCES: ::c_int = -2147483646; +pub const EINTR: ::c_int = -2147483638; +pub const EIO: ::c_int = -2147483647; +pub const EBUSY: ::c_int = -2147483634; +pub const EFAULT: ::c_int = -2147478783; +pub const ETIMEDOUT: ::c_int = -2147483639; +pub const EAGAIN: ::c_int = -2147483637; +pub const EWOULDBLOCK: ::c_int = -2147483637; +pub const EBADF: ::c_int = -2147459072; +pub const EEXIST: ::c_int = -2147459070; +pub const EINVAL: ::c_int = -2147483643; +pub const ENAMETOOLONG: ::c_int = -2147459068; +pub const ENOENT: ::c_int = -2147459069; +pub const EPERM: ::c_int = -2147483633; +pub const ENOTDIR: ::c_int = -2147459067; +pub const EISDIR: ::c_int = -2147459063; +pub const ENOTEMPTY: ::c_int = -2147459066; +pub const ENOSPC: ::c_int = -2147459065; +pub const EROFS: ::c_int = -2147459064; +pub const EMFILE: ::c_int = -2147459062; +pub const EXDEV: ::c_int = -2147459061; +pub const ELOOP: ::c_int = -2147459060; +pub const ENOEXEC: ::c_int = -2147478782; +pub const EPIPE: ::c_int = -2147459059; + +pub const IPPROTO_RAW: ::c_int = 255; + +// These are prefixed with POSIX_ on Haiku +pub const MADV_NORMAL: ::c_int = 1; +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/HEAD/headers/posix/net/if.h#L80 +pub const IFF_UP: ::c_int = 0x0001; +pub const IFF_BROADCAST: ::c_int = 0x0002; // valid broadcast address +pub const IFF_LOOPBACK: ::c_int = 0x0008; +pub const IFF_POINTOPOINT: ::c_int = 0x0010; // point-to-point link +pub const IFF_NOARP: ::c_int = 0x0040; // no address resolution +pub const IFF_AUTOUP: ::c_int = 0x0080; // auto dial +pub const IFF_PROMISC: ::c_int = 0x0100; // receive all packets +pub const IFF_ALLMULTI: ::c_int = 0x0200; // receive all multicast packets +pub const IFF_SIMPLEX: ::c_int = 0x0800; // doesn't receive own transmissions +pub const IFF_LINK: ::c_int = 0x1000; // has link +pub const IFF_AUTO_CONFIGURED: ::c_int = 0x2000; +pub const IFF_CONFIGURING: ::c_int = 0x4000; +pub const IFF_MULTICAST: ::c_int = 0x8000; // supports multicast + +pub const AF_UNSPEC: ::c_int = 0; +pub const AF_INET: ::c_int = 1; +pub const AF_APPLETALK: ::c_int = 2; +pub const AF_ROUTE: ::c_int = 3; +pub const AF_LINK: ::c_int = 4; +pub const AF_INET6: ::c_int = 5; +pub const AF_DLI: ::c_int = 6; +pub const AF_IPX: ::c_int = 7; +pub const AF_NOTIFY: ::c_int = 8; +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; +pub const IP_TTL: ::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_LOOP: ::c_int = 11; +pub const IP_ADD_MEMBERSHIP: ::c_int = 12; +pub const IP_DROP_MEMBERSHIP: ::c_int = 13; +pub const IP_BLOCK_SOURCE: ::c_int = 14; +pub const IP_UNBLOCK_SOURCE: ::c_int = 15; +pub const IP_ADD_SOURCE_MEMBERSHIP: ::c_int = 16; +pub const IP_DROP_SOURCE_MEMBERSHIP: ::c_int = 17; + +pub const TCP_NODELAY: ::c_int = 0x01; +pub const TCP_MAXSEG: ::c_int = 0x02; +pub const TCP_NOPUSH: ::c_int = 0x04; +pub const TCP_NOOPT: ::c_int = 0x08; + +pub const IF_NAMESIZE: ::size_t = 32; +pub const IFNAMSIZ: ::size_t = IF_NAMESIZE; + +pub const IPV6_MULTICAST_IF: ::c_int = 24; +pub const IPV6_MULTICAST_HOPS: ::c_int = 25; +pub const IPV6_MULTICAST_LOOP: ::c_int = 26; +pub const IPV6_UNICAST_HOPS: ::c_int = 27; +pub const IPV6_JOIN_GROUP: ::c_int = 28; +pub const IPV6_LEAVE_GROUP: ::c_int = 29; +pub const IPV6_V6ONLY: ::c_int = 30; +pub const IPV6_PKTINFO: ::c_int = 31; +pub const IPV6_RECVPKTINFO: ::c_int = 32; +pub const IPV6_HOPLIMIT: ::c_int = 33; +pub const IPV6_RECVHOPLIMIT: ::c_int = 34; +pub const IPV6_HOPOPTS: ::c_int = 35; +pub const IPV6_DSTOPTS: ::c_int = 36; +pub const IPV6_RTHDR: ::c_int = 37; + +pub const MSG_OOB: ::c_int = 0x0001; +pub const MSG_PEEK: ::c_int = 0x0002; +pub const MSG_DONTROUTE: ::c_int = 0x0004; +pub const MSG_EOR: ::c_int = 0x0008; +pub const MSG_TRUNC: ::c_int = 0x0010; +pub const MSG_CTRUNC: ::c_int = 0x0020; +pub const MSG_WAITALL: ::c_int = 0x0040; +pub const MSG_DONTWAIT: ::c_int = 0x0080; +pub const MSG_BCAST: ::c_int = 0x0100; +pub const MSG_MCAST: ::c_int = 0x0200; +pub const MSG_EOF: ::c_int = 0x0400; +pub const MSG_NOSIGNAL: ::c_int = 0x0800; + +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 = 0x01; +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; +pub const PATH_MAX: ::c_int = 1024; + +pub const SA_NOCLDSTOP: ::c_int = 0x01; +pub const SA_NOCLDWAIT: ::c_int = 0x02; +pub const SA_RESETHAND: ::c_int = 0x04; +pub const SA_NODEFER: ::c_int = 0x08; +pub const SA_RESTART: ::c_int = 0x10; +pub const SA_ONSTACK: ::c_int = 0x20; +pub const SA_SIGINFO: ::c_int = 0x40; +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; +pub const RTLD_NOW: ::c_int = 0x1; +pub const RTLD_GLOBAL: ::c_int = 0x2; +pub const RTLD_DEFAULT: *mut ::c_void = 0isize as *mut ::c_void; + +pub const BUFSIZ: ::c_uint = 8192; +pub const FILENAME_MAX: ::c_uint = 256; +pub const FOPEN_MAX: ::c_uint = 128; +pub const L_tmpnam: ::c_uint = 512; +pub const TMP_MAX: ::c_uint = 32768; + +pub const _PC_CHOWN_RESTRICTED: ::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_NO_TRUNC: ::c_int = 5; +pub const _PC_PATH_MAX: ::c_int = 6; +pub const _PC_PIPE_BUF: ::c_int = 7; +pub const _PC_VDISABLE: ::c_int = 8; +pub const _PC_LINK_MAX: ::c_int = 25; +pub const _PC_SYNC_IO: ::c_int = 26; +pub const _PC_ASYNC_IO: ::c_int = 27; +pub const _PC_PRIO_IO: ::c_int = 28; +pub const _PC_SOCK_MAXBUF: ::c_int = 29; +pub const _PC_FILESIZEBITS: ::c_int = 30; +pub const _PC_REC_INCR_XFER_SIZE: ::c_int = 31; +pub const _PC_REC_MAX_XFER_SIZE: ::c_int = 32; +pub const _PC_REC_MIN_XFER_SIZE: ::c_int = 33; +pub const _PC_REC_XFER_ALIGN: ::c_int = 34; +pub const _PC_ALLOC_SIZE_MIN: ::c_int = 35; +pub const _PC_SYMLINK_MAX: ::c_int = 36; +pub const _PC_2_SYMLINKS: ::c_int = 37; +pub const _PC_XATTR_EXISTS: ::c_int = 38; +pub const _PC_XATTR_ENABLED: ::c_int = 39; + +pub const FIONBIO: ::c_ulong = 0xbe000000; +pub const FIONREAD: ::c_ulong = 0xbe000001; +pub const FIOSEEKDATA: ::c_ulong = 0xbe000002; +pub const FIOSEEKHOLE: ::c_ulong = 0xbe000003; + +pub const _SC_ARG_MAX: ::c_int = 15; +pub const _SC_CHILD_MAX: ::c_int = 16; +pub const _SC_CLK_TCK: ::c_int = 17; +pub const _SC_JOB_CONTROL: ::c_int = 18; +pub const _SC_NGROUPS_MAX: ::c_int = 19; +pub const _SC_OPEN_MAX: ::c_int = 20; +pub const _SC_SAVED_IDS: ::c_int = 21; +pub const _SC_STREAM_MAX: ::c_int = 22; +pub const _SC_TZNAME_MAX: ::c_int = 23; +pub const _SC_VERSION: ::c_int = 24; +pub const _SC_GETGR_R_SIZE_MAX: ::c_int = 25; +pub const _SC_GETPW_R_SIZE_MAX: ::c_int = 26; +pub const _SC_PAGESIZE: ::c_int = 27; +pub const _SC_PAGE_SIZE: ::c_int = 27; +pub const _SC_SEM_NSEMS_MAX: ::c_int = 28; +pub const _SC_SEM_VALUE_MAX: ::c_int = 29; +pub const _SC_SEMAPHORES: ::c_int = 30; +pub const _SC_THREADS: ::c_int = 31; +pub const _SC_IOV_MAX: ::c_int = 32; +pub const _SC_UIO_MAXIOV: ::c_int = 32; +pub const _SC_NPROCESSORS_CONF: ::c_int = 34; +pub const _SC_NPROCESSORS_ONLN: ::c_int = 35; +pub const _SC_ATEXIT_MAX: ::c_int = 37; +pub const _SC_PASS_MAX: ::c_int = 39; +pub const _SC_PHYS_PAGES: ::c_int = 40; +pub const _SC_AVPHYS_PAGES: ::c_int = 41; +pub const _SC_PIPE: ::c_int = 42; +pub const _SC_SELECT: ::c_int = 43; +pub const _SC_POLL: ::c_int = 44; +pub const _SC_MAPPED_FILES: ::c_int = 45; +pub const _SC_THREAD_PROCESS_SHARED: ::c_int = 46; +pub const _SC_THREAD_STACK_MIN: ::c_int = 47; +pub const _SC_THREAD_ATTR_STACKADDR: ::c_int = 48; +pub const _SC_THREAD_ATTR_STACKSIZE: ::c_int = 49; +pub const _SC_THREAD_PRIORITY_SCHEDULING: ::c_int = 50; +pub const _SC_REALTIME_SIGNALS: ::c_int = 51; +pub const _SC_MEMORY_PROTECTION: ::c_int = 52; +pub const _SC_SIGQUEUE_MAX: ::c_int = 53; +pub const _SC_RTSIG_MAX: ::c_int = 54; +pub const _SC_MONOTONIC_CLOCK: ::c_int = 55; +pub const _SC_DELAYTIMER_MAX: ::c_int = 56; +pub const _SC_TIMER_MAX: ::c_int = 57; +pub const _SC_TIMERS: ::c_int = 58; +pub const _SC_CPUTIME: ::c_int = 59; +pub const _SC_THREAD_CPUTIME: ::c_int = 60; +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 _SC_ADVISORY_INFO: ::c_int = 66; +pub const _SC_BARRIERS: ::c_int = 67; +pub const _SC_CLOCK_SELECTION: ::c_int = 68; +pub const _SC_FSYNC: ::c_int = 69; +pub const _SC_IPV6: ::c_int = 70; +pub const _SC_MEMLOCK: ::c_int = 71; +pub const _SC_MEMLOCK_RANGE: ::c_int = 72; +pub const _SC_MESSAGE_PASSING: ::c_int = 73; +pub const _SC_PRIORITIZED_IO: ::c_int = 74; +pub const _SC_PRIORITY_SCHEDULING: ::c_int = 75; +pub const _SC_READER_WRITER_LOCKS: ::c_int = 76; +pub const _SC_SHARED_MEMORY_OBJECTS: ::c_int = 77; +pub const _SC_SPAWN: ::c_int = 78; +pub const _SC_SPIN_LOCKS: ::c_int = 79; +pub const _SC_SPORADIC_SERVER: ::c_int = 80; +pub const _SC_SYNCHRONIZED_IO: ::c_int = 81; +pub const _SC_THREAD_PRIO_INHERIT: ::c_int = 82; +pub const _SC_THREAD_PRIO_PROTECT: ::c_int = 83; +pub const _SC_THREAD_ROBUST_PRIO_INHERIT: ::c_int = 84; +pub const _SC_THREAD_ROBUST_PRIO_PROTECT: ::c_int = 85; +pub const _SC_THREAD_SAFE_FUNCTIONS: ::c_int = 86; +pub const _SC_THREAD_SPORADIC_SERVER: ::c_int = 87; +pub const _SC_TIMEOUTS: ::c_int = 88; +pub const _SC_TRACE: ::c_int = 89; +pub const _SC_TRACE_EVENT_FILTER: ::c_int = 90; +pub const _SC_TRACE_INHERIT: ::c_int = 91; +pub const _SC_TRACE_LOG: ::c_int = 92; +pub const _SC_TYPED_MEMORY_OBJECTS: ::c_int = 93; +pub const _SC_V6_ILP32_OFF32: ::c_int = 94; +pub const _SC_V6_ILP32_OFFBIG: ::c_int = 95; +pub const _SC_V6_LP64_OFF64: ::c_int = 96; +pub const _SC_V6_LPBIG_OFFBIG: ::c_int = 97; +pub const _SC_V7_ILP32_OFF32: ::c_int = 98; +pub const _SC_V7_ILP32_OFFBIG: ::c_int = 99; +pub const _SC_V7_LP64_OFF64: ::c_int = 100; +pub const _SC_V7_LPBIG_OFFBIG: ::c_int = 101; +pub const _SC_2_C_BIND: ::c_int = 102; +pub const _SC_2_C_DEV: ::c_int = 103; +pub const _SC_2_CHAR_TERM: ::c_int = 104; +pub const _SC_2_FORT_DEV: ::c_int = 105; +pub const _SC_2_FORT_RUN: ::c_int = 106; +pub const _SC_2_LOCALEDEF: ::c_int = 107; +pub const _SC_2_PBS: ::c_int = 108; +pub const _SC_2_PBS_ACCOUNTING: ::c_int = 109; +pub const _SC_2_PBS_CHECKPOINT: ::c_int = 110; +pub const _SC_2_PBS_LOCATE: ::c_int = 111; +pub const _SC_2_PBS_MESSAGE: ::c_int = 112; +pub const _SC_2_PBS_TRACK: ::c_int = 113; +pub const _SC_2_SW_DEV: ::c_int = 114; +pub const _SC_2_UPE: ::c_int = 115; +pub const _SC_2_VERSION: ::c_int = 116; +pub const _SC_XOPEN_CRYPT: ::c_int = 117; +pub const _SC_XOPEN_ENH_I18N: ::c_int = 118; +pub const _SC_XOPEN_REALTIME: ::c_int = 119; +pub const _SC_XOPEN_REALTIME_THREADS: ::c_int = 120; +pub const _SC_XOPEN_SHM: ::c_int = 121; +pub const _SC_XOPEN_STREAMS: ::c_int = 122; +pub const _SC_XOPEN_UNIX: ::c_int = 123; +pub const _SC_XOPEN_UUCP: ::c_int = 124; +pub const _SC_XOPEN_VERSION: ::c_int = 125; +pub const _SC_BC_BASE_MAX: ::c_int = 129; +pub const _SC_BC_DIM_MAX: ::c_int = 130; +pub const _SC_BC_SCALE_MAX: ::c_int = 131; +pub const _SC_BC_STRING_MAX: ::c_int = 132; +pub const _SC_COLL_WEIGHTS_MAX: ::c_int = 133; +pub const _SC_EXPR_NEST_MAX: ::c_int = 134; +pub const _SC_LINE_MAX: ::c_int = 135; +pub const _SC_LOGIN_NAME_MAX: ::c_int = 136; +pub const _SC_MQ_OPEN_MAX: ::c_int = 137; +pub const _SC_MQ_PRIO_MAX: ::c_int = 138; +pub const _SC_THREAD_DESTRUCTOR_ITERATIONS: ::c_int = 139; +pub const _SC_THREAD_KEYS_MAX: ::c_int = 140; +pub const _SC_THREAD_THREADS_MAX: ::c_int = 141; +pub const _SC_RE_DUP_MAX: ::c_int = 142; + +pub const PTHREAD_STACK_MIN: ::size_t = 8192; + +pub const PTHREAD_MUTEX_INITIALIZER: pthread_mutex_t = pthread_mutex_t { + flags: 0, + lock: 0, + unused: -42, + owner: -1, + owner_count: 0, +}; +pub const PTHREAD_COND_INITIALIZER: pthread_cond_t = pthread_cond_t { + flags: 0, + unused: -42, + mutex: 0 as *mut _, + waiter_count: 0, + lock: 0, +}; +pub const PTHREAD_RWLOCK_INITIALIZER: pthread_rwlock_t = pthread_rwlock_t { + flags: 0, + owner: -1, + lock_sem: 0, + lock_count: 0, + reader_count: 0, + writer_count: 0, + waiters: [0 as *mut _; 2], +}; + +pub const PTHREAD_MUTEX_DEFAULT: ::c_int = 0; +pub const PTHREAD_MUTEX_NORMAL: ::c_int = 1; +pub const PTHREAD_MUTEX_ERRORCHECK: ::c_int = 2; +pub const PTHREAD_MUTEX_RECURSIVE: ::c_int = 3; + +pub const FIOCLEX: c_ulong = 0; // FIXME: does not exist on Haiku! + +pub const RUSAGE_CHILDREN: ::c_int = -1; + +pub const SOCK_STREAM: ::c_int = 1; +pub const SOCK_DGRAM: ::c_int = 2; +pub const SOCK_RAW: ::c_int = 3; +pub const SOCK_SEQPACKET: ::c_int = 5; + +pub const SOL_SOCKET: ::c_int = -1; +pub const SO_ACCEPTCONN: ::c_int = 0x00000001; +pub const SO_BROADCAST: ::c_int = 0x00000002; +pub const SO_DEBUG: ::c_int = 0x00000004; +pub const SO_DONTROUTE: ::c_int = 0x00000008; +pub const SO_KEEPALIVE: ::c_int = 0x00000010; +pub const SO_OOBINLINE: ::c_int = 0x00000020; +pub const SO_REUSEADDR: ::c_int = 0x00000040; +pub const SO_REUSEPORT: ::c_int = 0x00000080; +pub const SO_USELOOPBACK: ::c_int = 0x00000100; +pub const SO_LINGER: ::c_int = 0x00000200; +pub const SO_SNDBUF: ::c_int = 0x40000001; +pub const SO_SNDLOWAT: ::c_int = 0x40000002; +pub const SO_SNDTIMEO: ::c_int = 0x40000003; +pub const SO_RCVBUF: ::c_int = 0x40000004; +pub const SO_RCVLOWAT: ::c_int = 0x40000005; +pub const SO_RCVTIMEO: ::c_int = 0x40000006; +pub const SO_ERROR: ::c_int = 0x40000007; +pub const SO_TYPE: ::c_int = 0x40000008; +pub const SO_NONBLOCK: ::c_int = 0x40000009; +pub const SO_BINDTODEVICE: ::c_int = 0x4000000a; +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; +pub const WUNTRACED: ::c_int = 0x02; +pub const WCONTINUED: ::c_int = 0x04; +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; +pub const CLD_TRAPPED: ::c_int = 63; +pub const CLD_STOPPED: ::c_int = 64; +pub const CLD_CONTINUED: ::c_int = 65; + +pub const P_ALL: idtype_t = 0; +pub const P_PID: idtype_t = 1; +pub const P_PGID: idtype_t = 2; + +pub const UTIME_OMIT: c_long = 1000000001; +pub const UTIME_NOW: c_long = 1000000000; + +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 VMIN: usize = 4; +pub const VTIME: usize = 5; +pub const VEOL2: usize = 6; +pub const VSWTCH: usize = 7; +pub const VSTART: usize = 8; +pub const VSTOP: usize = 9; +pub const VSUSP: usize = 10; + +pub const IGNBRK: ::tcflag_t = 0x01; +pub const BRKINT: ::tcflag_t = 0x02; +pub const IGNPAR: ::tcflag_t = 0x04; +pub const PARMRK: ::tcflag_t = 0x08; +pub const INPCK: ::tcflag_t = 0x10; +pub const ISTRIP: ::tcflag_t = 0x20; +pub const INLCR: ::tcflag_t = 0x40; +pub const IGNCR: ::tcflag_t = 0x80; +pub const ICRNL: ::tcflag_t = 0x100; +pub const IUCLC: ::tcflag_t = 0x200; +pub const IXON: ::tcflag_t = 0x400; +pub const IXANY: ::tcflag_t = 0x800; +pub const IXOFF: ::tcflag_t = 0x1000; + +pub const OPOST: ::tcflag_t = 0x00000001; +pub const OLCUC: ::tcflag_t = 0x00000002; +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 OFILL: ::tcflag_t = 0x00000040; +pub const OFDEL: ::tcflag_t = 0x00000080; +pub const NLDLY: ::tcflag_t = 0x00000100; +pub const NL0: ::tcflag_t = 0x00000000; +pub const NL1: ::tcflag_t = 0x00000100; +pub const CRDLY: ::tcflag_t = 0x00000600; +pub const CR0: ::tcflag_t = 0x00000000; +pub const CR1: ::tcflag_t = 0x00000200; +pub const CR2: ::tcflag_t = 0x00000400; +pub const CR3: ::tcflag_t = 0x00000600; +pub const TABDLY: ::tcflag_t = 0x00001800; +pub const TAB0: ::tcflag_t = 0x00000000; +pub const TAB1: ::tcflag_t = 0x00000800; +pub const TAB2: ::tcflag_t = 0x00001000; +pub const TAB3: ::tcflag_t = 0x00001800; +pub const BSDLY: ::tcflag_t = 0x00002000; +pub const BS0: ::tcflag_t = 0x00000000; +pub const BS1: ::tcflag_t = 0x00002000; +pub const VTDLY: ::tcflag_t = 0x00004000; +pub const VT0: ::tcflag_t = 0x00000000; +pub const VT1: ::tcflag_t = 0x00004000; +pub const FFDLY: ::tcflag_t = 0x00008000; +pub const FF0: ::tcflag_t = 0x00000000; +pub const FF1: ::tcflag_t = 0x00008000; + +pub const CSIZE: ::tcflag_t = 0x00000020; +pub const CS5: ::tcflag_t = 0x00000000; +pub const CS6: ::tcflag_t = 0x00000000; +pub const CS7: ::tcflag_t = 0x00000000; +pub const CS8: ::tcflag_t = 0x00000020; +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 XLOBLK: ::tcflag_t = 0x00001000; +pub const CTSFLOW: ::tcflag_t = 0x00002000; +pub const RTSFLOW: ::tcflag_t = 0x00004000; +pub const CRTSCTS: ::tcflag_t = RTSFLOW | CTSFLOW; + +pub const ISIG: ::tcflag_t = 0x00000001; +pub const ICANON: ::tcflag_t = 0x00000002; +pub const XCASE: ::tcflag_t = 0x00000004; +pub const ECHO: ::tcflag_t = 0x00000008; +pub const ECHOE: ::tcflag_t = 0x00000010; +pub const ECHOK: ::tcflag_t = 0x00000020; +pub const ECHONL: ::tcflag_t = 0x00000040; +pub const NOFLSH: ::tcflag_t = 0x00000080; +pub const TOSTOP: ::tcflag_t = 0x00000100; +pub const IEXTEN: ::tcflag_t = 0x00000200; +pub const ECHOCTL: ::tcflag_t = 0x00000400; +pub const ECHOPRT: ::tcflag_t = 0x00000800; +pub const ECHOKE: ::tcflag_t = 0x00001000; +pub const FLUSHO: ::tcflag_t = 0x00002000; +pub const PENDIN: ::tcflag_t = 0x00004000; + +pub const TCGB_CTS: ::c_int = 0x01; +pub const TCGB_DSR: ::c_int = 0x02; +pub const TCGB_RI: ::c_int = 0x04; +pub const TCGB_DCD: ::c_int = 0x08; +pub const TIOCM_CTS: ::c_int = TCGB_CTS; +pub const TIOCM_CD: ::c_int = TCGB_DCD; +pub const TIOCM_CAR: ::c_int = TCGB_DCD; +pub const TIOCM_RI: ::c_int = TCGB_RI; +pub const TIOCM_RNG: ::c_int = TCGB_RI; +pub const TIOCM_DSR: ::c_int = TCGB_DSR; +pub const TIOCM_DTR: ::c_int = 0x10; +pub const TIOCM_RTS: ::c_int = 0x20; + +pub const B0: speed_t = 0x00; +pub const B50: speed_t = 0x01; +pub const B75: speed_t = 0x02; +pub const B110: speed_t = 0x03; +pub const B134: speed_t = 0x04; +pub const B150: speed_t = 0x05; +pub const B200: speed_t = 0x06; +pub const B300: speed_t = 0x07; +pub const B600: speed_t = 0x08; +pub const B1200: speed_t = 0x09; +pub const B1800: speed_t = 0x0A; +pub const B2400: speed_t = 0x0B; +pub const B4800: speed_t = 0x0C; +pub const B9600: speed_t = 0x0D; +pub const B19200: speed_t = 0x0E; +pub const B38400: speed_t = 0x0F; +pub const B57600: speed_t = 0x10; +pub const B115200: speed_t = 0x11; +pub const B230400: speed_t = 0x12; +pub const B31250: speed_t = 0x13; + +pub const TCSANOW: ::c_int = 0x01; +pub const TCSADRAIN: ::c_int = 0x02; +pub const TCSAFLUSH: ::c_int = 0x04; + +pub const TCOOFF: ::c_int = 0x01; +pub const TCOON: ::c_int = 0x02; +pub const TCIOFF: ::c_int = 0x04; +pub const TCION: ::c_int = 0x08; + +pub const TCIFLUSH: ::c_int = 0x01; +pub const TCOFLUSH: ::c_int = 0x02; +pub const TCIOFLUSH: ::c_int = 0x03; + +pub const TCGETA: ::c_ulong = 0x8000; +pub const TCSETA: ::c_ulong = TCGETA + 1; +pub const TCSETAF: ::c_ulong = TCGETA + 2; +pub const TCSETAW: ::c_ulong = TCGETA + 3; +pub const TCSBRK: ::c_ulong = TCGETA + 5; +pub const TCFLSH: ::c_ulong = TCGETA + 6; +pub const TCXONC: ::c_ulong = TCGETA + 7; +pub const TCGETBITS: ::c_ulong = TCGETA + 9; +pub const TCSETDTR: ::c_ulong = TCGETA + 10; +pub const TCSETRTS: ::c_ulong = TCGETA + 11; +pub const TIOCGWINSZ: ::c_ulong = TCGETA + 12; +pub const TIOCSWINSZ: ::c_ulong = TCGETA + 13; +pub const TIOCGPGRP: ::c_ulong = TCGETA + 15; +pub const TIOCSPGRP: ::c_ulong = TCGETA + 16; +pub const TIOCSCTTY: ::c_ulong = TCGETA + 17; +pub const TIOCMGET: ::c_ulong = TCGETA + 18; +pub const TIOCMSET: ::c_ulong = TCGETA + 19; +pub const TIOCSBRK: ::c_ulong = TCGETA + 20; +pub const TIOCCBRK: ::c_ulong = TCGETA + 21; +pub const TIOCMBIS: ::c_ulong = TCGETA + 22; +pub const TIOCMBIC: ::c_ulong = TCGETA + 23; +pub const TIOCGSID: ::c_ulong = TCGETA + 24; +pub const TIOCOUTQ: ::c_ulong = TCGETA + 25; +pub const TIOCEXCL: ::c_ulong = TCGETA + 26; +pub const TIOCNXCL: ::c_ulong = TCGETA + 27; + +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; +pub const LOG_NDELAY: ::c_int = 8 << 12; +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) + } +} + +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_DATA(cmsg: *const ::cmsghdr) -> *mut ::c_uchar { + (cmsg as *mut ::c_uchar) + .offset(CMSG_ALIGN(::mem::size_of::<::cmsghdr>()) as isize) + } + + pub {const} fn CMSG_SPACE(length: ::c_uint) -> ::c_uint { + (CMSG_ALIGN(length as usize) + CMSG_ALIGN(::mem::size_of::())) + as ::c_uint + } + + pub {const} fn CMSG_LEN(length: ::c_uint) -> ::c_uint { + CMSG_ALIGN(::mem::size_of::()) as ::c_uint + length + } + + pub fn CMSG_NXTHDR(mhdr: *const msghdr, + cmsg: *const cmsghdr) -> *mut cmsghdr { + if cmsg.is_null() { + return ::CMSG_FIRSTHDR(mhdr); + }; + let next = cmsg as usize + CMSG_ALIGN((*cmsg).cmsg_len as usize) + + CMSG_ALIGN(::mem::size_of::<::cmsghdr>()); + let max = (*mhdr).msg_control as usize + + (*mhdr).msg_controllen as usize; + if next > max { + 0 as *mut ::cmsghdr + } else { + (cmsg as usize + CMSG_ALIGN((*cmsg).cmsg_len as usize)) + as *mut ::cmsghdr + } + } + + 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; + } + } +} + +safe_f! { + pub {const} fn WIFEXITED(status: ::c_int) -> bool { + (status & !0xff) == 0 + } + + pub {const} fn WEXITSTATUS(status: ::c_int) -> ::c_int { + status & 0xff + } + + pub {const} fn WIFSIGNALED(status: ::c_int) -> bool { + ((status >> 8) & 0xff) != 0 + } + + pub {const} fn WTERMSIG(status: ::c_int) -> ::c_int { + (status >> 8) & 0xff + } + + pub {const} fn WIFSTOPPED(status: ::c_int) -> bool { + ((status >> 16) & 0xff) != 0 + } + + pub {const} fn WSTOPSIG(status: ::c_int) -> ::c_int { + (status >> 16) & 0xff + } + + // actually WIFCORED, but this is used everywhere else + pub {const} fn WCOREDUMP(status: ::c_int) -> bool { + (status & 0x10000) != 0 + } + + pub {const} fn WIFCONTINUED(status: ::c_int) -> bool { + (status & 0x20000) != 0 + } +} + +extern "C" { + pub fn getrlimit(resource: ::c_int, rlim: *mut ::rlimit) -> ::c_int; + pub fn setrlimit(resource: ::c_int, rlim: *const ::rlimit) -> ::c_int; + 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, + times: *const ::timespec, + flag: ::c_int, + ) -> ::c_int; + pub fn futimens(fd: ::c_int, times: *const ::timespec) -> ::c_int; + pub fn strerror_r(errnum: ::c_int, buf: *mut c_char, buflen: ::size_t) -> ::c_int; + pub fn _errnop() -> *mut ::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 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; + + 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_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, + f: extern "C" fn(*mut ::c_void) -> *mut ::c_void, + value: *mut ::c_void, + ) -> ::c_int; + pub fn pthread_attr_getguardsize( + attr: *const ::pthread_attr_t, + guardsize: *mut ::size_t, + ) -> ::c_int; + pub fn pthread_attr_setguardsize(attr: *mut ::pthread_attr_t, guardsize: ::size_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 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 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; + pub fn getnameinfo( + sa: *const ::sockaddr, + salen: ::socklen_t, + host: *mut ::c_char, + hostlen: ::socklen_t, + serv: *mut ::c_char, + servlen: ::socklen_t, + flags: ::c_int, + ) -> ::c_int; + pub fn pthread_mutex_timedlock( + lock: *mut pthread_mutex_t, + abstime: *const ::timespec, + ) -> ::c_int; + pub fn pthread_sigqueue(thread: ::pthread_t, sig: ::c_int, value: ::sigval) -> ::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; + + 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 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; + + pub fn seekdir(dirp: *mut ::DIR, loc: ::c_long); + + pub fn telldir(dirp: *mut ::DIR) -> ::c_long; + 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 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 nl_langinfo(item: ::nl_item) -> *mut ::c_char; + + pub fn bind(socket: ::c_int, address: *const ::sockaddr, address_len: ::socklen_t) -> ::c_int; + + pub fn writev(fd: ::c_int, iov: *const ::iovec, count: ::c_int) -> ::ssize_t; + pub fn readv(fd: ::c_int, iov: *const ::iovec, count: ::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 execvpe( + file: *const ::c_char, + argv: *const *const ::c_char, + environment: *const *const ::c_char, + ) -> ::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 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 sigsuspend(mask: *const ::sigset_t) -> ::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 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 sem_unlink(name: *const ::c_char) -> ::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 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, + parent: ::Option, + child: ::Option, + ) -> ::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 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, + name: *mut ::c_char, + termp: *mut termios, + winp: *mut ::winsize, + ) -> ::pid_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 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; + + pub fn arc4random() -> u32; + pub fn arc4random_uniform(upper_bound: u32) -> u32; + pub fn arc4random_buf(buf: *mut ::c_void, n: ::size_t); +} + +#[link(name = "gnu")] +extern "C" { + pub fn memmem( + source: *const ::c_void, + sourceLength: ::size_t, + search: *const ::c_void, + searchLength: ::size_t, + ) -> *mut ::c_void; + + pub fn pthread_getattr_np(thread: ::pthread_t, attr: *mut ::pthread_attr_t) -> ::c_int; + pub fn pthread_getname_np( + thread: ::pthread_t, + buffer: *mut ::c_char, + length: ::size_t, + ) -> ::c_int; + pub fn pthread_setname_np(thread: ::pthread_t, name: *const ::c_char) -> ::c_int; +} + +cfg_if! { + if #[cfg(target_pointer_width = "64")] { + mod b64; + pub use self::b64::*; + } else { + mod b32; + pub use self::b32::*; + } +} + +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 new file mode 100644 index 0000000..85865ad --- /dev/null +++ b/vendor/libc/src/unix/haiku/native.rs @@ -0,0 +1,1489 @@ +// This module contains bindings to the native Haiku API. The Haiku API +// originates from BeOS, and it was the original way to perform low level +// system and IO operations. The POSIX API was in that era was like a +// compatibility layer. In current Haiku development, both the POSIX API and +// the Haiku API are considered to be co-equal status. However, they are not +// integrated like they are on other UNIX platforms, which means that for many +// low level concepts there are two versions, like processes (POSIX) and +// teams (Haiku), or pthreads and native threads. +// +// Both the POSIX API and the Haiku API live in libroot.so, the library that is +// linked to any binary by default. +// +// This file follows the Haiku API for Haiku R1 beta 2. It is organized by the +// C/C++ header files in which the concepts can be found, while adhering to the +// style guide for this crate. + +// Helper macro to generate u32 constants. The Haiku API uses (non-standard) +// multi-character constants (like 'UPDA' or 'MSGM') to represent 32 bit +// integer constants. + +macro_rules! haiku_constant { + ($a:tt, $b:tt, $c:tt, $d:tt) => { + (($a as u32) << 24) + (($b as u32) << 16) + (($c as u32) << 8) + ($d as u32) + }; +} + +// support/SupportDefs.h +pub type status_t = i32; +pub type bigtime_t = i64; +pub type nanotime_t = i64; +pub type type_code = u32; +pub type perform_code = u32; + +// kernel/OS.h +pub type area_id = i32; +pub type port_id = i32; +pub type sem_id = i32; +pub type team_id = i32; +pub type thread_id = i32; + +pub type thread_func = extern "C" fn(*mut ::c_void) -> status_t; + +// kernel/image.h +pub type image_id = i32; + +e! { + // kernel/OS.h + pub enum thread_state { + B_THREAD_RUNNING = 1, + B_THREAD_READY, + B_THREAD_RECEIVING, + B_THREAD_ASLEEP, + B_THREAD_SUSPENDED, + B_THREAD_WAITING + } + + // kernel/image.h + pub enum image_type { + B_APP_IMAGE = 1, + B_LIBRARY_IMAGE, + B_ADD_ON_IMAGE, + B_SYSTEM_IMAGE + } + + // 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, + } + + // kernel/OS.h + + pub enum topology_level_type { + B_TOPOLOGY_UNKNOWN, + B_TOPOLOGY_ROOT, + B_TOPOLOGY_SMT, + B_TOPOLOGY_CORE, + B_TOPOLOGY_PACKAGE, + } + + pub enum cpu_platform { + B_CPU_UNKNOWN, + B_CPU_x86, + B_CPU_x86_64, + B_CPU_PPC, + B_CPU_PPC_64, + B_CPU_M68K, + B_CPU_ARM, + B_CPU_ARM_64, + B_CPU_ALPHA, + B_CPU_MIPS, + B_CPU_SH, + B_CPU_SPARC, + B_CPU_RISC_V + } + + pub enum cpu_vendor { + B_CPU_VENDOR_UNKNOWN, + B_CPU_VENDOR_AMD, + B_CPU_VENDOR_CYRIX, + B_CPU_VENDOR_IDT, + B_CPU_VENDOR_INTEL, + B_CPU_VENDOR_NATIONAL_SEMICONDUCTOR, + B_CPU_VENDOR_RISE, + B_CPU_VENDOR_TRANSMETA, + B_CPU_VENDOR_VIA, + B_CPU_VENDOR_IBM, + B_CPU_VENDOR_MOTOROLA, + B_CPU_VENDOR_NEC, + B_CPU_VENDOR_HYGON, + B_CPU_VENDOR_SUN, + B_CPU_VENDOR_FUJITSU + } +} + +s! { + // kernel/OS.h + pub struct area_info { + pub area: area_id, + pub name: [::c_char; B_OS_NAME_LENGTH], + pub size: usize, + pub lock: u32, + pub protection: u32, + pub team: team_id, + pub ram_size: u32, + pub copy_count: u32, + pub in_count: u32, + pub out_count: u32, + pub address: *mut ::c_void + } + + pub struct port_info { + pub port: port_id, + pub team: team_id, + pub name: [::c_char; B_OS_NAME_LENGTH], + pub capacity: i32, + pub queue_count: i32, + pub total_count: i32, + } + + pub struct port_message_info { + pub size: ::size_t, + pub sender: ::uid_t, + pub sender_group: ::gid_t, + pub sender_team: ::team_id + } + + pub struct team_info { + pub team: team_id, + pub thread_count: i32, + pub image_count: i32, + pub area_count: i32, + pub debugger_nub_thread: thread_id, + pub debugger_nub_port: port_id, + pub argc: i32, + pub args: [::c_char; 64], + pub uid: ::uid_t, + pub gid: ::gid_t + } + + pub struct sem_info { + pub sem: sem_id, + pub team: team_id, + pub name: [::c_char; B_OS_NAME_LENGTH], + pub count: i32, + pub latest_holder: thread_id + } + + pub struct team_usage_info { + pub user_time: bigtime_t, + pub kernel_time: bigtime_t + } + + pub struct thread_info { + pub thread: thread_id, + pub team: team_id, + pub name: [::c_char; B_OS_NAME_LENGTH], + pub state: thread_state, + pub priority: i32, + pub sem: sem_id, + pub user_time: bigtime_t, + pub kernel_time: bigtime_t, + pub stack_base: *mut ::c_void, + pub stack_end: *mut ::c_void + } + + pub struct cpu_info { + pub active_time: bigtime_t, + pub enabled: bool, + pub current_frequency: u64 + } + + pub struct system_info { + pub boot_time: bigtime_t, + pub cpu_count: u32, + pub max_pages: u64, + pub used_pages: u64, + pub cached_pages: u64, + pub block_cache_pages: u64, + pub ignored_pages: u64, + pub needed_memory: u64, + pub free_memory: u64, + pub max_swap_pages: u64, + pub free_swap_pages: u64, + pub page_faults: u32, + pub max_sems: u32, + pub used_sems: u32, + pub max_ports: u32, + pub used_ports: u32, + pub max_threads: u32, + pub used_threads: u32, + pub max_teams: u32, + pub used_teams: u32, + pub kernel_name: [::c_char; B_FILE_NAME_LENGTH], + pub kernel_build_date: [::c_char; B_OS_NAME_LENGTH], + pub kernel_build_time: [::c_char; B_OS_NAME_LENGTH], + pub kernel_version: i64, + pub abi: u32 + } + + pub struct object_wait_info { + pub object: i32, + pub type_: u16, + pub events: u16 + } + + pub struct cpu_topology_root_info { + pub platform: cpu_platform, + } + + pub struct cpu_topology_package_info { + pub vendor: cpu_vendor, + pub cache_line_size: u32, + } + + pub struct cpu_topology_core_info { + pub model: u32, + pub default_frequency: u64, + } + // kernel/fs_attr.h + pub struct attr_info { + pub type_: u32, + pub size: ::off_t + } + + // kernel/fs_index.h + pub struct index_info { + pub type_: u32, + pub size: ::off_t, + pub modification_time: ::time_t, + pub creation_time: ::time_t, + pub uid: ::uid_t, + pub gid: ::gid_t + } + + //kernel/fs_info.h + pub struct fs_info { + pub dev: ::dev_t, + pub root: ::ino_t, + pub flags: u32, + pub block_size: ::off_t, + pub io_size: ::off_t, + pub total_blocks: ::off_t, + pub free_blocks: ::off_t, + pub total_nodes: ::off_t, + pub free_nodes: ::off_t, + pub device_name: [::c_char; 128], + pub volume_name: [::c_char; B_FILE_NAME_LENGTH], + pub fsh_name: [::c_char; B_OS_NAME_LENGTH] + } + + // kernel/image.h + pub struct image_info { + pub id: image_id, + pub image_type: ::c_int, + pub sequence: i32, + pub init_order: i32, + pub init_routine: extern "C" fn(), + pub term_routine: extern "C" fn(), + pub device: ::dev_t, + pub node: ::ino_t, + pub name: [::c_char; ::PATH_MAX as usize], + pub text: *mut ::c_void, + pub data: *mut ::c_void, + pub text_size: i32, + pub data_size: i32, + 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(libc_union)] + pub union __c_anonymous_cpu_topology_info_data { + pub root: cpu_topology_root_info, + pub package: cpu_topology_package_info, + pub core: cpu_topology_core_info, + } + + pub struct cpu_topology_node_info { + pub id: u32, + pub type_: topology_level_type, + pub level: u32, + #[cfg(libc_union)] + pub data: __c_anonymous_cpu_topology_info_data, + #[cfg(not(libc_union))] + pub data: cpu_topology_core_info, + } +} + +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() + } + } + } + + #[cfg(libc_union)] + impl PartialEq for __c_anonymous_cpu_topology_info_data { + fn eq(&self, other: &__c_anonymous_cpu_topology_info_data) -> bool { + unsafe { + self.root == other.root + || self.package == other.package + || self.core == other.core + } + } + } + #[cfg(libc_union)] + impl Eq for __c_anonymous_cpu_topology_info_data {} + #[cfg(libc_union)] + impl ::fmt::Debug for __c_anonymous_cpu_topology_info_data { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + unsafe { + f.debug_struct("__c_anonymous_cpu_topology_info_data") + .field("root", &self.root) + .field("package", &self.package) + .field("core", &self.core) + .finish() + } + } + } + + impl PartialEq for cpu_topology_node_info { + fn eq(&self, other: &cpu_topology_node_info) -> bool { + self.id == other.id + && self.type_ == other.type_ + && self.level == other.level + } + } + + impl Eq for cpu_topology_node_info {} + impl ::fmt::Debug for cpu_topology_node_info { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("cpu_topology_node_info") + .field("id", &self.id) + .field("type", &self.type_) + .field("level", &self.level) + .finish() + } + } + } +} + +// kernel/OS.h +pub const B_OS_NAME_LENGTH: usize = 32; +pub const B_PAGE_SIZE: usize = 4096; +pub const B_INFINITE_TIMEOUT: usize = 9223372036854775807; + +pub const B_RELATIVE_TIMEOUT: u32 = 0x8; +pub const B_ABSOLUTE_TIMEOUT: u32 = 0x10; +pub const B_TIMEOUT_REAL_TIME_BASE: u32 = 0x40; +pub const B_ABSOLUTE_REAL_TIME_TIMEOUT: u32 = B_ABSOLUTE_TIMEOUT | B_TIMEOUT_REAL_TIME_BASE; + +pub const B_NO_LOCK: u32 = 0; +pub const B_LAZY_LOCK: u32 = 1; +pub const B_FULL_LOCK: u32 = 2; +pub const B_CONTIGUOUS: u32 = 3; +pub const B_LOMEM: u32 = 4; +pub const B_32_BIT_FULL_LOCK: u32 = 5; +pub const B_32_BIT_CONTIGUOUS: u32 = 6; + +pub const B_ANY_ADDRESS: u32 = 0; +pub const B_EXACT_ADDRESS: u32 = 1; +pub const B_BASE_ADDRESS: u32 = 2; +pub const B_CLONE_ADDRESS: u32 = 3; +pub const B_ANY_KERNEL_ADDRESS: u32 = 4; +pub const B_RANDOMIZED_ANY_ADDRESS: u32 = 6; +pub const B_RANDOMIZED_BASE_ADDRESS: u32 = 7; + +pub const B_READ_AREA: u32 = 1 << 0; +pub const B_WRITE_AREA: u32 = 1 << 1; +pub const B_EXECUTE_AREA: u32 = 1 << 2; +pub const B_STACK_AREA: u32 = 1 << 3; +pub const B_CLONEABLE_AREA: u32 = 1 << 8; + +pub const B_CAN_INTERRUPT: u32 = 0x01; +pub const B_CHECK_PERMISSION: u32 = 0x04; +pub const B_KILL_CAN_INTERRUPT: u32 = 0x20; +pub const B_DO_NOT_RESCHEDULE: u32 = 0x02; +pub const B_RELEASE_ALL: u32 = 0x08; +pub const B_RELEASE_IF_WAITING_ONLY: u32 = 0x10; + +pub const B_CURRENT_TEAM: team_id = 0; +pub const B_SYSTEM_TEAM: team_id = 1; + +pub const B_TEAM_USAGE_SELF: i32 = 0; +pub const B_TEAM_USAGE_CHILDREN: i32 = -1; + +pub const B_IDLE_PRIORITY: i32 = 0; +pub const B_LOWEST_ACTIVE_PRIORITY: i32 = 1; +pub const B_LOW_PRIORITY: i32 = 5; +pub const B_NORMAL_PRIORITY: i32 = 10; +pub const B_DISPLAY_PRIORITY: i32 = 15; +pub const B_URGENT_DISPLAY_PRIORITY: i32 = 20; +pub const B_REAL_TIME_DISPLAY_PRIORITY: i32 = 100; +pub const B_URGENT_PRIORITY: i32 = 110; +pub const B_REAL_TIME_PRIORITY: i32 = 120; + +pub const B_SYSTEM_TIMEBASE: i32 = 0; +pub const B_FIRST_REAL_TIME_PRIORITY: i32 = B_REAL_TIME_DISPLAY_PRIORITY; + +pub const B_ONE_SHOT_ABSOLUTE_ALARM: u32 = 1; +pub const B_ONE_SHOT_RELATIVE_ALARM: u32 = 2; +pub const B_PERIODIC_ALARM: u32 = 3; + +pub const B_OBJECT_TYPE_FD: u16 = 0; +pub const B_OBJECT_TYPE_SEMAPHORE: u16 = 1; +pub const B_OBJECT_TYPE_PORT: u16 = 2; +pub const B_OBJECT_TYPE_THREAD: u16 = 3; + +pub const B_EVENT_READ: u16 = 0x0001; +pub const B_EVENT_WRITE: u16 = 0x0002; +pub const B_EVENT_ERROR: u16 = 0x0004; +pub const B_EVENT_PRIORITY_READ: u16 = 0x0008; +pub const B_EVENT_PRIORITY_WRITE: u16 = 0x0010; +pub const B_EVENT_HIGH_PRIORITY_READ: u16 = 0x0020; +pub const B_EVENT_HIGH_PRIORITY_WRITE: u16 = 0x0040; +pub const B_EVENT_DISCONNECTED: u16 = 0x0080; +pub const B_EVENT_ACQUIRE_SEMAPHORE: u16 = 0x0001; +pub const B_EVENT_INVALID: u16 = 0x1000; + +// kernel/fs_info.h +pub const B_FS_IS_READONLY: u32 = 0x00000001; +pub const B_FS_IS_REMOVABLE: u32 = 0x00000002; +pub const B_FS_IS_PERSISTENT: u32 = 0x00000004; +pub const B_FS_IS_SHARED: u32 = 0x00000008; +pub const B_FS_HAS_MIME: u32 = 0x00010000; +pub const B_FS_HAS_ATTR: u32 = 0x00020000; +pub const B_FS_HAS_QUERY: u32 = 0x00040000; +pub const B_FS_HAS_SELF_HEALING_LINKS: u32 = 0x00080000; +pub const B_FS_HAS_ALIASES: u32 = 0x00100000; +pub const B_FS_SUPPORTS_NODE_MONITORING: u32 = 0x00200000; +pub const B_FS_SUPPORTS_MONITOR_CHILDREN: u32 = 0x00400000; + +// kernel/fs_query.h +pub const B_LIVE_QUERY: u32 = 0x00000001; +pub const B_QUERY_NON_INDEXED: u32 = 0x00000002; + +// kernel/fs_volume.h +pub const B_MOUNT_READ_ONLY: u32 = 1; +pub const B_MOUNT_VIRTUAL_DEVICE: u32 = 2; +pub const B_FORCE_UNMOUNT: u32 = 1; + +// kernel/image.h +pub const B_FLUSH_DCACHE: u32 = 0x0001; +pub const B_FLUSH_ICACHE: u32 = 0x0004; +pub const B_INVALIDATE_DCACHE: u32 = 0x0002; +pub const B_INVALIDATE_ICACHE: u32 = 0x0008; + +pub const B_SYMBOL_TYPE_DATA: i32 = 0x1; +pub const B_SYMBOL_TYPE_TEXT: i32 = 0x2; +pub const B_SYMBOL_TYPE_ANY: i32 = 0x5; + +// storage/StorageDefs.h +pub const B_DEV_NAME_LENGTH: usize = 128; +pub const B_FILE_NAME_LENGTH: usize = ::FILENAME_MAX as usize; +pub const B_PATH_NAME_LENGTH: usize = ::PATH_MAX as usize; +pub const B_ATTR_NAME_LENGTH: usize = B_FILE_NAME_LENGTH - 1; +pub const B_MIME_TYPE_LENGTH: usize = B_ATTR_NAME_LENGTH - 15; +pub const B_MAX_SYMLINKS: usize = 16; + +// Haiku open modes in BFile are passed as u32 +pub const B_READ_ONLY: u32 = ::O_RDONLY as u32; +pub const B_WRITE_ONLY: u32 = ::O_WRONLY as u32; +pub const B_READ_WRITE: u32 = ::O_RDWR as u32; + +pub const B_FAIL_IF_EXISTS: u32 = ::O_EXCL as u32; +pub const B_CREATE_FILE: u32 = ::O_CREAT as u32; +pub const B_ERASE_FILE: u32 = ::O_TRUNC as u32; +pub const B_OPEN_AT_END: u32 = ::O_APPEND as u32; + +pub const B_FILE_NODE: u32 = 0x01; +pub const B_SYMLINK_NODE: u32 = 0x02; +pub const B_DIRECTORY_NODE: u32 = 0x04; +pub const B_ANY_NODE: u32 = 0x07; + +// support/Errors.h +pub const B_GENERAL_ERROR_BASE: status_t = core::i32::MIN; +pub const B_OS_ERROR_BASE: status_t = B_GENERAL_ERROR_BASE + 0x1000; +pub const B_APP_ERROR_BASE: status_t = B_GENERAL_ERROR_BASE + 0x2000; +pub const B_INTERFACE_ERROR_BASE: status_t = B_GENERAL_ERROR_BASE + 0x3000; +pub const B_MEDIA_ERROR_BASE: status_t = B_GENERAL_ERROR_BASE + 0x4000; +pub const B_TRANSLATION_ERROR_BASE: status_t = B_GENERAL_ERROR_BASE + 0x4800; +pub const B_MIDI_ERROR_BASE: status_t = B_GENERAL_ERROR_BASE + 0x5000; +pub const B_STORAGE_ERROR_BASE: status_t = B_GENERAL_ERROR_BASE + 0x6000; +pub const B_POSIX_ERROR_BASE: status_t = B_GENERAL_ERROR_BASE + 0x7000; +pub const B_MAIL_ERROR_BASE: status_t = B_GENERAL_ERROR_BASE + 0x8000; +pub const B_PRINT_ERROR_BASE: status_t = B_GENERAL_ERROR_BASE + 0x9000; +pub const B_DEVICE_ERROR_BASE: status_t = B_GENERAL_ERROR_BASE + 0xa000; +pub const B_ERRORS_END: status_t = B_GENERAL_ERROR_BASE + 0xffff; + +// General errors +pub const B_NO_MEMORY: status_t = B_GENERAL_ERROR_BASE + 0; +pub const B_IO_ERROR: status_t = B_GENERAL_ERROR_BASE + 1; +pub const B_PERMISSION_DENIED: status_t = B_GENERAL_ERROR_BASE + 2; +pub const B_BAD_INDEX: status_t = B_GENERAL_ERROR_BASE + 3; +pub const B_BAD_TYPE: status_t = B_GENERAL_ERROR_BASE + 4; +pub const B_BAD_VALUE: status_t = B_GENERAL_ERROR_BASE + 5; +pub const B_MISMATCHED_VALUES: status_t = B_GENERAL_ERROR_BASE + 6; +pub const B_NAME_NOT_FOUND: status_t = B_GENERAL_ERROR_BASE + 7; +pub const B_NAME_IN_USE: status_t = B_GENERAL_ERROR_BASE + 8; +pub const B_TIMED_OUT: status_t = B_GENERAL_ERROR_BASE + 9; +pub const B_INTERRUPTED: status_t = B_GENERAL_ERROR_BASE + 10; +pub const B_WOULD_BLOCK: status_t = B_GENERAL_ERROR_BASE + 11; +pub const B_CANCELED: status_t = B_GENERAL_ERROR_BASE + 12; +pub const B_NO_INIT: status_t = B_GENERAL_ERROR_BASE + 13; +pub const B_NOT_INITIALIZED: status_t = B_GENERAL_ERROR_BASE + 13; +pub const B_BUSY: status_t = B_GENERAL_ERROR_BASE + 14; +pub const B_NOT_ALLOWED: status_t = B_GENERAL_ERROR_BASE + 15; +pub const B_BAD_DATA: status_t = B_GENERAL_ERROR_BASE + 16; +pub const B_DONT_DO_THAT: status_t = B_GENERAL_ERROR_BASE + 17; + +pub const B_ERROR: status_t = -1; +pub const B_OK: status_t = 0; +pub const B_NO_ERROR: status_t = 0; + +// Kernel kit errors +pub const B_BAD_SEM_ID: status_t = B_OS_ERROR_BASE + 0; +pub const B_NO_MORE_SEMS: status_t = B_OS_ERROR_BASE + 1; + +pub const B_BAD_THREAD_ID: status_t = B_OS_ERROR_BASE + 0x100; +pub const B_NO_MORE_THREADS: status_t = B_OS_ERROR_BASE + 0x101; +pub const B_BAD_THREAD_STATE: status_t = B_OS_ERROR_BASE + 0x102; +pub const B_BAD_TEAM_ID: status_t = B_OS_ERROR_BASE + 0x103; +pub const B_NO_MORE_TEAMS: status_t = B_OS_ERROR_BASE + 0x104; + +pub const B_BAD_PORT_ID: status_t = B_OS_ERROR_BASE + 0x200; +pub const B_NO_MORE_PORTS: status_t = B_OS_ERROR_BASE + 0x201; + +pub const B_BAD_IMAGE_ID: status_t = B_OS_ERROR_BASE + 0x300; +pub const B_BAD_ADDRESS: status_t = B_OS_ERROR_BASE + 0x301; +pub const B_NOT_AN_EXECUTABLE: status_t = B_OS_ERROR_BASE + 0x302; +pub const B_MISSING_LIBRARY: status_t = B_OS_ERROR_BASE + 0x303; +pub const B_MISSING_SYMBOL: status_t = B_OS_ERROR_BASE + 0x304; +pub const B_UNKNOWN_EXECUTABLE: status_t = B_OS_ERROR_BASE + 0x305; +pub const B_LEGACY_EXECUTABLE: status_t = B_OS_ERROR_BASE + 0x306; + +pub const B_DEBUGGER_ALREADY_INSTALLED: status_t = B_OS_ERROR_BASE + 0x400; + +// Application kit errors +pub const B_BAD_REPLY: status_t = B_APP_ERROR_BASE + 0; +pub const B_DUPLICATE_REPLY: status_t = B_APP_ERROR_BASE + 1; +pub const B_MESSAGE_TO_SELF: status_t = B_APP_ERROR_BASE + 2; +pub const B_BAD_HANDLER: status_t = B_APP_ERROR_BASE + 3; +pub const B_ALREADY_RUNNING: status_t = B_APP_ERROR_BASE + 4; +pub const B_LAUNCH_FAILED: status_t = B_APP_ERROR_BASE + 5; +pub const B_AMBIGUOUS_APP_LAUNCH: status_t = B_APP_ERROR_BASE + 6; +pub const B_UNKNOWN_MIME_TYPE: status_t = B_APP_ERROR_BASE + 7; +pub const B_BAD_SCRIPT_SYNTAX: status_t = B_APP_ERROR_BASE + 8; +pub const B_LAUNCH_FAILED_NO_RESOLVE_LINK: status_t = B_APP_ERROR_BASE + 9; +pub const B_LAUNCH_FAILED_EXECUTABLE: status_t = B_APP_ERROR_BASE + 10; +pub const B_LAUNCH_FAILED_APP_NOT_FOUND: status_t = B_APP_ERROR_BASE + 11; +pub const B_LAUNCH_FAILED_APP_IN_TRASH: status_t = B_APP_ERROR_BASE + 12; +pub const B_LAUNCH_FAILED_NO_PREFERRED_APP: status_t = B_APP_ERROR_BASE + 13; +pub const B_LAUNCH_FAILED_FILES_APP_NOT_FOUND: status_t = B_APP_ERROR_BASE + 14; +pub const B_BAD_MIME_SNIFFER_RULE: status_t = B_APP_ERROR_BASE + 15; +pub const B_NOT_A_MESSAGE: status_t = B_APP_ERROR_BASE + 16; +pub const B_SHUTDOWN_CANCELLED: status_t = B_APP_ERROR_BASE + 17; +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_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; +pub const B_NOT_A_DIRECTORY: status_t = B_STORAGE_ERROR_BASE + 5; +pub const B_DIRECTORY_NOT_EMPTY: status_t = B_STORAGE_ERROR_BASE + 6; +pub const B_DEVICE_FULL: status_t = B_STORAGE_ERROR_BASE + 7; +pub const B_READ_ONLY_DEVICE: status_t = B_STORAGE_ERROR_BASE + 8; +pub const B_IS_A_DIRECTORY: status_t = B_STORAGE_ERROR_BASE + 9; +pub const B_NO_MORE_FDS: status_t = B_STORAGE_ERROR_BASE + 10; +pub const B_CROSS_DEVICE_LINK: status_t = B_STORAGE_ERROR_BASE + 11; +pub const B_LINK_LIMIT: status_t = B_STORAGE_ERROR_BASE + 12; +pub const B_BUSTED_PIPE: status_t = B_STORAGE_ERROR_BASE + 13; +pub const B_UNSUPPORTED: status_t = B_STORAGE_ERROR_BASE + 14; +pub const B_PARTITION_TOO_SMALL: status_t = B_STORAGE_ERROR_BASE + 15; +pub const B_PARTIAL_READ: status_t = B_STORAGE_ERROR_BASE + 16; +pub const B_PARTIAL_WRITE: status_t = B_STORAGE_ERROR_BASE + 17; + +// Mapped posix errors +pub const B_BUFFER_OVERFLOW: status_t = ::EOVERFLOW; +pub const B_TOO_MANY_ARGS: status_t = ::E2BIG; +pub const B_FILE_TOO_LARGE: status_t = ::EFBIG; +pub const B_RESULT_NOT_REPRESENTABLE: status_t = ::ERANGE; +pub const B_DEVICE_NOT_FOUND: status_t = ::ENODEV; +pub const B_NOT_SUPPORTED: status_t = ::EOPNOTSUPP; + +// Media kit errors +pub const B_STREAM_NOT_FOUND: status_t = B_MEDIA_ERROR_BASE + 0; +pub const B_SERVER_NOT_FOUND: status_t = B_MEDIA_ERROR_BASE + 1; +pub const B_RESOURCE_NOT_FOUND: status_t = B_MEDIA_ERROR_BASE + 2; +pub const B_RESOURCE_UNAVAILABLE: status_t = B_MEDIA_ERROR_BASE + 3; +pub const B_BAD_SUBSCRIBER: status_t = B_MEDIA_ERROR_BASE + 4; +pub const B_SUBSCRIBER_NOT_ENTERED: status_t = B_MEDIA_ERROR_BASE + 5; +pub const B_BUFFER_NOT_AVAILABLE: status_t = B_MEDIA_ERROR_BASE + 6; +pub const B_LAST_BUFFER_ERROR: status_t = B_MEDIA_ERROR_BASE + 7; + +pub const B_MEDIA_SYSTEM_FAILURE: status_t = B_MEDIA_ERROR_BASE + 100; +pub const B_MEDIA_BAD_NODE: status_t = B_MEDIA_ERROR_BASE + 101; +pub const B_MEDIA_NODE_BUSY: status_t = B_MEDIA_ERROR_BASE + 102; +pub const B_MEDIA_BAD_FORMAT: status_t = B_MEDIA_ERROR_BASE + 103; +pub const B_MEDIA_BAD_BUFFER: status_t = B_MEDIA_ERROR_BASE + 104; +pub const B_MEDIA_TOO_MANY_NODES: status_t = B_MEDIA_ERROR_BASE + 105; +pub const B_MEDIA_TOO_MANY_BUFFERS: status_t = B_MEDIA_ERROR_BASE + 106; +pub const B_MEDIA_NODE_ALREADY_EXISTS: status_t = B_MEDIA_ERROR_BASE + 107; +pub const B_MEDIA_BUFFER_ALREADY_EXISTS: status_t = B_MEDIA_ERROR_BASE + 108; +pub const B_MEDIA_CANNOT_SEEK: status_t = B_MEDIA_ERROR_BASE + 109; +pub const B_MEDIA_CANNOT_CHANGE_RUN_MODE: status_t = B_MEDIA_ERROR_BASE + 110; +pub const B_MEDIA_APP_ALREADY_REGISTERED: status_t = B_MEDIA_ERROR_BASE + 111; +pub const B_MEDIA_APP_NOT_REGISTERED: status_t = B_MEDIA_ERROR_BASE + 112; +pub const B_MEDIA_CANNOT_RECLAIM_BUFFERS: status_t = B_MEDIA_ERROR_BASE + 113; +pub const B_MEDIA_BUFFERS_NOT_RECLAIMED: status_t = B_MEDIA_ERROR_BASE + 114; +pub const B_MEDIA_TIME_SOURCE_STOPPED: status_t = B_MEDIA_ERROR_BASE + 115; +pub const B_MEDIA_TIME_SOURCE_BUSY: status_t = B_MEDIA_ERROR_BASE + 116; +pub const B_MEDIA_BAD_SOURCE: status_t = B_MEDIA_ERROR_BASE + 117; +pub const B_MEDIA_BAD_DESTINATION: status_t = B_MEDIA_ERROR_BASE + 118; +pub const B_MEDIA_ALREADY_CONNECTED: status_t = B_MEDIA_ERROR_BASE + 119; +pub const B_MEDIA_NOT_CONNECTED: status_t = B_MEDIA_ERROR_BASE + 120; +pub const B_MEDIA_BAD_CLIP_FORMAT: status_t = B_MEDIA_ERROR_BASE + 121; +pub const B_MEDIA_ADDON_FAILED: status_t = B_MEDIA_ERROR_BASE + 122; +pub const B_MEDIA_ADDON_DISABLED: status_t = B_MEDIA_ERROR_BASE + 123; +pub const B_MEDIA_CHANGE_IN_PROGRESS: status_t = B_MEDIA_ERROR_BASE + 124; +pub const B_MEDIA_STALE_CHANGE_COUNT: status_t = B_MEDIA_ERROR_BASE + 125; +pub const B_MEDIA_ADDON_RESTRICTED: status_t = B_MEDIA_ERROR_BASE + 126; +pub const B_MEDIA_NO_HANDLER: status_t = B_MEDIA_ERROR_BASE + 127; +pub const B_MEDIA_DUPLICATE_FORMAT: status_t = B_MEDIA_ERROR_BASE + 128; +pub const B_MEDIA_REALTIME_DISABLED: status_t = B_MEDIA_ERROR_BASE + 129; +pub const B_MEDIA_REALTIME_UNAVAILABLE: status_t = B_MEDIA_ERROR_BASE + 130; + +// Mail kit errors +pub const B_MAIL_NO_DAEMON: status_t = B_MAIL_ERROR_BASE + 0; +pub const B_MAIL_UNKNOWN_USER: status_t = B_MAIL_ERROR_BASE + 1; +pub const B_MAIL_WRONG_PASSWORD: status_t = B_MAIL_ERROR_BASE + 2; +pub const B_MAIL_UNKNOWN_HOST: status_t = B_MAIL_ERROR_BASE + 3; +pub const B_MAIL_ACCESS_ERROR: status_t = B_MAIL_ERROR_BASE + 4; +pub const B_MAIL_UNKNOWN_FIELD: status_t = B_MAIL_ERROR_BASE + 5; +pub const B_MAIL_NO_RECIPIENT: status_t = B_MAIL_ERROR_BASE + 6; +pub const B_MAIL_INVALID_MAIL: status_t = B_MAIL_ERROR_BASE + 7; + +// Print kit errors +pub const B_NO_PRINT_SERVER: status_t = B_PRINT_ERROR_BASE + 0; + +// Device kit errors +pub const B_DEV_INVALID_IOCTL: status_t = B_DEVICE_ERROR_BASE + 0; +pub const B_DEV_NO_MEMORY: status_t = B_DEVICE_ERROR_BASE + 1; +pub const B_DEV_BAD_DRIVE_NUM: status_t = B_DEVICE_ERROR_BASE + 2; +pub const B_DEV_NO_MEDIA: status_t = B_DEVICE_ERROR_BASE + 3; +pub const B_DEV_UNREADABLE: status_t = B_DEVICE_ERROR_BASE + 4; +pub const B_DEV_FORMAT_ERROR: status_t = B_DEVICE_ERROR_BASE + 5; +pub const B_DEV_TIMEOUT: status_t = B_DEVICE_ERROR_BASE + 6; +pub const B_DEV_RECALIBRATE_ERROR: status_t = B_DEVICE_ERROR_BASE + 7; +pub const B_DEV_SEEK_ERROR: status_t = B_DEVICE_ERROR_BASE + 8; +pub const B_DEV_ID_ERROR: status_t = B_DEVICE_ERROR_BASE + 9; +pub const B_DEV_READ_ERROR: status_t = B_DEVICE_ERROR_BASE + 10; +pub const B_DEV_WRITE_ERROR: status_t = B_DEVICE_ERROR_BASE + 11; +pub const B_DEV_NOT_READY: status_t = B_DEVICE_ERROR_BASE + 12; +pub const B_DEV_MEDIA_CHANGED: status_t = B_DEVICE_ERROR_BASE + 13; +pub const B_DEV_MEDIA_CHANGE_REQUESTED: status_t = B_DEVICE_ERROR_BASE + 14; +pub const B_DEV_RESOURCE_CONFLICT: status_t = B_DEVICE_ERROR_BASE + 15; +pub const B_DEV_CONFIGURATION_ERROR: status_t = B_DEVICE_ERROR_BASE + 16; +pub const B_DEV_DISABLED_BY_USER: status_t = B_DEVICE_ERROR_BASE + 17; +pub const B_DEV_DOOR_OPEN: status_t = B_DEVICE_ERROR_BASE + 18; + +pub const B_DEV_INVALID_PIPE: status_t = B_DEVICE_ERROR_BASE + 19; +pub const B_DEV_CRC_ERROR: status_t = B_DEVICE_ERROR_BASE + 20; +pub const B_DEV_STALLED: status_t = B_DEVICE_ERROR_BASE + 21; +pub const B_DEV_BAD_PID: status_t = B_DEVICE_ERROR_BASE + 22; +pub const B_DEV_UNEXPECTED_PID: status_t = B_DEVICE_ERROR_BASE + 23; +pub const B_DEV_DATA_OVERRUN: status_t = B_DEVICE_ERROR_BASE + 24; +pub const B_DEV_DATA_UNDERRUN: status_t = B_DEVICE_ERROR_BASE + 25; +pub const B_DEV_FIFO_OVERRUN: status_t = B_DEVICE_ERROR_BASE + 26; +pub const B_DEV_FIFO_UNDERRUN: status_t = B_DEVICE_ERROR_BASE + 27; +pub const B_DEV_PENDING: status_t = B_DEVICE_ERROR_BASE + 28; +pub const B_DEV_MULTIPLE_ERRORS: status_t = B_DEVICE_ERROR_BASE + 29; +pub const B_DEV_TOO_LATE: status_t = B_DEVICE_ERROR_BASE + 30; + +// translation kit errors +pub const B_TRANSLATION_BASE_ERROR: status_t = B_TRANSLATION_ERROR_BASE + 0; +pub const B_NO_TRANSLATOR: status_t = B_TRANSLATION_ERROR_BASE + 1; +pub const B_ILLEGAL_DATA: status_t = B_TRANSLATION_ERROR_BASE + 2; + +// support/TypeConstants.h +pub const B_AFFINE_TRANSFORM_TYPE: u32 = haiku_constant!('A', 'M', 'T', 'X'); +pub const B_ALIGNMENT_TYPE: u32 = haiku_constant!('A', 'L', 'G', 'N'); +pub const B_ANY_TYPE: u32 = haiku_constant!('A', 'N', 'Y', 'T'); +pub const B_ATOM_TYPE: u32 = haiku_constant!('A', 'T', 'O', 'M'); +pub const B_ATOMREF_TYPE: u32 = haiku_constant!('A', 'T', 'M', 'R'); +pub const B_BOOL_TYPE: u32 = haiku_constant!('B', 'O', 'O', 'L'); +pub const B_CHAR_TYPE: u32 = haiku_constant!('C', 'H', 'A', 'R'); +pub const B_COLOR_8_BIT_TYPE: u32 = haiku_constant!('C', 'L', 'R', 'B'); +pub const B_DOUBLE_TYPE: u32 = haiku_constant!('D', 'B', 'L', 'E'); +pub const B_FLOAT_TYPE: u32 = haiku_constant!('F', 'L', 'O', 'T'); +pub const B_GRAYSCALE_8_BIT_TYPE: u32 = haiku_constant!('G', 'R', 'Y', 'B'); +pub const B_INT16_TYPE: u32 = haiku_constant!('S', 'H', 'R', 'T'); +pub const B_INT32_TYPE: u32 = haiku_constant!('L', 'O', 'N', 'G'); +pub const B_INT64_TYPE: u32 = haiku_constant!('L', 'L', 'N', 'G'); +pub const B_INT8_TYPE: u32 = haiku_constant!('B', 'Y', 'T', 'E'); +pub const B_LARGE_ICON_TYPE: u32 = haiku_constant!('I', 'C', 'O', 'N'); +pub const B_MEDIA_PARAMETER_GROUP_TYPE: u32 = haiku_constant!('B', 'M', 'C', 'G'); +pub const B_MEDIA_PARAMETER_TYPE: u32 = haiku_constant!('B', 'M', 'C', 'T'); +pub const B_MEDIA_PARAMETER_WEB_TYPE: u32 = haiku_constant!('B', 'M', 'C', 'W'); +pub const B_MESSAGE_TYPE: u32 = haiku_constant!('M', 'S', 'G', 'G'); +pub const B_MESSENGER_TYPE: u32 = haiku_constant!('M', 'S', 'N', 'G'); +pub const B_MIME_TYPE: u32 = haiku_constant!('M', 'I', 'M', 'E'); +pub const B_MINI_ICON_TYPE: u32 = haiku_constant!('M', 'I', 'C', 'N'); +pub const B_MONOCHROME_1_BIT_TYPE: u32 = haiku_constant!('M', 'N', 'O', 'B'); +pub const B_OBJECT_TYPE: u32 = haiku_constant!('O', 'P', 'T', 'R'); +pub const B_OFF_T_TYPE: u32 = haiku_constant!('O', 'F', 'F', 'T'); +pub const B_PATTERN_TYPE: u32 = haiku_constant!('P', 'A', 'T', 'N'); +pub const B_POINTER_TYPE: u32 = haiku_constant!('P', 'N', 'T', 'R'); +pub const B_POINT_TYPE: u32 = haiku_constant!('B', 'P', 'N', 'T'); +pub const B_PROPERTY_INFO_TYPE: u32 = haiku_constant!('S', 'C', 'T', 'D'); +pub const B_RAW_TYPE: u32 = haiku_constant!('R', 'A', 'W', 'T'); +pub const B_RECT_TYPE: u32 = haiku_constant!('R', 'E', 'C', 'T'); +pub const B_REF_TYPE: u32 = haiku_constant!('R', 'R', 'E', 'F'); +pub const B_RGB_32_BIT_TYPE: u32 = haiku_constant!('R', 'G', 'B', 'B'); +pub const B_RGB_COLOR_TYPE: u32 = haiku_constant!('R', 'G', 'B', 'C'); +pub const B_SIZE_TYPE: u32 = haiku_constant!('S', 'I', 'Z', 'E'); +pub const B_SIZE_T_TYPE: u32 = haiku_constant!('S', 'I', 'Z', 'T'); +pub const B_SSIZE_T_TYPE: u32 = haiku_constant!('S', 'S', 'Z', 'T'); +pub const B_STRING_TYPE: u32 = haiku_constant!('C', 'S', 'T', 'R'); +pub const B_STRING_LIST_TYPE: u32 = haiku_constant!('S', 'T', 'R', 'L'); +pub const B_TIME_TYPE: u32 = haiku_constant!('T', 'I', 'M', 'E'); +pub const B_UINT16_TYPE: u32 = haiku_constant!('U', 'S', 'H', 'T'); +pub const B_UINT32_TYPE: u32 = haiku_constant!('U', 'L', 'N', 'G'); +pub const B_UINT64_TYPE: u32 = haiku_constant!('U', 'L', 'L', 'G'); +pub const B_UINT8_TYPE: u32 = haiku_constant!('U', 'B', 'Y', 'T'); +pub const B_VECTOR_ICON_TYPE: u32 = haiku_constant!('V', 'I', 'C', 'N'); +pub const B_XATTR_TYPE: u32 = haiku_constant!('X', 'A', 'T', 'R'); +pub const B_NETWORK_ADDRESS_TYPE: u32 = haiku_constant!('N', 'W', 'A', 'D'); +pub const B_MIME_STRING_TYPE: u32 = haiku_constant!('M', 'I', 'M', 'S'); +pub const B_ASCII_TYPE: u32 = haiku_constant!('T', 'E', 'X', 'T'); +pub const B_APP_IMAGE_SYMBOL: *const ::c_void = core::ptr::null(); + +extern "C" { + // kernel/OS.h + pub fn create_area( + name: *const ::c_char, + startAddress: *mut *mut ::c_void, + addressSpec: u32, + size: usize, + lock: u32, + protection: u32, + ) -> area_id; + pub fn clone_area( + name: *const ::c_char, + destAddress: *mut *mut ::c_void, + addressSpec: u32, + protection: u32, + source: area_id, + ) -> area_id; + pub fn find_area(name: *const ::c_char) -> area_id; + pub fn area_for(address: *mut ::c_void) -> area_id; + pub fn delete_area(id: area_id) -> status_t; + pub fn resize_area(id: area_id, newSize: usize) -> status_t; + pub fn set_area_protection(id: area_id, newProtection: u32) -> status_t; + pub fn _get_area_info(id: area_id, areaInfo: *mut area_info, size: usize) -> status_t; + pub fn _get_next_area_info( + team: team_id, + cookie: *mut isize, + areaInfo: *mut area_info, + size: usize, + ) -> status_t; + + pub fn create_port(capacity: i32, name: *const ::c_char) -> port_id; + pub fn find_port(name: *const ::c_char) -> port_id; + pub fn read_port( + port: port_id, + code: *mut i32, + buffer: *mut ::c_void, + bufferSize: ::size_t, + ) -> ::ssize_t; + pub fn read_port_etc( + port: port_id, + code: *mut i32, + buffer: *mut ::c_void, + bufferSize: ::size_t, + flags: u32, + timeout: bigtime_t, + ) -> ::ssize_t; + pub fn write_port( + port: port_id, + code: i32, + buffer: *const ::c_void, + bufferSize: ::size_t, + ) -> status_t; + pub fn write_port_etc( + port: port_id, + code: i32, + buffer: *const ::c_void, + bufferSize: ::size_t, + flags: u32, + timeout: bigtime_t, + ) -> status_t; + pub fn close_port(port: port_id) -> status_t; + pub fn delete_port(port: port_id) -> status_t; + pub fn port_buffer_size(port: port_id) -> ::ssize_t; + pub fn port_buffer_size_etc(port: port_id, flags: u32, timeout: bigtime_t) -> ::ssize_t; + pub fn port_count(port: port_id) -> ::ssize_t; + pub fn set_port_owner(port: port_id, team: team_id) -> status_t; + + pub fn _get_port_info(port: port_id, buf: *mut port_info, portInfoSize: ::size_t) -> status_t; + pub fn _get_next_port_info( + port: port_id, + cookie: *mut i32, + portInfo: *mut port_info, + portInfoSize: ::size_t, + ) -> status_t; + pub fn _get_port_message_info_etc( + port: port_id, + info: *mut port_message_info, + infoSize: ::size_t, + flags: u32, + timeout: bigtime_t, + ) -> status_t; + + pub fn create_sem(count: i32, name: *const ::c_char) -> sem_id; + pub fn delete_sem(id: sem_id) -> status_t; + pub fn acquire_sem(id: sem_id) -> status_t; + pub fn acquire_sem_etc(id: sem_id, count: i32, flags: u32, timeout: bigtime_t) -> status_t; + pub fn release_sem(id: sem_id) -> status_t; + pub fn release_sem_etc(id: sem_id, count: i32, flags: u32) -> status_t; + pub fn switch_sem(semToBeReleased: sem_id, id: sem_id) -> status_t; + pub fn switch_sem_etc( + semToBeReleased: sem_id, + id: sem_id, + count: i32, + flags: u32, + timeout: bigtime_t, + ) -> status_t; + pub fn get_sem_count(id: sem_id, threadCount: *mut i32) -> status_t; + pub fn set_sem_owner(id: sem_id, team: team_id) -> status_t; + pub fn _get_sem_info(id: sem_id, info: *mut sem_info, infoSize: ::size_t) -> status_t; + pub fn _get_next_sem_info( + team: team_id, + cookie: *mut i32, + info: *mut sem_info, + infoSize: ::size_t, + ) -> status_t; + + pub fn kill_team(team: team_id) -> status_t; + pub fn _get_team_info(team: team_id, info: *mut team_info, size: ::size_t) -> status_t; + pub fn _get_next_team_info(cookie: *mut i32, info: *mut team_info, size: ::size_t) -> status_t; + + pub fn spawn_thread( + func: thread_func, + name: *const ::c_char, + priority: i32, + data: *mut ::c_void, + ) -> thread_id; + pub fn kill_thread(thread: thread_id) -> status_t; + pub fn resume_thread(thread: thread_id) -> status_t; + pub fn suspend_thread(thread: thread_id) -> status_t; + + 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; + + pub fn find_thread(name: *const ::c_char) -> thread_id; + + pub fn get_scheduler_mode() -> i32; + pub fn set_scheduler_mode(mode: i32) -> status_t; + + pub fn send_data( + thread: thread_id, + code: i32, + buffer: *const ::c_void, + bufferSize: ::size_t, + ) -> status_t; + pub fn receive_data(sender: *mut thread_id, buffer: *mut ::c_void, bufferSize: ::size_t) + -> i32; + pub fn has_data(thread: thread_id) -> bool; + + pub fn snooze(amount: bigtime_t) -> status_t; + pub fn snooze_etc(amount: bigtime_t, timeBase: ::c_int, flags: u32) -> status_t; + pub fn snooze_until(time: bigtime_t, timeBase: ::c_int) -> status_t; + + pub fn _get_thread_info(id: thread_id, info: *mut thread_info, size: ::size_t) -> status_t; + pub fn _get_next_thread_info( + team: team_id, + cookie: *mut i32, + info: *mut thread_info, + size: ::size_t, + ) -> status_t; + + pub fn get_pthread_thread_id(thread: ::pthread_t) -> thread_id; + + pub fn _get_team_usage_info( + team: team_id, + who: i32, + info: *mut team_usage_info, + size: ::size_t, + ) -> status_t; + + pub fn real_time_clock() -> ::c_ulong; + pub fn set_real_time_clock(secsSinceJan1st1970: ::c_ulong); + pub fn real_time_clock_usecs() -> bigtime_t; + pub fn system_time() -> bigtime_t; + pub fn system_time_nsecs() -> nanotime_t; + // set_timezone() is deprecated and a no-op + + pub fn set_alarm(when: bigtime_t, flags: u32) -> bigtime_t; + pub fn debugger(message: *const ::c_char); + pub fn disable_debugger(state: ::c_int) -> ::c_int; + + pub fn get_system_info(info: *mut system_info) -> status_t; + pub fn _get_cpu_info_etc( + firstCPU: u32, + cpuCount: u32, + info: *mut cpu_info, + size: ::size_t, + ) -> status_t; + pub fn get_cpu_topology_info( + topologyInfos: *mut cpu_topology_node_info, + topologyInfoCount: *mut u32, + ) -> 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; + pub fn set_signal_stack(base: *mut ::c_void, size: ::size_t); + + pub fn wait_for_objects(infos: *mut object_wait_info, numInfos: ::c_int) -> ::ssize_t; + pub fn wait_for_objects_etc( + infos: *mut object_wait_info, + numInfos: ::c_int, + flags: u32, + timeout: bigtime_t, + ) -> ::ssize_t; + + // kernel/fs_attr.h + pub fn fs_read_attr( + fd: ::c_int, + attribute: *const ::c_char, + type_: u32, + pos: ::off_t, + buffer: *mut ::c_void, + readBytes: ::size_t, + ) -> ::ssize_t; + pub fn fs_write_attr( + fd: ::c_int, + attribute: *const ::c_char, + type_: u32, + pos: ::off_t, + buffer: *const ::c_void, + writeBytes: ::size_t, + ) -> ::ssize_t; + pub fn fs_remove_attr(fd: ::c_int, attribute: *const ::c_char) -> ::c_int; + pub fn fs_stat_attr( + fd: ::c_int, + attribute: *const ::c_char, + attrInfo: *mut attr_info, + ) -> ::c_int; + + pub fn fs_open_attr( + path: *const ::c_char, + attribute: *const ::c_char, + type_: u32, + openMode: ::c_int, + ) -> ::c_int; + pub fn fs_fopen_attr( + fd: ::c_int, + attribute: *const ::c_char, + type_: u32, + openMode: ::c_int, + ) -> ::c_int; + pub fn fs_close_attr(fd: ::c_int) -> ::c_int; + + pub fn fs_open_attr_dir(path: *const ::c_char) -> *mut ::DIR; + pub fn fs_lopen_attr_dir(path: *const ::c_char) -> *mut ::DIR; + pub fn fs_fopen_attr_dir(fd: ::c_int) -> *mut ::DIR; + pub fn fs_close_attr_dir(dir: *mut ::DIR) -> ::c_int; + pub fn fs_read_attr_dir(dir: *mut ::DIR) -> *mut ::dirent; + pub fn fs_rewind_attr_dir(dir: *mut ::DIR); + + // kernel/fs_image.h + pub fn fs_create_index( + device: ::dev_t, + name: *const ::c_char, + type_: u32, + flags: u32, + ) -> ::c_int; + pub fn fs_remove_index(device: ::dev_t, name: *const ::c_char) -> ::c_int; + pub fn fs_stat_index( + device: ::dev_t, + name: *const ::c_char, + indexInfo: *mut index_info, + ) -> ::c_int; + + pub fn fs_open_index_dir(device: ::dev_t) -> *mut ::DIR; + pub fn fs_close_index_dir(indexDirectory: *mut ::DIR) -> ::c_int; + pub fn fs_read_index_dir(indexDirectory: *mut ::DIR) -> *mut ::dirent; + pub fn fs_rewind_index_dir(indexDirectory: *mut ::DIR); + + // kernel/fs_info.h + pub fn dev_for_path(path: *const ::c_char) -> ::dev_t; + pub fn next_dev(pos: *mut i32) -> ::dev_t; + pub fn fs_stat_dev(dev: ::dev_t, info: *mut fs_info) -> ::c_int; + + // kernel/fs_query.h + pub fn fs_open_query(device: ::dev_t, query: *const ::c_char, flags: u32) -> *mut ::DIR; + pub fn fs_open_live_query( + device: ::dev_t, + query: *const ::c_char, + flags: u32, + port: port_id, + token: i32, + ) -> *mut ::DIR; + pub fn fs_close_query(d: *mut ::DIR) -> ::c_int; + pub fn fs_read_query(d: *mut ::DIR) -> *mut ::dirent; + pub fn get_path_for_dirent(dent: *mut ::dirent, buf: *mut ::c_char, len: ::size_t) -> status_t; + + // kernel/fs_volume.h + pub fn fs_mount_volume( + where_: *const ::c_char, + device: *const ::c_char, + filesystem: *const ::c_char, + flags: u32, + parameters: *const ::c_char, + ) -> ::dev_t; + pub fn fs_unmount_volume(path: *const ::c_char, flags: u32) -> status_t; + + // kernel/image.h + pub fn load_image( + argc: i32, + argv: *mut *const ::c_char, + environ: *mut *const ::c_char, + ) -> thread_id; + pub fn load_add_on(path: *const ::c_char) -> image_id; + pub fn unload_add_on(image: image_id) -> status_t; + pub fn get_image_symbol( + image: image_id, + name: *const ::c_char, + symbolType: i32, + symbolLocation: *mut *mut ::c_void, + ) -> status_t; + pub fn get_nth_image_symbol( + image: image_id, + n: i32, + nameBuffer: *mut ::c_char, + nameLength: *mut i32, + symbolType: *mut i32, + symbolLocation: *mut *mut ::c_void, + ) -> status_t; + pub fn clear_caches(address: *mut ::c_void, length: ::size_t, flags: u32); + pub fn _get_image_info(image: image_id, info: *mut image_info, size: ::size_t) -> status_t; + pub fn _get_next_image_info( + team: team_id, + cookie: *mut i32, + 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, + info: *mut area_info, +) -> status_t { + _get_next_area_info( + team, + cookie, + info, + core::mem::size_of::() as usize, + ) +} + +#[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, + portInfo: *mut port_info, +) -> status_t { + _get_next_port_info( + port, + cookie, + portInfo, + core::mem::size_of::() as ::size_t, + ) +} + +#[inline] +pub unsafe fn get_port_message_info_etc( + port: port_id, + info: *mut port_message_info, + flags: u32, + timeout: bigtime_t, +) -> status_t { + _get_port_message_info_etc( + port, + info, + core::mem::size_of::() as ::size_t, + flags, + timeout, + ) +} + +#[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, + cookie, + info, + core::mem::size_of::() as ::size_t, + ) +} + +#[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, + who, + info, + core::mem::size_of::() as ::size_t, + ) +} + +#[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, + info: *mut thread_info, +) -> status_t { + _get_next_thread_info( + team, + cookie, + info, + core::mem::size_of::() as ::size_t, + ) +} + +// 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, + info: *mut image_info, +) -> status_t { + _get_next_image_info( + team, + cookie, + info, + core::mem::size_of::() as ::size_t, + ) +} 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/hurd/align.rs b/vendor/libc/src/unix/hurd/align.rs new file mode 100644 index 0000000..1dd7d8e --- /dev/null +++ b/vendor/libc/src/unix/hurd/align.rs @@ -0,0 +1 @@ +// Placeholder file diff --git a/vendor/libc/src/unix/hurd/b32.rs b/vendor/libc/src/unix/hurd/b32.rs new file mode 100644 index 0000000..7e82a91 --- /dev/null +++ b/vendor/libc/src/unix/hurd/b32.rs @@ -0,0 +1,93 @@ +pub type c_long = i32; +pub type c_ulong = u32; + +pub type __int64_t = ::c_longlong; +pub type __uint64_t = ::c_ulonglong; + +pub type int_fast16_t = ::c_int; +pub type int_fast32_t = ::c_int; +pub type int_fast64_t = ::c_longlong; +pub type uint_fast16_t = ::c_uint; +pub type uint_fast32_t = ::c_uint; +pub type uint_fast64_t = ::c_ulonglong; + +pub type __quad_t = ::c_longlong; +pub type __u_quad_t = ::c_ulonglong; +pub type __intmax_t = ::c_longlong; +pub type __uintmax_t = ::c_ulonglong; + +pub type __squad_type = ::__int64_t; +pub type __uquad_type = ::__uint64_t; +pub type __sword_type = ::c_int; +pub type __uword_type = ::c_uint; +pub type __slong32_type = ::c_long; +pub type __ulong32_type = ::c_ulong; +pub type __s64_type = ::__int64_t; +pub type __u64_type = ::__uint64_t; + +pub type __ipc_pid_t = ::c_ushort; + +pub type Elf32_Half = u16; +pub type Elf32_Word = u32; +pub type Elf32_Off = u32; +pub type Elf32_Addr = u32; +pub type Elf32_Section = u16; + +pub type Elf_Addr = ::Elf32_Addr; +pub type Elf_Half = ::Elf32_Half; +pub type Elf_Ehdr = ::Elf32_Ehdr; +pub type Elf_Phdr = ::Elf32_Phdr; +pub type Elf_Shdr = ::Elf32_Shdr; +pub type Elf_Sym = ::Elf32_Sym; + +s! { + 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 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 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 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/hurd/b64.rs b/vendor/libc/src/unix/hurd/b64.rs new file mode 100644 index 0000000..e2e502a --- /dev/null +++ b/vendor/libc/src/unix/hurd/b64.rs @@ -0,0 +1,95 @@ +pub type c_long = i64; +pub type c_ulong = u64; + +pub type __int64_t = ::c_long; +pub type __uint64_t = ::c_ulong; + +pub type int_fast16_t = ::c_long; +pub type int_fast32_t = ::c_long; +pub type int_fast64_t = ::c_long; +pub type uint_fast16_t = ::c_ulong; +pub type uint_fast32_t = ::c_ulong; +pub type uint_fast64_t = ::c_ulong; + +pub type __quad_t = ::c_long; +pub type __u_quad_t = ::c_ulong; +pub type __intmax_t = ::c_long; +pub type __uintmax_t = ::c_ulong; + +pub type __squad_type = ::c_long; +pub type __uquad_type = ::c_ulong; +pub type __sword_type = ::c_long; +pub type __uword_type = ::c_ulong; +pub type __slong32_type = ::c_int; +pub type __ulong32_type = ::c_uint; +pub type __s64_type = ::c_long; +pub type __u64_type = ::c_ulong; + +pub type __ipc_pid_t = ::c_int; + +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_Section = u16; + +pub type Elf_Addr = ::Elf64_Addr; +pub type Elf_Half = ::Elf64_Half; +pub type Elf_Ehdr = ::Elf64_Ehdr; +pub type Elf_Phdr = ::Elf64_Phdr; +pub type Elf_Shdr = ::Elf64_Shdr; +pub type Elf_Sym = ::Elf64_Sym; + +s! { + 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 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 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 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/hurd/mod.rs b/vendor/libc/src/unix/hurd/mod.rs new file mode 100644 index 0000000..ad422fe --- /dev/null +++ b/vendor/libc/src/unix/hurd/mod.rs @@ -0,0 +1,4696 @@ +#![allow(dead_code)] + +// types +pub type c_char = i8; + +pub type __s16_type = ::c_short; +pub type __u16_type = ::c_ushort; +pub type __s32_type = ::c_int; +pub type __u32_type = ::c_uint; +pub type __slongword_type = ::c_long; +pub type __ulongword_type = ::c_ulong; + +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 __int8_t = ::c_schar; +pub type __uint8_t = ::c_uchar; +pub type __int16_t = ::c_short; +pub type __uint16_t = ::c_ushort; +pub type __int32_t = ::c_int; +pub type __uint32_t = ::c_uint; +pub type __int_least8_t = __int8_t; +pub type __uint_least8_t = __uint8_t; +pub type __int_least16_t = __int16_t; +pub type __uint_least16_t = __uint16_t; +pub type __int_least32_t = __int32_t; +pub type __uint_least32_t = __uint32_t; +pub type __int_least64_t = __int64_t; +pub type __uint_least64_t = __uint64_t; + +pub type __dev_t = __uword_type; +pub type __uid_t = __u32_type; +pub type __gid_t = __u32_type; +pub type __ino_t = __ulongword_type; +pub type __ino64_t = __uquad_type; +pub type __mode_t = __u32_type; +pub type __nlink_t = __uword_type; +pub type __off_t = __slongword_type; +pub type __off64_t = __squad_type; +pub type __pid_t = __s32_type; +pub type __rlim_t = __ulongword_type; +pub type __rlim64_t = __uquad_type; +pub type __blkcnt_t = __slongword_type; +pub type __blkcnt64_t = __squad_type; +pub type __fsblkcnt_t = __ulongword_type; +pub type __fsblkcnt64_t = __uquad_type; +pub type __fsfilcnt_t = __ulongword_type; +pub type __fsfilcnt64_t = __uquad_type; +pub type __fsword_t = __sword_type; +pub type __id_t = __u32_type; +pub type __clock_t = __slongword_type; +pub type __time_t = __slongword_type; +pub type __useconds_t = __u32_type; +pub type __suseconds_t = __slongword_type; +pub type __suseconds64_t = __squad_type; +pub type __daddr_t = __s32_type; +pub type __key_t = __s32_type; +pub type __clockid_t = __s32_type; +pub type __timer_t = __uword_type; +pub type __blksize_t = __slongword_type; +pub type __fsid_t = __uquad_type; +pub type __ssize_t = __sword_type; +pub type __syscall_slong_t = __slongword_type; +pub type __syscall_ulong_t = __ulongword_type; +pub type __cpu_mask = __ulongword_type; + +pub type __loff_t = __off64_t; +pub type __caddr_t = *mut ::c_char; +pub type __intptr_t = __sword_type; +pub type __ptrdiff_t = __sword_type; +pub type __socklen_t = __u32_type; +pub type __sig_atomic_t = ::c_int; +pub type __time64_t = __int64_t; +pub type ssize_t = __ssize_t; +pub type size_t = ::c_ulong; +pub type wchar_t = ::c_int; +pub type wint_t = ::c_uint; +pub type gid_t = __gid_t; +pub type uid_t = __uid_t; +pub type off_t = __off_t; +pub type off64_t = __off64_t; +pub type useconds_t = __useconds_t; +pub type pid_t = __pid_t; +pub type socklen_t = __socklen_t; + +pub type in_addr_t = u32; + +pub type _Float32 = f32; +pub type _Float64 = f64; +pub type _Float32x = f64; +pub type _Float64x = f64; + +pub type __locale_t = *mut __locale_struct; +pub type locale_t = __locale_t; + +pub type u_char = __u_char; +pub type u_short = __u_short; +pub type u_int = __u_int; +pub type u_long = __u_long; +pub type quad_t = __quad_t; +pub type u_quad_t = __u_quad_t; +pub type fsid_t = __fsid_t; +pub type loff_t = __loff_t; +pub type ino_t = __ino_t; +pub type ino64_t = __ino64_t; +pub type dev_t = __dev_t; +pub type mode_t = __mode_t; +pub type nlink_t = __nlink_t; +pub type id_t = __id_t; +pub type daddr_t = __daddr_t; +pub type caddr_t = __caddr_t; +pub type key_t = __key_t; +pub type clock_t = __clock_t; +pub type clockid_t = __clockid_t; +pub type time_t = __time_t; +pub type timer_t = __timer_t; +pub type suseconds_t = __suseconds_t; +pub type ulong = ::c_ulong; +pub type ushort = ::c_ushort; +pub type uint = ::c_uint; +pub type u_int8_t = __uint8_t; +pub type u_int16_t = __uint16_t; +pub type u_int32_t = __uint32_t; +pub type u_int64_t = __uint64_t; +pub type register_t = ::c_int; +pub type __sigset_t = ::c_ulong; +pub type sigset_t = __sigset_t; + +pub type __fd_mask = ::c_long; +pub type fd_mask = __fd_mask; +pub type blksize_t = __blksize_t; +pub type blkcnt_t = __blkcnt_t; +pub type fsblkcnt_t = __fsblkcnt_t; +pub type fsfilcnt_t = __fsfilcnt_t; +pub type blkcnt64_t = __blkcnt64_t; +pub type fsblkcnt64_t = __fsblkcnt64_t; +pub type fsfilcnt64_t = __fsfilcnt64_t; + +pub type __pthread_spinlock_t = ::c_int; +pub type __tss_t = ::c_int; +pub type __thrd_t = ::c_long; +pub type __pthread_t = ::c_long; +pub type pthread_t = __pthread_t; +pub type __pthread_process_shared = ::c_uint; +pub type __pthread_inheritsched = ::c_uint; +pub type __pthread_contentionscope = ::c_uint; +pub type __pthread_detachstate = ::c_uint; +pub type pthread_attr_t = __pthread_attr; +pub type __pthread_mutex_protocol = ::c_uint; +pub type __pthread_mutex_type = ::c_uint; +pub type __pthread_mutex_robustness = ::c_uint; +pub type pthread_mutexattr_t = __pthread_mutexattr; +pub type pthread_mutex_t = __pthread_mutex; +pub type pthread_condattr_t = __pthread_condattr; +pub type pthread_cond_t = __pthread_cond; +pub type pthread_spinlock_t = __pthread_spinlock_t; +pub type pthread_rwlockattr_t = __pthread_rwlockattr; +pub type pthread_rwlock_t = __pthread_rwlock; +pub type pthread_barrierattr_t = __pthread_barrierattr; +pub type pthread_barrier_t = __pthread_barrier; +pub type __pthread_key = ::c_int; +pub type pthread_key_t = __pthread_key; +pub type pthread_once_t = __pthread_once; + +pub type __rlimit_resource = ::c_uint; +pub type __rlimit_resource_t = __rlimit_resource; +pub type rlim_t = __rlim_t; +pub type rlim64_t = __rlim64_t; + +pub type __rusage_who = ::c_int; + +pub type __priority_which = ::c_uint; + +pub type sa_family_t = ::c_uchar; + +pub type in_port_t = u16; + +pub type __sigval_t = ::sigval; + +pub type sigevent_t = sigevent; + +pub type nfds_t = ::c_ulong; + +pub type tcflag_t = ::c_uint; +pub type cc_t = ::c_uchar; +pub type speed_t = ::c_int; + +pub type sigval_t = ::sigval; + +pub type greg_t = ::c_int; +pub type gregset_t = [greg_t; 19usize]; + +pub type __ioctl_dir = ::c_uint; + +pub type __ioctl_datum = ::c_uint; + +pub type __error_t_codes = ::c_int; + +pub type int_least8_t = __int_least8_t; +pub type int_least16_t = __int_least16_t; +pub type int_least32_t = __int_least32_t; +pub type int_least64_t = __int_least64_t; +pub type uint_least8_t = __uint_least8_t; +pub type uint_least16_t = __uint_least16_t; +pub type uint_least32_t = __uint_least32_t; +pub type uint_least64_t = __uint_least64_t; +pub type int_fast8_t = ::c_schar; +pub type uint_fast8_t = ::c_uchar; +pub type intmax_t = __intmax_t; +pub type uintmax_t = __uintmax_t; + +pub type tcp_seq = u32; + +pub type tcp_ca_state = ::c_uint; + +pub type idtype_t = ::c_uint; + +pub type mqd_t = ::c_int; + +pub type Lmid_t = ::c_long; + +pub type regoff_t = ::c_int; + +pub type nl_item = ::c_int; + +pub type iconv_t = *mut ::c_void; + +#[cfg_attr(feature = "extra_traits", derive(Debug))] +pub enum fpos64_t {} // FIXME: fill this out with a struct +impl ::Copy for fpos64_t {} +impl ::Clone for fpos64_t { + fn clone(&self) -> fpos64_t { + *self + } +} + +#[cfg_attr(feature = "extra_traits", derive(Debug))] +pub enum timezone {} +impl ::Copy for timezone {} +impl ::Clone for timezone { + fn clone(&self) -> timezone { + *self + } +} + +// structs +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_interface: in_addr, + pub imr_sourceaddr: in_addr, + } + + pub struct sockaddr { + pub sa_len: ::c_uchar, + pub sa_family: sa_family_t, + pub sa_data: [::c_char; 14usize], + } + + pub struct in_addr { + pub s_addr: in_addr_t, + } + + 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_uchar; 8usize], + } + + pub struct sockaddr_in6 { + pub sin6_len: ::c_uchar, + 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; 108usize], + } + + pub struct sockaddr_storage { + pub ss_len: ::c_uchar, + pub ss_family: sa_family_t, + pub __ss_padding: [::c_char; 122usize], + pub __ss_align: __uint32_t, + } + + pub struct sockaddr_at { + pub _address: u8, + } + + pub struct sockaddr_ax25 { + pub _address: u8, + } + + pub struct sockaddr_x25 { + pub _address: u8, + } + + pub struct sockaddr_dl { + pub _address: u8, + } + pub struct sockaddr_eon { + pub _address: u8, + } + pub struct sockaddr_inarp { + pub _address: u8, + } + + pub struct sockaddr_ipx { + pub _address: u8, + } + pub struct sockaddr_iso { + pub _address: u8, + } + + pub struct sockaddr_ns { + pub _address: u8, + } + + 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_addr: *mut sockaddr, + pub ai_canonname: *mut ::c_char, + pub ai_next: *mut addrinfo, + } + + 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 dirent { + pub d_ino: __ino_t, + pub d_reclen: ::c_ushort, + pub d_type: ::c_uchar, + pub d_namlen: ::c_uchar, + pub d_name: [::c_char; 1usize], + } + + pub struct dirent64 { + pub d_ino: __ino64_t, + pub d_reclen: ::c_ushort, + pub d_type: ::c_uchar, + pub d_namlen: ::c_uchar, + pub d_name: [::c_char; 1usize], + } + + pub struct fd_set { + pub fds_bits: [__fd_mask; 8usize], + } + + 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; 20usize], + pub __ispeed: ::speed_t, + pub __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 mallinfo2 { + 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 sigaction { + pub sa_sigaction: ::sighandler_t, + pub sa_mask: __sigset_t, + pub sa_flags: ::c_int, + } + + pub struct sigevent { + pub sigev_value: ::sigval, + pub sigev_signo: ::c_int, + pub sigev_notify: ::c_int, + __unused1: *mut ::c_void, //actually a function pointer + pub sigev_notify_attributes: *mut pthread_attr_t, + } + + 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_addr: *mut ::c_void, + pub si_status: ::c_int, + pub si_band: ::c_long, + pub si_value: ::sigval, + } + + pub struct timespec { + pub tv_sec: __time_t, + pub tv_nsec: __syscall_slong_t, + } + + pub struct __timeval { + pub tv_sec: i32, + pub tv_usec: i32, + } + + pub struct __locale_data { + pub _address: u8, + } + + pub struct stat { + pub st_fstype: ::c_int, + pub st_dev: __fsid_t, /* Actually st_fsid */ + pub st_ino: __ino_t, + pub st_gen: ::c_uint, + pub st_rdev: __dev_t, + pub st_mode: __mode_t, + pub st_nlink: __nlink_t, + pub st_uid: __uid_t, + pub st_gid: __gid_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_author: __uid_t, + pub st_flags: ::c_uint, + pub st_spare: [::c_int; 11usize], + } + + pub struct stat64 { + pub st_fstype: ::c_int, + pub st_fsid: __fsid_t, + pub st_ino: __ino64_t, + pub st_gen: ::c_uint, + pub st_rdev: __dev_t, + pub st_mode: __mode_t, + pub st_nlink: __nlink_t, + pub st_uid: __uid_t, + pub st_gid: __gid_t, + pub st_size: __off64_t, + pub st_atim: ::timespec, + pub st_mtim: ::timespec, + pub st_ctim: ::timespec, + pub st_blksize: __blksize_t, + pub st_blocks: __blkcnt64_t, + pub st_author: __uid_t, + pub st_flags: ::c_uint, + pub st_spare: [::c_int; 8usize], + } + + pub struct statx { + pub stx_mask: u32, + pub stx_blksize: u32, + pub stx_attributes: u64, + pub stx_nlink: u32, + pub stx_uid: u32, + pub stx_gid: u32, + pub stx_mode: u16, + __statx_pad1: [u16; 1], + pub stx_ino: u64, + pub stx_size: u64, + pub stx_blocks: u64, + pub stx_attributes_mask: u64, + pub stx_atime: ::statx_timestamp, + pub stx_btime: ::statx_timestamp, + pub stx_ctime: ::statx_timestamp, + pub stx_mtime: ::statx_timestamp, + pub stx_rdev_major: u32, + pub stx_rdev_minor: u32, + pub stx_dev_major: u32, + pub stx_dev_minor: u32, + __statx_pad2: [u64; 14], + } + + pub struct statx_timestamp { + pub tv_sec: i64, + pub tv_nsec: u32, + pub __statx_timestamp_pad1: [i32; 1], + } + + pub struct statfs { + pub f_type: ::c_uint, + 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: __fsid_t, + pub f_namelen: ::c_ulong, + pub f_favail: __fsfilcnt_t, + pub f_frsize: ::c_ulong, + pub f_flag: ::c_ulong, + pub f_spare: [::c_uint; 3usize], + } + + pub struct statfs64 { + pub f_type: ::c_uint, + pub f_bsize: ::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_fsid: __fsid_t, + pub f_namelen: ::c_ulong, + pub f_favail: __fsfilcnt64_t, + pub f_frsize: ::c_ulong, + pub f_flag: ::c_ulong, + pub f_spare: [::c_uint ; 3usize], + } + + pub struct statvfs { + pub __f_type: ::c_uint, + 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_namemax: ::c_ulong, + pub f_favail: __fsfilcnt_t, + pub f_frsize: ::c_ulong, + pub f_flag: ::c_ulong, + pub f_spare: [::c_uint; 3usize], + } + + pub struct statvfs64 { + pub __f_type: ::c_uint, + pub f_bsize: ::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_fsid: __fsid_t, + pub f_namemax: ::c_ulong, + pub f_favail: __fsfilcnt64_t, + pub f_frsize: ::c_ulong, + pub f_flag: ::c_ulong, + pub f_spare: [::c_uint; 3usize], + } + + pub struct aiocb { + pub aio_fildes: ::c_int, + pub aio_lio_opcode: ::c_int, + pub aio_reqprio: ::c_int, + pub aio_buf: *mut ::c_void, + pub aio_nbytes: ::size_t, + pub aio_sigevent: ::sigevent, + __next_prio: *mut aiocb, + __abs_prio: ::c_int, + __policy: ::c_int, + __error_code: ::c_int, + __return_value: ::ssize_t, + pub aio_offset: off_t, + #[cfg(all(not(target_arch = "x86_64"), target_pointer_width = "32"))] + __unused1: [::c_char; 4], + __glibc_reserved: [::c_char; 32] + } + + 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 __exit_status { + pub e_termination: ::c_short, + pub e_exit: ::c_short, + } + + #[cfg_attr(target_pointer_width = "32", + repr(align(4)))] + #[cfg_attr(target_pointer_width = "64", + repr(align(8)))] + pub struct sem_t { + __size: [::c_char; 20usize], + } + + pub struct __pthread { + pub _address: u8, + } + + pub struct __pthread_mutexattr { + pub __prioceiling: ::c_int, + pub __protocol: __pthread_mutex_protocol, + pub __pshared: __pthread_process_shared, + pub __mutex_type: __pthread_mutex_type, + } + pub struct __pthread_mutex { + pub __lock: ::c_uint, + pub __owner_id: ::c_uint, + pub __cnt: ::c_uint, + pub __shpid: ::c_int, + pub __type: ::c_int, + pub __flags: ::c_int, + pub __reserved1: ::c_uint, + pub __reserved2: ::c_uint, + } + + pub struct __pthread_condattr { + pub __pshared: __pthread_process_shared, + pub __clock: __clockid_t, + } + + pub struct __pthread_rwlockattr { + pub __pshared: __pthread_process_shared, + } + + pub struct __pthread_barrierattr { + pub __pshared: __pthread_process_shared, + } + + pub struct __pthread_once { + pub __run: ::c_int, + pub __lock: __pthread_spinlock_t, + } + + pub struct __pthread_cond { + pub __lock: __pthread_spinlock_t, + pub __queue: *mut __pthread, + pub __attr: *mut __pthread_condattr, + pub __wrefs: ::c_uint, + pub __data: *mut ::c_void, + } + + pub struct __pthread_attr { + pub __schedparam: sched_param, + pub __stackaddr: *mut ::c_void, + pub __stacksize: size_t, + pub __guardsize: size_t, + pub __detachstate: __pthread_detachstate, + pub __inheritsched: __pthread_inheritsched, + pub __contentionscope: __pthread_contentionscope, + pub __schedpolicy: ::c_int, + } + + pub struct __pthread_rwlock { + pub __held: __pthread_spinlock_t, + pub __lock: __pthread_spinlock_t, + pub __readers: ::c_int, + pub __readerqueue: *mut __pthread, + pub __writerqueue: *mut __pthread, + pub __attr: *mut __pthread_rwlockattr, + pub __data: *mut ::c_void, + } + + pub struct __pthread_barrier { + pub __lock: __pthread_spinlock_t, + pub __queue: *mut __pthread, + pub __pending: ::c_uint, + pub __count: ::c_uint, + pub __attr: *mut __pthread_barrierattr, + pub __data: *mut ::c_void, + } + + 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 _IO_FILE { + _unused: [u8; 0], + } + + pub struct sched_param { + pub sched_priority: ::c_int, + } + + pub struct iovec { + pub iov_base: *mut ::c_void, + pub iov_len: size_t, + } + + 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 spwd { + pub sp_namp: *mut ::c_char, + pub sp_pwdp: *mut ::c_char, + pub sp_lstchg: ::c_long, + pub sp_min: ::c_long, + pub sp_max: ::c_long, + pub sp_warn: ::c_long, + pub sp_inact: ::c_long, + pub sp_expire: ::c_long, + pub sp_flag: ::c_ulong, + } + + pub struct itimerspec { + pub it_interval: ::timespec, + pub it_value: ::timespec, + } + + 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, + } + + 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_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 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 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_ifu: *mut ::sockaddr, // FIXME This should be a union + pub ifa_data: *mut ::c_void + } + + pub struct arpreq { + pub arp_pa: ::sockaddr, + pub arp_ha: ::sockaddr, + pub arp_flags: ::c_int, + pub arp_netmask: ::sockaddr, + pub arp_dev: [::c_char; 16], + } + + pub struct arpreq_old { + pub arp_pa: ::sockaddr, + pub arp_ha: ::sockaddr, + pub arp_flags: ::c_int, + pub arp_netmask: ::sockaddr, + } + + 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 arpd_request { + pub req: ::c_ushort, + pub ip: u32, + pub dev: ::c_ulong, + pub stamp: ::c_ulong, + pub updated: ::c_ulong, + pub ha: [::c_uchar; ::MAX_ADDR_LEN], + } + + pub struct mmsghdr { + pub msg_hdr: ::msghdr, + pub msg_len: ::c_uint, + } + + pub struct ifreq { + /// interface name, e.g. "en0" + pub ifr_name: [::c_char; ::IFNAMSIZ], + pub ifr_ifru: ::sockaddr, + } + + pub struct __locale_struct { + pub __locales: [*mut __locale_data; 13usize], + pub __ctype_b: *const ::c_ushort, + pub __ctype_tolower: *const ::c_int, + pub __ctype_toupper: *const ::c_int, + pub __names: [*const ::c_char; 13usize], + } + + pub struct utsname { + pub sysname: [::c_char; 65], + pub nodename: [::c_char; 65], + pub release: [::c_char; 65], + pub version: [::c_char; 65], + pub machine: [::c_char; 65], + pub domainname: [::c_char; 65] + } + + pub struct rlimit64 { + pub rlim_cur: rlim64_t, + pub rlim_max: rlim64_t, + } + + pub struct stack_t { + pub ss_sp: * mut ::c_void, + pub ss_size: ::size_t, + pub ss_flags: ::c_int, + } + + 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, + pub dlpi_adds: ::c_ulonglong, + pub dlpi_subs: ::c_ulonglong, + pub dlpi_tls_modid: ::size_t, + pub dlpi_tls_data: *mut ::c_void, + } + + pub struct flock { + #[cfg(target_pointer_width = "32")] + pub l_type : ::c_int, + #[cfg(target_pointer_width = "32")] + pub l_whence : ::c_int, + #[cfg(target_pointer_width = "64")] + pub l_type : ::c_short, + #[cfg(target_pointer_width = "64")] + pub l_whence : ::c_short, + pub l_start : __off_t, + pub l_len : __off_t, + pub l_pid : __pid_t, + } + + pub struct flock64 { + #[cfg(target_pointer_width = "32")] + pub l_type : ::c_int, + #[cfg(target_pointer_width = "32")] + pub l_whence : ::c_int, + #[cfg(target_pointer_width = "64")] + pub l_type : ::c_short, + #[cfg(target_pointer_width = "64")] + pub l_whence : ::c_short, + pub l_start : __off_t, + pub l_len : __off64_t, + pub l_pid : __pid_t, + } + + pub struct glob_t { + pub gl_pathc: ::size_t, + pub gl_pathv: *mut *mut c_char, + pub gl_offs: ::size_t, + pub gl_flags: ::c_int, + + __unused1: *mut ::c_void, + __unused2: *mut ::c_void, + __unused3: *mut ::c_void, + __unused4: *mut ::c_void, + __unused5: *mut ::c_void, + } + + pub struct glob64_t { + pub gl_pathc: ::size_t, + pub gl_pathv: *mut *mut ::c_char, + pub gl_offs: ::size_t, + pub gl_flags: ::c_int, + + __unused1: *mut ::c_void, + __unused2: *mut ::c_void, + __unused3: *mut ::c_void, + __unused4: *mut ::c_void, + __unused5: *mut ::c_void, + } + + 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 cpu_set_t { + #[cfg(all(target_pointer_width = "32", + not(target_arch = "x86_64")))] + bits: [u32; 32], + #[cfg(not(all(target_pointer_width = "32", + not(target_arch = "x86_64"))))] + bits: [u64; 16], + } + + pub struct if_nameindex { + pub if_index: ::c_uint, + pub if_name: *mut ::c_char, + } + + // System V IPC + pub struct msginfo { + pub msgpool: ::c_int, + pub msgmap: ::c_int, + pub msgmax: ::c_int, + pub msgmnb: ::c_int, + pub msgmni: ::c_int, + pub msgssz: ::c_int, + pub msgtql: ::c_int, + pub msgseg: ::c_ushort, + } + + pub struct sembuf { + pub sem_num: ::c_ushort, + pub sem_op: ::c_short, + pub sem_flg: ::c_short, + } + + 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 posix_spawn_file_actions_t { + __allocated: ::c_int, + __used: ::c_int, + __actions: *mut ::c_int, + __pad: [::c_int; 16], + } + + pub struct posix_spawnattr_t { + __flags: ::c_short, + __pgrp: ::pid_t, + __sd: ::sigset_t, + __ss: ::sigset_t, + __sp: ::sched_param, + __policy: ::c_int, + __pad: [::c_int; 16], + } + + pub struct regmatch_t { + 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! { + pub struct utmpx { + pub ut_type: ::c_short, + pub ut_pid: ::pid_t, + pub ut_line: [::c_char; __UT_LINESIZE], + pub ut_id: [::c_char; 4], + + pub ut_user: [::c_char; __UT_NAMESIZE], + pub ut_host: [::c_char; __UT_HOSTSIZE], + pub ut_exit: __exit_status, + + #[cfg(any( all(target_pointer_width = "32", + not(target_arch = "x86_64"))))] + pub ut_session: ::c_long, + #[cfg(any(all(target_pointer_width = "32", + not(target_arch = "x86_64"))))] + pub ut_tv: ::timeval, + + #[cfg(not(any(all(target_pointer_width = "32", + not(target_arch = "x86_64")))))] + pub ut_session: i32, + #[cfg(not(any(all(target_pointer_width = "32", + not(target_arch = "x86_64")))))] + pub ut_tv: __timeval, + + pub ut_addr_v6: [i32; 4], + __glibc_reserved: [::c_char; 20], + } +} + +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_pid == other.ut_pid + && self.ut_line == other.ut_line + && self.ut_id == other.ut_id + && self.ut_user == other.ut_user + && self + .ut_host + .iter() + .zip(other.ut_host.iter()) + .all(|(a,b)| a == b) + && self.ut_exit == other.ut_exit + && self.ut_session == other.ut_session + && self.ut_tv == other.ut_tv + && self.ut_addr_v6 == other.ut_addr_v6 + && self.__glibc_reserved == other.__glibc_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_pid", &self.ut_pid) + .field("ut_line", &self.ut_line) + .field("ut_id", &self.ut_id) + .field("ut_user", &self.ut_user) + // FIXME: .field("ut_host", &self.ut_host) + .field("ut_exit", &self.ut_exit) + .field("ut_session", &self.ut_session) + .field("ut_tv", &self.ut_tv) + .field("ut_addr_v6", &self.ut_addr_v6) + .field("__glibc_reserved", &self.__glibc_reserved) + .finish() + } + } + + impl ::hash::Hash for utmpx { + fn hash(&self, state: &mut H) { + self.ut_type.hash(state); + self.ut_pid.hash(state); + self.ut_line.hash(state); + self.ut_id.hash(state); + self.ut_user.hash(state); + self.ut_host.hash(state); + self.ut_exit.hash(state); + self.ut_session.hash(state); + self.ut_tv.hash(state); + self.ut_addr_v6.hash(state); + self.__glibc_reserved.hash(state); + } + } + } +} + +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 + } +} + +// const + +// aio.h +pub const AIO_CANCELED: ::c_int = 0; +pub const AIO_NOTCANCELED: ::c_int = 1; +pub const AIO_ALLDONE: ::c_int = 2; +pub const LIO_READ: ::c_int = 0; +pub const LIO_WRITE: ::c_int = 1; +pub const LIO_NOP: ::c_int = 2; +pub const LIO_WAIT: ::c_int = 0; +pub const LIO_NOWAIT: ::c_int = 1; + +// glob.h +pub const GLOB_ERR: ::c_int = 1 << 0; +pub const GLOB_MARK: ::c_int = 1 << 1; +pub const GLOB_NOSORT: ::c_int = 1 << 2; +pub const GLOB_DOOFFS: ::c_int = 1 << 3; +pub const GLOB_NOCHECK: ::c_int = 1 << 4; +pub const GLOB_APPEND: ::c_int = 1 << 5; +pub const GLOB_NOESCAPE: ::c_int = 1 << 6; + +pub const GLOB_NOSPACE: ::c_int = 1; +pub const GLOB_ABORTED: ::c_int = 2; +pub const GLOB_NOMATCH: ::c_int = 3; + +pub const GLOB_PERIOD: ::c_int = 1 << 7; +pub const GLOB_ALTDIRFUNC: ::c_int = 1 << 9; +pub const GLOB_BRACE: ::c_int = 1 << 10; +pub const GLOB_NOMAGIC: ::c_int = 1 << 11; +pub const GLOB_TILDE: ::c_int = 1 << 12; +pub const GLOB_ONLYDIR: ::c_int = 1 << 13; +pub const GLOB_TILDE_CHECK: ::c_int = 1 << 14; + +// ipc.h +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 MSG_STAT: ::c_int = 11; +pub const MSG_INFO: ::c_int = 12; + +pub const MSG_NOERROR: ::c_int = 0o10000; +pub const MSG_EXCEPT: ::c_int = 0o20000; + +// 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_REMAP: ::c_int = 0o40000; + +pub const SHM_LOCK: ::c_int = 11; +pub const SHM_UNLOCK: ::c_int = 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 __FD_SETSIZE: usize = 256; +pub const R_OK: ::c_int = 4; +pub const W_OK: ::c_int = 2; +pub const X_OK: ::c_int = 1; +pub const F_OK: ::c_int = 0; +pub const SEEK_SET: ::c_int = 0; +pub const SEEK_CUR: ::c_int = 1; +pub const SEEK_END: ::c_int = 2; +pub const SEEK_DATA: ::c_int = 3; +pub const SEEK_HOLE: ::c_int = 4; +pub const L_SET: ::c_int = 0; +pub const L_INCR: ::c_int = 1; +pub const L_XTND: ::c_int = 2; +pub const F_ULOCK: ::c_int = 0; +pub const F_LOCK: ::c_int = 1; +pub const F_TLOCK: ::c_int = 2; +pub const F_TEST: ::c_int = 3; +pub const CLOSE_RANGE_CLOEXEC: ::c_int = 4; + +// stdio.h +pub const EOF: ::c_int = -1; + +// stdlib.h +pub const WNOHANG: ::c_int = 1; +pub const WUNTRACED: ::c_int = 2; +pub const WSTOPPED: ::c_int = 2; +pub const WCONTINUED: ::c_int = 4; +pub const WNOWAIT: ::c_int = 8; +pub const WEXITED: ::c_int = 16; +pub const __W_CONTINUED: ::c_int = 65535; +pub const __WCOREFLAG: ::c_int = 128; +pub const RAND_MAX: ::c_int = 2147483647; +pub const EXIT_FAILURE: ::c_int = 1; +pub const EXIT_SUCCESS: ::c_int = 0; +pub const __LITTLE_ENDIAN: usize = 1234; +pub const __BIG_ENDIAN: usize = 4321; +pub const __PDP_ENDIAN: usize = 3412; +pub const __BYTE_ORDER: usize = 1234; +pub const __FLOAT_WORD_ORDER: usize = 1234; +pub const LITTLE_ENDIAN: usize = 1234; +pub const BIG_ENDIAN: usize = 4321; +pub const PDP_ENDIAN: usize = 3412; +pub const BYTE_ORDER: usize = 1234; + +// sys/select.h +pub const FD_SETSIZE: usize = 256; +pub const __SIZEOF_PTHREAD_MUTEX_T: usize = 32; +pub const __SIZEOF_PTHREAD_ATTR_T: usize = 32; +pub const __SIZEOF_PTHREAD_RWLOCK_T: usize = 28; +pub const __SIZEOF_PTHREAD_BARRIER_T: usize = 24; +pub const __SIZEOF_PTHREAD_MUTEXATTR_T: usize = 16; +pub const __SIZEOF_PTHREAD_COND_T: usize = 20; +pub const __SIZEOF_PTHREAD_CONDATTR_T: usize = 8; +pub const __SIZEOF_PTHREAD_RWLOCKATTR_T: usize = 4; +pub const __SIZEOF_PTHREAD_BARRIERATTR_T: usize = 4; +pub const __SIZEOF_PTHREAD_ONCE_T: usize = 8; +pub const __PTHREAD_SPIN_LOCK_INITIALIZER: ::c_int = 0; +pub const PTHREAD_MUTEX_NORMAL: ::c_int = 0; + +// sys/resource.h +pub const RLIM_INFINITY: ::rlim_t = 2147483647; +pub const RLIM64_INFINITY: ::rlim64_t = 9223372036854775807; +pub const RLIM_SAVED_MAX: ::rlim_t = RLIM_INFINITY; +pub const RLIM_SAVED_CUR: ::rlim_t = RLIM_INFINITY; +pub const PRIO_MIN: ::c_int = -20; +pub const PRIO_MAX: ::c_int = 20; + +// pwd.h +pub const NSS_BUFLEN_PASSWD: usize = 1024; + +// sys/socket.h +pub const SOCK_TYPE_MASK: usize = 15; +pub const PF_UNSPEC: ::c_int = 0; +pub const PF_LOCAL: ::c_int = 1; +pub const PF_UNIX: ::c_int = 1; +pub const PF_FILE: ::c_int = 1; +pub const PF_INET: ::c_int = 2; +pub const PF_IMPLINK: ::c_int = 3; +pub const PF_PUP: ::c_int = 4; +pub const PF_CHAOS: ::c_int = 5; +pub const PF_NS: ::c_int = 6; +pub const PF_ISO: ::c_int = 7; +pub const PF_OSI: ::c_int = 7; +pub const PF_ECMA: ::c_int = 8; +pub const PF_DATAKIT: ::c_int = 9; +pub const PF_CCITT: ::c_int = 10; +pub const PF_SNA: ::c_int = 11; +pub const PF_DECnet: ::c_int = 12; +pub const PF_DLI: ::c_int = 13; +pub const PF_LAT: ::c_int = 14; +pub const PF_HYLINK: ::c_int = 15; +pub const PF_APPLETALK: ::c_int = 16; +pub const PF_ROUTE: ::c_int = 17; +pub const PF_XTP: ::c_int = 19; +pub const PF_COIP: ::c_int = 20; +pub const PF_CNT: ::c_int = 21; +pub const PF_RTIP: ::c_int = 22; +pub const PF_IPX: ::c_int = 23; +pub const PF_SIP: ::c_int = 24; +pub const PF_PIP: ::c_int = 25; +pub const PF_INET6: ::c_int = 26; +pub const PF_MAX: ::c_int = 27; +pub const AF_UNSPEC: ::c_int = 0; +pub const AF_LOCAL: ::c_int = 1; +pub const AF_UNIX: ::c_int = 1; +pub const AF_FILE: ::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_ISO: ::c_int = 7; +pub const AF_OSI: ::c_int = 7; +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 AF_HYLINK: ::c_int = 15; +pub const AF_APPLETALK: ::c_int = 16; +pub const AF_ROUTE: ::c_int = 17; +pub const pseudo_AF_XTP: ::c_int = 19; +pub const AF_COIP: ::c_int = 20; +pub const AF_CNT: ::c_int = 21; +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_INET6: ::c_int = 26; +pub const AF_MAX: ::c_int = 27; +pub const SOMAXCONN: ::c_int = 4096; +pub const _SS_SIZE: usize = 128; +pub const CMGROUP_MAX: usize = 16; +pub const SOL_SOCKET: ::c_int = 65535; + +// sys/time.h +pub const ITIMER_REAL: ::c_int = 0; +pub const ITIMER_VIRTUAL: ::c_int = 1; +pub const ITIMER_PROF: ::c_int = 2; + +// netinet/in.h +pub const SOL_IP: ::c_int = 0; +pub const SOL_TCP: ::c_int = 6; +pub const SOL_UDP: ::c_int = 17; +pub const SOL_IPV6: ::c_int = 41; +pub const SOL_ICMPV6: ::c_int = 58; +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_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_LOOP: ::c_int = 11; +pub const IP_ADD_MEMBERSHIP: ::c_int = 12; +pub const IP_DROP_MEMBERSHIP: ::c_int = 13; +pub const IPV6_ADDRFORM: ::c_int = 1; +pub const IPV6_2292PKTINFO: ::c_int = 2; +pub const IPV6_2292HOPOPTS: ::c_int = 3; +pub const IPV6_2292DSTOPTS: ::c_int = 4; +pub const IPV6_2292RTHDR: ::c_int = 5; +pub const IPV6_2292PKTOPTIONS: ::c_int = 6; +pub const IPV6_CHECKSUM: ::c_int = 7; +pub const IPV6_2292HOPLIMIT: ::c_int = 8; +pub const IPV6_RXINFO: ::c_int = 2; +pub const IPV6_TXINFO: ::c_int = 2; +pub const SCM_SRCINFO: ::c_int = 2; +pub const IPV6_UNICAST_HOPS: ::c_int = 16; +pub const IPV6_MULTICAST_IF: ::c_int = 17; +pub const IPV6_MULTICAST_HOPS: ::c_int = 18; +pub const IPV6_MULTICAST_LOOP: ::c_int = 19; +pub const IPV6_JOIN_GROUP: ::c_int = 20; +pub const IPV6_LEAVE_GROUP: ::c_int = 21; +pub const IPV6_ROUTER_ALERT: ::c_int = 22; +pub const IPV6_MTU_DISCOVER: ::c_int = 23; +pub const IPV6_MTU: ::c_int = 24; +pub const IPV6_RECVERR: ::c_int = 25; +pub const IPV6_V6ONLY: ::c_int = 26; +pub const IPV6_JOIN_ANYCAST: ::c_int = 27; +pub const IPV6_LEAVE_ANYCAST: ::c_int = 28; +pub const IPV6_RECVPKTINFO: ::c_int = 49; +pub const IPV6_PKTINFO: ::c_int = 50; +pub const IPV6_RECVHOPLIMIT: ::c_int = 51; +pub const IPV6_HOPLIMIT: ::c_int = 52; +pub const IPV6_RECVHOPOPTS: ::c_int = 53; +pub const IPV6_HOPOPTS: ::c_int = 54; +pub const IPV6_RTHDRDSTOPTS: ::c_int = 55; +pub const IPV6_RECVRTHDR: ::c_int = 56; +pub const IPV6_RTHDR: ::c_int = 57; +pub const IPV6_RECVDSTOPTS: ::c_int = 58; +pub const IPV6_DSTOPTS: ::c_int = 59; +pub const IPV6_RECVPATHMTU: ::c_int = 60; +pub const IPV6_PATHMTU: ::c_int = 61; +pub const IPV6_DONTFRAG: ::c_int = 62; +pub const IPV6_RECVTCLASS: ::c_int = 66; +pub const IPV6_TCLASS: ::c_int = 67; +pub const IPV6_ADDR_PREFERENCES: ::c_int = 72; +pub const IPV6_MINHOPCOUNT: ::c_int = 73; +pub const IPV6_ADD_MEMBERSHIP: ::c_int = 20; +pub const IPV6_DROP_MEMBERSHIP: ::c_int = 21; +pub const IPV6_RXHOPOPTS: ::c_int = 3; +pub const IPV6_RXDSTOPTS: ::c_int = 4; +pub const IPV6_RTHDR_LOOSE: ::c_int = 0; +pub const IPV6_RTHDR_STRICT: ::c_int = 1; +pub const IPV6_RTHDR_TYPE_0: ::c_int = 0; +pub const IN_CLASSA_NET: u32 = 4278190080; +pub const IN_CLASSA_NSHIFT: usize = 24; +pub const IN_CLASSA_HOST: u32 = 16777215; +pub const IN_CLASSA_MAX: u32 = 128; +pub const IN_CLASSB_NET: u32 = 4294901760; +pub const IN_CLASSB_NSHIFT: usize = 16; +pub const IN_CLASSB_HOST: u32 = 65535; +pub const IN_CLASSB_MAX: u32 = 65536; +pub const IN_CLASSC_NET: u32 = 4294967040; +pub const IN_CLASSC_NSHIFT: usize = 8; +pub const IN_CLASSC_HOST: u32 = 255; +pub const IN_LOOPBACKNET: u32 = 127; +pub const INET_ADDRSTRLEN: usize = 16; +pub const INET6_ADDRSTRLEN: usize = 46; + +// netinet/ip.h +pub const IPTOS_TOS_MASK: u8 = 0x1E; +pub const IPTOS_PREC_MASK: u8 = 0xE0; + +pub const IPTOS_ECN_NOT_ECT: u8 = 0x00; + +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_COPY: u8 = 0x80; +pub const IPOPT_CLASS_MASK: u8 = 0x60; +pub const IPOPT_NUMBER_MASK: u8 = 0x1f; + +pub const IPOPT_CONTROL: u8 = 0x00; +pub const IPOPT_RESERVED1: u8 = 0x20; +pub const IPOPT_MEASUREMENT: u8 = 0x40; +pub const IPOPT_RESERVED2: u8 = 0x60; +pub const IPOPT_END: u8 = 0 | IPOPT_CONTROL; +pub const IPOPT_NOOP: u8 = 1 | IPOPT_CONTROL; +pub const IPOPT_SEC: u8 = 2 | IPOPT_CONTROL | IPOPT_COPY; +pub const IPOPT_LSRR: u8 = 3 | IPOPT_CONTROL | IPOPT_COPY; +pub const IPOPT_TIMESTAMP: u8 = 4 | IPOPT_MEASUREMENT; +pub const IPOPT_RR: u8 = 7 | IPOPT_CONTROL; +pub const IPOPT_SID: u8 = 8 | IPOPT_CONTROL | IPOPT_COPY; +pub const IPOPT_SSRR: u8 = 9 | IPOPT_CONTROL | IPOPT_COPY; +pub const IPOPT_RA: u8 = 20 | IPOPT_CONTROL | IPOPT_COPY; +pub const IPVERSION: u8 = 4; +pub const MAXTTL: u8 = 255; +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 MAX_IPOPTLEN: u8 = 40; +pub const IPOPT_NOP: u8 = IPOPT_NOOP; +pub const IPOPT_EOL: u8 = IPOPT_END; +pub const IPOPT_TS: u8 = IPOPT_TIMESTAMP; +pub const IPOPT_TS_TSONLY: u8 = 0; +pub const IPOPT_TS_TSANDADDR: u8 = 1; +pub const IPOPT_TS_PRESPEC: u8 = 3; + +// net/if_arp.h +pub const ARPOP_REQUEST: u16 = 1; +pub const ARPOP_REPLY: u16 = 2; +pub const ARPOP_RREQUEST: u16 = 3; +pub const ARPOP_RREPLY: u16 = 4; +pub const ARPOP_InREQUEST: u16 = 8; +pub const ARPOP_InREPLY: u16 = 9; +pub const ARPOP_NAK: u16 = 10; + +pub const MAX_ADDR_LEN: usize = 7; +pub const ARPD_UPDATE: ::c_ushort = 0x01; +pub const ARPD_LOOKUP: ::c_ushort = 0x02; +pub const ARPD_FLUSH: ::c_ushort = 0x03; +pub const ATF_MAGIC: ::c_int = 0x80; + +pub const ATF_NETMASK: ::c_int = 0x20; +pub const ATF_DONTPUB: ::c_int = 0x40; + +pub const ARPHRD_NETROM: u16 = 0; +pub const ARPHRD_ETHER: u16 = 1; +pub const ARPHRD_EETHER: u16 = 2; +pub const ARPHRD_AX25: u16 = 3; +pub const ARPHRD_PRONET: u16 = 4; +pub const ARPHRD_CHAOS: u16 = 5; +pub const ARPHRD_IEEE802: u16 = 6; +pub const ARPHRD_ARCNET: u16 = 7; +pub const ARPHRD_APPLETLK: u16 = 8; +pub const ARPHRD_DLCI: u16 = 15; +pub const ARPHRD_ATM: u16 = 19; +pub const ARPHRD_METRICOM: u16 = 23; +pub const ARPHRD_IEEE1394: u16 = 24; +pub const ARPHRD_EUI64: u16 = 27; +pub const ARPHRD_INFINIBAND: u16 = 32; + +pub const ARPHRD_SLIP: u16 = 256; +pub const ARPHRD_CSLIP: u16 = 257; +pub const ARPHRD_SLIP6: u16 = 258; +pub const ARPHRD_CSLIP6: u16 = 259; +pub const ARPHRD_RSRVD: u16 = 260; +pub const ARPHRD_ADAPT: u16 = 264; +pub const ARPHRD_ROSE: u16 = 270; +pub const ARPHRD_X25: u16 = 271; +pub const ARPHRD_HWX25: u16 = 272; +pub const ARPHRD_CAN: u16 = 280; +pub const ARPHRD_PPP: u16 = 512; +pub const ARPHRD_CISCO: u16 = 513; +pub const ARPHRD_HDLC: u16 = ARPHRD_CISCO; +pub const ARPHRD_LAPB: u16 = 516; +pub const ARPHRD_DDCMP: u16 = 517; +pub const ARPHRD_RAWHDLC: u16 = 518; + +pub const ARPHRD_TUNNEL: u16 = 768; +pub const ARPHRD_TUNNEL6: u16 = 769; +pub const ARPHRD_FRAD: u16 = 770; +pub const ARPHRD_SKIP: u16 = 771; +pub const ARPHRD_LOOPBACK: u16 = 772; +pub const ARPHRD_LOCALTLK: u16 = 773; +pub const ARPHRD_FDDI: u16 = 774; +pub const ARPHRD_BIF: u16 = 775; +pub const ARPHRD_SIT: u16 = 776; +pub const ARPHRD_IPDDP: u16 = 777; +pub const ARPHRD_IPGRE: u16 = 778; +pub const ARPHRD_PIMREG: u16 = 779; +pub const ARPHRD_HIPPI: u16 = 780; +pub const ARPHRD_ASH: u16 = 781; +pub const ARPHRD_ECONET: u16 = 782; +pub const ARPHRD_IRDA: u16 = 783; +pub const ARPHRD_FCPP: u16 = 784; +pub const ARPHRD_FCAL: u16 = 785; +pub const ARPHRD_FCPL: u16 = 786; +pub const ARPHRD_FCFABRIC: u16 = 787; +pub const ARPHRD_IEEE802_TR: u16 = 800; +pub const ARPHRD_IEEE80211: u16 = 801; +pub const ARPHRD_IEEE80211_PRISM: u16 = 802; +pub const ARPHRD_IEEE80211_RADIOTAP: u16 = 803; +pub const ARPHRD_IEEE802154: u16 = 804; + +pub const ARPHRD_VOID: u16 = 0xFFFF; +pub const ARPHRD_NONE: u16 = 0xFFFE; + +// bits/posix1_lim.h +pub const _POSIX_AIO_LISTIO_MAX: usize = 2; +pub const _POSIX_AIO_MAX: usize = 1; +pub const _POSIX_ARG_MAX: usize = 4096; +pub const _POSIX_CHILD_MAX: usize = 25; +pub const _POSIX_DELAYTIMER_MAX: usize = 32; +pub const _POSIX_HOST_NAME_MAX: usize = 255; +pub const _POSIX_LINK_MAX: usize = 8; +pub const _POSIX_LOGIN_NAME_MAX: usize = 9; +pub const _POSIX_MAX_CANON: usize = 255; +pub const _POSIX_MAX_INPUT: usize = 255; +pub const _POSIX_MQ_OPEN_MAX: usize = 8; +pub const _POSIX_MQ_PRIO_MAX: usize = 32; +pub const _POSIX_NAME_MAX: usize = 14; +pub const _POSIX_NGROUPS_MAX: usize = 8; +pub const _POSIX_OPEN_MAX: usize = 20; +pub const _POSIX_FD_SETSIZE: usize = 20; +pub const _POSIX_PATH_MAX: usize = 256; +pub const _POSIX_PIPE_BUF: usize = 512; +pub const _POSIX_RE_DUP_MAX: usize = 255; +pub const _POSIX_RTSIG_MAX: usize = 8; +pub const _POSIX_SEM_NSEMS_MAX: usize = 256; +pub const _POSIX_SEM_VALUE_MAX: usize = 32767; +pub const _POSIX_SIGQUEUE_MAX: usize = 32; +pub const _POSIX_SSIZE_MAX: usize = 32767; +pub const _POSIX_STREAM_MAX: usize = 8; +pub const _POSIX_SYMLINK_MAX: usize = 255; +pub const _POSIX_SYMLOOP_MAX: usize = 8; +pub const _POSIX_TIMER_MAX: usize = 32; +pub const _POSIX_TTY_NAME_MAX: usize = 9; +pub const _POSIX_TZNAME_MAX: usize = 6; +pub const _POSIX_QLIMIT: usize = 1; +pub const _POSIX_HIWAT: usize = 512; +pub const _POSIX_UIO_MAXIOV: usize = 16; +pub const _POSIX_CLOCKRES_MIN: usize = 20000000; +pub const NAME_MAX: usize = 255; +pub const NGROUPS_MAX: usize = 256; +pub const _POSIX_THREAD_KEYS_MAX: usize = 128; +pub const _POSIX_THREAD_DESTRUCTOR_ITERATIONS: usize = 4; +pub const _POSIX_THREAD_THREADS_MAX: usize = 64; +pub const SEM_VALUE_MAX: ::c_int = 2147483647; +pub const MAXNAMLEN: usize = 255; + +// netdb.h +pub const _PATH_HEQUIV: &'static [u8; 17usize] = b"/etc/hosts.equiv\0"; +pub const _PATH_HOSTS: &'static [u8; 11usize] = b"/etc/hosts\0"; +pub const _PATH_NETWORKS: &'static [u8; 14usize] = b"/etc/networks\0"; +pub const _PATH_NSSWITCH_CONF: &'static [u8; 19usize] = b"/etc/nsswitch.conf\0"; +pub const _PATH_PROTOCOLS: &'static [u8; 15usize] = b"/etc/protocols\0"; +pub const _PATH_SERVICES: &'static [u8; 14usize] = b"/etc/services\0"; +pub const HOST_NOT_FOUND: ::c_int = 1; +pub const TRY_AGAIN: ::c_int = 2; +pub const NO_RECOVERY: ::c_int = 3; +pub const NO_DATA: ::c_int = 4; +pub const NETDB_INTERNAL: ::c_int = -1; +pub const NETDB_SUCCESS: ::c_int = 0; +pub const NO_ADDRESS: ::c_int = 4; +pub const IPPORT_RESERVED: ::c_int = 1024; +pub const SCOPE_DELIMITER: u8 = 37u8; +pub const GAI_WAIT: ::c_int = 0; +pub const GAI_NOWAIT: ::c_int = 1; +pub const AI_PASSIVE: ::c_int = 1; +pub const AI_CANONNAME: ::c_int = 2; +pub const AI_NUMERICHOST: ::c_int = 4; +pub const AI_V4MAPPED: ::c_int = 8; +pub const AI_ALL: ::c_int = 16; +pub const AI_ADDRCONFIG: ::c_int = 32; +pub const AI_IDN: ::c_int = 64; +pub const AI_CANONIDN: ::c_int = 128; +pub const AI_NUMERICSERV: ::c_int = 1024; +pub const EAI_BADFLAGS: ::c_int = -1; +pub const EAI_NONAME: ::c_int = -2; +pub const EAI_AGAIN: ::c_int = -3; +pub const EAI_FAIL: ::c_int = -4; +pub const EAI_FAMILY: ::c_int = -6; +pub const EAI_SOCKTYPE: ::c_int = -7; +pub const EAI_SERVICE: ::c_int = -8; +pub const EAI_MEMORY: ::c_int = -10; +pub const EAI_SYSTEM: ::c_int = -11; +pub const EAI_OVERFLOW: ::c_int = -12; +pub const EAI_NODATA: ::c_int = -5; +pub const EAI_ADDRFAMILY: ::c_int = -9; +pub const EAI_INPROGRESS: ::c_int = -100; +pub const EAI_CANCELED: ::c_int = -101; +pub const EAI_NOTCANCELED: ::c_int = -102; +pub const EAI_ALLDONE: ::c_int = -103; +pub const EAI_INTR: ::c_int = -104; +pub const EAI_IDN_ENCODE: ::c_int = -105; +pub const NI_MAXHOST: usize = 1025; +pub const NI_MAXSERV: usize = 32; +pub const NI_NUMERICHOST: ::c_int = 1; +pub const NI_NUMERICSERV: ::c_int = 2; +pub const NI_NOFQDN: ::c_int = 4; +pub const NI_NAMEREQD: ::c_int = 8; +pub const NI_DGRAM: ::c_int = 16; +pub const NI_IDN: ::c_int = 32; + +// time.h +pub const CLOCK_REALTIME: ::clockid_t = 0; +pub const CLOCK_MONOTONIC: ::clockid_t = 1; +pub const CLOCK_PROCESS_CPUTIME_ID: ::clockid_t = 2; +pub const CLOCK_THREAD_CPUTIME_ID: ::clockid_t = 3; +pub const CLOCK_MONOTONIC_RAW: ::clockid_t = 4; +pub const CLOCK_REALTIME_COARSE: ::clockid_t = 5; +pub const CLOCK_MONOTONIC_COARSE: ::clockid_t = 6; +pub const TIMER_ABSTIME: ::c_int = 1; +pub const TIME_UTC: ::c_int = 1; + +// sys/poll.h +pub const POLLIN: i16 = 1; +pub const POLLPRI: i16 = 2; +pub const POLLOUT: i16 = 4; +pub const POLLRDNORM: i16 = 1; +pub const POLLRDBAND: i16 = 2; +pub const POLLWRNORM: i16 = 4; +pub const POLLWRBAND: i16 = 4; +pub const POLLERR: i16 = 8; +pub const POLLHUP: i16 = 16; +pub const POLLNVAL: i16 = 32; + +// locale.h +pub const __LC_CTYPE: usize = 0; +pub const __LC_NUMERIC: usize = 1; +pub const __LC_TIME: usize = 2; +pub const __LC_COLLATE: usize = 3; +pub const __LC_MONETARY: usize = 4; +pub const __LC_MESSAGES: usize = 5; +pub const __LC_ALL: usize = 6; +pub const __LC_PAPER: usize = 7; +pub const __LC_NAME: usize = 8; +pub const __LC_ADDRESS: usize = 9; +pub const __LC_TELEPHONE: usize = 10; +pub const __LC_MEASUREMENT: usize = 11; +pub const __LC_IDENTIFICATION: usize = 12; +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_ALL: ::c_int = 6; +pub const LC_PAPER: ::c_int = 7; +pub const LC_NAME: ::c_int = 8; +pub const LC_ADDRESS: ::c_int = 9; +pub const LC_TELEPHONE: ::c_int = 10; +pub const LC_MEASUREMENT: ::c_int = 11; +pub const LC_IDENTIFICATION: ::c_int = 12; +pub const LC_CTYPE_MASK: ::c_int = 1; +pub const LC_NUMERIC_MASK: ::c_int = 2; +pub const LC_TIME_MASK: ::c_int = 4; +pub const LC_COLLATE_MASK: ::c_int = 8; +pub const LC_MONETARY_MASK: ::c_int = 16; +pub const LC_MESSAGES_MASK: ::c_int = 32; +pub const LC_PAPER_MASK: ::c_int = 128; +pub const LC_NAME_MASK: ::c_int = 256; +pub const LC_ADDRESS_MASK: ::c_int = 512; +pub const LC_TELEPHONE_MASK: ::c_int = 1024; +pub const LC_MEASUREMENT_MASK: ::c_int = 2048; +pub const LC_IDENTIFICATION_MASK: ::c_int = 4096; +pub const LC_ALL_MASK: ::c_int = 8127; + +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; + +// reboot.h +pub const RB_AUTOBOOT: ::c_int = 0x0; +pub const RB_ASKNAME: ::c_int = 0x1; +pub const RB_SINGLE: ::c_int = 0x2; +pub const RB_KBD: ::c_int = 0x4; +pub const RB_HALT: ::c_int = 0x8; +pub const RB_INITNAME: ::c_int = 0x10; +pub const RB_DFLTROOT: ::c_int = 0x20; +pub const RB_NOBOOTRC: ::c_int = 0x20; +pub const RB_ALTBOOT: ::c_int = 0x40; +pub const RB_UNIPROC: ::c_int = 0x80; +pub const RB_DEBUGGER: ::c_int = 0x1000; + +// semaphore.h +pub const __SIZEOF_SEM_T: usize = 20; +pub const SEM_FAILED: *mut ::sem_t = 0 as *mut sem_t; + +// termios.h +pub const IGNBRK: ::tcflag_t = 1; +pub const BRKINT: ::tcflag_t = 2; +pub const IGNPAR: ::tcflag_t = 4; +pub const PARMRK: ::tcflag_t = 8; +pub const INPCK: ::tcflag_t = 16; +pub const ISTRIP: ::tcflag_t = 32; +pub const INLCR: ::tcflag_t = 64; +pub const IGNCR: ::tcflag_t = 128; +pub const ICRNL: ::tcflag_t = 256; +pub const IXON: ::tcflag_t = 512; +pub const IXOFF: ::tcflag_t = 1024; +pub const IXANY: ::tcflag_t = 2048; +pub const IMAXBEL: ::tcflag_t = 8192; +pub const IUCLC: ::tcflag_t = 16384; +pub const OPOST: ::tcflag_t = 1; +pub const ONLCR: ::tcflag_t = 2; +pub const ONOEOT: ::tcflag_t = 8; +pub const OCRNL: ::tcflag_t = 16; +pub const ONOCR: ::tcflag_t = 32; +pub const ONLRET: ::tcflag_t = 64; +pub const NLDLY: ::tcflag_t = 768; +pub const NL0: ::tcflag_t = 0; +pub const NL1: ::tcflag_t = 256; +pub const TABDLY: ::tcflag_t = 3076; +pub const TAB0: ::tcflag_t = 0; +pub const TAB1: ::tcflag_t = 1024; +pub const TAB2: ::tcflag_t = 2048; +pub const TAB3: ::tcflag_t = 4; +pub const CRDLY: ::tcflag_t = 12288; +pub const CR0: ::tcflag_t = 0; +pub const CR1: ::tcflag_t = 4096; +pub const CR2: ::tcflag_t = 8192; +pub const CR3: ::tcflag_t = 12288; +pub const FFDLY: ::tcflag_t = 16384; +pub const FF0: ::tcflag_t = 0; +pub const FF1: ::tcflag_t = 16384; +pub const BSDLY: ::tcflag_t = 32768; +pub const BS0: ::tcflag_t = 0; +pub const BS1: ::tcflag_t = 32768; +pub const VTDLY: ::tcflag_t = 65536; +pub const VT0: ::tcflag_t = 0; +pub const VT1: ::tcflag_t = 65536; +pub const OLCUC: ::tcflag_t = 131072; +pub const OFILL: ::tcflag_t = 262144; +pub const OFDEL: ::tcflag_t = 524288; +pub const CIGNORE: ::tcflag_t = 1; +pub const CSIZE: ::tcflag_t = 768; +pub const CS5: ::tcflag_t = 0; +pub const CS6: ::tcflag_t = 256; +pub const CS7: ::tcflag_t = 512; +pub const CS8: ::tcflag_t = 768; +pub const CSTOPB: ::tcflag_t = 1024; +pub const CREAD: ::tcflag_t = 2048; +pub const PARENB: ::tcflag_t = 4096; +pub const PARODD: ::tcflag_t = 8192; +pub const HUPCL: ::tcflag_t = 16384; +pub const CLOCAL: ::tcflag_t = 32768; +pub const CRTSCTS: ::tcflag_t = 65536; +pub const CRTS_IFLOW: ::tcflag_t = 65536; +pub const CCTS_OFLOW: ::tcflag_t = 65536; +pub const CDTRCTS: ::tcflag_t = 131072; +pub const MDMBUF: ::tcflag_t = 1048576; +pub const CHWFLOW: ::tcflag_t = 1245184; +pub const ECHOKE: ::tcflag_t = 1; +pub const _ECHOE: ::tcflag_t = 2; +pub const ECHOE: ::tcflag_t = 2; +pub const _ECHOK: ::tcflag_t = 4; +pub const ECHOK: ::tcflag_t = 4; +pub const _ECHO: ::tcflag_t = 8; +pub const ECHO: ::tcflag_t = 8; +pub const _ECHONL: ::tcflag_t = 16; +pub const ECHONL: ::tcflag_t = 16; +pub const ECHOPRT: ::tcflag_t = 32; +pub const ECHOCTL: ::tcflag_t = 64; +pub const _ISIG: ::tcflag_t = 128; +pub const ISIG: ::tcflag_t = 128; +pub const _ICANON: ::tcflag_t = 256; +pub const ICANON: ::tcflag_t = 256; +pub const ALTWERASE: ::tcflag_t = 512; +pub const _IEXTEN: ::tcflag_t = 1024; +pub const IEXTEN: ::tcflag_t = 1024; +pub const EXTPROC: ::tcflag_t = 2048; +pub const _TOSTOP: ::tcflag_t = 4194304; +pub const TOSTOP: ::tcflag_t = 4194304; +pub const FLUSHO: ::tcflag_t = 8388608; +pub const NOKERNINFO: ::tcflag_t = 33554432; +pub const PENDIN: ::tcflag_t = 536870912; +pub const _NOFLSH: ::tcflag_t = 2147483648; +pub const NOFLSH: ::tcflag_t = 2147483648; +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 VINTR: usize = 8; +pub const VQUIT: usize = 9; +pub const VSUSP: usize = 10; +pub const VDSUSP: usize = 11; +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 VSTATUS: usize = 18; +pub const NCCS: usize = 20; +pub const B0: ::speed_t = 0; +pub const B50: ::speed_t = 50; +pub const B75: ::speed_t = 75; +pub const B110: ::speed_t = 110; +pub const B134: ::speed_t = 134; +pub const B150: ::speed_t = 150; +pub const B200: ::speed_t = 200; +pub const B300: ::speed_t = 300; +pub const B600: ::speed_t = 600; +pub const B1200: ::speed_t = 1200; +pub const B1800: ::speed_t = 1800; +pub const B2400: ::speed_t = 2400; +pub const B4800: ::speed_t = 4800; +pub const B9600: ::speed_t = 9600; +pub const B7200: ::speed_t = 7200; +pub const B14400: ::speed_t = 14400; +pub const B19200: ::speed_t = 19200; +pub const B28800: ::speed_t = 28800; +pub const B38400: ::speed_t = 38400; +pub const EXTA: ::speed_t = B19200; +pub const EXTB: ::speed_t = B38400; +pub const B57600: ::speed_t = 57600; +pub const B76800: ::speed_t = 76800; +pub const B115200: ::speed_t = 115200; +pub const B230400: ::speed_t = 230400; +pub const B460800: ::speed_t = 460800; +pub const B500000: ::speed_t = 500000; +pub const B576000: ::speed_t = 576000; +pub const B921600: ::speed_t = 921600; +pub const B1000000: ::speed_t = 1000000; +pub const B1152000: ::speed_t = 1152000; +pub const B1500000: ::speed_t = 1500000; +pub const B2000000: ::speed_t = 2000000; +pub const B2500000: ::speed_t = 2500000; +pub const B3000000: ::speed_t = 3000000; +pub const B3500000: ::speed_t = 3500000; +pub const B4000000: ::speed_t = 4000000; +pub const TCSANOW: ::c_int = 0; +pub const TCSADRAIN: ::c_int = 1; +pub const TCSAFLUSH: ::c_int = 2; +pub const TCSASOFT: ::c_int = 16; +pub const TCIFLUSH: ::c_int = 1; +pub const TCOFLUSH: ::c_int = 2; +pub const TCIOFLUSH: ::c_int = 3; +pub const TCOOFF: ::c_int = 1; +pub const TCOON: ::c_int = 2; +pub const TCIOFF: ::c_int = 3; +pub const TCION: ::c_int = 4; +pub const TTYDEF_IFLAG: ::tcflag_t = 11042; +pub const TTYDEF_LFLAG: ::tcflag_t = 1483; +pub const TTYDEF_CFLAG: ::tcflag_t = 23040; +pub const TTYDEF_SPEED: ::tcflag_t = 9600; +pub const CEOL: u8 = 0u8; +pub const CERASE: u8 = 127; +pub const CMIN: u8 = 1; +pub const CQUIT: u8 = 28; +pub const CTIME: u8 = 0; +pub const CBRK: u8 = 0u8; + +// dlfcn.h +pub const RTLD_DEFAULT: *mut ::c_void = 0i64 as *mut ::c_void; +pub const RTLD_NEXT: *mut ::c_void = -1i64 as *mut ::c_void; +pub const RTLD_LAZY: ::c_int = 1; +pub const RTLD_NOW: ::c_int = 2; +pub const RTLD_BINDING_MASK: ::c_int = 3; +pub const RTLD_NOLOAD: ::c_int = 4; +pub const RTLD_DEEPBIND: ::c_int = 8; +pub const RTLD_GLOBAL: ::c_int = 256; +pub const RTLD_LOCAL: ::c_int = 0; +pub const RTLD_NODELETE: ::c_int = 4096; +pub const DLFO_STRUCT_HAS_EH_DBASE: usize = 1; +pub const DLFO_STRUCT_HAS_EH_COUNT: usize = 0; +pub const LM_ID_BASE: c_long = 0; +pub const LM_ID_NEWLM: c_long = -1; + +// bits/signum_generic.h +pub const SIGINT: ::c_int = 2; +pub const SIGILL: ::c_int = 4; +pub const SIGABRT: ::c_int = 6; +pub const SIGFPE: ::c_int = 8; +pub const SIGSEGV: ::c_int = 11; +pub const SIGTERM: ::c_int = 15; +pub const SIGHUP: ::c_int = 1; +pub const SIGQUIT: ::c_int = 3; +pub const SIGTRAP: ::c_int = 5; +pub const SIGKILL: ::c_int = 9; +pub const SIGPIPE: ::c_int = 13; +pub const SIGALRM: ::c_int = 14; +pub const SIGIOT: ::c_int = 6; +pub const SIGBUS: ::c_int = 10; +pub const SIGSYS: ::c_int = 12; +pub const SIGEMT: ::c_int = 7; +pub const SIGINFO: ::c_int = 29; +pub const SIGLOST: ::c_int = 32; +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 SIGPOLL: ::c_int = 23; +pub const SIGXCPU: ::c_int = 24; +pub const SIGVTALRM: ::c_int = 26; +pub const SIGPROF: ::c_int = 27; +pub const SIGXFSZ: ::c_int = 25; +pub const SIGUSR1: ::c_int = 30; +pub const SIGUSR2: ::c_int = 31; +pub const SIGWINCH: ::c_int = 28; +pub const SIGIO: ::c_int = 23; +pub const SIGCLD: ::c_int = 20; +pub const __SIGRTMIN: usize = 32; +pub const __SIGRTMAX: usize = 32; +pub const _NSIG: usize = 33; +pub const NSIG: usize = 33; + +// bits/sigaction.h +pub const SA_ONSTACK: ::c_int = 1; +pub const SA_RESTART: ::c_int = 2; +pub const SA_NODEFER: ::c_int = 16; +pub const SA_RESETHAND: ::c_int = 4; +pub const SA_NOCLDSTOP: ::c_int = 8; +pub const SA_SIGINFO: ::c_int = 64; +pub const SA_INTERRUPT: ::c_int = 0; +pub const SA_NOMASK: ::c_int = 16; +pub const SA_ONESHOT: ::c_int = 4; +pub const SA_STACK: ::c_int = 1; +pub const SIG_BLOCK: ::c_int = 1; +pub const SIG_UNBLOCK: ::c_int = 2; +pub const SIG_SETMASK: ::c_int = 3; + +// bits/sigcontext.h +pub const FPC_IE: u16 = 1; +pub const FPC_IM: u16 = 1; +pub const FPC_DE: u16 = 2; +pub const FPC_DM: u16 = 2; +pub const FPC_ZE: u16 = 4; +pub const FPC_ZM: u16 = 4; +pub const FPC_OE: u16 = 8; +pub const FPC_OM: u16 = 8; +pub const FPC_UE: u16 = 16; +pub const FPC_PE: u16 = 32; +pub const FPC_PC: u16 = 768; +pub const FPC_PC_24: u16 = 0; +pub const FPC_PC_53: u16 = 512; +pub const FPC_PC_64: u16 = 768; +pub const FPC_RC: u16 = 3072; +pub const FPC_RC_RN: u16 = 0; +pub const FPC_RC_RD: u16 = 1024; +pub const FPC_RC_RU: u16 = 2048; +pub const FPC_RC_CHOP: u16 = 3072; +pub const FPC_IC: u16 = 4096; +pub const FPC_IC_PROJ: u16 = 0; +pub const FPC_IC_AFF: u16 = 4096; +pub const FPS_IE: u16 = 1; +pub const FPS_DE: u16 = 2; +pub const FPS_ZE: u16 = 4; +pub const FPS_OE: u16 = 8; +pub const FPS_UE: u16 = 16; +pub const FPS_PE: u16 = 32; +pub const FPS_SF: u16 = 64; +pub const FPS_ES: u16 = 128; +pub const FPS_C0: u16 = 256; +pub const FPS_C1: u16 = 512; +pub const FPS_C2: u16 = 1024; +pub const FPS_TOS: u16 = 14336; +pub const FPS_TOS_SHIFT: u16 = 11; +pub const FPS_C3: u16 = 16384; +pub const FPS_BUSY: u16 = 32768; +pub const FPE_INTOVF_TRAP: ::c_int = 1; +pub const FPE_INTDIV_FAULT: ::c_int = 2; +pub const FPE_FLTOVF_FAULT: ::c_int = 3; +pub const FPE_FLTDIV_FAULT: ::c_int = 4; +pub const FPE_FLTUND_FAULT: ::c_int = 5; +pub const FPE_SUBRNG_FAULT: ::c_int = 7; +pub const FPE_FLTDNR_FAULT: ::c_int = 8; +pub const FPE_FLTINX_FAULT: ::c_int = 9; +pub const FPE_EMERR_FAULT: ::c_int = 10; +pub const FPE_EMBND_FAULT: ::c_int = 11; +pub const ILL_INVOPR_FAULT: ::c_int = 1; +pub const ILL_STACK_FAULT: ::c_int = 2; +pub const ILL_FPEOPR_FAULT: ::c_int = 3; +pub const DBG_SINGLE_TRAP: ::c_int = 1; +pub const DBG_BRKPNT_FAULT: ::c_int = 2; +pub const __NGREG: usize = 19; +pub const NGREG: usize = 19; + +// bits/sigstack.h +pub const MINSIGSTKSZ: usize = 8192; +pub const SIGSTKSZ: usize = 40960; + +// sys/stat.h +pub const __S_IFMT: mode_t = 61440; +pub const __S_IFDIR: mode_t = 16384; +pub const __S_IFCHR: mode_t = 8192; +pub const __S_IFBLK: mode_t = 24576; +pub const __S_IFREG: mode_t = 32768; +pub const __S_IFLNK: mode_t = 40960; +pub const __S_IFSOCK: mode_t = 49152; +pub const __S_IFIFO: mode_t = 4096; +pub const __S_ISUID: mode_t = 2048; +pub const __S_ISGID: mode_t = 1024; +pub const __S_ISVTX: mode_t = 512; +pub const __S_IREAD: mode_t = 256; +pub const __S_IWRITE: mode_t = 128; +pub const __S_IEXEC: mode_t = 64; +pub const S_INOCACHE: mode_t = 65536; +pub const S_IUSEUNK: mode_t = 131072; +pub const S_IUNKNOWN: mode_t = 1835008; +pub const S_IUNKSHIFT: mode_t = 12; +pub const S_IPTRANS: mode_t = 2097152; +pub const S_IATRANS: mode_t = 4194304; +pub const S_IROOT: mode_t = 8388608; +pub const S_ITRANS: mode_t = 14680064; +pub const S_IMMAP0: mode_t = 16777216; +pub const CMASK: mode_t = 18; +pub const UF_SETTABLE: ::c_uint = 65535; +pub const UF_NODUMP: ::c_uint = 1; +pub const UF_IMMUTABLE: ::c_uint = 2; +pub const UF_APPEND: ::c_uint = 4; +pub const UF_OPAQUE: ::c_uint = 8; +pub const UF_NOUNLINK: ::c_uint = 16; +pub const SF_SETTABLE: ::c_uint = 4294901760; +pub const SF_ARCHIVED: ::c_uint = 65536; +pub const SF_IMMUTABLE: ::c_uint = 131072; +pub const SF_APPEND: ::c_uint = 262144; +pub const SF_NOUNLINK: ::c_uint = 1048576; +pub const SF_SNAPSHOT: ::c_uint = 2097152; +pub const UTIME_NOW: ::c_long = -1; +pub const UTIME_OMIT: ::c_long = -2; +pub const S_IFMT: ::mode_t = 61440; +pub const S_IFDIR: ::mode_t = 16384; +pub const S_IFCHR: ::mode_t = 8192; +pub const S_IFBLK: ::mode_t = 24576; +pub const S_IFREG: ::mode_t = 32768; +pub const S_IFIFO: ::mode_t = 4096; +pub const S_IFLNK: ::mode_t = 40960; +pub const S_IFSOCK: ::mode_t = 49152; +pub const S_ISUID: ::mode_t = 2048; +pub const S_ISGID: ::mode_t = 1024; +pub const S_ISVTX: ::mode_t = 512; +pub const S_IRUSR: ::mode_t = 256; +pub const S_IWUSR: ::mode_t = 128; +pub const S_IXUSR: ::mode_t = 64; +pub const S_IRWXU: ::mode_t = 448; +pub const S_IREAD: ::mode_t = 256; +pub const S_IWRITE: ::mode_t = 128; +pub const S_IEXEC: ::mode_t = 64; +pub const S_IRGRP: ::mode_t = 32; +pub const S_IWGRP: ::mode_t = 16; +pub const S_IXGRP: ::mode_t = 8; +pub const S_IRWXG: ::mode_t = 56; +pub const S_IROTH: ::mode_t = 4; +pub const S_IWOTH: ::mode_t = 2; +pub const S_IXOTH: ::mode_t = 1; +pub const S_IRWXO: ::mode_t = 7; +pub const ACCESSPERMS: ::mode_t = 511; +pub const ALLPERMS: ::mode_t = 4095; +pub const DEFFILEMODE: ::mode_t = 438; +pub const S_BLKSIZE: usize = 512; +pub const STATX_TYPE: ::c_uint = 1; +pub const STATX_MODE: ::c_uint = 2; +pub const STATX_NLINK: ::c_uint = 4; +pub const STATX_UID: ::c_uint = 8; +pub const STATX_GID: ::c_uint = 16; +pub const STATX_ATIME: ::c_uint = 32; +pub const STATX_MTIME: ::c_uint = 64; +pub const STATX_CTIME: ::c_uint = 128; +pub const STATX_INO: ::c_uint = 256; +pub const STATX_SIZE: ::c_uint = 512; +pub const STATX_BLOCKS: ::c_uint = 1024; +pub const STATX_BASIC_STATS: ::c_uint = 2047; +pub const STATX_ALL: ::c_uint = 4095; +pub const STATX_BTIME: ::c_uint = 2048; +pub const STATX_MNT_ID: ::c_uint = 4096; +pub const STATX_DIOALIGN: ::c_uint = 8192; +pub const STATX__RESERVED: ::c_uint = 2147483648; +pub const STATX_ATTR_COMPRESSED: ::c_uint = 4; +pub const STATX_ATTR_IMMUTABLE: ::c_uint = 16; +pub const STATX_ATTR_APPEND: ::c_uint = 32; +pub const STATX_ATTR_NODUMP: ::c_uint = 64; +pub const STATX_ATTR_ENCRYPTED: ::c_uint = 2048; +pub const STATX_ATTR_AUTOMOUNT: ::c_uint = 4096; +pub const STATX_ATTR_MOUNT_ROOT: ::c_uint = 8192; +pub const STATX_ATTR_VERITY: ::c_uint = 1048576; +pub const STATX_ATTR_DAX: ::c_uint = 2097152; + +// sys/ioctl.h +pub const TIOCM_LE: ::c_int = 1; +pub const TIOCM_DTR: ::c_int = 2; +pub const TIOCM_RTS: ::c_int = 4; +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_CD: ::c_int = 64; +pub const TIOCM_RNG: ::c_int = 128; +pub const TIOCM_RI: ::c_int = 128; +pub const TIOCM_DSR: ::c_int = 256; +pub const TIOCPKT_DATA: ::c_int = 0; +pub const TIOCPKT_FLUSHREAD: ::c_int = 1; +pub const TIOCPKT_FLUSHWRITE: ::c_int = 2; +pub const TIOCPKT_STOP: ::c_int = 4; +pub const TIOCPKT_START: ::c_int = 8; +pub const TIOCPKT_NOSTOP: ::c_int = 16; +pub const TIOCPKT_DOSTOP: ::c_int = 32; +pub const TIOCPKT_IOCTL: ::c_int = 64; +pub const TTYDISC: ::c_int = 0; +pub const TABLDISC: ::c_int = 3; +pub const SLIPDISC: ::c_int = 4; +pub const TANDEM: ::tcflag_t = 1; +pub const CBREAK: ::tcflag_t = 2; +pub const LCASE: ::tcflag_t = 4; +pub const CRMOD: ::tcflag_t = 16; +pub const RAW: ::tcflag_t = 32; +pub const ODDP: ::tcflag_t = 64; +pub const EVENP: ::tcflag_t = 128; +pub const ANYP: ::tcflag_t = 192; +pub const NLDELAY: ::tcflag_t = 768; +pub const NL2: ::tcflag_t = 512; +pub const NL3: ::tcflag_t = 768; +pub const TBDELAY: ::tcflag_t = 3072; +pub const XTABS: ::tcflag_t = 3072; +pub const CRDELAY: ::tcflag_t = 12288; +pub const VTDELAY: ::tcflag_t = 16384; +pub const BSDELAY: ::tcflag_t = 32768; +pub const ALLDELAY: ::tcflag_t = 65280; +pub const CRTBS: ::tcflag_t = 65536; +pub const PRTERA: ::tcflag_t = 131072; +pub const CRTERA: ::tcflag_t = 262144; +pub const TILDE: ::tcflag_t = 524288; +pub const LITOUT: ::tcflag_t = 2097152; +pub const NOHANG: ::tcflag_t = 16777216; +pub const L001000: ::tcflag_t = 33554432; +pub const CRTKIL: ::tcflag_t = 67108864; +pub const PASS8: ::tcflag_t = 134217728; +pub const CTLECH: ::tcflag_t = 268435456; +pub const DECCTQ: ::tcflag_t = 1073741824; + +pub const FIONBIO: ::c_ulong = 0xa008007e; +pub const FIONREAD: ::c_ulong = 0x6008007f; +pub const TIOCSWINSZ: ::c_ulong = 0x90200767; +pub const TIOCGWINSZ: ::c_ulong = 0x50200768; +pub const TIOCEXCL: ::c_ulong = 0x70d; +pub const TIOCNXCL: ::c_ulong = 0x70e; +pub const TIOCSCTTY: ::c_ulong = 0x761; + +pub const FIOCLEX: ::c_ulong = 1; + +// fcntl.h +pub const O_EXEC: ::c_int = 4; +pub const O_NORW: ::c_int = 0; +pub const O_RDONLY: ::c_int = 1; +pub const O_WRONLY: ::c_int = 2; +pub const O_RDWR: ::c_int = 3; +pub const O_ACCMODE: ::c_int = 3; +pub const O_LARGEFILE: ::c_int = 0; +pub const O_CREAT: ::c_int = 16; +pub const O_EXCL: ::c_int = 32; +pub const O_NOLINK: ::c_int = 64; +pub const O_NOTRANS: ::c_int = 128; +pub const O_NOFOLLOW: ::c_int = 1048576; +pub const O_DIRECTORY: ::c_int = 2097152; +pub const O_APPEND: ::c_int = 256; +pub const O_ASYNC: ::c_int = 512; +pub const O_FSYNC: ::c_int = 1024; +pub const O_SYNC: ::c_int = 1024; +pub const O_NOATIME: ::c_int = 2048; +pub const O_SHLOCK: ::c_int = 131072; +pub const O_EXLOCK: ::c_int = 262144; +pub const O_DSYNC: ::c_int = 1024; +pub const O_RSYNC: ::c_int = 1024; +pub const O_NONBLOCK: ::c_int = 8; +pub const O_NDELAY: ::c_int = 8; +pub const O_HURD: ::c_int = 458751; +pub const O_TRUNC: ::c_int = 65536; +pub const O_CLOEXEC: ::c_int = 4194304; +pub const O_IGNORE_CTTY: ::c_int = 524288; +pub const O_TMPFILE: ::c_int = 8388608; +pub const O_NOCTTY: ::c_int = 0; +pub const FREAD: ::c_int = 1; +pub const FWRITE: ::c_int = 2; +pub const FASYNC: ::c_int = 512; +pub const FCREAT: ::c_int = 16; +pub const FEXCL: ::c_int = 32; +pub const FTRUNC: ::c_int = 65536; +pub const FNOCTTY: ::c_int = 0; +pub const FFSYNC: ::c_int = 1024; +pub const FSYNC: ::c_int = 1024; +pub const FAPPEND: ::c_int = 256; +pub const FNONBLOCK: ::c_int = 8; +pub const FNDELAY: ::c_int = 8; +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_GETOWN: ::c_int = 5; +pub const F_SETOWN: ::c_int = 6; +pub const F_GETLK: ::c_int = 7; +pub const F_SETLK: ::c_int = 8; +pub const F_SETLKW: ::c_int = 9; +pub const F_GETLK64: ::c_int = 10; +pub const F_SETLK64: ::c_int = 11; +pub const F_SETLKW64: ::c_int = 12; +pub const F_DUPFD_CLOEXEC: ::c_int = 1030; +pub const FD_CLOEXEC: ::c_int = 1; +pub const F_RDLCK: ::c_int = 1; +pub const F_WRLCK: ::c_int = 2; +pub const F_UNLCK: ::c_int = 3; +pub const POSIX_FADV_NORMAL: ::c_int = 0; +pub const POSIX_FADV_RANDOM: ::c_int = 1; +pub const POSIX_FADV_SEQUENTIAL: ::c_int = 2; +pub const POSIX_FADV_WILLNEED: ::c_int = 3; +pub const POSIX_FADV_DONTNEED: ::c_int = 4; +pub const POSIX_FADV_NOREUSE: ::c_int = 5; +pub const AT_FDCWD: ::c_int = -100; +pub const AT_SYMLINK_NOFOLLOW: ::c_int = 256; +pub const AT_REMOVEDIR: ::c_int = 512; +pub const AT_SYMLINK_FOLLOW: ::c_int = 1024; +pub const AT_NO_AUTOMOUNT: ::c_int = 2048; +pub const AT_EMPTY_PATH: ::c_int = 4096; +pub const AT_STATX_SYNC_TYPE: ::c_int = 24576; +pub const AT_STATX_SYNC_AS_STAT: ::c_int = 0; +pub const AT_STATX_FORCE_SYNC: ::c_int = 8192; +pub const AT_STATX_DONT_SYNC: ::c_int = 16384; +pub const AT_RECURSIVE: ::c_int = 32768; +pub const AT_EACCESS: ::c_int = 512; + +// sys/uio.h +pub const RWF_HIPRI: ::c_int = 1; +pub const RWF_DSYNC: ::c_int = 2; +pub const RWF_SYNC: ::c_int = 4; +pub const RWF_NOWAIT: ::c_int = 8; +pub const RWF_APPEND: ::c_int = 16; + +// errno.h +pub const EPERM: ::c_int = 1073741825; +pub const ENOENT: ::c_int = 1073741826; +pub const ESRCH: ::c_int = 1073741827; +pub const EINTR: ::c_int = 1073741828; +pub const EIO: ::c_int = 1073741829; +pub const ENXIO: ::c_int = 1073741830; +pub const E2BIG: ::c_int = 1073741831; +pub const ENOEXEC: ::c_int = 1073741832; +pub const EBADF: ::c_int = 1073741833; +pub const ECHILD: ::c_int = 1073741834; +pub const EDEADLK: ::c_int = 1073741835; +pub const ENOMEM: ::c_int = 1073741836; +pub const EACCES: ::c_int = 1073741837; +pub const EFAULT: ::c_int = 1073741838; +pub const ENOTBLK: ::c_int = 1073741839; +pub const EBUSY: ::c_int = 1073741840; +pub const EEXIST: ::c_int = 1073741841; +pub const EXDEV: ::c_int = 1073741842; +pub const ENODEV: ::c_int = 1073741843; +pub const ENOTDIR: ::c_int = 1073741844; +pub const EISDIR: ::c_int = 1073741845; +pub const EINVAL: ::c_int = 1073741846; +pub const EMFILE: ::c_int = 1073741848; +pub const ENFILE: ::c_int = 1073741847; +pub const ENOTTY: ::c_int = 1073741849; +pub const ETXTBSY: ::c_int = 1073741850; +pub const EFBIG: ::c_int = 1073741851; +pub const ENOSPC: ::c_int = 1073741852; +pub const ESPIPE: ::c_int = 1073741853; +pub const EROFS: ::c_int = 1073741854; +pub const EMLINK: ::c_int = 1073741855; +pub const EPIPE: ::c_int = 1073741856; +pub const EDOM: ::c_int = 1073741857; +pub const ERANGE: ::c_int = 1073741858; +pub const EAGAIN: ::c_int = 1073741859; +pub const EWOULDBLOCK: ::c_int = 1073741859; +pub const EINPROGRESS: ::c_int = 1073741860; +pub const EALREADY: ::c_int = 1073741861; +pub const ENOTSOCK: ::c_int = 1073741862; +pub const EMSGSIZE: ::c_int = 1073741864; +pub const EPROTOTYPE: ::c_int = 1073741865; +pub const ENOPROTOOPT: ::c_int = 1073741866; +pub const EPROTONOSUPPORT: ::c_int = 1073741867; +pub const ESOCKTNOSUPPORT: ::c_int = 1073741868; +pub const EOPNOTSUPP: ::c_int = 1073741869; +pub const EPFNOSUPPORT: ::c_int = 1073741870; +pub const EAFNOSUPPORT: ::c_int = 1073741871; +pub const EADDRINUSE: ::c_int = 1073741872; +pub const EADDRNOTAVAIL: ::c_int = 1073741873; +pub const ENETDOWN: ::c_int = 1073741874; +pub const ENETUNREACH: ::c_int = 1073741875; +pub const ENETRESET: ::c_int = 1073741876; +pub const ECONNABORTED: ::c_int = 1073741877; +pub const ECONNRESET: ::c_int = 1073741878; +pub const ENOBUFS: ::c_int = 1073741879; +pub const EISCONN: ::c_int = 1073741880; +pub const ENOTCONN: ::c_int = 1073741881; +pub const EDESTADDRREQ: ::c_int = 1073741863; +pub const ESHUTDOWN: ::c_int = 1073741882; +pub const ETOOMANYREFS: ::c_int = 1073741883; +pub const ETIMEDOUT: ::c_int = 1073741884; +pub const ECONNREFUSED: ::c_int = 1073741885; +pub const ELOOP: ::c_int = 1073741886; +pub const ENAMETOOLONG: ::c_int = 1073741887; +pub const EHOSTDOWN: ::c_int = 1073741888; +pub const EHOSTUNREACH: ::c_int = 1073741889; +pub const ENOTEMPTY: ::c_int = 1073741890; +pub const EPROCLIM: ::c_int = 1073741891; +pub const EUSERS: ::c_int = 1073741892; +pub const EDQUOT: ::c_int = 1073741893; +pub const ESTALE: ::c_int = 1073741894; +pub const EREMOTE: ::c_int = 1073741895; +pub const EBADRPC: ::c_int = 1073741896; +pub const ERPCMISMATCH: ::c_int = 1073741897; +pub const EPROGUNAVAIL: ::c_int = 1073741898; +pub const EPROGMISMATCH: ::c_int = 1073741899; +pub const EPROCUNAVAIL: ::c_int = 1073741900; +pub const ENOLCK: ::c_int = 1073741901; +pub const EFTYPE: ::c_int = 1073741903; +pub const EAUTH: ::c_int = 1073741904; +pub const ENEEDAUTH: ::c_int = 1073741905; +pub const ENOSYS: ::c_int = 1073741902; +pub const ELIBEXEC: ::c_int = 1073741907; +pub const ENOTSUP: ::c_int = 1073741942; +pub const EILSEQ: ::c_int = 1073741930; +pub const EBACKGROUND: ::c_int = 1073741924; +pub const EDIED: ::c_int = 1073741925; +pub const EGREGIOUS: ::c_int = 1073741927; +pub const EIEIO: ::c_int = 1073741928; +pub const EGRATUITOUS: ::c_int = 1073741929; +pub const EBADMSG: ::c_int = 1073741931; +pub const EIDRM: ::c_int = 1073741932; +pub const EMULTIHOP: ::c_int = 1073741933; +pub const ENODATA: ::c_int = 1073741934; +pub const ENOLINK: ::c_int = 1073741935; +pub const ENOMSG: ::c_int = 1073741936; +pub const ENOSR: ::c_int = 1073741937; +pub const ENOSTR: ::c_int = 1073741938; +pub const EOVERFLOW: ::c_int = 1073741939; +pub const EPROTO: ::c_int = 1073741940; +pub const ETIME: ::c_int = 1073741941; +pub const ECANCELED: ::c_int = 1073741943; +pub const EOWNERDEAD: ::c_int = 1073741944; +pub const ENOTRECOVERABLE: ::c_int = 1073741945; +pub const EMACH_SEND_IN_PROGRESS: ::c_int = 268435457; +pub const EMACH_SEND_INVALID_DATA: ::c_int = 268435458; +pub const EMACH_SEND_INVALID_DEST: ::c_int = 268435459; +pub const EMACH_SEND_TIMED_OUT: ::c_int = 268435460; +pub const EMACH_SEND_WILL_NOTIFY: ::c_int = 268435461; +pub const EMACH_SEND_NOTIFY_IN_PROGRESS: ::c_int = 268435462; +pub const EMACH_SEND_INTERRUPTED: ::c_int = 268435463; +pub const EMACH_SEND_MSG_TOO_SMALL: ::c_int = 268435464; +pub const EMACH_SEND_INVALID_REPLY: ::c_int = 268435465; +pub const EMACH_SEND_INVALID_RIGHT: ::c_int = 268435466; +pub const EMACH_SEND_INVALID_NOTIFY: ::c_int = 268435467; +pub const EMACH_SEND_INVALID_MEMORY: ::c_int = 268435468; +pub const EMACH_SEND_NO_BUFFER: ::c_int = 268435469; +pub const EMACH_SEND_NO_NOTIFY: ::c_int = 268435470; +pub const EMACH_SEND_INVALID_TYPE: ::c_int = 268435471; +pub const EMACH_SEND_INVALID_HEADER: ::c_int = 268435472; +pub const EMACH_RCV_IN_PROGRESS: ::c_int = 268451841; +pub const EMACH_RCV_INVALID_NAME: ::c_int = 268451842; +pub const EMACH_RCV_TIMED_OUT: ::c_int = 268451843; +pub const EMACH_RCV_TOO_LARGE: ::c_int = 268451844; +pub const EMACH_RCV_INTERRUPTED: ::c_int = 268451845; +pub const EMACH_RCV_PORT_CHANGED: ::c_int = 268451846; +pub const EMACH_RCV_INVALID_NOTIFY: ::c_int = 268451847; +pub const EMACH_RCV_INVALID_DATA: ::c_int = 268451848; +pub const EMACH_RCV_PORT_DIED: ::c_int = 268451849; +pub const EMACH_RCV_IN_SET: ::c_int = 268451850; +pub const EMACH_RCV_HEADER_ERROR: ::c_int = 268451851; +pub const EMACH_RCV_BODY_ERROR: ::c_int = 268451852; +pub const EKERN_INVALID_ADDRESS: ::c_int = 1; +pub const EKERN_PROTECTION_FAILURE: ::c_int = 2; +pub const EKERN_NO_SPACE: ::c_int = 3; +pub const EKERN_INVALID_ARGUMENT: ::c_int = 4; +pub const EKERN_FAILURE: ::c_int = 5; +pub const EKERN_RESOURCE_SHORTAGE: ::c_int = 6; +pub const EKERN_NOT_RECEIVER: ::c_int = 7; +pub const EKERN_NO_ACCESS: ::c_int = 8; +pub const EKERN_MEMORY_FAILURE: ::c_int = 9; +pub const EKERN_MEMORY_ERROR: ::c_int = 10; +pub const EKERN_NOT_IN_SET: ::c_int = 12; +pub const EKERN_NAME_EXISTS: ::c_int = 13; +pub const EKERN_ABORTED: ::c_int = 14; +pub const EKERN_INVALID_NAME: ::c_int = 15; +pub const EKERN_INVALID_TASK: ::c_int = 16; +pub const EKERN_INVALID_RIGHT: ::c_int = 17; +pub const EKERN_INVALID_VALUE: ::c_int = 18; +pub const EKERN_UREFS_OVERFLOW: ::c_int = 19; +pub const EKERN_INVALID_CAPABILITY: ::c_int = 20; +pub const EKERN_RIGHT_EXISTS: ::c_int = 21; +pub const EKERN_INVALID_HOST: ::c_int = 22; +pub const EKERN_MEMORY_PRESENT: ::c_int = 23; +pub const EKERN_WRITE_PROTECTION_FAILURE: ::c_int = 24; +pub const EKERN_TERMINATED: ::c_int = 26; +pub const EKERN_TIMEDOUT: ::c_int = 27; +pub const EKERN_INTERRUPTED: ::c_int = 28; +pub const EMIG_TYPE_ERROR: ::c_int = -300; +pub const EMIG_REPLY_MISMATCH: ::c_int = -301; +pub const EMIG_REMOTE_ERROR: ::c_int = -302; +pub const EMIG_BAD_ID: ::c_int = -303; +pub const EMIG_BAD_ARGUMENTS: ::c_int = -304; +pub const EMIG_NO_REPLY: ::c_int = -305; +pub const EMIG_EXCEPTION: ::c_int = -306; +pub const EMIG_ARRAY_TOO_LARGE: ::c_int = -307; +pub const EMIG_SERVER_DIED: ::c_int = -308; +pub const EMIG_DESTROY_REQUEST: ::c_int = -309; +pub const ED_IO_ERROR: ::c_int = 2500; +pub const ED_WOULD_BLOCK: ::c_int = 2501; +pub const ED_NO_SUCH_DEVICE: ::c_int = 2502; +pub const ED_ALREADY_OPEN: ::c_int = 2503; +pub const ED_DEVICE_DOWN: ::c_int = 2504; +pub const ED_INVALID_OPERATION: ::c_int = 2505; +pub const ED_INVALID_RECNUM: ::c_int = 2506; +pub const ED_INVALID_SIZE: ::c_int = 2507; +pub const ED_NO_MEMORY: ::c_int = 2508; +pub const ED_READ_ONLY: ::c_int = 2509; +pub const _HURD_ERRNOS: usize = 122; + +// 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 _BITS_TYPES_STRUCT_SCHED_PARAM: usize = 1; +pub const __CPU_SETSIZE: usize = 1024; +pub const CPU_SETSIZE: usize = 1024; + +// pthread.h +pub const PTHREAD_SPINLOCK_INITIALIZER: ::c_int = 0; +pub const PTHREAD_CANCEL_DISABLE: ::c_int = 0; +pub const PTHREAD_CANCEL_ENABLE: ::c_int = 1; +pub const PTHREAD_CANCEL_DEFERRED: ::c_int = 0; +pub const PTHREAD_CANCEL_ASYNCHRONOUS: ::c_int = 1; +pub const PTHREAD_BARRIER_SERIAL_THREAD: ::c_int = -1; + +// netinet/tcp.h +pub const TCP_NODELAY: ::c_int = 1; +pub const TCP_MAXSEG: ::c_int = 2; +pub const TCP_CORK: ::c_int = 3; +pub const TCP_KEEPIDLE: ::c_int = 4; +pub const TCP_KEEPINTVL: ::c_int = 5; +pub const TCP_KEEPCNT: ::c_int = 6; +pub const TCP_SYNCNT: ::c_int = 7; +pub const TCP_LINGER2: ::c_int = 8; +pub const TCP_DEFER_ACCEPT: ::c_int = 9; +pub const TCP_WINDOW_CLAMP: ::c_int = 10; +pub const TCP_INFO: ::c_int = 11; +pub const TCP_QUICKACK: ::c_int = 12; +pub const TCP_CONGESTION: ::c_int = 13; +pub const TCP_MD5SIG: ::c_int = 14; +pub const TCP_COOKIE_TRANSACTIONS: ::c_int = 15; +pub const TCP_THIN_LINEAR_TIMEOUTS: ::c_int = 16; +pub const TCP_THIN_DUPACK: ::c_int = 17; +pub const TCP_USER_TIMEOUT: ::c_int = 18; +pub const TCP_REPAIR: ::c_int = 19; +pub const TCP_REPAIR_QUEUE: ::c_int = 20; +pub const TCP_QUEUE_SEQ: ::c_int = 21; +pub const TCP_REPAIR_OPTIONS: ::c_int = 22; +pub const TCP_FASTOPEN: ::c_int = 23; +pub const TCP_TIMESTAMP: ::c_int = 24; +pub const TCP_NOTSENT_LOWAT: ::c_int = 25; +pub const TCP_CC_INFO: ::c_int = 26; +pub const TCP_SAVE_SYN: ::c_int = 27; +pub const TCP_SAVED_SYN: ::c_int = 28; +pub const TCP_REPAIR_WINDOW: ::c_int = 29; +pub const TCP_FASTOPEN_CONNECT: ::c_int = 30; +pub const TCP_ULP: ::c_int = 31; +pub const TCP_MD5SIG_EXT: ::c_int = 32; +pub const TCP_FASTOPEN_KEY: ::c_int = 33; +pub const TCP_FASTOPEN_NO_COOKIE: ::c_int = 34; +pub const TCP_ZEROCOPY_RECEIVE: ::c_int = 35; +pub const TCP_INQ: ::c_int = 36; +pub const TCP_CM_INQ: ::c_int = 36; +pub const TCP_TX_DELAY: ::c_int = 37; +pub const TCP_REPAIR_ON: ::c_int = 1; +pub const TCP_REPAIR_OFF: ::c_int = 0; +pub const TCP_REPAIR_OFF_NO_WP: ::c_int = -1; + +// stdint.h +pub const INT8_MIN: i8 = -128; +pub const INT16_MIN: i16 = -32768; +pub const INT32_MIN: i32 = -2147483648; +pub const INT8_MAX: i8 = 127; +pub const INT16_MAX: i16 = 32767; +pub const INT32_MAX: i32 = 2147483647; +pub const UINT8_MAX: u8 = 255; +pub const UINT16_MAX: u16 = 65535; +pub const UINT32_MAX: u32 = 4294967295; +pub const INT_LEAST8_MIN: int_least8_t = -128; +pub const INT_LEAST16_MIN: int_least16_t = -32768; +pub const INT_LEAST32_MIN: int_least32_t = -2147483648; +pub const INT_LEAST8_MAX: int_least8_t = 127; +pub const INT_LEAST16_MAX: int_least16_t = 32767; +pub const INT_LEAST32_MAX: int_least32_t = 2147483647; +pub const UINT_LEAST8_MAX: uint_least8_t = 255; +pub const UINT_LEAST16_MAX: uint_least16_t = 65535; +pub const UINT_LEAST32_MAX: uint_least32_t = 4294967295; +pub const INT_FAST8_MIN: int_fast8_t = -128; +pub const INT_FAST16_MIN: int_fast16_t = -2147483648; +pub const INT_FAST32_MIN: int_fast32_t = -2147483648; +pub const INT_FAST8_MAX: int_fast8_t = 127; +pub const INT_FAST16_MAX: int_fast16_t = 2147483647; +pub const INT_FAST32_MAX: int_fast32_t = 2147483647; +pub const UINT_FAST8_MAX: uint_fast8_t = 255; +pub const UINT_FAST16_MAX: uint_fast16_t = 4294967295; +pub const UINT_FAST32_MAX: uint_fast32_t = 4294967295; +pub const INTPTR_MIN: __intptr_t = -2147483648; +pub const INTPTR_MAX: __intptr_t = 2147483647; +pub const UINTPTR_MAX: usize = 4294967295; +pub const PTRDIFF_MIN: __ptrdiff_t = -2147483648; +pub const PTRDIFF_MAX: __ptrdiff_t = 2147483647; +pub const SIG_ATOMIC_MIN: __sig_atomic_t = -2147483648; +pub const SIG_ATOMIC_MAX: __sig_atomic_t = 2147483647; +pub const SIZE_MAX: usize = 4294967295; +pub const WINT_MIN: wint_t = 0; +pub const WINT_MAX: wint_t = 4294967295; +pub const INT8_WIDTH: usize = 8; +pub const UINT8_WIDTH: usize = 8; +pub const INT16_WIDTH: usize = 16; +pub const UINT16_WIDTH: usize = 16; +pub const INT32_WIDTH: usize = 32; +pub const UINT32_WIDTH: usize = 32; +pub const INT64_WIDTH: usize = 64; +pub const UINT64_WIDTH: usize = 64; +pub const INT_LEAST8_WIDTH: usize = 8; +pub const UINT_LEAST8_WIDTH: usize = 8; +pub const INT_LEAST16_WIDTH: usize = 16; +pub const UINT_LEAST16_WIDTH: usize = 16; +pub const INT_LEAST32_WIDTH: usize = 32; +pub const UINT_LEAST32_WIDTH: usize = 32; +pub const INT_LEAST64_WIDTH: usize = 64; +pub const UINT_LEAST64_WIDTH: usize = 64; +pub const INT_FAST8_WIDTH: usize = 8; +pub const UINT_FAST8_WIDTH: usize = 8; +pub const INT_FAST16_WIDTH: usize = 32; +pub const UINT_FAST16_WIDTH: usize = 32; +pub const INT_FAST32_WIDTH: usize = 32; +pub const UINT_FAST32_WIDTH: usize = 32; +pub const INT_FAST64_WIDTH: usize = 64; +pub const UINT_FAST64_WIDTH: usize = 64; +pub const INTPTR_WIDTH: usize = 32; +pub const UINTPTR_WIDTH: usize = 32; +pub const INTMAX_WIDTH: usize = 64; +pub const UINTMAX_WIDTH: usize = 64; +pub const PTRDIFF_WIDTH: usize = 32; +pub const SIG_ATOMIC_WIDTH: usize = 32; +pub const SIZE_WIDTH: usize = 32; +pub const WCHAR_WIDTH: usize = 32; +pub const WINT_WIDTH: usize = 32; + +pub const TH_FIN: u8 = 1; +pub const TH_SYN: u8 = 2; +pub const TH_RST: u8 = 4; +pub const TH_PUSH: u8 = 8; +pub const TH_ACK: u8 = 16; +pub const TH_URG: u8 = 32; +pub const TCPOPT_EOL: u8 = 0; +pub const TCPOPT_NOP: u8 = 1; +pub const TCPOPT_MAXSEG: u8 = 2; +pub const TCPOLEN_MAXSEG: u8 = 4; +pub const TCPOPT_WINDOW: u8 = 3; +pub const TCPOLEN_WINDOW: u8 = 3; +pub const TCPOPT_SACK_PERMITTED: u8 = 4; +pub const TCPOLEN_SACK_PERMITTED: u8 = 2; +pub const TCPOPT_SACK: u8 = 5; +pub const TCPOPT_TIMESTAMP: u8 = 8; +pub const TCPOLEN_TIMESTAMP: u8 = 10; +pub const TCPOLEN_TSTAMP_APPA: u8 = 12; +pub const TCPOPT_TSTAMP_HDR: u32 = 16844810; +pub const TCP_MSS: usize = 512; +pub const TCP_MAXWIN: usize = 65535; +pub const TCP_MAX_WINSHIFT: usize = 14; +pub const TCPI_OPT_TIMESTAMPS: u8 = 1; +pub const TCPI_OPT_SACK: u8 = 2; +pub const TCPI_OPT_WSCALE: u8 = 4; +pub const TCPI_OPT_ECN: u8 = 8; +pub const TCPI_OPT_ECN_SEEN: u8 = 16; +pub const TCPI_OPT_SYN_DATA: u8 = 32; +pub const TCP_MD5SIG_MAXKEYLEN: usize = 80; +pub const TCP_MD5SIG_FLAG_PREFIX: usize = 1; +pub const TCP_COOKIE_MIN: usize = 8; +pub const TCP_COOKIE_MAX: usize = 16; +pub const TCP_COOKIE_PAIR_SIZE: usize = 32; +pub const TCP_COOKIE_IN_ALWAYS: ::c_int = 1; +pub const TCP_COOKIE_OUT_NEVER: ::c_int = 2; +pub const TCP_S_DATA_IN: ::c_int = 4; +pub const TCP_S_DATA_OUT: ::c_int = 8; +pub const TCP_MSS_DEFAULT: usize = 536; +pub const TCP_MSS_DESIRED: usize = 1220; + +// sys/wait.h +pub const WCOREFLAG: ::c_int = 128; +pub const WAIT_ANY: pid_t = -1; +pub const WAIT_MYPGRP: pid_t = 0; + +// sys/file.h +pub const LOCK_SH: ::c_int = 1; +pub const LOCK_EX: ::c_int = 2; +pub const LOCK_UN: ::c_int = 8; +pub const LOCK_NB: ::c_int = 4; + +// sys/mman.h +pub const PROT_NONE: ::c_int = 0; +pub const PROT_READ: ::c_int = 4; +pub const PROT_WRITE: ::c_int = 2; +pub const PROT_EXEC: ::c_int = 1; +pub const MAP_FILE: ::c_int = 1; +pub const MAP_ANON: ::c_int = 2; +pub const MAP_ANONYMOUS: ::c_int = MAP_ANON; +pub const MAP_TYPE: ::c_int = 15; +pub const MAP_COPY: ::c_int = 32; +pub const MAP_SHARED: ::c_int = 16; +pub const MAP_PRIVATE: ::c_int = 0; +pub const MAP_FIXED: ::c_int = 256; +pub const MAP_NOEXTEND: ::c_int = 512; +pub const MAP_HASSEMPHORE: ::c_int = 1024; +pub const MAP_INHERIT: ::c_int = 2048; +pub const MAP_FAILED: *mut ::c_void = !0 as *mut ::c_void; +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 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_MADV_WONTNEED: ::c_int = 4; + +pub const MS_ASYNC: ::c_int = 1; +pub const MS_SYNC: ::c_int = 0; +pub const MS_INVALIDATE: ::c_int = 2; +pub const MREMAP_MAYMOVE: ::c_int = 1; +pub const MREMAP_FIXED: ::c_int = 2; +pub const MCL_CURRENT: ::c_int = 0x0001; +pub const MCL_FUTURE: ::c_int = 0x0002; + +// sys/xattr.h +pub const XATTR_CREATE: ::c_int = 0x1; +pub const XATTR_REPLACE: ::c_int = 0x2; + +// spawn.h +pub const POSIX_SPAWN_USEVFORK: ::c_int = 64; +pub const POSIX_SPAWN_SETSID: ::c_int = 128; + +// sys/syslog.h +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; + +// net/if.h +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_MASTER: ::c_int = 0x400; +pub const IFF_SLAVE: ::c_int = 0x800; +pub const IFF_MULTICAST: ::c_int = 0x1000; +pub const IFF_PORTSEL: ::c_int = 0x2000; +pub const IFF_AUTOMEDIA: ::c_int = 0x4000; +pub const IFF_DYNAMIC: ::c_int = 0x8000; + +// random.h +pub const GRND_NONBLOCK: ::c_uint = 1; +pub const GRND_RANDOM: ::c_uint = 2; +pub const GRND_INSECURE: ::c_uint = 4; + +pub const _PC_LINK_MAX: ::c_int = 0; +pub const _PC_MAX_CANON: ::c_int = 1; +pub const _PC_MAX_INPUT: ::c_int = 2; +pub const _PC_NAME_MAX: ::c_int = 3; +pub const _PC_PATH_MAX: ::c_int = 4; +pub const _PC_PIPE_BUF: ::c_int = 5; +pub const _PC_CHOWN_RESTRICTED: ::c_int = 6; +pub const _PC_NO_TRUNC: ::c_int = 7; +pub const _PC_VDISABLE: ::c_int = 8; +pub const _PC_SYNC_IO: ::c_int = 9; +pub const _PC_ASYNC_IO: ::c_int = 10; +pub const _PC_PRIO_IO: ::c_int = 11; +pub const _PC_SOCK_MAXBUF: ::c_int = 12; +pub const _PC_FILESIZEBITS: ::c_int = 13; +pub const _PC_REC_INCR_XFER_SIZE: ::c_int = 14; +pub const _PC_REC_MAX_XFER_SIZE: ::c_int = 15; +pub const _PC_REC_MIN_XFER_SIZE: ::c_int = 16; +pub const _PC_REC_XFER_ALIGN: ::c_int = 17; +pub const _PC_ALLOC_SIZE_MIN: ::c_int = 18; +pub const _PC_SYMLINK_MAX: ::c_int = 19; +pub const _PC_2_SYMLINKS: ::c_int = 20; +pub const _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_STREAM_MAX: ::c_int = 5; +pub const _SC_TZNAME_MAX: ::c_int = 6; +pub const _SC_JOB_CONTROL: ::c_int = 7; +pub const _SC_SAVED_IDS: ::c_int = 8; +pub const _SC_REALTIME_SIGNALS: ::c_int = 9; +pub const _SC_PRIORITY_SCHEDULING: ::c_int = 10; +pub const _SC_TIMERS: ::c_int = 11; +pub const _SC_ASYNCHRONOUS_IO: ::c_int = 12; +pub const _SC_PRIORITIZED_IO: ::c_int = 13; +pub const _SC_SYNCHRONIZED_IO: ::c_int = 14; +pub const _SC_FSYNC: ::c_int = 15; +pub const _SC_MAPPED_FILES: ::c_int = 16; +pub const _SC_MEMLOCK: ::c_int = 17; +pub const _SC_MEMLOCK_RANGE: ::c_int = 18; +pub const _SC_MEMORY_PROTECTION: ::c_int = 19; +pub const _SC_MESSAGE_PASSING: ::c_int = 20; +pub const _SC_SEMAPHORES: ::c_int = 21; +pub const _SC_SHARED_MEMORY_OBJECTS: ::c_int = 22; +pub const _SC_AIO_LISTIO_MAX: ::c_int = 23; +pub const _SC_AIO_MAX: ::c_int = 24; +pub const _SC_AIO_PRIO_DELTA_MAX: ::c_int = 25; +pub const _SC_DELAYTIMER_MAX: ::c_int = 26; +pub const _SC_MQ_OPEN_MAX: ::c_int = 27; +pub const _SC_MQ_PRIO_MAX: ::c_int = 28; +pub const _SC_VERSION: ::c_int = 29; +pub const _SC_PAGESIZE: ::c_int = 30; +pub const _SC_PAGE_SIZE: ::c_int = 30; +pub const _SC_RTSIG_MAX: ::c_int = 31; +pub const _SC_SEM_NSEMS_MAX: ::c_int = 32; +pub const _SC_SEM_VALUE_MAX: ::c_int = 33; +pub const _SC_SIGQUEUE_MAX: ::c_int = 34; +pub const _SC_TIMER_MAX: ::c_int = 35; +pub const _SC_BC_BASE_MAX: ::c_int = 36; +pub const _SC_BC_DIM_MAX: ::c_int = 37; +pub const _SC_BC_SCALE_MAX: ::c_int = 38; +pub const _SC_BC_STRING_MAX: ::c_int = 39; +pub const _SC_COLL_WEIGHTS_MAX: ::c_int = 40; +pub const _SC_EQUIV_CLASS_MAX: ::c_int = 41; +pub const _SC_EXPR_NEST_MAX: ::c_int = 42; +pub const _SC_LINE_MAX: ::c_int = 43; +pub const _SC_RE_DUP_MAX: ::c_int = 44; +pub const _SC_CHARCLASS_NAME_MAX: ::c_int = 45; +pub const _SC_2_VERSION: ::c_int = 46; +pub const _SC_2_C_BIND: ::c_int = 47; +pub const _SC_2_C_DEV: ::c_int = 48; +pub const _SC_2_FORT_DEV: ::c_int = 49; +pub const _SC_2_FORT_RUN: ::c_int = 50; +pub const _SC_2_SW_DEV: ::c_int = 51; +pub const _SC_2_LOCALEDEF: ::c_int = 52; +pub const _SC_PII: ::c_int = 53; +pub const _SC_PII_XTI: ::c_int = 54; +pub const _SC_PII_SOCKET: ::c_int = 55; +pub const _SC_PII_INTERNET: ::c_int = 56; +pub const _SC_PII_OSI: ::c_int = 57; +pub const _SC_POLL: ::c_int = 58; +pub const _SC_SELECT: ::c_int = 59; +pub const _SC_UIO_MAXIOV: ::c_int = 60; +pub const _SC_IOV_MAX: ::c_int = 60; +pub const _SC_PII_INTERNET_STREAM: ::c_int = 61; +pub const _SC_PII_INTERNET_DGRAM: ::c_int = 62; +pub const _SC_PII_OSI_COTS: ::c_int = 63; +pub const _SC_PII_OSI_CLTS: ::c_int = 64; +pub const _SC_PII_OSI_M: ::c_int = 65; +pub const _SC_T_IOV_MAX: ::c_int = 66; +pub const _SC_THREADS: ::c_int = 67; +pub const _SC_THREAD_SAFE_FUNCTIONS: ::c_int = 68; +pub const _SC_GETGR_R_SIZE_MAX: ::c_int = 69; +pub const _SC_GETPW_R_SIZE_MAX: ::c_int = 70; +pub const _SC_LOGIN_NAME_MAX: ::c_int = 71; +pub const _SC_TTY_NAME_MAX: ::c_int = 72; +pub const _SC_THREAD_DESTRUCTOR_ITERATIONS: ::c_int = 73; +pub const _SC_THREAD_KEYS_MAX: ::c_int = 74; +pub const _SC_THREAD_STACK_MIN: ::c_int = 75; +pub const _SC_THREAD_THREADS_MAX: ::c_int = 76; +pub const _SC_THREAD_ATTR_STACKADDR: ::c_int = 77; +pub const _SC_THREAD_ATTR_STACKSIZE: ::c_int = 78; +pub const _SC_THREAD_PRIORITY_SCHEDULING: ::c_int = 79; +pub const _SC_THREAD_PRIO_INHERIT: ::c_int = 80; +pub const _SC_THREAD_PRIO_PROTECT: ::c_int = 81; +pub const _SC_THREAD_PROCESS_SHARED: ::c_int = 82; +pub const _SC_NPROCESSORS_CONF: ::c_int = 83; +pub const _SC_NPROCESSORS_ONLN: ::c_int = 84; +pub const _SC_PHYS_PAGES: ::c_int = 85; +pub const _SC_AVPHYS_PAGES: ::c_int = 86; +pub const _SC_ATEXIT_MAX: ::c_int = 87; +pub const _SC_PASS_MAX: ::c_int = 88; +pub const _SC_XOPEN_VERSION: ::c_int = 89; +pub const _SC_XOPEN_XCU_VERSION: ::c_int = 90; +pub const _SC_XOPEN_UNIX: ::c_int = 91; +pub const _SC_XOPEN_CRYPT: ::c_int = 92; +pub const _SC_XOPEN_ENH_I18N: ::c_int = 93; +pub const _SC_XOPEN_SHM: ::c_int = 94; +pub const _SC_2_CHAR_TERM: ::c_int = 95; +pub const _SC_2_C_VERSION: ::c_int = 96; +pub const _SC_2_UPE: ::c_int = 97; +pub const _SC_XOPEN_XPG2: ::c_int = 98; +pub const _SC_XOPEN_XPG3: ::c_int = 99; +pub const _SC_XOPEN_XPG4: ::c_int = 100; +pub const _SC_CHAR_BIT: ::c_int = 101; +pub const _SC_CHAR_MAX: ::c_int = 102; +pub const _SC_CHAR_MIN: ::c_int = 103; +pub const _SC_INT_MAX: ::c_int = 104; +pub const _SC_INT_MIN: ::c_int = 105; +pub const _SC_LONG_BIT: ::c_int = 106; +pub const _SC_WORD_BIT: ::c_int = 107; +pub const _SC_MB_LEN_MAX: ::c_int = 108; +pub const _SC_NZERO: ::c_int = 109; +pub const _SC_SSIZE_MAX: ::c_int = 110; +pub const _SC_SCHAR_MAX: ::c_int = 111; +pub const _SC_SCHAR_MIN: ::c_int = 112; +pub const _SC_SHRT_MAX: ::c_int = 113; +pub const _SC_SHRT_MIN: ::c_int = 114; +pub const _SC_UCHAR_MAX: ::c_int = 115; +pub const _SC_UINT_MAX: ::c_int = 116; +pub const _SC_ULONG_MAX: ::c_int = 117; +pub const _SC_USHRT_MAX: ::c_int = 118; +pub const _SC_NL_ARGMAX: ::c_int = 119; +pub const _SC_NL_LANGMAX: ::c_int = 120; +pub const _SC_NL_MSGMAX: ::c_int = 121; +pub const _SC_NL_NMAX: ::c_int = 122; +pub const _SC_NL_SETMAX: ::c_int = 123; +pub const _SC_NL_TEXTMAX: ::c_int = 124; +pub const _SC_XBS5_ILP32_OFF32: ::c_int = 125; +pub const _SC_XBS5_ILP32_OFFBIG: ::c_int = 126; +pub const _SC_XBS5_LP64_OFF64: ::c_int = 127; +pub const _SC_XBS5_LPBIG_OFFBIG: ::c_int = 128; +pub const _SC_XOPEN_LEGACY: ::c_int = 129; +pub const _SC_XOPEN_REALTIME: ::c_int = 130; +pub const _SC_XOPEN_REALTIME_THREADS: ::c_int = 131; +pub const _SC_ADVISORY_INFO: ::c_int = 132; +pub const _SC_BARRIERS: ::c_int = 133; +pub const _SC_BASE: ::c_int = 134; +pub const _SC_C_LANG_SUPPORT: ::c_int = 135; +pub const _SC_C_LANG_SUPPORT_R: ::c_int = 136; +pub const _SC_CLOCK_SELECTION: ::c_int = 137; +pub const _SC_CPUTIME: ::c_int = 138; +pub const _SC_THREAD_CPUTIME: ::c_int = 139; +pub const _SC_DEVICE_IO: ::c_int = 140; +pub const _SC_DEVICE_SPECIFIC: ::c_int = 141; +pub const _SC_DEVICE_SPECIFIC_R: ::c_int = 142; +pub const _SC_FD_MGMT: ::c_int = 143; +pub const _SC_FIFO: ::c_int = 144; +pub const _SC_PIPE: ::c_int = 145; +pub const _SC_FILE_ATTRIBUTES: ::c_int = 146; +pub const _SC_FILE_LOCKING: ::c_int = 147; +pub const _SC_FILE_SYSTEM: ::c_int = 148; +pub const _SC_MONOTONIC_CLOCK: ::c_int = 149; +pub const _SC_MULTI_PROCESS: ::c_int = 150; +pub const _SC_SINGLE_PROCESS: ::c_int = 151; +pub const _SC_NETWORKING: ::c_int = 152; +pub const _SC_READER_WRITER_LOCKS: ::c_int = 153; +pub const _SC_SPIN_LOCKS: ::c_int = 154; +pub const _SC_REGEXP: ::c_int = 155; +pub const _SC_REGEX_VERSION: ::c_int = 156; +pub const _SC_SHELL: ::c_int = 157; +pub const _SC_SIGNALS: ::c_int = 158; +pub const _SC_SPAWN: ::c_int = 159; +pub const _SC_SPORADIC_SERVER: ::c_int = 160; +pub const _SC_THREAD_SPORADIC_SERVER: ::c_int = 161; +pub const _SC_SYSTEM_DATABASE: ::c_int = 162; +pub const _SC_SYSTEM_DATABASE_R: ::c_int = 163; +pub const _SC_TIMEOUTS: ::c_int = 164; +pub const _SC_TYPED_MEMORY_OBJECTS: ::c_int = 165; +pub const _SC_USER_GROUPS: ::c_int = 166; +pub const _SC_USER_GROUPS_R: ::c_int = 167; +pub const _SC_2_PBS: ::c_int = 168; +pub const _SC_2_PBS_ACCOUNTING: ::c_int = 169; +pub const _SC_2_PBS_LOCATE: ::c_int = 170; +pub const _SC_2_PBS_MESSAGE: ::c_int = 171; +pub const _SC_2_PBS_TRACK: ::c_int = 172; +pub const _SC_SYMLOOP_MAX: ::c_int = 173; +pub const _SC_STREAMS: ::c_int = 174; +pub const _SC_2_PBS_CHECKPOINT: ::c_int = 175; +pub const _SC_V6_ILP32_OFF32: ::c_int = 176; +pub const _SC_V6_ILP32_OFFBIG: ::c_int = 177; +pub const _SC_V6_LP64_OFF64: ::c_int = 178; +pub const _SC_V6_LPBIG_OFFBIG: ::c_int = 179; +pub const _SC_HOST_NAME_MAX: ::c_int = 180; +pub const _SC_TRACE: ::c_int = 181; +pub const _SC_TRACE_EVENT_FILTER: ::c_int = 182; +pub const _SC_TRACE_INHERIT: ::c_int = 183; +pub const _SC_TRACE_LOG: ::c_int = 184; +pub const _SC_LEVEL1_ICACHE_SIZE: ::c_int = 185; +pub const _SC_LEVEL1_ICACHE_ASSOC: ::c_int = 186; +pub const _SC_LEVEL1_ICACHE_LINESIZE: ::c_int = 187; +pub const _SC_LEVEL1_DCACHE_SIZE: ::c_int = 188; +pub const _SC_LEVEL1_DCACHE_ASSOC: ::c_int = 189; +pub const _SC_LEVEL1_DCACHE_LINESIZE: ::c_int = 190; +pub const _SC_LEVEL2_CACHE_SIZE: ::c_int = 191; +pub const _SC_LEVEL2_CACHE_ASSOC: ::c_int = 192; +pub const _SC_LEVEL2_CACHE_LINESIZE: ::c_int = 193; +pub const _SC_LEVEL3_CACHE_SIZE: ::c_int = 194; +pub const _SC_LEVEL3_CACHE_ASSOC: ::c_int = 195; +pub const _SC_LEVEL3_CACHE_LINESIZE: ::c_int = 196; +pub const _SC_LEVEL4_CACHE_SIZE: ::c_int = 197; +pub const _SC_LEVEL4_CACHE_ASSOC: ::c_int = 198; +pub const _SC_LEVEL4_CACHE_LINESIZE: ::c_int = 199; +pub const _SC_IPV6: ::c_int = 235; +pub const _SC_RAW_SOCKETS: ::c_int = 236; +pub const _SC_V7_ILP32_OFF32: ::c_int = 237; +pub const _SC_V7_ILP32_OFFBIG: ::c_int = 238; +pub const _SC_V7_LP64_OFF64: ::c_int = 239; +pub const _SC_V7_LPBIG_OFFBIG: ::c_int = 240; +pub const _SC_SS_REPL_MAX: ::c_int = 241; +pub const _SC_TRACE_EVENT_NAME_MAX: ::c_int = 242; +pub const _SC_TRACE_NAME_MAX: ::c_int = 243; +pub const _SC_TRACE_SYS_MAX: ::c_int = 244; +pub const _SC_TRACE_USER_EVENT_MAX: ::c_int = 245; +pub const _SC_XOPEN_STREAMS: ::c_int = 246; +pub const _SC_THREAD_ROBUST_PRIO_INHERIT: ::c_int = 247; +pub const _SC_THREAD_ROBUST_PRIO_PROTECT: ::c_int = 248; +pub const _SC_MINSIGSTKSZ: ::c_int = 249; +pub const _SC_SIGSTKSZ: ::c_int = 250; + +pub const _CS_PATH: ::c_int = 0; +pub const _CS_V6_WIDTH_RESTRICTED_ENVS: ::c_int = 1; +pub const _CS_GNU_LIBC_VERSION: ::c_int = 2; +pub const _CS_GNU_LIBPTHREAD_VERSION: ::c_int = 3; +pub const _CS_V5_WIDTH_RESTRICTED_ENVS: ::c_int = 4; +pub const _CS_V7_WIDTH_RESTRICTED_ENVS: ::c_int = 5; +pub const _CS_LFS_CFLAGS: ::c_int = 1000; +pub const _CS_LFS_LDFLAGS: ::c_int = 1001; +pub const _CS_LFS_LIBS: ::c_int = 1002; +pub const _CS_LFS_LINTFLAGS: ::c_int = 1003; +pub const _CS_LFS64_CFLAGS: ::c_int = 1004; +pub const _CS_LFS64_LDFLAGS: ::c_int = 1005; +pub const _CS_LFS64_LIBS: ::c_int = 1006; +pub const _CS_LFS64_LINTFLAGS: ::c_int = 1007; +pub const _CS_XBS5_ILP32_OFF32_CFLAGS: ::c_int = 1100; +pub const _CS_XBS5_ILP32_OFF32_LDFLAGS: ::c_int = 1101; +pub const _CS_XBS5_ILP32_OFF32_LIBS: ::c_int = 1102; +pub const _CS_XBS5_ILP32_OFF32_LINTFLAGS: ::c_int = 1103; +pub const _CS_XBS5_ILP32_OFFBIG_CFLAGS: ::c_int = 1104; +pub const _CS_XBS5_ILP32_OFFBIG_LDFLAGS: ::c_int = 1105; +pub const _CS_XBS5_ILP32_OFFBIG_LIBS: ::c_int = 1106; +pub const _CS_XBS5_ILP32_OFFBIG_LINTFLAGS: ::c_int = 1107; +pub const _CS_XBS5_LP64_OFF64_CFLAGS: ::c_int = 1108; +pub const _CS_XBS5_LP64_OFF64_LDFLAGS: ::c_int = 1109; +pub const _CS_XBS5_LP64_OFF64_LIBS: ::c_int = 1110; +pub const _CS_XBS5_LP64_OFF64_LINTFLAGS: ::c_int = 1111; +pub const _CS_XBS5_LPBIG_OFFBIG_CFLAGS: ::c_int = 1112; +pub const _CS_XBS5_LPBIG_OFFBIG_LDFLAGS: ::c_int = 1113; +pub const _CS_XBS5_LPBIG_OFFBIG_LIBS: ::c_int = 1114; +pub const _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS: ::c_int = 1115; +pub const _CS_POSIX_V6_ILP32_OFF32_CFLAGS: ::c_int = 1116; +pub const _CS_POSIX_V6_ILP32_OFF32_LDFLAGS: ::c_int = 1117; +pub const _CS_POSIX_V6_ILP32_OFF32_LIBS: ::c_int = 1118; +pub const _CS_POSIX_V6_ILP32_OFF32_LINTFLAGS: ::c_int = 1119; +pub const _CS_POSIX_V6_ILP32_OFFBIG_CFLAGS: ::c_int = 1120; +pub const _CS_POSIX_V6_ILP32_OFFBIG_LDFLAGS: ::c_int = 1121; +pub const _CS_POSIX_V6_ILP32_OFFBIG_LIBS: ::c_int = 1122; +pub const _CS_POSIX_V6_ILP32_OFFBIG_LINTFLAGS: ::c_int = 1123; +pub const _CS_POSIX_V6_LP64_OFF64_CFLAGS: ::c_int = 1124; +pub const _CS_POSIX_V6_LP64_OFF64_LDFLAGS: ::c_int = 1125; +pub const _CS_POSIX_V6_LP64_OFF64_LIBS: ::c_int = 1126; +pub const _CS_POSIX_V6_LP64_OFF64_LINTFLAGS: ::c_int = 1127; +pub const _CS_POSIX_V6_LPBIG_OFFBIG_CFLAGS: ::c_int = 1128; +pub const _CS_POSIX_V6_LPBIG_OFFBIG_LDFLAGS: ::c_int = 1129; +pub const _CS_POSIX_V6_LPBIG_OFFBIG_LIBS: ::c_int = 1130; +pub const _CS_POSIX_V6_LPBIG_OFFBIG_LINTFLAGS: ::c_int = 1131; +pub const _CS_POSIX_V7_ILP32_OFF32_CFLAGS: ::c_int = 1132; +pub const _CS_POSIX_V7_ILP32_OFF32_LDFLAGS: ::c_int = 1133; +pub const _CS_POSIX_V7_ILP32_OFF32_LIBS: ::c_int = 1134; +pub const _CS_POSIX_V7_ILP32_OFF32_LINTFLAGS: ::c_int = 1135; +pub const _CS_POSIX_V7_ILP32_OFFBIG_CFLAGS: ::c_int = 1136; +pub const _CS_POSIX_V7_ILP32_OFFBIG_LDFLAGS: ::c_int = 1137; +pub const _CS_POSIX_V7_ILP32_OFFBIG_LIBS: ::c_int = 1138; +pub const _CS_POSIX_V7_ILP32_OFFBIG_LINTFLAGS: ::c_int = 1139; +pub const _CS_POSIX_V7_LP64_OFF64_CFLAGS: ::c_int = 1140; +pub const _CS_POSIX_V7_LP64_OFF64_LDFLAGS: ::c_int = 1141; +pub const _CS_POSIX_V7_LP64_OFF64_LIBS: ::c_int = 1142; +pub const _CS_POSIX_V7_LP64_OFF64_LINTFLAGS: ::c_int = 1143; +pub const _CS_POSIX_V7_LPBIG_OFFBIG_CFLAGS: ::c_int = 1144; +pub const _CS_POSIX_V7_LPBIG_OFFBIG_LDFLAGS: ::c_int = 1145; +pub const _CS_POSIX_V7_LPBIG_OFFBIG_LIBS: ::c_int = 1146; +pub const _CS_POSIX_V7_LPBIG_OFFBIG_LINTFLAGS: ::c_int = 1147; +pub const _CS_V6_ENV: ::c_int = 1148; +pub const _CS_V7_ENV: ::c_int = 1149; + +pub const PTHREAD_PROCESS_PRIVATE: __pthread_process_shared = 0; +pub const PTHREAD_PROCESS_SHARED: __pthread_process_shared = 1; + +pub const PTHREAD_EXPLICIT_SCHED: __pthread_inheritsched = 0; +pub const PTHREAD_INHERIT_SCHED: __pthread_inheritsched = 1; + +pub const PTHREAD_SCOPE_SYSTEM: __pthread_contentionscope = 0; +pub const PTHREAD_SCOPE_PROCESS: __pthread_contentionscope = 1; + +pub const PTHREAD_CREATE_JOINABLE: __pthread_detachstate = 0; +pub const PTHREAD_CREATE_DETACHED: __pthread_detachstate = 1; + +pub const PTHREAD_PRIO_NONE: __pthread_mutex_protocol = 0; +pub const PTHREAD_PRIO_INHERIT: __pthread_mutex_protocol = 1; +pub const PTHREAD_PRIO_PROTECT: __pthread_mutex_protocol = 2; + +pub const PTHREAD_MUTEX_TIMED: __pthread_mutex_type = 0; +pub const PTHREAD_MUTEX_ERRORCHECK: __pthread_mutex_type = 1; +pub const PTHREAD_MUTEX_RECURSIVE: __pthread_mutex_type = 2; + +pub const PTHREAD_MUTEX_STALLED: __pthread_mutex_robustness = 0; +pub const PTHREAD_MUTEX_ROBUST: __pthread_mutex_robustness = 256; + +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_MEMLOCK: ::__rlimit_resource_t = 6; +pub const RLIMIT_NPROC: ::__rlimit_resource_t = 7; +pub const RLIMIT_OFILE: ::__rlimit_resource_t = 8; +pub const RLIMIT_NOFILE: ::__rlimit_resource_t = 8; +pub const RLIMIT_SBSIZE: ::__rlimit_resource_t = 9; +pub const RLIMIT_AS: ::__rlimit_resource_t = 10; +pub const RLIMIT_VMEM: ::__rlimit_resource_t = 10; +pub const RLIMIT_NLIMITS: ::__rlimit_resource_t = 11; +pub const RLIM_NLIMITS: ::__rlimit_resource_t = 11; + +pub const RUSAGE_SELF: __rusage_who = 0; +pub const RUSAGE_CHILDREN: __rusage_who = -1; + +pub const PRIO_PROCESS: __priority_which = 0; +pub const PRIO_PGRP: __priority_which = 1; +pub const PRIO_USER: __priority_which = 2; + +pub const __UT_LINESIZE: usize = 32; +pub const __UT_NAMESIZE: usize = 32; +pub const __UT_HOSTSIZE: usize = 256; + +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_SEQPACKET: ::c_int = 5; +pub const SOCK_CLOEXEC: ::c_int = 4194304; +pub const SOCK_NONBLOCK: ::c_int = 2048; + +pub const MSG_OOB: ::c_int = 1; +pub const MSG_PEEK: ::c_int = 2; +pub const MSG_DONTROUTE: ::c_int = 4; +pub const MSG_EOR: ::c_int = 8; +pub const MSG_TRUNC: ::c_int = 16; +pub const MSG_CTRUNC: ::c_int = 32; +pub const MSG_WAITALL: ::c_int = 64; +pub const MSG_DONTWAIT: ::c_int = 128; +pub const MSG_NOSIGNAL: ::c_int = 1024; +pub const MSG_CMSG_CLOEXEC: ::c_int = 0x40000000; + +pub const SCM_RIGHTS: ::c_int = 1; +pub const SCM_TIMESTAMP: ::c_int = 2; +pub const SCM_CREDS: ::c_int = 3; + +pub const SO_DEBUG: ::c_int = 1; +pub const SO_ACCEPTCONN: ::c_int = 2; +pub const SO_REUSEADDR: ::c_int = 4; +pub const SO_KEEPALIVE: ::c_int = 8; +pub const SO_DONTROUTE: ::c_int = 16; +pub const SO_BROADCAST: ::c_int = 32; +pub const SO_USELOOPBACK: ::c_int = 64; +pub const SO_LINGER: ::c_int = 128; +pub const SO_OOBINLINE: ::c_int = 256; +pub const SO_REUSEPORT: ::c_int = 512; +pub const SO_SNDBUF: ::c_int = 4097; +pub const SO_RCVBUF: ::c_int = 4098; +pub const SO_SNDLOWAT: ::c_int = 4099; +pub const SO_RCVLOWAT: ::c_int = 4100; +pub const SO_SNDTIMEO: ::c_int = 4101; +pub const SO_RCVTIMEO: ::c_int = 4102; +pub const SO_ERROR: ::c_int = 4103; +pub const SO_STYLE: ::c_int = 4104; +pub const SO_TYPE: ::c_int = 4104; + +pub const IPPROTO_IP: ::c_int = 0; +pub const IPPROTO_ICMP: ::c_int = 1; +pub const IPPROTO_IGMP: ::c_int = 2; +pub const IPPROTO_IPIP: ::c_int = 4; +pub const IPPROTO_TCP: ::c_int = 6; +pub const IPPROTO_EGP: ::c_int = 8; +pub const IPPROTO_PUP: ::c_int = 12; +pub const IPPROTO_UDP: ::c_int = 17; +pub const IPPROTO_IDP: ::c_int = 22; +pub const IPPROTO_TP: ::c_int = 29; +pub const IPPROTO_DCCP: ::c_int = 33; +pub const IPPROTO_IPV6: ::c_int = 41; +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_MTP: ::c_int = 92; +pub const IPPROTO_BEETPH: ::c_int = 94; +pub const IPPROTO_ENCAP: ::c_int = 98; +pub const IPPROTO_PIM: ::c_int = 103; +pub const IPPROTO_COMP: ::c_int = 108; +pub const IPPROTO_L2TP: ::c_int = 115; +pub const IPPROTO_SCTP: ::c_int = 132; +pub const IPPROTO_UDPLITE: ::c_int = 136; +pub const IPPROTO_MPLS: ::c_int = 137; +pub const IPPROTO_ETHERNET: ::c_int = 143; +pub const IPPROTO_RAW: ::c_int = 255; +pub const IPPROTO_MPTCP: ::c_int = 262; +pub const IPPROTO_MAX: ::c_int = 263; + +pub const IPPROTO_HOPOPTS: ::c_int = 0; +pub const IPPROTO_ROUTING: ::c_int = 43; +pub const IPPROTO_FRAGMENT: ::c_int = 44; +pub const IPPROTO_ICMPV6: ::c_int = 58; +pub const IPPROTO_NONE: ::c_int = 59; +pub const IPPROTO_DSTOPTS: ::c_int = 60; +pub const IPPROTO_MH: ::c_int = 135; + +pub const IPPORT_ECHO: in_port_t = 7; +pub const IPPORT_DISCARD: in_port_t = 9; +pub const IPPORT_SYSTAT: in_port_t = 11; +pub const IPPORT_DAYTIME: in_port_t = 13; +pub const IPPORT_NETSTAT: in_port_t = 15; +pub const IPPORT_FTP: in_port_t = 21; +pub const IPPORT_TELNET: in_port_t = 23; +pub const IPPORT_SMTP: in_port_t = 25; +pub const IPPORT_TIMESERVER: in_port_t = 37; +pub const IPPORT_NAMESERVER: in_port_t = 42; +pub const IPPORT_WHOIS: in_port_t = 43; +pub const IPPORT_MTP: in_port_t = 57; +pub const IPPORT_TFTP: in_port_t = 69; +pub const IPPORT_RJE: in_port_t = 77; +pub const IPPORT_FINGER: in_port_t = 79; +pub const IPPORT_TTYLINK: in_port_t = 87; +pub const IPPORT_SUPDUP: in_port_t = 95; +pub const IPPORT_EXECSERVER: in_port_t = 512; +pub const IPPORT_LOGINSERVER: in_port_t = 513; +pub const IPPORT_CMDSERVER: in_port_t = 514; +pub const IPPORT_EFSSERVER: in_port_t = 520; +pub const IPPORT_BIFFUDP: in_port_t = 512; +pub const IPPORT_WHOSERVER: in_port_t = 513; +pub const IPPORT_ROUTESERVER: in_port_t = 520; +pub const IPPORT_USERRESERVED: in_port_t = 5000; + +pub const DT_UNKNOWN: ::c_uchar = 0; +pub const DT_FIFO: ::c_uchar = 1; +pub const DT_CHR: ::c_uchar = 2; +pub const DT_DIR: ::c_uchar = 4; +pub const DT_BLK: ::c_uchar = 6; +pub const DT_REG: ::c_uchar = 8; +pub const DT_LNK: ::c_uchar = 10; +pub const DT_SOCK: ::c_uchar = 12; +pub const DT_WHT: ::c_uchar = 14; + +pub const ST_RDONLY: ::c_ulong = 1; +pub const ST_NOSUID: ::c_ulong = 2; +pub const ST_NOEXEC: ::c_ulong = 8; +pub const ST_SYNCHRONOUS: ::c_ulong = 16; +pub const ST_NOATIME: ::c_ulong = 32; +pub const ST_RELATIME: ::c_ulong = 64; + +pub const RTLD_DI_LMID: ::c_int = 1; +pub const RTLD_DI_LINKMAP: ::c_int = 2; +pub const RTLD_DI_CONFIGADDR: ::c_int = 3; +pub const RTLD_DI_SERINFO: ::c_int = 4; +pub const RTLD_DI_SERINFOSIZE: ::c_int = 5; +pub const RTLD_DI_ORIGIN: ::c_int = 6; +pub const RTLD_DI_PROFILENAME: ::c_int = 7; +pub const RTLD_DI_PROFILEOUT: ::c_int = 8; +pub const RTLD_DI_TLS_MODID: ::c_int = 9; +pub const RTLD_DI_TLS_DATA: ::c_int = 10; +pub const RTLD_DI_PHDR: ::c_int = 11; +pub const RTLD_DI_MAX: ::c_int = 11; + +pub const SI_ASYNCIO: ::c_int = -4; +pub const SI_MESGQ: ::c_int = -3; +pub const SI_TIMER: ::c_int = -2; +pub const SI_QUEUE: ::c_int = -1; +pub const SI_USER: ::c_int = 0; + +pub const ILL_ILLOPC: ::c_int = 1; +pub const ILL_ILLOPN: ::c_int = 2; +pub const ILL_ILLADR: ::c_int = 3; +pub const ILL_ILLTRP: ::c_int = 4; +pub const ILL_PRVOPC: ::c_int = 5; +pub const ILL_PRVREG: ::c_int = 6; +pub const ILL_COPROC: ::c_int = 7; +pub const ILL_BADSTK: ::c_int = 8; + +pub const FPE_INTDIV: ::c_int = 1; +pub const FPE_INTOVF: ::c_int = 2; +pub const FPE_FLTDIV: ::c_int = 3; +pub const FPE_FLTOVF: ::c_int = 4; +pub const FPE_FLTUND: ::c_int = 5; +pub const FPE_FLTRES: ::c_int = 6; +pub const FPE_FLTINV: ::c_int = 7; +pub const FPE_FLTSUB: ::c_int = 8; + +pub const SEGV_MAPERR: ::c_int = 1; +pub const SEGV_ACCERR: ::c_int = 2; + +pub const BUS_ADRALN: ::c_int = 1; +pub const BUS_ADRERR: ::c_int = 2; +pub const BUS_OBJERR: ::c_int = 3; + +pub const TRAP_BRKPT: ::c_int = 1; +pub const TRAP_TRACE: ::c_int = 2; + +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 POLL_IN: ::c_int = 1; +pub const POLL_OUT: ::c_int = 2; +pub const POLL_MSG: ::c_int = 3; +pub const POLL_ERR: ::c_int = 4; +pub const POLL_PRI: ::c_int = 5; +pub const POLL_HUP: ::c_int = 6; + +pub const SIGEV_SIGNAL: ::c_int = 0; +pub const SIGEV_NONE: ::c_int = 1; +pub const SIGEV_THREAD: ::c_int = 2; + +pub const REG_GS: ::c_uint = 0; +pub const REG_FS: ::c_uint = 1; +pub const REG_ES: ::c_uint = 2; +pub const REG_DS: ::c_uint = 3; +pub const REG_EDI: ::c_uint = 4; +pub const REG_ESI: ::c_uint = 5; +pub const REG_EBP: ::c_uint = 6; +pub const REG_ESP: ::c_uint = 7; +pub const REG_EBX: ::c_uint = 8; +pub const REG_EDX: ::c_uint = 9; +pub const REG_ECX: ::c_uint = 10; +pub const REG_EAX: ::c_uint = 11; +pub const REG_TRAPNO: ::c_uint = 12; +pub const REG_ERR: ::c_uint = 13; +pub const REG_EIP: ::c_uint = 14; +pub const REG_CS: ::c_uint = 15; +pub const REG_EFL: ::c_uint = 16; +pub const REG_UESP: ::c_uint = 17; +pub const REG_SS: ::c_uint = 18; + +pub const IOC_VOID: __ioctl_dir = 0; +pub const IOC_OUT: __ioctl_dir = 1; +pub const IOC_IN: __ioctl_dir = 2; +pub const IOC_INOUT: __ioctl_dir = 3; + +pub const IOC_8: __ioctl_datum = 0; +pub const IOC_16: __ioctl_datum = 1; +pub const IOC_32: __ioctl_datum = 2; +pub const IOC_64: __ioctl_datum = 3; + +pub const TCP_ESTABLISHED: ::c_uint = 1; +pub const TCP_SYN_SENT: ::c_uint = 2; +pub const TCP_SYN_RECV: ::c_uint = 3; +pub const TCP_FIN_WAIT1: ::c_uint = 4; +pub const TCP_FIN_WAIT2: ::c_uint = 5; +pub const TCP_TIME_WAIT: ::c_uint = 6; +pub const TCP_CLOSE: ::c_uint = 7; +pub const TCP_CLOSE_WAIT: ::c_uint = 8; +pub const TCP_LAST_ACK: ::c_uint = 9; +pub const TCP_LISTEN: ::c_uint = 10; +pub const TCP_CLOSING: ::c_uint = 11; + +pub const TCP_CA_Open: tcp_ca_state = 0; +pub const TCP_CA_Disorder: tcp_ca_state = 1; +pub const TCP_CA_CWR: tcp_ca_state = 2; +pub const TCP_CA_Recovery: tcp_ca_state = 3; +pub const TCP_CA_Loss: tcp_ca_state = 4; + +pub const TCP_NO_QUEUE: ::c_uint = 0; +pub const TCP_RECV_QUEUE: ::c_uint = 1; +pub const TCP_SEND_QUEUE: ::c_uint = 2; +pub const TCP_QUEUES_NR: ::c_uint = 3; + +pub const P_ALL: idtype_t = 0; +pub const P_PID: idtype_t = 1; +pub const P_PGID: idtype_t = 2; + +pub const SS_ONSTACK: ::c_int = 1; +pub const SS_DISABLE: ::c_int = 4; + +pub const SHUT_RD: ::c_int = 0; +pub const SHUT_WR: ::c_int = 1; +pub const SHUT_RDWR: ::c_int = 2; +pub const PTHREAD_MUTEX_INITIALIZER: pthread_mutex_t = pthread_mutex_t { + __lock: 0, + __owner_id: 0, + __cnt: 0, + __shpid: 0, + __type: PTHREAD_MUTEX_TIMED as ::c_int, + __flags: 0, + __reserved1: 0, + __reserved2: 0, +}; +pub const PTHREAD_COND_INITIALIZER: pthread_cond_t = pthread_cond_t { + __lock: __PTHREAD_SPIN_LOCK_INITIALIZER, + __queue: 0i64 as *mut __pthread, + __attr: 0i64 as *mut __pthread_condattr, + __wrefs: 0, + __data: 0i64 as *mut ::c_void, +}; +pub const PTHREAD_RWLOCK_INITIALIZER: pthread_rwlock_t = pthread_rwlock_t { + __held: __PTHREAD_SPIN_LOCK_INITIALIZER, + __lock: __PTHREAD_SPIN_LOCK_INITIALIZER, + __readers: 0, + __readerqueue: 0i64 as *mut __pthread, + __writerqueue: 0i64 as *mut __pthread, + __attr: 0i64 as *mut __pthread_rwlockattr, + __data: 0i64 as *mut ::c_void, +}; +pub const PTHREAD_STACK_MIN: ::size_t = 0; + +const_fn! { + {const} fn CMSG_ALIGN(len: usize) -> usize { + len + ::mem::size_of::() - 1 & !(::mem::size_of::() - 1) + } +} + +// functions +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_DATA(cmsg: *const cmsghdr) -> *mut ::c_uchar { + cmsg.offset(1) as *mut ::c_uchar + } + + pub {const} fn CMSG_SPACE(length: ::c_uint) -> ::c_uint { + (CMSG_ALIGN(length as usize) + CMSG_ALIGN(::mem::size_of::())) + as ::c_uint + } + + pub {const} fn CMSG_LEN(length: ::c_uint) -> ::c_uint { + CMSG_ALIGN(::mem::size_of::()) as ::c_uint + length + } + + pub fn CMSG_NXTHDR(mhdr: *const msghdr, + cmsg: *const cmsghdr) -> *mut cmsghdr { + if ((*cmsg).cmsg_len as usize) < ::mem::size_of::() { + return 0 as *mut cmsghdr; + }; + let next = (cmsg as usize + + CMSG_ALIGN((*cmsg).cmsg_len as usize)) + as *mut cmsghdr; + let max = (*mhdr).msg_control as usize + + (*mhdr).msg_controllen as usize; + if (next.offset(1)) as usize > max || + next as usize + CMSG_ALIGN((*next).cmsg_len as usize) > max + { + 0 as *mut cmsghdr + } else { + next as *mut cmsghdr + } + } + + 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; + } + } + + pub fn CPU_SET(cpu: usize, cpuset: &mut cpu_set_t) -> () { + let size_in_bits + = 8 * ::mem::size_of_val(&cpuset.bits[0]); // 32, 64 etc + let (idx, offset) = (cpu / size_in_bits, cpu % size_in_bits); + cpuset.bits[idx] |= 1 << offset; + () + } + + pub fn CPU_CLR(cpu: usize, cpuset: &mut cpu_set_t) -> () { + let size_in_bits + = 8 * ::mem::size_of_val(&cpuset.bits[0]); // 32, 64 etc + let (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); + 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_uint { + ((dev >> 8) & 0xff) as ::c_uint + } + + pub fn minor(dev: ::dev_t) -> ::c_uint { + (dev & 0xffff00ff) as ::c_uint + } + + pub fn IPTOS_TOS(tos: u8) -> u8 { + tos & IPTOS_TOS_MASK + } + + pub fn IPTOS_PREC(tos: u8) -> u8 { + tos & IPTOS_PREC_MASK + } + + 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; + } + } +} + +extern "C" { + pub fn lutimes(file: *const ::c_char, times: *const ::timeval) -> ::c_int; + + pub fn futimes(fd: ::c_int, times: *const ::timeval) -> ::c_int; + pub fn futimens(__fd: ::c_int, __times: *const ::timespec) -> ::c_int; + + pub fn utimensat( + dirfd: ::c_int, + path: *const ::c_char, + times: *const ::timespec, + flag: ::c_int, + ) -> ::c_int; + + pub fn mkfifoat(__fd: ::c_int, __path: *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 __libc_current_sigrtmin() -> ::c_int; + + pub fn __libc_current_sigrtmax() -> ::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 sigwait(__set: *const sigset_t, __sig: *mut ::c_int) -> ::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 sigwaitinfo(set: *const sigset_t, info: *mut siginfo_t) -> ::c_int; + + pub fn sigaltstack(ss: *const stack_t, oss: *mut stack_t) -> ::c_int; + + pub fn ioctl(__fd: ::c_int, __request: ::c_ulong, ...) -> ::c_int; + + pub fn pipe2(fds: *mut ::c_int, flags: ::c_int) -> ::c_int; + + pub fn dup3(oldfd: ::c_int, newfd: ::c_int, flags: ::c_int) -> ::c_int; + + pub fn pread64(fd: ::c_int, buf: *mut ::c_void, count: ::size_t, offset: off64_t) -> ::ssize_t; + pub fn pwrite64( + fd: ::c_int, + buf: *const ::c_void, + count: ::size_t, + offset: off64_t, + ) -> ::ssize_t; + + pub fn readv(__fd: ::c_int, __iovec: *const ::iovec, __count: ::c_int) -> ::ssize_t; + pub fn writev(__fd: ::c_int, __iovec: *const ::iovec, __count: ::c_int) -> ::ssize_t; + + pub fn preadv( + __fd: ::c_int, + __iovec: *const ::iovec, + __count: ::c_int, + __offset: __off_t, + ) -> ssize_t; + pub fn pwritev( + __fd: ::c_int, + __iovec: *const ::iovec, + __count: ::c_int, + __offset: __off_t, + ) -> ssize_t; + + pub fn preadv64( + fd: ::c_int, + iov: *const ::iovec, + iovcnt: ::c_int, + offset: ::off64_t, + ) -> ::ssize_t; + pub fn pwritev64( + fd: ::c_int, + iov: *const ::iovec, + iovcnt: ::c_int, + offset: ::off64_t, + ) -> ::ssize_t; + + pub fn fread_unlocked( + buf: *mut ::c_void, + size: ::size_t, + nobj: ::size_t, + stream: *mut ::FILE, + ) -> ::size_t; + + pub fn aio_read(aiocbp: *mut aiocb) -> ::c_int; + pub fn aio_write(aiocbp: *mut aiocb) -> ::c_int; + pub fn aio_fsync(op: ::c_int, aiocbp: *mut aiocb) -> ::c_int; + pub fn aio_error(aiocbp: *const aiocb) -> ::c_int; + pub fn aio_return(aiocbp: *mut aiocb) -> ::ssize_t; + pub fn aio_suspend( + aiocb_list: *const *const aiocb, + nitems: ::c_int, + timeout: *const ::timespec, + ) -> ::c_int; + pub fn aio_cancel(fd: ::c_int, aiocbp: *mut aiocb) -> ::c_int; + pub fn lio_listio( + mode: ::c_int, + aiocb_list: *const *mut aiocb, + nitems: ::c_int, + sevp: *mut ::sigevent, + ) -> ::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 lseek64(__fd: ::c_int, __offset: __off64_t, __whence: ::c_int) -> __off64_t; + + pub fn lseek(__fd: ::c_int, __offset: __off_t, __whence: ::c_int) -> __off_t; + + pub fn fgetpos64(stream: *mut ::FILE, ptr: *mut fpos64_t) -> ::c_int; + 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 ftello64(stream: *mut ::FILE) -> ::off64_t; + + pub fn bind(__fd: ::c_int, __addr: *const sockaddr, __len: socklen_t) -> ::c_int; + + pub fn accept4( + fd: ::c_int, + addr: *mut ::sockaddr, + len: *mut ::socklen_t, + flg: ::c_int, + ) -> ::c_int; + + pub fn ppoll( + fds: *mut ::pollfd, + nfds: nfds_t, + timeout: *const ::timespec, + sigmask: *const sigset_t, + ) -> ::c_int; + + pub fn recvmsg(__fd: ::c_int, __message: *mut msghdr, __flags: ::c_int) -> ::ssize_t; + + pub fn sendmsg(__fd: ::c_int, __message: *const msghdr, __flags: ::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 sendfile( + out_fd: ::c_int, + in_fd: ::c_int, + offset: *mut off_t, + count: ::size_t, + ) -> ::ssize_t; + pub fn sendfile64( + out_fd: ::c_int, + in_fd: ::c_int, + offset: *mut off64_t, + count: ::size_t, + ) -> ::ssize_t; + + pub fn shutdown(__fd: ::c_int, __how: ::c_int) -> ::c_int; + + pub fn sethostname(name: *const ::c_char, len: ::size_t) -> ::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 if_nameindex() -> *mut if_nameindex; + pub fn if_freenameindex(ptr: *mut if_nameindex); + + pub fn getnameinfo( + sa: *const ::sockaddr, + salen: ::socklen_t, + host: *mut ::c_char, + hostlen: ::socklen_t, + serv: *mut ::c_char, + servlen: ::socklen_t, + flags: ::c_int, + ) -> ::c_int; + + pub fn getifaddrs(ifap: *mut *mut ::ifaddrs) -> ::c_int; + pub fn freeifaddrs(ifa: *mut ::ifaddrs); + + pub fn uname(buf: *mut ::utsname) -> ::c_int; + + pub fn gethostid() -> ::c_long; + pub fn sethostid(hostid: ::c_long) -> ::c_int; + + 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 getspent() -> *mut spwd; + + pub fn getspnam(name: *const ::c_char) -> *mut spwd; + + pub fn getpwent_r( + pwd: *mut ::passwd, + buf: *mut ::c_char, + buflen: ::size_t, + result: *mut *mut ::passwd, + ) -> ::c_int; + pub fn getgrent_r( + grp: *mut ::group, + buf: *mut ::c_char, + buflen: ::size_t, + result: *mut *mut ::group, + ) -> ::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 putpwent(p: *const ::passwd, stream: *mut ::FILE) -> ::c_int; + pub fn putgrent(grp: *const ::group, stream: *mut ::FILE) -> ::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 fgetspent_r( + fp: *mut ::FILE, + spbuf: *mut ::spwd, + buf: *mut ::c_char, + buflen: ::size_t, + spbufp: *mut *mut ::spwd, + ) -> ::c_int; + pub fn sgetspent_r( + s: *const ::c_char, + spbuf: *mut ::spwd, + buf: *mut ::c_char, + buflen: ::size_t, + spbufp: *mut *mut ::spwd, + ) -> ::c_int; + pub fn getspent_r( + spbuf: *mut ::spwd, + buf: *mut ::c_char, + buflen: ::size_t, + spbufp: *mut *mut ::spwd, + ) -> ::c_int; + + pub fn getspnam_r( + name: *const ::c_char, + spbuf: *mut spwd, + buf: *mut ::c_char, + buflen: ::size_t, + spbufp: *mut *mut spwd, + ) -> ::c_int; + + // mntent.h + pub fn getmntent_r( + stream: *mut ::FILE, + mntbuf: *mut ::mntent, + buf: *mut ::c_char, + buflen: ::c_int, + ) -> *mut ::mntent; + + pub fn utmpname(file: *const ::c_char) -> ::c_int; + pub fn utmpxname(file: *const ::c_char) -> ::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 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 setresuid(ruid: ::uid_t, euid: ::uid_t, suid: ::uid_t) -> ::c_int; + pub fn setresgid(rgid: ::gid_t, egid: ::gid_t, sgid: ::gid_t) -> ::c_int; + + pub fn initgroups(user: *const ::c_char, group: ::gid_t) -> ::c_int; + + 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 getgrouplist( + user: *const ::c_char, + group: ::gid_t, + groups: *mut ::gid_t, + ngroups: *mut ::c_int, + ) -> ::c_int; + + pub fn setgroups(ngroups: ::size_t, ptr: *const ::gid_t) -> ::c_int; + + pub fn acct(filename: *const ::c_char) -> ::c_int; + + pub fn setmntent(filename: *const ::c_char, ty: *const ::c_char) -> *mut ::FILE; + pub fn getmntent(stream: *mut ::FILE) -> *mut ::mntent; + pub fn addmntent(stream: *mut ::FILE, mnt: *const ::mntent) -> ::c_int; + pub fn endmntent(streamp: *mut ::FILE) -> ::c_int; + pub fn hasmntopt(mnt: *const ::mntent, opt: *const ::c_char) -> *mut ::c_char; + + 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_kill(__threadid: ::pthread_t, __signo: ::c_int) -> ::c_int; + pub fn pthread_cancel(thread: ::pthread_t) -> ::c_int; + pub fn __pthread_equal(__t1: __pthread_t, __t2: __pthread_t) -> ::c_int; + + pub fn pthread_getattr_np(__thr: ::pthread_t, __attr: *mut pthread_attr_t) -> ::c_int; + + pub fn pthread_attr_getguardsize( + __attr: *const pthread_attr_t, + __guardsize: *mut ::size_t, + ) -> ::c_int; + pub fn pthread_attr_setguardsize(attr: *mut ::pthread_attr_t, guardsize: ::size_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 pthread_mutexattr_getpshared( + attr: *const pthread_mutexattr_t, + pshared: *mut ::c_int, + ) -> ::c_int; + pub fn pthread_mutexattr_setpshared( + attr: *mut pthread_mutexattr_t, + pshared: ::c_int, + ) -> ::c_int; + + pub fn pthread_mutex_timedlock( + lock: *mut pthread_mutex_t, + abstime: *const ::timespec, + ) -> ::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_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_getpshared( + attr: *const pthread_condattr_t, + pshared: *mut ::c_int, + ) -> ::c_int; + pub fn pthread_condattr_setpshared(attr: *mut pthread_condattr_t, pshared: ::c_int) -> ::c_int; + + pub fn pthread_once(control: *mut pthread_once_t, routine: extern "C" fn()) -> ::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 pthread_atfork( + prepare: ::Option, + parent: ::Option, + child: ::Option, + ) -> ::c_int; + + pub fn pthread_sigmask( + __how: ::c_int, + __newmask: *const __sigset_t, + __oldmask: *mut __sigset_t, + ) -> ::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 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_getcpuclockid(thread: ::pthread_t, clk_id: *mut ::clockid_t) -> ::c_int; + + pub fn sem_init(sem: *mut sem_t, pshared: ::c_int, value: ::c_uint) -> ::c_int; + pub fn sem_destroy(sem: *mut sem_t) -> ::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 clock_getres(__clock_id: clockid_t, __res: *mut ::timespec) -> ::c_int; + pub fn clock_gettime(__clock_id: clockid_t, __tp: *mut ::timespec) -> ::c_int; + pub fn clock_settime(__clock_id: clockid_t, __tp: *const ::timespec) -> ::c_int; + pub fn clock_getcpuclockid(pid: ::pid_t, clk_id: *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 gettimeofday(tp: *mut ::timeval, tz: *mut ::timezone) -> ::c_int; + pub fn settimeofday(tv: *const ::timeval, tz: *const ::timezone) -> ::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 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 fstat(__fd: ::c_int, __buf: *mut stat) -> ::c_int; + pub fn fstat64(__fd: ::c_int, __buf: *mut stat64) -> ::c_int; + + pub fn fstatat( + __fd: ::c_int, + __file: *const ::c_char, + __buf: *mut stat, + __flag: ::c_int, + ) -> ::c_int; + pub fn fstatat64( + __fd: ::c_int, + __file: *const ::c_char, + __buf: *mut stat64, + __flag: ::c_int, + ) -> ::c_int; + + pub fn statx( + dirfd: ::c_int, + pathname: *const c_char, + flags: ::c_int, + mask: ::c_uint, + statxbuf: *mut statx, + ) -> ::c_int; + + pub fn ftruncate(__fd: ::c_int, __length: __off_t) -> ::c_int; + pub fn ftruncate64(__fd: ::c_int, __length: __off64_t) -> ::c_int; + pub fn truncate64(__file: *const ::c_char, __length: __off64_t) -> ::c_int; + + pub fn lstat(__file: *const ::c_char, __buf: *mut stat) -> ::c_int; + pub fn lstat64(__file: *const ::c_char, __buf: *mut stat64) -> ::c_int; + + pub fn statfs(path: *const ::c_char, buf: *mut statfs) -> ::c_int; + pub fn statfs64(__file: *const ::c_char, __buf: *mut statfs64) -> ::c_int; + pub fn fstatfs(fd: ::c_int, buf: *mut statfs) -> ::c_int; + pub fn fstatfs64(__fildes: ::c_int, __buf: *mut statfs64) -> ::c_int; + + pub fn statvfs(__file: *const ::c_char, __buf: *mut statvfs) -> ::c_int; + pub fn statvfs64(__file: *const ::c_char, __buf: *mut statvfs64) -> ::c_int; + pub fn fstatvfs(__fildes: ::c_int, __buf: *mut statvfs) -> ::c_int; + pub fn fstatvfs64(__fildes: ::c_int, __buf: *mut statvfs64) -> ::c_int; + + pub fn open(__file: *const ::c_char, __oflag: ::c_int, ...) -> ::c_int; + pub fn open64(__file: *const ::c_char, __oflag: ::c_int, ...) -> ::c_int; + + pub fn openat(__fd: ::c_int, __file: *const ::c_char, __oflag: ::c_int, ...) -> ::c_int; + pub fn openat64(__fd: ::c_int, __file: *const ::c_char, __oflag: ::c_int, ...) -> ::c_int; + + pub fn fopen64(filename: *const c_char, mode: *const c_char) -> *mut ::FILE; + pub fn freopen64( + filename: *const c_char, + mode: *const c_char, + file: *mut ::FILE, + ) -> *mut ::FILE; + + pub fn creat64(path: *const c_char, mode: mode_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 mkstemps(template: *mut ::c_char, suffixlen: ::c_int) -> ::c_int; + pub fn tmpfile64() -> *mut ::FILE; + + pub fn popen(command: *const c_char, mode: *const c_char) -> *mut ::FILE; + + pub fn getdtablesize() -> ::c_int; + + // Added in `glibc` 2.34 + pub fn close_range(first: ::c_uint, last: ::c_uint, flags: ::c_int) -> ::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 getpt() -> ::c_int; + pub fn ptsname_r(fd: ::c_int, buf: *mut ::c_char, buflen: ::size_t) -> ::c_int; + pub fn login_tty(fd: ::c_int) -> ::c_int; + + pub fn ctermid(s: *mut ::c_char) -> *mut ::c_char; + + pub fn clearenv() -> ::c_int; + + pub fn execveat( + dirfd: ::c_int, + pathname: *const ::c_char, + argv: *const *mut c_char, + envp: *const *mut c_char, + flags: ::c_int, + ) -> ::c_int; + pub fn execvpe( + file: *const ::c_char, + argv: *const *const ::c_char, + envp: *const *const ::c_char, + ) -> ::c_int; + pub fn fexecve( + fd: ::c_int, + argv: *const *const ::c_char, + envp: *const *const ::c_char, + ) -> ::c_int; + + pub fn daemon(nochdir: ::c_int, noclose: ::c_int) -> ::c_int; + + // posix/spawn.h + 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; + + // 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; + + 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 euidaccess(pathname: *const ::c_char, mode: ::c_int) -> ::c_int; + pub fn eaccess(pathname: *const ::c_char, mode: ::c_int) -> ::c_int; + + pub fn faccessat( + dirfd: ::c_int, + pathname: *const ::c_char, + mode: ::c_int, + flags: ::c_int, + ) -> ::c_int; + + pub fn stat(__file: *const ::c_char, __buf: *mut stat) -> ::c_int; + pub fn stat64(__file: *const ::c_char, __buf: *mut stat64) -> ::c_int; + + pub fn readdir(dirp: *mut ::DIR) -> *mut ::dirent; + pub fn readdir64(dirp: *mut ::DIR) -> *mut ::dirent64; + pub fn readdir_r(dirp: *mut ::DIR, entry: *mut ::dirent, result: *mut *mut ::dirent) + -> ::c_int; + pub fn readdir64_r( + dirp: *mut ::DIR, + entry: *mut ::dirent64, + result: *mut *mut ::dirent64, + ) -> ::c_int; + pub fn seekdir(dirp: *mut ::DIR, loc: ::c_long); + pub fn telldir(dirp: *mut ::DIR) -> ::c_long; + + pub fn dirfd(dirp: *mut ::DIR) -> ::c_int; + + #[link_name = "__xpg_strerror_r"] + pub fn strerror_r(__errnum: ::c_int, __buf: *mut ::c_char, __buflen: ::size_t) -> ::c_int; + + pub fn __errno_location() -> *mut ::c_int; + + pub fn mmap64( + __addr: *mut ::c_void, + __len: size_t, + __prot: ::c_int, + __flags: ::c_int, + __fd: ::c_int, + __offset: __off64_t, + ) -> *mut ::c_void; + + pub fn mremap( + addr: *mut ::c_void, + len: ::size_t, + new_len: ::size_t, + flags: ::c_int, + ... + ) -> *mut ::c_void; + + pub fn mprotect(__addr: *mut ::c_void, __len: ::size_t, __prot: ::c_int) -> ::c_int; + + pub fn msync(__addr: *mut ::c_void, __len: ::size_t, __flags: ::c_int) -> ::c_int; + pub fn sync(); + pub fn syncfs(fd: ::c_int) -> ::c_int; + pub fn fdatasync(fd: ::c_int) -> ::c_int; + + pub fn fallocate64(fd: ::c_int, mode: ::c_int, offset: ::off64_t, len: ::off64_t) -> ::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_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 madvise(__addr: *mut ::c_void, __len: ::size_t, __advice: ::c_int) -> ::c_int; + + pub fn posix_madvise(addr: *mut ::c_void, len: ::size_t, advice: ::c_int) -> ::c_int; + + pub fn getrlimit(resource: ::__rlimit_resource_t, rlim: *mut ::rlimit) -> ::c_int; + pub fn getrlimit64(resource: ::__rlimit_resource_t, rlim: *mut ::rlimit64) -> ::c_int; + pub fn setrlimit(resource: ::__rlimit_resource_t, rlim: *const ::rlimit) -> ::c_int; + pub fn setrlimit64(resource: ::__rlimit_resource_t, rlim: *const ::rlimit64) -> ::c_int; + + pub fn getpriority(which: ::__priority_which, who: ::id_t) -> ::c_int; + pub fn setpriority(which: ::__priority_which, who: ::id_t, prio: ::c_int) -> ::c_int; + + pub fn getrandom(__buffer: *mut ::c_void, __length: ::size_t, __flags: ::c_uint) -> ::ssize_t; + pub fn getentropy(__buffer: *mut ::c_void, __length: ::size_t) -> ::c_int; + + pub fn memrchr(cx: *const ::c_void, c: ::c_int, n: ::size_t) -> *mut ::c_void; + pub fn memmem( + haystack: *const ::c_void, + haystacklen: ::size_t, + needle: *const ::c_void, + needlelen: ::size_t, + ) -> *mut ::c_void; + pub fn strchrnul(s: *const ::c_char, c: ::c_int) -> *mut ::c_char; + + 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 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 qsort_r( + base: *mut ::c_void, + num: ::size_t, + size: ::size_t, + compar: ::Option< + unsafe extern "C" fn(*const ::c_void, *const ::c_void, *mut ::c_void) -> ::c_int, + >, + arg: *mut ::c_void, + ); + + pub fn brk(addr: *mut ::c_void) -> ::c_int; + pub fn sbrk(increment: ::intptr_t) -> *mut ::c_void; + + pub fn memalign(align: ::size_t, size: ::size_t) -> *mut ::c_void; + pub fn mallopt(param: ::c_int, value: ::c_int) -> ::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 malloc_trim(__pad: ::size_t) -> ::c_int; + + pub fn iconv_open(tocode: *const ::c_char, fromcode: *const ::c_char) -> iconv_t; + 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 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 backtrace(buf: *mut *mut ::c_void, sz: ::c_int) -> ::c_int; + + pub fn reboot(how_to: ::c_int) -> ::c_int; + + pub fn getloadavg(loadavg: *mut ::c_double, nelem: ::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 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 glob64( + pattern: *const ::c_char, + flags: ::c_int, + errfunc: ::Option ::c_int>, + pglob: *mut glob64_t, + ) -> ::c_int; + pub fn globfree64(pglob: *mut glob64_t); + + 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, + flags: ::c_int, + ) -> ::c_int; + pub fn lsetxattr( + path: *const c_char, + name: *const c_char, + value: *const ::c_void, + size: ::size_t, + flags: ::c_int, + ) -> ::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(filedes: ::c_int, name: *const c_char) -> ::c_int; + + 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; + + 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 duplocale(base: ::locale_t) -> ::locale_t; + pub fn freelocale(loc: ::locale_t); + 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 nl_langinfo(item: ::nl_item) -> *mut ::c_char; + pub fn nl_langinfo_l(item: ::nl_item, locale: ::locale_t) -> *mut ::c_char; + + pub fn dl_iterate_phdr( + callback: ::Option< + unsafe extern "C" fn( + info: *mut ::dl_phdr_info, + size: ::size_t, + data: *mut ::c_void, + ) -> ::c_int, + >, + data: *mut ::c_void, + ) -> ::c_int; + + pub fn gnu_get_libc_release() -> *const ::c_char; + pub fn gnu_get_libc_version() -> *const ::c_char; +} + +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 << 8; + dev |= minor; + dev + } + + 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 + } + + 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 W_EXITCODE(ret: ::c_int, sig: ::c_int) -> ::c_int { + (ret << 8) | sig + } + + pub {const} fn W_STOPCODE(sig: ::c_int) -> ::c_int { + (sig << 8) | 0x7f + } + + pub {const} fn QCMD(cmd: ::c_int, type_: ::c_int) -> ::c_int { + (cmd << 8) | (type_ & 0x00ff) + } + + pub {const} fn IPOPT_COPIED(o: u8) -> u8 { + o & IPOPT_COPY + } + + pub {const} fn IPOPT_CLASS(o: u8) -> u8 { + o & IPOPT_CLASS_MASK + } + + pub {const} fn IPOPT_NUMBER(o: u8) -> u8 { + o & IPOPT_NUMBER_MASK + } + + pub {const} fn IPTOS_ECN(x: u8) -> u8 { + x & ::IPTOS_ECN_MASK + } +} + +cfg_if! { + if #[cfg(libc_align)] { + mod align; + pub use self::align::*; + } else { + mod no_align; + pub use self::no_align::*; + } +} + +cfg_if! { + if #[cfg(target_pointer_width = "64")] { + mod b64; + pub use self::b64::*; + } else { + mod b32; + pub use self::b32::*; + } +} diff --git a/vendor/libc/src/unix/hurd/no_align.rs b/vendor/libc/src/unix/hurd/no_align.rs new file mode 100644 index 0000000..1dd7d8e --- /dev/null +++ b/vendor/libc/src/unix/hurd/no_align.rs @@ -0,0 +1 @@ +// Placeholder file diff --git a/vendor/libc/src/unix/linux_like/android/b32/arm.rs b/vendor/libc/src/unix/linux_like/android/b32/arm.rs new file mode 100644 index 0000000..c4c7893 --- /dev/null +++ b/vendor/libc/src/unix/linux_like/android/b32/arm.rs @@ -0,0 +1,553 @@ +pub type c_char = u8; +pub type wchar_t = u32; +pub type greg_t = i32; +pub type mcontext_t = sigcontext; + +s! { + pub struct sigcontext { + 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, + } +} + +cfg_if! { + if #[cfg(libc_union)] { + s_no_extra_traits! { + pub struct __c_anonymous_uc_sigmask_with_padding { + pub uc_sigmask: ::sigset_t, + /* Android has a wrong (smaller) sigset_t on x86. */ + __padding_rt_sigset: u32, + } + + pub union __c_anonymous_uc_sigmask { + uc_sigmask: __c_anonymous_uc_sigmask_with_padding, + uc_sigmask64: ::sigset64_t, + } + + 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__c_anonymous_union: __c_anonymous_uc_sigmask, + /* The kernel adds extra padding after uc_sigmask to match + * glibc sigset_t on ARM. */ + __padding: [c_char; 120], + __align: [::c_longlong; 0], + uc_regspace: [::c_ulong; 128], + } + } + + cfg_if! { + if #[cfg(feature = "extra_traits")] { + impl PartialEq for __c_anonymous_uc_sigmask_with_padding { + fn eq( + &self, other: &__c_anonymous_uc_sigmask_with_padding + ) -> bool { + self.uc_sigmask == other.uc_sigmask + // Ignore padding + } + } + impl Eq for __c_anonymous_uc_sigmask_with_padding {} + impl ::fmt::Debug for __c_anonymous_uc_sigmask_with_padding { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("uc_sigmask_with_padding") + .field("uc_sigmask_with_padding", &self.uc_sigmask) + // Ignore padding + .finish() + } + } + impl ::hash::Hash for __c_anonymous_uc_sigmask_with_padding { + fn hash(&self, state: &mut H) { + self.uc_sigmask.hash(state) + // Ignore padding + } + } + + impl PartialEq for __c_anonymous_uc_sigmask { + fn eq(&self, other: &__c_anonymous_uc_sigmask) -> bool { + unsafe { self.uc_sigmask == other.uc_sigmask } + } + } + impl Eq for __c_anonymous_uc_sigmask {} + impl ::fmt::Debug for __c_anonymous_uc_sigmask { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("uc_sigmask") + .field("uc_sigmask", unsafe { &self.uc_sigmask }) + .finish() + } + } + impl ::hash::Hash for __c_anonymous_uc_sigmask { + fn hash(&self, state: &mut H) { + unsafe { self.uc_sigmask.hash(state) } + } + } + + impl PartialEq for ucontext_t { + fn eq(&self, other: &Self) -> 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__c_anonymous_union + == other.uc_sigmask__c_anonymous_union + && &self.uc_regspace[..] == &other.uc_regspace[..] + // Ignore padding field + } + } + impl Eq for ucontext_t {} + impl ::fmt::Debug for ucontext_t { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("ucontext_t") + .field("uc_flags", &self.uc_flags) + .field("uc_link", &self.uc_link) + .field("uc_stack", &self.uc_stack) + .field("uc_mcontext", &self.uc_mcontext) + .field( + "uc_sigmask__c_anonymous_union", + &self.uc_sigmask__c_anonymous_union + ) + .field("uc_regspace", &&self.uc_regspace[..]) + // Ignore padding field + .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__c_anonymous_union.hash(state); + self.uc_regspace[..].hash(state); + // Ignore padding field + } + } + } + } + } +} + +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 = 0o400000; + +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_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_mknod: ::c_long = 14; +pub const SYS_chmod: ::c_long = 15; +pub const SYS_lchown: ::c_long = 16; +pub const SYS_lseek: ::c_long = 19; +pub const SYS_getpid: ::c_long = 20; +pub const SYS_mount: ::c_long = 21; +pub const SYS_setuid: ::c_long = 23; +pub const SYS_getuid: ::c_long = 24; +pub const SYS_ptrace: ::c_long = 26; +pub const SYS_pause: ::c_long = 29; +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_setgid: ::c_long = 46; +pub const SYS_getgid: ::c_long = 47; +pub const SYS_geteuid: ::c_long = 49; +pub const SYS_getegid: ::c_long = 50; +pub const SYS_acct: ::c_long = 51; +pub const SYS_umount2: ::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_setreuid: ::c_long = 70; +pub const SYS_setregid: ::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_getrusage: ::c_long = 77; +pub const SYS_gettimeofday: ::c_long = 78; +pub const SYS_settimeofday: ::c_long = 79; +pub const SYS_getgroups: ::c_long = 80; +pub const SYS_setgroups: ::c_long = 81; +pub const SYS_symlink: ::c_long = 83; +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_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_fchown: ::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_syslog: ::c_long = 103; +pub const SYS_setitimer: ::c_long = 104; +pub const SYS_getitimer: ::c_long = 105; +pub const SYS_stat: ::c_long = 106; +pub const SYS_lstat: ::c_long = 107; +pub const SYS_fstat: ::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_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_uname: ::c_long = 122; +pub const SYS_adjtimex: ::c_long = 124; +pub const SYS_mprotect: ::c_long = 125; +pub const SYS_sigprocmask: ::c_long = 126; +pub const SYS_init_module: ::c_long = 128; +pub const SYS_delete_module: ::c_long = 129; +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_setfsuid: ::c_long = 138; +pub const SYS_setfsgid: ::c_long = 139; +pub const SYS_getdents: ::c_long = 141; +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_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: ::c_long = 161; +pub const SYS_nanosleep: ::c_long = 162; +pub const SYS_mremap: ::c_long = 163; +pub const SYS_setresuid: ::c_long = 164; +pub const SYS_getresuid: ::c_long = 165; +pub const SYS_poll: ::c_long = 168; +pub const SYS_nfsservctl: ::c_long = 169; +pub const SYS_setresgid: ::c_long = 170; +pub const SYS_getresgid: ::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: ::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_chown: ::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_vfork: ::c_long = 190; +pub const SYS_ugetrlimit: ::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_lchown32: ::c_long = 198; +pub const SYS_getuid32: ::c_long = 199; +pub const SYS_getgid32: ::c_long = 200; +pub const SYS_geteuid32: ::c_long = 201; +pub const SYS_getegid32: ::c_long = 202; +pub const SYS_setreuid32: ::c_long = 203; +pub const SYS_setregid32: ::c_long = 204; +pub const SYS_getgroups32: ::c_long = 205; +pub const SYS_setgroups32: ::c_long = 206; +pub const SYS_fchown32: ::c_long = 207; +pub const SYS_setresuid32: ::c_long = 208; +pub const SYS_getresuid32: ::c_long = 209; +pub const SYS_setresgid32: ::c_long = 210; +pub const SYS_getresgid32: ::c_long = 211; +pub const SYS_chown32: ::c_long = 212; +pub const SYS_setuid32: ::c_long = 213; +pub const SYS_setgid32: ::c_long = 214; +pub const SYS_setfsuid32: ::c_long = 215; +pub const SYS_setfsgid32: ::c_long = 216; +pub const SYS_getdents64: ::c_long = 217; +pub const SYS_pivot_root: ::c_long = 218; +pub const SYS_mincore: ::c_long = 219; +pub const SYS_madvise: ::c_long = 220; +pub const SYS_fcntl64: ::c_long = 221; +pub const SYS_gettid: ::c_long = 224; +pub const SYS_readahead: ::c_long = 225; +pub const SYS_setxattr: ::c_long = 226; +pub const SYS_lsetxattr: ::c_long = 227; +pub const SYS_fsetxattr: ::c_long = 228; +pub const SYS_getxattr: ::c_long = 229; +pub const SYS_lgetxattr: ::c_long = 230; +pub const SYS_fgetxattr: ::c_long = 231; +pub const SYS_listxattr: ::c_long = 232; +pub const SYS_llistxattr: ::c_long = 233; +pub const SYS_flistxattr: ::c_long = 234; +pub const SYS_removexattr: ::c_long = 235; +pub const SYS_lremovexattr: ::c_long = 236; +pub const SYS_fremovexattr: ::c_long = 237; +pub const SYS_tkill: ::c_long = 238; +pub const SYS_sendfile64: ::c_long = 239; +pub const SYS_futex: ::c_long = 240; +pub const SYS_sched_setaffinity: ::c_long = 241; +pub const SYS_sched_getaffinity: ::c_long = 242; +pub const SYS_io_setup: ::c_long = 243; +pub const SYS_io_destroy: ::c_long = 244; +pub const SYS_io_getevents: ::c_long = 245; +pub const SYS_io_submit: ::c_long = 246; +pub const SYS_io_cancel: ::c_long = 247; +pub const SYS_exit_group: ::c_long = 248; +pub const SYS_lookup_dcookie: ::c_long = 249; +pub const SYS_epoll_create: ::c_long = 250; +pub const SYS_epoll_ctl: ::c_long = 251; +pub const SYS_epoll_wait: ::c_long = 252; +pub const SYS_remap_file_pages: ::c_long = 253; +pub const SYS_set_tid_address: ::c_long = 256; +pub const SYS_timer_create: ::c_long = 257; +pub const SYS_timer_settime: ::c_long = 258; +pub const SYS_timer_gettime: ::c_long = 259; +pub const SYS_timer_getoverrun: ::c_long = 260; +pub const SYS_timer_delete: ::c_long = 261; +pub const SYS_clock_settime: ::c_long = 262; +pub const SYS_clock_gettime: ::c_long = 263; +pub const SYS_clock_getres: ::c_long = 264; +pub const SYS_clock_nanosleep: ::c_long = 265; +pub const SYS_statfs64: ::c_long = 266; +pub const SYS_fstatfs64: ::c_long = 267; +pub const SYS_tgkill: ::c_long = 268; +pub const SYS_utimes: ::c_long = 269; +pub const SYS_arm_fadvise64_64: ::c_long = 270; +pub const SYS_pciconfig_iobase: ::c_long = 271; +pub const SYS_pciconfig_read: ::c_long = 272; +pub const SYS_pciconfig_write: ::c_long = 273; +pub const SYS_mq_open: ::c_long = 274; +pub const SYS_mq_unlink: ::c_long = 275; +pub const SYS_mq_timedsend: ::c_long = 276; +pub const SYS_mq_timedreceive: ::c_long = 277; +pub const SYS_mq_notify: ::c_long = 278; +pub const SYS_mq_getsetattr: ::c_long = 279; +pub const SYS_waitid: ::c_long = 280; +pub const SYS_socket: ::c_long = 281; +pub const SYS_bind: ::c_long = 282; +pub const SYS_connect: ::c_long = 283; +pub const SYS_listen: ::c_long = 284; +pub const SYS_accept: ::c_long = 285; +pub const SYS_getsockname: ::c_long = 286; +pub const SYS_getpeername: ::c_long = 287; +pub const SYS_socketpair: ::c_long = 288; +pub const SYS_send: ::c_long = 289; +pub const SYS_sendto: ::c_long = 290; +pub const SYS_recv: ::c_long = 291; +pub const SYS_recvfrom: ::c_long = 292; +pub const SYS_shutdown: ::c_long = 293; +pub const SYS_setsockopt: ::c_long = 294; +pub const SYS_getsockopt: ::c_long = 295; +pub const SYS_sendmsg: ::c_long = 296; +pub const SYS_recvmsg: ::c_long = 297; +pub const SYS_semop: ::c_long = 298; +pub const SYS_semget: ::c_long = 299; +pub const SYS_semctl: ::c_long = 300; +pub const SYS_msgsnd: ::c_long = 301; +pub const SYS_msgrcv: ::c_long = 302; +pub const SYS_msgget: ::c_long = 303; +pub const SYS_msgctl: ::c_long = 304; +pub const SYS_shmat: ::c_long = 305; +pub const SYS_shmdt: ::c_long = 306; +pub const SYS_shmget: ::c_long = 307; +pub const SYS_shmctl: ::c_long = 308; +pub const SYS_add_key: ::c_long = 309; +pub const SYS_request_key: ::c_long = 310; +pub const SYS_keyctl: ::c_long = 311; +pub const SYS_semtimedop: ::c_long = 312; +pub const SYS_vserver: ::c_long = 313; +pub const SYS_ioprio_set: ::c_long = 314; +pub const SYS_ioprio_get: ::c_long = 315; +pub const SYS_inotify_init: ::c_long = 316; +pub const SYS_inotify_add_watch: ::c_long = 317; +pub const SYS_inotify_rm_watch: ::c_long = 318; +pub const SYS_mbind: ::c_long = 319; +pub const SYS_get_mempolicy: ::c_long = 320; +pub const SYS_set_mempolicy: ::c_long = 321; +pub const SYS_openat: ::c_long = 322; +pub const SYS_mkdirat: ::c_long = 323; +pub const SYS_mknodat: ::c_long = 324; +pub const SYS_fchownat: ::c_long = 325; +pub const SYS_futimesat: ::c_long = 326; +pub const SYS_fstatat64: ::c_long = 327; +pub const SYS_unlinkat: ::c_long = 328; +pub const SYS_renameat: ::c_long = 329; +pub const SYS_linkat: ::c_long = 330; +pub const SYS_symlinkat: ::c_long = 331; +pub const SYS_readlinkat: ::c_long = 332; +pub const SYS_fchmodat: ::c_long = 333; +pub const SYS_faccessat: ::c_long = 334; +pub const SYS_pselect6: ::c_long = 335; +pub const SYS_ppoll: ::c_long = 336; +pub const SYS_unshare: ::c_long = 337; +pub const SYS_set_robust_list: ::c_long = 338; +pub const SYS_get_robust_list: ::c_long = 339; +pub const SYS_splice: ::c_long = 340; +pub const SYS_arm_sync_file_range: ::c_long = 341; +pub const SYS_tee: ::c_long = 342; +pub const SYS_vmsplice: ::c_long = 343; +pub const SYS_move_pages: ::c_long = 344; +pub const SYS_getcpu: ::c_long = 345; +pub const SYS_epoll_pwait: ::c_long = 346; +pub const SYS_kexec_load: ::c_long = 347; +pub const SYS_utimensat: ::c_long = 348; +pub const SYS_signalfd: ::c_long = 349; +pub const SYS_timerfd_create: ::c_long = 350; +pub const SYS_eventfd: ::c_long = 351; +pub const SYS_fallocate: ::c_long = 352; +pub const SYS_timerfd_settime: ::c_long = 353; +pub const SYS_timerfd_gettime: ::c_long = 354; +pub const SYS_signalfd4: ::c_long = 355; +pub const SYS_eventfd2: ::c_long = 356; +pub const SYS_epoll_create1: ::c_long = 357; +pub const SYS_dup3: ::c_long = 358; +pub const SYS_pipe2: ::c_long = 359; +pub const SYS_inotify_init1: ::c_long = 360; +pub const SYS_preadv: ::c_long = 361; +pub const SYS_pwritev: ::c_long = 362; +pub const SYS_rt_tgsigqueueinfo: ::c_long = 363; +pub const SYS_perf_event_open: ::c_long = 364; +pub const SYS_recvmmsg: ::c_long = 365; +pub const SYS_accept4: ::c_long = 366; +pub const SYS_fanotify_init: ::c_long = 367; +pub const SYS_fanotify_mark: ::c_long = 368; +pub const SYS_prlimit64: ::c_long = 369; +pub const SYS_name_to_handle_at: ::c_long = 370; +pub const SYS_open_by_handle_at: ::c_long = 371; +pub const SYS_clock_adjtime: ::c_long = 372; +pub const SYS_syncfs: ::c_long = 373; +pub const SYS_sendmmsg: ::c_long = 374; +pub const SYS_setns: ::c_long = 375; +pub const SYS_process_vm_readv: ::c_long = 376; +pub const SYS_process_vm_writev: ::c_long = 377; +pub const SYS_kcmp: ::c_long = 378; +pub const SYS_finit_module: ::c_long = 379; +pub const SYS_sched_setattr: ::c_long = 380; +pub const SYS_sched_getattr: ::c_long = 381; +pub const SYS_renameat2: ::c_long = 382; +pub const SYS_seccomp: ::c_long = 383; +pub const SYS_getrandom: ::c_long = 384; +pub const SYS_memfd_create: ::c_long = 385; +pub const SYS_bpf: ::c_long = 386; +pub const SYS_execveat: ::c_long = 387; +pub const SYS_userfaultfd: ::c_long = 388; +pub const SYS_membarrier: ::c_long = 389; +pub const SYS_mlock2: ::c_long = 390; +pub const SYS_copy_file_range: ::c_long = 391; +pub const SYS_preadv2: ::c_long = 392; +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; +pub const REG_R1: ::c_int = 1; +pub const REG_R2: ::c_int = 2; +pub const REG_R3: ::c_int = 3; +pub const REG_R4: ::c_int = 4; +pub const REG_R5: ::c_int = 5; +pub const REG_R6: ::c_int = 6; +pub const REG_R7: ::c_int = 7; +pub const REG_R8: ::c_int = 8; +pub const REG_R9: ::c_int = 9; +pub const REG_R10: ::c_int = 10; +pub const REG_R11: ::c_int = 11; +pub const REG_R12: ::c_int = 12; +pub const REG_R13: ::c_int = 13; +pub const REG_R14: ::c_int = 14; +pub const REG_R15: ::c_int = 15; + +pub const NGREG: ::c_int = 18; + +// From NDK's asm/auxvec.h +pub const AT_SYSINFO_EHDR: ::c_ulong = 33; + +f! { + // Sadly, Android before 5.0 (API level 21), the accept4 syscall is not + // exposed by the libc. As work-around, we implement it through `syscall` + // directly. This workaround can be removed if the minimum version of + // Android is bumped. When the workaround is removed, `accept4` can be + // moved back to `linux_like/mod.rs` + pub fn accept4( + fd: ::c_int, + addr: *mut ::sockaddr, + len: *mut ::socklen_t, + flg: ::c_int + ) -> ::c_int { + ::syscall(SYS_accept4, fd, addr, len, flg) as ::c_int + } +} diff --git a/vendor/libc/src/unix/linux_like/android/b32/mod.rs b/vendor/libc/src/unix/linux_like/android/b32/mod.rs new file mode 100644 index 0000000..1f4f796 --- /dev/null +++ b/vendor/libc/src/unix/linux_like/android/b32/mod.rs @@ -0,0 +1,244 @@ +// The following definitions are correct for arm and i686, +// but may be wrong for mips + +pub type c_long = i32; +pub type c_ulong = u32; +pub type mode_t = u16; +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 { + pub sa_sigaction: ::sighandler_t, + pub sa_mask: ::sigset_t, + pub sa_flags: ::c_int, + pub sa_restorer: ::Option, + } + + pub struct rlimit64 { + pub rlim_cur: u64, + pub rlim_max: u64, + } + + pub struct stat { + pub st_dev: ::c_ulonglong, + __pad0: [::c_uchar; 4], + __st_ino: ::ino_t, + pub st_mode: ::c_uint, + pub st_nlink: ::nlink_t, + pub st_uid: ::uid_t, + pub st_gid: ::gid_t, + pub st_rdev: ::c_ulonglong, + __pad3: [::c_uchar; 4], + pub st_size: ::c_longlong, + pub st_blksize: ::blksize_t, + pub st_blocks: ::c_ulonglong, + pub st_atime: ::c_long, + pub st_atime_nsec: ::c_long, + pub st_mtime: ::c_long, + pub st_mtime_nsec: ::c_long, + pub st_ctime: ::c_long, + pub st_ctime_nsec: ::c_long, + pub st_ino: ::c_ulonglong, + } + + pub struct stat64 { + pub st_dev: ::c_ulonglong, + __pad0: [::c_uchar; 4], + __st_ino: ::ino_t, + pub st_mode: ::c_uint, + pub st_nlink: ::nlink_t, + pub st_uid: ::uid_t, + pub st_gid: ::gid_t, + pub st_rdev: ::c_ulonglong, + __pad3: [::c_uchar; 4], + pub st_size: ::c_longlong, + pub st_blksize: ::blksize_t, + pub st_blocks: ::c_ulonglong, + pub st_atime: ::c_long, + pub st_atime_nsec: ::c_long, + pub st_mtime: ::c_long, + pub st_mtime_nsec: ::c_long, + pub st_ctime: ::c_long, + pub st_ctime_nsec: ::c_long, + pub st_ino: ::c_ulonglong, + } + + pub struct statfs64 { + pub f_type: u32, + pub f_bsize: u32, + 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: u32, + pub f_frsize: u32, + pub f_flags: u32, + pub f_spare: [u32; 4], + } + + pub struct statvfs64 { + pub f_bsize: ::c_ulong, + pub f_frsize: ::c_ulong, + pub f_blocks: ::c_ulong, + pub f_bfree: ::c_ulong, + pub f_bavail: ::c_ulong, + pub f_files: ::c_ulong, + pub f_ffree: ::c_ulong, + pub f_favail: ::c_ulong, + pub f_fsid: ::c_ulong, + pub f_flag: ::c_ulong, + pub f_namemax: ::c_ulong, + } + + pub struct pthread_attr_t { + pub flags: u32, + pub stack_base: *mut ::c_void, + pub stack_size: ::size_t, + pub guard_size: ::size_t, + pub sched_policy: i32, + pub sched_priority: i32, + } + + pub struct pthread_mutex_t { value: ::c_int } + + pub struct pthread_cond_t { value: ::c_int } + + pub struct pthread_rwlock_t { + lock: pthread_mutex_t, + cond: pthread_cond_t, + numLocks: ::c_int, + writerThreadId: ::c_int, + pendingReaders: ::c_int, + pendingWriters: ::c_int, + attr: i32, + __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, + pub pw_uid: ::uid_t, + pub pw_gid: ::gid_t, + pub pw_dir: *mut ::c_char, + pub pw_shell: *mut ::c_char, + } + + pub struct statfs { + pub f_type: u32, + pub f_bsize: u32, + 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: u32, + pub f_frsize: u32, + pub f_flags: u32, + pub f_spare: [u32; 4], + } + + pub struct sysinfo { + pub uptime: ::c_long, + pub loads: [::c_ulong; 3], + pub totalram: ::c_ulong, + pub freeram: ::c_ulong, + pub sharedram: ::c_ulong, + pub bufferram: ::c_ulong, + pub totalswap: ::c_ulong, + pub freeswap: ::c_ulong, + pub procs: ::c_ushort, + pub pad: ::c_ushort, + pub totalhigh: ::c_ulong, + pub freehigh: ::c_ulong, + pub mem_unit: ::c_uint, + pub _f: [::c_char; 8], + } +} + +s_no_extra_traits! { + pub struct sigset64_t { + __bits: [::c_ulong; 2] + } +} + +cfg_if! { + if #[cfg(feature = "extra_traits")] { + impl ::fmt::Debug for sigset64_t { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("sigset64_t") + .field("__bits", &self.__bits) + .finish() + } + } + } +} + +// These constants must be of the same type of sigaction.sa_flags +pub const SA_NOCLDSTOP: ::c_int = 0x00000001; +pub const SA_NOCLDWAIT: ::c_int = 0x00000002; +pub const SA_NODEFER: ::c_int = 0x40000000; +pub const SA_ONSTACK: ::c_int = 0x08000000; +pub const SA_RESETHAND: ::c_int = 0x80000000; +pub const SA_RESTART: ::c_int = 0x10000000; +pub const SA_SIGINFO: ::c_int = 0x00000004; + +pub const RTLD_GLOBAL: ::c_int = 2; +pub const RTLD_NOW: ::c_int = 0; +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 PTHREAD_MUTEX_INITIALIZER: pthread_mutex_t = pthread_mutex_t { value: 0 }; +pub const PTHREAD_COND_INITIALIZER: pthread_cond_t = pthread_cond_t { value: 0 }; +pub const PTHREAD_RWLOCK_INITIALIZER: pthread_rwlock_t = pthread_rwlock_t { + lock: PTHREAD_MUTEX_INITIALIZER, + cond: PTHREAD_COND_INITIALIZER, + numLocks: 0, + writerThreadId: 0, + pendingReaders: 0, + pendingWriters: 0, + attr: 0, + __reserved: [0; 12], +}; +pub const PTHREAD_STACK_MIN: ::size_t = 4096 * 2; +pub const CPU_SETSIZE: ::size_t = 32; +pub const __CPU_BITS: ::size_t = 32; + +pub const UT_LINESIZE: usize = 8; +pub const UT_NAMESIZE: usize = 8; +pub const UT_HOSTSIZE: usize = 16; + +pub const SIGSTKSZ: ::size_t = 8192; +pub const MINSIGSTKSZ: ::size_t = 2048; + +extern "C" { + pub fn timegm64(tm: *const ::tm) -> ::time64_t; +} + +cfg_if! { + if #[cfg(target_arch = "x86")] { + mod x86; + pub use self::x86::*; + } else if #[cfg(target_arch = "arm")] { + mod arm; + pub use self::arm::*; + } else { + // Unknown target_arch + } +} diff --git a/vendor/libc/src/unix/linux_like/android/b32/x86/align.rs b/vendor/libc/src/unix/linux_like/android/b32/x86/align.rs new file mode 100644 index 0000000..04df4a0 --- /dev/null +++ b/vendor/libc/src/unix/linux_like/android/b32/x86/align.rs @@ -0,0 +1,7 @@ +s_no_extra_traits! { + #[allow(missing_debug_implementations)] + #[repr(align(8))] + pub struct max_align_t { + priv_: [f64; 2] + } +} 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 new file mode 100644 index 0000000..64ce93d --- /dev/null +++ b/vendor/libc/src/unix/linux_like/android/b32/x86/mod.rs @@ -0,0 +1,627 @@ +pub type c_char = i8; +pub type wchar_t = i32; +pub type greg_t = i32; + +s! { + pub struct _libc_fpreg { + pub significand: [u16; 4], + pub exponent: u16, + } + + pub struct _libc_fpstate { + pub cw: ::c_ulong, + pub sw: ::c_ulong, + pub tag: ::c_ulong, + pub ipoff: ::c_ulong, + pub cssel: ::c_ulong, + pub dataoff: ::c_ulong, + pub datasel: ::c_ulong, + pub _st: [_libc_fpreg; 8], + pub status: ::c_ulong, + } + + pub struct mcontext_t { + pub gregs: [greg_t; 19], + pub fpregs: *mut _libc_fpstate, + pub oldmask: ::c_ulong, + pub cr2: ::c_ulong, + } +} + +cfg_if! { + if #[cfg(libc_union)] { + s_no_extra_traits! { + pub struct __c_anonymous_uc_sigmask_with_padding { + pub uc_sigmask: ::sigset_t, + /* Android has a wrong (smaller) sigset_t on x86. */ + __padding_rt_sigset: u32, + } + + pub union __c_anonymous_uc_sigmask { + uc_sigmask: __c_anonymous_uc_sigmask_with_padding, + uc_sigmask64: ::sigset64_t, + } + + 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__c_anonymous_union: __c_anonymous_uc_sigmask, + __padding_rt_sigset: u32, + __fpregs_mem: _libc_fpstate, + } + } + + cfg_if! { + if #[cfg(feature = "extra_traits")] { + impl PartialEq for __c_anonymous_uc_sigmask_with_padding { + fn eq( + &self, other: &__c_anonymous_uc_sigmask_with_padding + ) -> bool { + self.uc_sigmask == other.uc_sigmask + // Ignore padding + } + } + impl Eq for __c_anonymous_uc_sigmask_with_padding {} + impl ::fmt::Debug for __c_anonymous_uc_sigmask_with_padding { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("uc_sigmask_with_padding") + .field("uc_sigmask_with_padding", &self.uc_sigmask) + // Ignore padding + .finish() + } + } + impl ::hash::Hash for __c_anonymous_uc_sigmask_with_padding { + fn hash(&self, state: &mut H) { + self.uc_sigmask.hash(state) + // Ignore padding + } + } + + impl PartialEq for __c_anonymous_uc_sigmask { + fn eq(&self, other: &__c_anonymous_uc_sigmask) -> bool { + unsafe { self.uc_sigmask == other.uc_sigmask } + } + } + impl Eq for __c_anonymous_uc_sigmask {} + impl ::fmt::Debug for __c_anonymous_uc_sigmask { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("uc_sigmask") + .field("uc_sigmask", unsafe { &self.uc_sigmask }) + .finish() + } + } + impl ::hash::Hash for __c_anonymous_uc_sigmask { + fn hash(&self, state: &mut H) { + unsafe { self.uc_sigmask.hash(state) } + } + } + + impl PartialEq for ucontext_t { + fn eq(&self, other: &Self) -> 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__c_anonymous_union + == other.uc_sigmask__c_anonymous_union + // Ignore padding field + } + } + impl Eq for ucontext_t {} + impl ::fmt::Debug for ucontext_t { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("ucontext_t") + .field("uc_flags", &self.uc_flags) + .field("uc_link", &self.uc_link) + .field("uc_stack", &self.uc_stack) + .field("uc_mcontext", &self.uc_mcontext) + .field( + "uc_sigmask__c_anonymous_union", + &self.uc_sigmask__c_anonymous_union + ) + // Ignore padding field + .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__c_anonymous_union.hash(state); + // Ignore padding field + } + } + } + } + } +} + +pub const O_DIRECT: ::c_int = 0x4000; +pub const O_DIRECTORY: ::c_int = 0x10000; +pub const O_NOFOLLOW: ::c_int = 0x20000; +pub const O_LARGEFILE: ::c_int = 0o0100000; + +pub const MAP_32BIT: ::c_int = 0x40; + +// Syscall table +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_time: ::c_long = 13; +pub const SYS_mknod: ::c_long = 14; +pub const SYS_chmod: ::c_long = 15; +pub const SYS_lchown: ::c_long = 16; +pub const SYS_break: ::c_long = 17; +pub const SYS_oldstat: ::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_umount: ::c_long = 22; +pub const SYS_setuid: ::c_long = 23; +pub const SYS_getuid: ::c_long = 24; +pub const SYS_stime: ::c_long = 25; +pub const SYS_ptrace: ::c_long = 26; +pub const SYS_alarm: ::c_long = 27; +pub const SYS_oldfstat: ::c_long = 28; +pub const SYS_pause: ::c_long = 29; +pub const SYS_utime: ::c_long = 30; +pub const SYS_stty: ::c_long = 31; +pub const SYS_gtty: ::c_long = 32; +pub const SYS_access: ::c_long = 33; +pub const SYS_nice: ::c_long = 34; +pub const SYS_ftime: ::c_long = 35; +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_prof: ::c_long = 44; +pub const SYS_brk: ::c_long = 45; +pub const SYS_setgid: ::c_long = 46; +pub const SYS_getgid: ::c_long = 47; +pub const SYS_signal: ::c_long = 48; +pub const SYS_geteuid: ::c_long = 49; +pub const SYS_getegid: ::c_long = 50; +pub const SYS_acct: ::c_long = 51; +pub const SYS_umount2: ::c_long = 52; +pub const SYS_lock: ::c_long = 53; +pub const SYS_ioctl: ::c_long = 54; +pub const SYS_fcntl: ::c_long = 55; +pub const SYS_mpx: ::c_long = 56; +pub const SYS_setpgid: ::c_long = 57; +pub const SYS_ulimit: ::c_long = 58; +pub const SYS_oldolduname: ::c_long = 59; +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_setreuid: ::c_long = 70; +pub const SYS_setregid: ::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_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_getgroups: ::c_long = 80; +pub const SYS_setgroups: ::c_long = 81; +pub const SYS_select: ::c_long = 82; +pub const SYS_symlink: ::c_long = 83; +pub const SYS_oldlstat: ::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_readdir: ::c_long = 89; +pub const SYS_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_fchown: ::c_long = 95; +pub const SYS_getpriority: ::c_long = 96; +pub const SYS_setpriority: ::c_long = 97; +pub const SYS_profil: ::c_long = 98; +pub const SYS_statfs: ::c_long = 99; +pub const SYS_fstatfs: ::c_long = 100; +pub const SYS_ioperm: ::c_long = 101; +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_stat: ::c_long = 106; +pub const SYS_lstat: ::c_long = 107; +pub const SYS_fstat: ::c_long = 108; +pub const SYS_olduname: ::c_long = 109; +pub const SYS_iopl: ::c_long = 110; +pub const SYS_vhangup: ::c_long = 111; +pub const SYS_idle: ::c_long = 112; +pub const SYS_vm86old: ::c_long = 113; +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_uname: ::c_long = 122; +pub const SYS_modify_ldt: ::c_long = 123; +pub const SYS_adjtimex: ::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_afs_syscall: ::c_long = 137; +pub const SYS_setfsuid: ::c_long = 138; +pub const SYS_setfsgid: ::c_long = 139; +// FIXME: SYS__llseek is in the NDK sources but for some reason is +// not available in the tests +// pub const SYS__llseek: ::c_long = 140; +pub const SYS_getdents: ::c_long = 141; +// FIXME: SYS__newselect is in the NDK sources but for some reason is +// not available in the tests +// pub const SYS__newselect: ::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; +// FIXME: SYS__llseek is in the NDK sources but for some reason is +// not available in the tests +// 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: ::c_long = 161; +pub const SYS_nanosleep: ::c_long = 162; +pub const SYS_mremap: ::c_long = 163; +pub const SYS_setresuid: ::c_long = 164; +pub const SYS_getresuid: ::c_long = 165; +pub const SYS_vm86: ::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_setresgid: ::c_long = 170; +pub const SYS_getresgid: ::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: ::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_chown: ::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_ugetrlimit: ::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_lchown32: ::c_long = 198; +pub const SYS_getuid32: ::c_long = 199; +pub const SYS_getgid32: ::c_long = 200; +pub const SYS_geteuid32: ::c_long = 201; +pub const SYS_getegid32: ::c_long = 202; +pub const SYS_setreuid32: ::c_long = 203; +pub const SYS_setregid32: ::c_long = 204; +pub const SYS_getgroups32: ::c_long = 205; +pub const SYS_setgroups32: ::c_long = 206; +pub const SYS_fchown32: ::c_long = 207; +pub const SYS_setresuid32: ::c_long = 208; +pub const SYS_getresuid32: ::c_long = 209; +pub const SYS_setresgid32: ::c_long = 210; +pub const SYS_getresgid32: ::c_long = 211; +pub const SYS_chown32: ::c_long = 212; +pub const SYS_setuid32: ::c_long = 213; +pub const SYS_setgid32: ::c_long = 214; +pub const SYS_setfsuid32: ::c_long = 215; +pub const SYS_setfsgid32: ::c_long = 216; +pub const SYS_pivot_root: ::c_long = 217; +pub const SYS_mincore: ::c_long = 218; +pub const SYS_madvise: ::c_long = 219; +pub const SYS_getdents64: ::c_long = 220; +pub const SYS_fcntl64: ::c_long = 221; +pub const SYS_gettid: ::c_long = 224; +pub const SYS_readahead: ::c_long = 225; +pub const SYS_setxattr: ::c_long = 226; +pub const SYS_lsetxattr: ::c_long = 227; +pub const SYS_fsetxattr: ::c_long = 228; +pub const SYS_getxattr: ::c_long = 229; +pub const SYS_lgetxattr: ::c_long = 230; +pub const SYS_fgetxattr: ::c_long = 231; +pub const SYS_listxattr: ::c_long = 232; +pub const SYS_llistxattr: ::c_long = 233; +pub const SYS_flistxattr: ::c_long = 234; +pub const SYS_removexattr: ::c_long = 235; +pub const SYS_lremovexattr: ::c_long = 236; +pub const SYS_fremovexattr: ::c_long = 237; +pub const SYS_tkill: ::c_long = 238; +pub const SYS_sendfile64: ::c_long = 239; +pub const SYS_futex: ::c_long = 240; +pub const SYS_sched_setaffinity: ::c_long = 241; +pub const SYS_sched_getaffinity: ::c_long = 242; +pub const SYS_set_thread_area: ::c_long = 243; +pub const SYS_get_thread_area: ::c_long = 244; +pub const SYS_io_setup: ::c_long = 245; +pub const SYS_io_destroy: ::c_long = 246; +pub const SYS_io_getevents: ::c_long = 247; +pub const SYS_io_submit: ::c_long = 248; +pub const SYS_io_cancel: ::c_long = 249; +pub const SYS_fadvise64: ::c_long = 250; +pub const SYS_exit_group: ::c_long = 252; +pub const SYS_lookup_dcookie: ::c_long = 253; +pub const SYS_epoll_create: ::c_long = 254; +pub const SYS_epoll_ctl: ::c_long = 255; +pub const SYS_epoll_wait: ::c_long = 256; +pub const SYS_remap_file_pages: ::c_long = 257; +pub const SYS_set_tid_address: ::c_long = 258; +pub const SYS_timer_create: ::c_long = 259; +pub const SYS_timer_settime: ::c_long = 260; +pub const SYS_timer_gettime: ::c_long = 261; +pub const SYS_timer_getoverrun: ::c_long = 262; +pub const SYS_timer_delete: ::c_long = 263; +pub const SYS_clock_settime: ::c_long = 264; +pub const SYS_clock_gettime: ::c_long = 265; +pub const SYS_clock_getres: ::c_long = 266; +pub const SYS_clock_nanosleep: ::c_long = 267; +pub const SYS_statfs64: ::c_long = 268; +pub const SYS_fstatfs64: ::c_long = 269; +pub const SYS_tgkill: ::c_long = 270; +pub const SYS_utimes: ::c_long = 271; +pub const SYS_fadvise64_64: ::c_long = 272; +pub const SYS_vserver: ::c_long = 273; +pub const SYS_mbind: ::c_long = 274; +pub const SYS_get_mempolicy: ::c_long = 275; +pub const SYS_set_mempolicy: ::c_long = 276; +pub const SYS_mq_open: ::c_long = 277; +pub const SYS_mq_unlink: ::c_long = 278; +pub const SYS_mq_timedsend: ::c_long = 279; +pub const SYS_mq_timedreceive: ::c_long = 280; +pub const SYS_mq_notify: ::c_long = 281; +pub const SYS_mq_getsetattr: ::c_long = 282; +pub const SYS_kexec_load: ::c_long = 283; +pub const SYS_waitid: ::c_long = 284; +pub const SYS_add_key: ::c_long = 286; +pub const SYS_request_key: ::c_long = 287; +pub const SYS_keyctl: ::c_long = 288; +pub const SYS_ioprio_set: ::c_long = 289; +pub const SYS_ioprio_get: ::c_long = 290; +pub const SYS_inotify_init: ::c_long = 291; +pub const SYS_inotify_add_watch: ::c_long = 292; +pub const SYS_inotify_rm_watch: ::c_long = 293; +pub const SYS_migrate_pages: ::c_long = 294; +pub const SYS_openat: ::c_long = 295; +pub const SYS_mkdirat: ::c_long = 296; +pub const SYS_mknodat: ::c_long = 297; +pub const SYS_fchownat: ::c_long = 298; +pub const SYS_futimesat: ::c_long = 299; +pub const SYS_fstatat64: ::c_long = 300; +pub const SYS_unlinkat: ::c_long = 301; +pub const SYS_renameat: ::c_long = 302; +pub const SYS_linkat: ::c_long = 303; +pub const SYS_symlinkat: ::c_long = 304; +pub const SYS_readlinkat: ::c_long = 305; +pub const SYS_fchmodat: ::c_long = 306; +pub const SYS_faccessat: ::c_long = 307; +pub const SYS_pselect6: ::c_long = 308; +pub const SYS_ppoll: ::c_long = 309; +pub const SYS_unshare: ::c_long = 310; +pub const SYS_set_robust_list: ::c_long = 311; +pub const SYS_get_robust_list: ::c_long = 312; +pub const SYS_splice: ::c_long = 313; +pub const SYS_sync_file_range: ::c_long = 314; +pub const SYS_tee: ::c_long = 315; +pub const SYS_vmsplice: ::c_long = 316; +pub const SYS_move_pages: ::c_long = 317; +pub const SYS_getcpu: ::c_long = 318; +pub const SYS_epoll_pwait: ::c_long = 319; +pub const SYS_utimensat: ::c_long = 320; +pub const SYS_signalfd: ::c_long = 321; +pub const SYS_timerfd_create: ::c_long = 322; +pub const SYS_eventfd: ::c_long = 323; +pub const SYS_fallocate: ::c_long = 324; +pub const SYS_timerfd_settime: ::c_long = 325; +pub const SYS_timerfd_gettime: ::c_long = 326; +pub const SYS_signalfd4: ::c_long = 327; +pub const SYS_eventfd2: ::c_long = 328; +pub const SYS_epoll_create1: ::c_long = 329; +pub const SYS_dup3: ::c_long = 330; +pub const SYS_pipe2: ::c_long = 331; +pub const SYS_inotify_init1: ::c_long = 332; +pub const SYS_preadv: ::c_long = 333; +pub const SYS_pwritev: ::c_long = 334; +pub const SYS_rt_tgsigqueueinfo: ::c_long = 335; +pub const SYS_perf_event_open: ::c_long = 336; +pub const SYS_recvmmsg: ::c_long = 337; +pub const SYS_fanotify_init: ::c_long = 338; +pub const SYS_fanotify_mark: ::c_long = 339; +pub const SYS_prlimit64: ::c_long = 340; +pub const SYS_name_to_handle_at: ::c_long = 341; +pub const SYS_open_by_handle_at: ::c_long = 342; +pub const SYS_clock_adjtime: ::c_long = 343; +pub const SYS_syncfs: ::c_long = 344; +pub const SYS_sendmmsg: ::c_long = 345; +pub const SYS_setns: ::c_long = 346; +pub const SYS_process_vm_readv: ::c_long = 347; +pub const SYS_process_vm_writev: ::c_long = 348; +pub const SYS_kcmp: ::c_long = 349; +pub const SYS_finit_module: ::c_long = 350; +pub const SYS_sched_setattr: ::c_long = 351; +pub const SYS_sched_getattr: ::c_long = 352; +pub const SYS_renameat2: ::c_long = 353; +pub const SYS_seccomp: ::c_long = 354; +pub const SYS_getrandom: ::c_long = 355; +pub const SYS_memfd_create: ::c_long = 356; +pub const SYS_bpf: ::c_long = 357; +pub const SYS_execveat: ::c_long = 358; +pub const SYS_socket: ::c_long = 359; +pub const SYS_socketpair: ::c_long = 360; +pub const SYS_bind: ::c_long = 361; +pub const SYS_connect: ::c_long = 362; +pub const SYS_listen: ::c_long = 363; +pub const SYS_accept4: ::c_long = 364; +pub const SYS_getsockopt: ::c_long = 365; +pub const SYS_setsockopt: ::c_long = 366; +pub const SYS_getsockname: ::c_long = 367; +pub const SYS_getpeername: ::c_long = 368; +pub const SYS_sendto: ::c_long = 369; +pub const SYS_sendmsg: ::c_long = 370; +pub const SYS_recvfrom: ::c_long = 371; +pub const SYS_recvmsg: ::c_long = 372; +pub const SYS_shutdown: ::c_long = 373; +pub const SYS_userfaultfd: ::c_long = 374; +pub const SYS_membarrier: ::c_long = 375; +pub const SYS_mlock2: ::c_long = 376; +pub const SYS_copy_file_range: ::c_long = 377; +pub const SYS_preadv2: ::c_long = 378; +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; +pub const ECX: ::c_int = 1; +pub const EDX: ::c_int = 2; +pub const ESI: ::c_int = 3; +pub const EDI: ::c_int = 4; +pub const EBP: ::c_int = 5; +pub const EAX: ::c_int = 6; +pub const DS: ::c_int = 7; +pub const ES: ::c_int = 8; +pub const FS: ::c_int = 9; +pub const GS: ::c_int = 10; +pub const ORIG_EAX: ::c_int = 11; +pub const EIP: ::c_int = 12; +pub const CS: ::c_int = 13; +pub const EFL: ::c_int = 14; +pub const UESP: ::c_int = 15; +pub const SS: ::c_int = 16; + +// offsets in mcontext_t.gregs from sys/ucontext.h +pub const REG_GS: ::c_int = 0; +pub const REG_FS: ::c_int = 1; +pub const REG_ES: ::c_int = 2; +pub const REG_DS: ::c_int = 3; +pub const REG_EDI: ::c_int = 4; +pub const REG_ESI: ::c_int = 5; +pub const REG_EBP: ::c_int = 6; +pub const REG_ESP: ::c_int = 7; +pub const REG_EBX: ::c_int = 8; +pub const REG_EDX: ::c_int = 9; +pub const REG_ECX: ::c_int = 10; +pub const REG_EAX: ::c_int = 11; +pub const REG_TRAPNO: ::c_int = 12; +pub const REG_ERR: ::c_int = 13; +pub const REG_EIP: ::c_int = 14; +pub const REG_CS: ::c_int = 15; +pub const REG_EFL: ::c_int = 16; +pub const REG_UESP: ::c_int = 17; +pub const REG_SS: ::c_int = 18; + +// From NDK's asm/auxvec.h +pub const AT_SYSINFO: ::c_ulong = 32; +pub const AT_SYSINFO_EHDR: ::c_ulong = 33; +pub const AT_VECTOR_SIZE_ARCH: ::c_ulong = 3; + +// socketcall values from linux/net.h (only the needed ones, and not public) +const SYS_ACCEPT4: ::c_int = 18; + +f! { + // Sadly, Android before 5.0 (API level 21), the accept4 syscall is not + // exposed by the libc. As work-around, we implement it as raw syscall. + // Note that for x86, the `accept4` syscall is not available either, + // and we must use the `socketcall` syscall instead. + // This workaround can be removed if the minimum Android version is bumped. + // When the workaround is removed, `accept4` can be moved back + // to `linux_like/mod.rs` + pub fn accept4( + fd: ::c_int, + addr: *mut ::sockaddr, + len: *mut ::socklen_t, + flg: ::c_int + ) -> ::c_int { + // Arguments are passed as array of `long int` + // (which is big enough on x86 for a pointer). + let mut args = [ + fd as ::c_long, + addr as ::c_long, + len as ::c_long, + flg as ::c_long, + ]; + ::syscall(SYS_socketcall, SYS_ACCEPT4, args[..].as_mut_ptr()) + } +} + +cfg_if! { + if #[cfg(libc_align)] { + mod align; + pub use self::align::*; + } +} diff --git a/vendor/libc/src/unix/linux_like/android/b64/aarch64/align.rs b/vendor/libc/src/unix/linux_like/android/b64/aarch64/align.rs new file mode 100644 index 0000000..154c2c5 --- /dev/null +++ b/vendor/libc/src/unix/linux_like/android/b64/aarch64/align.rs @@ -0,0 +1,29 @@ +s_no_extra_traits! { + #[allow(missing_debug_implementations)] + #[repr(align(16))] + pub struct max_align_t { + priv_: [f32; 8] + } +} + +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 fault_address: ::c_ulonglong, + pub regs: [::c_ulonglong; 31], + pub sp: ::c_ulonglong, + pub pc: ::c_ulonglong, + pub pstate: ::c_ulonglong, + // nested arrays to get the right size/length while being able to + // auto-derive traits like Debug + __reserved: [[u64; 32]; 16], + } +} 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 new file mode 100644 index 0000000..bd3146d --- /dev/null +++ b/vendor/libc/src/unix/linux_like/android/b64/aarch64/mod.rs @@ -0,0 +1,436 @@ +pub type c_char = u8; +pub type wchar_t = u32; +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: ::nlink_t, + 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: ::nlink_t, + 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 user_regs_struct { + pub regs: [u64; 31], + pub sp: u64, + pub pc: u64, + pub pstate: u64, + } +} + +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 = 0o400000; + +pub const SIGSTKSZ: ::size_t = 16384; +pub const MINSIGSTKSZ: ::size_t = 5120; + +// From NDK's asm/hwcap.h +pub const HWCAP_FP: ::c_ulong = 1 << 0; +pub const HWCAP_ASIMD: ::c_ulong = 1 << 1; +pub const HWCAP_EVTSTRM: ::c_ulong = 1 << 2; +pub const HWCAP_AES: ::c_ulong = 1 << 3; +pub const HWCAP_PMULL: ::c_ulong = 1 << 4; +pub const HWCAP_SHA1: ::c_ulong = 1 << 5; +pub const HWCAP_SHA2: ::c_ulong = 1 << 6; +pub const HWCAP_CRC32: ::c_ulong = 1 << 7; +pub const HWCAP_ATOMICS: ::c_ulong = 1 << 8; +pub const HWCAP_FPHP: ::c_ulong = 1 << 9; +pub const HWCAP_ASIMDHP: ::c_ulong = 1 << 10; +pub const HWCAP_CPUID: ::c_ulong = 1 << 11; +pub const HWCAP_ASIMDRDM: ::c_ulong = 1 << 12; +pub const HWCAP_JSCVT: ::c_ulong = 1 << 13; +pub const HWCAP_FCMA: ::c_ulong = 1 << 14; +pub const HWCAP_LRCPC: ::c_ulong = 1 << 15; +pub const HWCAP_DCPOP: ::c_ulong = 1 << 16; +pub const HWCAP_SHA3: ::c_ulong = 1 << 17; +pub const HWCAP_SM3: ::c_ulong = 1 << 18; +pub const HWCAP_SM4: ::c_ulong = 1 << 19; +pub const HWCAP_ASIMDDP: ::c_ulong = 1 << 20; +pub const HWCAP_SHA512: ::c_ulong = 1 << 21; +pub const HWCAP_SVE: ::c_ulong = 1 << 22; +pub const HWCAP_ASIMDFHM: ::c_ulong = 1 << 23; +pub const HWCAP_DIT: ::c_ulong = 1 << 24; +pub const HWCAP_USCAT: ::c_ulong = 1 << 25; +pub const HWCAP_ILRCPC: ::c_ulong = 1 << 26; +pub const HWCAP_FLAGM: ::c_ulong = 1 << 27; +pub const HWCAP_SSBS: ::c_ulong = 1 << 28; +pub const HWCAP_SB: ::c_ulong = 1 << 29; +pub const HWCAP_PACA: ::c_ulong = 1 << 30; +pub const HWCAP_PACG: ::c_ulong = 1 << 31; +pub const HWCAP2_DCPODP: ::c_ulong = 1 << 0; +pub const HWCAP2_SVE2: ::c_ulong = 1 << 1; +pub const HWCAP2_SVEAES: ::c_ulong = 1 << 2; +pub const HWCAP2_SVEPMULL: ::c_ulong = 1 << 3; +pub const HWCAP2_SVEBITPERM: ::c_ulong = 1 << 4; +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; +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_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_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_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_mmap: ::c_long = 222; +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; + +pub const PROT_BTI: ::c_int = 0x10; +pub const PROT_MTE: ::c_int = 0x20; + +// From NDK's asm/auxvec.h +pub const AT_SYSINFO_EHDR: ::c_ulong = 33; +pub const AT_VECTOR_SIZE_ARCH: ::c_ulong = 2; + +cfg_if! { + if #[cfg(libc_align)] { + mod align; + 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 new file mode 100644 index 0000000..97cf137 --- /dev/null +++ b/vendor/libc/src/unix/linux_like/android/b64/mod.rs @@ -0,0 +1,330 @@ +// The following definitions are correct for aarch64 and x86_64, +// but may be wrong for mips64 + +pub type c_long = i64; +pub type c_ulong = u64; +pub type mode_t = u32; +pub type off64_t = i64; +pub type socklen_t = u32; + +s! { + pub struct sigset_t { + __val: [::c_ulong; 1], + } + + pub struct sigaction { + pub sa_flags: ::c_int, + pub sa_sigaction: ::sighandler_t, + pub sa_mask: ::sigset_t, + pub sa_restorer: ::Option, + } + + pub struct rlimit64 { + pub rlim_cur: ::c_ulonglong, + pub rlim_max: ::c_ulonglong, + } + + pub struct pthread_attr_t { + pub flags: u32, + pub stack_base: *mut ::c_void, + pub stack_size: ::size_t, + pub guard_size: ::size_t, + pub sched_policy: i32, + pub sched_priority: i32, + __reserved: [::c_char; 16], + } + + 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 statfs { + pub f_type: u64, + pub f_bsize: u64, + 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: u64, + pub f_frsize: u64, + pub f_flags: u64, + pub f_spare: [u64; 4], + } + + pub struct sysinfo { + pub uptime: ::c_long, + pub loads: [::c_ulong; 3], + pub totalram: ::c_ulong, + pub freeram: ::c_ulong, + pub sharedram: ::c_ulong, + pub bufferram: ::c_ulong, + pub totalswap: ::c_ulong, + pub freeswap: ::c_ulong, + pub procs: ::c_ushort, + pub pad: ::c_ushort, + pub totalhigh: ::c_ulong, + pub freehigh: ::c_ulong, + pub mem_unit: ::c_uint, + pub _f: [::c_char; 0], + } + + pub struct statfs64 { + pub f_type: u64, + pub f_bsize: u64, + 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: u64, + pub f_frsize: u64, + pub f_flags: u64, + pub f_spare: [u64; 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, + pub f_flag: ::c_ulong, + 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! { + pub struct pthread_mutex_t { + value: ::c_int, + __reserved: [::c_char; 36], + } + + pub struct pthread_cond_t { + value: ::c_int, + __reserved: [::c_char; 44], + } + + pub struct pthread_rwlock_t { + numLocks: ::c_int, + writerThreadId: ::c_int, + pendingReaders: ::c_int, + pendingWriters: ::c_int, + attr: i32, + __reserved: [::c_char; 36], + } + + pub struct sigset64_t { + __bits: [::c_ulong; 1] + } +} + +cfg_if! { + if #[cfg(feature = "extra_traits")] { + impl PartialEq for pthread_mutex_t { + fn eq(&self, other: &pthread_mutex_t) -> bool { + self.value == other.value + && self + .__reserved + .iter() + .zip(other.__reserved.iter()) + .all(|(a,b)| a == b) + } + } + + impl Eq for pthread_mutex_t {} + + impl ::fmt::Debug for pthread_mutex_t { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("pthread_mutex_t") + .field("value", &self.value) + // FIXME: .field("__reserved", &self.__reserved) + .finish() + } + } + + impl ::hash::Hash for pthread_mutex_t { + fn hash(&self, state: &mut H) { + self.value.hash(state); + self.__reserved.hash(state); + } + } + + impl PartialEq for pthread_cond_t { + fn eq(&self, other: &pthread_cond_t) -> bool { + self.value == other.value + && self + .__reserved + .iter() + .zip(other.__reserved.iter()) + .all(|(a,b)| a == b) + } + } + + impl Eq for pthread_cond_t {} + + impl ::fmt::Debug for pthread_cond_t { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("pthread_cond_t") + .field("value", &self.value) + // FIXME: .field("__reserved", &self.__reserved) + .finish() + } + } + + impl ::hash::Hash for pthread_cond_t { + fn hash(&self, state: &mut H) { + self.value.hash(state); + self.__reserved.hash(state); + } + } + + impl PartialEq for pthread_rwlock_t { + fn eq(&self, other: &pthread_rwlock_t) -> bool { + self.numLocks == other.numLocks + && self.writerThreadId == other.writerThreadId + && self.pendingReaders == other.pendingReaders + && self.pendingWriters == other.pendingWriters + && self.attr == other.attr + && self + .__reserved + .iter() + .zip(other.__reserved.iter()) + .all(|(a,b)| a == b) + } + } + + impl Eq for pthread_rwlock_t {} + + impl ::fmt::Debug for pthread_rwlock_t { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("pthread_rwlock_t") + .field("numLocks", &self.numLocks) + .field("writerThreadId", &self.writerThreadId) + .field("pendingReaders", &self.pendingReaders) + .field("pendingWriters", &self.pendingWriters) + .field("attr", &self.attr) + // FIXME: .field("__reserved", &self.__reserved) + .finish() + } + } + + impl ::hash::Hash for pthread_rwlock_t { + fn hash(&self, state: &mut H) { + self.numLocks.hash(state); + self.writerThreadId.hash(state); + self.pendingReaders.hash(state); + self.pendingWriters.hash(state); + self.attr.hash(state); + self.__reserved.hash(state); + } + } + + impl ::fmt::Debug for sigset64_t { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("sigset64_t") + .field("__bits", &self.__bits) + .finish() + } + } + } +} + +// These constants must be of the same type of sigaction.sa_flags +pub const SA_NOCLDSTOP: ::c_int = 0x00000001; +pub const SA_NOCLDWAIT: ::c_int = 0x00000002; +pub const SA_NODEFER: ::c_int = 0x40000000; +pub const SA_ONSTACK: ::c_int = 0x08000000; +pub const SA_RESETHAND: ::c_int = 0x80000000; +pub const SA_RESTART: ::c_int = 0x10000000; +pub const SA_SIGINFO: ::c_int = 0x00000004; + +pub const RTLD_GLOBAL: ::c_int = 0x00100; +pub const RTLD_NOW: ::c_int = 2; +pub const RTLD_DEFAULT: *mut ::c_void = 0i64 as *mut ::c_void; + +pub const PTHREAD_MUTEX_INITIALIZER: pthread_mutex_t = pthread_mutex_t { + value: 0, + __reserved: [0; 36], +}; +pub const PTHREAD_COND_INITIALIZER: pthread_cond_t = pthread_cond_t { + value: 0, + __reserved: [0; 44], +}; +pub const PTHREAD_RWLOCK_INITIALIZER: pthread_rwlock_t = pthread_rwlock_t { + numLocks: 0, + writerThreadId: 0, + pendingReaders: 0, + pendingWriters: 0, + attr: 0, + __reserved: [0; 36], +}; +pub const PTHREAD_STACK_MIN: ::size_t = 4096 * 4; +pub const CPU_SETSIZE: ::size_t = 1024; +pub const __CPU_BITS: ::size_t = 64; + +pub const UT_LINESIZE: usize = 32; +pub const UT_NAMESIZE: usize = 32; +pub const UT_HOSTSIZE: usize = 256; + +f! { + // Sadly, Android before 5.0 (API level 21), the accept4 syscall is not + // exposed by the libc. As work-around, we implement it through `syscall` + // directly. This workaround can be removed if the minimum version of + // Android is bumped. When the workaround is removed, `accept4` can be + // moved back to `linux_like/mod.rs` + pub fn accept4( + fd: ::c_int, + addr: *mut ::sockaddr, + len: *mut ::socklen_t, + flg: ::c_int + ) -> ::c_int { + ::syscall(SYS_accept4, fd, addr, len, flg) as ::c_int + } +} + +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! { + 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 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..209f050 --- /dev/null +++ b/vendor/libc/src/unix/linux_like/android/b64/riscv64/mod.rs @@ -0,0 +1,365 @@ +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; + +// From NDK's asm/auxvec.h +pub const AT_SYSINFO_EHDR: ::c_ulong = 33; +pub const AT_L1I_CACHESIZE: ::c_ulong = 40; +pub const AT_L1I_CACHEGEOMETRY: ::c_ulong = 41; +pub const AT_L1D_CACHESIZE: ::c_ulong = 42; +pub const AT_L1D_CACHEGEOMETRY: ::c_ulong = 43; +pub const AT_L2_CACHESIZE: ::c_ulong = 44; +pub const AT_L2_CACHEGEOMETRY: ::c_ulong = 45; +pub const AT_L3_CACHESIZE: ::c_ulong = 46; +pub const AT_L3_CACHEGEOMETRY: ::c_ulong = 47; +pub const AT_VECTOR_SIZE_ARCH: ::c_ulong = 9; + +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/align.rs b/vendor/libc/src/unix/linux_like/android/b64/x86_64/align.rs new file mode 100644 index 0000000..7ca870f --- /dev/null +++ b/vendor/libc/src/unix/linux_like/android/b64/x86_64/align.rs @@ -0,0 +1,7 @@ +s_no_extra_traits! { + #[allow(missing_debug_implementations)] + #[repr(align(16))] + pub struct max_align_t { + priv_: [f64; 4] + } +} 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 new file mode 100644 index 0000000..a736330 --- /dev/null +++ b/vendor/libc/src/unix/linux_like/android/b64/x86_64/mod.rs @@ -0,0 +1,806 @@ +pub type c_char = i8; +pub type wchar_t = i32; +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_nlink: ::c_ulong, + pub st_mode: ::c_uint, + pub st_uid: ::uid_t, + pub st_gid: ::gid_t, + pub st_rdev: ::dev_t, + pub st_size: ::off64_t, + pub st_blksize: ::c_long, + pub st_blocks: ::c_long, + pub st_atime: ::c_long, + pub st_atime_nsec: ::c_long, + pub st_mtime: ::c_long, + pub st_mtime_nsec: ::c_long, + pub st_ctime: ::c_long, + pub st_ctime_nsec: ::c_long, + __unused: [::c_long; 3], + } + + pub struct stat64 { + pub st_dev: ::dev_t, + pub st_ino: ::ino_t, + pub st_nlink: ::c_ulong, + pub st_mode: ::c_uint, + pub st_uid: ::uid_t, + pub st_gid: ::gid_t, + pub st_rdev: ::dev_t, + pub st_size: ::off64_t, + pub st_blksize: ::c_long, + pub st_blocks: ::c_long, + pub st_atime: ::c_long, + pub st_atime_nsec: ::c_long, + pub st_mtime: ::c_long, + pub st_mtime_nsec: ::c_long, + pub st_ctime: ::c_long, + pub st_ctime_nsec: ::c_long, + __unused: [::c_long; 3], + } + + 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! { + if #[cfg(libc_union)] { + s_no_extra_traits! { + pub union __c_anonymous_uc_sigmask { + uc_sigmask: ::sigset_t, + uc_sigmask64: ::sigset64_t, + } + } + + cfg_if! { + if #[cfg(feature = "extra_traits")] { + impl PartialEq for __c_anonymous_uc_sigmask { + fn eq(&self, other: &__c_anonymous_uc_sigmask) -> bool { + unsafe { self.uc_sigmask == other.uc_sigmask } + } + } + impl Eq for __c_anonymous_uc_sigmask {} + impl ::fmt::Debug for __c_anonymous_uc_sigmask { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("uc_sigmask") + .field("uc_sigmask", unsafe { &self.uc_sigmask }) + .finish() + } + } + impl ::hash::Hash for __c_anonymous_uc_sigmask { + fn hash(&self, state: &mut H) { + unsafe { self.uc_sigmask.hash(state) } + } + } + } + } + } +} + +s_no_extra_traits! { + pub struct _libc_fpxreg { + pub significand: [u16; 4], + pub exponent: u16, + __padding: [u16; 3], + } + + pub struct _libc_fpstate { + pub cwd: u16, + pub swd: u16, + pub ftw: u16, + pub fop: u16, + pub rip: u64, + pub rdp: u64, + pub mxcsr: u32, + pub mxcr_mask: u32, + pub _st: [_libc_fpxreg; 8], + pub _xmm: [_libc_xmmreg; 16], + __private: [u32; 24], + } + + pub struct mcontext_t { + pub gregs: [greg_t; 23], + pub fpregs: *mut _libc_fpstate, + __private: [u64; 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_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! { + if #[cfg(feature = "extra_traits")] { + impl PartialEq for _libc_fpxreg { + fn eq(&self, other: &Self) -> bool { + self.significand == other.significand + && self.exponent == other.exponent + // Ignore padding field + } + } + impl Eq for _libc_fpxreg {} + impl ::fmt::Debug for _libc_fpxreg { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("_libc_fpxreg") + .field("significand", &self.significand) + .field("exponent", &self.exponent) + // Ignore padding field + .finish() + } + } + impl ::hash::Hash for _libc_fpxreg { + fn hash(&self, state: &mut H) { + self.significand.hash(state); + self.exponent.hash(state); + // Ignore padding field + } + } + + impl PartialEq for _libc_fpstate { + fn eq(&self, other: &Self) -> 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 == other._st + && self._xmm == other._xmm + // Ignore padding field + } + } + impl Eq for _libc_fpstate {} + impl ::fmt::Debug for _libc_fpstate { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("_libc_fpstate") + .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", &self._st) + .field("_xmm", &self._xmm) + // Ignore padding field + .finish() + } + } + impl ::hash::Hash for _libc_fpstate { + 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.hash(state); + self._xmm.hash(state); + // Ignore padding field + } + } + + impl PartialEq for mcontext_t { + fn eq(&self, other: &Self) -> bool { + self.gregs == other.gregs + && self.fpregs == other.fpregs + // Ignore padding field + } + } + 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) + // Ignore padding field + .finish() + } + } + impl ::hash::Hash for mcontext_t { + fn hash(&self, state: &mut H) { + self.gregs.hash(state); + self.fpregs.hash(state); + // Ignore padding field + } + } + + impl PartialEq for ucontext_t { + fn eq(&self, other: &Self) -> 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_sigmask64 == other.uc_sigmask64 + // Ignore padding field + } + } + impl Eq for ucontext_t {} + impl ::fmt::Debug for ucontext_t { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("ucontext_t") + .field("uc_flags", &self.uc_flags) + .field("uc_link", &self.uc_link) + .field("uc_stack", &self.uc_stack) + .field("uc_mcontext", &self.uc_mcontext) + .field("uc_sigmask64", &self.uc_sigmask64) + // Ignore padding field + .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_sigmask64.hash(state); + // 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 + } + } + } +} + +pub const O_DIRECT: ::c_int = 0x4000; +pub const O_DIRECTORY: ::c_int = 0x10000; +pub const O_NOFOLLOW: ::c_int = 0x20000; +pub const O_LARGEFILE: ::c_int = 0o0100000; + +pub const SIGSTKSZ: ::size_t = 8192; +pub const MINSIGSTKSZ: ::size_t = 2048; + +pub const MAP_32BIT: ::c_int = 0x40; + +// Syscall table + +pub const SYS_read: ::c_long = 0; +pub const SYS_write: ::c_long = 1; +pub const SYS_open: ::c_long = 2; +pub const SYS_close: ::c_long = 3; +pub const SYS_stat: ::c_long = 4; +pub const SYS_fstat: ::c_long = 5; +pub const SYS_lstat: ::c_long = 6; +pub const SYS_poll: ::c_long = 7; +pub const SYS_lseek: ::c_long = 8; +pub const SYS_mmap: ::c_long = 9; +pub const SYS_mprotect: ::c_long = 10; +pub const SYS_munmap: ::c_long = 11; +pub const SYS_brk: ::c_long = 12; +pub const SYS_rt_sigaction: ::c_long = 13; +pub const SYS_rt_sigprocmask: ::c_long = 14; +pub const SYS_rt_sigreturn: ::c_long = 15; +pub const SYS_ioctl: ::c_long = 16; +pub const SYS_pread64: ::c_long = 17; +pub const SYS_pwrite64: ::c_long = 18; +pub const SYS_readv: ::c_long = 19; +pub const SYS_writev: ::c_long = 20; +pub const SYS_access: ::c_long = 21; +pub const SYS_pipe: ::c_long = 22; +pub const SYS_select: ::c_long = 23; +pub const SYS_sched_yield: ::c_long = 24; +pub const SYS_mremap: ::c_long = 25; +pub const SYS_msync: ::c_long = 26; +pub const SYS_mincore: ::c_long = 27; +pub const SYS_madvise: ::c_long = 28; +pub const SYS_shmget: ::c_long = 29; +pub const SYS_shmat: ::c_long = 30; +pub const SYS_shmctl: ::c_long = 31; +pub const SYS_dup: ::c_long = 32; +pub const SYS_dup2: ::c_long = 33; +pub const SYS_pause: ::c_long = 34; +pub const SYS_nanosleep: ::c_long = 35; +pub const SYS_getitimer: ::c_long = 36; +pub const SYS_alarm: ::c_long = 37; +pub const SYS_setitimer: ::c_long = 38; +pub const SYS_getpid: ::c_long = 39; +pub const SYS_sendfile: ::c_long = 40; +pub const SYS_socket: ::c_long = 41; +pub const SYS_connect: ::c_long = 42; +pub const SYS_accept: ::c_long = 43; +pub const SYS_sendto: ::c_long = 44; +pub const SYS_recvfrom: ::c_long = 45; +pub const SYS_sendmsg: ::c_long = 46; +pub const SYS_recvmsg: ::c_long = 47; +pub const SYS_shutdown: ::c_long = 48; +pub const SYS_bind: ::c_long = 49; +pub const SYS_listen: ::c_long = 50; +pub const SYS_getsockname: ::c_long = 51; +pub const SYS_getpeername: ::c_long = 52; +pub const SYS_socketpair: ::c_long = 53; +pub const SYS_setsockopt: ::c_long = 54; +pub const SYS_getsockopt: ::c_long = 55; +pub const SYS_clone: ::c_long = 56; +pub const SYS_fork: ::c_long = 57; +pub const SYS_vfork: ::c_long = 58; +pub const SYS_execve: ::c_long = 59; +pub const SYS_exit: ::c_long = 60; +pub const SYS_wait4: ::c_long = 61; +pub const SYS_kill: ::c_long = 62; +pub const SYS_uname: ::c_long = 63; +pub const SYS_semget: ::c_long = 64; +pub const SYS_semop: ::c_long = 65; +pub const SYS_semctl: ::c_long = 66; +pub const SYS_shmdt: ::c_long = 67; +pub const SYS_msgget: ::c_long = 68; +pub const SYS_msgsnd: ::c_long = 69; +pub const SYS_msgrcv: ::c_long = 70; +pub const SYS_msgctl: ::c_long = 71; +pub const SYS_fcntl: ::c_long = 72; +pub const SYS_flock: ::c_long = 73; +pub const SYS_fsync: ::c_long = 74; +pub const SYS_fdatasync: ::c_long = 75; +pub const SYS_truncate: ::c_long = 76; +pub const SYS_ftruncate: ::c_long = 77; +pub const SYS_getdents: ::c_long = 78; +pub const SYS_getcwd: ::c_long = 79; +pub const SYS_chdir: ::c_long = 80; +pub const SYS_fchdir: ::c_long = 81; +pub const SYS_rename: ::c_long = 82; +pub const SYS_mkdir: ::c_long = 83; +pub const SYS_rmdir: ::c_long = 84; +pub const SYS_creat: ::c_long = 85; +pub const SYS_link: ::c_long = 86; +pub const SYS_unlink: ::c_long = 87; +pub const SYS_symlink: ::c_long = 88; +pub const SYS_readlink: ::c_long = 89; +pub const SYS_chmod: ::c_long = 90; +pub const SYS_fchmod: ::c_long = 91; +pub const SYS_chown: ::c_long = 92; +pub const SYS_fchown: ::c_long = 93; +pub const SYS_lchown: ::c_long = 94; +pub const SYS_umask: ::c_long = 95; +pub const SYS_gettimeofday: ::c_long = 96; +pub const SYS_getrlimit: ::c_long = 97; +pub const SYS_getrusage: ::c_long = 98; +pub const SYS_sysinfo: ::c_long = 99; +pub const SYS_times: ::c_long = 100; +pub const SYS_ptrace: ::c_long = 101; +pub const SYS_getuid: ::c_long = 102; +pub const SYS_syslog: ::c_long = 103; +pub const SYS_getgid: ::c_long = 104; +pub const SYS_setuid: ::c_long = 105; +pub const SYS_setgid: ::c_long = 106; +pub const SYS_geteuid: ::c_long = 107; +pub const SYS_getegid: ::c_long = 108; +pub const SYS_setpgid: ::c_long = 109; +pub const SYS_getppid: ::c_long = 110; +pub const SYS_getpgrp: ::c_long = 111; +pub const SYS_setsid: ::c_long = 112; +pub const SYS_setreuid: ::c_long = 113; +pub const SYS_setregid: ::c_long = 114; +pub const SYS_getgroups: ::c_long = 115; +pub const SYS_setgroups: ::c_long = 116; +pub const SYS_setresuid: ::c_long = 117; +pub const SYS_getresuid: ::c_long = 118; +pub const SYS_setresgid: ::c_long = 119; +pub const SYS_getresgid: ::c_long = 120; +pub const SYS_getpgid: ::c_long = 121; +pub const SYS_setfsuid: ::c_long = 122; +pub const SYS_setfsgid: ::c_long = 123; +pub const SYS_getsid: ::c_long = 124; +pub const SYS_capget: ::c_long = 125; +pub const SYS_capset: ::c_long = 126; +pub const SYS_rt_sigpending: ::c_long = 127; +pub const SYS_rt_sigtimedwait: ::c_long = 128; +pub const SYS_rt_sigqueueinfo: ::c_long = 129; +pub const SYS_rt_sigsuspend: ::c_long = 130; +pub const SYS_sigaltstack: ::c_long = 131; +pub const SYS_utime: ::c_long = 132; +pub const SYS_mknod: ::c_long = 133; +pub const SYS_uselib: ::c_long = 134; +pub const SYS_personality: ::c_long = 135; +pub const SYS_ustat: ::c_long = 136; +pub const SYS_statfs: ::c_long = 137; +pub const SYS_fstatfs: ::c_long = 138; +pub const SYS_sysfs: ::c_long = 139; +pub const SYS_getpriority: ::c_long = 140; +pub const SYS_setpriority: ::c_long = 141; +pub const SYS_sched_setparam: ::c_long = 142; +pub const SYS_sched_getparam: ::c_long = 143; +pub const SYS_sched_setscheduler: ::c_long = 144; +pub const SYS_sched_getscheduler: ::c_long = 145; +pub const SYS_sched_get_priority_max: ::c_long = 146; +pub const SYS_sched_get_priority_min: ::c_long = 147; +pub const SYS_sched_rr_get_interval: ::c_long = 148; +pub const SYS_mlock: ::c_long = 149; +pub const SYS_munlock: ::c_long = 150; +pub const SYS_mlockall: ::c_long = 151; +pub const SYS_munlockall: ::c_long = 152; +pub const SYS_vhangup: ::c_long = 153; +pub const SYS_modify_ldt: ::c_long = 154; +pub const SYS_pivot_root: ::c_long = 155; +// FIXME: SYS__sysctl is in the NDK sources but for some reason is +// not available in the tests +// pub const SYS__sysctl: ::c_long = 156; +pub const SYS_prctl: ::c_long = 157; +pub const SYS_arch_prctl: ::c_long = 158; +pub const SYS_adjtimex: ::c_long = 159; +pub const SYS_setrlimit: ::c_long = 160; +pub const SYS_chroot: ::c_long = 161; +pub const SYS_sync: ::c_long = 162; +pub const SYS_acct: ::c_long = 163; +pub const SYS_settimeofday: ::c_long = 164; +pub const SYS_mount: ::c_long = 165; +pub const SYS_umount2: ::c_long = 166; +pub const SYS_swapon: ::c_long = 167; +pub const SYS_swapoff: ::c_long = 168; +pub const SYS_reboot: ::c_long = 169; +pub const SYS_sethostname: ::c_long = 170; +pub const SYS_setdomainname: ::c_long = 171; +pub const SYS_iopl: ::c_long = 172; +pub const SYS_ioperm: ::c_long = 173; +pub const SYS_create_module: ::c_long = 174; +pub const SYS_init_module: ::c_long = 175; +pub const SYS_delete_module: ::c_long = 176; +pub const SYS_get_kernel_syms: ::c_long = 177; +pub const SYS_query_module: ::c_long = 178; +pub const SYS_quotactl: ::c_long = 179; +pub const SYS_nfsservctl: ::c_long = 180; +pub const SYS_getpmsg: ::c_long = 181; +pub const SYS_putpmsg: ::c_long = 182; +pub const SYS_afs_syscall: ::c_long = 183; +pub const SYS_tuxcall: ::c_long = 184; +pub const SYS_security: ::c_long = 185; +pub const SYS_gettid: ::c_long = 186; +pub const SYS_readahead: ::c_long = 187; +pub const SYS_setxattr: ::c_long = 188; +pub const SYS_lsetxattr: ::c_long = 189; +pub const SYS_fsetxattr: ::c_long = 190; +pub const SYS_getxattr: ::c_long = 191; +pub const SYS_lgetxattr: ::c_long = 192; +pub const SYS_fgetxattr: ::c_long = 193; +pub const SYS_listxattr: ::c_long = 194; +pub const SYS_llistxattr: ::c_long = 195; +pub const SYS_flistxattr: ::c_long = 196; +pub const SYS_removexattr: ::c_long = 197; +pub const SYS_lremovexattr: ::c_long = 198; +pub const SYS_fremovexattr: ::c_long = 199; +pub const SYS_tkill: ::c_long = 200; +pub const SYS_time: ::c_long = 201; +pub const SYS_futex: ::c_long = 202; +pub const SYS_sched_setaffinity: ::c_long = 203; +pub const SYS_sched_getaffinity: ::c_long = 204; +pub const SYS_set_thread_area: ::c_long = 205; +pub const SYS_io_setup: ::c_long = 206; +pub const SYS_io_destroy: ::c_long = 207; +pub const SYS_io_getevents: ::c_long = 208; +pub const SYS_io_submit: ::c_long = 209; +pub const SYS_io_cancel: ::c_long = 210; +pub const SYS_get_thread_area: ::c_long = 211; +pub const SYS_lookup_dcookie: ::c_long = 212; +pub const SYS_epoll_create: ::c_long = 213; +pub const SYS_epoll_ctl_old: ::c_long = 214; +pub const SYS_epoll_wait_old: ::c_long = 215; +pub const SYS_remap_file_pages: ::c_long = 216; +pub const SYS_getdents64: ::c_long = 217; +pub const SYS_set_tid_address: ::c_long = 218; +pub const SYS_restart_syscall: ::c_long = 219; +pub const SYS_semtimedop: ::c_long = 220; +pub const SYS_fadvise64: ::c_long = 221; +pub const SYS_timer_create: ::c_long = 222; +pub const SYS_timer_settime: ::c_long = 223; +pub const SYS_timer_gettime: ::c_long = 224; +pub const SYS_timer_getoverrun: ::c_long = 225; +pub const SYS_timer_delete: ::c_long = 226; +pub const SYS_clock_settime: ::c_long = 227; +pub const SYS_clock_gettime: ::c_long = 228; +pub const SYS_clock_getres: ::c_long = 229; +pub const SYS_clock_nanosleep: ::c_long = 230; +pub const SYS_exit_group: ::c_long = 231; +pub const SYS_epoll_wait: ::c_long = 232; +pub const SYS_epoll_ctl: ::c_long = 233; +pub const SYS_tgkill: ::c_long = 234; +pub const SYS_utimes: ::c_long = 235; +pub const SYS_vserver: ::c_long = 236; +pub const SYS_mbind: ::c_long = 237; +pub const SYS_set_mempolicy: ::c_long = 238; +pub const SYS_get_mempolicy: ::c_long = 239; +pub const SYS_mq_open: ::c_long = 240; +pub const SYS_mq_unlink: ::c_long = 241; +pub const SYS_mq_timedsend: ::c_long = 242; +pub const SYS_mq_timedreceive: ::c_long = 243; +pub const SYS_mq_notify: ::c_long = 244; +pub const SYS_mq_getsetattr: ::c_long = 245; +pub const SYS_kexec_load: ::c_long = 246; +pub const SYS_waitid: ::c_long = 247; +pub const SYS_add_key: ::c_long = 248; +pub const SYS_request_key: ::c_long = 249; +pub const SYS_keyctl: ::c_long = 250; +pub const SYS_ioprio_set: ::c_long = 251; +pub const SYS_ioprio_get: ::c_long = 252; +pub const SYS_inotify_init: ::c_long = 253; +pub const SYS_inotify_add_watch: ::c_long = 254; +pub const SYS_inotify_rm_watch: ::c_long = 255; +pub const SYS_migrate_pages: ::c_long = 256; +pub const SYS_openat: ::c_long = 257; +pub const SYS_mkdirat: ::c_long = 258; +pub const SYS_mknodat: ::c_long = 259; +pub const SYS_fchownat: ::c_long = 260; +pub const SYS_futimesat: ::c_long = 261; +pub const SYS_newfstatat: ::c_long = 262; +pub const SYS_unlinkat: ::c_long = 263; +pub const SYS_renameat: ::c_long = 264; +pub const SYS_linkat: ::c_long = 265; +pub const SYS_symlinkat: ::c_long = 266; +pub const SYS_readlinkat: ::c_long = 267; +pub const SYS_fchmodat: ::c_long = 268; +pub const SYS_faccessat: ::c_long = 269; +pub const SYS_pselect6: ::c_long = 270; +pub const SYS_ppoll: ::c_long = 271; +pub const SYS_unshare: ::c_long = 272; +pub const SYS_set_robust_list: ::c_long = 273; +pub const SYS_get_robust_list: ::c_long = 274; +pub const SYS_splice: ::c_long = 275; +pub const SYS_tee: ::c_long = 276; +pub const SYS_sync_file_range: ::c_long = 277; +pub const SYS_vmsplice: ::c_long = 278; +pub const SYS_move_pages: ::c_long = 279; +pub const SYS_utimensat: ::c_long = 280; +pub const SYS_epoll_pwait: ::c_long = 281; +pub const SYS_signalfd: ::c_long = 282; +pub const SYS_timerfd_create: ::c_long = 283; +pub const SYS_eventfd: ::c_long = 284; +pub const SYS_fallocate: ::c_long = 285; +pub const SYS_timerfd_settime: ::c_long = 286; +pub const SYS_timerfd_gettime: ::c_long = 287; +pub const SYS_accept4: ::c_long = 288; +pub const SYS_signalfd4: ::c_long = 289; +pub const SYS_eventfd2: ::c_long = 290; +pub const SYS_epoll_create1: ::c_long = 291; +pub const SYS_dup3: ::c_long = 292; +pub const SYS_pipe2: ::c_long = 293; +pub const SYS_inotify_init1: ::c_long = 294; +pub const SYS_preadv: ::c_long = 295; +pub const SYS_pwritev: ::c_long = 296; +pub const SYS_rt_tgsigqueueinfo: ::c_long = 297; +pub const SYS_perf_event_open: ::c_long = 298; +pub const SYS_recvmmsg: ::c_long = 299; +pub const SYS_fanotify_init: ::c_long = 300; +pub const SYS_fanotify_mark: ::c_long = 301; +pub const SYS_prlimit64: ::c_long = 302; +pub const SYS_name_to_handle_at: ::c_long = 303; +pub const SYS_open_by_handle_at: ::c_long = 304; +pub const SYS_clock_adjtime: ::c_long = 305; +pub const SYS_syncfs: ::c_long = 306; +pub const SYS_sendmmsg: ::c_long = 307; +pub const SYS_setns: ::c_long = 308; +pub const SYS_getcpu: ::c_long = 309; +pub const SYS_process_vm_readv: ::c_long = 310; +pub const SYS_process_vm_writev: ::c_long = 311; +pub const SYS_kcmp: ::c_long = 312; +pub const SYS_finit_module: ::c_long = 313; +pub const SYS_sched_setattr: ::c_long = 314; +pub const SYS_sched_getattr: ::c_long = 315; +pub const SYS_renameat2: ::c_long = 316; +pub const SYS_seccomp: ::c_long = 317; +pub const SYS_getrandom: ::c_long = 318; +pub const SYS_memfd_create: ::c_long = 319; +pub const SYS_kexec_file_load: ::c_long = 320; +pub const SYS_bpf: ::c_long = 321; +pub const SYS_execveat: ::c_long = 322; +pub const SYS_userfaultfd: ::c_long = 323; +pub const SYS_membarrier: ::c_long = 324; +pub const SYS_mlock2: ::c_long = 325; +pub const SYS_copy_file_range: ::c_long = 326; +pub const SYS_preadv2: ::c_long = 327; +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; +pub const R14: ::c_int = 1; +pub const R13: ::c_int = 2; +pub const R12: ::c_int = 3; +pub const RBP: ::c_int = 4; +pub const RBX: ::c_int = 5; +pub const R11: ::c_int = 6; +pub const R10: ::c_int = 7; +pub const R9: ::c_int = 8; +pub const R8: ::c_int = 9; +pub const RAX: ::c_int = 10; +pub const RCX: ::c_int = 11; +pub const RDX: ::c_int = 12; +pub const RSI: ::c_int = 13; +pub const RDI: ::c_int = 14; +pub const ORIG_RAX: ::c_int = 15; +pub const RIP: ::c_int = 16; +pub const CS: ::c_int = 17; +pub const EFLAGS: ::c_int = 18; +pub const RSP: ::c_int = 19; +pub const SS: ::c_int = 20; +pub const FS_BASE: ::c_int = 21; +pub const GS_BASE: ::c_int = 22; +pub const DS: ::c_int = 23; +pub const ES: ::c_int = 24; +pub const FS: ::c_int = 25; +pub const GS: ::c_int = 26; + +// offsets in mcontext_t.gregs from sys/ucontext.h +pub const REG_R8: ::c_int = 0; +pub const REG_R9: ::c_int = 1; +pub const REG_R10: ::c_int = 2; +pub const REG_R11: ::c_int = 3; +pub const REG_R12: ::c_int = 4; +pub const REG_R13: ::c_int = 5; +pub const REG_R14: ::c_int = 6; +pub const REG_R15: ::c_int = 7; +pub const REG_RDI: ::c_int = 8; +pub const REG_RSI: ::c_int = 9; +pub const REG_RBP: ::c_int = 10; +pub const REG_RBX: ::c_int = 11; +pub const REG_RDX: ::c_int = 12; +pub const REG_RAX: ::c_int = 13; +pub const REG_RCX: ::c_int = 14; +pub const REG_RSP: ::c_int = 15; +pub const REG_RIP: ::c_int = 16; +pub const REG_EFL: ::c_int = 17; +pub const REG_CSGSFS: ::c_int = 18; +pub const REG_ERR: ::c_int = 19; +pub const REG_TRAPNO: ::c_int = 20; +pub const REG_OLDMASK: ::c_int = 21; +pub const REG_CR2: ::c_int = 22; + +// From NDK's asm/auxvec.h +pub const AT_SYSINFO_EHDR: ::c_ulong = 33; +pub const AT_VECTOR_SIZE_ARCH: ::c_ulong = 3; + +cfg_if! { + if #[cfg(libc_align)] { + mod align; + pub use self::align::*; + } +} diff --git a/vendor/libc/src/unix/linux_like/android/mod.rs b/vendor/libc/src/unix/linux_like/android/mod.rs new file mode 100644 index 0000000..3896492 --- /dev/null +++ b/vendor/libc/src/unix/linux_like/android/mod.rs @@ -0,0 +1,4250 @@ +//! Android-specific definitions for linux-like values + +pub type clock_t = ::c_long; +pub type time_t = ::c_long; +pub type suseconds_t = ::c_long; +pub type off_t = ::c_long; +pub type blkcnt_t = ::c_ulong; +pub type blksize_t = ::c_ulong; +pub type nlink_t = u32; +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; +pub type fsblkcnt_t = ::c_ulong; +pub type nfds_t = ::c_uint; +pub type rlim_t = ::c_ulong; +pub type dev_t = ::c_ulong; +pub type ino_t = ::c_ulong; +pub type ino64_t = u64; +pub type __CPU_BITTYPE = ::c_ulong; +pub type idtype_t = ::c_int; +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; +pub type Elf32_Half = u16; +pub type Elf32_Off = u32; +pub type Elf32_Word = u32; + +pub type Elf64_Addr = u64; +pub type Elf64_Half = u16; +pub type Elf64_Off = u64; +pub type Elf64_Word = u32; +pub type Elf64_Xword = u64; + +pub type eventfd_t = u64; + +// these structs sit behind a heap allocation on Android +pub type posix_spawn_file_actions_t = *mut ::c_void; +pub type posix_spawnattr_t = *mut ::c_void; + +s! { + pub struct stack_t { + pub ss_sp: *mut ::c_void, + pub ss_flags: ::c_int, + pub ss_size: ::size_t + } + + pub struct __fsid_t { + __val: [::c_int; 2], + } + + pub struct msghdr { + pub msg_name: *mut ::c_void, + pub msg_namelen: ::socklen_t, + pub msg_iov: *mut ::iovec, + pub msg_iovlen: ::size_t, + pub msg_control: *mut ::c_void, + pub msg_controllen: ::size_t, + pub msg_flags: ::c_int, + } + + pub struct cmsghdr { + pub cmsg_len: ::size_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_line: ::cc_t, + pub c_cc: [::cc_t; ::NCCS], + } + + 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 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, + 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: ::__kernel_loff_t, + pub l_len: ::__kernel_loff_t, + pub l_pid: ::__kernel_pid_t, + } + + pub struct cpu_set_t { + #[cfg(target_pointer_width = "64")] + __bits: [__CPU_BITTYPE; 16], + #[cfg(target_pointer_width = "32")] + __bits: [__CPU_BITTYPE; 1], + } + + pub struct sem_t { + count: ::c_uint, + #[cfg(target_pointer_width = "64")] + __reserved: [::c_int; 3], + } + + pub struct exit_status { + pub e_termination: ::c_short, + pub e_exit: ::c_short, + } + + 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, + #[cfg(target_pointer_width = "64")] + __f_reserved: [u32; 6], + } + + pub struct signalfd_siginfo { + pub ssi_signo: u32, + pub ssi_errno: i32, + pub ssi_code: i32, + pub ssi_pid: u32, + pub ssi_uid: u32, + pub ssi_fd: i32, + pub ssi_tid: u32, + pub ssi_band: u32, + pub ssi_overrun: u32, + pub ssi_trapno: u32, + pub ssi_status: i32, + pub ssi_int: i32, + pub ssi_ptr: ::c_ulonglong, + pub ssi_utime: ::c_ulonglong, + pub ssi_stime: ::c_ulonglong, + pub ssi_addr: ::c_ulonglong, + pub ssi_addr_lsb: u16, + _pad2: u16, + pub ssi_syscall: i32, + pub ssi_call_addr: u64, + pub ssi_arch: u32, + _pad: [u8; 28], + } + + pub struct itimerspec { + pub it_interval: ::timespec, + pub it_value: ::timespec, + } + + pub struct ucred { + pub pid: ::pid_t, + pub uid: ::uid_t, + pub gid: ::gid_t, + } + + pub struct genlmsghdr { + pub cmd: u8, + pub version: u8, + pub reserved: u16, + } + + 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, + } + + pub struct nl_mmap_req { + pub nm_block_size: ::c_uint, + pub nm_block_nr: ::c_uint, + pub nm_frame_size: ::c_uint, + pub nm_frame_nr: ::c_uint, + } + + pub struct nl_mmap_hdr { + pub nm_status: ::c_uint, + pub nm_len: ::c_uint, + pub nm_group: u32, + pub nm_pid: u32, + pub nm_uid: u32, + pub nm_gid: u32, + } + + pub struct nlattr { + pub nla_len: u16, + pub nla_type: u16, + } + + pub struct in6_pktinfo { + pub ipi6_addr: ::in6_addr, + pub ipi6_ifindex: ::c_int, + } + + pub struct inotify_event { + pub wd: ::c_int, + pub mask: u32, + pub cookie: u32, + pub len: u32 + } + + pub struct sock_extended_err { + pub ee_errno: u32, + pub ee_origin: u8, + pub ee_type: u8, + pub ee_code: u8, + pub ee_pad: u8, + pub ee_info: u32, + pub ee_data: u32, + } + + pub struct regex_t { + re_magic: ::c_int, + re_nsub: ::size_t, + re_endp: *const ::c_char, + re_guts: *mut ::c_void, + } + + pub struct regmatch_t { + pub rm_so: ::ssize_t, + pub rm_eo: ::ssize_t, + } + + pub struct sockaddr_vm { + pub svm_family: ::sa_family_t, + pub svm_reserved1: ::c_ushort, + pub svm_port: ::c_uint, + pub svm_cid: ::c_uint, + pub svm_zero: [u8; 4] + } + + // linux/elf.h + + 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, + } + + // link.h + + pub struct dl_phdr_info { + #[cfg(target_pointer_width = "64")] + pub dlpi_addr: Elf64_Addr, + #[cfg(target_pointer_width = "32")] + pub dlpi_addr: Elf32_Addr, + + pub dlpi_name: *const ::c_char, + + #[cfg(target_pointer_width = "64")] + pub dlpi_phdr: *const Elf64_Phdr, + #[cfg(target_pointer_width = "32")] + pub dlpi_phdr: *const Elf32_Phdr, + + #[cfg(target_pointer_width = "64")] + pub dlpi_phnum: Elf64_Half, + #[cfg(target_pointer_width = "32")] + pub dlpi_phnum: Elf32_Half, + + // These fields were added in Android R + pub dlpi_adds: ::c_ulonglong, + pub dlpi_subs: ::c_ulonglong, + 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 seccomp_metadata { + pub filter_off: ::__u64, + pub flags: ::__u64, + } + + 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, + } + + 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, + } + +} + +s_no_extra_traits! { + pub struct sockaddr_nl { + pub nl_family: ::sa_family_t, + nl_pad: ::c_ushort, + pub nl_pid: u32, + pub nl_groups: u32 + } + + pub struct dirent { + pub d_ino: u64, + pub d_off: i64, + pub d_reclen: ::c_ushort, + pub d_type: ::c_uchar, + pub d_name: [::c_char; 256], + } + + pub struct dirent64 { + pub d_ino: u64, + pub d_off: i64, + pub d_reclen: ::c_ushort, + pub d_type: ::c_uchar, + pub d_name: [::c_char; 256], + } + + pub struct siginfo_t { + pub si_signo: ::c_int, + pub si_errno: ::c_int, + pub si_code: ::c_int, + pub _pad: [::c_int; 29], + _align: [usize; 0], + } + + pub struct lastlog { + ll_time: ::time_t, + ll_line: [::c_char; UT_LINESIZE], + ll_host: [::c_char; UT_HOSTSIZE], + } + + pub struct utmp { + pub ut_type: ::c_short, + pub ut_pid: ::pid_t, + pub ut_line: [::c_char; UT_LINESIZE], + pub ut_id: [::c_char; 4], + pub ut_user: [::c_char; UT_NAMESIZE], + pub ut_host: [::c_char; UT_HOSTSIZE], + pub ut_exit: exit_status, + pub ut_session: ::c_long, + pub ut_tv: ::timeval, + pub ut_addr_v6: [i32; 4], + unused: [::c_char; 20], + } + + pub struct sockaddr_alg { + pub salg_family: ::sa_family_t, + pub salg_type: [::c_uchar; 14], + pub salg_feat: u32, + pub salg_mask: u32, + pub salg_name: [::c_uchar; 64], + } + + pub struct 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( + note = "this struct has unsafe trait implementations that will be \ + removed in the future", + since = "0.2.80" + )] + pub struct af_alg_iv { + 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(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, + } + + #[cfg(libc_union)] + pub union __c_anonymous_ifc_ifcu { + pub ifcu_buf: *mut ::c_char, + pub ifcu_req: *mut ::ifreq, + } + + /* Structure used in SIOCGIFCONF request. Used to retrieve interface + configuration for machine (useful for programs which must know all + networks accessible). */ + pub struct ifconf { + pub ifc_len: ::c_int, /* Size of buffer. */ + #[cfg(libc_union)] + pub ifc_ifcu: __c_anonymous_ifc_ifcu, + #[cfg(not(libc_union))] + pub ifc_ifcu: *mut ::ifreq, + } + +} + +cfg_if! { + if #[cfg(feature = "extra_traits")] { + impl PartialEq for sockaddr_nl { + fn eq(&self, other: &sockaddr_nl) -> bool { + self.nl_family == other.nl_family && + self.nl_pid == other.nl_pid && + self.nl_groups == other.nl_groups + } + } + impl Eq for sockaddr_nl {} + impl ::fmt::Debug for sockaddr_nl { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("sockaddr_nl") + .field("nl_family", &self.nl_family) + .field("nl_pid", &self.nl_pid) + .field("nl_groups", &self.nl_groups) + .finish() + } + } + impl ::hash::Hash for sockaddr_nl { + fn hash(&self, state: &mut H) { + self.nl_family.hash(state); + self.nl_pid.hash(state); + self.nl_groups.hash(state); + } + } + + impl PartialEq for dirent { + fn eq(&self, other: &dirent) -> bool { + self.d_ino == other.d_ino + && self.d_off == other.d_off + && self.d_reclen == other.d_reclen + && self.d_type == other.d_type + && self + .d_name + .iter() + .zip(other.d_name.iter()) + .all(|(a,b)| a == b) + } + } + + impl Eq for dirent {} + + impl ::fmt::Debug for dirent { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("dirent") + .field("d_ino", &self.d_ino) + .field("d_off", &self.d_off) + .field("d_reclen", &self.d_reclen) + .field("d_type", &self.d_type) + // FIXME: .field("d_name", &self.d_name) + .finish() + } + } + + impl ::hash::Hash for dirent { + fn hash(&self, state: &mut H) { + self.d_ino.hash(state); + self.d_off.hash(state); + self.d_reclen.hash(state); + self.d_type.hash(state); + self.d_name.hash(state); + } + } + + impl PartialEq for dirent64 { + fn eq(&self, other: &dirent64) -> bool { + self.d_ino == other.d_ino + && self.d_off == other.d_off + && self.d_reclen == other.d_reclen + && self.d_type == other.d_type + && self + .d_name + .iter() + .zip(other.d_name.iter()) + .all(|(a,b)| a == b) + } + } + + impl Eq for dirent64 {} + + impl ::fmt::Debug for dirent64 { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("dirent64") + .field("d_ino", &self.d_ino) + .field("d_off", &self.d_off) + .field("d_reclen", &self.d_reclen) + .field("d_type", &self.d_type) + // FIXME: .field("d_name", &self.d_name) + .finish() + } + } + + impl ::hash::Hash for dirent64 { + fn hash(&self, state: &mut H) { + self.d_ino.hash(state); + self.d_off.hash(state); + self.d_reclen.hash(state); + self.d_type.hash(state); + self.d_name.hash(state); + } + } + + impl PartialEq for siginfo_t { + fn eq(&self, other: &siginfo_t) -> bool { + self.si_signo == other.si_signo + && self.si_errno == other.si_errno + && self.si_code == other.si_code + // Ignore _pad + // Ignore _align + } + } + + impl Eq for siginfo_t {} + + impl ::fmt::Debug for siginfo_t { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("siginfo_t") + .field("si_signo", &self.si_signo) + .field("si_errno", &self.si_errno) + .field("si_code", &self.si_code) + // Ignore _pad + // Ignore _align + .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); + // Ignore _pad + // Ignore _align + } + } + + impl PartialEq for lastlog { + fn eq(&self, other: &lastlog) -> bool { + self.ll_time == other.ll_time + && self + .ll_line + .iter() + .zip(other.ll_line.iter()) + .all(|(a,b)| a == b) + && self + .ll_host + .iter() + .zip(other.ll_host.iter()) + .all(|(a,b)| a == b) + } + } + + impl Eq for lastlog {} + + impl ::fmt::Debug for lastlog { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("lastlog") + .field("ll_time", &self.ll_time) + .field("ll_line", &self.ll_line) + // FIXME: .field("ll_host", &self.ll_host) + .finish() + } + } + + impl ::hash::Hash for lastlog { + fn hash(&self, state: &mut H) { + self.ll_time.hash(state); + self.ll_line.hash(state); + self.ll_host.hash(state); + } + } + + impl PartialEq for utmp { + fn eq(&self, other: &utmp) -> bool { + self.ut_type == other.ut_type + && self.ut_pid == other.ut_pid + && self + .ut_line + .iter() + .zip(other.ut_line.iter()) + .all(|(a,b)| a == b) + && self.ut_id == other.ut_id + && self + .ut_user + .iter() + .zip(other.ut_user.iter()) + .all(|(a,b)| a == b) + && self + .ut_host + .iter() + .zip(other.ut_host.iter()) + .all(|(a,b)| a == b) + && self.ut_exit == other.ut_exit + && self.ut_session == other.ut_session + && self.ut_tv == other.ut_tv + && self.ut_addr_v6 == other.ut_addr_v6 + && self.unused == other.unused + } + } + + impl Eq for utmp {} + + impl ::fmt::Debug for utmp { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("utmp") + .field("ut_type", &self.ut_type) + .field("ut_pid", &self.ut_pid) + .field("ut_line", &self.ut_line) + .field("ut_id", &self.ut_id) + .field("ut_user", &self.ut_user) + // FIXME: .field("ut_host", &self.ut_host) + .field("ut_exit", &self.ut_exit) + .field("ut_session", &self.ut_session) + .field("ut_tv", &self.ut_tv) + .field("ut_addr_v6", &self.ut_addr_v6) + .field("unused", &self.unused) + .finish() + } + } + + impl ::hash::Hash for utmp { + fn hash(&self, state: &mut H) { + self.ut_type.hash(state); + self.ut_pid.hash(state); + self.ut_line.hash(state); + self.ut_id.hash(state); + self.ut_user.hash(state); + self.ut_host.hash(state); + self.ut_exit.hash(state); + self.ut_session.hash(state); + self.ut_tv.hash(state); + self.ut_addr_v6.hash(state); + self.unused.hash(state); + } + } + + impl PartialEq for sockaddr_alg { + fn eq(&self, other: &sockaddr_alg) -> bool { + self.salg_family == other.salg_family + && self + .salg_type + .iter() + .zip(other.salg_type.iter()) + .all(|(a, b)| a == b) + && self.salg_feat == other.salg_feat + && self.salg_mask == other.salg_mask + && self + .salg_name + .iter() + .zip(other.salg_name.iter()) + .all(|(a, b)| a == b) + } + } + + impl Eq for sockaddr_alg {} + + impl ::fmt::Debug for sockaddr_alg { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("sockaddr_alg") + .field("salg_family", &self.salg_family) + .field("salg_type", &self.salg_type) + .field("salg_feat", &self.salg_feat) + .field("salg_mask", &self.salg_mask) + .field("salg_name", &&self.salg_name[..]) + .finish() + } + } + + impl ::hash::Hash for sockaddr_alg { + fn hash(&self, state: &mut H) { + self.salg_family.hash(state); + self.salg_type.hash(state); + self.salg_feat.hash(state); + self.salg_mask.hash(state); + self.salg_name.hash(state); + } + } + + impl 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); + } + } + + #[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() + } + } + + #[cfg(libc_union)] + impl ::fmt::Debug for __c_anonymous_ifc_ifcu { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("ifr_ifru") + .field("ifcu_buf", unsafe { &self.ifcu_buf }) + .field("ifcu_req", unsafe { &self.ifcu_req }) + .finish() + } + } + impl ::fmt::Debug for ifconf { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("ifconf") + .field("ifc_len", &self.ifc_len) + .field("ifc_ifcu", &self.ifc_ifcu) + .finish() + } + } + + #[allow(deprecated)] + impl af_alg_iv { + fn as_slice(&self) -> &[u8] { + unsafe { + ::core::slice::from_raw_parts( + self.iv.as_ptr(), + self.ivlen as usize + ) + } + } + } + + #[allow(deprecated)] + impl PartialEq for af_alg_iv { + fn eq(&self, other: &af_alg_iv) -> bool { + *self.as_slice() == *other.as_slice() + } + } + + #[allow(deprecated)] + impl Eq for af_alg_iv {} + + #[allow(deprecated)] + impl ::fmt::Debug for af_alg_iv { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("af_alg_iv") + .field("ivlen", &self.ivlen) + .finish() + } + } + + #[allow(deprecated)] + impl ::hash::Hash for af_alg_iv { + fn hash(&self, state: &mut H) { + 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() + } + } + } +} + +pub const MADV_SOFT_OFFLINE: ::c_int = 101; +pub const MS_NOUSER: ::c_ulong = 0xffffffff80000000; +pub const MS_RMT_MASK: ::c_ulong = 0x02800051; + +pub const O_TRUNC: ::c_int = 512; +pub const O_CLOEXEC: ::c_int = 0x80000; +pub const O_PATH: ::c_int = 0o10000000; +pub const O_NOATIME: ::c_int = 0o1000000; + +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 EPOLL_CLOEXEC: ::c_int = 0x80000; + +// sys/eventfd.h +pub const EFD_SEMAPHORE: ::c_int = 0x1; +pub const EFD_CLOEXEC: ::c_int = O_CLOEXEC; +pub const EFD_NONBLOCK: ::c_int = O_NONBLOCK; + +// sys/timerfd.h +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 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; +pub const FALLOC_FL_NO_HIDE_STALE: ::c_int = 0x04; +pub const FALLOC_FL_COLLAPSE_RANGE: ::c_int = 0x08; +pub const FALLOC_FL_ZERO_RANGE: ::c_int = 0x10; +pub const FALLOC_FL_INSERT_RANGE: ::c_int = 0x20; +pub const FALLOC_FL_UNSHARE_RANGE: ::c_int = 0x40; + +pub const BUFSIZ: ::c_uint = 1024; +pub const FILENAME_MAX: ::c_uint = 4096; +pub const FOPEN_MAX: ::c_uint = 20; +pub const POSIX_FADV_DONTNEED: ::c_int = 4; +pub const POSIX_FADV_NOREUSE: ::c_int = 5; +pub const L_tmpnam: ::c_uint = 4096; +pub const TMP_MAX: ::c_uint = 308915776; +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_2_SYMLINKS: ::c_int = 7; +pub const _PC_ALLOC_SIZE_MIN: ::c_int = 8; +pub const _PC_REC_INCR_XFER_SIZE: ::c_int = 9; +pub const _PC_REC_MAX_XFER_SIZE: ::c_int = 10; +pub const _PC_REC_MIN_XFER_SIZE: ::c_int = 11; +pub const _PC_REC_XFER_ALIGN: ::c_int = 12; +pub const _PC_SYMLINK_MAX: ::c_int = 13; +pub const _PC_CHOWN_RESTRICTED: ::c_int = 14; +pub const _PC_NO_TRUNC: ::c_int = 15; +pub const _PC_VDISABLE: ::c_int = 16; +pub const _PC_ASYNC_IO: ::c_int = 17; +pub const _PC_PRIO_IO: ::c_int = 18; +pub const _PC_SYNC_IO: ::c_int = 19; + +pub const FIONBIO: ::c_int = 0x5421; + +pub const _SC_ARG_MAX: ::c_int = 0x0000; +pub const _SC_BC_BASE_MAX: ::c_int = 0x0001; +pub const _SC_BC_DIM_MAX: ::c_int = 0x0002; +pub const _SC_BC_SCALE_MAX: ::c_int = 0x0003; +pub const _SC_BC_STRING_MAX: ::c_int = 0x0004; +pub const _SC_CHILD_MAX: ::c_int = 0x0005; +pub const _SC_CLK_TCK: ::c_int = 0x0006; +pub const _SC_COLL_WEIGHTS_MAX: ::c_int = 0x0007; +pub const _SC_EXPR_NEST_MAX: ::c_int = 0x0008; +pub const _SC_LINE_MAX: ::c_int = 0x0009; +pub const _SC_NGROUPS_MAX: ::c_int = 0x000a; +pub const _SC_OPEN_MAX: ::c_int = 0x000b; +pub const _SC_PASS_MAX: ::c_int = 0x000c; +pub const _SC_2_C_BIND: ::c_int = 0x000d; +pub const _SC_2_C_DEV: ::c_int = 0x000e; +pub const _SC_2_C_VERSION: ::c_int = 0x000f; +pub const _SC_2_CHAR_TERM: ::c_int = 0x0010; +pub const _SC_2_FORT_DEV: ::c_int = 0x0011; +pub const _SC_2_FORT_RUN: ::c_int = 0x0012; +pub const _SC_2_LOCALEDEF: ::c_int = 0x0013; +pub const _SC_2_SW_DEV: ::c_int = 0x0014; +pub const _SC_2_UPE: ::c_int = 0x0015; +pub const _SC_2_VERSION: ::c_int = 0x0016; +pub const _SC_JOB_CONTROL: ::c_int = 0x0017; +pub const _SC_SAVED_IDS: ::c_int = 0x0018; +pub const _SC_VERSION: ::c_int = 0x0019; +pub const _SC_RE_DUP_MAX: ::c_int = 0x001a; +pub const _SC_STREAM_MAX: ::c_int = 0x001b; +pub const _SC_TZNAME_MAX: ::c_int = 0x001c; +pub const _SC_XOPEN_CRYPT: ::c_int = 0x001d; +pub const _SC_XOPEN_ENH_I18N: ::c_int = 0x001e; +pub const _SC_XOPEN_SHM: ::c_int = 0x001f; +pub const _SC_XOPEN_VERSION: ::c_int = 0x0020; +pub const _SC_XOPEN_XCU_VERSION: ::c_int = 0x0021; +pub const _SC_XOPEN_REALTIME: ::c_int = 0x0022; +pub const _SC_XOPEN_REALTIME_THREADS: ::c_int = 0x0023; +pub const _SC_XOPEN_LEGACY: ::c_int = 0x0024; +pub const _SC_ATEXIT_MAX: ::c_int = 0x0025; +pub const _SC_IOV_MAX: ::c_int = 0x0026; +pub const _SC_UIO_MAXIOV: ::c_int = _SC_IOV_MAX; +pub const _SC_PAGESIZE: ::c_int = 0x0027; +pub const _SC_PAGE_SIZE: ::c_int = 0x0028; +pub const _SC_XOPEN_UNIX: ::c_int = 0x0029; +pub const _SC_XBS5_ILP32_OFF32: ::c_int = 0x002a; +pub const _SC_XBS5_ILP32_OFFBIG: ::c_int = 0x002b; +pub const _SC_XBS5_LP64_OFF64: ::c_int = 0x002c; +pub const _SC_XBS5_LPBIG_OFFBIG: ::c_int = 0x002d; +pub const _SC_AIO_LISTIO_MAX: ::c_int = 0x002e; +pub const _SC_AIO_MAX: ::c_int = 0x002f; +pub const _SC_AIO_PRIO_DELTA_MAX: ::c_int = 0x0030; +pub const _SC_DELAYTIMER_MAX: ::c_int = 0x0031; +pub const _SC_MQ_OPEN_MAX: ::c_int = 0x0032; +pub const _SC_MQ_PRIO_MAX: ::c_int = 0x0033; +pub const _SC_RTSIG_MAX: ::c_int = 0x0034; +pub const _SC_SEM_NSEMS_MAX: ::c_int = 0x0035; +pub const _SC_SEM_VALUE_MAX: ::c_int = 0x0036; +pub const _SC_SIGQUEUE_MAX: ::c_int = 0x0037; +pub const _SC_TIMER_MAX: ::c_int = 0x0038; +pub const _SC_ASYNCHRONOUS_IO: ::c_int = 0x0039; +pub const _SC_FSYNC: ::c_int = 0x003a; +pub const _SC_MAPPED_FILES: ::c_int = 0x003b; +pub const _SC_MEMLOCK: ::c_int = 0x003c; +pub const _SC_MEMLOCK_RANGE: ::c_int = 0x003d; +pub const _SC_MEMORY_PROTECTION: ::c_int = 0x003e; +pub const _SC_MESSAGE_PASSING: ::c_int = 0x003f; +pub const _SC_PRIORITIZED_IO: ::c_int = 0x0040; +pub const _SC_PRIORITY_SCHEDULING: ::c_int = 0x0041; +pub const _SC_REALTIME_SIGNALS: ::c_int = 0x0042; +pub const _SC_SEMAPHORES: ::c_int = 0x0043; +pub const _SC_SHARED_MEMORY_OBJECTS: ::c_int = 0x0044; +pub const _SC_SYNCHRONIZED_IO: ::c_int = 0x0045; +pub const _SC_TIMERS: ::c_int = 0x0046; +pub const _SC_GETGR_R_SIZE_MAX: ::c_int = 0x0047; +pub const _SC_GETPW_R_SIZE_MAX: ::c_int = 0x0048; +pub const _SC_LOGIN_NAME_MAX: ::c_int = 0x0049; +pub const _SC_THREAD_DESTRUCTOR_ITERATIONS: ::c_int = 0x004a; +pub const _SC_THREAD_KEYS_MAX: ::c_int = 0x004b; +pub const _SC_THREAD_STACK_MIN: ::c_int = 0x004c; +pub const _SC_THREAD_THREADS_MAX: ::c_int = 0x004d; +pub const _SC_TTY_NAME_MAX: ::c_int = 0x004e; +pub const _SC_THREADS: ::c_int = 0x004f; +pub const _SC_THREAD_ATTR_STACKADDR: ::c_int = 0x0050; +pub const _SC_THREAD_ATTR_STACKSIZE: ::c_int = 0x0051; +pub const _SC_THREAD_PRIORITY_SCHEDULING: ::c_int = 0x0052; +pub const _SC_THREAD_PRIO_INHERIT: ::c_int = 0x0053; +pub const _SC_THREAD_PRIO_PROTECT: ::c_int = 0x0054; +pub const _SC_THREAD_SAFE_FUNCTIONS: ::c_int = 0x0055; +pub const _SC_NPROCESSORS_CONF: ::c_int = 0x0060; +pub const _SC_NPROCESSORS_ONLN: ::c_int = 0x0061; +pub const _SC_PHYS_PAGES: ::c_int = 0x0062; +pub const _SC_AVPHYS_PAGES: ::c_int = 0x0063; +pub const _SC_MONOTONIC_CLOCK: ::c_int = 0x0064; +pub const _SC_2_PBS: ::c_int = 0x0065; +pub const _SC_2_PBS_ACCOUNTING: ::c_int = 0x0066; +pub const _SC_2_PBS_CHECKPOINT: ::c_int = 0x0067; +pub const _SC_2_PBS_LOCATE: ::c_int = 0x0068; +pub const _SC_2_PBS_MESSAGE: ::c_int = 0x0069; +pub const _SC_2_PBS_TRACK: ::c_int = 0x006a; +pub const _SC_ADVISORY_INFO: ::c_int = 0x006b; +pub const _SC_BARRIERS: ::c_int = 0x006c; +pub const _SC_CLOCK_SELECTION: ::c_int = 0x006d; +pub const _SC_CPUTIME: ::c_int = 0x006e; +pub const _SC_HOST_NAME_MAX: ::c_int = 0x006f; +pub const _SC_IPV6: ::c_int = 0x0070; +pub const _SC_RAW_SOCKETS: ::c_int = 0x0071; +pub const _SC_READER_WRITER_LOCKS: ::c_int = 0x0072; +pub const _SC_REGEXP: ::c_int = 0x0073; +pub const _SC_SHELL: ::c_int = 0x0074; +pub const _SC_SPAWN: ::c_int = 0x0075; +pub const _SC_SPIN_LOCKS: ::c_int = 0x0076; +pub const _SC_SPORADIC_SERVER: ::c_int = 0x0077; +pub const _SC_SS_REPL_MAX: ::c_int = 0x0078; +pub const _SC_SYMLOOP_MAX: ::c_int = 0x0079; +pub const _SC_THREAD_CPUTIME: ::c_int = 0x007a; +pub const _SC_THREAD_PROCESS_SHARED: ::c_int = 0x007b; +pub const _SC_THREAD_ROBUST_PRIO_INHERIT: ::c_int = 0x007c; +pub const _SC_THREAD_ROBUST_PRIO_PROTECT: ::c_int = 0x007d; +pub const _SC_THREAD_SPORADIC_SERVER: ::c_int = 0x007e; +pub const _SC_TIMEOUTS: ::c_int = 0x007f; +pub const _SC_TRACE: ::c_int = 0x0080; +pub const _SC_TRACE_EVENT_FILTER: ::c_int = 0x0081; +pub const _SC_TRACE_EVENT_NAME_MAX: ::c_int = 0x0082; +pub const _SC_TRACE_INHERIT: ::c_int = 0x0083; +pub const _SC_TRACE_LOG: ::c_int = 0x0084; +pub const _SC_TRACE_NAME_MAX: ::c_int = 0x0085; +pub const _SC_TRACE_SYS_MAX: ::c_int = 0x0086; +pub const _SC_TRACE_USER_EVENT_MAX: ::c_int = 0x0087; +pub const _SC_TYPED_MEMORY_OBJECTS: ::c_int = 0x0088; +pub const _SC_V7_ILP32_OFF32: ::c_int = 0x0089; +pub const _SC_V7_ILP32_OFFBIG: ::c_int = 0x008a; +pub const _SC_V7_LP64_OFF64: ::c_int = 0x008b; +pub const _SC_V7_LPBIG_OFFBIG: ::c_int = 0x008c; +pub const _SC_XOPEN_STREAMS: ::c_int = 0x008d; +pub const _SC_XOPEN_UUCP: ::c_int = 0x008e; +pub const _SC_LEVEL1_ICACHE_SIZE: ::c_int = 0x008f; +pub const _SC_LEVEL1_ICACHE_ASSOC: ::c_int = 0x0090; +pub const _SC_LEVEL1_ICACHE_LINESIZE: ::c_int = 0x0091; +pub const _SC_LEVEL1_DCACHE_SIZE: ::c_int = 0x0092; +pub const _SC_LEVEL1_DCACHE_ASSOC: ::c_int = 0x0093; +pub const _SC_LEVEL1_DCACHE_LINESIZE: ::c_int = 0x0094; +pub const _SC_LEVEL2_CACHE_SIZE: ::c_int = 0x0095; +pub const _SC_LEVEL2_CACHE_ASSOC: ::c_int = 0x0096; +pub const _SC_LEVEL2_CACHE_LINESIZE: ::c_int = 0x0097; +pub const _SC_LEVEL3_CACHE_SIZE: ::c_int = 0x0098; +pub const _SC_LEVEL3_CACHE_ASSOC: ::c_int = 0x0099; +pub const _SC_LEVEL3_CACHE_LINESIZE: ::c_int = 0x009a; +pub const _SC_LEVEL4_CACHE_SIZE: ::c_int = 0x009b; +pub const _SC_LEVEL4_CACHE_ASSOC: ::c_int = 0x009c; +pub const _SC_LEVEL4_CACHE_LINESIZE: ::c_int = 0x009d; + +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_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_BARRIER_SERIAL_THREAD: ::c_int = -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 PTHREAD_MUTEX_DEFAULT: ::c_int = PTHREAD_MUTEX_NORMAL; + +pub const PTHREAD_EXPLICIT_SCHED: ::c_int = 0; +pub const PTHREAD_INHERIT_SCHED: ::c_int = 1; + +// stdio.h +pub const RENAME_NOREPLACE: ::c_int = 1; +pub const RENAME_EXCHANGE: ::c_int = 2; +pub const RENAME_WHITEOUT: ::c_int = 4; + +pub const FIOCLEX: ::c_int = 0x5451; +pub const FIONCLEX: ::c_int = 0x5450; + +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 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 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 RUSAGE_CHILDREN: ::c_int = -1; + +pub const LC_PAPER: ::c_int = 7; +pub const LC_NAME: ::c_int = 8; +pub const LC_ADDRESS: ::c_int = 9; +pub const LC_TELEPHONE: ::c_int = 10; +pub const LC_MEASUREMENT: ::c_int = 11; +pub const LC_IDENTIFICATION: ::c_int = 12; +pub const LC_PAPER_MASK: ::c_int = 1 << LC_PAPER; +pub const LC_NAME_MASK: ::c_int = 1 << LC_NAME; +pub const LC_ADDRESS_MASK: ::c_int = 1 << LC_ADDRESS; +pub const LC_TELEPHONE_MASK: ::c_int = 1 << LC_TELEPHONE; +pub const LC_MEASUREMENT_MASK: ::c_int = 1 << LC_MEASUREMENT; +pub const LC_IDENTIFICATION_MASK: ::c_int = 1 << LC_IDENTIFICATION; +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 + | LC_PAPER_MASK + | LC_NAME_MASK + | LC_ADDRESS_MASK + | LC_TELEPHONE_MASK + | LC_MEASUREMENT_MASK + | LC_IDENTIFICATION_MASK; + +pub const MAP_ANON: ::c_int = 0x0020; +pub const MAP_ANONYMOUS: ::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 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 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 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 SOCK_STREAM: ::c_int = 1; +pub const SOCK_DGRAM: ::c_int = 2; +pub const SOCK_SEQPACKET: ::c_int = 5; +pub const SOCK_DCCP: ::c_int = 6; +pub const SOCK_PACKET: ::c_int = 10; + +pub const IPPROTO_MAX: ::c_int = 256; + +pub const SOL_SOCKET: ::c_int = 1; +pub const SOL_SCTP: ::c_int = 132; +pub const SOL_IPX: ::c_int = 256; +pub const SOL_AX25: ::c_int = 257; +pub const SOL_ATALK: ::c_int = 258; +pub const SOL_NETROM: ::c_int = 259; +pub const SOL_ROSE: ::c_int = 260; + +/* 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 SO_REUSEADDR: ::c_int = 2; +pub const SO_TYPE: ::c_int = 3; +pub const SO_ERROR: ::c_int = 4; +pub const SO_DONTROUTE: ::c_int = 5; +pub const SO_BROADCAST: ::c_int = 6; +pub const SO_SNDBUF: ::c_int = 7; +pub const SO_RCVBUF: ::c_int = 8; +pub const SO_KEEPALIVE: ::c_int = 9; +pub const SO_OOBINLINE: ::c_int = 10; +pub const SO_PRIORITY: ::c_int = 12; +pub const SO_LINGER: ::c_int = 13; +pub const SO_BSDCOMPAT: ::c_int = 14; +pub const SO_REUSEPORT: ::c_int = 15; +pub const SO_PASSCRED: ::c_int = 16; +pub const SO_PEERCRED: ::c_int = 17; +pub const SO_RCVLOWAT: ::c_int = 18; +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; +pub const SO_SNDBUFFORCE: ::c_int = 32; +pub const SO_RCVBUFFORCE: ::c_int = 33; +pub const SO_PASSSEC: ::c_int = 34; +pub const SO_TIMESTAMPNS: ::c_int = 35; +// pub const SO_TIMESTAMPNS_OLD: ::c_int = 35; +pub const SO_MARK: ::c_int = 36; +pub const SO_TIMESTAMPING: ::c_int = 37; +// pub const SO_TIMESTAMPING_OLD: ::c_int = 37; +pub const SO_PROTOCOL: ::c_int = 38; +pub const SO_DOMAIN: ::c_int = 39; +pub const SO_RXQ_OVFL: ::c_int = 40; +pub const SO_PEEK_OFF: ::c_int = 42; +pub const SO_BUSY_POLL: ::c_int = 46; +pub const SCM_TIMESTAMPING_OPT_STATS: ::c_int = 54; +pub const SCM_TIMESTAMPING_PKTINFO: ::c_int = 58; +pub const SO_TIMESTAMP_NEW: ::c_int = 63; +pub const SO_TIMESTAMPNS_NEW: ::c_int = 64; +pub const SO_TIMESTAMPING_NEW: ::c_int = 65; + +// Defined in unix/linux_like/mod.rs +// pub const SCM_TIMESTAMP: ::c_int = SO_TIMESTAMP; +pub const SCM_TIMESTAMPNS: ::c_int = SO_TIMESTAMPNS; +pub const SCM_TIMESTAMPING: ::c_int = SO_TIMESTAMPING; + +pub const IPTOS_ECN_NOTECT: u8 = 0x00; + +pub const O_ACCMODE: ::c_int = 3; +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 = 0x101000; +pub const O_ASYNC: ::c_int = 0x2000; +pub const O_NDELAY: ::c_int = 0x800; +pub const O_DSYNC: ::c_int = 4096; +pub const O_RSYNC: ::c_int = O_SYNC; + +pub const NI_MAXHOST: ::size_t = 1025; +pub const NI_MAXSERV: ::size_t = 32; + +pub const NI_NOFQDN: ::c_int = 0x00000001; +pub const NI_NUMERICHOST: ::c_int = 0x00000002; +pub const NI_NAMEREQD: ::c_int = 0x00000004; +pub const NI_NUMERICSERV: ::c_int = 0x00000008; +pub const NI_DGRAM: ::c_int = 0x00000010; + +pub const NCCS: usize = 19; +pub const TCSBRKP: ::c_int = 0x5425; +pub const TCSANOW: ::c_int = 0; +pub const TCSADRAIN: ::c_int = 0x1; +pub const TCSAFLUSH: ::c_int = 0x2; +pub const VEOF: usize = 4; +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 = 0o200000; + +pub const MAP_HUGETLB: ::c_int = 0x040000; + +pub const PTRACE_TRACEME: ::c_int = 0; +pub const PTRACE_PEEKTEXT: ::c_int = 1; +pub const PTRACE_PEEKDATA: ::c_int = 2; +pub const PTRACE_PEEKUSER: ::c_int = 3; +pub const PTRACE_POKETEXT: ::c_int = 4; +pub const PTRACE_POKEDATA: ::c_int = 5; +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; +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_SECCOMP_GET_METADATA: ::c_int = 0x420d; + +pub const PTRACE_EVENT_STOP: ::c_int = 128; + +pub const F_GETLK: ::c_int = 5; +pub const F_GETOWN: ::c_int = 9; +pub const F_SETOWN: ::c_int = 8; +pub const F_SETLK: ::c_int = 6; +pub const F_SETLKW: ::c_int = 7; +pub const F_RDLCK: ::c_int = 0; +pub const F_WRLCK: ::c_int = 1; +pub const F_UNLCK: ::c_int = 2; +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 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; + +#[deprecated(since = "0.2.64", note = "Not stable across OS versions")] +pub const RLIM_NLIMITS: ::c_int = 16; +pub const RLIM_INFINITY: ::rlim_t = !0; + +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; +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 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 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; +pub const ST_NODEV: ::c_ulong = 4; +pub const ST_NOEXEC: ::c_ulong = 8; +pub const ST_SYNCHRONOUS: ::c_ulong = 16; +pub const ST_MANDLOCK: ::c_ulong = 64; +pub const ST_NOATIME: ::c_ulong = 1024; +pub const ST_NODIRATIME: ::c_ulong = 2048; +pub const ST_RELATIME: ::c_ulong = 4096; + +pub const RTLD_NOLOAD: ::c_int = 0x4; +pub const RTLD_NODELETE: ::c_int = 0x1000; + +pub const SEM_FAILED: *mut sem_t = 0 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 AI_MASK: ::c_int = + AI_PASSIVE | AI_CANONNAME | AI_NUMERICHOST | AI_NUMERICSERV | AI_ADDRCONFIG; +pub const AI_ALL: ::c_int = 0x00000100; +pub const AI_V4MAPPED_CFG: ::c_int = 0x00000200; +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; +pub const LINUX_REBOOT_MAGIC2B: ::c_int = 369367448; +pub const LINUX_REBOOT_MAGIC2C: ::c_int = 537993216; + +pub const LINUX_REBOOT_CMD_RESTART: ::c_int = 0x01234567; +pub const LINUX_REBOOT_CMD_HALT: ::c_int = 0xCDEF0123; +pub const LINUX_REBOOT_CMD_CAD_ON: ::c_int = 0x89ABCDEF; +pub const LINUX_REBOOT_CMD_CAD_OFF: ::c_int = 0x00000000; +pub const LINUX_REBOOT_CMD_POWER_OFF: ::c_int = 0x4321FEDC; +pub const LINUX_REBOOT_CMD_RESTART2: ::c_int = 0xA1B2C3D4; +pub const LINUX_REBOOT_CMD_SW_SUSPEND: ::c_int = 0xD000FCE2; +pub const LINUX_REBOOT_CMD_KEXEC: ::c_int = 0x45584543; + +pub const REG_BASIC: ::c_int = 0; +pub const REG_EXTENDED: ::c_int = 1; +pub const REG_ICASE: ::c_int = 2; +pub const REG_NOSUB: ::c_int = 4; +pub const REG_NEWLINE: ::c_int = 8; +pub const REG_NOSPEC: ::c_int = 16; +pub const REG_PEND: ::c_int = 32; +pub const REG_DUMP: ::c_int = 128; + +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_EMPTY: ::c_int = 14; +pub const REG_ASSERT: ::c_int = 15; +pub const REG_INVARG: ::c_int = 16; +pub const REG_ATOI: ::c_int = 255; +pub const REG_ITOA: ::c_int = 256; + +pub const REG_NOTBOL: ::c_int = 1; +pub const REG_NOTEOL: ::c_int = 2; +pub const REG_STARTEND: ::c_int = 4; +pub const REG_TRACE: ::c_int = 256; +pub const REG_LARGE: ::c_int = 512; +pub const REG_BACKR: ::c_int = 1024; + +pub const MCL_CURRENT: ::c_int = 0x0001; +pub const MCL_FUTURE: ::c_int = 0x0002; +pub const MCL_ONFAULT: ::c_int = 0x0004; + +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 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 BOTHER: ::speed_t = 0o010000; +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 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; + +cfg_if! { + // Those type are constructed using the _IOC macro + // DD-SS_SSSS_SSSS_SSSS-TTTT_TTTT-NNNN_NNNN + // where D stands for direction (either None (00), Read (01) or Write (11)) + // where S stands for size (int, long, struct...) + // where T stands for type ('f','v','X'...) + // where N stands for NR (NumbeR) + if #[cfg(any(target_arch = "x86", target_arch = "arm"))] { + pub const FS_IOC_GETFLAGS: ::c_int = 0x80046601; + pub const FS_IOC_SETFLAGS: ::c_int = 0x40046602; + pub const FS_IOC_GETVERSION: ::c_int = 0x80047601; + pub const FS_IOC_SETVERSION: ::c_int = 0x40047602; + pub const FS_IOC32_GETFLAGS: ::c_int = 0x80046601; + pub const FS_IOC32_SETFLAGS: ::c_int = 0x40046602; + pub const FS_IOC32_GETVERSION: ::c_int = 0x80047601; + pub const FS_IOC32_SETVERSION: ::c_int = 0x40047602; + } else if #[cfg(any(target_arch = "x86_64", target_arch = "riscv64", target_arch = "aarch64"))] { + pub const FS_IOC_GETFLAGS: ::c_int = 0x80086601; + pub const FS_IOC_SETFLAGS: ::c_int = 0x40086602; + pub const FS_IOC_GETVERSION: ::c_int = 0x80087601; + pub const FS_IOC_SETVERSION: ::c_int = 0x40087602; + pub const FS_IOC32_GETFLAGS: ::c_int = 0x80046601; + pub const FS_IOC32_SETFLAGS: ::c_int = 0x40046602; + pub const FS_IOC32_GETVERSION: ::c_int = 0x80047601; + pub const FS_IOC32_SETVERSION: ::c_int = 0x40047602; + } +} + +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 = 14; + +pub const NETLINK_ROUTE: ::c_int = 0; +pub const NETLINK_UNUSED: ::c_int = 1; +pub const NETLINK_USERSOCK: ::c_int = 2; +pub const NETLINK_FIREWALL: ::c_int = 3; +pub const NETLINK_SOCK_DIAG: ::c_int = 4; +pub const NETLINK_NFLOG: ::c_int = 5; +pub const NETLINK_XFRM: ::c_int = 6; +pub const NETLINK_SELINUX: ::c_int = 7; +pub const NETLINK_ISCSI: ::c_int = 8; +pub const NETLINK_AUDIT: ::c_int = 9; +pub const NETLINK_FIB_LOOKUP: ::c_int = 10; +pub const NETLINK_CONNECTOR: ::c_int = 11; +pub const NETLINK_NETFILTER: ::c_int = 12; +pub const NETLINK_IP6_FW: ::c_int = 13; +pub const NETLINK_DNRTMSG: ::c_int = 14; +pub const NETLINK_KOBJECT_UEVENT: ::c_int = 15; +pub const NETLINK_GENERIC: ::c_int = 16; +pub const NETLINK_SCSITRANSPORT: ::c_int = 18; +pub const NETLINK_ECRYPTFS: ::c_int = 19; +pub const NETLINK_RDMA: ::c_int = 20; +pub const NETLINK_CRYPTO: ::c_int = 21; +pub const NETLINK_INET_DIAG: ::c_int = NETLINK_SOCK_DIAG; + +pub const MAX_LINKS: ::c_int = 32; + +pub const NLM_F_REQUEST: ::c_int = 1; +pub const NLM_F_MULTI: ::c_int = 2; +pub const NLM_F_ACK: ::c_int = 4; +pub const NLM_F_ECHO: ::c_int = 8; +pub const NLM_F_DUMP_INTR: ::c_int = 16; +pub const NLM_F_DUMP_FILTERED: ::c_int = 32; + +pub const NLM_F_ROOT: ::c_int = 0x100; +pub const NLM_F_MATCH: ::c_int = 0x200; +pub const NLM_F_ATOMIC: ::c_int = 0x400; +pub const NLM_F_DUMP: ::c_int = NLM_F_ROOT | NLM_F_MATCH; + +pub const NLM_F_REPLACE: ::c_int = 0x100; +pub const NLM_F_EXCL: ::c_int = 0x200; +pub const NLM_F_CREATE: ::c_int = 0x400; +pub const NLM_F_APPEND: ::c_int = 0x800; + +pub const NLMSG_NOOP: ::c_int = 0x1; +pub const NLMSG_ERROR: ::c_int = 0x2; +pub const NLMSG_DONE: ::c_int = 0x3; +pub const NLMSG_OVERRUN: ::c_int = 0x4; +pub const NLMSG_MIN_TYPE: ::c_int = 0x10; + +// linux/netfilter/nfnetlink.h +pub const NFNLGRP_NONE: ::c_int = 0; +pub const NFNLGRP_CONNTRACK_NEW: ::c_int = 1; +pub const NFNLGRP_CONNTRACK_UPDATE: ::c_int = 2; +pub const NFNLGRP_CONNTRACK_DESTROY: ::c_int = 3; +pub const NFNLGRP_CONNTRACK_EXP_NEW: ::c_int = 4; +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 NFNETLINK_V0: ::c_int = 0; + +pub const NFNL_SUBSYS_NONE: ::c_int = 0; +pub const NFNL_SUBSYS_CTNETLINK: ::c_int = 1; +pub const NFNL_SUBSYS_CTNETLINK_EXP: ::c_int = 2; +pub const NFNL_SUBSYS_QUEUE: ::c_int = 3; +pub const NFNL_SUBSYS_ULOG: ::c_int = 4; +pub const NFNL_SUBSYS_OSF: ::c_int = 5; +pub const NFNL_SUBSYS_IPSET: ::c_int = 6; +pub const NFNL_SUBSYS_ACCT: ::c_int = 7; +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_MSG_BATCH_BEGIN: ::c_int = NLMSG_MIN_TYPE; +pub const NFNL_MSG_BATCH_END: ::c_int = NLMSG_MIN_TYPE + 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_UNSPEC: ::c_int = 0; +pub const NFULA_PACKET_HDR: ::c_int = 1; +pub const NFULA_MARK: ::c_int = 2; +pub const NFULA_TIMESTAMP: ::c_int = 3; +pub const NFULA_IFINDEX_INDEV: ::c_int = 4; +pub const NFULA_IFINDEX_OUTDEV: ::c_int = 5; +pub const NFULA_IFINDEX_PHYSINDEV: ::c_int = 6; +pub const NFULA_IFINDEX_PHYSOUTDEV: ::c_int = 7; +pub const NFULA_HWADDR: ::c_int = 8; +pub const NFULA_PAYLOAD: ::c_int = 9; +pub const NFULA_PREFIX: ::c_int = 10; +pub const NFULA_UID: ::c_int = 11; +pub const NFULA_SEQ: ::c_int = 12; +pub const NFULA_SEQ_GLOBAL: ::c_int = 13; +pub const NFULA_GID: ::c_int = 14; +pub const NFULA_HWTYPE: ::c_int = 15; +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 NFULNL_CFG_CMD_NONE: ::c_int = 0; +pub const NFULNL_CFG_CMD_BIND: ::c_int = 1; +pub const NFULNL_CFG_CMD_UNBIND: ::c_int = 2; +pub const NFULNL_CFG_CMD_PF_BIND: ::c_int = 3; +pub const NFULNL_CFG_CMD_PF_UNBIND: ::c_int = 4; + +pub const NFULA_CFG_UNSPEC: ::c_int = 0; +pub const NFULA_CFG_CMD: ::c_int = 1; +pub const NFULA_CFG_MODE: ::c_int = 2; +pub const NFULA_CFG_NLBUFSIZ: ::c_int = 3; +pub const NFULA_CFG_TIMEOUT: ::c_int = 4; +pub const NFULA_CFG_QTHRESH: ::c_int = 5; +pub const NFULA_CFG_FLAGS: ::c_int = 6; + +pub const NFULNL_COPY_NONE: ::c_int = 0x00; +pub const NFULNL_COPY_META: ::c_int = 0x01; +pub const NFULNL_COPY_PACKET: ::c_int = 0x02; + +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 +pub const NFQNL_MSG_PACKET: ::c_int = 0; +pub const NFQNL_MSG_VERDICT: ::c_int = 1; +pub const NFQNL_MSG_CONFIG: ::c_int = 2; +pub const NFQNL_MSG_VERDICT_BATCH: ::c_int = 3; + +pub const NFQA_UNSPEC: ::c_int = 0; +pub const NFQA_PACKET_HDR: ::c_int = 1; +pub const NFQA_VERDICT_HDR: ::c_int = 2; +pub const NFQA_MARK: ::c_int = 3; +pub const NFQA_TIMESTAMP: ::c_int = 4; +pub const NFQA_IFINDEX_INDEV: ::c_int = 5; +pub const NFQA_IFINDEX_OUTDEV: ::c_int = 6; +pub const NFQA_IFINDEX_PHYSINDEV: ::c_int = 7; +pub const NFQA_IFINDEX_PHYSOUTDEV: ::c_int = 8; +pub const NFQA_HWADDR: ::c_int = 9; +pub const NFQA_PAYLOAD: ::c_int = 10; +pub const NFQA_CT: ::c_int = 11; +pub const NFQA_CT_INFO: ::c_int = 12; +pub const NFQA_CAP_LEN: ::c_int = 13; +pub const NFQA_SKB_INFO: ::c_int = 14; +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_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; +pub const NFQNL_CFG_CMD_UNBIND: ::c_int = 2; +pub const NFQNL_CFG_CMD_PF_BIND: ::c_int = 3; +pub const NFQNL_CFG_CMD_PF_UNBIND: ::c_int = 4; + +pub const NFQNL_COPY_NONE: ::c_int = 0; +pub const NFQNL_COPY_META: ::c_int = 1; +pub const NFQNL_COPY_PACKET: ::c_int = 2; + +pub const NFQA_CFG_UNSPEC: ::c_int = 0; +pub const NFQA_CFG_CMD: ::c_int = 1; +pub const NFQA_CFG_PARAMS: ::c_int = 2; +pub const NFQA_CFG_QUEUE_MAXLEN: ::c_int = 3; +pub const NFQA_CFG_MASK: ::c_int = 4; +pub const NFQA_CFG_FLAGS: ::c_int = 5; + +pub const NFQA_CFG_F_FAIL_OPEN: ::c_int = 0x0001; +pub const NFQA_CFG_F_CONNTRACK: ::c_int = 0x0002; +pub const NFQA_CFG_F_GSO: ::c_int = 0x0004; +pub const NFQA_CFG_F_UID_GID: ::c_int = 0x0008; +pub const NFQA_CFG_F_SECCTX: ::c_int = 0x0010; +pub const NFQA_CFG_F_MAX: ::c_int = 0x0020; + +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; + +pub const GENL_NAMSIZ: ::c_int = 16; + +pub const GENL_MIN_ID: ::c_int = NLMSG_MIN_TYPE; +pub const GENL_MAX_ID: ::c_int = 1023; + +pub const GENL_ADMIN_PERM: ::c_int = 0x01; +pub const GENL_CMD_CAP_DO: ::c_int = 0x02; +pub const GENL_CMD_CAP_DUMP: ::c_int = 0x04; +pub const GENL_CMD_CAP_HASPOL: ::c_int = 0x08; +pub const GENL_UNS_ADMIN_PERM: ::c_int = 0x10; + +pub const GENL_ID_CTRL: ::c_int = NLMSG_MIN_TYPE; +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 CTRL_CMD_UNSPEC: ::c_int = 0; +pub const CTRL_CMD_NEWFAMILY: ::c_int = 1; +pub const CTRL_CMD_DELFAMILY: ::c_int = 2; +pub const CTRL_CMD_GETFAMILY: ::c_int = 3; +pub const CTRL_CMD_NEWOPS: ::c_int = 4; +pub const CTRL_CMD_DELOPS: ::c_int = 5; +pub const CTRL_CMD_GETOPS: ::c_int = 6; +pub const CTRL_CMD_NEWMCAST_GRP: ::c_int = 7; +pub const CTRL_CMD_DELMCAST_GRP: ::c_int = 8; +pub const CTRL_CMD_GETMCAST_GRP: ::c_int = 9; + +pub const CTRL_ATTR_UNSPEC: ::c_int = 0; +pub const CTRL_ATTR_FAMILY_ID: ::c_int = 1; +pub const CTRL_ATTR_FAMILY_NAME: ::c_int = 2; +pub const CTRL_ATTR_VERSION: ::c_int = 3; +pub const CTRL_ATTR_HDRSIZE: ::c_int = 4; +pub const CTRL_ATTR_MAXATTR: ::c_int = 5; +pub const CTRL_ATTR_OPS: ::c_int = 6; +pub const CTRL_ATTR_MCAST_GROUPS: ::c_int = 7; + +pub const CTRL_ATTR_OP_UNSPEC: ::c_int = 0; +pub const CTRL_ATTR_OP_ID: ::c_int = 1; +pub const CTRL_ATTR_OP_FLAGS: ::c_int = 2; + +pub const CTRL_ATTR_MCAST_GRP_UNSPEC: ::c_int = 0; +pub const CTRL_ATTR_MCAST_GRP_NAME: ::c_int = 1; +pub const CTRL_ATTR_MCAST_GRP_ID: ::c_int = 2; + +pub const NETLINK_ADD_MEMBERSHIP: ::c_int = 1; +pub const NETLINK_DROP_MEMBERSHIP: ::c_int = 2; +pub const NETLINK_PKTINFO: ::c_int = 3; +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); + +pub const NLA_ALIGNTO: ::c_int = 4; + +pub const SIGEV_THREAD_ID: ::c_int = 4; + +pub const CIBAUD: ::tcflag_t = 0o02003600000; +pub const CBAUDEX: ::tcflag_t = 0o010000; + +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 POLLWRNORM: ::c_short = 0x100; +pub const POLLWRBAND: ::c_short = 0x200; + +pub const SFD_CLOEXEC: ::c_int = O_CLOEXEC; +pub const SFD_NONBLOCK: ::c_int = O_NONBLOCK; + +pub const SOCK_NONBLOCK: ::c_int = O_NONBLOCK; + +pub const SO_ORIGINAL_DST: ::c_int = 80; + +pub const IP_RECVFRAGSIZE: ::c_int = 25; + +pub const IPV6_FLOWINFO: ::c_int = 11; +pub const IPV6_MULTICAST_ALL: ::c_int = 29; +pub const IPV6_ROUTER_ALERT_ISOLATE: ::c_int = 30; +pub const IPV6_FLOWLABEL_MGR: ::c_int = 32; +pub const IPV6_FLOWINFO_SEND: ::c_int = 33; +pub const IPV6_RECVFRAGSIZE: ::c_int = 77; +pub const IPV6_FREEBIND: ::c_int = 78; +pub const IPV6_FLOWINFO_FLOWLABEL: ::c_int = 0x000fffff; +pub const IPV6_FLOWINFO_PRIORITY: ::c_int = 0x0ff00000; + +pub const IUTF8: ::tcflag_t = 0x00004000; +pub const CMSPAR: ::tcflag_t = 0o10000000000; +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_NOEXEC_SEAL: ::c_uint = 0x0008; +pub const MFD_EXEC: ::c_uint = 0x0010; +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; +pub const NF_ACCEPT: ::c_int = 1; +pub const NF_STOLEN: ::c_int = 2; +pub const NF_QUEUE: ::c_int = 3; +pub const NF_REPEAT: ::c_int = 4; +pub const NF_STOP: ::c_int = 5; +pub const NF_MAX_VERDICT: ::c_int = NF_STOP; + +pub const NF_VERDICT_MASK: ::c_int = 0x000000ff; +pub const NF_VERDICT_FLAG_QUEUE_BYPASS: ::c_int = 0x00008000; + +pub const NF_VERDICT_QMASK: ::c_int = 0xffff0000; +pub const NF_VERDICT_QBITS: ::c_int = 16; + +pub const NF_VERDICT_BITS: ::c_int = 16; + +pub const NF_INET_PRE_ROUTING: ::c_int = 0; +pub const NF_INET_LOCAL_IN: ::c_int = 1; +pub const NF_INET_FORWARD: ::c_int = 2; +pub const NF_INET_LOCAL_OUT: ::c_int = 3; +pub const NF_INET_POST_ROUTING: ::c_int = 4; +pub const NF_INET_NUMHOOKS: ::c_int = 5; + +pub const NF_NETDEV_INGRESS: ::c_int = 0; +pub const NF_NETDEV_NUMHOOKS: ::c_int = 1; + +pub const NFPROTO_UNSPEC: ::c_int = 0; +pub const NFPROTO_INET: ::c_int = 1; +pub const NFPROTO_IPV4: ::c_int = 2; +pub const NFPROTO_ARP: ::c_int = 3; +pub const NFPROTO_NETDEV: ::c_int = 5; +pub const NFPROTO_BRIDGE: ::c_int = 7; +pub const NFPROTO_IPV6: ::c_int = 10; +pub const NFPROTO_DECNET: ::c_int = 12; +pub const NFPROTO_NUMPROTO: ::c_int = 13; + +// linux/netfilter_ipv4.h +pub const NF_IP_PRE_ROUTING: ::c_int = 0; +pub const NF_IP_LOCAL_IN: ::c_int = 1; +pub const NF_IP_FORWARD: ::c_int = 2; +pub const NF_IP_LOCAL_OUT: ::c_int = 3; +pub const NF_IP_POST_ROUTING: ::c_int = 4; +pub const NF_IP_NUMHOOKS: ::c_int = 5; + +pub const NF_IP_PRI_FIRST: ::c_int = ::INT_MIN; +pub const NF_IP_PRI_CONNTRACK_DEFRAG: ::c_int = -400; +pub const NF_IP_PRI_RAW: ::c_int = -300; +pub const NF_IP_PRI_SELINUX_FIRST: ::c_int = -225; +pub const NF_IP_PRI_CONNTRACK: ::c_int = -200; +pub const NF_IP_PRI_MANGLE: ::c_int = -150; +pub const NF_IP_PRI_NAT_DST: ::c_int = -100; +pub const NF_IP_PRI_FILTER: ::c_int = 0; +pub const NF_IP_PRI_SECURITY: ::c_int = 50; +pub const NF_IP_PRI_NAT_SRC: ::c_int = 100; +pub const NF_IP_PRI_SELINUX_LAST: ::c_int = 225; +pub const NF_IP_PRI_CONNTRACK_HELPER: ::c_int = 300; +pub const NF_IP_PRI_CONNTRACK_CONFIRM: ::c_int = ::INT_MAX; +pub const NF_IP_PRI_LAST: ::c_int = ::INT_MAX; + +// linux/netfilter_ipv6.h +pub const NF_IP6_PRE_ROUTING: ::c_int = 0; +pub const NF_IP6_LOCAL_IN: ::c_int = 1; +pub const NF_IP6_FORWARD: ::c_int = 2; +pub const NF_IP6_LOCAL_OUT: ::c_int = 3; +pub const NF_IP6_POST_ROUTING: ::c_int = 4; +pub const NF_IP6_NUMHOOKS: ::c_int = 5; + +pub const NF_IP6_PRI_FIRST: ::c_int = ::INT_MIN; +pub const NF_IP6_PRI_CONNTRACK_DEFRAG: ::c_int = -400; +pub const NF_IP6_PRI_RAW: ::c_int = -300; +pub const NF_IP6_PRI_SELINUX_FIRST: ::c_int = -225; +pub const NF_IP6_PRI_CONNTRACK: ::c_int = -200; +pub const NF_IP6_PRI_MANGLE: ::c_int = -150; +pub const NF_IP6_PRI_NAT_DST: ::c_int = -100; +pub const NF_IP6_PRI_FILTER: ::c_int = 0; +pub const NF_IP6_PRI_SECURITY: ::c_int = 50; +pub const NF_IP6_PRI_NAT_SRC: ::c_int = 100; +pub const NF_IP6_PRI_SELINUX_LAST: ::c_int = 225; +pub const NF_IP6_PRI_CONNTRACK_HELPER: ::c_int = 300; +pub const NF_IP6_PRI_LAST: ::c_int = ::INT_MAX; + +// linux/netfilter_ipv6/ip6_tables.h +pub const IP6T_SO_ORIGINAL_DST: ::c_int = 80; + +// linux/netfilter/nf_tables.h +pub const NFT_TABLE_MAXNAMELEN: ::c_int = 256; +pub const NFT_CHAIN_MAXNAMELEN: ::c_int = 256; +pub const NFT_SET_MAXNAMELEN: ::c_int = 256; +pub const NFT_OBJ_MAXNAMELEN: ::c_int = 256; +pub const NFT_USERDATA_MAXLEN: ::c_int = 256; + +pub const NFT_REG_VERDICT: ::c_int = 0; +pub const NFT_REG_1: ::c_int = 1; +pub const NFT_REG_2: ::c_int = 2; +pub const NFT_REG_3: ::c_int = 3; +pub const NFT_REG_4: ::c_int = 4; +pub const __NFT_REG_MAX: ::c_int = 5; +pub const NFT_REG32_00: ::c_int = 8; +pub const NFT_REG32_01: ::c_int = 9; +pub const NFT_REG32_02: ::c_int = 10; +pub const NFT_REG32_03: ::c_int = 11; +pub const NFT_REG32_04: ::c_int = 12; +pub const NFT_REG32_05: ::c_int = 13; +pub const NFT_REG32_06: ::c_int = 14; +pub const NFT_REG32_07: ::c_int = 15; +pub const NFT_REG32_08: ::c_int = 16; +pub const NFT_REG32_09: ::c_int = 17; +pub const NFT_REG32_10: ::c_int = 18; +pub const NFT_REG32_11: ::c_int = 19; +pub const NFT_REG32_12: ::c_int = 20; +pub const NFT_REG32_13: ::c_int = 21; +pub const NFT_REG32_14: ::c_int = 22; +pub const NFT_REG32_15: ::c_int = 23; + +pub const NFT_REG_SIZE: ::c_int = 16; +pub const NFT_REG32_SIZE: ::c_int = 4; + +pub const NFT_CONTINUE: ::c_int = -1; +pub const NFT_BREAK: ::c_int = -2; +pub const NFT_JUMP: ::c_int = -3; +pub const NFT_GOTO: ::c_int = -4; +pub const NFT_RETURN: ::c_int = -5; + +pub const NFT_MSG_NEWTABLE: ::c_int = 0; +pub const NFT_MSG_GETTABLE: ::c_int = 1; +pub const NFT_MSG_DELTABLE: ::c_int = 2; +pub const NFT_MSG_NEWCHAIN: ::c_int = 3; +pub const NFT_MSG_GETCHAIN: ::c_int = 4; +pub const NFT_MSG_DELCHAIN: ::c_int = 5; +pub const NFT_MSG_NEWRULE: ::c_int = 6; +pub const NFT_MSG_GETRULE: ::c_int = 7; +pub const NFT_MSG_DELRULE: ::c_int = 8; +pub const NFT_MSG_NEWSET: ::c_int = 9; +pub const NFT_MSG_GETSET: ::c_int = 10; +pub const NFT_MSG_DELSET: ::c_int = 11; +pub const NFT_MSG_NEWSETELEM: ::c_int = 12; +pub const NFT_MSG_GETSETELEM: ::c_int = 13; +pub const NFT_MSG_DELSETELEM: ::c_int = 14; +pub const NFT_MSG_NEWGEN: ::c_int = 15; +pub const NFT_MSG_GETGEN: ::c_int = 16; +pub const NFT_MSG_TRACE: ::c_int = 17; +pub const NFT_MSG_NEWOBJ: ::c_int = 18; +pub const NFT_MSG_GETOBJ: ::c_int = 19; +pub const NFT_MSG_DELOBJ: ::c_int = 20; +pub const NFT_MSG_GETOBJ_RESET: ::c_int = 21; +pub const NFT_MSG_MAX: ::c_int = 25; + +pub const NFT_SET_ANONYMOUS: ::c_int = 0x1; +pub const NFT_SET_CONSTANT: ::c_int = 0x2; +pub const NFT_SET_INTERVAL: ::c_int = 0x4; +pub const NFT_SET_MAP: ::c_int = 0x8; +pub const NFT_SET_TIMEOUT: ::c_int = 0x10; +pub const NFT_SET_EVAL: ::c_int = 0x20; + +pub const NFT_SET_POL_PERFORMANCE: ::c_int = 0; +pub const NFT_SET_POL_MEMORY: ::c_int = 1; + +pub const NFT_SET_ELEM_INTERVAL_END: ::c_int = 0x1; + +pub const NFT_DATA_VALUE: ::c_uint = 0; +pub const NFT_DATA_VERDICT: ::c_uint = 0xffffff00; + +pub const NFT_DATA_RESERVED_MASK: ::c_uint = 0xffffff00; + +pub const NFT_DATA_VALUE_MAXLEN: ::c_int = 64; + +pub const NFT_BYTEORDER_NTOH: ::c_int = 0; +pub const NFT_BYTEORDER_HTON: ::c_int = 1; + +pub const NFT_CMP_EQ: ::c_int = 0; +pub const NFT_CMP_NEQ: ::c_int = 1; +pub const NFT_CMP_LT: ::c_int = 2; +pub const NFT_CMP_LTE: ::c_int = 3; +pub const NFT_CMP_GT: ::c_int = 4; +pub const NFT_CMP_GTE: ::c_int = 5; + +pub const NFT_RANGE_EQ: ::c_int = 0; +pub const NFT_RANGE_NEQ: ::c_int = 1; + +pub const NFT_LOOKUP_F_INV: ::c_int = 1 << 0; + +pub const NFT_DYNSET_OP_ADD: ::c_int = 0; +pub const NFT_DYNSET_OP_UPDATE: ::c_int = 1; + +pub const NFT_DYNSET_F_INV: ::c_int = 1 << 0; + +pub const NFT_PAYLOAD_LL_HEADER: ::c_int = 0; +pub const NFT_PAYLOAD_NETWORK_HEADER: ::c_int = 1; +pub const NFT_PAYLOAD_TRANSPORT_HEADER: ::c_int = 2; + +pub const NFT_PAYLOAD_CSUM_NONE: ::c_int = 0; +pub const NFT_PAYLOAD_CSUM_INET: ::c_int = 1; + +pub const NFT_META_LEN: ::c_int = 0; +pub const NFT_META_PROTOCOL: ::c_int = 1; +pub const NFT_META_PRIORITY: ::c_int = 2; +pub const NFT_META_MARK: ::c_int = 3; +pub const NFT_META_IIF: ::c_int = 4; +pub const NFT_META_OIF: ::c_int = 5; +pub const NFT_META_IIFNAME: ::c_int = 6; +pub const NFT_META_OIFNAME: ::c_int = 7; +pub const NFT_META_IIFTYPE: ::c_int = 8; +pub const NFT_META_OIFTYPE: ::c_int = 9; +pub const NFT_META_SKUID: ::c_int = 10; +pub const NFT_META_SKGID: ::c_int = 11; +pub const NFT_META_NFTRACE: ::c_int = 12; +pub const NFT_META_RTCLASSID: ::c_int = 13; +pub const NFT_META_SECMARK: ::c_int = 14; +pub const NFT_META_NFPROTO: ::c_int = 15; +pub const NFT_META_L4PROTO: ::c_int = 16; +pub const NFT_META_BRI_IIFNAME: ::c_int = 17; +pub const NFT_META_BRI_OIFNAME: ::c_int = 18; +pub const NFT_META_PKTTYPE: ::c_int = 19; +pub const NFT_META_CPU: ::c_int = 20; +pub const NFT_META_IIFGROUP: ::c_int = 21; +pub const NFT_META_OIFGROUP: ::c_int = 22; +pub const NFT_META_CGROUP: ::c_int = 23; +pub const NFT_META_PRANDOM: ::c_int = 24; + +pub const NFT_CT_STATE: ::c_int = 0; +pub const NFT_CT_DIRECTION: ::c_int = 1; +pub const NFT_CT_STATUS: ::c_int = 2; +pub const NFT_CT_MARK: ::c_int = 3; +pub const NFT_CT_SECMARK: ::c_int = 4; +pub const NFT_CT_EXPIRATION: ::c_int = 5; +pub const NFT_CT_HELPER: ::c_int = 6; +pub const NFT_CT_L3PROTOCOL: ::c_int = 7; +pub const NFT_CT_SRC: ::c_int = 8; +pub const NFT_CT_DST: ::c_int = 9; +pub const NFT_CT_PROTOCOL: ::c_int = 10; +pub const NFT_CT_PROTO_SRC: ::c_int = 11; +pub const NFT_CT_PROTO_DST: ::c_int = 12; +pub const NFT_CT_LABELS: ::c_int = 13; +pub const NFT_CT_PKTS: ::c_int = 14; +pub const NFT_CT_BYTES: ::c_int = 15; +pub const NFT_CT_AVGPKT: ::c_int = 16; +pub const NFT_CT_ZONE: ::c_int = 17; +pub const NFT_CT_EVENTMASK: ::c_int = 18; +pub const NFT_CT_SRC_IP: ::c_int = 19; +pub const NFT_CT_DST_IP: ::c_int = 20; +pub const NFT_CT_SRC_IP6: ::c_int = 21; +pub const NFT_CT_DST_IP6: ::c_int = 22; +pub const NFT_CT_ID: ::c_int = 23; + +pub const NFT_LIMIT_PKTS: ::c_int = 0; +pub const NFT_LIMIT_PKT_BYTES: ::c_int = 1; + +pub const NFT_LIMIT_F_INV: ::c_int = 1 << 0; + +pub const NFT_QUEUE_FLAG_BYPASS: ::c_int = 0x01; +pub const NFT_QUEUE_FLAG_CPU_FANOUT: ::c_int = 0x02; +pub const NFT_QUEUE_FLAG_MASK: ::c_int = 0x03; + +pub const NFT_QUOTA_F_INV: ::c_int = 1 << 0; + +pub const NFT_REJECT_ICMP_UNREACH: ::c_int = 0; +pub const NFT_REJECT_TCP_RST: ::c_int = 1; +pub const NFT_REJECT_ICMPX_UNREACH: ::c_int = 2; + +pub const NFT_REJECT_ICMPX_NO_ROUTE: ::c_int = 0; +pub const NFT_REJECT_ICMPX_PORT_UNREACH: ::c_int = 1; +pub const NFT_REJECT_ICMPX_HOST_UNREACH: ::c_int = 2; +pub const NFT_REJECT_ICMPX_ADMIN_PROHIBITED: ::c_int = 3; + +pub const NFT_NAT_SNAT: ::c_int = 0; +pub const NFT_NAT_DNAT: ::c_int = 1; + +pub const NFT_TRACETYPE_UNSPEC: ::c_int = 0; +pub const NFT_TRACETYPE_POLICY: ::c_int = 1; +pub const NFT_TRACETYPE_RETURN: ::c_int = 2; +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_CARRIER: ::c_int = 0x0040; +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; +// Features for GSO (TUNSETOFFLOAD) +pub const TUN_F_CSUM: ::c_uint = 0x01; +pub const TUN_F_TSO4: ::c_uint = 0x02; +pub const TUN_F_TSO6: ::c_uint = 0x04; +pub const TUN_F_TSO_ECN: ::c_uint = 0x08; +pub const TUN_F_UFO: ::c_uint = 0x10; +pub const TUN_F_USO4: ::c_uint = 0x20; +pub const TUN_F_USO6: ::c_uint = 0x40; + +// start android/platform/bionic/libc/kernel/uapi/linux/if_ether.h +// from https://android.googlesource.com/platform/bionic/+/HEAD/libc/kernel/uapi/linux/if_ether.h +pub const ETH_ALEN: ::c_int = 6; +pub const ETH_HLEN: ::c_int = 14; +pub const ETH_ZLEN: ::c_int = 60; +pub const ETH_DATA_LEN: ::c_int = 1500; +pub const ETH_FRAME_LEN: ::c_int = 1514; +pub const ETH_FCS_LEN: ::c_int = 4; +pub const ETH_MIN_MTU: ::c_int = 68; +pub const ETH_MAX_MTU: ::c_int = 0xFFFF; +pub const ETH_P_LOOP: ::c_int = 0x0060; +pub const ETH_P_PUP: ::c_int = 0x0200; +pub const ETH_P_PUPAT: ::c_int = 0x0201; +pub const ETH_P_TSN: ::c_int = 0x22F0; +pub const ETH_P_IP: ::c_int = 0x0800; +pub const ETH_P_X25: ::c_int = 0x0805; +pub const ETH_P_ARP: ::c_int = 0x0806; +pub const ETH_P_BPQ: ::c_int = 0x08FF; +pub const ETH_P_IEEEPUP: ::c_int = 0x0a00; +pub const ETH_P_IEEEPUPAT: ::c_int = 0x0a01; +pub const ETH_P_BATMAN: ::c_int = 0x4305; +pub const ETH_P_DEC: ::c_int = 0x6000; +pub const ETH_P_DNA_DL: ::c_int = 0x6001; +pub const ETH_P_DNA_RC: ::c_int = 0x6002; +pub const ETH_P_DNA_RT: ::c_int = 0x6003; +pub const ETH_P_LAT: ::c_int = 0x6004; +pub const ETH_P_DIAG: ::c_int = 0x6005; +pub const ETH_P_CUST: ::c_int = 0x6006; +pub const ETH_P_SCA: ::c_int = 0x6007; +pub const ETH_P_TEB: ::c_int = 0x6558; +pub const ETH_P_RARP: ::c_int = 0x8035; +pub const ETH_P_ATALK: ::c_int = 0x809B; +pub const ETH_P_AARP: ::c_int = 0x80F3; +pub const ETH_P_8021Q: ::c_int = 0x8100; +/* see rust-lang/libc#924 pub const ETH_P_ERSPAN: ::c_int = 0x88BE;*/ +pub const ETH_P_IPX: ::c_int = 0x8137; +pub const ETH_P_IPV6: ::c_int = 0x86DD; +pub const ETH_P_PAUSE: ::c_int = 0x8808; +pub const ETH_P_SLOW: ::c_int = 0x8809; +pub const ETH_P_WCCP: ::c_int = 0x883E; +pub const ETH_P_MPLS_UC: ::c_int = 0x8847; +pub const ETH_P_MPLS_MC: ::c_int = 0x8848; +pub const ETH_P_ATMMPOA: ::c_int = 0x884c; +pub const ETH_P_PPP_DISC: ::c_int = 0x8863; +pub const ETH_P_PPP_SES: ::c_int = 0x8864; +pub const ETH_P_LINK_CTL: ::c_int = 0x886c; +pub const ETH_P_ATMFATE: ::c_int = 0x8884; +pub const ETH_P_PAE: ::c_int = 0x888E; +pub const ETH_P_AOE: ::c_int = 0x88A2; +pub const ETH_P_8021AD: ::c_int = 0x88A8; +pub const ETH_P_802_EX1: ::c_int = 0x88B5; +pub const ETH_P_TIPC: ::c_int = 0x88CA; +pub const ETH_P_MACSEC: ::c_int = 0x88E5; +pub const ETH_P_8021AH: ::c_int = 0x88E7; +pub const ETH_P_MVRP: ::c_int = 0x88F5; +pub const ETH_P_1588: ::c_int = 0x88F7; +pub const ETH_P_NCSI: ::c_int = 0x88F8; +pub const ETH_P_PRP: ::c_int = 0x88FB; +pub const ETH_P_FCOE: ::c_int = 0x8906; +/* see rust-lang/libc#924 pub const ETH_P_IBOE: ::c_int = 0x8915;*/ +pub const ETH_P_TDLS: ::c_int = 0x890D; +pub const ETH_P_FIP: ::c_int = 0x8914; +pub const ETH_P_80221: ::c_int = 0x8917; +pub const ETH_P_HSR: ::c_int = 0x892F; +/* see rust-lang/libc#924 pub const ETH_P_NSH: ::c_int = 0x894F;*/ +pub const ETH_P_LOOPBACK: ::c_int = 0x9000; +pub const ETH_P_QINQ1: ::c_int = 0x9100; +pub const ETH_P_QINQ2: ::c_int = 0x9200; +pub const ETH_P_QINQ3: ::c_int = 0x9300; +pub const ETH_P_EDSA: ::c_int = 0xDADA; +/* see rust-lang/libc#924 pub const ETH_P_IFE: ::c_int = 0xED3E;*/ +pub const ETH_P_AF_IUCV: ::c_int = 0xFBFB; +pub const ETH_P_802_3_MIN: ::c_int = 0x0600; +pub const ETH_P_802_3: ::c_int = 0x0001; +pub const ETH_P_AX25: ::c_int = 0x0002; +pub const ETH_P_ALL: ::c_int = 0x0003; +pub const ETH_P_802_2: ::c_int = 0x0004; +pub const ETH_P_SNAP: ::c_int = 0x0005; +pub const ETH_P_DDCMP: ::c_int = 0x0006; +pub const ETH_P_WAN_PPP: ::c_int = 0x0007; +pub const ETH_P_PPP_MP: ::c_int = 0x0008; +pub const ETH_P_LOCALTALK: ::c_int = 0x0009; +pub const ETH_P_CAN: ::c_int = 0x000C; +pub const ETH_P_CANFD: ::c_int = 0x000D; +pub const ETH_P_PPPTALK: ::c_int = 0x0010; +pub const ETH_P_TR_802_2: ::c_int = 0x0011; +pub const ETH_P_MOBITEX: ::c_int = 0x0015; +pub const ETH_P_CONTROL: ::c_int = 0x0016; +pub const ETH_P_IRDA: ::c_int = 0x0017; +pub const ETH_P_ECONET: ::c_int = 0x0018; +pub const ETH_P_HDLC: ::c_int = 0x0019; +pub const ETH_P_ARCNET: ::c_int = 0x001A; +pub const ETH_P_DSA: ::c_int = 0x001B; +pub const ETH_P_TRAILER: ::c_int = 0x001C; +pub const ETH_P_PHONET: ::c_int = 0x00F5; +pub const ETH_P_IEEE802154: ::c_int = 0x00F6; +pub const ETH_P_CAIF: ::c_int = 0x00F7; +pub const ETH_P_XDSA: ::c_int = 0x00F8; +/* see rust-lang/libc#924 pub const ETH_P_MAP: ::c_int = 0x00F9;*/ +// end android/platform/bionic/libc/kernel/uapi/linux/if_ether.h + +// start android/platform/bionic/libc/kernel/uapi/linux/neighbour.h +pub const NDA_UNSPEC: ::c_ushort = 0; +pub const NDA_DST: ::c_ushort = 1; +pub const NDA_LLADDR: ::c_ushort = 2; +pub const NDA_CACHEINFO: ::c_ushort = 3; +pub const NDA_PROBES: ::c_ushort = 4; +pub const NDA_VLAN: ::c_ushort = 5; +pub const NDA_PORT: ::c_ushort = 6; +pub const NDA_VNI: ::c_ushort = 7; +pub const NDA_IFINDEX: ::c_ushort = 8; +pub const NDA_MASTER: ::c_ushort = 9; +pub const NDA_LINK_NETNSID: ::c_ushort = 10; +pub const NDA_SRC_VNI: ::c_ushort = 11; +pub const NDA_PROTOCOL: ::c_ushort = 12; +pub const NDA_NH_ID: ::c_ushort = 13; +pub const NDA_FDB_EXT_ATTRS: ::c_ushort = 14; +pub const NDA_FLAGS_EXT: ::c_ushort = 15; +pub const NDA_NDM_STATE_MASK: ::c_ushort = 16; +pub const NDA_NDM_FLAGS_MASK: ::c_ushort = 17; + +pub const NTF_USE: u8 = 0x01; +pub const NTF_SELF: u8 = 0x02; +pub const NTF_MASTER: u8 = 0x04; +pub const NTF_PROXY: u8 = 0x08; +pub const NTF_EXT_LEARNED: u8 = 0x10; +pub const NTF_OFFLOADED: u8 = 0x20; +pub const NTF_STICKY: u8 = 0x40; +pub const NTF_ROUTER: u8 = 0x80; + +pub const NTF_EXT_MANAGED: u8 = 0x01; +pub const NTF_EXT_LOCKED: u8 = 0x02; + +pub const NUD_NONE: u16 = 0x00; +pub const NUD_INCOMPLETE: u16 = 0x01; +pub const NUD_REACHABLE: u16 = 0x02; +pub const NUD_STALE: u16 = 0x04; +pub const NUD_DELAY: u16 = 0x08; +pub const NUD_PROBE: u16 = 0x10; +pub const NUD_FAILED: u16 = 0x20; +pub const NUD_NOARP: u16 = 0x40; +pub const NUD_PERMANENT: u16 = 0x80; + +pub const NDTPA_UNSPEC: ::c_ushort = 0; +pub const NDTPA_IFINDEX: ::c_ushort = 1; +pub const NDTPA_REFCNT: ::c_ushort = 2; +pub const NDTPA_REACHABLE_TIME: ::c_ushort = 3; +pub const NDTPA_BASE_REACHABLE_TIME: ::c_ushort = 4; +pub const NDTPA_RETRANS_TIME: ::c_ushort = 5; +pub const NDTPA_GC_STALETIME: ::c_ushort = 6; +pub const NDTPA_DELAY_PROBE_TIME: ::c_ushort = 7; +pub const NDTPA_QUEUE_LEN: ::c_ushort = 8; +pub const NDTPA_APP_PROBES: ::c_ushort = 9; +pub const NDTPA_UCAST_PROBES: ::c_ushort = 10; +pub const NDTPA_MCAST_PROBES: ::c_ushort = 11; +pub const NDTPA_ANYCAST_DELAY: ::c_ushort = 12; +pub const NDTPA_PROXY_DELAY: ::c_ushort = 13; +pub const NDTPA_PROXY_QLEN: ::c_ushort = 14; +pub const NDTPA_LOCKTIME: ::c_ushort = 15; +pub const NDTPA_QUEUE_LENBYTES: ::c_ushort = 16; +pub const NDTPA_MCAST_REPROBES: ::c_ushort = 17; +pub const NDTPA_PAD: ::c_ushort = 18; +pub const NDTPA_INTERVAL_PROBE_TIME_MS: ::c_ushort = 19; + +pub const NDTA_UNSPEC: ::c_ushort = 0; +pub const NDTA_NAME: ::c_ushort = 1; +pub const NDTA_THRESH1: ::c_ushort = 2; +pub const NDTA_THRESH2: ::c_ushort = 3; +pub const NDTA_THRESH3: ::c_ushort = 4; +pub const NDTA_CONFIG: ::c_ushort = 5; +pub const NDTA_PARMS: ::c_ushort = 6; +pub const NDTA_STATS: ::c_ushort = 7; +pub const NDTA_GC_INTERVAL: ::c_ushort = 8; +pub const NDTA_PAD: ::c_ushort = 9; + +pub const FDB_NOTIFY_BIT: u16 = 0x01; +pub const FDB_NOTIFY_INACTIVE_BIT: u16 = 0x02; + +pub const NFEA_UNSPEC: ::c_ushort = 0; +pub const NFEA_ACTIVITY_NOTIFY: ::c_ushort = 1; +pub const NFEA_DONT_REFRESH: ::c_ushort = 2; +// end android/platform/bionic/libc/kernel/uapi/linux/neighbour.h + +pub const SIOCADDRT: ::c_ulong = 0x0000890B; +pub const SIOCDELRT: ::c_ulong = 0x0000890C; +pub const SIOCRTMSG: ::c_ulong = 0x0000890D; +pub const SIOCGIFNAME: ::c_ulong = 0x00008910; +pub const SIOCSIFLINK: ::c_ulong = 0x00008911; +pub const SIOCGIFCONF: ::c_ulong = 0x00008912; +pub const SIOCGIFFLAGS: ::c_ulong = 0x00008913; +pub const SIOCSIFFLAGS: ::c_ulong = 0x00008914; +pub const SIOCGIFADDR: ::c_ulong = 0x00008915; +pub const SIOCSIFADDR: ::c_ulong = 0x00008916; +pub const SIOCGIFDSTADDR: ::c_ulong = 0x00008917; +pub const SIOCSIFDSTADDR: ::c_ulong = 0x00008918; +pub const SIOCGIFBRDADDR: ::c_ulong = 0x00008919; +pub const SIOCSIFBRDADDR: ::c_ulong = 0x0000891A; +pub const SIOCGIFNETMASK: ::c_ulong = 0x0000891B; +pub const SIOCSIFNETMASK: ::c_ulong = 0x0000891C; +pub const SIOCGIFMETRIC: ::c_ulong = 0x0000891D; +pub const SIOCSIFMETRIC: ::c_ulong = 0x0000891E; +pub const SIOCGIFMEM: ::c_ulong = 0x0000891F; +pub const SIOCSIFMEM: ::c_ulong = 0x00008920; +pub const SIOCGIFMTU: ::c_ulong = 0x00008921; +pub const SIOCSIFMTU: ::c_ulong = 0x00008922; +pub const SIOCSIFNAME: ::c_ulong = 0x00008923; +pub const SIOCSIFHWADDR: ::c_ulong = 0x00008924; +pub const SIOCGIFENCAP: ::c_ulong = 0x00008925; +pub const SIOCSIFENCAP: ::c_ulong = 0x00008926; +pub const SIOCGIFHWADDR: ::c_ulong = 0x00008927; +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; +pub const SIOCDRARP: ::c_ulong = 0x00008960; +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 SIOCADDDLCI: ::c_ulong = 0x00008980; +pub const SIOCDELDLCI: ::c_ulong = 0x00008981; +pub const SIOCGIFVLAN: ::c_ulong = 0x00008982; +pub const SIOCSIFVLAN: ::c_ulong = 0x00008983; +pub const SIOCBONDENSLAVE: ::c_ulong = 0x00008990; +pub const SIOCBONDRELEASE: ::c_ulong = 0x00008991; +pub const SIOCBONDSETHWADDR: ::c_ulong = 0x00008992; +pub const SIOCBONDSLAVEINFOQUERY: ::c_ulong = 0x00008993; +pub const SIOCBONDINFOQUERY: ::c_ulong = 0x00008994; +pub const SIOCBONDCHANGEACTIVE: ::c_ulong = 0x00008995; +pub const SIOCBRADDBR: ::c_ulong = 0x000089a0; +pub const SIOCBRDELBR: ::c_ulong = 0x000089a1; +pub const SIOCBRADDIF: ::c_ulong = 0x000089a2; +pub const SIOCBRDELIF: ::c_ulong = 0x000089a3; +pub const SIOCSHWTSTAMP: ::c_ulong = 0x000089b0; +pub const SIOCGHWTSTAMP: ::c_ulong = 0x000089b1; +pub const SIOCDEVPRIVATE: ::c_ulong = 0x000089F0; +pub const SIOCPROTOPRIVATE: ::c_ulong = 0x000089E0; + +// linux/module.h +pub const MODULE_INIT_IGNORE_MODVERSIONS: ::c_uint = 0x0001; +pub const MODULE_INIT_IGNORE_VERMAGIC: ::c_uint = 0x0002; + +// linux/net_tstamp.h +pub const SOF_TIMESTAMPING_TX_HARDWARE: ::c_uint = 1 << 0; +pub const SOF_TIMESTAMPING_TX_SOFTWARE: ::c_uint = 1 << 1; +pub const SOF_TIMESTAMPING_RX_HARDWARE: ::c_uint = 1 << 2; +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; + +#[deprecated( + since = "0.2.55", + note = "ENOATTR is not available on Android; use ENODATA instead" +)] +pub const ENOATTR: ::c_int = ::ENODATA; + +// linux/if_alg.h +pub const ALG_SET_KEY: ::c_int = 1; +pub const ALG_SET_IV: ::c_int = 2; +pub const ALG_SET_OP: ::c_int = 3; +pub const ALG_SET_AEAD_ASSOCLEN: ::c_int = 4; +pub const ALG_SET_AEAD_AUTHSIZE: ::c_int = 5; +pub const ALG_SET_DRBG_ENTROPY: ::c_int = 6; + +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; +pub const VMADDR_CID_LOCAL: ::c_uint = 1; +pub const VMADDR_CID_HOST: ::c_uint = 2; +pub const VMADDR_PORT_ANY: ::c_uint = 0xFFFFFFFF; + +// uapi/linux/inotify.h +pub const IN_ACCESS: u32 = 0x0000_0001; +pub const IN_MODIFY: u32 = 0x0000_0002; +pub const IN_ATTRIB: u32 = 0x0000_0004; +pub const IN_CLOSE_WRITE: u32 = 0x0000_0008; +pub const IN_CLOSE_NOWRITE: u32 = 0x0000_0010; +pub const IN_CLOSE: u32 = IN_CLOSE_WRITE | IN_CLOSE_NOWRITE; +pub const IN_OPEN: u32 = 0x0000_0020; +pub const IN_MOVED_FROM: u32 = 0x0000_0040; +pub const IN_MOVED_TO: u32 = 0x0000_0080; +pub const IN_MOVE: u32 = IN_MOVED_FROM | IN_MOVED_TO; +pub const IN_CREATE: u32 = 0x0000_0100; +pub const IN_DELETE: u32 = 0x0000_0200; +pub const IN_DELETE_SELF: u32 = 0x0000_0400; +pub const IN_MOVE_SELF: u32 = 0x0000_0800; +pub const IN_UNMOUNT: u32 = 0x0000_2000; +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_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; + +pub const IN_ALL_EVENTS: u32 = IN_ACCESS + | IN_MODIFY + | IN_ATTRIB + | IN_CLOSE_WRITE + | IN_CLOSE_NOWRITE + | IN_OPEN + | IN_MOVED_FROM + | IN_MOVED_TO + | IN_DELETE + | IN_CREATE + | IN_DELETE_SELF + | IN_MOVE_SELF; + +pub const IN_CLOEXEC: ::c_int = O_CLOEXEC; +pub const IN_NONBLOCK: ::c_int = O_NONBLOCK; + +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_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); + +// linux/errqueue.h +pub const SO_EE_ORIGIN_NONE: u8 = 0; +pub const SO_EE_ORIGIN_LOCAL: u8 = 1; +pub const SO_EE_ORIGIN_ICMP: u8 = 2; +pub const SO_EE_ORIGIN_ICMP6: u8 = 3; +pub const SO_EE_ORIGIN_TXSTATUS: u8 = 4; +pub const SO_EE_ORIGIN_TIMESTAMPING: u8 = SO_EE_ORIGIN_TXSTATUS; + +// 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 EWOULDBLOCK: ::c_int = EAGAIN; + +pub const PRIO_PROCESS: ::c_int = 0; +pub const PRIO_PGRP: ::c_int = 1; +pub const PRIO_USER: ::c_int = 2; + +// linux/sched.h +pub const SCHED_NORMAL: ::c_int = 0; +pub const SCHED_FIFO: ::c_int = 1; +pub const SCHED_RR: ::c_int = 2; +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; + +// sys/socket.h +pub const AF_NFC: ::c_int = 39; +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; +pub const PR_SET_NAME: ::c_int = 15; +pub const PR_GET_NAME: ::c_int = 16; + +// 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_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_DEVLINK_PORT: ::c_ushort = 62; +pub const IFLA_GSO_IPV4_MAX_SIZE: ::c_ushort = 63; +pub const IFLA_GRO_IPV4_MAX_SIZE: ::c_ushort = 64; + +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; + +pub const CTL_KERN: ::c_int = 1; +pub const CTL_VM: ::c_int = 2; +pub const CTL_NET: ::c_int = 3; +pub const CTL_FS: ::c_int = 5; +pub const CTL_DEBUG: ::c_int = 6; +pub const CTL_DEV: ::c_int = 7; +pub const CTL_BUS: ::c_int = 8; +pub const CTL_ABI: ::c_int = 9; +pub const CTL_CPU: ::c_int = 10; + +pub const CTL_BUS_ISA: ::c_int = 1; + +pub const INOTIFY_MAX_USER_INSTANCES: ::c_int = 1; +pub const INOTIFY_MAX_USER_WATCHES: ::c_int = 2; +pub const INOTIFY_MAX_QUEUED_EVENTS: ::c_int = 3; + +pub const KERN_OSTYPE: ::c_int = 1; +pub const KERN_OSRELEASE: ::c_int = 2; +pub const KERN_OSREV: ::c_int = 3; +pub const KERN_VERSION: ::c_int = 4; +pub const KERN_SECUREMASK: ::c_int = 5; +pub const KERN_PROF: ::c_int = 6; +pub const KERN_NODENAME: ::c_int = 7; +pub const KERN_DOMAINNAME: ::c_int = 8; +pub const KERN_PANIC: ::c_int = 15; +pub const KERN_REALROOTDEV: ::c_int = 16; +pub const KERN_SPARC_REBOOT: ::c_int = 21; +pub const KERN_CTLALTDEL: ::c_int = 22; +pub const KERN_PRINTK: ::c_int = 23; +pub const KERN_NAMETRANS: ::c_int = 24; +pub const KERN_PPC_HTABRECLAIM: ::c_int = 25; +pub const KERN_PPC_ZEROPAGED: ::c_int = 26; +pub const KERN_PPC_POWERSAVE_NAP: ::c_int = 27; +pub const KERN_MODPROBE: ::c_int = 28; +pub const KERN_SG_BIG_BUFF: ::c_int = 29; +pub const KERN_ACCT: ::c_int = 30; +pub const KERN_PPC_L2CR: ::c_int = 31; +pub const KERN_RTSIGNR: ::c_int = 32; +pub const KERN_RTSIGMAX: ::c_int = 33; +pub const KERN_SHMMAX: ::c_int = 34; +pub const KERN_MSGMAX: ::c_int = 35; +pub const KERN_MSGMNB: ::c_int = 36; +pub const KERN_MSGPOOL: ::c_int = 37; +pub const KERN_SYSRQ: ::c_int = 38; +pub const KERN_MAX_THREADS: ::c_int = 39; +pub const KERN_RANDOM: ::c_int = 40; +pub const KERN_SHMALL: ::c_int = 41; +pub const KERN_MSGMNI: ::c_int = 42; +pub const KERN_SEM: ::c_int = 43; +pub const KERN_SPARC_STOP_A: ::c_int = 44; +pub const KERN_SHMMNI: ::c_int = 45; +pub const KERN_OVERFLOWUID: ::c_int = 46; +pub const KERN_OVERFLOWGID: ::c_int = 47; +pub const KERN_SHMPATH: ::c_int = 48; +pub const KERN_HOTPLUG: ::c_int = 49; +pub const KERN_IEEE_EMULATION_WARNINGS: ::c_int = 50; +pub const KERN_S390_USER_DEBUG_LOGGING: ::c_int = 51; +pub const KERN_CORE_USES_PID: ::c_int = 52; +pub const KERN_TAINTED: ::c_int = 53; +pub const KERN_CADPID: ::c_int = 54; +pub const KERN_PIDMAX: ::c_int = 55; +pub const KERN_CORE_PATTERN: ::c_int = 56; +pub const KERN_PANIC_ON_OOPS: ::c_int = 57; +pub const KERN_HPPA_PWRSW: ::c_int = 58; +pub const KERN_HPPA_UNALIGNED: ::c_int = 59; +pub const KERN_PRINTK_RATELIMIT: ::c_int = 60; +pub const KERN_PRINTK_RATELIMIT_BURST: ::c_int = 61; +pub const KERN_PTY: ::c_int = 62; +pub const KERN_NGROUPS_MAX: ::c_int = 63; +pub const KERN_SPARC_SCONS_PWROFF: ::c_int = 64; +pub const KERN_HZ_TIMER: ::c_int = 65; +pub const KERN_UNKNOWN_NMI_PANIC: ::c_int = 66; +pub const KERN_BOOTLOADER_TYPE: ::c_int = 67; +pub const KERN_RANDOMIZE: ::c_int = 68; +pub const KERN_SETUID_DUMPABLE: ::c_int = 69; +pub const KERN_SPIN_RETRY: ::c_int = 70; +pub const KERN_ACPI_VIDEO_FLAGS: ::c_int = 71; +pub const KERN_IA64_UNALIGNED: ::c_int = 72; +pub const KERN_COMPAT_LOG: ::c_int = 73; +pub const KERN_MAX_LOCK_DEPTH: ::c_int = 74; + +pub const VM_OVERCOMMIT_MEMORY: ::c_int = 5; +pub const VM_PAGE_CLUSTER: ::c_int = 10; +pub const VM_DIRTY_BACKGROUND: ::c_int = 11; +pub const VM_DIRTY_RATIO: ::c_int = 12; +pub const VM_DIRTY_WB_CS: ::c_int = 13; +pub const VM_DIRTY_EXPIRE_CS: ::c_int = 14; +pub const VM_NR_PDFLUSH_THREADS: ::c_int = 15; +pub const VM_OVERCOMMIT_RATIO: ::c_int = 16; +pub const VM_PAGEBUF: ::c_int = 17; +pub const VM_HUGETLB_PAGES: ::c_int = 18; +pub const VM_SWAPPINESS: ::c_int = 19; +pub const VM_LOWMEM_RESERVE_RATIO: ::c_int = 20; +pub const VM_MIN_FREE_KBYTES: ::c_int = 21; +pub const VM_MAX_MAP_COUNT: ::c_int = 22; +pub const VM_LAPTOP_MODE: ::c_int = 23; +pub const VM_BLOCK_DUMP: ::c_int = 24; +pub const VM_HUGETLB_GROUP: ::c_int = 25; +pub const VM_VFS_CACHE_PRESSURE: ::c_int = 26; +pub const VM_LEGACY_VA_LAYOUT: ::c_int = 27; +pub const VM_SWAP_TOKEN_TIMEOUT: ::c_int = 28; +pub const VM_DROP_PAGECACHE: ::c_int = 29; +pub const VM_PERCPU_PAGELIST_FRACTION: ::c_int = 30; +pub const VM_ZONE_RECLAIM_MODE: ::c_int = 31; +pub const VM_MIN_UNMAPPED: ::c_int = 32; +pub const VM_PANIC_ON_OOM: ::c_int = 33; +pub const VM_VDSO_ENABLED: ::c_int = 34; + +pub const NET_CORE: ::c_int = 1; +pub const NET_ETHER: ::c_int = 2; +pub const NET_802: ::c_int = 3; +pub const NET_UNIX: ::c_int = 4; +pub const NET_IPV4: ::c_int = 5; +pub const NET_IPX: ::c_int = 6; +pub const NET_ATALK: ::c_int = 7; +pub const NET_NETROM: ::c_int = 8; +pub const NET_AX25: ::c_int = 9; +pub const NET_BRIDGE: ::c_int = 10; +pub const NET_ROSE: ::c_int = 11; +pub const NET_IPV6: ::c_int = 12; +pub const NET_X25: ::c_int = 13; +pub const NET_TR: ::c_int = 14; +pub const NET_DECNET: ::c_int = 15; +pub const NET_ECONET: ::c_int = 16; +pub const NET_SCTP: ::c_int = 17; +pub const NET_LLC: ::c_int = 18; +pub const NET_NETFILTER: ::c_int = 19; +pub const NET_DCCP: ::c_int = 20; +pub const HUGETLB_FLAG_ENCODE_SHIFT: ::c_int = 26; +pub const MAP_HUGE_SHIFT: ::c_int = HUGETLB_FLAG_ENCODE_SHIFT; + +// include/linux/sched.h +pub const PF_VCPU: ::c_int = 0x00000001; +pub const PF_IDLE: ::c_int = 0x00000002; +pub const PF_EXITING: ::c_int = 0x00000004; +pub const PF_POSTCOREDUMP: ::c_int = 0x00000008; +pub const PF_IO_WORKER: ::c_int = 0x00000010; +pub const PF_WQ_WORKER: ::c_int = 0x00000020; +pub const PF_FORKNOEXEC: ::c_int = 0x00000040; +pub const PF_MCE_PROCESS: ::c_int = 0x00000080; +pub const PF_SUPERPRIV: ::c_int = 0x00000100; +pub const PF_DUMPCORE: ::c_int = 0x00000200; +pub const PF_SIGNALED: ::c_int = 0x00000400; +pub const PF_MEMALLOC: ::c_int = 0x00000800; +pub const PF_NPROC_EXCEEDED: ::c_int = 0x00001000; +pub const PF_USED_MATH: ::c_int = 0x00002000; +pub const PF_USER_WORKER: ::c_int = 0x00004000; +pub const PF_NOFREEZE: ::c_int = 0x00008000; + +pub const PF_KSWAPD: ::c_int = 0x00020000; +pub const PF_MEMALLOC_NOFS: ::c_int = 0x00040000; +pub const PF_MEMALLOC_NOIO: ::c_int = 0x00080000; +pub const PF_LOCAL_THROTTLE: ::c_int = 0x00100000; +pub const PF_KTHREAD: ::c_int = 0x00200000; +pub const PF_RANDOMIZE: ::c_int = 0x00400000; + +pub const PF_NO_SETAFFINITY: ::c_int = 0x04000000; +pub const PF_MCE_EARLY: ::c_int = 0x08000000; +pub const PF_MEMALLOC_PIN: ::c_int = 0x10000000; + +pub const PF_SUSPEND_TASK: ::c_int = 0x80000000; + +pub const KLOG_CLOSE: ::c_int = 0; +pub const KLOG_OPEN: ::c_int = 1; +pub const KLOG_READ: ::c_int = 2; +pub const KLOG_READ_ALL: ::c_int = 3; +pub const KLOG_READ_CLEAR: ::c_int = 4; +pub const KLOG_CLEAR: ::c_int = 5; +pub const KLOG_CONSOLE_OFF: ::c_int = 6; +pub const KLOG_CONSOLE_ON: ::c_int = 7; +pub const KLOG_CONSOLE_LEVEL: ::c_int = 8; +pub const KLOG_SIZE_UNREAD: ::c_int = 9; +pub const KLOG_SIZE_BUFFER: ::c_int = 10; + +// From NDK's linux/auxvec.h +pub const AT_NULL: ::c_ulong = 0; +pub const AT_IGNORE: ::c_ulong = 1; +pub const AT_EXECFD: ::c_ulong = 2; +pub const AT_PHDR: ::c_ulong = 3; +pub const AT_PHENT: ::c_ulong = 4; +pub const AT_PHNUM: ::c_ulong = 5; +pub const AT_PAGESZ: ::c_ulong = 6; +pub const AT_BASE: ::c_ulong = 7; +pub const AT_FLAGS: ::c_ulong = 8; +pub const AT_ENTRY: ::c_ulong = 9; +pub const AT_NOTELF: ::c_ulong = 10; +pub const AT_UID: ::c_ulong = 11; +pub const AT_EUID: ::c_ulong = 12; +pub const AT_GID: ::c_ulong = 13; +pub const AT_EGID: ::c_ulong = 14; +pub const AT_PLATFORM: ::c_ulong = 15; +pub const AT_HWCAP: ::c_ulong = 16; +pub const AT_CLKTCK: ::c_ulong = 17; +pub const AT_SECURE: ::c_ulong = 23; +pub const AT_BASE_PLATFORM: ::c_ulong = 24; +pub const AT_RANDOM: ::c_ulong = 25; +pub const AT_HWCAP2: ::c_ulong = 26; +pub const AT_RSEQ_FEATURE_SIZE: ::c_ulong = 27; +pub const AT_RSEQ_ALIGN: ::c_ulong = 28; +pub const AT_EXECFN: ::c_ulong = 31; +pub const AT_MINSIGSTKSZ: ::c_ulong = 51; + +// 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, + cmsg: *const cmsghdr) -> *mut cmsghdr { + let next = (cmsg as usize + + super::CMSG_ALIGN((*cmsg).cmsg_len as usize)) + as *mut cmsghdr; + let max = (*mhdr).msg_control as usize + + (*mhdr).msg_controllen as usize; + if (next.offset(1)) as usize > max { + 0 as *mut cmsghdr + } else { + next as *mut cmsghdr + } + } + + 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; + } + } + + pub fn CPU_SET(cpu: usize, cpuset: &mut cpu_set_t) -> () { + let size_in_bits + = 8 * ::mem::size_of_val(&cpuset.__bits[0]); // 32, 64 etc + let (idx, offset) = (cpu / size_in_bits, cpu % size_in_bits); + cpuset.__bits[idx] |= 1 << offset; + () + } + + pub fn CPU_CLR(cpu: usize, cpuset: &mut cpu_set_t) -> () { + let size_in_bits + = 8 * ::mem::size_of_val(&cpuset.__bits[0]); // 32, 64 etc + let (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); + 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 NLA_ALIGN(len: ::c_int) -> ::c_int { + return ((len) + NLA_ALIGNTO - 1) & !(NLA_ALIGNTO - 1) + } + + pub fn SO_EE_OFFENDER(ee: *const ::sock_extended_err) -> *mut ::sockaddr { + ee.offset(1) as *mut ::sockaddr + } +} + +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; + pub fn getrlimit(resource: ::c_int, rlim: *mut ::rlimit) -> ::c_int; + pub fn setrlimit(resource: ::c_int, rlim: *const ::rlimit) -> ::c_int; + pub fn prlimit( + pid: ::pid_t, + resource: ::c_int, + new_limit: *const ::rlimit, + old_limit: *mut ::rlimit, + ) -> ::c_int; + pub fn prlimit64( + pid: ::pid_t, + resource: ::c_int, + new_limit: *const ::rlimit64, + old_limit: *mut ::rlimit64, + ) -> ::c_int; + 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; + pub fn mprotect(addr: *mut ::c_void, len: ::size_t, prot: ::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 getnameinfo( + sa: *const ::sockaddr, + salen: ::socklen_t, + host: *mut ::c_char, + hostlen: ::size_t, + serv: *mut ::c_char, + servlen: ::size_t, + flags: ::c_int, + ) -> ::c_int; + pub fn preadv(fd: ::c_int, iov: *const ::iovec, count: ::c_int, offset: ::off_t) -> ::ssize_t; + pub fn pwritev(fd: ::c_int, iov: *const ::iovec, count: ::c_int, offset: ::off_t) -> ::ssize_t; + pub fn process_vm_readv( + pid: ::pid_t, + local_iov: *const ::iovec, + local_iov_count: ::c_ulong, + remote_iov: *const ::iovec, + remote_iov_count: ::c_ulong, + flags: ::c_ulong, + ) -> ::ssize_t; + pub fn process_vm_writev( + pid: ::pid_t, + local_iov: *const ::iovec, + local_iov_count: ::c_ulong, + remote_iov: *const ::iovec, + remote_iov_count: ::c_ulong, + flags: ::c_ulong, + ) -> ::ssize_t; + 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 __sched_cpualloc(count: ::size_t) -> *mut ::cpu_set_t; + 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(); + pub fn getutent() -> *mut utmp; + + pub fn seekdir(dirp: *mut ::DIR, loc: ::c_long); + pub fn telldir(dirp: *mut ::DIR) -> ::c_long; + pub fn fallocate(fd: ::c_int, mode: ::c_int, offset: ::off_t, len: ::off_t) -> ::c_int; + pub fn fallocate64(fd: ::c_int, mode: ::c_int, offset: ::off64_t, len: ::off64_t) -> ::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 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, + flags: ::c_int, + ) -> ::c_int; + pub fn lsetxattr( + path: *const c_char, + name: *const c_char, + value: *const ::c_void, + size: ::size_t, + flags: ::c_int, + ) -> ::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(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(clock: ::clockid_t, flags: ::c_int) -> ::c_int; + pub fn timerfd_gettime(fd: ::c_int, current_value: *mut itimerspec) -> ::c_int; + pub fn timerfd_settime( + fd: ::c_int, + flags: ::c_int, + new_value: *const itimerspec, + old_value: *mut itimerspec, + ) -> ::c_int; + pub fn syscall(num: ::c_long, ...) -> ::c_long; + pub fn sched_getaffinity(pid: ::pid_t, cpusetsize: ::size_t, cpuset: *mut cpu_set_t) + -> ::c_int; + pub fn sched_setaffinity( + pid: ::pid_t, + cpusetsize: ::size_t, + cpuset: *const cpu_set_t, + ) -> ::c_int; + pub fn epoll_create(size: ::c_int) -> ::c_int; + pub fn epoll_create1(flags: ::c_int) -> ::c_int; + pub fn epoll_wait( + epfd: ::c_int, + events: *mut ::epoll_event, + maxevents: ::c_int, + timeout: ::c_int, + ) -> ::c_int; + pub fn epoll_ctl(epfd: ::c_int, op: ::c_int, fd: ::c_int, event: *mut ::epoll_event) + -> ::c_int; + pub fn pthread_getschedparam( + native: ::pthread_t, + policy: *mut ::c_int, + param: *mut ::sched_param, + ) -> ::c_int; + pub fn unshare(flags: ::c_int) -> ::c_int; + pub fn umount(target: *const ::c_char) -> ::c_int; + pub fn sched_get_priority_max(policy: ::c_int) -> ::c_int; + pub fn tee(fd_in: ::c_int, fd_out: ::c_int, len: ::size_t, flags: ::c_uint) -> ::ssize_t; + pub fn settimeofday(tv: *const ::timeval, tz: *const ::timezone) -> ::c_int; + pub fn splice( + fd_in: ::c_int, + off_in: *mut ::loff_t, + fd_out: ::c_int, + off_out: *mut ::loff_t, + len: ::size_t, + flags: ::c_uint, + ) -> ::ssize_t; + pub fn eventfd(init: ::c_uint, flags: ::c_int) -> ::c_int; + pub fn eventfd_read(fd: ::c_int, value: *mut eventfd_t) -> ::c_int; + pub fn eventfd_write(fd: ::c_int, value: eventfd_t) -> ::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 setns(fd: ::c_int, nstype: ::c_int) -> ::c_int; + pub fn swapoff(puath: *const ::c_char) -> ::c_int; + pub fn vmsplice( + fd: ::c_int, + iov: *const ::iovec, + nr_segs: ::size_t, + flags: ::c_uint, + ) -> ::ssize_t; + pub fn mount( + src: *const ::c_char, + target: *const ::c_char, + fstype: *const ::c_char, + flags: ::c_ulong, + data: *const ::c_void, + ) -> ::c_int; + pub fn personality(persona: ::c_uint) -> ::c_int; + pub fn prctl(option: ::c_int, ...) -> ::c_int; + pub fn sched_getparam(pid: ::pid_t, param: *mut ::sched_param) -> ::c_int; + pub fn ppoll( + fds: *mut ::pollfd, + nfds: nfds_t, + timeout: *const ::timespec, + sigmask: *const sigset_t, + ) -> ::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, + flags: ::c_int, + arg: *mut ::c_void, + ... + ) -> ::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 pthread_attr_setguardsize(attr: *mut ::pthread_attr_t, guardsize: ::size_t) -> ::c_int; + pub fn pthread_attr_getinheritsched( + attr: *const ::pthread_attr_t, + flag: *mut ::c_int, + ) -> ::c_int; + pub fn pthread_attr_setinheritsched(attr: *mut ::pthread_attr_t, flag: ::c_int) -> ::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 sysinfo(info: *mut ::sysinfo) -> ::c_int; + pub fn umount2(target: *const ::c_char, flags: ::c_int) -> ::c_int; + pub fn pthread_setschedparam( + native: ::pthread_t, + policy: ::c_int, + param: *const ::sched_param, + ) -> ::c_int; + pub fn swapon(path: *const ::c_char, swapflags: ::c_int) -> ::c_int; + pub fn sched_setscheduler( + pid: ::pid_t, + policy: ::c_int, + param: *const ::sched_param, + ) -> ::c_int; + pub fn sendfile( + out_fd: ::c_int, + in_fd: ::c_int, + offset: *mut ::off_t, + count: ::size_t, + ) -> ::ssize_t; + pub fn sendfile64( + out_fd: ::c_int, + in_fd: ::c_int, + offset: *mut ::off64_t, + count: ::size_t, + ) -> ::ssize_t; + pub fn setfsgid(gid: ::gid_t) -> ::c_int; + pub fn setfsuid(uid: ::uid_t) -> ::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 sigaltstack(ss: *const stack_t, oss: *mut stack_t) -> ::c_int; + pub fn sem_close(sem: *mut sem_t) -> ::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 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 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 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 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 initgroups(user: *const ::c_char, group: ::gid_t) -> ::c_int; + pub fn pthread_mutexattr_getpshared( + attr: *const pthread_mutexattr_t, + pshared: *mut ::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 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 __errno() -> *mut ::c_int; + pub fn inotify_rm_watch(fd: ::c_int, wd: u32) -> ::c_int; + pub fn sendmmsg( + sockfd: ::c_int, + msgvec: *const ::mmsghdr, + vlen: ::c_uint, + flags: ::c_int, + ) -> ::c_int; + pub fn recvmmsg( + sockfd: ::c_int, + msgvec: *mut ::mmsghdr, + vlen: ::c_uint, + flags: ::c_int, + timeout: *const ::timespec, + ) -> ::c_int; + pub fn inotify_init() -> ::c_int; + pub fn inotify_init1(flags: ::c_int) -> ::c_int; + pub fn inotify_add_watch(fd: ::c_int, path: *const ::c_char, mask: u32) -> ::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 android_set_abort_message(msg: *const ::c_char); + + pub fn gettid() -> ::pid_t; + + /// Only available in API Version 28+ + 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 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+ + 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 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; + + pub fn memmem( + haystack: *const ::c_void, + haystacklen: ::size_t, + needle: *const ::c_void, + needlelen: ::size_t, + ) -> *mut ::c_void; + pub fn fread_unlocked( + buf: *mut ::c_void, + size: ::size_t, + nobj: ::size_t, + stream: *mut ::FILE, + ) -> ::size_t; + pub fn fwrite_unlocked( + buf: *const ::c_void, + size: ::size_t, + nobj: ::size_t, + stream: *mut ::FILE, + ) -> ::size_t; + pub fn fflush_unlocked(stream: *mut ::FILE) -> ::c_int; + pub fn fgets_unlocked(buf: *mut ::c_char, size: ::c_int, stream: *mut ::FILE) -> *mut ::c_char; + + pub fn klogctl(syslog_type: ::c_int, bufp: *mut ::c_char, len: ::c_int) -> ::c_int; +} + +cfg_if! { + if #[cfg(target_pointer_width = "32")] { + mod b32; + pub use self::b32::*; + } else if #[cfg(target_pointer_width = "64")] { + mod b64; + pub use self::b64::*; + } else { + // Unknown target_pointer_width + } +} + +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_timer { + _si_signo: ::c_int, + _si_errno: ::c_int, + _si_code: ::c_int, + _si_tid: ::c_int, + _si_overrun: ::c_int, + si_sigval: ::sigval, + } + (*(self as *const siginfo_t as *const siginfo_timer)).si_sigval + } +} + +cfg_if! { + if #[cfg(libc_union)] { + // Internal, for casts to access union fields + #[repr(C)] + struct sifields_sigchld { + si_pid: ::pid_t, + si_uid: ::uid_t, + si_status: ::c_int, + si_utime: ::c_long, + si_stime: ::c_long, + } + impl ::Copy for sifields_sigchld {} + impl ::Clone for sifields_sigchld { + fn clone(&self) -> sifields_sigchld { + *self + } + } + + // Internal, for casts to access union fields + #[repr(C)] + union sifields { + _align_pointer: *mut ::c_void, + sigchld: sifields_sigchld, + } + + // Internal, for casts to access union fields. Note that some variants + // of sifields start with a pointer, which makes the alignment of + // sifields vary on 32-bit and 64-bit architectures. + #[repr(C)] + struct siginfo_f { + _siginfo_base: [::c_int; 3], + sifields: sifields, + } + + impl siginfo_t { + unsafe fn sifields(&self) -> &sifields { + &(*(self as *const siginfo_t as *const siginfo_f)).sifields + } + + pub unsafe fn si_pid(&self) -> ::pid_t { + self.sifields().sigchld.si_pid + } + + pub unsafe fn si_uid(&self) -> ::uid_t { + self.sifields().sigchld.si_uid + } + + pub unsafe fn si_status(&self) -> ::c_int { + self.sifields().sigchld.si_status + } + + pub unsafe fn si_utime(&self) -> ::c_long { + self.sifields().sigchld.si_utime + } + + pub unsafe fn si_stime(&self) -> ::c_long { + self.sifields().sigchld.si_stime + } + } + } +} diff --git a/vendor/libc/src/unix/linux_like/emscripten/align.rs b/vendor/libc/src/unix/linux_like/emscripten/align.rs new file mode 100644 index 0000000..b9ea3f3 --- /dev/null +++ b/vendor/libc/src/unix/linux_like/emscripten/align.rs @@ -0,0 +1,74 @@ +macro_rules! expand_align { + () => { + s! { + #[allow(missing_debug_implementations)] + #[repr(align(4))] + pub struct pthread_mutex_t { + size: [u8; ::__SIZEOF_PTHREAD_MUTEX_T], + } + + #[repr(align(4))] + pub struct pthread_rwlock_t { + size: [u8; ::__SIZEOF_PTHREAD_RWLOCK_T], + } + + #[repr(align(4))] + pub struct pthread_mutexattr_t { + size: [u8; ::__SIZEOF_PTHREAD_MUTEXATTR_T], + } + + #[repr(align(4))] + pub struct pthread_rwlockattr_t { + size: [u8; ::__SIZEOF_PTHREAD_RWLOCKATTR_T], + } + + #[repr(align(4))] + pub struct pthread_condattr_t { + size: [u8; ::__SIZEOF_PTHREAD_CONDATTR_T], + } + } + + s_no_extra_traits! { + #[cfg_attr(target_pointer_width = "32", + repr(align(4)))] + #[cfg_attr(target_pointer_width = "64", + repr(align(8)))] + pub struct pthread_cond_t { + size: [u8; ::__SIZEOF_PTHREAD_COND_T], + } + + #[allow(missing_debug_implementations)] + #[repr(align(16))] + pub struct max_align_t { + priv_: [f64; 4] + } + + } + + cfg_if! { + if #[cfg(feature = "extra_traits")] { + impl PartialEq for pthread_cond_t { + fn eq(&self, other: &pthread_cond_t) -> bool { + self.size + .iter() + .zip(other.size.iter()) + .all(|(a,b)| a == b) + } + } + impl Eq for pthread_cond_t {} + impl ::fmt::Debug for pthread_cond_t { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("pthread_cond_t") + // FIXME: .field("size", &self.size) + .finish() + } + } + impl ::hash::Hash for pthread_cond_t { + fn hash(&self, state: &mut H) { + self.size.hash(state); + } + } + } + } + }; +} diff --git a/vendor/libc/src/unix/linux_like/emscripten/lfs64.rs b/vendor/libc/src/unix/linux_like/emscripten/lfs64.rs new file mode 100644 index 0000000..1616cc9 --- /dev/null +++ b/vendor/libc/src/unix/linux_like/emscripten/lfs64.rs @@ -0,0 +1,213 @@ +// In-sync with ../linux/musl/lfs64.rs except for fallocate64, prlimit64 and sendfile64 + +#[inline] +pub unsafe extern "C" fn creat64(path: *const ::c_char, mode: ::mode_t) -> ::c_int { + ::creat(path, mode) +} + +#[inline] +pub unsafe extern "C" fn fgetpos64(stream: *mut ::FILE, pos: *mut ::fpos64_t) -> ::c_int { + ::fgetpos(stream, pos as *mut _) +} + +#[inline] +pub unsafe extern "C" fn fopen64(pathname: *const ::c_char, mode: *const ::c_char) -> *mut ::FILE { + ::fopen(pathname, mode) +} + +#[inline] +pub unsafe extern "C" fn freopen64( + pathname: *const ::c_char, + mode: *const ::c_char, + stream: *mut ::FILE, +) -> *mut ::FILE { + ::freopen(pathname, mode, stream) +} + +#[inline] +pub unsafe extern "C" fn fseeko64( + stream: *mut ::FILE, + offset: ::off64_t, + whence: ::c_int, +) -> ::c_int { + ::fseeko(stream, offset, whence) +} + +#[inline] +pub unsafe extern "C" fn fsetpos64(stream: *mut ::FILE, pos: *const ::fpos64_t) -> ::c_int { + ::fsetpos(stream, pos as *mut _) +} + +#[inline] +pub unsafe extern "C" fn fstat64(fildes: ::c_int, buf: *mut ::stat64) -> ::c_int { + ::fstat(fildes, buf as *mut _) +} + +#[inline] +pub unsafe extern "C" fn fstatat64( + fd: ::c_int, + path: *const ::c_char, + buf: *mut ::stat64, + flag: ::c_int, +) -> ::c_int { + ::fstatat(fd, path, buf as *mut _, flag) +} + +#[inline] +pub unsafe extern "C" fn fstatfs64(fd: ::c_int, buf: *mut ::statfs64) -> ::c_int { + ::fstatfs(fd, buf as *mut _) +} + +#[inline] +pub unsafe extern "C" fn fstatvfs64(fd: ::c_int, buf: *mut ::statvfs64) -> ::c_int { + ::fstatvfs(fd, buf as *mut _) +} + +#[inline] +pub unsafe extern "C" fn ftello64(stream: *mut ::FILE) -> ::off64_t { + ::ftello(stream) +} + +#[inline] +pub unsafe extern "C" fn ftruncate64(fd: ::c_int, length: ::off64_t) -> ::c_int { + ::ftruncate(fd, length) +} + +#[inline] +pub unsafe extern "C" fn getrlimit64(resource: ::c_int, rlim: *mut ::rlimit64) -> ::c_int { + ::getrlimit(resource, rlim as *mut _) +} + +#[inline] +pub unsafe extern "C" fn lseek64(fd: ::c_int, offset: ::off64_t, whence: ::c_int) -> ::off64_t { + ::lseek(fd, offset, whence) +} + +#[inline] +pub unsafe extern "C" fn lstat64(path: *const ::c_char, buf: *mut ::stat64) -> ::c_int { + ::lstat(path, buf as *mut _) +} + +#[inline] +pub unsafe extern "C" fn mmap64( + addr: *mut ::c_void, + length: ::size_t, + prot: ::c_int, + flags: ::c_int, + fd: ::c_int, + offset: ::off64_t, +) -> *mut ::c_void { + ::mmap(addr, length, prot, flags, fd, offset) +} + +// These functions are variadic in the C ABI since the `mode` argument is "optional". Variadic +// `extern "C"` functions are unstable in Rust so we cannot write a shim function for these +// entrypoints. See https://github.com/rust-lang/rust/issues/44930. +// +// These aliases are mostly fine though, neither function takes a LFS64-namespaced type as an +// argument, nor do their names clash with any declared types. +pub use open as open64; +pub use openat as openat64; + +#[inline] +pub unsafe extern "C" fn posix_fadvise64( + fd: ::c_int, + offset: ::off64_t, + len: ::off64_t, + advice: ::c_int, +) -> ::c_int { + ::posix_fadvise(fd, offset, len, advice) +} + +#[inline] +pub unsafe extern "C" fn posix_fallocate64( + fd: ::c_int, + offset: ::off64_t, + len: ::off64_t, +) -> ::c_int { + ::posix_fallocate(fd, offset, len) +} + +#[inline] +pub unsafe extern "C" fn pread64( + fd: ::c_int, + buf: *mut ::c_void, + count: ::size_t, + offset: ::off64_t, +) -> ::ssize_t { + ::pread(fd, buf, count, offset) +} + +#[inline] +pub unsafe extern "C" fn preadv64( + fd: ::c_int, + iov: *const ::iovec, + iovcnt: ::c_int, + offset: ::off64_t, +) -> ::ssize_t { + ::preadv(fd, iov, iovcnt, offset) +} + +#[inline] +pub unsafe extern "C" fn pwrite64( + fd: ::c_int, + buf: *const ::c_void, + count: ::size_t, + offset: ::off64_t, +) -> ::ssize_t { + ::pwrite(fd, buf, count, offset) +} + +#[inline] +pub unsafe extern "C" fn pwritev64( + fd: ::c_int, + iov: *const ::iovec, + iovcnt: ::c_int, + offset: ::off64_t, +) -> ::ssize_t { + ::pwritev(fd, iov, iovcnt, offset) +} + +#[inline] +pub unsafe extern "C" fn readdir64(dirp: *mut ::DIR) -> *mut ::dirent64 { + ::readdir(dirp) as *mut _ +} + +#[inline] +pub unsafe extern "C" fn readdir64_r( + dirp: *mut ::DIR, + entry: *mut ::dirent64, + result: *mut *mut ::dirent64, +) -> ::c_int { + ::readdir_r(dirp, entry as *mut _, result as *mut _) +} + +#[inline] +pub unsafe extern "C" fn setrlimit64(resource: ::c_int, rlim: *const ::rlimit64) -> ::c_int { + ::setrlimit(resource, rlim as *mut _) +} + +#[inline] +pub unsafe extern "C" fn stat64(pathname: *const ::c_char, statbuf: *mut ::stat64) -> ::c_int { + ::stat(pathname, statbuf as *mut _) +} + +#[inline] +pub unsafe extern "C" fn statfs64(pathname: *const ::c_char, buf: *mut ::statfs64) -> ::c_int { + ::statfs(pathname, buf as *mut _) +} + +#[inline] +pub unsafe extern "C" fn statvfs64(path: *const ::c_char, buf: *mut ::statvfs64) -> ::c_int { + ::statvfs(path, buf as *mut _) +} + +#[inline] +pub unsafe extern "C" fn tmpfile64() -> *mut ::FILE { + ::tmpfile() +} + +#[inline] +pub unsafe extern "C" fn truncate64(path: *const ::c_char, length: ::off64_t) -> ::c_int { + ::truncate(path, length) +} diff --git a/vendor/libc/src/unix/linux_like/emscripten/mod.rs b/vendor/libc/src/unix/linux_like/emscripten/mod.rs new file mode 100644 index 0000000..2f515f3 --- /dev/null +++ b/vendor/libc/src/unix/linux_like/emscripten/mod.rs @@ -0,0 +1,1829 @@ +pub type c_char = i8; +pub type wchar_t = i32; +pub type useconds_t = u32; +pub type dev_t = u32; +pub type socklen_t = u32; +pub type pthread_t = c_ulong; +pub type mode_t = u32; +pub type shmatt_t = ::c_ulong; +pub type mqd_t = ::c_int; +pub type msgqnum_t = ::c_ulong; +pub type msglen_t = ::c_ulong; +pub type nfds_t = ::c_ulong; +pub type nl_item = ::c_int; +pub type idtype_t = ::c_uint; +pub type loff_t = i64; +pub type pthread_key_t = ::c_uint; + +pub type clock_t = c_long; +pub type time_t = c_long; +pub type suseconds_t = c_long; +pub type ino_t = u64; +pub type off_t = i64; +pub type blkcnt_t = i32; + +pub type blksize_t = c_long; +pub type fsblkcnt_t = u32; +pub type fsfilcnt_t = u32; +pub type rlim_t = u64; +pub type c_long = i32; +pub type c_ulong = u32; +pub type nlink_t = u32; + +pub type ino64_t = ::ino_t; +pub type off64_t = ::off_t; +pub type blkcnt64_t = ::blkcnt_t; +pub type rlim64_t = ::rlim_t; + +pub type rlimit64 = ::rlimit; +pub type flock64 = ::flock; +pub type stat64 = ::stat; +pub type statfs64 = ::statfs; +pub type statvfs64 = ::statvfs; +pub type dirent64 = ::dirent; + +#[cfg_attr(feature = "extra_traits", derive(Debug))] +pub enum fpos64_t {} // FIXME: fill this out with a struct +impl ::Copy for fpos64_t {} +impl ::Clone for fpos64_t { + fn clone(&self) -> fpos64_t { + *self + } +} + +s! { + pub struct glob_t { + pub gl_pathc: ::size_t, + pub gl_pathv: *mut *mut c_char, + pub gl_offs: ::size_t, + pub gl_flags: ::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_gecos: *mut ::c_char, + pub pw_dir: *mut ::c_char, + pub pw_shell: *mut ::c_char, + } + + pub struct spwd { + pub sp_namp: *mut ::c_char, + pub sp_pwdp: *mut ::c_char, + pub sp_lstchg: ::c_long, + pub sp_min: ::c_long, + pub sp_max: ::c_long, + pub sp_warn: ::c_long, + pub sp_inact: ::c_long, + pub sp_expire: ::c_long, + pub sp_flag: ::c_ulong, + } + + 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, + __f_unused: ::c_int, + pub f_flag: ::c_ulong, + pub f_namemax: ::c_ulong, + __f_spare: [::c_int; 6], + } + + pub struct dqblk { + pub dqb_bhardlimit: u64, + pub dqb_bsoftlimit: u64, + pub dqb_curspace: u64, + pub dqb_ihardlimit: u64, + pub dqb_isoftlimit: u64, + pub dqb_curinodes: u64, + pub dqb_btime: u64, + pub dqb_itime: u64, + pub dqb_valid: u32, + } + + pub struct signalfd_siginfo { + pub ssi_signo: u32, + pub ssi_errno: i32, + pub ssi_code: i32, + pub ssi_pid: u32, + pub ssi_uid: u32, + pub ssi_fd: i32, + pub ssi_tid: u32, + pub ssi_band: u32, + pub ssi_overrun: u32, + pub ssi_trapno: u32, + pub ssi_status: i32, + pub ssi_int: i32, + pub ssi_ptr: u64, + pub ssi_utime: u64, + pub ssi_stime: u64, + pub ssi_addr: u64, + pub ssi_addr_lsb: u16, + _pad2: u16, + pub ssi_syscall: i32, + pub ssi_call_addr: u64, + pub ssi_arch: u32, + _pad: [u8; 28], + } + + pub struct fsid_t { + __val: [::c_int; 2], + } + + pub struct cpu_set_t { + bits: [u32; 32], + } + + pub struct if_nameindex { + pub if_index: ::c_uint, + pub if_name: *mut ::c_char, + } + + // System V IPC + pub struct msginfo { + pub msgpool: ::c_int, + pub msgmap: ::c_int, + pub msgmax: ::c_int, + pub msgmnb: ::c_int, + pub msgmni: ::c_int, + pub msgssz: ::c_int, + pub msgtql: ::c_int, + pub msgseg: ::c_ushort, + } + + pub struct sembuf { + pub sem_num: ::c_ushort, + pub sem_op: ::c_short, + pub sem_flg: ::c_short, + } + + pub struct aiocb { + pub aio_fildes: ::c_int, + pub aio_lio_opcode: ::c_int, + pub aio_reqprio: ::c_int, + pub aio_buf: *mut ::c_void, + pub aio_nbytes: ::size_t, + pub aio_sigevent: ::sigevent, + __td: *mut ::c_void, + __lock: [::c_int; 2], + __err: ::c_int, + __ret: ::ssize_t, + pub aio_offset: off_t, + __next: *mut ::c_void, + __prev: *mut ::c_void, + __dummy4: [::c_char; 24], + } + + 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 __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_int, + __unused1: ::c_long, + __unused2: ::c_long + } + + pub struct termios { + pub c_iflag: ::tcflag_t, + pub c_oflag: ::tcflag_t, + pub c_cflag: ::tcflag_t, + pub c_lflag: ::tcflag_t, + pub c_line: ::cc_t, + pub c_cc: [::cc_t; ::NCCS], + pub __c_ispeed: ::speed_t, + pub __c_ospeed: ::speed_t, + } + + pub struct 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 pthread_attr_t { + __size: [u32; 11] + } + + pub struct sigset_t { + __val: [::c_ulong; 32], + } + + 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 sem_t { + __val: [::c_int; 4], + } + pub struct stat { + pub st_dev: ::dev_t, + #[cfg(not(emscripten_new_stat_abi))] + __st_dev_padding: ::c_int, + #[cfg(not(emscripten_new_stat_abi))] + __st_ino_truncated: ::c_long, + 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, + #[cfg(not(emscripten_new_stat_abi))] + __st_rdev_padding: ::c_int, + 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, + pub st_ino: ::ino_t, + } + + pub struct stack_t { + pub ss_sp: *mut ::c_void, + pub ss_flags: ::c_int, + pub ss_size: ::size_t + } + + pub struct shmid_ds { + pub shm_perm: ::ipc_perm, + pub shm_segsz: ::size_t, + pub shm_atime: ::time_t, + __unused1: ::c_int, + pub shm_dtime: ::time_t, + __unused2: ::c_int, + pub shm_ctime: ::time_t, + __unused3: ::c_int, + pub shm_cpid: ::pid_t, + pub shm_lpid: ::pid_t, + pub shm_nattch: ::c_ulong, + __pad1: ::c_ulong, + __pad2: ::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 statfs { + 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 siginfo_t { + pub si_signo: ::c_int, + pub si_errno: ::c_int, + pub si_code: ::c_int, + pub _pad: [::c_int; 29], + _align: [usize; 0], + } + + pub struct arpd_request { + pub req: ::c_ushort, + pub ip: u32, + pub dev: ::c_ulong, + pub stamp: ::c_ulong, + pub updated: ::c_ulong, + pub ha: [::c_uchar; ::MAX_ADDR_LEN], + } +} + +s_no_extra_traits! { + pub struct dirent { + pub d_ino: ::ino_t, + pub d_off: ::off_t, + pub d_reclen: ::c_ushort, + pub d_type: ::c_uchar, + pub d_name: [::c_char; 256], + } + + pub struct sysinfo { + pub uptime: ::c_ulong, + pub loads: [::c_ulong; 3], + pub totalram: ::c_ulong, + pub freeram: ::c_ulong, + pub sharedram: ::c_ulong, + pub bufferram: ::c_ulong, + pub totalswap: ::c_ulong, + pub freeswap: ::c_ulong, + pub procs: ::c_ushort, + pub pad: ::c_ushort, + pub totalhigh: ::c_ulong, + pub freehigh: ::c_ulong, + pub mem_unit: ::c_uint, + pub __reserved: [::c_char; 256], + } + + pub struct mq_attr { + pub mq_flags: ::c_long, + pub mq_maxmsg: ::c_long, + pub mq_msgsize: ::c_long, + pub mq_curmsgs: ::c_long, + pad: [::c_long; 4] + } +} + +cfg_if! { + if #[cfg(feature = "extra_traits")] { + impl PartialEq for dirent { + fn eq(&self, other: &dirent) -> bool { + self.d_ino == other.d_ino + && self.d_off == other.d_off + && self.d_reclen == other.d_reclen + && self.d_type == other.d_type + && self + .d_name + .iter() + .zip(other.d_name.iter()) + .all(|(a,b)| a == b) + } + } + impl Eq for dirent {} + impl ::fmt::Debug for dirent { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("dirent") + .field("d_ino", &self.d_ino) + .field("d_off", &self.d_off) + .field("d_reclen", &self.d_reclen) + .field("d_type", &self.d_type) + // FIXME: .field("d_name", &self.d_name) + .finish() + } + } + impl ::hash::Hash for dirent { + fn hash(&self, state: &mut H) { + self.d_ino.hash(state); + self.d_off.hash(state); + self.d_reclen.hash(state); + self.d_type.hash(state); + self.d_name.hash(state); + } + } + + impl PartialEq for sysinfo { + fn eq(&self, other: &sysinfo) -> bool { + self.uptime == other.uptime + && self.loads == other.loads + && self.totalram == other.totalram + && self.freeram == other.freeram + && self.sharedram == other.sharedram + && self.bufferram == other.bufferram + && self.totalswap == other.totalswap + && self.freeswap == other.freeswap + && self.procs == other.procs + && self.pad == other.pad + && self.totalhigh == other.totalhigh + && self.freehigh == other.freehigh + && self.mem_unit == other.mem_unit + && self + .__reserved + .iter() + .zip(other.__reserved.iter()) + .all(|(a,b)| a == b) + } + } + impl Eq for sysinfo {} + impl ::fmt::Debug for sysinfo { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("sysinfo") + .field("uptime", &self.uptime) + .field("loads", &self.loads) + .field("totalram", &self.totalram) + .field("freeram", &self.freeram) + .field("sharedram", &self.sharedram) + .field("bufferram", &self.bufferram) + .field("totalswap", &self.totalswap) + .field("freeswap", &self.freeswap) + .field("procs", &self.procs) + .field("pad", &self.pad) + .field("totalhigh", &self.totalhigh) + .field("freehigh", &self.freehigh) + .field("mem_unit", &self.mem_unit) + // FIXME: .field("__reserved", &self.__reserved) + .finish() + } + } + impl ::hash::Hash for sysinfo { + fn hash(&self, state: &mut H) { + self.uptime.hash(state); + self.loads.hash(state); + self.totalram.hash(state); + self.freeram.hash(state); + self.sharedram.hash(state); + self.bufferram.hash(state); + self.totalswap.hash(state); + self.freeswap.hash(state); + self.procs.hash(state); + self.pad.hash(state); + self.totalhigh.hash(state); + self.freehigh.hash(state); + self.mem_unit.hash(state); + self.__reserved.hash(state); + } + } + + impl PartialEq for 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); + } + } + } +} + +pub const MADV_SOFT_OFFLINE: ::c_int = 101; +pub const MS_NOUSER: ::c_ulong = 0x80000000; +pub const MS_RMT_MASK: ::c_ulong = 0x02800051; + +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 RUSAGE_THREAD: ::c_int = 1; +pub const RUSAGE_CHILDREN: ::c_int = -1; + +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; + +pub const FILENAME_MAX: ::c_uint = 4096; +pub const L_tmpnam: ::c_uint = 20; +pub const _PC_LINK_MAX: ::c_int = 0; +pub const _PC_MAX_CANON: ::c_int = 1; +pub const _PC_MAX_INPUT: ::c_int = 2; +pub const _PC_NAME_MAX: ::c_int = 3; +pub const _PC_PATH_MAX: ::c_int = 4; +pub const _PC_PIPE_BUF: ::c_int = 5; +pub const _PC_CHOWN_RESTRICTED: ::c_int = 6; +pub const _PC_NO_TRUNC: ::c_int = 7; +pub const _PC_VDISABLE: ::c_int = 8; +pub const _PC_SYNC_IO: ::c_int = 9; +pub const _PC_ASYNC_IO: ::c_int = 10; +pub const _PC_PRIO_IO: ::c_int = 11; +pub const _PC_SOCK_MAXBUF: ::c_int = 12; +pub const _PC_FILESIZEBITS: ::c_int = 13; +pub const _PC_REC_INCR_XFER_SIZE: ::c_int = 14; +pub const _PC_REC_MAX_XFER_SIZE: ::c_int = 15; +pub const _PC_REC_MIN_XFER_SIZE: ::c_int = 16; +pub const _PC_REC_XFER_ALIGN: ::c_int = 17; +pub const _PC_ALLOC_SIZE_MIN: ::c_int = 18; +pub const _PC_SYMLINK_MAX: ::c_int = 19; +pub const _PC_2_SYMLINKS: ::c_int = 20; + +pub const _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_STREAM_MAX: ::c_int = 5; +pub const _SC_TZNAME_MAX: ::c_int = 6; +pub const _SC_JOB_CONTROL: ::c_int = 7; +pub const _SC_SAVED_IDS: ::c_int = 8; +pub const _SC_REALTIME_SIGNALS: ::c_int = 9; +pub const _SC_PRIORITY_SCHEDULING: ::c_int = 10; +pub const _SC_TIMERS: ::c_int = 11; +pub const _SC_ASYNCHRONOUS_IO: ::c_int = 12; +pub const _SC_PRIORITIZED_IO: ::c_int = 13; +pub const _SC_SYNCHRONIZED_IO: ::c_int = 14; +pub const _SC_FSYNC: ::c_int = 15; +pub const _SC_MAPPED_FILES: ::c_int = 16; +pub const _SC_MEMLOCK: ::c_int = 17; +pub const _SC_MEMLOCK_RANGE: ::c_int = 18; +pub const _SC_MEMORY_PROTECTION: ::c_int = 19; +pub const _SC_MESSAGE_PASSING: ::c_int = 20; +pub const _SC_SEMAPHORES: ::c_int = 21; +pub const _SC_SHARED_MEMORY_OBJECTS: ::c_int = 22; +pub const _SC_AIO_LISTIO_MAX: ::c_int = 23; +pub const _SC_AIO_MAX: ::c_int = 24; +pub const _SC_AIO_PRIO_DELTA_MAX: ::c_int = 25; +pub const _SC_DELAYTIMER_MAX: ::c_int = 26; +pub const _SC_MQ_OPEN_MAX: ::c_int = 27; +pub const _SC_MQ_PRIO_MAX: ::c_int = 28; +pub const _SC_VERSION: ::c_int = 29; +pub const _SC_PAGESIZE: ::c_int = 30; +pub const _SC_PAGE_SIZE: ::c_int = _SC_PAGESIZE; +pub const _SC_RTSIG_MAX: ::c_int = 31; +pub const _SC_SEM_NSEMS_MAX: ::c_int = 32; +pub const _SC_SEM_VALUE_MAX: ::c_int = 33; +pub const _SC_SIGQUEUE_MAX: ::c_int = 34; +pub const _SC_TIMER_MAX: ::c_int = 35; +pub const _SC_BC_BASE_MAX: ::c_int = 36; +pub const _SC_BC_DIM_MAX: ::c_int = 37; +pub const _SC_BC_SCALE_MAX: ::c_int = 38; +pub const _SC_BC_STRING_MAX: ::c_int = 39; +pub const _SC_COLL_WEIGHTS_MAX: ::c_int = 40; +pub const _SC_EXPR_NEST_MAX: ::c_int = 42; +pub const _SC_LINE_MAX: ::c_int = 43; +pub const _SC_RE_DUP_MAX: ::c_int = 44; +pub const _SC_2_VERSION: ::c_int = 46; +pub const _SC_2_C_BIND: ::c_int = 47; +pub const _SC_2_C_DEV: ::c_int = 48; +pub const _SC_2_FORT_DEV: ::c_int = 49; +pub const _SC_2_FORT_RUN: ::c_int = 50; +pub const _SC_2_SW_DEV: ::c_int = 51; +pub const _SC_2_LOCALEDEF: ::c_int = 52; +pub const _SC_UIO_MAXIOV: ::c_int = 60; +pub const _SC_IOV_MAX: ::c_int = 60; +pub const _SC_THREADS: ::c_int = 67; +pub const _SC_THREAD_SAFE_FUNCTIONS: ::c_int = 68; +pub const _SC_GETGR_R_SIZE_MAX: ::c_int = 69; +pub const _SC_GETPW_R_SIZE_MAX: ::c_int = 70; +pub const _SC_LOGIN_NAME_MAX: ::c_int = 71; +pub const _SC_TTY_NAME_MAX: ::c_int = 72; +pub const _SC_THREAD_DESTRUCTOR_ITERATIONS: ::c_int = 73; +pub const _SC_THREAD_KEYS_MAX: ::c_int = 74; +pub const _SC_THREAD_STACK_MIN: ::c_int = 75; +pub const _SC_THREAD_THREADS_MAX: ::c_int = 76; +pub const _SC_THREAD_ATTR_STACKADDR: ::c_int = 77; +pub const _SC_THREAD_ATTR_STACKSIZE: ::c_int = 78; +pub const _SC_THREAD_PRIORITY_SCHEDULING: ::c_int = 79; +pub const _SC_THREAD_PRIO_INHERIT: ::c_int = 80; +pub const _SC_THREAD_PRIO_PROTECT: ::c_int = 81; +pub const _SC_THREAD_PROCESS_SHARED: ::c_int = 82; +pub const _SC_NPROCESSORS_CONF: ::c_int = 83; +pub const _SC_NPROCESSORS_ONLN: ::c_int = 84; +pub const _SC_PHYS_PAGES: ::c_int = 85; +pub const _SC_AVPHYS_PAGES: ::c_int = 86; +pub const _SC_ATEXIT_MAX: ::c_int = 87; +pub const _SC_PASS_MAX: ::c_int = 88; +pub const _SC_XOPEN_VERSION: ::c_int = 89; +pub const _SC_XOPEN_XCU_VERSION: ::c_int = 90; +pub const _SC_XOPEN_UNIX: ::c_int = 91; +pub const _SC_XOPEN_CRYPT: ::c_int = 92; +pub const _SC_XOPEN_ENH_I18N: ::c_int = 93; +pub const _SC_XOPEN_SHM: ::c_int = 94; +pub const _SC_2_CHAR_TERM: ::c_int = 95; +pub const _SC_2_UPE: ::c_int = 97; +pub const _SC_XOPEN_XPG2: ::c_int = 98; +pub const _SC_XOPEN_XPG3: ::c_int = 99; +pub const _SC_XOPEN_XPG4: ::c_int = 100; +pub const _SC_NZERO: ::c_int = 109; +pub const _SC_XBS5_ILP32_OFF32: ::c_int = 125; +pub const _SC_XBS5_ILP32_OFFBIG: ::c_int = 126; +pub const _SC_XBS5_LP64_OFF64: ::c_int = 127; +pub const _SC_XBS5_LPBIG_OFFBIG: ::c_int = 128; +pub const _SC_XOPEN_LEGACY: ::c_int = 129; +pub const _SC_XOPEN_REALTIME: ::c_int = 130; +pub const _SC_XOPEN_REALTIME_THREADS: ::c_int = 131; +pub const _SC_ADVISORY_INFO: ::c_int = 132; +pub const _SC_BARRIERS: ::c_int = 133; +pub const _SC_CLOCK_SELECTION: ::c_int = 137; +pub const _SC_CPUTIME: ::c_int = 138; +pub const _SC_THREAD_CPUTIME: ::c_int = 139; +pub const _SC_MONOTONIC_CLOCK: ::c_int = 149; +pub const _SC_READER_WRITER_LOCKS: ::c_int = 153; +pub const _SC_SPIN_LOCKS: ::c_int = 154; +pub const _SC_REGEXP: ::c_int = 155; +pub const _SC_SHELL: ::c_int = 157; +pub const _SC_SPAWN: ::c_int = 159; +pub const _SC_SPORADIC_SERVER: ::c_int = 160; +pub const _SC_THREAD_SPORADIC_SERVER: ::c_int = 161; +pub const _SC_TIMEOUTS: ::c_int = 164; +pub const _SC_TYPED_MEMORY_OBJECTS: ::c_int = 165; +pub const _SC_2_PBS: ::c_int = 168; +pub const _SC_2_PBS_ACCOUNTING: ::c_int = 169; +pub const _SC_2_PBS_LOCATE: ::c_int = 170; +pub const _SC_2_PBS_MESSAGE: ::c_int = 171; +pub const _SC_2_PBS_TRACK: ::c_int = 172; +pub const _SC_SYMLOOP_MAX: ::c_int = 173; +pub const _SC_STREAMS: ::c_int = 174; +pub const _SC_2_PBS_CHECKPOINT: ::c_int = 175; +pub const _SC_V6_ILP32_OFF32: ::c_int = 176; +pub const _SC_V6_ILP32_OFFBIG: ::c_int = 177; +pub const _SC_V6_LP64_OFF64: ::c_int = 178; +pub const _SC_V6_LPBIG_OFFBIG: ::c_int = 179; +pub const _SC_HOST_NAME_MAX: ::c_int = 180; +pub const _SC_TRACE: ::c_int = 181; +pub const _SC_TRACE_EVENT_FILTER: ::c_int = 182; +pub const _SC_TRACE_INHERIT: ::c_int = 183; +pub const _SC_TRACE_LOG: ::c_int = 184; +pub const _SC_IPV6: ::c_int = 235; +pub const _SC_RAW_SOCKETS: ::c_int = 236; +pub const _SC_V7_ILP32_OFF32: ::c_int = 237; +pub const _SC_V7_ILP32_OFFBIG: ::c_int = 238; +pub const _SC_V7_LP64_OFF64: ::c_int = 239; +pub const _SC_V7_LPBIG_OFFBIG: ::c_int = 240; +pub const _SC_SS_REPL_MAX: ::c_int = 241; +pub const _SC_TRACE_EVENT_NAME_MAX: ::c_int = 242; +pub const _SC_TRACE_NAME_MAX: ::c_int = 243; +pub const _SC_TRACE_SYS_MAX: ::c_int = 244; +pub const _SC_TRACE_USER_EVENT_MAX: ::c_int = 245; +pub const _SC_XOPEN_STREAMS: ::c_int = 246; +pub const _SC_THREAD_ROBUST_PRIO_INHERIT: ::c_int = 247; +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; + +pub const GLOB_ERR: ::c_int = 1 << 0; +pub const GLOB_MARK: ::c_int = 1 << 1; +pub const GLOB_NOSORT: ::c_int = 1 << 2; +pub const GLOB_DOOFFS: ::c_int = 1 << 3; +pub const GLOB_NOCHECK: ::c_int = 1 << 4; +pub const GLOB_APPEND: ::c_int = 1 << 5; +pub const GLOB_NOESCAPE: ::c_int = 1 << 6; + +pub const GLOB_NOSPACE: ::c_int = 1; +pub const GLOB_ABORTED: ::c_int = 2; +pub const GLOB_NOMATCH: ::c_int = 3; + +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 AT_EACCESS: ::c_int = 0x200; + +pub const S_IEXEC: mode_t = 64; +pub const S_IWRITE: mode_t = 128; +pub const S_IREAD: mode_t = 256; + +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 = 1; +pub const ST_NOSUID: ::c_ulong = 2; +pub const ST_NODEV: ::c_ulong = 4; +pub const ST_NOEXEC: ::c_ulong = 8; +pub const ST_SYNCHRONOUS: ::c_ulong = 16; +pub const ST_MANDLOCK: ::c_ulong = 64; +pub const ST_WRITE: ::c_ulong = 128; +pub const ST_APPEND: ::c_ulong = 256; +pub const ST_IMMUTABLE: ::c_ulong = 512; +pub const ST_NOATIME: ::c_ulong = 1024; +pub const ST_NODIRATIME: ::c_ulong = 2048; + +pub const RTLD_NEXT: *mut ::c_void = -1i64 as *mut ::c_void; +pub const RTLD_DEFAULT: *mut ::c_void = 0i64 as *mut ::c_void; +pub const RTLD_NODELETE: ::c_int = 0x1000; +pub const RTLD_NOW: ::c_int = 0x2; + +align_const! { + pub const PTHREAD_MUTEX_INITIALIZER: pthread_mutex_t = pthread_mutex_t { + size: [0; __SIZEOF_PTHREAD_MUTEX_T], + }; + pub const PTHREAD_COND_INITIALIZER: pthread_cond_t = pthread_cond_t { + size: [0; __SIZEOF_PTHREAD_COND_T], + }; + pub const PTHREAD_RWLOCK_INITIALIZER: pthread_rwlock_t = pthread_rwlock_t { + size: [0; __SIZEOF_PTHREAD_RWLOCK_T], + }; +} + +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_PROCESS_PRIVATE: ::c_int = 0; +pub const PTHREAD_PROCESS_SHARED: ::c_int = 1; +pub const __SIZEOF_PTHREAD_COND_T: usize = 48; + +pub const SCHED_OTHER: ::c_int = 0; +pub const SCHED_FIFO: ::c_int = 1; +pub const SCHED_RR: ::c_int = 2; +pub const SCHED_BATCH: ::c_int = 3; +pub const SCHED_IDLE: ::c_int = 5; + +pub const AF_IB: ::c_int = 27; +pub const AF_MPLS: ::c_int = 28; +pub const AF_NFC: ::c_int = 39; +pub const AF_VSOCK: ::c_int = 40; +pub const PF_IB: ::c_int = AF_IB; +pub const PF_MPLS: ::c_int = AF_MPLS; +pub const PF_NFC: ::c_int = AF_NFC; +pub const PF_VSOCK: ::c_int = AF_VSOCK; + +// 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 MSG_STAT: ::c_int = 11; +pub const MSG_INFO: ::c_int = 12; + +pub const MSG_NOERROR: ::c_int = 0o10000; +pub const MSG_EXCEPT: ::c_int = 0o20000; + +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_REMAP: ::c_int = 0o40000; +pub const SHM_EXEC: ::c_int = 0o100000; + +pub const SHM_LOCK: ::c_int = 11; +pub const SHM_UNLOCK: ::c_int = 12; + +pub const SHM_HUGETLB: ::c_int = 0o4000; +pub const SHM_NORESERVE: ::c_int = 0o10000; + +pub const QFMT_VFS_OLD: ::c_int = 1; +pub const QFMT_VFS_V0: ::c_int = 2; + +pub const EFD_SEMAPHORE: ::c_int = 0x1; + +pub const LOG_NFACILITIES: ::c_int = 24; + +pub const SEM_FAILED: *mut ::sem_t = 0 as *mut sem_t; + +pub const RB_AUTOBOOT: ::c_int = 0x01234567u32 as i32; +pub const RB_HALT_SYSTEM: ::c_int = 0xcdef0123u32 as i32; +pub const RB_ENABLE_CAD: ::c_int = 0x89abcdefu32 as i32; +pub const RB_DISABLE_CAD: ::c_int = 0x00000000u32 as i32; +pub const RB_POWER_OFF: ::c_int = 0x4321fedcu32 as i32; +pub const RB_SW_SUSPEND: ::c_int = 0xd000fce2u32 as i32; +pub const RB_KEXEC: ::c_int = 0x45584543u32 as i32; + +pub const AI_PASSIVE: ::c_int = 0x0001; +pub const AI_CANONNAME: ::c_int = 0x0002; +pub const AI_NUMERICHOST: ::c_int = 0x0004; +pub const AI_V4MAPPED: ::c_int = 0x0008; +pub const AI_ALL: ::c_int = 0x0010; +pub const AI_ADDRCONFIG: ::c_int = 0x0020; + +pub const AI_NUMERICSERV: ::c_int = 0x0400; + +pub const EAI_BADFLAGS: ::c_int = -1; +pub const EAI_NONAME: ::c_int = -2; +pub const EAI_AGAIN: ::c_int = -3; +pub const EAI_FAIL: ::c_int = -4; +pub const EAI_FAMILY: ::c_int = -6; +pub const EAI_SOCKTYPE: ::c_int = -7; +pub const EAI_SERVICE: ::c_int = -8; +pub const EAI_MEMORY: ::c_int = -10; +pub const EAI_OVERFLOW: ::c_int = -12; + +pub const NI_NUMERICHOST: ::c_int = 1; +pub const NI_NUMERICSERV: ::c_int = 2; +pub const NI_NOFQDN: ::c_int = 4; +pub const NI_NAMEREQD: ::c_int = 8; +pub const NI_DGRAM: ::c_int = 16; + +pub const SYNC_FILE_RANGE_WAIT_BEFORE: ::c_uint = 1; +pub const SYNC_FILE_RANGE_WRITE: ::c_uint = 2; +pub const SYNC_FILE_RANGE_WAIT_AFTER: ::c_uint = 4; + +pub const EAI_SYSTEM: ::c_int = -11; + +pub const AIO_CANCELED: ::c_int = 0; +pub const AIO_NOTCANCELED: ::c_int = 1; +pub const AIO_ALLDONE: ::c_int = 2; +pub const LIO_READ: ::c_int = 0; +pub const LIO_WRITE: ::c_int = 1; +pub const LIO_NOP: ::c_int = 2; +pub const LIO_WAIT: ::c_int = 0; +pub const LIO_NOWAIT: ::c_int = 1; + +pub const MREMAP_MAYMOVE: ::c_int = 1; +pub const MREMAP_FIXED: ::c_int = 2; + +pub const PR_SET_PDEATHSIG: ::c_int = 1; +pub const PR_GET_PDEATHSIG: ::c_int = 2; + +pub const PR_GET_DUMPABLE: ::c_int = 3; +pub const PR_SET_DUMPABLE: ::c_int = 4; + +pub const PR_GET_UNALIGN: ::c_int = 5; +pub const PR_SET_UNALIGN: ::c_int = 6; +pub const PR_UNALIGN_NOPRINT: ::c_int = 1; +pub const PR_UNALIGN_SIGBUS: ::c_int = 2; + +pub const PR_GET_KEEPCAPS: ::c_int = 7; +pub const PR_SET_KEEPCAPS: ::c_int = 8; + +pub const PR_GET_FPEMU: ::c_int = 9; +pub const PR_SET_FPEMU: ::c_int = 10; +pub const PR_FPEMU_NOPRINT: ::c_int = 1; +pub const PR_FPEMU_SIGFPE: ::c_int = 2; + +pub const PR_GET_FPEXC: ::c_int = 11; +pub const PR_SET_FPEXC: ::c_int = 12; +pub const PR_FP_EXC_SW_ENABLE: ::c_int = 0x80; +pub const PR_FP_EXC_DIV: ::c_int = 0x010000; +pub const PR_FP_EXC_OVF: ::c_int = 0x020000; +pub const PR_FP_EXC_UND: ::c_int = 0x040000; +pub const PR_FP_EXC_RES: ::c_int = 0x080000; +pub const PR_FP_EXC_INV: ::c_int = 0x100000; +pub const PR_FP_EXC_DISABLED: ::c_int = 0; +pub const PR_FP_EXC_NONRECOV: ::c_int = 1; +pub const PR_FP_EXC_ASYNC: ::c_int = 2; +pub const PR_FP_EXC_PRECISE: ::c_int = 3; + +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; + +pub const PR_SET_NAME: ::c_int = 15; +pub const PR_GET_NAME: ::c_int = 16; + +pub const PR_GET_ENDIAN: ::c_int = 19; +pub const PR_SET_ENDIAN: ::c_int = 20; +pub const PR_ENDIAN_BIG: ::c_int = 0; +pub const PR_ENDIAN_LITTLE: ::c_int = 1; +pub const PR_ENDIAN_PPC_LITTLE: ::c_int = 2; + +pub const PR_GET_SECCOMP: ::c_int = 21; +pub const PR_SET_SECCOMP: ::c_int = 22; + +pub const PR_CAPBSET_READ: ::c_int = 23; +pub const PR_CAPBSET_DROP: ::c_int = 24; + +pub const PR_GET_TSC: ::c_int = 25; +pub const PR_SET_TSC: ::c_int = 26; +pub const PR_TSC_ENABLE: ::c_int = 1; +pub const PR_TSC_SIGSEGV: ::c_int = 2; + +pub const PR_GET_SECUREBITS: ::c_int = 27; +pub const PR_SET_SECUREBITS: ::c_int = 28; + +pub const PR_SET_TIMERSLACK: ::c_int = 29; +pub const PR_GET_TIMERSLACK: ::c_int = 30; + +pub const PR_TASK_PERF_EVENTS_DISABLE: ::c_int = 31; +pub const PR_TASK_PERF_EVENTS_ENABLE: ::c_int = 32; + +pub const PR_MCE_KILL: ::c_int = 33; +pub const PR_MCE_KILL_CLEAR: ::c_int = 0; +pub const PR_MCE_KILL_SET: ::c_int = 1; + +pub const PR_MCE_KILL_LATE: ::c_int = 0; +pub const PR_MCE_KILL_EARLY: ::c_int = 1; +pub const PR_MCE_KILL_DEFAULT: ::c_int = 2; + +pub const PR_MCE_KILL_GET: ::c_int = 34; + +pub const PR_SET_MM: ::c_int = 35; +pub const PR_SET_MM_START_CODE: ::c_int = 1; +pub const PR_SET_MM_END_CODE: ::c_int = 2; +pub const PR_SET_MM_START_DATA: ::c_int = 3; +pub const PR_SET_MM_END_DATA: ::c_int = 4; +pub const PR_SET_MM_START_STACK: ::c_int = 5; +pub const PR_SET_MM_START_BRK: ::c_int = 6; +pub const PR_SET_MM_BRK: ::c_int = 7; +pub const PR_SET_MM_ARG_START: ::c_int = 8; +pub const PR_SET_MM_ARG_END: ::c_int = 9; +pub const PR_SET_MM_ENV_START: ::c_int = 10; +pub const PR_SET_MM_ENV_END: ::c_int = 11; +pub const PR_SET_MM_AUXV: ::c_int = 12; +pub const PR_SET_MM_EXE_FILE: ::c_int = 13; +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; + +pub const PR_SET_NO_NEW_PRIVS: ::c_int = 38; +pub const PR_GET_NO_NEW_PRIVS: ::c_int = 39; + +pub const PR_GET_TID_ADDRESS: ::c_int = 40; + +pub const PR_SET_THP_DISABLE: ::c_int = 41; +pub const PR_GET_THP_DISABLE: ::c_int = 42; + +pub const PR_MPX_ENABLE_MANAGEMENT: ::c_int = 43; +pub const PR_MPX_DISABLE_MANAGEMENT: ::c_int = 44; + +pub const PR_SET_FP_MODE: ::c_int = 45; +pub const PR_GET_FP_MODE: ::c_int = 46; +pub const PR_FP_MODE_FR: ::c_int = 1 << 0; +pub const PR_FP_MODE_FRE: ::c_int = 1 << 1; + +pub const PR_CAP_AMBIENT: ::c_int = 47; +pub const PR_CAP_AMBIENT_IS_SET: ::c_int = 1; +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 ITIMER_REAL: ::c_int = 0; +pub const ITIMER_VIRTUAL: ::c_int = 1; +pub const ITIMER_PROF: ::c_int = 2; + +pub const _POSIX_VDISABLE: ::cc_t = 0; + +pub const FALLOC_FL_KEEP_SIZE: ::c_int = 0x01; +pub const FALLOC_FL_PUNCH_HOLE: ::c_int = 0x02; + +// On Linux, libc doesn't define this constant, libattr does instead. +// We still define it for Linux as it's defined by libc on other platforms, +// and it's mentioned in the man pages for getxattr and setxattr. +pub const SFD_CLOEXEC: ::c_int = 0x080000; + +pub const NCCS: usize = 32; + +pub const O_TRUNC: ::c_int = 512; +pub const O_NOATIME: ::c_int = 0o1000000; +pub const O_CLOEXEC: ::c_int = 0x80000; + +// Defined as wasi value. +pub const EPERM: ::c_int = 63; +pub const ENOENT: ::c_int = 44; +pub const ESRCH: ::c_int = 71; +pub const EINTR: ::c_int = 27; +pub const EIO: ::c_int = 29; +pub const ENXIO: ::c_int = 60; +pub const E2BIG: ::c_int = 1; +pub const ENOEXEC: ::c_int = 45; +pub const EBADF: ::c_int = 8; +pub const ECHILD: ::c_int = 12; +pub const EAGAIN: ::c_int = 6; +pub const ENOMEM: ::c_int = 48; +pub const EACCES: ::c_int = 2; +pub const EFAULT: ::c_int = 21; +pub const ENOTBLK: ::c_int = 105; +pub const EBUSY: ::c_int = 10; +pub const EEXIST: ::c_int = 20; +pub const EXDEV: ::c_int = 75; +pub const ENODEV: ::c_int = 43; +pub const ENOTDIR: ::c_int = 54; +pub const EISDIR: ::c_int = 31; +pub const EINVAL: ::c_int = 28; +pub const ENFILE: ::c_int = 41; +pub const EMFILE: ::c_int = 33; +pub const ENOTTY: ::c_int = 59; +pub const ETXTBSY: ::c_int = 74; +pub const EFBIG: ::c_int = 22; +pub const ENOSPC: ::c_int = 51; +pub const ESPIPE: ::c_int = 70; +pub const EROFS: ::c_int = 69; +pub const EMLINK: ::c_int = 34; +pub const EPIPE: ::c_int = 64; +pub const EDOM: ::c_int = 18; +pub const ERANGE: ::c_int = 68; +pub const EWOULDBLOCK: ::c_int = EAGAIN; +pub const ENOLINK: ::c_int = 47; +pub const EPROTO: ::c_int = 65; +pub const EDEADLK: ::c_int = 16; +pub const EDEADLOCK: ::c_int = EDEADLK; +pub const ENAMETOOLONG: ::c_int = 37; +pub const ENOLCK: ::c_int = 46; +pub const ENOSYS: ::c_int = 52; +pub const ENOTEMPTY: ::c_int = 55; +pub const ELOOP: ::c_int = 32; +pub const ENOMSG: ::c_int = 49; +pub const EIDRM: ::c_int = 24; +pub const EMULTIHOP: ::c_int = 36; +pub const EBADMSG: ::c_int = 9; +pub const EOVERFLOW: ::c_int = 61; +pub const EILSEQ: ::c_int = 25; +pub const ENOTSOCK: ::c_int = 57; +pub const EDESTADDRREQ: ::c_int = 17; +pub const EMSGSIZE: ::c_int = 35; +pub const EPROTOTYPE: ::c_int = 67; +pub const ENOPROTOOPT: ::c_int = 50; +pub const EPROTONOSUPPORT: ::c_int = 66; +pub const EAFNOSUPPORT: ::c_int = 5; +pub const EADDRINUSE: ::c_int = 3; +pub const EADDRNOTAVAIL: ::c_int = 4; +pub const ENETDOWN: ::c_int = 38; +pub const ENETUNREACH: ::c_int = 40; +pub const ENETRESET: ::c_int = 39; +pub const ECONNABORTED: ::c_int = 13; +pub const ECONNRESET: ::c_int = 15; +pub const ENOBUFS: ::c_int = 42; +pub const EISCONN: ::c_int = 30; +pub const ENOTCONN: ::c_int = 53; +pub const ETIMEDOUT: ::c_int = 73; +pub const ECONNREFUSED: ::c_int = 14; +pub const EHOSTUNREACH: ::c_int = 23; +pub const EALREADY: ::c_int = 7; +pub const EINPROGRESS: ::c_int = 26; +pub const ESTALE: ::c_int = 72; +pub const EDQUOT: ::c_int = 19; +pub const ECANCELED: ::c_int = 11; +pub const EOWNERDEAD: ::c_int = 62; +pub const ENOTRECOVERABLE: ::c_int = 56; + +pub const ENOSTR: ::c_int = 100; +pub const EBFONT: ::c_int = 101; +pub const EBADSLT: ::c_int = 102; +pub const EBADRQC: ::c_int = 103; +pub const ENOANO: ::c_int = 104; +pub const ECHRNG: ::c_int = 106; +pub const EL3HLT: ::c_int = 107; +pub const EL3RST: ::c_int = 108; +pub const ELNRNG: ::c_int = 109; +pub const EUNATCH: ::c_int = 110; +pub const ENOCSI: ::c_int = 111; +pub const EL2HLT: ::c_int = 112; +pub const EBADE: ::c_int = 113; +pub const EBADR: ::c_int = 114; +pub const EXFULL: ::c_int = 115; +pub const ENODATA: ::c_int = 116; +pub const ETIME: ::c_int = 117; +pub const ENOSR: ::c_int = 118; +pub const ENONET: ::c_int = 119; +pub const ENOPKG: ::c_int = 120; +pub const EREMOTE: ::c_int = 121; +pub const EADV: ::c_int = 122; +pub const ESRMNT: ::c_int = 123; +pub const ECOMM: ::c_int = 124; +pub const EDOTDOT: ::c_int = 125; +pub const ENOTUNIQ: ::c_int = 126; +pub const EBADFD: ::c_int = 127; +pub const EREMCHG: ::c_int = 128; +pub const ELIBACC: ::c_int = 129; +pub const ELIBBAD: ::c_int = 130; +pub const ELIBSCN: ::c_int = 131; +pub const ELIBMAX: ::c_int = 132; +pub const ELIBEXEC: ::c_int = 133; +pub const ERESTART: ::c_int = 134; +pub const ESTRPIPE: ::c_int = 135; +pub const EUSERS: ::c_int = 136; +pub const ESOCKTNOSUPPORT: ::c_int = 137; +pub const EOPNOTSUPP: ::c_int = 138; +pub const ENOTSUP: ::c_int = EOPNOTSUPP; +pub const EPFNOSUPPORT: ::c_int = 139; +pub const ESHUTDOWN: ::c_int = 140; +pub const ETOOMANYREFS: ::c_int = 141; +pub const EHOSTDOWN: ::c_int = 142; +pub const EUCLEAN: ::c_int = 143; +pub const ENOTNAM: ::c_int = 144; +pub const ENAVAIL: ::c_int = 145; +pub const EISNAM: ::c_int = 146; +pub const EREMOTEIO: ::c_int = 147; +pub const ENOMEDIUM: ::c_int = 148; +pub const EMEDIUMTYPE: ::c_int = 149; +pub const ENOKEY: ::c_int = 150; +pub const EKEYEXPIRED: ::c_int = 151; +pub const EKEYREVOKED: ::c_int = 152; +pub const EKEYREJECTED: ::c_int = 153; +pub const ERFKILL: ::c_int = 154; +pub const EHWPOISON: ::c_int = 155; +pub const EL2NSYNC: ::c_int = 156; + +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 EPOLL_CLOEXEC: ::c_int = 0x80000; + +pub const EFD_CLOEXEC: ::c_int = 0x80000; + +pub const BUFSIZ: ::c_uint = 1024; +pub const TMP_MAX: ::c_uint = 10000; +pub const FOPEN_MAX: ::c_uint = 1000; +pub const O_PATH: ::c_int = 0o10000000; +pub const O_EXEC: ::c_int = 0o10000000; +pub const O_SEARCH: ::c_int = 0o10000000; +pub const O_ACCMODE: ::c_int = 0o10000003; +pub const O_NDELAY: ::c_int = O_NONBLOCK; +pub const NI_MAXHOST: ::socklen_t = 255; +pub const PTHREAD_STACK_MIN: ::size_t = 2048; +pub const POSIX_FADV_DONTNEED: ::c_int = 4; +pub const POSIX_FADV_NOREUSE: ::c_int = 5; + +pub const POSIX_MADV_DONTNEED: ::c_int = 0; + +pub const RLIM_INFINITY: ::rlim_t = !0; +#[deprecated(since = "0.2.64", note = "Not stable across OS versions")] +pub const RLIMIT_NLIMITS: ::c_int = 15; +#[allow(deprecated)] +#[deprecated(since = "0.2.64", note = "Not stable across OS versions")] +pub const RLIM_NLIMITS: ::c_int = RLIMIT_NLIMITS; + +pub const MAP_ANONYMOUS: ::c_int = MAP_ANON; + +#[doc(hidden)] +#[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 CPU_SETSIZE: ::c_int = 128; + +pub const QFMT_VFS_V1: ::c_int = 4; + +pub const PTRACE_TRACEME: ::c_int = 0; +pub const PTRACE_PEEKTEXT: ::c_int = 1; +pub const PTRACE_PEEKDATA: ::c_int = 2; +pub const PTRACE_PEEKUSER: ::c_int = 3; +pub const PTRACE_POKETEXT: ::c_int = 4; +pub const PTRACE_POKEDATA: ::c_int = 5; +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_ATTACH: ::c_int = 16; +pub const PTRACE_DETACH: ::c_int = 17; +pub const PTRACE_SYSCALL: ::c_int = 24; +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_SEIZE: ::c_int = 0x4206; +pub const PTRACE_INTERRUPT: ::c_int = 0x4207; +pub const PTRACE_LISTEN: ::c_int = 0x4208; +pub const PTRACE_PEEKSIGINFO: ::c_int = 0x4209; + +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 EFD_NONBLOCK: ::c_int = ::O_NONBLOCK; + +pub const SFD_NONBLOCK: ::c_int = ::O_NONBLOCK; + +pub const TCSANOW: ::c_int = 0; +pub const TCSADRAIN: ::c_int = 1; +pub const TCSAFLUSH: ::c_int = 2; + +pub const TIOCINQ: ::c_int = ::FIONREAD; + +pub const RTLD_GLOBAL: ::c_int = 0x100; +pub const RTLD_NOLOAD: ::c_int = 0x4; + +pub const CLOCK_SGI_CYCLE: ::clockid_t = 10; + +pub const MCL_CURRENT: ::c_int = 0x0001; +pub const MCL_FUTURE: ::c_int = 0x0002; + +pub const SIGSTKSZ: ::size_t = 8192; +pub const MINSIGSTKSZ: ::size_t = 2048; +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 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 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 SO_BINDTODEVICE: ::c_int = 25; +pub const SO_TIMESTAMP: ::c_int = 29; +pub const SO_MARK: ::c_int = 36; +pub const SO_RXQ_OVFL: ::c_int = 40; +pub const SO_PEEK_OFF: ::c_int = 42; +pub const SO_BUSY_POLL: ::c_int = 46; + +pub const __SIZEOF_PTHREAD_RWLOCK_T: usize = 32; +pub const __SIZEOF_PTHREAD_MUTEX_T: usize = 28; + +pub const O_DIRECT: ::c_int = 0x4000; +pub const O_DIRECTORY: ::c_int = 0x10000; +pub const O_NOFOLLOW: ::c_int = 0x20000; +pub const O_ASYNC: ::c_int = 0x2000; + +pub const FIOCLEX: ::c_int = 0x5451; +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_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 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 SOCK_NONBLOCK: ::c_int = 2048; + +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 SOCK_STREAM: ::c_int = 1; +pub const SOCK_DGRAM: ::c_int = 2; +pub const SOCK_SEQPACKET: ::c_int = 5; + +pub const IPPROTO_MAX: ::c_int = 256; + +pub const SOL_SOCKET: ::c_int = 1; + +pub const SO_REUSEADDR: ::c_int = 2; +pub const SO_TYPE: ::c_int = 3; +pub const SO_ERROR: ::c_int = 4; +pub const SO_DONTROUTE: ::c_int = 5; +pub const SO_BROADCAST: ::c_int = 6; +pub const SO_SNDBUF: ::c_int = 7; +pub const SO_RCVBUF: ::c_int = 8; +pub const SO_KEEPALIVE: ::c_int = 9; +pub const SO_OOBINLINE: ::c_int = 10; +pub const SO_LINGER: ::c_int = 13; +pub const SO_REUSEPORT: ::c_int = 15; +pub const SO_RCVLOWAT: ::c_int = 18; +pub const SO_SNDLOWAT: ::c_int = 19; +pub const SO_RCVTIMEO: ::c_int = 20; +pub const SO_SNDTIMEO: ::c_int = 21; +pub const SO_ACCEPTCONN: ::c_int = 30; + +pub const IPV6_RTHDR_LOOSE: ::c_int = 0; +pub const IPV6_RTHDR_STRICT: ::c_int = 1; + +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 EXTPROC: ::tcflag_t = 0x00010000; + +pub const MAP_HUGETLB: ::c_int = 0x040000; + +pub const F_GETLK: ::c_int = 12; +pub const F_GETOWN: ::c_int = 9; +pub const F_SETLK: ::c_int = 13; +pub const F_SETLKW: ::c_int = 14; +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 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 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 SYS_gettid: ::c_long = 224; // Valid for arm (32-bit) and x86 (32-bit) + +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; +pub const O_TMPFILE: ::c_int = 0x400000; + +pub const MAX_ADDR_LEN: usize = 7; +pub const ARPD_UPDATE: ::c_ushort = 0x01; +pub const ARPD_LOOKUP: ::c_ushort = 0x02; +pub const ARPD_FLUSH: ::c_ushort = 0x03; +pub const ATF_MAGIC: ::c_int = 0x80; + +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 { + if ((*cmsg).cmsg_len as usize) < ::mem::size_of::() { + return 0 as *mut cmsghdr; + }; + let next = (cmsg as usize + + super::CMSG_ALIGN((*cmsg).cmsg_len as usize)) + as *mut cmsghdr; + let max = (*mhdr).msg_control as usize + + (*mhdr).msg_controllen as usize; + if (next.offset(1)) as usize > max { + 0 as *mut cmsghdr + } else { + next as *mut cmsghdr + } + } + + pub fn CPU_ZERO(cpuset: &mut cpu_set_t) -> () { + for slot in cpuset.bits.iter_mut() { + *slot = 0; + } + } + + pub fn CPU_SET(cpu: usize, cpuset: &mut cpu_set_t) -> () { + let size_in_bits + = 8 * ::mem::size_of_val(&cpuset.bits[0]); // 32, 64 etc + let (idx, offset) = (cpu / size_in_bits, cpu % size_in_bits); + cpuset.bits[idx] |= 1 << offset; + () + } + + pub fn CPU_CLR(cpu: usize, cpuset: &mut cpu_set_t) -> () { + let size_in_bits + = 8 * ::mem::size_of_val(&cpuset.bits[0]); // 32, 64 etc + let (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); + 0 != (cpuset.bits[idx] & (1 << offset)) + } + + pub fn CPU_EQUAL(set1: &cpu_set_t, set2: &cpu_set_t) -> bool { + set1.bits == set2.bits + } + + pub fn major(dev: ::dev_t) -> ::c_uint { + // see + // https://github.com/emscripten-core/emscripten/blob/ + // main/system/lib/libc/musl/include/sys/sysmacros.h + let mut major = 0; + major |= (dev & 0x00000fff) >> 8; + major |= (dev & 0xfffff000) >> 31 >> 1; + major as ::c_uint + } + + pub fn minor(dev: ::dev_t) -> ::c_uint { + // see + // https://github.com/emscripten-core/emscripten/blob/ + // 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 + } +} + +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) << 31 << 1; + dev |= (minor & 0x000000ff) << 0; + dev |= (minor & 0xffffff00) << 12; + dev + } +} + +extern "C" { + pub fn getrlimit(resource: ::c_int, rlim: *mut ::rlimit) -> ::c_int; + pub fn setrlimit(resource: ::c_int, rlim: *const ::rlimit) -> ::c_int; + pub fn strerror_r(errnum: ::c_int, buf: *mut c_char, buflen: ::size_t) -> ::c_int; + + 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 gettimeofday(tp: *mut ::timeval, tz: *mut ::c_void) -> ::c_int; + + pub fn setpwent(); + pub fn endpwent(); + pub fn getpwent() -> *mut passwd; + + pub fn shm_open(name: *const c_char, oflag: ::c_int, mode: mode_t) -> ::c_int; + + pub fn mprotect(addr: *mut ::c_void, len: ::size_t, prot: ::c_int) -> ::c_int; + pub fn __errno_location() -> *mut ::c_int; + + pub fn posix_fallocate(fd: ::c_int, offset: ::off_t, len: ::off_t) -> ::c_int; + pub fn pwritev(fd: ::c_int, iov: *const ::iovec, iovcnt: ::c_int, offset: ::off_t) + -> ::ssize_t; + pub fn preadv(fd: ::c_int, iov: *const ::iovec, iovcnt: ::c_int, offset: ::off_t) -> ::ssize_t; + pub fn dup3(oldfd: ::c_int, newfd: ::c_int, flags: ::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; + pub fn nl_langinfo_l(item: ::nl_item, locale: ::locale_t) -> *mut ::c_char; + pub fn accept4( + fd: ::c_int, + addr: *mut ::sockaddr, + len: *mut ::socklen_t, + flg: ::c_int, + ) -> ::c_int; + pub fn getnameinfo( + sa: *const ::sockaddr, + salen: ::socklen_t, + host: *mut ::c_char, + hostlen: ::socklen_t, + serv: *mut ::c_char, + servlen: ::socklen_t, + flags: ::c_int, + ) -> ::c_int; + pub fn getloadavg(loadavg: *mut ::c_double, nelem: ::c_int) -> ::c_int; + + 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); + + pub fn mremap( + addr: *mut ::c_void, + len: ::size_t, + new_len: ::size_t, + flags: ::c_int, + ... + ) -> *mut ::c_void; + + 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 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 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 nl_langinfo(item: ::nl_item) -> *mut ::c_char; + + pub fn getdomainname(name: *mut ::c_char, len: ::size_t) -> ::c_int; + pub fn setdomainname(name: *const ::c_char, len: ::size_t) -> ::c_int; + pub fn sendmmsg( + sockfd: ::c_int, + msgvec: *mut ::mmsghdr, + vlen: ::c_uint, + 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 sync(); + pub fn ioctl(fd: ::c_int, request: ::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 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 getentropy(buf: *mut ::c_void, buflen: ::size_t) -> ::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; + + // grp.h + pub fn getgrgid(gid: ::gid_t) -> *mut ::group; + 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 getgrgid_r( + gid: ::gid_t, + grp: *mut ::group, + buf: *mut ::c_char, + buflen: ::size_t, + result: *mut *mut ::group, + ) -> ::c_int; +} + +// Alias to 64 to mimic glibc's LFS64 support +mod lfs64; +pub use self::lfs64::*; + +cfg_if! { + if #[cfg(libc_align)] { + #[macro_use] + mod align; + } else { + #[macro_use] + mod no_align; + } +} +expand_align!(); diff --git a/vendor/libc/src/unix/linux_like/emscripten/no_align.rs b/vendor/libc/src/unix/linux_like/emscripten/no_align.rs new file mode 100644 index 0000000..768dc73 --- /dev/null +++ b/vendor/libc/src/unix/linux_like/emscripten/no_align.rs @@ -0,0 +1,63 @@ +macro_rules! expand_align { + () => { + s! { + pub struct pthread_mutex_t { + __align: [::c_long; 0], + size: [u8; ::__SIZEOF_PTHREAD_MUTEX_T], + } + + pub struct pthread_rwlock_t { + __align: [::c_long; 0], + size: [u8; ::__SIZEOF_PTHREAD_RWLOCK_T], + } + + pub struct pthread_mutexattr_t { + __align: [::c_int; 0], + size: [u8; ::__SIZEOF_PTHREAD_MUTEXATTR_T], + } + + pub struct pthread_rwlockattr_t { + __align: [::c_int; 0], + size: [u8; ::__SIZEOF_PTHREAD_RWLOCKATTR_T], + } + + pub struct pthread_condattr_t { + __align: [::c_int; 0], + size: [u8; ::__SIZEOF_PTHREAD_CONDATTR_T], + } + } + + s_no_extra_traits! { + pub struct pthread_cond_t { + __align: [*const ::c_void; 0], + size: [u8; ::__SIZEOF_PTHREAD_COND_T], + } + } + + cfg_if! { + if #[cfg(feature = "extra_traits")] { + impl PartialEq for pthread_cond_t { + fn eq(&self, other: &pthread_cond_t) -> bool { + self.size + .iter() + .zip(other.size.iter()) + .all(|(a,b)| a == b) + } + } + impl Eq for pthread_cond_t {} + impl ::fmt::Debug for pthread_cond_t { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("pthread_cond_t") + // FIXME: .field("size", &self.size) + .finish() + } + } + impl ::hash::Hash for pthread_cond_t { + fn hash(&self, state: &mut H) { + self.size.hash(state); + } + } + } + } + }; +} diff --git a/vendor/libc/src/unix/linux_like/linux/align.rs b/vendor/libc/src/unix/linux_like/linux/align.rs new file mode 100644 index 0000000..bd16e44 --- /dev/null +++ b/vendor/libc/src/unix/linux_like/linux/align.rs @@ -0,0 +1,223 @@ +macro_rules! expand_align { + () => { + s! { + #[cfg_attr(any(target_pointer_width = "32", + target_arch = "x86_64", + target_arch = "powerpc64", + target_arch = "mips64", + target_arch = "mips64r6", + target_arch = "s390x", + target_arch = "sparc64", + target_arch = "aarch64", + target_arch = "riscv64", + target_arch = "riscv32", + target_arch = "loongarch64"), + repr(align(4)))] + #[cfg_attr(not(any(target_pointer_width = "32", + target_arch = "x86_64", + target_arch = "powerpc64", + target_arch = "mips64", + target_arch = "mips64r6", + target_arch = "s390x", + target_arch = "sparc64", + target_arch = "aarch64", + target_arch = "riscv64", + 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_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 { + #[doc(hidden)] + size: [u8; ::__SIZEOF_PTHREAD_RWLOCKATTR_T], + } + + #[repr(align(4))] + pub struct pthread_condattr_t { + #[doc(hidden)] + 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, + pub vers: __u8, + pub reserved: __u8, + pub metadata_len: __u16, + pub mask: __u64, + pub fd: ::c_int, + pub pid: ::c_int, + } + + #[repr(align(8))] + pub struct tpacket_rollover_stats { + pub tp_all: ::__u64, + pub tp_huge: ::__u64, + pub tp_failed: ::__u64, + } + + #[repr(align(8))] + pub struct tpacket_hdr_v1 { + pub block_status: ::__u32, + pub num_pkts: ::__u32, + pub offset_to_first_pkt: ::__u32, + pub blk_len: ::__u32, + pub seq_num: ::__u64, + pub ts_first_pkt: ::tpacket_bd_ts, + pub ts_last_pkt: ::tpacket_bd_ts, + } + } + + s_no_extra_traits! { + #[cfg_attr(all(any(target_env = "musl", target_env = "ohos"), + target_pointer_width = "32"), + repr(align(4)))] + #[cfg_attr(all(any(target_env = "musl", target_env = "ohos"), + target_pointer_width = "64"), + repr(align(8)))] + #[cfg_attr(all(not(any(target_env = "musl", target_env = "ohos")), + target_arch = "x86"), + repr(align(4)))] + #[cfg_attr(all(not(any(target_env = "musl", target_env = "ohos")), + not(target_arch = "x86")), + repr(align(8)))] + pub struct pthread_cond_t { + #[doc(hidden)] + size: [u8; ::__SIZEOF_PTHREAD_COND_T], + } + + #[cfg_attr(all(target_pointer_width = "32", + any(target_arch = "mips", + target_arch = "mips32r6", + target_arch = "arm", + target_arch = "hexagon", + target_arch = "m68k", + target_arch = "csky", + 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 = "mips32r6", + target_arch = "arm", + target_arch = "hexagon", + target_arch = "m68k", + target_arch = "csky", + target_arch = "powerpc", + target_arch = "sparc", + target_arch = "x86_64", + target_arch = "x86"))), + repr(align(8)))] + pub struct pthread_mutex_t { + #[doc(hidden)] + size: [u8; ::__SIZEOF_PTHREAD_MUTEX_T], + } + + #[cfg_attr(all(target_pointer_width = "32", + any(target_arch = "mips", + target_arch = "mips32r6", + target_arch = "arm", + target_arch = "hexagon", + target_arch = "m68k", + target_arch = "csky", + 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 = "mips32r6", + 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_rwlock_t { + size: [u8; ::__SIZEOF_PTHREAD_RWLOCK_T], + } + + #[cfg_attr(all(target_pointer_width = "32", + any(target_arch = "mips", + target_arch = "mips32r6", + target_arch = "arm", + target_arch = "hexagon", + target_arch = "m68k", + target_arch = "csky", + 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 = "mips32r6", + target_arch = "arm", + target_arch = "hexagon", + target_arch = "m68k", + target_arch = "csky", + 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)] + pub struct can_frame { + pub can_id: canid_t, + pub can_dlc: u8, + __pad: u8, + __res0: u8, + __res1: u8, + pub data: [u8; CAN_MAX_DLEN], + } + + #[repr(align(8))] + #[allow(missing_debug_implementations)] + pub struct canfd_frame { + pub can_id: canid_t, + pub len: u8, + pub flags: u8, + __res0: u8, + __res1: u8, + pub data: [u8; CANFD_MAX_DLEN], + } + + #[repr(align(8))] + #[allow(missing_debug_implementations)] + pub struct canxl_frame { + pub prio: canid_t, + pub flags: u8, + pub sdt: u8, + pub len: u16, + pub af: u32, + pub data: [u8; CANXL_MAX_DLEN], + } + } + }; +} 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 new file mode 100644 index 0000000..2f437e1 --- /dev/null +++ b/vendor/libc/src/unix/linux_like/linux/arch/generic/mod.rs @@ -0,0 +1,333 @@ +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 +// arch/mips/include/uapi/asm/socket.h +pub const SOL_SOCKET: ::c_int = 1; + +// Defined in unix/linux_like/mod.rs +// pub const SO_DEBUG: ::c_int = 1; +pub const SO_REUSEADDR: ::c_int = 2; +pub const SO_TYPE: ::c_int = 3; +pub const SO_ERROR: ::c_int = 4; +pub const SO_DONTROUTE: ::c_int = 5; +pub const SO_BROADCAST: ::c_int = 6; +pub const SO_SNDBUF: ::c_int = 7; +pub const SO_RCVBUF: ::c_int = 8; +pub const SO_KEEPALIVE: ::c_int = 9; +pub const SO_OOBINLINE: ::c_int = 10; +pub const SO_NO_CHECK: ::c_int = 11; +pub const SO_PRIORITY: ::c_int = 12; +pub const SO_LINGER: ::c_int = 13; +pub const SO_BSDCOMPAT: ::c_int = 14; +pub const SO_REUSEPORT: ::c_int = 15; +pub const SO_PASSCRED: ::c_int = 16; +pub const SO_PEERCRED: ::c_int = 17; +pub const SO_RCVLOWAT: ::c_int = 18; +pub const SO_SNDLOWAT: ::c_int = 19; +pub const SO_RCVTIMEO: ::c_int = 20; +pub const SO_SNDTIMEO: ::c_int = 21; +// pub const SO_RCVTIMEO_OLD: ::c_int = 20; +// pub const SO_SNDTIMEO_OLD: ::c_int = 21; +pub const SO_SECURITY_AUTHENTICATION: ::c_int = 22; +pub const SO_SECURITY_ENCRYPTION_TRANSPORT: ::c_int = 23; +pub const SO_SECURITY_ENCRYPTION_NETWORK: ::c_int = 24; +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_PEERNAME: ::c_int = 28; +pub const SO_TIMESTAMP: ::c_int = 29; +// pub const SO_TIMESTAMP_OLD: ::c_int = 29; +pub const SO_ACCEPTCONN: ::c_int = 30; +pub const SO_PEERSEC: ::c_int = 31; +pub const SO_SNDBUFFORCE: ::c_int = 32; +pub const SO_RCVBUFFORCE: ::c_int = 33; +pub const SO_PASSSEC: ::c_int = 34; +pub const SO_TIMESTAMPNS: ::c_int = 35; +// pub const SO_TIMESTAMPNS_OLD: ::c_int = 35; +pub const SO_MARK: ::c_int = 36; +pub const SO_TIMESTAMPING: ::c_int = 37; +// pub const SO_TIMESTAMPING_OLD: ::c_int = 37; +pub const SO_PROTOCOL: ::c_int = 38; +pub const SO_DOMAIN: ::c_int = 39; +pub const SO_RXQ_OVFL: ::c_int = 40; +pub const SO_WIFI_STATUS: ::c_int = 41; +pub const SCM_WIFI_STATUS: ::c_int = SO_WIFI_STATUS; +pub const SO_PEEK_OFF: ::c_int = 42; +pub const SO_NOFCS: ::c_int = 43; +pub const SO_LOCK_FILTER: ::c_int = 44; +pub const SO_SELECT_ERR_QUEUE: ::c_int = 45; +pub const SO_BUSY_POLL: ::c_int = 46; +pub const SO_MAX_PACING_RATE: ::c_int = 47; +pub const SO_BPF_EXTENSIONS: ::c_int = 48; +pub const SO_INCOMING_CPU: ::c_int = 49; +pub const SO_ATTACH_BPF: ::c_int = 50; +pub const SO_DETACH_BPF: ::c_int = SO_DETACH_FILTER; +pub const SO_ATTACH_REUSEPORT_CBPF: ::c_int = 51; +pub const SO_ATTACH_REUSEPORT_EBPF: ::c_int = 52; +pub const SO_CNX_ADVICE: ::c_int = 53; +pub const SCM_TIMESTAMPING_OPT_STATS: ::c_int = 54; +pub const SO_MEMINFO: ::c_int = 55; +pub const SO_INCOMING_NAPI_ID: ::c_int = 56; +pub const SO_COOKIE: ::c_int = 57; +pub const SCM_TIMESTAMPING_PKTINFO: ::c_int = 58; +pub const SO_PEERGROUPS: ::c_int = 59; +pub const SO_ZEROCOPY: ::c_int = 60; +pub const SO_TXTIME: ::c_int = 61; +pub const SCM_TXTIME: ::c_int = SO_TXTIME; +pub const SO_BINDTOIFINDEX: ::c_int = 62; +cfg_if! { + // Some of these platforms in CI already have these constants. + // But they may still not have those _OLD ones. + if #[cfg(all(any(target_arch = "x86", + target_arch = "x86_64", + target_arch = "aarch64", + target_arch = "csky", + target_arch = "loongarch64"), + 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; + pub const SO_RCVTIMEO_NEW: ::c_int = 66; + pub const SO_SNDTIMEO_NEW: ::c_int = 67; + pub const SO_DETACH_REUSEPORT_BPF: ::c_int = 68; + } +} +// pub const SO_PREFER_BUSY_POLL: ::c_int = 69; +// pub const SO_BUSY_POLL_BUDGET: ::c_int = 70; + +cfg_if! { + if #[cfg(any(target_arch = "x86", + target_arch = "x86_64", + target_arch = "arm", + target_arch = "aarch64", + target_arch = "riscv64", + target_arch = "s390x", + target_arch = "csky", + target_arch = "loongarch64"))] { + pub const FICLONE: ::c_ulong = 0x40049409; + pub const FICLONERANGE: ::c_ulong = 0x4020940D; + } +} + +// Defined in unix/linux_like/mod.rs +// 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! { + // Those type are constructed using the _IOC macro + // DD-SS_SSSS_SSSS_SSSS-TTTT_TTTT-NNNN_NNNN + // where D stands for direction (either None (00), Read (01) or Write (11)) + // where S stands for size (int, long, struct...) + // where T stands for type ('f','v','X'...) + // where N stands for NR (NumbeR) + if #[cfg(any(target_arch = "x86", target_arch = "arm", target_arch = "csky"))] { + pub const FS_IOC_GETFLAGS: ::Ioctl = 0x80046601; + pub const FS_IOC_SETFLAGS: ::Ioctl = 0x40046602; + pub const FS_IOC_GETVERSION: ::Ioctl = 0x80047601; + pub const FS_IOC_SETVERSION: ::Ioctl = 0x40047602; + pub const FS_IOC32_GETFLAGS: ::Ioctl = 0x80046601; + pub const FS_IOC32_SETFLAGS: ::Ioctl = 0x40046602; + pub const FS_IOC32_GETVERSION: ::Ioctl = 0x80047601; + pub const FS_IOC32_SETVERSION: ::Ioctl = 0x40047602; + } else if #[cfg(any(target_arch = "x86_64", + target_arch = "riscv64", + target_arch = "aarch64", + target_arch = "s390x", + target_arch = "loongarch64"))] { + pub const FS_IOC_GETFLAGS: ::Ioctl = 0x80086601; + pub const FS_IOC_SETFLAGS: ::Ioctl = 0x40086602; + pub const FS_IOC_GETVERSION: ::Ioctl = 0x80087601; + pub const FS_IOC_SETVERSION: ::Ioctl = 0x40087602; + pub const FS_IOC32_GETFLAGS: ::Ioctl = 0x80046601; + pub const FS_IOC32_SETFLAGS: ::Ioctl = 0x40046602; + pub const FS_IOC32_GETVERSION: ::Ioctl = 0x80047601; + pub const FS_IOC32_SETVERSION: ::Ioctl = 0x40047602; + } +} + +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; + #[allow(deprecated)] + #[deprecated(since = "0.2.64", note = "Not stable across OS versions")] + 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; + #[deprecated(since = "0.2.64", note = "Not stable across OS versions")] + pub const RLIM_NLIMITS: ::c_int = 15; + #[allow(deprecated)] + #[deprecated(since = "0.2.64", note = "Not stable across OS versions")] + pub const RLIMIT_NLIMITS: ::c_int = RLIM_NLIMITS; + } +} + +cfg_if! { + if #[cfg(target_env = "gnu")] { + #[deprecated(since = "0.2.64", note = "Not stable across OS versions")] + pub const RLIM_NLIMITS: ::__rlimit_resource_t = 16; + } + else if #[cfg(target_env = "uclibc")] { + #[deprecated(since = "0.2.64", note = "Not stable across OS versions")] + 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 new file mode 100644 index 0000000..6a96aa9 --- /dev/null +++ b/vendor/libc/src/unix/linux_like/linux/arch/mips/mod.rs @@ -0,0 +1,323 @@ +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; + +// Defined in unix/linux_like/mod.rs +// pub const SO_DEBUG: ::c_int = 0x0001; +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_LINGER: ::c_int = 0x0080; +pub const SO_OOBINLINE: ::c_int = 0x0100; +pub const SO_REUSEPORT: ::c_int = 0x0200; +pub const SO_TYPE: ::c_int = 0x1008; +// pub const SO_STYLE: ::c_int = SO_TYPE; +pub const SO_ERROR: ::c_int = 0x1007; +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; +// NOTE: These definitions are now being renamed with _OLD postfix, +// but CI haven't support them yet. +// Some related consts could be found in b32.rs and b64.rs +pub const SO_SNDTIMEO: ::c_int = 0x1005; +pub const SO_RCVTIMEO: ::c_int = 0x1006; +// pub const SO_SNDTIMEO_OLD: ::c_int = 0x1005; +// pub const SO_RCVTIMEO_OLD: ::c_int = 0x1006; +pub const SO_ACCEPTCONN: ::c_int = 0x1009; +pub const SO_PROTOCOL: ::c_int = 0x1028; +pub const SO_DOMAIN: ::c_int = 0x1029; + +pub const SO_NO_CHECK: ::c_int = 11; +pub const SO_PRIORITY: ::c_int = 12; +pub const SO_BSDCOMPAT: ::c_int = 14; +pub const SO_PASSCRED: ::c_int = 17; +pub const SO_PEERCRED: ::c_int = 18; +pub const SO_SECURITY_AUTHENTICATION: ::c_int = 22; +pub const SO_SECURITY_ENCRYPTION_TRANSPORT: ::c_int = 23; +pub const SO_SECURITY_ENCRYPTION_NETWORK: ::c_int = 24; +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_PEERNAME: ::c_int = 28; +pub const SO_PEERSEC: ::c_int = 30; +pub const SO_SNDBUFFORCE: ::c_int = 31; +pub const SO_RCVBUFFORCE: ::c_int = 33; +pub const SO_PASSSEC: ::c_int = 34; +pub const SO_MARK: ::c_int = 36; +pub const SO_RXQ_OVFL: ::c_int = 40; +pub const SO_WIFI_STATUS: ::c_int = 41; +pub const SCM_WIFI_STATUS: ::c_int = SO_WIFI_STATUS; +pub const SO_PEEK_OFF: ::c_int = 42; +pub const SO_NOFCS: ::c_int = 43; +pub const SO_LOCK_FILTER: ::c_int = 44; +pub const SO_SELECT_ERR_QUEUE: ::c_int = 45; +pub const SO_BUSY_POLL: ::c_int = 46; +pub const SO_MAX_PACING_RATE: ::c_int = 47; +pub const SO_BPF_EXTENSIONS: ::c_int = 48; +pub const SO_INCOMING_CPU: ::c_int = 49; +pub const SO_ATTACH_BPF: ::c_int = 50; +pub const SO_DETACH_BPF: ::c_int = SO_DETACH_FILTER; +pub const SO_ATTACH_REUSEPORT_CBPF: ::c_int = 51; +pub const SO_ATTACH_REUSEPORT_EBPF: ::c_int = 52; +pub const SO_CNX_ADVICE: ::c_int = 53; +pub const SCM_TIMESTAMPING_OPT_STATS: ::c_int = 54; +pub const SO_MEMINFO: ::c_int = 55; +pub const SO_INCOMING_NAPI_ID: ::c_int = 56; +pub const SO_COOKIE: ::c_int = 57; +pub const SCM_TIMESTAMPING_PKTINFO: ::c_int = 58; +pub const SO_PEERGROUPS: ::c_int = 59; +pub const SO_ZEROCOPY: ::c_int = 60; +pub const SO_TXTIME: ::c_int = 61; +pub const SCM_TXTIME: ::c_int = SO_TXTIME; +pub const SO_BINDTOIFINDEX: ::c_int = 62; +// NOTE: These definitions are now being renamed with _OLD postfix, +// but CI haven't support them yet. +// Some related consts could be found in b32.rs and b64.rs +pub const SO_TIMESTAMP: ::c_int = 29; +pub const SO_TIMESTAMPNS: ::c_int = 35; +pub const SO_TIMESTAMPING: ::c_int = 37; +// pub const SO_TIMESTAMP_OLD: ::c_int = 29; +// pub const SO_TIMESTAMPNS_OLD: ::c_int = 35; +// pub const SO_TIMESTAMPING_OLD: ::c_int = 37; +// pub const SO_TIMESTAMP_NEW: ::c_int = 63; +// pub const SO_TIMESTAMPNS_NEW: ::c_int = 64; +// pub const SO_TIMESTAMPING_NEW: ::c_int = 65; +// pub const SO_RCVTIMEO_NEW: ::c_int = 66; +// pub const SO_SNDTIMEO_NEW: ::c_int = 67; +// pub const SO_DETACH_REUSEPORT_BPF: ::c_int = 68; +// pub const SO_PREFER_BUSY_POLL: ::c_int = 69; +// pub const SO_BUSY_POLL_BUDGET: ::c_int = 70; + +pub const FICLONE: ::c_ulong = 0x80049409; +pub const FICLONERANGE: ::c_ulong = 0x8020940D; + +// Defined in unix/linux_like/mod.rs +// 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! { + // Those type are constructed using the _IOC macro + // DD-SS_SSSS_SSSS_SSSS-TTTT_TTTT-NNNN_NNNN + // where D stands for direction (either None (00), Read (01) or Write (11)) + // where S stands for size (int, long, struct...) + // where T stands for type ('f','v','X'...) + // where N stands for NR (NumbeR) + if #[cfg(any(target_arch = "mips", target_arch = "mips32r6"))] { + pub const FS_IOC_GETFLAGS: ::Ioctl = 0x40046601; + pub const FS_IOC_SETFLAGS: ::Ioctl = 0x80046602; + pub const FS_IOC_GETVERSION: ::Ioctl = 0x40047601; + pub const FS_IOC_SETVERSION: ::Ioctl = 0x80047602; + pub const FS_IOC32_GETFLAGS: ::Ioctl = 0x40046601; + pub const FS_IOC32_SETFLAGS: ::Ioctl = 0x80046602; + pub const FS_IOC32_GETVERSION: ::Ioctl = 0x40047601; + pub const FS_IOC32_SETVERSION: ::Ioctl = 0x80047602; + } else if #[cfg(any(target_arch = "mips64", target_arch = "mips64r6"))] { + pub const FS_IOC_GETFLAGS: ::Ioctl = 0x40086601; + pub const FS_IOC_SETFLAGS: ::Ioctl = 0x80086602; + pub const FS_IOC_GETVERSION: ::Ioctl = 0x40087601; + pub const FS_IOC_SETVERSION: ::Ioctl = 0x80087602; + pub const FS_IOC32_GETFLAGS: ::Ioctl = 0x40046601; + pub const FS_IOC32_SETFLAGS: ::Ioctl = 0x80046602; + pub const FS_IOC32_GETVERSION: ::Ioctl = 0x40047601; + pub const FS_IOC32_SETVERSION: ::Ioctl = 0x80047602; + } +} + +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; + #[allow(deprecated)] + #[deprecated(since = "0.2.64", note = "Not stable across OS versions")] + 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; + #[deprecated(since = "0.2.64", note = "Not stable across OS versions")] + pub const RLIM_NLIMITS: ::c_int = 15; + #[allow(deprecated)] + #[deprecated(since = "0.2.64", note = "Not stable across OS versions")] + pub const RLIMIT_NLIMITS: ::c_int = RLIM_NLIMITS; + pub const RLIM_INFINITY: ::rlim_t = !0; + } +} + +cfg_if! { + if #[cfg(target_env = "gnu")] { + #[deprecated(since = "0.2.64", note = "Not stable across OS versions")] + pub const RLIM_NLIMITS: ::__rlimit_resource_t = 16; + } else if #[cfg(target_env = "uclibc")] { + #[deprecated(since = "0.2.64", note = "Not stable across OS versions")] + pub const RLIM_NLIMITS: ::__rlimit_resource_t = 15; + } +} + +cfg_if! { + if #[cfg(any(target_arch = "mips64", target_arch = "mips64r6"), + any(target_env = "gnu", + target_env = "uclibc"))] { + pub const RLIM_INFINITY: ::rlim_t = !0; + } +} + +cfg_if! { + if #[cfg(any(target_arch = "mips", target_arch = "mips32r6"), + 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/mod.rs b/vendor/libc/src/unix/linux_like/linux/arch/mod.rs new file mode 100644 index 0000000..7f6ddc5 --- /dev/null +++ b/vendor/libc/src/unix/linux_like/linux/arch/mod.rs @@ -0,0 +1,18 @@ +cfg_if! { + if #[cfg(any(target_arch = "mips", + target_arch = "mips32r6", + target_arch = "mips64", + target_arch = "mips64r6"))] { + mod mips; + pub use self::mips::*; + } else if #[cfg(any(target_arch = "powerpc", target_arch = "powerpc64"))] { + mod powerpc; + pub use self::powerpc::*; + } else if #[cfg(any(target_arch = "sparc", target_arch = "sparc64"))] { + mod sparc; + pub use self::sparc::*; + } else { + mod generic; + pub use self::generic::*; + } +} 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 new file mode 100644 index 0000000..27834db --- /dev/null +++ b/vendor/libc/src/unix/linux_like/linux/arch/powerpc/mod.rs @@ -0,0 +1,277 @@ +// arch/powerpc/include/uapi/asm/socket.h + +pub const SOL_SOCKET: ::c_int = 1; + +// Defined in unix/linux_like/mod.rs +// pub const SO_DEBUG: ::c_int = 1; +pub const SO_REUSEADDR: ::c_int = 2; +pub const SO_TYPE: ::c_int = 3; +pub const SO_ERROR: ::c_int = 4; +pub const SO_DONTROUTE: ::c_int = 5; +pub const SO_BROADCAST: ::c_int = 6; +pub const SO_SNDBUF: ::c_int = 7; +pub const SO_RCVBUF: ::c_int = 8; +pub const SO_KEEPALIVE: ::c_int = 9; +pub const SO_OOBINLINE: ::c_int = 10; +pub const SO_NO_CHECK: ::c_int = 11; +pub const SO_PRIORITY: ::c_int = 12; +pub const SO_LINGER: ::c_int = 13; +pub const SO_BSDCOMPAT: ::c_int = 14; +pub const SO_REUSEPORT: ::c_int = 15; +// powerpc only differs in these +pub const SO_RCVLOWAT: ::c_int = 16; +pub const SO_SNDLOWAT: ::c_int = 17; +pub const SO_RCVTIMEO: ::c_int = 18; +pub const SO_SNDTIMEO: ::c_int = 19; +// pub const SO_RCVTIMEO_OLD: ::c_int = 18; +// pub const SO_SNDTIMEO_OLD: ::c_int = 19; +pub const SO_PASSCRED: ::c_int = 20; +pub const SO_PEERCRED: ::c_int = 21; +// end +pub const SO_SECURITY_AUTHENTICATION: ::c_int = 22; +pub const SO_SECURITY_ENCRYPTION_TRANSPORT: ::c_int = 23; +pub const SO_SECURITY_ENCRYPTION_NETWORK: ::c_int = 24; +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_PEERNAME: ::c_int = 28; +pub const SO_TIMESTAMP: ::c_int = 29; +// pub const SO_TIMESTAMP_OLD: ::c_int = 29; +pub const SO_ACCEPTCONN: ::c_int = 30; +pub const SO_PEERSEC: ::c_int = 31; +pub const SO_SNDBUFFORCE: ::c_int = 32; +pub const SO_RCVBUFFORCE: ::c_int = 33; +pub const SO_PASSSEC: ::c_int = 34; +pub const SO_TIMESTAMPNS: ::c_int = 35; +// pub const SO_TIMESTAMPNS_OLD: ::c_int = 35; +pub const SO_MARK: ::c_int = 36; +pub const SO_TIMESTAMPING: ::c_int = 37; +// pub const SO_TIMESTAMPING_OLD: ::c_int = 37; +pub const SO_PROTOCOL: ::c_int = 38; +pub const SO_DOMAIN: ::c_int = 39; +pub const SO_RXQ_OVFL: ::c_int = 40; +pub const SO_WIFI_STATUS: ::c_int = 41; +pub const SCM_WIFI_STATUS: ::c_int = SO_WIFI_STATUS; +pub const SO_PEEK_OFF: ::c_int = 42; +pub const SO_NOFCS: ::c_int = 43; +pub const SO_LOCK_FILTER: ::c_int = 44; +pub const SO_SELECT_ERR_QUEUE: ::c_int = 45; +pub const SO_BUSY_POLL: ::c_int = 46; +pub const SO_MAX_PACING_RATE: ::c_int = 47; +pub const SO_BPF_EXTENSIONS: ::c_int = 48; +pub const SO_INCOMING_CPU: ::c_int = 49; +pub const SO_ATTACH_BPF: ::c_int = 50; +pub const SO_DETACH_BPF: ::c_int = SO_DETACH_FILTER; +pub const SO_ATTACH_REUSEPORT_CBPF: ::c_int = 51; +pub const SO_ATTACH_REUSEPORT_EBPF: ::c_int = 52; +pub const SO_CNX_ADVICE: ::c_int = 53; +pub const SCM_TIMESTAMPING_OPT_STATS: ::c_int = 54; +pub const SO_MEMINFO: ::c_int = 55; +pub const SO_INCOMING_NAPI_ID: ::c_int = 56; +pub const SO_COOKIE: ::c_int = 57; +pub const SCM_TIMESTAMPING_PKTINFO: ::c_int = 58; +pub const SO_PEERGROUPS: ::c_int = 59; +pub const SO_ZEROCOPY: ::c_int = 60; +pub const SO_TXTIME: ::c_int = 61; +pub const SCM_TXTIME: ::c_int = SO_TXTIME; +pub const SO_BINDTOIFINDEX: ::c_int = 62; +// pub const SO_TIMESTAMP_NEW: ::c_int = 63; +// pub const SO_TIMESTAMPNS_NEW: ::c_int = 64; +// pub const SO_TIMESTAMPING_NEW: ::c_int = 65; +// pub const SO_RCVTIMEO_NEW: ::c_int = 66; +// pub const SO_SNDTIMEO_NEW: ::c_int = 67; +// pub const SO_DETACH_REUSEPORT_BPF: ::c_int = 68; +// pub const SO_PREFER_BUSY_POLL: ::c_int = 69; +// pub const SO_BUSY_POLL_BUDGET: ::c_int = 70; + +pub const FICLONE: ::c_ulong = 0x80049409; +pub const FICLONERANGE: ::c_ulong = 0x8020940D; + +// Defined in unix/linux_like/mod.rs +// 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; + +cfg_if! { + // Those type are constructed using the _IOC macro + // DD-SS_SSSS_SSSS_SSSS-TTTT_TTTT-NNNN_NNNN + // where D stands for direction (either None (00), Read (01) or Write (11)) + // where S stands for size (int, long, struct...) + // where T stands for type ('f','v','X'...) + // where N stands for NR (NumbeR) + if #[cfg(target_arch = "powerpc")] { + pub const FS_IOC_GETFLAGS: ::Ioctl = 0x40046601; + pub const FS_IOC_SETFLAGS: ::Ioctl = 0x80046602; + pub const FS_IOC_GETVERSION: ::Ioctl = 0x40047601; + pub const FS_IOC_SETVERSION: ::Ioctl = 0x80047602; + pub const FS_IOC32_GETFLAGS: ::Ioctl = 0x40046601; + pub const FS_IOC32_SETFLAGS: ::Ioctl = 0x80046602; + pub const FS_IOC32_GETVERSION: ::Ioctl = 0x40047601; + pub const FS_IOC32_SETVERSION: ::Ioctl = 0x80047602; + } else if #[cfg(target_arch = "powerpc64")] { + pub const FS_IOC_GETFLAGS: ::Ioctl = 0x40086601; + pub const FS_IOC_SETFLAGS: ::Ioctl = 0x80086602; + pub const FS_IOC_GETVERSION: ::Ioctl = 0x40087601; + pub const FS_IOC_SETVERSION: ::Ioctl = 0x80087602; + pub const FS_IOC32_GETFLAGS: ::Ioctl = 0x40046601; + pub const FS_IOC32_SETFLAGS: ::Ioctl = 0x80046602; + pub const FS_IOC32_GETVERSION: ::Ioctl = 0x40047601; + pub const FS_IOC32_SETVERSION: ::Ioctl = 0x80047602; + } +} + +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; + #[deprecated(since = "0.2.64", note = "Not stable across OS versions")] + pub const RLIM_NLIMITS: ::__rlimit_resource_t = 16; + #[allow(deprecated)] + #[deprecated(since = "0.2.64", note = "Not stable across OS versions")] + 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; + #[deprecated(since = "0.2.64", note = "Not stable across OS versions")] + pub const RLIM_NLIMITS: ::c_int = 15; + #[allow(deprecated)] + #[deprecated(since = "0.2.64", note = "Not stable across OS versions")] + 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 new file mode 100644 index 0000000..fce466c --- /dev/null +++ b/vendor/libc/src/unix/linux_like/linux/arch/sparc/mod.rs @@ -0,0 +1,259 @@ +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; + +// Defined in unix/linux_like/mod.rs +// pub const SO_DEBUG: ::c_int = 0x0001; +pub const SO_PASSCRED: ::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_PEERCRED: ::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_BSDCOMPAT: ::c_int = 0x0400; +pub const SO_RCVLOWAT: ::c_int = 0x0800; +pub const SO_SNDLOWAT: ::c_int = 0x1000; +pub const SO_RCVTIMEO: ::c_int = 0x2000; +pub const SO_SNDTIMEO: ::c_int = 0x4000; +// pub const SO_RCVTIMEO_OLD: ::c_int = 0x2000; +// pub const SO_SNDTIMEO_OLD: ::c_int = 0x4000; +pub const SO_ACCEPTCONN: ::c_int = 0x8000; +pub const SO_SNDBUF: ::c_int = 0x1001; +pub const SO_RCVBUF: ::c_int = 0x1002; +pub const SO_SNDBUFFORCE: ::c_int = 0x100a; +pub const SO_RCVBUFFORCE: ::c_int = 0x100b; +pub const SO_ERROR: ::c_int = 0x1007; +pub const SO_TYPE: ::c_int = 0x1008; +pub const SO_PROTOCOL: ::c_int = 0x1028; +pub const SO_DOMAIN: ::c_int = 0x1029; +pub const SO_NO_CHECK: ::c_int = 0x000b; +pub const SO_PRIORITY: ::c_int = 0x000c; +pub const SO_BINDTODEVICE: ::c_int = 0x000d; +pub const SO_ATTACH_FILTER: ::c_int = 0x001a; +pub const SO_DETACH_FILTER: ::c_int = 0x001b; +pub const SO_GET_FILTER: ::c_int = SO_ATTACH_FILTER; +pub const SO_PEERNAME: ::c_int = 0x001c; +pub const SO_PEERSEC: ::c_int = 0x001e; +pub const SO_PASSSEC: ::c_int = 0x001f; +pub const SO_MARK: ::c_int = 0x0022; +pub const SO_RXQ_OVFL: ::c_int = 0x0024; +pub const SO_WIFI_STATUS: ::c_int = 0x0025; +pub const SCM_WIFI_STATUS: ::c_int = SO_WIFI_STATUS; +pub const SO_PEEK_OFF: ::c_int = 0x0026; +pub const SO_NOFCS: ::c_int = 0x0027; +pub const SO_LOCK_FILTER: ::c_int = 0x0028; +pub const SO_SELECT_ERR_QUEUE: ::c_int = 0x0029; +pub const SO_BUSY_POLL: ::c_int = 0x0030; +pub const SO_MAX_PACING_RATE: ::c_int = 0x0031; +pub const SO_BPF_EXTENSIONS: ::c_int = 0x0032; +pub const SO_INCOMING_CPU: ::c_int = 0x0033; +pub const SO_ATTACH_BPF: ::c_int = 0x0034; +pub const SO_DETACH_BPF: ::c_int = SO_DETACH_FILTER; +pub const SO_ATTACH_REUSEPORT_CBPF: ::c_int = 0x0035; +pub const SO_ATTACH_REUSEPORT_EBPF: ::c_int = 0x0036; +pub const SO_CNX_ADVICE: ::c_int = 0x0037; +pub const SCM_TIMESTAMPING_OPT_STATS: ::c_int = 0x0038; +pub const SO_MEMINFO: ::c_int = 0x0039; +pub const SO_INCOMING_NAPI_ID: ::c_int = 0x003a; +pub const SO_COOKIE: ::c_int = 0x003b; +pub const SCM_TIMESTAMPING_PKTINFO: ::c_int = 0x003c; +pub const SO_PEERGROUPS: ::c_int = 0x003d; +pub const SO_ZEROCOPY: ::c_int = 0x003e; +pub const SO_TXTIME: ::c_int = 0x003f; +pub const SCM_TXTIME: ::c_int = SO_TXTIME; +pub const SO_BINDTOIFINDEX: ::c_int = 0x0041; +pub const SO_SECURITY_AUTHENTICATION: ::c_int = 0x5001; +pub const SO_SECURITY_ENCRYPTION_TRANSPORT: ::c_int = 0x5002; +pub const SO_SECURITY_ENCRYPTION_NETWORK: ::c_int = 0x5004; +pub const SO_TIMESTAMP: ::c_int = 0x001d; +pub const SO_TIMESTAMPNS: ::c_int = 0x0021; +pub const SO_TIMESTAMPING: ::c_int = 0x0023; +// pub const SO_TIMESTAMP_OLD: ::c_int = 0x001d; +// pub const SO_TIMESTAMPNS_OLD: ::c_int = 0x0021; +// pub const SO_TIMESTAMPING_OLD: ::c_int = 0x0023; +// pub const SO_TIMESTAMP_NEW: ::c_int = 0x0046; +// pub const SO_TIMESTAMPNS_NEW: ::c_int = 0x0042; +// pub const SO_TIMESTAMPING_NEW: ::c_int = 0x0043; +// pub const SO_RCVTIMEO_NEW: ::c_int = 0x0044; +// pub const SO_SNDTIMEO_NEW: ::c_int = 0x0045; +// pub const SO_DETACH_REUSEPORT_BPF: ::c_int = 0x0047; +// pub const SO_PREFER_BUSY_POLL: ::c_int = 0x0048; +// pub const SO_BUSY_POLL_BUDGET: ::c_int = 0x0049; + +// Defined in unix/linux_like/mod.rs +// 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; +#[deprecated(since = "0.2.64", note = "Not stable across OS versions")] +pub const RLIM_NLIMITS: ::__rlimit_resource_t = 16; +#[allow(deprecated)] +#[deprecated(since = "0.2.64", note = "Not stable across OS versions")] +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; + } +} + +cfg_if! { + // Those type are constructed using the _IOC macro + // DD-SS_SSSS_SSSS_SSSS-TTTT_TTTT-NNNN_NNNN + // where D stands for direction (either None (00), Read (01) or Write (11)) + // where S stands for size (int, long, struct...) + // where T stands for type ('f','v','X'...) + // where N stands for NR (NumbeR) + if #[cfg(target_arch = "sparc")] { + pub const FS_IOC_GETFLAGS: ::Ioctl = 0x40046601; + pub const FS_IOC_SETFLAGS: ::Ioctl = 0x80046602; + pub const FS_IOC_GETVERSION: ::Ioctl = 0x40047601; + pub const FS_IOC_SETVERSION: ::Ioctl = 0x80047602; + pub const FS_IOC32_GETFLAGS: ::Ioctl = 0x40046601; + pub const FS_IOC32_SETFLAGS: ::Ioctl = 0x80046602; + pub const FS_IOC32_GETVERSION: ::Ioctl = 0x40047601; + pub const FS_IOC32_SETVERSION: ::Ioctl = 0x80047602; + } else if #[cfg(target_arch = "sparc64")] { + pub const FS_IOC_GETFLAGS: ::Ioctl = 0x40086601; + pub const FS_IOC_SETFLAGS: ::Ioctl = 0x80086602; + pub const FS_IOC_GETVERSION: ::Ioctl = 0x40087601; + pub const FS_IOC_SETVERSION: ::Ioctl = 0x80087602; + pub const FS_IOC32_GETFLAGS: ::Ioctl = 0x40046601; + pub const FS_IOC32_SETFLAGS: ::Ioctl = 0x80046602; + pub const FS_IOC32_GETVERSION: ::Ioctl = 0x40047601; + pub const FS_IOC32_SETVERSION: ::Ioctl = 0x80047602; + } +} diff --git a/vendor/libc/src/unix/linux_like/linux/gnu/align.rs b/vendor/libc/src/unix/linux_like/linux/gnu/align.rs new file mode 100644 index 0000000..4a0e074 --- /dev/null +++ b/vendor/libc/src/unix/linux_like/linux/gnu/align.rs @@ -0,0 +1,13 @@ +s! { + // FIXME this is actually a union + #[cfg_attr(target_pointer_width = "32", + repr(align(4)))] + #[cfg_attr(target_pointer_width = "64", + repr(align(8)))] + pub struct sem_t { + #[cfg(target_pointer_width = "32")] + __size: [::c_char; 16], + #[cfg(target_pointer_width = "64")] + __size: [::c_char; 32], + } +} diff --git a/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 new file mode 100644 index 0000000..2645ec4 --- /dev/null +++ b/vendor/libc/src/unix/linux_like/linux/gnu/b32/arm/align.rs @@ -0,0 +1,53 @@ +s_no_extra_traits! { + #[allow(missing_debug_implementations)] + #[repr(align(8))] + 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 new file mode 100644 index 0000000..4a14d69 --- /dev/null +++ b/vendor/libc/src/unix/linux_like/linux/gnu/b32/arm/mod.rs @@ -0,0 +1,865 @@ +pub type c_char = u8; +pub type wchar_t = u32; + +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, + f_spare: [::__fsword_t; 5], + } + + 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 { + 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 stat64 { + pub st_dev: ::dev_t, + __pad1: ::c_uint, + __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_uint, + 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_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_ino: ::ino64_t, + } + + 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 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 shmid_ds { + pub shm_perm: ::ipc_perm, + pub shm_segsz: ::size_t, + pub shm_atime: ::time_t, + __unused1: ::c_ulong, + pub shm_dtime: ::time_t, + __unused2: ::c_ulong, + pub shm_ctime: ::time_t, + __unused3: ::c_ulong, + pub shm_cpid: ::pid_t, + pub shm_lpid: ::pid_t, + pub shm_nattch: ::shmatt_t, + __unused4: ::c_ulong, + __unused5: ::c_ulong + } + + pub struct msqid_ds { + pub msg_perm: ::ipc_perm, + pub msg_stime: ::time_t, + __glibc_reserved1: ::c_ulong, + pub msg_rtime: ::time_t, + __glibc_reserved2: ::c_ulong, + pub msg_ctime: ::time_t, + __glibc_reserved3: ::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, + __glibc_reserved4: ::c_ulong, + __glibc_reserved5: ::c_ulong, + } + + 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: [usize; 0], + } + + pub struct stack_t { + pub ss_sp: *mut ::c_void, + pub ss_flags: ::c_int, + pub ss_size: ::size_t + } + + 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 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 = 0o400000; +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_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 MCL_CURRENT: ::c_int = 0x0001; +pub const MCL_FUTURE: ::c_int = 0x0002; +pub const MCL_ONFAULT: ::c_int = 0x0004; + +pub const POLLWRNORM: ::c_short = 0x100; +pub const POLLWRBAND: ::c_short = 0x200; + +pub const F_GETLK: ::c_int = 5; +pub const F_GETOWN: ::c_int = 9; +pub const F_SETOWN: ::c_int = 8; + +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; + +// Syscall table +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_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_mknod: ::c_long = 14; +pub const SYS_chmod: ::c_long = 15; +pub const SYS_lchown: ::c_long = 16; +pub const SYS_lseek: ::c_long = 19; +pub const SYS_getpid: ::c_long = 20; +pub const SYS_mount: ::c_long = 21; +pub const SYS_setuid: ::c_long = 23; +pub const SYS_getuid: ::c_long = 24; +pub const SYS_ptrace: ::c_long = 26; +pub const SYS_pause: ::c_long = 29; +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_setgid: ::c_long = 46; +pub const SYS_getgid: ::c_long = 47; +pub const SYS_geteuid: ::c_long = 49; +pub const SYS_getegid: ::c_long = 50; +pub const SYS_acct: ::c_long = 51; +pub const SYS_umount2: ::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_setreuid: ::c_long = 70; +pub const SYS_setregid: ::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_getrusage: ::c_long = 77; +pub const SYS_gettimeofday: ::c_long = 78; +pub const SYS_settimeofday: ::c_long = 79; +pub const SYS_getgroups: ::c_long = 80; +pub const SYS_setgroups: ::c_long = 81; +pub const SYS_symlink: ::c_long = 83; +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_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_fchown: ::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_syslog: ::c_long = 103; +pub const SYS_setitimer: ::c_long = 104; +pub const SYS_getitimer: ::c_long = 105; +pub const SYS_stat: ::c_long = 106; +pub const SYS_lstat: ::c_long = 107; +pub const SYS_fstat: ::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_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_uname: ::c_long = 122; +pub const SYS_adjtimex: ::c_long = 124; +pub const SYS_mprotect: ::c_long = 125; +pub const SYS_sigprocmask: ::c_long = 126; +pub const SYS_init_module: ::c_long = 128; +pub const SYS_delete_module: ::c_long = 129; +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_setfsuid: ::c_long = 138; +pub const SYS_setfsgid: ::c_long = 139; +pub const SYS__llseek: ::c_long = 140; +pub const SYS_getdents: ::c_long = 141; +pub const SYS__newselect: ::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: ::c_long = 161; +pub const SYS_nanosleep: ::c_long = 162; +pub const SYS_mremap: ::c_long = 163; +pub const SYS_setresuid: ::c_long = 164; +pub const SYS_getresuid: ::c_long = 165; +pub const SYS_poll: ::c_long = 168; +pub const SYS_nfsservctl: ::c_long = 169; +pub const SYS_setresgid: ::c_long = 170; +pub const SYS_getresgid: ::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: ::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_chown: ::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_vfork: ::c_long = 190; +pub const SYS_ugetrlimit: ::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_lchown32: ::c_long = 198; +pub const SYS_getuid32: ::c_long = 199; +pub const SYS_getgid32: ::c_long = 200; +pub const SYS_geteuid32: ::c_long = 201; +pub const SYS_getegid32: ::c_long = 202; +pub const SYS_setreuid32: ::c_long = 203; +pub const SYS_setregid32: ::c_long = 204; +pub const SYS_getgroups32: ::c_long = 205; +pub const SYS_setgroups32: ::c_long = 206; +pub const SYS_fchown32: ::c_long = 207; +pub const SYS_setresuid32: ::c_long = 208; +pub const SYS_getresuid32: ::c_long = 209; +pub const SYS_setresgid32: ::c_long = 210; +pub const SYS_getresgid32: ::c_long = 211; +pub const SYS_chown32: ::c_long = 212; +pub const SYS_setuid32: ::c_long = 213; +pub const SYS_setgid32: ::c_long = 214; +pub const SYS_setfsuid32: ::c_long = 215; +pub const SYS_setfsgid32: ::c_long = 216; +pub const SYS_getdents64: ::c_long = 217; +pub const SYS_pivot_root: ::c_long = 218; +pub const SYS_mincore: ::c_long = 219; +pub const SYS_madvise: ::c_long = 220; +pub const SYS_fcntl64: ::c_long = 221; +pub const SYS_gettid: ::c_long = 224; +pub const SYS_readahead: ::c_long = 225; +pub const SYS_setxattr: ::c_long = 226; +pub const SYS_lsetxattr: ::c_long = 227; +pub const SYS_fsetxattr: ::c_long = 228; +pub const SYS_getxattr: ::c_long = 229; +pub const SYS_lgetxattr: ::c_long = 230; +pub const SYS_fgetxattr: ::c_long = 231; +pub const SYS_listxattr: ::c_long = 232; +pub const SYS_llistxattr: ::c_long = 233; +pub const SYS_flistxattr: ::c_long = 234; +pub const SYS_removexattr: ::c_long = 235; +pub const SYS_lremovexattr: ::c_long = 236; +pub const SYS_fremovexattr: ::c_long = 237; +pub const SYS_tkill: ::c_long = 238; +pub const SYS_sendfile64: ::c_long = 239; +pub const SYS_futex: ::c_long = 240; +pub const SYS_sched_setaffinity: ::c_long = 241; +pub const SYS_sched_getaffinity: ::c_long = 242; +pub const SYS_io_setup: ::c_long = 243; +pub const SYS_io_destroy: ::c_long = 244; +pub const SYS_io_getevents: ::c_long = 245; +pub const SYS_io_submit: ::c_long = 246; +pub const SYS_io_cancel: ::c_long = 247; +pub const SYS_exit_group: ::c_long = 248; +pub const SYS_lookup_dcookie: ::c_long = 249; +pub const SYS_epoll_create: ::c_long = 250; +pub const SYS_epoll_ctl: ::c_long = 251; +pub const SYS_epoll_wait: ::c_long = 252; +pub const SYS_remap_file_pages: ::c_long = 253; +pub const SYS_set_tid_address: ::c_long = 256; +pub const SYS_timer_create: ::c_long = 257; +pub const SYS_timer_settime: ::c_long = 258; +pub const SYS_timer_gettime: ::c_long = 259; +pub const SYS_timer_getoverrun: ::c_long = 260; +pub const SYS_timer_delete: ::c_long = 261; +pub const SYS_clock_settime: ::c_long = 262; +pub const SYS_clock_gettime: ::c_long = 263; +pub const SYS_clock_getres: ::c_long = 264; +pub const SYS_clock_nanosleep: ::c_long = 265; +pub const SYS_statfs64: ::c_long = 266; +pub const SYS_fstatfs64: ::c_long = 267; +pub const SYS_tgkill: ::c_long = 268; +pub const SYS_utimes: ::c_long = 269; +pub const SYS_arm_fadvise64_64: ::c_long = 270; +pub const SYS_pciconfig_iobase: ::c_long = 271; +pub const SYS_pciconfig_read: ::c_long = 272; +pub const SYS_pciconfig_write: ::c_long = 273; +pub const SYS_mq_open: ::c_long = 274; +pub const SYS_mq_unlink: ::c_long = 275; +pub const SYS_mq_timedsend: ::c_long = 276; +pub const SYS_mq_timedreceive: ::c_long = 277; +pub const SYS_mq_notify: ::c_long = 278; +pub const SYS_mq_getsetattr: ::c_long = 279; +pub const SYS_waitid: ::c_long = 280; +pub const SYS_socket: ::c_long = 281; +pub const SYS_bind: ::c_long = 282; +pub const SYS_connect: ::c_long = 283; +pub const SYS_listen: ::c_long = 284; +pub const SYS_accept: ::c_long = 285; +pub const SYS_getsockname: ::c_long = 286; +pub const SYS_getpeername: ::c_long = 287; +pub const SYS_socketpair: ::c_long = 288; +pub const SYS_send: ::c_long = 289; +pub const SYS_sendto: ::c_long = 290; +pub const SYS_recv: ::c_long = 291; +pub const SYS_recvfrom: ::c_long = 292; +pub const SYS_shutdown: ::c_long = 293; +pub const SYS_setsockopt: ::c_long = 294; +pub const SYS_getsockopt: ::c_long = 295; +pub const SYS_sendmsg: ::c_long = 296; +pub const SYS_recvmsg: ::c_long = 297; +pub const SYS_semop: ::c_long = 298; +pub const SYS_semget: ::c_long = 299; +pub const SYS_semctl: ::c_long = 300; +pub const SYS_msgsnd: ::c_long = 301; +pub const SYS_msgrcv: ::c_long = 302; +pub const SYS_msgget: ::c_long = 303; +pub const SYS_msgctl: ::c_long = 304; +pub const SYS_shmat: ::c_long = 305; +pub const SYS_shmdt: ::c_long = 306; +pub const SYS_shmget: ::c_long = 307; +pub const SYS_shmctl: ::c_long = 308; +pub const SYS_add_key: ::c_long = 309; +pub const SYS_request_key: ::c_long = 310; +pub const SYS_keyctl: ::c_long = 311; +pub const SYS_semtimedop: ::c_long = 312; +pub const SYS_vserver: ::c_long = 313; +pub const SYS_ioprio_set: ::c_long = 314; +pub const SYS_ioprio_get: ::c_long = 315; +pub const SYS_inotify_init: ::c_long = 316; +pub const SYS_inotify_add_watch: ::c_long = 317; +pub const SYS_inotify_rm_watch: ::c_long = 318; +pub const SYS_mbind: ::c_long = 319; +pub const SYS_get_mempolicy: ::c_long = 320; +pub const SYS_set_mempolicy: ::c_long = 321; +pub const SYS_openat: ::c_long = 322; +pub const SYS_mkdirat: ::c_long = 323; +pub const SYS_mknodat: ::c_long = 324; +pub const SYS_fchownat: ::c_long = 325; +pub const SYS_futimesat: ::c_long = 326; +pub const SYS_fstatat64: ::c_long = 327; +pub const SYS_unlinkat: ::c_long = 328; +pub const SYS_renameat: ::c_long = 329; +pub const SYS_linkat: ::c_long = 330; +pub const SYS_symlinkat: ::c_long = 331; +pub const SYS_readlinkat: ::c_long = 332; +pub const SYS_fchmodat: ::c_long = 333; +pub const SYS_faccessat: ::c_long = 334; +pub const SYS_pselect6: ::c_long = 335; +pub const SYS_ppoll: ::c_long = 336; +pub const SYS_unshare: ::c_long = 337; +pub const SYS_set_robust_list: ::c_long = 338; +pub const SYS_get_robust_list: ::c_long = 339; +pub const SYS_splice: ::c_long = 340; +pub const SYS_arm_sync_file_range: ::c_long = 341; +pub const SYS_tee: ::c_long = 342; +pub const SYS_vmsplice: ::c_long = 343; +pub const SYS_move_pages: ::c_long = 344; +pub const SYS_getcpu: ::c_long = 345; +pub const SYS_epoll_pwait: ::c_long = 346; +pub const SYS_kexec_load: ::c_long = 347; +pub const SYS_utimensat: ::c_long = 348; +pub const SYS_signalfd: ::c_long = 349; +pub const SYS_timerfd_create: ::c_long = 350; +pub const SYS_eventfd: ::c_long = 351; +pub const SYS_fallocate: ::c_long = 352; +pub const SYS_timerfd_settime: ::c_long = 353; +pub const SYS_timerfd_gettime: ::c_long = 354; +pub const SYS_signalfd4: ::c_long = 355; +pub const SYS_eventfd2: ::c_long = 356; +pub const SYS_epoll_create1: ::c_long = 357; +pub const SYS_dup3: ::c_long = 358; +pub const SYS_pipe2: ::c_long = 359; +pub const SYS_inotify_init1: ::c_long = 360; +pub const SYS_preadv: ::c_long = 361; +pub const SYS_pwritev: ::c_long = 362; +pub const SYS_rt_tgsigqueueinfo: ::c_long = 363; +pub const SYS_perf_event_open: ::c_long = 364; +pub const SYS_recvmmsg: ::c_long = 365; +pub const SYS_accept4: ::c_long = 366; +pub const SYS_fanotify_init: ::c_long = 367; +pub const SYS_fanotify_mark: ::c_long = 368; +pub const SYS_prlimit64: ::c_long = 369; +pub const SYS_name_to_handle_at: ::c_long = 370; +pub const SYS_open_by_handle_at: ::c_long = 371; +pub const SYS_clock_adjtime: ::c_long = 372; +pub const SYS_syncfs: ::c_long = 373; +pub const SYS_sendmmsg: ::c_long = 374; +pub const SYS_setns: ::c_long = 375; +pub const SYS_process_vm_readv: ::c_long = 376; +pub const SYS_process_vm_writev: ::c_long = 377; +pub const SYS_kcmp: ::c_long = 378; +pub const SYS_finit_module: ::c_long = 379; +pub const SYS_sched_setattr: ::c_long = 380; +pub const SYS_sched_getattr: ::c_long = 381; +pub const SYS_renameat2: ::c_long = 382; +pub const SYS_seccomp: ::c_long = 383; +pub const SYS_getrandom: ::c_long = 384; +pub const SYS_memfd_create: ::c_long = 385; +pub const SYS_bpf: ::c_long = 386; +pub const SYS_execveat: ::c_long = 387; +pub const SYS_userfaultfd: ::c_long = 388; +pub const SYS_membarrier: ::c_long = 389; +pub const SYS_mlock2: ::c_long = 390; +pub const SYS_copy_file_range: ::c_long = 391; +pub const SYS_preadv2: ::c_long = 392; +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_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; +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; +pub const SYS_mseal: ::c_long = 462; + +cfg_if! { + if #[cfg(libc_align)] { + mod align; + pub use self::align::*; + } +} diff --git a/vendor/libc/src/unix/linux_like/linux/gnu/b32/csky/align.rs b/vendor/libc/src/unix/linux_like/linux/gnu/b32/csky/align.rs new file mode 100644 index 0000000..825546b --- /dev/null +++ b/vendor/libc/src/unix/linux_like/linux/gnu/b32/csky/align.rs @@ -0,0 +1,7 @@ +s_no_extra_traits! { + #[allow(missing_debug_implementations)] + #[repr(align(8))] + pub struct max_align_t { + priv_: [i64; 2] + } +} diff --git a/vendor/libc/src/unix/linux_like/linux/gnu/b32/csky/mod.rs b/vendor/libc/src/unix/linux_like/linux/gnu/b32/csky/mod.rs new file mode 100644 index 0000000..5e92e30 --- /dev/null +++ b/vendor/libc/src/unix/linux_like/linux/gnu/b32/csky/mod.rs @@ -0,0 +1,741 @@ +pub type c_char = u8; +pub type wchar_t = u32; + +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, + f_spare: [::__fsword_t; 5], + } + + 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 { + 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 stat64 { + pub st_dev: ::dev_t, + __pad1: ::c_uint, + __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_uint, + 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_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_ino: ::ino64_t, + } + + 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 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 shmid_ds { + pub shm_perm: ::ipc_perm, + pub shm_segsz: ::size_t, + pub shm_atime: ::time_t, + __unused1: ::c_ulong, + pub shm_dtime: ::time_t, + __unused2: ::c_ulong, + pub shm_ctime: ::time_t, + __unused3: ::c_ulong, + pub shm_cpid: ::pid_t, + pub shm_lpid: ::pid_t, + pub shm_nattch: ::shmatt_t, + __unused4: ::c_ulong, + __unused5: ::c_ulong + } + + pub struct msqid_ds { + pub msg_perm: ::ipc_perm, + pub msg_stime: ::time_t, + __glibc_reserved1: ::c_ulong, + pub msg_rtime: ::time_t, + __glibc_reserved2: ::c_ulong, + pub msg_ctime: ::time_t, + __glibc_reserved3: ::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, + __glibc_reserved4: ::c_ulong, + __glibc_reserved5: ::c_ulong, + } + + 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: [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 = 0x4000; +pub const O_DIRECTORY: ::c_int = 0x10000; +pub const O_NOFOLLOW: ::c_int = 0x20000; +pub const O_LARGEFILE: ::c_int = 0o100000; +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_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 MCL_CURRENT: ::c_int = 0x0001; +pub const MCL_FUTURE: ::c_int = 0x0002; +pub const MCL_ONFAULT: ::c_int = 0x0004; + +pub const POLLWRNORM: ::c_short = 0x100; +pub const POLLWRBAND: ::c_short = 0x200; + +pub const F_GETLK: ::c_int = 5; +pub const F_GETOWN: ::c_int = 9; +pub const F_SETOWN: ::c_int = 8; + +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; + +// Syscall table +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_rseq: ::c_long = 293; +pub const SYS_syscall: ::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_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/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..8ca7d3d --- /dev/null +++ b/vendor/libc/src/unix/linux_like/linux/gnu/b32/m68k/mod.rs @@ -0,0 +1,850 @@ +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 MCL_ONFAULT: ::c_int = 0x0004; + +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/align.rs b/vendor/libc/src/unix/linux_like/linux/gnu/b32/mips/align.rs new file mode 100644 index 0000000..8c228eb --- /dev/null +++ b/vendor/libc/src/unix/linux_like/linux/gnu/b32/mips/align.rs @@ -0,0 +1,7 @@ +s_no_extra_traits! { + #[allow(missing_debug_implementations)] + #[repr(align(8))] + pub struct max_align_t { + priv_: [f32; 4] + } +} 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 new file mode 100644 index 0000000..fa27075 --- /dev/null +++ b/vendor/libc/src/unix/linux_like/linux/gnu/b32/mips/mod.rs @@ -0,0 +1,819 @@ +pub type c_char = i8; +pub type wchar_t = i32; + +s! { + pub struct stat64 { + pub st_dev: ::c_ulong, + st_pad1: [::c_long; 3], + 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: ::c_ulong, + st_pad2: [::c_long; 2], + pub st_size: ::off64_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_blksize: ::blksize_t, + st_pad3: ::c_long, + pub st_blocks: ::blkcnt64_t, + st_pad5: [::c_long; 14], + } + + pub struct statfs { + pub f_type: ::c_long, + pub f_bsize: ::c_long, + pub f_frsize: ::c_long, + pub f_blocks: ::fsblkcnt_t, + pub f_bfree: ::fsblkcnt_t, + pub f_files: ::fsblkcnt_t, + pub f_ffree: ::fsblkcnt_t, + pub f_bavail: ::fsblkcnt_t, + pub f_fsid: ::fsid_t, + + pub f_namelen: ::c_long, + f_spare: [::c_long; 6], + } + + pub struct statfs64 { + pub f_type: ::c_long, + pub f_bsize: ::c_long, + pub f_frsize: ::c_long, + pub f_blocks: u64, + pub f_bfree: u64, + pub f_files: u64, + pub f_ffree: u64, + pub f_bavail: u64, + pub f_fsid: ::fsid_t, + pub f_namelen: ::c_long, + pub f_flags: ::c_long, + pub f_spare: [::c_long; 5], + } + + 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 sigaction { + pub sa_flags: ::c_int, + pub sa_sigaction: ::sighandler_t, + pub sa_mask: ::sigset_t, + pub sa_restorer: ::Option, + _resv: [::c_int; 1], + } + + pub struct stack_t { + pub ss_sp: *mut ::c_void, + pub ss_size: ::size_t, + pub ss_flags: ::c_int, + } + + pub struct siginfo_t { + pub si_signo: ::c_int, + pub si_code: ::c_int, + pub si_errno: ::c_int, + pub _pad: [::c_int; 29], + } + + 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, + __pad1: ::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 struct msqid_ds { + pub msg_perm: ::ipc_perm, + #[cfg(target_endian = "big")] + __glibc_reserved1: ::c_ulong, + pub msg_stime: ::time_t, + #[cfg(target_endian = "little")] + __glibc_reserved1: ::c_ulong, + #[cfg(target_endian = "big")] + __glibc_reserved2: ::c_ulong, + pub msg_rtime: ::time_t, + #[cfg(target_endian = "little")] + __glibc_reserved2: ::c_ulong, + #[cfg(target_endian = "big")] + __glibc_reserved3: ::c_ulong, + pub msg_ctime: ::time_t, + #[cfg(target_endian = "little")] + __glibc_reserved3: ::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, + __glibc_reserved4: ::c_ulong, + __glibc_reserved5: ::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_sysid: ::c_long, + pub l_pid: ::pid_t, + pad: [::c_long; 4], + } +} + +pub const O_LARGEFILE: ::c_int = 0x2000; + +pub const SYS_syscall: ::c_long = 4000 + 0; +pub const SYS_exit: ::c_long = 4000 + 1; +pub const SYS_fork: ::c_long = 4000 + 2; +pub const SYS_read: ::c_long = 4000 + 3; +pub const SYS_write: ::c_long = 4000 + 4; +pub const SYS_open: ::c_long = 4000 + 5; +pub const SYS_close: ::c_long = 4000 + 6; +pub const SYS_waitpid: ::c_long = 4000 + 7; +pub const SYS_creat: ::c_long = 4000 + 8; +pub const SYS_link: ::c_long = 4000 + 9; +pub const SYS_unlink: ::c_long = 4000 + 10; +pub const SYS_execve: ::c_long = 4000 + 11; +pub const SYS_chdir: ::c_long = 4000 + 12; +pub const SYS_time: ::c_long = 4000 + 13; +pub const SYS_mknod: ::c_long = 4000 + 14; +pub const SYS_chmod: ::c_long = 4000 + 15; +pub const SYS_lchown: ::c_long = 4000 + 16; +pub const SYS_break: ::c_long = 4000 + 17; +pub const SYS_lseek: ::c_long = 4000 + 19; +pub const SYS_getpid: ::c_long = 4000 + 20; +pub const SYS_mount: ::c_long = 4000 + 21; +pub const SYS_umount: ::c_long = 4000 + 22; +pub const SYS_setuid: ::c_long = 4000 + 23; +pub const SYS_getuid: ::c_long = 4000 + 24; +pub const SYS_stime: ::c_long = 4000 + 25; +pub const SYS_ptrace: ::c_long = 4000 + 26; +pub const SYS_alarm: ::c_long = 4000 + 27; +pub const SYS_pause: ::c_long = 4000 + 29; +pub const SYS_utime: ::c_long = 4000 + 30; +pub const SYS_stty: ::c_long = 4000 + 31; +pub const SYS_gtty: ::c_long = 4000 + 32; +pub const SYS_access: ::c_long = 4000 + 33; +pub const SYS_nice: ::c_long = 4000 + 34; +pub const SYS_ftime: ::c_long = 4000 + 35; +pub const SYS_sync: ::c_long = 4000 + 36; +pub const SYS_kill: ::c_long = 4000 + 37; +pub const SYS_rename: ::c_long = 4000 + 38; +pub const SYS_mkdir: ::c_long = 4000 + 39; +pub const SYS_rmdir: ::c_long = 4000 + 40; +pub const SYS_dup: ::c_long = 4000 + 41; +pub const SYS_pipe: ::c_long = 4000 + 42; +pub const SYS_times: ::c_long = 4000 + 43; +pub const SYS_prof: ::c_long = 4000 + 44; +pub const SYS_brk: ::c_long = 4000 + 45; +pub const SYS_setgid: ::c_long = 4000 + 46; +pub const SYS_getgid: ::c_long = 4000 + 47; +pub const SYS_signal: ::c_long = 4000 + 48; +pub const SYS_geteuid: ::c_long = 4000 + 49; +pub const SYS_getegid: ::c_long = 4000 + 50; +pub const SYS_acct: ::c_long = 4000 + 51; +pub const SYS_umount2: ::c_long = 4000 + 52; +pub const SYS_lock: ::c_long = 4000 + 53; +pub const SYS_ioctl: ::c_long = 4000 + 54; +pub const SYS_fcntl: ::c_long = 4000 + 55; +pub const SYS_mpx: ::c_long = 4000 + 56; +pub const SYS_setpgid: ::c_long = 4000 + 57; +pub const SYS_ulimit: ::c_long = 4000 + 58; +pub const SYS_umask: ::c_long = 4000 + 60; +pub const SYS_chroot: ::c_long = 4000 + 61; +pub const SYS_ustat: ::c_long = 4000 + 62; +pub const SYS_dup2: ::c_long = 4000 + 63; +pub const SYS_getppid: ::c_long = 4000 + 64; +pub const SYS_getpgrp: ::c_long = 4000 + 65; +pub const SYS_setsid: ::c_long = 4000 + 66; +pub const SYS_sigaction: ::c_long = 4000 + 67; +pub const SYS_sgetmask: ::c_long = 4000 + 68; +pub const SYS_ssetmask: ::c_long = 4000 + 69; +pub const SYS_setreuid: ::c_long = 4000 + 70; +pub const SYS_setregid: ::c_long = 4000 + 71; +pub const SYS_sigsuspend: ::c_long = 4000 + 72; +pub const SYS_sigpending: ::c_long = 4000 + 73; +pub const SYS_sethostname: ::c_long = 4000 + 74; +pub const SYS_setrlimit: ::c_long = 4000 + 75; +pub const SYS_getrlimit: ::c_long = 4000 + 76; +pub const SYS_getrusage: ::c_long = 4000 + 77; +pub const SYS_gettimeofday: ::c_long = 4000 + 78; +pub const SYS_settimeofday: ::c_long = 4000 + 79; +pub const SYS_getgroups: ::c_long = 4000 + 80; +pub const SYS_setgroups: ::c_long = 4000 + 81; +pub const SYS_symlink: ::c_long = 4000 + 83; +pub const SYS_readlink: ::c_long = 4000 + 85; +pub const SYS_uselib: ::c_long = 4000 + 86; +pub const SYS_swapon: ::c_long = 4000 + 87; +pub const SYS_reboot: ::c_long = 4000 + 88; +pub const SYS_readdir: ::c_long = 4000 + 89; +pub const SYS_mmap: ::c_long = 4000 + 90; +pub const SYS_munmap: ::c_long = 4000 + 91; +pub const SYS_truncate: ::c_long = 4000 + 92; +pub const SYS_ftruncate: ::c_long = 4000 + 93; +pub const SYS_fchmod: ::c_long = 4000 + 94; +pub const SYS_fchown: ::c_long = 4000 + 95; +pub const SYS_getpriority: ::c_long = 4000 + 96; +pub const SYS_setpriority: ::c_long = 4000 + 97; +pub const SYS_profil: ::c_long = 4000 + 98; +pub const SYS_statfs: ::c_long = 4000 + 99; +pub const SYS_fstatfs: ::c_long = 4000 + 100; +pub const SYS_ioperm: ::c_long = 4000 + 101; +pub const SYS_socketcall: ::c_long = 4000 + 102; +pub const SYS_syslog: ::c_long = 4000 + 103; +pub const SYS_setitimer: ::c_long = 4000 + 104; +pub const SYS_getitimer: ::c_long = 4000 + 105; +pub const SYS_stat: ::c_long = 4000 + 106; +pub const SYS_lstat: ::c_long = 4000 + 107; +pub const SYS_fstat: ::c_long = 4000 + 108; +pub const SYS_iopl: ::c_long = 4000 + 110; +pub const SYS_vhangup: ::c_long = 4000 + 111; +pub const SYS_idle: ::c_long = 4000 + 112; +pub const SYS_vm86: ::c_long = 4000 + 113; +pub const SYS_wait4: ::c_long = 4000 + 114; +pub const SYS_swapoff: ::c_long = 4000 + 115; +pub const SYS_sysinfo: ::c_long = 4000 + 116; +pub const SYS_ipc: ::c_long = 4000 + 117; +pub const SYS_fsync: ::c_long = 4000 + 118; +pub const SYS_sigreturn: ::c_long = 4000 + 119; +pub const SYS_clone: ::c_long = 4000 + 120; +pub const SYS_setdomainname: ::c_long = 4000 + 121; +pub const SYS_uname: ::c_long = 4000 + 122; +pub const SYS_modify_ldt: ::c_long = 4000 + 123; +pub const SYS_adjtimex: ::c_long = 4000 + 124; +pub const SYS_mprotect: ::c_long = 4000 + 125; +pub const SYS_sigprocmask: ::c_long = 4000 + 126; +pub const SYS_create_module: ::c_long = 4000 + 127; +pub const SYS_init_module: ::c_long = 4000 + 128; +pub const SYS_delete_module: ::c_long = 4000 + 129; +pub const SYS_get_kernel_syms: ::c_long = 4000 + 130; +pub const SYS_quotactl: ::c_long = 4000 + 131; +pub const SYS_getpgid: ::c_long = 4000 + 132; +pub const SYS_fchdir: ::c_long = 4000 + 133; +pub const SYS_bdflush: ::c_long = 4000 + 134; +pub const SYS_sysfs: ::c_long = 4000 + 135; +pub const SYS_personality: ::c_long = 4000 + 136; +pub const SYS_afs_syscall: ::c_long = 4000 + 137; +pub const SYS_setfsuid: ::c_long = 4000 + 138; +pub const SYS_setfsgid: ::c_long = 4000 + 139; +pub const SYS__llseek: ::c_long = 4000 + 140; +pub const SYS_getdents: ::c_long = 4000 + 141; +pub const SYS__newselect: ::c_long = 4000 + 142; +pub const SYS_flock: ::c_long = 4000 + 143; +pub const SYS_msync: ::c_long = 4000 + 144; +pub const SYS_readv: ::c_long = 4000 + 145; +pub const SYS_writev: ::c_long = 4000 + 146; +pub const SYS_cacheflush: ::c_long = 4000 + 147; +pub const SYS_cachectl: ::c_long = 4000 + 148; +pub const SYS_sysmips: ::c_long = 4000 + 149; +pub const SYS_getsid: ::c_long = 4000 + 151; +pub const SYS_fdatasync: ::c_long = 4000 + 152; +pub const SYS__sysctl: ::c_long = 4000 + 153; +pub const SYS_mlock: ::c_long = 4000 + 154; +pub const SYS_munlock: ::c_long = 4000 + 155; +pub const SYS_mlockall: ::c_long = 4000 + 156; +pub const SYS_munlockall: ::c_long = 4000 + 157; +pub const SYS_sched_setparam: ::c_long = 4000 + 158; +pub const SYS_sched_getparam: ::c_long = 4000 + 159; +pub const SYS_sched_setscheduler: ::c_long = 4000 + 160; +pub const SYS_sched_getscheduler: ::c_long = 4000 + 161; +pub const SYS_sched_yield: ::c_long = 4000 + 162; +pub const SYS_sched_get_priority_max: ::c_long = 4000 + 163; +pub const SYS_sched_get_priority_min: ::c_long = 4000 + 164; +pub const SYS_sched_rr_get_interval: ::c_long = 4000 + 165; +pub const SYS_nanosleep: ::c_long = 4000 + 166; +pub const SYS_mremap: ::c_long = 4000 + 167; +pub const SYS_accept: ::c_long = 4000 + 168; +pub const SYS_bind: ::c_long = 4000 + 169; +pub const SYS_connect: ::c_long = 4000 + 170; +pub const SYS_getpeername: ::c_long = 4000 + 171; +pub const SYS_getsockname: ::c_long = 4000 + 172; +pub const SYS_getsockopt: ::c_long = 4000 + 173; +pub const SYS_listen: ::c_long = 4000 + 174; +pub const SYS_recv: ::c_long = 4000 + 175; +pub const SYS_recvfrom: ::c_long = 4000 + 176; +pub const SYS_recvmsg: ::c_long = 4000 + 177; +pub const SYS_send: ::c_long = 4000 + 178; +pub const SYS_sendmsg: ::c_long = 4000 + 179; +pub const SYS_sendto: ::c_long = 4000 + 180; +pub const SYS_setsockopt: ::c_long = 4000 + 181; +pub const SYS_shutdown: ::c_long = 4000 + 182; +pub const SYS_socket: ::c_long = 4000 + 183; +pub const SYS_socketpair: ::c_long = 4000 + 184; +pub const SYS_setresuid: ::c_long = 4000 + 185; +pub const SYS_getresuid: ::c_long = 4000 + 186; +pub const SYS_query_module: ::c_long = 4000 + 187; +pub const SYS_poll: ::c_long = 4000 + 188; +pub const SYS_nfsservctl: ::c_long = 4000 + 189; +pub const SYS_setresgid: ::c_long = 4000 + 190; +pub const SYS_getresgid: ::c_long = 4000 + 191; +pub const SYS_prctl: ::c_long = 4000 + 192; +pub const SYS_rt_sigreturn: ::c_long = 4000 + 193; +pub const SYS_rt_sigaction: ::c_long = 4000 + 194; +pub const SYS_rt_sigprocmask: ::c_long = 4000 + 195; +pub const SYS_rt_sigpending: ::c_long = 4000 + 196; +pub const SYS_rt_sigtimedwait: ::c_long = 4000 + 197; +pub const SYS_rt_sigqueueinfo: ::c_long = 4000 + 198; +pub const SYS_rt_sigsuspend: ::c_long = 4000 + 199; +pub const SYS_pread64: ::c_long = 4000 + 200; +pub const SYS_pwrite64: ::c_long = 4000 + 201; +pub const SYS_chown: ::c_long = 4000 + 202; +pub const SYS_getcwd: ::c_long = 4000 + 203; +pub const SYS_capget: ::c_long = 4000 + 204; +pub const SYS_capset: ::c_long = 4000 + 205; +pub const SYS_sigaltstack: ::c_long = 4000 + 206; +pub const SYS_sendfile: ::c_long = 4000 + 207; +pub const SYS_getpmsg: ::c_long = 4000 + 208; +pub const SYS_putpmsg: ::c_long = 4000 + 209; +pub const SYS_mmap2: ::c_long = 4000 + 210; +pub const SYS_truncate64: ::c_long = 4000 + 211; +pub const SYS_ftruncate64: ::c_long = 4000 + 212; +pub const SYS_stat64: ::c_long = 4000 + 213; +pub const SYS_lstat64: ::c_long = 4000 + 214; +pub const SYS_fstat64: ::c_long = 4000 + 215; +pub const SYS_pivot_root: ::c_long = 4000 + 216; +pub const SYS_mincore: ::c_long = 4000 + 217; +pub const SYS_madvise: ::c_long = 4000 + 218; +pub const SYS_getdents64: ::c_long = 4000 + 219; +pub const SYS_fcntl64: ::c_long = 4000 + 220; +pub const SYS_gettid: ::c_long = 4000 + 222; +pub const SYS_readahead: ::c_long = 4000 + 223; +pub const SYS_setxattr: ::c_long = 4000 + 224; +pub const SYS_lsetxattr: ::c_long = 4000 + 225; +pub const SYS_fsetxattr: ::c_long = 4000 + 226; +pub const SYS_getxattr: ::c_long = 4000 + 227; +pub const SYS_lgetxattr: ::c_long = 4000 + 228; +pub const SYS_fgetxattr: ::c_long = 4000 + 229; +pub const SYS_listxattr: ::c_long = 4000 + 230; +pub const SYS_llistxattr: ::c_long = 4000 + 231; +pub const SYS_flistxattr: ::c_long = 4000 + 232; +pub const SYS_removexattr: ::c_long = 4000 + 233; +pub const SYS_lremovexattr: ::c_long = 4000 + 234; +pub const SYS_fremovexattr: ::c_long = 4000 + 235; +pub const SYS_tkill: ::c_long = 4000 + 236; +pub const SYS_sendfile64: ::c_long = 4000 + 237; +pub const SYS_futex: ::c_long = 4000 + 238; +pub const SYS_sched_setaffinity: ::c_long = 4000 + 239; +pub const SYS_sched_getaffinity: ::c_long = 4000 + 240; +pub const SYS_io_setup: ::c_long = 4000 + 241; +pub const SYS_io_destroy: ::c_long = 4000 + 242; +pub const SYS_io_getevents: ::c_long = 4000 + 243; +pub const SYS_io_submit: ::c_long = 4000 + 244; +pub const SYS_io_cancel: ::c_long = 4000 + 245; +pub const SYS_exit_group: ::c_long = 4000 + 246; +pub const SYS_lookup_dcookie: ::c_long = 4000 + 247; +pub const SYS_epoll_create: ::c_long = 4000 + 248; +pub const SYS_epoll_ctl: ::c_long = 4000 + 249; +pub const SYS_epoll_wait: ::c_long = 4000 + 250; +pub const SYS_remap_file_pages: ::c_long = 4000 + 251; +pub const SYS_set_tid_address: ::c_long = 4000 + 252; +pub const SYS_restart_syscall: ::c_long = 4000 + 253; +pub const SYS_fadvise64: ::c_long = 4000 + 254; +pub const SYS_statfs64: ::c_long = 4000 + 255; +pub const SYS_fstatfs64: ::c_long = 4000 + 256; +pub const SYS_timer_create: ::c_long = 4000 + 257; +pub const SYS_timer_settime: ::c_long = 4000 + 258; +pub const SYS_timer_gettime: ::c_long = 4000 + 259; +pub const SYS_timer_getoverrun: ::c_long = 4000 + 260; +pub const SYS_timer_delete: ::c_long = 4000 + 261; +pub const SYS_clock_settime: ::c_long = 4000 + 262; +pub const SYS_clock_gettime: ::c_long = 4000 + 263; +pub const SYS_clock_getres: ::c_long = 4000 + 264; +pub const SYS_clock_nanosleep: ::c_long = 4000 + 265; +pub const SYS_tgkill: ::c_long = 4000 + 266; +pub const SYS_utimes: ::c_long = 4000 + 267; +pub const SYS_mbind: ::c_long = 4000 + 268; +pub const SYS_get_mempolicy: ::c_long = 4000 + 269; +pub const SYS_set_mempolicy: ::c_long = 4000 + 270; +pub const SYS_mq_open: ::c_long = 4000 + 271; +pub const SYS_mq_unlink: ::c_long = 4000 + 272; +pub const SYS_mq_timedsend: ::c_long = 4000 + 273; +pub const SYS_mq_timedreceive: ::c_long = 4000 + 274; +pub const SYS_mq_notify: ::c_long = 4000 + 275; +pub const SYS_mq_getsetattr: ::c_long = 4000 + 276; +pub const SYS_vserver: ::c_long = 4000 + 277; +pub const SYS_waitid: ::c_long = 4000 + 278; +/* pub const SYS_sys_setaltroot: ::c_long = 4000 + 279; */ +pub const SYS_add_key: ::c_long = 4000 + 280; +pub const SYS_request_key: ::c_long = 4000 + 281; +pub const SYS_keyctl: ::c_long = 4000 + 282; +pub const SYS_set_thread_area: ::c_long = 4000 + 283; +pub const SYS_inotify_init: ::c_long = 4000 + 284; +pub const SYS_inotify_add_watch: ::c_long = 4000 + 285; +pub const SYS_inotify_rm_watch: ::c_long = 4000 + 286; +pub const SYS_migrate_pages: ::c_long = 4000 + 287; +pub const SYS_openat: ::c_long = 4000 + 288; +pub const SYS_mkdirat: ::c_long = 4000 + 289; +pub const SYS_mknodat: ::c_long = 4000 + 290; +pub const SYS_fchownat: ::c_long = 4000 + 291; +pub const SYS_futimesat: ::c_long = 4000 + 292; +pub const SYS_fstatat64: ::c_long = 4000 + 293; +pub const SYS_unlinkat: ::c_long = 4000 + 294; +pub const SYS_renameat: ::c_long = 4000 + 295; +pub const SYS_linkat: ::c_long = 4000 + 296; +pub const SYS_symlinkat: ::c_long = 4000 + 297; +pub const SYS_readlinkat: ::c_long = 4000 + 298; +pub const SYS_fchmodat: ::c_long = 4000 + 299; +pub const SYS_faccessat: ::c_long = 4000 + 300; +pub const SYS_pselect6: ::c_long = 4000 + 301; +pub const SYS_ppoll: ::c_long = 4000 + 302; +pub const SYS_unshare: ::c_long = 4000 + 303; +pub const SYS_splice: ::c_long = 4000 + 304; +pub const SYS_sync_file_range: ::c_long = 4000 + 305; +pub const SYS_tee: ::c_long = 4000 + 306; +pub const SYS_vmsplice: ::c_long = 4000 + 307; +pub const SYS_move_pages: ::c_long = 4000 + 308; +pub const SYS_set_robust_list: ::c_long = 4000 + 309; +pub const SYS_get_robust_list: ::c_long = 4000 + 310; +pub const SYS_kexec_load: ::c_long = 4000 + 311; +pub const SYS_getcpu: ::c_long = 4000 + 312; +pub const SYS_epoll_pwait: ::c_long = 4000 + 313; +pub const SYS_ioprio_set: ::c_long = 4000 + 314; +pub const SYS_ioprio_get: ::c_long = 4000 + 315; +pub const SYS_utimensat: ::c_long = 4000 + 316; +pub const SYS_signalfd: ::c_long = 4000 + 317; +pub const SYS_timerfd: ::c_long = 4000 + 318; +pub const SYS_eventfd: ::c_long = 4000 + 319; +pub const SYS_fallocate: ::c_long = 4000 + 320; +pub const SYS_timerfd_create: ::c_long = 4000 + 321; +pub const SYS_timerfd_gettime: ::c_long = 4000 + 322; +pub const SYS_timerfd_settime: ::c_long = 4000 + 323; +pub const SYS_signalfd4: ::c_long = 4000 + 324; +pub const SYS_eventfd2: ::c_long = 4000 + 325; +pub const SYS_epoll_create1: ::c_long = 4000 + 326; +pub const SYS_dup3: ::c_long = 4000 + 327; +pub const SYS_pipe2: ::c_long = 4000 + 328; +pub const SYS_inotify_init1: ::c_long = 4000 + 329; +pub const SYS_preadv: ::c_long = 4000 + 330; +pub const SYS_pwritev: ::c_long = 4000 + 331; +pub const SYS_rt_tgsigqueueinfo: ::c_long = 4000 + 332; +pub const SYS_perf_event_open: ::c_long = 4000 + 333; +pub const SYS_accept4: ::c_long = 4000 + 334; +pub const SYS_recvmmsg: ::c_long = 4000 + 335; +pub const SYS_fanotify_init: ::c_long = 4000 + 336; +pub const SYS_fanotify_mark: ::c_long = 4000 + 337; +pub const SYS_prlimit64: ::c_long = 4000 + 338; +pub const SYS_name_to_handle_at: ::c_long = 4000 + 339; +pub const SYS_open_by_handle_at: ::c_long = 4000 + 340; +pub const SYS_clock_adjtime: ::c_long = 4000 + 341; +pub const SYS_syncfs: ::c_long = 4000 + 342; +pub const SYS_sendmmsg: ::c_long = 4000 + 343; +pub const SYS_setns: ::c_long = 4000 + 344; +pub const SYS_process_vm_readv: ::c_long = 4000 + 345; +pub const SYS_process_vm_writev: ::c_long = 4000 + 346; +pub const SYS_kcmp: ::c_long = 4000 + 347; +pub const SYS_finit_module: ::c_long = 4000 + 348; +pub const SYS_sched_setattr: ::c_long = 4000 + 349; +pub const SYS_sched_getattr: ::c_long = 4000 + 350; +pub const SYS_renameat2: ::c_long = 4000 + 351; +pub const SYS_seccomp: ::c_long = 4000 + 352; +pub const SYS_getrandom: ::c_long = 4000 + 353; +pub const SYS_memfd_create: ::c_long = 4000 + 354; +pub const SYS_bpf: ::c_long = 4000 + 355; +pub const SYS_execveat: ::c_long = 4000 + 356; +pub const SYS_userfaultfd: ::c_long = 4000 + 357; +pub const SYS_membarrier: ::c_long = 4000 + 358; +pub const SYS_mlock2: ::c_long = 4000 + 359; +pub const SYS_copy_file_range: ::c_long = 4000 + 360; +pub const SYS_preadv2: ::c_long = 4000 + 361; +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_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; +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; + +pub const O_DIRECT: ::c_int = 0x8000; +pub const O_DIRECTORY: ::c_int = 0x10000; +pub const O_NOFOLLOW: ::c_int = 0x20000; + +pub const O_APPEND: ::c_int = 8; +pub const O_CREAT: ::c_int = 256; +pub const O_EXCL: ::c_int = 1024; +pub const O_NOCTTY: ::c_int = 2048; +pub const O_NONBLOCK: ::c_int = 128; +pub const O_SYNC: ::c_int = 0x4010; +pub const O_RSYNC: ::c_int = 0x4010; +pub const O_DSYNC: ::c_int = 0x10; +pub const O_FSYNC: ::c_int = 0x4010; +pub const O_ASYNC: ::c_int = 0x1000; +pub const O_NDELAY: ::c_int = 0x80; + +pub const EDEADLK: ::c_int = 45; +pub const ENAMETOOLONG: ::c_int = 78; +pub const ENOLCK: ::c_int = 46; +pub const ENOSYS: ::c_int = 89; +pub const ENOTEMPTY: ::c_int = 93; +pub const ELOOP: ::c_int = 90; +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 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 EMULTIHOP: ::c_int = 74; +pub const EOVERFLOW: ::c_int = 79; +pub const ENOTUNIQ: ::c_int = 80; +pub const EBADFD: ::c_int = 81; +pub const EBADMSG: ::c_int = 77; +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 ERESTART: ::c_int = 91; +pub const ESTRPIPE: ::c_int = 92; +pub const EUSERS: ::c_int = 94; +pub const ENOTSOCK: ::c_int = 95; +pub const EDESTADDRREQ: ::c_int = 96; +pub const EMSGSIZE: ::c_int = 97; +pub const EPROTOTYPE: ::c_int = 98; +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 EPFNOSUPPORT: ::c_int = 123; +pub const EAFNOSUPPORT: ::c_int = 124; +pub const EADDRINUSE: ::c_int = 125; +pub const EADDRNOTAVAIL: ::c_int = 126; +pub const ENETDOWN: ::c_int = 127; +pub const ENETUNREACH: ::c_int = 128; +pub const ENETRESET: ::c_int = 129; +pub const ECONNABORTED: ::c_int = 130; +pub const ECONNRESET: ::c_int = 131; +pub const ENOBUFS: ::c_int = 132; +pub const EISCONN: ::c_int = 133; +pub const ENOTCONN: ::c_int = 134; +pub const ESHUTDOWN: ::c_int = 143; +pub const ETOOMANYREFS: ::c_int = 144; +pub const ETIMEDOUT: ::c_int = 145; +pub const ECONNREFUSED: ::c_int = 146; +pub const EHOSTDOWN: ::c_int = 147; +pub const EHOSTUNREACH: ::c_int = 148; +pub const EALREADY: ::c_int = 149; +pub const EINPROGRESS: ::c_int = 150; +pub const ESTALE: ::c_int = 151; +pub const EUCLEAN: ::c_int = 135; +pub const ENOTNAM: ::c_int = 137; +pub const ENAVAIL: ::c_int = 138; +pub const EISNAM: ::c_int = 139; +pub const EREMOTEIO: ::c_int = 140; +pub const EDQUOT: ::c_int = 1133; +pub const ENOMEDIUM: ::c_int = 159; +pub const EMEDIUMTYPE: ::c_int = 160; +pub const ECANCELED: ::c_int = 158; +pub const ENOKEY: ::c_int = 161; +pub const EKEYEXPIRED: ::c_int = 162; +pub const EKEYREVOKED: ::c_int = 163; +pub const EKEYREJECTED: ::c_int = 164; +pub const EOWNERDEAD: ::c_int = 165; +pub const ENOTRECOVERABLE: ::c_int = 166; +pub const ERFKILL: ::c_int = 167; + +pub const MAP_NORESERVE: ::c_int = 0x400; +pub const MAP_ANON: ::c_int = 0x800; +pub const MAP_ANONYMOUS: ::c_int = 0x800; +pub const MAP_GROWSDOWN: ::c_int = 0x1000; +pub const MAP_DENYWRITE: ::c_int = 0x2000; +pub const MAP_EXECUTABLE: ::c_int = 0x4000; +pub const MAP_LOCKED: ::c_int = 0x8000; +pub const MAP_POPULATE: ::c_int = 0x10000; +pub const MAP_NONBLOCK: ::c_int = 0x20000; +pub const MAP_STACK: ::c_int = 0x40000; + +pub const SOCK_STREAM: ::c_int = 2; +pub const SOCK_DGRAM: ::c_int = 1; + +pub const SA_SIGINFO: ::c_int = 0x00000008; +pub const SA_NOCLDWAIT: ::c_int = 0x00010000; + +pub const SIGCHLD: ::c_int = 18; +pub const SIGBUS: ::c_int = 10; +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 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 = 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; +pub const SIG_UNBLOCK: ::c_int = 0x2; + +pub const POLLWRNORM: ::c_short = 0x004; +pub const POLLWRBAND: ::c_short = 0x100; + +pub const VEOF: usize = 16; +pub const VEOL: usize = 17; +pub const VEOL2: usize = 6; +pub const VMIN: usize = 4; +pub const IEXTEN: ::tcflag_t = 0x00000100; +pub const TOSTOP: ::tcflag_t = 0x00008000; +pub const FLUSHO: ::tcflag_t = 0x00002000; +pub const EXTPROC: ::tcflag_t = 0o200000; +pub const TCSANOW: ::c_int = 0x540e; +pub const TCSADRAIN: ::c_int = 0x540f; +pub const TCSAFLUSH: ::c_int = 0x5410; + +pub const PTRACE_GETFPXREGS: ::c_uint = 18; +pub const PTRACE_SETFPXREGS: ::c_uint = 19; + +pub const MAP_HUGETLB: ::c_int = 0x080000; + +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 SFD_NONBLOCK: ::c_int = 0x80; + +pub const RTLD_DEEPBIND: ::c_int = 0x10; +pub const RTLD_GLOBAL: ::c_int = 0x4; +pub const RTLD_NOLOAD: ::c_int = 0x8; + +pub const MCL_CURRENT: ::c_int = 0x0001; +pub const MCL_FUTURE: ::c_int = 0x0002; +pub const MCL_ONFAULT: ::c_int = 0x0004; + +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 EHWPOISON: ::c_int = 168; + +cfg_if! { + if #[cfg(libc_align)] { + mod align; + pub use self::align::*; + } +} 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 new file mode 100644 index 0000000..d5b1134 --- /dev/null +++ b/vendor/libc/src/unix/linux_like/linux/gnu/b32/mod.rs @@ -0,0 +1,361 @@ +//! 32-bit specific definitions for linux-like values + +use pthread_mutex_t; + +pub type c_long = i32; +pub type c_ulong = u32; +pub type clock_t = i32; + +pub type shmatt_t = ::c_ulong; +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")] { + pub type time_t = i64; + pub type suseconds_t = i64; + pub type ino_t = u64; + pub type off_t = i64; + pub type blkcnt_t = i64; + pub type fsblkcnt_t = u64; + pub type fsfilcnt_t = u64; + pub type rlim_t = u64; + pub type blksize_t = i64; + } else { + pub type time_t = i32; + pub type suseconds_t = i32; + pub type ino_t = u32; + pub type off_t = i32; + pub type blkcnt_t = i32; + pub type fsblkcnt_t = ::c_ulong; + pub type fsfilcnt_t = ::c_ulong; + pub type rlim_t = c_ulong; + pub type blksize_t = i32; + } +} + +s! { + pub struct stat { + #[cfg(not(any(target_arch = "mips", target_arch = "mips32r6")))] + pub st_dev: ::dev_t, + #[cfg(any(target_arch = "mips", target_arch = "mips32r6"))] + pub st_dev: ::c_ulong, + + #[cfg(not(any(target_arch = "mips", target_arch = "mips32r6")))] + __pad1: ::c_short, + #[cfg(any(target_arch = "mips", target_arch = "mips32r6"))] + st_pad1: [::c_long; 3], + 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, + #[cfg(not(any(target_arch = "mips", target_arch = "mips32r6")))] + pub st_rdev: ::dev_t, + #[cfg(any(target_arch = "mips", target_arch = "mips32r6"))] + pub st_rdev: ::c_ulong, + #[cfg(not(any(target_arch = "mips", target_arch = "mips32r6")))] + __pad2: ::c_short, + #[cfg(any(target_arch = "mips", target_arch = "mips32r6"))] + st_pad2: [::c_long; 2], + pub st_size: ::off_t, + #[cfg(any(target_arch = "mips", target_arch = "mips32r6"))] + st_pad3: ::c_long, + #[cfg(not(any(target_arch = "mips", target_arch = "mips32r6")))] + pub st_blksize: ::blksize_t, + #[cfg(not(any(target_arch = "mips", target_arch = "mips32r6")))] + 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, + #[cfg(not(any(target_arch = "mips", target_arch = "mips32r6")))] + __unused4: ::c_long, + #[cfg(not(any(target_arch = "mips", target_arch = "mips32r6")))] + __unused5: ::c_long, + #[cfg(any(target_arch = "mips", target_arch = "mips32r6"))] + pub st_blksize: ::blksize_t, + #[cfg(any(target_arch = "mips", target_arch = "mips32r6"))] + pub st_blocks: ::blkcnt_t, + #[cfg(any(target_arch = "mips", target_arch = "mips32r6"))] + st_pad5: [::c_long; 14], + } + + 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, + __f_unused: ::c_int, + pub f_flag: ::c_ulong, + pub f_namemax: ::c_ulong, + __f_spare: [::c_int; 6], + } + + pub struct pthread_attr_t { + __size: [u32; 9] + } + + pub struct sigset_t { + __val: [::c_ulong; 32], + } + + pub struct sysinfo { + pub uptime: ::c_long, + pub loads: [::c_ulong; 3], + pub totalram: ::c_ulong, + pub freeram: ::c_ulong, + pub sharedram: ::c_ulong, + pub bufferram: ::c_ulong, + pub totalswap: ::c_ulong, + pub freeswap: ::c_ulong, + pub procs: ::c_ushort, + #[deprecated( + since = "0.2.58", + note = "This padding field might become private in the future" + )] + pub pad: ::c_ushort, + pub totalhigh: ::c_ulong, + pub freehigh: ::c_ulong, + pub mem_unit: ::c_uint, + pub _f: [::c_char; 8], + } + + 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 = "mips32r6", 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 = "mips32r6", target_arch = "powerpc")))] + __reserved2: ::__syscall_ulong_t, + pub sem_nsems: ::__syscall_ulong_t, + __glibc_reserved3: ::__syscall_ulong_t, + __glibc_reserved4: ::__syscall_ulong_t, + } +} + +pub const POSIX_FADV_DONTNEED: ::c_int = 4; +pub const POSIX_FADV_NOREUSE: ::c_int = 5; + +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 __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")] { + pub const O_NOATIME: ::c_int = 0x200000; + pub const O_PATH: ::c_int = 0x1000000; + pub const O_TMPFILE: ::c_int = 0x2000000 | O_DIRECTORY; + + pub const SA_ONSTACK: ::c_int = 1; + + pub const PTRACE_DETACH: ::c_uint = 11; + + pub const F_SETLK: ::c_int = 8; + pub const F_SETLKW: ::c_int = 9; + + pub const F_RDLCK: ::c_int = 1; + pub const F_WRLCK: ::c_int = 2; + pub const F_UNLCK: ::c_int = 3; + + pub const SFD_CLOEXEC: ::c_int = 0x400000; + + pub const NCCS: usize = 17; + + pub const O_TRUNC: ::c_int = 0x400; + pub const O_CLOEXEC: ::c_int = 0x400000; + + pub const EBFONT: ::c_int = 109; + pub const ENOSTR: ::c_int = 72; + pub const ENODATA: ::c_int = 111; + pub const ETIME: ::c_int = 73; + pub const ENOSR: ::c_int = 74; + pub const ENONET: ::c_int = 80; + pub const ENOPKG: ::c_int = 113; + pub const EREMOTE: ::c_int = 71; + pub const ENOLINK: ::c_int = 82; + pub const EADV: ::c_int = 83; + pub const ESRMNT: ::c_int = 84; + pub const ECOMM: ::c_int = 85; + pub const EPROTO: ::c_int = 86; + pub const EDOTDOT: ::c_int = 88; + + pub const SA_NODEFER: ::c_int = 0x20; + pub const SA_RESETHAND: ::c_int = 0x4; + pub const SA_RESTART: ::c_int = 0x2; + pub const SA_NOCLDSTOP: ::c_int = 0x00000008; + + pub const EPOLL_CLOEXEC: ::c_int = 0x400000; + + pub const EFD_CLOEXEC: ::c_int = 0x400000; + } else { + pub const O_NOATIME: ::c_int = 0o1000000; + pub const O_PATH: ::c_int = 0o10000000; + pub const O_TMPFILE: ::c_int = 0o20000000 | O_DIRECTORY; + + pub const SA_ONSTACK: ::c_int = 0x08000000; + + pub const PTRACE_DETACH: ::c_uint = 17; + + pub const F_SETLK: ::c_int = 6; + pub const F_SETLKW: ::c_int = 7; + + pub const F_RDLCK: ::c_int = 0; + pub const F_WRLCK: ::c_int = 1; + pub const F_UNLCK: ::c_int = 2; + + pub const SFD_CLOEXEC: ::c_int = 0x080000; + + pub const NCCS: usize = 32; + + pub const O_TRUNC: ::c_int = 512; + pub const O_CLOEXEC: ::c_int = 0x80000; + 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 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 EPOLL_CLOEXEC: ::c_int = 0x80000; + + pub const EFD_CLOEXEC: ::c_int = 0x80000; + } +} + +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, 1, 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, 2, 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, 3, 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, 1, 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, 2, 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, 3, 0, 0, 0, 0, 0, + 0, 0, 0, + ], + }; +} + +pub const PTRACE_GETFPREGS: ::c_uint = 14; +pub const PTRACE_SETFPREGS: ::c_uint = 15; +pub const PTRACE_GETREGS: ::c_uint = 12; +pub const PTRACE_SETREGS: ::c_uint = 13; + +extern "C" { + pub fn sysctl( + name: *mut ::c_int, + namelen: ::c_int, + oldp: *mut ::c_void, + oldlenp: *mut ::size_t, + newp: *mut ::c_void, + newlen: ::size_t, + ) -> ::c_int; +} + +cfg_if! { + if #[cfg(target_arch = "x86")] { + mod x86; + pub use self::x86::*; + } else if #[cfg(target_arch = "arm")] { + mod arm; + pub use self::arm::*; + } else if #[cfg(any(target_arch = "mips", target_arch = "mips32r6"))] { + 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::*; + } else if #[cfg(target_arch = "sparc")] { + mod sparc; + pub use self::sparc::*; + } else if #[cfg(target_arch = "riscv32")] { + mod riscv32; + pub use self::riscv32::*; + } else if #[cfg(target_arch = "csky")] { + mod csky; + pub use self::csky::*; + } else { + // Unknown target_arch + } +} 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 new file mode 100644 index 0000000..cb7fdf7 --- /dev/null +++ b/vendor/libc/src/unix/linux_like/linux/gnu/b32/powerpc.rs @@ -0,0 +1,826 @@ +pub type c_char = u8; +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, + f_spare: [::__fsword_t; 5], + } + + 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: u32, + __pad1: u32, + __glibc_reserved1: u64, + __glibc_reserved2: u64, + } + + 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, + __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_long, + pub st_mtime: ::time_t, + pub st_mtime_nsec: ::c_long, + pub st_ctime: ::time_t, + pub st_ctime_nsec: ::c_long, + __glibc_reserved4: ::c_ulong, + __glibc_reserved5: ::c_ulong, + } + + 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 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 shmid_ds { + pub shm_perm: ::ipc_perm, + __glibc_reserved1: ::c_uint, + pub shm_atime: ::time_t, + __glibc_reserved2: ::c_uint, + pub shm_dtime: ::time_t, + __glibc_reserved3: ::c_uint, + pub shm_ctime: ::time_t, + __glibc_reserved4: ::c_uint, + pub shm_segsz: ::size_t, + 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, + __glibc_reserved1: ::c_uint, + pub msg_stime: ::time_t, + __glibc_reserved2: ::c_uint, + pub msg_rtime: ::time_t, + __glibc_reserved3: ::c_uint, + pub msg_ctime: ::time_t, + __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_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: [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 = 0x20000; +pub const O_DIRECTORY: ::c_int = 0x4000; +pub const O_NOFOLLOW: ::c_int = 0x8000; +pub const O_LARGEFILE: ::c_int = 0o200000; +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 TCSANOW: ::c_int = 0; +pub const TCSADRAIN: ::c_int = 1; +pub const TCSAFLUSH: ::c_int = 2; + +pub const MADV_SOFT_OFFLINE: ::c_int = 101; +pub const MAP_LOCKED: ::c_int = 0x00080; +pub const MAP_NORESERVE: ::c_int = 0x00040; +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 = 58; +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 MCL_CURRENT: ::c_int = 0x2000; +pub const MCL_FUTURE: ::c_int = 0x4000; +pub const MCL_ONFAULT: ::c_int = 0x8000; + +pub const POLLWRNORM: ::c_short = 0x100; +pub const POLLWRBAND: ::c_short = 0x200; + +pub const F_GETLK: ::c_int = 5; +pub const F_GETOWN: ::c_int = 9; +pub const F_SETOWN: ::c_int = 8; + +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 = 0x4000; +pub const MINSIGSTKSZ: ::size_t = 4096; +pub const CBAUD: ::tcflag_t = 0xff; +pub const TAB1: ::tcflag_t = 0x400; +pub const TAB2: ::tcflag_t = 0x800; +pub const TAB3: ::tcflag_t = 0xc00; +pub const CR1: ::tcflag_t = 0x1000; +pub const CR2: ::tcflag_t = 0x2000; +pub const CR3: ::tcflag_t = 0x3000; +pub const FF1: ::tcflag_t = 0x4000; +pub const BS1: ::tcflag_t = 0x8000; +pub const VT1: ::tcflag_t = 0x10000; +pub const VWERASE: usize = 0xa; +pub const VREPRINT: usize = 0xb; +pub const VSUSP: usize = 0xc; +pub const VSTART: usize = 0xd; +pub const VSTOP: usize = 0xe; +pub const VDISCARD: usize = 0x10; +pub const VTIME: usize = 0x7; +pub const IXON: ::tcflag_t = 0x200; +pub const IXOFF: ::tcflag_t = 0x400; +pub const ONLCR: ::tcflag_t = 0x2; +pub const CSIZE: ::tcflag_t = 0x300; +pub const CS6: ::tcflag_t = 0x100; +pub const CS7: ::tcflag_t = 0x200; +pub const CS8: ::tcflag_t = 0x300; +pub const CSTOPB: ::tcflag_t = 0x400; +pub const CREAD: ::tcflag_t = 0x800; +pub const PARENB: ::tcflag_t = 0x1000; +pub const PARODD: ::tcflag_t = 0x2000; +pub const HUPCL: ::tcflag_t = 0x4000; +pub const CLOCAL: ::tcflag_t = 0x8000; +pub const ECHOKE: ::tcflag_t = 0x1; +pub const ECHOE: ::tcflag_t = 0x2; +pub const ECHOK: ::tcflag_t = 0x4; +pub const ECHONL: ::tcflag_t = 0x10; +pub const ECHOPRT: ::tcflag_t = 0x20; +pub const ECHOCTL: ::tcflag_t = 0x40; +pub const ISIG: ::tcflag_t = 0x80; +pub const ICANON: ::tcflag_t = 0x100; +pub const PENDIN: ::tcflag_t = 0x20000000; +pub const NOFLSH: ::tcflag_t = 0x80000000; +pub const VSWTC: usize = 9; +pub const OLCUC: ::tcflag_t = 0o000004; +pub const NLDLY: ::tcflag_t = 0o001400; +pub const CRDLY: ::tcflag_t = 0o030000; +pub const TABDLY: ::tcflag_t = 0o006000; +pub const BSDLY: ::tcflag_t = 0o100000; +pub const FFDLY: ::tcflag_t = 0o040000; +pub const VTDLY: ::tcflag_t = 0o200000; +pub const XTABS: ::tcflag_t = 0o006000; + +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 CBAUDEX: ::speed_t = 0o000020; +pub const B57600: ::speed_t = 0o0020; +pub const B115200: ::speed_t = 0o0021; +pub const B230400: ::speed_t = 0o0022; +pub const B460800: ::speed_t = 0o0023; +pub const B500000: ::speed_t = 0o0024; +pub const B576000: ::speed_t = 0o0025; +pub const B921600: ::speed_t = 0o0026; +pub const B1000000: ::speed_t = 0o0027; +pub const B1152000: ::speed_t = 0o0030; +pub const B1500000: ::speed_t = 0o0031; +pub const B2000000: ::speed_t = 0o0032; +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 VEOL: usize = 6; +pub const VEOL2: usize = 8; +pub const VMIN: usize = 5; +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 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_time: ::c_long = 13; +pub const SYS_mknod: ::c_long = 14; +pub const SYS_chmod: ::c_long = 15; +pub const SYS_lchown: ::c_long = 16; +pub const SYS_break: ::c_long = 17; +pub const SYS_oldstat: ::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_umount: ::c_long = 22; +pub const SYS_setuid: ::c_long = 23; +pub const SYS_getuid: ::c_long = 24; +pub const SYS_stime: ::c_long = 25; +pub const SYS_ptrace: ::c_long = 26; +pub const SYS_alarm: ::c_long = 27; +pub const SYS_oldfstat: ::c_long = 28; +pub const SYS_pause: ::c_long = 29; +pub const SYS_utime: ::c_long = 30; +pub const SYS_stty: ::c_long = 31; +pub const SYS_gtty: ::c_long = 32; +pub const SYS_access: ::c_long = 33; +pub const SYS_nice: ::c_long = 34; +pub const SYS_ftime: ::c_long = 35; +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_prof: ::c_long = 44; +pub const SYS_brk: ::c_long = 45; +pub const SYS_setgid: ::c_long = 46; +pub const SYS_getgid: ::c_long = 47; +pub const SYS_signal: ::c_long = 48; +pub const SYS_geteuid: ::c_long = 49; +pub const SYS_getegid: ::c_long = 50; +pub const SYS_acct: ::c_long = 51; +pub const SYS_umount2: ::c_long = 52; +pub const SYS_lock: ::c_long = 53; +pub const SYS_ioctl: ::c_long = 54; +pub const SYS_fcntl: ::c_long = 55; +pub const SYS_mpx: ::c_long = 56; +pub const SYS_setpgid: ::c_long = 57; +pub const SYS_ulimit: ::c_long = 58; +pub const SYS_oldolduname: ::c_long = 59; +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_setreuid: ::c_long = 70; +pub const SYS_setregid: ::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_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_getgroups: ::c_long = 80; +pub const SYS_setgroups: ::c_long = 81; +pub const SYS_select: ::c_long = 82; +pub const SYS_symlink: ::c_long = 83; +pub const SYS_oldlstat: ::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_readdir: ::c_long = 89; +pub const SYS_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_fchown: ::c_long = 95; +pub const SYS_getpriority: ::c_long = 96; +pub const SYS_setpriority: ::c_long = 97; +pub const SYS_profil: ::c_long = 98; +pub const SYS_statfs: ::c_long = 99; +pub const SYS_fstatfs: ::c_long = 100; +pub const SYS_ioperm: ::c_long = 101; +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_stat: ::c_long = 106; +pub const SYS_lstat: ::c_long = 107; +pub const SYS_fstat: ::c_long = 108; +pub const SYS_olduname: ::c_long = 109; +pub const SYS_iopl: ::c_long = 110; +pub const SYS_vhangup: ::c_long = 111; +pub const SYS_idle: ::c_long = 112; +pub const SYS_vm86: ::c_long = 113; +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_uname: ::c_long = 122; +pub const SYS_modify_ldt: ::c_long = 123; +pub const SYS_adjtimex: ::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_afs_syscall: ::c_long = 137; /* Syscall for Andrew File System */ +pub const SYS_setfsuid: ::c_long = 138; +pub const SYS_setfsgid: ::c_long = 139; +pub const SYS__llseek: ::c_long = 140; +pub const SYS_getdents: ::c_long = 141; +pub const SYS__newselect: ::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: ::c_long = 161; +pub const SYS_nanosleep: ::c_long = 162; +pub const SYS_mremap: ::c_long = 163; +pub const SYS_setresuid: ::c_long = 164; +pub const SYS_getresuid: ::c_long = 165; +pub const SYS_query_module: ::c_long = 166; +pub const SYS_poll: ::c_long = 167; +pub const SYS_nfsservctl: ::c_long = 168; +pub const SYS_setresgid: ::c_long = 169; +pub const SYS_getresgid: ::c_long = 170; +pub const SYS_prctl: ::c_long = 171; +pub const SYS_rt_sigreturn: ::c_long = 172; +pub const SYS_rt_sigaction: ::c_long = 173; +pub const SYS_rt_sigprocmask: ::c_long = 174; +pub const SYS_rt_sigpending: ::c_long = 175; +pub const SYS_rt_sigtimedwait: ::c_long = 176; +pub const SYS_rt_sigqueueinfo: ::c_long = 177; +pub const SYS_rt_sigsuspend: ::c_long = 178; +pub const SYS_pread64: ::c_long = 179; +pub const SYS_pwrite64: ::c_long = 180; +pub const SYS_chown: ::c_long = 181; +pub const SYS_getcwd: ::c_long = 182; +pub const SYS_capget: ::c_long = 183; +pub const SYS_capset: ::c_long = 184; +pub const SYS_sigaltstack: ::c_long = 185; +pub const SYS_sendfile: ::c_long = 186; +pub const SYS_getpmsg: ::c_long = 187; /* some people actually want streams */ +pub const SYS_putpmsg: ::c_long = 188; /* some people actually want streams */ +pub const SYS_vfork: ::c_long = 189; +pub const SYS_ugetrlimit: ::c_long = 190; /* SuS compliant getrlimit */ +pub const SYS_readahead: ::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_pciconfig_read: ::c_long = 198; +pub const SYS_pciconfig_write: ::c_long = 199; +pub const SYS_pciconfig_iobase: ::c_long = 200; +pub const SYS_multiplexer: ::c_long = 201; +pub const SYS_getdents64: ::c_long = 202; +pub const SYS_pivot_root: ::c_long = 203; +pub const SYS_fcntl64: ::c_long = 204; +pub const SYS_madvise: ::c_long = 205; +pub const SYS_mincore: ::c_long = 206; +pub const SYS_gettid: ::c_long = 207; +pub const SYS_tkill: ::c_long = 208; +pub const SYS_setxattr: ::c_long = 209; +pub const SYS_lsetxattr: ::c_long = 210; +pub const SYS_fsetxattr: ::c_long = 211; +pub const SYS_getxattr: ::c_long = 212; +pub const SYS_lgetxattr: ::c_long = 213; +pub const SYS_fgetxattr: ::c_long = 214; +pub const SYS_listxattr: ::c_long = 215; +pub const SYS_llistxattr: ::c_long = 216; +pub const SYS_flistxattr: ::c_long = 217; +pub const SYS_removexattr: ::c_long = 218; +pub const SYS_lremovexattr: ::c_long = 219; +pub const SYS_fremovexattr: ::c_long = 220; +pub const SYS_futex: ::c_long = 221; +pub const SYS_sched_setaffinity: ::c_long = 222; +pub const SYS_sched_getaffinity: ::c_long = 223; +pub const SYS_tuxcall: ::c_long = 225; +pub const SYS_sendfile64: ::c_long = 226; +pub const SYS_io_setup: ::c_long = 227; +pub const SYS_io_destroy: ::c_long = 228; +pub const SYS_io_getevents: ::c_long = 229; +pub const SYS_io_submit: ::c_long = 230; +pub const SYS_io_cancel: ::c_long = 231; +pub const SYS_set_tid_address: ::c_long = 232; +pub const SYS_fadvise64: ::c_long = 233; +pub const SYS_exit_group: ::c_long = 234; +pub const SYS_lookup_dcookie: ::c_long = 235; +pub const SYS_epoll_create: ::c_long = 236; +pub const SYS_epoll_ctl: ::c_long = 237; +pub const SYS_epoll_wait: ::c_long = 238; +pub const SYS_remap_file_pages: ::c_long = 239; +pub const SYS_timer_create: ::c_long = 240; +pub const SYS_timer_settime: ::c_long = 241; +pub const SYS_timer_gettime: ::c_long = 242; +pub const SYS_timer_getoverrun: ::c_long = 243; +pub const SYS_timer_delete: ::c_long = 244; +pub const SYS_clock_settime: ::c_long = 245; +pub const SYS_clock_gettime: ::c_long = 246; +pub const SYS_clock_getres: ::c_long = 247; +pub const SYS_clock_nanosleep: ::c_long = 248; +pub const SYS_swapcontext: ::c_long = 249; +pub const SYS_tgkill: ::c_long = 250; +pub const SYS_utimes: ::c_long = 251; +pub const SYS_statfs64: ::c_long = 252; +pub const SYS_fstatfs64: ::c_long = 253; +pub const SYS_fadvise64_64: ::c_long = 254; +pub const SYS_rtas: ::c_long = 255; +pub const SYS_sys_debug_setcontext: ::c_long = 256; +pub const SYS_migrate_pages: ::c_long = 258; +pub const SYS_mbind: ::c_long = 259; +pub const SYS_get_mempolicy: ::c_long = 260; +pub const SYS_set_mempolicy: ::c_long = 261; +pub const SYS_mq_open: ::c_long = 262; +pub const SYS_mq_unlink: ::c_long = 263; +pub const SYS_mq_timedsend: ::c_long = 264; +pub const SYS_mq_timedreceive: ::c_long = 265; +pub const SYS_mq_notify: ::c_long = 266; +pub const SYS_mq_getsetattr: ::c_long = 267; +pub const SYS_kexec_load: ::c_long = 268; +pub const SYS_add_key: ::c_long = 269; +pub const SYS_request_key: ::c_long = 270; +pub const SYS_keyctl: ::c_long = 271; +pub const SYS_waitid: ::c_long = 272; +pub const SYS_ioprio_set: ::c_long = 273; +pub const SYS_ioprio_get: ::c_long = 274; +pub const SYS_inotify_init: ::c_long = 275; +pub const SYS_inotify_add_watch: ::c_long = 276; +pub const SYS_inotify_rm_watch: ::c_long = 277; +pub const SYS_spu_run: ::c_long = 278; +pub const SYS_spu_create: ::c_long = 279; +pub const SYS_pselect6: ::c_long = 280; +pub const SYS_ppoll: ::c_long = 281; +pub const SYS_unshare: ::c_long = 282; +pub const SYS_splice: ::c_long = 283; +pub const SYS_tee: ::c_long = 284; +pub const SYS_vmsplice: ::c_long = 285; +pub const SYS_openat: ::c_long = 286; +pub const SYS_mkdirat: ::c_long = 287; +pub const SYS_mknodat: ::c_long = 288; +pub const SYS_fchownat: ::c_long = 289; +pub const SYS_futimesat: ::c_long = 290; +pub const SYS_fstatat64: ::c_long = 291; +pub const SYS_unlinkat: ::c_long = 292; +pub const SYS_renameat: ::c_long = 293; +pub const SYS_linkat: ::c_long = 294; +pub const SYS_symlinkat: ::c_long = 295; +pub const SYS_readlinkat: ::c_long = 296; +pub const SYS_fchmodat: ::c_long = 297; +pub const SYS_faccessat: ::c_long = 298; +pub const SYS_get_robust_list: ::c_long = 299; +pub const SYS_set_robust_list: ::c_long = 300; +pub const SYS_move_pages: ::c_long = 301; +pub const SYS_getcpu: ::c_long = 302; +pub const SYS_epoll_pwait: ::c_long = 303; +pub const SYS_utimensat: ::c_long = 304; +pub const SYS_signalfd: ::c_long = 305; +pub const SYS_timerfd_create: ::c_long = 306; +pub const SYS_eventfd: ::c_long = 307; +pub const SYS_sync_file_range2: ::c_long = 308; +pub const SYS_fallocate: ::c_long = 309; +pub const SYS_subpage_prot: ::c_long = 310; +pub const SYS_timerfd_settime: ::c_long = 311; +pub const SYS_timerfd_gettime: ::c_long = 312; +pub const SYS_signalfd4: ::c_long = 313; +pub const SYS_eventfd2: ::c_long = 314; +pub const SYS_epoll_create1: ::c_long = 315; +pub const SYS_dup3: ::c_long = 316; +pub const SYS_pipe2: ::c_long = 317; +pub const SYS_inotify_init1: ::c_long = 318; +pub const SYS_perf_event_open: ::c_long = 319; +pub const SYS_preadv: ::c_long = 320; +pub const SYS_pwritev: ::c_long = 321; +pub const SYS_rt_tgsigqueueinfo: ::c_long = 322; +pub const SYS_fanotify_init: ::c_long = 323; +pub const SYS_fanotify_mark: ::c_long = 324; +pub const SYS_prlimit64: ::c_long = 325; +pub const SYS_socket: ::c_long = 326; +pub const SYS_bind: ::c_long = 327; +pub const SYS_connect: ::c_long = 328; +pub const SYS_listen: ::c_long = 329; +pub const SYS_accept: ::c_long = 330; +pub const SYS_getsockname: ::c_long = 331; +pub const SYS_getpeername: ::c_long = 332; +pub const SYS_socketpair: ::c_long = 333; +pub const SYS_send: ::c_long = 334; +pub const SYS_sendto: ::c_long = 335; +pub const SYS_recv: ::c_long = 336; +pub const SYS_recvfrom: ::c_long = 337; +pub const SYS_shutdown: ::c_long = 338; +pub const SYS_setsockopt: ::c_long = 339; +pub const SYS_getsockopt: ::c_long = 340; +pub const SYS_sendmsg: ::c_long = 341; +pub const SYS_recvmsg: ::c_long = 342; +pub const SYS_recvmmsg: ::c_long = 343; +pub const SYS_accept4: ::c_long = 344; +pub const SYS_name_to_handle_at: ::c_long = 345; +pub const SYS_open_by_handle_at: ::c_long = 346; +pub const SYS_clock_adjtime: ::c_long = 347; +pub const SYS_syncfs: ::c_long = 348; +pub const SYS_sendmmsg: ::c_long = 349; +pub const SYS_setns: ::c_long = 350; +pub const SYS_process_vm_readv: ::c_long = 351; +pub const SYS_process_vm_writev: ::c_long = 352; +pub const SYS_finit_module: ::c_long = 353; +pub const SYS_kcmp: ::c_long = 354; +pub const SYS_sched_setattr: ::c_long = 355; +pub const SYS_sched_getattr: ::c_long = 356; +pub const SYS_renameat2: ::c_long = 357; +pub const SYS_seccomp: ::c_long = 358; +pub const SYS_getrandom: ::c_long = 359; +pub const SYS_memfd_create: ::c_long = 360; +pub const SYS_bpf: ::c_long = 361; +pub const SYS_execveat: ::c_long = 362; +pub const SYS_switch_endian: ::c_long = 363; +pub const SYS_userfaultfd: ::c_long = 364; +pub const SYS_membarrier: ::c_long = 365; +pub const SYS_mlock2: ::c_long = 378; +pub const SYS_copy_file_range: ::c_long = 379; +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; +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; +pub const SYS_mseal: ::c_long = 462; 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 new file mode 100644 index 0000000..65b7aaa --- /dev/null +++ b/vendor/libc/src/unix/linux_like/linux/gnu/b32/riscv32/mod.rs @@ -0,0 +1,813 @@ +//! 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 msqid_ds { + pub msg_perm: ::ipc_perm, + pub msg_stime: ::time_t, + pub msg_rtime: ::time_t, + pub msg_ctime: ::time_t, + __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 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 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 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 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 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 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; +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 SOCK_STREAM: ::c_int = 1; +pub const SOCK_DGRAM: ::c_int = 2; +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 __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 MCL_CURRENT: ::c_int = 1; +pub const MCL_FUTURE: ::c_int = 2; +pub const MCL_ONFAULT: ::c_int = 4; +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 __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; +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_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; +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)] { + mod align; + pub use self::align::*; + } +} diff --git a/vendor/libc/src/unix/linux_like/linux/gnu/b32/sparc/align.rs b/vendor/libc/src/unix/linux_like/linux/gnu/b32/sparc/align.rs new file mode 100644 index 0000000..98fda88 --- /dev/null +++ b/vendor/libc/src/unix/linux_like/linux/gnu/b32/sparc/align.rs @@ -0,0 +1,7 @@ +s_no_extra_traits! { + #[allow(missing_debug_implementations)] + #[repr(align(8))] + pub struct max_align_t { + priv_: [i64; 3] + } +} 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 new file mode 100644 index 0000000..da9cf29 --- /dev/null +++ b/vendor/libc/src/unix/linux_like/linux/gnu/b32/sparc/mod.rs @@ -0,0 +1,857 @@ +//! SPARC-specific definitions for 32-bit linux-like values + +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, + f_spare: [::__fsword_t; 5], + } + + 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 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, + __reserved: ::c_short, + } + + pub struct stack_t { + pub ss_sp: *mut ::c_void, + pub ss_flags: ::c_int, + pub ss_size: ::size_t + } + + pub struct stat { + 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, + __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_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; 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, + __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_long, + pub st_mtime: ::time_t, + pub st_mtime_nsec: ::c_long, + pub st_ctime: ::time_t, + pub st_ctime_nsec: ::c_long, + __reserved: [::c_long; 2], + } + + 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 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 ipc_perm { + pub __key: ::key_t, + pub uid: ::uid_t, + pub gid: ::gid_t, + pub cuid: ::uid_t, + pub cgid: ::gid_t, + __pad1: ::c_ushort, + pub mode: ::c_ushort, + __pad2: ::c_ushort, + pub __seq: ::c_ushort, + __unused1: ::c_ulonglong, + __unused2: ::c_ulonglong, + } + + pub struct shmid_ds { + pub shm_perm: ::ipc_perm, + __pad1: ::c_uint, + pub shm_atime: ::time_t, + __pad2: ::c_uint, + pub shm_dtime: ::time_t, + __pad3: ::c_uint, + pub shm_ctime: ::time_t, + pub shm_segsz: ::size_t, + pub shm_cpid: ::pid_t, + pub shm_lpid: ::pid_t, + pub shm_nattch: ::shmatt_t, + __reserved1: ::c_ulong, + __reserved2: ::c_ulong, + } + + pub struct msqid_ds { + pub msg_perm: ::ipc_perm, + __pad1: ::c_uint, + pub msg_stime: ::time_t, + __pad2: ::c_uint, + pub msg_rtime: ::time_t, + __pad3: ::c_uint, + pub msg_ctime: ::time_t, + __msg_cbytes: ::c_ushort, + pub msg_qnum: ::msgqnum_t, + pub msg_qbytes: ::msglen_t, + pub msg_lspid: ::pid_t, + pub msg_lrpid: ::pid_t, + __glibc_reserved1: ::c_ulong, + __glibc_reserved2: ::c_ulong, + } +} + +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_APPEND: ::c_int = 0x8; +pub const O_CREAT: ::c_int = 0x200; +pub const O_EXCL: ::c_int = 0x800; +pub const O_NOCTTY: ::c_int = 0x8000; +pub const O_NONBLOCK: ::c_int = 0x4000; +pub const O_SYNC: ::c_int = 0x802000; +pub const O_RSYNC: ::c_int = 0x802000; +pub const O_DSYNC: ::c_int = 0x2000; +pub const O_FSYNC: ::c_int = 0x802000; + +pub const MADV_SOFT_OFFLINE: ::c_int = 101; +pub const MAP_GROWSDOWN: ::c_int = 0x0200; +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_SYNC: ::c_int = 0x080000; + +pub const EDEADLK: ::c_int = 78; +pub const ENAMETOOLONG: ::c_int = 63; +pub const ENOLCK: ::c_int = 79; +pub const ENOSYS: ::c_int = 90; +pub const ENOTEMPTY: ::c_int = 66; +pub const ELOOP: ::c_int = 62; +pub const ENOMSG: ::c_int = 75; +pub const EIDRM: ::c_int = 77; +pub const ECHRNG: ::c_int = 94; +pub const EL2NSYNC: ::c_int = 95; +pub const EL3HLT: ::c_int = 96; +pub const EL3RST: ::c_int = 97; +pub const ELNRNG: ::c_int = 98; +pub const EUNATCH: ::c_int = 99; +pub const ENOCSI: ::c_int = 100; +pub const EL2HLT: ::c_int = 101; +pub const EBADE: ::c_int = 102; +pub const EBADR: ::c_int = 103; +pub const EXFULL: ::c_int = 104; +pub const ENOANO: ::c_int = 105; +pub const EBADRQC: ::c_int = 106; +pub const EBADSLT: ::c_int = 107; +pub const EMULTIHOP: ::c_int = 87; +pub const EOVERFLOW: ::c_int = 92; +pub const ENOTUNIQ: ::c_int = 115; +pub const EBADFD: ::c_int = 93; +pub const EBADMSG: ::c_int = 76; +pub const EREMCHG: ::c_int = 89; +pub const ELIBACC: ::c_int = 114; +pub const ELIBBAD: ::c_int = 112; +pub const ELIBSCN: ::c_int = 124; +pub const ELIBMAX: ::c_int = 123; +pub const ELIBEXEC: ::c_int = 110; +pub const EILSEQ: ::c_int = 122; +pub const ERESTART: ::c_int = 116; +pub const ESTRPIPE: ::c_int = 91; +pub const EUSERS: ::c_int = 68; +pub const ENOTSOCK: ::c_int = 38; +pub const EDESTADDRREQ: ::c_int = 39; +pub const EMSGSIZE: ::c_int = 40; +pub const EPROTOTYPE: ::c_int = 41; +pub const ENOPROTOOPT: ::c_int = 42; +pub const EPROTONOSUPPORT: ::c_int = 43; +pub const ESOCKTNOSUPPORT: ::c_int = 44; +pub const EOPNOTSUPP: ::c_int = 45; +pub const EPFNOSUPPORT: ::c_int = 46; +pub const EAFNOSUPPORT: ::c_int = 47; +pub const EADDRINUSE: ::c_int = 48; +pub const EADDRNOTAVAIL: ::c_int = 49; +pub const ENETDOWN: ::c_int = 50; +pub const ENETUNREACH: ::c_int = 51; +pub const ENETRESET: ::c_int = 52; +pub const ECONNABORTED: ::c_int = 53; +pub const ECONNRESET: ::c_int = 54; +pub const ENOBUFS: ::c_int = 55; +pub const EISCONN: ::c_int = 56; +pub const ENOTCONN: ::c_int = 57; +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 EHOSTDOWN: ::c_int = 64; +pub const EHOSTUNREACH: ::c_int = 65; +pub const EALREADY: ::c_int = 37; +pub const EINPROGRESS: ::c_int = 36; +pub const ESTALE: ::c_int = 70; +pub const EDQUOT: ::c_int = 69; +pub const ENOMEDIUM: ::c_int = 125; +pub const EMEDIUMTYPE: ::c_int = 126; +pub const ECANCELED: ::c_int = 127; +pub const ENOKEY: ::c_int = 128; +pub const EKEYEXPIRED: ::c_int = 129; +pub const EKEYREVOKED: ::c_int = 130; +pub const EKEYREJECTED: ::c_int = 131; +pub const EOWNERDEAD: ::c_int = 132; +pub const ENOTRECOVERABLE: ::c_int = 133; +pub const EHWPOISON: ::c_int = 135; +pub const ERFKILL: ::c_int = 134; + +pub const SOCK_STREAM: ::c_int = 1; +pub const SOCK_DGRAM: ::c_int = 2; + +pub const SA_SIGINFO: ::c_int = 0x200; +pub const SA_NOCLDWAIT: ::c_int = 0x100; + +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 = 20; +pub const SIGBUS: ::c_int = 10; +pub const SIGUSR1: ::c_int = 30; +pub const SIGUSR2: ::c_int = 31; +pub const SIGCONT: ::c_int = 19; +pub const SIGSTOP: ::c_int = 17; +pub const SIGTSTP: ::c_int = 18; +pub const SIGURG: ::c_int = 16; +pub const SIGIO: ::c_int = 23; +pub const SIGSYS: ::c_int = 12; +pub const SIGPOLL: ::c_int = 23; +pub const SIGPWR: ::c_int = 29; +pub const SIG_SETMASK: ::c_int = 4; +pub const SIG_BLOCK: ::c_int = 1; +pub const SIG_UNBLOCK: ::c_int = 2; + +pub const POLLWRNORM: ::c_short = 4; +pub const POLLWRBAND: ::c_short = 0x100; + +pub const O_ASYNC: ::c_int = 0x40; +pub const O_NDELAY: ::c_int = 0x4004; + +pub const EFD_NONBLOCK: ::c_int = 0x4000; + +pub const F_GETLK: ::c_int = 7; +pub const F_GETOWN: ::c_int = 5; +pub const F_SETOWN: ::c_int = 6; + +pub const SFD_NONBLOCK: ::c_int = 0x4000; + +pub const TCSANOW: ::c_int = 0; +pub const TCSADRAIN: ::c_int = 1; +pub const TCSAFLUSH: ::c_int = 2; + +pub const O_DIRECTORY: ::c_int = 0o200000; +pub const O_NOFOLLOW: ::c_int = 0o400000; +pub const O_LARGEFILE: ::c_int = 0x40000; +pub const O_DIRECT: ::c_int = 0x100000; + +pub const MAP_LOCKED: ::c_int = 0x0100; +pub const MAP_NORESERVE: ::c_int = 0x00040; + +pub const EDEADLOCK: ::c_int = 108; +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 MCL_CURRENT: ::c_int = 0x2000; +pub const MCL_FUTURE: ::c_int = 0x4000; +pub const MCL_ONFAULT: ::c_int = 0x8000; + +pub const SIGSTKSZ: ::size_t = 16384; +pub const MINSIGSTKSZ: ::size_t = 4096; +pub const CBAUD: ::tcflag_t = 0x0000100f; +pub const TAB1: ::tcflag_t = 0x800; +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 = 0xe; +pub const VREPRINT: usize = 0xc; +pub const VSUSP: usize = 0xa; +pub const VSTART: usize = 0x8; +pub const VSTOP: usize = 0x9; +pub const VDISCARD: usize = 0xd; +pub const VTIME: usize = 0x5; +pub const IXON: ::tcflag_t = 0x400; +pub const IXOFF: ::tcflag_t = 0x1000; +pub const ONLCR: ::tcflag_t = 0x4; +pub const CSIZE: ::tcflag_t = 0x30; +pub const CS6: ::tcflag_t = 0x10; +pub const CS7: ::tcflag_t = 0x20; +pub const CS8: ::tcflag_t = 0x30; +pub const CSTOPB: ::tcflag_t = 0x40; +pub const CREAD: ::tcflag_t = 0x80; +pub const PARENB: ::tcflag_t = 0x100; +pub const PARODD: ::tcflag_t = 0x200; +pub const HUPCL: ::tcflag_t = 0x400; +pub const CLOCAL: ::tcflag_t = 0x800; +pub const ECHOKE: ::tcflag_t = 0x800; +pub const ECHOE: ::tcflag_t = 0x10; +pub const ECHOK: ::tcflag_t = 0x20; +pub const ECHONL: ::tcflag_t = 0x40; +pub const ECHOPRT: ::tcflag_t = 0x400; +pub const ECHOCTL: ::tcflag_t = 0x200; +pub const ISIG: ::tcflag_t = 0x1; +pub const ICANON: ::tcflag_t = 0x2; +pub const PENDIN: ::tcflag_t = 0x4000; +pub const NOFLSH: ::tcflag_t = 0x80; +pub const CIBAUD: ::tcflag_t = 0o02003600000; +pub const CBAUDEX: ::tcflag_t = 0x00001000; +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 = 0x1001; +pub const B115200: ::speed_t = 0x1002; +pub const B230400: ::speed_t = 0x1003; +pub const B460800: ::speed_t = 0x1004; +pub const B76800: ::speed_t = 0x1005; +pub const B153600: ::speed_t = 0x1006; +pub const B307200: ::speed_t = 0x1007; +pub const B614400: ::speed_t = 0x1008; +pub const B921600: ::speed_t = 0x1009; +pub const B500000: ::speed_t = 0x100a; +pub const B576000: ::speed_t = 0x100b; +pub const B1000000: ::speed_t = 0x100c; +pub const B1152000: ::speed_t = 0x100d; +pub const B1500000: ::speed_t = 0x100e; +pub const B2000000: ::speed_t = 0x100f; + +pub const VEOL: usize = 5; +pub const VEOL2: usize = 6; +pub const VMIN: usize = 4; +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 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_wait4: ::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_execv: ::c_long = 11; +pub const SYS_chdir: ::c_long = 12; +pub const SYS_chown: ::c_long = 13; +pub const SYS_mknod: ::c_long = 14; +pub const SYS_chmod: ::c_long = 15; +pub const SYS_lchown: ::c_long = 16; +pub const SYS_brk: ::c_long = 17; +pub const SYS_perfctr: ::c_long = 18; +pub const SYS_lseek: ::c_long = 19; +pub const SYS_getpid: ::c_long = 20; +pub const SYS_capget: ::c_long = 21; +pub const SYS_capset: ::c_long = 22; +pub const SYS_setuid: ::c_long = 23; +pub const SYS_getuid: ::c_long = 24; +pub const SYS_vmsplice: ::c_long = 25; +pub const SYS_ptrace: ::c_long = 26; +pub const SYS_alarm: ::c_long = 27; +pub const SYS_sigaltstack: ::c_long = 28; +pub const SYS_pause: ::c_long = 29; +pub const SYS_utime: ::c_long = 30; +pub const SYS_lchown32: ::c_long = 31; +pub const SYS_fchown32: ::c_long = 32; +pub const SYS_access: ::c_long = 33; +pub const SYS_nice: ::c_long = 34; +pub const SYS_chown32: ::c_long = 35; +pub const SYS_sync: ::c_long = 36; +pub const SYS_kill: ::c_long = 37; +pub const SYS_stat: ::c_long = 38; +pub const SYS_sendfile: ::c_long = 39; +pub const SYS_lstat: ::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_getuid32: ::c_long = 44; +pub const SYS_umount2: ::c_long = 45; +pub const SYS_setgid: ::c_long = 46; +pub const SYS_getgid: ::c_long = 47; +pub const SYS_signal: ::c_long = 48; +pub const SYS_geteuid: ::c_long = 49; +pub const SYS_getegid: ::c_long = 50; +pub const SYS_acct: ::c_long = 51; +pub const SYS_getgid32: ::c_long = 53; +pub const SYS_ioctl: ::c_long = 54; +pub const SYS_reboot: ::c_long = 55; +pub const SYS_mmap2: ::c_long = 56; +pub const SYS_symlink: ::c_long = 57; +pub const SYS_readlink: ::c_long = 58; +pub const SYS_execve: ::c_long = 59; +pub const SYS_umask: ::c_long = 60; +pub const SYS_chroot: ::c_long = 61; +pub const SYS_fstat: ::c_long = 62; +pub const SYS_fstat64: ::c_long = 63; +pub const SYS_getpagesize: ::c_long = 64; +pub const SYS_msync: ::c_long = 65; +pub const SYS_vfork: ::c_long = 66; +pub const SYS_pread64: ::c_long = 67; +pub const SYS_pwrite64: ::c_long = 68; +pub const SYS_geteuid32: ::c_long = 69; +pub const SYS_getegid32: ::c_long = 70; +pub const SYS_mmap: ::c_long = 71; +pub const SYS_setreuid32: ::c_long = 72; +pub const SYS_munmap: ::c_long = 73; +pub const SYS_mprotect: ::c_long = 74; +pub const SYS_madvise: ::c_long = 75; +pub const SYS_vhangup: ::c_long = 76; +pub const SYS_truncate64: ::c_long = 77; +pub const SYS_mincore: ::c_long = 78; +pub const SYS_getgroups: ::c_long = 79; +pub const SYS_setgroups: ::c_long = 80; +pub const SYS_getpgrp: ::c_long = 81; +pub const SYS_setgroups32: ::c_long = 82; +pub const SYS_setitimer: ::c_long = 83; +pub const SYS_ftruncate64: ::c_long = 84; +pub const SYS_swapon: ::c_long = 85; +pub const SYS_getitimer: ::c_long = 86; +pub const SYS_setuid32: ::c_long = 87; +pub const SYS_sethostname: ::c_long = 88; +pub const SYS_setgid32: ::c_long = 89; +pub const SYS_dup2: ::c_long = 90; +pub const SYS_setfsuid32: ::c_long = 91; +pub const SYS_fcntl: ::c_long = 92; +pub const SYS_select: ::c_long = 93; +pub const SYS_setfsgid32: ::c_long = 94; +pub const SYS_fsync: ::c_long = 95; +pub const SYS_setpriority: ::c_long = 96; +pub const SYS_socket: ::c_long = 97; +pub const SYS_connect: ::c_long = 98; +pub const SYS_accept: ::c_long = 99; +pub const SYS_getpriority: ::c_long = 100; +pub const SYS_rt_sigreturn: ::c_long = 101; +pub const SYS_rt_sigaction: ::c_long = 102; +pub const SYS_rt_sigprocmask: ::c_long = 103; +pub const SYS_rt_sigpending: ::c_long = 104; +pub const SYS_rt_sigtimedwait: ::c_long = 105; +pub const SYS_rt_sigqueueinfo: ::c_long = 106; +pub const SYS_rt_sigsuspend: ::c_long = 107; +pub const SYS_setresuid32: ::c_long = 108; +pub const SYS_getresuid32: ::c_long = 109; +pub const SYS_setresgid32: ::c_long = 110; +pub const SYS_getresgid32: ::c_long = 111; +pub const SYS_setregid32: ::c_long = 112; +pub const SYS_recvmsg: ::c_long = 113; +pub const SYS_sendmsg: ::c_long = 114; +pub const SYS_getgroups32: ::c_long = 115; +pub const SYS_gettimeofday: ::c_long = 116; +pub const SYS_getrusage: ::c_long = 117; +pub const SYS_getsockopt: ::c_long = 118; +pub const SYS_getcwd: ::c_long = 119; +pub const SYS_readv: ::c_long = 120; +pub const SYS_writev: ::c_long = 121; +pub const SYS_settimeofday: ::c_long = 122; +pub const SYS_fchown: ::c_long = 123; +pub const SYS_fchmod: ::c_long = 124; +pub const SYS_recvfrom: ::c_long = 125; +pub const SYS_setreuid: ::c_long = 126; +pub const SYS_setregid: ::c_long = 127; +pub const SYS_rename: ::c_long = 128; +pub const SYS_truncate: ::c_long = 129; +pub const SYS_ftruncate: ::c_long = 130; +pub const SYS_flock: ::c_long = 131; +pub const SYS_lstat64: ::c_long = 132; +pub const SYS_sendto: ::c_long = 133; +pub const SYS_shutdown: ::c_long = 134; +pub const SYS_socketpair: ::c_long = 135; +pub const SYS_mkdir: ::c_long = 136; +pub const SYS_rmdir: ::c_long = 137; +pub const SYS_utimes: ::c_long = 138; +pub const SYS_stat64: ::c_long = 139; +pub const SYS_sendfile64: ::c_long = 140; +pub const SYS_getpeername: ::c_long = 141; +pub const SYS_futex: ::c_long = 142; +pub const SYS_gettid: ::c_long = 143; +pub const SYS_getrlimit: ::c_long = 144; +pub const SYS_setrlimit: ::c_long = 145; +pub const SYS_pivot_root: ::c_long = 146; +pub const SYS_prctl: ::c_long = 147; +pub const SYS_pciconfig_read: ::c_long = 148; +pub const SYS_pciconfig_write: ::c_long = 149; +pub const SYS_getsockname: ::c_long = 150; +pub const SYS_inotify_init: ::c_long = 151; +pub const SYS_inotify_add_watch: ::c_long = 152; +pub const SYS_poll: ::c_long = 153; +pub const SYS_getdents64: ::c_long = 154; +pub const SYS_fcntl64: ::c_long = 155; +pub const SYS_inotify_rm_watch: ::c_long = 156; +pub const SYS_statfs: ::c_long = 157; +pub const SYS_fstatfs: ::c_long = 158; +pub const SYS_umount: ::c_long = 159; +pub const SYS_sched_set_affinity: ::c_long = 160; +pub const SYS_sched_get_affinity: ::c_long = 161; +pub const SYS_getdomainname: ::c_long = 162; +pub const SYS_setdomainname: ::c_long = 163; +pub const SYS_quotactl: ::c_long = 165; +pub const SYS_set_tid_address: ::c_long = 166; +pub const SYS_mount: ::c_long = 167; +pub const SYS_ustat: ::c_long = 168; +pub const SYS_setxattr: ::c_long = 169; +pub const SYS_lsetxattr: ::c_long = 170; +pub const SYS_fsetxattr: ::c_long = 171; +pub const SYS_getxattr: ::c_long = 172; +pub const SYS_lgetxattr: ::c_long = 173; +pub const SYS_getdents: ::c_long = 174; +pub const SYS_setsid: ::c_long = 175; +pub const SYS_fchdir: ::c_long = 176; +pub const SYS_fgetxattr: ::c_long = 177; +pub const SYS_listxattr: ::c_long = 178; +pub const SYS_llistxattr: ::c_long = 179; +pub const SYS_flistxattr: ::c_long = 180; +pub const SYS_removexattr: ::c_long = 181; +pub const SYS_lremovexattr: ::c_long = 182; +pub const SYS_sigpending: ::c_long = 183; +pub const SYS_query_module: ::c_long = 184; +pub const SYS_setpgid: ::c_long = 185; +pub const SYS_fremovexattr: ::c_long = 186; +pub const SYS_tkill: ::c_long = 187; +pub const SYS_exit_group: ::c_long = 188; +pub const SYS_uname: ::c_long = 189; +pub const SYS_init_module: ::c_long = 190; +pub const SYS_personality: ::c_long = 191; +pub const SYS_remap_file_pages: ::c_long = 192; +pub const SYS_epoll_create: ::c_long = 193; +pub const SYS_epoll_ctl: ::c_long = 194; +pub const SYS_epoll_wait: ::c_long = 195; +pub const SYS_ioprio_set: ::c_long = 196; +pub const SYS_getppid: ::c_long = 197; +pub const SYS_sigaction: ::c_long = 198; +pub const SYS_sgetmask: ::c_long = 199; +pub const SYS_ssetmask: ::c_long = 200; +pub const SYS_sigsuspend: ::c_long = 201; +pub const SYS_oldlstat: ::c_long = 202; +pub const SYS_uselib: ::c_long = 203; +pub const SYS_readdir: ::c_long = 204; +pub const SYS_readahead: ::c_long = 205; +pub const SYS_socketcall: ::c_long = 206; +pub const SYS_syslog: ::c_long = 207; +pub const SYS_lookup_dcookie: ::c_long = 208; +pub const SYS_fadvise64: ::c_long = 209; +pub const SYS_fadvise64_64: ::c_long = 210; +pub const SYS_tgkill: ::c_long = 211; +pub const SYS_waitpid: ::c_long = 212; +pub const SYS_swapoff: ::c_long = 213; +pub const SYS_sysinfo: ::c_long = 214; +pub const SYS_ipc: ::c_long = 215; +pub const SYS_sigreturn: ::c_long = 216; +pub const SYS_clone: ::c_long = 217; +pub const SYS_ioprio_get: ::c_long = 218; +pub const SYS_adjtimex: ::c_long = 219; +pub const SYS_sigprocmask: ::c_long = 220; +pub const SYS_create_module: ::c_long = 221; +pub const SYS_delete_module: ::c_long = 222; +pub const SYS_get_kernel_syms: ::c_long = 223; +pub const SYS_getpgid: ::c_long = 224; +pub const SYS_bdflush: ::c_long = 225; +pub const SYS_sysfs: ::c_long = 226; +pub const SYS_afs_syscall: ::c_long = 227; +pub const SYS_setfsuid: ::c_long = 228; +pub const SYS_setfsgid: ::c_long = 229; +pub const SYS__newselect: ::c_long = 230; +pub const SYS_time: ::c_long = 231; +pub const SYS_splice: ::c_long = 232; +pub const SYS_stime: ::c_long = 233; +pub const SYS_statfs64: ::c_long = 234; +pub const SYS_fstatfs64: ::c_long = 235; +pub const SYS__llseek: ::c_long = 236; +pub const SYS_mlock: ::c_long = 237; +pub const SYS_munlock: ::c_long = 238; +pub const SYS_mlockall: ::c_long = 239; +pub const SYS_munlockall: ::c_long = 240; +pub const SYS_sched_setparam: ::c_long = 241; +pub const SYS_sched_getparam: ::c_long = 242; +pub const SYS_sched_setscheduler: ::c_long = 243; +pub const SYS_sched_getscheduler: ::c_long = 244; +pub const SYS_sched_yield: ::c_long = 245; +pub const SYS_sched_get_priority_max: ::c_long = 246; +pub const SYS_sched_get_priority_min: ::c_long = 247; +pub const SYS_sched_rr_get_interval: ::c_long = 248; +pub const SYS_nanosleep: ::c_long = 249; +pub const SYS_mremap: ::c_long = 250; +pub const SYS__sysctl: ::c_long = 251; +pub const SYS_getsid: ::c_long = 252; +pub const SYS_fdatasync: ::c_long = 253; +pub const SYS_nfsservctl: ::c_long = 254; +pub const SYS_sync_file_range: ::c_long = 255; +pub const SYS_clock_settime: ::c_long = 256; +pub const SYS_clock_gettime: ::c_long = 257; +pub const SYS_clock_getres: ::c_long = 258; +pub const SYS_clock_nanosleep: ::c_long = 259; +pub const SYS_sched_getaffinity: ::c_long = 260; +pub const SYS_sched_setaffinity: ::c_long = 261; +pub const SYS_timer_settime: ::c_long = 262; +pub const SYS_timer_gettime: ::c_long = 263; +pub const SYS_timer_getoverrun: ::c_long = 264; +pub const SYS_timer_delete: ::c_long = 265; +pub const SYS_timer_create: ::c_long = 266; +pub const SYS_io_setup: ::c_long = 268; +pub const SYS_io_destroy: ::c_long = 269; +pub const SYS_io_submit: ::c_long = 270; +pub const SYS_io_cancel: ::c_long = 271; +pub const SYS_io_getevents: ::c_long = 272; +pub const SYS_mq_open: ::c_long = 273; +pub const SYS_mq_unlink: ::c_long = 274; +pub const SYS_mq_timedsend: ::c_long = 275; +pub const SYS_mq_timedreceive: ::c_long = 276; +pub const SYS_mq_notify: ::c_long = 277; +pub const SYS_mq_getsetattr: ::c_long = 278; +pub const SYS_waitid: ::c_long = 279; +pub const SYS_tee: ::c_long = 280; +pub const SYS_add_key: ::c_long = 281; +pub const SYS_request_key: ::c_long = 282; +pub const SYS_keyctl: ::c_long = 283; +pub const SYS_openat: ::c_long = 284; +pub const SYS_mkdirat: ::c_long = 285; +pub const SYS_mknodat: ::c_long = 286; +pub const SYS_fchownat: ::c_long = 287; +pub const SYS_futimesat: ::c_long = 288; +pub const SYS_fstatat64: ::c_long = 289; +pub const SYS_unlinkat: ::c_long = 290; +pub const SYS_renameat: ::c_long = 291; +pub const SYS_linkat: ::c_long = 292; +pub const SYS_symlinkat: ::c_long = 293; +pub const SYS_readlinkat: ::c_long = 294; +pub const SYS_fchmodat: ::c_long = 295; +pub const SYS_faccessat: ::c_long = 296; +pub const SYS_pselect6: ::c_long = 297; +pub const SYS_ppoll: ::c_long = 298; +pub const SYS_unshare: ::c_long = 299; +pub const SYS_set_robust_list: ::c_long = 300; +pub const SYS_get_robust_list: ::c_long = 301; +pub const SYS_migrate_pages: ::c_long = 302; +pub const SYS_mbind: ::c_long = 303; +pub const SYS_get_mempolicy: ::c_long = 304; +pub const SYS_set_mempolicy: ::c_long = 305; +pub const SYS_kexec_load: ::c_long = 306; +pub const SYS_move_pages: ::c_long = 307; +pub const SYS_getcpu: ::c_long = 308; +pub const SYS_epoll_pwait: ::c_long = 309; +pub const SYS_utimensat: ::c_long = 310; +pub const SYS_signalfd: ::c_long = 311; +pub const SYS_timerfd_create: ::c_long = 312; +pub const SYS_eventfd: ::c_long = 313; +pub const SYS_fallocate: ::c_long = 314; +pub const SYS_timerfd_settime: ::c_long = 315; +pub const SYS_timerfd_gettime: ::c_long = 316; +pub const SYS_signalfd4: ::c_long = 317; +pub const SYS_eventfd2: ::c_long = 318; +pub const SYS_epoll_create1: ::c_long = 319; +pub const SYS_dup3: ::c_long = 320; +pub const SYS_pipe2: ::c_long = 321; +pub const SYS_inotify_init1: ::c_long = 322; +pub const SYS_accept4: ::c_long = 323; +pub const SYS_preadv: ::c_long = 324; +pub const SYS_pwritev: ::c_long = 325; +pub const SYS_rt_tgsigqueueinfo: ::c_long = 326; +pub const SYS_perf_event_open: ::c_long = 327; +pub const SYS_recvmmsg: ::c_long = 328; +pub const SYS_fanotify_init: ::c_long = 329; +pub const SYS_fanotify_mark: ::c_long = 330; +pub const SYS_prlimit64: ::c_long = 331; +pub const SYS_name_to_handle_at: ::c_long = 332; +pub const SYS_open_by_handle_at: ::c_long = 333; +pub const SYS_clock_adjtime: ::c_long = 334; +pub const SYS_syncfs: ::c_long = 335; +pub const SYS_sendmmsg: ::c_long = 336; +pub const SYS_setns: ::c_long = 337; +pub const SYS_process_vm_readv: ::c_long = 338; +pub const SYS_process_vm_writev: ::c_long = 339; +pub const SYS_kern_features: ::c_long = 340; +pub const SYS_kcmp: ::c_long = 341; +pub const SYS_finit_module: ::c_long = 342; +pub const SYS_sched_setattr: ::c_long = 343; +pub const SYS_sched_getattr: ::c_long = 344; +pub const SYS_renameat2: ::c_long = 345; +pub const SYS_seccomp: ::c_long = 346; +pub const SYS_getrandom: ::c_long = 347; +pub const SYS_memfd_create: ::c_long = 348; +pub const SYS_bpf: ::c_long = 349; +pub const SYS_execveat: ::c_long = 350; +pub const SYS_membarrier: ::c_long = 351; +pub const SYS_userfaultfd: ::c_long = 352; +pub const SYS_bind: ::c_long = 353; +pub const SYS_listen: ::c_long = 354; +pub const SYS_setsockopt: ::c_long = 355; +pub const SYS_mlock2: ::c_long = 356; +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; +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; +// Reserved in the kernel, but not actually implemented yet +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)] { + mod align; + pub use self::align::*; + } +} diff --git a/vendor/libc/src/unix/linux_like/linux/gnu/b32/x86/align.rs b/vendor/libc/src/unix/linux_like/linux/gnu/b32/x86/align.rs new file mode 100644 index 0000000..9663474 --- /dev/null +++ b/vendor/libc/src/unix/linux_like/linux/gnu/b32/x86/align.rs @@ -0,0 +1,7 @@ +s_no_extra_traits! { + #[allow(missing_debug_implementations)] + #[repr(align(16))] + pub struct max_align_t { + priv_: [f64; 6] + } +} 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 new file mode 100644 index 0000000..4391eb3 --- /dev/null +++ b/vendor/libc/src/unix/linux_like/linux/gnu/b32/x86/mod.rs @@ -0,0 +1,1102 @@ +pub type c_char = i8; +pub type wchar_t = i32; +pub type greg_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, + f_spare: [::__fsword_t; 5], + } + + 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 _libc_fpreg { + pub significand: [u16; 4], + pub exponent: u16, + } + + pub struct _libc_fpstate { + pub cw: ::c_ulong, + pub sw: ::c_ulong, + pub tag: ::c_ulong, + pub ipoff: ::c_ulong, + pub cssel: ::c_ulong, + pub dataoff: ::c_ulong, + pub datasel: ::c_ulong, + pub _st: [_libc_fpreg; 8], + pub status: ::c_ulong, + } + + pub struct user_fpregs_struct { + pub cwd: ::c_long, + pub swd: ::c_long, + pub twd: ::c_long, + pub fip: ::c_long, + pub fcs: ::c_long, + pub foo: ::c_long, + pub fos: ::c_long, + pub st_space: [::c_long; 20], + } + + pub struct user_regs_struct { + pub ebx: ::c_long, + pub ecx: ::c_long, + pub edx: ::c_long, + pub esi: ::c_long, + pub edi: ::c_long, + pub ebp: ::c_long, + pub eax: ::c_long, + pub xds: ::c_long, + pub xes: ::c_long, + pub xfs: ::c_long, + pub xgs: ::c_long, + pub orig_eax: ::c_long, + pub eip: ::c_long, + pub xcs: ::c_long, + pub eflags: ::c_long, + pub esp: ::c_long, + pub xss: ::c_long, + } + + 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, + pub u_ar0: *mut user_regs_struct, + pub u_fpstate: *mut user_fpregs_struct, + pub magic: ::c_ulong, + pub u_comm: [c_char; 32], + pub u_debugreg: [::c_int; 8], + } + + pub struct mcontext_t { + pub gregs: [greg_t; 19], + pub fpregs: *mut _libc_fpstate, + pub oldmask: ::c_ulong, + pub cr2: ::c_ulong, + } + + 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 stat64 { + pub st_dev: ::dev_t, + __pad1: ::c_uint, + __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_uint, + 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_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_ino: ::ino64_t, + } + + 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 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 shmid_ds { + pub shm_perm: ::ipc_perm, + pub shm_segsz: ::size_t, + pub shm_atime: ::time_t, + __unused1: ::c_ulong, + pub shm_dtime: ::time_t, + __unused2: ::c_ulong, + pub shm_ctime: ::time_t, + __unused3: ::c_ulong, + pub shm_cpid: ::pid_t, + pub shm_lpid: ::pid_t, + pub shm_nattch: ::shmatt_t, + __unused4: ::c_ulong, + __unused5: ::c_ulong + } + + pub struct msqid_ds { + pub msg_perm: ::ipc_perm, + pub msg_stime: ::time_t, + __glibc_reserved1: ::c_ulong, + pub msg_rtime: ::time_t, + __glibc_reserved2: ::c_ulong, + pub msg_ctime: ::time_t, + __glibc_reserved3: ::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, + __glibc_reserved4: ::c_ulong, + __glibc_reserved5: ::c_ulong, + } + + 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: [usize; 0], + } + + pub struct stack_t { + pub ss_sp: *mut ::c_void, + pub ss_flags: ::c_int, + pub ss_size: ::size_t + } + +} + +s_no_extra_traits! { + pub struct user_fpxregs_struct { + pub cwd: ::c_ushort, + pub swd: ::c_ushort, + pub twd: ::c_ushort, + pub fop: ::c_ushort, + pub fip: ::c_long, + pub fcs: ::c_long, + pub foo: ::c_long, + pub fos: ::c_long, + pub mxcsr: ::c_long, + __reserved: ::c_long, + pub st_space: [::c_long; 32], + pub xmm_space: [::c_long; 32], + padding: [::c_long; 56], + } + + 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, + __private: [u8; 112], + __ssp: [::c_ulong; 4], + } +} + +cfg_if! { + if #[cfg(feature = "extra_traits")] { + impl PartialEq for user_fpxregs_struct { + fn eq(&self, other: &user_fpxregs_struct) -> bool { + self.cwd == other.cwd + && self.swd == other.swd + && self.twd == other.twd + && self.fop == other.fop + && self.fip == other.fip + && self.fcs == other.fcs + && self.foo == other.foo + && self.fos == other.fos + && self.mxcsr == other.mxcsr + // Ignore __reserved field + && self.st_space == other.st_space + && self.xmm_space == other.xmm_space + // Ignore padding field + } + } + + impl Eq for user_fpxregs_struct {} + + impl ::fmt::Debug for user_fpxregs_struct { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("user_fpxregs_struct") + .field("cwd", &self.cwd) + .field("swd", &self.swd) + .field("twd", &self.twd) + .field("fop", &self.fop) + .field("fip", &self.fip) + .field("fcs", &self.fcs) + .field("foo", &self.foo) + .field("fos", &self.fos) + .field("mxcsr", &self.mxcsr) + // Ignore __reserved field + .field("st_space", &self.st_space) + .field("xmm_space", &self.xmm_space) + // Ignore padding field + .finish() + } + } + + impl ::hash::Hash for user_fpxregs_struct { + fn hash(&self, state: &mut H) { + self.cwd.hash(state); + self.swd.hash(state); + self.twd.hash(state); + self.fop.hash(state); + self.fip.hash(state); + self.fcs.hash(state); + self.foo.hash(state); + self.fos.hash(state); + self.mxcsr.hash(state); + // Ignore __reserved field + self.st_space.hash(state); + self.xmm_space.hash(state); + // Ignore padding field + } + } + + 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 + // Ignore __private field + } + } + + impl Eq for ucontext_t {} + + impl ::fmt::Debug for ucontext_t { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("ucontext_t") + .field("uc_flags", &self.uc_flags) + .field("uc_link", &self.uc_link) + .field("uc_stack", &self.uc_stack) + .field("uc_mcontext", &self.uc_mcontext) + .field("uc_sigmask", &self.uc_sigmask) + // Ignore __private field + .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); + // Ignore __private field + } + } + } +} + +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 = 0x4000; +pub const O_DIRECTORY: ::c_int = 0x10000; +pub const O_NOFOLLOW: ::c_int = 0x20000; +pub const O_LARGEFILE: ::c_int = 0o0100000; +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 MCL_ONFAULT: ::c_int = 0x0004; + +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; + +// Syscall table +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_time: ::c_long = 13; +pub const SYS_mknod: ::c_long = 14; +pub const SYS_chmod: ::c_long = 15; +pub const SYS_lchown: ::c_long = 16; +pub const SYS_break: ::c_long = 17; +pub const SYS_oldstat: ::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_umount: ::c_long = 22; +pub const SYS_setuid: ::c_long = 23; +pub const SYS_getuid: ::c_long = 24; +pub const SYS_stime: ::c_long = 25; +pub const SYS_ptrace: ::c_long = 26; +pub const SYS_alarm: ::c_long = 27; +pub const SYS_oldfstat: ::c_long = 28; +pub const SYS_pause: ::c_long = 29; +pub const SYS_utime: ::c_long = 30; +pub const SYS_stty: ::c_long = 31; +pub const SYS_gtty: ::c_long = 32; +pub const SYS_access: ::c_long = 33; +pub const SYS_nice: ::c_long = 34; +pub const SYS_ftime: ::c_long = 35; +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_prof: ::c_long = 44; +pub const SYS_brk: ::c_long = 45; +pub const SYS_setgid: ::c_long = 46; +pub const SYS_getgid: ::c_long = 47; +pub const SYS_signal: ::c_long = 48; +pub const SYS_geteuid: ::c_long = 49; +pub const SYS_getegid: ::c_long = 50; +pub const SYS_acct: ::c_long = 51; +pub const SYS_umount2: ::c_long = 52; +pub const SYS_lock: ::c_long = 53; +pub const SYS_ioctl: ::c_long = 54; +pub const SYS_fcntl: ::c_long = 55; +pub const SYS_mpx: ::c_long = 56; +pub const SYS_setpgid: ::c_long = 57; +pub const SYS_ulimit: ::c_long = 58; +pub const SYS_oldolduname: ::c_long = 59; +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_setreuid: ::c_long = 70; +pub const SYS_setregid: ::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_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_getgroups: ::c_long = 80; +pub const SYS_setgroups: ::c_long = 81; +pub const SYS_select: ::c_long = 82; +pub const SYS_symlink: ::c_long = 83; +pub const SYS_oldlstat: ::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_readdir: ::c_long = 89; +pub const SYS_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_fchown: ::c_long = 95; +pub const SYS_getpriority: ::c_long = 96; +pub const SYS_setpriority: ::c_long = 97; +pub const SYS_profil: ::c_long = 98; +pub const SYS_statfs: ::c_long = 99; +pub const SYS_fstatfs: ::c_long = 100; +pub const SYS_ioperm: ::c_long = 101; +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_stat: ::c_long = 106; +pub const SYS_lstat: ::c_long = 107; +pub const SYS_fstat: ::c_long = 108; +pub const SYS_olduname: ::c_long = 109; +pub const SYS_iopl: ::c_long = 110; +pub const SYS_vhangup: ::c_long = 111; +pub const SYS_idle: ::c_long = 112; +pub const SYS_vm86old: ::c_long = 113; +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_uname: ::c_long = 122; +pub const SYS_modify_ldt: ::c_long = 123; +pub const SYS_adjtimex: ::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_afs_syscall: ::c_long = 137; +pub const SYS_setfsuid: ::c_long = 138; +pub const SYS_setfsgid: ::c_long = 139; +pub const SYS__llseek: ::c_long = 140; +pub const SYS_getdents: ::c_long = 141; +pub const SYS__newselect: ::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: ::c_long = 161; +pub const SYS_nanosleep: ::c_long = 162; +pub const SYS_mremap: ::c_long = 163; +pub const SYS_setresuid: ::c_long = 164; +pub const SYS_getresuid: ::c_long = 165; +pub const SYS_vm86: ::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_setresgid: ::c_long = 170; +pub const SYS_getresgid: ::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: ::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_chown: ::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_ugetrlimit: ::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_lchown32: ::c_long = 198; +pub const SYS_getuid32: ::c_long = 199; +pub const SYS_getgid32: ::c_long = 200; +pub const SYS_geteuid32: ::c_long = 201; +pub const SYS_getegid32: ::c_long = 202; +pub const SYS_setreuid32: ::c_long = 203; +pub const SYS_setregid32: ::c_long = 204; +pub const SYS_getgroups32: ::c_long = 205; +pub const SYS_setgroups32: ::c_long = 206; +pub const SYS_fchown32: ::c_long = 207; +pub const SYS_setresuid32: ::c_long = 208; +pub const SYS_getresuid32: ::c_long = 209; +pub const SYS_setresgid32: ::c_long = 210; +pub const SYS_getresgid32: ::c_long = 211; +pub const SYS_chown32: ::c_long = 212; +pub const SYS_setuid32: ::c_long = 213; +pub const SYS_setgid32: ::c_long = 214; +pub const SYS_setfsuid32: ::c_long = 215; +pub const SYS_setfsgid32: ::c_long = 216; +pub const SYS_pivot_root: ::c_long = 217; +pub const SYS_mincore: ::c_long = 218; +pub const SYS_madvise: ::c_long = 219; +pub const SYS_getdents64: ::c_long = 220; +pub const SYS_fcntl64: ::c_long = 221; +pub const SYS_gettid: ::c_long = 224; +pub const SYS_readahead: ::c_long = 225; +pub const SYS_setxattr: ::c_long = 226; +pub const SYS_lsetxattr: ::c_long = 227; +pub const SYS_fsetxattr: ::c_long = 228; +pub const SYS_getxattr: ::c_long = 229; +pub const SYS_lgetxattr: ::c_long = 230; +pub const SYS_fgetxattr: ::c_long = 231; +pub const SYS_listxattr: ::c_long = 232; +pub const SYS_llistxattr: ::c_long = 233; +pub const SYS_flistxattr: ::c_long = 234; +pub const SYS_removexattr: ::c_long = 235; +pub const SYS_lremovexattr: ::c_long = 236; +pub const SYS_fremovexattr: ::c_long = 237; +pub const SYS_tkill: ::c_long = 238; +pub const SYS_sendfile64: ::c_long = 239; +pub const SYS_futex: ::c_long = 240; +pub const SYS_sched_setaffinity: ::c_long = 241; +pub const SYS_sched_getaffinity: ::c_long = 242; +pub const SYS_set_thread_area: ::c_long = 243; +pub const SYS_get_thread_area: ::c_long = 244; +pub const SYS_io_setup: ::c_long = 245; +pub const SYS_io_destroy: ::c_long = 246; +pub const SYS_io_getevents: ::c_long = 247; +pub const SYS_io_submit: ::c_long = 248; +pub const SYS_io_cancel: ::c_long = 249; +pub const SYS_fadvise64: ::c_long = 250; +pub const SYS_exit_group: ::c_long = 252; +pub const SYS_lookup_dcookie: ::c_long = 253; +pub const SYS_epoll_create: ::c_long = 254; +pub const SYS_epoll_ctl: ::c_long = 255; +pub const SYS_epoll_wait: ::c_long = 256; +pub const SYS_remap_file_pages: ::c_long = 257; +pub const SYS_set_tid_address: ::c_long = 258; +pub const SYS_timer_create: ::c_long = 259; +pub const SYS_timer_settime: ::c_long = 260; +pub const SYS_timer_gettime: ::c_long = 261; +pub const SYS_timer_getoverrun: ::c_long = 262; +pub const SYS_timer_delete: ::c_long = 263; +pub const SYS_clock_settime: ::c_long = 264; +pub const SYS_clock_gettime: ::c_long = 265; +pub const SYS_clock_getres: ::c_long = 266; +pub const SYS_clock_nanosleep: ::c_long = 267; +pub const SYS_statfs64: ::c_long = 268; +pub const SYS_fstatfs64: ::c_long = 269; +pub const SYS_tgkill: ::c_long = 270; +pub const SYS_utimes: ::c_long = 271; +pub const SYS_fadvise64_64: ::c_long = 272; +pub const SYS_vserver: ::c_long = 273; +pub const SYS_mbind: ::c_long = 274; +pub const SYS_get_mempolicy: ::c_long = 275; +pub const SYS_set_mempolicy: ::c_long = 276; +pub const SYS_mq_open: ::c_long = 277; +pub const SYS_mq_unlink: ::c_long = 278; +pub const SYS_mq_timedsend: ::c_long = 279; +pub const SYS_mq_timedreceive: ::c_long = 280; +pub const SYS_mq_notify: ::c_long = 281; +pub const SYS_mq_getsetattr: ::c_long = 282; +pub const SYS_kexec_load: ::c_long = 283; +pub const SYS_waitid: ::c_long = 284; +pub const SYS_add_key: ::c_long = 286; +pub const SYS_request_key: ::c_long = 287; +pub const SYS_keyctl: ::c_long = 288; +pub const SYS_ioprio_set: ::c_long = 289; +pub const SYS_ioprio_get: ::c_long = 290; +pub const SYS_inotify_init: ::c_long = 291; +pub const SYS_inotify_add_watch: ::c_long = 292; +pub const SYS_inotify_rm_watch: ::c_long = 293; +pub const SYS_migrate_pages: ::c_long = 294; +pub const SYS_openat: ::c_long = 295; +pub const SYS_mkdirat: ::c_long = 296; +pub const SYS_mknodat: ::c_long = 297; +pub const SYS_fchownat: ::c_long = 298; +pub const SYS_futimesat: ::c_long = 299; +pub const SYS_fstatat64: ::c_long = 300; +pub const SYS_unlinkat: ::c_long = 301; +pub const SYS_renameat: ::c_long = 302; +pub const SYS_linkat: ::c_long = 303; +pub const SYS_symlinkat: ::c_long = 304; +pub const SYS_readlinkat: ::c_long = 305; +pub const SYS_fchmodat: ::c_long = 306; +pub const SYS_faccessat: ::c_long = 307; +pub const SYS_pselect6: ::c_long = 308; +pub const SYS_ppoll: ::c_long = 309; +pub const SYS_unshare: ::c_long = 310; +pub const SYS_set_robust_list: ::c_long = 311; +pub const SYS_get_robust_list: ::c_long = 312; +pub const SYS_splice: ::c_long = 313; +pub const SYS_sync_file_range: ::c_long = 314; +pub const SYS_tee: ::c_long = 315; +pub const SYS_vmsplice: ::c_long = 316; +pub const SYS_move_pages: ::c_long = 317; +pub const SYS_getcpu: ::c_long = 318; +pub const SYS_epoll_pwait: ::c_long = 319; +pub const SYS_utimensat: ::c_long = 320; +pub const SYS_signalfd: ::c_long = 321; +pub const SYS_timerfd_create: ::c_long = 322; +pub const SYS_eventfd: ::c_long = 323; +pub const SYS_fallocate: ::c_long = 324; +pub const SYS_timerfd_settime: ::c_long = 325; +pub const SYS_timerfd_gettime: ::c_long = 326; +pub const SYS_signalfd4: ::c_long = 327; +pub const SYS_eventfd2: ::c_long = 328; +pub const SYS_epoll_create1: ::c_long = 329; +pub const SYS_dup3: ::c_long = 330; +pub const SYS_pipe2: ::c_long = 331; +pub const SYS_inotify_init1: ::c_long = 332; +pub const SYS_preadv: ::c_long = 333; +pub const SYS_pwritev: ::c_long = 334; +pub const SYS_rt_tgsigqueueinfo: ::c_long = 335; +pub const SYS_perf_event_open: ::c_long = 336; +pub const SYS_recvmmsg: ::c_long = 337; +pub const SYS_fanotify_init: ::c_long = 338; +pub const SYS_fanotify_mark: ::c_long = 339; +pub const SYS_prlimit64: ::c_long = 340; +pub const SYS_name_to_handle_at: ::c_long = 341; +pub const SYS_open_by_handle_at: ::c_long = 342; +pub const SYS_clock_adjtime: ::c_long = 343; +pub const SYS_syncfs: ::c_long = 344; +pub const SYS_sendmmsg: ::c_long = 345; +pub const SYS_setns: ::c_long = 346; +pub const SYS_process_vm_readv: ::c_long = 347; +pub const SYS_process_vm_writev: ::c_long = 348; +pub const SYS_kcmp: ::c_long = 349; +pub const SYS_finit_module: ::c_long = 350; +pub const SYS_sched_setattr: ::c_long = 351; +pub const SYS_sched_getattr: ::c_long = 352; +pub const SYS_renameat2: ::c_long = 353; +pub const SYS_seccomp: ::c_long = 354; +pub const SYS_getrandom: ::c_long = 355; +pub const SYS_memfd_create: ::c_long = 356; +pub const SYS_bpf: ::c_long = 357; +pub const SYS_execveat: ::c_long = 358; +pub const SYS_socket: ::c_long = 359; +pub const SYS_socketpair: ::c_long = 360; +pub const SYS_bind: ::c_long = 361; +pub const SYS_connect: ::c_long = 362; +pub const SYS_listen: ::c_long = 363; +pub const SYS_accept4: ::c_long = 364; +pub const SYS_getsockopt: ::c_long = 365; +pub const SYS_setsockopt: ::c_long = 366; +pub const SYS_getsockname: ::c_long = 367; +pub const SYS_getpeername: ::c_long = 368; +pub const SYS_sendto: ::c_long = 369; +pub const SYS_sendmsg: ::c_long = 370; +pub const SYS_recvfrom: ::c_long = 371; +pub const SYS_recvmsg: ::c_long = 372; +pub const SYS_shutdown: ::c_long = 373; +pub const SYS_userfaultfd: ::c_long = 374; +pub const SYS_membarrier: ::c_long = 375; +pub const SYS_mlock2: ::c_long = 376; +pub const SYS_copy_file_range: ::c_long = 377; +pub const SYS_preadv2: ::c_long = 378; +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_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; +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; +pub const SYS_fchmodat2: ::c_long = 452; +pub const SYS_mseal: ::c_long = 462; + +// offsets in user_regs_structs, from sys/reg.h +pub const EBX: ::c_int = 0; +pub const ECX: ::c_int = 1; +pub const EDX: ::c_int = 2; +pub const ESI: ::c_int = 3; +pub const EDI: ::c_int = 4; +pub const EBP: ::c_int = 5; +pub const EAX: ::c_int = 6; +pub const DS: ::c_int = 7; +pub const ES: ::c_int = 8; +pub const FS: ::c_int = 9; +pub const GS: ::c_int = 10; +pub const ORIG_EAX: ::c_int = 11; +pub const EIP: ::c_int = 12; +pub const CS: ::c_int = 13; +pub const EFL: ::c_int = 14; +pub const UESP: ::c_int = 15; +pub const SS: ::c_int = 16; + +// offsets in mcontext_t.gregs from sys/ucontext.h +pub const REG_GS: ::c_int = 0; +pub const REG_FS: ::c_int = 1; +pub const REG_ES: ::c_int = 2; +pub const REG_DS: ::c_int = 3; +pub const REG_EDI: ::c_int = 4; +pub const REG_ESI: ::c_int = 5; +pub const REG_EBP: ::c_int = 6; +pub const REG_ESP: ::c_int = 7; +pub const REG_EBX: ::c_int = 8; +pub const REG_EDX: ::c_int = 9; +pub const REG_ECX: ::c_int = 10; +pub const REG_EAX: ::c_int = 11; +pub const REG_TRAPNO: ::c_int = 12; +pub const REG_ERR: ::c_int = 13; +pub const REG_EIP: ::c_int = 14; +pub const REG_CS: ::c_int = 15; +pub const REG_EFL: ::c_int = 16; +pub const REG_UESP: ::c_int = 17; +pub const REG_SS: ::c_int = 18; + +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; +} + +cfg_if! { + if #[cfg(libc_align)] { + mod align; + pub use self::align::*; + } +} 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 new file mode 100644 index 0000000..a035773 --- /dev/null +++ b/vendor/libc/src/unix/linux_like/linux/gnu/b64/aarch64/align.rs @@ -0,0 +1,51 @@ +s_no_extra_traits! { + #[allow(missing_debug_implementations)] + #[repr(align(16))] + pub struct max_align_t { + priv_: [f32; 8] + } +} + +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 fault_address: ::c_ulonglong, + pub regs: [::c_ulonglong; 31], + pub sp: ::c_ulonglong, + pub pc: ::c_ulonglong, + pub pstate: ::c_ulonglong, + // nested arrays to get the right size/length while being able to + // auto-derive traits like Debug + __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, + } +} + +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/fallback.rs b/vendor/libc/src/unix/linux_like/linux/gnu/b64/aarch64/fallback.rs new file mode 100644 index 0000000..398fbb5 --- /dev/null +++ b/vendor/libc/src/unix/linux_like/linux/gnu/b64/aarch64/fallback.rs @@ -0,0 +1,8 @@ +s! { + #[repr(align(16))] + pub struct user_fpsimd_struct { + pub vregs: [[u64; 2]; 32], + pub fpsr: ::c_uint, + pub fpcr: ::c_uint, + } +} 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 new file mode 100644 index 0000000..0848fb5 --- /dev/null +++ b/vendor/libc/src/unix/linux_like/linux/gnu/b64/aarch64/ilp32.rs @@ -0,0 +1,64 @@ +use pthread_mutex_t; + +pub type c_long = i32; +pub type c_ulong = u32; + +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")] + 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, 1, 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, 2, 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, 3, 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, 1, 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, 2, 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, 3, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + ], + }; +} + +pub const SYS_sync_file_range2: ::c_long = 84; 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 new file mode 100644 index 0000000..3802caf --- /dev/null +++ b/vendor/libc/src/unix/linux_like/linux/gnu/b64/aarch64/lp64.rs @@ -0,0 +1,73 @@ +use pthread_mutex_t; + +pub type c_long = i64; +pub type c_ulong = u64; + +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")] + 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, 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, 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, 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, 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, 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, 0, 0, + 0, 0, 0, 0, 0, 0, + ], + }; +} + +pub const SYS_renameat: ::c_long = 38; +pub const SYS_sync_file_range: ::c_long = 84; +pub const SYS_getrlimit: ::c_long = 163; +pub const SYS_setrlimit: ::c_long = 164; 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 new file mode 100644 index 0000000..c8a805c --- /dev/null +++ b/vendor/libc/src/unix/linux_like/linux/gnu/b64/aarch64/mod.rs @@ -0,0 +1,938 @@ +//! AArch64-specific definitions for 64-bit linux-like values + +pub type c_char = u8; +pub type wchar_t = u32; +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 { + pub sa_sigaction: ::sighandler_t, + pub sa_mask: ::sigset_t, + #[cfg(target_arch = "sparc64")] + __reserved0: ::c_int, + 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, + f_spare: [::__fsword_t; 5], + } + + 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 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: ::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: ::off64_t, + pub st_blksize: ::blksize_t, + __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 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 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: [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, + pub gid: ::gid_t, + pub cuid: ::uid_t, + pub cgid: ::gid_t, + pub mode: ::c_uint, + pub __seq: ::c_ushort, + __pad1: ::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 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: [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_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_NOATIME: ::c_int = 0o1000000; +pub const O_PATH: ::c_int = 0o10000000; +pub const O_TMPFILE: ::c_int = 0o20000000 | O_DIRECTORY; + +pub const MADV_SOFT_OFFLINE: ::c_int = 101; +pub const MAP_GROWSDOWN: ::c_int = 0x0100; + +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 POSIX_FADV_DONTNEED: ::c_int = 4; +pub const POSIX_FADV_NOREUSE: ::c_int = 5; + +pub const SOCK_STREAM: ::c_int = 1; +pub const SOCK_DGRAM: ::c_int = 2; + +pub const SA_ONSTACK: ::c_int = 0x08000000; +pub const SA_SIGINFO: ::c_int = 0x00000004; +pub const SA_NOCLDWAIT: ::c_int = 0x00000002; + +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; +#[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 POLLWRNORM: ::c_short = 0x100; +pub const POLLWRBAND: ::c_short = 0x200; + +pub const O_ASYNC: ::c_int = 0x2000; +pub const O_NDELAY: ::c_int = 0x800; + +pub const PTRACE_DETACH: ::c_uint = 17; + +pub const EFD_NONBLOCK: ::c_int = 0x800; + +pub const F_GETLK: ::c_int = 5; +pub const F_GETOWN: ::c_int = 9; +pub const F_SETOWN: ::c_int = 8; +pub const F_SETLK: ::c_int = 6; +pub const F_SETLKW: ::c_int = 7; +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_WRLCK: ::c_int = 1; +pub const F_UNLCK: ::c_int = 2; + +pub const SFD_NONBLOCK: ::c_int = 0x0800; + +pub const SFD_CLOEXEC: ::c_int = 0x080000; + +pub const NCCS: usize = 32; + +pub const O_TRUNC: ::c_int = 512; + +pub const O_CLOEXEC: ::c_int = 0x80000; + +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 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 EPOLL_CLOEXEC: ::c_int = 0x80000; + +pub const EFD_CLOEXEC: ::c_int = 0x80000; + +pub const O_DIRECT: ::c_int = 0x10000; +pub const O_DIRECTORY: ::c_int = 0x4000; +pub const O_NOFOLLOW: ::c_int = 0x8000; + +pub const MAP_LOCKED: ::c_int = 0x02000; +pub const MAP_NORESERVE: ::c_int = 0x04000; +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_SYNC: ::c_int = 0x080000; + +pub const EDEADLOCK: ::c_int = 35; + +pub const MCL_CURRENT: ::c_int = 0x0001; +pub const MCL_FUTURE: ::c_int = 0x0002; +pub const MCL_ONFAULT: ::c_int = 0x0004; + +pub const SIGSTKSZ: ::size_t = 16384; +pub const MINSIGSTKSZ: ::size_t = 5120; +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; + +// sys/auxv.h +pub const HWCAP_FP: ::c_ulong = 1 << 0; +pub const HWCAP_ASIMD: ::c_ulong = 1 << 1; +pub const HWCAP_EVTSTRM: ::c_ulong = 1 << 2; +pub const HWCAP_AES: ::c_ulong = 1 << 3; +pub const HWCAP_PMULL: ::c_ulong = 1 << 4; +pub const HWCAP_SHA1: ::c_ulong = 1 << 5; +pub const HWCAP_SHA2: ::c_ulong = 1 << 6; +pub const HWCAP_CRC32: ::c_ulong = 1 << 7; +pub const HWCAP_ATOMICS: ::c_ulong = 1 << 8; +pub const HWCAP_FPHP: ::c_ulong = 1 << 9; +pub const HWCAP_ASIMDHP: ::c_ulong = 1 << 10; +pub const HWCAP_CPUID: ::c_ulong = 1 << 11; +pub const HWCAP_ASIMDRDM: ::c_ulong = 1 << 12; +pub const HWCAP_JSCVT: ::c_ulong = 1 << 13; +pub const HWCAP_FCMA: ::c_ulong = 1 << 14; +pub const HWCAP_LRCPC: ::c_ulong = 1 << 15; +pub const HWCAP_DCPOP: ::c_ulong = 1 << 16; +pub const HWCAP_SHA3: ::c_ulong = 1 << 17; +pub const HWCAP_SM3: ::c_ulong = 1 << 18; +pub const HWCAP_SM4: ::c_ulong = 1 << 19; +pub const HWCAP_ASIMDDP: ::c_ulong = 1 << 20; +pub const HWCAP_SHA512: ::c_ulong = 1 << 21; +pub const HWCAP_SVE: ::c_ulong = 1 << 22; +pub const HWCAP_ASIMDFHM: ::c_ulong = 1 << 23; +pub const HWCAP_DIT: ::c_ulong = 1 << 24; +pub const HWCAP_USCAT: ::c_ulong = 1 << 25; +pub const HWCAP_ILRCPC: ::c_ulong = 1 << 26; +pub const HWCAP_FLAGM: ::c_ulong = 1 << 27; +pub const HWCAP_SSBS: ::c_ulong = 1 << 28; +pub const HWCAP_SB: ::c_ulong = 1 << 29; +pub const HWCAP_PACA: ::c_ulong = 1 << 30; +pub const HWCAP_PACG: ::c_ulong = 1 << 31; +// FIXME: enable these again once linux-api-headers are up to date enough on CI. +// See discussion in https://github.com/rust-lang/libc/pull/1638 +//pub const HWCAP2_DCPODP: ::c_ulong = 1 << 0; +//pub const HWCAP2_SVE2: ::c_ulong = 1 << 1; +//pub const HWCAP2_SVEAES: ::c_ulong = 1 << 2; +//pub const HWCAP2_SVEPMULL: ::c_ulong = 1 << 3; +//pub const HWCAP2_SVEBITPERM: ::c_ulong = 1 << 4; +//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_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; +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; +// 38 is renameat only on LP64 +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_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_newfstatat: ::c_long = 79; +pub const SYS_fstat: ::c_long = 80; +pub const SYS_sync: ::c_long = 81; +pub const SYS_fsync: ::c_long = 82; +pub const SYS_fdatasync: ::c_long = 83; +// 84 sync_file_range on LP64 and sync_file_range2 on ILP32 +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; +// 163 is getrlimit only on LP64 +// 164 is setrlimit only on LP64 +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_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_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_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_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 SYS_mseal: ::c_long = 462; + +pub const PROT_BTI: ::c_int = 0x10; +pub const PROT_MTE: ::c_int = 0x20; + +extern "C" { + pub fn sysctl( + name: *mut ::c_int, + namelen: ::c_int, + oldp: *mut ::c_void, + oldlenp: *mut ::size_t, + newp: *mut ::c_void, + newlen: ::size_t, + ) -> ::c_int; +} + +cfg_if! { + if #[cfg(target_pointer_width = "32")] { + mod ilp32; + pub use self::ilp32::*; + } else { + mod lp64; + pub use self::lp64::*; + } +} + +cfg_if! { + if #[cfg(libc_align)] { + mod align; + pub use self::align::*; + } + + +} + +cfg_if! { + if #[cfg(libc_int128)] { + mod int128; + pub use self::int128::*; + } else if #[cfg(libc_align)] { + mod fallback; + pub use self::fallback::*; + } +} 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..dc191f5 --- /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 __pc: ::c_ulonglong, + pub __gregs: [::c_ulonglong; 32], + pub __flags: ::c_uint, + pub __extcontext: [::c_ulonglong; 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..ac3f889 --- /dev/null +++ b/vendor/libc/src/unix/linux_like/linux/gnu/b64/loongarch64/mod.rs @@ -0,0 +1,900 @@ +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 struct user_regs_struct { + pub regs: [u64; 32], + pub orig_a0: u64, + pub csr_era: u64, + pub csr_badv: u64, + pub reserved: [u64; 10], + + } + + pub struct user_fp_struct { + pub fpr: [u64; 32], + pub fcc: u64, + pub fcsr: u32, + } +} + +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 HWCAP_LOONGARCH_CPUCFG: ::c_ulong = 1 << 0; +pub const HWCAP_LOONGARCH_LAM: ::c_ulong = 1 << 1; +pub const HWCAP_LOONGARCH_UAL: ::c_ulong = 1 << 2; +pub const HWCAP_LOONGARCH_FPU: ::c_ulong = 1 << 3; +pub const HWCAP_LOONGARCH_LSX: ::c_ulong = 1 << 4; +pub const HWCAP_LOONGARCH_LASX: ::c_ulong = 1 << 5; +pub const HWCAP_LOONGARCH_CRC32: ::c_ulong = 1 << 6; +pub const HWCAP_LOONGARCH_COMPLEX: ::c_ulong = 1 << 7; +pub const HWCAP_LOONGARCH_CRYPTO: ::c_ulong = 1 << 8; +pub const HWCAP_LOONGARCH_LVZ: ::c_ulong = 1 << 9; +pub const HWCAP_LOONGARCH_LBT_X86: ::c_ulong = 1 << 10; +pub const HWCAP_LOONGARCH_LBT_ARM: ::c_ulong = 1 << 11; +pub const HWCAP_LOONGARCH_LBT_MIPS: ::c_ulong = 1 << 12; +pub const HWCAP_LOONGARCH_PTW: ::c_ulong = 1 << 13; + +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 MADV_SOFT_OFFLINE: ::c_int = 101; + +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 MAP_SYNC: ::c_int = 0x080000; +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 PTRACE_SYSEMU: ::c_uint = 31; +pub const PTRACE_SYSEMU_SINGLESTEP: ::c_uint = 32; + +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 XCASE: ::tcflag_t = 0x00000004; +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/align.rs b/vendor/libc/src/unix/linux_like/linux/gnu/b64/mips64/align.rs new file mode 100644 index 0000000..7ca870f --- /dev/null +++ b/vendor/libc/src/unix/linux_like/linux/gnu/b64/mips64/align.rs @@ -0,0 +1,7 @@ +s_no_extra_traits! { + #[allow(missing_debug_implementations)] + #[repr(align(16))] + pub struct max_align_t { + priv_: [f64; 4] + } +} 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 new file mode 100644 index 0000000..f7b52be --- /dev/null +++ b/vendor/libc/src/unix/linux_like/linux/gnu/b64/mips64/mod.rs @@ -0,0 +1,934 @@ +use pthread_mutex_t; + +pub type blksize_t = i64; +pub type c_char = i8; +pub type c_long = i64; +pub type c_ulong = u64; +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 { + pub st_dev: ::c_ulong, + st_pad1: [::c_long; 2], + 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_ulong, + st_pad2: [::c_ulong; 1], + pub st_size: ::off_t, + st_pad3: ::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, + pub st_blksize: ::blksize_t, + st_pad4: ::c_long, + pub st_blocks: ::blkcnt_t, + st_pad5: [::c_long; 7], + } + + pub struct statfs { + pub f_type: ::c_long, + pub f_bsize: ::c_long, + pub f_frsize: ::c_long, + pub f_blocks: ::fsblkcnt_t, + pub f_bfree: ::fsblkcnt_t, + pub f_files: ::fsblkcnt_t, + pub f_ffree: ::fsblkcnt_t, + pub f_bavail: ::fsblkcnt_t, + pub f_fsid: ::fsid_t, + + pub f_namelen: ::c_long, + f_spare: [::c_long; 6], + } + + 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 stat64 { + pub st_dev: ::c_ulong, + st_pad1: [::c_long; 2], + 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: ::c_ulong, + st_pad2: [::c_long; 2], + pub st_size: ::off64_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_blksize: ::blksize_t, + st_pad3: ::c_long, + pub st_blocks: ::blkcnt64_t, + st_pad5: [::c_long; 7], + } + + pub struct statfs64 { + pub f_type: ::c_long, + pub f_bsize: ::c_long, + pub f_frsize: ::c_long, + pub f_blocks: u64, + pub f_bfree: u64, + pub f_files: u64, + pub f_ffree: u64, + pub f_bavail: u64, + pub f_fsid: ::fsid_t, + pub f_namelen: ::c_long, + pub f_flags: ::c_long, + pub f_spare: [::c_long; 5], + } + + 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_flags: ::c_int, + pub sa_sigaction: ::sighandler_t, + pub sa_mask: ::sigset_t, + pub sa_restorer: ::Option, + } + + pub struct stack_t { + pub ss_sp: *mut ::c_void, + pub ss_size: ::size_t, + pub ss_flags: ::c_int, + } + + pub struct siginfo_t { + pub si_signo: ::c_int, + pub si_code: ::c_int, + pub si_errno: ::c_int, + _pad: ::c_int, + _pad2: [::c_long; 14], + } + + 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, + __pad1: ::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_read: ::c_long = 5000 + 0; +pub const SYS_write: ::c_long = 5000 + 1; +pub const SYS_open: ::c_long = 5000 + 2; +pub const SYS_close: ::c_long = 5000 + 3; +pub const SYS_stat: ::c_long = 5000 + 4; +pub const SYS_fstat: ::c_long = 5000 + 5; +pub const SYS_lstat: ::c_long = 5000 + 6; +pub const SYS_poll: ::c_long = 5000 + 7; +pub const SYS_lseek: ::c_long = 5000 + 8; +pub const SYS_mmap: ::c_long = 5000 + 9; +pub const SYS_mprotect: ::c_long = 5000 + 10; +pub const SYS_munmap: ::c_long = 5000 + 11; +pub const SYS_brk: ::c_long = 5000 + 12; +pub const SYS_rt_sigaction: ::c_long = 5000 + 13; +pub const SYS_rt_sigprocmask: ::c_long = 5000 + 14; +pub const SYS_ioctl: ::c_long = 5000 + 15; +pub const SYS_pread64: ::c_long = 5000 + 16; +pub const SYS_pwrite64: ::c_long = 5000 + 17; +pub const SYS_readv: ::c_long = 5000 + 18; +pub const SYS_writev: ::c_long = 5000 + 19; +pub const SYS_access: ::c_long = 5000 + 20; +pub const SYS_pipe: ::c_long = 5000 + 21; +pub const SYS__newselect: ::c_long = 5000 + 22; +pub const SYS_sched_yield: ::c_long = 5000 + 23; +pub const SYS_mremap: ::c_long = 5000 + 24; +pub const SYS_msync: ::c_long = 5000 + 25; +pub const SYS_mincore: ::c_long = 5000 + 26; +pub const SYS_madvise: ::c_long = 5000 + 27; +pub const SYS_shmget: ::c_long = 5000 + 28; +pub const SYS_shmat: ::c_long = 5000 + 29; +pub const SYS_shmctl: ::c_long = 5000 + 30; +pub const SYS_dup: ::c_long = 5000 + 31; +pub const SYS_dup2: ::c_long = 5000 + 32; +pub const SYS_pause: ::c_long = 5000 + 33; +pub const SYS_nanosleep: ::c_long = 5000 + 34; +pub const SYS_getitimer: ::c_long = 5000 + 35; +pub const SYS_setitimer: ::c_long = 5000 + 36; +pub const SYS_alarm: ::c_long = 5000 + 37; +pub const SYS_getpid: ::c_long = 5000 + 38; +pub const SYS_sendfile: ::c_long = 5000 + 39; +pub const SYS_socket: ::c_long = 5000 + 40; +pub const SYS_connect: ::c_long = 5000 + 41; +pub const SYS_accept: ::c_long = 5000 + 42; +pub const SYS_sendto: ::c_long = 5000 + 43; +pub const SYS_recvfrom: ::c_long = 5000 + 44; +pub const SYS_sendmsg: ::c_long = 5000 + 45; +pub const SYS_recvmsg: ::c_long = 5000 + 46; +pub const SYS_shutdown: ::c_long = 5000 + 47; +pub const SYS_bind: ::c_long = 5000 + 48; +pub const SYS_listen: ::c_long = 5000 + 49; +pub const SYS_getsockname: ::c_long = 5000 + 50; +pub const SYS_getpeername: ::c_long = 5000 + 51; +pub const SYS_socketpair: ::c_long = 5000 + 52; +pub const SYS_setsockopt: ::c_long = 5000 + 53; +pub const SYS_getsockopt: ::c_long = 5000 + 54; +pub const SYS_clone: ::c_long = 5000 + 55; +pub const SYS_fork: ::c_long = 5000 + 56; +pub const SYS_execve: ::c_long = 5000 + 57; +pub const SYS_exit: ::c_long = 5000 + 58; +pub const SYS_wait4: ::c_long = 5000 + 59; +pub const SYS_kill: ::c_long = 5000 + 60; +pub const SYS_uname: ::c_long = 5000 + 61; +pub const SYS_semget: ::c_long = 5000 + 62; +pub const SYS_semop: ::c_long = 5000 + 63; +pub const SYS_semctl: ::c_long = 5000 + 64; +pub const SYS_shmdt: ::c_long = 5000 + 65; +pub const SYS_msgget: ::c_long = 5000 + 66; +pub const SYS_msgsnd: ::c_long = 5000 + 67; +pub const SYS_msgrcv: ::c_long = 5000 + 68; +pub const SYS_msgctl: ::c_long = 5000 + 69; +pub const SYS_fcntl: ::c_long = 5000 + 70; +pub const SYS_flock: ::c_long = 5000 + 71; +pub const SYS_fsync: ::c_long = 5000 + 72; +pub const SYS_fdatasync: ::c_long = 5000 + 73; +pub const SYS_truncate: ::c_long = 5000 + 74; +pub const SYS_ftruncate: ::c_long = 5000 + 75; +pub const SYS_getdents: ::c_long = 5000 + 76; +pub const SYS_getcwd: ::c_long = 5000 + 77; +pub const SYS_chdir: ::c_long = 5000 + 78; +pub const SYS_fchdir: ::c_long = 5000 + 79; +pub const SYS_rename: ::c_long = 5000 + 80; +pub const SYS_mkdir: ::c_long = 5000 + 81; +pub const SYS_rmdir: ::c_long = 5000 + 82; +pub const SYS_creat: ::c_long = 5000 + 83; +pub const SYS_link: ::c_long = 5000 + 84; +pub const SYS_unlink: ::c_long = 5000 + 85; +pub const SYS_symlink: ::c_long = 5000 + 86; +pub const SYS_readlink: ::c_long = 5000 + 87; +pub const SYS_chmod: ::c_long = 5000 + 88; +pub const SYS_fchmod: ::c_long = 5000 + 89; +pub const SYS_chown: ::c_long = 5000 + 90; +pub const SYS_fchown: ::c_long = 5000 + 91; +pub const SYS_lchown: ::c_long = 5000 + 92; +pub const SYS_umask: ::c_long = 5000 + 93; +pub const SYS_gettimeofday: ::c_long = 5000 + 94; +pub const SYS_getrlimit: ::c_long = 5000 + 95; +pub const SYS_getrusage: ::c_long = 5000 + 96; +pub const SYS_sysinfo: ::c_long = 5000 + 97; +pub const SYS_times: ::c_long = 5000 + 98; +pub const SYS_ptrace: ::c_long = 5000 + 99; +pub const SYS_getuid: ::c_long = 5000 + 100; +pub const SYS_syslog: ::c_long = 5000 + 101; +pub const SYS_getgid: ::c_long = 5000 + 102; +pub const SYS_setuid: ::c_long = 5000 + 103; +pub const SYS_setgid: ::c_long = 5000 + 104; +pub const SYS_geteuid: ::c_long = 5000 + 105; +pub const SYS_getegid: ::c_long = 5000 + 106; +pub const SYS_setpgid: ::c_long = 5000 + 107; +pub const SYS_getppid: ::c_long = 5000 + 108; +pub const SYS_getpgrp: ::c_long = 5000 + 109; +pub const SYS_setsid: ::c_long = 5000 + 110; +pub const SYS_setreuid: ::c_long = 5000 + 111; +pub const SYS_setregid: ::c_long = 5000 + 112; +pub const SYS_getgroups: ::c_long = 5000 + 113; +pub const SYS_setgroups: ::c_long = 5000 + 114; +pub const SYS_setresuid: ::c_long = 5000 + 115; +pub const SYS_getresuid: ::c_long = 5000 + 116; +pub const SYS_setresgid: ::c_long = 5000 + 117; +pub const SYS_getresgid: ::c_long = 5000 + 118; +pub const SYS_getpgid: ::c_long = 5000 + 119; +pub const SYS_setfsuid: ::c_long = 5000 + 120; +pub const SYS_setfsgid: ::c_long = 5000 + 121; +pub const SYS_getsid: ::c_long = 5000 + 122; +pub const SYS_capget: ::c_long = 5000 + 123; +pub const SYS_capset: ::c_long = 5000 + 124; +pub const SYS_rt_sigpending: ::c_long = 5000 + 125; +pub const SYS_rt_sigtimedwait: ::c_long = 5000 + 126; +pub const SYS_rt_sigqueueinfo: ::c_long = 5000 + 127; +pub const SYS_rt_sigsuspend: ::c_long = 5000 + 128; +pub const SYS_sigaltstack: ::c_long = 5000 + 129; +pub const SYS_utime: ::c_long = 5000 + 130; +pub const SYS_mknod: ::c_long = 5000 + 131; +pub const SYS_personality: ::c_long = 5000 + 132; +pub const SYS_ustat: ::c_long = 5000 + 133; +pub const SYS_statfs: ::c_long = 5000 + 134; +pub const SYS_fstatfs: ::c_long = 5000 + 135; +pub const SYS_sysfs: ::c_long = 5000 + 136; +pub const SYS_getpriority: ::c_long = 5000 + 137; +pub const SYS_setpriority: ::c_long = 5000 + 138; +pub const SYS_sched_setparam: ::c_long = 5000 + 139; +pub const SYS_sched_getparam: ::c_long = 5000 + 140; +pub const SYS_sched_setscheduler: ::c_long = 5000 + 141; +pub const SYS_sched_getscheduler: ::c_long = 5000 + 142; +pub const SYS_sched_get_priority_max: ::c_long = 5000 + 143; +pub const SYS_sched_get_priority_min: ::c_long = 5000 + 144; +pub const SYS_sched_rr_get_interval: ::c_long = 5000 + 145; +pub const SYS_mlock: ::c_long = 5000 + 146; +pub const SYS_munlock: ::c_long = 5000 + 147; +pub const SYS_mlockall: ::c_long = 5000 + 148; +pub const SYS_munlockall: ::c_long = 5000 + 149; +pub const SYS_vhangup: ::c_long = 5000 + 150; +pub const SYS_pivot_root: ::c_long = 5000 + 151; +pub const SYS__sysctl: ::c_long = 5000 + 152; +pub const SYS_prctl: ::c_long = 5000 + 153; +pub const SYS_adjtimex: ::c_long = 5000 + 154; +pub const SYS_setrlimit: ::c_long = 5000 + 155; +pub const SYS_chroot: ::c_long = 5000 + 156; +pub const SYS_sync: ::c_long = 5000 + 157; +pub const SYS_acct: ::c_long = 5000 + 158; +pub const SYS_settimeofday: ::c_long = 5000 + 159; +pub const SYS_mount: ::c_long = 5000 + 160; +pub const SYS_umount2: ::c_long = 5000 + 161; +pub const SYS_swapon: ::c_long = 5000 + 162; +pub const SYS_swapoff: ::c_long = 5000 + 163; +pub const SYS_reboot: ::c_long = 5000 + 164; +pub const SYS_sethostname: ::c_long = 5000 + 165; +pub const SYS_setdomainname: ::c_long = 5000 + 166; +pub const SYS_create_module: ::c_long = 5000 + 167; +pub const SYS_init_module: ::c_long = 5000 + 168; +pub const SYS_delete_module: ::c_long = 5000 + 169; +pub const SYS_get_kernel_syms: ::c_long = 5000 + 170; +pub const SYS_query_module: ::c_long = 5000 + 171; +pub const SYS_quotactl: ::c_long = 5000 + 172; +pub const SYS_nfsservctl: ::c_long = 5000 + 173; +pub const SYS_getpmsg: ::c_long = 5000 + 174; +pub const SYS_putpmsg: ::c_long = 5000 + 175; +pub const SYS_afs_syscall: ::c_long = 5000 + 176; +pub const SYS_gettid: ::c_long = 5000 + 178; +pub const SYS_readahead: ::c_long = 5000 + 179; +pub const SYS_setxattr: ::c_long = 5000 + 180; +pub const SYS_lsetxattr: ::c_long = 5000 + 181; +pub const SYS_fsetxattr: ::c_long = 5000 + 182; +pub const SYS_getxattr: ::c_long = 5000 + 183; +pub const SYS_lgetxattr: ::c_long = 5000 + 184; +pub const SYS_fgetxattr: ::c_long = 5000 + 185; +pub const SYS_listxattr: ::c_long = 5000 + 186; +pub const SYS_llistxattr: ::c_long = 5000 + 187; +pub const SYS_flistxattr: ::c_long = 5000 + 188; +pub const SYS_removexattr: ::c_long = 5000 + 189; +pub const SYS_lremovexattr: ::c_long = 5000 + 190; +pub const SYS_fremovexattr: ::c_long = 5000 + 191; +pub const SYS_tkill: ::c_long = 5000 + 192; +pub const SYS_futex: ::c_long = 5000 + 194; +pub const SYS_sched_setaffinity: ::c_long = 5000 + 195; +pub const SYS_sched_getaffinity: ::c_long = 5000 + 196; +pub const SYS_cacheflush: ::c_long = 5000 + 197; +pub const SYS_cachectl: ::c_long = 5000 + 198; +pub const SYS_sysmips: ::c_long = 5000 + 199; +pub const SYS_io_setup: ::c_long = 5000 + 200; +pub const SYS_io_destroy: ::c_long = 5000 + 201; +pub const SYS_io_getevents: ::c_long = 5000 + 202; +pub const SYS_io_submit: ::c_long = 5000 + 203; +pub const SYS_io_cancel: ::c_long = 5000 + 204; +pub const SYS_exit_group: ::c_long = 5000 + 205; +pub const SYS_lookup_dcookie: ::c_long = 5000 + 206; +pub const SYS_epoll_create: ::c_long = 5000 + 207; +pub const SYS_epoll_ctl: ::c_long = 5000 + 208; +pub const SYS_epoll_wait: ::c_long = 5000 + 209; +pub const SYS_remap_file_pages: ::c_long = 5000 + 210; +pub const SYS_rt_sigreturn: ::c_long = 5000 + 211; +pub const SYS_set_tid_address: ::c_long = 5000 + 212; +pub const SYS_restart_syscall: ::c_long = 5000 + 213; +pub const SYS_semtimedop: ::c_long = 5000 + 214; +pub const SYS_fadvise64: ::c_long = 5000 + 215; +pub const SYS_timer_create: ::c_long = 5000 + 216; +pub const SYS_timer_settime: ::c_long = 5000 + 217; +pub const SYS_timer_gettime: ::c_long = 5000 + 218; +pub const SYS_timer_getoverrun: ::c_long = 5000 + 219; +pub const SYS_timer_delete: ::c_long = 5000 + 220; +pub const SYS_clock_settime: ::c_long = 5000 + 221; +pub const SYS_clock_gettime: ::c_long = 5000 + 222; +pub const SYS_clock_getres: ::c_long = 5000 + 223; +pub const SYS_clock_nanosleep: ::c_long = 5000 + 224; +pub const SYS_tgkill: ::c_long = 5000 + 225; +pub const SYS_utimes: ::c_long = 5000 + 226; +pub const SYS_mbind: ::c_long = 5000 + 227; +pub const SYS_get_mempolicy: ::c_long = 5000 + 228; +pub const SYS_set_mempolicy: ::c_long = 5000 + 229; +pub const SYS_mq_open: ::c_long = 5000 + 230; +pub const SYS_mq_unlink: ::c_long = 5000 + 231; +pub const SYS_mq_timedsend: ::c_long = 5000 + 232; +pub const SYS_mq_timedreceive: ::c_long = 5000 + 233; +pub const SYS_mq_notify: ::c_long = 5000 + 234; +pub const SYS_mq_getsetattr: ::c_long = 5000 + 235; +pub const SYS_vserver: ::c_long = 5000 + 236; +pub const SYS_waitid: ::c_long = 5000 + 237; +/* pub const SYS_sys_setaltroot: ::c_long = 5000 + 238; */ +pub const SYS_add_key: ::c_long = 5000 + 239; +pub const SYS_request_key: ::c_long = 5000 + 240; +pub const SYS_keyctl: ::c_long = 5000 + 241; +pub const SYS_set_thread_area: ::c_long = 5000 + 242; +pub const SYS_inotify_init: ::c_long = 5000 + 243; +pub const SYS_inotify_add_watch: ::c_long = 5000 + 244; +pub const SYS_inotify_rm_watch: ::c_long = 5000 + 245; +pub const SYS_migrate_pages: ::c_long = 5000 + 246; +pub const SYS_openat: ::c_long = 5000 + 247; +pub const SYS_mkdirat: ::c_long = 5000 + 248; +pub const SYS_mknodat: ::c_long = 5000 + 249; +pub const SYS_fchownat: ::c_long = 5000 + 250; +pub const SYS_futimesat: ::c_long = 5000 + 251; +pub const SYS_newfstatat: ::c_long = 5000 + 252; +pub const SYS_unlinkat: ::c_long = 5000 + 253; +pub const SYS_renameat: ::c_long = 5000 + 254; +pub const SYS_linkat: ::c_long = 5000 + 255; +pub const SYS_symlinkat: ::c_long = 5000 + 256; +pub const SYS_readlinkat: ::c_long = 5000 + 257; +pub const SYS_fchmodat: ::c_long = 5000 + 258; +pub const SYS_faccessat: ::c_long = 5000 + 259; +pub const SYS_pselect6: ::c_long = 5000 + 260; +pub const SYS_ppoll: ::c_long = 5000 + 261; +pub const SYS_unshare: ::c_long = 5000 + 262; +pub const SYS_splice: ::c_long = 5000 + 263; +pub const SYS_sync_file_range: ::c_long = 5000 + 264; +pub const SYS_tee: ::c_long = 5000 + 265; +pub const SYS_vmsplice: ::c_long = 5000 + 266; +pub const SYS_move_pages: ::c_long = 5000 + 267; +pub const SYS_set_robust_list: ::c_long = 5000 + 268; +pub const SYS_get_robust_list: ::c_long = 5000 + 269; +pub const SYS_kexec_load: ::c_long = 5000 + 270; +pub const SYS_getcpu: ::c_long = 5000 + 271; +pub const SYS_epoll_pwait: ::c_long = 5000 + 272; +pub const SYS_ioprio_set: ::c_long = 5000 + 273; +pub const SYS_ioprio_get: ::c_long = 5000 + 274; +pub const SYS_utimensat: ::c_long = 5000 + 275; +pub const SYS_signalfd: ::c_long = 5000 + 276; +pub const SYS_timerfd: ::c_long = 5000 + 277; +pub const SYS_eventfd: ::c_long = 5000 + 278; +pub const SYS_fallocate: ::c_long = 5000 + 279; +pub const SYS_timerfd_create: ::c_long = 5000 + 280; +pub const SYS_timerfd_gettime: ::c_long = 5000 + 281; +pub const SYS_timerfd_settime: ::c_long = 5000 + 282; +pub const SYS_signalfd4: ::c_long = 5000 + 283; +pub const SYS_eventfd2: ::c_long = 5000 + 284; +pub const SYS_epoll_create1: ::c_long = 5000 + 285; +pub const SYS_dup3: ::c_long = 5000 + 286; +pub const SYS_pipe2: ::c_long = 5000 + 287; +pub const SYS_inotify_init1: ::c_long = 5000 + 288; +pub const SYS_preadv: ::c_long = 5000 + 289; +pub const SYS_pwritev: ::c_long = 5000 + 290; +pub const SYS_rt_tgsigqueueinfo: ::c_long = 5000 + 291; +pub const SYS_perf_event_open: ::c_long = 5000 + 292; +pub const SYS_accept4: ::c_long = 5000 + 293; +pub const SYS_recvmmsg: ::c_long = 5000 + 294; +pub const SYS_fanotify_init: ::c_long = 5000 + 295; +pub const SYS_fanotify_mark: ::c_long = 5000 + 296; +pub const SYS_prlimit64: ::c_long = 5000 + 297; +pub const SYS_name_to_handle_at: ::c_long = 5000 + 298; +pub const SYS_open_by_handle_at: ::c_long = 5000 + 299; +pub const SYS_clock_adjtime: ::c_long = 5000 + 300; +pub const SYS_syncfs: ::c_long = 5000 + 301; +pub const SYS_sendmmsg: ::c_long = 5000 + 302; +pub const SYS_setns: ::c_long = 5000 + 303; +pub const SYS_process_vm_readv: ::c_long = 5000 + 304; +pub const SYS_process_vm_writev: ::c_long = 5000 + 305; +pub const SYS_kcmp: ::c_long = 5000 + 306; +pub const SYS_finit_module: ::c_long = 5000 + 307; +pub const SYS_getdents64: ::c_long = 5000 + 308; +pub const SYS_sched_setattr: ::c_long = 5000 + 309; +pub const SYS_sched_getattr: ::c_long = 5000 + 310; +pub const SYS_renameat2: ::c_long = 5000 + 311; +pub const SYS_seccomp: ::c_long = 5000 + 312; +pub const SYS_getrandom: ::c_long = 5000 + 313; +pub const SYS_memfd_create: ::c_long = 5000 + 314; +pub const SYS_bpf: ::c_long = 5000 + 315; +pub const SYS_execveat: ::c_long = 5000 + 316; +pub const SYS_userfaultfd: ::c_long = 5000 + 317; +pub const SYS_membarrier: ::c_long = 5000 + 318; +pub const SYS_mlock2: ::c_long = 5000 + 319; +pub const SYS_copy_file_range: ::c_long = 5000 + 320; +pub const SYS_preadv2: ::c_long = 5000 + 321; +pub const SYS_pwritev2: ::c_long = 5000 + 322; +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; +pub const SYS_io_uring_register: ::c_long = 5000 + 427; +pub const SYS_open_tree: ::c_long = 5000 + 428; +pub const SYS_move_mount: ::c_long = 5000 + 429; +pub const SYS_fsopen: ::c_long = 5000 + 430; +pub const SYS_fsconfig: ::c_long = 5000 + 431; +pub const SYS_fsmount: ::c_long = 5000 + 432; +pub const SYS_fspick: ::c_long = 5000 + 433; +pub const SYS_pidfd_open: ::c_long = 5000 + 434; +pub const SYS_clone3: ::c_long = 5000 + 435; +pub const SYS_close_range: ::c_long = 5000 + 436; +pub const SYS_openat2: ::c_long = 5000 + 437; +pub const SYS_pidfd_getfd: ::c_long = 5000 + 438; +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; + +pub const NCCS: usize = 32; + +pub const O_TRUNC: ::c_int = 512; + +pub const O_NOATIME: ::c_int = 0o1000000; +pub const O_CLOEXEC: ::c_int = 0x80000; +pub const O_PATH: ::c_int = 0o10000000; +pub const O_TMPFILE: ::c_int = 0o20000000 | O_DIRECTORY; + +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 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 POSIX_FADV_DONTNEED: ::c_int = 4; +pub const POSIX_FADV_NOREUSE: ::c_int = 5; + +pub const EPOLL_CLOEXEC: ::c_int = 0x80000; + +pub const EFD_CLOEXEC: ::c_int = 0x80000; + +pub const O_DIRECT: ::c_int = 0x8000; +pub const O_DIRECTORY: ::c_int = 0x10000; +pub const O_NOFOLLOW: ::c_int = 0x20000; + +pub const O_APPEND: ::c_int = 8; +pub const O_CREAT: ::c_int = 256; +pub const O_EXCL: ::c_int = 1024; +pub const O_NOCTTY: ::c_int = 2048; +pub const O_NONBLOCK: ::c_int = 128; +pub const O_SYNC: ::c_int = 0x4010; +pub const O_RSYNC: ::c_int = 0x4010; +pub const O_DSYNC: ::c_int = 0x10; +pub const O_FSYNC: ::c_int = 0x4010; +pub const O_ASYNC: ::c_int = 0x1000; +pub const O_NDELAY: ::c_int = 0x80; + +pub const EDEADLK: ::c_int = 45; +pub const ENAMETOOLONG: ::c_int = 78; +pub const ENOLCK: ::c_int = 46; +pub const ENOSYS: ::c_int = 89; +pub const ENOTEMPTY: ::c_int = 93; +pub const ELOOP: ::c_int = 90; +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 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 EMULTIHOP: ::c_int = 74; +pub const EOVERFLOW: ::c_int = 79; +pub const ENOTUNIQ: ::c_int = 80; +pub const EBADFD: ::c_int = 81; +pub const EBADMSG: ::c_int = 77; +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 ERESTART: ::c_int = 91; +pub const ESTRPIPE: ::c_int = 92; +pub const EUSERS: ::c_int = 94; +pub const ENOTSOCK: ::c_int = 95; +pub const EDESTADDRREQ: ::c_int = 96; +pub const EMSGSIZE: ::c_int = 97; +pub const EPROTOTYPE: ::c_int = 98; +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 EPFNOSUPPORT: ::c_int = 123; +pub const EAFNOSUPPORT: ::c_int = 124; +pub const EADDRINUSE: ::c_int = 125; +pub const EADDRNOTAVAIL: ::c_int = 126; +pub const ENETDOWN: ::c_int = 127; +pub const ENETUNREACH: ::c_int = 128; +pub const ENETRESET: ::c_int = 129; +pub const ECONNABORTED: ::c_int = 130; +pub const ECONNRESET: ::c_int = 131; +pub const ENOBUFS: ::c_int = 132; +pub const EISCONN: ::c_int = 133; +pub const ENOTCONN: ::c_int = 134; +pub const ESHUTDOWN: ::c_int = 143; +pub const ETOOMANYREFS: ::c_int = 144; +pub const ETIMEDOUT: ::c_int = 145; +pub const ECONNREFUSED: ::c_int = 146; +pub const EHOSTDOWN: ::c_int = 147; +pub const EHOSTUNREACH: ::c_int = 148; +pub const EALREADY: ::c_int = 149; +pub const EINPROGRESS: ::c_int = 150; +pub const ESTALE: ::c_int = 151; +pub const EUCLEAN: ::c_int = 135; +pub const ENOTNAM: ::c_int = 137; +pub const ENAVAIL: ::c_int = 138; +pub const EISNAM: ::c_int = 139; +pub const EREMOTEIO: ::c_int = 140; +pub const EDQUOT: ::c_int = 1133; +pub const ENOMEDIUM: ::c_int = 159; +pub const EMEDIUMTYPE: ::c_int = 160; +pub const ECANCELED: ::c_int = 158; +pub const ENOKEY: ::c_int = 161; +pub const EKEYEXPIRED: ::c_int = 162; +pub const EKEYREVOKED: ::c_int = 163; +pub const EKEYREJECTED: ::c_int = 164; +pub const EOWNERDEAD: ::c_int = 165; +pub const ENOTRECOVERABLE: ::c_int = 166; +pub const ERFKILL: ::c_int = 167; + +pub const MAP_NORESERVE: ::c_int = 0x400; +pub const MAP_ANON: ::c_int = 0x800; +pub const MAP_ANONYMOUS: ::c_int = 0x800; +pub const MAP_GROWSDOWN: ::c_int = 0x1000; +pub const MAP_DENYWRITE: ::c_int = 0x2000; +pub const MAP_EXECUTABLE: ::c_int = 0x4000; +pub const MAP_LOCKED: ::c_int = 0x8000; +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 = 0x080000; + +pub const SOCK_STREAM: ::c_int = 2; +pub const SOCK_DGRAM: ::c_int = 1; + +pub const SA_ONSTACK: ::c_int = 0x08000000; +pub const SA_SIGINFO: ::c_int = 0x00000008; +pub const SA_NOCLDWAIT: ::c_int = 0x00010000; + +pub const SIGCHLD: ::c_int = 18; +pub const SIGBUS: ::c_int = 10; +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 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 = 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; +pub const SIG_UNBLOCK: ::c_int = 0x2; + +pub const POLLWRNORM: ::c_short = 0x004; +pub const POLLWRBAND: ::c_short = 0x100; + +pub const VEOF: usize = 16; +pub const VEOL: usize = 17; +pub const VEOL2: usize = 6; +pub const VMIN: usize = 4; +pub const IEXTEN: ::tcflag_t = 0x00000100; +pub const TOSTOP: ::tcflag_t = 0x00008000; +pub const FLUSHO: ::tcflag_t = 0x00002000; +pub const EXTPROC: ::tcflag_t = 0o200000; +pub const TCSANOW: ::c_int = 0x540e; +pub const TCSADRAIN: ::c_int = 0x540f; +pub const TCSAFLUSH: ::c_int = 0x5410; + +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 EFD_NONBLOCK: ::c_int = 0x80; + +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 = 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 F_OFD_GETLK: ::c_int = 36; +pub const F_OFD_SETLK: ::c_int = 37; +pub const F_OFD_SETLKW: ::c_int = 38; + +pub const SFD_NONBLOCK: ::c_int = 0x80; + +pub const RTLD_DEEPBIND: ::c_int = 0x10; +pub const RTLD_GLOBAL: ::c_int = 0x4; +pub const RTLD_NOLOAD: ::c_int = 0x8; + +pub const MCL_CURRENT: ::c_int = 0x0001; +pub const MCL_FUTURE: ::c_int = 0x0002; +pub const MCL_ONFAULT: ::c_int = 0x0004; + +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 EHWPOISON: ::c_int = 168; + +extern "C" { + pub fn sysctl( + name: *mut ::c_int, + namelen: ::c_int, + oldp: *mut ::c_void, + oldlenp: *mut ::size_t, + newp: *mut ::c_void, + newlen: ::size_t, + ) -> ::c_int; +} + +cfg_if! { + if #[cfg(libc_align)] { + mod align; + pub use self::align::*; + } +} 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 new file mode 100644 index 0000000..ff394e3 --- /dev/null +++ b/vendor/libc/src/unix/linux_like/linux/gnu/b64/mod.rs @@ -0,0 +1,128 @@ +//! 64-bit specific definitions for linux-like values + +pub type ino_t = u64; +pub type off_t = i64; +pub type blkcnt_t = i64; +pub type shmatt_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; +#[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; + pub type time_t = i32; + pub type __fsword_t = i32; + } else { + pub type __fsword_t = i64; + pub type clock_t = i64; + pub type time_t = i64; + } +} + +s! { + pub struct sigset_t { + #[cfg(target_pointer_width = "32")] + __val: [u32; 32], + #[cfg(target_pointer_width = "64")] + __val: [u64; 16], + } + + pub struct sysinfo { + pub uptime: i64, + pub loads: [u64; 3], + pub totalram: u64, + pub freeram: u64, + pub sharedram: u64, + pub bufferram: u64, + pub totalswap: u64, + pub freeswap: u64, + pub procs: ::c_ushort, + pub pad: ::c_ushort, + pub totalhigh: u64, + pub freehigh: u64, + pub mem_unit: ::c_uint, + pub _f: [::c_char; 0], + } + + pub struct msqid_ds { + pub msg_perm: ::ipc_perm, + pub msg_stime: ::time_t, + pub msg_rtime: ::time_t, + pub msg_ctime: ::time_t, + __msg_cbytes: u64, + pub msg_qnum: ::msgqnum_t, + pub msg_qbytes: ::msglen_t, + pub msg_lspid: ::pid_t, + pub msg_lrpid: ::pid_t, + __glibc_reserved4: u64, + __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 = "mips64r6", + 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 = "mips64r6", + 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 __SIZEOF_PTHREAD_RWLOCKATTR_T: usize = 8; + +pub const O_LARGEFILE: ::c_int = 0; + +cfg_if! { + if #[cfg(target_arch = "aarch64")] { + mod aarch64; + pub use self::aarch64::*; + } else if #[cfg(any(target_arch = "powerpc64"))] { + mod powerpc64; + pub use self::powerpc64::*; + } else if #[cfg(any(target_arch = "sparc64"))] { + mod sparc64; + pub use self::sparc64::*; + } else if #[cfg(any(target_arch = "mips64", target_arch = "mips64r6"))] { + mod mips64; + pub use self::mips64::*; + } else if #[cfg(any(target_arch = "s390x"))] { + mod s390x; + pub use self::s390x::*; + } 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 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/align.rs b/vendor/libc/src/unix/linux_like/linux/gnu/b64/powerpc64/align.rs new file mode 100644 index 0000000..29d1e1c --- /dev/null +++ b/vendor/libc/src/unix/linux_like/linux/gnu/b64/powerpc64/align.rs @@ -0,0 +1,7 @@ +s_no_extra_traits! { + #[allow(missing_debug_implementations)] + #[repr(align(16))] + pub struct max_align_t { + priv_: [i64; 4] + } +} 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 new file mode 100644 index 0000000..3088c25 --- /dev/null +++ b/vendor/libc/src/unix/linux_like/linux/gnu/b64/powerpc64/mod.rs @@ -0,0 +1,979 @@ +//! PowerPC64-specific definitions for 64-bit linux-like values + +use pthread_mutex_t; + +pub type c_long = i64; +pub type c_ulong = u64; +pub type c_char = u8; +pub type wchar_t = i32; +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 { + pub sa_sigaction: ::sighandler_t, + pub sa_mask: ::sigset_t, + #[cfg(target_arch = "sparc64")] + __reserved0: ::c_int, + 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, + f_spare: [::__fsword_t; 5], + } + + 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 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], + } + + pub struct stat64 { + pub st_dev: ::dev_t, + pub st_ino: ::ino64_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: ::off64_t, + pub st_blksize: ::blksize_t, + 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, + __reserved: [::c_long; 3], + } + + 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 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: [u64; 7] + } + + 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 __seq: u32, + __pad1: u32, + __unused1: u64, + __unused2: ::c_ulong, + } + + pub struct shmid_ds { + pub shm_perm: ::ipc_perm, + pub shm_atime: ::time_t, + pub shm_dtime: ::time_t, + pub shm_ctime: ::time_t, + pub shm_segsz: ::size_t, + pub shm_cpid: ::pid_t, + pub shm_lpid: ::pid_t, + pub shm_nattch: ::shmatt_t, + __unused4: ::c_ulong, + __unused5: ::c_ulong + } + + 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: [usize; 0], + } + + pub struct stack_t { + pub ss_sp: *mut ::c_void, + pub ss_flags: ::c_int, + pub ss_size: ::size_t + } +} + +pub const POSIX_FADV_DONTNEED: ::c_int = 4; +pub const POSIX_FADV_NOREUSE: ::c_int = 5; + +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 __SIZEOF_PTHREAD_RWLOCK_T: usize = 56; +pub const __SIZEOF_PTHREAD_BARRIER_T: usize = 32; + +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_NOATIME: ::c_int = 0o1000000; +pub const O_PATH: ::c_int = 0o10000000; +pub const O_TMPFILE: ::c_int = 0o20000000 | O_DIRECTORY; + +pub const MADV_SOFT_OFFLINE: ::c_int = 101; +pub const MAP_GROWSDOWN: ::c_int = 0x0100; +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 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 SOCK_STREAM: ::c_int = 1; +pub const SOCK_DGRAM: ::c_int = 2; + +pub const SA_ONSTACK: ::c_int = 0x08000000; +pub const SA_SIGINFO: ::c_int = 0x00000004; +pub const SA_NOCLDWAIT: ::c_int = 0x00000002; + +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; +#[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 POLLWRNORM: ::c_short = 0x100; +pub const POLLWRBAND: ::c_short = 0x200; + +pub const O_ASYNC: ::c_int = 0x2000; +pub const O_NDELAY: ::c_int = 0x800; + +pub const PTRACE_DETACH: ::c_uint = 17; + +pub const EFD_NONBLOCK: ::c_int = 0x800; + +pub const F_GETLK: ::c_int = 5; +pub const F_GETOWN: ::c_int = 9; +pub const F_SETOWN: ::c_int = 8; +pub const F_SETLK: ::c_int = 6; +pub const F_SETLKW: ::c_int = 7; +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_WRLCK: ::c_int = 1; +pub const F_UNLCK: ::c_int = 2; + +pub const SFD_NONBLOCK: ::c_int = 0x0800; + +pub const TCSANOW: ::c_int = 0; +pub const TCSADRAIN: ::c_int = 1; +pub const TCSAFLUSH: ::c_int = 2; + +pub const SFD_CLOEXEC: ::c_int = 0x080000; + +pub const NCCS: usize = 32; + +pub const O_TRUNC: ::c_int = 512; + +pub const O_CLOEXEC: ::c_int = 0x80000; + +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 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 EPOLL_CLOEXEC: ::c_int = 0x80000; + +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")] + 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 O_DIRECTORY: ::c_int = 0x4000; +pub const O_NOFOLLOW: ::c_int = 0x8000; +pub const O_DIRECT: ::c_int = 0x20000; + +pub const MAP_LOCKED: ::c_int = 0x00080; +pub const MAP_NORESERVE: ::c_int = 0x00040; +pub const MAP_SYNC: ::c_int = 0x080000; + +pub const EDEADLOCK: ::c_int = 58; +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 MCL_CURRENT: ::c_int = 0x2000; +pub const MCL_FUTURE: ::c_int = 0x4000; +pub const MCL_ONFAULT: ::c_int = 0x8000; + +pub const SIGSTKSZ: ::size_t = 0x4000; +pub const MINSIGSTKSZ: ::size_t = 4096; +pub const CBAUD: ::tcflag_t = 0xff; +pub const TAB1: ::tcflag_t = 0x400; +pub const TAB2: ::tcflag_t = 0x800; +pub const TAB3: ::tcflag_t = 0xc00; +pub const CR1: ::tcflag_t = 0x1000; +pub const CR2: ::tcflag_t = 0x2000; +pub const CR3: ::tcflag_t = 0x3000; +pub const FF1: ::tcflag_t = 0x4000; +pub const BS1: ::tcflag_t = 0x8000; +pub const VT1: ::tcflag_t = 0x10000; +pub const VWERASE: usize = 0xa; +pub const VREPRINT: usize = 0xb; +pub const VSUSP: usize = 0xc; +pub const VSTART: usize = 0xd; +pub const VSTOP: usize = 0xe; +pub const VDISCARD: usize = 0x10; +pub const VTIME: usize = 0x7; +pub const IXON: ::tcflag_t = 0x200; +pub const IXOFF: ::tcflag_t = 0x400; +pub const ONLCR: ::tcflag_t = 0x2; +pub const CSIZE: ::tcflag_t = 0x300; +pub const CS6: ::tcflag_t = 0x100; +pub const CS7: ::tcflag_t = 0x200; +pub const CS8: ::tcflag_t = 0x300; +pub const CSTOPB: ::tcflag_t = 0x400; +pub const CREAD: ::tcflag_t = 0x800; +pub const PARENB: ::tcflag_t = 0x1000; +pub const PARODD: ::tcflag_t = 0x2000; +pub const HUPCL: ::tcflag_t = 0x4000; +pub const CLOCAL: ::tcflag_t = 0x8000; +pub const ECHOKE: ::tcflag_t = 0x1; +pub const ECHOE: ::tcflag_t = 0x2; +pub const ECHOK: ::tcflag_t = 0x4; +pub const ECHONL: ::tcflag_t = 0x10; +pub const ECHOPRT: ::tcflag_t = 0x20; +pub const ECHOCTL: ::tcflag_t = 0x40; +pub const ISIG: ::tcflag_t = 0x80; +pub const ICANON: ::tcflag_t = 0x100; +pub const PENDIN: ::tcflag_t = 0x20000000; +pub const NOFLSH: ::tcflag_t = 0x80000000; +pub const VSWTC: usize = 9; +pub const OLCUC: ::tcflag_t = 0o000004; +pub const NLDLY: ::tcflag_t = 0o001400; +pub const CRDLY: ::tcflag_t = 0o030000; +pub const TABDLY: ::tcflag_t = 0o006000; +pub const BSDLY: ::tcflag_t = 0o100000; +pub const FFDLY: ::tcflag_t = 0o040000; +pub const VTDLY: ::tcflag_t = 0o200000; +pub const XTABS: ::tcflag_t = 0o006000; + +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 CBAUDEX: ::speed_t = 0o000020; +pub const B57600: ::speed_t = 0o0020; +pub const B115200: ::speed_t = 0o0021; +pub const B230400: ::speed_t = 0o0022; +pub const B460800: ::speed_t = 0o0023; +pub const B500000: ::speed_t = 0o0024; +pub const B576000: ::speed_t = 0o0025; +pub const B921600: ::speed_t = 0o0026; +pub const B1000000: ::speed_t = 0o0027; +pub const B1152000: ::speed_t = 0o0030; +pub const B1500000: ::speed_t = 0o0031; +pub const B2000000: ::speed_t = 0o0032; +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 VEOL: usize = 6; +pub const VEOL2: usize = 8; +pub const VMIN: usize = 5; +pub const IEXTEN: ::tcflag_t = 0x400; +pub const TOSTOP: ::tcflag_t = 0x400000; +pub const FLUSHO: ::tcflag_t = 0x800000; +pub const EXTPROC: ::tcflag_t = 0x10000000; + +// Syscall table +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_time: ::c_long = 13; +pub const SYS_mknod: ::c_long = 14; +pub const SYS_chmod: ::c_long = 15; +pub const SYS_lchown: ::c_long = 16; +pub const SYS_break: ::c_long = 17; +pub const SYS_oldstat: ::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_umount: ::c_long = 22; +pub const SYS_setuid: ::c_long = 23; +pub const SYS_getuid: ::c_long = 24; +pub const SYS_stime: ::c_long = 25; +pub const SYS_ptrace: ::c_long = 26; +pub const SYS_alarm: ::c_long = 27; +pub const SYS_oldfstat: ::c_long = 28; +pub const SYS_pause: ::c_long = 29; +pub const SYS_utime: ::c_long = 30; +pub const SYS_stty: ::c_long = 31; +pub const SYS_gtty: ::c_long = 32; +pub const SYS_access: ::c_long = 33; +pub const SYS_nice: ::c_long = 34; +pub const SYS_ftime: ::c_long = 35; +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_prof: ::c_long = 44; +pub const SYS_brk: ::c_long = 45; +pub const SYS_setgid: ::c_long = 46; +pub const SYS_getgid: ::c_long = 47; +pub const SYS_signal: ::c_long = 48; +pub const SYS_geteuid: ::c_long = 49; +pub const SYS_getegid: ::c_long = 50; +pub const SYS_acct: ::c_long = 51; +pub const SYS_umount2: ::c_long = 52; +pub const SYS_lock: ::c_long = 53; +pub const SYS_ioctl: ::c_long = 54; +pub const SYS_fcntl: ::c_long = 55; +pub const SYS_mpx: ::c_long = 56; +pub const SYS_setpgid: ::c_long = 57; +pub const SYS_ulimit: ::c_long = 58; +pub const SYS_oldolduname: ::c_long = 59; +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_setreuid: ::c_long = 70; +pub const SYS_setregid: ::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_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_getgroups: ::c_long = 80; +pub const SYS_setgroups: ::c_long = 81; +pub const SYS_select: ::c_long = 82; +pub const SYS_symlink: ::c_long = 83; +pub const SYS_oldlstat: ::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_readdir: ::c_long = 89; +pub const SYS_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_fchown: ::c_long = 95; +pub const SYS_getpriority: ::c_long = 96; +pub const SYS_setpriority: ::c_long = 97; +pub const SYS_profil: ::c_long = 98; +pub const SYS_statfs: ::c_long = 99; +pub const SYS_fstatfs: ::c_long = 100; +pub const SYS_ioperm: ::c_long = 101; +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_stat: ::c_long = 106; +pub const SYS_lstat: ::c_long = 107; +pub const SYS_fstat: ::c_long = 108; +pub const SYS_olduname: ::c_long = 109; +pub const SYS_iopl: ::c_long = 110; +pub const SYS_vhangup: ::c_long = 111; +pub const SYS_idle: ::c_long = 112; +pub const SYS_vm86: ::c_long = 113; +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_uname: ::c_long = 122; +pub const SYS_modify_ldt: ::c_long = 123; +pub const SYS_adjtimex: ::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_afs_syscall: ::c_long = 137; /* Syscall for Andrew File System */ +pub const SYS_setfsuid: ::c_long = 138; +pub const SYS_setfsgid: ::c_long = 139; +pub const SYS__llseek: ::c_long = 140; +pub const SYS_getdents: ::c_long = 141; +pub const SYS__newselect: ::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: ::c_long = 161; +pub const SYS_nanosleep: ::c_long = 162; +pub const SYS_mremap: ::c_long = 163; +pub const SYS_setresuid: ::c_long = 164; +pub const SYS_getresuid: ::c_long = 165; +pub const SYS_query_module: ::c_long = 166; +pub const SYS_poll: ::c_long = 167; +pub const SYS_nfsservctl: ::c_long = 168; +pub const SYS_setresgid: ::c_long = 169; +pub const SYS_getresgid: ::c_long = 170; +pub const SYS_prctl: ::c_long = 171; +pub const SYS_rt_sigreturn: ::c_long = 172; +pub const SYS_rt_sigaction: ::c_long = 173; +pub const SYS_rt_sigprocmask: ::c_long = 174; +pub const SYS_rt_sigpending: ::c_long = 175; +pub const SYS_rt_sigtimedwait: ::c_long = 176; +pub const SYS_rt_sigqueueinfo: ::c_long = 177; +pub const SYS_rt_sigsuspend: ::c_long = 178; +pub const SYS_pread64: ::c_long = 179; +pub const SYS_pwrite64: ::c_long = 180; +pub const SYS_chown: ::c_long = 181; +pub const SYS_getcwd: ::c_long = 182; +pub const SYS_capget: ::c_long = 183; +pub const SYS_capset: ::c_long = 184; +pub const SYS_sigaltstack: ::c_long = 185; +pub const SYS_sendfile: ::c_long = 186; +pub const SYS_getpmsg: ::c_long = 187; /* some people actually want streams */ +pub const SYS_putpmsg: ::c_long = 188; /* some people actually want streams */ +pub const SYS_vfork: ::c_long = 189; +pub const SYS_ugetrlimit: ::c_long = 190; /* SuS compliant getrlimit */ +pub const SYS_readahead: ::c_long = 191; +pub const SYS_pciconfig_read: ::c_long = 198; +pub const SYS_pciconfig_write: ::c_long = 199; +pub const SYS_pciconfig_iobase: ::c_long = 200; +pub const SYS_multiplexer: ::c_long = 201; +pub const SYS_getdents64: ::c_long = 202; +pub const SYS_pivot_root: ::c_long = 203; +pub const SYS_madvise: ::c_long = 205; +pub const SYS_mincore: ::c_long = 206; +pub const SYS_gettid: ::c_long = 207; +pub const SYS_tkill: ::c_long = 208; +pub const SYS_setxattr: ::c_long = 209; +pub const SYS_lsetxattr: ::c_long = 210; +pub const SYS_fsetxattr: ::c_long = 211; +pub const SYS_getxattr: ::c_long = 212; +pub const SYS_lgetxattr: ::c_long = 213; +pub const SYS_fgetxattr: ::c_long = 214; +pub const SYS_listxattr: ::c_long = 215; +pub const SYS_llistxattr: ::c_long = 216; +pub const SYS_flistxattr: ::c_long = 217; +pub const SYS_removexattr: ::c_long = 218; +pub const SYS_lremovexattr: ::c_long = 219; +pub const SYS_fremovexattr: ::c_long = 220; +pub const SYS_futex: ::c_long = 221; +pub const SYS_sched_setaffinity: ::c_long = 222; +pub const SYS_sched_getaffinity: ::c_long = 223; +pub const SYS_tuxcall: ::c_long = 225; +pub const SYS_io_setup: ::c_long = 227; +pub const SYS_io_destroy: ::c_long = 228; +pub const SYS_io_getevents: ::c_long = 229; +pub const SYS_io_submit: ::c_long = 230; +pub const SYS_io_cancel: ::c_long = 231; +pub const SYS_set_tid_address: ::c_long = 232; +pub const SYS_exit_group: ::c_long = 234; +pub const SYS_lookup_dcookie: ::c_long = 235; +pub const SYS_epoll_create: ::c_long = 236; +pub const SYS_epoll_ctl: ::c_long = 237; +pub const SYS_epoll_wait: ::c_long = 238; +pub const SYS_remap_file_pages: ::c_long = 239; +pub const SYS_timer_create: ::c_long = 240; +pub const SYS_timer_settime: ::c_long = 241; +pub const SYS_timer_gettime: ::c_long = 242; +pub const SYS_timer_getoverrun: ::c_long = 243; +pub const SYS_timer_delete: ::c_long = 244; +pub const SYS_clock_settime: ::c_long = 245; +pub const SYS_clock_gettime: ::c_long = 246; +pub const SYS_clock_getres: ::c_long = 247; +pub const SYS_clock_nanosleep: ::c_long = 248; +pub const SYS_swapcontext: ::c_long = 249; +pub const SYS_tgkill: ::c_long = 250; +pub const SYS_utimes: ::c_long = 251; +pub const SYS_statfs64: ::c_long = 252; +pub const SYS_fstatfs64: ::c_long = 253; +pub const SYS_rtas: ::c_long = 255; +pub const SYS_sys_debug_setcontext: ::c_long = 256; +pub const SYS_migrate_pages: ::c_long = 258; +pub const SYS_mbind: ::c_long = 259; +pub const SYS_get_mempolicy: ::c_long = 260; +pub const SYS_set_mempolicy: ::c_long = 261; +pub const SYS_mq_open: ::c_long = 262; +pub const SYS_mq_unlink: ::c_long = 263; +pub const SYS_mq_timedsend: ::c_long = 264; +pub const SYS_mq_timedreceive: ::c_long = 265; +pub const SYS_mq_notify: ::c_long = 266; +pub const SYS_mq_getsetattr: ::c_long = 267; +pub const SYS_kexec_load: ::c_long = 268; +pub const SYS_add_key: ::c_long = 269; +pub const SYS_request_key: ::c_long = 270; +pub const SYS_keyctl: ::c_long = 271; +pub const SYS_waitid: ::c_long = 272; +pub const SYS_ioprio_set: ::c_long = 273; +pub const SYS_ioprio_get: ::c_long = 274; +pub const SYS_inotify_init: ::c_long = 275; +pub const SYS_inotify_add_watch: ::c_long = 276; +pub const SYS_inotify_rm_watch: ::c_long = 277; +pub const SYS_spu_run: ::c_long = 278; +pub const SYS_spu_create: ::c_long = 279; +pub const SYS_pselect6: ::c_long = 280; +pub const SYS_ppoll: ::c_long = 281; +pub const SYS_unshare: ::c_long = 282; +pub const SYS_splice: ::c_long = 283; +pub const SYS_tee: ::c_long = 284; +pub const SYS_vmsplice: ::c_long = 285; +pub const SYS_openat: ::c_long = 286; +pub const SYS_mkdirat: ::c_long = 287; +pub const SYS_mknodat: ::c_long = 288; +pub const SYS_fchownat: ::c_long = 289; +pub const SYS_futimesat: ::c_long = 290; +pub const SYS_newfstatat: ::c_long = 291; +pub const SYS_unlinkat: ::c_long = 292; +pub const SYS_renameat: ::c_long = 293; +pub const SYS_linkat: ::c_long = 294; +pub const SYS_symlinkat: ::c_long = 295; +pub const SYS_readlinkat: ::c_long = 296; +pub const SYS_fchmodat: ::c_long = 297; +pub const SYS_faccessat: ::c_long = 298; +pub const SYS_get_robust_list: ::c_long = 299; +pub const SYS_set_robust_list: ::c_long = 300; +pub const SYS_move_pages: ::c_long = 301; +pub const SYS_getcpu: ::c_long = 302; +pub const SYS_epoll_pwait: ::c_long = 303; +pub const SYS_utimensat: ::c_long = 304; +pub const SYS_signalfd: ::c_long = 305; +pub const SYS_timerfd_create: ::c_long = 306; +pub const SYS_eventfd: ::c_long = 307; +pub const SYS_sync_file_range2: ::c_long = 308; +pub const SYS_fallocate: ::c_long = 309; +pub const SYS_subpage_prot: ::c_long = 310; +pub const SYS_timerfd_settime: ::c_long = 311; +pub const SYS_timerfd_gettime: ::c_long = 312; +pub const SYS_signalfd4: ::c_long = 313; +pub const SYS_eventfd2: ::c_long = 314; +pub const SYS_epoll_create1: ::c_long = 315; +pub const SYS_dup3: ::c_long = 316; +pub const SYS_pipe2: ::c_long = 317; +pub const SYS_inotify_init1: ::c_long = 318; +pub const SYS_perf_event_open: ::c_long = 319; +pub const SYS_preadv: ::c_long = 320; +pub const SYS_pwritev: ::c_long = 321; +pub const SYS_rt_tgsigqueueinfo: ::c_long = 322; +pub const SYS_fanotify_init: ::c_long = 323; +pub const SYS_fanotify_mark: ::c_long = 324; +pub const SYS_prlimit64: ::c_long = 325; +pub const SYS_socket: ::c_long = 326; +pub const SYS_bind: ::c_long = 327; +pub const SYS_connect: ::c_long = 328; +pub const SYS_listen: ::c_long = 329; +pub const SYS_accept: ::c_long = 330; +pub const SYS_getsockname: ::c_long = 331; +pub const SYS_getpeername: ::c_long = 332; +pub const SYS_socketpair: ::c_long = 333; +pub const SYS_send: ::c_long = 334; +pub const SYS_sendto: ::c_long = 335; +pub const SYS_recv: ::c_long = 336; +pub const SYS_recvfrom: ::c_long = 337; +pub const SYS_shutdown: ::c_long = 338; +pub const SYS_setsockopt: ::c_long = 339; +pub const SYS_getsockopt: ::c_long = 340; +pub const SYS_sendmsg: ::c_long = 341; +pub const SYS_recvmsg: ::c_long = 342; +pub const SYS_recvmmsg: ::c_long = 343; +pub const SYS_accept4: ::c_long = 344; +pub const SYS_name_to_handle_at: ::c_long = 345; +pub const SYS_open_by_handle_at: ::c_long = 346; +pub const SYS_clock_adjtime: ::c_long = 347; +pub const SYS_syncfs: ::c_long = 348; +pub const SYS_sendmmsg: ::c_long = 349; +pub const SYS_setns: ::c_long = 350; +pub const SYS_process_vm_readv: ::c_long = 351; +pub const SYS_process_vm_writev: ::c_long = 352; +pub const SYS_finit_module: ::c_long = 353; +pub const SYS_kcmp: ::c_long = 354; +pub const SYS_sched_setattr: ::c_long = 355; +pub const SYS_sched_getattr: ::c_long = 356; +pub const SYS_renameat2: ::c_long = 357; +pub const SYS_seccomp: ::c_long = 358; +pub const SYS_getrandom: ::c_long = 359; +pub const SYS_memfd_create: ::c_long = 360; +pub const SYS_bpf: ::c_long = 361; +pub const SYS_execveat: ::c_long = 362; +pub const SYS_switch_endian: ::c_long = 363; +pub const SYS_userfaultfd: ::c_long = 364; +pub const SYS_membarrier: ::c_long = 365; +pub const SYS_mlock2: ::c_long = 378; +pub const SYS_copy_file_range: ::c_long = 379; +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; +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; + +extern "C" { + pub fn sysctl( + name: *mut ::c_int, + namelen: ::c_int, + oldp: *mut ::c_void, + oldlenp: *mut ::size_t, + newp: *mut ::c_void, + newlen: ::size_t, + ) -> ::c_int; +} + +cfg_if! { + if #[cfg(libc_align)] { + mod align; + pub use self::align::*; + } +} 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..5b33f23 --- /dev/null +++ b/vendor/libc/src/unix/linux_like/linux/gnu/b64/riscv64/align.rs @@ -0,0 +1,61 @@ +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], + } +} + +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/riscv64/mod.rs b/vendor/libc/src/unix/linux_like/linux/gnu/b64/riscv64/mod.rs new file mode 100644 index 0000000..64f5cf1 --- /dev/null +++ b/vendor/libc/src/unix/linux_like/linux/gnu/b64/riscv64/mod.rs @@ -0,0 +1,860 @@ +//! RISC-V-specific definitions for 64-bit linux-like values + +pub type c_char = u8; +pub type c_long = i64; +pub type c_ulong = u64; +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 suseconds_t = i64; +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 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 POSIX_FADV_DONTNEED: ::c_int = 4; +pub const POSIX_FADV_NOREUSE: ::c_int = 5; +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_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 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; +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 SOCK_STREAM: ::c_int = 1; +pub const SOCK_DGRAM: ::c_int = 2; +pub const SA_ONSTACK: ::c_int = 134217728; +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 PTRACE_DETACH: ::c_uint = 17; +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 F_SETLK: ::c_int = 6; +pub const F_SETLKW: ::c_int = 7; +pub const F_RDLCK: ::c_int = 0; +pub const F_WRLCK: ::c_int = 1; +pub const F_UNLCK: ::c_int = 2; +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 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 SFD_CLOEXEC: ::c_int = 524288; +pub const NCCS: usize = 32; +pub const O_TRUNC: ::c_int = 512; +pub const O_CLOEXEC: ::c_int = 524288; +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 SA_NODEFER: ::c_int = 1073741824; +pub const SA_RESETHAND: ::c_int = -2147483648; +pub const SA_RESTART: ::c_int = 268435456; +pub const SA_NOCLDSTOP: ::c_int = 1; +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; +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 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 MCL_ONFAULT: ::c_int = 4; +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 __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 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 COMPAT_HWCAP_ISA_V: ::c_ulong = 1 << (b'V' - b'A'); + +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_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; +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)] { + 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 new file mode 100644 index 0000000..e85429e --- /dev/null +++ b/vendor/libc/src/unix/linux_like/linux/gnu/b64/s390x.rs @@ -0,0 +1,965 @@ +//! s390x + +use pthread_mutex_t; + +pub type blksize_t = i64; +pub type c_char = u8; +pub type c_long = i64; +pub type c_ulong = u64; +pub type nlink_t = u64; +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 { + pub sa_sigaction: ::sighandler_t, + __glibc_reserved0: ::c_int, + pub sa_flags: ::c_int, + pub sa_restorer: ::Option, + pub sa_mask: ::sigset_t, + } + + pub struct statfs { + pub f_type: ::c_uint, + pub f_bsize: ::c_uint, + 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_uint, + pub f_frsize: ::c_uint, + pub f_flags: ::c_uint, + f_spare: [::c_uint; 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 siginfo_t { + pub si_signo: ::c_int, + pub si_errno: ::c_int, + pub si_code: ::c_int, + _pad: ::c_int, + _pad2: [::c_long; 14], + } + + pub struct stack_t { + pub ss_sp: *mut ::c_void, + pub ss_flags: ::c_int, + pub ss_size: ::size_t + } + + 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, + st_pad0: ::c_int, + pub st_rdev: ::dev_t, + pub st_size: ::off_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_blksize: ::blksize_t, + pub st_blocks: ::blkcnt_t, + __glibc_reserved: [::c_long; 3], + } + + pub struct stat64 { + pub st_dev: ::dev_t, + pub st_ino: ::ino64_t, + pub st_nlink: ::nlink_t, + pub st_mode: ::mode_t, + pub st_uid: ::uid_t, + pub st_gid: ::gid_t, + st_pad0: ::c_int, + pub st_rdev: ::dev_t, + pub st_size: ::off_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_blksize: ::blksize_t, + pub st_blocks: ::blkcnt64_t, + __glibc_reserved: [::c_long; 3], + } + + pub struct pthread_attr_t { + __size: [::c_ulong; 7] + } + + 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 __seq: ::c_ushort, + __pad1: ::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 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 __psw_t { + pub mask: u64, + pub addr: u64, + } + + pub struct fpregset_t { + pub fpc: u32, + __pad: u32, + pub fprs: [fpreg_t; 16], + } + + pub struct mcontext_t { + pub psw: __psw_t, + pub gregs: [u64; 16], + pub aregs: [u32; 16], + pub fpregs: fpregset_t, + } + + 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 struct statfs64 { + pub f_type: ::c_uint, + pub f_bsize: ::c_uint, + 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: ::c_uint, + pub f_frsize: ::c_uint, + pub f_flags: ::c_uint, + pub f_spare: [::c_uint; 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, + pub f_flag: ::c_ulong, + pub f_namemax: ::c_ulong, + __f_spare: [::c_int; 6], + } +} + +s_no_extra_traits! { + // FIXME: This is actually a union. + pub struct fpreg_t { + pub d: ::c_double, + // f: ::c_float, + } +} + +cfg_if! { + if #[cfg(feature = "extra_traits")] { + impl PartialEq for fpreg_t { + fn eq(&self, other: &fpreg_t) -> bool { + self.d == other.d + } + } + + impl Eq for fpreg_t {} + + impl ::fmt::Debug for fpreg_t { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("fpreg_t") + .field("d", &self.d) + .finish() + } + } + + impl ::hash::Hash for fpreg_t { + fn hash(&self, state: &mut H) { + let d: u64 = unsafe { ::mem::transmute(self.d) }; + d.hash(state); + } + } + } +} + +pub const POSIX_FADV_DONTNEED: ::c_int = 6; +pub const POSIX_FADV_NOREUSE: ::c_int = 7; + +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 SFD_CLOEXEC: ::c_int = 0x080000; + +pub const NCCS: usize = 32; + +pub const O_TRUNC: ::c_int = 512; +pub const O_NOATIME: ::c_int = 0o1000000; +pub const O_CLOEXEC: ::c_int = 0x80000; +pub const O_PATH: ::c_int = 0o10000000; +pub const O_TMPFILE: ::c_int = 0o20000000 | O_DIRECTORY; + +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 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 EPOLL_CLOEXEC: ::c_int = 0x80000; + +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 = + 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, + ], + }; + 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, + ], + }; + 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 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 EADDRINUSE: ::c_int = 98; +pub const EADDRNOTAVAIL: ::c_int = 99; +pub const ECONNABORTED: ::c_int = 103; +pub const ECONNREFUSED: ::c_int = 111; +pub const ECONNRESET: ::c_int = 104; +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 O_APPEND: ::c_int = 1024; +pub const O_CREAT: ::c_int = 64; +pub const O_EXCL: ::c_int = 128; +pub const O_NONBLOCK: ::c_int = 2048; +pub const SA_NOCLDWAIT: ::c_int = 2; +pub const SA_ONSTACK: ::c_int = 0x08000000; +pub const SA_SIGINFO: ::c_int = 4; +pub const SIGBUS: ::c_int = 7; +pub const SIGSTKSZ: ::size_t = 0x2000; +pub const MINSIGSTKSZ: ::size_t = 2048; +pub const SIG_SETMASK: ::c_int = 2; + +pub const SOCK_STREAM: ::c_int = 1; +pub const SOCK_DGRAM: ::c_int = 2; + +pub const O_NOCTTY: ::c_int = 256; +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_DIRECT: ::c_int = 0x4000; +pub const O_DIRECTORY: ::c_int = 0x10000; +pub const O_NOFOLLOW: ::c_int = 0x20000; + +pub const MADV_SOFT_OFFLINE: ::c_int = 101; +pub const MAP_GROWSDOWN: ::c_int = 0x0100; +pub const MAP_LOCKED: ::c_int = 0x02000; +pub const MAP_NORESERVE: ::c_int = 0x04000; +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_SYNC: ::c_int = 0x080000; + +pub const EDEADLOCK: ::c_int = 35; +pub const ENAMETOOLONG: ::c_int = 36; +pub const ENOLCK: ::c_int = 37; +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 ENETDOWN: ::c_int = 100; +pub const ENETUNREACH: ::c_int = 101; +pub const ENETRESET: ::c_int = 102; +pub const ENOBUFS: ::c_int = 105; +pub const EISCONN: ::c_int = 106; +pub const ESHUTDOWN: ::c_int = 108; +pub const ETOOMANYREFS: ::c_int = 109; +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 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 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_BLOCK: ::c_int = 0x000000; +pub const SIG_UNBLOCK: ::c_int = 0x01; + +pub const O_ASYNC: ::c_int = 0x2000; +pub const O_NDELAY: ::c_int = 0x800; + +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 PTRACE_DETACH: ::c_uint = 17; + +pub const MCL_CURRENT: ::c_int = 0x0001; +pub const MCL_FUTURE: ::c_int = 0x0002; +pub const MCL_ONFAULT: ::c_int = 0x0004; + +pub const EFD_NONBLOCK: ::c_int = 0x800; + +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_GETOWN: ::c_int = 9; +pub const F_SETOWN: ::c_int = 8; +pub const F_SETLK: ::c_int = 6; +pub const F_SETLKW: ::c_int = 7; +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 SFD_NONBLOCK: ::c_int = 0x0800; + +pub const TCSANOW: ::c_int = 0; +pub const TCSADRAIN: ::c_int = 1; +pub const TCSAFLUSH: ::c_int = 2; + +pub const VTIME: usize = 5; +pub const VSWTC: usize = 7; +pub const VSTART: usize = 8; +pub const VSTOP: usize = 9; +pub const VSUSP: usize = 10; +pub const VREPRINT: usize = 12; +pub const VDISCARD: usize = 13; +pub const VWERASE: usize = 14; +pub const OLCUC: ::tcflag_t = 0o000002; +pub const ONLCR: ::tcflag_t = 0o000004; +pub const NLDLY: ::tcflag_t = 0o000400; +pub const CRDLY: ::tcflag_t = 0o003000; +pub const CR1: ::tcflag_t = 0x00000200; +pub const CR2: ::tcflag_t = 0x00000400; +pub const CR3: ::tcflag_t = 0x00000600; +pub const TABDLY: ::tcflag_t = 0o014000; +pub const TAB1: ::tcflag_t = 0x00000800; +pub const TAB2: ::tcflag_t = 0x00001000; +pub const TAB3: ::tcflag_t = 0x00001800; +pub const BSDLY: ::tcflag_t = 0o020000; +pub const BS1: ::tcflag_t = 0x00002000; +pub const FFDLY: ::tcflag_t = 0o100000; +pub const FF1: ::tcflag_t = 0x00008000; +pub const VTDLY: ::tcflag_t = 0o040000; +pub const VT1: ::tcflag_t = 0x00004000; +pub const XTABS: ::tcflag_t = 0o014000; + +pub const CBAUD: ::speed_t = 0o010017; +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 CSIZE: ::tcflag_t = 0o000060; +pub const CS6: ::tcflag_t = 0o000020; +pub const CS7: ::tcflag_t = 0o000040; +pub const CS8: ::tcflag_t = 0o000060; +pub const CSTOPB: ::tcflag_t = 0o000100; +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 CBAUDEX: ::tcflag_t = 0o010000; +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 CIBAUD: ::tcflag_t = 0o02003600000; + +pub const ISIG: ::tcflag_t = 0o000001; +pub const ICANON: ::tcflag_t = 0o000002; +pub const XCASE: ::tcflag_t = 0o000004; +pub const ECHOE: ::tcflag_t = 0o000020; +pub const ECHOK: ::tcflag_t = 0o000040; +pub const ECHONL: ::tcflag_t = 0o000100; +pub const NOFLSH: ::tcflag_t = 0o000200; +pub const ECHOCTL: ::tcflag_t = 0o001000; +pub const ECHOPRT: ::tcflag_t = 0o002000; +pub const ECHOKE: ::tcflag_t = 0o004000; +pub const PENDIN: ::tcflag_t = 0o040000; + +pub const POLLWRNORM: ::c_short = 0x100; +pub const POLLWRBAND: ::c_short = 0x200; + +pub const IXON: ::tcflag_t = 0o002000; +pub const IXOFF: ::tcflag_t = 0o010000; + +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_restart_syscall: ::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_mknod: ::c_long = 14; +pub const SYS_chmod: ::c_long = 15; +pub const SYS_lseek: ::c_long = 19; +pub const SYS_getpid: ::c_long = 20; +pub const SYS_mount: ::c_long = 21; +pub const SYS_umount: ::c_long = 22; +pub const SYS_ptrace: ::c_long = 26; +pub const SYS_alarm: ::c_long = 27; +pub const SYS_pause: ::c_long = 29; +pub const SYS_utime: ::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_signal: ::c_long = 48; +pub const SYS_acct: ::c_long = 51; +pub const SYS_umount2: ::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_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_getrusage: ::c_long = 77; +pub const SYS_gettimeofday: ::c_long = 78; +pub const SYS_settimeofday: ::c_long = 79; +pub const SYS_symlink: ::c_long = 83; +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_readdir: ::c_long = 89; +pub const SYS_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_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_stat: ::c_long = 106; +pub const SYS_lstat: ::c_long = 107; +pub const SYS_fstat: ::c_long = 108; +pub const SYS_lookup_dcookie: ::c_long = 110; +pub const SYS_vhangup: ::c_long = 111; +pub const SYS_idle: ::c_long = 112; +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_uname: ::c_long = 122; +pub const SYS_adjtimex: ::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_afs_syscall: ::c_long = 137; /* Syscall for Andrew File System */ +pub const SYS_getdents: ::c_long = 141; +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: ::c_long = 161; +pub const SYS_nanosleep: ::c_long = 162; +pub const SYS_mremap: ::c_long = 163; +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_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: ::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_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_pivot_root: ::c_long = 217; +pub const SYS_mincore: ::c_long = 218; +pub const SYS_madvise: ::c_long = 219; +pub const SYS_getdents64: ::c_long = 220; +pub const SYS_readahead: ::c_long = 222; +pub const SYS_setxattr: ::c_long = 224; +pub const SYS_lsetxattr: ::c_long = 225; +pub const SYS_fsetxattr: ::c_long = 226; +pub const SYS_getxattr: ::c_long = 227; +pub const SYS_lgetxattr: ::c_long = 228; +pub const SYS_fgetxattr: ::c_long = 229; +pub const SYS_listxattr: ::c_long = 230; +pub const SYS_llistxattr: ::c_long = 231; +pub const SYS_flistxattr: ::c_long = 232; +pub const SYS_removexattr: ::c_long = 233; +pub const SYS_lremovexattr: ::c_long = 234; +pub const SYS_fremovexattr: ::c_long = 235; +pub const SYS_gettid: ::c_long = 236; +pub const SYS_tkill: ::c_long = 237; +pub const SYS_futex: ::c_long = 238; +pub const SYS_sched_setaffinity: ::c_long = 239; +pub const SYS_sched_getaffinity: ::c_long = 240; +pub const SYS_tgkill: ::c_long = 241; +pub const SYS_io_setup: ::c_long = 243; +pub const SYS_io_destroy: ::c_long = 244; +pub const SYS_io_getevents: ::c_long = 245; +pub const SYS_io_submit: ::c_long = 246; +pub const SYS_io_cancel: ::c_long = 247; +pub const SYS_exit_group: ::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_set_tid_address: ::c_long = 252; +pub const SYS_fadvise64: ::c_long = 253; +pub const SYS_timer_create: ::c_long = 254; +pub const SYS_timer_settime: ::c_long = 255; +pub const SYS_timer_gettime: ::c_long = 256; +pub const SYS_timer_getoverrun: ::c_long = 257; +pub const SYS_timer_delete: ::c_long = 258; +pub const SYS_clock_settime: ::c_long = 259; +pub const SYS_clock_gettime: ::c_long = 260; +pub const SYS_clock_getres: ::c_long = 261; +pub const SYS_clock_nanosleep: ::c_long = 262; +pub const SYS_statfs64: ::c_long = 265; +pub const SYS_fstatfs64: ::c_long = 266; +pub const SYS_remap_file_pages: ::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: ::c_long = 273; +pub const SYS_mq_timedreceive: ::c_long = 274; +pub const SYS_mq_notify: ::c_long = 275; +pub const SYS_mq_getsetattr: ::c_long = 276; +pub const SYS_kexec_load: ::c_long = 277; +pub const SYS_add_key: ::c_long = 278; +pub const SYS_request_key: ::c_long = 279; +pub const SYS_keyctl: ::c_long = 280; +pub const SYS_waitid: ::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: ::c_long = 292; +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: ::c_long = 301; +pub const SYS_ppoll: ::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_getcpu: ::c_long = 311; +pub const SYS_epoll_pwait: ::c_long = 312; +pub const SYS_utimes: ::c_long = 313; +pub const SYS_fallocate: ::c_long = 314; +pub const SYS_utimensat: ::c_long = 315; +pub const SYS_signalfd: ::c_long = 316; +pub const SYS_timerfd: ::c_long = 317; +pub const SYS_eventfd: ::c_long = 318; +pub const SYS_timerfd_create: ::c_long = 319; +pub const SYS_timerfd_settime: ::c_long = 320; +pub const SYS_timerfd_gettime: ::c_long = 321; +pub const SYS_signalfd4: ::c_long = 322; +pub const SYS_eventfd2: ::c_long = 323; +pub const SYS_inotify_init1: ::c_long = 324; +pub const SYS_pipe2: ::c_long = 325; +pub const SYS_dup3: ::c_long = 326; +pub const SYS_epoll_create1: ::c_long = 327; +pub const SYS_preadv: ::c_long = 328; +pub const SYS_pwritev: ::c_long = 329; +pub const SYS_rt_tgsigqueueinfo: ::c_long = 330; +pub const SYS_perf_event_open: ::c_long = 331; +pub const SYS_fanotify_init: ::c_long = 332; +pub const SYS_fanotify_mark: ::c_long = 333; +pub const SYS_prlimit64: ::c_long = 334; +pub const SYS_name_to_handle_at: ::c_long = 335; +pub const SYS_open_by_handle_at: ::c_long = 336; +pub const SYS_clock_adjtime: ::c_long = 337; +pub const SYS_syncfs: ::c_long = 338; +pub const SYS_setns: ::c_long = 339; +pub const SYS_process_vm_readv: ::c_long = 340; +pub const SYS_process_vm_writev: ::c_long = 341; +pub const SYS_s390_runtime_instr: ::c_long = 342; +pub const SYS_kcmp: ::c_long = 343; +pub const SYS_finit_module: ::c_long = 344; +pub const SYS_sched_setattr: ::c_long = 345; +pub const SYS_sched_getattr: ::c_long = 346; +pub const SYS_renameat2: ::c_long = 347; +pub const SYS_seccomp: ::c_long = 348; +pub const SYS_getrandom: ::c_long = 349; +pub const SYS_memfd_create: ::c_long = 350; +pub const SYS_bpf: ::c_long = 351; +pub const SYS_s390_pci_mmio_write: ::c_long = 352; +pub const SYS_s390_pci_mmio_read: ::c_long = 353; +pub const SYS_execveat: ::c_long = 354; +pub const SYS_userfaultfd: ::c_long = 355; +pub const SYS_membarrier: ::c_long = 356; +pub const SYS_recvmmsg: ::c_long = 357; +pub const SYS_sendmmsg: ::c_long = 358; +pub const SYS_socket: ::c_long = 359; +pub const SYS_socketpair: ::c_long = 360; +pub const SYS_bind: ::c_long = 361; +pub const SYS_connect: ::c_long = 362; +pub const SYS_listen: ::c_long = 363; +pub const SYS_accept4: ::c_long = 364; +pub const SYS_getsockopt: ::c_long = 365; +pub const SYS_setsockopt: ::c_long = 366; +pub const SYS_getsockname: ::c_long = 367; +pub const SYS_getpeername: ::c_long = 368; +pub const SYS_sendto: ::c_long = 369; +pub const SYS_sendmsg: ::c_long = 370; +pub const SYS_recvfrom: ::c_long = 371; +pub const SYS_recvmsg: ::c_long = 372; +pub const SYS_shutdown: ::c_long = 373; +pub const SYS_mlock2: ::c_long = 374; +pub const SYS_copy_file_range: ::c_long = 375; +pub const SYS_preadv2: ::c_long = 376; +pub const SYS_pwritev2: ::c_long = 377; +pub const SYS_lchown: ::c_long = 198; +pub const SYS_setuid: ::c_long = 213; +pub const SYS_getuid: ::c_long = 199; +pub const SYS_setgid: ::c_long = 214; +pub const SYS_getgid: ::c_long = 200; +pub const SYS_geteuid: ::c_long = 201; +pub const SYS_setreuid: ::c_long = 203; +pub const SYS_setregid: ::c_long = 204; +pub const SYS_getrlimit: ::c_long = 191; +pub const SYS_getgroups: ::c_long = 205; +pub const SYS_fchown: ::c_long = 207; +pub const SYS_setresuid: ::c_long = 208; +pub const SYS_setresgid: ::c_long = 210; +pub const SYS_getresgid: ::c_long = 211; +pub const SYS_select: ::c_long = 142; +pub const SYS_getegid: ::c_long = 202; +pub const SYS_setgroups: ::c_long = 206; +pub const SYS_getresuid: ::c_long = 209; +pub const SYS_chown: ::c_long = 212; +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; +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; +pub const SYS_mseal: ::c_long = 462; + +extern "C" { + + pub fn sysctl( + name: *mut ::c_int, + namelen: ::c_int, + oldp: *mut ::c_void, + oldlenp: *mut ::size_t, + newp: *mut ::c_void, + newlen: ::size_t, + ) -> ::c_int; + 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/sparc64/align.rs b/vendor/libc/src/unix/linux_like/linux/gnu/b64/sparc64/align.rs new file mode 100644 index 0000000..29d1e1c --- /dev/null +++ b/vendor/libc/src/unix/linux_like/linux/gnu/b64/sparc64/align.rs @@ -0,0 +1,7 @@ +s_no_extra_traits! { + #[allow(missing_debug_implementations)] + #[repr(align(16))] + pub struct max_align_t { + priv_: [i64; 4] + } +} 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 new file mode 100644 index 0000000..de2f0d6 --- /dev/null +++ b/vendor/libc/src/unix/linux_like/linux/gnu/b64/sparc64/mod.rs @@ -0,0 +1,931 @@ +//! SPARC64-specific definitions for 64-bit linux-like values + +use pthread_mutex_t; + +pub type c_long = i64; +pub type c_ulong = u64; +pub type c_char = i8; +pub type wchar_t = i32; +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 { + pub sa_sigaction: ::sighandler_t, + pub sa_mask: ::sigset_t, + #[cfg(target_arch = "sparc64")] + __reserved0: ::c_int, + 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, + f_spare: [::__fsword_t; 5], + } + + 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: [usize; 0], + } + + 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, + __reserved: ::c_short, + } + + pub struct stack_t { + pub ss_sp: *mut ::c_void, + pub ss_flags: ::c_int, + pub ss_size: ::size_t + } + + pub struct stat { + pub st_dev: ::dev_t, + __pad0: u64, + 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: u64, + 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; 2], + } + + pub struct stat64 { + pub st_dev: ::dev_t, + __pad0: u64, + 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, + __pad2: ::c_int, + 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_long, + pub st_mtime: ::time_t, + pub st_mtime_nsec: ::c_long, + pub st_ctime: ::time_t, + pub st_ctime_nsec: ::c_long, + __reserved: [::c_long; 2], + } + + 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 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: [u64; 7] + } + + 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, + __pad0: u16, + pub __seq: ::c_ushort, + __unused1: ::c_ulonglong, + __unused2: ::c_ulonglong, + } + + pub struct shmid_ds { + pub shm_perm: ::ipc_perm, + pub shm_atime: ::time_t, + pub shm_dtime: ::time_t, + pub shm_ctime: ::time_t, + pub shm_segsz: ::size_t, + pub shm_cpid: ::pid_t, + pub shm_lpid: ::pid_t, + pub shm_nattch: ::shmatt_t, + __reserved1: ::c_ulong, + __reserved2: ::c_ulong + } +} + +pub const POSIX_FADV_DONTNEED: ::c_int = 4; +pub const POSIX_FADV_NOREUSE: ::c_int = 5; + +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 __SIZEOF_PTHREAD_RWLOCK_T: usize = 56; +pub const __SIZEOF_PTHREAD_BARRIER_T: usize = 32; + +pub const O_APPEND: ::c_int = 0x8; +pub const O_CREAT: ::c_int = 0x200; +pub const O_EXCL: ::c_int = 0x800; +pub const O_NOCTTY: ::c_int = 0x8000; +pub const O_NONBLOCK: ::c_int = 0x4000; +pub const O_SYNC: ::c_int = 0x802000; +pub const O_RSYNC: ::c_int = 0x802000; +pub const O_DSYNC: ::c_int = 0x2000; +pub const O_FSYNC: ::c_int = 0x802000; +pub const O_NOATIME: ::c_int = 0x200000; +pub const O_PATH: ::c_int = 0x1000000; +pub const O_TMPFILE: ::c_int = 0x2000000 | O_DIRECTORY; + +pub const MADV_SOFT_OFFLINE: ::c_int = 101; +pub const MAP_GROWSDOWN: ::c_int = 0x0200; +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_SYNC: ::c_int = 0x080000; + +pub const EDEADLK: ::c_int = 78; +pub const ENAMETOOLONG: ::c_int = 63; +pub const ENOLCK: ::c_int = 79; +pub const ENOSYS: ::c_int = 90; +pub const ENOTEMPTY: ::c_int = 66; +pub const ELOOP: ::c_int = 62; +pub const ENOMSG: ::c_int = 75; +pub const EIDRM: ::c_int = 77; +pub const ECHRNG: ::c_int = 94; +pub const EL2NSYNC: ::c_int = 95; +pub const EL3HLT: ::c_int = 96; +pub const EL3RST: ::c_int = 97; +pub const ELNRNG: ::c_int = 98; +pub const EUNATCH: ::c_int = 99; +pub const ENOCSI: ::c_int = 100; +pub const EL2HLT: ::c_int = 101; +pub const EBADE: ::c_int = 102; +pub const EBADR: ::c_int = 103; +pub const EXFULL: ::c_int = 104; +pub const ENOANO: ::c_int = 105; +pub const EBADRQC: ::c_int = 106; +pub const EBADSLT: ::c_int = 107; +pub const EMULTIHOP: ::c_int = 87; +pub const EOVERFLOW: ::c_int = 92; +pub const ENOTUNIQ: ::c_int = 115; +pub const EBADFD: ::c_int = 93; +pub const EBADMSG: ::c_int = 76; +pub const EREMCHG: ::c_int = 89; +pub const ELIBACC: ::c_int = 114; +pub const ELIBBAD: ::c_int = 112; +pub const ELIBSCN: ::c_int = 124; +pub const ELIBMAX: ::c_int = 123; +pub const ELIBEXEC: ::c_int = 110; +pub const EILSEQ: ::c_int = 122; +pub const ERESTART: ::c_int = 116; +pub const ESTRPIPE: ::c_int = 91; +pub const EUSERS: ::c_int = 68; +pub const ENOTSOCK: ::c_int = 38; +pub const EDESTADDRREQ: ::c_int = 39; +pub const EMSGSIZE: ::c_int = 40; +pub const EPROTOTYPE: ::c_int = 41; +pub const ENOPROTOOPT: ::c_int = 42; +pub const EPROTONOSUPPORT: ::c_int = 43; +pub const ESOCKTNOSUPPORT: ::c_int = 44; +pub const EOPNOTSUPP: ::c_int = 45; +pub const EPFNOSUPPORT: ::c_int = 46; +pub const EAFNOSUPPORT: ::c_int = 47; +pub const EADDRINUSE: ::c_int = 48; +pub const EADDRNOTAVAIL: ::c_int = 49; +pub const ENETDOWN: ::c_int = 50; +pub const ENETUNREACH: ::c_int = 51; +pub const ENETRESET: ::c_int = 52; +pub const ECONNABORTED: ::c_int = 53; +pub const ECONNRESET: ::c_int = 54; +pub const ENOBUFS: ::c_int = 55; +pub const EISCONN: ::c_int = 56; +pub const ENOTCONN: ::c_int = 57; +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 EHOSTDOWN: ::c_int = 64; +pub const EHOSTUNREACH: ::c_int = 65; +pub const EALREADY: ::c_int = 37; +pub const EINPROGRESS: ::c_int = 36; +pub const ESTALE: ::c_int = 70; +pub const EDQUOT: ::c_int = 69; +pub const ENOMEDIUM: ::c_int = 125; +pub const EMEDIUMTYPE: ::c_int = 126; +pub const ECANCELED: ::c_int = 127; +pub const ENOKEY: ::c_int = 128; +pub const EKEYEXPIRED: ::c_int = 129; +pub const EKEYREVOKED: ::c_int = 130; +pub const EKEYREJECTED: ::c_int = 131; +pub const EOWNERDEAD: ::c_int = 132; +pub const ENOTRECOVERABLE: ::c_int = 133; +pub const EHWPOISON: ::c_int = 135; +pub const ERFKILL: ::c_int = 134; + +pub const SOCK_STREAM: ::c_int = 1; +pub const SOCK_DGRAM: ::c_int = 2; + +pub const SA_ONSTACK: ::c_int = 1; +pub const SA_SIGINFO: ::c_int = 0x200; +pub const SA_NOCLDWAIT: ::c_int = 0x100; + +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 = 20; +pub const SIGBUS: ::c_int = 10; +pub const SIGUSR1: ::c_int = 30; +pub const SIGUSR2: ::c_int = 31; +pub const SIGCONT: ::c_int = 19; +pub const SIGSTOP: ::c_int = 17; +pub const SIGTSTP: ::c_int = 18; +pub const SIGURG: ::c_int = 16; +pub const SIGIO: ::c_int = 23; +pub const SIGSYS: ::c_int = 12; +pub const SIGPOLL: ::c_int = 23; +pub const SIGPWR: ::c_int = 29; +pub const SIG_SETMASK: ::c_int = 4; +pub const SIG_BLOCK: ::c_int = 1; +pub const SIG_UNBLOCK: ::c_int = 2; + +pub const POLLWRNORM: ::c_short = 4; +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 = 17; + +pub const EFD_NONBLOCK: ::c_int = 0x4000; + +pub const F_GETLK: ::c_int = 7; +pub const F_GETOWN: ::c_int = 5; +pub const F_SETOWN: ::c_int = 6; +pub const F_SETLK: ::c_int = 8; +pub const F_SETLKW: ::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 = 1; +pub const F_WRLCK: ::c_int = 2; +pub const F_UNLCK: ::c_int = 3; + +pub const SFD_NONBLOCK: ::c_int = 0x4000; + +pub const TCSANOW: ::c_int = 0; +pub const TCSADRAIN: ::c_int = 1; +pub const TCSAFLUSH: ::c_int = 2; + +pub const SFD_CLOEXEC: ::c_int = 0x400000; + +pub const NCCS: usize = 17; +pub const O_TRUNC: ::c_int = 0x400; + +pub const O_CLOEXEC: ::c_int = 0x400000; + +pub const EBFONT: ::c_int = 109; +pub const ENOSTR: ::c_int = 72; +pub const ENODATA: ::c_int = 111; +pub const ETIME: ::c_int = 73; +pub const ENOSR: ::c_int = 74; +pub const ENONET: ::c_int = 80; +pub const ENOPKG: ::c_int = 113; +pub const EREMOTE: ::c_int = 71; +pub const ENOLINK: ::c_int = 82; +pub const EADV: ::c_int = 83; +pub const ESRMNT: ::c_int = 84; +pub const ECOMM: ::c_int = 85; +pub const EPROTO: ::c_int = 86; +pub const EDOTDOT: ::c_int = 88; + +pub const SA_NODEFER: ::c_int = 0x20; +pub const SA_RESETHAND: ::c_int = 0x4; +pub const SA_RESTART: ::c_int = 0x2; +pub const SA_NOCLDSTOP: ::c_int = 0x00000008; + +pub const EPOLL_CLOEXEC: ::c_int = 0x400000; + +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 = + 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, + ], + }; + 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, + ], + }; + 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 O_DIRECTORY: ::c_int = 0o200000; +pub const O_NOFOLLOW: ::c_int = 0o400000; +pub const O_DIRECT: ::c_int = 0x100000; + +pub const MAP_LOCKED: ::c_int = 0x0100; +pub const MAP_NORESERVE: ::c_int = 0x00040; + +pub const EDEADLOCK: ::c_int = 108; +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 MCL_CURRENT: ::c_int = 0x2000; +pub const MCL_FUTURE: ::c_int = 0x4000; +pub const MCL_ONFAULT: ::c_int = 0x8000; + +pub const SIGSTKSZ: ::size_t = 16384; +pub const MINSIGSTKSZ: ::size_t = 4096; +pub const CBAUD: ::tcflag_t = 0x0000100f; +pub const TAB1: ::tcflag_t = 0x800; +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 = 0xe; +pub const VREPRINT: usize = 0xc; +pub const VSUSP: usize = 0xa; +pub const VSTART: usize = 0x8; +pub const VSTOP: usize = 0x9; +pub const VDISCARD: usize = 0xd; +pub const VTIME: usize = 0x5; +pub const IXON: ::tcflag_t = 0x400; +pub const IXOFF: ::tcflag_t = 0x1000; +pub const ONLCR: ::tcflag_t = 0x4; +pub const CSIZE: ::tcflag_t = 0x30; +pub const CS6: ::tcflag_t = 0x10; +pub const CS7: ::tcflag_t = 0x20; +pub const CS8: ::tcflag_t = 0x30; +pub const CSTOPB: ::tcflag_t = 0x40; +pub const CREAD: ::tcflag_t = 0x80; +pub const PARENB: ::tcflag_t = 0x100; +pub const PARODD: ::tcflag_t = 0x200; +pub const HUPCL: ::tcflag_t = 0x400; +pub const CLOCAL: ::tcflag_t = 0x800; +pub const ECHOKE: ::tcflag_t = 0x800; +pub const ECHOE: ::tcflag_t = 0x10; +pub const ECHOK: ::tcflag_t = 0x20; +pub const ECHONL: ::tcflag_t = 0x40; +pub const ECHOPRT: ::tcflag_t = 0x400; +pub const ECHOCTL: ::tcflag_t = 0x200; +pub const ISIG: ::tcflag_t = 0x1; +pub const ICANON: ::tcflag_t = 0x2; +pub const PENDIN: ::tcflag_t = 0x4000; +pub const NOFLSH: ::tcflag_t = 0x80; +pub const CIBAUD: ::tcflag_t = 0o02003600000; +pub const CBAUDEX: ::tcflag_t = 0x00001000; +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 = 0x1001; +pub const B115200: ::speed_t = 0x1002; +pub const B230400: ::speed_t = 0x1003; +pub const B460800: ::speed_t = 0x1004; +pub const B76800: ::speed_t = 0x1005; +pub const B153600: ::speed_t = 0x1006; +pub const B307200: ::speed_t = 0x1007; +pub const B614400: ::speed_t = 0x1008; +pub const B921600: ::speed_t = 0x1009; +pub const B500000: ::speed_t = 0x100a; +pub const B576000: ::speed_t = 0x100b; +pub const B1000000: ::speed_t = 0x100c; +pub const B1152000: ::speed_t = 0x100d; +pub const B1500000: ::speed_t = 0x100e; +pub const B2000000: ::speed_t = 0x100f; + +pub const VEOL: usize = 5; +pub const VEOL2: usize = 6; +pub const VMIN: usize = 4; +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 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_wait4: ::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_execv: ::c_long = 11; +pub const SYS_chdir: ::c_long = 12; +pub const SYS_chown: ::c_long = 13; +pub const SYS_mknod: ::c_long = 14; +pub const SYS_chmod: ::c_long = 15; +pub const SYS_lchown: ::c_long = 16; +pub const SYS_brk: ::c_long = 17; +pub const SYS_perfctr: ::c_long = 18; +pub const SYS_lseek: ::c_long = 19; +pub const SYS_getpid: ::c_long = 20; +pub const SYS_capget: ::c_long = 21; +pub const SYS_capset: ::c_long = 22; +pub const SYS_setuid: ::c_long = 23; +pub const SYS_getuid: ::c_long = 24; +pub const SYS_vmsplice: ::c_long = 25; +pub const SYS_ptrace: ::c_long = 26; +pub const SYS_alarm: ::c_long = 27; +pub const SYS_sigaltstack: ::c_long = 28; +pub const SYS_pause: ::c_long = 29; +pub const SYS_utime: ::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_stat: ::c_long = 38; +pub const SYS_sendfile: ::c_long = 39; +pub const SYS_lstat: ::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_umount2: ::c_long = 45; +pub const SYS_setgid: ::c_long = 46; +pub const SYS_getgid: ::c_long = 47; +pub const SYS_signal: ::c_long = 48; +pub const SYS_geteuid: ::c_long = 49; +pub const SYS_getegid: ::c_long = 50; +pub const SYS_acct: ::c_long = 51; +pub const SYS_memory_ordering: ::c_long = 52; +pub const SYS_ioctl: ::c_long = 54; +pub const SYS_reboot: ::c_long = 55; +pub const SYS_symlink: ::c_long = 57; +pub const SYS_readlink: ::c_long = 58; +pub const SYS_execve: ::c_long = 59; +pub const SYS_umask: ::c_long = 60; +pub const SYS_chroot: ::c_long = 61; +pub const SYS_fstat: ::c_long = 62; +pub const SYS_fstat64: ::c_long = 63; +pub const SYS_getpagesize: ::c_long = 64; +pub const SYS_msync: ::c_long = 65; +pub const SYS_vfork: ::c_long = 66; +pub const SYS_pread64: ::c_long = 67; +pub const SYS_pwrite64: ::c_long = 68; +pub const SYS_mmap: ::c_long = 71; +pub const SYS_munmap: ::c_long = 73; +pub const SYS_mprotect: ::c_long = 74; +pub const SYS_madvise: ::c_long = 75; +pub const SYS_vhangup: ::c_long = 76; +pub const SYS_mincore: ::c_long = 78; +pub const SYS_getgroups: ::c_long = 79; +pub const SYS_setgroups: ::c_long = 80; +pub const SYS_getpgrp: ::c_long = 81; +pub const SYS_setitimer: ::c_long = 83; +pub const SYS_swapon: ::c_long = 85; +pub const SYS_getitimer: ::c_long = 86; +pub const SYS_sethostname: ::c_long = 88; +pub const SYS_dup2: ::c_long = 90; +pub const SYS_fcntl: ::c_long = 92; +pub const SYS_select: ::c_long = 93; +pub const SYS_fsync: ::c_long = 95; +pub const SYS_setpriority: ::c_long = 96; +pub const SYS_socket: ::c_long = 97; +pub const SYS_connect: ::c_long = 98; +pub const SYS_accept: ::c_long = 99; +pub const SYS_getpriority: ::c_long = 100; +pub const SYS_rt_sigreturn: ::c_long = 101; +pub const SYS_rt_sigaction: ::c_long = 102; +pub const SYS_rt_sigprocmask: ::c_long = 103; +pub const SYS_rt_sigpending: ::c_long = 104; +pub const SYS_rt_sigtimedwait: ::c_long = 105; +pub const SYS_rt_sigqueueinfo: ::c_long = 106; +pub const SYS_rt_sigsuspend: ::c_long = 107; +pub const SYS_setresuid: ::c_long = 108; +pub const SYS_getresuid: ::c_long = 109; +pub const SYS_setresgid: ::c_long = 110; +pub const SYS_getresgid: ::c_long = 111; +pub const SYS_recvmsg: ::c_long = 113; +pub const SYS_sendmsg: ::c_long = 114; +pub const SYS_gettimeofday: ::c_long = 116; +pub const SYS_getrusage: ::c_long = 117; +pub const SYS_getsockopt: ::c_long = 118; +pub const SYS_getcwd: ::c_long = 119; +pub const SYS_readv: ::c_long = 120; +pub const SYS_writev: ::c_long = 121; +pub const SYS_settimeofday: ::c_long = 122; +pub const SYS_fchown: ::c_long = 123; +pub const SYS_fchmod: ::c_long = 124; +pub const SYS_recvfrom: ::c_long = 125; +pub const SYS_setreuid: ::c_long = 126; +pub const SYS_setregid: ::c_long = 127; +pub const SYS_rename: ::c_long = 128; +pub const SYS_truncate: ::c_long = 129; +pub const SYS_ftruncate: ::c_long = 130; +pub const SYS_flock: ::c_long = 131; +pub const SYS_lstat64: ::c_long = 132; +pub const SYS_sendto: ::c_long = 133; +pub const SYS_shutdown: ::c_long = 134; +pub const SYS_socketpair: ::c_long = 135; +pub const SYS_mkdir: ::c_long = 136; +pub const SYS_rmdir: ::c_long = 137; +pub const SYS_utimes: ::c_long = 138; +pub const SYS_stat64: ::c_long = 139; +pub const SYS_sendfile64: ::c_long = 140; +pub const SYS_getpeername: ::c_long = 141; +pub const SYS_futex: ::c_long = 142; +pub const SYS_gettid: ::c_long = 143; +pub const SYS_getrlimit: ::c_long = 144; +pub const SYS_setrlimit: ::c_long = 145; +pub const SYS_pivot_root: ::c_long = 146; +pub const SYS_prctl: ::c_long = 147; +pub const SYS_pciconfig_read: ::c_long = 148; +pub const SYS_pciconfig_write: ::c_long = 149; +pub const SYS_getsockname: ::c_long = 150; +pub const SYS_inotify_init: ::c_long = 151; +pub const SYS_inotify_add_watch: ::c_long = 152; +pub const SYS_poll: ::c_long = 153; +pub const SYS_getdents64: ::c_long = 154; +pub const SYS_inotify_rm_watch: ::c_long = 156; +pub const SYS_statfs: ::c_long = 157; +pub const SYS_fstatfs: ::c_long = 158; +pub const SYS_umount: ::c_long = 159; +pub const SYS_sched_set_affinity: ::c_long = 160; +pub const SYS_sched_get_affinity: ::c_long = 161; +pub const SYS_getdomainname: ::c_long = 162; +pub const SYS_setdomainname: ::c_long = 163; +pub const SYS_utrap_install: ::c_long = 164; +pub const SYS_quotactl: ::c_long = 165; +pub const SYS_set_tid_address: ::c_long = 166; +pub const SYS_mount: ::c_long = 167; +pub const SYS_ustat: ::c_long = 168; +pub const SYS_setxattr: ::c_long = 169; +pub const SYS_lsetxattr: ::c_long = 170; +pub const SYS_fsetxattr: ::c_long = 171; +pub const SYS_getxattr: ::c_long = 172; +pub const SYS_lgetxattr: ::c_long = 173; +pub const SYS_getdents: ::c_long = 174; +pub const SYS_setsid: ::c_long = 175; +pub const SYS_fchdir: ::c_long = 176; +pub const SYS_fgetxattr: ::c_long = 177; +pub const SYS_listxattr: ::c_long = 178; +pub const SYS_llistxattr: ::c_long = 179; +pub const SYS_flistxattr: ::c_long = 180; +pub const SYS_removexattr: ::c_long = 181; +pub const SYS_lremovexattr: ::c_long = 182; +pub const SYS_sigpending: ::c_long = 183; +pub const SYS_query_module: ::c_long = 184; +pub const SYS_setpgid: ::c_long = 185; +pub const SYS_fremovexattr: ::c_long = 186; +pub const SYS_tkill: ::c_long = 187; +pub const SYS_exit_group: ::c_long = 188; +pub const SYS_uname: ::c_long = 189; +pub const SYS_init_module: ::c_long = 190; +pub const SYS_personality: ::c_long = 191; +pub const SYS_remap_file_pages: ::c_long = 192; +pub const SYS_epoll_create: ::c_long = 193; +pub const SYS_epoll_ctl: ::c_long = 194; +pub const SYS_epoll_wait: ::c_long = 195; +pub const SYS_ioprio_set: ::c_long = 196; +pub const SYS_getppid: ::c_long = 197; +pub const SYS_sigaction: ::c_long = 198; +pub const SYS_sgetmask: ::c_long = 199; +pub const SYS_ssetmask: ::c_long = 200; +pub const SYS_sigsuspend: ::c_long = 201; +pub const SYS_oldlstat: ::c_long = 202; +pub const SYS_uselib: ::c_long = 203; +pub const SYS_readdir: ::c_long = 204; +pub const SYS_readahead: ::c_long = 205; +pub const SYS_socketcall: ::c_long = 206; +pub const SYS_syslog: ::c_long = 207; +pub const SYS_lookup_dcookie: ::c_long = 208; +pub const SYS_fadvise64: ::c_long = 209; +pub const SYS_fadvise64_64: ::c_long = 210; +pub const SYS_tgkill: ::c_long = 211; +pub const SYS_waitpid: ::c_long = 212; +pub const SYS_swapoff: ::c_long = 213; +pub const SYS_sysinfo: ::c_long = 214; +pub const SYS_ipc: ::c_long = 215; +pub const SYS_sigreturn: ::c_long = 216; +pub const SYS_clone: ::c_long = 217; +pub const SYS_ioprio_get: ::c_long = 218; +pub const SYS_adjtimex: ::c_long = 219; +pub const SYS_sigprocmask: ::c_long = 220; +pub const SYS_create_module: ::c_long = 221; +pub const SYS_delete_module: ::c_long = 222; +pub const SYS_get_kernel_syms: ::c_long = 223; +pub const SYS_getpgid: ::c_long = 224; +pub const SYS_bdflush: ::c_long = 225; +pub const SYS_sysfs: ::c_long = 226; +pub const SYS_afs_syscall: ::c_long = 227; +pub const SYS_setfsuid: ::c_long = 228; +pub const SYS_setfsgid: ::c_long = 229; +pub const SYS__newselect: ::c_long = 230; +pub const SYS_splice: ::c_long = 232; +pub const SYS_stime: ::c_long = 233; +pub const SYS_statfs64: ::c_long = 234; +pub const SYS_fstatfs64: ::c_long = 235; +pub const SYS__llseek: ::c_long = 236; +pub const SYS_mlock: ::c_long = 237; +pub const SYS_munlock: ::c_long = 238; +pub const SYS_mlockall: ::c_long = 239; +pub const SYS_munlockall: ::c_long = 240; +pub const SYS_sched_setparam: ::c_long = 241; +pub const SYS_sched_getparam: ::c_long = 242; +pub const SYS_sched_setscheduler: ::c_long = 243; +pub const SYS_sched_getscheduler: ::c_long = 244; +pub const SYS_sched_yield: ::c_long = 245; +pub const SYS_sched_get_priority_max: ::c_long = 246; +pub const SYS_sched_get_priority_min: ::c_long = 247; +pub const SYS_sched_rr_get_interval: ::c_long = 248; +pub const SYS_nanosleep: ::c_long = 249; +pub const SYS_mremap: ::c_long = 250; +pub const SYS__sysctl: ::c_long = 251; +pub const SYS_getsid: ::c_long = 252; +pub const SYS_fdatasync: ::c_long = 253; +pub const SYS_nfsservctl: ::c_long = 254; +pub const SYS_sync_file_range: ::c_long = 255; +pub const SYS_clock_settime: ::c_long = 256; +pub const SYS_clock_gettime: ::c_long = 257; +pub const SYS_clock_getres: ::c_long = 258; +pub const SYS_clock_nanosleep: ::c_long = 259; +pub const SYS_sched_getaffinity: ::c_long = 260; +pub const SYS_sched_setaffinity: ::c_long = 261; +pub const SYS_timer_settime: ::c_long = 262; +pub const SYS_timer_gettime: ::c_long = 263; +pub const SYS_timer_getoverrun: ::c_long = 264; +pub const SYS_timer_delete: ::c_long = 265; +pub const SYS_timer_create: ::c_long = 266; +pub const SYS_io_setup: ::c_long = 268; +pub const SYS_io_destroy: ::c_long = 269; +pub const SYS_io_submit: ::c_long = 270; +pub const SYS_io_cancel: ::c_long = 271; +pub const SYS_io_getevents: ::c_long = 272; +pub const SYS_mq_open: ::c_long = 273; +pub const SYS_mq_unlink: ::c_long = 274; +pub const SYS_mq_timedsend: ::c_long = 275; +pub const SYS_mq_timedreceive: ::c_long = 276; +pub const SYS_mq_notify: ::c_long = 277; +pub const SYS_mq_getsetattr: ::c_long = 278; +pub const SYS_waitid: ::c_long = 279; +pub const SYS_tee: ::c_long = 280; +pub const SYS_add_key: ::c_long = 281; +pub const SYS_request_key: ::c_long = 282; +pub const SYS_keyctl: ::c_long = 283; +pub const SYS_openat: ::c_long = 284; +pub const SYS_mkdirat: ::c_long = 285; +pub const SYS_mknodat: ::c_long = 286; +pub const SYS_fchownat: ::c_long = 287; +pub const SYS_futimesat: ::c_long = 288; +pub const SYS_fstatat64: ::c_long = 289; +pub const SYS_unlinkat: ::c_long = 290; +pub const SYS_renameat: ::c_long = 291; +pub const SYS_linkat: ::c_long = 292; +pub const SYS_symlinkat: ::c_long = 293; +pub const SYS_readlinkat: ::c_long = 294; +pub const SYS_fchmodat: ::c_long = 295; +pub const SYS_faccessat: ::c_long = 296; +pub const SYS_pselect6: ::c_long = 297; +pub const SYS_ppoll: ::c_long = 298; +pub const SYS_unshare: ::c_long = 299; +pub const SYS_set_robust_list: ::c_long = 300; +pub const SYS_get_robust_list: ::c_long = 301; +pub const SYS_migrate_pages: ::c_long = 302; +pub const SYS_mbind: ::c_long = 303; +pub const SYS_get_mempolicy: ::c_long = 304; +pub const SYS_set_mempolicy: ::c_long = 305; +pub const SYS_kexec_load: ::c_long = 306; +pub const SYS_move_pages: ::c_long = 307; +pub const SYS_getcpu: ::c_long = 308; +pub const SYS_epoll_pwait: ::c_long = 309; +pub const SYS_utimensat: ::c_long = 310; +pub const SYS_signalfd: ::c_long = 311; +pub const SYS_timerfd_create: ::c_long = 312; +pub const SYS_eventfd: ::c_long = 313; +pub const SYS_fallocate: ::c_long = 314; +pub const SYS_timerfd_settime: ::c_long = 315; +pub const SYS_timerfd_gettime: ::c_long = 316; +pub const SYS_signalfd4: ::c_long = 317; +pub const SYS_eventfd2: ::c_long = 318; +pub const SYS_epoll_create1: ::c_long = 319; +pub const SYS_dup3: ::c_long = 320; +pub const SYS_pipe2: ::c_long = 321; +pub const SYS_inotify_init1: ::c_long = 322; +pub const SYS_accept4: ::c_long = 323; +pub const SYS_preadv: ::c_long = 324; +pub const SYS_pwritev: ::c_long = 325; +pub const SYS_rt_tgsigqueueinfo: ::c_long = 326; +pub const SYS_perf_event_open: ::c_long = 327; +pub const SYS_recvmmsg: ::c_long = 328; +pub const SYS_fanotify_init: ::c_long = 329; +pub const SYS_fanotify_mark: ::c_long = 330; +pub const SYS_prlimit64: ::c_long = 331; +pub const SYS_name_to_handle_at: ::c_long = 332; +pub const SYS_open_by_handle_at: ::c_long = 333; +pub const SYS_clock_adjtime: ::c_long = 334; +pub const SYS_syncfs: ::c_long = 335; +pub const SYS_sendmmsg: ::c_long = 336; +pub const SYS_setns: ::c_long = 337; +pub const SYS_process_vm_readv: ::c_long = 338; +pub const SYS_process_vm_writev: ::c_long = 339; +pub const SYS_kern_features: ::c_long = 340; +pub const SYS_kcmp: ::c_long = 341; +pub const SYS_finit_module: ::c_long = 342; +pub const SYS_sched_setattr: ::c_long = 343; +pub const SYS_sched_getattr: ::c_long = 344; +pub const SYS_renameat2: ::c_long = 345; +pub const SYS_seccomp: ::c_long = 346; +pub const SYS_getrandom: ::c_long = 347; +pub const SYS_memfd_create: ::c_long = 348; +pub const SYS_bpf: ::c_long = 349; +pub const SYS_execveat: ::c_long = 350; +pub const SYS_membarrier: ::c_long = 351; +pub const SYS_userfaultfd: ::c_long = 352; +pub const SYS_bind: ::c_long = 353; +pub const SYS_listen: ::c_long = 354; +pub const SYS_setsockopt: ::c_long = 355; +pub const SYS_mlock2: ::c_long = 356; +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; +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; +// Reserved in the kernel, but not actually implemented yet +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; + +extern "C" { + pub fn sysctl( + name: *mut ::c_int, + namelen: ::c_int, + oldp: *mut ::c_void, + oldlenp: *mut ::size_t, + newp: *mut ::c_void, + newlen: ::size_t, + ) -> ::c_int; +} + +cfg_if! { + if #[cfg(libc_align)] { + mod align; + pub use self::align::*; + } +} 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 new file mode 100644 index 0000000..ba3075e --- /dev/null +++ b/vendor/libc/src/unix/linux_like/linux/gnu/b64/x86_64/align.rs @@ -0,0 +1,24 @@ +s_no_extra_traits! { + #[allow(missing_debug_implementations)] + #[repr(align(16))] + 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/gnu/b64/x86_64/mod.rs b/vendor/libc/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs new file mode 100644 index 0000000..f66eb04 --- /dev/null +++ b/vendor/libc/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs @@ -0,0 +1,822 @@ +//! x86_64-specific definitions for 64-bit linux-like values + +pub type c_char = i8; +pub type wchar_t = i32; +pub type nlink_t = u64; +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 { + pub sa_sigaction: ::sighandler_t, + pub sa_mask: ::sigset_t, + #[cfg(target_arch = "sparc64")] + __reserved0: ::c_int, + 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, + f_spare: [::__fsword_t; 5], + } + + 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 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 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: i64, + pub st_mtime: ::time_t, + pub st_mtime_nsec: i64, + pub st_ctime: ::time_t, + pub st_ctime_nsec: i64, + __unused: [i64; 3], + } + + pub struct stat64 { + pub st_dev: ::dev_t, + pub st_ino: ::ino64_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: ::blkcnt64_t, + pub st_atime: ::time_t, + pub st_atime_nsec: i64, + pub st_mtime: ::time_t, + pub st_mtime_nsec: i64, + pub st_ctime: ::time_t, + pub st_ctime_nsec: i64, + __reserved: [i64; 3], + } + + 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 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 { + #[cfg(target_pointer_width = "32")] + __size: [u32; 8], + #[cfg(target_pointer_width = "64")] + __size: [u64; 7] + } + + pub struct _libc_fpxreg { + pub significand: [u16; 4], + pub exponent: u16, + __private: [u16; 3], + } + + pub struct _libc_xmmreg { + pub element: [u32; 4], + } + + pub struct _libc_fpstate { + pub cwd: u16, + pub swd: u16, + pub ftw: u16, + pub fop: u16, + pub rip: u64, + pub rdp: u64, + pub mxcsr: u32, + pub mxcr_mask: u32, + pub _st: [_libc_fpxreg; 8], + pub _xmm: [_libc_xmmreg; 16], + __private: [u64; 12], + } + + pub struct user_regs_struct { + pub r15: ::c_ulonglong, + pub r14: ::c_ulonglong, + pub r13: ::c_ulonglong, + pub r12: ::c_ulonglong, + pub rbp: ::c_ulonglong, + pub rbx: ::c_ulonglong, + pub r11: ::c_ulonglong, + pub r10: ::c_ulonglong, + pub r9: ::c_ulonglong, + pub r8: ::c_ulonglong, + pub rax: ::c_ulonglong, + pub rcx: ::c_ulonglong, + pub rdx: ::c_ulonglong, + pub rsi: ::c_ulonglong, + pub rdi: ::c_ulonglong, + pub orig_rax: ::c_ulonglong, + pub rip: ::c_ulonglong, + pub cs: ::c_ulonglong, + pub eflags: ::c_ulonglong, + pub rsp: ::c_ulonglong, + pub ss: ::c_ulonglong, + pub fs_base: ::c_ulonglong, + pub gs_base: ::c_ulonglong, + pub ds: ::c_ulonglong, + pub es: ::c_ulonglong, + pub fs: ::c_ulonglong, + pub gs: ::c_ulonglong, + } + + pub struct user { + pub regs: user_regs_struct, + pub u_fpvalid: ::c_int, + pub i387: user_fpregs_struct, + pub u_tsize: ::c_ulonglong, + pub u_dsize: ::c_ulonglong, + pub u_ssize: ::c_ulonglong, + pub start_code: ::c_ulonglong, + pub start_stack: ::c_ulonglong, + pub signal: ::c_longlong, + __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_ulonglong, + pub u_comm: [::c_char; 32], + pub u_debugreg: [::c_ulonglong; 8], + } + + pub struct mcontext_t { + pub gregs: [greg_t; 23], + pub fpregs: *mut _libc_fpstate, + __private: [u64; 8], + } + + 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: u64, + __unused2: u64 + } + + 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: u64, + __unused5: u64 + } + + pub struct ptrace_rseq_configuration { + pub rseq_abi_pointer: ::__u64, + pub rseq_abi_size: ::__u32, + pub signature: ::__u32, + pub flags: ::__u32, + pub pad: ::__u32, + } +} + +s_no_extra_traits! { + pub struct user_fpregs_struct { + pub cwd: ::c_ushort, + pub swd: ::c_ushort, + pub ftw: ::c_ushort, + pub fop: ::c_ushort, + pub rip: ::c_ulonglong, + pub rdp: ::c_ulonglong, + 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], + } + + 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, + __private: [u8; 512], + // FIXME: the shadow stack field requires glibc >= 2.28. + // Re-add once we drop compatibility with glibc versions older than + // 2.28. + // + // __ssp: [::c_ulonglong; 4], + } +} + +cfg_if! { + if #[cfg(feature = "extra_traits")] { + 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("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.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 + } + } + + 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 + // Ignore __private field + } + } + + impl Eq for ucontext_t {} + + impl ::fmt::Debug for ucontext_t { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("ucontext_t") + .field("uc_flags", &self.uc_flags) + .field("uc_link", &self.uc_link) + .field("uc_stack", &self.uc_stack) + .field("uc_mcontext", &self.uc_mcontext) + .field("uc_sigmask", &self.uc_sigmask) + // Ignore __private field + .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); + // Ignore __private field + } + } + } +} + +pub const POSIX_FADV_DONTNEED: ::c_int = 4; +pub const POSIX_FADV_NOREUSE: ::c_int = 5; + +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_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_NOATIME: ::c_int = 0o1000000; +pub const O_PATH: ::c_int = 0o10000000; +pub const O_TMPFILE: ::c_int = 0o20000000 | O_DIRECTORY; + +pub const MADV_SOFT_OFFLINE: ::c_int = 101; +pub const MAP_GROWSDOWN: ::c_int = 0x0100; + +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 SOCK_STREAM: ::c_int = 1; +pub const SOCK_DGRAM: ::c_int = 2; + +pub const SA_ONSTACK: ::c_int = 0x08000000; +pub const SA_SIGINFO: ::c_int = 0x00000004; +pub const SA_NOCLDWAIT: ::c_int = 0x00000002; + +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; +#[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 POLLWRNORM: ::c_short = 0x100; +pub const POLLWRBAND: ::c_short = 0x200; + +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; + +pub const F_GETLK: ::c_int = 5; +pub const F_GETOWN: ::c_int = 9; +pub const F_SETOWN: ::c_int = 8; +pub const F_SETLK: ::c_int = 6; +pub const F_SETLKW: ::c_int = 7; +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_WRLCK: ::c_int = 1; +pub const F_UNLCK: ::c_int = 2; + +pub const SFD_NONBLOCK: ::c_int = 0x0800; + +pub const TCSANOW: ::c_int = 0; +pub const TCSADRAIN: ::c_int = 1; +pub const TCSAFLUSH: ::c_int = 2; + +pub const SFD_CLOEXEC: ::c_int = 0x080000; + +pub const NCCS: usize = 32; + +pub const O_TRUNC: ::c_int = 512; + +pub const O_CLOEXEC: ::c_int = 0x80000; + +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 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 EPOLL_CLOEXEC: ::c_int = 0x80000; + +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; +pub const O_NOFOLLOW: ::c_int = 0x20000; + +pub const MAP_HUGETLB: ::c_int = 0x040000; +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_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 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 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; +pub const MCL_ONFAULT: ::c_int = 0x0004; + +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; + +// offsets in user_regs_structs, from sys/reg.h +pub const R15: ::c_int = 0; +pub const R14: ::c_int = 1; +pub const R13: ::c_int = 2; +pub const R12: ::c_int = 3; +pub const RBP: ::c_int = 4; +pub const RBX: ::c_int = 5; +pub const R11: ::c_int = 6; +pub const R10: ::c_int = 7; +pub const R9: ::c_int = 8; +pub const R8: ::c_int = 9; +pub const RAX: ::c_int = 10; +pub const RCX: ::c_int = 11; +pub const RDX: ::c_int = 12; +pub const RSI: ::c_int = 13; +pub const RDI: ::c_int = 14; +pub const ORIG_RAX: ::c_int = 15; +pub const RIP: ::c_int = 16; +pub const CS: ::c_int = 17; +pub const EFLAGS: ::c_int = 18; +pub const RSP: ::c_int = 19; +pub const SS: ::c_int = 20; +pub const FS_BASE: ::c_int = 21; +pub const GS_BASE: ::c_int = 22; +pub const DS: ::c_int = 23; +pub const ES: ::c_int = 24; +pub const FS: ::c_int = 25; +pub const GS: ::c_int = 26; + +// offsets in mcontext_t.gregs from sys/ucontext.h +pub const REG_R8: ::c_int = 0; +pub const REG_R9: ::c_int = 1; +pub const REG_R10: ::c_int = 2; +pub const REG_R11: ::c_int = 3; +pub const REG_R12: ::c_int = 4; +pub const REG_R13: ::c_int = 5; +pub const REG_R14: ::c_int = 6; +pub const REG_R15: ::c_int = 7; +pub const REG_RDI: ::c_int = 8; +pub const REG_RSI: ::c_int = 9; +pub const REG_RBP: ::c_int = 10; +pub const REG_RBX: ::c_int = 11; +pub const REG_RDX: ::c_int = 12; +pub const REG_RAX: ::c_int = 13; +pub const REG_RCX: ::c_int = 14; +pub const REG_RSP: ::c_int = 15; +pub const REG_RIP: ::c_int = 16; +pub const REG_EFL: ::c_int = 17; +pub const REG_CSGSFS: ::c_int = 18; +pub const REG_ERR: ::c_int = 19; +pub const REG_TRAPNO: ::c_int = 20; +pub const REG_OLDMASK: ::c_int = 21; +pub const REG_CR2: ::c_int = 22; + +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; +} + +cfg_if! { + if #[cfg(target_pointer_width = "32")] { + mod x32; + pub use self::x32::*; + } else { + mod not_x32; + pub use self::not_x32::*; + } +} + +cfg_if! { + if #[cfg(libc_align)] { + mod align; + pub use self::align::*; + } +} 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 new file mode 100644 index 0000000..9b37907 --- /dev/null +++ b/vendor/libc/src/unix/linux_like/linux/gnu/b64/x86_64/not_x32.rs @@ -0,0 +1,453 @@ +use pthread_mutex_t; + +pub type c_long = i64; +pub type c_ulong = u64; + +s! { + 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 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, + ], + }; +} + +// Syscall table + +pub const SYS_read: ::c_long = 0; +pub const SYS_write: ::c_long = 1; +pub const SYS_open: ::c_long = 2; +pub const SYS_close: ::c_long = 3; +pub const SYS_stat: ::c_long = 4; +pub const SYS_fstat: ::c_long = 5; +pub const SYS_lstat: ::c_long = 6; +pub const SYS_poll: ::c_long = 7; +pub const SYS_lseek: ::c_long = 8; +pub const SYS_mmap: ::c_long = 9; +pub const SYS_mprotect: ::c_long = 10; +pub const SYS_munmap: ::c_long = 11; +pub const SYS_brk: ::c_long = 12; +pub const SYS_rt_sigaction: ::c_long = 13; +pub const SYS_rt_sigprocmask: ::c_long = 14; +pub const SYS_rt_sigreturn: ::c_long = 15; +pub const SYS_ioctl: ::c_long = 16; +pub const SYS_pread64: ::c_long = 17; +pub const SYS_pwrite64: ::c_long = 18; +pub const SYS_readv: ::c_long = 19; +pub const SYS_writev: ::c_long = 20; +pub const SYS_access: ::c_long = 21; +pub const SYS_pipe: ::c_long = 22; +pub const SYS_select: ::c_long = 23; +pub const SYS_sched_yield: ::c_long = 24; +pub const SYS_mremap: ::c_long = 25; +pub const SYS_msync: ::c_long = 26; +pub const SYS_mincore: ::c_long = 27; +pub const SYS_madvise: ::c_long = 28; +pub const SYS_shmget: ::c_long = 29; +pub const SYS_shmat: ::c_long = 30; +pub const SYS_shmctl: ::c_long = 31; +pub const SYS_dup: ::c_long = 32; +pub const SYS_dup2: ::c_long = 33; +pub const SYS_pause: ::c_long = 34; +pub const SYS_nanosleep: ::c_long = 35; +pub const SYS_getitimer: ::c_long = 36; +pub const SYS_alarm: ::c_long = 37; +pub const SYS_setitimer: ::c_long = 38; +pub const SYS_getpid: ::c_long = 39; +pub const SYS_sendfile: ::c_long = 40; +pub const SYS_socket: ::c_long = 41; +pub const SYS_connect: ::c_long = 42; +pub const SYS_accept: ::c_long = 43; +pub const SYS_sendto: ::c_long = 44; +pub const SYS_recvfrom: ::c_long = 45; +pub const SYS_sendmsg: ::c_long = 46; +pub const SYS_recvmsg: ::c_long = 47; +pub const SYS_shutdown: ::c_long = 48; +pub const SYS_bind: ::c_long = 49; +pub const SYS_listen: ::c_long = 50; +pub const SYS_getsockname: ::c_long = 51; +pub const SYS_getpeername: ::c_long = 52; +pub const SYS_socketpair: ::c_long = 53; +pub const SYS_setsockopt: ::c_long = 54; +pub const SYS_getsockopt: ::c_long = 55; +pub const SYS_clone: ::c_long = 56; +pub const SYS_fork: ::c_long = 57; +pub const SYS_vfork: ::c_long = 58; +pub const SYS_execve: ::c_long = 59; +pub const SYS_exit: ::c_long = 60; +pub const SYS_wait4: ::c_long = 61; +pub const SYS_kill: ::c_long = 62; +pub const SYS_uname: ::c_long = 63; +pub const SYS_semget: ::c_long = 64; +pub const SYS_semop: ::c_long = 65; +pub const SYS_semctl: ::c_long = 66; +pub const SYS_shmdt: ::c_long = 67; +pub const SYS_msgget: ::c_long = 68; +pub const SYS_msgsnd: ::c_long = 69; +pub const SYS_msgrcv: ::c_long = 70; +pub const SYS_msgctl: ::c_long = 71; +pub const SYS_fcntl: ::c_long = 72; +pub const SYS_flock: ::c_long = 73; +pub const SYS_fsync: ::c_long = 74; +pub const SYS_fdatasync: ::c_long = 75; +pub const SYS_truncate: ::c_long = 76; +pub const SYS_ftruncate: ::c_long = 77; +pub const SYS_getdents: ::c_long = 78; +pub const SYS_getcwd: ::c_long = 79; +pub const SYS_chdir: ::c_long = 80; +pub const SYS_fchdir: ::c_long = 81; +pub const SYS_rename: ::c_long = 82; +pub const SYS_mkdir: ::c_long = 83; +pub const SYS_rmdir: ::c_long = 84; +pub const SYS_creat: ::c_long = 85; +pub const SYS_link: ::c_long = 86; +pub const SYS_unlink: ::c_long = 87; +pub const SYS_symlink: ::c_long = 88; +pub const SYS_readlink: ::c_long = 89; +pub const SYS_chmod: ::c_long = 90; +pub const SYS_fchmod: ::c_long = 91; +pub const SYS_chown: ::c_long = 92; +pub const SYS_fchown: ::c_long = 93; +pub const SYS_lchown: ::c_long = 94; +pub const SYS_umask: ::c_long = 95; +pub const SYS_gettimeofday: ::c_long = 96; +pub const SYS_getrlimit: ::c_long = 97; +pub const SYS_getrusage: ::c_long = 98; +pub const SYS_sysinfo: ::c_long = 99; +pub const SYS_times: ::c_long = 100; +pub const SYS_ptrace: ::c_long = 101; +pub const SYS_getuid: ::c_long = 102; +pub const SYS_syslog: ::c_long = 103; +pub const SYS_getgid: ::c_long = 104; +pub const SYS_setuid: ::c_long = 105; +pub const SYS_setgid: ::c_long = 106; +pub const SYS_geteuid: ::c_long = 107; +pub const SYS_getegid: ::c_long = 108; +pub const SYS_setpgid: ::c_long = 109; +pub const SYS_getppid: ::c_long = 110; +pub const SYS_getpgrp: ::c_long = 111; +pub const SYS_setsid: ::c_long = 112; +pub const SYS_setreuid: ::c_long = 113; +pub const SYS_setregid: ::c_long = 114; +pub const SYS_getgroups: ::c_long = 115; +pub const SYS_setgroups: ::c_long = 116; +pub const SYS_setresuid: ::c_long = 117; +pub const SYS_getresuid: ::c_long = 118; +pub const SYS_setresgid: ::c_long = 119; +pub const SYS_getresgid: ::c_long = 120; +pub const SYS_getpgid: ::c_long = 121; +pub const SYS_setfsuid: ::c_long = 122; +pub const SYS_setfsgid: ::c_long = 123; +pub const SYS_getsid: ::c_long = 124; +pub const SYS_capget: ::c_long = 125; +pub const SYS_capset: ::c_long = 126; +pub const SYS_rt_sigpending: ::c_long = 127; +pub const SYS_rt_sigtimedwait: ::c_long = 128; +pub const SYS_rt_sigqueueinfo: ::c_long = 129; +pub const SYS_rt_sigsuspend: ::c_long = 130; +pub const SYS_sigaltstack: ::c_long = 131; +pub const SYS_utime: ::c_long = 132; +pub const SYS_mknod: ::c_long = 133; +pub const SYS_uselib: ::c_long = 134; +pub const SYS_personality: ::c_long = 135; +pub const SYS_ustat: ::c_long = 136; +pub const SYS_statfs: ::c_long = 137; +pub const SYS_fstatfs: ::c_long = 138; +pub const SYS_sysfs: ::c_long = 139; +pub const SYS_getpriority: ::c_long = 140; +pub const SYS_setpriority: ::c_long = 141; +pub const SYS_sched_setparam: ::c_long = 142; +pub const SYS_sched_getparam: ::c_long = 143; +pub const SYS_sched_setscheduler: ::c_long = 144; +pub const SYS_sched_getscheduler: ::c_long = 145; +pub const SYS_sched_get_priority_max: ::c_long = 146; +pub const SYS_sched_get_priority_min: ::c_long = 147; +pub const SYS_sched_rr_get_interval: ::c_long = 148; +pub const SYS_mlock: ::c_long = 149; +pub const SYS_munlock: ::c_long = 150; +pub const SYS_mlockall: ::c_long = 151; +pub const SYS_munlockall: ::c_long = 152; +pub const SYS_vhangup: ::c_long = 153; +pub const SYS_modify_ldt: ::c_long = 154; +pub const SYS_pivot_root: ::c_long = 155; +pub const SYS__sysctl: ::c_long = 156; +pub const SYS_prctl: ::c_long = 157; +pub const SYS_arch_prctl: ::c_long = 158; +pub const SYS_adjtimex: ::c_long = 159; +pub const SYS_setrlimit: ::c_long = 160; +pub const SYS_chroot: ::c_long = 161; +pub const SYS_sync: ::c_long = 162; +pub const SYS_acct: ::c_long = 163; +pub const SYS_settimeofday: ::c_long = 164; +pub const SYS_mount: ::c_long = 165; +pub const SYS_umount2: ::c_long = 166; +pub const SYS_swapon: ::c_long = 167; +pub const SYS_swapoff: ::c_long = 168; +pub const SYS_reboot: ::c_long = 169; +pub const SYS_sethostname: ::c_long = 170; +pub const SYS_setdomainname: ::c_long = 171; +pub const SYS_iopl: ::c_long = 172; +pub const SYS_ioperm: ::c_long = 173; +pub const SYS_create_module: ::c_long = 174; +pub const SYS_init_module: ::c_long = 175; +pub const SYS_delete_module: ::c_long = 176; +pub const SYS_get_kernel_syms: ::c_long = 177; +pub const SYS_query_module: ::c_long = 178; +pub const SYS_quotactl: ::c_long = 179; +pub const SYS_nfsservctl: ::c_long = 180; +pub const SYS_getpmsg: ::c_long = 181; +pub const SYS_putpmsg: ::c_long = 182; +pub const SYS_afs_syscall: ::c_long = 183; +pub const SYS_tuxcall: ::c_long = 184; +pub const SYS_security: ::c_long = 185; +pub const SYS_gettid: ::c_long = 186; +pub const SYS_readahead: ::c_long = 187; +pub const SYS_setxattr: ::c_long = 188; +pub const SYS_lsetxattr: ::c_long = 189; +pub const SYS_fsetxattr: ::c_long = 190; +pub const SYS_getxattr: ::c_long = 191; +pub const SYS_lgetxattr: ::c_long = 192; +pub const SYS_fgetxattr: ::c_long = 193; +pub const SYS_listxattr: ::c_long = 194; +pub const SYS_llistxattr: ::c_long = 195; +pub const SYS_flistxattr: ::c_long = 196; +pub const SYS_removexattr: ::c_long = 197; +pub const SYS_lremovexattr: ::c_long = 198; +pub const SYS_fremovexattr: ::c_long = 199; +pub const SYS_tkill: ::c_long = 200; +pub const SYS_time: ::c_long = 201; +pub const SYS_futex: ::c_long = 202; +pub const SYS_sched_setaffinity: ::c_long = 203; +pub const SYS_sched_getaffinity: ::c_long = 204; +pub const SYS_set_thread_area: ::c_long = 205; +pub const SYS_io_setup: ::c_long = 206; +pub const SYS_io_destroy: ::c_long = 207; +pub const SYS_io_getevents: ::c_long = 208; +pub const SYS_io_submit: ::c_long = 209; +pub const SYS_io_cancel: ::c_long = 210; +pub const SYS_get_thread_area: ::c_long = 211; +pub const SYS_lookup_dcookie: ::c_long = 212; +pub const SYS_epoll_create: ::c_long = 213; +pub const SYS_epoll_ctl_old: ::c_long = 214; +pub const SYS_epoll_wait_old: ::c_long = 215; +pub const SYS_remap_file_pages: ::c_long = 216; +pub const SYS_getdents64: ::c_long = 217; +pub const SYS_set_tid_address: ::c_long = 218; +pub const SYS_restart_syscall: ::c_long = 219; +pub const SYS_semtimedop: ::c_long = 220; +pub const SYS_fadvise64: ::c_long = 221; +pub const SYS_timer_create: ::c_long = 222; +pub const SYS_timer_settime: ::c_long = 223; +pub const SYS_timer_gettime: ::c_long = 224; +pub const SYS_timer_getoverrun: ::c_long = 225; +pub const SYS_timer_delete: ::c_long = 226; +pub const SYS_clock_settime: ::c_long = 227; +pub const SYS_clock_gettime: ::c_long = 228; +pub const SYS_clock_getres: ::c_long = 229; +pub const SYS_clock_nanosleep: ::c_long = 230; +pub const SYS_exit_group: ::c_long = 231; +pub const SYS_epoll_wait: ::c_long = 232; +pub const SYS_epoll_ctl: ::c_long = 233; +pub const SYS_tgkill: ::c_long = 234; +pub const SYS_utimes: ::c_long = 235; +pub const SYS_vserver: ::c_long = 236; +pub const SYS_mbind: ::c_long = 237; +pub const SYS_set_mempolicy: ::c_long = 238; +pub const SYS_get_mempolicy: ::c_long = 239; +pub const SYS_mq_open: ::c_long = 240; +pub const SYS_mq_unlink: ::c_long = 241; +pub const SYS_mq_timedsend: ::c_long = 242; +pub const SYS_mq_timedreceive: ::c_long = 243; +pub const SYS_mq_notify: ::c_long = 244; +pub const SYS_mq_getsetattr: ::c_long = 245; +pub const SYS_kexec_load: ::c_long = 246; +pub const SYS_waitid: ::c_long = 247; +pub const SYS_add_key: ::c_long = 248; +pub const SYS_request_key: ::c_long = 249; +pub const SYS_keyctl: ::c_long = 250; +pub const SYS_ioprio_set: ::c_long = 251; +pub const SYS_ioprio_get: ::c_long = 252; +pub const SYS_inotify_init: ::c_long = 253; +pub const SYS_inotify_add_watch: ::c_long = 254; +pub const SYS_inotify_rm_watch: ::c_long = 255; +pub const SYS_migrate_pages: ::c_long = 256; +pub const SYS_openat: ::c_long = 257; +pub const SYS_mkdirat: ::c_long = 258; +pub const SYS_mknodat: ::c_long = 259; +pub const SYS_fchownat: ::c_long = 260; +pub const SYS_futimesat: ::c_long = 261; +pub const SYS_newfstatat: ::c_long = 262; +pub const SYS_unlinkat: ::c_long = 263; +pub const SYS_renameat: ::c_long = 264; +pub const SYS_linkat: ::c_long = 265; +pub const SYS_symlinkat: ::c_long = 266; +pub const SYS_readlinkat: ::c_long = 267; +pub const SYS_fchmodat: ::c_long = 268; +pub const SYS_faccessat: ::c_long = 269; +pub const SYS_pselect6: ::c_long = 270; +pub const SYS_ppoll: ::c_long = 271; +pub const SYS_unshare: ::c_long = 272; +pub const SYS_set_robust_list: ::c_long = 273; +pub const SYS_get_robust_list: ::c_long = 274; +pub const SYS_splice: ::c_long = 275; +pub const SYS_tee: ::c_long = 276; +pub const SYS_sync_file_range: ::c_long = 277; +pub const SYS_vmsplice: ::c_long = 278; +pub const SYS_move_pages: ::c_long = 279; +pub const SYS_utimensat: ::c_long = 280; +pub const SYS_epoll_pwait: ::c_long = 281; +pub const SYS_signalfd: ::c_long = 282; +pub const SYS_timerfd_create: ::c_long = 283; +pub const SYS_eventfd: ::c_long = 284; +pub const SYS_fallocate: ::c_long = 285; +pub const SYS_timerfd_settime: ::c_long = 286; +pub const SYS_timerfd_gettime: ::c_long = 287; +pub const SYS_accept4: ::c_long = 288; +pub const SYS_signalfd4: ::c_long = 289; +pub const SYS_eventfd2: ::c_long = 290; +pub const SYS_epoll_create1: ::c_long = 291; +pub const SYS_dup3: ::c_long = 292; +pub const SYS_pipe2: ::c_long = 293; +pub const SYS_inotify_init1: ::c_long = 294; +pub const SYS_preadv: ::c_long = 295; +pub const SYS_pwritev: ::c_long = 296; +pub const SYS_rt_tgsigqueueinfo: ::c_long = 297; +pub const SYS_perf_event_open: ::c_long = 298; +pub const SYS_recvmmsg: ::c_long = 299; +pub const SYS_fanotify_init: ::c_long = 300; +pub const SYS_fanotify_mark: ::c_long = 301; +pub const SYS_prlimit64: ::c_long = 302; +pub const SYS_name_to_handle_at: ::c_long = 303; +pub const SYS_open_by_handle_at: ::c_long = 304; +pub const SYS_clock_adjtime: ::c_long = 305; +pub const SYS_syncfs: ::c_long = 306; +pub const SYS_sendmmsg: ::c_long = 307; +pub const SYS_setns: ::c_long = 308; +pub const SYS_getcpu: ::c_long = 309; +pub const SYS_process_vm_readv: ::c_long = 310; +pub const SYS_process_vm_writev: ::c_long = 311; +pub const SYS_kcmp: ::c_long = 312; +pub const SYS_finit_module: ::c_long = 313; +pub const SYS_sched_setattr: ::c_long = 314; +pub const SYS_sched_getattr: ::c_long = 315; +pub const SYS_renameat2: ::c_long = 316; +pub const SYS_seccomp: ::c_long = 317; +pub const SYS_getrandom: ::c_long = 318; +pub const SYS_memfd_create: ::c_long = 319; +pub const SYS_kexec_file_load: ::c_long = 320; +pub const SYS_bpf: ::c_long = 321; +pub const SYS_execveat: ::c_long = 322; +pub const SYS_userfaultfd: ::c_long = 323; +pub const SYS_membarrier: ::c_long = 324; +pub const SYS_mlock2: ::c_long = 325; +pub const SYS_copy_file_range: ::c_long = 326; +pub const SYS_preadv2: ::c_long = 327; +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_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; +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; +pub const SYS_fchmodat2: ::c_long = 452; +pub const SYS_mseal: ::c_long = 462; + +extern "C" { + pub fn sysctl( + name: *mut ::c_int, + namelen: ::c_int, + oldp: *mut ::c_void, + oldlenp: *mut ::size_t, + newp: *mut ::c_void, + newlen: ::size_t, + ) -> ::c_int; +} 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 new file mode 100644 index 0000000..90745b1 --- /dev/null +++ b/vendor/libc/src/unix/linux_like/linux/gnu/b64/x86_64/x32.rs @@ -0,0 +1,405 @@ +use pthread_mutex_t; + +pub type c_long = i32; +pub type c_ulong = u32; + +s! { + 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 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 = + 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, + ], + }; + 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, + ], + }; + 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, + ], + }; +} + +// Syscall table + +pub const __X32_SYSCALL_BIT: ::c_long = 0x40000000; + +pub const SYS_read: ::c_long = __X32_SYSCALL_BIT + 0; +pub const SYS_write: ::c_long = __X32_SYSCALL_BIT + 1; +pub const SYS_open: ::c_long = __X32_SYSCALL_BIT + 2; +pub const SYS_close: ::c_long = __X32_SYSCALL_BIT + 3; +pub const SYS_stat: ::c_long = __X32_SYSCALL_BIT + 4; +pub const SYS_fstat: ::c_long = __X32_SYSCALL_BIT + 5; +pub const SYS_lstat: ::c_long = __X32_SYSCALL_BIT + 6; +pub const SYS_poll: ::c_long = __X32_SYSCALL_BIT + 7; +pub const SYS_lseek: ::c_long = __X32_SYSCALL_BIT + 8; +pub const SYS_mmap: ::c_long = __X32_SYSCALL_BIT + 9; +pub const SYS_mprotect: ::c_long = __X32_SYSCALL_BIT + 10; +pub const SYS_munmap: ::c_long = __X32_SYSCALL_BIT + 11; +pub const SYS_brk: ::c_long = __X32_SYSCALL_BIT + 12; +pub const SYS_rt_sigprocmask: ::c_long = __X32_SYSCALL_BIT + 14; +pub const SYS_pread64: ::c_long = __X32_SYSCALL_BIT + 17; +pub const SYS_pwrite64: ::c_long = __X32_SYSCALL_BIT + 18; +pub const SYS_access: ::c_long = __X32_SYSCALL_BIT + 21; +pub const SYS_pipe: ::c_long = __X32_SYSCALL_BIT + 22; +pub const SYS_select: ::c_long = __X32_SYSCALL_BIT + 23; +pub const SYS_sched_yield: ::c_long = __X32_SYSCALL_BIT + 24; +pub const SYS_mremap: ::c_long = __X32_SYSCALL_BIT + 25; +pub const SYS_msync: ::c_long = __X32_SYSCALL_BIT + 26; +pub const SYS_mincore: ::c_long = __X32_SYSCALL_BIT + 27; +pub const SYS_madvise: ::c_long = __X32_SYSCALL_BIT + 28; +pub const SYS_shmget: ::c_long = __X32_SYSCALL_BIT + 29; +pub const SYS_shmat: ::c_long = __X32_SYSCALL_BIT + 30; +pub const SYS_shmctl: ::c_long = __X32_SYSCALL_BIT + 31; +pub const SYS_dup: ::c_long = __X32_SYSCALL_BIT + 32; +pub const SYS_dup2: ::c_long = __X32_SYSCALL_BIT + 33; +pub const SYS_pause: ::c_long = __X32_SYSCALL_BIT + 34; +pub const SYS_nanosleep: ::c_long = __X32_SYSCALL_BIT + 35; +pub const SYS_getitimer: ::c_long = __X32_SYSCALL_BIT + 36; +pub const SYS_alarm: ::c_long = __X32_SYSCALL_BIT + 37; +pub const SYS_setitimer: ::c_long = __X32_SYSCALL_BIT + 38; +pub const SYS_getpid: ::c_long = __X32_SYSCALL_BIT + 39; +pub const SYS_sendfile: ::c_long = __X32_SYSCALL_BIT + 40; +pub const SYS_socket: ::c_long = __X32_SYSCALL_BIT + 41; +pub const SYS_connect: ::c_long = __X32_SYSCALL_BIT + 42; +pub const SYS_accept: ::c_long = __X32_SYSCALL_BIT + 43; +pub const SYS_sendto: ::c_long = __X32_SYSCALL_BIT + 44; +pub const SYS_shutdown: ::c_long = __X32_SYSCALL_BIT + 48; +pub const SYS_bind: ::c_long = __X32_SYSCALL_BIT + 49; +pub const SYS_listen: ::c_long = __X32_SYSCALL_BIT + 50; +pub const SYS_getsockname: ::c_long = __X32_SYSCALL_BIT + 51; +pub const SYS_getpeername: ::c_long = __X32_SYSCALL_BIT + 52; +pub const SYS_socketpair: ::c_long = __X32_SYSCALL_BIT + 53; +pub const SYS_clone: ::c_long = __X32_SYSCALL_BIT + 56; +pub const SYS_fork: ::c_long = __X32_SYSCALL_BIT + 57; +pub const SYS_vfork: ::c_long = __X32_SYSCALL_BIT + 58; +pub const SYS_exit: ::c_long = __X32_SYSCALL_BIT + 60; +pub const SYS_wait4: ::c_long = __X32_SYSCALL_BIT + 61; +pub const SYS_kill: ::c_long = __X32_SYSCALL_BIT + 62; +pub const SYS_uname: ::c_long = __X32_SYSCALL_BIT + 63; +pub const SYS_semget: ::c_long = __X32_SYSCALL_BIT + 64; +pub const SYS_semop: ::c_long = __X32_SYSCALL_BIT + 65; +pub const SYS_semctl: ::c_long = __X32_SYSCALL_BIT + 66; +pub const SYS_shmdt: ::c_long = __X32_SYSCALL_BIT + 67; +pub const SYS_msgget: ::c_long = __X32_SYSCALL_BIT + 68; +pub const SYS_msgsnd: ::c_long = __X32_SYSCALL_BIT + 69; +pub const SYS_msgrcv: ::c_long = __X32_SYSCALL_BIT + 70; +pub const SYS_msgctl: ::c_long = __X32_SYSCALL_BIT + 71; +pub const SYS_fcntl: ::c_long = __X32_SYSCALL_BIT + 72; +pub const SYS_flock: ::c_long = __X32_SYSCALL_BIT + 73; +pub const SYS_fsync: ::c_long = __X32_SYSCALL_BIT + 74; +pub const SYS_fdatasync: ::c_long = __X32_SYSCALL_BIT + 75; +pub const SYS_truncate: ::c_long = __X32_SYSCALL_BIT + 76; +pub const SYS_ftruncate: ::c_long = __X32_SYSCALL_BIT + 77; +pub const SYS_getdents: ::c_long = __X32_SYSCALL_BIT + 78; +pub const SYS_getcwd: ::c_long = __X32_SYSCALL_BIT + 79; +pub const SYS_chdir: ::c_long = __X32_SYSCALL_BIT + 80; +pub const SYS_fchdir: ::c_long = __X32_SYSCALL_BIT + 81; +pub const SYS_rename: ::c_long = __X32_SYSCALL_BIT + 82; +pub const SYS_mkdir: ::c_long = __X32_SYSCALL_BIT + 83; +pub const SYS_rmdir: ::c_long = __X32_SYSCALL_BIT + 84; +pub const SYS_creat: ::c_long = __X32_SYSCALL_BIT + 85; +pub const SYS_link: ::c_long = __X32_SYSCALL_BIT + 86; +pub const SYS_unlink: ::c_long = __X32_SYSCALL_BIT + 87; +pub const SYS_symlink: ::c_long = __X32_SYSCALL_BIT + 88; +pub const SYS_readlink: ::c_long = __X32_SYSCALL_BIT + 89; +pub const SYS_chmod: ::c_long = __X32_SYSCALL_BIT + 90; +pub const SYS_fchmod: ::c_long = __X32_SYSCALL_BIT + 91; +pub const SYS_chown: ::c_long = __X32_SYSCALL_BIT + 92; +pub const SYS_fchown: ::c_long = __X32_SYSCALL_BIT + 93; +pub const SYS_lchown: ::c_long = __X32_SYSCALL_BIT + 94; +pub const SYS_umask: ::c_long = __X32_SYSCALL_BIT + 95; +pub const SYS_gettimeofday: ::c_long = __X32_SYSCALL_BIT + 96; +pub const SYS_getrlimit: ::c_long = __X32_SYSCALL_BIT + 97; +pub const SYS_getrusage: ::c_long = __X32_SYSCALL_BIT + 98; +pub const SYS_sysinfo: ::c_long = __X32_SYSCALL_BIT + 99; +pub const SYS_times: ::c_long = __X32_SYSCALL_BIT + 100; +pub const SYS_getuid: ::c_long = __X32_SYSCALL_BIT + 102; +pub const SYS_syslog: ::c_long = __X32_SYSCALL_BIT + 103; +pub const SYS_getgid: ::c_long = __X32_SYSCALL_BIT + 104; +pub const SYS_setuid: ::c_long = __X32_SYSCALL_BIT + 105; +pub const SYS_setgid: ::c_long = __X32_SYSCALL_BIT + 106; +pub const SYS_geteuid: ::c_long = __X32_SYSCALL_BIT + 107; +pub const SYS_getegid: ::c_long = __X32_SYSCALL_BIT + 108; +pub const SYS_setpgid: ::c_long = __X32_SYSCALL_BIT + 109; +pub const SYS_getppid: ::c_long = __X32_SYSCALL_BIT + 110; +pub const SYS_getpgrp: ::c_long = __X32_SYSCALL_BIT + 111; +pub const SYS_setsid: ::c_long = __X32_SYSCALL_BIT + 112; +pub const SYS_setreuid: ::c_long = __X32_SYSCALL_BIT + 113; +pub const SYS_setregid: ::c_long = __X32_SYSCALL_BIT + 114; +pub const SYS_getgroups: ::c_long = __X32_SYSCALL_BIT + 115; +pub const SYS_setgroups: ::c_long = __X32_SYSCALL_BIT + 116; +pub const SYS_setresuid: ::c_long = __X32_SYSCALL_BIT + 117; +pub const SYS_getresuid: ::c_long = __X32_SYSCALL_BIT + 118; +pub const SYS_setresgid: ::c_long = __X32_SYSCALL_BIT + 119; +pub const SYS_getresgid: ::c_long = __X32_SYSCALL_BIT + 120; +pub const SYS_getpgid: ::c_long = __X32_SYSCALL_BIT + 121; +pub const SYS_setfsuid: ::c_long = __X32_SYSCALL_BIT + 122; +pub const SYS_setfsgid: ::c_long = __X32_SYSCALL_BIT + 123; +pub const SYS_getsid: ::c_long = __X32_SYSCALL_BIT + 124; +pub const SYS_capget: ::c_long = __X32_SYSCALL_BIT + 125; +pub const SYS_capset: ::c_long = __X32_SYSCALL_BIT + 126; +pub const SYS_rt_sigsuspend: ::c_long = __X32_SYSCALL_BIT + 130; +pub const SYS_utime: ::c_long = __X32_SYSCALL_BIT + 132; +pub const SYS_mknod: ::c_long = __X32_SYSCALL_BIT + 133; +pub const SYS_personality: ::c_long = __X32_SYSCALL_BIT + 135; +pub const SYS_ustat: ::c_long = __X32_SYSCALL_BIT + 136; +pub const SYS_statfs: ::c_long = __X32_SYSCALL_BIT + 137; +pub const SYS_fstatfs: ::c_long = __X32_SYSCALL_BIT + 138; +pub const SYS_sysfs: ::c_long = __X32_SYSCALL_BIT + 139; +pub const SYS_getpriority: ::c_long = __X32_SYSCALL_BIT + 140; +pub const SYS_setpriority: ::c_long = __X32_SYSCALL_BIT + 141; +pub const SYS_sched_setparam: ::c_long = __X32_SYSCALL_BIT + 142; +pub const SYS_sched_getparam: ::c_long = __X32_SYSCALL_BIT + 143; +pub const SYS_sched_setscheduler: ::c_long = __X32_SYSCALL_BIT + 144; +pub const SYS_sched_getscheduler: ::c_long = __X32_SYSCALL_BIT + 145; +pub const SYS_sched_get_priority_max: ::c_long = __X32_SYSCALL_BIT + 146; +pub const SYS_sched_get_priority_min: ::c_long = __X32_SYSCALL_BIT + 147; +pub const SYS_sched_rr_get_interval: ::c_long = __X32_SYSCALL_BIT + 148; +pub const SYS_mlock: ::c_long = __X32_SYSCALL_BIT + 149; +pub const SYS_munlock: ::c_long = __X32_SYSCALL_BIT + 150; +pub const SYS_mlockall: ::c_long = __X32_SYSCALL_BIT + 151; +pub const SYS_munlockall: ::c_long = __X32_SYSCALL_BIT + 152; +pub const SYS_vhangup: ::c_long = __X32_SYSCALL_BIT + 153; +pub const SYS_modify_ldt: ::c_long = __X32_SYSCALL_BIT + 154; +pub const SYS_pivot_root: ::c_long = __X32_SYSCALL_BIT + 155; +pub const SYS_prctl: ::c_long = __X32_SYSCALL_BIT + 157; +pub const SYS_arch_prctl: ::c_long = __X32_SYSCALL_BIT + 158; +pub const SYS_adjtimex: ::c_long = __X32_SYSCALL_BIT + 159; +pub const SYS_setrlimit: ::c_long = __X32_SYSCALL_BIT + 160; +pub const SYS_chroot: ::c_long = __X32_SYSCALL_BIT + 161; +pub const SYS_sync: ::c_long = __X32_SYSCALL_BIT + 162; +pub const SYS_acct: ::c_long = __X32_SYSCALL_BIT + 163; +pub const SYS_settimeofday: ::c_long = __X32_SYSCALL_BIT + 164; +pub const SYS_mount: ::c_long = __X32_SYSCALL_BIT + 165; +pub const SYS_umount2: ::c_long = __X32_SYSCALL_BIT + 166; +pub const SYS_swapon: ::c_long = __X32_SYSCALL_BIT + 167; +pub const SYS_swapoff: ::c_long = __X32_SYSCALL_BIT + 168; +pub const SYS_reboot: ::c_long = __X32_SYSCALL_BIT + 169; +pub const SYS_sethostname: ::c_long = __X32_SYSCALL_BIT + 170; +pub const SYS_setdomainname: ::c_long = __X32_SYSCALL_BIT + 171; +pub const SYS_iopl: ::c_long = __X32_SYSCALL_BIT + 172; +pub const SYS_ioperm: ::c_long = __X32_SYSCALL_BIT + 173; +pub const SYS_init_module: ::c_long = __X32_SYSCALL_BIT + 175; +pub const SYS_delete_module: ::c_long = __X32_SYSCALL_BIT + 176; +pub const SYS_quotactl: ::c_long = __X32_SYSCALL_BIT + 179; +pub const SYS_getpmsg: ::c_long = __X32_SYSCALL_BIT + 181; +pub const SYS_putpmsg: ::c_long = __X32_SYSCALL_BIT + 182; +pub const SYS_afs_syscall: ::c_long = __X32_SYSCALL_BIT + 183; +pub const SYS_tuxcall: ::c_long = __X32_SYSCALL_BIT + 184; +pub const SYS_security: ::c_long = __X32_SYSCALL_BIT + 185; +pub const SYS_gettid: ::c_long = __X32_SYSCALL_BIT + 186; +pub const SYS_readahead: ::c_long = __X32_SYSCALL_BIT + 187; +pub const SYS_setxattr: ::c_long = __X32_SYSCALL_BIT + 188; +pub const SYS_lsetxattr: ::c_long = __X32_SYSCALL_BIT + 189; +pub const SYS_fsetxattr: ::c_long = __X32_SYSCALL_BIT + 190; +pub const SYS_getxattr: ::c_long = __X32_SYSCALL_BIT + 191; +pub const SYS_lgetxattr: ::c_long = __X32_SYSCALL_BIT + 192; +pub const SYS_fgetxattr: ::c_long = __X32_SYSCALL_BIT + 193; +pub const SYS_listxattr: ::c_long = __X32_SYSCALL_BIT + 194; +pub const SYS_llistxattr: ::c_long = __X32_SYSCALL_BIT + 195; +pub const SYS_flistxattr: ::c_long = __X32_SYSCALL_BIT + 196; +pub const SYS_removexattr: ::c_long = __X32_SYSCALL_BIT + 197; +pub const SYS_lremovexattr: ::c_long = __X32_SYSCALL_BIT + 198; +pub const SYS_fremovexattr: ::c_long = __X32_SYSCALL_BIT + 199; +pub const SYS_tkill: ::c_long = __X32_SYSCALL_BIT + 200; +pub const SYS_time: ::c_long = __X32_SYSCALL_BIT + 201; +pub const SYS_futex: ::c_long = __X32_SYSCALL_BIT + 202; +pub const SYS_sched_setaffinity: ::c_long = __X32_SYSCALL_BIT + 203; +pub const SYS_sched_getaffinity: ::c_long = __X32_SYSCALL_BIT + 204; +pub const SYS_io_destroy: ::c_long = __X32_SYSCALL_BIT + 207; +pub const SYS_io_getevents: ::c_long = __X32_SYSCALL_BIT + 208; +pub const SYS_io_cancel: ::c_long = __X32_SYSCALL_BIT + 210; +pub const SYS_lookup_dcookie: ::c_long = __X32_SYSCALL_BIT + 212; +pub const SYS_epoll_create: ::c_long = __X32_SYSCALL_BIT + 213; +pub const SYS_remap_file_pages: ::c_long = __X32_SYSCALL_BIT + 216; +pub const SYS_getdents64: ::c_long = __X32_SYSCALL_BIT + 217; +pub const SYS_set_tid_address: ::c_long = __X32_SYSCALL_BIT + 218; +pub const SYS_restart_syscall: ::c_long = __X32_SYSCALL_BIT + 219; +pub const SYS_semtimedop: ::c_long = __X32_SYSCALL_BIT + 220; +pub const SYS_fadvise64: ::c_long = __X32_SYSCALL_BIT + 221; +pub const SYS_timer_settime: ::c_long = __X32_SYSCALL_BIT + 223; +pub const SYS_timer_gettime: ::c_long = __X32_SYSCALL_BIT + 224; +pub const SYS_timer_getoverrun: ::c_long = __X32_SYSCALL_BIT + 225; +pub const SYS_timer_delete: ::c_long = __X32_SYSCALL_BIT + 226; +pub const SYS_clock_settime: ::c_long = __X32_SYSCALL_BIT + 227; +pub const SYS_clock_gettime: ::c_long = __X32_SYSCALL_BIT + 228; +pub const SYS_clock_getres: ::c_long = __X32_SYSCALL_BIT + 229; +pub const SYS_clock_nanosleep: ::c_long = __X32_SYSCALL_BIT + 230; +pub const SYS_exit_group: ::c_long = __X32_SYSCALL_BIT + 231; +pub const SYS_epoll_wait: ::c_long = __X32_SYSCALL_BIT + 232; +pub const SYS_epoll_ctl: ::c_long = __X32_SYSCALL_BIT + 233; +pub const SYS_tgkill: ::c_long = __X32_SYSCALL_BIT + 234; +pub const SYS_utimes: ::c_long = __X32_SYSCALL_BIT + 235; +pub const SYS_mbind: ::c_long = __X32_SYSCALL_BIT + 237; +pub const SYS_set_mempolicy: ::c_long = __X32_SYSCALL_BIT + 238; +pub const SYS_get_mempolicy: ::c_long = __X32_SYSCALL_BIT + 239; +pub const SYS_mq_open: ::c_long = __X32_SYSCALL_BIT + 240; +pub const SYS_mq_unlink: ::c_long = __X32_SYSCALL_BIT + 241; +pub const SYS_mq_timedsend: ::c_long = __X32_SYSCALL_BIT + 242; +pub const SYS_mq_timedreceive: ::c_long = __X32_SYSCALL_BIT + 243; +pub const SYS_mq_getsetattr: ::c_long = __X32_SYSCALL_BIT + 245; +pub const SYS_add_key: ::c_long = __X32_SYSCALL_BIT + 248; +pub const SYS_request_key: ::c_long = __X32_SYSCALL_BIT + 249; +pub const SYS_keyctl: ::c_long = __X32_SYSCALL_BIT + 250; +pub const SYS_ioprio_set: ::c_long = __X32_SYSCALL_BIT + 251; +pub const SYS_ioprio_get: ::c_long = __X32_SYSCALL_BIT + 252; +pub const SYS_inotify_init: ::c_long = __X32_SYSCALL_BIT + 253; +pub const SYS_inotify_add_watch: ::c_long = __X32_SYSCALL_BIT + 254; +pub const SYS_inotify_rm_watch: ::c_long = __X32_SYSCALL_BIT + 255; +pub const SYS_migrate_pages: ::c_long = __X32_SYSCALL_BIT + 256; +pub const SYS_openat: ::c_long = __X32_SYSCALL_BIT + 257; +pub const SYS_mkdirat: ::c_long = __X32_SYSCALL_BIT + 258; +pub const SYS_mknodat: ::c_long = __X32_SYSCALL_BIT + 259; +pub const SYS_fchownat: ::c_long = __X32_SYSCALL_BIT + 260; +pub const SYS_futimesat: ::c_long = __X32_SYSCALL_BIT + 261; +pub const SYS_newfstatat: ::c_long = __X32_SYSCALL_BIT + 262; +pub const SYS_unlinkat: ::c_long = __X32_SYSCALL_BIT + 263; +pub const SYS_renameat: ::c_long = __X32_SYSCALL_BIT + 264; +pub const SYS_linkat: ::c_long = __X32_SYSCALL_BIT + 265; +pub const SYS_symlinkat: ::c_long = __X32_SYSCALL_BIT + 266; +pub const SYS_readlinkat: ::c_long = __X32_SYSCALL_BIT + 267; +pub const SYS_fchmodat: ::c_long = __X32_SYSCALL_BIT + 268; +pub const SYS_faccessat: ::c_long = __X32_SYSCALL_BIT + 269; +pub const SYS_pselect6: ::c_long = __X32_SYSCALL_BIT + 270; +pub const SYS_ppoll: ::c_long = __X32_SYSCALL_BIT + 271; +pub const SYS_unshare: ::c_long = __X32_SYSCALL_BIT + 272; +pub const SYS_splice: ::c_long = __X32_SYSCALL_BIT + 275; +pub const SYS_tee: ::c_long = __X32_SYSCALL_BIT + 276; +pub const SYS_sync_file_range: ::c_long = __X32_SYSCALL_BIT + 277; +pub const SYS_utimensat: ::c_long = __X32_SYSCALL_BIT + 280; +pub const SYS_epoll_pwait: ::c_long = __X32_SYSCALL_BIT + 281; +pub const SYS_signalfd: ::c_long = __X32_SYSCALL_BIT + 282; +pub const SYS_timerfd_create: ::c_long = __X32_SYSCALL_BIT + 283; +pub const SYS_eventfd: ::c_long = __X32_SYSCALL_BIT + 284; +pub const SYS_fallocate: ::c_long = __X32_SYSCALL_BIT + 285; +pub const SYS_timerfd_settime: ::c_long = __X32_SYSCALL_BIT + 286; +pub const SYS_timerfd_gettime: ::c_long = __X32_SYSCALL_BIT + 287; +pub const SYS_accept4: ::c_long = __X32_SYSCALL_BIT + 288; +pub const SYS_signalfd4: ::c_long = __X32_SYSCALL_BIT + 289; +pub const SYS_eventfd2: ::c_long = __X32_SYSCALL_BIT + 290; +pub const SYS_epoll_create1: ::c_long = __X32_SYSCALL_BIT + 291; +pub const SYS_dup3: ::c_long = __X32_SYSCALL_BIT + 292; +pub const SYS_pipe2: ::c_long = __X32_SYSCALL_BIT + 293; +pub const SYS_inotify_init1: ::c_long = __X32_SYSCALL_BIT + 294; +pub const SYS_perf_event_open: ::c_long = __X32_SYSCALL_BIT + 298; +pub const SYS_fanotify_init: ::c_long = __X32_SYSCALL_BIT + 300; +pub const SYS_fanotify_mark: ::c_long = __X32_SYSCALL_BIT + 301; +pub const SYS_prlimit64: ::c_long = __X32_SYSCALL_BIT + 302; +pub const SYS_name_to_handle_at: ::c_long = __X32_SYSCALL_BIT + 303; +pub const SYS_open_by_handle_at: ::c_long = __X32_SYSCALL_BIT + 304; +pub const SYS_clock_adjtime: ::c_long = __X32_SYSCALL_BIT + 305; +pub const SYS_syncfs: ::c_long = __X32_SYSCALL_BIT + 306; +pub const SYS_setns: ::c_long = __X32_SYSCALL_BIT + 308; +pub const SYS_getcpu: ::c_long = __X32_SYSCALL_BIT + 309; +pub const SYS_kcmp: ::c_long = __X32_SYSCALL_BIT + 312; +pub const SYS_finit_module: ::c_long = __X32_SYSCALL_BIT + 313; +pub const SYS_sched_setattr: ::c_long = __X32_SYSCALL_BIT + 314; +pub const SYS_sched_getattr: ::c_long = __X32_SYSCALL_BIT + 315; +pub const SYS_renameat2: ::c_long = __X32_SYSCALL_BIT + 316; +pub const SYS_seccomp: ::c_long = __X32_SYSCALL_BIT + 317; +pub const SYS_getrandom: ::c_long = __X32_SYSCALL_BIT + 318; +pub const SYS_memfd_create: ::c_long = __X32_SYSCALL_BIT + 319; +pub const SYS_kexec_file_load: ::c_long = __X32_SYSCALL_BIT + 320; +pub const SYS_bpf: ::c_long = __X32_SYSCALL_BIT + 321; +pub const SYS_userfaultfd: ::c_long = __X32_SYSCALL_BIT + 323; +pub const SYS_membarrier: ::c_long = __X32_SYSCALL_BIT + 324; +pub const SYS_mlock2: ::c_long = __X32_SYSCALL_BIT + 325; +pub const SYS_copy_file_range: ::c_long = __X32_SYSCALL_BIT + 326; +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; +pub const SYS_io_uring_register: ::c_long = __X32_SYSCALL_BIT + 427; +pub const SYS_open_tree: ::c_long = __X32_SYSCALL_BIT + 428; +pub const SYS_move_mount: ::c_long = __X32_SYSCALL_BIT + 429; +pub const SYS_fsopen: ::c_long = __X32_SYSCALL_BIT + 430; +pub const SYS_fsconfig: ::c_long = __X32_SYSCALL_BIT + 431; +pub const SYS_fsmount: ::c_long = __X32_SYSCALL_BIT + 432; +pub const SYS_fspick: ::c_long = __X32_SYSCALL_BIT + 433; +pub const SYS_pidfd_open: ::c_long = __X32_SYSCALL_BIT + 434; +pub const SYS_clone3: ::c_long = __X32_SYSCALL_BIT + 435; +pub const SYS_close_range: ::c_long = __X32_SYSCALL_BIT + 436; +pub const SYS_openat2: ::c_long = __X32_SYSCALL_BIT + 437; +pub const SYS_pidfd_getfd: ::c_long = __X32_SYSCALL_BIT + 438; +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_fchmodat2: ::c_long = __X32_SYSCALL_BIT + 452; +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; +pub const SYS_readv: ::c_long = __X32_SYSCALL_BIT + 515; +pub const SYS_writev: ::c_long = __X32_SYSCALL_BIT + 516; +pub const SYS_recvfrom: ::c_long = __X32_SYSCALL_BIT + 517; +pub const SYS_sendmsg: ::c_long = __X32_SYSCALL_BIT + 518; +pub const SYS_recvmsg: ::c_long = __X32_SYSCALL_BIT + 519; +pub const SYS_execve: ::c_long = __X32_SYSCALL_BIT + 520; +pub const SYS_ptrace: ::c_long = __X32_SYSCALL_BIT + 521; +pub const SYS_rt_sigpending: ::c_long = __X32_SYSCALL_BIT + 522; +pub const SYS_rt_sigtimedwait: ::c_long = __X32_SYSCALL_BIT + 523; +pub const SYS_rt_sigqueueinfo: ::c_long = __X32_SYSCALL_BIT + 524; +pub const SYS_sigaltstack: ::c_long = __X32_SYSCALL_BIT + 525; +pub const SYS_timer_create: ::c_long = __X32_SYSCALL_BIT + 526; +pub const SYS_mq_notify: ::c_long = __X32_SYSCALL_BIT + 527; +pub const SYS_kexec_load: ::c_long = __X32_SYSCALL_BIT + 528; +pub const SYS_waitid: ::c_long = __X32_SYSCALL_BIT + 529; +pub const SYS_set_robust_list: ::c_long = __X32_SYSCALL_BIT + 530; +pub const SYS_get_robust_list: ::c_long = __X32_SYSCALL_BIT + 531; +pub const SYS_vmsplice: ::c_long = __X32_SYSCALL_BIT + 532; +pub const SYS_move_pages: ::c_long = __X32_SYSCALL_BIT + 533; +pub const SYS_preadv: ::c_long = __X32_SYSCALL_BIT + 534; +pub const SYS_pwritev: ::c_long = __X32_SYSCALL_BIT + 535; +pub const SYS_rt_tgsigqueueinfo: ::c_long = __X32_SYSCALL_BIT + 536; +pub const SYS_recvmmsg: ::c_long = __X32_SYSCALL_BIT + 537; +pub const SYS_sendmmsg: ::c_long = __X32_SYSCALL_BIT + 538; +pub const SYS_process_vm_readv: ::c_long = __X32_SYSCALL_BIT + 539; +pub const SYS_process_vm_writev: ::c_long = __X32_SYSCALL_BIT + 540; +pub const SYS_setsockopt: ::c_long = __X32_SYSCALL_BIT + 541; +pub const SYS_getsockopt: ::c_long = __X32_SYSCALL_BIT + 542; +pub const SYS_io_setup: ::c_long = __X32_SYSCALL_BIT + 543; +pub const SYS_io_submit: ::c_long = __X32_SYSCALL_BIT + 544; +pub const SYS_execveat: ::c_long = __X32_SYSCALL_BIT + 545; +pub const SYS_preadv2: ::c_long = __X32_SYSCALL_BIT + 546; +pub const SYS_pwritev2: ::c_long = __X32_SYSCALL_BIT + 547; diff --git a/vendor/libc/src/unix/linux_like/linux/gnu/mod.rs b/vendor/libc/src/unix/linux_like/linux/gnu/mod.rs new file mode 100644 index 0000000..b28c33f --- /dev/null +++ b/vendor/libc/src/unix/linux_like/linux/gnu/mod.rs @@ -0,0 +1,1621 @@ +pub type pthread_t = c_ulong; +pub type __priority_which_t = ::c_uint; +pub type __rlimit_resource_t = ::c_uint; +pub type Lmid_t = ::c_long; +pub type regoff_t = ::c_int; +pub type __kernel_rwf_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, + pub stx_blksize: u32, + pub stx_attributes: u64, + pub stx_nlink: u32, + pub stx_uid: u32, + pub stx_gid: u32, + pub stx_mode: u16, + __statx_pad1: [u16; 1], + pub stx_ino: u64, + pub stx_size: u64, + pub stx_blocks: u64, + pub stx_attributes_mask: u64, + pub stx_atime: ::statx_timestamp, + pub stx_btime: ::statx_timestamp, + pub stx_ctime: ::statx_timestamp, + pub stx_mtime: ::statx_timestamp, + pub stx_rdev_major: u32, + pub stx_rdev_minor: u32, + pub stx_dev_major: u32, + pub stx_dev_minor: u32, + pub stx_mnt_id: u64, + pub stx_dio_mem_align: u32, + pub stx_dio_offset_align: u32, + __statx_pad3: [u64; 12], + } + + pub struct statx_timestamp { + pub tv_sec: i64, + pub tv_nsec: u32, + pub __statx_timestamp_pad1: [i32; 1], + } + + pub struct aiocb { + pub aio_fildes: ::c_int, + pub aio_lio_opcode: ::c_int, + pub aio_reqprio: ::c_int, + pub aio_buf: *mut ::c_void, + pub aio_nbytes: ::size_t, + pub aio_sigevent: ::sigevent, + __next_prio: *mut aiocb, + __abs_prio: ::c_int, + __policy: ::c_int, + __error_code: ::c_int, + __return_value: ::ssize_t, + pub aio_offset: off_t, + #[cfg(all(not(target_arch = "x86_64"), target_pointer_width = "32"))] + __unused1: [::c_char; 4], + __glibc_reserved: [::c_char; 32] + } + + pub struct __exit_status { + pub e_termination: ::c_short, + pub e_exit: ::c_short, + } + + pub struct __timeval { + pub tv_sec: i32, + pub tv_usec: i32, + } + + pub struct glob64_t { + pub gl_pathc: ::size_t, + pub gl_pathv: *mut *mut ::c_char, + pub gl_offs: ::size_t, + pub gl_flags: ::c_int, + + __unused1: *mut ::c_void, + __unused2: *mut ::c_void, + __unused3: *mut ::c_void, + __unused4: *mut ::c_void, + __unused5: *mut ::c_void, + } + + pub struct msghdr { + pub msg_name: *mut ::c_void, + pub msg_namelen: ::socklen_t, + pub msg_iov: *mut ::iovec, + pub msg_iovlen: ::size_t, + pub msg_control: *mut ::c_void, + pub msg_controllen: ::size_t, + pub msg_flags: ::c_int, + } + + pub struct cmsghdr { + pub cmsg_len: ::size_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_line: ::cc_t, + pub c_cc: [::cc_t; ::NCCS], + #[cfg(not(any( + target_arch = "sparc", + target_arch = "sparc64", + target_arch = "mips", + target_arch = "mips32r6", + target_arch = "mips64", + target_arch = "mips64r6")))] + pub c_ispeed: ::speed_t, + #[cfg(not(any( + target_arch = "sparc", + target_arch = "sparc64", + target_arch = "mips", + target_arch = "mips32r6", + target_arch = "mips64", + target_arch = "mips64r6")))] + 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 mallinfo2 { + 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 nl_pktinfo { + pub group: u32, + } + + pub struct nl_mmap_req { + pub nm_block_size: ::c_uint, + pub nm_block_nr: ::c_uint, + pub nm_frame_size: ::c_uint, + pub nm_frame_nr: ::c_uint, + } + + pub struct nl_mmap_hdr { + pub nm_status: ::c_uint, + pub nm_len: ::c_uint, + pub nm_group: u32, + pub nm_pid: u32, + pub nm_uid: u32, + pub nm_gid: u32, + } + + 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 timex { + pub modes: ::c_uint, + #[cfg(all(target_arch = "x86_64", target_pointer_width = "32"))] + pub offset: i64, + #[cfg(not(all(target_arch = "x86_64", target_pointer_width = "32")))] + pub offset: ::c_long, + #[cfg(all(target_arch = "x86_64", target_pointer_width = "32"))] + pub freq: i64, + #[cfg(not(all(target_arch = "x86_64", target_pointer_width = "32")))] + pub freq: ::c_long, + #[cfg(all(target_arch = "x86_64", target_pointer_width = "32"))] + pub maxerror: i64, + #[cfg(not(all(target_arch = "x86_64", target_pointer_width = "32")))] + pub maxerror: ::c_long, + #[cfg(all(target_arch = "x86_64", target_pointer_width = "32"))] + pub esterror: i64, + #[cfg(not(all(target_arch = "x86_64", target_pointer_width = "32")))] + pub esterror: ::c_long, + pub status: ::c_int, + #[cfg(all(target_arch = "x86_64", target_pointer_width = "32"))] + pub constant: i64, + #[cfg(not(all(target_arch = "x86_64", target_pointer_width = "32")))] + pub constant: ::c_long, + #[cfg(all(target_arch = "x86_64", target_pointer_width = "32"))] + pub precision: i64, + #[cfg(not(all(target_arch = "x86_64", target_pointer_width = "32")))] + pub precision: ::c_long, + #[cfg(all(target_arch = "x86_64", target_pointer_width = "32"))] + pub tolerance: i64, + #[cfg(not(all(target_arch = "x86_64", target_pointer_width = "32")))] + pub tolerance: ::c_long, + pub time: ::timeval, + #[cfg(all(target_arch = "x86_64", target_pointer_width = "32"))] + pub tick: i64, + #[cfg(not(all(target_arch = "x86_64", target_pointer_width = "32")))] + pub tick: ::c_long, + #[cfg(all(target_arch = "x86_64", target_pointer_width = "32"))] + pub ppsfreq: i64, + #[cfg(not(all(target_arch = "x86_64", target_pointer_width = "32")))] + pub ppsfreq: ::c_long, + #[cfg(all(target_arch = "x86_64", target_pointer_width = "32"))] + pub jitter: i64, + #[cfg(not(all(target_arch = "x86_64", target_pointer_width = "32")))] + pub jitter: ::c_long, + pub shift: ::c_int, + #[cfg(all(target_arch = "x86_64", target_pointer_width = "32"))] + pub stabil: i64, + #[cfg(not(all(target_arch = "x86_64", target_pointer_width = "32")))] + pub stabil: ::c_long, + #[cfg(all(target_arch = "x86_64", target_pointer_width = "32"))] + pub jitcnt: i64, + #[cfg(not(all(target_arch = "x86_64", target_pointer_width = "32")))] + pub jitcnt: ::c_long, + #[cfg(all(target_arch = "x86_64", target_pointer_width = "32"))] + pub calcnt: i64, + #[cfg(not(all(target_arch = "x86_64", target_pointer_width = "32")))] + pub calcnt: ::c_long, + #[cfg(all(target_arch = "x86_64", target_pointer_width = "32"))] + pub errcnt: i64, + #[cfg(not(all(target_arch = "x86_64", target_pointer_width = "32")))] + pub errcnt: ::c_long, + #[cfg(all(target_arch = "x86_64", target_pointer_width = "32"))] + pub stbcnt: i64, + #[cfg(not(all(target_arch = "x86_64", target_pointer_width = "32")))] + pub stbcnt: ::c_long, + pub tai: ::c_int, + pub __unused1: i32, + pub __unused2: i32, + pub __unused3: i32, + pub __unused4: i32, + pub __unused5: i32, + pub __unused6: i32, + pub __unused7: i32, + pub __unused8: i32, + pub __unused9: i32, + pub __unused10: i32, + pub __unused11: i32, + } + + pub struct ntptimeval { + pub time: ::timeval, + pub maxerror: ::c_long, + pub esterror: ::c_long, + pub tai: ::c_long, + pub __glibc_reserved1: ::c_long, + pub __glibc_reserved2: ::c_long, + pub __glibc_reserved3: ::c_long, + pub __glibc_reserved4: ::c_long, + } + + 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 Elf64_Chdr { + pub ch_type: ::Elf64_Word, + pub ch_reserved: ::Elf64_Word, + pub ch_size: ::Elf64_Xword, + pub ch_addralign: ::Elf64_Xword, + } + + pub struct Elf32_Chdr { + pub ch_type: ::Elf32_Word, + 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, + } + + // linux/if_xdp.h + + pub struct sockaddr_xdp { + pub sxdp_family: ::__u16, + pub sxdp_flags: ::__u16, + pub sxdp_ifindex: ::__u32, + pub sxdp_queue_id: ::__u32, + pub sxdp_shared_umem_fd: ::__u32, + } + + pub struct xdp_ring_offset { + pub producer: ::__u64, + pub consumer: ::__u64, + pub desc: ::__u64, + pub flags: ::__u64, + } + + pub struct xdp_mmap_offsets { + pub rx: xdp_ring_offset, + pub tx: xdp_ring_offset, + pub fr: xdp_ring_offset, + pub cr: xdp_ring_offset, + } + + pub struct xdp_ring_offset_v1 { + pub producer: ::__u64, + pub consumer: ::__u64, + pub desc: ::__u64, + } + + pub struct xdp_mmap_offsets_v1 { + pub rx: xdp_ring_offset_v1, + pub tx: xdp_ring_offset_v1, + pub fr: xdp_ring_offset_v1, + pub cr: xdp_ring_offset_v1, + } + + pub struct xdp_umem_reg { + pub addr: ::__u64, + pub len: ::__u64, + pub chunk_size: ::__u32, + pub headroom: ::__u32, + pub flags: ::__u32, + } + + pub struct xdp_umem_reg_v1 { + pub addr: ::__u64, + pub len: ::__u64, + pub chunk_size: ::__u32, + pub headroom: ::__u32, + } + + pub struct xdp_statistics { + pub rx_dropped: ::__u64, + pub rx_invalid_descs: ::__u64, + pub tx_invalid_descs: ::__u64, + pub rx_ring_full: ::__u64, + pub rx_fill_ring_empty_descs: ::__u64, + pub tx_ring_empty_descs: ::__u64, + } + + pub struct xdp_statistics_v1 { + pub rx_dropped: ::__u64, + pub rx_invalid_descs: ::__u64, + pub tx_invalid_descs: ::__u64, + } + + pub struct xdp_options { + pub flags: ::__u32, + } + + pub struct xdp_desc { + pub addr: ::__u64, + pub len: ::__u32, + pub options: ::__u32, + } + + pub struct iocb { + pub aio_data: ::__u64, + #[cfg(target_endian = "little")] + pub aio_key: ::__u32, + #[cfg(target_endian = "little")] + pub aio_rw_flags: ::__kernel_rwf_t, + #[cfg(target_endian = "big")] + pub aio_rw_flags: ::__kernel_rwf_t, + #[cfg(target_endian = "big")] + pub aio_key: ::__u32, + pub aio_lio_opcode: ::__u16, + pub aio_reqprio: ::__s16, + pub aio_fildes: ::__u32, + pub aio_buf: ::__u64, + pub aio_nbytes: ::__u64, + pub aio_offset: ::__s64, + aio_reserved2: ::__u64, + pub aio_flags: ::__u32, + pub aio_resfd: ::__u32, + } + + // netinet/tcp.h + + 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, + /// This contains the bitfields `tcpi_snd_wscale` and `tcpi_rcv_wscale`. + /// Each is 4 bits. + pub tcpi_snd_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_total_retrans: u32, + } + + pub struct fanotify_event_info_pidfd { + pub hdr: ::fanotify_event_info_header, + pub pidfd: ::__s32, + } + + pub struct fanotify_event_info_error { + pub hdr: ::fanotify_event_info_header, + pub error: ::__s32, + pub error_count: ::__u32, + } +} + +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_timer { + _si_signo: ::c_int, + _si_errno: ::c_int, + _si_code: ::c_int, + _si_tid: ::c_int, + _si_overrun: ::c_int, + si_sigval: ::sigval, + } + (*(self as *const siginfo_t as *const siginfo_timer)).si_sigval + } +} + +cfg_if! { + if #[cfg(libc_union)] { + // Internal, for casts to access union fields + #[repr(C)] + struct sifields_sigchld { + si_pid: ::pid_t, + si_uid: ::uid_t, + si_status: ::c_int, + si_utime: ::c_long, + si_stime: ::c_long, + } + impl ::Copy for sifields_sigchld {} + impl ::Clone for sifields_sigchld { + fn clone(&self) -> sifields_sigchld { + *self + } + } + + // Internal, for casts to access union fields + #[repr(C)] + union sifields { + _align_pointer: *mut ::c_void, + sigchld: sifields_sigchld, + } + + // Internal, for casts to access union fields. Note that some variants + // of sifields start with a pointer, which makes the alignment of + // sifields vary on 32-bit and 64-bit architectures. + #[repr(C)] + struct siginfo_f { + _siginfo_base: [::c_int; 3], + sifields: sifields, + } + + impl siginfo_t { + unsafe fn sifields(&self) -> &sifields { + &(*(self as *const siginfo_t as *const siginfo_f)).sifields + } + + pub unsafe fn si_pid(&self) -> ::pid_t { + self.sifields().sigchld.si_pid + } + + pub unsafe fn si_uid(&self) -> ::uid_t { + self.sifields().sigchld.si_uid + } + + pub unsafe fn si_status(&self) -> ::c_int { + self.sifields().sigchld.si_status + } + + pub unsafe fn si_utime(&self) -> ::c_long { + self.sifields().sigchld.si_utime + } + + pub unsafe fn si_stime(&self) -> ::c_long { + 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 + } + } + } +} + +s_no_extra_traits! { + pub struct utmpx { + pub ut_type: ::c_short, + pub ut_pid: ::pid_t, + pub ut_line: [::c_char; __UT_LINESIZE], + pub ut_id: [::c_char; 4], + + pub ut_user: [::c_char; __UT_NAMESIZE], + pub ut_host: [::c_char; __UT_HOSTSIZE], + pub ut_exit: __exit_status, + + #[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, + + pub ut_addr_v6: [i32; 4], + __glibc_reserved: [::c_char; 20], + } +} + +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_pid == other.ut_pid + && self.ut_line == other.ut_line + && self.ut_id == other.ut_id + && self.ut_user == other.ut_user + && self + .ut_host + .iter() + .zip(other.ut_host.iter()) + .all(|(a,b)| a == b) + && self.ut_exit == other.ut_exit + && self.ut_session == other.ut_session + && self.ut_tv == other.ut_tv + && self.ut_addr_v6 == other.ut_addr_v6 + && self.__glibc_reserved == other.__glibc_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_pid", &self.ut_pid) + .field("ut_line", &self.ut_line) + .field("ut_id", &self.ut_id) + .field("ut_user", &self.ut_user) + // FIXME: .field("ut_host", &self.ut_host) + .field("ut_exit", &self.ut_exit) + .field("ut_session", &self.ut_session) + .field("ut_tv", &self.ut_tv) + .field("ut_addr_v6", &self.ut_addr_v6) + .field("__glibc_reserved", &self.__glibc_reserved) + .finish() + } + } + + impl ::hash::Hash for utmpx { + fn hash(&self, state: &mut H) { + self.ut_type.hash(state); + self.ut_pid.hash(state); + self.ut_line.hash(state); + self.ut_id.hash(state); + self.ut_user.hash(state); + self.ut_host.hash(state); + self.ut_exit.hash(state); + self.ut_session.hash(state); + self.ut_tv.hash(state); + self.ut_addr_v6.hash(state); + 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); + } + } + } + } +} + +// include/uapi/asm-generic/hugetlb_encode.h +pub const HUGETLB_FLAG_ENCODE_SHIFT: ::c_int = 26; +pub const HUGETLB_FLAG_ENCODE_MASK: ::c_int = 0x3f; + +pub const HUGETLB_FLAG_ENCODE_64KB: ::c_int = 16 << HUGETLB_FLAG_ENCODE_SHIFT; +pub const HUGETLB_FLAG_ENCODE_512KB: ::c_int = 19 << HUGETLB_FLAG_ENCODE_SHIFT; +pub const HUGETLB_FLAG_ENCODE_1MB: ::c_int = 20 << HUGETLB_FLAG_ENCODE_SHIFT; +pub const HUGETLB_FLAG_ENCODE_2MB: ::c_int = 21 << HUGETLB_FLAG_ENCODE_SHIFT; +pub const HUGETLB_FLAG_ENCODE_8MB: ::c_int = 23 << HUGETLB_FLAG_ENCODE_SHIFT; +pub const HUGETLB_FLAG_ENCODE_16MB: ::c_int = 24 << HUGETLB_FLAG_ENCODE_SHIFT; +pub const HUGETLB_FLAG_ENCODE_32MB: ::c_int = 25 << HUGETLB_FLAG_ENCODE_SHIFT; +pub const HUGETLB_FLAG_ENCODE_256MB: ::c_int = 28 << HUGETLB_FLAG_ENCODE_SHIFT; +pub const HUGETLB_FLAG_ENCODE_512MB: ::c_int = 29 << HUGETLB_FLAG_ENCODE_SHIFT; +pub const HUGETLB_FLAG_ENCODE_1GB: ::c_int = 30 << HUGETLB_FLAG_ENCODE_SHIFT; +pub const HUGETLB_FLAG_ENCODE_2GB: ::c_int = 31 << HUGETLB_FLAG_ENCODE_SHIFT; +pub const HUGETLB_FLAG_ENCODE_16GB: ::c_int = 34 << HUGETLB_FLAG_ENCODE_SHIFT; + +// include/uapi/linux/mman.h +/* + * Huge page size encoding when MAP_HUGETLB is specified, and a huge page + * size other than the default is desired. See hugetlb_encode.h. + * All known huge page size encodings are provided here. It is the + * responsibility of the application to know which sizes are supported on + * the running system. See mmap(2) man page for details. + */ +pub const MAP_HUGE_SHIFT: ::c_int = HUGETLB_FLAG_ENCODE_SHIFT; +pub const MAP_HUGE_MASK: ::c_int = HUGETLB_FLAG_ENCODE_MASK; + +pub const MAP_HUGE_64KB: ::c_int = HUGETLB_FLAG_ENCODE_64KB; +pub const MAP_HUGE_512KB: ::c_int = HUGETLB_FLAG_ENCODE_512KB; +pub const MAP_HUGE_1MB: ::c_int = HUGETLB_FLAG_ENCODE_1MB; +pub const MAP_HUGE_2MB: ::c_int = HUGETLB_FLAG_ENCODE_2MB; +pub const MAP_HUGE_8MB: ::c_int = HUGETLB_FLAG_ENCODE_8MB; +pub const MAP_HUGE_16MB: ::c_int = HUGETLB_FLAG_ENCODE_16MB; +pub const MAP_HUGE_32MB: ::c_int = HUGETLB_FLAG_ENCODE_32MB; +pub const MAP_HUGE_256MB: ::c_int = HUGETLB_FLAG_ENCODE_256MB; +pub const MAP_HUGE_512MB: ::c_int = HUGETLB_FLAG_ENCODE_512MB; +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 PRIO_PROCESS: ::__priority_which_t = 0; +pub const PRIO_PGRP: ::__priority_which_t = 1; +pub const PRIO_USER: ::__priority_which_t = 2; + +pub const MS_RMT_MASK: ::c_ulong = 0x02800051; + +pub const __UT_LINESIZE: usize = 32; +pub const __UT_NAMESIZE: usize = 32; +pub const __UT_HOSTSIZE: usize = 256; +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 = 3; +pub const OLD_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; + +// dlfcn.h +pub const LM_ID_BASE: ::c_long = 0; +pub const LM_ID_NEWLM: ::c_long = -1; + +pub const RTLD_DI_LMID: ::c_int = 1; +pub const RTLD_DI_LINKMAP: ::c_int = 2; +pub const RTLD_DI_CONFIGADDR: ::c_int = 3; +pub const RTLD_DI_SERINFO: ::c_int = 4; +pub const RTLD_DI_SERINFOSIZE: ::c_int = 5; +pub const RTLD_DI_ORIGIN: ::c_int = 6; +pub const RTLD_DI_PROFILENAME: ::c_int = 7; +pub const RTLD_DI_PROFILEOUT: ::c_int = 8; +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; +pub const SOL_PNPIPE: ::c_int = 275; +pub const SOL_RDS: ::c_int = 276; +pub const SOL_IUCV: ::c_int = 277; +pub const SOL_CAIF: ::c_int = 278; +pub const SOL_NFC: ::c_int = 280; +pub const SOL_XDP: ::c_int = 283; + +pub const MSG_TRYHARD: ::c_int = 4; + +pub const LC_PAPER: ::c_int = 7; +pub const LC_NAME: ::c_int = 8; +pub const LC_ADDRESS: ::c_int = 9; +pub const LC_TELEPHONE: ::c_int = 10; +pub const LC_MEASUREMENT: ::c_int = 11; +pub const LC_IDENTIFICATION: ::c_int = 12; +pub const LC_PAPER_MASK: ::c_int = 1 << LC_PAPER; +pub const LC_NAME_MASK: ::c_int = 1 << LC_NAME; +pub const LC_ADDRESS_MASK: ::c_int = 1 << LC_ADDRESS; +pub const LC_TELEPHONE_MASK: ::c_int = 1 << LC_TELEPHONE; +pub const LC_MEASUREMENT_MASK: ::c_int = 1 << LC_MEASUREMENT; +pub const LC_IDENTIFICATION_MASK: ::c_int = 1 << LC_IDENTIFICATION; +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 + | LC_PAPER_MASK + | LC_NAME_MASK + | LC_ADDRESS_MASK + | LC_TELEPHONE_MASK + | LC_MEASUREMENT_MASK + | LC_IDENTIFICATION_MASK; + +pub const ENOTSUP: ::c_int = EOPNOTSUPP; + +pub const SOCK_SEQPACKET: ::c_int = 5; +pub const SOCK_DCCP: ::c_int = 6; +pub const SOCK_PACKET: ::c_int = 10; + +pub const AF_IB: ::c_int = 27; +pub const AF_MPLS: ::c_int = 28; +pub const AF_NFC: ::c_int = 39; +pub const AF_VSOCK: ::c_int = 40; +pub const AF_XDP: ::c_int = 44; +pub const PF_IB: ::c_int = AF_IB; +pub const PF_MPLS: ::c_int = AF_MPLS; +pub const PF_NFC: ::c_int = AF_NFC; +pub const PF_VSOCK: ::c_int = AF_VSOCK; +pub const PF_XDP: ::c_int = AF_XDP; + +pub const SIGEV_THREAD_ID: ::c_int = 4; + +pub const BUFSIZ: ::c_uint = 8192; +pub const TMP_MAX: ::c_uint = 238328; +pub const FOPEN_MAX: ::c_uint = 16; +pub const FILENAME_MAX: ::c_uint = 4096; +pub const POSIX_MADV_DONTNEED: ::c_int = 4; +pub const _CS_GNU_LIBC_VERSION: ::c_int = 2; +pub const _CS_GNU_LIBPTHREAD_VERSION: ::c_int = 3; +pub const _CS_PATH: ::c_int = 0; +pub const _SC_EQUIV_CLASS_MAX: ::c_int = 41; +pub const _SC_CHARCLASS_NAME_MAX: ::c_int = 45; +pub const _SC_PII: ::c_int = 53; +pub const _SC_PII_XTI: ::c_int = 54; +pub const _SC_PII_SOCKET: ::c_int = 55; +pub const _SC_PII_INTERNET: ::c_int = 56; +pub const _SC_PII_OSI: ::c_int = 57; +pub const _SC_POLL: ::c_int = 58; +pub const _SC_SELECT: ::c_int = 59; +pub const _SC_PII_INTERNET_STREAM: ::c_int = 61; +pub const _SC_PII_INTERNET_DGRAM: ::c_int = 62; +pub const _SC_PII_OSI_COTS: ::c_int = 63; +pub const _SC_PII_OSI_CLTS: ::c_int = 64; +pub const _SC_PII_OSI_M: ::c_int = 65; +pub const _SC_T_IOV_MAX: ::c_int = 66; +pub const _SC_2_C_VERSION: ::c_int = 96; +pub const _SC_CHAR_BIT: ::c_int = 101; +pub const _SC_CHAR_MAX: ::c_int = 102; +pub const _SC_CHAR_MIN: ::c_int = 103; +pub const _SC_INT_MAX: ::c_int = 104; +pub const _SC_INT_MIN: ::c_int = 105; +pub const _SC_LONG_BIT: ::c_int = 106; +pub const _SC_WORD_BIT: ::c_int = 107; +pub const _SC_MB_LEN_MAX: ::c_int = 108; +pub const _SC_SSIZE_MAX: ::c_int = 110; +pub const _SC_SCHAR_MAX: ::c_int = 111; +pub const _SC_SCHAR_MIN: ::c_int = 112; +pub const _SC_SHRT_MAX: ::c_int = 113; +pub const _SC_SHRT_MIN: ::c_int = 114; +pub const _SC_UCHAR_MAX: ::c_int = 115; +pub const _SC_UINT_MAX: ::c_int = 116; +pub const _SC_ULONG_MAX: ::c_int = 117; +pub const _SC_USHRT_MAX: ::c_int = 118; +pub const _SC_NL_ARGMAX: ::c_int = 119; +pub const _SC_NL_LANGMAX: ::c_int = 120; +pub const _SC_NL_MSGMAX: ::c_int = 121; +pub const _SC_NL_NMAX: ::c_int = 122; +pub const _SC_NL_SETMAX: ::c_int = 123; +pub const _SC_NL_TEXTMAX: ::c_int = 124; +pub const _SC_BASE: ::c_int = 134; +pub const _SC_C_LANG_SUPPORT: ::c_int = 135; +pub const _SC_C_LANG_SUPPORT_R: ::c_int = 136; +pub const _SC_DEVICE_IO: ::c_int = 140; +pub const _SC_DEVICE_SPECIFIC: ::c_int = 141; +pub const _SC_DEVICE_SPECIFIC_R: ::c_int = 142; +pub const _SC_FD_MGMT: ::c_int = 143; +pub const _SC_FIFO: ::c_int = 144; +pub const _SC_PIPE: ::c_int = 145; +pub const _SC_FILE_ATTRIBUTES: ::c_int = 146; +pub const _SC_FILE_LOCKING: ::c_int = 147; +pub const _SC_FILE_SYSTEM: ::c_int = 148; +pub const _SC_MULTI_PROCESS: ::c_int = 150; +pub const _SC_SINGLE_PROCESS: ::c_int = 151; +pub const _SC_NETWORKING: ::c_int = 152; +pub const _SC_REGEX_VERSION: ::c_int = 156; +pub const _SC_SIGNALS: ::c_int = 158; +pub const _SC_SYSTEM_DATABASE: ::c_int = 162; +pub const _SC_SYSTEM_DATABASE_R: ::c_int = 163; +pub const _SC_USER_GROUPS: ::c_int = 166; +pub const _SC_USER_GROUPS_R: ::c_int = 167; +pub const _SC_LEVEL1_ICACHE_SIZE: ::c_int = 185; +pub const _SC_LEVEL1_ICACHE_ASSOC: ::c_int = 186; +pub const _SC_LEVEL1_ICACHE_LINESIZE: ::c_int = 187; +pub const _SC_LEVEL1_DCACHE_SIZE: ::c_int = 188; +pub const _SC_LEVEL1_DCACHE_ASSOC: ::c_int = 189; +pub const _SC_LEVEL1_DCACHE_LINESIZE: ::c_int = 190; +pub const _SC_LEVEL2_CACHE_SIZE: ::c_int = 191; +pub const _SC_LEVEL2_CACHE_ASSOC: ::c_int = 192; +pub const _SC_LEVEL2_CACHE_LINESIZE: ::c_int = 193; +pub const _SC_LEVEL3_CACHE_SIZE: ::c_int = 194; +pub const _SC_LEVEL3_CACHE_ASSOC: ::c_int = 195; +pub const _SC_LEVEL3_CACHE_LINESIZE: ::c_int = 196; +pub const _SC_LEVEL4_CACHE_SIZE: ::c_int = 197; +pub const _SC_LEVEL4_CACHE_ASSOC: ::c_int = 198; +pub const _SC_LEVEL4_CACHE_LINESIZE: ::c_int = 199; +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 BINDERFS_SUPER_MAGIC: ::c_long = 0x6c6f6f70; + pub const XFS_SUPER_MAGIC: ::c_long = 0x58465342; + } else if #[cfg(target_arch = "s390x")] { + pub const BINDERFS_SUPER_MAGIC: ::c_uint = 0x6c6f6f70; + pub const XFS_SUPER_MAGIC: ::c_uint = 0x58465342; + } +} + +pub const CPU_SETSIZE: ::c_int = 0x400; + +pub const PTRACE_TRACEME: ::c_uint = 0; +pub const PTRACE_PEEKTEXT: ::c_uint = 1; +pub const PTRACE_PEEKDATA: ::c_uint = 2; +pub const PTRACE_PEEKUSER: ::c_uint = 3; +pub const PTRACE_POKETEXT: ::c_uint = 4; +pub const PTRACE_POKEDATA: ::c_uint = 5; +pub const PTRACE_POKEUSER: ::c_uint = 6; +pub const PTRACE_CONT: ::c_uint = 7; +pub const PTRACE_KILL: ::c_uint = 8; +pub const PTRACE_SINGLESTEP: ::c_uint = 9; +pub const PTRACE_ATTACH: ::c_uint = 16; +pub const PTRACE_SYSCALL: ::c_uint = 24; +pub const PTRACE_SETOPTIONS: ::c_uint = 0x4200; +pub const PTRACE_GETEVENTMSG: ::c_uint = 0x4201; +pub const PTRACE_GETSIGINFO: ::c_uint = 0x4202; +pub const PTRACE_SETSIGINFO: ::c_uint = 0x4203; +pub const PTRACE_GETREGSET: ::c_uint = 0x4204; +pub const PTRACE_SETREGSET: ::c_uint = 0x4205; +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_GETSIGMASK: ::c_uint = 0x420a; +pub const PTRACE_SETSIGMASK: ::c_uint = 0x420b; +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 + +// Flags for preadv2/pwritev2 +pub const RWF_HIPRI: ::c_int = 0x00000001; +pub const RWF_DSYNC: ::c_int = 0x00000002; +pub const RWF_SYNC: ::c_int = 0x00000004; +pub const RWF_NOWAIT: ::c_int = 0x00000008; +pub const RWF_APPEND: ::c_int = 0x00000010; + +// linux/rtnetlink.h +pub const TCA_PAD: ::c_ushort = 9; +pub const TCA_DUMP_INVISIBLE: ::c_ushort = 10; +pub const TCA_CHAIN: ::c_ushort = 11; +pub const TCA_HW_OFFLOAD: ::c_ushort = 12; + +pub const RTM_DELNETCONF: u16 = 81; +pub const RTM_NEWSTATS: u16 = 92; +pub const RTM_GETSTATS: u16 = 94; +pub const RTM_NEWCACHEREPORT: u16 = 96; + +pub const RTM_F_LOOKUP_TABLE: ::c_uint = 0x1000; +pub const RTM_F_FIB_MATCH: ::c_uint = 0x2000; + +pub const RTA_VIA: ::c_ushort = 18; +pub const RTA_NEWDST: ::c_ushort = 19; +pub const RTA_PREF: ::c_ushort = 20; +pub const RTA_ENCAP_TYPE: ::c_ushort = 21; +pub const RTA_ENCAP: ::c_ushort = 22; +pub const RTA_EXPIRES: ::c_ushort = 23; +pub const RTA_PAD: ::c_ushort = 24; +pub const RTA_UID: ::c_ushort = 25; +pub const RTA_TTL_PROPAGATE: ::c_ushort = 26; + +// linux/neighbor.h +pub const NTF_EXT_LEARNED: u8 = 0x10; +pub const NTF_OFFLOADED: u8 = 0x20; + +pub const NDA_MASTER: ::c_ushort = 9; +pub const NDA_LINK_NETNSID: ::c_ushort = 10; +pub const NDA_SRC_VNI: ::c_ushort = 11; + +// linux/personality.h +pub const UNAME26: ::c_int = 0x0020000; +pub const FDPIC_FUNCPTRS: ::c_int = 0x0080000; + +// linux/if_addr.h +pub const IFA_FLAGS: ::c_ushort = 8; + +pub const IFA_F_MANAGETEMPADDR: u32 = 0x100; +pub const IFA_F_NOPREFIXROUTE: u32 = 0x200; +pub const IFA_F_MCAUTOJOIN: u32 = 0x400; +pub const IFA_F_STABLE_PRIVACY: u32 = 0x800; + +pub const MAX_LINKS: ::c_int = 32; + +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; + +// linux/if_xdp.h +pub const XDP_SHARED_UMEM: ::__u16 = 1 << 0; +pub const XDP_COPY: ::__u16 = 1 << 1; +pub const XDP_ZEROCOPY: ::__u16 = 1 << 2; +pub const XDP_USE_NEED_WAKEUP: ::__u16 = 1 << 3; +pub const XDP_USE_SG: ::__u16 = 1 << 4; + +pub const XDP_UMEM_UNALIGNED_CHUNK_FLAG: ::__u32 = 1 << 0; + +pub const XDP_RING_NEED_WAKEUP: ::__u32 = 1 << 0; + +pub const XDP_MMAP_OFFSETS: ::c_int = 1; +pub const XDP_RX_RING: ::c_int = 2; +pub const XDP_TX_RING: ::c_int = 3; +pub const XDP_UMEM_REG: ::c_int = 4; +pub const XDP_UMEM_FILL_RING: ::c_int = 5; +pub const XDP_UMEM_COMPLETION_RING: ::c_int = 6; +pub const XDP_STATISTICS: ::c_int = 7; +pub const XDP_OPTIONS: ::c_int = 8; + +pub const XDP_OPTIONS_ZEROCOPY: ::__u32 = 1 << 0; + +pub const XDP_PGOFF_RX_RING: ::off_t = 0; +pub const XDP_PGOFF_TX_RING: ::off_t = 0x80000000; +pub const XDP_UMEM_PGOFF_FILL_RING: ::c_ulonglong = 0x100000000; +pub const XDP_UMEM_PGOFF_COMPLETION_RING: ::c_ulonglong = 0x180000000; + +pub const XSK_UNALIGNED_BUF_OFFSET_SHIFT: ::c_int = 48; +pub const XSK_UNALIGNED_BUF_ADDR_MASK: ::c_ulonglong = (1 << XSK_UNALIGNED_BUF_OFFSET_SHIFT) - 1; + +pub const XDP_PKT_CONTD: ::__u32 = 1 << 0; + +pub const ELFOSABI_ARM_AEABI: u8 = 64; + +// linux/sched.h +pub const CLONE_NEWTIME: ::c_int = 0x80; +pub const CLONE_CLEAR_SIGHAND: ::c_int = 0x100000000; +pub const CLONE_INTO_CGROUP: ::c_int = 0x200000000; + +// linux/keyctl.h +pub const KEYCTL_DH_COMPUTE: u32 = 23; +pub const KEYCTL_PKEY_QUERY: u32 = 24; +pub const KEYCTL_PKEY_ENCRYPT: u32 = 25; +pub const KEYCTL_PKEY_DECRYPT: u32 = 26; +pub const KEYCTL_PKEY_SIGN: u32 = 27; +pub const KEYCTL_PKEY_VERIFY: u32 = 28; +pub const KEYCTL_RESTRICT_KEYRING: u32 = 29; + +pub const KEYCTL_SUPPORTS_ENCRYPT: u32 = 0x01; +pub const KEYCTL_SUPPORTS_DECRYPT: u32 = 0x02; +pub const KEYCTL_SUPPORTS_SIGN: u32 = 0x04; +pub const KEYCTL_SUPPORTS_VERIFY: u32 = 0x08; +cfg_if! { + if #[cfg(not(any(target_arch = "mips", + target_arch = "mips32r6", + target_arch = "mips64", + target_arch = "mips64r6")))] { + pub const KEYCTL_MOVE: u32 = 30; + pub const KEYCTL_CAPABILITIES: u32 = 31; + + pub const KEYCTL_CAPS0_CAPABILITIES: u32 = 0x01; + pub const KEYCTL_CAPS0_PERSISTENT_KEYRINGS: u32 = 0x02; + pub const KEYCTL_CAPS0_DIFFIE_HELLMAN: u32 = 0x04; + pub const KEYCTL_CAPS0_PUBLIC_KEY: u32 = 0x08; + pub const KEYCTL_CAPS0_BIG_KEY: u32 = 0x10; + pub const KEYCTL_CAPS0_INVALIDATE: u32 = 0x20; + pub const KEYCTL_CAPS0_RESTRICT_KEYRING: u32 = 0x40; + pub const KEYCTL_CAPS0_MOVE: u32 = 0x80; + pub const KEYCTL_CAPS1_NS_KEYRING_NAME: u32 = 0x01; + pub const KEYCTL_CAPS1_NS_KEY_TAG: u32 = 0x02; + } +} + +pub const M_MXFAST: ::c_int = 1; +pub const M_NLBLKS: ::c_int = 2; +pub const M_GRAIN: ::c_int = 3; +pub const M_KEEP: ::c_int = 4; +pub const M_TRIM_THRESHOLD: ::c_int = -1; +pub const M_TOP_PAD: ::c_int = -2; +pub const M_MMAP_THRESHOLD: ::c_int = -3; +pub const M_MMAP_MAX: ::c_int = -4; +pub const M_CHECK_ACTION: ::c_int = -5; +pub const M_PERTURB: ::c_int = -6; +pub const M_ARENA_TEST: ::c_int = -7; +pub const M_ARENA_MAX: ::c_int = -8; + +pub const AT_STATX_SYNC_TYPE: ::c_int = 0x6000; +pub const AT_STATX_SYNC_AS_STAT: ::c_int = 0x0000; +pub const AT_STATX_FORCE_SYNC: ::c_int = 0x2000; +pub const AT_STATX_DONT_SYNC: ::c_int = 0x4000; +pub const STATX_TYPE: ::c_uint = 0x0001; +pub const STATX_MODE: ::c_uint = 0x0002; +pub const STATX_NLINK: ::c_uint = 0x0004; +pub const STATX_UID: ::c_uint = 0x0008; +pub const STATX_GID: ::c_uint = 0x0010; +pub const STATX_ATIME: ::c_uint = 0x0020; +pub const STATX_MTIME: ::c_uint = 0x0040; +pub const STATX_CTIME: ::c_uint = 0x0080; +pub const STATX_INO: ::c_uint = 0x0100; +pub const STATX_SIZE: ::c_uint = 0x0200; +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; +pub const STATX_ATTR_IMMUTABLE: ::c_int = 0x0010; +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; + +// linux/mount.h +pub const MOVE_MOUNT_F_SYMLINKS: ::c_uint = 0x00000001; +pub const MOVE_MOUNT_F_AUTOMOUNTS: ::c_uint = 0x00000002; +pub const MOVE_MOUNT_F_EMPTY_PATH: ::c_uint = 0x00000004; +pub const MOVE_MOUNT_T_SYMLINKS: ::c_uint = 0x00000010; +pub const MOVE_MOUNT_T_AUTOMOUNTS: ::c_uint = 0x00000020; +pub const MOVE_MOUNT_T_EMPTY_PATH: ::c_uint = 0x00000040; +pub const MOVE_MOUNT_SET_GROUP: ::c_uint = 0x00000100; +pub const MOVE_MOUNT_BENEATH: ::c_uint = 0x00000200; + +// sys/timex.h +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 NTP_API: ::c_int = 4; +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; + +// Portable GLOB_* flags are defined at the `linux_like` level. +// The following are GNU extensions. +pub const GLOB_PERIOD: ::c_int = 1 << 7; +pub const GLOB_ALTDIRFUNC: ::c_int = 1 << 9; +pub const GLOB_BRACE: ::c_int = 1 << 10; +pub const GLOB_NOMAGIC: ::c_int = 1 << 11; +pub const GLOB_TILDE: ::c_int = 1 << 12; +pub const GLOB_ONLYDIR: ::c_int = 1 << 13; +pub const GLOB_TILDE_CHECK: ::c_int = 1 << 14; + +pub const MADV_COLLAPSE: ::c_int = 25; + +cfg_if! { + if #[cfg(any( + target_arch = "arm", + target_arch = "x86", + target_arch = "x86_64", + target_arch = "s390x", + target_arch = "riscv64", + target_arch = "riscv32" + ))] { + pub const PTHREAD_STACK_MIN: ::size_t = 16384; + } else if #[cfg(any( + target_arch = "sparc", + target_arch = "sparc64" + ))] { + pub const PTHREAD_STACK_MIN: ::size_t = 0x6000; + } else { + pub const PTHREAD_STACK_MIN: ::size_t = 131072; + } +} +pub const PTHREAD_MUTEX_ADAPTIVE_NP: ::c_int = 3; + +pub const REG_STARTEND: ::c_int = 4; + +pub const REG_EEND: ::c_int = 14; +pub const REG_ESIZE: ::c_int = 15; +pub const REG_ERPAREN: ::c_int = 16; + +extern "C" { + pub fn fgetspent_r( + fp: *mut ::FILE, + spbuf: *mut ::spwd, + buf: *mut ::c_char, + buflen: ::size_t, + spbufp: *mut *mut ::spwd, + ) -> ::c_int; + pub fn sgetspent_r( + s: *const ::c_char, + spbuf: *mut ::spwd, + buf: *mut ::c_char, + buflen: ::size_t, + spbufp: *mut *mut ::spwd, + ) -> ::c_int; + pub fn getspent_r( + spbuf: *mut ::spwd, + buf: *mut ::c_char, + buflen: ::size_t, + spbufp: *mut *mut ::spwd, + ) -> ::c_int; + pub fn qsort_r( + base: *mut ::c_void, + num: ::size_t, + size: ::size_t, + compar: ::Option< + unsafe extern "C" fn(*const ::c_void, *const ::c_void, *mut ::c_void) -> ::c_int, + >, + arg: *mut ::c_void, + ); + pub fn sendmmsg( + sockfd: ::c_int, + msgvec: *mut ::mmsghdr, + vlen: ::c_uint, + flags: ::c_int, + ) -> ::c_int; + pub fn recvmmsg( + sockfd: ::c_int, + msgvec: *mut ::mmsghdr, + vlen: ::c_uint, + flags: ::c_int, + timeout: *mut ::timespec, + ) -> ::c_int; + + 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 prlimit( + pid: ::pid_t, + resource: ::__rlimit_resource_t, + new_limit: *const ::rlimit, + old_limit: *mut ::rlimit, + ) -> ::c_int; + pub fn prlimit64( + pid: ::pid_t, + resource: ::__rlimit_resource_t, + new_limit: *const ::rlimit64, + old_limit: *mut ::rlimit64, + ) -> ::c_int; + pub fn utmpname(file: *const ::c_char) -> ::c_int; + pub fn utmpxname(file: *const ::c_char) -> ::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 getpt() -> ::c_int; + pub fn mallopt(param: ::c_int, value: ::c_int) -> ::c_int; + pub fn gettimeofday(tp: *mut ::timeval, tz: *mut ::timezone) -> ::c_int; + pub fn statx( + dirfd: ::c_int, + pathname: *const c_char, + flags: ::c_int, + 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 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 clock_adjtime(clk_id: ::clockid_t, buf: *mut ::timex) -> ::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 preadv2( + fd: ::c_int, + iov: *const ::iovec, + iovcnt: ::c_int, + offset: ::off_t, + flags: ::c_int, + ) -> ::ssize_t; + pub fn pwritev2( + fd: ::c_int, + iov: *const ::iovec, + iovcnt: ::c_int, + 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, + newdirfd: ::c_int, + newpath: *const ::c_char, + flags: ::c_uint, + ) -> ::c_int; + + // 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; + pub fn backtrace(buf: *mut *mut ::c_void, sz: ::c_int) -> ::c_int; + pub fn glob64( + pattern: *const ::c_char, + flags: ::c_int, + errfunc: ::Option ::c_int>, + pglob: *mut glob64_t, + ) -> ::c_int; + pub fn globfree64(pglob: *mut glob64_t); + pub fn ptrace(request: ::c_uint, ...) -> ::c_long; + pub fn pthread_attr_getaffinity_np( + attr: *const ::pthread_attr_t, + cpusetsize: ::size_t, + cpuset: *mut ::cpu_set_t, + ) -> ::c_int; + pub fn pthread_attr_setaffinity_np( + attr: *mut ::pthread_attr_t, + cpusetsize: ::size_t, + cpuset: *const ::cpu_set_t, + ) -> ::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_rwlockattr_getkind_np( + attr: *const ::pthread_rwlockattr_t, + val: *mut ::c_int, + ) -> ::c_int; + pub fn pthread_rwlockattr_setkind_np( + attr: *mut ::pthread_rwlockattr_t, + val: ::c_int, + ) -> ::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, + buf: *mut ::c_char, + buflen: ::size_t, + result: *mut *mut ::passwd, + ) -> ::c_int; + pub fn getgrent_r( + grp: *mut ::group, + buf: *mut ::c_char, + buflen: ::size_t, + result: *mut *mut ::group, + ) -> ::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 putpwent(p: *const ::passwd, stream: *mut ::FILE) -> ::c_int; + pub fn putgrent(grp: *const ::group, stream: *mut ::FILE) -> ::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 confstr(name: ::c_int, buf: *mut ::c_char, len: ::size_t) -> ::size_t; + 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; + 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; + pub fn gnu_get_libc_release() -> *const ::c_char; + pub fn gnu_get_libc_version() -> *const ::c_char; + + // posix/spawn.h + // 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 + pub fn getmntent_r( + stream: *mut ::FILE, + mntbuf: *mut ::mntent, + buf: *mut ::c_char, + buflen: ::c_int, + ) -> *mut ::mntent; + + pub fn execveat( + dirfd: ::c_int, + pathname: *const ::c_char, + argv: *const *mut c_char, + envp: *const *mut c_char, + flags: ::c_int, + ) -> ::c_int; + + // Added in `glibc` 2.34 + pub fn close_range(first: ::c_uint, last: ::c_uint, flags: ::c_int) -> ::c_int; + + pub fn mq_notify(mqdes: ::mqd_t, sevp: *const ::sigevent) -> ::c_int; + + pub fn epoll_pwait2( + epfd: ::c_int, + events: *mut ::epoll_event, + maxevents: ::c_int, + timeout: *const ::timespec, + sigmask: *const ::sigset_t, + ) -> ::c_int; +} + +cfg_if! { + if #[cfg(any(target_arch = "x86", + target_arch = "arm", + target_arch = "m68k", + target_arch = "csky", + target_arch = "mips", + target_arch = "mips32r6", + target_arch = "powerpc", + target_arch = "sparc", + target_arch = "riscv32"))] { + mod b32; + pub use self::b32::*; + } else if #[cfg(any(target_arch = "x86_64", + target_arch = "aarch64", + target_arch = "powerpc64", + target_arch = "mips64", + target_arch = "mips64r6", + target_arch = "s390x", + target_arch = "sparc64", + target_arch = "riscv64", + target_arch = "loongarch64"))] { + mod b64; + pub use self::b64::*; + } else { + // Unknown target_arch + } +} + +cfg_if! { + if #[cfg(libc_align)] { + mod align; + pub use self::align::*; + } else { + mod no_align; + pub use self::no_align::*; + } +} diff --git a/vendor/libc/src/unix/linux_like/linux/gnu/no_align.rs b/vendor/libc/src/unix/linux_like/linux/gnu/no_align.rs new file mode 100644 index 0000000..e32bf67 --- /dev/null +++ b/vendor/libc/src/unix/linux_like/linux/gnu/no_align.rs @@ -0,0 +1,10 @@ +s! { + // FIXME this is actually a union + pub struct sem_t { + #[cfg(target_pointer_width = "32")] + __size: [::c_char; 16], + #[cfg(target_pointer_width = "64")] + __size: [::c_char; 32], + __align: [::c_long; 0], + } +} diff --git a/vendor/libc/src/unix/linux_like/linux/mod.rs b/vendor/libc/src/unix/linux_like/linux/mod.rs new file mode 100644 index 0000000..20c4a16 --- /dev/null +++ b/vendor/libc/src/unix/linux_like/linux/mod.rs @@ -0,0 +1,5970 @@ +//! Linux-specific definitions for linux-like values + +pub type useconds_t = u32; +pub type dev_t = u64; +pub type socklen_t = u32; +pub type mode_t = u32; +pub type ino64_t = u64; +pub type off64_t = i64; +pub type blkcnt64_t = i64; +pub type rlim64_t = u64; +pub type mqd_t = ::c_int; +pub type nfds_t = ::c_ulong; +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_once_t = ::c_int; +pub type pthread_spinlock_t = ::c_int; +pub type __kernel_fsid_t = __c_anonymous__kernel_fsid_t; + +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; + +pub type Elf32_Half = u16; +pub type Elf32_Word = u32; +pub type Elf32_Off = u32; +pub type Elf32_Addr = u32; + +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 Elf32_Section = u16; +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; + +pub type eventfd_t = u64; +missing! { + #[cfg_attr(feature = "extra_traits", derive(Debug))] + pub enum fpos64_t {} // FIXME: fill this out with a struct +} + +e! { + #[repr(u32)] + pub enum tpacket_versions { + TPACKET_V1, + TPACKET_V2, + TPACKET_V3, + } +} + +s! { + pub struct glob_t { + pub gl_pathc: ::size_t, + pub gl_pathv: *mut *mut c_char, + pub gl_offs: ::size_t, + pub gl_flags: ::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_gecos: *mut ::c_char, + pub pw_dir: *mut ::c_char, + pub pw_shell: *mut ::c_char, + } + + pub struct spwd { + pub sp_namp: *mut ::c_char, + pub sp_pwdp: *mut ::c_char, + pub sp_lstchg: ::c_long, + pub sp_min: ::c_long, + pub sp_max: ::c_long, + pub sp_warn: ::c_long, + pub sp_inact: ::c_long, + pub sp_expire: ::c_long, + pub sp_flag: ::c_ulong, + } + + pub struct dqblk { + pub dqb_bhardlimit: u64, + pub dqb_bsoftlimit: u64, + pub dqb_curspace: u64, + pub dqb_ihardlimit: u64, + pub dqb_isoftlimit: u64, + pub dqb_curinodes: u64, + pub dqb_btime: u64, + pub dqb_itime: u64, + pub dqb_valid: u32, + } + + pub struct signalfd_siginfo { + pub ssi_signo: u32, + pub ssi_errno: i32, + pub ssi_code: i32, + pub ssi_pid: u32, + pub ssi_uid: u32, + pub ssi_fd: i32, + pub ssi_tid: u32, + pub ssi_band: u32, + pub ssi_overrun: u32, + pub ssi_trapno: u32, + pub ssi_status: i32, + pub ssi_int: i32, + pub ssi_ptr: u64, + pub ssi_utime: u64, + pub ssi_stime: u64, + pub ssi_addr: u64, + pub ssi_addr_lsb: u16, + _pad2: u16, + pub ssi_syscall: i32, + pub ssi_call_addr: u64, + pub ssi_arch: u32, + _pad: [u8; 28], + } + + pub struct itimerspec { + pub it_interval: ::timespec, + pub it_value: ::timespec, + } + + pub struct fsid_t { + __val: [::c_int; 2], + } + + pub struct fanout_args { + #[cfg(target_endian = "little")] + pub id: ::__u16, + pub type_flags: ::__u16, + #[cfg(target_endian = "big")] + pub id: ::__u16, + pub max_num_members: ::__u32, + } + + pub struct packet_mreq { + pub mr_ifindex: ::c_int, + pub mr_type: ::c_ushort, + pub mr_alen: ::c_ushort, + pub mr_address: [::c_uchar; 8], + } + + pub struct sockaddr_pkt { + pub spkt_family: ::c_ushort, + pub spkt_device: [::c_uchar; 14], + pub spkt_protocol: ::c_ushort, + } + + pub struct tpacket_auxdata { + pub tp_status: ::__u32, + pub tp_len: ::__u32, + pub tp_snaplen: ::__u32, + pub tp_mac: ::__u16, + pub tp_net: ::__u16, + pub tp_vlan_tci: ::__u16, + pub tp_vlan_tpid: ::__u16, + } + + pub struct tpacket_hdr { + pub tp_status: ::c_ulong, + pub tp_len: ::c_uint, + pub tp_snaplen: ::c_uint, + pub tp_mac: ::c_ushort, + pub tp_net: ::c_ushort, + pub tp_sec: ::c_uint, + pub tp_usec: ::c_uint, + } + + pub struct tpacket_hdr_variant1 { + pub tp_rxhash: ::__u32, + pub tp_vlan_tci: ::__u32, + pub tp_vlan_tpid: ::__u16, + pub tp_padding: ::__u16, + } + + pub struct tpacket2_hdr { + pub tp_status: ::__u32, + pub tp_len: ::__u32, + pub tp_snaplen: ::__u32, + pub tp_mac: ::__u16, + pub tp_net: ::__u16, + pub tp_sec: ::__u32, + pub tp_nsec: ::__u32, + pub tp_vlan_tci: ::__u16, + pub tp_vlan_tpid: ::__u16, + pub tp_padding: [::__u8; 4], + } + + pub struct tpacket_req { + pub tp_block_size: ::c_uint, + pub tp_block_nr: ::c_uint, + pub tp_frame_size: ::c_uint, + pub tp_frame_nr: ::c_uint, + } + + pub struct tpacket_req3 { + pub tp_block_size: ::c_uint, + pub tp_block_nr: ::c_uint, + pub tp_frame_size: ::c_uint, + pub tp_frame_nr: ::c_uint, + pub tp_retire_blk_tov: ::c_uint, + pub tp_sizeof_priv: ::c_uint, + pub tp_feature_req_word: ::c_uint, + } + + pub struct tpacket_stats { + pub tp_packets: ::c_uint, + pub tp_drops: ::c_uint, + } + + pub struct tpacket_stats_v3 { + pub tp_packets: ::c_uint, + pub tp_drops: ::c_uint, + pub tp_freeze_q_cnt: ::c_uint, + } + + pub struct tpacket3_hdr { + pub tp_next_offset: ::__u32, + pub tp_sec: ::__u32, + pub tp_nsec: ::__u32, + pub tp_snaplen: ::__u32, + pub tp_len: ::__u32, + pub tp_status: ::__u32, + pub tp_mac: ::__u16, + pub tp_net: ::__u16, + pub hv1: ::tpacket_hdr_variant1, + pub tp_padding: [::__u8; 8], + } + + pub struct tpacket_bd_ts { + pub ts_sec: ::c_uint, + pub ts_usec: ::c_uint, + } + + pub struct cpu_set_t { + #[cfg(all(target_pointer_width = "32", + not(target_arch = "x86_64")))] + bits: [u32; 32], + #[cfg(not(all(target_pointer_width = "32", + not(target_arch = "x86_64"))))] + bits: [u64; 16], + } + + pub struct if_nameindex { + pub if_index: ::c_uint, + pub if_name: *mut ::c_char, + } + + // System V IPC + pub struct msginfo { + pub msgpool: ::c_int, + pub msgmap: ::c_int, + pub msgmax: ::c_int, + pub msgmnb: ::c_int, + pub msgmni: ::c_int, + pub msgssz: ::c_int, + pub msgtql: ::c_int, + pub msgseg: ::c_ushort, + } + + pub struct sembuf { + pub sem_num: ::c_ushort, + pub sem_op: ::c_short, + pub sem_flg: ::c_short, + } + + 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], + } + + 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 dl_phdr_info { + #[cfg(target_pointer_width = "64")] + pub dlpi_addr: Elf64_Addr, + #[cfg(target_pointer_width = "32")] + pub dlpi_addr: Elf32_Addr, + + pub dlpi_name: *const ::c_char, + + #[cfg(target_pointer_width = "64")] + pub dlpi_phdr: *const Elf64_Phdr, + #[cfg(target_pointer_width = "32")] + pub dlpi_phdr: *const Elf32_Phdr, + + #[cfg(target_pointer_width = "64")] + pub dlpi_phnum: Elf64_Half, + #[cfg(target_pointer_width = "32")] + pub dlpi_phnum: Elf32_Half, + + // As of uClibc 1.0.36, the following fields are + // gated behind a "#if 0" block which always evaluates + // to false. So I'm just removing these, and if uClibc changes + // the #if block in the future to include the following fields, these + // will probably need including here. tsidea, skrap + // QNX (NTO) platform does not define these fields + #[cfg(not(any(target_env = "uclibc", target_os = "nto")))] + pub dlpi_adds: ::c_ulonglong, + #[cfg(not(any(target_env = "uclibc", target_os = "nto")))] + pub dlpi_subs: ::c_ulonglong, + #[cfg(not(any(target_env = "uclibc", target_os = "nto")))] + pub dlpi_tls_modid: ::size_t, + #[cfg(not(any(target_env = "uclibc", target_os = "nto")))] + pub dlpi_tls_data: *mut ::c_void, + } + + 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 __c_anonymous_elf32_rel { + pub r_offset: Elf32_Addr, + pub r_info: Elf32_Word, + } + + pub struct __c_anonymous_elf64_rel { + pub r_offset: Elf64_Addr, + pub r_info: Elf64_Xword, + } + + pub struct __c_anonymous__kernel_fsid_t { + pub val: [::c_int; 2], + } + + pub struct ucred { + pub pid: ::pid_t, + pub uid: ::uid_t, + pub gid: ::gid_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 posix_spawn_file_actions_t { + __allocated: ::c_int, + __used: ::c_int, + __actions: *mut ::c_int, + __pad: [::c_int; 16], + } + + pub struct posix_spawnattr_t { + __flags: ::c_short, + __pgrp: ::pid_t, + __sd: ::sigset_t, + __ss: ::sigset_t, + #[cfg(any(target_env = "musl", target_env = "ohos"))] + __prio: ::c_int, + #[cfg(not(any(target_env = "musl", target_env = "ohos")))] + __sp: ::sched_param, + __policy: ::c_int, + __pad: [::c_int; 16], + } + + pub struct genlmsghdr { + pub cmd: u8, + pub version: u8, + pub reserved: u16, + } + + pub struct in6_pktinfo { + pub ipi6_addr: ::in6_addr, + pub ipi6_ifindex: ::c_uint, + } + + pub struct arpd_request { + pub req: ::c_ushort, + pub ip: u32, + pub dev: ::c_ulong, + pub stamp: ::c_ulong, + pub updated: ::c_ulong, + pub ha: [::c_uchar; ::MAX_ADDR_LEN], + } + + pub struct inotify_event { + pub wd: ::c_int, + pub mask: u32, + pub cookie: u32, + pub len: u32 + } + + pub struct fanotify_response { + pub fd: ::c_int, + pub response: __u32, + } + + pub struct fanotify_event_info_header { + pub info_type: __u8, + pub pad: __u8, + pub len: __u16, + } + + pub struct fanotify_event_info_fid { + pub hdr: fanotify_event_info_header, + pub fsid: ::__kernel_fsid_t, + pub handle: [::c_uchar; 0], + } + + pub struct sockaddr_vm { + pub svm_family: ::sa_family_t, + pub svm_reserved1: ::c_ushort, + pub svm_port: ::c_uint, + pub svm_cid: ::c_uint, + pub svm_zero: [u8; 4] + } + + pub struct regmatch_t { + pub rm_so: regoff_t, + pub rm_eo: regoff_t, + } + + pub struct sock_extended_err { + pub ee_errno: u32, + pub ee_origin: u8, + pub ee_type: u8, + pub ee_code: u8, + pub ee_pad: u8, + pub ee_info: u32, + pub ee_data: u32, + } + + // linux/can.h + pub struct __c_anonymous_sockaddr_can_tp { + pub rx_id: canid_t, + pub tx_id: canid_t, + } + + pub struct __c_anonymous_sockaddr_can_j1939 { + pub name: u64, + pub pgn: u32, + pub addr: u8, + } + + pub struct can_filter { + 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 seccomp_notif_sizes { + pub seccomp_notif: ::__u16, + pub seccomp_notif_resp: ::__u16, + pub seccomp_data: ::__u16, + } + + pub struct seccomp_notif { + pub id: ::__u64, + pub pid: ::__u32, + pub flags: ::__u32, + pub data: seccomp_data, + } + + pub struct seccomp_notif_resp { + pub id: ::__u64, + pub val: ::__s64, + pub error: ::__s32, + pub flags: ::__u32, + } + + pub struct seccomp_notif_addfd { + pub id: ::__u64, + pub flags: ::__u32, + pub srcfd: ::__u32, + pub newfd: ::__u32, + pub newfd_flags: ::__u32, + } + + 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, + } + + pub struct rlimit64 { + pub rlim_cur: rlim64_t, + pub rlim_max: rlim64_t, + } + + // linux/tls.h + + pub struct tls_crypto_info { + pub version: ::__u16, + pub cipher_type: ::__u16, + } + + pub struct tls12_crypto_info_aes_gcm_128 { + pub info: tls_crypto_info, + pub iv: [::c_uchar; TLS_CIPHER_AES_GCM_128_IV_SIZE], + pub key: [::c_uchar; TLS_CIPHER_AES_GCM_128_KEY_SIZE], + pub salt: [::c_uchar; TLS_CIPHER_AES_GCM_128_SALT_SIZE], + pub rec_seq: [::c_uchar; TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE], + } + + pub struct tls12_crypto_info_aes_gcm_256 { + pub info: tls_crypto_info, + pub iv: [::c_uchar; TLS_CIPHER_AES_GCM_256_IV_SIZE], + pub key: [::c_uchar; TLS_CIPHER_AES_GCM_256_KEY_SIZE], + pub salt: [::c_uchar; TLS_CIPHER_AES_GCM_256_SALT_SIZE], + pub rec_seq: [::c_uchar; TLS_CIPHER_AES_GCM_256_REC_SEQ_SIZE], + } + + pub struct tls12_crypto_info_chacha20_poly1305 { + pub info: tls_crypto_info, + pub iv: [::c_uchar; TLS_CIPHER_CHACHA20_POLY1305_IV_SIZE], + pub key: [::c_uchar; TLS_CIPHER_CHACHA20_POLY1305_KEY_SIZE], + pub salt: [::c_uchar; TLS_CIPHER_CHACHA20_POLY1305_SALT_SIZE], + pub rec_seq: [::c_uchar; TLS_CIPHER_CHACHA20_POLY1305_REC_SEQ_SIZE], + } +} + +s_no_extra_traits! { + pub struct sockaddr_nl { + pub nl_family: ::sa_family_t, + nl_pad: ::c_ushort, + pub nl_pid: u32, + pub nl_groups: u32 + } + + pub struct dirent { + pub d_ino: ::ino_t, + pub d_off: ::off_t, + pub d_reclen: ::c_ushort, + pub d_type: ::c_uchar, + pub d_name: [::c_char; 256], + } + + pub struct sockaddr_alg { + pub salg_family: ::sa_family_t, + pub salg_type: [::c_uchar; 14], + pub salg_feat: u32, + pub salg_mask: u32, + pub salg_name: [::c_uchar; 64], + } + + pub struct 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( + note = "this struct has unsafe trait implementations that will be \ + removed in the future", + since = "0.2.80" + )] + pub struct af_alg_iv { + pub ivlen: u32, + pub iv: [::c_uchar; 0], + } + + // x32 compatibility + // See https://sourceware.org/bugzilla/show_bug.cgi?id=21279 + pub struct mq_attr { + #[cfg(all(target_arch = "x86_64", target_pointer_width = "32"))] + pub mq_flags: i64, + #[cfg(all(target_arch = "x86_64", target_pointer_width = "32"))] + pub mq_maxmsg: i64, + #[cfg(all(target_arch = "x86_64", target_pointer_width = "32"))] + pub mq_msgsize: i64, + #[cfg(all(target_arch = "x86_64", target_pointer_width = "32"))] + pub mq_curmsgs: i64, + #[cfg(all(target_arch = "x86_64", target_pointer_width = "32"))] + pad: [i64; 4], + + #[cfg(not(all(target_arch = "x86_64", target_pointer_width = "32")))] + pub mq_flags: ::c_long, + #[cfg(not(all(target_arch = "x86_64", target_pointer_width = "32")))] + pub mq_maxmsg: ::c_long, + #[cfg(not(all(target_arch = "x86_64", target_pointer_width = "32")))] + pub mq_msgsize: ::c_long, + #[cfg(not(all(target_arch = "x86_64", target_pointer_width = "32")))] + pub mq_curmsgs: ::c_long, + #[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, + } + + #[cfg(libc_union)] + pub union __c_anonymous_ifc_ifcu { + pub ifcu_buf: *mut ::c_char, + pub ifcu_req: *mut ::ifreq, + } + + /* Structure used in SIOCGIFCONF request. Used to retrieve interface + configuration for machine (useful for programs which must know all + networks accessible). */ + pub struct ifconf { + pub ifc_len: ::c_int, /* Size of buffer. */ + #[cfg(libc_union)] + pub ifc_ifcu: __c_anonymous_ifc_ifcu, + #[cfg(not(libc_union))] + pub ifc_ifcu: *mut ::ifreq, + } + + pub struct hwtstamp_config { + pub flags: ::c_int, + pub tx_type: ::c_int, + pub rx_filter: ::c_int, + } + + pub struct dirent64 { + pub d_ino: ::ino64_t, + pub d_off: ::off64_t, + pub d_reclen: ::c_ushort, + pub d_type: ::c_uchar, + pub d_name: [::c_char; 256], + } + + pub struct sched_attr { + pub size: ::__u32, + pub sched_policy: ::__u32, + pub sched_flags: ::__u64, + pub sched_nice: ::__s32, + pub sched_priority: ::__u32, + pub sched_runtime: ::__u64, + pub sched_deadline: ::__u64, + pub sched_period: ::__u64, + } + + #[cfg(libc_union)] + #[allow(missing_debug_implementations)] + pub union tpacket_req_u { + pub req: ::tpacket_req, + pub req3: ::tpacket_req3, + } + + #[cfg(libc_union)] + #[allow(missing_debug_implementations)] + pub union tpacket_bd_header_u { + pub bh1: ::tpacket_hdr_v1, + } + + #[cfg(libc_union)] + #[allow(missing_debug_implementations)] + pub struct tpacket_block_desc { + pub version: ::__u32, + pub offset_to_priv: ::__u32, + pub hdr: ::tpacket_bd_header_u, + } +} + +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! { + if #[cfg(libc_union)] { + s_no_extra_traits! { + // linux/can.h + #[allow(missing_debug_implementations)] + pub union __c_anonymous_sockaddr_can_can_addr { + pub tp: __c_anonymous_sockaddr_can_tp, + pub j1939: __c_anonymous_sockaddr_can_j1939, + } + + #[allow(missing_debug_implementations)] + pub struct sockaddr_can { + pub can_family: ::sa_family_t, + pub can_ifindex: ::c_int, + pub can_addr: __c_anonymous_sockaddr_can_can_addr, + } + } + } +} + +cfg_if! { + if #[cfg(feature = "extra_traits")] { + impl PartialEq for sockaddr_nl { + fn eq(&self, other: &sockaddr_nl) -> bool { + self.nl_family == other.nl_family && + self.nl_pid == other.nl_pid && + self.nl_groups == other.nl_groups + } + } + impl Eq for sockaddr_nl {} + impl ::fmt::Debug for sockaddr_nl { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("sockaddr_nl") + .field("nl_family", &self.nl_family) + .field("nl_pid", &self.nl_pid) + .field("nl_groups", &self.nl_groups) + .finish() + } + } + impl ::hash::Hash for sockaddr_nl { + fn hash(&self, state: &mut H) { + self.nl_family.hash(state); + self.nl_pid.hash(state); + self.nl_groups.hash(state); + } + } + + impl PartialEq for dirent { + fn eq(&self, other: &dirent) -> bool { + self.d_ino == other.d_ino + && self.d_off == other.d_off + && self.d_reclen == other.d_reclen + && self.d_type == other.d_type + && self + .d_name + .iter() + .zip(other.d_name.iter()) + .all(|(a,b)| a == b) + } + } + + impl Eq for dirent {} + + impl ::fmt::Debug for dirent { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("dirent") + .field("d_ino", &self.d_ino) + .field("d_off", &self.d_off) + .field("d_reclen", &self.d_reclen) + .field("d_type", &self.d_type) + // FIXME: .field("d_name", &self.d_name) + .finish() + } + } + + impl ::hash::Hash for dirent { + fn hash(&self, state: &mut H) { + self.d_ino.hash(state); + self.d_off.hash(state); + self.d_reclen.hash(state); + self.d_type.hash(state); + self.d_name.hash(state); + } + } + + impl PartialEq for dirent64 { + fn eq(&self, other: &dirent64) -> bool { + self.d_ino == other.d_ino + && self.d_off == other.d_off + && self.d_reclen == other.d_reclen + && self.d_type == other.d_type + && self + .d_name + .iter() + .zip(other.d_name.iter()) + .all(|(a,b)| a == b) + } + } + + impl Eq for dirent64 {} + + impl ::fmt::Debug for dirent64 { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("dirent64") + .field("d_ino", &self.d_ino) + .field("d_off", &self.d_off) + .field("d_reclen", &self.d_reclen) + .field("d_type", &self.d_type) + // FIXME: .field("d_name", &self.d_name) + .finish() + } + } + + impl ::hash::Hash for dirent64 { + fn hash(&self, state: &mut H) { + self.d_ino.hash(state); + self.d_off.hash(state); + self.d_reclen.hash(state); + self.d_type.hash(state); + self.d_name.hash(state); + } + } + + impl PartialEq for pthread_cond_t { + fn eq(&self, other: &pthread_cond_t) -> bool { + self.size.iter().zip(other.size.iter()).all(|(a,b)| a == b) + } + } + + impl Eq for pthread_cond_t {} + + impl ::fmt::Debug for pthread_cond_t { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("pthread_cond_t") + // FIXME: .field("size", &self.size) + .finish() + } + } + + impl ::hash::Hash for pthread_cond_t { + fn hash(&self, state: &mut H) { + self.size.hash(state); + } + } + + impl PartialEq for pthread_mutex_t { + fn eq(&self, other: &pthread_mutex_t) -> bool { + self.size.iter().zip(other.size.iter()).all(|(a,b)| a == b) + } + } + + impl Eq for pthread_mutex_t {} + + impl ::fmt::Debug for pthread_mutex_t { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("pthread_mutex_t") + // FIXME: .field("size", &self.size) + .finish() + } + } + + impl ::hash::Hash for pthread_mutex_t { + fn hash(&self, state: &mut H) { + self.size.hash(state); + } + } + + impl PartialEq for pthread_rwlock_t { + fn eq(&self, other: &pthread_rwlock_t) -> bool { + self.size.iter().zip(other.size.iter()).all(|(a,b)| a == b) + } + } + + impl Eq for pthread_rwlock_t {} + + impl ::fmt::Debug for pthread_rwlock_t { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("pthread_rwlock_t") + // FIXME: .field("size", &self.size) + .finish() + } + } + + impl ::hash::Hash for pthread_rwlock_t { + fn hash(&self, state: &mut H) { + self.size.hash(state); + } + } + + 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 + && self + .salg_type + .iter() + .zip(other.salg_type.iter()) + .all(|(a, b)| a == b) + && self.salg_feat == other.salg_feat + && self.salg_mask == other.salg_mask + && self + .salg_name + .iter() + .zip(other.salg_name.iter()) + .all(|(a, b)| a == b) + } + } + + impl Eq for sockaddr_alg {} + + impl ::fmt::Debug for sockaddr_alg { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("sockaddr_alg") + .field("salg_family", &self.salg_family) + .field("salg_type", &self.salg_type) + .field("salg_feat", &self.salg_feat) + .field("salg_mask", &self.salg_mask) + .field("salg_name", &&self.salg_name[..]) + .finish() + } + } + + impl ::hash::Hash for sockaddr_alg { + fn hash(&self, state: &mut H) { + self.salg_family.hash(state); + self.salg_type.hash(state); + self.salg_feat.hash(state); + self.salg_mask.hash(state); + self.salg_name.hash(state); + } + } + + impl 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] { + unsafe { + ::core::slice::from_raw_parts( + self.iv.as_ptr(), + self.ivlen as usize + ) + } + } + } + + #[allow(deprecated)] + impl PartialEq for af_alg_iv { + fn eq(&self, other: &af_alg_iv) -> bool { + *self.as_slice() == *other.as_slice() + } + } + + #[allow(deprecated)] + impl Eq for af_alg_iv {} + + #[allow(deprecated)] + impl ::fmt::Debug for af_alg_iv { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("af_alg_iv") + .field("ivlen", &self.ivlen) + .finish() + } + } + + #[allow(deprecated)] + impl ::hash::Hash for af_alg_iv { + fn hash(&self, state: &mut H) { + self.as_slice().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); + } + } + #[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() + } + } + + #[cfg(libc_union)] + impl ::fmt::Debug for __c_anonymous_ifc_ifcu { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("ifr_ifru") + .field("ifcu_buf", unsafe { &self.ifcu_buf }) + .field("ifcu_req", unsafe { &self.ifcu_req }) + .finish() + } + } + impl ::fmt::Debug for ifconf { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("ifconf") + .field("ifc_len", &self.ifc_len) + .field("ifc_ifcu", &self.ifc_ifcu) + .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); + } + } + + impl ::fmt::Debug for sched_attr { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("sched_attr") + .field("size", &self.size) + .field("sched_policy", &self.sched_policy) + .field("sched_flags", &self.sched_flags) + .field("sched_nice", &self.sched_nice) + .field("sched_priority", &self.sched_priority) + .field("sched_runtime", &self.sched_runtime) + .field("sched_deadline", &self.sched_deadline) + .field("sched_period", &self.sched_period) + .finish() + } + } + impl PartialEq for sched_attr { + fn eq(&self, other: &sched_attr) -> bool { + self.size == other.size && + self.sched_policy == other.sched_policy && + self.sched_flags == other.sched_flags && + self.sched_nice == other.sched_nice && + self.sched_priority == other.sched_priority && + self.sched_runtime == other.sched_runtime && + self.sched_deadline == other.sched_deadline && + self.sched_period == other.sched_period + } + } + impl Eq for sched_attr {} + impl ::hash::Hash for sched_attr { + fn hash(&self, state: &mut H) { + self.size.hash(state); + self.sched_policy.hash(state); + self.sched_flags.hash(state); + self.sched_nice.hash(state); + self.sched_priority.hash(state); + self.sched_runtime.hash(state); + self.sched_deadline.hash(state); + self.sched_period.hash(state); + } + } + } +} + +cfg_if! { + if #[cfg(all(any(target_env = "gnu", target_env = "musl", target_env = "ohos"), + any(target_arch = "x86_64", target_arch = "x86")))] { + extern "C" { + pub fn iopl(level: ::c_int) -> ::c_int; + pub fn ioperm(from: ::c_ulong, num: ::c_ulong, turn_on: ::c_int) -> ::c_int; + } + } +} + +cfg_if! { + 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; + 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; + } +} + +pub const RUSAGE_CHILDREN: ::c_int = -1; +pub const L_tmpnam: ::c_uint = 20; +pub const _PC_LINK_MAX: ::c_int = 0; +pub const _PC_MAX_CANON: ::c_int = 1; +pub const _PC_MAX_INPUT: ::c_int = 2; +pub const _PC_NAME_MAX: ::c_int = 3; +pub const _PC_PATH_MAX: ::c_int = 4; +pub const _PC_PIPE_BUF: ::c_int = 5; +pub const _PC_CHOWN_RESTRICTED: ::c_int = 6; +pub const _PC_NO_TRUNC: ::c_int = 7; +pub const _PC_VDISABLE: ::c_int = 8; +pub const _PC_SYNC_IO: ::c_int = 9; +pub const _PC_ASYNC_IO: ::c_int = 10; +pub const _PC_PRIO_IO: ::c_int = 11; +pub const _PC_SOCK_MAXBUF: ::c_int = 12; +pub const _PC_FILESIZEBITS: ::c_int = 13; +pub const _PC_REC_INCR_XFER_SIZE: ::c_int = 14; +pub const _PC_REC_MAX_XFER_SIZE: ::c_int = 15; +pub const _PC_REC_MIN_XFER_SIZE: ::c_int = 16; +pub const _PC_REC_XFER_ALIGN: ::c_int = 17; +pub const _PC_ALLOC_SIZE_MIN: ::c_int = 18; +pub const _PC_SYMLINK_MAX: ::c_int = 19; +pub const _PC_2_SYMLINKS: ::c_int = 20; + +pub const MS_NOUSER: ::c_ulong = 0xffffffff80000000; + +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_STREAM_MAX: ::c_int = 5; +pub const _SC_TZNAME_MAX: ::c_int = 6; +pub const _SC_JOB_CONTROL: ::c_int = 7; +pub const _SC_SAVED_IDS: ::c_int = 8; +pub const _SC_REALTIME_SIGNALS: ::c_int = 9; +pub const _SC_PRIORITY_SCHEDULING: ::c_int = 10; +pub const _SC_TIMERS: ::c_int = 11; +pub const _SC_ASYNCHRONOUS_IO: ::c_int = 12; +pub const _SC_PRIORITIZED_IO: ::c_int = 13; +pub const _SC_SYNCHRONIZED_IO: ::c_int = 14; +pub const _SC_FSYNC: ::c_int = 15; +pub const _SC_MAPPED_FILES: ::c_int = 16; +pub const _SC_MEMLOCK: ::c_int = 17; +pub const _SC_MEMLOCK_RANGE: ::c_int = 18; +pub const _SC_MEMORY_PROTECTION: ::c_int = 19; +pub const _SC_MESSAGE_PASSING: ::c_int = 20; +pub const _SC_SEMAPHORES: ::c_int = 21; +pub const _SC_SHARED_MEMORY_OBJECTS: ::c_int = 22; +pub const _SC_AIO_LISTIO_MAX: ::c_int = 23; +pub const _SC_AIO_MAX: ::c_int = 24; +pub const _SC_AIO_PRIO_DELTA_MAX: ::c_int = 25; +pub const _SC_DELAYTIMER_MAX: ::c_int = 26; +pub const _SC_MQ_OPEN_MAX: ::c_int = 27; +pub const _SC_MQ_PRIO_MAX: ::c_int = 28; +pub const _SC_VERSION: ::c_int = 29; +pub const _SC_PAGESIZE: ::c_int = 30; +pub const _SC_PAGE_SIZE: ::c_int = _SC_PAGESIZE; +pub const _SC_RTSIG_MAX: ::c_int = 31; +pub const _SC_SEM_NSEMS_MAX: ::c_int = 32; +pub const _SC_SEM_VALUE_MAX: ::c_int = 33; +pub const _SC_SIGQUEUE_MAX: ::c_int = 34; +pub const _SC_TIMER_MAX: ::c_int = 35; +pub const _SC_BC_BASE_MAX: ::c_int = 36; +pub const _SC_BC_DIM_MAX: ::c_int = 37; +pub const _SC_BC_SCALE_MAX: ::c_int = 38; +pub const _SC_BC_STRING_MAX: ::c_int = 39; +pub const _SC_COLL_WEIGHTS_MAX: ::c_int = 40; +pub const _SC_EXPR_NEST_MAX: ::c_int = 42; +pub const _SC_LINE_MAX: ::c_int = 43; +pub const _SC_RE_DUP_MAX: ::c_int = 44; +pub const _SC_2_VERSION: ::c_int = 46; +pub const _SC_2_C_BIND: ::c_int = 47; +pub const _SC_2_C_DEV: ::c_int = 48; +pub const _SC_2_FORT_DEV: ::c_int = 49; +pub const _SC_2_FORT_RUN: ::c_int = 50; +pub const _SC_2_SW_DEV: ::c_int = 51; +pub const _SC_2_LOCALEDEF: ::c_int = 52; +pub const _SC_UIO_MAXIOV: ::c_int = 60; +pub const _SC_IOV_MAX: ::c_int = 60; +pub const _SC_THREADS: ::c_int = 67; +pub const _SC_THREAD_SAFE_FUNCTIONS: ::c_int = 68; +pub const _SC_GETGR_R_SIZE_MAX: ::c_int = 69; +pub const _SC_GETPW_R_SIZE_MAX: ::c_int = 70; +pub const _SC_LOGIN_NAME_MAX: ::c_int = 71; +pub const _SC_TTY_NAME_MAX: ::c_int = 72; +pub const _SC_THREAD_DESTRUCTOR_ITERATIONS: ::c_int = 73; +pub const _SC_THREAD_KEYS_MAX: ::c_int = 74; +pub const _SC_THREAD_STACK_MIN: ::c_int = 75; +pub const _SC_THREAD_THREADS_MAX: ::c_int = 76; +pub const _SC_THREAD_ATTR_STACKADDR: ::c_int = 77; +pub const _SC_THREAD_ATTR_STACKSIZE: ::c_int = 78; +pub const _SC_THREAD_PRIORITY_SCHEDULING: ::c_int = 79; +pub const _SC_THREAD_PRIO_INHERIT: ::c_int = 80; +pub const _SC_THREAD_PRIO_PROTECT: ::c_int = 81; +pub const _SC_THREAD_PROCESS_SHARED: ::c_int = 82; +pub const _SC_NPROCESSORS_CONF: ::c_int = 83; +pub const _SC_NPROCESSORS_ONLN: ::c_int = 84; +pub const _SC_PHYS_PAGES: ::c_int = 85; +pub const _SC_AVPHYS_PAGES: ::c_int = 86; +pub const _SC_ATEXIT_MAX: ::c_int = 87; +pub const _SC_PASS_MAX: ::c_int = 88; +pub const _SC_XOPEN_VERSION: ::c_int = 89; +pub const _SC_XOPEN_XCU_VERSION: ::c_int = 90; +pub const _SC_XOPEN_UNIX: ::c_int = 91; +pub const _SC_XOPEN_CRYPT: ::c_int = 92; +pub const _SC_XOPEN_ENH_I18N: ::c_int = 93; +pub const _SC_XOPEN_SHM: ::c_int = 94; +pub const _SC_2_CHAR_TERM: ::c_int = 95; +pub const _SC_2_UPE: ::c_int = 97; +pub const _SC_XOPEN_XPG2: ::c_int = 98; +pub const _SC_XOPEN_XPG3: ::c_int = 99; +pub const _SC_XOPEN_XPG4: ::c_int = 100; +pub const _SC_NZERO: ::c_int = 109; +pub const _SC_XBS5_ILP32_OFF32: ::c_int = 125; +pub const _SC_XBS5_ILP32_OFFBIG: ::c_int = 126; +pub const _SC_XBS5_LP64_OFF64: ::c_int = 127; +pub const _SC_XBS5_LPBIG_OFFBIG: ::c_int = 128; +pub const _SC_XOPEN_LEGACY: ::c_int = 129; +pub const _SC_XOPEN_REALTIME: ::c_int = 130; +pub const _SC_XOPEN_REALTIME_THREADS: ::c_int = 131; +pub const _SC_ADVISORY_INFO: ::c_int = 132; +pub const _SC_BARRIERS: ::c_int = 133; +pub const _SC_CLOCK_SELECTION: ::c_int = 137; +pub const _SC_CPUTIME: ::c_int = 138; +pub const _SC_THREAD_CPUTIME: ::c_int = 139; +pub const _SC_MONOTONIC_CLOCK: ::c_int = 149; +pub const _SC_READER_WRITER_LOCKS: ::c_int = 153; +pub const _SC_SPIN_LOCKS: ::c_int = 154; +pub const _SC_REGEXP: ::c_int = 155; +pub const _SC_SHELL: ::c_int = 157; +pub const _SC_SPAWN: ::c_int = 159; +pub const _SC_SPORADIC_SERVER: ::c_int = 160; +pub const _SC_THREAD_SPORADIC_SERVER: ::c_int = 161; +pub const _SC_TIMEOUTS: ::c_int = 164; +pub const _SC_TYPED_MEMORY_OBJECTS: ::c_int = 165; +pub const _SC_2_PBS: ::c_int = 168; +pub const _SC_2_PBS_ACCOUNTING: ::c_int = 169; +pub const _SC_2_PBS_LOCATE: ::c_int = 170; +pub const _SC_2_PBS_MESSAGE: ::c_int = 171; +pub const _SC_2_PBS_TRACK: ::c_int = 172; +pub const _SC_SYMLOOP_MAX: ::c_int = 173; +pub const _SC_STREAMS: ::c_int = 174; +pub const _SC_2_PBS_CHECKPOINT: ::c_int = 175; +pub const _SC_V6_ILP32_OFF32: ::c_int = 176; +pub const _SC_V6_ILP32_OFFBIG: ::c_int = 177; +pub const _SC_V6_LP64_OFF64: ::c_int = 178; +pub const _SC_V6_LPBIG_OFFBIG: ::c_int = 179; +pub const _SC_HOST_NAME_MAX: ::c_int = 180; +pub const _SC_TRACE: ::c_int = 181; +pub const _SC_TRACE_EVENT_FILTER: ::c_int = 182; +pub const _SC_TRACE_INHERIT: ::c_int = 183; +pub const _SC_TRACE_LOG: ::c_int = 184; +pub const _SC_IPV6: ::c_int = 235; +pub const _SC_RAW_SOCKETS: ::c_int = 236; +pub const _SC_V7_ILP32_OFF32: ::c_int = 237; +pub const _SC_V7_ILP32_OFFBIG: ::c_int = 238; +pub const _SC_V7_LP64_OFF64: ::c_int = 239; +pub const _SC_V7_LPBIG_OFFBIG: ::c_int = 240; +pub const _SC_SS_REPL_MAX: ::c_int = 241; +pub const _SC_TRACE_EVENT_NAME_MAX: ::c_int = 242; +pub const _SC_TRACE_NAME_MAX: ::c_int = 243; +pub const _SC_TRACE_SYS_MAX: ::c_int = 244; +pub const _SC_TRACE_USER_EVENT_MAX: ::c_int = 245; +pub const _SC_XOPEN_STREAMS: ::c_int = 246; +pub const _SC_THREAD_ROBUST_PRIO_INHERIT: ::c_int = 247; +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; +pub const AT_PHDR: ::c_ulong = 3; +pub const AT_PHENT: ::c_ulong = 4; +pub const AT_PHNUM: ::c_ulong = 5; +pub const AT_PAGESZ: ::c_ulong = 6; +pub const AT_BASE: ::c_ulong = 7; +pub const AT_FLAGS: ::c_ulong = 8; +pub const AT_ENTRY: ::c_ulong = 9; +pub const AT_NOTELF: ::c_ulong = 10; +pub const AT_UID: ::c_ulong = 11; +pub const AT_EUID: ::c_ulong = 12; +pub const AT_GID: ::c_ulong = 13; +pub const AT_EGID: ::c_ulong = 14; +pub const AT_PLATFORM: ::c_ulong = 15; +pub const AT_HWCAP: ::c_ulong = 16; +pub const AT_CLKTCK: ::c_ulong = 17; + +pub const AT_SECURE: ::c_ulong = 23; +pub const AT_BASE_PLATFORM: ::c_ulong = 24; +pub const AT_RANDOM: ::c_ulong = 25; +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 AT_MINSIGSTKSZ: ::c_ulong = 51; + +pub const GLOB_ERR: ::c_int = 1 << 0; +pub const GLOB_MARK: ::c_int = 1 << 1; +pub const GLOB_NOSORT: ::c_int = 1 << 2; +pub const GLOB_DOOFFS: ::c_int = 1 << 3; +pub const GLOB_NOCHECK: ::c_int = 1 << 4; +pub const GLOB_APPEND: ::c_int = 1 << 5; +pub const GLOB_NOESCAPE: ::c_int = 1 << 6; + +pub const GLOB_NOSPACE: ::c_int = 1; +pub const GLOB_ABORTED: ::c_int = 2; +pub const GLOB_NOMATCH: ::c_int = 3; + +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; +pub const S_IREAD: mode_t = 256; + +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_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; + +// 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_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; +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/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; +// Used in TUNSETIFF to bring up tun/tap without carrier +pub const IFF_NO_CARRIER: ::c_int = 0x0040; +pub const IFF_NO_PI: ::c_int = 0x1000; +// Read queue size +pub const TUN_READQ_SIZE: ::c_short = 500; +// TUN device type flags: deprecated. Use IFF_TUN/IFF_TAP instead. +pub const TUN_TUN_DEV: ::c_short = ::IFF_TUN as ::c_short; +pub const TUN_TAP_DEV: ::c_short = ::IFF_TAP as ::c_short; +pub const TUN_TYPE_MASK: ::c_short = 0x000f; +// This flag has no real effect +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; +// read-only flag +pub const IFF_PERSIST: ::c_int = 0x0800; +pub const IFF_NOFILTER: ::c_int = 0x1000; +// Socket options +pub const TUN_TX_TIMESTAMP: ::c_int = 1; +// Features for GSO (TUNSETOFFLOAD) +pub const TUN_F_CSUM: ::c_uint = 0x01; +pub const TUN_F_TSO4: ::c_uint = 0x02; +pub const TUN_F_TSO6: ::c_uint = 0x04; +pub const TUN_F_TSO_ECN: ::c_uint = 0x08; +pub const TUN_F_UFO: ::c_uint = 0x10; +pub const TUN_F_USO4: ::c_uint = 0x20; +pub const TUN_F_USO6: ::c_uint = 0x40; +// Protocol info prepended to the packets (when IFF_NO_PI is not set) +pub const TUN_PKT_STRIP: ::c_int = 0x0001; +// Accept all multicast packets +pub const TUN_FLT_ALLMULTI: ::c_int = 0x0001; + +// Since Linux 3.1 +pub const SEEK_DATA: ::c_int = 3; +pub const SEEK_HOLE: ::c_int = 4; + +pub const ST_RDONLY: ::c_ulong = 1; +pub const ST_NOSUID: ::c_ulong = 2; +pub const ST_NODEV: ::c_ulong = 4; +pub const ST_NOEXEC: ::c_ulong = 8; +pub const ST_SYNCHRONOUS: ::c_ulong = 16; +pub const ST_MANDLOCK: ::c_ulong = 64; +pub const ST_WRITE: ::c_ulong = 128; +pub const ST_APPEND: ::c_ulong = 256; +pub const ST_IMMUTABLE: ::c_ulong = 512; +pub const ST_NOATIME: ::c_ulong = 1024; +pub const ST_NODIRATIME: ::c_ulong = 2048; + +pub const RTLD_NEXT: *mut ::c_void = -1i64 as *mut ::c_void; +pub const RTLD_DEFAULT: *mut ::c_void = 0i64 as *mut ::c_void; +pub const RTLD_NODELETE: ::c_int = 0x1000; +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], + }; + pub const PTHREAD_COND_INITIALIZER: pthread_cond_t = pthread_cond_t { + size: [0; __SIZEOF_PTHREAD_COND_T], + }; + pub const PTHREAD_RWLOCK_INITIALIZER: pthread_rwlock_t = pthread_rwlock_t { + size: [0; __SIZEOF_PTHREAD_RWLOCK_T], + }; +} +pub const PTHREAD_BARRIER_SERIAL_THREAD: ::c_int = -1; +pub const PTHREAD_ONCE_INIT: pthread_once_t = 0; +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 PTHREAD_INHERIT_SCHED: ::c_int = 0; +pub const PTHREAD_EXPLICIT_SCHED: ::c_int = 1; +pub const __SIZEOF_PTHREAD_COND_T: usize = 48; + +pub const RENAME_NOREPLACE: ::c_uint = 1; +pub const RENAME_EXCHANGE: ::c_uint = 2; +pub const RENAME_WHITEOUT: ::c_uint = 4; + +// netinet/in.h +// NOTE: These are in addition to the constants defined in src/unix/mod.rs + +#[deprecated( + since = "0.2.80", + note = "This value was increased in the newer kernel \ + and we'll change this following upstream in the future release. \ + See #1896 for more info." +)] +pub const IPPROTO_MAX: ::c_int = 256; + +// 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 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; + +pub const SHM_RDONLY: ::c_int = 0o10000; +pub const SHM_RND: ::c_int = 0o20000; +pub const SHM_REMAP: ::c_int = 0o40000; + +pub const SHM_LOCK: ::c_int = 11; +pub const SHM_UNLOCK: ::c_int = 12; + +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 QFMT_VFS_OLD: ::c_int = 1; +pub const QFMT_VFS_V0: ::c_int = 2; +pub const QFMT_VFS_V1: ::c_int = 4; + +pub const EFD_SEMAPHORE: ::c_int = 0x1; + +pub const LOG_NFACILITIES: ::c_int = 24; + +pub const SEM_FAILED: *mut ::sem_t = 0 as *mut sem_t; + +pub const RB_AUTOBOOT: ::c_int = 0x01234567u32 as i32; +pub const RB_HALT_SYSTEM: ::c_int = 0xcdef0123u32 as i32; +pub const RB_ENABLE_CAD: ::c_int = 0x89abcdefu32 as i32; +pub const RB_DISABLE_CAD: ::c_int = 0x00000000u32 as i32; +pub const RB_POWER_OFF: ::c_int = 0x4321fedcu32 as i32; +pub const RB_SW_SUSPEND: ::c_int = 0xd000fce2u32 as i32; +pub const RB_KEXEC: ::c_int = 0x45584543u32 as i32; + +pub const AI_PASSIVE: ::c_int = 0x0001; +pub const AI_CANONNAME: ::c_int = 0x0002; +pub const AI_NUMERICHOST: ::c_int = 0x0004; +pub const AI_V4MAPPED: ::c_int = 0x0008; +pub const AI_ALL: ::c_int = 0x0010; +pub const AI_ADDRCONFIG: ::c_int = 0x0020; + +pub const AI_NUMERICSERV: ::c_int = 0x0400; + +pub const EAI_BADFLAGS: ::c_int = -1; +pub const EAI_NONAME: ::c_int = -2; +pub const EAI_AGAIN: ::c_int = -3; +pub const EAI_FAIL: ::c_int = -4; +pub const EAI_NODATA: ::c_int = -5; +pub const EAI_FAMILY: ::c_int = -6; +pub const EAI_SOCKTYPE: ::c_int = -7; +pub const EAI_SERVICE: ::c_int = -8; +pub const EAI_MEMORY: ::c_int = -10; +pub const EAI_SYSTEM: ::c_int = -11; +pub const EAI_OVERFLOW: ::c_int = -12; + +pub const NI_NUMERICHOST: ::c_int = 1; +pub const NI_NUMERICSERV: ::c_int = 2; +pub const NI_NOFQDN: ::c_int = 4; +pub const NI_NAMEREQD: ::c_int = 8; +pub const NI_DGRAM: ::c_int = 16; +pub const NI_IDN: ::c_int = 32; + +pub const SYNC_FILE_RANGE_WAIT_BEFORE: ::c_uint = 1; +pub const SYNC_FILE_RANGE_WRITE: ::c_uint = 2; +pub const SYNC_FILE_RANGE_WAIT_AFTER: ::c_uint = 4; + +cfg_if! { + if #[cfg(not(target_env = "uclibc"))] { + pub const AIO_CANCELED: ::c_int = 0; + pub const AIO_NOTCANCELED: ::c_int = 1; + pub const AIO_ALLDONE: ::c_int = 2; + pub const LIO_READ: ::c_int = 0; + pub const LIO_WRITE: ::c_int = 1; + pub const LIO_NOP: ::c_int = 2; + pub const LIO_WAIT: ::c_int = 0; + pub const LIO_NOWAIT: ::c_int = 1; + pub const RUSAGE_THREAD: ::c_int = 1; + pub const MSG_COPY: ::c_int = 0o40000; + pub const SHM_EXEC: ::c_int = 0o100000; + pub const IPV6_MULTICAST_ALL: ::c_int = 29; + pub const IPV6_ROUTER_ALERT_ISOLATE: ::c_int = 30; + pub const PACKET_MR_UNICAST: ::c_int = 3; + pub const PTRACE_EVENT_STOP: ::c_int = 128; + pub const UDP_SEGMENT: ::c_int = 103; + pub const UDP_GRO: ::c_int = 104; + } +} + +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; + +pub const PR_GET_DUMPABLE: ::c_int = 3; +pub const PR_SET_DUMPABLE: ::c_int = 4; + +pub const PR_GET_UNALIGN: ::c_int = 5; +pub const PR_SET_UNALIGN: ::c_int = 6; +pub const PR_UNALIGN_NOPRINT: ::c_int = 1; +pub const PR_UNALIGN_SIGBUS: ::c_int = 2; + +pub const PR_GET_KEEPCAPS: ::c_int = 7; +pub const PR_SET_KEEPCAPS: ::c_int = 8; + +pub const PR_GET_FPEMU: ::c_int = 9; +pub const PR_SET_FPEMU: ::c_int = 10; +pub const PR_FPEMU_NOPRINT: ::c_int = 1; +pub const PR_FPEMU_SIGFPE: ::c_int = 2; + +pub const PR_GET_FPEXC: ::c_int = 11; +pub const PR_SET_FPEXC: ::c_int = 12; +pub const PR_FP_EXC_SW_ENABLE: ::c_int = 0x80; +pub const PR_FP_EXC_DIV: ::c_int = 0x010000; +pub const PR_FP_EXC_OVF: ::c_int = 0x020000; +pub const PR_FP_EXC_UND: ::c_int = 0x040000; +pub const PR_FP_EXC_RES: ::c_int = 0x080000; +pub const PR_FP_EXC_INV: ::c_int = 0x100000; +pub const PR_FP_EXC_DISABLED: ::c_int = 0; +pub const PR_FP_EXC_NONRECOV: ::c_int = 1; +pub const PR_FP_EXC_ASYNC: ::c_int = 2; +pub const PR_FP_EXC_PRECISE: ::c_int = 3; + +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; + +pub const PR_SET_NAME: ::c_int = 15; +pub const PR_GET_NAME: ::c_int = 16; + +pub const PR_GET_ENDIAN: ::c_int = 19; +pub const PR_SET_ENDIAN: ::c_int = 20; +pub const PR_ENDIAN_BIG: ::c_int = 0; +pub const PR_ENDIAN_LITTLE: ::c_int = 1; +pub const PR_ENDIAN_PPC_LITTLE: ::c_int = 2; + +pub const PR_GET_SECCOMP: ::c_int = 21; +pub const PR_SET_SECCOMP: ::c_int = 22; + +pub const PR_CAPBSET_READ: ::c_int = 23; +pub const PR_CAPBSET_DROP: ::c_int = 24; + +pub const PR_GET_TSC: ::c_int = 25; +pub const PR_SET_TSC: ::c_int = 26; +pub const PR_TSC_ENABLE: ::c_int = 1; +pub const PR_TSC_SIGSEGV: ::c_int = 2; + +pub const PR_GET_SECUREBITS: ::c_int = 27; +pub const PR_SET_SECUREBITS: ::c_int = 28; + +pub const PR_SET_TIMERSLACK: ::c_int = 29; +pub const PR_GET_TIMERSLACK: ::c_int = 30; + +pub const PR_TASK_PERF_EVENTS_DISABLE: ::c_int = 31; +pub const PR_TASK_PERF_EVENTS_ENABLE: ::c_int = 32; + +pub const PR_MCE_KILL: ::c_int = 33; +pub const PR_MCE_KILL_CLEAR: ::c_int = 0; +pub const PR_MCE_KILL_SET: ::c_int = 1; + +pub const PR_MCE_KILL_LATE: ::c_int = 0; +pub const PR_MCE_KILL_EARLY: ::c_int = 1; +pub const PR_MCE_KILL_DEFAULT: ::c_int = 2; + +pub const PR_MCE_KILL_GET: ::c_int = 34; + +pub const PR_SET_MM: ::c_int = 35; +pub const PR_SET_MM_START_CODE: ::c_int = 1; +pub const PR_SET_MM_END_CODE: ::c_int = 2; +pub const PR_SET_MM_START_DATA: ::c_int = 3; +pub const PR_SET_MM_END_DATA: ::c_int = 4; +pub const PR_SET_MM_START_STACK: ::c_int = 5; +pub const PR_SET_MM_START_BRK: ::c_int = 6; +pub const PR_SET_MM_BRK: ::c_int = 7; +pub const PR_SET_MM_ARG_START: ::c_int = 8; +pub const PR_SET_MM_ARG_END: ::c_int = 9; +pub const PR_SET_MM_ENV_START: ::c_int = 10; +pub const PR_SET_MM_ENV_END: ::c_int = 11; +pub const PR_SET_MM_AUXV: ::c_int = 12; +pub const PR_SET_MM_EXE_FILE: ::c_int = 13; +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; + +pub const PR_SET_NO_NEW_PRIVS: ::c_int = 38; +pub const PR_GET_NO_NEW_PRIVS: ::c_int = 39; + +pub const PR_GET_TID_ADDRESS: ::c_int = 40; + +pub const PR_SET_THP_DISABLE: ::c_int = 41; +pub const PR_GET_THP_DISABLE: ::c_int = 42; + +pub const PR_MPX_ENABLE_MANAGEMENT: ::c_int = 43; +pub const PR_MPX_DISABLE_MANAGEMENT: ::c_int = 44; + +pub const PR_SET_FP_MODE: ::c_int = 45; +pub const PR_GET_FP_MODE: ::c_int = 46; +pub const PR_FP_MODE_FR: ::c_int = 1 << 0; +pub const PR_FP_MODE_FRE: ::c_int = 1 << 1; + +pub const PR_CAP_AMBIENT: ::c_int = 47; +pub const PR_CAP_AMBIENT_IS_SET: ::c_int = 1; +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_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 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_FILTER_FLAG_TSYNC_ESRCH: ::c_ulong = 16; +pub const SECCOMP_FILTER_FLAG_WAIT_KILLABLE_RECV: ::c_ulong = 32; + +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 SECCOMP_USER_NOTIF_FLAG_CONTINUE: ::c_ulong = 1; + +pub const SECCOMP_ADDFD_FLAG_SETFD: ::c_ulong = 1; +pub const SECCOMP_ADDFD_FLAG_SEND: ::c_ulong = 2; + +pub const ITIMER_REAL: ::c_int = 0; +pub const ITIMER_VIRTUAL: ::c_int = 1; +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; + +pub const FALLOC_FL_KEEP_SIZE: ::c_int = 0x01; +pub const FALLOC_FL_PUNCH_HOLE: ::c_int = 0x02; +pub const FALLOC_FL_COLLAPSE_RANGE: ::c_int = 0x08; +pub const FALLOC_FL_ZERO_RANGE: ::c_int = 0x10; +pub const FALLOC_FL_INSERT_RANGE: ::c_int = 0x20; +pub const FALLOC_FL_UNSHARE_RANGE: ::c_int = 0x40; + +#[deprecated( + since = "0.2.55", + note = "ENOATTR is not available on Linux; use ENODATA instead" +)] +pub const ENOATTR: ::c_int = ::ENODATA; + +pub const SO_ORIGINAL_DST: ::c_int = 80; + +pub const IP_RECVFRAGSIZE: ::c_int = 25; + +pub const IPV6_FLOWINFO: ::c_int = 11; +pub const IPV6_FLOWLABEL_MGR: ::c_int = 32; +pub const IPV6_FLOWINFO_SEND: ::c_int = 33; +pub const IPV6_RECVFRAGSIZE: ::c_int = 77; +pub const IPV6_FREEBIND: ::c_int = 78; +pub const IPV6_FLOWINFO_FLOWLABEL: ::c_int = 0x000fffff; +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; + +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_NOEXEC_SEAL: ::c_uint = 0x0008; +pub const MFD_EXEC: ::c_uint = 0x0010; +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; +pub const ETH_HLEN: ::c_int = 14; +pub const ETH_ZLEN: ::c_int = 60; +pub const ETH_DATA_LEN: ::c_int = 1500; +pub const ETH_FRAME_LEN: ::c_int = 1514; +pub const ETH_FCS_LEN: ::c_int = 4; + +// These are the defined Ethernet Protocol ID's. +pub const ETH_P_LOOP: ::c_int = 0x0060; +pub const ETH_P_PUP: ::c_int = 0x0200; +pub const ETH_P_PUPAT: ::c_int = 0x0201; +pub const ETH_P_IP: ::c_int = 0x0800; +pub const ETH_P_X25: ::c_int = 0x0805; +pub const ETH_P_ARP: ::c_int = 0x0806; +pub const ETH_P_BPQ: ::c_int = 0x08FF; +pub const ETH_P_IEEEPUP: ::c_int = 0x0a00; +pub const ETH_P_IEEEPUPAT: ::c_int = 0x0a01; +pub const ETH_P_BATMAN: ::c_int = 0x4305; +pub const ETH_P_DEC: ::c_int = 0x6000; +pub const ETH_P_DNA_DL: ::c_int = 0x6001; +pub const ETH_P_DNA_RC: ::c_int = 0x6002; +pub const ETH_P_DNA_RT: ::c_int = 0x6003; +pub const ETH_P_LAT: ::c_int = 0x6004; +pub const ETH_P_DIAG: ::c_int = 0x6005; +pub const ETH_P_CUST: ::c_int = 0x6006; +pub const ETH_P_SCA: ::c_int = 0x6007; +pub const ETH_P_TEB: ::c_int = 0x6558; +pub const ETH_P_RARP: ::c_int = 0x8035; +pub const ETH_P_ATALK: ::c_int = 0x809B; +pub const ETH_P_AARP: ::c_int = 0x80F3; +pub const ETH_P_8021Q: ::c_int = 0x8100; +pub const ETH_P_IPX: ::c_int = 0x8137; +pub const ETH_P_IPV6: ::c_int = 0x86DD; +pub const ETH_P_PAUSE: ::c_int = 0x8808; +pub const ETH_P_SLOW: ::c_int = 0x8809; +pub const ETH_P_WCCP: ::c_int = 0x883E; +pub const ETH_P_MPLS_UC: ::c_int = 0x8847; +pub const ETH_P_MPLS_MC: ::c_int = 0x8848; +pub const ETH_P_ATMMPOA: ::c_int = 0x884c; +pub const ETH_P_PPP_DISC: ::c_int = 0x8863; +pub const ETH_P_PPP_SES: ::c_int = 0x8864; +pub const ETH_P_LINK_CTL: ::c_int = 0x886c; +pub const ETH_P_ATMFATE: ::c_int = 0x8884; +pub const ETH_P_PAE: ::c_int = 0x888E; +pub const ETH_P_AOE: ::c_int = 0x88A2; +pub const ETH_P_8021AD: ::c_int = 0x88A8; +pub const ETH_P_802_EX1: ::c_int = 0x88B5; +pub const ETH_P_TIPC: ::c_int = 0x88CA; +pub const ETH_P_MACSEC: ::c_int = 0x88E5; +pub const ETH_P_8021AH: ::c_int = 0x88E7; +pub const ETH_P_MVRP: ::c_int = 0x88F5; +pub const ETH_P_1588: ::c_int = 0x88F7; +pub const ETH_P_PRP: ::c_int = 0x88FB; +pub const ETH_P_FCOE: ::c_int = 0x8906; +pub const ETH_P_TDLS: ::c_int = 0x890D; +pub const ETH_P_FIP: ::c_int = 0x8914; +pub const ETH_P_80221: ::c_int = 0x8917; +pub const ETH_P_LOOPBACK: ::c_int = 0x9000; +pub const ETH_P_QINQ1: ::c_int = 0x9100; +pub const ETH_P_QINQ2: ::c_int = 0x9200; +pub const ETH_P_QINQ3: ::c_int = 0x9300; +pub const ETH_P_EDSA: ::c_int = 0xDADA; +pub const ETH_P_AF_IUCV: ::c_int = 0xFBFB; + +pub const ETH_P_802_3_MIN: ::c_int = 0x0600; + +// Non DIX types. Won't clash for 1500 types. +pub const ETH_P_802_3: ::c_int = 0x0001; +pub const ETH_P_AX25: ::c_int = 0x0002; +pub const ETH_P_ALL: ::c_int = 0x0003; +pub const ETH_P_802_2: ::c_int = 0x0004; +pub const ETH_P_SNAP: ::c_int = 0x0005; +pub const ETH_P_DDCMP: ::c_int = 0x0006; +pub const ETH_P_WAN_PPP: ::c_int = 0x0007; +pub const ETH_P_PPP_MP: ::c_int = 0x0008; +pub const ETH_P_LOCALTALK: ::c_int = 0x0009; +pub const ETH_P_CANFD: ::c_int = 0x000D; +pub const ETH_P_PPPTALK: ::c_int = 0x0010; +pub const ETH_P_TR_802_2: ::c_int = 0x0011; +pub const ETH_P_MOBITEX: ::c_int = 0x0015; +pub const ETH_P_CONTROL: ::c_int = 0x0016; +pub const ETH_P_IRDA: ::c_int = 0x0017; +pub const ETH_P_ECONET: ::c_int = 0x0018; +pub const ETH_P_HDLC: ::c_int = 0x0019; +pub const ETH_P_ARCNET: ::c_int = 0x001A; +pub const ETH_P_DSA: ::c_int = 0x001B; +pub const ETH_P_TRAILER: ::c_int = 0x001C; +pub const ETH_P_PHONET: ::c_int = 0x00F5; +pub const ETH_P_IEEE802154: ::c_int = 0x00F6; +pub const ETH_P_CAIF: ::c_int = 0x00F7; + +pub const POSIX_SPAWN_RESETIDS: ::c_int = 0x01; +pub const POSIX_SPAWN_SETPGROUP: ::c_int = 0x02; +pub const POSIX_SPAWN_SETSIGDEF: ::c_int = 0x04; +pub const POSIX_SPAWN_SETSIGMASK: ::c_int = 0x08; +pub const POSIX_SPAWN_SETSCHEDPARAM: ::c_int = 0x10; +pub const POSIX_SPAWN_SETSCHEDULER: ::c_int = 0x20; + +pub const NLMSG_NOOP: ::c_int = 0x1; +pub const NLMSG_ERROR: ::c_int = 0x2; +pub const NLMSG_DONE: ::c_int = 0x3; +pub const NLMSG_OVERRUN: ::c_int = 0x4; +pub const NLMSG_MIN_TYPE: ::c_int = 0x10; + +// linux/netfilter/nfnetlink.h +pub const NFNLGRP_NONE: ::c_int = 0; +pub const NFNLGRP_CONNTRACK_NEW: ::c_int = 1; +pub const NFNLGRP_CONNTRACK_UPDATE: ::c_int = 2; +pub const NFNLGRP_CONNTRACK_DESTROY: ::c_int = 3; +pub const NFNLGRP_CONNTRACK_EXP_NEW: ::c_int = 4; +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; + +pub const NFNL_SUBSYS_NONE: ::c_int = 0; +pub const NFNL_SUBSYS_CTNETLINK: ::c_int = 1; +pub const NFNL_SUBSYS_CTNETLINK_EXP: ::c_int = 2; +pub const NFNL_SUBSYS_QUEUE: ::c_int = 3; +pub const NFNL_SUBSYS_ULOG: ::c_int = 4; +pub const NFNL_SUBSYS_OSF: ::c_int = 5; +pub const NFNL_SUBSYS_IPSET: ::c_int = 6; +pub const NFNL_SUBSYS_ACCT: ::c_int = 7; +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_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; +pub const NFULA_TIMESTAMP: ::c_int = 3; +pub const NFULA_IFINDEX_INDEV: ::c_int = 4; +pub const NFULA_IFINDEX_OUTDEV: ::c_int = 5; +pub const NFULA_IFINDEX_PHYSINDEV: ::c_int = 6; +pub const NFULA_IFINDEX_PHYSOUTDEV: ::c_int = 7; +pub const NFULA_HWADDR: ::c_int = 8; +pub const NFULA_PAYLOAD: ::c_int = 9; +pub const NFULA_PREFIX: ::c_int = 10; +pub const NFULA_UID: ::c_int = 11; +pub const NFULA_SEQ: ::c_int = 12; +pub const NFULA_SEQ_GLOBAL: ::c_int = 13; +pub const NFULA_GID: ::c_int = 14; +pub const NFULA_HWTYPE: ::c_int = 15; +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; +pub const NFULNL_CFG_CMD_UNBIND: ::c_int = 2; +pub const NFULNL_CFG_CMD_PF_BIND: ::c_int = 3; +pub const NFULNL_CFG_CMD_PF_UNBIND: ::c_int = 4; + +pub const NFULA_CFG_UNSPEC: ::c_int = 0; +pub const NFULA_CFG_CMD: ::c_int = 1; +pub const NFULA_CFG_MODE: ::c_int = 2; +pub const NFULA_CFG_NLBUFSIZ: ::c_int = 3; +pub const NFULA_CFG_TIMEOUT: ::c_int = 4; +pub const NFULA_CFG_QTHRESH: ::c_int = 5; +pub const NFULA_CFG_FLAGS: ::c_int = 6; + +pub const NFULNL_COPY_NONE: ::c_int = 0x00; +pub const NFULNL_COPY_META: ::c_int = 0x01; +pub const NFULNL_COPY_PACKET: ::c_int = 0x02; + +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_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; +pub const NFQNL_MSG_VERDICT_BATCH: ::c_int = 3; + +pub const NFQA_UNSPEC: ::c_int = 0; +pub const NFQA_PACKET_HDR: ::c_int = 1; +pub const NFQA_VERDICT_HDR: ::c_int = 2; +pub const NFQA_MARK: ::c_int = 3; +pub const NFQA_TIMESTAMP: ::c_int = 4; +pub const NFQA_IFINDEX_INDEV: ::c_int = 5; +pub const NFQA_IFINDEX_OUTDEV: ::c_int = 6; +pub const NFQA_IFINDEX_PHYSINDEV: ::c_int = 7; +pub const NFQA_IFINDEX_PHYSOUTDEV: ::c_int = 8; +pub const NFQA_HWADDR: ::c_int = 9; +pub const NFQA_PAYLOAD: ::c_int = 10; +pub const NFQA_CT: ::c_int = 11; +pub const NFQA_CT_INFO: ::c_int = 12; +pub const NFQA_CAP_LEN: ::c_int = 13; +pub const NFQA_SKB_INFO: ::c_int = 14; +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; +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; +pub const NFQNL_CFG_CMD_UNBIND: ::c_int = 2; +pub const NFQNL_CFG_CMD_PF_BIND: ::c_int = 3; +pub const NFQNL_CFG_CMD_PF_UNBIND: ::c_int = 4; + +pub const NFQNL_COPY_NONE: ::c_int = 0; +pub const NFQNL_COPY_META: ::c_int = 1; +pub const NFQNL_COPY_PACKET: ::c_int = 2; + +pub const NFQA_CFG_UNSPEC: ::c_int = 0; +pub const NFQA_CFG_CMD: ::c_int = 1; +pub const NFQA_CFG_PARAMS: ::c_int = 2; +pub const NFQA_CFG_QUEUE_MAXLEN: ::c_int = 3; +pub const NFQA_CFG_MASK: ::c_int = 4; +pub const NFQA_CFG_FLAGS: ::c_int = 5; + +pub const NFQA_CFG_F_FAIL_OPEN: ::c_int = 0x0001; +pub const NFQA_CFG_F_CONNTRACK: ::c_int = 0x0002; +pub const NFQA_CFG_F_GSO: ::c_int = 0x0004; +pub const NFQA_CFG_F_UID_GID: ::c_int = 0x0008; +pub const NFQA_CFG_F_SECCTX: ::c_int = 0x0010; +pub const NFQA_CFG_F_MAX: ::c_int = 0x0020; + +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; +pub const GENL_MAX_ID: ::c_int = 1023; + +pub const GENL_ADMIN_PERM: ::c_int = 0x01; +pub const GENL_CMD_CAP_DO: ::c_int = 0x02; +pub const GENL_CMD_CAP_DUMP: ::c_int = 0x04; +pub const GENL_CMD_CAP_HASPOL: ::c_int = 0x08; + +pub const GENL_ID_CTRL: ::c_int = NLMSG_MIN_TYPE; + +pub const CTRL_CMD_UNSPEC: ::c_int = 0; +pub const CTRL_CMD_NEWFAMILY: ::c_int = 1; +pub const CTRL_CMD_DELFAMILY: ::c_int = 2; +pub const CTRL_CMD_GETFAMILY: ::c_int = 3; +pub const CTRL_CMD_NEWOPS: ::c_int = 4; +pub const CTRL_CMD_DELOPS: ::c_int = 5; +pub const CTRL_CMD_GETOPS: ::c_int = 6; +pub const CTRL_CMD_NEWMCAST_GRP: ::c_int = 7; +pub const CTRL_CMD_DELMCAST_GRP: ::c_int = 8; +pub const CTRL_CMD_GETMCAST_GRP: ::c_int = 9; + +pub const CTRL_ATTR_UNSPEC: ::c_int = 0; +pub const CTRL_ATTR_FAMILY_ID: ::c_int = 1; +pub const CTRL_ATTR_FAMILY_NAME: ::c_int = 2; +pub const CTRL_ATTR_VERSION: ::c_int = 3; +pub const CTRL_ATTR_HDRSIZE: ::c_int = 4; +pub const CTRL_ATTR_MAXATTR: ::c_int = 5; +pub const CTRL_ATTR_OPS: ::c_int = 6; +pub const CTRL_ATTR_MCAST_GROUPS: ::c_int = 7; + +pub const CTRL_ATTR_OP_UNSPEC: ::c_int = 0; +pub const CTRL_ATTR_OP_ID: ::c_int = 1; +pub const CTRL_ATTR_OP_FLAGS: ::c_int = 2; + +pub const CTRL_ATTR_MCAST_GRP_UNSPEC: ::c_int = 0; +pub const CTRL_ATTR_MCAST_GRP_NAME: ::c_int = 1; +pub const CTRL_ATTR_MCAST_GRP_ID: ::c_int = 2; + +// linux/if_packet.h +pub const PACKET_HOST: ::c_uchar = 0; +pub const PACKET_BROADCAST: ::c_uchar = 1; +pub const PACKET_MULTICAST: ::c_uchar = 2; +pub const PACKET_OTHERHOST: ::c_uchar = 3; +pub const PACKET_OUTGOING: ::c_uchar = 4; +pub const PACKET_LOOPBACK: ::c_uchar = 5; +pub const PACKET_USER: ::c_uchar = 6; +pub const PACKET_KERNEL: ::c_uchar = 7; + +pub const PACKET_ADD_MEMBERSHIP: ::c_int = 1; +pub const PACKET_DROP_MEMBERSHIP: ::c_int = 2; +pub const PACKET_RX_RING: ::c_int = 5; +pub const PACKET_STATISTICS: ::c_int = 6; +pub const PACKET_AUXDATA: ::c_int = 8; +pub const PACKET_VERSION: ::c_int = 10; +pub const PACKET_RESERVE: ::c_int = 12; +pub const PACKET_TX_RING: ::c_int = 13; +pub const PACKET_LOSS: ::c_int = 14; +pub const PACKET_TIMESTAMP: ::c_int = 17; +pub const PACKET_FANOUT: ::c_int = 18; +pub const PACKET_QDISC_BYPASS: ::c_int = 20; + +pub const PACKET_FANOUT_HASH: ::c_uint = 0; +pub const PACKET_FANOUT_LB: ::c_uint = 1; +pub const PACKET_FANOUT_CPU: ::c_uint = 2; +pub const PACKET_FANOUT_ROLLOVER: ::c_uint = 3; +pub const PACKET_FANOUT_RND: ::c_uint = 4; +pub const PACKET_FANOUT_QM: ::c_uint = 5; +pub const PACKET_FANOUT_CBPF: ::c_uint = 6; +pub const PACKET_FANOUT_EBPF: ::c_uint = 7; +pub const PACKET_FANOUT_FLAG_ROLLOVER: ::c_uint = 0x1000; +pub const PACKET_FANOUT_FLAG_UNIQUEID: ::c_uint = 0x2000; +pub const PACKET_FANOUT_FLAG_DEFRAG: ::c_uint = 0x8000; + +pub const PACKET_MR_MULTICAST: ::c_int = 0; +pub const PACKET_MR_PROMISC: ::c_int = 1; +pub const PACKET_MR_ALLMULTI: ::c_int = 2; + +pub const TP_STATUS_KERNEL: ::__u32 = 0; +pub const TP_STATUS_USER: ::__u32 = 1 << 0; +pub const TP_STATUS_COPY: ::__u32 = 1 << 1; +pub const TP_STATUS_LOSING: ::__u32 = 1 << 2; +pub const TP_STATUS_CSUMNOTREADY: ::__u32 = 1 << 3; +pub const TP_STATUS_VLAN_VALID: ::__u32 = 1 << 4; +pub const TP_STATUS_BLK_TMO: ::__u32 = 1 << 5; +pub const TP_STATUS_VLAN_TPID_VALID: ::__u32 = 1 << 6; +pub const TP_STATUS_CSUM_VALID: ::__u32 = 1 << 7; + +pub const TP_STATUS_AVAILABLE: ::__u32 = 0; +pub const TP_STATUS_SEND_REQUEST: ::__u32 = 1 << 0; +pub const TP_STATUS_SENDING: ::__u32 = 1 << 1; +pub const TP_STATUS_WRONG_FORMAT: ::__u32 = 1 << 2; + +pub const TP_STATUS_TS_SOFTWARE: ::__u32 = 1 << 29; +pub const TP_STATUS_TS_SYS_HARDWARE: ::__u32 = 1 << 30; +pub const TP_STATUS_TS_RAW_HARDWARE: ::__u32 = 1 << 31; + +pub const TP_FT_REQ_FILL_RXHASH: ::__u32 = 1; + +pub const TPACKET_ALIGNMENT: usize = 16; + +cfg_if! { + if #[cfg(libc_const_size_of)] { + pub const TPACKET_HDRLEN: usize = ( + (::mem::size_of::<::tpacket_hdr>() + TPACKET_ALIGNMENT - 1) + & !(TPACKET_ALIGNMENT - 1) + ) + ::mem::size_of::<::sockaddr_ll>(); + pub const TPACKET2_HDRLEN: usize = ( + (::mem::size_of::<::tpacket2_hdr>() + TPACKET_ALIGNMENT - 1) + & !(TPACKET_ALIGNMENT - 1) + ) + ::mem::size_of::<::sockaddr_ll>(); + pub const TPACKET3_HDRLEN: usize = ( + (::mem::size_of::<::tpacket3_hdr>() + TPACKET_ALIGNMENT - 1) + & !(TPACKET_ALIGNMENT - 1) + ) + ::mem::size_of::<::sockaddr_ll>(); + } +} + +// linux/netfilter.h +pub const NF_DROP: ::c_int = 0; +pub const NF_ACCEPT: ::c_int = 1; +pub const NF_STOLEN: ::c_int = 2; +pub const NF_QUEUE: ::c_int = 3; +pub const NF_REPEAT: ::c_int = 4; +pub const NF_STOP: ::c_int = 5; +pub const NF_MAX_VERDICT: ::c_int = NF_STOP; + +pub const NF_VERDICT_MASK: ::c_int = 0x000000ff; +pub const NF_VERDICT_FLAG_QUEUE_BYPASS: ::c_int = 0x00008000; + +pub const NF_VERDICT_QMASK: ::c_int = 0xffff0000; +pub const NF_VERDICT_QBITS: ::c_int = 16; + +pub const NF_VERDICT_BITS: ::c_int = 16; + +pub const NF_INET_PRE_ROUTING: ::c_int = 0; +pub const NF_INET_LOCAL_IN: ::c_int = 1; +pub const NF_INET_FORWARD: ::c_int = 2; +pub const NF_INET_LOCAL_OUT: ::c_int = 3; +pub const NF_INET_POST_ROUTING: ::c_int = 4; +pub const NF_INET_NUMHOOKS: ::c_int = 5; + +// Some NFPROTO are not compatible with musl and are defined in submodules. +pub const NFPROTO_UNSPEC: ::c_int = 0; +pub const NFPROTO_IPV4: ::c_int = 2; +pub const NFPROTO_ARP: ::c_int = 3; +pub const NFPROTO_BRIDGE: ::c_int = 7; +pub const NFPROTO_IPV6: ::c_int = 10; +pub const NFPROTO_DECNET: ::c_int = 12; +pub const NFPROTO_NUMPROTO: ::c_int = 13; +pub const NFPROTO_INET: ::c_int = 1; +pub const NFPROTO_NETDEV: ::c_int = 5; + +pub const NF_NETDEV_INGRESS: ::c_int = 0; +pub const NF_NETDEV_NUMHOOKS: ::c_int = 1; + +// linux/netfilter_ipv4.h +pub const NF_IP_PRE_ROUTING: ::c_int = 0; +pub const NF_IP_LOCAL_IN: ::c_int = 1; +pub const NF_IP_FORWARD: ::c_int = 2; +pub const NF_IP_LOCAL_OUT: ::c_int = 3; +pub const NF_IP_POST_ROUTING: ::c_int = 4; +pub const NF_IP_NUMHOOKS: ::c_int = 5; + +pub const NF_IP_PRI_FIRST: ::c_int = ::INT_MIN; +pub const NF_IP_PRI_CONNTRACK_DEFRAG: ::c_int = -400; +pub const NF_IP_PRI_RAW: ::c_int = -300; +pub const NF_IP_PRI_SELINUX_FIRST: ::c_int = -225; +pub const NF_IP_PRI_CONNTRACK: ::c_int = -200; +pub const NF_IP_PRI_MANGLE: ::c_int = -150; +pub const NF_IP_PRI_NAT_DST: ::c_int = -100; +pub const NF_IP_PRI_FILTER: ::c_int = 0; +pub const NF_IP_PRI_SECURITY: ::c_int = 50; +pub const NF_IP_PRI_NAT_SRC: ::c_int = 100; +pub const NF_IP_PRI_SELINUX_LAST: ::c_int = 225; +pub const NF_IP_PRI_CONNTRACK_HELPER: ::c_int = 300; +pub const NF_IP_PRI_CONNTRACK_CONFIRM: ::c_int = ::INT_MAX; +pub const NF_IP_PRI_LAST: ::c_int = ::INT_MAX; + +// linux/netfilter_ipv6.h +pub const NF_IP6_PRE_ROUTING: ::c_int = 0; +pub const NF_IP6_LOCAL_IN: ::c_int = 1; +pub const NF_IP6_FORWARD: ::c_int = 2; +pub const NF_IP6_LOCAL_OUT: ::c_int = 3; +pub const NF_IP6_POST_ROUTING: ::c_int = 4; +pub const NF_IP6_NUMHOOKS: ::c_int = 5; + +pub const NF_IP6_PRI_FIRST: ::c_int = ::INT_MIN; +pub const NF_IP6_PRI_CONNTRACK_DEFRAG: ::c_int = -400; +pub const NF_IP6_PRI_RAW: ::c_int = -300; +pub const NF_IP6_PRI_SELINUX_FIRST: ::c_int = -225; +pub const NF_IP6_PRI_CONNTRACK: ::c_int = -200; +pub const NF_IP6_PRI_MANGLE: ::c_int = -150; +pub const NF_IP6_PRI_NAT_DST: ::c_int = -100; +pub const NF_IP6_PRI_FILTER: ::c_int = 0; +pub const NF_IP6_PRI_SECURITY: ::c_int = 50; +pub const NF_IP6_PRI_NAT_SRC: ::c_int = 100; +pub const NF_IP6_PRI_SELINUX_LAST: ::c_int = 225; +pub const NF_IP6_PRI_CONNTRACK_HELPER: ::c_int = 300; +pub const NF_IP6_PRI_LAST: ::c_int = ::INT_MAX; + +// linux/netfilter_ipv6/ip6_tables.h +pub const IP6T_SO_ORIGINAL_DST: ::c_int = 80; + +pub const SIOCADDRT: ::c_ulong = 0x0000890B; +pub const SIOCDELRT: ::c_ulong = 0x0000890C; +pub const SIOCGIFNAME: ::c_ulong = 0x00008910; +pub const SIOCSIFLINK: ::c_ulong = 0x00008911; +pub const SIOCGIFCONF: ::c_ulong = 0x00008912; +pub const SIOCGIFFLAGS: ::c_ulong = 0x00008913; +pub const SIOCSIFFLAGS: ::c_ulong = 0x00008914; +pub const SIOCGIFADDR: ::c_ulong = 0x00008915; +pub const SIOCSIFADDR: ::c_ulong = 0x00008916; +pub const SIOCGIFDSTADDR: ::c_ulong = 0x00008917; +pub const SIOCSIFDSTADDR: ::c_ulong = 0x00008918; +pub const SIOCGIFBRDADDR: ::c_ulong = 0x00008919; +pub const SIOCSIFBRDADDR: ::c_ulong = 0x0000891A; +pub const SIOCGIFNETMASK: ::c_ulong = 0x0000891B; +pub const SIOCSIFNETMASK: ::c_ulong = 0x0000891C; +pub const SIOCGIFMETRIC: ::c_ulong = 0x0000891D; +pub const SIOCSIFMETRIC: ::c_ulong = 0x0000891E; +pub const SIOCGIFMEM: ::c_ulong = 0x0000891F; +pub const SIOCSIFMEM: ::c_ulong = 0x00008920; +pub const SIOCGIFMTU: ::c_ulong = 0x00008921; +pub const SIOCSIFMTU: ::c_ulong = 0x00008922; +pub const SIOCSIFNAME: ::c_ulong = 0x00008923; +pub const SIOCSIFHWADDR: ::c_ulong = 0x00008924; +pub const SIOCGIFENCAP: ::c_ulong = 0x00008925; +pub const SIOCSIFENCAP: ::c_ulong = 0x00008926; +pub const SIOCGIFHWADDR: ::c_ulong = 0x00008927; +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; +pub const SIOCDRARP: ::c_ulong = 0x00008960; +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; + +// wireless.h +pub const WIRELESS_EXT: ::c_ulong = 0x16; + +pub const SIOCSIWCOMMIT: ::c_ulong = 0x8B00; +pub const SIOCGIWNAME: ::c_ulong = 0x8B01; + +pub const SIOCSIWNWID: ::c_ulong = 0x8B02; +pub const SIOCGIWNWID: ::c_ulong = 0x8B03; +pub const SIOCSIWFREQ: ::c_ulong = 0x8B04; +pub const SIOCGIWFREQ: ::c_ulong = 0x8B05; +pub const SIOCSIWMODE: ::c_ulong = 0x8B06; +pub const SIOCGIWMODE: ::c_ulong = 0x8B07; +pub const SIOCSIWSENS: ::c_ulong = 0x8B08; +pub const SIOCGIWSENS: ::c_ulong = 0x8B09; + +pub const SIOCSIWRANGE: ::c_ulong = 0x8B0A; +pub const SIOCGIWRANGE: ::c_ulong = 0x8B0B; +pub const SIOCSIWPRIV: ::c_ulong = 0x8B0C; +pub const SIOCGIWPRIV: ::c_ulong = 0x8B0D; +pub const SIOCSIWSTATS: ::c_ulong = 0x8B0E; +pub const SIOCGIWSTATS: ::c_ulong = 0x8B0F; + +pub const SIOCSIWSPY: ::c_ulong = 0x8B10; +pub const SIOCGIWSPY: ::c_ulong = 0x8B11; +pub const SIOCSIWTHRSPY: ::c_ulong = 0x8B12; +pub const SIOCGIWTHRSPY: ::c_ulong = 0x8B13; + +pub const SIOCSIWAP: ::c_ulong = 0x8B14; +pub const SIOCGIWAP: ::c_ulong = 0x8B15; +pub const SIOCGIWAPLIST: ::c_ulong = 0x8B17; +pub const SIOCSIWSCAN: ::c_ulong = 0x8B18; +pub const SIOCGIWSCAN: ::c_ulong = 0x8B19; + +pub const SIOCSIWESSID: ::c_ulong = 0x8B1A; +pub const SIOCGIWESSID: ::c_ulong = 0x8B1B; +pub const SIOCSIWNICKN: ::c_ulong = 0x8B1C; +pub const SIOCGIWNICKN: ::c_ulong = 0x8B1D; + +pub const SIOCSIWRATE: ::c_ulong = 0x8B20; +pub const SIOCGIWRATE: ::c_ulong = 0x8B21; +pub const SIOCSIWRTS: ::c_ulong = 0x8B22; +pub const SIOCGIWRTS: ::c_ulong = 0x8B23; +pub const SIOCSIWFRAG: ::c_ulong = 0x8B24; +pub const SIOCGIWFRAG: ::c_ulong = 0x8B25; +pub const SIOCSIWTXPOW: ::c_ulong = 0x8B26; +pub const SIOCGIWTXPOW: ::c_ulong = 0x8B27; +pub const SIOCSIWRETRY: ::c_ulong = 0x8B28; +pub const SIOCGIWRETRY: ::c_ulong = 0x8B29; + +pub const SIOCSIWENCODE: ::c_ulong = 0x8B2A; +pub const SIOCGIWENCODE: ::c_ulong = 0x8B2B; + +pub const SIOCSIWPOWER: ::c_ulong = 0x8B2C; +pub const SIOCGIWPOWER: ::c_ulong = 0x8B2D; + +pub const SIOCSIWGENIE: ::c_ulong = 0x8B30; +pub const SIOCGIWGENIE: ::c_ulong = 0x8B31; + +pub const SIOCSIWMLME: ::c_ulong = 0x8B16; + +pub const SIOCSIWAUTH: ::c_ulong = 0x8B32; +pub const SIOCGIWAUTH: ::c_ulong = 0x8B33; + +pub const SIOCSIWENCODEEXT: ::c_ulong = 0x8B34; +pub const SIOCGIWENCODEEXT: ::c_ulong = 0x8B35; + +pub const SIOCSIWPMKSA: ::c_ulong = 0x8B36; + +pub const SIOCIWFIRSTPRIV: ::c_ulong = 0x8BE0; +pub const SIOCIWLASTPRIV: ::c_ulong = 0x8BFF; + +pub const SIOCIWFIRST: ::c_ulong = 0x8B00; +pub const SIOCIWLAST: ::c_ulong = SIOCIWLASTPRIV; + +pub const IWEVTXDROP: ::c_ulong = 0x8C00; +pub const IWEVQUAL: ::c_ulong = 0x8C01; +pub const IWEVCUSTOM: ::c_ulong = 0x8C02; +pub const IWEVREGISTERED: ::c_ulong = 0x8C03; +pub const IWEVEXPIRED: ::c_ulong = 0x8C04; +pub const IWEVGENIE: ::c_ulong = 0x8C05; +pub const IWEVMICHAELMICFAILURE: ::c_ulong = 0x8C06; +pub const IWEVASSOCREQIE: ::c_ulong = 0x8C07; +pub const IWEVASSOCRESPIE: ::c_ulong = 0x8C08; +pub const IWEVPMKIDCAND: ::c_ulong = 0x8C09; +pub const IWEVFIRST: ::c_ulong = 0x8C00; + +pub const IW_PRIV_TYPE_MASK: ::c_ulong = 0x7000; +pub const IW_PRIV_TYPE_NONE: ::c_ulong = 0x0000; +pub const IW_PRIV_TYPE_BYTE: ::c_ulong = 0x1000; +pub const IW_PRIV_TYPE_CHAR: ::c_ulong = 0x2000; +pub const IW_PRIV_TYPE_INT: ::c_ulong = 0x4000; +pub const IW_PRIV_TYPE_FLOAT: ::c_ulong = 0x5000; +pub const IW_PRIV_TYPE_ADDR: ::c_ulong = 0x6000; + +pub const IW_PRIV_SIZE_FIXED: ::c_ulong = 0x0800; + +pub const IW_PRIV_SIZE_MASK: ::c_ulong = 0x07FF; + +pub const IW_MAX_FREQUENCIES: usize = 32; +pub const IW_MAX_BITRATES: usize = 32; +pub const IW_MAX_TXPOWER: usize = 8; +pub const IW_MAX_SPY: usize = 8; +pub const IW_MAX_AP: usize = 64; +pub const IW_ESSID_MAX_SIZE: usize = 32; + +pub const IW_MODE_AUTO: usize = 0; +pub const IW_MODE_ADHOC: usize = 1; +pub const IW_MODE_INFRA: usize = 2; +pub const IW_MODE_MASTER: usize = 3; +pub const IW_MODE_REPEAT: usize = 4; +pub const IW_MODE_SECOND: usize = 5; +pub const IW_MODE_MONITOR: usize = 6; +pub const IW_MODE_MESH: usize = 7; + +pub const IW_QUAL_QUAL_UPDATED: ::c_ulong = 0x01; +pub const IW_QUAL_LEVEL_UPDATED: ::c_ulong = 0x02; +pub const IW_QUAL_NOISE_UPDATED: ::c_ulong = 0x04; +pub const IW_QUAL_ALL_UPDATED: ::c_ulong = 0x07; +pub const IW_QUAL_DBM: ::c_ulong = 0x08; +pub const IW_QUAL_QUAL_INVALID: ::c_ulong = 0x10; +pub const IW_QUAL_LEVEL_INVALID: ::c_ulong = 0x20; +pub const IW_QUAL_NOISE_INVALID: ::c_ulong = 0x40; +pub const IW_QUAL_RCPI: ::c_ulong = 0x80; +pub const IW_QUAL_ALL_INVALID: ::c_ulong = 0x70; + +pub const IW_FREQ_AUTO: ::c_ulong = 0x00; +pub const IW_FREQ_FIXED: ::c_ulong = 0x01; + +pub const IW_MAX_ENCODING_SIZES: usize = 8; +pub const IW_ENCODING_TOKEN_MAX: usize = 64; + +pub const IW_ENCODE_INDEX: ::c_ulong = 0x00FF; +pub const IW_ENCODE_FLAGS: ::c_ulong = 0xFF00; +pub const IW_ENCODE_MODE: ::c_ulong = 0xF000; +pub const IW_ENCODE_DISABLED: ::c_ulong = 0x8000; +pub const IW_ENCODE_ENABLED: ::c_ulong = 0x0000; +pub const IW_ENCODE_RESTRICTED: ::c_ulong = 0x4000; +pub const IW_ENCODE_OPEN: ::c_ulong = 0x2000; +pub const IW_ENCODE_NOKEY: ::c_ulong = 0x0800; +pub const IW_ENCODE_TEMP: ::c_ulong = 0x0400; + +pub const IW_POWER_ON: ::c_ulong = 0x0000; +pub const IW_POWER_TYPE: ::c_ulong = 0xF000; +pub const IW_POWER_PERIOD: ::c_ulong = 0x1000; +pub const IW_POWER_TIMEOUT: ::c_ulong = 0x2000; +pub const IW_POWER_MODE: ::c_ulong = 0x0F00; +pub const IW_POWER_UNICAST_R: ::c_ulong = 0x0100; +pub const IW_POWER_MULTICAST_R: ::c_ulong = 0x0200; +pub const IW_POWER_ALL_R: ::c_ulong = 0x0300; +pub const IW_POWER_FORCE_S: ::c_ulong = 0x0400; +pub const IW_POWER_REPEATER: ::c_ulong = 0x0800; +pub const IW_POWER_MODIFIER: ::c_ulong = 0x000F; +pub const IW_POWER_MIN: ::c_ulong = 0x0001; +pub const IW_POWER_MAX: ::c_ulong = 0x0002; +pub const IW_POWER_RELATIVE: ::c_ulong = 0x0004; + +pub const IW_TXPOW_TYPE: ::c_ulong = 0x00FF; +pub const IW_TXPOW_DBM: ::c_ulong = 0x0000; +pub const IW_TXPOW_MWATT: ::c_ulong = 0x0001; +pub const IW_TXPOW_RELATIVE: ::c_ulong = 0x0002; +pub const IW_TXPOW_RANGE: ::c_ulong = 0x1000; + +pub const IW_RETRY_ON: ::c_ulong = 0x0000; +pub const IW_RETRY_TYPE: ::c_ulong = 0xF000; +pub const IW_RETRY_LIMIT: ::c_ulong = 0x1000; +pub const IW_RETRY_LIFETIME: ::c_ulong = 0x2000; +pub const IW_RETRY_MODIFIER: ::c_ulong = 0x00FF; +pub const IW_RETRY_MIN: ::c_ulong = 0x0001; +pub const IW_RETRY_MAX: ::c_ulong = 0x0002; +pub const IW_RETRY_RELATIVE: ::c_ulong = 0x0004; +pub const IW_RETRY_SHORT: ::c_ulong = 0x0010; +pub const IW_RETRY_LONG: ::c_ulong = 0x0020; + +pub const IW_SCAN_DEFAULT: ::c_ulong = 0x0000; +pub const IW_SCAN_ALL_ESSID: ::c_ulong = 0x0001; +pub const IW_SCAN_THIS_ESSID: ::c_ulong = 0x0002; +pub const IW_SCAN_ALL_FREQ: ::c_ulong = 0x0004; +pub const IW_SCAN_THIS_FREQ: ::c_ulong = 0x0008; +pub const IW_SCAN_ALL_MODE: ::c_ulong = 0x0010; +pub const IW_SCAN_THIS_MODE: ::c_ulong = 0x0020; +pub const IW_SCAN_ALL_RATE: ::c_ulong = 0x0040; +pub const IW_SCAN_THIS_RATE: ::c_ulong = 0x0080; + +pub const IW_SCAN_TYPE_ACTIVE: usize = 0; +pub const IW_SCAN_TYPE_PASSIVE: usize = 1; + +pub const IW_SCAN_MAX_DATA: usize = 4096; + +pub const IW_SCAN_CAPA_NONE: ::c_ulong = 0x00; +pub const IW_SCAN_CAPA_ESSID: ::c_ulong = 0x01; +pub const IW_SCAN_CAPA_BSSID: ::c_ulong = 0x02; +pub const IW_SCAN_CAPA_CHANNEL: ::c_ulong = 0x04; +pub const IW_SCAN_CAPA_MODE: ::c_ulong = 0x08; +pub const IW_SCAN_CAPA_RATE: ::c_ulong = 0x10; +pub const IW_SCAN_CAPA_TYPE: ::c_ulong = 0x20; +pub const IW_SCAN_CAPA_TIME: ::c_ulong = 0x40; + +pub const IW_CUSTOM_MAX: ::c_ulong = 256; + +pub const IW_GENERIC_IE_MAX: ::c_ulong = 1024; + +pub const IW_MLME_DEAUTH: ::c_ulong = 0; +pub const IW_MLME_DISASSOC: ::c_ulong = 1; +pub const IW_MLME_AUTH: ::c_ulong = 2; +pub const IW_MLME_ASSOC: ::c_ulong = 3; + +pub const IW_AUTH_INDEX: ::c_ulong = 0x0FFF; +pub const IW_AUTH_FLAGS: ::c_ulong = 0xF000; + +pub const IW_AUTH_WPA_VERSION: usize = 0; +pub const IW_AUTH_CIPHER_PAIRWISE: usize = 1; +pub const IW_AUTH_CIPHER_GROUP: usize = 2; +pub const IW_AUTH_KEY_MGMT: usize = 3; +pub const IW_AUTH_TKIP_COUNTERMEASURES: usize = 4; +pub const IW_AUTH_DROP_UNENCRYPTED: usize = 5; +pub const IW_AUTH_80211_AUTH_ALG: usize = 6; +pub const IW_AUTH_WPA_ENABLED: usize = 7; +pub const IW_AUTH_RX_UNENCRYPTED_EAPOL: usize = 8; +pub const IW_AUTH_ROAMING_CONTROL: usize = 9; +pub const IW_AUTH_PRIVACY_INVOKED: usize = 10; +pub const IW_AUTH_CIPHER_GROUP_MGMT: usize = 11; +pub const IW_AUTH_MFP: usize = 12; + +pub const IW_AUTH_WPA_VERSION_DISABLED: ::c_ulong = 0x00000001; +pub const IW_AUTH_WPA_VERSION_WPA: ::c_ulong = 0x00000002; +pub const IW_AUTH_WPA_VERSION_WPA2: ::c_ulong = 0x00000004; + +pub const IW_AUTH_CIPHER_NONE: ::c_ulong = 0x00000001; +pub const IW_AUTH_CIPHER_WEP40: ::c_ulong = 0x00000002; +pub const IW_AUTH_CIPHER_TKIP: ::c_ulong = 0x00000004; +pub const IW_AUTH_CIPHER_CCMP: ::c_ulong = 0x00000008; +pub const IW_AUTH_CIPHER_WEP104: ::c_ulong = 0x00000010; +pub const IW_AUTH_CIPHER_AES_CMAC: ::c_ulong = 0x00000020; + +pub const IW_AUTH_KEY_MGMT_802_1X: usize = 1; +pub const IW_AUTH_KEY_MGMT_PSK: usize = 2; + +pub const IW_AUTH_ALG_OPEN_SYSTEM: ::c_ulong = 0x00000001; +pub const IW_AUTH_ALG_SHARED_KEY: ::c_ulong = 0x00000002; +pub const IW_AUTH_ALG_LEAP: ::c_ulong = 0x00000004; + +pub const IW_AUTH_ROAMING_ENABLE: usize = 0; +pub const IW_AUTH_ROAMING_DISABLE: usize = 1; + +pub const IW_AUTH_MFP_DISABLED: usize = 0; +pub const IW_AUTH_MFP_OPTIONAL: usize = 1; +pub const IW_AUTH_MFP_REQUIRED: usize = 2; + +pub const IW_ENCODE_SEQ_MAX_SIZE: usize = 8; + +pub const IW_ENCODE_ALG_NONE: usize = 0; +pub const IW_ENCODE_ALG_WEP: usize = 1; +pub const IW_ENCODE_ALG_TKIP: usize = 2; +pub const IW_ENCODE_ALG_CCMP: usize = 3; +pub const IW_ENCODE_ALG_PMK: usize = 4; +pub const IW_ENCODE_ALG_AES_CMAC: usize = 5; + +pub const IW_ENCODE_EXT_TX_SEQ_VALID: ::c_ulong = 0x00000001; +pub const IW_ENCODE_EXT_RX_SEQ_VALID: ::c_ulong = 0x00000002; +pub const IW_ENCODE_EXT_GROUP_KEY: ::c_ulong = 0x00000004; +pub const IW_ENCODE_EXT_SET_TX_KEY: ::c_ulong = 0x00000008; + +pub const IW_MICFAILURE_KEY_ID: ::c_ulong = 0x00000003; +pub const IW_MICFAILURE_GROUP: ::c_ulong = 0x00000004; +pub const IW_MICFAILURE_PAIRWISE: ::c_ulong = 0x00000008; +pub const IW_MICFAILURE_STAKEY: ::c_ulong = 0x00000010; +pub const IW_MICFAILURE_COUNT: ::c_ulong = 0x00000060; + +pub const IW_ENC_CAPA_WPA: ::c_ulong = 0x00000001; +pub const IW_ENC_CAPA_WPA2: ::c_ulong = 0x00000002; +pub const IW_ENC_CAPA_CIPHER_TKIP: ::c_ulong = 0x00000004; +pub const IW_ENC_CAPA_CIPHER_CCMP: ::c_ulong = 0x00000008; +pub const IW_ENC_CAPA_4WAY_HANDSHAKE: ::c_ulong = 0x00000010; + +pub const IW_PMKSA_ADD: usize = 1; +pub const IW_PMKSA_REMOVE: usize = 2; +pub const IW_PMKSA_FLUSH: usize = 3; + +pub const IW_PMKID_LEN: usize = 16; + +pub const IW_PMKID_CAND_PREAUTH: ::c_ulong = 0x00000001; + +pub const IW_EV_LCP_PK_LEN: usize = 4; + +pub const IW_EV_CHAR_PK_LEN: usize = IW_EV_LCP_PK_LEN + ::IFNAMSIZ; +pub const IW_EV_POINT_PK_LEN: usize = IW_EV_LCP_PK_LEN + 4; + +pub const IPTOS_TOS_MASK: u8 = 0x1E; +pub const IPTOS_PREC_MASK: u8 = 0xE0; + +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_REINSTATE: ::c_ushort = 0x0008; +pub const RTF_DYNAMIC: ::c_ushort = 0x0010; +pub const RTF_MODIFIED: ::c_ushort = 0x0020; +pub const RTF_MTU: ::c_ushort = 0x0040; +pub const RTF_MSS: ::c_ushort = RTF_MTU; +pub const RTF_WINDOW: ::c_ushort = 0x0080; +pub const RTF_IRTT: ::c_ushort = 0x0100; +pub const RTF_REJECT: ::c_ushort = 0x0200; +pub const RTF_STATIC: ::c_ushort = 0x0400; +pub const RTF_XRESOLVE: ::c_ushort = 0x0800; +pub const RTF_NOFORWARD: ::c_ushort = 0x1000; +pub const RTF_THROW: ::c_ushort = 0x2000; +pub const RTF_NOPMTUDISC: ::c_ushort = 0x4000; + +pub const RTF_DEFAULT: u32 = 0x00010000; +pub const RTF_ALLONLINK: u32 = 0x00020000; +pub const RTF_ADDRCONF: u32 = 0x00040000; +pub const RTF_LINKRT: u32 = 0x00100000; +pub const RTF_NONEXTHOP: u32 = 0x00200000; +pub const RTF_CACHE: u32 = 0x01000000; +pub const RTF_FLOW: u32 = 0x02000000; +pub const RTF_POLICY: u32 = 0x04000000; + +pub const RTCF_VALVE: u32 = 0x00200000; +pub const RTCF_MASQ: u32 = 0x00400000; +pub const RTCF_NAT: u32 = 0x00800000; +pub const RTCF_DOREDIRECT: u32 = 0x01000000; +pub const RTCF_LOG: u32 = 0x02000000; +pub const RTCF_DIRECTSRC: u32 = 0x04000000; + +pub const RTF_LOCAL: u32 = 0x80000000; +pub const RTF_INTERFACE: u32 = 0x40000000; +pub const RTF_MULTICAST: u32 = 0x20000000; +pub const RTF_BROADCAST: u32 = 0x10000000; +pub const RTF_NAT: u32 = 0x08000000; +pub const RTF_ADDRCLASSMASK: u32 = 0xF8000000; + +pub const RT_CLASS_UNSPEC: u8 = 0; +pub const RT_CLASS_DEFAULT: u8 = 253; +pub const RT_CLASS_MAIN: u8 = 254; +pub const RT_CLASS_LOCAL: u8 = 255; +pub const RT_CLASS_MAX: u8 = 255; + +// linux/neighbor.h +pub const NUD_NONE: u16 = 0x00; +pub const NUD_INCOMPLETE: u16 = 0x01; +pub const NUD_REACHABLE: u16 = 0x02; +pub const NUD_STALE: u16 = 0x04; +pub const NUD_DELAY: u16 = 0x08; +pub const NUD_PROBE: u16 = 0x10; +pub const NUD_FAILED: u16 = 0x20; +pub const NUD_NOARP: u16 = 0x40; +pub const NUD_PERMANENT: u16 = 0x80; + +pub const NTF_USE: u8 = 0x01; +pub const NTF_SELF: u8 = 0x02; +pub const NTF_MASTER: u8 = 0x04; +pub const NTF_PROXY: u8 = 0x08; +pub const NTF_ROUTER: u8 = 0x80; + +pub const NDA_UNSPEC: ::c_ushort = 0; +pub const NDA_DST: ::c_ushort = 1; +pub const NDA_LLADDR: ::c_ushort = 2; +pub const NDA_CACHEINFO: ::c_ushort = 3; +pub const NDA_PROBES: ::c_ushort = 4; +pub const NDA_VLAN: ::c_ushort = 5; +pub const NDA_PORT: ::c_ushort = 6; +pub const NDA_VNI: ::c_ushort = 7; +pub const NDA_IFINDEX: ::c_ushort = 8; + +// linux/netlink.h +pub const NLA_ALIGNTO: ::c_int = 4; + +pub const NETLINK_ROUTE: ::c_int = 0; +pub const NETLINK_UNUSED: ::c_int = 1; +pub const NETLINK_USERSOCK: ::c_int = 2; +pub const NETLINK_FIREWALL: ::c_int = 3; +pub const NETLINK_SOCK_DIAG: ::c_int = 4; +pub const NETLINK_NFLOG: ::c_int = 5; +pub const NETLINK_XFRM: ::c_int = 6; +pub const NETLINK_SELINUX: ::c_int = 7; +pub const NETLINK_ISCSI: ::c_int = 8; +pub const NETLINK_AUDIT: ::c_int = 9; +pub const NETLINK_FIB_LOOKUP: ::c_int = 10; +pub const NETLINK_CONNECTOR: ::c_int = 11; +pub const NETLINK_NETFILTER: ::c_int = 12; +pub const NETLINK_IP6_FW: ::c_int = 13; +pub const NETLINK_DNRTMSG: ::c_int = 14; +pub const NETLINK_KOBJECT_UEVENT: ::c_int = 15; +pub const NETLINK_GENERIC: ::c_int = 16; +pub const NETLINK_SCSITRANSPORT: ::c_int = 18; +pub const NETLINK_ECRYPTFS: ::c_int = 19; +pub const NETLINK_RDMA: ::c_int = 20; +pub const NETLINK_CRYPTO: ::c_int = 21; +pub const NETLINK_INET_DIAG: ::c_int = NETLINK_SOCK_DIAG; + +pub const NLM_F_REQUEST: ::c_int = 1; +pub const NLM_F_MULTI: ::c_int = 2; +pub const NLM_F_ACK: ::c_int = 4; +pub const NLM_F_ECHO: ::c_int = 8; +pub const NLM_F_DUMP_INTR: ::c_int = 16; +pub const NLM_F_DUMP_FILTERED: ::c_int = 32; + +pub const NLM_F_ROOT: ::c_int = 0x100; +pub const NLM_F_MATCH: ::c_int = 0x200; +pub const NLM_F_ATOMIC: ::c_int = 0x400; +pub const NLM_F_DUMP: ::c_int = NLM_F_ROOT | NLM_F_MATCH; + +pub const NLM_F_REPLACE: ::c_int = 0x100; +pub const NLM_F_EXCL: ::c_int = 0x200; +pub const NLM_F_CREATE: ::c_int = 0x400; +pub const NLM_F_APPEND: ::c_int = 0x800; + +pub const NETLINK_ADD_MEMBERSHIP: ::c_int = 1; +pub const NETLINK_DROP_MEMBERSHIP: ::c_int = 2; +pub const NETLINK_PKTINFO: ::c_int = 3; +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 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); + +// 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_OVERRUN: u32 = ::NLMSG_OVERRUN as u32; +pub const RTMSG_NEWDEVICE: u32 = 0x11; +pub const RTMSG_DELDEVICE: u32 = 0x12; +pub const RTMSG_NEWROUTE: u32 = 0x21; +pub const RTMSG_DELROUTE: u32 = 0x22; +pub const RTMSG_NEWRULE: u32 = 0x31; +pub const RTMSG_DELRULE: u32 = 0x32; +pub const RTMSG_CONTROL: u32 = 0x40; +pub const RTMSG_AR_FAILED: u32 = 0x51; + +pub const MAX_ADDR_LEN: usize = 7; +pub const ARPD_UPDATE: ::c_ushort = 0x01; +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; + +// linux/net_tstamp.h +pub const SOF_TIMESTAMPING_TX_HARDWARE: ::c_uint = 1 << 0; +pub const SOF_TIMESTAMPING_TX_SOFTWARE: ::c_uint = 1 << 1; +pub const SOF_TIMESTAMPING_RX_HARDWARE: ::c_uint = 1 << 2; +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/tls.h +pub const TLS_TX: ::c_int = 1; +pub const TLS_RX: ::c_int = 2; + +pub const TLS_1_2_VERSION_MAJOR: ::__u8 = 0x3; +pub const TLS_1_2_VERSION_MINOR: ::__u8 = 0x3; +pub const TLS_1_2_VERSION: ::__u16 = + ((TLS_1_2_VERSION_MAJOR as ::__u16) << 8) | (TLS_1_2_VERSION_MINOR as ::__u16); + +pub const TLS_1_3_VERSION_MAJOR: ::__u8 = 0x3; +pub const TLS_1_3_VERSION_MINOR: ::__u8 = 0x4; +pub const TLS_1_3_VERSION: ::__u16 = + ((TLS_1_3_VERSION_MAJOR as ::__u16) << 8) | (TLS_1_3_VERSION_MINOR as ::__u16); + +pub const TLS_CIPHER_AES_GCM_128: ::__u16 = 51; +pub const TLS_CIPHER_AES_GCM_128_IV_SIZE: usize = 8; +pub const TLS_CIPHER_AES_GCM_128_KEY_SIZE: usize = 16; +pub const TLS_CIPHER_AES_GCM_128_SALT_SIZE: usize = 4; +pub const TLS_CIPHER_AES_GCM_128_TAG_SIZE: usize = 16; +pub const TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE: usize = 8; + +pub const TLS_CIPHER_AES_GCM_256: ::__u16 = 52; +pub const TLS_CIPHER_AES_GCM_256_IV_SIZE: usize = 8; +pub const TLS_CIPHER_AES_GCM_256_KEY_SIZE: usize = 32; +pub const TLS_CIPHER_AES_GCM_256_SALT_SIZE: usize = 4; +pub const TLS_CIPHER_AES_GCM_256_TAG_SIZE: usize = 16; +pub const TLS_CIPHER_AES_GCM_256_REC_SEQ_SIZE: usize = 8; + +pub const TLS_CIPHER_CHACHA20_POLY1305: ::__u16 = 54; +pub const TLS_CIPHER_CHACHA20_POLY1305_IV_SIZE: usize = 12; +pub const TLS_CIPHER_CHACHA20_POLY1305_KEY_SIZE: usize = 32; +pub const TLS_CIPHER_CHACHA20_POLY1305_SALT_SIZE: usize = 0; +pub const TLS_CIPHER_CHACHA20_POLY1305_TAG_SIZE: usize = 16; +pub const TLS_CIPHER_CHACHA20_POLY1305_REC_SEQ_SIZE: usize = 8; + +pub const TLS_SET_RECORD_TYPE: ::c_int = 1; +pub const TLS_GET_RECORD_TYPE: ::c_int = 2; + +pub const SOL_TLS: ::c_int = 282; + +// linux/if_alg.h +pub const ALG_SET_KEY: ::c_int = 1; +pub const ALG_SET_IV: ::c_int = 2; +pub const ALG_SET_OP: ::c_int = 3; +pub const ALG_SET_AEAD_ASSOCLEN: ::c_int = 4; +pub const ALG_SET_AEAD_AUTHSIZE: ::c_int = 5; +pub const ALG_SET_DRBG_ENTROPY: ::c_int = 6; +pub const ALG_SET_KEY_BY_KEY_SERIAL: ::c_int = 7; + +pub const ALG_OP_DECRYPT: ::c_int = 0; +pub const ALG_OP_ENCRYPT: ::c_int = 1; + +// include/uapi/linux/if.h +pub const IF_OPER_UNKNOWN: ::c_int = 0; +pub const IF_OPER_NOTPRESENT: ::c_int = 1; +pub const IF_OPER_DOWN: ::c_int = 2; +pub const IF_OPER_LOWERLAYERDOWN: ::c_int = 3; +pub const IF_OPER_TESTING: ::c_int = 4; +pub const IF_OPER_DORMANT: ::c_int = 5; +pub const IF_OPER_UP: ::c_int = 6; + +pub const IF_LINK_MODE_DEFAULT: ::c_int = 0; +pub const IF_LINK_MODE_DORMANT: ::c_int = 1; +pub const IF_LINK_MODE_TESTING: ::c_int = 2; + +// include/uapi/linux/udp.h +pub const UDP_CORK: ::c_int = 1; +pub const UDP_ENCAP: ::c_int = 100; +pub const UDP_NO_CHECK6_TX: ::c_int = 101; +pub const UDP_NO_CHECK6_RX: ::c_int = 102; + +// include/uapi/linux/mman.h +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; +pub const VMADDR_CID_HYPERVISOR: ::c_uint = 0; +#[deprecated( + since = "0.2.74", + note = "VMADDR_CID_RESERVED is removed since Linux v5.6 and \ + replaced with VMADDR_CID_LOCAL" +)] +pub const VMADDR_CID_RESERVED: ::c_uint = 1; +pub const VMADDR_CID_LOCAL: ::c_uint = 1; +pub const VMADDR_CID_HOST: ::c_uint = 2; +pub const VMADDR_PORT_ANY: ::c_uint = 0xFFFFFFFF; + +// uapi/linux/inotify.h +pub const IN_ACCESS: u32 = 0x0000_0001; +pub const IN_MODIFY: u32 = 0x0000_0002; +pub const IN_ATTRIB: u32 = 0x0000_0004; +pub const IN_CLOSE_WRITE: u32 = 0x0000_0008; +pub const IN_CLOSE_NOWRITE: u32 = 0x0000_0010; +pub const IN_CLOSE: u32 = IN_CLOSE_WRITE | IN_CLOSE_NOWRITE; +pub const IN_OPEN: u32 = 0x0000_0020; +pub const IN_MOVED_FROM: u32 = 0x0000_0040; +pub const IN_MOVED_TO: u32 = 0x0000_0080; +pub const IN_MOVE: u32 = IN_MOVED_FROM | IN_MOVED_TO; +pub const IN_CREATE: u32 = 0x0000_0100; +pub const IN_DELETE: u32 = 0x0000_0200; +pub const IN_DELETE_SELF: u32 = 0x0000_0400; +pub const IN_MOVE_SELF: u32 = 0x0000_0800; +pub const IN_UNMOUNT: u32 = 0x0000_2000; +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; + +// linux/keyctl.h +pub const KEY_SPEC_THREAD_KEYRING: i32 = -1; +pub const KEY_SPEC_PROCESS_KEYRING: i32 = -2; +pub const KEY_SPEC_SESSION_KEYRING: i32 = -3; +pub const KEY_SPEC_USER_KEYRING: i32 = -4; +pub const KEY_SPEC_USER_SESSION_KEYRING: i32 = -5; +pub const KEY_SPEC_GROUP_KEYRING: i32 = -6; +pub const KEY_SPEC_REQKEY_AUTH_KEY: i32 = -7; +pub const KEY_SPEC_REQUESTOR_KEYRING: i32 = -8; + +pub const KEY_REQKEY_DEFL_NO_CHANGE: i32 = -1; +pub const KEY_REQKEY_DEFL_DEFAULT: i32 = 0; +pub const KEY_REQKEY_DEFL_THREAD_KEYRING: i32 = 1; +pub const KEY_REQKEY_DEFL_PROCESS_KEYRING: i32 = 2; +pub const KEY_REQKEY_DEFL_SESSION_KEYRING: i32 = 3; +pub const KEY_REQKEY_DEFL_USER_KEYRING: i32 = 4; +pub const KEY_REQKEY_DEFL_USER_SESSION_KEYRING: i32 = 5; +pub const KEY_REQKEY_DEFL_GROUP_KEYRING: i32 = 6; +pub const KEY_REQKEY_DEFL_REQUESTOR_KEYRING: i32 = 7; + +pub const KEYCTL_GET_KEYRING_ID: u32 = 0; +pub const KEYCTL_JOIN_SESSION_KEYRING: u32 = 1; +pub const KEYCTL_UPDATE: u32 = 2; +pub const KEYCTL_REVOKE: u32 = 3; +pub const KEYCTL_CHOWN: u32 = 4; +pub const KEYCTL_SETPERM: u32 = 5; +pub const KEYCTL_DESCRIBE: u32 = 6; +pub const KEYCTL_CLEAR: u32 = 7; +pub const KEYCTL_LINK: u32 = 8; +pub const KEYCTL_UNLINK: u32 = 9; +pub const KEYCTL_SEARCH: u32 = 10; +pub const KEYCTL_READ: u32 = 11; +pub const KEYCTL_INSTANTIATE: u32 = 12; +pub const KEYCTL_NEGATE: u32 = 13; +pub const KEYCTL_SET_REQKEY_KEYRING: u32 = 14; +pub const KEYCTL_SET_TIMEOUT: u32 = 15; +pub const KEYCTL_ASSUME_AUTHORITY: u32 = 16; +pub const KEYCTL_GET_SECURITY: u32 = 17; +pub const KEYCTL_SESSION_TO_PARENT: u32 = 18; +pub const KEYCTL_REJECT: u32 = 19; +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_ISDIR: u32 = 0x4000_0000; +pub const IN_ONESHOT: u32 = 0x8000_0000; + +pub const IN_ALL_EVENTS: u32 = IN_ACCESS + | IN_MODIFY + | IN_ATTRIB + | IN_CLOSE_WRITE + | IN_CLOSE_NOWRITE + | IN_OPEN + | IN_MOVED_FROM + | IN_MOVED_TO + | IN_DELETE + | IN_CREATE + | IN_DELETE_SELF + | IN_MOVE_SELF; + +pub const IN_CLOEXEC: ::c_int = O_CLOEXEC; +pub const IN_NONBLOCK: ::c_int = O_NONBLOCK; + +// 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; +pub const NFT_SET_MAXNAMELEN: ::c_int = 256; +pub const NFT_OBJ_MAXNAMELEN: ::c_int = 256; +pub const NFT_USERDATA_MAXLEN: ::c_int = 256; + +pub const NFT_REG_VERDICT: ::c_int = 0; +pub const NFT_REG_1: ::c_int = 1; +pub const NFT_REG_2: ::c_int = 2; +pub const NFT_REG_3: ::c_int = 3; +pub const NFT_REG_4: ::c_int = 4; +pub const __NFT_REG_MAX: ::c_int = 5; +pub const NFT_REG32_00: ::c_int = 8; +pub const NFT_REG32_01: ::c_int = 9; +pub const NFT_REG32_02: ::c_int = 10; +pub const NFT_REG32_03: ::c_int = 11; +pub const NFT_REG32_04: ::c_int = 12; +pub const NFT_REG32_05: ::c_int = 13; +pub const NFT_REG32_06: ::c_int = 14; +pub const NFT_REG32_07: ::c_int = 15; +pub const NFT_REG32_08: ::c_int = 16; +pub const NFT_REG32_09: ::c_int = 17; +pub const NFT_REG32_10: ::c_int = 18; +pub const NFT_REG32_11: ::c_int = 19; +pub const NFT_REG32_12: ::c_int = 20; +pub const NFT_REG32_13: ::c_int = 21; +pub const NFT_REG32_14: ::c_int = 22; +pub const NFT_REG32_15: ::c_int = 23; + +pub const NFT_REG_SIZE: ::c_int = 16; +pub const NFT_REG32_SIZE: ::c_int = 4; + +pub const NFT_CONTINUE: ::c_int = -1; +pub const NFT_BREAK: ::c_int = -2; +pub const NFT_JUMP: ::c_int = -3; +pub const NFT_GOTO: ::c_int = -4; +pub const NFT_RETURN: ::c_int = -5; + +pub const NFT_MSG_NEWTABLE: ::c_int = 0; +pub const NFT_MSG_GETTABLE: ::c_int = 1; +pub const NFT_MSG_DELTABLE: ::c_int = 2; +pub const NFT_MSG_NEWCHAIN: ::c_int = 3; +pub const NFT_MSG_GETCHAIN: ::c_int = 4; +pub const NFT_MSG_DELCHAIN: ::c_int = 5; +pub const NFT_MSG_NEWRULE: ::c_int = 6; +pub const NFT_MSG_GETRULE: ::c_int = 7; +pub const NFT_MSG_DELRULE: ::c_int = 8; +pub const NFT_MSG_NEWSET: ::c_int = 9; +pub const NFT_MSG_GETSET: ::c_int = 10; +pub const NFT_MSG_DELSET: ::c_int = 11; +pub const NFT_MSG_NEWSETELEM: ::c_int = 12; +pub const NFT_MSG_GETSETELEM: ::c_int = 13; +pub const NFT_MSG_DELSETELEM: ::c_int = 14; +pub const NFT_MSG_NEWGEN: ::c_int = 15; +pub const NFT_MSG_GETGEN: ::c_int = 16; +pub const NFT_MSG_TRACE: ::c_int = 17; +cfg_if! { + if #[cfg(not(target_arch = "sparc64"))] { + pub const NFT_MSG_NEWOBJ: ::c_int = 18; + pub const NFT_MSG_GETOBJ: ::c_int = 19; + pub const NFT_MSG_DELOBJ: ::c_int = 20; + pub const NFT_MSG_GETOBJ_RESET: ::c_int = 21; + } +} +pub const NFT_MSG_MAX: ::c_int = 25; + +pub const NFT_SET_ANONYMOUS: ::c_int = 0x1; +pub const NFT_SET_CONSTANT: ::c_int = 0x2; +pub const NFT_SET_INTERVAL: ::c_int = 0x4; +pub const NFT_SET_MAP: ::c_int = 0x8; +pub const NFT_SET_TIMEOUT: ::c_int = 0x10; +pub const NFT_SET_EVAL: ::c_int = 0x20; + +pub const NFT_SET_POL_PERFORMANCE: ::c_int = 0; +pub const NFT_SET_POL_MEMORY: ::c_int = 1; + +pub const NFT_SET_ELEM_INTERVAL_END: ::c_int = 0x1; + +pub const NFT_DATA_VALUE: ::c_uint = 0; +pub const NFT_DATA_VERDICT: ::c_uint = 0xffffff00; + +pub const NFT_DATA_RESERVED_MASK: ::c_uint = 0xffffff00; + +pub const NFT_DATA_VALUE_MAXLEN: ::c_int = 64; + +pub const NFT_BYTEORDER_NTOH: ::c_int = 0; +pub const NFT_BYTEORDER_HTON: ::c_int = 1; + +pub const NFT_CMP_EQ: ::c_int = 0; +pub const NFT_CMP_NEQ: ::c_int = 1; +pub const NFT_CMP_LT: ::c_int = 2; +pub const NFT_CMP_LTE: ::c_int = 3; +pub const NFT_CMP_GT: ::c_int = 4; +pub const NFT_CMP_GTE: ::c_int = 5; + +pub const NFT_RANGE_EQ: ::c_int = 0; +pub const NFT_RANGE_NEQ: ::c_int = 1; + +pub const NFT_LOOKUP_F_INV: ::c_int = 1 << 0; + +pub const NFT_DYNSET_OP_ADD: ::c_int = 0; +pub const NFT_DYNSET_OP_UPDATE: ::c_int = 1; + +pub const NFT_DYNSET_F_INV: ::c_int = 1 << 0; + +pub const NFT_PAYLOAD_LL_HEADER: ::c_int = 0; +pub const NFT_PAYLOAD_NETWORK_HEADER: ::c_int = 1; +pub const NFT_PAYLOAD_TRANSPORT_HEADER: ::c_int = 2; + +pub const NFT_PAYLOAD_CSUM_NONE: ::c_int = 0; +pub const NFT_PAYLOAD_CSUM_INET: ::c_int = 1; + +pub const NFT_META_LEN: ::c_int = 0; +pub const NFT_META_PROTOCOL: ::c_int = 1; +pub const NFT_META_PRIORITY: ::c_int = 2; +pub const NFT_META_MARK: ::c_int = 3; +pub const NFT_META_IIF: ::c_int = 4; +pub const NFT_META_OIF: ::c_int = 5; +pub const NFT_META_IIFNAME: ::c_int = 6; +pub const NFT_META_OIFNAME: ::c_int = 7; +pub const NFT_META_IIFTYPE: ::c_int = 8; +pub const NFT_META_OIFTYPE: ::c_int = 9; +pub const NFT_META_SKUID: ::c_int = 10; +pub const NFT_META_SKGID: ::c_int = 11; +pub const NFT_META_NFTRACE: ::c_int = 12; +pub const NFT_META_RTCLASSID: ::c_int = 13; +pub const NFT_META_SECMARK: ::c_int = 14; +pub const NFT_META_NFPROTO: ::c_int = 15; +pub const NFT_META_L4PROTO: ::c_int = 16; +pub const NFT_META_BRI_IIFNAME: ::c_int = 17; +pub const NFT_META_BRI_OIFNAME: ::c_int = 18; +pub const NFT_META_PKTTYPE: ::c_int = 19; +pub const NFT_META_CPU: ::c_int = 20; +pub const NFT_META_IIFGROUP: ::c_int = 21; +pub const NFT_META_OIFGROUP: ::c_int = 22; +pub const NFT_META_CGROUP: ::c_int = 23; +pub const NFT_META_PRANDOM: ::c_int = 24; + +pub const NFT_CT_STATE: ::c_int = 0; +pub const NFT_CT_DIRECTION: ::c_int = 1; +pub const NFT_CT_STATUS: ::c_int = 2; +pub const NFT_CT_MARK: ::c_int = 3; +pub const NFT_CT_SECMARK: ::c_int = 4; +pub const NFT_CT_EXPIRATION: ::c_int = 5; +pub const NFT_CT_HELPER: ::c_int = 6; +pub const NFT_CT_L3PROTOCOL: ::c_int = 7; +pub const NFT_CT_SRC: ::c_int = 8; +pub const NFT_CT_DST: ::c_int = 9; +pub const NFT_CT_PROTOCOL: ::c_int = 10; +pub const NFT_CT_PROTO_SRC: ::c_int = 11; +pub const NFT_CT_PROTO_DST: ::c_int = 12; +pub const NFT_CT_LABELS: ::c_int = 13; +pub const NFT_CT_PKTS: ::c_int = 14; +pub const NFT_CT_BYTES: ::c_int = 15; +pub const NFT_CT_AVGPKT: ::c_int = 16; +pub const NFT_CT_ZONE: ::c_int = 17; +pub const NFT_CT_EVENTMASK: ::c_int = 18; +pub const NFT_CT_SRC_IP: ::c_int = 19; +pub const NFT_CT_DST_IP: ::c_int = 20; +pub const NFT_CT_SRC_IP6: ::c_int = 21; +pub const NFT_CT_DST_IP6: ::c_int = 22; + +pub const NFT_LIMIT_PKTS: ::c_int = 0; +pub const NFT_LIMIT_PKT_BYTES: ::c_int = 1; + +pub const NFT_LIMIT_F_INV: ::c_int = 1 << 0; + +pub const NFT_QUEUE_FLAG_BYPASS: ::c_int = 0x01; +pub const NFT_QUEUE_FLAG_CPU_FANOUT: ::c_int = 0x02; +pub const NFT_QUEUE_FLAG_MASK: ::c_int = 0x03; + +pub const NFT_QUOTA_F_INV: ::c_int = 1 << 0; + +pub const NFT_REJECT_ICMP_UNREACH: ::c_int = 0; +pub const NFT_REJECT_TCP_RST: ::c_int = 1; +pub const NFT_REJECT_ICMPX_UNREACH: ::c_int = 2; + +pub const NFT_REJECT_ICMPX_NO_ROUTE: ::c_int = 0; +pub const NFT_REJECT_ICMPX_PORT_UNREACH: ::c_int = 1; +pub const NFT_REJECT_ICMPX_HOST_UNREACH: ::c_int = 2; +pub const NFT_REJECT_ICMPX_ADMIN_PROHIBITED: ::c_int = 3; + +pub const NFT_NAT_SNAT: ::c_int = 0; +pub const NFT_NAT_DNAT: ::c_int = 1; + +pub const NFT_TRACETYPE_UNSPEC: ::c_int = 0; +pub const NFT_TRACETYPE_POLICY: ::c_int = 1; +pub const NFT_TRACETYPE_RETURN: ::c_int = 2; +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 = 0x10; +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; + +// uapi/linux/fanotify.h +pub const FAN_ACCESS: u64 = 0x0000_0001; +pub const FAN_MODIFY: u64 = 0x0000_0002; +pub const FAN_ATTRIB: u64 = 0x0000_0004; +pub const FAN_CLOSE_WRITE: u64 = 0x0000_0008; +pub const FAN_CLOSE_NOWRITE: u64 = 0x0000_0010; +pub const FAN_OPEN: u64 = 0x0000_0020; +pub const FAN_MOVED_FROM: u64 = 0x0000_0040; +pub const FAN_MOVED_TO: u64 = 0x0000_0080; +pub const FAN_CREATE: u64 = 0x0000_0100; +pub const FAN_DELETE: u64 = 0x0000_0200; +pub const FAN_DELETE_SELF: u64 = 0x0000_0400; +pub const FAN_MOVE_SELF: u64 = 0x0000_0800; +pub const FAN_OPEN_EXEC: u64 = 0x0000_1000; + +pub const FAN_Q_OVERFLOW: u64 = 0x0000_4000; +pub const FAN_FS_ERROR: u64 = 0x0000_8000; + +pub const FAN_OPEN_PERM: u64 = 0x0001_0000; +pub const FAN_ACCESS_PERM: u64 = 0x0002_0000; +pub const FAN_OPEN_EXEC_PERM: u64 = 0x0004_0000; + +pub const FAN_EVENT_ON_CHILD: u64 = 0x0800_0000; + +pub const FAN_RENAME: u64 = 0x1000_0000; + +pub const FAN_ONDIR: u64 = 0x4000_0000; + +pub const FAN_CLOSE: u64 = FAN_CLOSE_WRITE | FAN_CLOSE_NOWRITE; +pub const FAN_MOVE: u64 = FAN_MOVED_FROM | FAN_MOVED_TO; + +pub const FAN_CLOEXEC: ::c_uint = 0x0000_0001; +pub const FAN_NONBLOCK: ::c_uint = 0x0000_0002; + +pub const FAN_CLASS_NOTIF: ::c_uint = 0x0000_0000; +pub const FAN_CLASS_CONTENT: ::c_uint = 0x0000_0004; +pub const FAN_CLASS_PRE_CONTENT: ::c_uint = 0x0000_0008; + +pub const FAN_UNLIMITED_QUEUE: ::c_uint = 0x0000_0010; +pub const FAN_UNLIMITED_MARKS: ::c_uint = 0x0000_0020; +pub const FAN_ENABLE_AUDIT: ::c_uint = 0x0000_0040; + +pub const FAN_REPORT_PIDFD: ::c_uint = 0x0000_0080; +pub const FAN_REPORT_TID: ::c_uint = 0x0000_0100; +pub const FAN_REPORT_FID: ::c_uint = 0x0000_0200; +pub const FAN_REPORT_DIR_FID: ::c_uint = 0x0000_0400; +pub const FAN_REPORT_NAME: ::c_uint = 0x0000_0800; +pub const FAN_REPORT_TARGET_FID: ::c_uint = 0x0000_1000; + +pub const FAN_REPORT_DFID_NAME: ::c_uint = FAN_REPORT_DIR_FID | FAN_REPORT_NAME; +pub const FAN_REPORT_DFID_NAME_TARGET: ::c_uint = + FAN_REPORT_DFID_NAME | FAN_REPORT_FID | FAN_REPORT_TARGET_FID; + +pub const FAN_MARK_ADD: ::c_uint = 0x0000_0001; +pub const FAN_MARK_REMOVE: ::c_uint = 0x0000_0002; +pub const FAN_MARK_DONT_FOLLOW: ::c_uint = 0x0000_0004; +pub const FAN_MARK_ONLYDIR: ::c_uint = 0x0000_0008; +pub const FAN_MARK_IGNORED_MASK: ::c_uint = 0x0000_0020; +pub const FAN_MARK_IGNORED_SURV_MODIFY: ::c_uint = 0x0000_0040; +pub const FAN_MARK_FLUSH: ::c_uint = 0x0000_0080; +pub const FAN_MARK_EVICTABLE: ::c_uint = 0x0000_0200; +pub const FAN_MARK_IGNORE: ::c_uint = 0x0000_0400; + +pub const FAN_MARK_INODE: ::c_uint = 0x0000_0000; +pub const FAN_MARK_MOUNT: ::c_uint = 0x0000_0010; +pub const FAN_MARK_FILESYSTEM: ::c_uint = 0x0000_0100; + +pub const FAN_MARK_IGNORE_SURV: ::c_uint = FAN_MARK_IGNORE | FAN_MARK_IGNORED_SURV_MODIFY; + +pub const FANOTIFY_METADATA_VERSION: u8 = 3; + +pub const FAN_EVENT_INFO_TYPE_FID: u8 = 1; +pub const FAN_EVENT_INFO_TYPE_DFID_NAME: u8 = 2; +pub const FAN_EVENT_INFO_TYPE_DFID: u8 = 3; +pub const FAN_EVENT_INFO_TYPE_PIDFD: u8 = 4; +pub const FAN_EVENT_INFO_TYPE_ERROR: u8 = 5; + +pub const FAN_EVENT_INFO_TYPE_OLD_DFID_NAME: u8 = 10; +pub const FAN_EVENT_INFO_TYPE_NEW_DFID_NAME: u8 = 12; + +pub const FAN_RESPONSE_INFO_NONE: u8 = 0; +pub const FAN_RESPONSE_INFO_AUDIT_RULE: u8 = 1; + +pub const FAN_ALLOW: u32 = 0x01; +pub const FAN_DENY: u32 = 0x02; +pub const FAN_AUDIT: u32 = 0x10; +pub const FAN_INFO: u32 = 0x20; + +pub const FAN_NOFD: ::c_int = -1; +pub const FAN_NOPIDFD: ::c_int = FAN_NOFD; +pub const FAN_EPIDFD: ::c_int = -2; + +// linux/futex.h +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_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_WAITERS: u32 = 0x80000000; +pub const FUTEX_OWNER_DIED: u32 = 0x40000000; +pub const FUTEX_TID_MASK: u32 = 0x3fffffff; + +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; +pub const LINUX_REBOOT_MAGIC2A: ::c_int = 85072278; +pub const LINUX_REBOOT_MAGIC2B: ::c_int = 369367448; +pub const LINUX_REBOOT_MAGIC2C: ::c_int = 537993216; + +pub const LINUX_REBOOT_CMD_RESTART: ::c_int = 0x01234567; +pub const LINUX_REBOOT_CMD_HALT: ::c_int = 0xCDEF0123; +pub const LINUX_REBOOT_CMD_CAD_ON: ::c_int = 0x89ABCDEF; +pub const LINUX_REBOOT_CMD_CAD_OFF: ::c_int = 0x00000000; +pub const LINUX_REBOOT_CMD_POWER_OFF: ::c_int = 0x4321FEDC; +pub const LINUX_REBOOT_CMD_RESTART2: ::c_int = 0xA1B2C3D4; +pub const LINUX_REBOOT_CMD_SW_SUSPEND: ::c_int = 0xD000FCE2; +pub const LINUX_REBOOT_CMD_KEXEC: ::c_int = 0x45584543; + +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 = 1; +pub const REG_NOTEOL: ::c_int = 2; + +pub const REG_ENOSYS: ::c_int = -1; +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; + +// linux/errqueue.h +pub const SO_EE_ORIGIN_NONE: u8 = 0; +pub const SO_EE_ORIGIN_LOCAL: u8 = 1; +pub const SO_EE_ORIGIN_ICMP: u8 = 2; +pub const SO_EE_ORIGIN_ICMP6: u8 = 3; +pub const SO_EE_ORIGIN_TXSTATUS: u8 = 4; +pub const SO_EE_ORIGIN_TIMESTAMPING: u8 = SO_EE_ORIGIN_TXSTATUS; + +// 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 EWOULDBLOCK: ::c_int = EAGAIN; + +// linux/can.h +pub const CAN_EFF_FLAG: canid_t = 0x80000000; +pub const CAN_RTR_FLAG: canid_t = 0x40000000; +pub const CAN_ERR_FLAG: canid_t = 0x20000000; +pub const CAN_SFF_MASK: canid_t = 0x000007FF; +pub const CAN_EFF_MASK: canid_t = 0x1FFFFFFF; +pub const CAN_ERR_MASK: canid_t = 0x1FFFFFFF; +pub const CANXL_PRIO_MASK: ::canid_t = CAN_SFF_MASK; + +pub const CAN_SFF_ID_BITS: ::c_int = 11; +pub const CAN_EFF_ID_BITS: ::c_int = 29; +pub const CANXL_PRIO_BITS: ::c_int = CAN_SFF_ID_BITS; + +pub const CAN_MAX_DLC: ::c_int = 8; +pub const CAN_MAX_DLEN: usize = 8; +pub const CANFD_MAX_DLC: ::c_int = 15; +pub const CANFD_MAX_DLEN: usize = 64; + +pub const CANFD_BRS: ::c_int = 0x01; +pub const CANFD_ESI: ::c_int = 0x02; + +pub const CANXL_MIN_DLC: ::c_int = 0; +pub const CANXL_MAX_DLC: ::c_int = 2047; +pub const CANXL_MAX_DLC_MASK: ::c_int = 0x07FF; +pub const CANXL_MIN_DLEN: usize = 1; +pub const CANXL_MAX_DLEN: usize = 2048; + +pub const CANXL_XLF: ::c_int = 0x80; +pub const CANXL_SEC: ::c_int = 0x01; + +cfg_if! { + if #[cfg(libc_align)] { + pub const CAN_MTU: usize = ::mem::size_of::(); + pub const CANFD_MTU: usize = ::mem::size_of::(); + pub const CANXL_MTU: usize = ::mem::size_of::(); + // FIXME: use `core::mem::offset_of!` once that is available + // https://github.com/rust-lang/rfcs/pull/3308 + // pub const CANXL_HDR_SIZE: usize = core::mem::offset_of!(canxl_frame, data); + pub const CANXL_HDR_SIZE: usize = 12; + pub const CANXL_MIN_MTU: usize = CANXL_HDR_SIZE + 64; + pub const CANXL_MAX_MTU: usize = CANXL_MTU; + } +} + +pub const CAN_RAW: ::c_int = 1; +pub const CAN_BCM: ::c_int = 2; +pub const CAN_TP16: ::c_int = 3; +pub const CAN_TP20: ::c_int = 4; +pub const CAN_MCNET: ::c_int = 5; +pub const CAN_ISOTP: ::c_int = 6; +pub const CAN_J1939: ::c_int = 7; +pub const CAN_NPROTO: ::c_int = 8; + +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; +pub const CAN_RAW_XL_FRAMES: ::c_int = 7; + +// 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; + +pub const CTL_KERN: ::c_int = 1; +pub const CTL_VM: ::c_int = 2; +pub const CTL_NET: ::c_int = 3; +pub const CTL_FS: ::c_int = 5; +pub const CTL_DEBUG: ::c_int = 6; +pub const CTL_DEV: ::c_int = 7; +pub const CTL_BUS: ::c_int = 8; +pub const CTL_ABI: ::c_int = 9; +pub const CTL_CPU: ::c_int = 10; + +pub const CTL_BUS_ISA: ::c_int = 1; + +pub const INOTIFY_MAX_USER_INSTANCES: ::c_int = 1; +pub const INOTIFY_MAX_USER_WATCHES: ::c_int = 2; +pub const INOTIFY_MAX_QUEUED_EVENTS: ::c_int = 3; + +pub const KERN_OSTYPE: ::c_int = 1; +pub const KERN_OSRELEASE: ::c_int = 2; +pub const KERN_OSREV: ::c_int = 3; +pub const KERN_VERSION: ::c_int = 4; +pub const KERN_SECUREMASK: ::c_int = 5; +pub const KERN_PROF: ::c_int = 6; +pub const KERN_NODENAME: ::c_int = 7; +pub const KERN_DOMAINNAME: ::c_int = 8; +pub const KERN_PANIC: ::c_int = 15; +pub const KERN_REALROOTDEV: ::c_int = 16; +pub const KERN_SPARC_REBOOT: ::c_int = 21; +pub const KERN_CTLALTDEL: ::c_int = 22; +pub const KERN_PRINTK: ::c_int = 23; +pub const KERN_NAMETRANS: ::c_int = 24; +pub const KERN_PPC_HTABRECLAIM: ::c_int = 25; +pub const KERN_PPC_ZEROPAGED: ::c_int = 26; +pub const KERN_PPC_POWERSAVE_NAP: ::c_int = 27; +pub const KERN_MODPROBE: ::c_int = 28; +pub const KERN_SG_BIG_BUFF: ::c_int = 29; +pub const KERN_ACCT: ::c_int = 30; +pub const KERN_PPC_L2CR: ::c_int = 31; +pub const KERN_RTSIGNR: ::c_int = 32; +pub const KERN_RTSIGMAX: ::c_int = 33; +pub const KERN_SHMMAX: ::c_int = 34; +pub const KERN_MSGMAX: ::c_int = 35; +pub const KERN_MSGMNB: ::c_int = 36; +pub const KERN_MSGPOOL: ::c_int = 37; +pub const KERN_SYSRQ: ::c_int = 38; +pub const KERN_MAX_THREADS: ::c_int = 39; +pub const KERN_RANDOM: ::c_int = 40; +pub const KERN_SHMALL: ::c_int = 41; +pub const KERN_MSGMNI: ::c_int = 42; +pub const KERN_SEM: ::c_int = 43; +pub const KERN_SPARC_STOP_A: ::c_int = 44; +pub const KERN_SHMMNI: ::c_int = 45; +pub const KERN_OVERFLOWUID: ::c_int = 46; +pub const KERN_OVERFLOWGID: ::c_int = 47; +pub const KERN_SHMPATH: ::c_int = 48; +pub const KERN_HOTPLUG: ::c_int = 49; +pub const KERN_IEEE_EMULATION_WARNINGS: ::c_int = 50; +pub const KERN_S390_USER_DEBUG_LOGGING: ::c_int = 51; +pub const KERN_CORE_USES_PID: ::c_int = 52; +pub const KERN_TAINTED: ::c_int = 53; +pub const KERN_CADPID: ::c_int = 54; +pub const KERN_PIDMAX: ::c_int = 55; +pub const KERN_CORE_PATTERN: ::c_int = 56; +pub const KERN_PANIC_ON_OOPS: ::c_int = 57; +pub const KERN_HPPA_PWRSW: ::c_int = 58; +pub const KERN_HPPA_UNALIGNED: ::c_int = 59; +pub const KERN_PRINTK_RATELIMIT: ::c_int = 60; +pub const KERN_PRINTK_RATELIMIT_BURST: ::c_int = 61; +pub const KERN_PTY: ::c_int = 62; +pub const KERN_NGROUPS_MAX: ::c_int = 63; +pub const KERN_SPARC_SCONS_PWROFF: ::c_int = 64; +pub const KERN_HZ_TIMER: ::c_int = 65; +pub const KERN_UNKNOWN_NMI_PANIC: ::c_int = 66; +pub const KERN_BOOTLOADER_TYPE: ::c_int = 67; +pub const KERN_RANDOMIZE: ::c_int = 68; +pub const KERN_SETUID_DUMPABLE: ::c_int = 69; +pub const KERN_SPIN_RETRY: ::c_int = 70; +pub const KERN_ACPI_VIDEO_FLAGS: ::c_int = 71; +pub const KERN_IA64_UNALIGNED: ::c_int = 72; +pub const KERN_COMPAT_LOG: ::c_int = 73; +pub const KERN_MAX_LOCK_DEPTH: ::c_int = 74; +pub const KERN_NMI_WATCHDOG: ::c_int = 75; +pub const KERN_PANIC_ON_NMI: ::c_int = 76; + +pub const VM_OVERCOMMIT_MEMORY: ::c_int = 5; +pub const VM_PAGE_CLUSTER: ::c_int = 10; +pub const VM_DIRTY_BACKGROUND: ::c_int = 11; +pub const VM_DIRTY_RATIO: ::c_int = 12; +pub const VM_DIRTY_WB_CS: ::c_int = 13; +pub const VM_DIRTY_EXPIRE_CS: ::c_int = 14; +pub const VM_NR_PDFLUSH_THREADS: ::c_int = 15; +pub const VM_OVERCOMMIT_RATIO: ::c_int = 16; +pub const VM_PAGEBUF: ::c_int = 17; +pub const VM_HUGETLB_PAGES: ::c_int = 18; +pub const VM_SWAPPINESS: ::c_int = 19; +pub const VM_LOWMEM_RESERVE_RATIO: ::c_int = 20; +pub const VM_MIN_FREE_KBYTES: ::c_int = 21; +pub const VM_MAX_MAP_COUNT: ::c_int = 22; +pub const VM_LAPTOP_MODE: ::c_int = 23; +pub const VM_BLOCK_DUMP: ::c_int = 24; +pub const VM_HUGETLB_GROUP: ::c_int = 25; +pub const VM_VFS_CACHE_PRESSURE: ::c_int = 26; +pub const VM_LEGACY_VA_LAYOUT: ::c_int = 27; +pub const VM_SWAP_TOKEN_TIMEOUT: ::c_int = 28; +pub const VM_DROP_PAGECACHE: ::c_int = 29; +pub const VM_PERCPU_PAGELIST_FRACTION: ::c_int = 30; +pub const VM_ZONE_RECLAIM_MODE: ::c_int = 31; +pub const VM_MIN_UNMAPPED: ::c_int = 32; +pub const VM_PANIC_ON_OOM: ::c_int = 33; +pub const VM_VDSO_ENABLED: ::c_int = 34; +pub const VM_MIN_SLAB: ::c_int = 35; + +pub const NET_CORE: ::c_int = 1; +pub const NET_ETHER: ::c_int = 2; +pub const NET_802: ::c_int = 3; +pub const NET_UNIX: ::c_int = 4; +pub const NET_IPV4: ::c_int = 5; +pub const NET_IPX: ::c_int = 6; +pub const NET_ATALK: ::c_int = 7; +pub const NET_NETROM: ::c_int = 8; +pub const NET_AX25: ::c_int = 9; +pub const NET_BRIDGE: ::c_int = 10; +pub const NET_ROSE: ::c_int = 11; +pub const NET_IPV6: ::c_int = 12; +pub const NET_X25: ::c_int = 13; +pub const NET_TR: ::c_int = 14; +pub const NET_DECNET: ::c_int = 15; +pub const NET_ECONET: ::c_int = 16; +pub const NET_SCTP: ::c_int = 17; +pub const NET_LLC: ::c_int = 18; +pub const NET_NETFILTER: ::c_int = 19; +pub const NET_DCCP: ::c_int = 20; +pub const NET_IRDA: ::c_int = 412; + +// include/linux/sched.h +pub const PF_VCPU: ::c_int = 0x00000001; +pub const PF_IDLE: ::c_int = 0x00000002; +pub const PF_EXITING: ::c_int = 0x00000004; +pub const PF_POSTCOREDUMP: ::c_int = 0x00000008; +pub const PF_IO_WORKER: ::c_int = 0x00000010; +pub const PF_WQ_WORKER: ::c_int = 0x00000020; +pub const PF_FORKNOEXEC: ::c_int = 0x00000040; +pub const PF_MCE_PROCESS: ::c_int = 0x00000080; +pub const PF_SUPERPRIV: ::c_int = 0x00000100; +pub const PF_DUMPCORE: ::c_int = 0x00000200; +pub const PF_SIGNALED: ::c_int = 0x00000400; +pub const PF_MEMALLOC: ::c_int = 0x00000800; +pub const PF_NPROC_EXCEEDED: ::c_int = 0x00001000; +pub const PF_USED_MATH: ::c_int = 0x00002000; +pub const PF_USER_WORKER: ::c_int = 0x00004000; +pub const PF_NOFREEZE: ::c_int = 0x00008000; +pub const PF_KSWAPD: ::c_int = 0x00020000; +pub const PF_MEMALLOC_NOFS: ::c_int = 0x00040000; +pub const PF_MEMALLOC_NOIO: ::c_int = 0x00080000; +pub const PF_LOCAL_THROTTLE: ::c_int = 0x00100000; +pub const PF_KTHREAD: ::c_int = 0x00200000; +pub const PF_RANDOMIZE: ::c_int = 0x00400000; +pub const PF_NO_SETAFFINITY: ::c_int = 0x04000000; +pub const PF_MCE_EARLY: ::c_int = 0x08000000; +pub const PF_MEMALLOC_PIN: ::c_int = 0x10000000; + +pub const CSIGNAL: ::c_int = 0x000000ff; + +pub const SCHED_NORMAL: ::c_int = 0; +pub const SCHED_OTHER: ::c_int = 0; +pub const SCHED_FIFO: ::c_int = 1; +pub const SCHED_RR: ::c_int = 2; +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; + +pub const SCHED_FLAG_RESET_ON_FORK: ::c_int = 0x01; +pub const SCHED_FLAG_RECLAIM: ::c_int = 0x02; +pub const SCHED_FLAG_DL_OVERRUN: ::c_int = 0x04; +pub const SCHED_FLAG_KEEP_POLICY: ::c_int = 0x08; +pub const SCHED_FLAG_KEEP_PARAMS: ::c_int = 0x10; +pub const SCHED_FLAG_UTIL_CLAMP_MIN: ::c_int = 0x20; +pub const SCHED_FLAG_UTIL_CLAMP_MAX: ::c_int = 0x40; + +// 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 SCHED_FLAG_KEEP_ALL: ::c_int = SCHED_FLAG_KEEP_POLICY | SCHED_FLAG_KEEP_PARAMS; + +pub const SCHED_FLAG_UTIL_CLAMP: ::c_int = SCHED_FLAG_UTIL_CLAMP_MIN | SCHED_FLAG_UTIL_CLAMP_MAX; + +pub const SCHED_FLAG_ALL: ::c_int = SCHED_FLAG_RESET_ON_FORK + | SCHED_FLAG_RECLAIM + | SCHED_FLAG_DL_OVERRUN + | SCHED_FLAG_KEEP_ALL + | SCHED_FLAG_UTIL_CLAMP; + +f! { + pub fn NLA_ALIGN(len: ::c_int) -> ::c_int { + return ((len) + NLA_ALIGNTO - 1) & !(NLA_ALIGNTO - 1) + } + + pub fn CMSG_NXTHDR(mhdr: *const msghdr, + cmsg: *const cmsghdr) -> *mut cmsghdr { + if ((*cmsg).cmsg_len as usize) < ::mem::size_of::() { + return 0 as *mut cmsghdr; + }; + let next = (cmsg as usize + + super::CMSG_ALIGN((*cmsg).cmsg_len as usize)) + as *mut cmsghdr; + let max = (*mhdr).msg_control as usize + + (*mhdr).msg_controllen as usize; + if (next.wrapping_offset(1)) as usize > max || + next as usize + super::CMSG_ALIGN((*next).cmsg_len as usize) > max + { + 0 as *mut cmsghdr + } else { + next as *mut cmsghdr + } + } + + 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; + } + } + + pub fn CPU_SET(cpu: usize, cpuset: &mut cpu_set_t) -> () { + let size_in_bits + = 8 * ::mem::size_of_val(&cpuset.bits[0]); // 32, 64 etc + let (idx, offset) = (cpu / size_in_bits, cpu % size_in_bits); + cpuset.bits[idx] |= 1 << offset; + () + } + + pub fn CPU_CLR(cpu: usize, cpuset: &mut cpu_set_t) -> () { + let size_in_bits + = 8 * ::mem::size_of_val(&cpuset.bits[0]); // 32, 64 etc + let (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); + 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 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; + major |= (dev & 0xfffff00000000000) >> 32; + major as ::c_uint + } + + pub fn minor(dev: ::dev_t) -> ::c_uint { + let mut minor = 0; + minor |= (dev & 0x00000000000000ff) >> 0; + minor |= (dev & 0x00000ffffff00000) >> 12; + minor as ::c_uint + } + + pub fn IPTOS_TOS(tos: u8) -> u8 { + tos & IPTOS_TOS_MASK + } + + pub fn IPTOS_PREC(tos: u8) -> u8 { + tos & IPTOS_PREC_MASK + } + + pub fn RT_TOS(tos: u8) -> u8 { + tos & ::IPTOS_TOS_MASK + } + + pub fn RT_ADDRCLASS(flags: u32) -> u32 { + flags >> 23 + } + + pub fn RT_LOCALADDR(flags: u32) -> bool { + (flags & RTF_ADDRCLASSMASK) == (RTF_LOCAL | RTF_INTERFACE) + } + + pub fn SO_EE_OFFENDER(ee: *const ::sock_extended_err) -> *mut ::sockaddr { + ee.offset(1) as *mut ::sockaddr + } + + pub fn TPACKET_ALIGN(x: usize) -> usize { + (x + TPACKET_ALIGNMENT - 1) & !(TPACKET_ALIGNMENT - 1) + } + + 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(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; + pub fn aio_fsync(op: ::c_int, aiocbp: *mut aiocb) -> ::c_int; + pub fn aio_error(aiocbp: *const aiocb) -> ::c_int; + pub fn aio_return(aiocbp: *mut aiocb) -> ::ssize_t; + pub fn aio_suspend( + aiocb_list: *const *const aiocb, + nitems: ::c_int, + timeout: *const ::timespec, + ) -> ::c_int; + pub fn aio_cancel(fd: ::c_int, aiocbp: *mut aiocb) -> ::c_int; + pub fn lio_listio( + mode: ::c_int, + aiocb_list: *const *mut aiocb, + 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, + iovcnt: ::c_int, + offset: ::off_t, + ) -> ::ssize_t; + pub fn preadv( + fd: ::c_int, + iov: *const ::iovec, + iovcnt: ::c_int, + offset: ::off_t, + ) -> ::ssize_t; + pub fn getnameinfo( + sa: *const ::sockaddr, + salen: ::socklen_t, + host: *mut ::c_char, + hostlen: ::socklen_t, + serv: *mut ::c_char, + servlen: ::socklen_t, + flags: ::c_int, + ) -> ::c_int; + pub fn getloadavg( + loadavg: *mut ::c_double, + nelem: ::c_int + ) -> ::c_int; + pub fn process_vm_readv( + pid: ::pid_t, + local_iov: *const ::iovec, + liovcnt: ::c_ulong, + remote_iov: *const ::iovec, + riovcnt: ::c_ulong, + flags: ::c_ulong, + ) -> isize; + pub fn process_vm_writev( + pid: ::pid_t, + local_iov: *const ::iovec, + liovcnt: ::c_ulong, + remote_iov: *const ::iovec, + riovcnt: ::c_ulong, + flags: ::c_ulong, + ) -> isize; + pub fn futimes( + fd: ::c_int, + times: *const ::timeval + ) -> ::c_int; + } + } +} + +// 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 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(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 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(); + 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 getspent() -> *mut spwd; + + pub fn getspnam(name: *const ::c_char) -> *mut spwd; + + 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; + + // System V IPC + 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 ftok(pathname: *const ::c_char, proj_id: ::c_int) -> ::key_t; + 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 semctl(semid: ::c_int, semnum: ::c_int, cmd: ::c_int, ...) -> ::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 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 mprotect(addr: *mut ::c_void, len: ::size_t, prot: ::c_int) -> ::c_int; + pub fn __errno_location() -> *mut ::c_int; + + pub fn fallocate(fd: ::c_int, mode: ::c_int, offset: ::off_t, len: ::off_t) -> ::c_int; + pub fn posix_fallocate(fd: ::c_int, offset: ::off_t, len: ::off_t) -> ::c_int; + pub fn readahead(fd: ::c_int, offset: ::off64_t, count: ::size_t) -> ::ssize_t; + 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, + flags: ::c_int, + ) -> ::c_int; + pub fn lsetxattr( + path: *const c_char, + name: *const c_char, + value: *const ::c_void, + size: ::size_t, + flags: ::c_int, + ) -> ::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(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: ::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, + flags: ::c_int, + new_value: *const itimerspec, + old_value: *mut itimerspec, + ) -> ::c_int; + pub fn quotactl( + cmd: ::c_int, + special: *const ::c_char, + id: ::c_int, + data: *mut ::c_char, + ) -> ::c_int; + pub fn epoll_pwait( + epfd: ::c_int, + events: *mut ::epoll_event, + maxevents: ::c_int, + timeout: ::c_int, + sigmask: *const ::sigset_t, + ) -> ::c_int; + pub fn dup3(oldfd: ::c_int, newfd: ::c_int, flags: ::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; + 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 nl_langinfo_l(item: ::nl_item, locale: ::locale_t) -> *mut ::c_char; + pub fn accept4( + fd: ::c_int, + addr: *mut ::sockaddr, + 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; + pub fn setfsuid(uid: ::uid_t) -> ::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); + pub fn sync_file_range( + fd: ::c_int, + offset: ::off64_t, + nbytes: ::off64_t, + flags: ::c_uint, + ) -> ::c_int; + pub fn mremap( + addr: *mut ::c_void, + len: ::size_t, + new_len: ::size_t, + flags: ::c_int, + ... + ) -> *mut ::c_void; + + 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 seekdir(dirp: *mut ::DIR, loc: ::c_long); + + pub fn telldir(dirp: *mut ::DIR) -> ::c_long; + 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 remap_file_pages( + addr: *mut ::c_void, + size: ::size_t, + prot: ::c_int, + pgoff: ::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 nl_langinfo(item: ::nl_item) -> *mut ::c_char; + + pub fn getdomainname(name: *mut ::c_char, len: ::size_t) -> ::c_int; + pub fn setdomainname(name: *const ::c_char, len: ::size_t) -> ::c_int; + pub fn vhangup() -> ::c_int; + pub fn sync(); + pub fn syncfs(fd: ::c_int) -> ::c_int; + pub fn syscall(num: ::c_long, ...) -> ::c_long; + pub fn sched_getaffinity(pid: ::pid_t, cpusetsize: ::size_t, cpuset: *mut cpu_set_t) + -> ::c_int; + pub fn sched_setaffinity( + pid: ::pid_t, + cpusetsize: ::size_t, + cpuset: *const cpu_set_t, + ) -> ::c_int; + pub fn epoll_create(size: ::c_int) -> ::c_int; + pub fn epoll_create1(flags: ::c_int) -> ::c_int; + pub fn epoll_wait( + epfd: ::c_int, + events: *mut ::epoll_event, + maxevents: ::c_int, + timeout: ::c_int, + ) -> ::c_int; + pub fn epoll_ctl(epfd: ::c_int, op: ::c_int, fd: ::c_int, event: *mut ::epoll_event) + -> ::c_int; + pub fn pthread_getschedparam( + native: ::pthread_t, + policy: *mut ::c_int, + param: *mut ::sched_param, + ) -> ::c_int; + pub fn unshare(flags: ::c_int) -> ::c_int; + pub fn umount(target: *const ::c_char) -> ::c_int; + pub fn sched_get_priority_max(policy: ::c_int) -> ::c_int; + pub fn tee(fd_in: ::c_int, fd_out: ::c_int, len: ::size_t, flags: ::c_uint) -> ::ssize_t; + pub fn settimeofday(tv: *const ::timeval, tz: *const ::timezone) -> ::c_int; + pub fn splice( + fd_in: ::c_int, + off_in: *mut ::loff_t, + fd_out: ::c_int, + off_out: *mut ::loff_t, + len: ::size_t, + flags: ::c_uint, + ) -> ::ssize_t; + pub fn eventfd(init: ::c_uint, flags: ::c_int) -> ::c_int; + pub fn eventfd_read(fd: ::c_int, value: *mut eventfd_t) -> ::c_int; + pub fn eventfd_write(fd: ::c_int, value: eventfd_t) -> ::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 setns(fd: ::c_int, nstype: ::c_int) -> ::c_int; + pub fn swapoff(path: *const ::c_char) -> ::c_int; + pub fn vmsplice( + fd: ::c_int, + iov: *const ::iovec, + nr_segs: ::size_t, + flags: ::c_uint, + ) -> ::ssize_t; + pub fn mount( + src: *const ::c_char, + target: *const ::c_char, + fstype: *const ::c_char, + flags: ::c_ulong, + data: *const ::c_void, + ) -> ::c_int; + pub fn personality(persona: ::c_ulong) -> ::c_int; + pub fn prctl(option: ::c_int, ...) -> ::c_int; + pub fn sched_getparam(pid: ::pid_t, param: *mut ::sched_param) -> ::c_int; + pub fn ppoll( + fds: *mut ::pollfd, + nfds: nfds_t, + 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, + flags: ::c_int, + arg: *mut ::c_void, + ... + ) -> ::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 pthread_attr_setguardsize(attr: *mut ::pthread_attr_t, guardsize: ::size_t) -> ::c_int; + pub fn pthread_attr_getinheritsched( + attr: *const ::pthread_attr_t, + inheritsched: *mut ::c_int, + ) -> ::c_int; + pub fn pthread_attr_setinheritsched( + attr: *mut ::pthread_attr_t, + inheritsched: ::c_int, + ) -> ::c_int; + pub fn pthread_attr_getschedpolicy( + attr: *const ::pthread_attr_t, + policy: *mut ::c_int, + ) -> ::c_int; + pub fn pthread_attr_setschedpolicy(attr: *mut ::pthread_attr_t, policy: ::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 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 sysinfo(info: *mut ::sysinfo) -> ::c_int; + pub fn umount2(target: *const ::c_char, flags: ::c_int) -> ::c_int; + pub fn pthread_setschedparam( + native: ::pthread_t, + policy: ::c_int, + param: *const ::sched_param, + ) -> ::c_int; + pub fn swapon(path: *const ::c_char, swapflags: ::c_int) -> ::c_int; + pub fn sched_setscheduler( + pid: ::pid_t, + policy: ::c_int, + param: *const ::sched_param, + ) -> ::c_int; + pub fn sendfile( + out_fd: ::c_int, + in_fd: ::c_int, + offset: *mut off_t, + count: ::size_t, + ) -> ::ssize_t; + 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 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; + 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_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 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 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 dl_iterate_phdr( + callback: ::Option< + unsafe extern "C" fn( + info: *mut ::dl_phdr_info, + size: ::size_t, + data: *mut ::c_void, + ) -> ::c_int, + >, + data: *mut ::c_void, + ) -> ::c_int; + + pub fn setmntent(filename: *const ::c_char, ty: *const ::c_char) -> *mut ::FILE; + pub fn getmntent(stream: *mut ::FILE) -> *mut ::mntent; + pub fn addmntent(stream: *mut ::FILE, mnt: *const ::mntent) -> ::c_int; + pub fn endmntent(streamp: *mut ::FILE) -> ::c_int; + pub fn hasmntopt(mnt: *const ::mntent, opt: *const ::c_char) -> *mut ::c_char; + + 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 fread_unlocked( + buf: *mut ::c_void, + size: ::size_t, + nobj: ::size_t, + stream: *mut ::FILE, + ) -> ::size_t; + pub fn inotify_rm_watch(fd: ::c_int, wd: ::c_int) -> ::c_int; + pub fn inotify_init() -> ::c_int; + pub fn inotify_init1(flags: ::c_int) -> ::c_int; + pub fn inotify_add_watch(fd: ::c_int, path: *const ::c_char, mask: u32) -> ::c_int; + pub fn fanotify_init(flags: ::c_uint, event_f_flags: ::c_uint) -> ::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 iconv_open(tocode: *const ::c_char, fromcode: *const ::c_char) -> iconv_t; + 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 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 pthread_once(control: *mut pthread_once_t, routine: extern "C" fn()) -> ::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 klogctl(syslog_type: ::c_int, bufp: *mut ::c_char, len: ::c_int) -> ::c_int; + + pub fn ioctl(fd: ::c_int, request: ::Ioctl, ...) -> ::c_int; +} + +// LFS64 extensions +// +// * musl has 64-bit versions only so aliases the LFS64 symbols to the standard ones +cfg_if! { + if #[cfg(not(target_env = "musl"))] { + extern "C" { + pub fn fallocate64( + fd: ::c_int, + mode: ::c_int, + offset: ::off64_t, + len: ::off64_t + ) -> ::c_int; + pub fn fgetpos64(stream: *mut ::FILE, ptr: *mut fpos64_t) -> ::c_int; + pub fn fopen64(filename: *const c_char, mode: *const c_char) -> *mut ::FILE; + 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 ftello64(stream: *mut ::FILE) -> ::off64_t; + pub fn posix_fallocate64(fd: ::c_int, offset: ::off64_t, len: ::off64_t) -> ::c_int; + pub fn sendfile64( + out_fd: ::c_int, + in_fd: ::c_int, + offset: *mut off64_t, + count: ::size_t, + ) -> ::ssize_t; + pub fn tmpfile64() -> *mut ::FILE; + } + } +} + +cfg_if! { + if #[cfg(target_env = "uclibc")] { + mod uclibc; + pub use self::uclibc::*; + } else if #[cfg(any(target_env = "musl", target_env = "ohos"))] { + mod musl; + pub use self::musl::*; + } else if #[cfg(target_env = "gnu")] { + mod gnu; + pub use self::gnu::*; + } +} + +mod arch; +pub use self::arch::*; + +cfg_if! { + if #[cfg(libc_align)] { + #[macro_use] + mod align; + } else { + #[macro_use] + mod no_align; + } +} +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/align.rs b/vendor/libc/src/unix/linux_like/linux/musl/b32/arm/align.rs new file mode 100644 index 0000000..aedbf7a --- /dev/null +++ b/vendor/libc/src/unix/linux_like/linux/musl/b32/arm/align.rs @@ -0,0 +1,7 @@ +s_no_extra_traits! { + #[allow(missing_debug_implementations)] + #[repr(align(8))] + pub struct max_align_t { + priv_: (i64, i64) + } +} 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 new file mode 100644 index 0000000..4ac3e60 --- /dev/null +++ b/vendor/libc/src/unix/linux_like/linux/musl/b32/arm/mod.rs @@ -0,0 +1,854 @@ +pub type c_char = u8; +pub type wchar_t = u32; + +s! { + pub struct stat { + pub st_dev: ::dev_t, + __st_dev_padding: ::c_int, + __st_ino_truncated: ::c_long, + 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, + __st_rdev_padding: ::c_int, + 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, + pub st_ino: ::ino_t, + } + + pub struct stat64 { + pub st_dev: ::dev_t, + __st_dev_padding: ::c_int, + __st_ino_truncated: ::c_long, + 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, + __st_rdev_padding: ::c_int, + 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, + pub st_ino: ::ino_t, + } + + pub struct stack_t { + pub ss_sp: *mut ::c_void, + pub ss_flags: ::c_int, + pub ss_size: ::size_t + } + + 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_int, + __unused1: ::c_long, + __unused2: ::c_long + } + + pub struct shmid_ds { + pub shm_perm: ::ipc_perm, + pub shm_segsz: ::size_t, + pub shm_atime: ::time_t, + __unused1: ::c_int, + pub shm_dtime: ::time_t, + __unused2: ::c_int, + pub shm_ctime: ::time_t, + __unused3: ::c_int, + pub shm_cpid: ::pid_t, + pub shm_lpid: ::pid_t, + pub shm_nattch: ::c_ulong, + __pad1: ::c_ulong, + __pad2: ::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 statfs { + 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 siginfo_t { + pub si_signo: ::c_int, + pub si_errno: ::c_int, + pub si_code: ::c_int, + pub _pad: [::c_int; 29], + _align: [usize; 0], + } + + 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 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; +pub const MINSIGSTKSZ: ::size_t = 2048; + +pub const O_DIRECT: ::c_int = 0x10000; +pub const O_DIRECTORY: ::c_int = 0x4000; +pub const O_NOFOLLOW: ::c_int = 0x8000; +pub const O_ASYNC: ::c_int = 0x2000; +pub const O_LARGEFILE: ::c_int = 0o400000; + +pub const MADV_SOFT_OFFLINE: ::c_int = 101; +pub const MCL_CURRENT: ::c_int = 0x0001; +pub const MCL_FUTURE: ::c_int = 0x0002; +pub const MCL_ONFAULT: ::c_int = 0x0004; +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 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 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_SYNC: ::c_int = 0x080000; + +pub const SOCK_STREAM: ::c_int = 1; +pub const SOCK_DGRAM: ::c_int = 2; + +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 EDEADLOCK: ::c_int = EDEADLK; +pub const EMULTIHOP: ::c_int = 72; +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 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 ERFKILL: ::c_int = 132; +pub const EHWPOISON: ::c_int = 133; + +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 EXTPROC: ::tcflag_t = 0x00010000; + +pub const MAP_HUGETLB: ::c_int = 0x040000; + +pub const F_GETLK: ::c_int = 12; +pub const F_GETOWN: ::c_int = 9; +pub const F_SETLK: ::c_int = 13; +pub const F_SETLKW: ::c_int = 14; +pub const F_SETOWN: ::c_int = 8; + +pub const VEOF: usize = 4; +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 POLLWRNORM: ::c_short = 0x100; +pub const POLLWRBAND: ::c_short = 0x200; + +// Syscall table +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_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_mknod: ::c_long = 14; +pub const SYS_chmod: ::c_long = 15; +pub const SYS_lchown: ::c_long = 16; +pub const SYS_lseek: ::c_long = 19; +pub const SYS_getpid: ::c_long = 20; +pub const SYS_mount: ::c_long = 21; +pub const SYS_setuid: ::c_long = 23; +pub const SYS_getuid: ::c_long = 24; +pub const SYS_ptrace: ::c_long = 26; +pub const SYS_pause: ::c_long = 29; +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_setgid: ::c_long = 46; +pub const SYS_getgid: ::c_long = 47; +pub const SYS_geteuid: ::c_long = 49; +pub const SYS_getegid: ::c_long = 50; +pub const SYS_acct: ::c_long = 51; +pub const SYS_umount2: ::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_setreuid: ::c_long = 70; +pub const SYS_setregid: ::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_getrusage: ::c_long = 77; +pub const SYS_gettimeofday: ::c_long = 78; +pub const SYS_settimeofday: ::c_long = 79; +pub const SYS_getgroups: ::c_long = 80; +pub const SYS_setgroups: ::c_long = 81; +pub const SYS_symlink: ::c_long = 83; +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_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_fchown: ::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_syslog: ::c_long = 103; +pub const SYS_setitimer: ::c_long = 104; +pub const SYS_getitimer: ::c_long = 105; +pub const SYS_stat: ::c_long = 106; +pub const SYS_lstat: ::c_long = 107; +pub const SYS_fstat: ::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_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_uname: ::c_long = 122; +pub const SYS_adjtimex: ::c_long = 124; +pub const SYS_mprotect: ::c_long = 125; +pub const SYS_sigprocmask: ::c_long = 126; +pub const SYS_init_module: ::c_long = 128; +pub const SYS_delete_module: ::c_long = 129; +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_setfsuid: ::c_long = 138; +pub const SYS_setfsgid: ::c_long = 139; +pub const SYS__llseek: ::c_long = 140; +pub const SYS_getdents: ::c_long = 141; +pub const SYS__newselect: ::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: ::c_long = 161; +pub const SYS_nanosleep: ::c_long = 162; +pub const SYS_mremap: ::c_long = 163; +pub const SYS_setresuid: ::c_long = 164; +pub const SYS_getresuid: ::c_long = 165; +pub const SYS_poll: ::c_long = 168; +pub const SYS_nfsservctl: ::c_long = 169; +pub const SYS_setresgid: ::c_long = 170; +pub const SYS_getresgid: ::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: ::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_chown: ::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_vfork: ::c_long = 190; +pub const SYS_ugetrlimit: ::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_lchown32: ::c_long = 198; +pub const SYS_getuid32: ::c_long = 199; +pub const SYS_getgid32: ::c_long = 200; +pub const SYS_geteuid32: ::c_long = 201; +pub const SYS_getegid32: ::c_long = 202; +pub const SYS_setreuid32: ::c_long = 203; +pub const SYS_setregid32: ::c_long = 204; +pub const SYS_getgroups32: ::c_long = 205; +pub const SYS_setgroups32: ::c_long = 206; +pub const SYS_fchown32: ::c_long = 207; +pub const SYS_setresuid32: ::c_long = 208; +pub const SYS_getresuid32: ::c_long = 209; +pub const SYS_setresgid32: ::c_long = 210; +pub const SYS_getresgid32: ::c_long = 211; +pub const SYS_chown32: ::c_long = 212; +pub const SYS_setuid32: ::c_long = 213; +pub const SYS_setgid32: ::c_long = 214; +pub const SYS_setfsuid32: ::c_long = 215; +pub const SYS_setfsgid32: ::c_long = 216; +pub const SYS_getdents64: ::c_long = 217; +pub const SYS_pivot_root: ::c_long = 218; +pub const SYS_mincore: ::c_long = 219; +pub const SYS_madvise: ::c_long = 220; +pub const SYS_fcntl64: ::c_long = 221; +pub const SYS_gettid: ::c_long = 224; +pub const SYS_readahead: ::c_long = 225; +pub const SYS_setxattr: ::c_long = 226; +pub const SYS_lsetxattr: ::c_long = 227; +pub const SYS_fsetxattr: ::c_long = 228; +pub const SYS_getxattr: ::c_long = 229; +pub const SYS_lgetxattr: ::c_long = 230; +pub const SYS_fgetxattr: ::c_long = 231; +pub const SYS_listxattr: ::c_long = 232; +pub const SYS_llistxattr: ::c_long = 233; +pub const SYS_flistxattr: ::c_long = 234; +pub const SYS_removexattr: ::c_long = 235; +pub const SYS_lremovexattr: ::c_long = 236; +pub const SYS_fremovexattr: ::c_long = 237; +pub const SYS_tkill: ::c_long = 238; +pub const SYS_sendfile64: ::c_long = 239; +pub const SYS_futex: ::c_long = 240; +pub const SYS_sched_setaffinity: ::c_long = 241; +pub const SYS_sched_getaffinity: ::c_long = 242; +pub const SYS_io_setup: ::c_long = 243; +pub const SYS_io_destroy: ::c_long = 244; +pub const SYS_io_getevents: ::c_long = 245; +pub const SYS_io_submit: ::c_long = 246; +pub const SYS_io_cancel: ::c_long = 247; +pub const SYS_exit_group: ::c_long = 248; +pub const SYS_lookup_dcookie: ::c_long = 249; +pub const SYS_epoll_create: ::c_long = 250; +pub const SYS_epoll_ctl: ::c_long = 251; +pub const SYS_epoll_wait: ::c_long = 252; +pub const SYS_remap_file_pages: ::c_long = 253; +pub const SYS_set_tid_address: ::c_long = 256; +pub const SYS_timer_create: ::c_long = 257; +pub const SYS_timer_settime: ::c_long = 258; +pub const SYS_timer_gettime: ::c_long = 259; +pub const SYS_timer_getoverrun: ::c_long = 260; +pub const SYS_timer_delete: ::c_long = 261; +pub const SYS_clock_settime: ::c_long = 262; +pub const SYS_clock_gettime: ::c_long = 263; +pub const SYS_clock_getres: ::c_long = 264; +pub const SYS_clock_nanosleep: ::c_long = 265; +pub const SYS_statfs64: ::c_long = 266; +pub const SYS_fstatfs64: ::c_long = 267; +pub const SYS_tgkill: ::c_long = 268; +pub const SYS_utimes: ::c_long = 269; +pub const SYS_pciconfig_iobase: ::c_long = 271; +pub const SYS_pciconfig_read: ::c_long = 272; +pub const SYS_pciconfig_write: ::c_long = 273; +pub const SYS_mq_open: ::c_long = 274; +pub const SYS_mq_unlink: ::c_long = 275; +pub const SYS_mq_timedsend: ::c_long = 276; +pub const SYS_mq_timedreceive: ::c_long = 277; +pub const SYS_mq_notify: ::c_long = 278; +pub const SYS_mq_getsetattr: ::c_long = 279; +pub const SYS_waitid: ::c_long = 280; +pub const SYS_socket: ::c_long = 281; +pub const SYS_bind: ::c_long = 282; +pub const SYS_connect: ::c_long = 283; +pub const SYS_listen: ::c_long = 284; +pub const SYS_accept: ::c_long = 285; +pub const SYS_getsockname: ::c_long = 286; +pub const SYS_getpeername: ::c_long = 287; +pub const SYS_socketpair: ::c_long = 288; +pub const SYS_send: ::c_long = 289; +pub const SYS_sendto: ::c_long = 290; +pub const SYS_recv: ::c_long = 291; +pub const SYS_recvfrom: ::c_long = 292; +pub const SYS_shutdown: ::c_long = 293; +pub const SYS_setsockopt: ::c_long = 294; +pub const SYS_getsockopt: ::c_long = 295; +pub const SYS_sendmsg: ::c_long = 296; +pub const SYS_recvmsg: ::c_long = 297; +pub const SYS_semop: ::c_long = 298; +pub const SYS_semget: ::c_long = 299; +pub const SYS_semctl: ::c_long = 300; +pub const SYS_msgsnd: ::c_long = 301; +pub const SYS_msgrcv: ::c_long = 302; +pub const SYS_msgget: ::c_long = 303; +pub const SYS_msgctl: ::c_long = 304; +pub const SYS_shmat: ::c_long = 305; +pub const SYS_shmdt: ::c_long = 306; +pub const SYS_shmget: ::c_long = 307; +pub const SYS_shmctl: ::c_long = 308; +pub const SYS_add_key: ::c_long = 309; +pub const SYS_request_key: ::c_long = 310; +pub const SYS_keyctl: ::c_long = 311; +pub const SYS_semtimedop: ::c_long = 312; +pub const SYS_vserver: ::c_long = 313; +pub const SYS_ioprio_set: ::c_long = 314; +pub const SYS_ioprio_get: ::c_long = 315; +pub const SYS_inotify_init: ::c_long = 316; +pub const SYS_inotify_add_watch: ::c_long = 317; +pub const SYS_inotify_rm_watch: ::c_long = 318; +pub const SYS_mbind: ::c_long = 319; +pub const SYS_get_mempolicy: ::c_long = 320; +pub const SYS_set_mempolicy: ::c_long = 321; +pub const SYS_openat: ::c_long = 322; +pub const SYS_mkdirat: ::c_long = 323; +pub const SYS_mknodat: ::c_long = 324; +pub const SYS_fchownat: ::c_long = 325; +pub const SYS_futimesat: ::c_long = 326; +pub const SYS_fstatat64: ::c_long = 327; +pub const SYS_unlinkat: ::c_long = 328; +pub const SYS_renameat: ::c_long = 329; +pub const SYS_linkat: ::c_long = 330; +pub const SYS_symlinkat: ::c_long = 331; +pub const SYS_readlinkat: ::c_long = 332; +pub const SYS_fchmodat: ::c_long = 333; +pub const SYS_faccessat: ::c_long = 334; +pub const SYS_pselect6: ::c_long = 335; +pub const SYS_ppoll: ::c_long = 336; +pub const SYS_unshare: ::c_long = 337; +pub const SYS_set_robust_list: ::c_long = 338; +pub const SYS_get_robust_list: ::c_long = 339; +pub const SYS_splice: ::c_long = 340; +pub const SYS_tee: ::c_long = 342; +pub const SYS_vmsplice: ::c_long = 343; +pub const SYS_move_pages: ::c_long = 344; +pub const SYS_getcpu: ::c_long = 345; +pub const SYS_epoll_pwait: ::c_long = 346; +pub const SYS_kexec_load: ::c_long = 347; +pub const SYS_utimensat: ::c_long = 348; +pub const SYS_signalfd: ::c_long = 349; +pub const SYS_timerfd_create: ::c_long = 350; +pub const SYS_eventfd: ::c_long = 351; +pub const SYS_fallocate: ::c_long = 352; +pub const SYS_timerfd_settime: ::c_long = 353; +pub const SYS_timerfd_gettime: ::c_long = 354; +pub const SYS_signalfd4: ::c_long = 355; +pub const SYS_eventfd2: ::c_long = 356; +pub const SYS_epoll_create1: ::c_long = 357; +pub const SYS_dup3: ::c_long = 358; +pub const SYS_pipe2: ::c_long = 359; +pub const SYS_inotify_init1: ::c_long = 360; +pub const SYS_preadv: ::c_long = 361; +pub const SYS_pwritev: ::c_long = 362; +pub const SYS_rt_tgsigqueueinfo: ::c_long = 363; +pub const SYS_perf_event_open: ::c_long = 364; +pub const SYS_recvmmsg: ::c_long = 365; +pub const SYS_accept4: ::c_long = 366; +pub const SYS_fanotify_init: ::c_long = 367; +pub const SYS_fanotify_mark: ::c_long = 368; +pub const SYS_prlimit64: ::c_long = 369; +pub const SYS_name_to_handle_at: ::c_long = 370; +pub const SYS_open_by_handle_at: ::c_long = 371; +pub const SYS_clock_adjtime: ::c_long = 372; +pub const SYS_syncfs: ::c_long = 373; +pub const SYS_sendmmsg: ::c_long = 374; +pub const SYS_setns: ::c_long = 375; +pub const SYS_process_vm_readv: ::c_long = 376; +pub const SYS_process_vm_writev: ::c_long = 377; +pub const SYS_kcmp: ::c_long = 378; +pub const SYS_finit_module: ::c_long = 379; +pub const SYS_sched_setattr: ::c_long = 380; +pub const SYS_sched_getattr: ::c_long = 381; +pub const SYS_renameat2: ::c_long = 382; +pub const SYS_seccomp: ::c_long = 383; +pub const SYS_getrandom: ::c_long = 384; +pub const SYS_memfd_create: ::c_long = 385; +pub const SYS_bpf: ::c_long = 386; +pub const SYS_execveat: ::c_long = 387; +pub const SYS_userfaultfd: ::c_long = 388; +pub const SYS_membarrier: ::c_long = 389; +pub const SYS_mlock2: ::c_long = 390; +pub const SYS_copy_file_range: ::c_long = 391; +pub const SYS_preadv2: ::c_long = 392; +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; +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; +pub const SYS_mseal: ::c_long = 462; + +extern "C" { + pub fn getrandom(buf: *mut ::c_void, buflen: ::size_t, flags: ::c_uint) -> ::ssize_t; +} + +cfg_if! { + if #[cfg(libc_align)] { + mod align; + pub use self::align::*; + } +} 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 new file mode 100644 index 0000000..089c06f --- /dev/null +++ b/vendor/libc/src/unix/linux_like/linux/musl/b32/hexagon.rs @@ -0,0 +1,667 @@ +pub type c_char = u8; +pub type wchar_t = u32; +pub type stat64 = ::stat; + +s! { + + pub struct stat { + pub st_dev: ::dev_t, + pub st_ino: ::c_ulonglong, + pub st_mode: ::c_uint, + pub st_nlink: ::c_uint, + pub st_uid: ::c_uint, + pub st_gid: ::c_uint, + pub st_rdev: ::c_ulonglong, + __st_rdev_padding: ::c_ulong, + pub st_size: ::c_longlong, + pub st_blksize: ::blksize_t, + __st_blksize_padding: ::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 stack_t { + pub ss_sp: *mut ::c_void, + pub ss_flags: ::c_int, + pub ss_size: ::size_t + } + + 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, + } + + pub struct shmid_ds { + pub shm_perm: ::ipc_perm, + pub shm_segsz: ::size_t, + pub shm_atime: ::time_t, + __unused1: ::c_int, + pub shm_dtime: ::time_t, + __unused2: ::c_int, + pub shm_ctime: ::time_t, + __unused3: ::c_int, + pub shm_cpid: ::pid_t, + pub shm_lpid: ::pid_t, + pub shm_nattch: ::c_ulong, + __pad1: ::c_ulong, + __pad2: ::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 statfs { + 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 siginfo_t { + pub si_signo: ::c_int, + pub si_errno: ::c_int, + pub si_code: ::c_int, + pub _pad: [::c_int; 29], + _align: [usize; 0], + } + + 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 const AF_FILE: ::c_int = 1; +pub const AF_KCM: ::c_int = 41; +pub const AF_MAX: ::c_int = 43; +pub const AF_QIPCRTR: ::c_int = 42; +pub const EADDRINUSE: ::c_int = 98; +pub const EADDRNOTAVAIL: ::c_int = 99; +pub const EAFNOSUPPORT: ::c_int = 97; +pub const EALREADY: ::c_int = 114; +pub const EBADE: ::c_int = 52; +pub const EBADMSG: ::c_int = 74; +pub const EBADR: ::c_int = 53; +pub const EBADRQC: ::c_int = 56; +pub const EBADSLT: ::c_int = 57; +pub const ECANCELED: ::c_int = 125; +pub const ECHRNG: ::c_int = 44; +pub const ECONNABORTED: ::c_int = 103; +pub const ECONNREFUSED: ::c_int = 111; +pub const ECONNRESET: ::c_int = 104; +pub const EDEADLK: ::c_int = 35; +pub const EDEADLOCK: ::c_int = 35; +pub const EDESTADDRREQ: ::c_int = 89; +pub const EDQUOT: ::c_int = 122; +pub const EHOSTDOWN: ::c_int = 112; +pub const EHOSTUNREACH: ::c_int = 113; +pub const EHWPOISON: ::c_int = 133; +pub const EIDRM: ::c_int = 43; +pub const EILSEQ: ::c_int = 84; +pub const EINPROGRESS: ::c_int = 115; +pub const EISCONN: ::c_int = 106; +pub const EISNAM: ::c_int = 120; +pub const EKEYEXPIRED: ::c_int = 127; +pub const EKEYREJECTED: ::c_int = 129; +pub const EKEYREVOKED: ::c_int = 128; +pub const EL2HLT: ::c_int = 51; +pub const EL2NSYNC: ::c_int = 45; +pub const EL3HLT: ::c_int = 46; +pub const EL3RST: ::c_int = 47; +pub const ELIBACC: ::c_int = 79; +pub const ELIBBAD: ::c_int = 80; +pub const ELIBEXEC: ::c_int = 83; +pub const ELIBMAX: ::c_int = 82; +pub const ELIBSCN: ::c_int = 81; +pub const ELNRNG: ::c_int = 48; +pub const ELOOP: ::c_int = 40; +pub const EMEDIUMTYPE: ::c_int = 124; +pub const EMSGSIZE: ::c_int = 90; +pub const EMULTIHOP: ::c_int = 72; +pub const ENAMETOOLONG: ::c_int = 36; +pub const ENAVAIL: ::c_int = 119; +pub const ENETDOWN: ::c_int = 100; +pub const ENETRESET: ::c_int = 102; +pub const ENETUNREACH: ::c_int = 101; +pub const ENOANO: ::c_int = 55; +pub const ENOBUFS: ::c_int = 105; +pub const ENOCSI: ::c_int = 50; +pub const ENOKEY: ::c_int = 126; +pub const ENOLCK: ::c_int = 37; +pub const ENOMEDIUM: ::c_int = 123; +pub const ENOMSG: ::c_int = 42; +pub const ENOPROTOOPT: ::c_int = 92; +pub const ENOSYS: ::c_int = 38; +pub const ENOTCONN: ::c_int = 107; +pub const ENOTEMPTY: ::c_int = 39; +pub const ENOTNAM: ::c_int = 118; +pub const ENOTRECOVERABLE: ::c_int = 131; +pub const ENOTSOCK: ::c_int = 88; +pub const ENOTSUP: ::c_int = 95; +pub const ENOTUNIQ: ::c_int = 76; +pub const EOPNOTSUPP: ::c_int = 95; +pub const EOVERFLOW: ::c_int = 75; +pub const EOWNERDEAD: ::c_int = 130; +pub const EPFNOSUPPORT: ::c_int = 96; +pub const EREMCHG: ::c_int = 78; +pub const ERESTART: ::c_int = 85; +pub const ERFKILL: ::c_int = 132; +pub const ESHUTDOWN: ::c_int = 108; +pub const ESOCKTNOSUPPORT: ::c_int = 94; +pub const ESTALE: ::c_int = 116; +pub const ESTRPIPE: ::c_int = 86; +pub const ETOOMANYREFS: ::c_int = 109; +pub const ETIMEDOUT: ::c_int = 110; +pub const EUCLEAN: ::c_int = 117; +pub const EUNATCH: ::c_int = 49; +pub const EUSERS: ::c_int = 87; +pub const EXFULL: ::c_int = 54; +pub const EXTPROC: ::c_int = 65536; +pub const F_EXLCK: ::c_int = 4; +pub const F_GETLK: ::c_int = 12; +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 F_LINUX_SPECIFIC_BASE: ::c_int = 1024; +pub const FLUSHO: ::c_int = 4096; +pub const F_OWNER_PGRP: ::c_int = 2; +pub const F_OWNER_PID: ::c_int = 1; +pub const F_OWNER_TID: ::c_int = 0; +pub const F_SETLK: ::c_int = 13; +pub const F_SETLKW: ::c_int = 14; +pub const F_SETOWN: ::c_int = 8; +pub const F_SETOWN_EX: ::c_int = 15; +pub const F_SETSIG: ::c_int = 10; +pub const F_SHLCK: ::c_int = 8; +pub const IEXTEN: ::c_int = 32768; +pub const MAP_ANON: ::c_int = 32; +pub const MAP_DENYWRITE: ::c_int = 2048; +pub const MAP_EXECUTABLE: ::c_int = 4096; +pub const MAP_GROWSDOWN: ::c_int = 256; +pub const MAP_HUGETLB: ::c_int = 262144; +pub const MAP_LOCKED: ::c_int = 8192; +pub const MAP_NONBLOCK: ::c_int = 65536; +pub const MAP_NORESERVE: ::c_int = 16384; +pub const MAP_POPULATE: ::c_int = 32768; +pub const MAP_STACK: ::c_int = 131072; +pub const MAP_UNINITIALIZED: ::c_int = 0; +pub const O_APPEND: ::c_int = 1024; +pub const O_ASYNC: ::c_int = 8192; +pub const O_CREAT: ::c_int = 64; +pub const O_DIRECT: ::c_int = 16384; +pub const O_DIRECTORY: ::c_int = 65536; +pub const O_DSYNC: ::c_int = 4096; +pub const O_EXCL: ::c_int = 128; +pub const O_LARGEFILE: ::c_int = 32768; +pub const O_NOCTTY: ::c_int = 256; +pub const O_NOFOLLOW: ::c_int = 131072; +pub const O_NONBLOCK: ::c_int = 2048; +pub const O_SYNC: ::c_int = 1052672; +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 SA_ONSTACK: ::c_int = 0x08000000; +pub const SA_SIGINFO: ::c_int = 0x00000004; +pub const SA_NOCLDWAIT: ::c_int = 0x00000002; +pub const SIGBUS: ::c_int = 7; +pub const SIGCHLD: ::c_int = 17; +pub const SIGCONT: ::c_int = 18; +pub const SIGIO: ::c_int = 29; +pub const SIGPOLL: ::c_int = 29; +pub const SIGPROF: ::c_int = 27; +pub const SIGPWR: ::c_int = 30; +pub const SIGSTKFLT: ::c_int = 16; +pub const SIGSTKSZ: ::size_t = 8192; +pub const MINSIGSTKSZ: ::size_t = 2048; +pub const SIGSTOP: ::c_int = 19; +pub const SIGSYS: ::c_int = 31; +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 SIGUSR1: ::c_int = 10; +pub const SIGUSR2: ::c_int = 12; +pub const SIGVTALRM: ::c_int = 26; +pub const SIGWINCH: ::c_int = 28; +pub const SIGXCPU: ::c_int = 24; +pub const SIGXFSZ: ::c_int = 25; +pub const SIG_SETMASK: ::c_int = 2; // FIXME check these +pub const SIG_BLOCK: ::c_int = 0x000000; +pub const SIG_UNBLOCK: ::c_int = 0x01; +pub const SOCK_DGRAM: ::c_int = 2; +pub const SOCK_STREAM: ::c_int = 1; +pub const SOL_CAIF: ::c_int = 278; +pub const SOL_IUCV: ::c_int = 277; +pub const SOL_KCM: ::c_int = 281; +pub const SOL_NFC: ::c_int = 280; +pub const SOL_PNPIPE: ::c_int = 275; +pub const SOL_PPPOL2TP: ::c_int = 273; +pub const SOL_RDS: ::c_int = 276; +pub const SOL_RXRPC: ::c_int = 272; + +pub const SYS3264_fadvise64: ::c_int = 223; +pub const SYS3264_fcntl: ::c_int = 25; +pub const SYS3264_fstatat: ::c_int = 79; +pub const SYS3264_fstat: ::c_int = 80; +pub const SYS3264_fstatfs: ::c_int = 44; +pub const SYS3264_ftruncate: ::c_int = 46; +pub const SYS3264_lseek: ::c_int = 62; +pub const SYS3264_lstat: ::c_int = 1039; +pub const SYS3264_mmap: ::c_int = 222; +pub const SYS3264_sendfile: ::c_int = 71; +pub const SYS3264_stat: ::c_int = 1038; +pub const SYS3264_statfs: ::c_int = 43; +pub const SYS3264_truncate: ::c_int = 45; +pub const SYS_accept4: ::c_int = 242; +pub const SYS_accept: ::c_int = 202; +pub const SYS_access: ::c_int = 1033; +pub const SYS_acct: ::c_int = 89; +pub const SYS_add_key: ::c_int = 217; +pub const SYS_adjtimex: ::c_int = 171; +pub const SYS_alarm: ::c_int = 1059; +pub const SYS_arch_specific_syscall: ::c_int = 244; +pub const SYS_bdflush: ::c_int = 1075; +pub const SYS_bind: ::c_int = 200; +pub const SYS_bpf: ::c_int = 280; +pub const SYS_brk: ::c_int = 214; +pub const SYS_capget: ::c_int = 90; +pub const SYS_capset: ::c_int = 91; +pub const SYS_chdir: ::c_int = 49; +pub const SYS_chmod: ::c_int = 1028; +pub const SYS_chown: ::c_int = 1029; +pub const SYS_chroot: ::c_int = 51; +pub const SYS_clock_adjtime: ::c_int = 266; +pub const SYS_clock_getres: ::c_int = 114; +pub const SYS_clock_gettime: ::c_int = 113; +pub const SYS_clock_nanosleep: ::c_int = 115; +pub const SYS_clock_settime: ::c_int = 112; +pub const SYS_clone: ::c_int = 220; +pub const SYS_close: ::c_int = 57; +pub const SYS_connect: ::c_int = 203; +pub const SYS_copy_file_range: ::c_int = -1; // FIXME +pub const SYS_creat: ::c_int = 1064; +pub const SYS_delete_module: ::c_int = 106; +pub const SYS_dup2: ::c_int = 1041; +pub const SYS_dup3: ::c_int = 24; +pub const SYS_dup: ::c_int = 23; +pub const SYS_epoll_create1: ::c_int = 20; +pub const SYS_epoll_create: ::c_int = 1042; +pub const SYS_epoll_ctl: ::c_int = 21; +pub const SYS_epoll_pwait: ::c_int = 22; +pub const SYS_epoll_wait: ::c_int = 1069; +pub const SYS_eventfd2: ::c_int = 19; +pub const SYS_eventfd: ::c_int = 1044; +pub const SYS_execveat: ::c_int = 281; +pub const SYS_execve: ::c_int = 221; +pub const SYS_exit: ::c_int = 93; +pub const SYS_exit_group: ::c_int = 94; +pub const SYS_faccessat: ::c_int = 48; +pub const SYS_fadvise64_64: ::c_int = 223; +pub const SYS_fallocate: ::c_int = 47; +pub const SYS_fanotify_init: ::c_int = 262; +pub const SYS_fanotify_mark: ::c_int = 263; +pub const SYS_fchdir: ::c_int = 50; +pub const SYS_fchmodat: ::c_int = 53; +pub const SYS_fchmod: ::c_int = 52; +pub const SYS_fchownat: ::c_int = 54; +pub const SYS_fchown: ::c_int = 55; +pub const SYS_fcntl64: ::c_int = 25; +pub const SYS_fcntl: ::c_int = 25; +pub const SYS_fdatasync: ::c_int = 83; +pub const SYS_fgetxattr: ::c_int = 10; +pub const SYS_finit_module: ::c_int = 273; +pub const SYS_flistxattr: ::c_int = 13; +pub const SYS_flock: ::c_int = 32; +pub const SYS_fork: ::c_int = 1079; +pub const SYS_fremovexattr: ::c_int = 16; +pub const SYS_fsetxattr: ::c_int = 7; +pub const SYS_fstat64: ::c_int = 80; +pub const SYS_fstatat64: ::c_int = 79; +pub const SYS_fstatfs64: ::c_int = 44; +pub const SYS_fstatfs: ::c_int = 44; +pub const SYS_fsync: ::c_int = 82; +pub const SYS_ftruncate64: ::c_int = 46; +pub const SYS_ftruncate: ::c_int = 46; +pub const SYS_futex: ::c_int = 98; +pub const SYS_futimesat: ::c_int = 1066; +pub const SYS_getcpu: ::c_int = 168; +pub const SYS_getcwd: ::c_int = 17; +pub const SYS_getdents64: ::c_int = 61; +pub const SYS_getdents: ::c_int = 1065; +pub const SYS_getegid: ::c_int = 177; +pub const SYS_geteuid: ::c_int = 175; +pub const SYS_getgid: ::c_int = 176; +pub const SYS_getgroups: ::c_int = 158; +pub const SYS_getitimer: ::c_int = 102; +pub const SYS_get_mempolicy: ::c_int = 236; +pub const SYS_getpeername: ::c_int = 205; +pub const SYS_getpgid: ::c_int = 155; +pub const SYS_getpgrp: ::c_int = 1060; +pub const SYS_getpid: ::c_int = 172; +pub const SYS_getppid: ::c_int = 173; +pub const SYS_getpriority: ::c_int = 141; +pub const SYS_getrandom: ::c_int = 278; +pub const SYS_getresgid: ::c_int = 150; +pub const SYS_getresuid: ::c_int = 148; +pub const SYS_getrlimit: ::c_int = 163; +pub const SYS_get_robust_list: ::c_int = 100; +pub const SYS_getrusage: ::c_int = 165; +pub const SYS_getsid: ::c_int = 156; +pub const SYS_getsockname: ::c_int = 204; +pub const SYS_getsockopt: ::c_int = 209; +pub const SYS_gettid: ::c_int = 178; +pub const SYS_gettimeofday: ::c_int = 169; +pub const SYS_getuid: ::c_int = 174; +pub const SYS_getxattr: ::c_int = 8; +pub const SYS_init_module: ::c_int = 105; +pub const SYS_inotify_add_watch: ::c_int = 27; +pub const SYS_inotify_init1: ::c_int = 26; +pub const SYS_inotify_init: ::c_int = 1043; +pub const SYS_inotify_rm_watch: ::c_int = 28; +pub const SYS_io_cancel: ::c_int = 3; +pub const SYS_ioctl: ::c_int = 29; +pub const SYS_io_destroy: ::c_int = 1; +pub const SYS_io_getevents: ::c_int = 4; +pub const SYS_ioprio_get: ::c_int = 31; +pub const SYS_ioprio_set: ::c_int = 30; +pub const SYS_io_setup: ::c_int = 0; +pub const SYS_io_submit: ::c_int = 2; +pub const SYS_kcmp: ::c_int = 272; +pub const SYS_kexec_load: ::c_int = 104; +pub const SYS_keyctl: ::c_int = 219; +pub const SYS_kill: ::c_int = 129; +pub const SYS_lchown: ::c_int = 1032; +pub const SYS_lgetxattr: ::c_int = 9; +pub const SYS_linkat: ::c_int = 37; +pub const SYS_link: ::c_int = 1025; +pub const SYS_listen: ::c_int = 201; +pub const SYS_listxattr: ::c_int = 11; +pub const SYS_llistxattr: ::c_int = 12; +pub const SYS__llseek: ::c_int = 62; +pub const SYS_lookup_dcookie: ::c_int = 18; +pub const SYS_lremovexattr: ::c_int = 15; +pub const SYS_lseek: ::c_int = 62; +pub const SYS_lsetxattr: ::c_int = 6; +pub const SYS_lstat64: ::c_int = 1039; +pub const SYS_lstat: ::c_int = 1039; +pub const SYS_madvise: ::c_int = 233; +pub const SYS_mbind: ::c_int = 235; +pub const SYS_memfd_create: ::c_int = 279; +pub const SYS_migrate_pages: ::c_int = 238; +pub const SYS_mincore: ::c_int = 232; +pub const SYS_mkdirat: ::c_int = 34; +pub const SYS_mkdir: ::c_int = 1030; +pub const SYS_mknodat: ::c_int = 33; +pub const SYS_mknod: ::c_int = 1027; +pub const SYS_mlockall: ::c_int = 230; +pub const SYS_mlock: ::c_int = 228; +pub const SYS_mmap2: ::c_int = 222; +pub const SYS_mount: ::c_int = 40; +pub const SYS_move_pages: ::c_int = 239; +pub const SYS_mprotect: ::c_int = 226; +pub const SYS_mq_getsetattr: ::c_int = 185; +pub const SYS_mq_notify: ::c_int = 184; +pub const SYS_mq_open: ::c_int = 180; +pub const SYS_mq_timedreceive: ::c_int = 183; +pub const SYS_mq_timedsend: ::c_int = 182; +pub const SYS_mq_unlink: ::c_int = 181; +pub const SYS_mremap: ::c_int = 216; +pub const SYS_msgctl: ::c_int = 187; +pub const SYS_msgget: ::c_int = 186; +pub const SYS_msgrcv: ::c_int = 188; +pub const SYS_msgsnd: ::c_int = 189; +pub const SYS_msync: ::c_int = 227; +pub const SYS_munlockall: ::c_int = 231; +pub const SYS_munlock: ::c_int = 229; +pub const SYS_munmap: ::c_int = 215; +pub const SYS_name_to_handle_at: ::c_int = 264; +pub const SYS_nanosleep: ::c_int = 101; +pub const SYS_newfstatat: ::c_int = 79; +pub const SYS_nfsservctl: ::c_int = 42; +pub const SYS_oldwait4: ::c_int = 1072; +pub const SYS_openat: ::c_int = 56; +pub const SYS_open_by_handle_at: ::c_int = 265; +pub const SYS_open: ::c_int = 1024; +pub const SYS_pause: ::c_int = 1061; +pub const SYS_perf_event_open: ::c_int = 241; +pub const SYS_personality: ::c_int = 92; +pub const SYS_pipe2: ::c_int = 59; +pub const SYS_pipe: ::c_int = 1040; +pub const SYS_pivot_root: ::c_int = 41; +pub const SYS_poll: ::c_int = 1068; +pub const SYS_ppoll: ::c_int = 73; +pub const SYS_prctl: ::c_int = 167; +pub const SYS_pread64: ::c_int = 67; +pub const SYS_preadv: ::c_int = 69; +pub const SYS_prlimit64: ::c_int = 261; +pub const SYS_process_vm_readv: ::c_int = 270; +pub const SYS_process_vm_writev: ::c_int = 271; +pub const SYS_pselect6: ::c_int = 72; +pub const SYS_ptrace: ::c_int = 117; +pub const SYS_pwrite64: ::c_int = 68; +pub const SYS_pwritev: ::c_int = 70; +pub const SYS_quotactl: ::c_int = 60; +pub const SYS_readahead: ::c_int = 213; +pub const SYS_read: ::c_int = 63; +pub const SYS_readlinkat: ::c_int = 78; +pub const SYS_readlink: ::c_int = 1035; +pub const SYS_readv: ::c_int = 65; +pub const SYS_reboot: ::c_int = 142; +pub const SYS_recv: ::c_int = 1073; +pub const SYS_recvfrom: ::c_int = 207; +pub const SYS_recvmmsg: ::c_int = 243; +pub const SYS_recvmsg: ::c_int = 212; +pub const SYS_remap_file_pages: ::c_int = 234; +pub const SYS_removexattr: ::c_int = 14; +pub const SYS_renameat2: ::c_int = 276; +pub const SYS_renameat: ::c_int = 38; +pub const SYS_rename: ::c_int = 1034; +pub const SYS_request_key: ::c_int = 218; +pub const SYS_restart_syscall: ::c_int = 128; +pub const SYS_rmdir: ::c_int = 1031; +pub const SYS_rt_sigaction: ::c_int = 134; +pub const SYS_rt_sigpending: ::c_int = 136; +pub const SYS_rt_sigprocmask: ::c_int = 135; +pub const SYS_rt_sigqueueinfo: ::c_int = 138; +pub const SYS_rt_sigreturn: ::c_int = 139; +pub const SYS_rt_sigsuspend: ::c_int = 133; +pub const SYS_rt_sigtimedwait: ::c_int = 137; +pub const SYS_rt_tgsigqueueinfo: ::c_int = 240; +pub const SYS_sched_getaffinity: ::c_int = 123; +pub const SYS_sched_getattr: ::c_int = 275; +pub const SYS_sched_getparam: ::c_int = 121; +pub const SYS_sched_get_priority_max: ::c_int = 125; +pub const SYS_sched_get_priority_min: ::c_int = 126; +pub const SYS_sched_getscheduler: ::c_int = 120; +pub const SYS_sched_rr_get_interval: ::c_int = 127; +pub const SYS_sched_setaffinity: ::c_int = 122; +pub const SYS_sched_setattr: ::c_int = 274; +pub const SYS_sched_setparam: ::c_int = 118; +pub const SYS_sched_setscheduler: ::c_int = 119; +pub const SYS_sched_yield: ::c_int = 124; +pub const SYS_seccomp: ::c_int = 277; +pub const SYS_select: ::c_int = 1067; +pub const SYS_semctl: ::c_int = 191; +pub const SYS_semget: ::c_int = 190; +pub const SYS_semop: ::c_int = 193; +pub const SYS_semtimedop: ::c_int = 192; +pub const SYS_send: ::c_int = 1074; +pub const SYS_sendfile64: ::c_int = 71; +pub const SYS_sendfile: ::c_int = 71; +pub const SYS_sendmmsg: ::c_int = 269; +pub const SYS_sendmsg: ::c_int = 211; +pub const SYS_sendto: ::c_int = 206; +pub const SYS_setdomainname: ::c_int = 162; +pub const SYS_setfsgid: ::c_int = 152; +pub const SYS_setfsuid: ::c_int = 151; +pub const SYS_setgid: ::c_int = 144; +pub const SYS_setgroups: ::c_int = 159; +pub const SYS_sethostname: ::c_int = 161; +pub const SYS_setitimer: ::c_int = 103; +pub const SYS_set_mempolicy: ::c_int = 237; +pub const SYS_setns: ::c_int = 268; +pub const SYS_setpgid: ::c_int = 154; +pub const SYS_setpriority: ::c_int = 140; +pub const SYS_setregid: ::c_int = 143; +pub const SYS_setresgid: ::c_int = 149; +pub const SYS_setresuid: ::c_int = 147; +pub const SYS_setreuid: ::c_int = 145; +pub const SYS_setrlimit: ::c_int = 164; +pub const SYS_set_robust_list: ::c_int = 99; +pub const SYS_setsid: ::c_int = 157; +pub const SYS_setsockopt: ::c_int = 208; +pub const SYS_set_tid_address: ::c_int = 96; +pub const SYS_settimeofday: ::c_int = 170; +pub const SYS_setuid: ::c_int = 146; +pub const SYS_setxattr: ::c_int = 5; +pub const SYS_shmat: ::c_int = 196; +pub const SYS_shmctl: ::c_int = 195; +pub const SYS_shmdt: ::c_int = 197; +pub const SYS_shmget: ::c_int = 194; +pub const SYS_shutdown: ::c_int = 210; +pub const SYS_sigaltstack: ::c_int = 132; +pub const SYS_signalfd4: ::c_int = 74; +pub const SYS_signalfd: ::c_int = 1045; +pub const SYS_socket: ::c_int = 198; +pub const SYS_socketpair: ::c_int = 199; +pub const SYS_splice: ::c_int = 76; +pub const SYS_stat64: ::c_int = 1038; +pub const SYS_stat: ::c_int = 1038; +pub const SYS_statfs64: ::c_int = 43; +pub const SYS_swapoff: ::c_int = 225; +pub const SYS_swapon: ::c_int = 224; +pub const SYS_symlinkat: ::c_int = 36; +pub const SYS_symlink: ::c_int = 1036; +pub const SYS_sync: ::c_int = 81; +pub const SYS_sync_file_range2: ::c_int = 84; +pub const SYS_sync_file_range: ::c_int = 84; +pub const SYS_syncfs: ::c_int = 267; +pub const SYS_syscalls: ::c_int = 1080; +pub const SYS__sysctl: ::c_int = 1078; +pub const SYS_sysinfo: ::c_int = 179; +pub const SYS_syslog: ::c_int = 116; +pub const SYS_tee: ::c_int = 77; +pub const SYS_tgkill: ::c_int = 131; +pub const SYS_time: ::c_int = 1062; +pub const SYS_timer_create: ::c_int = 107; +pub const SYS_timer_delete: ::c_int = 111; +pub const SYS_timerfd_create: ::c_int = 85; +pub const SYS_timerfd_gettime: ::c_int = 87; +pub const SYS_timerfd_settime: ::c_int = 86; +pub const SYS_timer_getoverrun: ::c_int = 109; +pub const SYS_timer_gettime: ::c_int = 108; +pub const SYS_timer_settime: ::c_int = 110; +pub const SYS_times: ::c_int = 153; +pub const SYS_tkill: ::c_int = 130; +pub const SYS_truncate64: ::c_int = 45; +pub const SYS_truncate: ::c_int = 45; +pub const SYS_umask: ::c_int = 166; +pub const SYS_umount2: ::c_int = 39; +pub const SYS_umount: ::c_int = 1076; +pub const SYS_uname: ::c_int = 160; +pub const SYS_unlinkat: ::c_int = 35; +pub const SYS_unlink: ::c_int = 1026; +pub const SYS_unshare: ::c_int = 97; +pub const SYS_uselib: ::c_int = 1077; +pub const SYS_ustat: ::c_int = 1070; +pub const SYS_utime: ::c_int = 1063; +pub const SYS_utimensat: ::c_int = 88; +pub const SYS_utimes: ::c_int = 1037; +pub const SYS_vfork: ::c_int = 1071; +pub const SYS_vhangup: ::c_int = 58; +pub const SYS_vmsplice: ::c_int = 75; +pub const SYS_wait4: ::c_int = 260; +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 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 TIOCSER_TEMT: ::c_int = 1; +pub const TOSTOP: ::c_int = 256; +pub const VEOF: ::c_int = 4; +pub const VEOL2: ::c_int = 16; +pub const VEOL: ::c_int = 11; +pub const VMIN: ::c_int = 6; diff --git a/vendor/libc/src/unix/linux_like/linux/musl/b32/mips/align.rs b/vendor/libc/src/unix/linux_like/linux/musl/b32/mips/align.rs new file mode 100644 index 0000000..8c228eb --- /dev/null +++ b/vendor/libc/src/unix/linux_like/linux/musl/b32/mips/align.rs @@ -0,0 +1,7 @@ +s_no_extra_traits! { + #[allow(missing_debug_implementations)] + #[repr(align(8))] + pub struct max_align_t { + priv_: [f32; 4] + } +} 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 new file mode 100644 index 0000000..2fb405b --- /dev/null +++ b/vendor/libc/src/unix/linux_like/linux/musl/b32/mips/mod.rs @@ -0,0 +1,788 @@ +pub type c_char = i8; +pub type wchar_t = ::c_int; + +s! { + pub struct stat { + pub st_dev: ::dev_t, + __st_padding1: [::c_long; 2], + 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, + __st_padding2: [::c_long; 2], + pub st_size: ::off_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_blksize: ::blksize_t, + __st_padding3: ::c_long, + pub st_blocks: ::blkcnt_t, + __st_padding4: [::c_long; 14], + } + + pub struct stat64 { + pub st_dev: ::dev_t, + __st_padding1: [::c_long; 2], + 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, + __st_padding2: [::c_long; 2], + pub st_size: ::off_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_blksize: ::blksize_t, + __st_padding3: ::c_long, + pub st_blocks: ::blkcnt64_t, + __st_padding4: [::c_long; 14], + } + + pub struct stack_t { + pub ss_sp: *mut ::c_void, + pub ss_size: ::size_t, + pub ss_flags: ::c_int, + } + + 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_int, + __unused1: ::c_long, + __unused2: ::c_long + } + + 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: ::c_ulong, + __pad1: ::c_ulong, + __pad2: ::c_ulong, + } + + pub struct msqid_ds { + pub msg_perm: ::ipc_perm, + #[cfg(target_endian = "big")] + __unused1: ::c_int, + pub msg_stime: ::time_t, + #[cfg(target_endian = "little")] + __unused1: ::c_int, + #[cfg(target_endian = "big")] + __unused2: ::c_int, + pub msg_rtime: ::time_t, + #[cfg(target_endian = "little")] + __unused2: ::c_int, + #[cfg(target_endian = "big")] + __unused3: ::c_int, + pub msg_ctime: ::time_t, + #[cfg(target_endian = "little")] + __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 statfs { + pub f_type: ::c_ulong, + pub f_bsize: ::c_ulong, + pub f_frsize: ::c_ulong, + pub f_blocks: ::fsblkcnt_t, + pub f_bfree: ::fsblkcnt_t, + pub f_files: ::fsfilcnt_t, + pub f_ffree: ::fsfilcnt_t, + pub f_bavail: ::fsblkcnt_t, + pub f_fsid: ::fsid_t, + pub f_namelen: ::c_ulong, + pub f_flags: ::c_ulong, + pub f_spare: [::c_ulong; 5], + } + + pub struct siginfo_t { + pub si_signo: ::c_int, + pub si_code: ::c_int, + pub si_errno: ::c_int, + pub _pad: [::c_int; 29], + _align: [usize; 0], + } + + pub struct statfs64 { + pub f_type: ::c_ulong, + pub f_bsize: ::c_ulong, + pub f_frsize: ::c_ulong, + pub f_blocks: ::fsblkcnt_t, + pub f_bfree: ::fsblkcnt_t, + pub f_files: ::fsfilcnt_t, + pub f_ffree: ::fsfilcnt_t, + pub f_bavail: ::fsblkcnt_t, + pub f_fsid: ::fsid_t, + pub f_namelen: ::c_ulong, + pub f_flags: ::c_ulong, + pub f_spare: [::c_ulong; 5], + } + + 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, + #[cfg(target_endian = "little")] + pub f_fsid: ::c_ulong, + __f_unused: ::c_int, + #[cfg(target_endian = "big")] + pub f_fsid: ::c_ulong, + pub f_flag: ::c_ulong, + pub f_namemax: ::c_ulong, + __f_spare: [::c_int; 6], + } +} + +pub const SIGSTKSZ: ::size_t = 8192; +pub const MINSIGSTKSZ: ::size_t = 2048; + +pub const O_DIRECT: ::c_int = 0o100000; +pub const O_DIRECTORY: ::c_int = 0o200000; +pub const O_NOFOLLOW: ::c_int = 0o400000; +pub const O_ASYNC: ::c_int = 0o10000; +pub const O_LARGEFILE: ::c_int = 0x2000; + +pub const MCL_CURRENT: ::c_int = 0x0001; +pub const MCL_FUTURE: ::c_int = 0x0002; +pub const MCL_ONFAULT: ::c_int = 0x0004; +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 O_APPEND: ::c_int = 0o010; +pub const O_CREAT: ::c_int = 0o400; +pub const O_EXCL: ::c_int = 0o2000; +pub const O_NOCTTY: ::c_int = 0o4000; +pub const O_NONBLOCK: ::c_int = 0o200; +pub const O_SYNC: ::c_int = 0o40020; +pub const O_RSYNC: ::c_int = 0o40020; +pub const O_DSYNC: ::c_int = 0o020; + +pub const MAP_ANON: ::c_int = 0x800; +pub const MAP_GROWSDOWN: ::c_int = 0x1000; +pub const MAP_DENYWRITE: ::c_int = 0x2000; +pub const MAP_EXECUTABLE: ::c_int = 0x4000; +pub const MAP_LOCKED: ::c_int = 0x8000; +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; +pub const ENOLCK: ::c_int = 46; +pub const ENOSYS: ::c_int = 89; +pub const ENOTEMPTY: ::c_int = 93; +pub const ELOOP: ::c_int = 90; +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 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 EMULTIHOP: ::c_int = 74; +pub const EOVERFLOW: ::c_int = 79; +pub const ENOTUNIQ: ::c_int = 80; +pub const EBADFD: ::c_int = 81; +pub const EBADMSG: ::c_int = 77; +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 ERESTART: ::c_int = 91; +pub const ESTRPIPE: ::c_int = 92; +pub const EUSERS: ::c_int = 94; +pub const ENOTSOCK: ::c_int = 95; +pub const EDESTADDRREQ: ::c_int = 96; +pub const EMSGSIZE: ::c_int = 97; +pub const EPROTOTYPE: ::c_int = 98; +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; +pub const EADDRNOTAVAIL: ::c_int = 126; +pub const ENETDOWN: ::c_int = 127; +pub const ENETUNREACH: ::c_int = 128; +pub const ENETRESET: ::c_int = 129; +pub const ECONNABORTED: ::c_int = 130; +pub const ECONNRESET: ::c_int = 131; +pub const ENOBUFS: ::c_int = 132; +pub const EISCONN: ::c_int = 133; +pub const ENOTCONN: ::c_int = 134; +pub const ESHUTDOWN: ::c_int = 143; +pub const ETOOMANYREFS: ::c_int = 144; +pub const ETIMEDOUT: ::c_int = 145; +pub const ECONNREFUSED: ::c_int = 146; +pub const EHOSTDOWN: ::c_int = 147; +pub const EHOSTUNREACH: ::c_int = 148; +pub const EALREADY: ::c_int = 149; +pub const EINPROGRESS: ::c_int = 150; +pub const ESTALE: ::c_int = 151; +pub const EUCLEAN: ::c_int = 135; +pub const ENOTNAM: ::c_int = 137; +pub const ENAVAIL: ::c_int = 138; +pub const EISNAM: ::c_int = 139; +pub const EREMOTEIO: ::c_int = 140; +pub const EDQUOT: ::c_int = 1133; +pub const ENOMEDIUM: ::c_int = 159; +pub const EMEDIUMTYPE: ::c_int = 160; +pub const ECANCELED: ::c_int = 158; +pub const ENOKEY: ::c_int = 161; +pub const EKEYEXPIRED: ::c_int = 162; +pub const EKEYREVOKED: ::c_int = 163; +pub const EKEYREJECTED: ::c_int = 164; +pub const EOWNERDEAD: ::c_int = 165; +pub const ENOTRECOVERABLE: ::c_int = 166; +pub const EHWPOISON: ::c_int = 168; +pub const ERFKILL: ::c_int = 167; + +pub const SOCK_STREAM: ::c_int = 2; +pub const SOCK_DGRAM: ::c_int = 1; + +pub const SA_ONSTACK: ::c_int = 0x08000000; +pub const SA_SIGINFO: ::c_int = 8; +pub const SA_NOCLDWAIT: ::c_int = 0x10000; + +pub const SIGCHLD: ::c_int = 18; +pub const SIGBUS: ::c_int = 10; +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 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 = 22; +pub const SIGSYS: ::c_int = 12; +pub const SIGSTKFLT: ::c_int = 7; +pub const SIGPOLL: ::c_int = ::SIGIO; +pub const SIGPWR: ::c_int = 19; +pub const SIG_SETMASK: ::c_int = 3; +pub const SIG_BLOCK: ::c_int = 1; +pub const SIG_UNBLOCK: ::c_int = 2; + +pub const EXTPROC: ::tcflag_t = 0o200000; + +pub const F_GETLK: ::c_int = 33; +pub const F_GETOWN: ::c_int = 23; +pub const F_SETLK: ::c_int = 34; +pub const F_SETLKW: ::c_int = 35; +pub const F_SETOWN: ::c_int = 24; + +pub const VEOF: usize = 16; +pub const VEOL: usize = 17; +pub const VEOL2: usize = 6; +pub const VMIN: usize = 4; +pub const IEXTEN: ::tcflag_t = 0o000400; +pub const TOSTOP: ::tcflag_t = 0o100000; +pub const FLUSHO: ::tcflag_t = 0o020000; + +pub const POLLWRNORM: ::c_short = 0x4; +pub const POLLWRBAND: ::c_short = 0x100; + +pub const SYS_syscall: ::c_long = 4000 + 0; +pub const SYS_exit: ::c_long = 4000 + 1; +pub const SYS_fork: ::c_long = 4000 + 2; +pub const SYS_read: ::c_long = 4000 + 3; +pub const SYS_write: ::c_long = 4000 + 4; +pub const SYS_open: ::c_long = 4000 + 5; +pub const SYS_close: ::c_long = 4000 + 6; +pub const SYS_waitpid: ::c_long = 4000 + 7; +pub const SYS_creat: ::c_long = 4000 + 8; +pub const SYS_link: ::c_long = 4000 + 9; +pub const SYS_unlink: ::c_long = 4000 + 10; +pub const SYS_execve: ::c_long = 4000 + 11; +pub const SYS_chdir: ::c_long = 4000 + 12; +pub const SYS_time: ::c_long = 4000 + 13; +pub const SYS_mknod: ::c_long = 4000 + 14; +pub const SYS_chmod: ::c_long = 4000 + 15; +pub const SYS_lchown: ::c_long = 4000 + 16; +pub const SYS_break: ::c_long = 4000 + 17; +pub const SYS_lseek: ::c_long = 4000 + 19; +pub const SYS_getpid: ::c_long = 4000 + 20; +pub const SYS_mount: ::c_long = 4000 + 21; +pub const SYS_umount: ::c_long = 4000 + 22; +pub const SYS_setuid: ::c_long = 4000 + 23; +pub const SYS_getuid: ::c_long = 4000 + 24; +pub const SYS_stime: ::c_long = 4000 + 25; +pub const SYS_ptrace: ::c_long = 4000 + 26; +pub const SYS_alarm: ::c_long = 4000 + 27; +pub const SYS_pause: ::c_long = 4000 + 29; +pub const SYS_utime: ::c_long = 4000 + 30; +pub const SYS_stty: ::c_long = 4000 + 31; +pub const SYS_gtty: ::c_long = 4000 + 32; +pub const SYS_access: ::c_long = 4000 + 33; +pub const SYS_nice: ::c_long = 4000 + 34; +pub const SYS_ftime: ::c_long = 4000 + 35; +pub const SYS_sync: ::c_long = 4000 + 36; +pub const SYS_kill: ::c_long = 4000 + 37; +pub const SYS_rename: ::c_long = 4000 + 38; +pub const SYS_mkdir: ::c_long = 4000 + 39; +pub const SYS_rmdir: ::c_long = 4000 + 40; +pub const SYS_dup: ::c_long = 4000 + 41; +pub const SYS_pipe: ::c_long = 4000 + 42; +pub const SYS_times: ::c_long = 4000 + 43; +pub const SYS_prof: ::c_long = 4000 + 44; +pub const SYS_brk: ::c_long = 4000 + 45; +pub const SYS_setgid: ::c_long = 4000 + 46; +pub const SYS_getgid: ::c_long = 4000 + 47; +pub const SYS_signal: ::c_long = 4000 + 48; +pub const SYS_geteuid: ::c_long = 4000 + 49; +pub const SYS_getegid: ::c_long = 4000 + 50; +pub const SYS_acct: ::c_long = 4000 + 51; +pub const SYS_umount2: ::c_long = 4000 + 52; +pub const SYS_lock: ::c_long = 4000 + 53; +pub const SYS_ioctl: ::c_long = 4000 + 54; +pub const SYS_fcntl: ::c_long = 4000 + 55; +pub const SYS_mpx: ::c_long = 4000 + 56; +pub const SYS_setpgid: ::c_long = 4000 + 57; +pub const SYS_ulimit: ::c_long = 4000 + 58; +pub const SYS_umask: ::c_long = 4000 + 60; +pub const SYS_chroot: ::c_long = 4000 + 61; +pub const SYS_ustat: ::c_long = 4000 + 62; +pub const SYS_dup2: ::c_long = 4000 + 63; +pub const SYS_getppid: ::c_long = 4000 + 64; +pub const SYS_getpgrp: ::c_long = 4000 + 65; +pub const SYS_setsid: ::c_long = 4000 + 66; +pub const SYS_sigaction: ::c_long = 4000 + 67; +pub const SYS_sgetmask: ::c_long = 4000 + 68; +pub const SYS_ssetmask: ::c_long = 4000 + 69; +pub const SYS_setreuid: ::c_long = 4000 + 70; +pub const SYS_setregid: ::c_long = 4000 + 71; +pub const SYS_sigsuspend: ::c_long = 4000 + 72; +pub const SYS_sigpending: ::c_long = 4000 + 73; +pub const SYS_sethostname: ::c_long = 4000 + 74; +pub const SYS_setrlimit: ::c_long = 4000 + 75; +pub const SYS_getrlimit: ::c_long = 4000 + 76; +pub const SYS_getrusage: ::c_long = 4000 + 77; +pub const SYS_gettimeofday: ::c_long = 4000 + 78; +pub const SYS_settimeofday: ::c_long = 4000 + 79; +pub const SYS_getgroups: ::c_long = 4000 + 80; +pub const SYS_setgroups: ::c_long = 4000 + 81; +pub const SYS_symlink: ::c_long = 4000 + 83; +pub const SYS_readlink: ::c_long = 4000 + 85; +pub const SYS_uselib: ::c_long = 4000 + 86; +pub const SYS_swapon: ::c_long = 4000 + 87; +pub const SYS_reboot: ::c_long = 4000 + 88; +pub const SYS_readdir: ::c_long = 4000 + 89; +pub const SYS_mmap: ::c_long = 4000 + 90; +pub const SYS_munmap: ::c_long = 4000 + 91; +pub const SYS_truncate: ::c_long = 4000 + 92; +pub const SYS_ftruncate: ::c_long = 4000 + 93; +pub const SYS_fchmod: ::c_long = 4000 + 94; +pub const SYS_fchown: ::c_long = 4000 + 95; +pub const SYS_getpriority: ::c_long = 4000 + 96; +pub const SYS_setpriority: ::c_long = 4000 + 97; +pub const SYS_profil: ::c_long = 4000 + 98; +pub const SYS_statfs: ::c_long = 4000 + 99; +pub const SYS_fstatfs: ::c_long = 4000 + 100; +pub const SYS_ioperm: ::c_long = 4000 + 101; +pub const SYS_socketcall: ::c_long = 4000 + 102; +pub const SYS_syslog: ::c_long = 4000 + 103; +pub const SYS_setitimer: ::c_long = 4000 + 104; +pub const SYS_getitimer: ::c_long = 4000 + 105; +pub const SYS_stat: ::c_long = 4000 + 106; +pub const SYS_lstat: ::c_long = 4000 + 107; +pub const SYS_fstat: ::c_long = 4000 + 108; +pub const SYS_iopl: ::c_long = 4000 + 110; +pub const SYS_vhangup: ::c_long = 4000 + 111; +pub const SYS_idle: ::c_long = 4000 + 112; +pub const SYS_vm86: ::c_long = 4000 + 113; +pub const SYS_wait4: ::c_long = 4000 + 114; +pub const SYS_swapoff: ::c_long = 4000 + 115; +pub const SYS_sysinfo: ::c_long = 4000 + 116; +pub const SYS_ipc: ::c_long = 4000 + 117; +pub const SYS_fsync: ::c_long = 4000 + 118; +pub const SYS_sigreturn: ::c_long = 4000 + 119; +pub const SYS_clone: ::c_long = 4000 + 120; +pub const SYS_setdomainname: ::c_long = 4000 + 121; +pub const SYS_uname: ::c_long = 4000 + 122; +pub const SYS_modify_ldt: ::c_long = 4000 + 123; +pub const SYS_adjtimex: ::c_long = 4000 + 124; +pub const SYS_mprotect: ::c_long = 4000 + 125; +pub const SYS_sigprocmask: ::c_long = 4000 + 126; +pub const SYS_create_module: ::c_long = 4000 + 127; +pub const SYS_init_module: ::c_long = 4000 + 128; +pub const SYS_delete_module: ::c_long = 4000 + 129; +pub const SYS_get_kernel_syms: ::c_long = 4000 + 130; +pub const SYS_quotactl: ::c_long = 4000 + 131; +pub const SYS_getpgid: ::c_long = 4000 + 132; +pub const SYS_fchdir: ::c_long = 4000 + 133; +pub const SYS_bdflush: ::c_long = 4000 + 134; +pub const SYS_sysfs: ::c_long = 4000 + 135; +pub const SYS_personality: ::c_long = 4000 + 136; +pub const SYS_afs_syscall: ::c_long = 4000 + 137; +pub const SYS_setfsuid: ::c_long = 4000 + 138; +pub const SYS_setfsgid: ::c_long = 4000 + 139; +pub const SYS__llseek: ::c_long = 4000 + 140; +pub const SYS_getdents: ::c_long = 4000 + 141; +pub const SYS_flock: ::c_long = 4000 + 143; +pub const SYS_msync: ::c_long = 4000 + 144; +pub const SYS_readv: ::c_long = 4000 + 145; +pub const SYS_writev: ::c_long = 4000 + 146; +pub const SYS_cacheflush: ::c_long = 4000 + 147; +pub const SYS_cachectl: ::c_long = 4000 + 148; +pub const SYS_sysmips: ::c_long = 4000 + 149; +pub const SYS_getsid: ::c_long = 4000 + 151; +pub const SYS_fdatasync: ::c_long = 4000 + 152; +pub const SYS__sysctl: ::c_long = 4000 + 153; +pub const SYS_mlock: ::c_long = 4000 + 154; +pub const SYS_munlock: ::c_long = 4000 + 155; +pub const SYS_mlockall: ::c_long = 4000 + 156; +pub const SYS_munlockall: ::c_long = 4000 + 157; +pub const SYS_sched_setparam: ::c_long = 4000 + 158; +pub const SYS_sched_getparam: ::c_long = 4000 + 159; +pub const SYS_sched_setscheduler: ::c_long = 4000 + 160; +pub const SYS_sched_getscheduler: ::c_long = 4000 + 161; +pub const SYS_sched_yield: ::c_long = 4000 + 162; +pub const SYS_sched_get_priority_max: ::c_long = 4000 + 163; +pub const SYS_sched_get_priority_min: ::c_long = 4000 + 164; +pub const SYS_sched_rr_get_interval: ::c_long = 4000 + 165; +pub const SYS_nanosleep: ::c_long = 4000 + 166; +pub const SYS_mremap: ::c_long = 4000 + 167; +pub const SYS_accept: ::c_long = 4000 + 168; +pub const SYS_bind: ::c_long = 4000 + 169; +pub const SYS_connect: ::c_long = 4000 + 170; +pub const SYS_getpeername: ::c_long = 4000 + 171; +pub const SYS_getsockname: ::c_long = 4000 + 172; +pub const SYS_getsockopt: ::c_long = 4000 + 173; +pub const SYS_listen: ::c_long = 4000 + 174; +pub const SYS_recv: ::c_long = 4000 + 175; +pub const SYS_recvfrom: ::c_long = 4000 + 176; +pub const SYS_recvmsg: ::c_long = 4000 + 177; +pub const SYS_send: ::c_long = 4000 + 178; +pub const SYS_sendmsg: ::c_long = 4000 + 179; +pub const SYS_sendto: ::c_long = 4000 + 180; +pub const SYS_setsockopt: ::c_long = 4000 + 181; +pub const SYS_shutdown: ::c_long = 4000 + 182; +pub const SYS_socket: ::c_long = 4000 + 183; +pub const SYS_socketpair: ::c_long = 4000 + 184; +pub const SYS_setresuid: ::c_long = 4000 + 185; +pub const SYS_getresuid: ::c_long = 4000 + 186; +pub const SYS_query_module: ::c_long = 4000 + 187; +pub const SYS_poll: ::c_long = 4000 + 188; +pub const SYS_nfsservctl: ::c_long = 4000 + 189; +pub const SYS_setresgid: ::c_long = 4000 + 190; +pub const SYS_getresgid: ::c_long = 4000 + 191; +pub const SYS_prctl: ::c_long = 4000 + 192; +pub const SYS_rt_sigreturn: ::c_long = 4000 + 193; +pub const SYS_rt_sigaction: ::c_long = 4000 + 194; +pub const SYS_rt_sigprocmask: ::c_long = 4000 + 195; +pub const SYS_rt_sigpending: ::c_long = 4000 + 196; +pub const SYS_rt_sigtimedwait: ::c_long = 4000 + 197; +pub const SYS_rt_sigqueueinfo: ::c_long = 4000 + 198; +pub const SYS_rt_sigsuspend: ::c_long = 4000 + 199; +pub const SYS_chown: ::c_long = 4000 + 202; +pub const SYS_getcwd: ::c_long = 4000 + 203; +pub const SYS_capget: ::c_long = 4000 + 204; +pub const SYS_capset: ::c_long = 4000 + 205; +pub const SYS_sigaltstack: ::c_long = 4000 + 206; +pub const SYS_sendfile: ::c_long = 4000 + 207; +pub const SYS_getpmsg: ::c_long = 4000 + 208; +pub const SYS_putpmsg: ::c_long = 4000 + 209; +pub const SYS_mmap2: ::c_long = 4000 + 210; +pub const SYS_truncate64: ::c_long = 4000 + 211; +pub const SYS_ftruncate64: ::c_long = 4000 + 212; +pub const SYS_stat64: ::c_long = 4000 + 213; +pub const SYS_lstat64: ::c_long = 4000 + 214; +pub const SYS_fstat64: ::c_long = 4000 + 215; +pub const SYS_pivot_root: ::c_long = 4000 + 216; +pub const SYS_mincore: ::c_long = 4000 + 217; +pub const SYS_madvise: ::c_long = 4000 + 218; +pub const SYS_getdents64: ::c_long = 4000 + 219; +pub const SYS_fcntl64: ::c_long = 4000 + 220; +pub const SYS_gettid: ::c_long = 4000 + 222; +pub const SYS_readahead: ::c_long = 4000 + 223; +pub const SYS_setxattr: ::c_long = 4000 + 224; +pub const SYS_lsetxattr: ::c_long = 4000 + 225; +pub const SYS_fsetxattr: ::c_long = 4000 + 226; +pub const SYS_getxattr: ::c_long = 4000 + 227; +pub const SYS_lgetxattr: ::c_long = 4000 + 228; +pub const SYS_fgetxattr: ::c_long = 4000 + 229; +pub const SYS_listxattr: ::c_long = 4000 + 230; +pub const SYS_llistxattr: ::c_long = 4000 + 231; +pub const SYS_flistxattr: ::c_long = 4000 + 232; +pub const SYS_removexattr: ::c_long = 4000 + 233; +pub const SYS_lremovexattr: ::c_long = 4000 + 234; +pub const SYS_fremovexattr: ::c_long = 4000 + 235; +pub const SYS_tkill: ::c_long = 4000 + 236; +pub const SYS_sendfile64: ::c_long = 4000 + 237; +pub const SYS_futex: ::c_long = 4000 + 238; +pub const SYS_sched_setaffinity: ::c_long = 4000 + 239; +pub const SYS_sched_getaffinity: ::c_long = 4000 + 240; +pub const SYS_io_setup: ::c_long = 4000 + 241; +pub const SYS_io_destroy: ::c_long = 4000 + 242; +pub const SYS_io_getevents: ::c_long = 4000 + 243; +pub const SYS_io_submit: ::c_long = 4000 + 244; +pub const SYS_io_cancel: ::c_long = 4000 + 245; +pub const SYS_exit_group: ::c_long = 4000 + 246; +pub const SYS_lookup_dcookie: ::c_long = 4000 + 247; +pub const SYS_epoll_create: ::c_long = 4000 + 248; +pub const SYS_epoll_ctl: ::c_long = 4000 + 249; +pub const SYS_epoll_wait: ::c_long = 4000 + 250; +pub const SYS_remap_file_pages: ::c_long = 4000 + 251; +pub const SYS_set_tid_address: ::c_long = 4000 + 252; +pub const SYS_restart_syscall: ::c_long = 4000 + 253; +pub const SYS_statfs64: ::c_long = 4000 + 255; +pub const SYS_fstatfs64: ::c_long = 4000 + 256; +pub const SYS_timer_create: ::c_long = 4000 + 257; +pub const SYS_timer_settime: ::c_long = 4000 + 258; +pub const SYS_timer_gettime: ::c_long = 4000 + 259; +pub const SYS_timer_getoverrun: ::c_long = 4000 + 260; +pub const SYS_timer_delete: ::c_long = 4000 + 261; +pub const SYS_clock_settime: ::c_long = 4000 + 262; +pub const SYS_clock_gettime: ::c_long = 4000 + 263; +pub const SYS_clock_getres: ::c_long = 4000 + 264; +pub const SYS_clock_nanosleep: ::c_long = 4000 + 265; +pub const SYS_tgkill: ::c_long = 4000 + 266; +pub const SYS_utimes: ::c_long = 4000 + 267; +pub const SYS_mbind: ::c_long = 4000 + 268; +pub const SYS_get_mempolicy: ::c_long = 4000 + 269; +pub const SYS_set_mempolicy: ::c_long = 4000 + 270; +pub const SYS_mq_open: ::c_long = 4000 + 271; +pub const SYS_mq_unlink: ::c_long = 4000 + 272; +pub const SYS_mq_timedsend: ::c_long = 4000 + 273; +pub const SYS_mq_timedreceive: ::c_long = 4000 + 274; +pub const SYS_mq_notify: ::c_long = 4000 + 275; +pub const SYS_mq_getsetattr: ::c_long = 4000 + 276; +pub const SYS_vserver: ::c_long = 4000 + 277; +pub const SYS_waitid: ::c_long = 4000 + 278; +/* pub const SYS_sys_setaltroot: ::c_long = 4000 + 279; */ +pub const SYS_add_key: ::c_long = 4000 + 280; +pub const SYS_request_key: ::c_long = 4000 + 281; +pub const SYS_keyctl: ::c_long = 4000 + 282; +pub const SYS_set_thread_area: ::c_long = 4000 + 283; +pub const SYS_inotify_init: ::c_long = 4000 + 284; +pub const SYS_inotify_add_watch: ::c_long = 4000 + 285; +pub const SYS_inotify_rm_watch: ::c_long = 4000 + 286; +pub const SYS_migrate_pages: ::c_long = 4000 + 287; +pub const SYS_openat: ::c_long = 4000 + 288; +pub const SYS_mkdirat: ::c_long = 4000 + 289; +pub const SYS_mknodat: ::c_long = 4000 + 290; +pub const SYS_fchownat: ::c_long = 4000 + 291; +pub const SYS_futimesat: ::c_long = 4000 + 292; +pub const SYS_unlinkat: ::c_long = 4000 + 294; +pub const SYS_renameat: ::c_long = 4000 + 295; +pub const SYS_linkat: ::c_long = 4000 + 296; +pub const SYS_symlinkat: ::c_long = 4000 + 297; +pub const SYS_readlinkat: ::c_long = 4000 + 298; +pub const SYS_fchmodat: ::c_long = 4000 + 299; +pub const SYS_faccessat: ::c_long = 4000 + 300; +pub const SYS_pselect6: ::c_long = 4000 + 301; +pub const SYS_ppoll: ::c_long = 4000 + 302; +pub const SYS_unshare: ::c_long = 4000 + 303; +pub const SYS_splice: ::c_long = 4000 + 304; +pub const SYS_sync_file_range: ::c_long = 4000 + 305; +pub const SYS_tee: ::c_long = 4000 + 306; +pub const SYS_vmsplice: ::c_long = 4000 + 307; +pub const SYS_move_pages: ::c_long = 4000 + 308; +pub const SYS_set_robust_list: ::c_long = 4000 + 309; +pub const SYS_get_robust_list: ::c_long = 4000 + 310; +pub const SYS_kexec_load: ::c_long = 4000 + 311; +pub const SYS_getcpu: ::c_long = 4000 + 312; +pub const SYS_epoll_pwait: ::c_long = 4000 + 313; +pub const SYS_ioprio_set: ::c_long = 4000 + 314; +pub const SYS_ioprio_get: ::c_long = 4000 + 315; +pub const SYS_utimensat: ::c_long = 4000 + 316; +pub const SYS_signalfd: ::c_long = 4000 + 317; +pub const SYS_timerfd: ::c_long = 4000 + 318; +pub const SYS_eventfd: ::c_long = 4000 + 319; +pub const SYS_fallocate: ::c_long = 4000 + 320; +pub const SYS_timerfd_create: ::c_long = 4000 + 321; +pub const SYS_timerfd_gettime: ::c_long = 4000 + 322; +pub const SYS_timerfd_settime: ::c_long = 4000 + 323; +pub const SYS_signalfd4: ::c_long = 4000 + 324; +pub const SYS_eventfd2: ::c_long = 4000 + 325; +pub const SYS_epoll_create1: ::c_long = 4000 + 326; +pub const SYS_dup3: ::c_long = 4000 + 327; +pub const SYS_pipe2: ::c_long = 4000 + 328; +pub const SYS_inotify_init1: ::c_long = 4000 + 329; +pub const SYS_preadv: ::c_long = 4000 + 330; +pub const SYS_pwritev: ::c_long = 4000 + 331; +pub const SYS_rt_tgsigqueueinfo: ::c_long = 4000 + 332; +pub const SYS_perf_event_open: ::c_long = 4000 + 333; +pub const SYS_accept4: ::c_long = 4000 + 334; +pub const SYS_recvmmsg: ::c_long = 4000 + 335; +pub const SYS_fanotify_init: ::c_long = 4000 + 336; +pub const SYS_fanotify_mark: ::c_long = 4000 + 337; +pub const SYS_prlimit64: ::c_long = 4000 + 338; +pub const SYS_name_to_handle_at: ::c_long = 4000 + 339; +pub const SYS_open_by_handle_at: ::c_long = 4000 + 340; +pub const SYS_clock_adjtime: ::c_long = 4000 + 341; +pub const SYS_syncfs: ::c_long = 4000 + 342; +pub const SYS_sendmmsg: ::c_long = 4000 + 343; +pub const SYS_setns: ::c_long = 4000 + 344; +pub const SYS_process_vm_readv: ::c_long = 4000 + 345; +pub const SYS_process_vm_writev: ::c_long = 4000 + 346; +pub const SYS_kcmp: ::c_long = 4000 + 347; +pub const SYS_finit_module: ::c_long = 4000 + 348; +pub const SYS_sched_setattr: ::c_long = 4000 + 349; +pub const SYS_sched_getattr: ::c_long = 4000 + 350; +pub const SYS_renameat2: ::c_long = 4000 + 351; +pub const SYS_seccomp: ::c_long = 4000 + 352; +pub const SYS_getrandom: ::c_long = 4000 + 353; +pub const SYS_memfd_create: ::c_long = 4000 + 354; +pub const SYS_bpf: ::c_long = 4000 + 355; +pub const SYS_execveat: ::c_long = 4000 + 356; +pub const SYS_userfaultfd: ::c_long = 4000 + 357; +pub const SYS_membarrier: ::c_long = 4000 + 358; +pub const SYS_mlock2: ::c_long = 4000 + 359; +pub const SYS_copy_file_range: ::c_long = 4000 + 360; +pub const SYS_preadv2: ::c_long = 4000 + 361; +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; + +cfg_if! { + if #[cfg(libc_align)] { + mod align; + pub use self::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 new file mode 100644 index 0000000..cecd6dc --- /dev/null +++ b/vendor/libc/src/unix/linux_like/linux/musl/b32/mod.rs @@ -0,0 +1,65 @@ +pub type c_long = i32; +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! { + pub struct pthread_attr_t { + __size: [u32; 9] + } + + pub struct sigset_t { + __val: [::c_ulong; 32], + } + + 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 sem_t { + __val: [::c_int; 4], + } +} + +pub const __SIZEOF_PTHREAD_RWLOCK_T: usize = 32; +pub const __SIZEOF_PTHREAD_MUTEX_T: usize = 24; +pub const __SIZEOF_PTHREAD_BARRIER_T: usize = 20; + +cfg_if! { + if #[cfg(any(target_arch = "x86"))] { + mod x86; + pub use self::x86::*; + } else if #[cfg(any(target_arch = "mips"))] { + mod mips; + pub use self::mips::*; + } else if #[cfg(any(target_arch = "arm"))] { + mod arm; + pub use self::arm::*; + } else if #[cfg(any(target_arch = "powerpc"))] { + mod powerpc; + pub use self::powerpc::*; + } 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 new file mode 100644 index 0000000..834a442 --- /dev/null +++ b/vendor/libc/src/unix/linux_like/linux/musl/b32/powerpc.rs @@ -0,0 +1,803 @@ +pub type c_char = u8; +pub type wchar_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, + __st_rdev_padding: ::c_short, + 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; 2], + } + + 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_uid: ::uid_t, + pub st_gid: ::gid_t, + pub st_rdev: ::dev_t, + __st_rdev_padding: ::c_short, + 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; 2], + } + + pub struct stack_t { + pub ss_sp: *mut ::c_void, + pub ss_flags: ::c_int, + pub ss_size: ::size_t + } + + 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_int, + __pad1: ::c_int, + __pad2: ::c_longlong, + __pad3: ::c_longlong + } + + pub struct shmid_ds { + pub shm_perm: ::ipc_perm, + __unused1: ::c_int, + pub shm_atime: ::time_t, + __unused2: ::c_int, + pub shm_dtime: ::time_t, + __unused3: ::c_int, + pub shm_ctime: ::time_t, + __unused4: ::c_int, + pub shm_segsz: ::size_t, + pub shm_cpid: ::pid_t, + pub shm_lpid: ::pid_t, + pub shm_nattch: ::c_ulong, + __pad1: ::c_ulong, + __pad2: ::c_ulong, + } + + pub struct msqid_ds { + pub msg_perm: ::ipc_perm, + __unused1: ::c_int, + pub msg_stime: ::time_t, + __unused2: ::c_int, + pub msg_rtime: ::time_t, + __unused3: ::c_int, + pub msg_ctime: ::time_t, + __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 statfs { + 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 siginfo_t { + pub si_signo: ::c_int, + pub si_errno: ::c_int, + pub si_code: ::c_int, + pub _pad: [::c_int; 29], + _align: [usize; 0], + } + + 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, + #[cfg(target_endian = "little")] + pub f_fsid: ::c_ulong, + __f_unused: ::c_int, + #[cfg(target_endian = "big")] + pub f_fsid: ::c_ulong, + pub f_flag: ::c_ulong, + pub f_namemax: ::c_ulong, + __f_spare: [::c_int; 6], + } +} + +pub const MADV_SOFT_OFFLINE: ::c_int = 101; +pub const SIGSTKSZ: ::size_t = 10240; +pub const MINSIGSTKSZ: ::size_t = 4096; + +pub const O_DIRECT: ::c_int = 0x20000; +pub const O_DIRECTORY: ::c_int = 0x4000; +pub const O_NOFOLLOW: ::c_int = 0x8000; +pub const O_ASYNC: ::c_int = 0x2000; +pub const O_LARGEFILE: ::c_int = 0x10000; + +pub const MCL_CURRENT: ::c_int = 0x2000; +pub const MCL_FUTURE: ::c_int = 0x4000; +pub const MCL_ONFAULT: ::c_int = 0x8000; +pub const CBAUD: ::tcflag_t = 0o0000377; +pub const TAB1: ::c_int = 0x00000400; +pub const TAB2: ::c_int = 0x00000800; +pub const TAB3: ::c_int = 0x00000C00; +pub const CR1: ::c_int = 0x00001000; +pub const CR2: ::c_int = 0x00002000; +pub const CR3: ::c_int = 0x00003000; +pub const FF1: ::c_int = 0x00004000; +pub const BS1: ::c_int = 0x00008000; +pub const VT1: ::c_int = 0x00010000; +pub const VWERASE: usize = 10; +pub const VREPRINT: usize = 11; +pub const VSUSP: usize = 12; +pub const VSTART: usize = 13; +pub const VSTOP: usize = 14; +pub const VDISCARD: usize = 16; +pub const VTIME: usize = 7; +pub const IXON: ::tcflag_t = 0x00000200; +pub const IXOFF: ::tcflag_t = 0x00000400; +pub const ONLCR: ::tcflag_t = 0x00000002; +pub const CSIZE: ::tcflag_t = 0x00000300; +pub const CS6: ::tcflag_t = 0x00000100; +pub const CS7: ::tcflag_t = 0x00000200; +pub const CS8: ::tcflag_t = 0x00000300; +pub const CSTOPB: ::tcflag_t = 0x00000400; +pub const CREAD: ::tcflag_t = 0x00000800; +pub const PARENB: ::tcflag_t = 0x00001000; +pub const PARODD: ::tcflag_t = 0x00002000; +pub const HUPCL: ::tcflag_t = 0x00004000; +pub const CLOCAL: ::tcflag_t = 0x00008000; +pub const ECHOKE: ::tcflag_t = 0x00000001; +pub const ECHOE: ::tcflag_t = 0x00000002; +pub const ECHOK: ::tcflag_t = 0x00000004; +pub const ECHONL: ::tcflag_t = 0x00000010; +pub const ECHOPRT: ::tcflag_t = 0x00000020; +pub const ECHOCTL: ::tcflag_t = 0x00000040; +pub const ISIG: ::tcflag_t = 0x00000080; +pub const ICANON: ::tcflag_t = 0x00000100; +pub const PENDIN: ::tcflag_t = 0x20000000; +pub const NOFLSH: ::tcflag_t = 0x80000000; +pub const CIBAUD: ::tcflag_t = 0o00077600000; +pub const CBAUDEX: ::tcflag_t = 0o000020; +pub const VSWTC: usize = 9; +pub const OLCUC: ::tcflag_t = 0o000004; +pub const NLDLY: ::tcflag_t = 0o001400; +pub const CRDLY: ::tcflag_t = 0o030000; +pub const TABDLY: ::tcflag_t = 0o006000; +pub const BSDLY: ::tcflag_t = 0o100000; +pub const FFDLY: ::tcflag_t = 0o040000; +pub const VTDLY: ::tcflag_t = 0o200000; +pub const XTABS: ::tcflag_t = 0o006000; +pub const B57600: ::speed_t = 0o000020; +pub const B115200: ::speed_t = 0o000021; +pub const B230400: ::speed_t = 0o000022; +pub const B460800: ::speed_t = 0o000023; +pub const B500000: ::speed_t = 0o000024; +pub const B576000: ::speed_t = 0o000025; +pub const B921600: ::speed_t = 0o000026; +pub const B1000000: ::speed_t = 0o000027; +pub const B1152000: ::speed_t = 0o000030; +pub const B1500000: ::speed_t = 0o000031; +pub const B2000000: ::speed_t = 0o000032; +pub const B2500000: ::speed_t = 0o000033; +pub const B3000000: ::speed_t = 0o000034; +pub const B3500000: ::speed_t = 0o000035; +pub const B4000000: ::speed_t = 0o000036; + +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 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 = 0x00080; +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 PTRACE_SYSEMU: ::c_int = 0x1d; +pub const PTRACE_SYSEMU_SINGLESTEP: ::c_int = 0x1e; + +pub const SOCK_STREAM: ::c_int = 1; +pub const SOCK_DGRAM: ::c_int = 2; + +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 EDEADLOCK: ::c_int = 58; +pub const EMULTIHOP: ::c_int = 72; +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 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 ERFKILL: ::c_int = 132; +pub const EHWPOISON: ::c_int = 133; + +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 EXTPROC: ::tcflag_t = 0x10000000; + +pub const F_GETLK: ::c_int = 12; +pub const F_GETOWN: ::c_int = 9; +pub const F_SETLK: ::c_int = 13; +pub const F_SETLKW: ::c_int = 14; +pub const F_SETOWN: ::c_int = 8; + +pub const VEOF: usize = 4; +pub const VEOL: usize = 6; +pub const VEOL2: usize = 8; +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 POLLWRNORM: ::c_short = 0x100; +pub const POLLWRBAND: ::c_short = 0x200; + +// Syscall table +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_time: ::c_long = 13; +pub const SYS_mknod: ::c_long = 14; +pub const SYS_chmod: ::c_long = 15; +pub const SYS_lchown: ::c_long = 16; +pub const SYS_break: ::c_long = 17; +pub const SYS_oldstat: ::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_umount: ::c_long = 22; +pub const SYS_setuid: ::c_long = 23; +pub const SYS_getuid: ::c_long = 24; +pub const SYS_stime: ::c_long = 25; +pub const SYS_ptrace: ::c_long = 26; +pub const SYS_alarm: ::c_long = 27; +pub const SYS_oldfstat: ::c_long = 28; +pub const SYS_pause: ::c_long = 29; +pub const SYS_utime: ::c_long = 30; +pub const SYS_stty: ::c_long = 31; +pub const SYS_gtty: ::c_long = 32; +pub const SYS_access: ::c_long = 33; +pub const SYS_nice: ::c_long = 34; +pub const SYS_ftime: ::c_long = 35; +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_prof: ::c_long = 44; +pub const SYS_brk: ::c_long = 45; +pub const SYS_setgid: ::c_long = 46; +pub const SYS_getgid: ::c_long = 47; +pub const SYS_signal: ::c_long = 48; +pub const SYS_geteuid: ::c_long = 49; +pub const SYS_getegid: ::c_long = 50; +pub const SYS_acct: ::c_long = 51; +pub const SYS_umount2: ::c_long = 52; +pub const SYS_lock: ::c_long = 53; +pub const SYS_ioctl: ::c_long = 54; +pub const SYS_fcntl: ::c_long = 55; +pub const SYS_mpx: ::c_long = 56; +pub const SYS_setpgid: ::c_long = 57; +pub const SYS_ulimit: ::c_long = 58; +pub const SYS_oldolduname: ::c_long = 59; +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_setreuid: ::c_long = 70; +pub const SYS_setregid: ::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_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_getgroups: ::c_long = 80; +pub const SYS_setgroups: ::c_long = 81; +pub const SYS_select: ::c_long = 82; +pub const SYS_symlink: ::c_long = 83; +pub const SYS_oldlstat: ::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_readdir: ::c_long = 89; +pub const SYS_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_fchown: ::c_long = 95; +pub const SYS_getpriority: ::c_long = 96; +pub const SYS_setpriority: ::c_long = 97; +pub const SYS_profil: ::c_long = 98; +pub const SYS_statfs: ::c_long = 99; +pub const SYS_fstatfs: ::c_long = 100; +pub const SYS_ioperm: ::c_long = 101; +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_stat: ::c_long = 106; +pub const SYS_lstat: ::c_long = 107; +pub const SYS_fstat: ::c_long = 108; +pub const SYS_olduname: ::c_long = 109; +pub const SYS_iopl: ::c_long = 110; +pub const SYS_vhangup: ::c_long = 111; +pub const SYS_idle: ::c_long = 112; +pub const SYS_vm86: ::c_long = 113; +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_uname: ::c_long = 122; +pub const SYS_modify_ldt: ::c_long = 123; +pub const SYS_adjtimex: ::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_afs_syscall: ::c_long = 137; +pub const SYS_setfsuid: ::c_long = 138; +pub const SYS_setfsgid: ::c_long = 139; +pub const SYS__llseek: ::c_long = 140; +pub const SYS_getdents: ::c_long = 141; +pub const SYS__newselect: ::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: ::c_long = 161; +pub const SYS_nanosleep: ::c_long = 162; +pub const SYS_mremap: ::c_long = 163; +pub const SYS_setresuid: ::c_long = 164; +pub const SYS_getresuid: ::c_long = 165; +pub const SYS_query_module: ::c_long = 166; +pub const SYS_poll: ::c_long = 167; +pub const SYS_nfsservctl: ::c_long = 168; +pub const SYS_setresgid: ::c_long = 169; +pub const SYS_getresgid: ::c_long = 170; +pub const SYS_prctl: ::c_long = 171; +pub const SYS_rt_sigreturn: ::c_long = 172; +pub const SYS_rt_sigaction: ::c_long = 173; +pub const SYS_rt_sigprocmask: ::c_long = 174; +pub const SYS_rt_sigpending: ::c_long = 175; +pub const SYS_rt_sigtimedwait: ::c_long = 176; +pub const SYS_rt_sigqueueinfo: ::c_long = 177; +pub const SYS_rt_sigsuspend: ::c_long = 178; +pub const SYS_pread64: ::c_long = 179; +pub const SYS_pwrite64: ::c_long = 180; +pub const SYS_chown: ::c_long = 181; +pub const SYS_getcwd: ::c_long = 182; +pub const SYS_capget: ::c_long = 183; +pub const SYS_capset: ::c_long = 184; +pub const SYS_sigaltstack: ::c_long = 185; +pub const SYS_sendfile: ::c_long = 186; +pub const SYS_getpmsg: ::c_long = 187; +pub const SYS_putpmsg: ::c_long = 188; +pub const SYS_vfork: ::c_long = 189; +pub const SYS_ugetrlimit: ::c_long = 190; +pub const SYS_readahead: ::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_pciconfig_read: ::c_long = 198; +pub const SYS_pciconfig_write: ::c_long = 199; +pub const SYS_pciconfig_iobase: ::c_long = 200; +pub const SYS_multiplexer: ::c_long = 201; +pub const SYS_getdents64: ::c_long = 202; +pub const SYS_pivot_root: ::c_long = 203; +pub const SYS_fcntl64: ::c_long = 204; +pub const SYS_madvise: ::c_long = 205; +pub const SYS_mincore: ::c_long = 206; +pub const SYS_gettid: ::c_long = 207; +pub const SYS_tkill: ::c_long = 208; +pub const SYS_setxattr: ::c_long = 209; +pub const SYS_lsetxattr: ::c_long = 210; +pub const SYS_fsetxattr: ::c_long = 211; +pub const SYS_getxattr: ::c_long = 212; +pub const SYS_lgetxattr: ::c_long = 213; +pub const SYS_fgetxattr: ::c_long = 214; +pub const SYS_listxattr: ::c_long = 215; +pub const SYS_llistxattr: ::c_long = 216; +pub const SYS_flistxattr: ::c_long = 217; +pub const SYS_removexattr: ::c_long = 218; +pub const SYS_lremovexattr: ::c_long = 219; +pub const SYS_fremovexattr: ::c_long = 220; +pub const SYS_futex: ::c_long = 221; +pub const SYS_sched_setaffinity: ::c_long = 222; +pub const SYS_sched_getaffinity: ::c_long = 223; +pub const SYS_tuxcall: ::c_long = 225; +pub const SYS_sendfile64: ::c_long = 226; +pub const SYS_io_setup: ::c_long = 227; +pub const SYS_io_destroy: ::c_long = 228; +pub const SYS_io_getevents: ::c_long = 229; +pub const SYS_io_submit: ::c_long = 230; +pub const SYS_io_cancel: ::c_long = 231; +pub const SYS_set_tid_address: ::c_long = 232; +pub const SYS_fadvise64: ::c_long = 233; +pub const SYS_exit_group: ::c_long = 234; +pub const SYS_lookup_dcookie: ::c_long = 235; +pub const SYS_epoll_create: ::c_long = 236; +pub const SYS_epoll_ctl: ::c_long = 237; +pub const SYS_epoll_wait: ::c_long = 238; +pub const SYS_remap_file_pages: ::c_long = 239; +pub const SYS_timer_create: ::c_long = 240; +pub const SYS_timer_settime: ::c_long = 241; +pub const SYS_timer_gettime: ::c_long = 242; +pub const SYS_timer_getoverrun: ::c_long = 243; +pub const SYS_timer_delete: ::c_long = 244; +pub const SYS_clock_settime: ::c_long = 245; +pub const SYS_clock_gettime: ::c_long = 246; +pub const SYS_clock_getres: ::c_long = 247; +pub const SYS_clock_nanosleep: ::c_long = 248; +pub const SYS_swapcontext: ::c_long = 249; +pub const SYS_tgkill: ::c_long = 250; +pub const SYS_utimes: ::c_long = 251; +pub const SYS_statfs64: ::c_long = 252; +pub const SYS_fstatfs64: ::c_long = 253; +pub const SYS_fadvise64_64: ::c_long = 254; +pub const SYS_rtas: ::c_long = 255; +pub const SYS_sys_debug_setcontext: ::c_long = 256; +pub const SYS_migrate_pages: ::c_long = 258; +pub const SYS_mbind: ::c_long = 259; +pub const SYS_get_mempolicy: ::c_long = 260; +pub const SYS_set_mempolicy: ::c_long = 261; +pub const SYS_mq_open: ::c_long = 262; +pub const SYS_mq_unlink: ::c_long = 263; +pub const SYS_mq_timedsend: ::c_long = 264; +pub const SYS_mq_timedreceive: ::c_long = 265; +pub const SYS_mq_notify: ::c_long = 266; +pub const SYS_mq_getsetattr: ::c_long = 267; +pub const SYS_kexec_load: ::c_long = 268; +pub const SYS_add_key: ::c_long = 269; +pub const SYS_request_key: ::c_long = 270; +pub const SYS_keyctl: ::c_long = 271; +pub const SYS_waitid: ::c_long = 272; +pub const SYS_ioprio_set: ::c_long = 273; +pub const SYS_ioprio_get: ::c_long = 274; +pub const SYS_inotify_init: ::c_long = 275; +pub const SYS_inotify_add_watch: ::c_long = 276; +pub const SYS_inotify_rm_watch: ::c_long = 277; +pub const SYS_spu_run: ::c_long = 278; +pub const SYS_spu_create: ::c_long = 279; +pub const SYS_pselect6: ::c_long = 280; +pub const SYS_ppoll: ::c_long = 281; +pub const SYS_unshare: ::c_long = 282; +pub const SYS_splice: ::c_long = 283; +pub const SYS_tee: ::c_long = 284; +pub const SYS_vmsplice: ::c_long = 285; +pub const SYS_openat: ::c_long = 286; +pub const SYS_mkdirat: ::c_long = 287; +pub const SYS_mknodat: ::c_long = 288; +pub const SYS_fchownat: ::c_long = 289; +pub const SYS_futimesat: ::c_long = 290; +pub const SYS_fstatat64: ::c_long = 291; +pub const SYS_unlinkat: ::c_long = 292; +pub const SYS_renameat: ::c_long = 293; +pub const SYS_linkat: ::c_long = 294; +pub const SYS_symlinkat: ::c_long = 295; +pub const SYS_readlinkat: ::c_long = 296; +pub const SYS_fchmodat: ::c_long = 297; +pub const SYS_faccessat: ::c_long = 298; +pub const SYS_get_robust_list: ::c_long = 299; +pub const SYS_set_robust_list: ::c_long = 300; +pub const SYS_move_pages: ::c_long = 301; +pub const SYS_getcpu: ::c_long = 302; +pub const SYS_epoll_pwait: ::c_long = 303; +pub const SYS_utimensat: ::c_long = 304; +pub const SYS_signalfd: ::c_long = 305; +pub const SYS_timerfd_create: ::c_long = 306; +pub const SYS_eventfd: ::c_long = 307; +pub const SYS_sync_file_range2: ::c_long = 308; +pub const SYS_fallocate: ::c_long = 309; +pub const SYS_subpage_prot: ::c_long = 310; +pub const SYS_timerfd_settime: ::c_long = 311; +pub const SYS_timerfd_gettime: ::c_long = 312; +pub const SYS_signalfd4: ::c_long = 313; +pub const SYS_eventfd2: ::c_long = 314; +pub const SYS_epoll_create1: ::c_long = 315; +pub const SYS_dup3: ::c_long = 316; +pub const SYS_pipe2: ::c_long = 317; +pub const SYS_inotify_init1: ::c_long = 318; +pub const SYS_perf_event_open: ::c_long = 319; +pub const SYS_preadv: ::c_long = 320; +pub const SYS_pwritev: ::c_long = 321; +pub const SYS_rt_tgsigqueueinfo: ::c_long = 322; +pub const SYS_fanotify_init: ::c_long = 323; +pub const SYS_fanotify_mark: ::c_long = 324; +pub const SYS_prlimit64: ::c_long = 325; +pub const SYS_socket: ::c_long = 326; +pub const SYS_bind: ::c_long = 327; +pub const SYS_connect: ::c_long = 328; +pub const SYS_listen: ::c_long = 329; +pub const SYS_accept: ::c_long = 330; +pub const SYS_getsockname: ::c_long = 331; +pub const SYS_getpeername: ::c_long = 332; +pub const SYS_socketpair: ::c_long = 333; +pub const SYS_send: ::c_long = 334; +pub const SYS_sendto: ::c_long = 335; +pub const SYS_recv: ::c_long = 336; +pub const SYS_recvfrom: ::c_long = 337; +pub const SYS_shutdown: ::c_long = 338; +pub const SYS_setsockopt: ::c_long = 339; +pub const SYS_getsockopt: ::c_long = 340; +pub const SYS_sendmsg: ::c_long = 341; +pub const SYS_recvmsg: ::c_long = 342; +pub const SYS_recvmmsg: ::c_long = 343; +pub const SYS_accept4: ::c_long = 344; +pub const SYS_name_to_handle_at: ::c_long = 345; +pub const SYS_open_by_handle_at: ::c_long = 346; +pub const SYS_clock_adjtime: ::c_long = 347; +pub const SYS_syncfs: ::c_long = 348; +pub const SYS_sendmmsg: ::c_long = 349; +pub const SYS_setns: ::c_long = 350; +pub const SYS_process_vm_readv: ::c_long = 351; +pub const SYS_process_vm_writev: ::c_long = 352; +pub const SYS_finit_module: ::c_long = 353; +pub const SYS_kcmp: ::c_long = 354; +pub const SYS_sched_setattr: ::c_long = 355; +pub const SYS_sched_getattr: ::c_long = 356; +pub const SYS_renameat2: ::c_long = 357; +pub const SYS_seccomp: ::c_long = 358; +pub const SYS_getrandom: ::c_long = 359; +pub const SYS_memfd_create: ::c_long = 360; +pub const SYS_bpf: ::c_long = 361; +pub const SYS_execveat: ::c_long = 362; +pub const SYS_switch_endian: ::c_long = 363; +pub const SYS_userfaultfd: ::c_long = 364; +pub const SYS_membarrier: ::c_long = 365; +pub const SYS_mlock2: ::c_long = 378; +pub const SYS_copy_file_range: ::c_long = 379; +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_pkey_alloc: ::c_long = 384; +pub const SYS_pkey_free: ::c_long = 385; +pub const SYS_pkey_mprotect: ::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; +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; +pub const SYS_mseal: ::c_long = 462; + +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..f963f64 --- /dev/null +++ b/vendor/libc/src/unix/linux_like/linux/musl/b32/riscv32/mod.rs @@ -0,0 +1,798 @@ +//! 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 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_SETOWN: ::c_int = 8; +pub const F_GETOWN: ::c_int = 9; +pub const F_GETLK: ::c_int = 12; +pub const F_SETLK: ::c_int = 13; +pub const F_SETLKW: ::c_int = 14; +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_LARGEFILE: ::c_int = 0o0100000; +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 MCL_ONFAULT: ::c_int = 4; +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/align.rs b/vendor/libc/src/unix/linux_like/linux/musl/b32/x86/align.rs new file mode 100644 index 0000000..7954417 --- /dev/null +++ b/vendor/libc/src/unix/linux_like/linux/musl/b32/x86/align.rs @@ -0,0 +1,7 @@ +s_no_extra_traits! { + #[allow(missing_debug_implementations)] + #[repr(align(8))] + pub struct max_align_t { + priv_: [f64; 3] + } +} 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 new file mode 100644 index 0000000..7fad046 --- /dev/null +++ b/vendor/libc/src/unix/linux_like/linux/musl/b32/x86/mod.rs @@ -0,0 +1,969 @@ +pub type c_char = i8; +pub type wchar_t = i32; + +s! { + pub struct stat { + pub st_dev: ::dev_t, + __st_dev_padding: ::c_int, + __st_ino_truncated: ::c_long, + 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, + __st_rdev_padding: ::c_int, + 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, + pub st_ino: ::ino_t, + } + + pub struct stat64 { + pub st_dev: ::dev_t, + __st_dev_padding: ::c_int, + __st_ino_truncated: ::c_long, + 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, + __st_rdev_padding: ::c_int, + 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, + pub st_ino: ::ino_t, + } + + pub struct stack_t { + pub ss_sp: *mut ::c_void, + pub ss_flags: ::c_int, + pub ss_size: ::size_t + } + + 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_int, + __unused1: ::c_long, + __unused2: ::c_long + } + + pub struct shmid_ds { + pub shm_perm: ::ipc_perm, + pub shm_segsz: ::size_t, + pub shm_atime: ::time_t, + __unused1: ::c_int, + pub shm_dtime: ::time_t, + __unused2: ::c_int, + pub shm_ctime: ::time_t, + __unused3: ::c_int, + pub shm_cpid: ::pid_t, + pub shm_lpid: ::pid_t, + pub shm_nattch: ::c_ulong, + __pad1: ::c_ulong, + __pad2: ::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 statfs { + 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 mcontext_t { + __private: [u32; 22] + } + + pub struct siginfo_t { + pub si_signo: ::c_int, + pub si_errno: ::c_int, + pub si_code: ::c_int, + pub _pad: [::c_int; 29], + _align: [usize; 0], + } + + 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], + } +} + +s_no_extra_traits! { + pub struct user_fpxregs_struct { + pub cwd: ::c_ushort, + pub swd: ::c_ushort, + pub twd: ::c_ushort, + pub fop: ::c_ushort, + pub fip: ::c_long, + pub fcs: ::c_long, + pub foo: ::c_long, + pub fos: ::c_long, + pub mxcsr: ::c_long, + __reserved: ::c_long, + pub st_space: [::c_long; 32], + pub xmm_space: [::c_long; 32], + padding: [::c_long; 56], + } + + 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, + __private: [u8; 112], + } +} + +cfg_if! { + if #[cfg(feature = "extra_traits")] { + impl PartialEq for user_fpxregs_struct { + fn eq(&self, other: &user_fpxregs_struct) -> bool { + self.cwd == other.cwd + && self.swd == other.swd + && self.twd == other.twd + && self.fop == other.fop + && self.fip == other.fip + && self.fcs == other.fcs + && self.foo == other.foo + && self.fos == other.fos + && self.mxcsr == other.mxcsr + // Ignore __reserved field + && self.st_space == other.st_space + && self.xmm_space == other.xmm_space + // Ignore padding field + } + } + + impl Eq for user_fpxregs_struct {} + + impl ::fmt::Debug for user_fpxregs_struct { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("user_fpxregs_struct") + .field("cwd", &self.cwd) + .field("swd", &self.swd) + .field("twd", &self.twd) + .field("fop", &self.fop) + .field("fip", &self.fip) + .field("fcs", &self.fcs) + .field("foo", &self.foo) + .field("fos", &self.fos) + .field("mxcsr", &self.mxcsr) + // Ignore __reserved field + .field("st_space", &self.st_space) + .field("xmm_space", &self.xmm_space) + // Ignore padding field + .finish() + } + } + + impl ::hash::Hash for user_fpxregs_struct { + fn hash(&self, state: &mut H) { + self.cwd.hash(state); + self.swd.hash(state); + self.twd.hash(state); + self.fop.hash(state); + self.fip.hash(state); + self.fcs.hash(state); + self.foo.hash(state); + self.fos.hash(state); + self.mxcsr.hash(state); + // Ignore __reserved field + self.st_space.hash(state); + self.xmm_space.hash(state); + // Ignore padding field + } + } + + impl PartialEq for ucontext_t { + fn eq(&self, other: &ucontext_t) -> bool { + self.uc_flags == other.uc_flags + && self.uc_link == other.uc_link + && self.uc_stack == other.uc_stack + && self.uc_mcontext == other.uc_mcontext + && self.uc_sigmask == other.uc_sigmask + && self + .__private + .iter() + .zip(other.__private.iter()) + .all(|(a,b)| a == b) + } + } + + impl Eq for ucontext_t {} + + impl ::fmt::Debug for ucontext_t { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("ucontext_t") + .field("uc_flags", &self.uc_flags) + .field("uc_link", &self.uc_link) + .field("uc_stack", &self.uc_stack) + .field("uc_mcontext", &self.uc_mcontext) + .field("uc_sigmask", &self.uc_sigmask) + // Ignore __private field + .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); + self.__private.hash(state); + } + } + } +} + +pub const SIGSTKSZ: ::size_t = 8192; +pub const MINSIGSTKSZ: ::size_t = 2048; + +pub const O_DIRECT: ::c_int = 0x4000; +pub const O_DIRECTORY: ::c_int = 0x10000; +pub const O_NOFOLLOW: ::c_int = 0x20000; +pub const O_ASYNC: ::c_int = 0x2000; +pub const O_LARGEFILE: ::c_int = 0o0100000; + +pub const MADV_SOFT_OFFLINE: ::c_int = 101; +pub const MCL_CURRENT: ::c_int = 0x0001; +pub const MCL_FUTURE: ::c_int = 0x0002; +pub const MCL_ONFAULT: ::c_int = 0x0004; +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 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 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_SYNC: ::c_int = 0x080000; + +pub const SOCK_STREAM: ::c_int = 1; +pub const SOCK_DGRAM: ::c_int = 2; + +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 EDEADLOCK: ::c_int = EDEADLK; +pub const EMULTIHOP: ::c_int = 72; +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 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 ERFKILL: ::c_int = 132; +pub const EHWPOISON: ::c_int = 133; + +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 EXTPROC: ::tcflag_t = 0x00010000; + +pub const MAP_HUGETLB: ::c_int = 0x040000; +pub const MAP_32BIT: ::c_int = 0x0040; + +pub const F_GETLK: ::c_int = 12; +pub const F_GETOWN: ::c_int = 9; +pub const F_SETLK: ::c_int = 13; +pub const F_SETLKW: ::c_int = 14; +pub const F_SETOWN: ::c_int = 8; + +pub const VEOF: usize = 4; +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 POLLWRNORM: ::c_short = 0x100; +pub const POLLWRBAND: ::c_short = 0x200; + +pub const PTRACE_SYSEMU: ::c_int = 31; +pub const PTRACE_SYSEMU_SINGLESTEP: ::c_int = 32; + +// Syscall table +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_time: ::c_long = 13; +pub const SYS_mknod: ::c_long = 14; +pub const SYS_chmod: ::c_long = 15; +pub const SYS_lchown: ::c_long = 16; +pub const SYS_break: ::c_long = 17; +pub const SYS_oldstat: ::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_umount: ::c_long = 22; +pub const SYS_setuid: ::c_long = 23; +pub const SYS_getuid: ::c_long = 24; +pub const SYS_stime: ::c_long = 25; +pub const SYS_ptrace: ::c_long = 26; +pub const SYS_alarm: ::c_long = 27; +pub const SYS_oldfstat: ::c_long = 28; +pub const SYS_pause: ::c_long = 29; +pub const SYS_utime: ::c_long = 30; +pub const SYS_stty: ::c_long = 31; +pub const SYS_gtty: ::c_long = 32; +pub const SYS_access: ::c_long = 33; +pub const SYS_nice: ::c_long = 34; +pub const SYS_ftime: ::c_long = 35; +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_prof: ::c_long = 44; +pub const SYS_brk: ::c_long = 45; +pub const SYS_setgid: ::c_long = 46; +pub const SYS_getgid: ::c_long = 47; +pub const SYS_signal: ::c_long = 48; +pub const SYS_geteuid: ::c_long = 49; +pub const SYS_getegid: ::c_long = 50; +pub const SYS_acct: ::c_long = 51; +pub const SYS_umount2: ::c_long = 52; +pub const SYS_lock: ::c_long = 53; +pub const SYS_ioctl: ::c_long = 54; +pub const SYS_fcntl: ::c_long = 55; +pub const SYS_mpx: ::c_long = 56; +pub const SYS_setpgid: ::c_long = 57; +pub const SYS_ulimit: ::c_long = 58; +pub const SYS_oldolduname: ::c_long = 59; +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_setreuid: ::c_long = 70; +pub const SYS_setregid: ::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_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_getgroups: ::c_long = 80; +pub const SYS_setgroups: ::c_long = 81; +pub const SYS_select: ::c_long = 82; +pub const SYS_symlink: ::c_long = 83; +pub const SYS_oldlstat: ::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_readdir: ::c_long = 89; +pub const SYS_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_fchown: ::c_long = 95; +pub const SYS_getpriority: ::c_long = 96; +pub const SYS_setpriority: ::c_long = 97; +pub const SYS_profil: ::c_long = 98; +pub const SYS_statfs: ::c_long = 99; +pub const SYS_fstatfs: ::c_long = 100; +pub const SYS_ioperm: ::c_long = 101; +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_stat: ::c_long = 106; +pub const SYS_lstat: ::c_long = 107; +pub const SYS_fstat: ::c_long = 108; +pub const SYS_olduname: ::c_long = 109; +pub const SYS_iopl: ::c_long = 110; +pub const SYS_vhangup: ::c_long = 111; +pub const SYS_idle: ::c_long = 112; +pub const SYS_vm86old: ::c_long = 113; +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_uname: ::c_long = 122; +pub const SYS_modify_ldt: ::c_long = 123; +pub const SYS_adjtimex: ::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_afs_syscall: ::c_long = 137; +pub const SYS_setfsuid: ::c_long = 138; +pub const SYS_setfsgid: ::c_long = 139; +pub const SYS__llseek: ::c_long = 140; +pub const SYS_getdents: ::c_long = 141; +pub const SYS__newselect: ::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: ::c_long = 161; +pub const SYS_nanosleep: ::c_long = 162; +pub const SYS_mremap: ::c_long = 163; +pub const SYS_setresuid: ::c_long = 164; +pub const SYS_getresuid: ::c_long = 165; +pub const SYS_vm86: ::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_setresgid: ::c_long = 170; +pub const SYS_getresgid: ::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: ::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_chown: ::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_ugetrlimit: ::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_lchown32: ::c_long = 198; +pub const SYS_getuid32: ::c_long = 199; +pub const SYS_getgid32: ::c_long = 200; +pub const SYS_geteuid32: ::c_long = 201; +pub const SYS_getegid32: ::c_long = 202; +pub const SYS_setreuid32: ::c_long = 203; +pub const SYS_setregid32: ::c_long = 204; +pub const SYS_getgroups32: ::c_long = 205; +pub const SYS_setgroups32: ::c_long = 206; +pub const SYS_fchown32: ::c_long = 207; +pub const SYS_setresuid32: ::c_long = 208; +pub const SYS_getresuid32: ::c_long = 209; +pub const SYS_setresgid32: ::c_long = 210; +pub const SYS_getresgid32: ::c_long = 211; +pub const SYS_chown32: ::c_long = 212; +pub const SYS_setuid32: ::c_long = 213; +pub const SYS_setgid32: ::c_long = 214; +pub const SYS_setfsuid32: ::c_long = 215; +pub const SYS_setfsgid32: ::c_long = 216; +pub const SYS_pivot_root: ::c_long = 217; +pub const SYS_mincore: ::c_long = 218; +pub const SYS_madvise: ::c_long = 219; +pub const SYS_getdents64: ::c_long = 220; +pub const SYS_fcntl64: ::c_long = 221; +pub const SYS_gettid: ::c_long = 224; +pub const SYS_readahead: ::c_long = 225; +pub const SYS_setxattr: ::c_long = 226; +pub const SYS_lsetxattr: ::c_long = 227; +pub const SYS_fsetxattr: ::c_long = 228; +pub const SYS_getxattr: ::c_long = 229; +pub const SYS_lgetxattr: ::c_long = 230; +pub const SYS_fgetxattr: ::c_long = 231; +pub const SYS_listxattr: ::c_long = 232; +pub const SYS_llistxattr: ::c_long = 233; +pub const SYS_flistxattr: ::c_long = 234; +pub const SYS_removexattr: ::c_long = 235; +pub const SYS_lremovexattr: ::c_long = 236; +pub const SYS_fremovexattr: ::c_long = 237; +pub const SYS_tkill: ::c_long = 238; +pub const SYS_sendfile64: ::c_long = 239; +pub const SYS_futex: ::c_long = 240; +pub const SYS_sched_setaffinity: ::c_long = 241; +pub const SYS_sched_getaffinity: ::c_long = 242; +pub const SYS_set_thread_area: ::c_long = 243; +pub const SYS_get_thread_area: ::c_long = 244; +pub const SYS_io_setup: ::c_long = 245; +pub const SYS_io_destroy: ::c_long = 246; +pub const SYS_io_getevents: ::c_long = 247; +pub const SYS_io_submit: ::c_long = 248; +pub const SYS_io_cancel: ::c_long = 249; +pub const SYS_fadvise64: ::c_long = 250; +pub const SYS_exit_group: ::c_long = 252; +pub const SYS_lookup_dcookie: ::c_long = 253; +pub const SYS_epoll_create: ::c_long = 254; +pub const SYS_epoll_ctl: ::c_long = 255; +pub const SYS_epoll_wait: ::c_long = 256; +pub const SYS_remap_file_pages: ::c_long = 257; +pub const SYS_set_tid_address: ::c_long = 258; +pub const SYS_timer_create: ::c_long = 259; +pub const SYS_timer_settime: ::c_long = 260; +pub const SYS_timer_gettime: ::c_long = 261; +pub const SYS_timer_getoverrun: ::c_long = 262; +pub const SYS_timer_delete: ::c_long = 263; +pub const SYS_clock_settime: ::c_long = 264; +pub const SYS_clock_gettime: ::c_long = 265; +pub const SYS_clock_getres: ::c_long = 266; +pub const SYS_clock_nanosleep: ::c_long = 267; +pub const SYS_statfs64: ::c_long = 268; +pub const SYS_fstatfs64: ::c_long = 269; +pub const SYS_tgkill: ::c_long = 270; +pub const SYS_utimes: ::c_long = 271; +pub const SYS_fadvise64_64: ::c_long = 272; +pub const SYS_vserver: ::c_long = 273; +pub const SYS_mbind: ::c_long = 274; +pub const SYS_get_mempolicy: ::c_long = 275; +pub const SYS_set_mempolicy: ::c_long = 276; +pub const SYS_mq_open: ::c_long = 277; +pub const SYS_mq_unlink: ::c_long = 278; +pub const SYS_mq_timedsend: ::c_long = 279; +pub const SYS_mq_timedreceive: ::c_long = 280; +pub const SYS_mq_notify: ::c_long = 281; +pub const SYS_mq_getsetattr: ::c_long = 282; +pub const SYS_kexec_load: ::c_long = 283; +pub const SYS_waitid: ::c_long = 284; +pub const SYS_add_key: ::c_long = 286; +pub const SYS_request_key: ::c_long = 287; +pub const SYS_keyctl: ::c_long = 288; +pub const SYS_ioprio_set: ::c_long = 289; +pub const SYS_ioprio_get: ::c_long = 290; +pub const SYS_inotify_init: ::c_long = 291; +pub const SYS_inotify_add_watch: ::c_long = 292; +pub const SYS_inotify_rm_watch: ::c_long = 293; +pub const SYS_migrate_pages: ::c_long = 294; +pub const SYS_openat: ::c_long = 295; +pub const SYS_mkdirat: ::c_long = 296; +pub const SYS_mknodat: ::c_long = 297; +pub const SYS_fchownat: ::c_long = 298; +pub const SYS_futimesat: ::c_long = 299; +pub const SYS_fstatat64: ::c_long = 300; +pub const SYS_unlinkat: ::c_long = 301; +pub const SYS_renameat: ::c_long = 302; +pub const SYS_linkat: ::c_long = 303; +pub const SYS_symlinkat: ::c_long = 304; +pub const SYS_readlinkat: ::c_long = 305; +pub const SYS_fchmodat: ::c_long = 306; +pub const SYS_faccessat: ::c_long = 307; +pub const SYS_pselect6: ::c_long = 308; +pub const SYS_ppoll: ::c_long = 309; +pub const SYS_unshare: ::c_long = 310; +pub const SYS_set_robust_list: ::c_long = 311; +pub const SYS_get_robust_list: ::c_long = 312; +pub const SYS_splice: ::c_long = 313; +pub const SYS_sync_file_range: ::c_long = 314; +pub const SYS_tee: ::c_long = 315; +pub const SYS_vmsplice: ::c_long = 316; +pub const SYS_move_pages: ::c_long = 317; +pub const SYS_getcpu: ::c_long = 318; +pub const SYS_epoll_pwait: ::c_long = 319; +pub const SYS_utimensat: ::c_long = 320; +pub const SYS_signalfd: ::c_long = 321; +pub const SYS_timerfd_create: ::c_long = 322; +pub const SYS_eventfd: ::c_long = 323; +pub const SYS_fallocate: ::c_long = 324; +pub const SYS_timerfd_settime: ::c_long = 325; +pub const SYS_timerfd_gettime: ::c_long = 326; +pub const SYS_signalfd4: ::c_long = 327; +pub const SYS_eventfd2: ::c_long = 328; +pub const SYS_epoll_create1: ::c_long = 329; +pub const SYS_dup3: ::c_long = 330; +pub const SYS_pipe2: ::c_long = 331; +pub const SYS_inotify_init1: ::c_long = 332; +pub const SYS_preadv: ::c_long = 333; +pub const SYS_pwritev: ::c_long = 334; +pub const SYS_rt_tgsigqueueinfo: ::c_long = 335; +pub const SYS_perf_event_open: ::c_long = 336; +pub const SYS_recvmmsg: ::c_long = 337; +pub const SYS_fanotify_init: ::c_long = 338; +pub const SYS_fanotify_mark: ::c_long = 339; +pub const SYS_prlimit64: ::c_long = 340; +pub const SYS_name_to_handle_at: ::c_long = 341; +pub const SYS_open_by_handle_at: ::c_long = 342; +pub const SYS_clock_adjtime: ::c_long = 343; +pub const SYS_syncfs: ::c_long = 344; +pub const SYS_sendmmsg: ::c_long = 345; +pub const SYS_setns: ::c_long = 346; +pub const SYS_process_vm_readv: ::c_long = 347; +pub const SYS_process_vm_writev: ::c_long = 348; +pub const SYS_kcmp: ::c_long = 349; +pub const SYS_finit_module: ::c_long = 350; +pub const SYS_sched_setattr: ::c_long = 351; +pub const SYS_sched_getattr: ::c_long = 352; +pub const SYS_renameat2: ::c_long = 353; +pub const SYS_seccomp: ::c_long = 354; +pub const SYS_getrandom: ::c_long = 355; +pub const SYS_memfd_create: ::c_long = 356; +pub const SYS_bpf: ::c_long = 357; +pub const SYS_execveat: ::c_long = 358; +pub const SYS_socket: ::c_long = 359; +pub const SYS_socketpair: ::c_long = 360; +pub const SYS_bind: ::c_long = 361; +pub const SYS_connect: ::c_long = 362; +pub const SYS_listen: ::c_long = 363; +pub const SYS_accept4: ::c_long = 364; +pub const SYS_getsockopt: ::c_long = 365; +pub const SYS_setsockopt: ::c_long = 366; +pub const SYS_getsockname: ::c_long = 367; +pub const SYS_getpeername: ::c_long = 368; +pub const SYS_sendto: ::c_long = 369; +pub const SYS_sendmsg: ::c_long = 370; +pub const SYS_recvfrom: ::c_long = 371; +pub const SYS_recvmsg: ::c_long = 372; +pub const SYS_shutdown: ::c_long = 373; +pub const SYS_userfaultfd: ::c_long = 374; +pub const SYS_membarrier: ::c_long = 375; +pub const SYS_mlock2: ::c_long = 376; +pub const SYS_copy_file_range: ::c_long = 377; +pub const SYS_preadv2: ::c_long = 378; +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; +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; +pub const SYS_fchmodat2: ::c_long = 452; + +// offsets in user_regs_structs, from sys/reg.h +pub const EBX: ::c_int = 0; +pub const ECX: ::c_int = 1; +pub const EDX: ::c_int = 2; +pub const ESI: ::c_int = 3; +pub const EDI: ::c_int = 4; +pub const EBP: ::c_int = 5; +pub const EAX: ::c_int = 6; +pub const DS: ::c_int = 7; +pub const ES: ::c_int = 8; +pub const FS: ::c_int = 9; +pub const GS: ::c_int = 10; +pub const ORIG_EAX: ::c_int = 11; +pub const EIP: ::c_int = 12; +pub const CS: ::c_int = 13; +pub const EFL: ::c_int = 14; +pub const UESP: ::c_int = 15; +pub const SS: ::c_int = 16; + +extern "C" { + pub fn getrandom(buf: *mut ::c_void, buflen: ::size_t, flags: ::c_uint) -> ::ssize_t; +} + +cfg_if! { + if #[cfg(libc_align)] { + mod align; + pub use self::align::*; + } +} 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 new file mode 100644 index 0000000..a4bf9bf --- /dev/null +++ b/vendor/libc/src/unix/linux_like/linux/musl/b64/aarch64/align.rs @@ -0,0 +1,42 @@ +s_no_extra_traits! { + #[allow(missing_debug_implementations)] + #[repr(align(16))] + pub struct max_align_t { + priv_: [f32; 8] + } +} + +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 fault_address: ::c_ulong, + pub regs: [::c_ulong; 31], + pub sp: ::c_ulong, + pub pc: ::c_ulong, + 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 new file mode 100644 index 0000000..24e6b84 --- /dev/null +++ b/vendor/libc/src/unix/linux_like/linux/musl/b64/aarch64/mod.rs @@ -0,0 +1,659 @@ +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; + +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, + __pad0: ::c_ulong, + pub st_size: ::off_t, + pub st_blksize: ::blksize_t, + __pad1: ::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_uint; 2], + } + + 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_uid: ::uid_t, + pub st_gid: ::gid_t, + pub st_rdev: ::dev_t, + __pad0: ::c_ulong, + pub st_size: ::off_t, + pub st_blksize: ::blksize_t, + __pad1: ::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_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, + 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, + } +} + +pub const O_APPEND: ::c_int = 1024; +pub const O_DIRECT: ::c_int = 0x10000; +pub const O_DIRECTORY: ::c_int = 0x4000; +pub const O_LARGEFILE: ::c_int = 0x20000; +pub const O_NOFOLLOW: ::c_int = 0x8000; +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 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 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 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 ERFKILL: ::c_int = 132; +pub const EHWPOISON: ::c_int = 133; + +// bits/hwcap.h +pub const HWCAP_FP: ::c_ulong = 1 << 0; +pub const HWCAP_ASIMD: ::c_ulong = 1 << 1; +pub const HWCAP_EVTSTRM: ::c_ulong = 1 << 2; +pub const HWCAP_AES: ::c_ulong = 1 << 3; +pub const HWCAP_PMULL: ::c_ulong = 1 << 4; +pub const HWCAP_SHA1: ::c_ulong = 1 << 5; +pub const HWCAP_SHA2: ::c_ulong = 1 << 6; +pub const HWCAP_CRC32: ::c_ulong = 1 << 7; +pub const HWCAP_ATOMICS: ::c_ulong = 1 << 8; +pub const HWCAP_FPHP: ::c_ulong = 1 << 9; +pub const HWCAP_ASIMDHP: ::c_ulong = 1 << 10; +pub const HWCAP_CPUID: ::c_ulong = 1 << 11; +pub const HWCAP_ASIMDRDM: ::c_ulong = 1 << 12; +pub const HWCAP_JSCVT: ::c_ulong = 1 << 13; +pub const HWCAP_FCMA: ::c_ulong = 1 << 14; +pub const HWCAP_LRCPC: ::c_ulong = 1 << 15; +pub const HWCAP_DCPOP: ::c_ulong = 1 << 16; +pub const HWCAP_SHA3: ::c_ulong = 1 << 17; +pub const HWCAP_SM3: ::c_ulong = 1 << 18; +pub const HWCAP_SM4: ::c_ulong = 1 << 19; +pub const HWCAP_ASIMDDP: ::c_ulong = 1 << 20; +pub const HWCAP_SHA512: ::c_ulong = 1 << 21; +pub const HWCAP_SVE: ::c_ulong = 1 << 22; +pub const HWCAP_ASIMDFHM: ::c_ulong = 1 << 23; +pub const HWCAP_DIT: ::c_ulong = 1 << 24; +pub const HWCAP_USCAT: ::c_ulong = 1 << 25; +pub const HWCAP_ILRCPC: ::c_ulong = 1 << 26; +pub const HWCAP_FLAGM: ::c_ulong = 1 << 27; +pub const HWCAP_SSBS: ::c_ulong = 1 << 28; +pub const HWCAP_SB: ::c_ulong = 1 << 29; +pub const HWCAP_PACA: ::c_ulong = 1 << 30; +pub const HWCAP_PACG: ::c_ulong = 1 << 31; + +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 SOCK_STREAM: ::c_int = 1; +pub const SOCK_DGRAM: ::c_int = 2; + +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 VEOF: usize = 4; + +pub const POLLWRNORM: ::c_short = 0x100; +pub const POLLWRBAND: ::c_short = 0x200; + +pub const MINSIGSTKSZ: ::size_t = 6144; +pub const SIGSTKSZ: ::size_t = 12288; + +pub const MADV_SOFT_OFFLINE: ::c_int = 101; +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_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_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_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_newfstatat: ::c_long = 79; +pub const SYS_fstat: ::c_long = 80; +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_mmap: ::c_long = 222; +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_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_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; +pub const SYS_mseal: ::c_long = 462; + +pub const MCL_CURRENT: ::c_int = 0x0001; +pub const MCL_FUTURE: ::c_int = 0x0002; +pub const MCL_ONFAULT: ::c_int = 0x0004; +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; + +cfg_if! { + if #[cfg(libc_align)] { + mod align; + 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/loongarch64/align.rs b/vendor/libc/src/unix/linux_like/linux/musl/b64/loongarch64/align.rs new file mode 100644 index 0000000..dc191f5 --- /dev/null +++ b/vendor/libc/src/unix/linux_like/linux/musl/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 __pc: ::c_ulonglong, + pub __gregs: [::c_ulonglong; 32], + pub __flags: ::c_uint, + pub __extcontext: [::c_ulonglong; 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/musl/b64/loongarch64/mod.rs b/vendor/libc/src/unix/linux_like/linux/musl/b64/loongarch64/mod.rs new file mode 100644 index 0000000..59a824b --- /dev/null +++ b/vendor/libc/src/unix/linux_like/linux/musl/b64/loongarch64/mod.rs @@ -0,0 +1,669 @@ +//! LoongArch-specific definitions for 64-bit linux-like values + +pub type c_char = i8; +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, + __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; 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 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 user_regs_struct { + pub regs: [u64; 32], + pub orig_a0: u64, + pub csr_era: u64, + pub csr_badv: u64, + pub reserved: [u64; 10], + + } + + pub struct user_fp_struct { + pub fpr: [u64; 32], + pub fcc: u64, + pub fcsr: u32, + } +} + +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 SYS_cachestat: ::c_long = 451; +pub const SYS_fchmodat2: ::c_long = 452; +pub const SYS_map_shadow_stack: ::c_long = 453; +pub const SYS_futex_wake: ::c_long = 454; +pub const SYS_futex_wait: ::c_long = 455; +pub const SYS_futex_requeue: ::c_long = 456; + +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 = 4096; + +pub const SIGSTKSZ: ::size_t = 16384; +pub const MINSIGSTKSZ: ::size_t = 4096; + +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 = 0; +pub const SIG_UNBLOCK: ::c_int = 1; + +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 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 MCL_ONFAULT: ::c_int = 0x0004; +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; + +cfg_if! { + if #[cfg(libc_align)] { + mod align; + pub use self::align::*; + } +} 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 new file mode 100644 index 0000000..18fa6c6 --- /dev/null +++ b/vendor/libc/src/unix/linux_like/linux/musl/b64/mips64.rs @@ -0,0 +1,688 @@ +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; + +s! { + pub struct stat { + pub st_dev: ::dev_t, + __pad1: [::c_int; 3], + 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_uint; 2], + pub st_size: ::off_t, + __pad3: ::c_int, + 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_blksize: ::blksize_t, + __pad4: ::c_uint, + pub st_blocks: ::blkcnt_t, + __pad5: [::c_int; 14], + } + + pub struct stat64 { + pub st_dev: ::dev_t, + __pad1: [::c_int; 3], + 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_uint; 2], + pub st_size: ::off_t, + __pad3: ::c_int, + 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_blksize: ::blksize_t, + __pad4: ::c_uint, + pub st_blocks: ::blkcnt_t, + __pad5: [::c_int; 14], + } + + pub struct statfs { + 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; 5], + } + + 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; 5], + } + + 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_int, + __pad1: ::c_int, + __unused1: ::c_ulong, + __unused2: ::c_ulong + } +} + +pub const SIGSTKSZ: ::size_t = 8192; +pub const MINSIGSTKSZ: ::size_t = 2048; + +pub const SYS_read: ::c_long = 5000 + 0; +pub const SYS_write: ::c_long = 5000 + 1; +pub const SYS_open: ::c_long = 5000 + 2; +pub const SYS_close: ::c_long = 5000 + 3; +pub const SYS_stat: ::c_long = 5000 + 4; +pub const SYS_fstat: ::c_long = 5000 + 5; +pub const SYS_lstat: ::c_long = 5000 + 6; +pub const SYS_poll: ::c_long = 5000 + 7; +pub const SYS_lseek: ::c_long = 5000 + 8; +pub const SYS_mmap: ::c_long = 5000 + 9; +pub const SYS_mprotect: ::c_long = 5000 + 10; +pub const SYS_munmap: ::c_long = 5000 + 11; +pub const SYS_brk: ::c_long = 5000 + 12; +pub const SYS_rt_sigaction: ::c_long = 5000 + 13; +pub const SYS_rt_sigprocmask: ::c_long = 5000 + 14; +pub const SYS_ioctl: ::c_long = 5000 + 15; +pub const SYS_pread64: ::c_long = 5000 + 16; +pub const SYS_pwrite64: ::c_long = 5000 + 17; +pub const SYS_readv: ::c_long = 5000 + 18; +pub const SYS_writev: ::c_long = 5000 + 19; +pub const SYS_access: ::c_long = 5000 + 20; +pub const SYS_pipe: ::c_long = 5000 + 21; +pub const SYS__newselect: ::c_long = 5000 + 22; +pub const SYS_sched_yield: ::c_long = 5000 + 23; +pub const SYS_mremap: ::c_long = 5000 + 24; +pub const SYS_msync: ::c_long = 5000 + 25; +pub const SYS_mincore: ::c_long = 5000 + 26; +pub const SYS_madvise: ::c_long = 5000 + 27; +pub const SYS_shmget: ::c_long = 5000 + 28; +pub const SYS_shmat: ::c_long = 5000 + 29; +pub const SYS_shmctl: ::c_long = 5000 + 30; +pub const SYS_dup: ::c_long = 5000 + 31; +pub const SYS_dup2: ::c_long = 5000 + 32; +pub const SYS_pause: ::c_long = 5000 + 33; +pub const SYS_nanosleep: ::c_long = 5000 + 34; +pub const SYS_getitimer: ::c_long = 5000 + 35; +pub const SYS_setitimer: ::c_long = 5000 + 36; +pub const SYS_alarm: ::c_long = 5000 + 37; +pub const SYS_getpid: ::c_long = 5000 + 38; +pub const SYS_sendfile: ::c_long = 5000 + 39; +pub const SYS_socket: ::c_long = 5000 + 40; +pub const SYS_connect: ::c_long = 5000 + 41; +pub const SYS_accept: ::c_long = 5000 + 42; +pub const SYS_sendto: ::c_long = 5000 + 43; +pub const SYS_recvfrom: ::c_long = 5000 + 44; +pub const SYS_sendmsg: ::c_long = 5000 + 45; +pub const SYS_recvmsg: ::c_long = 5000 + 46; +pub const SYS_shutdown: ::c_long = 5000 + 47; +pub const SYS_bind: ::c_long = 5000 + 48; +pub const SYS_listen: ::c_long = 5000 + 49; +pub const SYS_getsockname: ::c_long = 5000 + 50; +pub const SYS_getpeername: ::c_long = 5000 + 51; +pub const SYS_socketpair: ::c_long = 5000 + 52; +pub const SYS_setsockopt: ::c_long = 5000 + 53; +pub const SYS_getsockopt: ::c_long = 5000 + 54; +pub const SYS_clone: ::c_long = 5000 + 55; +pub const SYS_fork: ::c_long = 5000 + 56; +pub const SYS_execve: ::c_long = 5000 + 57; +pub const SYS_exit: ::c_long = 5000 + 58; +pub const SYS_wait4: ::c_long = 5000 + 59; +pub const SYS_kill: ::c_long = 5000 + 60; +pub const SYS_uname: ::c_long = 5000 + 61; +pub const SYS_semget: ::c_long = 5000 + 62; +pub const SYS_semop: ::c_long = 5000 + 63; +pub const SYS_semctl: ::c_long = 5000 + 64; +pub const SYS_shmdt: ::c_long = 5000 + 65; +pub const SYS_msgget: ::c_long = 5000 + 66; +pub const SYS_msgsnd: ::c_long = 5000 + 67; +pub const SYS_msgrcv: ::c_long = 5000 + 68; +pub const SYS_msgctl: ::c_long = 5000 + 69; +pub const SYS_fcntl: ::c_long = 5000 + 70; +pub const SYS_flock: ::c_long = 5000 + 71; +pub const SYS_fsync: ::c_long = 5000 + 72; +pub const SYS_fdatasync: ::c_long = 5000 + 73; +pub const SYS_truncate: ::c_long = 5000 + 74; +pub const SYS_ftruncate: ::c_long = 5000 + 75; +pub const SYS_getdents: ::c_long = 5000 + 76; +pub const SYS_getcwd: ::c_long = 5000 + 77; +pub const SYS_chdir: ::c_long = 5000 + 78; +pub const SYS_fchdir: ::c_long = 5000 + 79; +pub const SYS_rename: ::c_long = 5000 + 80; +pub const SYS_mkdir: ::c_long = 5000 + 81; +pub const SYS_rmdir: ::c_long = 5000 + 82; +pub const SYS_creat: ::c_long = 5000 + 83; +pub const SYS_link: ::c_long = 5000 + 84; +pub const SYS_unlink: ::c_long = 5000 + 85; +pub const SYS_symlink: ::c_long = 5000 + 86; +pub const SYS_readlink: ::c_long = 5000 + 87; +pub const SYS_chmod: ::c_long = 5000 + 88; +pub const SYS_fchmod: ::c_long = 5000 + 89; +pub const SYS_chown: ::c_long = 5000 + 90; +pub const SYS_fchown: ::c_long = 5000 + 91; +pub const SYS_lchown: ::c_long = 5000 + 92; +pub const SYS_umask: ::c_long = 5000 + 93; +pub const SYS_gettimeofday: ::c_long = 5000 + 94; +pub const SYS_getrlimit: ::c_long = 5000 + 95; +pub const SYS_getrusage: ::c_long = 5000 + 96; +pub const SYS_sysinfo: ::c_long = 5000 + 97; +pub const SYS_times: ::c_long = 5000 + 98; +pub const SYS_ptrace: ::c_long = 5000 + 99; +pub const SYS_getuid: ::c_long = 5000 + 100; +pub const SYS_syslog: ::c_long = 5000 + 101; +pub const SYS_getgid: ::c_long = 5000 + 102; +pub const SYS_setuid: ::c_long = 5000 + 103; +pub const SYS_setgid: ::c_long = 5000 + 104; +pub const SYS_geteuid: ::c_long = 5000 + 105; +pub const SYS_getegid: ::c_long = 5000 + 106; +pub const SYS_setpgid: ::c_long = 5000 + 107; +pub const SYS_getppid: ::c_long = 5000 + 108; +pub const SYS_getpgrp: ::c_long = 5000 + 109; +pub const SYS_setsid: ::c_long = 5000 + 110; +pub const SYS_setreuid: ::c_long = 5000 + 111; +pub const SYS_setregid: ::c_long = 5000 + 112; +pub const SYS_getgroups: ::c_long = 5000 + 113; +pub const SYS_setgroups: ::c_long = 5000 + 114; +pub const SYS_setresuid: ::c_long = 5000 + 115; +pub const SYS_getresuid: ::c_long = 5000 + 116; +pub const SYS_setresgid: ::c_long = 5000 + 117; +pub const SYS_getresgid: ::c_long = 5000 + 118; +pub const SYS_getpgid: ::c_long = 5000 + 119; +pub const SYS_setfsuid: ::c_long = 5000 + 120; +pub const SYS_setfsgid: ::c_long = 5000 + 121; +pub const SYS_getsid: ::c_long = 5000 + 122; +pub const SYS_capget: ::c_long = 5000 + 123; +pub const SYS_capset: ::c_long = 5000 + 124; +pub const SYS_rt_sigpending: ::c_long = 5000 + 125; +pub const SYS_rt_sigtimedwait: ::c_long = 5000 + 126; +pub const SYS_rt_sigqueueinfo: ::c_long = 5000 + 127; +pub const SYS_rt_sigsuspend: ::c_long = 5000 + 128; +pub const SYS_sigaltstack: ::c_long = 5000 + 129; +pub const SYS_utime: ::c_long = 5000 + 130; +pub const SYS_mknod: ::c_long = 5000 + 131; +pub const SYS_personality: ::c_long = 5000 + 132; +pub const SYS_ustat: ::c_long = 5000 + 133; +pub const SYS_statfs: ::c_long = 5000 + 134; +pub const SYS_fstatfs: ::c_long = 5000 + 135; +pub const SYS_sysfs: ::c_long = 5000 + 136; +pub const SYS_getpriority: ::c_long = 5000 + 137; +pub const SYS_setpriority: ::c_long = 5000 + 138; +pub const SYS_sched_setparam: ::c_long = 5000 + 139; +pub const SYS_sched_getparam: ::c_long = 5000 + 140; +pub const SYS_sched_setscheduler: ::c_long = 5000 + 141; +pub const SYS_sched_getscheduler: ::c_long = 5000 + 142; +pub const SYS_sched_get_priority_max: ::c_long = 5000 + 143; +pub const SYS_sched_get_priority_min: ::c_long = 5000 + 144; +pub const SYS_sched_rr_get_interval: ::c_long = 5000 + 145; +pub const SYS_mlock: ::c_long = 5000 + 146; +pub const SYS_munlock: ::c_long = 5000 + 147; +pub const SYS_mlockall: ::c_long = 5000 + 148; +pub const SYS_munlockall: ::c_long = 5000 + 149; +pub const SYS_vhangup: ::c_long = 5000 + 150; +pub const SYS_pivot_root: ::c_long = 5000 + 151; +pub const SYS__sysctl: ::c_long = 5000 + 152; +pub const SYS_prctl: ::c_long = 5000 + 153; +pub const SYS_adjtimex: ::c_long = 5000 + 154; +pub const SYS_setrlimit: ::c_long = 5000 + 155; +pub const SYS_chroot: ::c_long = 5000 + 156; +pub const SYS_sync: ::c_long = 5000 + 157; +pub const SYS_acct: ::c_long = 5000 + 158; +pub const SYS_settimeofday: ::c_long = 5000 + 159; +pub const SYS_mount: ::c_long = 5000 + 160; +pub const SYS_umount2: ::c_long = 5000 + 161; +pub const SYS_swapon: ::c_long = 5000 + 162; +pub const SYS_swapoff: ::c_long = 5000 + 163; +pub const SYS_reboot: ::c_long = 5000 + 164; +pub const SYS_sethostname: ::c_long = 5000 + 165; +pub const SYS_setdomainname: ::c_long = 5000 + 166; +pub const SYS_create_module: ::c_long = 5000 + 167; +pub const SYS_init_module: ::c_long = 5000 + 168; +pub const SYS_delete_module: ::c_long = 5000 + 169; +pub const SYS_get_kernel_syms: ::c_long = 5000 + 170; +pub const SYS_query_module: ::c_long = 5000 + 171; +pub const SYS_quotactl: ::c_long = 5000 + 172; +pub const SYS_nfsservctl: ::c_long = 5000 + 173; +pub const SYS_getpmsg: ::c_long = 5000 + 174; +pub const SYS_putpmsg: ::c_long = 5000 + 175; +pub const SYS_afs_syscall: ::c_long = 5000 + 176; +pub const SYS_gettid: ::c_long = 5000 + 178; +pub const SYS_readahead: ::c_long = 5000 + 179; +pub const SYS_setxattr: ::c_long = 5000 + 180; +pub const SYS_lsetxattr: ::c_long = 5000 + 181; +pub const SYS_fsetxattr: ::c_long = 5000 + 182; +pub const SYS_getxattr: ::c_long = 5000 + 183; +pub const SYS_lgetxattr: ::c_long = 5000 + 184; +pub const SYS_fgetxattr: ::c_long = 5000 + 185; +pub const SYS_listxattr: ::c_long = 5000 + 186; +pub const SYS_llistxattr: ::c_long = 5000 + 187; +pub const SYS_flistxattr: ::c_long = 5000 + 188; +pub const SYS_removexattr: ::c_long = 5000 + 189; +pub const SYS_lremovexattr: ::c_long = 5000 + 190; +pub const SYS_fremovexattr: ::c_long = 5000 + 191; +pub const SYS_tkill: ::c_long = 5000 + 192; +pub const SYS_futex: ::c_long = 5000 + 194; +pub const SYS_sched_setaffinity: ::c_long = 5000 + 195; +pub const SYS_sched_getaffinity: ::c_long = 5000 + 196; +pub const SYS_cacheflush: ::c_long = 5000 + 197; +pub const SYS_cachectl: ::c_long = 5000 + 198; +pub const SYS_sysmips: ::c_long = 5000 + 199; +pub const SYS_io_setup: ::c_long = 5000 + 200; +pub const SYS_io_destroy: ::c_long = 5000 + 201; +pub const SYS_io_getevents: ::c_long = 5000 + 202; +pub const SYS_io_submit: ::c_long = 5000 + 203; +pub const SYS_io_cancel: ::c_long = 5000 + 204; +pub const SYS_exit_group: ::c_long = 5000 + 205; +pub const SYS_lookup_dcookie: ::c_long = 5000 + 206; +pub const SYS_epoll_create: ::c_long = 5000 + 207; +pub const SYS_epoll_ctl: ::c_long = 5000 + 208; +pub const SYS_epoll_wait: ::c_long = 5000 + 209; +pub const SYS_remap_file_pages: ::c_long = 5000 + 210; +pub const SYS_rt_sigreturn: ::c_long = 5000 + 211; +pub const SYS_set_tid_address: ::c_long = 5000 + 212; +pub const SYS_restart_syscall: ::c_long = 5000 + 213; +pub const SYS_semtimedop: ::c_long = 5000 + 214; +pub const SYS_fadvise64: ::c_long = 5000 + 215; +pub const SYS_timer_create: ::c_long = 5000 + 216; +pub const SYS_timer_settime: ::c_long = 5000 + 217; +pub const SYS_timer_gettime: ::c_long = 5000 + 218; +pub const SYS_timer_getoverrun: ::c_long = 5000 + 219; +pub const SYS_timer_delete: ::c_long = 5000 + 220; +pub const SYS_clock_settime: ::c_long = 5000 + 221; +pub const SYS_clock_gettime: ::c_long = 5000 + 222; +pub const SYS_clock_getres: ::c_long = 5000 + 223; +pub const SYS_clock_nanosleep: ::c_long = 5000 + 224; +pub const SYS_tgkill: ::c_long = 5000 + 225; +pub const SYS_utimes: ::c_long = 5000 + 226; +pub const SYS_mbind: ::c_long = 5000 + 227; +pub const SYS_get_mempolicy: ::c_long = 5000 + 228; +pub const SYS_set_mempolicy: ::c_long = 5000 + 229; +pub const SYS_mq_open: ::c_long = 5000 + 230; +pub const SYS_mq_unlink: ::c_long = 5000 + 231; +pub const SYS_mq_timedsend: ::c_long = 5000 + 232; +pub const SYS_mq_timedreceive: ::c_long = 5000 + 233; +pub const SYS_mq_notify: ::c_long = 5000 + 234; +pub const SYS_mq_getsetattr: ::c_long = 5000 + 235; +pub const SYS_vserver: ::c_long = 5000 + 236; +pub const SYS_waitid: ::c_long = 5000 + 237; +/* pub const SYS_sys_setaltroot: ::c_long = 5000 + 238; */ +pub const SYS_add_key: ::c_long = 5000 + 239; +pub const SYS_request_key: ::c_long = 5000 + 240; +pub const SYS_keyctl: ::c_long = 5000 + 241; +pub const SYS_set_thread_area: ::c_long = 5000 + 242; +pub const SYS_inotify_init: ::c_long = 5000 + 243; +pub const SYS_inotify_add_watch: ::c_long = 5000 + 244; +pub const SYS_inotify_rm_watch: ::c_long = 5000 + 245; +pub const SYS_migrate_pages: ::c_long = 5000 + 246; +pub const SYS_openat: ::c_long = 5000 + 247; +pub const SYS_mkdirat: ::c_long = 5000 + 248; +pub const SYS_mknodat: ::c_long = 5000 + 249; +pub const SYS_fchownat: ::c_long = 5000 + 250; +pub const SYS_futimesat: ::c_long = 5000 + 251; +pub const SYS_newfstatat: ::c_long = 5000 + 252; +pub const SYS_unlinkat: ::c_long = 5000 + 253; +pub const SYS_renameat: ::c_long = 5000 + 254; +pub const SYS_linkat: ::c_long = 5000 + 255; +pub const SYS_symlinkat: ::c_long = 5000 + 256; +pub const SYS_readlinkat: ::c_long = 5000 + 257; +pub const SYS_fchmodat: ::c_long = 5000 + 258; +pub const SYS_faccessat: ::c_long = 5000 + 259; +pub const SYS_pselect6: ::c_long = 5000 + 260; +pub const SYS_ppoll: ::c_long = 5000 + 261; +pub const SYS_unshare: ::c_long = 5000 + 262; +pub const SYS_splice: ::c_long = 5000 + 263; +pub const SYS_sync_file_range: ::c_long = 5000 + 264; +pub const SYS_tee: ::c_long = 5000 + 265; +pub const SYS_vmsplice: ::c_long = 5000 + 266; +pub const SYS_move_pages: ::c_long = 5000 + 267; +pub const SYS_set_robust_list: ::c_long = 5000 + 268; +pub const SYS_get_robust_list: ::c_long = 5000 + 269; +pub const SYS_kexec_load: ::c_long = 5000 + 270; +pub const SYS_getcpu: ::c_long = 5000 + 271; +pub const SYS_epoll_pwait: ::c_long = 5000 + 272; +pub const SYS_ioprio_set: ::c_long = 5000 + 273; +pub const SYS_ioprio_get: ::c_long = 5000 + 274; +pub const SYS_utimensat: ::c_long = 5000 + 275; +pub const SYS_signalfd: ::c_long = 5000 + 276; +pub const SYS_timerfd: ::c_long = 5000 + 277; +pub const SYS_eventfd: ::c_long = 5000 + 278; +pub const SYS_fallocate: ::c_long = 5000 + 279; +pub const SYS_timerfd_create: ::c_long = 5000 + 280; +pub const SYS_timerfd_gettime: ::c_long = 5000 + 281; +pub const SYS_timerfd_settime: ::c_long = 5000 + 282; +pub const SYS_signalfd4: ::c_long = 5000 + 283; +pub const SYS_eventfd2: ::c_long = 5000 + 284; +pub const SYS_epoll_create1: ::c_long = 5000 + 285; +pub const SYS_dup3: ::c_long = 5000 + 286; +pub const SYS_pipe2: ::c_long = 5000 + 287; +pub const SYS_inotify_init1: ::c_long = 5000 + 288; +pub const SYS_preadv: ::c_long = 5000 + 289; +pub const SYS_pwritev: ::c_long = 5000 + 290; +pub const SYS_rt_tgsigqueueinfo: ::c_long = 5000 + 291; +pub const SYS_perf_event_open: ::c_long = 5000 + 292; +pub const SYS_accept4: ::c_long = 5000 + 293; +pub const SYS_recvmmsg: ::c_long = 5000 + 294; +pub const SYS_fanotify_init: ::c_long = 5000 + 295; +pub const SYS_fanotify_mark: ::c_long = 5000 + 296; +pub const SYS_prlimit64: ::c_long = 5000 + 297; +pub const SYS_name_to_handle_at: ::c_long = 5000 + 298; +pub const SYS_open_by_handle_at: ::c_long = 5000 + 299; +pub const SYS_clock_adjtime: ::c_long = 5000 + 300; +pub const SYS_syncfs: ::c_long = 5000 + 301; +pub const SYS_sendmmsg: ::c_long = 5000 + 302; +pub const SYS_setns: ::c_long = 5000 + 303; +pub const SYS_process_vm_readv: ::c_long = 5000 + 304; +pub const SYS_process_vm_writev: ::c_long = 5000 + 305; +pub const SYS_kcmp: ::c_long = 5000 + 306; +pub const SYS_finit_module: ::c_long = 5000 + 307; +pub const SYS_getdents64: ::c_long = 5000 + 308; +pub const SYS_sched_setattr: ::c_long = 5000 + 309; +pub const SYS_sched_getattr: ::c_long = 5000 + 310; +pub const SYS_renameat2: ::c_long = 5000 + 311; +pub const SYS_seccomp: ::c_long = 5000 + 312; +pub const SYS_getrandom: ::c_long = 5000 + 313; +pub const SYS_memfd_create: ::c_long = 5000 + 314; +pub const SYS_bpf: ::c_long = 5000 + 315; +pub const SYS_execveat: ::c_long = 5000 + 316; +pub const SYS_userfaultfd: ::c_long = 5000 + 317; +pub const SYS_membarrier: ::c_long = 5000 + 318; +pub const SYS_mlock2: ::c_long = 5000 + 319; +pub const SYS_copy_file_range: ::c_long = 5000 + 320; +pub const SYS_preadv2: ::c_long = 5000 + 321; +pub const SYS_pwritev2: ::c_long = 5000 + 322; +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_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; +pub const SYS_io_uring_register: ::c_long = 5000 + 427; +pub const SYS_open_tree: ::c_long = 5000 + 428; +pub const SYS_move_mount: ::c_long = 5000 + 429; +pub const SYS_fsopen: ::c_long = 5000 + 430; +pub const SYS_fsconfig: ::c_long = 5000 + 431; +pub const SYS_fsmount: ::c_long = 5000 + 432; +pub const SYS_fspick: ::c_long = 5000 + 433; +pub const SYS_pidfd_open: ::c_long = 5000 + 434; +pub const SYS_clone3: ::c_long = 5000 + 435; +pub const SYS_close_range: ::c_long = 5000 + 436; +pub const SYS_openat2: ::c_long = 5000 + 437; +pub const SYS_pidfd_getfd: ::c_long = 5000 + 438; +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; +pub const O_NOFOLLOW: ::c_int = 0x20000; + +pub const O_APPEND: ::c_int = 8; +pub const O_CREAT: ::c_int = 256; +pub const O_EXCL: ::c_int = 1024; +pub const O_NOCTTY: ::c_int = 2048; +pub const O_NONBLOCK: ::c_int = 128; +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; +pub const ENOLCK: ::c_int = 46; +pub const ENOSYS: ::c_int = 89; +pub const ENOTEMPTY: ::c_int = 93; +pub const ELOOP: ::c_int = 90; +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 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 EMULTIHOP: ::c_int = 74; +pub const EOVERFLOW: ::c_int = 79; +pub const ENOTUNIQ: ::c_int = 80; +pub const EBADFD: ::c_int = 81; +pub const EBADMSG: ::c_int = 77; +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 ERESTART: ::c_int = 91; +pub const ESTRPIPE: ::c_int = 92; +pub const EUSERS: ::c_int = 94; +pub const ENOTSOCK: ::c_int = 95; +pub const EDESTADDRREQ: ::c_int = 96; +pub const EMSGSIZE: ::c_int = 97; +pub const EPROTOTYPE: ::c_int = 98; +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; +pub const EADDRNOTAVAIL: ::c_int = 126; +pub const ENETDOWN: ::c_int = 127; +pub const ENETUNREACH: ::c_int = 128; +pub const ENETRESET: ::c_int = 129; +pub const ECONNABORTED: ::c_int = 130; +pub const ECONNRESET: ::c_int = 131; +pub const ENOBUFS: ::c_int = 132; +pub const EISCONN: ::c_int = 133; +pub const ENOTCONN: ::c_int = 134; +pub const ESHUTDOWN: ::c_int = 143; +pub const ETOOMANYREFS: ::c_int = 144; +pub const ETIMEDOUT: ::c_int = 145; +pub const ECONNREFUSED: ::c_int = 146; +pub const EHOSTDOWN: ::c_int = 147; +pub const EHOSTUNREACH: ::c_int = 148; +pub const EALREADY: ::c_int = 149; +pub const EINPROGRESS: ::c_int = 150; +pub const ESTALE: ::c_int = 151; +pub const EUCLEAN: ::c_int = 135; +pub const ENOTNAM: ::c_int = 137; +pub const ENAVAIL: ::c_int = 138; +pub const EISNAM: ::c_int = 139; +pub const EREMOTEIO: ::c_int = 140; +pub const EDQUOT: ::c_int = 1133; +pub const ENOMEDIUM: ::c_int = 159; +pub const EMEDIUMTYPE: ::c_int = 160; +pub const ECANCELED: ::c_int = 158; +pub const ENOKEY: ::c_int = 161; +pub const EKEYEXPIRED: ::c_int = 162; +pub const EKEYREVOKED: ::c_int = 163; +pub const EKEYREJECTED: ::c_int = 164; +pub const EOWNERDEAD: ::c_int = 165; +pub const ENOTRECOVERABLE: ::c_int = 166; +pub const ERFKILL: ::c_int = 167; + +pub const MAP_ANON: ::c_int = 0x800; +pub const MAP_GROWSDOWN: ::c_int = 0x1000; +pub const MAP_DENYWRITE: ::c_int = 0x2000; +pub const MAP_EXECUTABLE: ::c_int = 0x4000; +pub const MAP_LOCKED: ::c_int = 0x8000; +pub const MAP_NORESERVE: ::c_int = 0x400; +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 = 0x080000; + +pub const SOCK_STREAM: ::c_int = 2; +pub const SOCK_DGRAM: ::c_int = 1; + +pub const SA_ONSTACK: ::c_int = 0x08000000; +pub const SA_SIGINFO: ::c_int = 0x00000008; +pub const SA_NOCLDWAIT: ::c_int = 0x00010000; + +pub const SIGCHLD: ::c_int = 18; +pub const SIGBUS: ::c_int = 10; +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 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 = 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; +pub const SIG_UNBLOCK: ::c_int = 0x2; + +pub const POLLWRNORM: ::c_short = 0x004; +pub const POLLWRBAND: ::c_short = 0x100; + +pub const VEOF: usize = 16; +pub const VEOL: usize = 17; +pub const VEOL2: usize = 6; +pub const VMIN: usize = 4; +pub const IEXTEN: ::tcflag_t = 0x00000100; +pub const TOSTOP: ::tcflag_t = 0x00008000; +pub const FLUSHO: ::tcflag_t = 0x00002000; +pub const EXTPROC: ::tcflag_t = 0o200000; + +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 MCL_CURRENT: ::c_int = 0x0001; +pub const MCL_FUTURE: ::c_int = 0x0002; +pub const MCL_ONFAULT: ::c_int = 0x0004; + +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 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 EHWPOISON: ::c_int = 168; 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 new file mode 100644 index 0000000..d593430 --- /dev/null +++ b/vendor/libc/src/unix/linux_like/linux/musl/b64/mod.rs @@ -0,0 +1,166 @@ +pub type c_long = i64; +pub type c_ulong = u64; +pub type regoff_t = ::c_long; + +s! { + 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, + pub f_flag: ::c_ulong, + pub f_namemax: ::c_ulong, + __f_spare: [::c_int; 6], + } + + pub struct stack_t { + pub ss_sp: *mut ::c_void, + pub ss_flags: ::c_int, + pub ss_size: ::size_t + } + + pub struct pthread_attr_t { + __size: [u64; 7] + } + + pub struct sigset_t { + __val: [::c_ulong; 16], + } + + 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: ::c_ulong, + __pad1: ::c_ulong, + __pad2: ::c_ulong, + } + + pub struct msqid_ds { + pub msg_perm: ::ipc_perm, + pub msg_stime: ::time_t, + pub msg_rtime: ::time_t, + pub msg_ctime: ::time_t, + __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 statfs { + 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 msghdr { + pub msg_name: *mut ::c_void, + pub msg_namelen: ::socklen_t, + pub msg_iov: *mut ::iovec, + #[cfg(target_endian = "big")] + __pad1: ::c_int, + pub msg_iovlen: ::c_int, + #[cfg(target_endian = "little")] + __pad1: ::c_int, + pub msg_control: *mut ::c_void, + #[cfg(target_endian = "big")] + __pad2: ::c_int, + pub msg_controllen: ::socklen_t, + #[cfg(target_endian = "little")] + __pad2: ::c_int, + pub msg_flags: ::c_int, + } + + pub struct cmsghdr { + #[cfg(target_endian = "big")] + pub __pad1: ::c_int, + pub cmsg_len: ::socklen_t, + #[cfg(target_endian = "little")] + pub __pad1: ::c_int, + pub cmsg_level: ::c_int, + pub cmsg_type: ::c_int, + } + + pub struct sem_t { + __val: [::c_int; 8], + } + + pub struct siginfo_t { + pub si_signo: ::c_int, + pub si_errno: ::c_int, + pub si_code: ::c_int, + pub _pad: [::c_int; 29], + _align: [usize; 0], + } +} + +pub const __SIZEOF_PTHREAD_RWLOCK_T: usize = 56; +pub const __SIZEOF_PTHREAD_MUTEX_T: usize = 40; +pub const __SIZEOF_PTHREAD_BARRIER_T: usize = 32; + +extern "C" { + pub fn getrandom(buf: *mut ::c_void, buflen: ::size_t, flags: ::c_uint) -> ::ssize_t; +} + +cfg_if! { + if #[cfg(target_arch = "aarch64")] { + mod aarch64; + pub use self::aarch64::*; + } else if #[cfg(target_arch = "mips64")] { + mod mips64; + pub use self::mips64::*; + } else if #[cfg(any(target_arch = "powerpc64"))] { + mod powerpc64; + pub use self::powerpc64::*; + } else if #[cfg(any(target_arch = "s390x"))] { + mod s390x; + pub use self::s390x::*; + } 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 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/musl/b64/powerpc64.rs b/vendor/libc/src/unix/linux_like/linux/musl/b64/powerpc64.rs new file mode 100644 index 0000000..202abe8 --- /dev/null +++ b/vendor/libc/src/unix/linux_like/linux/musl/b64/powerpc64.rs @@ -0,0 +1,695 @@ +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; + +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], + } + + pub struct stat64 { + pub st_dev: ::dev_t, + pub st_ino: ::ino64_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: ::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, + __reserved: [::c_long; 3], + } + + 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_int, + __unused1: ::c_long, + __unused2: ::c_long + } +} + +pub const MADV_SOFT_OFFLINE: ::c_int = 101; +pub const MAP_32BIT: ::c_int = 0x0040; +pub const O_APPEND: ::c_int = 1024; +pub const O_DIRECT: ::c_int = 0x20000; +pub const O_DIRECTORY: ::c_int = 0x4000; +pub const O_LARGEFILE: ::c_int = 0x10000; +pub const O_NOFOLLOW: ::c_int = 0x8000; +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 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 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 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 ERFKILL: ::c_int = 132; +pub const EHWPOISON: ::c_int = 133; + +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 PTRACE_SYSEMU: ::c_int = 0x1d; +pub const PTRACE_SYSEMU_SINGLESTEP: ::c_int = 0x1e; + +pub const SOCK_STREAM: ::c_int = 1; +pub const SOCK_DGRAM: ::c_int = 2; + +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 VEOF: usize = 4; + +pub const POLLWRNORM: ::c_short = 0x100; +pub const POLLWRBAND: ::c_short = 0x200; + +pub const SIGSTKSZ: ::size_t = 10240; +pub const MINSIGSTKSZ: ::size_t = 4096; + +// Syscall table +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_time: ::c_long = 13; +pub const SYS_mknod: ::c_long = 14; +pub const SYS_chmod: ::c_long = 15; +pub const SYS_lchown: ::c_long = 16; +pub const SYS_break: ::c_long = 17; +pub const SYS_oldstat: ::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_umount: ::c_long = 22; +pub const SYS_setuid: ::c_long = 23; +pub const SYS_getuid: ::c_long = 24; +pub const SYS_stime: ::c_long = 25; +pub const SYS_ptrace: ::c_long = 26; +pub const SYS_alarm: ::c_long = 27; +pub const SYS_oldfstat: ::c_long = 28; +pub const SYS_pause: ::c_long = 29; +pub const SYS_utime: ::c_long = 30; +pub const SYS_stty: ::c_long = 31; +pub const SYS_gtty: ::c_long = 32; +pub const SYS_access: ::c_long = 33; +pub const SYS_nice: ::c_long = 34; +pub const SYS_ftime: ::c_long = 35; +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_prof: ::c_long = 44; +pub const SYS_brk: ::c_long = 45; +pub const SYS_setgid: ::c_long = 46; +pub const SYS_getgid: ::c_long = 47; +pub const SYS_signal: ::c_long = 48; +pub const SYS_geteuid: ::c_long = 49; +pub const SYS_getegid: ::c_long = 50; +pub const SYS_acct: ::c_long = 51; +pub const SYS_umount2: ::c_long = 52; +pub const SYS_lock: ::c_long = 53; +pub const SYS_ioctl: ::c_long = 54; +pub const SYS_fcntl: ::c_long = 55; +pub const SYS_mpx: ::c_long = 56; +pub const SYS_setpgid: ::c_long = 57; +pub const SYS_ulimit: ::c_long = 58; +pub const SYS_oldolduname: ::c_long = 59; +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_setreuid: ::c_long = 70; +pub const SYS_setregid: ::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_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_getgroups: ::c_long = 80; +pub const SYS_setgroups: ::c_long = 81; +pub const SYS_select: ::c_long = 82; +pub const SYS_symlink: ::c_long = 83; +pub const SYS_oldlstat: ::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_readdir: ::c_long = 89; +pub const SYS_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_fchown: ::c_long = 95; +pub const SYS_getpriority: ::c_long = 96; +pub const SYS_setpriority: ::c_long = 97; +pub const SYS_profil: ::c_long = 98; +pub const SYS_statfs: ::c_long = 99; +pub const SYS_fstatfs: ::c_long = 100; +pub const SYS_ioperm: ::c_long = 101; +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_stat: ::c_long = 106; +pub const SYS_lstat: ::c_long = 107; +pub const SYS_fstat: ::c_long = 108; +pub const SYS_olduname: ::c_long = 109; +pub const SYS_iopl: ::c_long = 110; +pub const SYS_vhangup: ::c_long = 111; +pub const SYS_idle: ::c_long = 112; +pub const SYS_vm86: ::c_long = 113; +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_uname: ::c_long = 122; +pub const SYS_modify_ldt: ::c_long = 123; +pub const SYS_adjtimex: ::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_afs_syscall: ::c_long = 137; /* Syscall for Andrew File System */ +pub const SYS_setfsuid: ::c_long = 138; +pub const SYS_setfsgid: ::c_long = 139; +pub const SYS__llseek: ::c_long = 140; +pub const SYS_getdents: ::c_long = 141; +pub const SYS__newselect: ::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: ::c_long = 161; +pub const SYS_nanosleep: ::c_long = 162; +pub const SYS_mremap: ::c_long = 163; +pub const SYS_setresuid: ::c_long = 164; +pub const SYS_getresuid: ::c_long = 165; +pub const SYS_query_module: ::c_long = 166; +pub const SYS_poll: ::c_long = 167; +pub const SYS_nfsservctl: ::c_long = 168; +pub const SYS_setresgid: ::c_long = 169; +pub const SYS_getresgid: ::c_long = 170; +pub const SYS_prctl: ::c_long = 171; +pub const SYS_rt_sigreturn: ::c_long = 172; +pub const SYS_rt_sigaction: ::c_long = 173; +pub const SYS_rt_sigprocmask: ::c_long = 174; +pub const SYS_rt_sigpending: ::c_long = 175; +pub const SYS_rt_sigtimedwait: ::c_long = 176; +pub const SYS_rt_sigqueueinfo: ::c_long = 177; +pub const SYS_rt_sigsuspend: ::c_long = 178; +pub const SYS_pread64: ::c_long = 179; +pub const SYS_pwrite64: ::c_long = 180; +pub const SYS_chown: ::c_long = 181; +pub const SYS_getcwd: ::c_long = 182; +pub const SYS_capget: ::c_long = 183; +pub const SYS_capset: ::c_long = 184; +pub const SYS_sigaltstack: ::c_long = 185; +pub const SYS_sendfile: ::c_long = 186; +pub const SYS_getpmsg: ::c_long = 187; /* some people actually want streams */ +pub const SYS_putpmsg: ::c_long = 188; /* some people actually want streams */ +pub const SYS_vfork: ::c_long = 189; +pub const SYS_ugetrlimit: ::c_long = 190; /* SuS compliant getrlimit */ +pub const SYS_readahead: ::c_long = 191; +pub const SYS_pciconfig_read: ::c_long = 198; +pub const SYS_pciconfig_write: ::c_long = 199; +pub const SYS_pciconfig_iobase: ::c_long = 200; +pub const SYS_multiplexer: ::c_long = 201; +pub const SYS_getdents64: ::c_long = 202; +pub const SYS_pivot_root: ::c_long = 203; +pub const SYS_madvise: ::c_long = 205; +pub const SYS_mincore: ::c_long = 206; +pub const SYS_gettid: ::c_long = 207; +pub const SYS_tkill: ::c_long = 208; +pub const SYS_setxattr: ::c_long = 209; +pub const SYS_lsetxattr: ::c_long = 210; +pub const SYS_fsetxattr: ::c_long = 211; +pub const SYS_getxattr: ::c_long = 212; +pub const SYS_lgetxattr: ::c_long = 213; +pub const SYS_fgetxattr: ::c_long = 214; +pub const SYS_listxattr: ::c_long = 215; +pub const SYS_llistxattr: ::c_long = 216; +pub const SYS_flistxattr: ::c_long = 217; +pub const SYS_removexattr: ::c_long = 218; +pub const SYS_lremovexattr: ::c_long = 219; +pub const SYS_fremovexattr: ::c_long = 220; +pub const SYS_futex: ::c_long = 221; +pub const SYS_sched_setaffinity: ::c_long = 222; +pub const SYS_sched_getaffinity: ::c_long = 223; +pub const SYS_tuxcall: ::c_long = 225; +pub const SYS_io_setup: ::c_long = 227; +pub const SYS_io_destroy: ::c_long = 228; +pub const SYS_io_getevents: ::c_long = 229; +pub const SYS_io_submit: ::c_long = 230; +pub const SYS_io_cancel: ::c_long = 231; +pub const SYS_set_tid_address: ::c_long = 232; +pub const SYS_exit_group: ::c_long = 234; +pub const SYS_lookup_dcookie: ::c_long = 235; +pub const SYS_epoll_create: ::c_long = 236; +pub const SYS_epoll_ctl: ::c_long = 237; +pub const SYS_epoll_wait: ::c_long = 238; +pub const SYS_remap_file_pages: ::c_long = 239; +pub const SYS_timer_create: ::c_long = 240; +pub const SYS_timer_settime: ::c_long = 241; +pub const SYS_timer_gettime: ::c_long = 242; +pub const SYS_timer_getoverrun: ::c_long = 243; +pub const SYS_timer_delete: ::c_long = 244; +pub const SYS_clock_settime: ::c_long = 245; +pub const SYS_clock_gettime: ::c_long = 246; +pub const SYS_clock_getres: ::c_long = 247; +pub const SYS_clock_nanosleep: ::c_long = 248; +pub const SYS_swapcontext: ::c_long = 249; +pub const SYS_tgkill: ::c_long = 250; +pub const SYS_utimes: ::c_long = 251; +pub const SYS_statfs64: ::c_long = 252; +pub const SYS_fstatfs64: ::c_long = 253; +pub const SYS_rtas: ::c_long = 255; +pub const SYS_sys_debug_setcontext: ::c_long = 256; +pub const SYS_migrate_pages: ::c_long = 258; +pub const SYS_mbind: ::c_long = 259; +pub const SYS_get_mempolicy: ::c_long = 260; +pub const SYS_set_mempolicy: ::c_long = 261; +pub const SYS_mq_open: ::c_long = 262; +pub const SYS_mq_unlink: ::c_long = 263; +pub const SYS_mq_timedsend: ::c_long = 264; +pub const SYS_mq_timedreceive: ::c_long = 265; +pub const SYS_mq_notify: ::c_long = 266; +pub const SYS_mq_getsetattr: ::c_long = 267; +pub const SYS_kexec_load: ::c_long = 268; +pub const SYS_add_key: ::c_long = 269; +pub const SYS_request_key: ::c_long = 270; +pub const SYS_keyctl: ::c_long = 271; +pub const SYS_waitid: ::c_long = 272; +pub const SYS_ioprio_set: ::c_long = 273; +pub const SYS_ioprio_get: ::c_long = 274; +pub const SYS_inotify_init: ::c_long = 275; +pub const SYS_inotify_add_watch: ::c_long = 276; +pub const SYS_inotify_rm_watch: ::c_long = 277; +pub const SYS_spu_run: ::c_long = 278; +pub const SYS_spu_create: ::c_long = 279; +pub const SYS_pselect6: ::c_long = 280; +pub const SYS_ppoll: ::c_long = 281; +pub const SYS_unshare: ::c_long = 282; +pub const SYS_splice: ::c_long = 283; +pub const SYS_tee: ::c_long = 284; +pub const SYS_vmsplice: ::c_long = 285; +pub const SYS_openat: ::c_long = 286; +pub const SYS_mkdirat: ::c_long = 287; +pub const SYS_mknodat: ::c_long = 288; +pub const SYS_fchownat: ::c_long = 289; +pub const SYS_futimesat: ::c_long = 290; +pub const SYS_newfstatat: ::c_long = 291; +pub const SYS_unlinkat: ::c_long = 292; +pub const SYS_renameat: ::c_long = 293; +pub const SYS_linkat: ::c_long = 294; +pub const SYS_symlinkat: ::c_long = 295; +pub const SYS_readlinkat: ::c_long = 296; +pub const SYS_fchmodat: ::c_long = 297; +pub const SYS_faccessat: ::c_long = 298; +pub const SYS_get_robust_list: ::c_long = 299; +pub const SYS_set_robust_list: ::c_long = 300; +pub const SYS_move_pages: ::c_long = 301; +pub const SYS_getcpu: ::c_long = 302; +pub const SYS_epoll_pwait: ::c_long = 303; +pub const SYS_utimensat: ::c_long = 304; +pub const SYS_signalfd: ::c_long = 305; +pub const SYS_timerfd_create: ::c_long = 306; +pub const SYS_eventfd: ::c_long = 307; +pub const SYS_sync_file_range2: ::c_long = 308; +pub const SYS_fallocate: ::c_long = 309; +pub const SYS_subpage_prot: ::c_long = 310; +pub const SYS_timerfd_settime: ::c_long = 311; +pub const SYS_timerfd_gettime: ::c_long = 312; +pub const SYS_signalfd4: ::c_long = 313; +pub const SYS_eventfd2: ::c_long = 314; +pub const SYS_epoll_create1: ::c_long = 315; +pub const SYS_dup3: ::c_long = 316; +pub const SYS_pipe2: ::c_long = 317; +pub const SYS_inotify_init1: ::c_long = 318; +pub const SYS_perf_event_open: ::c_long = 319; +pub const SYS_preadv: ::c_long = 320; +pub const SYS_pwritev: ::c_long = 321; +pub const SYS_rt_tgsigqueueinfo: ::c_long = 322; +pub const SYS_fanotify_init: ::c_long = 323; +pub const SYS_fanotify_mark: ::c_long = 324; +pub const SYS_prlimit64: ::c_long = 325; +pub const SYS_socket: ::c_long = 326; +pub const SYS_bind: ::c_long = 327; +pub const SYS_connect: ::c_long = 328; +pub const SYS_listen: ::c_long = 329; +pub const SYS_accept: ::c_long = 330; +pub const SYS_getsockname: ::c_long = 331; +pub const SYS_getpeername: ::c_long = 332; +pub const SYS_socketpair: ::c_long = 333; +pub const SYS_send: ::c_long = 334; +pub const SYS_sendto: ::c_long = 335; +pub const SYS_recv: ::c_long = 336; +pub const SYS_recvfrom: ::c_long = 337; +pub const SYS_shutdown: ::c_long = 338; +pub const SYS_setsockopt: ::c_long = 339; +pub const SYS_getsockopt: ::c_long = 340; +pub const SYS_sendmsg: ::c_long = 341; +pub const SYS_recvmsg: ::c_long = 342; +pub const SYS_recvmmsg: ::c_long = 343; +pub const SYS_accept4: ::c_long = 344; +pub const SYS_name_to_handle_at: ::c_long = 345; +pub const SYS_open_by_handle_at: ::c_long = 346; +pub const SYS_clock_adjtime: ::c_long = 347; +pub const SYS_syncfs: ::c_long = 348; +pub const SYS_sendmmsg: ::c_long = 349; +pub const SYS_setns: ::c_long = 350; +pub const SYS_process_vm_readv: ::c_long = 351; +pub const SYS_process_vm_writev: ::c_long = 352; +pub const SYS_finit_module: ::c_long = 353; +pub const SYS_kcmp: ::c_long = 354; +pub const SYS_sched_setattr: ::c_long = 355; +pub const SYS_sched_getattr: ::c_long = 356; +pub const SYS_renameat2: ::c_long = 357; +pub const SYS_seccomp: ::c_long = 358; +pub const SYS_getrandom: ::c_long = 359; +pub const SYS_memfd_create: ::c_long = 360; +pub const SYS_bpf: ::c_long = 361; +pub const SYS_execveat: ::c_long = 362; +pub const SYS_switch_endian: ::c_long = 363; +pub const SYS_userfaultfd: ::c_long = 364; +pub const SYS_membarrier: ::c_long = 365; +pub const SYS_mlock2: ::c_long = 378; +pub const SYS_copy_file_range: ::c_long = 379; +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_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; + +pub const EDEADLK: ::c_int = 58; +pub const EDEADLOCK: ::c_int = EDEADLK; + +pub const EXTPROC: ::tcflag_t = 0x10000000; +pub const VEOL: usize = 6; +pub const VEOL2: usize = 8; +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 MCL_CURRENT: ::c_int = 0x2000; +pub const MCL_FUTURE: ::c_int = 0x4000; +pub const MCL_ONFAULT: ::c_int = 0x8000; +pub const CBAUD: ::tcflag_t = 0xff; +pub const TAB1: ::c_int = 0x400; +pub const TAB2: ::c_int = 0x800; +pub const TAB3: ::c_int = 0xc00; +pub const CR1: ::c_int = 0x1000; +pub const CR2: ::c_int = 0x2000; +pub const CR3: ::c_int = 0x3000; +pub const FF1: ::c_int = 0x4000; +pub const BS1: ::c_int = 0x8000; +pub const VT1: ::c_int = 0x10000; +pub const VWERASE: usize = 10; +pub const VREPRINT: usize = 11; +pub const VSUSP: usize = 12; +pub const VSTART: usize = 13; +pub const VSTOP: usize = 14; +pub const VDISCARD: usize = 16; +pub const VTIME: usize = 7; +pub const IXON: ::tcflag_t = 0x00000200; +pub const IXOFF: ::tcflag_t = 0x00000400; +pub const ONLCR: ::tcflag_t = 0x2; +pub const CSIZE: ::tcflag_t = 0x00000300; + +pub const CS6: ::tcflag_t = 0x00000100; +pub const CS7: ::tcflag_t = 0x00000200; +pub const CS8: ::tcflag_t = 0x00000300; +pub const CSTOPB: ::tcflag_t = 0x00000400; +pub const CREAD: ::tcflag_t = 0x00000800; +pub const PARENB: ::tcflag_t = 0x00001000; +pub const PARODD: ::tcflag_t = 0x00002000; +pub const HUPCL: ::tcflag_t = 0x00004000; +pub const CLOCAL: ::tcflag_t = 0x00008000; +pub const ECHOKE: ::tcflag_t = 0x00000001; +pub const ECHOE: ::tcflag_t = 0x00000002; +pub const ECHOK: ::tcflag_t = 0x00000004; +pub const ECHONL: ::tcflag_t = 0x00000010; +pub const ECHOPRT: ::tcflag_t = 0x00000020; +pub const ECHOCTL: ::tcflag_t = 0x00000040; +pub const ISIG: ::tcflag_t = 0x00000080; +pub const ICANON: ::tcflag_t = 0x00000100; +pub const PENDIN: ::tcflag_t = 0x20000000; +pub const NOFLSH: ::tcflag_t = 0x80000000; + +pub const CIBAUD: ::tcflag_t = 0o77600000; +pub const CBAUDEX: ::tcflag_t = 0o0000020; +pub const VSWTC: usize = 9; +pub const OLCUC: ::tcflag_t = 0o000004; +pub const NLDLY: ::tcflag_t = 0o0001400; +pub const CRDLY: ::tcflag_t = 0o0030000; +pub const TABDLY: ::tcflag_t = 0o0006000; +pub const BSDLY: ::tcflag_t = 0o0100000; +pub const FFDLY: ::tcflag_t = 0o0040000; +pub const VTDLY: ::tcflag_t = 0o0200000; +pub const XTABS: ::tcflag_t = 0o00006000; + +pub const B57600: ::speed_t = 0o00020; +pub const B115200: ::speed_t = 0o00021; +pub const B230400: ::speed_t = 0o00022; +pub const B460800: ::speed_t = 0o00023; +pub const B500000: ::speed_t = 0o00024; +pub const B576000: ::speed_t = 0o00025; +pub const B921600: ::speed_t = 0o00026; +pub const B1000000: ::speed_t = 0o00027; +pub const B1152000: ::speed_t = 0o00030; +pub const B1500000: ::speed_t = 0o00031; +pub const B2000000: ::speed_t = 0o00032; +pub const B2500000: ::speed_t = 0o00033; +pub const B3000000: ::speed_t = 0o00034; +pub const B3500000: ::speed_t = 0o00035; +pub const B4000000: ::speed_t = 0o00036; 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..5b33f23 --- /dev/null +++ b/vendor/libc/src/unix/linux_like/linux/musl/b64/riscv64/align.rs @@ -0,0 +1,61 @@ +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], + } +} + +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/riscv64/mod.rs b/vendor/libc/src/unix/linux_like/linux/musl/b64/riscv64/mod.rs new file mode 100644 index 0000000..393f54d --- /dev/null +++ b/vendor/libc/src/unix/linux_like/linux/musl/b64/riscv64/mod.rs @@ -0,0 +1,727 @@ +//! 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 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 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 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 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 MCL_ONFAULT: ::c_int = 0x0004; +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 new file mode 100644 index 0000000..567914f --- /dev/null +++ b/vendor/libc/src/unix/linux_like/linux/musl/b64/s390x.rs @@ -0,0 +1,725 @@ +pub type blksize_t = i64; +pub type c_char = u8; +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 { + 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_int, + __pad1: ::c_long, + __pad2: ::c_long, + } + + 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, + pub st_rdev: ::dev_t, + pub st_size: ::off_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_blksize: ::blksize_t, + pub st_blocks: ::blkcnt_t, + __unused: [::c_long; 3], + } + + pub struct stat64 { + pub st_dev: ::dev_t, + pub st_ino: ::ino64_t, + pub st_nlink: ::nlink_t, + pub st_mode: ::mode_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_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_blksize: ::blksize_t, + pub st_blocks: ::blkcnt64_t, + __unused: [::c_long; 3], + } + + pub struct statfs { + pub f_type: ::c_uint, + pub f_bsize: ::c_uint, + 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_uint, + pub f_frsize: ::c_uint, + pub f_flags: ::c_uint, + pub f_spare: [::c_uint; 4], + } + + pub struct statfs64 { + pub f_type: ::c_uint, + pub f_bsize: ::c_uint, + 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_uint, + pub f_frsize: ::c_uint, + pub f_flags: ::c_uint, + pub f_spare: [::c_uint; 4], + } +} + +s_no_extra_traits! { + // FIXME: This is actually a union. + pub struct fpreg_t { + pub d: ::c_double, + // f: ::c_float, + } +} + +cfg_if! { + if #[cfg(feature = "extra_traits")] { + impl PartialEq for fpreg_t { + fn eq(&self, other: &fpreg_t) -> bool { + self.d == other.d + } + } + + impl Eq for fpreg_t {} + + impl ::fmt::Debug for fpreg_t { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("fpreg_t") + .field("d", &self.d) + .finish() + } + } + + impl ::hash::Hash for fpreg_t { + fn hash(&self, state: &mut H) { + let d: u64 = unsafe { ::mem::transmute(self.d) }; + d.hash(state); + } + } + } +} + +pub const VEOF: usize = 4; +pub const RTLD_DEEPBIND: ::c_int = 0x8; + +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 EADDRINUSE: ::c_int = 98; +pub const EADDRNOTAVAIL: ::c_int = 99; +pub const ECONNABORTED: ::c_int = 103; +pub const ECONNREFUSED: ::c_int = 111; +pub const ECONNRESET: ::c_int = 104; +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 O_APPEND: ::c_int = 1024; +pub const O_CREAT: ::c_int = 64; +pub const O_EXCL: ::c_int = 128; +pub const O_LARGEFILE: ::c_int = 0x8000; +pub const O_NONBLOCK: ::c_int = 2048; +pub const SA_NOCLDWAIT: ::c_int = 2; +pub const SA_ONSTACK: ::c_int = 0x08000000; +pub const SA_SIGINFO: ::c_int = 4; +pub const SIGBUS: ::c_int = 7; +pub const SIGSTKSZ: ::size_t = 0x2000; +pub const MINSIGSTKSZ: ::size_t = 2048; +pub const SIG_SETMASK: ::c_int = 2; + +pub const SOCK_STREAM: ::c_int = 1; +pub const SOCK_DGRAM: ::c_int = 2; + +pub const O_NOCTTY: ::c_int = 256; +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_DIRECT: ::c_int = 0x4000; +pub const O_DIRECTORY: ::c_int = 0x10000; +pub const O_NOFOLLOW: ::c_int = 0x20000; + +pub const MADV_SOFT_OFFLINE: ::c_int = 101; +pub const MAP_GROWSDOWN: ::c_int = 0x0100; +pub const MAP_LOCKED: ::c_int = 0x02000; +pub const MAP_NORESERVE: ::c_int = 0x04000; +pub const MAP_ANON: ::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_SYNC: ::c_int = 0x080000; + +pub const PTRACE_SYSEMU: ::c_int = 31; +pub const PTRACE_SYSEMU_SINGLESTEP: ::c_int = 32; + +pub const EDEADLOCK: ::c_int = 35; +pub const ENAMETOOLONG: ::c_int = 36; +pub const ENOLCK: ::c_int = 37; +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 ENETDOWN: ::c_int = 100; +pub const ENETUNREACH: ::c_int = 101; +pub const ENETRESET: ::c_int = 102; +pub const ENOBUFS: ::c_int = 105; +pub const EISCONN: ::c_int = 106; +pub const ESHUTDOWN: ::c_int = 108; +pub const ETOOMANYREFS: ::c_int = 109; +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 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 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_BLOCK: ::c_int = 0x000000; +pub const SIG_UNBLOCK: ::c_int = 0x01; + +pub const O_ASYNC: ::c_int = 0x2000; + +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 MCL_CURRENT: ::c_int = 0x0001; +pub const MCL_FUTURE: ::c_int = 0x0002; +pub const MCL_ONFAULT: ::c_int = 0x0004; + +pub const F_GETLK: ::c_int = 5; +pub const F_GETOWN: ::c_int = 9; +pub const F_SETOWN: ::c_int = 8; +pub const F_SETLK: ::c_int = 6; +pub const F_SETLKW: ::c_int = 7; + +pub const VTIME: usize = 5; +pub const VSWTC: usize = 7; +pub const VSTART: usize = 8; +pub const VSTOP: usize = 9; +pub const VSUSP: usize = 10; +pub const VREPRINT: usize = 12; +pub const VDISCARD: usize = 13; +pub const VWERASE: usize = 14; +pub const OLCUC: ::tcflag_t = 0o000002; +pub const ONLCR: ::tcflag_t = 0o000004; +pub const NLDLY: ::tcflag_t = 0o000400; +pub const CRDLY: ::tcflag_t = 0o003000; +pub const CR1: ::tcflag_t = 0x00000200; +pub const CR2: ::tcflag_t = 0x00000400; +pub const CR3: ::tcflag_t = 0x00000600; +pub const TABDLY: ::tcflag_t = 0o014000; +pub const TAB1: ::tcflag_t = 0x00000800; +pub const TAB2: ::tcflag_t = 0x00001000; +pub const TAB3: ::tcflag_t = 0x00001800; +pub const BSDLY: ::tcflag_t = 0o020000; +pub const BS1: ::tcflag_t = 0x00002000; +pub const FFDLY: ::tcflag_t = 0o100000; +pub const FF1: ::tcflag_t = 0x00008000; +pub const VTDLY: ::tcflag_t = 0o040000; +pub const VT1: ::tcflag_t = 0x00004000; +pub const XTABS: ::tcflag_t = 0o014000; + +pub const CBAUD: ::speed_t = 0o010017; +pub const CSIZE: ::tcflag_t = 0o000060; +pub const CS6: ::tcflag_t = 0o000020; +pub const CS7: ::tcflag_t = 0o000040; +pub const CS8: ::tcflag_t = 0o000060; +pub const CSTOPB: ::tcflag_t = 0o000100; +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 CBAUDEX: ::tcflag_t = 0o010000; +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 CIBAUD: ::tcflag_t = 0o02003600000; + +pub const ISIG: ::tcflag_t = 0o000001; +pub const ICANON: ::tcflag_t = 0o000002; +pub const XCASE: ::tcflag_t = 0o000004; +pub const ECHOE: ::tcflag_t = 0o000020; +pub const ECHOK: ::tcflag_t = 0o000040; +pub const ECHONL: ::tcflag_t = 0o000100; +pub const NOFLSH: ::tcflag_t = 0o000200; +pub const ECHOCTL: ::tcflag_t = 0o001000; +pub const ECHOPRT: ::tcflag_t = 0o002000; +pub const ECHOKE: ::tcflag_t = 0o004000; +pub const PENDIN: ::tcflag_t = 0o040000; + +pub const POLLWRNORM: ::c_short = 0x100; +pub const POLLWRBAND: ::c_short = 0x200; + +pub const IXON: ::tcflag_t = 0o002000; +pub const IXOFF: ::tcflag_t = 0o010000; + +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_restart_syscall: ::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_mknod: ::c_long = 14; +pub const SYS_chmod: ::c_long = 15; +pub const SYS_lseek: ::c_long = 19; +pub const SYS_getpid: ::c_long = 20; +pub const SYS_mount: ::c_long = 21; +pub const SYS_umount: ::c_long = 22; +pub const SYS_ptrace: ::c_long = 26; +pub const SYS_alarm: ::c_long = 27; +pub const SYS_pause: ::c_long = 29; +pub const SYS_utime: ::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_signal: ::c_long = 48; +pub const SYS_acct: ::c_long = 51; +pub const SYS_umount2: ::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_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_getrusage: ::c_long = 77; +pub const SYS_gettimeofday: ::c_long = 78; +pub const SYS_settimeofday: ::c_long = 79; +pub const SYS_symlink: ::c_long = 83; +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_readdir: ::c_long = 89; +pub const SYS_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_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_stat: ::c_long = 106; +pub const SYS_lstat: ::c_long = 107; +pub const SYS_fstat: ::c_long = 108; +pub const SYS_lookup_dcookie: ::c_long = 110; +pub const SYS_vhangup: ::c_long = 111; +pub const SYS_idle: ::c_long = 112; +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_uname: ::c_long = 122; +pub const SYS_adjtimex: ::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_afs_syscall: ::c_long = 137; /* Syscall for Andrew File System */ +pub const SYS_getdents: ::c_long = 141; +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: ::c_long = 161; +pub const SYS_nanosleep: ::c_long = 162; +pub const SYS_mremap: ::c_long = 163; +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_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: ::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_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_pivot_root: ::c_long = 217; +pub const SYS_mincore: ::c_long = 218; +pub const SYS_madvise: ::c_long = 219; +pub const SYS_getdents64: ::c_long = 220; +pub const SYS_readahead: ::c_long = 222; +pub const SYS_setxattr: ::c_long = 224; +pub const SYS_lsetxattr: ::c_long = 225; +pub const SYS_fsetxattr: ::c_long = 226; +pub const SYS_getxattr: ::c_long = 227; +pub const SYS_lgetxattr: ::c_long = 228; +pub const SYS_fgetxattr: ::c_long = 229; +pub const SYS_listxattr: ::c_long = 230; +pub const SYS_llistxattr: ::c_long = 231; +pub const SYS_flistxattr: ::c_long = 232; +pub const SYS_removexattr: ::c_long = 233; +pub const SYS_lremovexattr: ::c_long = 234; +pub const SYS_fremovexattr: ::c_long = 235; +pub const SYS_gettid: ::c_long = 236; +pub const SYS_tkill: ::c_long = 237; +pub const SYS_futex: ::c_long = 238; +pub const SYS_sched_setaffinity: ::c_long = 239; +pub const SYS_sched_getaffinity: ::c_long = 240; +pub const SYS_tgkill: ::c_long = 241; +pub const SYS_io_setup: ::c_long = 243; +pub const SYS_io_destroy: ::c_long = 244; +pub const SYS_io_getevents: ::c_long = 245; +pub const SYS_io_submit: ::c_long = 246; +pub const SYS_io_cancel: ::c_long = 247; +pub const SYS_exit_group: ::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_set_tid_address: ::c_long = 252; +pub const SYS_fadvise64: ::c_long = 253; +pub const SYS_timer_create: ::c_long = 254; +pub const SYS_timer_settime: ::c_long = 255; +pub const SYS_timer_gettime: ::c_long = 256; +pub const SYS_timer_getoverrun: ::c_long = 257; +pub const SYS_timer_delete: ::c_long = 258; +pub const SYS_clock_settime: ::c_long = 259; +pub const SYS_clock_gettime: ::c_long = 260; +pub const SYS_clock_getres: ::c_long = 261; +pub const SYS_clock_nanosleep: ::c_long = 262; +pub const SYS_statfs64: ::c_long = 265; +pub const SYS_fstatfs64: ::c_long = 266; +pub const SYS_remap_file_pages: ::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: ::c_long = 273; +pub const SYS_mq_timedreceive: ::c_long = 274; +pub const SYS_mq_notify: ::c_long = 275; +pub const SYS_mq_getsetattr: ::c_long = 276; +pub const SYS_kexec_load: ::c_long = 277; +pub const SYS_add_key: ::c_long = 278; +pub const SYS_request_key: ::c_long = 279; +pub const SYS_keyctl: ::c_long = 280; +pub const SYS_waitid: ::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: ::c_long = 292; +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: ::c_long = 301; +pub const SYS_ppoll: ::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_getcpu: ::c_long = 311; +pub const SYS_epoll_pwait: ::c_long = 312; +pub const SYS_utimes: ::c_long = 313; +pub const SYS_fallocate: ::c_long = 314; +pub const SYS_utimensat: ::c_long = 315; +pub const SYS_signalfd: ::c_long = 316; +pub const SYS_timerfd: ::c_long = 317; +pub const SYS_eventfd: ::c_long = 318; +pub const SYS_timerfd_create: ::c_long = 319; +pub const SYS_timerfd_settime: ::c_long = 320; +pub const SYS_timerfd_gettime: ::c_long = 321; +pub const SYS_signalfd4: ::c_long = 322; +pub const SYS_eventfd2: ::c_long = 323; +pub const SYS_inotify_init1: ::c_long = 324; +pub const SYS_pipe2: ::c_long = 325; +pub const SYS_dup3: ::c_long = 326; +pub const SYS_epoll_create1: ::c_long = 327; +pub const SYS_preadv: ::c_long = 328; +pub const SYS_pwritev: ::c_long = 329; +pub const SYS_rt_tgsigqueueinfo: ::c_long = 330; +pub const SYS_perf_event_open: ::c_long = 331; +pub const SYS_fanotify_init: ::c_long = 332; +pub const SYS_fanotify_mark: ::c_long = 333; +pub const SYS_prlimit64: ::c_long = 334; +pub const SYS_name_to_handle_at: ::c_long = 335; +pub const SYS_open_by_handle_at: ::c_long = 336; +pub const SYS_clock_adjtime: ::c_long = 337; +pub const SYS_syncfs: ::c_long = 338; +pub const SYS_setns: ::c_long = 339; +pub const SYS_process_vm_readv: ::c_long = 340; +pub const SYS_process_vm_writev: ::c_long = 341; +pub const SYS_s390_runtime_instr: ::c_long = 342; +pub const SYS_kcmp: ::c_long = 343; +pub const SYS_finit_module: ::c_long = 344; +pub const SYS_sched_setattr: ::c_long = 345; +pub const SYS_sched_getattr: ::c_long = 346; +pub const SYS_renameat2: ::c_long = 347; +pub const SYS_seccomp: ::c_long = 348; +pub const SYS_getrandom: ::c_long = 349; +pub const SYS_memfd_create: ::c_long = 350; +pub const SYS_bpf: ::c_long = 351; +pub const SYS_s390_pci_mmio_write: ::c_long = 352; +pub const SYS_s390_pci_mmio_read: ::c_long = 353; +pub const SYS_execveat: ::c_long = 354; +pub const SYS_userfaultfd: ::c_long = 355; +pub const SYS_membarrier: ::c_long = 356; +pub const SYS_recvmmsg: ::c_long = 357; +pub const SYS_sendmmsg: ::c_long = 358; +pub const SYS_socket: ::c_long = 359; +pub const SYS_socketpair: ::c_long = 360; +pub const SYS_bind: ::c_long = 361; +pub const SYS_connect: ::c_long = 362; +pub const SYS_listen: ::c_long = 363; +pub const SYS_accept4: ::c_long = 364; +pub const SYS_getsockopt: ::c_long = 365; +pub const SYS_setsockopt: ::c_long = 366; +pub const SYS_getsockname: ::c_long = 367; +pub const SYS_getpeername: ::c_long = 368; +pub const SYS_sendto: ::c_long = 369; +pub const SYS_sendmsg: ::c_long = 370; +pub const SYS_recvfrom: ::c_long = 371; +pub const SYS_recvmsg: ::c_long = 372; +pub const SYS_shutdown: ::c_long = 373; +pub const SYS_mlock2: ::c_long = 374; +pub const SYS_copy_file_range: ::c_long = 375; +pub const SYS_preadv2: ::c_long = 376; +pub const SYS_pwritev2: ::c_long = 377; +pub const SYS_lchown: ::c_long = 198; +pub const SYS_setuid: ::c_long = 213; +pub const SYS_getuid: ::c_long = 199; +pub const SYS_setgid: ::c_long = 214; +pub const SYS_getgid: ::c_long = 200; +pub const SYS_geteuid: ::c_long = 201; +pub const SYS_setreuid: ::c_long = 203; +pub const SYS_setregid: ::c_long = 204; +pub const SYS_getrlimit: ::c_long = 191; +pub const SYS_getgroups: ::c_long = 205; +pub const SYS_fchown: ::c_long = 207; +pub const SYS_setresuid: ::c_long = 208; +pub const SYS_setresgid: ::c_long = 210; +pub const SYS_getresgid: ::c_long = 211; +pub const SYS_select: ::c_long = 142; +pub const SYS_getegid: ::c_long = 202; +pub const SYS_setgroups: ::c_long = 206; +pub const SYS_getresuid: ::c_long = 209; +pub const SYS_chown: ::c_long = 212; +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_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; +pub const SYS_mseal: ::c_long = 462; 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 new file mode 100644 index 0000000..94391a0 --- /dev/null +++ b/vendor/libc/src/unix/linux_like/linux/musl/b64/x86_64/align.rs @@ -0,0 +1,25 @@ +s_no_extra_traits! { + #[allow(missing_debug_implementations)] + #[repr(align(16))] + 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 new file mode 100644 index 0000000..dc617d4 --- /dev/null +++ b/vendor/libc/src/unix/linux_like/linux/musl/b64/x86_64/mod.rs @@ -0,0 +1,917 @@ +pub type c_char = i8; +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! { + 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], + } + + pub struct stat64 { + pub st_dev: ::dev_t, + pub st_ino: ::ino64_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: ::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, + __reserved: [::c_long; 3], + } + + 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], + } + + // GitHub repo: ifduyue/musl/ + // commit: b4b1e10364c8737a632be61582e05a8d3acf5690 + // file: arch/x86_64/bits/signal.h#L80-L84 + pub struct mcontext_t { + pub gregs: [greg_t; 23], + __private: [u64; 9], + } + + 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_int, + __unused1: ::c_long, + __unused2: ::c_long + } +} + +s_no_extra_traits! { + 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], + } + + 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, + __private: [u8; 512], + } +} + +cfg_if! { + if #[cfg(feature = "extra_traits")] { + 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("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.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 + } + } + + impl PartialEq for ucontext_t { + fn eq(&self, other: &ucontext_t) -> bool { + self.uc_flags == other.uc_flags + && self.uc_link == other.uc_link + && self.uc_stack == other.uc_stack + && self.uc_mcontext == other.uc_mcontext + && self.uc_sigmask == other.uc_sigmask + && self + .__private + .iter() + .zip(other.__private.iter()) + .all(|(a,b)| a == b) + } + } + + impl Eq for ucontext_t {} + + impl ::fmt::Debug for ucontext_t { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("ucontext_t") + .field("uc_flags", &self.uc_flags) + .field("uc_link", &self.uc_link) + .field("uc_stack", &self.uc_stack) + .field("uc_mcontext", &self.uc_mcontext) + .field("uc_sigmask", &self.uc_sigmask) + // Ignore __private field + .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); + self.__private.hash(state); + } + } + } +} + +// Syscall table + +pub const SYS_read: ::c_long = 0; +pub const SYS_write: ::c_long = 1; +pub const SYS_open: ::c_long = 2; +pub const SYS_close: ::c_long = 3; +pub const SYS_stat: ::c_long = 4; +pub const SYS_fstat: ::c_long = 5; +pub const SYS_lstat: ::c_long = 6; +pub const SYS_poll: ::c_long = 7; +pub const SYS_lseek: ::c_long = 8; +pub const SYS_mmap: ::c_long = 9; +pub const SYS_mprotect: ::c_long = 10; +pub const SYS_munmap: ::c_long = 11; +pub const SYS_brk: ::c_long = 12; +pub const SYS_rt_sigaction: ::c_long = 13; +pub const SYS_rt_sigprocmask: ::c_long = 14; +pub const SYS_rt_sigreturn: ::c_long = 15; +pub const SYS_ioctl: ::c_long = 16; +pub const SYS_pread64: ::c_long = 17; +pub const SYS_pwrite64: ::c_long = 18; +pub const SYS_readv: ::c_long = 19; +pub const SYS_writev: ::c_long = 20; +pub const SYS_access: ::c_long = 21; +pub const SYS_pipe: ::c_long = 22; +pub const SYS_select: ::c_long = 23; +pub const SYS_sched_yield: ::c_long = 24; +pub const SYS_mremap: ::c_long = 25; +pub const SYS_msync: ::c_long = 26; +pub const SYS_mincore: ::c_long = 27; +pub const SYS_madvise: ::c_long = 28; +pub const SYS_shmget: ::c_long = 29; +pub const SYS_shmat: ::c_long = 30; +pub const SYS_shmctl: ::c_long = 31; +pub const SYS_dup: ::c_long = 32; +pub const SYS_dup2: ::c_long = 33; +pub const SYS_pause: ::c_long = 34; +pub const SYS_nanosleep: ::c_long = 35; +pub const SYS_getitimer: ::c_long = 36; +pub const SYS_alarm: ::c_long = 37; +pub const SYS_setitimer: ::c_long = 38; +pub const SYS_getpid: ::c_long = 39; +pub const SYS_sendfile: ::c_long = 40; +pub const SYS_socket: ::c_long = 41; +pub const SYS_connect: ::c_long = 42; +pub const SYS_accept: ::c_long = 43; +pub const SYS_sendto: ::c_long = 44; +pub const SYS_recvfrom: ::c_long = 45; +pub const SYS_sendmsg: ::c_long = 46; +pub const SYS_recvmsg: ::c_long = 47; +pub const SYS_shutdown: ::c_long = 48; +pub const SYS_bind: ::c_long = 49; +pub const SYS_listen: ::c_long = 50; +pub const SYS_getsockname: ::c_long = 51; +pub const SYS_getpeername: ::c_long = 52; +pub const SYS_socketpair: ::c_long = 53; +pub const SYS_setsockopt: ::c_long = 54; +pub const SYS_getsockopt: ::c_long = 55; +pub const SYS_clone: ::c_long = 56; +pub const SYS_fork: ::c_long = 57; +pub const SYS_vfork: ::c_long = 58; +pub const SYS_execve: ::c_long = 59; +pub const SYS_exit: ::c_long = 60; +pub const SYS_wait4: ::c_long = 61; +pub const SYS_kill: ::c_long = 62; +pub const SYS_uname: ::c_long = 63; +pub const SYS_semget: ::c_long = 64; +pub const SYS_semop: ::c_long = 65; +pub const SYS_semctl: ::c_long = 66; +pub const SYS_shmdt: ::c_long = 67; +pub const SYS_msgget: ::c_long = 68; +pub const SYS_msgsnd: ::c_long = 69; +pub const SYS_msgrcv: ::c_long = 70; +pub const SYS_msgctl: ::c_long = 71; +pub const SYS_fcntl: ::c_long = 72; +pub const SYS_flock: ::c_long = 73; +pub const SYS_fsync: ::c_long = 74; +pub const SYS_fdatasync: ::c_long = 75; +pub const SYS_truncate: ::c_long = 76; +pub const SYS_ftruncate: ::c_long = 77; +pub const SYS_getdents: ::c_long = 78; +pub const SYS_getcwd: ::c_long = 79; +pub const SYS_chdir: ::c_long = 80; +pub const SYS_fchdir: ::c_long = 81; +pub const SYS_rename: ::c_long = 82; +pub const SYS_mkdir: ::c_long = 83; +pub const SYS_rmdir: ::c_long = 84; +pub const SYS_creat: ::c_long = 85; +pub const SYS_link: ::c_long = 86; +pub const SYS_unlink: ::c_long = 87; +pub const SYS_symlink: ::c_long = 88; +pub const SYS_readlink: ::c_long = 89; +pub const SYS_chmod: ::c_long = 90; +pub const SYS_fchmod: ::c_long = 91; +pub const SYS_chown: ::c_long = 92; +pub const SYS_fchown: ::c_long = 93; +pub const SYS_lchown: ::c_long = 94; +pub const SYS_umask: ::c_long = 95; +pub const SYS_gettimeofday: ::c_long = 96; +pub const SYS_getrlimit: ::c_long = 97; +pub const SYS_getrusage: ::c_long = 98; +pub const SYS_sysinfo: ::c_long = 99; +pub const SYS_times: ::c_long = 100; +pub const SYS_ptrace: ::c_long = 101; +pub const SYS_getuid: ::c_long = 102; +pub const SYS_syslog: ::c_long = 103; +pub const SYS_getgid: ::c_long = 104; +pub const SYS_setuid: ::c_long = 105; +pub const SYS_setgid: ::c_long = 106; +pub const SYS_geteuid: ::c_long = 107; +pub const SYS_getegid: ::c_long = 108; +pub const SYS_setpgid: ::c_long = 109; +pub const SYS_getppid: ::c_long = 110; +pub const SYS_getpgrp: ::c_long = 111; +pub const SYS_setsid: ::c_long = 112; +pub const SYS_setreuid: ::c_long = 113; +pub const SYS_setregid: ::c_long = 114; +pub const SYS_getgroups: ::c_long = 115; +pub const SYS_setgroups: ::c_long = 116; +pub const SYS_setresuid: ::c_long = 117; +pub const SYS_getresuid: ::c_long = 118; +pub const SYS_setresgid: ::c_long = 119; +pub const SYS_getresgid: ::c_long = 120; +pub const SYS_getpgid: ::c_long = 121; +pub const SYS_setfsuid: ::c_long = 122; +pub const SYS_setfsgid: ::c_long = 123; +pub const SYS_getsid: ::c_long = 124; +pub const SYS_capget: ::c_long = 125; +pub const SYS_capset: ::c_long = 126; +pub const SYS_rt_sigpending: ::c_long = 127; +pub const SYS_rt_sigtimedwait: ::c_long = 128; +pub const SYS_rt_sigqueueinfo: ::c_long = 129; +pub const SYS_rt_sigsuspend: ::c_long = 130; +pub const SYS_sigaltstack: ::c_long = 131; +pub const SYS_utime: ::c_long = 132; +pub const SYS_mknod: ::c_long = 133; +pub const SYS_uselib: ::c_long = 134; +pub const SYS_personality: ::c_long = 135; +pub const SYS_ustat: ::c_long = 136; +pub const SYS_statfs: ::c_long = 137; +pub const SYS_fstatfs: ::c_long = 138; +pub const SYS_sysfs: ::c_long = 139; +pub const SYS_getpriority: ::c_long = 140; +pub const SYS_setpriority: ::c_long = 141; +pub const SYS_sched_setparam: ::c_long = 142; +pub const SYS_sched_getparam: ::c_long = 143; +pub const SYS_sched_setscheduler: ::c_long = 144; +pub const SYS_sched_getscheduler: ::c_long = 145; +pub const SYS_sched_get_priority_max: ::c_long = 146; +pub const SYS_sched_get_priority_min: ::c_long = 147; +pub const SYS_sched_rr_get_interval: ::c_long = 148; +pub const SYS_mlock: ::c_long = 149; +pub const SYS_munlock: ::c_long = 150; +pub const SYS_mlockall: ::c_long = 151; +pub const SYS_munlockall: ::c_long = 152; +pub const SYS_vhangup: ::c_long = 153; +pub const SYS_modify_ldt: ::c_long = 154; +pub const SYS_pivot_root: ::c_long = 155; +pub const SYS__sysctl: ::c_long = 156; +pub const SYS_prctl: ::c_long = 157; +pub const SYS_arch_prctl: ::c_long = 158; +pub const SYS_adjtimex: ::c_long = 159; +pub const SYS_setrlimit: ::c_long = 160; +pub const SYS_chroot: ::c_long = 161; +pub const SYS_sync: ::c_long = 162; +pub const SYS_acct: ::c_long = 163; +pub const SYS_settimeofday: ::c_long = 164; +pub const SYS_mount: ::c_long = 165; +pub const SYS_umount2: ::c_long = 166; +pub const SYS_swapon: ::c_long = 167; +pub const SYS_swapoff: ::c_long = 168; +pub const SYS_reboot: ::c_long = 169; +pub const SYS_sethostname: ::c_long = 170; +pub const SYS_setdomainname: ::c_long = 171; +pub const SYS_iopl: ::c_long = 172; +pub const SYS_ioperm: ::c_long = 173; +pub const SYS_create_module: ::c_long = 174; +pub const SYS_init_module: ::c_long = 175; +pub const SYS_delete_module: ::c_long = 176; +pub const SYS_get_kernel_syms: ::c_long = 177; +pub const SYS_query_module: ::c_long = 178; +pub const SYS_quotactl: ::c_long = 179; +pub const SYS_nfsservctl: ::c_long = 180; +pub const SYS_getpmsg: ::c_long = 181; +pub const SYS_putpmsg: ::c_long = 182; +pub const SYS_afs_syscall: ::c_long = 183; +pub const SYS_tuxcall: ::c_long = 184; +pub const SYS_security: ::c_long = 185; +pub const SYS_gettid: ::c_long = 186; +pub const SYS_readahead: ::c_long = 187; +pub const SYS_setxattr: ::c_long = 188; +pub const SYS_lsetxattr: ::c_long = 189; +pub const SYS_fsetxattr: ::c_long = 190; +pub const SYS_getxattr: ::c_long = 191; +pub const SYS_lgetxattr: ::c_long = 192; +pub const SYS_fgetxattr: ::c_long = 193; +pub const SYS_listxattr: ::c_long = 194; +pub const SYS_llistxattr: ::c_long = 195; +pub const SYS_flistxattr: ::c_long = 196; +pub const SYS_removexattr: ::c_long = 197; +pub const SYS_lremovexattr: ::c_long = 198; +pub const SYS_fremovexattr: ::c_long = 199; +pub const SYS_tkill: ::c_long = 200; +pub const SYS_time: ::c_long = 201; +pub const SYS_futex: ::c_long = 202; +pub const SYS_sched_setaffinity: ::c_long = 203; +pub const SYS_sched_getaffinity: ::c_long = 204; +pub const SYS_set_thread_area: ::c_long = 205; +pub const SYS_io_setup: ::c_long = 206; +pub const SYS_io_destroy: ::c_long = 207; +pub const SYS_io_getevents: ::c_long = 208; +pub const SYS_io_submit: ::c_long = 209; +pub const SYS_io_cancel: ::c_long = 210; +pub const SYS_get_thread_area: ::c_long = 211; +pub const SYS_lookup_dcookie: ::c_long = 212; +pub const SYS_epoll_create: ::c_long = 213; +pub const SYS_epoll_ctl_old: ::c_long = 214; +pub const SYS_epoll_wait_old: ::c_long = 215; +pub const SYS_remap_file_pages: ::c_long = 216; +pub const SYS_getdents64: ::c_long = 217; +pub const SYS_set_tid_address: ::c_long = 218; +pub const SYS_restart_syscall: ::c_long = 219; +pub const SYS_semtimedop: ::c_long = 220; +pub const SYS_fadvise64: ::c_long = 221; +pub const SYS_timer_create: ::c_long = 222; +pub const SYS_timer_settime: ::c_long = 223; +pub const SYS_timer_gettime: ::c_long = 224; +pub const SYS_timer_getoverrun: ::c_long = 225; +pub const SYS_timer_delete: ::c_long = 226; +pub const SYS_clock_settime: ::c_long = 227; +pub const SYS_clock_gettime: ::c_long = 228; +pub const SYS_clock_getres: ::c_long = 229; +pub const SYS_clock_nanosleep: ::c_long = 230; +pub const SYS_exit_group: ::c_long = 231; +pub const SYS_epoll_wait: ::c_long = 232; +pub const SYS_epoll_ctl: ::c_long = 233; +pub const SYS_tgkill: ::c_long = 234; +pub const SYS_utimes: ::c_long = 235; +pub const SYS_vserver: ::c_long = 236; +pub const SYS_mbind: ::c_long = 237; +pub const SYS_set_mempolicy: ::c_long = 238; +pub const SYS_get_mempolicy: ::c_long = 239; +pub const SYS_mq_open: ::c_long = 240; +pub const SYS_mq_unlink: ::c_long = 241; +pub const SYS_mq_timedsend: ::c_long = 242; +pub const SYS_mq_timedreceive: ::c_long = 243; +pub const SYS_mq_notify: ::c_long = 244; +pub const SYS_mq_getsetattr: ::c_long = 245; +pub const SYS_kexec_load: ::c_long = 246; +pub const SYS_waitid: ::c_long = 247; +pub const SYS_add_key: ::c_long = 248; +pub const SYS_request_key: ::c_long = 249; +pub const SYS_keyctl: ::c_long = 250; +pub const SYS_ioprio_set: ::c_long = 251; +pub const SYS_ioprio_get: ::c_long = 252; +pub const SYS_inotify_init: ::c_long = 253; +pub const SYS_inotify_add_watch: ::c_long = 254; +pub const SYS_inotify_rm_watch: ::c_long = 255; +pub const SYS_migrate_pages: ::c_long = 256; +pub const SYS_openat: ::c_long = 257; +pub const SYS_mkdirat: ::c_long = 258; +pub const SYS_mknodat: ::c_long = 259; +pub const SYS_fchownat: ::c_long = 260; +pub const SYS_futimesat: ::c_long = 261; +pub const SYS_newfstatat: ::c_long = 262; +pub const SYS_unlinkat: ::c_long = 263; +pub const SYS_renameat: ::c_long = 264; +pub const SYS_linkat: ::c_long = 265; +pub const SYS_symlinkat: ::c_long = 266; +pub const SYS_readlinkat: ::c_long = 267; +pub const SYS_fchmodat: ::c_long = 268; +pub const SYS_faccessat: ::c_long = 269; +pub const SYS_pselect6: ::c_long = 270; +pub const SYS_ppoll: ::c_long = 271; +pub const SYS_unshare: ::c_long = 272; +pub const SYS_set_robust_list: ::c_long = 273; +pub const SYS_get_robust_list: ::c_long = 274; +pub const SYS_splice: ::c_long = 275; +pub const SYS_tee: ::c_long = 276; +pub const SYS_sync_file_range: ::c_long = 277; +pub const SYS_vmsplice: ::c_long = 278; +pub const SYS_move_pages: ::c_long = 279; +pub const SYS_utimensat: ::c_long = 280; +pub const SYS_epoll_pwait: ::c_long = 281; +pub const SYS_signalfd: ::c_long = 282; +pub const SYS_timerfd_create: ::c_long = 283; +pub const SYS_eventfd: ::c_long = 284; +pub const SYS_fallocate: ::c_long = 285; +pub const SYS_timerfd_settime: ::c_long = 286; +pub const SYS_timerfd_gettime: ::c_long = 287; +pub const SYS_accept4: ::c_long = 288; +pub const SYS_signalfd4: ::c_long = 289; +pub const SYS_eventfd2: ::c_long = 290; +pub const SYS_epoll_create1: ::c_long = 291; +pub const SYS_dup3: ::c_long = 292; +pub const SYS_pipe2: ::c_long = 293; +pub const SYS_inotify_init1: ::c_long = 294; +pub const SYS_preadv: ::c_long = 295; +pub const SYS_pwritev: ::c_long = 296; +pub const SYS_rt_tgsigqueueinfo: ::c_long = 297; +pub const SYS_perf_event_open: ::c_long = 298; +pub const SYS_recvmmsg: ::c_long = 299; +pub const SYS_fanotify_init: ::c_long = 300; +pub const SYS_fanotify_mark: ::c_long = 301; +pub const SYS_prlimit64: ::c_long = 302; +pub const SYS_name_to_handle_at: ::c_long = 303; +pub const SYS_open_by_handle_at: ::c_long = 304; +pub const SYS_clock_adjtime: ::c_long = 305; +pub const SYS_syncfs: ::c_long = 306; +pub const SYS_sendmmsg: ::c_long = 307; +pub const SYS_setns: ::c_long = 308; +pub const SYS_getcpu: ::c_long = 309; +pub const SYS_process_vm_readv: ::c_long = 310; +pub const SYS_process_vm_writev: ::c_long = 311; +pub const SYS_kcmp: ::c_long = 312; +pub const SYS_finit_module: ::c_long = 313; +pub const SYS_sched_setattr: ::c_long = 314; +pub const SYS_sched_getattr: ::c_long = 315; +pub const SYS_renameat2: ::c_long = 316; +pub const SYS_seccomp: ::c_long = 317; +pub const SYS_getrandom: ::c_long = 318; +pub const SYS_memfd_create: ::c_long = 319; +pub const SYS_kexec_file_load: ::c_long = 320; +pub const SYS_bpf: ::c_long = 321; +pub const SYS_execveat: ::c_long = 322; +pub const SYS_userfaultfd: ::c_long = 323; +pub const SYS_membarrier: ::c_long = 324; +pub const SYS_mlock2: ::c_long = 325; +pub const SYS_copy_file_range: ::c_long = 326; +pub const SYS_preadv2: ::c_long = 327; +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; +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; +pub const SYS_fchmodat2: ::c_long = 452; +pub const SYS_mseal: ::c_long = 462; + +// offsets in user_regs_structs, from sys/reg.h +pub const R15: ::c_int = 0; +pub const R14: ::c_int = 1; +pub const R13: ::c_int = 2; +pub const R12: ::c_int = 3; +pub const RBP: ::c_int = 4; +pub const RBX: ::c_int = 5; +pub const R11: ::c_int = 6; +pub const R10: ::c_int = 7; +pub const R9: ::c_int = 8; +pub const R8: ::c_int = 9; +pub const RAX: ::c_int = 10; +pub const RCX: ::c_int = 11; +pub const RDX: ::c_int = 12; +pub const RSI: ::c_int = 13; +pub const RDI: ::c_int = 14; +pub const ORIG_RAX: ::c_int = 15; +pub const RIP: ::c_int = 16; +pub const CS: ::c_int = 17; +pub const EFLAGS: ::c_int = 18; +pub const RSP: ::c_int = 19; +pub const SS: ::c_int = 20; +pub const FS_BASE: ::c_int = 21; +pub const GS_BASE: ::c_int = 22; +pub const DS: ::c_int = 23; +pub const ES: ::c_int = 24; +pub const FS: ::c_int = 25; +pub const GS: ::c_int = 26; + +// offsets in mcontext_t.gregs from bits/signal.h +// GitHub repo: ifduyue/musl/ +// commit: b4b1e10364c8737a632be61582e05a8d3acf5690 +// file: arch/x86_64/bits/signal.h#L9-L56 +pub const REG_R8: ::c_int = 0; +pub const REG_R9: ::c_int = 1; +pub const REG_R10: ::c_int = 2; +pub const REG_R11: ::c_int = 3; +pub const REG_R12: ::c_int = 4; +pub const REG_R13: ::c_int = 5; +pub const REG_R14: ::c_int = 6; +pub const REG_R15: ::c_int = 7; +pub const REG_RDI: ::c_int = 8; +pub const REG_RSI: ::c_int = 9; +pub const REG_RBP: ::c_int = 10; +pub const REG_RBX: ::c_int = 11; +pub const REG_RDX: ::c_int = 12; +pub const REG_RAX: ::c_int = 13; +pub const REG_RCX: ::c_int = 14; +pub const REG_RSP: ::c_int = 15; +pub const REG_RIP: ::c_int = 16; +pub const REG_EFL: ::c_int = 17; +pub const REG_CSGSFS: ::c_int = 18; +pub const REG_ERR: ::c_int = 19; +pub const REG_TRAPNO: ::c_int = 20; +pub const REG_OLDMASK: ::c_int = 21; +pub const REG_CR2: ::c_int = 22; + +pub const MADV_SOFT_OFFLINE: ::c_int = 101; +pub const MAP_32BIT: ::c_int = 0x0040; +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 PTRACE_SYSEMU: ::c_int = 31; +pub const PTRACE_SYSEMU_SINGLESTEP: ::c_int = 32; + +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 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 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 ERFKILL: ::c_int = 132; +pub const EHWPOISON: ::c_int = 133; + +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 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 MCL_ONFAULT: ::c_int = 0x0004; +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; + +cfg_if! { + if #[cfg(libc_align)] { + mod align; + pub use self::align::*; + } +} diff --git a/vendor/libc/src/unix/linux_like/linux/musl/lfs64.rs b/vendor/libc/src/unix/linux_like/linux/musl/lfs64.rs new file mode 100644 index 0000000..27c1d25 --- /dev/null +++ b/vendor/libc/src/unix/linux_like/linux/musl/lfs64.rs @@ -0,0 +1,241 @@ +#[inline] +pub unsafe extern "C" fn creat64(path: *const ::c_char, mode: ::mode_t) -> ::c_int { + ::creat(path, mode) +} + +#[inline] +pub unsafe extern "C" fn fallocate64( + fd: ::c_int, + mode: ::c_int, + offset: ::off64_t, + len: ::off64_t, +) -> ::c_int { + ::fallocate(fd, mode, offset, len) +} + +#[inline] +pub unsafe extern "C" fn fgetpos64(stream: *mut ::FILE, pos: *mut ::fpos64_t) -> ::c_int { + ::fgetpos(stream, pos as *mut _) +} + +#[inline] +pub unsafe extern "C" fn fopen64(pathname: *const ::c_char, mode: *const ::c_char) -> *mut ::FILE { + ::fopen(pathname, mode) +} + +#[inline] +pub unsafe extern "C" fn freopen64( + pathname: *const ::c_char, + mode: *const ::c_char, + stream: *mut ::FILE, +) -> *mut ::FILE { + ::freopen(pathname, mode, stream) +} + +#[inline] +pub unsafe extern "C" fn fseeko64( + stream: *mut ::FILE, + offset: ::off64_t, + whence: ::c_int, +) -> ::c_int { + ::fseeko(stream, offset, whence) +} + +#[inline] +pub unsafe extern "C" fn fsetpos64(stream: *mut ::FILE, pos: *const ::fpos64_t) -> ::c_int { + ::fsetpos(stream, pos as *mut _) +} + +#[inline] +pub unsafe extern "C" fn fstat64(fildes: ::c_int, buf: *mut ::stat64) -> ::c_int { + ::fstat(fildes, buf as *mut _) +} + +#[inline] +pub unsafe extern "C" fn fstatat64( + fd: ::c_int, + path: *const ::c_char, + buf: *mut ::stat64, + flag: ::c_int, +) -> ::c_int { + ::fstatat(fd, path, buf as *mut _, flag) +} + +#[inline] +pub unsafe extern "C" fn fstatfs64(fd: ::c_int, buf: *mut ::statfs64) -> ::c_int { + ::fstatfs(fd, buf as *mut _) +} + +#[inline] +pub unsafe extern "C" fn fstatvfs64(fd: ::c_int, buf: *mut ::statvfs64) -> ::c_int { + ::fstatvfs(fd, buf as *mut _) +} + +#[inline] +pub unsafe extern "C" fn ftello64(stream: *mut ::FILE) -> ::off64_t { + ::ftello(stream) +} + +#[inline] +pub unsafe extern "C" fn ftruncate64(fd: ::c_int, length: ::off64_t) -> ::c_int { + ::ftruncate(fd, length) +} + +#[inline] +pub unsafe extern "C" fn getrlimit64(resource: ::c_int, rlim: *mut ::rlimit64) -> ::c_int { + ::getrlimit(resource, rlim as *mut _) +} + +#[inline] +pub unsafe extern "C" fn lseek64(fd: ::c_int, offset: ::off64_t, whence: ::c_int) -> ::off64_t { + ::lseek(fd, offset, whence) +} + +#[inline] +pub unsafe extern "C" fn lstat64(path: *const ::c_char, buf: *mut ::stat64) -> ::c_int { + ::lstat(path, buf as *mut _) +} + +#[inline] +pub unsafe extern "C" fn mmap64( + addr: *mut ::c_void, + length: ::size_t, + prot: ::c_int, + flags: ::c_int, + fd: ::c_int, + offset: ::off64_t, +) -> *mut ::c_void { + ::mmap(addr, length, prot, flags, fd, offset) +} + +// These functions are variadic in the C ABI since the `mode` argument is "optional". Variadic +// `extern "C"` functions are unstable in Rust so we cannot write a shim function for these +// entrypoints. See https://github.com/rust-lang/rust/issues/44930. +// +// These aliases are mostly fine though, neither function takes a LFS64-namespaced type as an +// argument, nor do their names clash with any declared types. +pub use open as open64; +pub use openat as openat64; + +#[inline] +pub unsafe extern "C" fn posix_fadvise64( + fd: ::c_int, + offset: ::off64_t, + len: ::off64_t, + advice: ::c_int, +) -> ::c_int { + ::posix_fadvise(fd, offset, len, advice) +} + +#[inline] +pub unsafe extern "C" fn posix_fallocate64( + fd: ::c_int, + offset: ::off64_t, + len: ::off64_t, +) -> ::c_int { + ::posix_fallocate(fd, offset, len) +} + +#[inline] +pub unsafe extern "C" fn pread64( + fd: ::c_int, + buf: *mut ::c_void, + count: ::size_t, + offset: ::off64_t, +) -> ::ssize_t { + ::pread(fd, buf, count, offset) +} + +#[inline] +pub unsafe extern "C" fn preadv64( + fd: ::c_int, + iov: *const ::iovec, + iovcnt: ::c_int, + offset: ::off64_t, +) -> ::ssize_t { + ::preadv(fd, iov, iovcnt, offset) +} + +#[inline] +pub unsafe extern "C" fn prlimit64( + pid: ::pid_t, + resource: ::c_int, + new_limit: *const ::rlimit64, + old_limit: *mut ::rlimit64, +) -> ::c_int { + ::prlimit(pid, resource, new_limit as *mut _, old_limit as *mut _) +} + +#[inline] +pub unsafe extern "C" fn pwrite64( + fd: ::c_int, + buf: *const ::c_void, + count: ::size_t, + offset: ::off64_t, +) -> ::ssize_t { + ::pwrite(fd, buf, count, offset) +} + +#[inline] +pub unsafe extern "C" fn pwritev64( + fd: ::c_int, + iov: *const ::iovec, + iovcnt: ::c_int, + offset: ::off64_t, +) -> ::ssize_t { + ::pwritev(fd, iov, iovcnt, offset) +} + +#[inline] +pub unsafe extern "C" fn readdir64(dirp: *mut ::DIR) -> *mut ::dirent64 { + ::readdir(dirp) as *mut _ +} + +#[inline] +pub unsafe extern "C" fn readdir64_r( + dirp: *mut ::DIR, + entry: *mut ::dirent64, + result: *mut *mut ::dirent64, +) -> ::c_int { + ::readdir_r(dirp, entry as *mut _, result as *mut _) +} + +#[inline] +pub unsafe extern "C" fn sendfile64( + out_fd: ::c_int, + in_fd: ::c_int, + offset: *mut ::off64_t, + count: ::size_t, +) -> ::ssize_t { + ::sendfile(out_fd, in_fd, offset, count) +} + +#[inline] +pub unsafe extern "C" fn setrlimit64(resource: ::c_int, rlim: *const ::rlimit64) -> ::c_int { + ::setrlimit(resource, rlim as *mut _) +} + +#[inline] +pub unsafe extern "C" fn stat64(pathname: *const ::c_char, statbuf: *mut ::stat64) -> ::c_int { + ::stat(pathname, statbuf as *mut _) +} + +#[inline] +pub unsafe extern "C" fn statfs64(pathname: *const ::c_char, buf: *mut ::statfs64) -> ::c_int { + ::statfs(pathname, buf as *mut _) +} + +#[inline] +pub unsafe extern "C" fn statvfs64(path: *const ::c_char, buf: *mut ::statvfs64) -> ::c_int { + ::statvfs(path, buf as *mut _) +} + +#[inline] +pub unsafe extern "C" fn tmpfile64() -> *mut ::FILE { + ::tmpfile() +} + +#[inline] +pub unsafe extern "C" fn truncate64(path: *const ::c_char, length: ::off64_t) -> ::c_int { + ::truncate(path, length) +} diff --git a/vendor/libc/src/unix/linux_like/linux/musl/mod.rs b/vendor/libc/src/unix/linux_like/linux/musl/mod.rs new file mode 100644 index 0000000..14e1e6d --- /dev/null +++ b/vendor/libc/src/unix/linux_like/linux/musl/mod.rs @@ -0,0 +1,1022 @@ +pub type pthread_t = *mut ::c_void; +pub type clock_t = c_long; +#[cfg_attr( + not(feature = "rustc-dep-of-std"), + deprecated( + since = "0.2.80", + note = "This type is changed to 64-bit in musl 1.2.0, \ + we'll follow that change in the future release. \ + See #1848 for more info." + ) +)] +pub type time_t = c_long; +pub type suseconds_t = c_long; +pub type ino_t = u64; +pub type off_t = i64; +pub type blkcnt_t = i64; + +pub type shmatt_t = ::c_ulong; +pub type msgqnum_t = ::c_ulong; +pub type msglen_t = ::c_ulong; +pub type fsblkcnt_t = ::c_ulonglong; +pub type fsfilcnt_t = ::c_ulonglong; +pub type rlim_t = ::c_ulonglong; + +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)] + 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 + } +} + +cfg_if! { + if #[cfg(libc_union)] { + // Internal, for casts to access union fields + #[repr(C)] + struct sifields_sigchld { + si_pid: ::pid_t, + si_uid: ::uid_t, + si_status: ::c_int, + si_utime: ::c_long, + si_stime: ::c_long, + } + impl ::Copy for sifields_sigchld {} + impl ::Clone for sifields_sigchld { + fn clone(&self) -> sifields_sigchld { + *self + } + } + + // Internal, for casts to access union fields + #[repr(C)] + union sifields { + _align_pointer: *mut ::c_void, + sigchld: sifields_sigchld, + } + + // Internal, for casts to access union fields. Note that some variants + // of sifields start with a pointer, which makes the alignment of + // sifields vary on 32-bit and 64-bit architectures. + #[repr(C)] + struct siginfo_f { + _siginfo_base: [::c_int; 3], + sifields: sifields, + } + + impl siginfo_t { + unsafe fn sifields(&self) -> &sifields { + &(*(self as *const siginfo_t as *const siginfo_f)).sifields + } + + pub unsafe fn si_pid(&self) -> ::pid_t { + self.sifields().sigchld.si_pid + } + + pub unsafe fn si_uid(&self) -> ::uid_t { + self.sifields().sigchld.si_uid + } + + pub unsafe fn si_status(&self) -> ::c_int { + self.sifields().sigchld.si_status + } + + pub unsafe fn si_utime(&self) -> ::c_long { + self.sifields().sigchld.si_utime + } + + pub unsafe fn si_stime(&self) -> ::c_long { + self.sifields().sigchld.si_stime + } + } + } +} + +s! { + pub struct aiocb { + pub aio_fildes: ::c_int, + pub aio_lio_opcode: ::c_int, + pub aio_reqprio: ::c_int, + pub aio_buf: *mut ::c_void, + pub aio_nbytes: ::size_t, + pub aio_sigevent: ::sigevent, + __td: *mut ::c_void, + __lock: [::c_int; 2], + __err: ::c_int, + __ret: ::ssize_t, + pub aio_offset: off_t, + __next: *mut ::c_void, + __prev: *mut ::c_void, + #[cfg(target_pointer_width = "32")] + __dummy4: [::c_char; 24], + #[cfg(target_pointer_width = "64")] + __dummy4: [::c_char; 16], + } + + pub struct sigaction { + pub sa_sigaction: ::sighandler_t, + pub sa_mask: ::sigset_t, + pub sa_flags: ::c_int, + pub sa_restorer: ::Option, + } + + 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, + #[cfg(target_endian = "little")] + pub f_fsid: ::c_ulong, + #[cfg(target_pointer_width = "32")] + __f_unused: ::c_int, + #[cfg(target_endian = "big")] + pub f_fsid: ::c_ulong, + pub f_flag: ::c_ulong, + pub f_namemax: ::c_ulong, + __f_spare: [::c_int; 6], + } + + pub struct termios { + pub c_iflag: ::tcflag_t, + pub c_oflag: ::tcflag_t, + pub c_cflag: ::tcflag_t, + pub c_lflag: ::tcflag_t, + pub c_line: ::cc_t, + pub c_cc: [::cc_t; ::NCCS], + pub __c_ispeed: ::speed_t, + pub __c_ospeed: ::speed_t, + } + + pub struct 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 regex_t { + __re_nsub: ::size_t, + __opaque: *mut ::c_void, + __padding: [*mut ::c_void; 4usize], + __nsub2: ::size_t, + __padding2: ::c_char, + } + + 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; 1usize], + 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 Elf64_Chdr { + pub ch_type: ::Elf64_Word, + pub ch_reserved: ::Elf64_Word, + pub ch_size: ::Elf64_Xword, + pub ch_addralign: ::Elf64_Xword, + } + + pub struct Elf32_Chdr { + pub ch_type: ::Elf32_Word, + 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, + } + + // linux/if_xdp.h + + pub struct sockaddr_xdp { + pub sxdp_family: ::__u16, + pub sxdp_flags: ::__u16, + pub sxdp_ifindex: ::__u32, + pub sxdp_queue_id: ::__u32, + pub sxdp_shared_umem_fd: ::__u32, + } + + pub struct xdp_ring_offset { + pub producer: ::__u64, + pub consumer: ::__u64, + pub desc: ::__u64, + pub flags: ::__u64, + } + + pub struct xdp_mmap_offsets { + pub rx: xdp_ring_offset, + pub tx: xdp_ring_offset, + pub fr: xdp_ring_offset, + pub cr: xdp_ring_offset, + } + + pub struct xdp_ring_offset_v1 { + pub producer: ::__u64, + pub consumer: ::__u64, + pub desc: ::__u64, + } + + pub struct xdp_mmap_offsets_v1 { + pub rx: xdp_ring_offset_v1, + pub tx: xdp_ring_offset_v1, + pub fr: xdp_ring_offset_v1, + pub cr: xdp_ring_offset_v1, + } + + pub struct xdp_umem_reg { + pub addr: ::__u64, + pub len: ::__u64, + pub chunk_size: ::__u32, + pub headroom: ::__u32, + pub flags: ::__u32, + } + + pub struct xdp_umem_reg_v1 { + pub addr: ::__u64, + pub len: ::__u64, + pub chunk_size: ::__u32, + pub headroom: ::__u32, + } + + pub struct xdp_statistics { + pub rx_dropped: ::__u64, + pub rx_invalid_descs: ::__u64, + pub tx_invalid_descs: ::__u64, + pub rx_ring_full: ::__u64, + pub rx_fill_ring_empty_descs: ::__u64, + pub tx_ring_empty_descs: ::__u64, + } + + pub struct xdp_statistics_v1 { + pub rx_dropped: ::__u64, + pub rx_invalid_descs: ::__u64, + pub tx_invalid_descs: ::__u64, + } + + pub struct xdp_options { + pub flags: ::__u32, + } + + pub struct xdp_desc { + pub addr: ::__u64, + pub len: ::__u32, + pub options: ::__u32, + } + + // netinet/tcp.h + + 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, + /* + * FIXME(musl): when musl headers are more up to date + /// This contains the bitfields `tcpi_snd_wscale` and `tcpi_rcv_wscale`. + /// Each is 4 bits. + pub tcpi_snd_rcv_wscale: u8, + /// This contains the bitfields `tcpi_delivery_rate_app_limited` (1 bit) and + /// `tcpi_fastopen_client_fail` (2 bits). + pub tcpi_delivery_fastopen_bitfields: 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_total_retrans: u32, + pub tcpi_pacing_rate: u64, + pub tcpi_max_pacing_rate: u64, + pub tcpi_bytes_acked: u64, + pub tcpi_bytes_received: u64, + pub tcpi_segs_out: u32, + pub tcpi_segs_in: u32, + pub tcpi_notsent_bytes: u32, + pub tcpi_min_rtt: u32, + pub tcpi_data_segs_in: u32, + pub tcpi_data_segs_out: u32, + pub tcpi_delivery_rate: u64, + pub tcpi_busy_time: u64, + pub tcpi_rwnd_limited: u64, + pub tcpi_sndbuf_limited: u64, + pub tcpi_delivered: u32, + pub tcpi_delivered_ce: u32, + pub tcpi_bytes_sent: u64, + pub tcpi_bytes_retrans: u64, + pub tcpi_dsack_dups: u32, + pub tcpi_reord_seen: u32, + // FIXME(musl): to uncomment once CI musl is updated + //pub tcpi_rcv_ooopack: u32, + //pub tcpi_snd_wnd: u32, + } +} + +s_no_extra_traits! { + pub struct sysinfo { + pub uptime: ::c_ulong, + pub loads: [::c_ulong; 3], + pub totalram: ::c_ulong, + pub freeram: ::c_ulong, + pub sharedram: ::c_ulong, + pub bufferram: ::c_ulong, + pub totalswap: ::c_ulong, + pub freeswap: ::c_ulong, + pub procs: ::c_ushort, + pub pad: ::c_ushort, + pub totalhigh: ::c_ulong, + pub freehigh: ::c_ulong, + pub mem_unit: ::c_uint, + pub __reserved: [::c_char; 256], + } + + // 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 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, + pub ut_pid: ::pid_t, + pub ut_line: [::c_char; 32], + pub ut_id: [::c_char; 4], + pub ut_user: [::c_char; 32], + pub ut_host: [::c_char; 256], + pub ut_exit: __exit_status, + + #[cfg(target_env = "musl")] + pub ut_session: ::c_long, + + #[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], + __unused: [::c_char; 20], + } +} + +cfg_if! { + if #[cfg(feature = "extra_traits")] { + impl PartialEq for sysinfo { + fn eq(&self, other: &sysinfo) -> bool { + self.uptime == other.uptime + && self.loads == other.loads + && self.totalram == other.totalram + && self.freeram == other.freeram + && self.sharedram == other.sharedram + && self.bufferram == other.bufferram + && self.totalswap == other.totalswap + && self.freeswap == other.freeswap + && self.procs == other.procs + && self.pad == other.pad + && self.totalhigh == other.totalhigh + && self.freehigh == other.freehigh + && self.mem_unit == other.mem_unit + && self + .__reserved + .iter() + .zip(other.__reserved.iter()) + .all(|(a,b)| a == b) + } + } + + impl Eq for sysinfo {} + + impl ::fmt::Debug for sysinfo { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("sysinfo") + .field("uptime", &self.uptime) + .field("loads", &self.loads) + .field("totalram", &self.totalram) + .field("freeram", &self.freeram) + .field("sharedram", &self.sharedram) + .field("bufferram", &self.bufferram) + .field("totalswap", &self.totalswap) + .field("freeswap", &self.freeswap) + .field("procs", &self.procs) + .field("pad", &self.pad) + .field("totalhigh", &self.totalhigh) + .field("freehigh", &self.freehigh) + .field("mem_unit", &self.mem_unit) + // FIXME: .field("__reserved", &self.__reserved) + .finish() + } + } + + impl ::hash::Hash for sysinfo { + fn hash(&self, state: &mut H) { + self.uptime.hash(state); + self.loads.hash(state); + self.totalram.hash(state); + self.freeram.hash(state); + self.sharedram.hash(state); + self.bufferram.hash(state); + self.totalswap.hash(state); + self.freeswap.hash(state); + self.procs.hash(state); + self.pad.hash(state); + self.totalhigh.hash(state); + self.freehigh.hash(state); + self.mem_unit.hash(state); + self.__reserved.hash(state); + } + } + + impl PartialEq for utmpx { + fn eq(&self, other: &utmpx) -> bool { + self.ut_type == other.ut_type + //&& self.__ut_pad1 == other.__ut_pad1 + && self.ut_pid == other.ut_pid + && self.ut_line == other.ut_line + && self.ut_id == other.ut_id + && self.ut_user == other.ut_user + && self + .ut_host + .iter() + .zip(other.ut_host.iter()) + .all(|(a,b)| a == b) + && self.ut_exit == other.ut_exit + && self.ut_session == other.ut_session + //&& self.__ut_pad2 == other.__ut_pad2 + && self.ut_tv == other.ut_tv + && self.ut_addr_v6 == other.ut_addr_v6 + && self.__unused == other.__unused + } + } + + 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_pad1", &self.__ut_pad1) + .field("ut_pid", &self.ut_pid) + .field("ut_line", &self.ut_line) + .field("ut_id", &self.ut_id) + .field("ut_user", &self.ut_user) + //FIXME: .field("ut_host", &self.ut_host) + .field("ut_exit", &self.ut_exit) + .field("ut_session", &self.ut_session) + //.field("__ut_pad2", &self.__ut_pad2) + .field("ut_tv", &self.ut_tv) + .field("ut_addr_v6", &self.ut_addr_v6) + .field("__unused", &self.__unused) + .finish() + } + } + + impl ::hash::Hash for utmpx { + fn hash(&self, state: &mut H) { + self.ut_type.hash(state); + //self.__ut_pad1.hash(state); + self.ut_pid.hash(state); + self.ut_line.hash(state); + self.ut_id.hash(state); + self.ut_user.hash(state); + self.ut_host.hash(state); + self.ut_exit.hash(state); + self.ut_session.hash(state); + //self.__ut_pad2.hash(state); + self.ut_tv.hash(state); + self.ut_addr_v6.hash(state); + self.__unused.hash(state); + } + } + } +} + +// include/sys/mman.h +/* + * Huge page size encoding when MAP_HUGETLB is specified, and a huge page + * size other than the default is desired. See hugetlb_encode.h. + * All known huge page size encodings are provided here. It is the + * responsibility of the application to know which sizes are supported on + * the running system. See mmap(2) man page for details. + */ +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 MS_RMT_MASK: ::c_ulong = 0x02800051; + +// include/utmpx.h +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 = 3; +pub const OLD_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; +// musl does not define ACCOUNTING + +pub const SFD_CLOEXEC: ::c_int = 0x080000; + +pub const NCCS: usize = 32; + +pub const O_TRUNC: ::c_int = 512; +pub const O_NOATIME: ::c_int = 0o1000000; +pub const O_CLOEXEC: ::c_int = 0x80000; +pub const O_TMPFILE: ::c_int = 0o20000000 | O_DIRECTORY; + +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 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_WRLCK: ::c_int = 1; +pub const F_UNLCK: ::c_int = 2; + +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 EPOLL_CLOEXEC: ::c_int = 0x80000; + +pub const EFD_CLOEXEC: ::c_int = 0x80000; + +pub const BUFSIZ: ::c_uint = 1024; +pub const TMP_MAX: ::c_uint = 10000; +pub const FOPEN_MAX: ::c_uint = 1000; +pub const FILENAME_MAX: ::c_uint = 4096; +pub const O_PATH: ::c_int = 0o10000000; +pub const O_EXEC: ::c_int = 0o10000000; +pub const O_SEARCH: ::c_int = 0o10000000; +pub const O_ACCMODE: ::c_int = 0o10000003; +pub const O_NDELAY: ::c_int = O_NONBLOCK; +pub const NI_MAXHOST: ::socklen_t = 255; +pub const PTHREAD_STACK_MIN: ::size_t = 2048; + +pub const POSIX_MADV_DONTNEED: ::c_int = 4; + +pub const MAP_ANONYMOUS: ::c_int = MAP_ANON; + +pub const SOCK_SEQPACKET: ::c_int = 5; +pub const SOCK_DCCP: ::c_int = 6; +pub const SOCK_NONBLOCK: ::c_int = O_NONBLOCK; +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; + +pub const PTRACE_TRACEME: ::c_int = 0; +pub const PTRACE_PEEKTEXT: ::c_int = 1; +pub const PTRACE_PEEKDATA: ::c_int = 2; +pub const PTRACE_PEEKUSER: ::c_int = 3; +pub const PTRACE_POKETEXT: ::c_int = 4; +pub const PTRACE_POKEDATA: ::c_int = 5; +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_GETFPREGS: ::c_int = 14; +pub const PTRACE_SETFPREGS: ::c_int = 15; +pub const PTRACE_ATTACH: ::c_int = 16; +pub const PTRACE_DETACH: ::c_int = 17; +pub const PTRACE_GETFPXREGS: ::c_int = 18; +pub const PTRACE_SETFPXREGS: ::c_int = 19; +pub const PTRACE_SYSCALL: ::c_int = 24; +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_SEIZE: ::c_int = 0x4206; +pub const PTRACE_INTERRUPT: ::c_int = 0x4207; +pub const PTRACE_LISTEN: ::c_int = 0x4208; +pub const PTRACE_PEEKSIGINFO: ::c_int = 0x4209; +pub const PTRACE_GETSIGMASK: ::c_uint = 0x420a; +pub const PTRACE_SETSIGMASK: ::c_uint = 0x420b; + +pub const RWF_HIPRI: ::c_int = 0x00000001; +pub const RWF_DSYNC: ::c_int = 0x00000002; +pub const RWF_SYNC: ::c_int = 0x00000004; +pub const RWF_NOWAIT: ::c_int = 0x00000008; +pub const RWF_APPEND: ::c_int = 0x00000010; + +pub const AF_IB: ::c_int = 27; +pub const AF_MPLS: ::c_int = 28; +pub const AF_NFC: ::c_int = 39; +pub const AF_VSOCK: ::c_int = 40; +pub const AF_XDP: ::c_int = 44; +pub const PF_IB: ::c_int = AF_IB; +pub const PF_MPLS: ::c_int = AF_MPLS; +pub const PF_NFC: ::c_int = AF_NFC; +pub const PF_VSOCK: ::c_int = AF_VSOCK; +pub const PF_XDP: ::c_int = AF_XDP; + +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; + +pub const RTLD_GLOBAL: ::c_int = 0x100; +pub const RTLD_NOLOAD: ::c_int = 0x4; + +pub const CLOCK_SGI_CYCLE: ::clockid_t = 10; + +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 REG_OK: ::c_int = 0; + +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; + +pub const SOL_XDP: ::c_int = 283; + +// linux/if_xdp.h +pub const XDP_SHARED_UMEM: ::__u16 = 1 << 0; +pub const XDP_COPY: ::__u16 = 1 << 1; +pub const XDP_ZEROCOPY: ::__u16 = 1 << 2; +pub const XDP_USE_NEED_WAKEUP: ::__u16 = 1 << 3; +pub const XDP_USE_SG: ::__u16 = 1 << 4; + +pub const XDP_UMEM_UNALIGNED_CHUNK_FLAG: ::__u32 = 1 << 0; + +pub const XDP_RING_NEED_WAKEUP: ::__u32 = 1 << 0; + +pub const XDP_MMAP_OFFSETS: ::c_int = 1; +pub const XDP_RX_RING: ::c_int = 2; +pub const XDP_TX_RING: ::c_int = 3; +pub const XDP_UMEM_REG: ::c_int = 4; +pub const XDP_UMEM_FILL_RING: ::c_int = 5; +pub const XDP_UMEM_COMPLETION_RING: ::c_int = 6; +pub const XDP_STATISTICS: ::c_int = 7; +pub const XDP_OPTIONS: ::c_int = 8; + +pub const XDP_OPTIONS_ZEROCOPY: ::__u32 = 1 << 0; + +pub const XDP_PGOFF_RX_RING: ::off_t = 0; +pub const XDP_PGOFF_TX_RING: ::off_t = 0x80000000; +pub const XDP_UMEM_PGOFF_FILL_RING: ::c_ulonglong = 0x100000000; +pub const XDP_UMEM_PGOFF_COMPLETION_RING: ::c_ulonglong = 0x180000000; + +pub const XSK_UNALIGNED_BUF_OFFSET_SHIFT: ::c_int = 48; +pub const XSK_UNALIGNED_BUF_ADDR_MASK: ::c_ulonglong = (1 << XSK_UNALIGNED_BUF_OFFSET_SHIFT) - 1; + +pub const XDP_PKT_CONTD: ::__u32 = 1 << 0; + +cfg_if! { + if #[cfg(target_arch = "s390x")] { + pub const POSIX_FADV_DONTNEED: ::c_int = 6; + pub const POSIX_FADV_NOREUSE: ::c_int = 7; + } else { + pub const POSIX_FADV_DONTNEED: ::c_int = 4; + pub const POSIX_FADV_NOREUSE: ::c_int = 5; + } +} + +extern "C" { + 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 getrlimit(resource: ::c_int, rlim: *mut ::rlimit) -> ::c_int; + pub fn setrlimit(resource: ::c_int, rlim: *const ::rlimit) -> ::c_int; + pub fn prlimit( + pid: ::pid_t, + resource: ::c_int, + new_limit: *const ::rlimit, + old_limit: *mut ::rlimit, + ) -> ::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; + // 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`. + pub fn fanotify_mark( + fd: ::c_int, + flags: ::c_uint, + mask: ::c_ulonglong, + dirfd: ::c_int, + path: *const ::c_char, + ) -> ::c_int; + pub fn preadv2( + fd: ::c_int, + iov: *const ::iovec, + iovcnt: ::c_int, + offset: ::off_t, + flags: ::c_int, + ) -> ::ssize_t; + pub fn pwritev2( + fd: ::c_int, + iov: *const ::iovec, + iovcnt: ::c_int, + offset: ::off_t, + flags: ::c_int, + ) -> ::ssize_t; + pub fn getauxval(type_: ::c_ulong) -> ::c_ulong; + + // 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 dirname(path: *mut ::c_char) -> *mut ::c_char; + pub fn basename(path: *mut ::c_char) -> *mut ::c_char; + + // Added in `musl` 1.1.24 + pub fn posix_spawn_file_actions_addchdir_np( + actions: *mut ::posix_spawn_file_actions_t, + path: *const ::c_char, + ) -> ::c_int; + // Added in `musl` 1.1.24 + pub fn posix_spawn_file_actions_addfchdir_np( + actions: *mut ::posix_spawn_file_actions_t, + fd: ::c_int, + ) -> ::c_int; +} + +// Alias to 64 to mimic glibc's LFS64 support +mod lfs64; +pub use self::lfs64::*; + +cfg_if! { + if #[cfg(any(target_arch = "x86_64", + target_arch = "aarch64", + target_arch = "mips64", + target_arch = "powerpc64", + target_arch = "s390x", + target_arch = "riscv64", + target_arch = "loongarch64"))] { + 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::*; + } else { } +} diff --git a/vendor/libc/src/unix/linux_like/linux/no_align.rs b/vendor/libc/src/unix/linux_like/linux/no_align.rs new file mode 100644 index 0000000..f81d046 --- /dev/null +++ b/vendor/libc/src/unix/linux_like/linux/no_align.rs @@ -0,0 +1,162 @@ +macro_rules! expand_align { + () => { + s! { + pub struct pthread_mutexattr_t { + #[cfg(any(target_arch = "x86_64", + target_arch = "powerpc64", + target_arch = "mips64", + target_arch = "mips64r6", + target_arch = "s390x", + target_arch = "sparc64", + target_arch = "riscv64", + target_arch = "riscv32", + target_arch = "loongarch64", + all(target_arch = "aarch64", + any(target_env = "musl", target_env = "ohos"))))] + __align: [::c_int; 0], + #[cfg(not(any(target_arch = "x86_64", + target_arch = "powerpc64", + target_arch = "mips64", + target_arch = "mips64r6", + target_arch = "s390x", + target_arch = "sparc64", + target_arch = "riscv64", + target_arch = "riscv32", + target_arch = "loongarch64", + all(target_arch = "aarch64", + any(target_env = "musl", target_env = "ohos")))))] + __align: [::c_long; 0], + size: [u8; ::__SIZEOF_PTHREAD_MUTEXATTR_T], + } + + pub struct pthread_rwlockattr_t { + #[cfg(any(target_env = "musl", target_env = "ohos"))] + __align: [::c_int; 0], + #[cfg(not(any(target_env = "musl", target_env = "ohos")))] + __align: [::c_long; 0], + size: [u8; ::__SIZEOF_PTHREAD_RWLOCKATTR_T], + } + + pub struct pthread_condattr_t { + __align: [::c_int; 0], + 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, + pub vers: __u8, + pub reserved: __u8, + pub metadata_len: __u16, + pub mask: __u64, + pub fd: ::c_int, + pub pid: ::c_int, + } + + pub struct tpacket_rollover_stats { + __align: [::c_long; 0], + pub tp_all: ::__u64, + pub tp_huge: ::__u64, + pub tp_failed: ::__u64, + } + + pub struct tpacket_hdr_v1 { + __align: [::c_long; 0], + pub block_status: ::__u32, + pub num_pkts: ::__u32, + pub offset_to_first_pkt: ::__u32, + pub blk_len: ::__u32, + pub seq_num: ::__u64, + pub ts_first_pkt: ::tpacket_bd_ts, + pub ts_last_pkt: ::tpacket_bd_ts, + } + } + + s_no_extra_traits! { + pub struct pthread_cond_t { + #[cfg(any(target_env = "musl", target_env = "ohos"))] + __align: [*const ::c_void; 0], + #[cfg(not(any(target_env = "musl", target_env = "ohos")))] + __align: [::c_longlong; 0], + size: [u8; ::__SIZEOF_PTHREAD_COND_T], + } + + pub struct pthread_mutex_t { + #[cfg(any(target_arch = "mips", + target_arch = "mips32r6", + target_arch = "arm", + target_arch = "m68k", + target_arch = "csky", + 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 = "mips32r6", + target_arch = "arm", + target_arch = "m68k", + target_arch = "csky", + target_arch = "powerpc", + target_arch = "sparc", + all(target_arch = "x86_64", + target_pointer_width = "32"))))] + __align: [::c_longlong; 0], + size: [u8; ::__SIZEOF_PTHREAD_MUTEX_T], + } + + pub struct pthread_rwlock_t { + #[cfg(any(target_arch = "mips", + target_arch = "mips32r6", + target_arch = "arm", + target_arch = "m68k", + target_arch = "csky", + 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 = "mips32r6", + target_arch = "arm", + target_arch = "m68k", + target_arch = "csky", + target_arch = "powerpc", + target_arch = "sparc", + all(target_arch = "x86_64", + target_pointer_width = "32"))))] + __align: [::c_longlong; 0], + size: [u8; ::__SIZEOF_PTHREAD_RWLOCK_T], + } + + pub struct pthread_barrier_t { + #[cfg(any(target_arch = "mips", + target_arch = "mips32r6", + target_arch = "arm", + target_arch = "m68k", + target_arch = "csky", + 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 = "mips32r6", + target_arch = "arm", + target_arch = "m68k", + target_arch = "csky", + 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/align.rs b/vendor/libc/src/unix/linux_like/linux/uclibc/align.rs new file mode 100644 index 0000000..e6610bb --- /dev/null +++ b/vendor/libc/src/unix/linux_like/linux/uclibc/align.rs @@ -0,0 +1,28 @@ +macro_rules! expand_align { + () => { + s! { + #[cfg_attr(any(target_pointer_width = "32", + target_arch = "x86_64", + target_arch = "powerpc64", + target_arch = "mips64", + target_arch = "s390x", + target_arch = "sparc64"), + repr(align(4)))] + #[cfg_attr(not(any(target_pointer_width = "32", + target_arch = "x86_64", + target_arch = "powerpc64", + target_arch = "mips64", + target_arch = "s390x", + target_arch = "sparc64")), + repr(align(8)))] + pub struct pthread_mutexattr_t { + size: [u8; ::__SIZEOF_PTHREAD_MUTEXATTR_T], + } + + #[repr(align(4))] + pub struct pthread_condattr_t { + size: [u8; ::__SIZEOF_PTHREAD_CONDATTR_T], + } + } + }; +} diff --git a/vendor/libc/src/unix/linux_like/linux/uclibc/arm/align.rs b/vendor/libc/src/unix/linux_like/linux/uclibc/arm/align.rs new file mode 100644 index 0000000..4a0e074 --- /dev/null +++ b/vendor/libc/src/unix/linux_like/linux/uclibc/arm/align.rs @@ -0,0 +1,13 @@ +s! { + // FIXME this is actually a union + #[cfg_attr(target_pointer_width = "32", + repr(align(4)))] + #[cfg_attr(target_pointer_width = "64", + repr(align(8)))] + pub struct sem_t { + #[cfg(target_pointer_width = "32")] + __size: [::c_char; 16], + #[cfg(target_pointer_width = "64")] + __size: [::c_char; 32], + } +} diff --git a/vendor/libc/src/unix/linux_like/linux/uclibc/arm/mod.rs b/vendor/libc/src/unix/linux_like/linux/uclibc/arm/mod.rs new file mode 100644 index 0000000..cff82f0 --- /dev/null +++ b/vendor/libc/src/unix/linux_like/linux/uclibc/arm/mod.rs @@ -0,0 +1,925 @@ +pub type c_char = u8; +pub type wchar_t = ::c_uint; +pub type c_long = i32; +pub type c_ulong = u32; +pub type time_t = ::c_long; + +pub type clock_t = ::c_long; +pub type fsblkcnt_t = ::c_ulong; +pub type fsfilcnt_t = ::c_ulong; +pub type ino_t = ::c_ulong; +pub type off_t = ::c_long; +pub type pthread_t = ::c_ulong; +pub type suseconds_t = ::c_long; + +pub type nlink_t = ::c_uint; +pub type blksize_t = ::c_long; +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 { + pub cmsg_len: ::size_t, + pub cmsg_level: ::c_int, + pub cmsg_type: ::c_int, + } + + pub struct msghdr { + pub msg_name: *mut ::c_void, + pub msg_namelen: ::socklen_t, + pub msg_iov: *mut ::iovec, + pub msg_iovlen: ::c_int, + pub msg_control: *mut ::c_void, + pub msg_controllen: ::socklen_t, + pub msg_flags: ::c_int, + } + + pub struct pthread_attr_t { + __size: [::c_long; 9], + } + + pub struct stat { + pub st_dev: ::c_ulonglong, + __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, + __pad2: ::c_ushort, + 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, + __unused4: ::c_ulong, + __unused5: ::c_ulong, + } + + pub struct stat64 + { + pub st_dev: ::c_ulonglong, + pub __pad1: ::c_uint, + pub __st_ino: ::ino_t, + pub st_mode: ::mode_t, + pub st_nlink: ::nlink_t, + pub st_uid: ::uid_t, + pub st_gid: ::gid_t, + pub st_rdev: ::c_ulonglong, + pub __pad2: ::c_uint, + pub st_size: ::off64_t, + pub st_blksize: ::blksize_t, + pub st_blocks: ::blkcnt64_t, + pub st_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_ino: ::ino64_t, + } + + pub struct flock { + pub l_type: ::c_short, + pub l_whence: ::c_short, + pub l_start: ::off_t, + pub l_len: ::off_t, + pub l_pid: ::pid_t, + } + + pub struct sysinfo { + pub uptime: ::c_long, + pub loads: [::c_ulong; 3], + pub totalram: ::c_ulong, + pub freeram: ::c_ulong, + pub sharedram: ::c_ulong, + pub bufferram: ::c_ulong, + pub totalswap: ::c_ulong, + pub freeswap: ::c_ulong, + pub procs: ::c_ushort, + pub pad: ::c_ushort, + pub totalhigh: ::c_ulong, + pub freehigh: ::c_ulong, + pub mem_unit: ::c_uint, + pub _f: [::c_char; 8], + } + + pub struct statfs { + pub f_type: ::c_int, + pub f_bsize: ::c_int, + pub f_blocks: ::fsblkcnt_t, + pub f_bfree: ::fsblkcnt_t, + pub f_bavail: ::fsblkcnt_t, + pub f_files: ::fsfilcnt_t, + pub f_ffree: ::fsfilcnt_t, + + pub f_fsid: ::fsid_t, + pub f_namelen: ::c_int, + pub f_frsize: ::c_int, + pub f_flags: ::c_int, + pub f_spare: [::c_int; 4], + } + + pub struct statfs64 { + pub f_type: ::c_int, + pub f_bsize: ::c_int, + 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_int, + pub f_frsize: ::c_int, + pub f_flags: ::c_int, + pub f_spare: [::c_int; 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 sigset_t { + __val: [::c_ulong; 2], + } + + pub struct sigaction { + pub sa_sigaction: ::sighandler_t, + pub sa_flags: ::c_ulong, + pub sa_restorer: ::Option, + pub sa_mask: sigset_t, + } + + pub struct termios { + pub c_iflag: ::tcflag_t, + pub c_oflag: ::tcflag_t, + pub c_cflag: ::tcflag_t, + pub c_lflag: ::tcflag_t, + pub c_line: ::cc_t, + pub c_cc: [::cc_t; ::NCCS], + pub c_ispeed: ::speed_t, + pub c_ospeed: ::speed_t, + } + + pub struct siginfo_t { + pub si_signo: ::c_int, + pub si_errno: ::c_int, + pub si_code: ::c_int, + pub _pad: [::c_int; 29], + } + + pub struct stack_t { + pub ss_sp: *mut ::c_void, + pub ss_flags: ::c_int, + pub ss_size: ::size_t, + } + + pub struct ipc_perm { + pub __key: ::key_t, + pub uid: ::uid_t, + pub gid: ::gid_t, + pub cuid: ::uid_t, + pub cgid: ::gid_t, + pub mode: ::c_ushort, + __pad1: ::c_ushort, + pub __seq: ::c_ushort, + __pad2: ::c_ushort, + __unused1: ::c_ulong, + __unused2: ::c_ulong, + } + + pub struct msqid_ds { + pub msg_perm: ::ipc_perm, + pub msg_stime: ::time_t, + __unused1: ::c_ulong, + pub msg_rtime: ::time_t, + __unused2: ::c_ulong, + pub msg_ctime: ::time_t, + __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, + __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, + __unused1: ::c_ulong, + pub shm_dtime: ::time_t, + __unused2: ::c_ulong, + pub shm_ctime: ::time_t, + __unused3: ::c_ulong, + pub shm_cpid: ::pid_t, + pub shm_lpid: ::pid_t, + pub shm_nattch: ::shmatt_t, + __unused4: ::c_ulong, + __unused5: ::c_ulong, + } +} + +pub const O_CLOEXEC: ::c_int = 0o2000000; +pub const __SIZEOF_PTHREAD_ATTR_T: usize = 36; +pub const __SIZEOF_PTHREAD_MUTEX_T: usize = 24; +pub const __SIZEOF_PTHREAD_MUTEXATTR_T: usize = 4; +pub const __SIZEOF_PTHREAD_COND_COMPAT_T: usize = 12; +pub const __SIZEOF_PTHREAD_CONDATTR_T: usize = 4; +pub const __SIZEOF_PTHREAD_RWLOCK_T: usize = 32; +pub const __SIZEOF_PTHREAD_RWLOCKATTR_T: usize = 8; +pub const __SIZEOF_PTHREAD_BARRIER_T: usize = 20; +pub const __SIZEOF_PTHREAD_BARRIERATTR_T: usize = 4; +pub const NCCS: usize = 32; + +// I wasn't able to find those constants +// in uclibc build environment for armv7 +pub const MAP_HUGETLB: ::c_int = 0x040000; // from linux/other/mod.rs + +// autogenerated constants with hand tuned types +pub const B0: ::speed_t = 0; +pub const B1000000: ::speed_t = 0x1008; +pub const B110: ::speed_t = 0x3; +pub const B115200: ::speed_t = 0x1002; +pub const B1152000: ::speed_t = 0x1009; +pub const B1200: ::speed_t = 0x9; +pub const B134: ::speed_t = 0x4; +pub const B150: ::speed_t = 0x5; +pub const B1500000: ::speed_t = 0x100a; +pub const B1800: ::speed_t = 0xa; +pub const B19200: ::speed_t = 0xe; +pub const B200: ::speed_t = 0x6; +pub const B2000000: ::speed_t = 0x100b; +pub const B230400: ::speed_t = 0x1003; +pub const B2400: ::speed_t = 0xb; +pub const B2500000: ::speed_t = 0x100c; +pub const B300: ::speed_t = 0x7; +pub const B3000000: ::speed_t = 0x100d; +pub const B3500000: ::speed_t = 0x100e; +pub const B38400: ::speed_t = 0xf; +pub const B4000000: ::speed_t = 0x100f; +pub const B460800: ::speed_t = 0x1004; +pub const B4800: ::speed_t = 0xc; +pub const B50: ::speed_t = 0x1; +pub const B500000: ::speed_t = 0x1005; +pub const B57600: ::speed_t = 0x1001; +pub const B576000: ::speed_t = 0x1006; +pub const B600: ::speed_t = 0x8; +pub const B75: ::speed_t = 0x2; +pub const B921600: ::speed_t = 0x1007; +pub const B9600: ::speed_t = 0xd; +pub const BS1: ::c_int = 0x2000; +pub const BSDLY: ::c_int = 0x2000; +pub const CBAUD: ::tcflag_t = 0x100f; +pub const CBAUDEX: ::tcflag_t = 0x1000; +pub const CIBAUD: ::tcflag_t = 0x100f0000; +pub const CLOCAL: ::tcflag_t = 0x800; +pub const CPU_SETSIZE: ::c_int = 0x400; +pub const CR1: ::c_int = 0x200; +pub const CR2: ::c_int = 0x400; +pub const CR3: ::c_int = 0x600; +pub const CRDLY: ::c_int = 0x600; +pub const CREAD: ::tcflag_t = 0x80; +pub const CS6: ::tcflag_t = 0x10; +pub const CS7: ::tcflag_t = 0x20; +pub const CS8: ::tcflag_t = 0x30; +pub const CSIZE: ::tcflag_t = 0x30; +pub const CSTOPB: ::tcflag_t = 0x40; +pub const EADDRINUSE: ::c_int = 0x62; +pub const EADDRNOTAVAIL: ::c_int = 0x63; +pub const EADV: ::c_int = 0x44; +pub const EAFNOSUPPORT: ::c_int = 0x61; +pub const EALREADY: ::c_int = 0x72; +pub const EBADE: ::c_int = 0x34; +pub const EBADFD: ::c_int = 0x4d; +pub const EBADMSG: ::c_int = 0x4a; +pub const EBADR: ::c_int = 0x35; +pub const EBADRQC: ::c_int = 0x38; +pub const EBADSLT: ::c_int = 0x39; +pub const EBFONT: ::c_int = 0x3b; +pub const ECANCELED: ::c_int = 0x7d; +pub const ECHOCTL: ::tcflag_t = 0x200; +pub const ECHOE: ::tcflag_t = 0x10; +pub const ECHOK: ::tcflag_t = 0x20; +pub const ECHOKE: ::tcflag_t = 0x800; +pub const ECHONL: ::tcflag_t = 0x40; +pub const ECHOPRT: ::tcflag_t = 0x400; +pub const ECHRNG: ::c_int = 0x2c; +pub const ECOMM: ::c_int = 0x46; +pub const ECONNABORTED: ::c_int = 0x67; +pub const ECONNREFUSED: ::c_int = 0x6f; +pub const ECONNRESET: ::c_int = 0x68; +pub const EDEADLK: ::c_int = 0x23; +pub const EDESTADDRREQ: ::c_int = 0x59; +pub const EDOTDOT: ::c_int = 0x49; +pub const EDQUOT: ::c_int = 0x7a; +pub const EFD_CLOEXEC: ::c_int = 0x80000; +pub const EFD_NONBLOCK: ::c_int = 0x800; +pub const EHOSTDOWN: ::c_int = 0x70; +pub const EHOSTUNREACH: ::c_int = 0x71; +pub const EHWPOISON: ::c_int = 0x85; +pub const EIDRM: ::c_int = 0x2b; +pub const EILSEQ: ::c_int = 0x54; +pub const EINPROGRESS: ::c_int = 0x73; +pub const EISCONN: ::c_int = 0x6a; +pub const EISNAM: ::c_int = 0x78; +pub const EKEYEXPIRED: ::c_int = 0x7f; +pub const EKEYREJECTED: ::c_int = 0x81; +pub const EKEYREVOKED: ::c_int = 0x80; +pub const EL2HLT: ::c_int = 0x33; +pub const EL2NSYNC: ::c_int = 0x2d; +pub const EL3HLT: ::c_int = 0x2e; +pub const EL3RST: ::c_int = 0x2f; +pub const ELIBACC: ::c_int = 0x4f; +pub const ELIBBAD: ::c_int = 0x50; +pub const ELIBEXEC: ::c_int = 0x53; +pub const ELIBMAX: ::c_int = 0x52; +pub const ELIBSCN: ::c_int = 0x51; +pub const ELNRNG: ::c_int = 0x30; +pub const ELOOP: ::c_int = 0x28; +pub const EMEDIUMTYPE: ::c_int = 0x7c; +pub const EMSGSIZE: ::c_int = 0x5a; +pub const EMULTIHOP: ::c_int = 0x48; +pub const ENAMETOOLONG: ::c_int = 0x24; +pub const ENAVAIL: ::c_int = 0x77; +pub const ENETDOWN: ::c_int = 0x64; +pub const ENETRESET: ::c_int = 0x66; +pub const ENETUNREACH: ::c_int = 0x65; +pub const ENOANO: ::c_int = 0x37; +pub const ENOBUFS: ::c_int = 0x69; +pub const ENOCSI: ::c_int = 0x32; +pub const ENODATA: ::c_int = 0x3d; +pub const ENOKEY: ::c_int = 0x7e; +pub const ENOLCK: ::c_int = 0x25; +pub const ENOLINK: ::c_int = 0x43; +pub const ENOMEDIUM: ::c_int = 0x7b; +pub const ENOMSG: ::c_int = 0x2a; +pub const ENONET: ::c_int = 0x40; +pub const ENOPKG: ::c_int = 0x41; +pub const ENOPROTOOPT: ::c_int = 0x5c; +pub const ENOSR: ::c_int = 0x3f; +pub const ENOSTR: ::c_int = 0x3c; +pub const ENOSYS: ::c_int = 0x26; +pub const ENOTCONN: ::c_int = 0x6b; +pub const ENOTEMPTY: ::c_int = 0x27; +pub const ENOTNAM: ::c_int = 0x76; +pub const ENOTRECOVERABLE: ::c_int = 0x83; +pub const ENOTSOCK: ::c_int = 0x58; +pub const ENOTUNIQ: ::c_int = 0x4c; +pub const EOPNOTSUPP: ::c_int = 0x5f; +pub const EOVERFLOW: ::c_int = 0x4b; +pub const EOWNERDEAD: ::c_int = 0x82; +pub const EPFNOSUPPORT: ::c_int = 0x60; +pub const EPOLL_CLOEXEC: ::c_int = 0x80000; +pub const EPROTO: ::c_int = 0x47; +pub const EPROTONOSUPPORT: ::c_int = 0x5d; +pub const EPROTOTYPE: ::c_int = 0x5b; +pub const EREMCHG: ::c_int = 0x4e; +pub const EREMOTE: ::c_int = 0x42; +pub const EREMOTEIO: ::c_int = 0x79; +pub const ERESTART: ::c_int = 0x55; +pub const ERFKILL: ::c_int = 0x84; +pub const ESHUTDOWN: ::c_int = 0x6c; +pub const ESOCKTNOSUPPORT: ::c_int = 0x5e; +pub const ESRMNT: ::c_int = 0x45; +pub const ESTALE: ::c_int = 0x74; +pub const ESTRPIPE: ::c_int = 0x56; +pub const ETIME: ::c_int = 0x3e; +pub const ETIMEDOUT: ::c_int = 0x6e; +pub const ETOOMANYREFS: ::c_int = 0x6d; +pub const EUCLEAN: ::c_int = 0x75; +pub const EUNATCH: ::c_int = 0x31; +pub const EUSERS: ::c_int = 0x57; +pub const EXFULL: ::c_int = 0x36; +pub const FF1: ::c_int = 0x8000; +pub const FFDLY: ::c_int = 0x8000; +pub const FLUSHO: ::tcflag_t = 0x1000; +pub const F_GETLK: ::c_int = 0x5; +pub const F_SETLK: ::c_int = 0x6; +pub const F_SETLKW: ::c_int = 0x7; +pub const HUPCL: ::tcflag_t = 0x400; +pub const ICANON: ::tcflag_t = 0x2; +pub const IEXTEN: ::tcflag_t = 0x8000; +pub const ISIG: ::tcflag_t = 0x1; +pub const IXOFF: ::tcflag_t = 0x1000; +pub const IXON: ::tcflag_t = 0x400; +pub const MAP_ANON: ::c_int = 0x20; +pub const MAP_ANONYMOUS: ::c_int = 0x20; +pub const MAP_DENYWRITE: ::c_int = 0x800; +pub const MAP_EXECUTABLE: ::c_int = 0x1000; +pub const MAP_GROWSDOWN: ::c_int = 0x100; +pub const MAP_LOCKED: ::c_int = 0x2000; +pub const MAP_NONBLOCK: ::c_int = 0x10000; +pub const MAP_NORESERVE: ::c_int = 0x4000; +pub const MAP_POPULATE: ::c_int = 0x8000; +pub const MAP_STACK: ::c_int = 0x20000; +pub const NLDLY: ::tcflag_t = 0x100; +pub const NOFLSH: ::tcflag_t = 0x80; +pub const OLCUC: ::tcflag_t = 0x2; +pub const ONLCR: ::tcflag_t = 0x4; +pub const O_ACCMODE: ::c_int = 0x3; +pub const O_APPEND: ::c_int = 0x400; +pub const O_ASYNC: ::c_int = 0o20000; +pub const O_CREAT: ::c_int = 0x40; +pub const O_DIRECT: ::c_int = 0x10000; +pub const O_DIRECTORY: ::c_int = 0x4000; +pub const O_DSYNC: ::c_int = O_SYNC; +pub const O_EXCL: ::c_int = 0x80; +pub const O_FSYNC: ::c_int = O_SYNC; +pub const O_LARGEFILE: ::c_int = 0o400000; +pub const O_NDELAY: ::c_int = O_NONBLOCK; +pub const O_NOATIME: ::c_int = 0o1000000; +pub const O_NOCTTY: ::c_int = 0x100; +pub const O_NOFOLLOW: ::c_int = 0x8000; +pub const O_NONBLOCK: ::c_int = 0x800; +pub const O_PATH: ::c_int = 0o10000000; +pub const O_RSYNC: ::c_int = O_SYNC; +pub const O_SYNC: ::c_int = 0o10000; +pub const O_TRUNC: ::c_int = 0x200; +pub const PARENB: ::tcflag_t = 0x100; +pub const PARODD: ::tcflag_t = 0x200; +pub const PENDIN: ::tcflag_t = 0x4000; +pub const 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; +pub const SA_NOCLDWAIT: ::c_ulong = 0x2; +pub const SA_SIGINFO: ::c_ulong = 0x4; +pub const SA_NODEFER: ::c_ulong = 0x40000000; +pub const SA_ONSTACK: ::c_ulong = 0x8000000; +pub const SA_RESETHAND: ::c_ulong = 0x80000000; +pub const SA_RESTART: ::c_ulong = 0x10000000; + +pub const SFD_CLOEXEC: ::c_int = 0x80000; +pub const SFD_NONBLOCK: ::c_int = 0x800; +pub const SIGBUS: ::c_int = 0x7; +pub const SIGCHLD: ::c_int = 0x11; +pub const SIGCONT: ::c_int = 0x12; +pub const SIGIO: ::c_int = 0x1d; +pub const SIGPROF: ::c_int = 0x1b; +pub const SIGPWR: ::c_int = 0x1e; +pub const SIGSTKFLT: ::c_int = 0x10; +pub const SIGSTKSZ: ::size_t = 8192; +pub const SIGSTOP: ::c_int = 0x13; +pub const SIGSYS: ::c_int = 0x1f; +pub const SIGTSTP: ::c_int = 0x14; +pub const SIGTTIN: ::c_int = 0x15; +pub const SIGTTOU: ::c_int = 0x16; +pub const SIGURG: ::c_int = 0x17; +pub const SIGUSR1: ::c_int = 0xa; +pub const SIGUSR2: ::c_int = 0xc; +pub const SIGVTALRM: ::c_int = 0x1a; +pub const SIGWINCH: ::c_int = 0x1c; +pub const SIGXCPU: ::c_int = 0x18; +pub const SIGXFSZ: ::c_int = 0x19; +pub const SIG_BLOCK: ::c_int = 0; +pub const SIG_SETMASK: ::c_int = 0x2; +pub const SIG_UNBLOCK: ::c_int = 0x1; +pub const SOCK_DGRAM: ::c_int = 0x2; +pub const SOCK_NONBLOCK: ::c_int = 0o0004000; +pub const SOCK_SEQPACKET: ::c_int = 0x5; +pub const SOCK_STREAM: ::c_int = 0x1; + +pub const TAB1: ::c_int = 0x800; +pub const TAB2: ::c_int = 0x1000; +pub const TAB3: ::c_int = 0x1800; +pub const TABDLY: ::c_int = 0x1800; +pub const TCSADRAIN: ::c_int = 0x1; +pub const TCSAFLUSH: ::c_int = 0x2; +pub const TCSANOW: ::c_int = 0; +pub const TOSTOP: ::tcflag_t = 0x100; +pub const VDISCARD: usize = 0xd; +pub const VEOF: usize = 0x4; +pub const VEOL: usize = 0xb; +pub const VEOL2: usize = 0x10; +pub const VMIN: usize = 0x6; +pub const VREPRINT: usize = 0xc; +pub const VSTART: usize = 0x8; +pub const VSTOP: usize = 0x9; +pub const VSUSP: usize = 0xa; +pub const VSWTC: usize = 0x7; +pub const VT1: ::c_int = 0x4000; +pub const VTDLY: ::c_int = 0x4000; +pub const VTIME: usize = 0x5; +pub const VWERASE: usize = 0xe; +pub const XTABS: ::tcflag_t = 0x1800; + +pub const MADV_SOFT_OFFLINE: ::c_int = 101; + +// Syscall table is copied from src/unix/notbsd/linux/musl/b32/arm.rs +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_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_mknod: ::c_long = 14; +pub const SYS_chmod: ::c_long = 15; +pub const SYS_lchown: ::c_long = 16; +pub const SYS_lseek: ::c_long = 19; +pub const SYS_getpid: ::c_long = 20; +pub const SYS_mount: ::c_long = 21; +pub const SYS_setuid: ::c_long = 23; +pub const SYS_getuid: ::c_long = 24; +pub const SYS_ptrace: ::c_long = 26; +pub const SYS_pause: ::c_long = 29; +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_setgid: ::c_long = 46; +pub const SYS_getgid: ::c_long = 47; +pub const SYS_geteuid: ::c_long = 49; +pub const SYS_getegid: ::c_long = 50; +pub const SYS_acct: ::c_long = 51; +pub const SYS_umount2: ::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_setreuid: ::c_long = 70; +pub const SYS_setregid: ::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_getrusage: ::c_long = 77; +pub const SYS_gettimeofday: ::c_long = 78; +pub const SYS_settimeofday: ::c_long = 79; +pub const SYS_getgroups: ::c_long = 80; +pub const SYS_setgroups: ::c_long = 81; +pub const SYS_symlink: ::c_long = 83; +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_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_fchown: ::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_syslog: ::c_long = 103; +pub const SYS_setitimer: ::c_long = 104; +pub const SYS_getitimer: ::c_long = 105; +pub const SYS_stat: ::c_long = 106; +pub const SYS_lstat: ::c_long = 107; +pub const SYS_fstat: ::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_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_uname: ::c_long = 122; +pub const SYS_adjtimex: ::c_long = 124; +pub const SYS_mprotect: ::c_long = 125; +pub const SYS_sigprocmask: ::c_long = 126; +pub const SYS_init_module: ::c_long = 128; +pub const SYS_delete_module: ::c_long = 129; +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_setfsuid: ::c_long = 138; +pub const SYS_setfsgid: ::c_long = 139; +pub const SYS__llseek: ::c_long = 140; +pub const SYS_getdents: ::c_long = 141; +pub const SYS__newselect: ::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: ::c_long = 161; +pub const SYS_nanosleep: ::c_long = 162; +pub const SYS_mremap: ::c_long = 163; +pub const SYS_setresuid: ::c_long = 164; +pub const SYS_getresuid: ::c_long = 165; +pub const SYS_poll: ::c_long = 168; +pub const SYS_nfsservctl: ::c_long = 169; +pub const SYS_setresgid: ::c_long = 170; +pub const SYS_getresgid: ::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: ::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_chown: ::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_vfork: ::c_long = 190; +pub const SYS_ugetrlimit: ::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_lchown32: ::c_long = 198; +pub const SYS_getuid32: ::c_long = 199; +pub const SYS_getgid32: ::c_long = 200; +pub const SYS_geteuid32: ::c_long = 201; +pub const SYS_getegid32: ::c_long = 202; +pub const SYS_setreuid32: ::c_long = 203; +pub const SYS_setregid32: ::c_long = 204; +pub const SYS_getgroups32: ::c_long = 205; +pub const SYS_setgroups32: ::c_long = 206; +pub const SYS_fchown32: ::c_long = 207; +pub const SYS_setresuid32: ::c_long = 208; +pub const SYS_getresuid32: ::c_long = 209; +pub const SYS_setresgid32: ::c_long = 210; +pub const SYS_getresgid32: ::c_long = 211; +pub const SYS_chown32: ::c_long = 212; +pub const SYS_setuid32: ::c_long = 213; +pub const SYS_setgid32: ::c_long = 214; +pub const SYS_setfsuid32: ::c_long = 215; +pub const SYS_setfsgid32: ::c_long = 216; +pub const SYS_getdents64: ::c_long = 217; +pub const SYS_pivot_root: ::c_long = 218; +pub const SYS_mincore: ::c_long = 219; +pub const SYS_madvise: ::c_long = 220; +pub const SYS_fcntl64: ::c_long = 221; +pub const SYS_gettid: ::c_long = 224; +pub const SYS_readahead: ::c_long = 225; +pub const SYS_setxattr: ::c_long = 226; +pub const SYS_lsetxattr: ::c_long = 227; +pub const SYS_fsetxattr: ::c_long = 228; +pub const SYS_getxattr: ::c_long = 229; +pub const SYS_lgetxattr: ::c_long = 230; +pub const SYS_fgetxattr: ::c_long = 231; +pub const SYS_listxattr: ::c_long = 232; +pub const SYS_llistxattr: ::c_long = 233; +pub const SYS_flistxattr: ::c_long = 234; +pub const SYS_removexattr: ::c_long = 235; +pub const SYS_lremovexattr: ::c_long = 236; +pub const SYS_fremovexattr: ::c_long = 237; +pub const SYS_tkill: ::c_long = 238; +pub const SYS_sendfile64: ::c_long = 239; +pub const SYS_futex: ::c_long = 240; +pub const SYS_sched_setaffinity: ::c_long = 241; +pub const SYS_sched_getaffinity: ::c_long = 242; +pub const SYS_io_setup: ::c_long = 243; +pub const SYS_io_destroy: ::c_long = 244; +pub const SYS_io_getevents: ::c_long = 245; +pub const SYS_io_submit: ::c_long = 246; +pub const SYS_io_cancel: ::c_long = 247; +pub const SYS_exit_group: ::c_long = 248; +pub const SYS_lookup_dcookie: ::c_long = 249; +pub const SYS_epoll_create: ::c_long = 250; +pub const SYS_epoll_ctl: ::c_long = 251; +pub const SYS_epoll_wait: ::c_long = 252; +pub const SYS_remap_file_pages: ::c_long = 253; +pub const SYS_set_tid_address: ::c_long = 256; +pub const SYS_timer_create: ::c_long = 257; +pub const SYS_timer_settime: ::c_long = 258; +pub const SYS_timer_gettime: ::c_long = 259; +pub const SYS_timer_getoverrun: ::c_long = 260; +pub const SYS_timer_delete: ::c_long = 261; +pub const SYS_clock_settime: ::c_long = 262; +pub const SYS_clock_gettime: ::c_long = 263; +pub const SYS_clock_getres: ::c_long = 264; +pub const SYS_clock_nanosleep: ::c_long = 265; +pub const SYS_statfs64: ::c_long = 266; +pub const SYS_fstatfs64: ::c_long = 267; +pub const SYS_tgkill: ::c_long = 268; +pub const SYS_utimes: ::c_long = 269; +pub const SYS_pciconfig_iobase: ::c_long = 271; +pub const SYS_pciconfig_read: ::c_long = 272; +pub const SYS_pciconfig_write: ::c_long = 273; +pub const SYS_mq_open: ::c_long = 274; +pub const SYS_mq_unlink: ::c_long = 275; +pub const SYS_mq_timedsend: ::c_long = 276; +pub const SYS_mq_timedreceive: ::c_long = 277; +pub const SYS_mq_notify: ::c_long = 278; +pub const SYS_mq_getsetattr: ::c_long = 279; +pub const SYS_waitid: ::c_long = 280; +pub const SYS_socket: ::c_long = 281; +pub const SYS_bind: ::c_long = 282; +pub const SYS_connect: ::c_long = 283; +pub const SYS_listen: ::c_long = 284; +pub const SYS_accept: ::c_long = 285; +pub const SYS_getsockname: ::c_long = 286; +pub const SYS_getpeername: ::c_long = 287; +pub const SYS_socketpair: ::c_long = 288; +pub const SYS_send: ::c_long = 289; +pub const SYS_sendto: ::c_long = 290; +pub const SYS_recv: ::c_long = 291; +pub const SYS_recvfrom: ::c_long = 292; +pub const SYS_shutdown: ::c_long = 293; +pub const SYS_setsockopt: ::c_long = 294; +pub const SYS_getsockopt: ::c_long = 295; +pub const SYS_sendmsg: ::c_long = 296; +pub const SYS_recvmsg: ::c_long = 297; +pub const SYS_semop: ::c_long = 298; +pub const SYS_semget: ::c_long = 299; +pub const SYS_semctl: ::c_long = 300; +pub const SYS_msgsnd: ::c_long = 301; +pub const SYS_msgrcv: ::c_long = 302; +pub const SYS_msgget: ::c_long = 303; +pub const SYS_msgctl: ::c_long = 304; +pub const SYS_shmat: ::c_long = 305; +pub const SYS_shmdt: ::c_long = 306; +pub const SYS_shmget: ::c_long = 307; +pub const SYS_shmctl: ::c_long = 308; +pub const SYS_add_key: ::c_long = 309; +pub const SYS_request_key: ::c_long = 310; +pub const SYS_keyctl: ::c_long = 311; +pub const SYS_semtimedop: ::c_long = 312; +pub const SYS_vserver: ::c_long = 313; +pub const SYS_ioprio_set: ::c_long = 314; +pub const SYS_ioprio_get: ::c_long = 315; +pub const SYS_inotify_init: ::c_long = 316; +pub const SYS_inotify_add_watch: ::c_long = 317; +pub const SYS_inotify_rm_watch: ::c_long = 318; +pub const SYS_mbind: ::c_long = 319; +pub const SYS_get_mempolicy: ::c_long = 320; +pub const SYS_set_mempolicy: ::c_long = 321; +pub const SYS_openat: ::c_long = 322; +pub const SYS_mkdirat: ::c_long = 323; +pub const SYS_mknodat: ::c_long = 324; +pub const SYS_fchownat: ::c_long = 325; +pub const SYS_futimesat: ::c_long = 326; +pub const SYS_fstatat64: ::c_long = 327; +pub const SYS_unlinkat: ::c_long = 328; +pub const SYS_renameat: ::c_long = 329; +pub const SYS_linkat: ::c_long = 330; +pub const SYS_symlinkat: ::c_long = 331; +pub const SYS_readlinkat: ::c_long = 332; +pub const SYS_fchmodat: ::c_long = 333; +pub const SYS_faccessat: ::c_long = 334; +pub const SYS_pselect6: ::c_long = 335; +pub const SYS_ppoll: ::c_long = 336; +pub const SYS_unshare: ::c_long = 337; +pub const SYS_set_robust_list: ::c_long = 338; +pub const SYS_get_robust_list: ::c_long = 339; +pub const SYS_splice: ::c_long = 340; +pub const SYS_tee: ::c_long = 342; +pub const SYS_vmsplice: ::c_long = 343; +pub const SYS_move_pages: ::c_long = 344; +pub const SYS_getcpu: ::c_long = 345; +pub const SYS_epoll_pwait: ::c_long = 346; +pub const SYS_kexec_load: ::c_long = 347; +pub const SYS_utimensat: ::c_long = 348; +pub const SYS_signalfd: ::c_long = 349; +pub const SYS_timerfd_create: ::c_long = 350; +pub const SYS_eventfd: ::c_long = 351; +pub const SYS_fallocate: ::c_long = 352; +pub const SYS_timerfd_settime: ::c_long = 353; +pub const SYS_timerfd_gettime: ::c_long = 354; +pub const SYS_signalfd4: ::c_long = 355; +pub const SYS_eventfd2: ::c_long = 356; +pub const SYS_epoll_create1: ::c_long = 357; +pub const SYS_dup3: ::c_long = 358; +pub const SYS_pipe2: ::c_long = 359; +pub const SYS_inotify_init1: ::c_long = 360; +pub const SYS_preadv: ::c_long = 361; +pub const SYS_pwritev: ::c_long = 362; +pub const SYS_rt_tgsigqueueinfo: ::c_long = 363; +pub const SYS_perf_event_open: ::c_long = 364; +pub const SYS_recvmmsg: ::c_long = 365; +pub const SYS_accept4: ::c_long = 366; +pub const SYS_fanotify_init: ::c_long = 367; +pub const SYS_fanotify_mark: ::c_long = 368; +pub const SYS_prlimit64: ::c_long = 369; +pub const SYS_name_to_handle_at: ::c_long = 370; +pub const SYS_open_by_handle_at: ::c_long = 371; +pub const SYS_clock_adjtime: ::c_long = 372; +pub const SYS_syncfs: ::c_long = 373; +pub const SYS_sendmmsg: ::c_long = 374; +pub const SYS_setns: ::c_long = 375; +pub const SYS_process_vm_readv: ::c_long = 376; +pub const SYS_process_vm_writev: ::c_long = 377; +pub const SYS_kcmp: ::c_long = 378; +pub const SYS_finit_module: ::c_long = 379; +pub const SYS_sched_setattr: ::c_long = 380; +pub const SYS_sched_getattr: ::c_long = 381; +pub const SYS_renameat2: ::c_long = 382; +pub const SYS_seccomp: ::c_long = 383; +pub const SYS_getrandom: ::c_long = 384; +pub const SYS_memfd_create: ::c_long = 385; +pub const SYS_bpf: ::c_long = 386; +pub const SYS_execveat: ::c_long = 387; +pub const SYS_userfaultfd: ::c_long = 388; +pub const SYS_membarrier: ::c_long = 389; +pub const SYS_mlock2: ::c_long = 390; +pub const SYS_copy_file_range: ::c_long = 391; +pub const SYS_preadv2: ::c_long = 392; +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; +// 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)] { + mod align; + pub use self::align::*; + } else { + mod no_align; + pub use self::no_align::*; + } +} diff --git a/vendor/libc/src/unix/linux_like/linux/uclibc/arm/no_align.rs b/vendor/libc/src/unix/linux_like/linux/uclibc/arm/no_align.rs new file mode 100644 index 0000000..e32bf67 --- /dev/null +++ b/vendor/libc/src/unix/linux_like/linux/uclibc/arm/no_align.rs @@ -0,0 +1,10 @@ +s! { + // FIXME this is actually a union + pub struct sem_t { + #[cfg(target_pointer_width = "32")] + __size: [::c_char; 16], + #[cfg(target_pointer_width = "64")] + __size: [::c_char; 32], + __align: [::c_long; 0], + } +} diff --git a/vendor/libc/src/unix/linux_like/linux/uclibc/mips/mips32/align.rs b/vendor/libc/src/unix/linux_like/linux/uclibc/mips/mips32/align.rs new file mode 100644 index 0000000..4a0e074 --- /dev/null +++ b/vendor/libc/src/unix/linux_like/linux/uclibc/mips/mips32/align.rs @@ -0,0 +1,13 @@ +s! { + // FIXME this is actually a union + #[cfg_attr(target_pointer_width = "32", + repr(align(4)))] + #[cfg_attr(target_pointer_width = "64", + repr(align(8)))] + pub struct sem_t { + #[cfg(target_pointer_width = "32")] + __size: [::c_char; 16], + #[cfg(target_pointer_width = "64")] + __size: [::c_char; 32], + } +} diff --git a/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 new file mode 100644 index 0000000..a5aca85 --- /dev/null +++ b/vendor/libc/src/unix/linux_like/linux/uclibc/mips/mips32/mod.rs @@ -0,0 +1,692 @@ +pub type c_char = i8; +pub type c_long = i32; +pub type c_ulong = u32; +pub type clock_t = i32; +pub type time_t = i32; +pub type suseconds_t = i32; +pub type wchar_t = i32; +pub type off_t = i32; +pub type ino_t = u32; +pub type blkcnt_t = i32; +pub type blksize_t = i32; +pub type nlink_t = u32; +pub type fsblkcnt_t = ::c_ulong; +pub type fsfilcnt_t = ::c_ulong; +pub type __u64 = ::c_ulonglong; +pub type __s64 = ::c_longlong; +pub type fsblkcnt64_t = u64; +pub type fsfilcnt64_t = u64; + +s! { + pub struct stat { + pub st_dev: ::dev_t, + st_pad1: [::c_long; 2], + 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_pad2: [::c_long; 1], + pub st_size: ::off_t, + st_pad3: ::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, + pub st_blksize: ::blksize_t, + pub st_blocks: ::blkcnt_t, + st_pad5: [::c_long; 14], + } + + pub struct stat64 { + pub st_dev: ::dev_t, + st_pad1: [::c_long; 2], + 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, + st_pad2: [::c_long; 2], + pub st_size: ::off64_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_blksize: ::blksize_t, + st_pad3: ::c_long, + pub st_blocks: ::blkcnt64_t, + st_pad5: [::c_long; 14], + } + + 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_unused: ::c_int, + pub f_flag: ::c_ulong, + pub f_namemax: ::c_ulong, + pub __f_spare: [::c_int; 6], + } + + pub struct pthread_attr_t { + __size: [u32; 9] + } + + pub struct sigaction { + pub sa_flags: ::c_uint, + pub sa_sigaction: ::sighandler_t, + pub sa_mask: sigset_t, + _restorer: *mut ::c_void, + } + + pub struct stack_t { + pub ss_sp: *mut ::c_void, + pub ss_size: ::size_t, + pub ss_flags: ::c_int, + } + + pub struct sigset_t { + __val: [::c_ulong; 4], + } + + pub struct siginfo_t { + pub si_signo: ::c_int, + pub si_code: ::c_int, + pub si_errno: ::c_int, + pub _pad: [::c_int; 29], + } + + pub struct glob64_t { + pub gl_pathc: ::size_t, + pub gl_pathv: *mut *mut ::c_char, + pub gl_offs: ::size_t, + pub gl_flags: ::c_int, + + __unused1: *mut ::c_void, + __unused2: *mut ::c_void, + __unused3: *mut ::c_void, + __unused4: *mut ::c_void, + __unused5: *mut ::c_void, + } + + 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, + __pad1: ::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 struct msqid_ds { + pub msg_perm: ::ipc_perm, + #[cfg(target_endian = "big")] + __glibc_reserved1: ::c_ulong, + pub msg_stime: ::time_t, + #[cfg(target_endian = "little")] + __glibc_reserved1: ::c_ulong, + #[cfg(target_endian = "big")] + __glibc_reserved2: ::c_ulong, + pub msg_rtime: ::time_t, + #[cfg(target_endian = "little")] + __glibc_reserved2: ::c_ulong, + #[cfg(target_endian = "big")] + __glibc_reserved3: ::c_ulong, + pub msg_ctime: ::time_t, + #[cfg(target_endian = "little")] + __glibc_reserved3: ::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, + __glibc_reserved4: ::c_ulong, + __glibc_reserved5: ::c_ulong, + } + + pub struct statfs { + pub f_type: ::c_long, + pub f_bsize: ::c_long, + pub f_frsize: ::c_long, + pub f_blocks: ::fsblkcnt_t, + pub f_bfree: ::fsblkcnt_t, + pub f_files: ::fsblkcnt_t, + pub f_ffree: ::fsblkcnt_t, + pub f_bavail: ::fsblkcnt_t, + pub f_fsid: ::fsid_t, + + pub f_namelen: ::c_long, + f_spare: [::c_long; 6], + } + + pub struct statfs64 { + pub f_type: ::c_long, + pub f_bsize: ::c_long, + pub f_frsize: ::c_long, + pub f_blocks: ::fsblkcnt64_t, + pub f_bfree: ::fsblkcnt64_t, + pub f_files: ::fsblkcnt64_t, + pub f_ffree: ::fsblkcnt64_t, + pub f_bavail: ::fsblkcnt64_t, + pub f_fsid: ::fsid_t, + pub f_namelen: ::c_long, + pub f_flags: ::c_long, + pub f_spare: [::c_long; 5], + } + + 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: ::size_t, + pub msg_flags: ::c_int, + } + + pub struct cmsghdr { + pub cmsg_len: ::size_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_line: ::cc_t, + pub c_cc: [::cc_t; ::NCCS], + } + + 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_sysid: ::c_long, + pub l_pid: ::pid_t, + pad: [::c_long; 4], + } + + pub struct sysinfo { + pub uptime: ::c_long, + pub loads: [::c_ulong; 3], + pub totalram: ::c_ulong, + pub freeram: ::c_ulong, + pub sharedram: ::c_ulong, + pub bufferram: ::c_ulong, + pub totalswap: ::c_ulong, + pub freeswap: ::c_ulong, + pub procs: ::c_ushort, + pub pad: ::c_ushort, + pub totalhigh: ::c_ulong, + pub freehigh: ::c_ulong, + pub mem_unit: ::c_uint, + pub _f: [::c_char; 8], + } +} + +pub const __SIZEOF_PTHREAD_ATTR_T: usize = 36; +pub const __SIZEOF_PTHREAD_MUTEX_T: usize = 24; +pub const __SIZEOF_PTHREAD_MUTEXATTR_T: usize = 4; +pub const __SIZEOF_PTHREAD_CONDATTR_T: usize = 4; +pub const __SIZEOF_PTHREAD_RWLOCK_T: usize = 32; +pub const __SIZEOF_PTHREAD_RWLOCKATTR_T: usize = 8; +pub const __SIZEOF_PTHREAD_BARRIER_T: usize = 20; +pub const __SIZEOF_PTHREAD_BARRIERATTR_T: usize = 4; + +pub const SYS_syscall: ::c_long = 4000 + 0; +pub const SYS_exit: ::c_long = 4000 + 1; +pub const SYS_fork: ::c_long = 4000 + 2; +pub const SYS_read: ::c_long = 4000 + 3; +pub const SYS_write: ::c_long = 4000 + 4; +pub const SYS_open: ::c_long = 4000 + 5; +pub const SYS_close: ::c_long = 4000 + 6; +pub const SYS_waitpid: ::c_long = 4000 + 7; +pub const SYS_creat: ::c_long = 4000 + 8; +pub const SYS_link: ::c_long = 4000 + 9; +pub const SYS_unlink: ::c_long = 4000 + 10; +pub const SYS_execve: ::c_long = 4000 + 11; +pub const SYS_chdir: ::c_long = 4000 + 12; +pub const SYS_time: ::c_long = 4000 + 13; +pub const SYS_mknod: ::c_long = 4000 + 14; +pub const SYS_chmod: ::c_long = 4000 + 15; +pub const SYS_lchown: ::c_long = 4000 + 16; +pub const SYS_break: ::c_long = 4000 + 17; +pub const SYS_lseek: ::c_long = 4000 + 19; +pub const SYS_getpid: ::c_long = 4000 + 20; +pub const SYS_mount: ::c_long = 4000 + 21; +pub const SYS_umount: ::c_long = 4000 + 22; +pub const SYS_setuid: ::c_long = 4000 + 23; +pub const SYS_getuid: ::c_long = 4000 + 24; +pub const SYS_stime: ::c_long = 4000 + 25; +pub const SYS_ptrace: ::c_long = 4000 + 26; +pub const SYS_alarm: ::c_long = 4000 + 27; +pub const SYS_pause: ::c_long = 4000 + 29; +pub const SYS_utime: ::c_long = 4000 + 30; +pub const SYS_stty: ::c_long = 4000 + 31; +pub const SYS_gtty: ::c_long = 4000 + 32; +pub const SYS_access: ::c_long = 4000 + 33; +pub const SYS_nice: ::c_long = 4000 + 34; +pub const SYS_ftime: ::c_long = 4000 + 35; +pub const SYS_sync: ::c_long = 4000 + 36; +pub const SYS_kill: ::c_long = 4000 + 37; +pub const SYS_rename: ::c_long = 4000 + 38; +pub const SYS_mkdir: ::c_long = 4000 + 39; +pub const SYS_rmdir: ::c_long = 4000 + 40; +pub const SYS_dup: ::c_long = 4000 + 41; +pub const SYS_pipe: ::c_long = 4000 + 42; +pub const SYS_times: ::c_long = 4000 + 43; +pub const SYS_prof: ::c_long = 4000 + 44; +pub const SYS_brk: ::c_long = 4000 + 45; +pub const SYS_setgid: ::c_long = 4000 + 46; +pub const SYS_getgid: ::c_long = 4000 + 47; +pub const SYS_signal: ::c_long = 4000 + 48; +pub const SYS_geteuid: ::c_long = 4000 + 49; +pub const SYS_getegid: ::c_long = 4000 + 50; +pub const SYS_acct: ::c_long = 4000 + 51; +pub const SYS_umount2: ::c_long = 4000 + 52; +pub const SYS_lock: ::c_long = 4000 + 53; +pub const SYS_ioctl: ::c_long = 4000 + 54; +pub const SYS_fcntl: ::c_long = 4000 + 55; +pub const SYS_mpx: ::c_long = 4000 + 56; +pub const SYS_setpgid: ::c_long = 4000 + 57; +pub const SYS_ulimit: ::c_long = 4000 + 58; +pub const SYS_umask: ::c_long = 4000 + 60; +pub const SYS_chroot: ::c_long = 4000 + 61; +pub const SYS_ustat: ::c_long = 4000 + 62; +pub const SYS_dup2: ::c_long = 4000 + 63; +pub const SYS_getppid: ::c_long = 4000 + 64; +pub const SYS_getpgrp: ::c_long = 4000 + 65; +pub const SYS_setsid: ::c_long = 4000 + 66; +pub const SYS_sigaction: ::c_long = 4000 + 67; +pub const SYS_sgetmask: ::c_long = 4000 + 68; +pub const SYS_ssetmask: ::c_long = 4000 + 69; +pub const SYS_setreuid: ::c_long = 4000 + 70; +pub const SYS_setregid: ::c_long = 4000 + 71; +pub const SYS_sigsuspend: ::c_long = 4000 + 72; +pub const SYS_sigpending: ::c_long = 4000 + 73; +pub const SYS_sethostname: ::c_long = 4000 + 74; +pub const SYS_setrlimit: ::c_long = 4000 + 75; +pub const SYS_getrlimit: ::c_long = 4000 + 76; +pub const SYS_getrusage: ::c_long = 4000 + 77; +pub const SYS_gettimeofday: ::c_long = 4000 + 78; +pub const SYS_settimeofday: ::c_long = 4000 + 79; +pub const SYS_getgroups: ::c_long = 4000 + 80; +pub const SYS_setgroups: ::c_long = 4000 + 81; +pub const SYS_symlink: ::c_long = 4000 + 83; +pub const SYS_readlink: ::c_long = 4000 + 85; +pub const SYS_uselib: ::c_long = 4000 + 86; +pub const SYS_swapon: ::c_long = 4000 + 87; +pub const SYS_reboot: ::c_long = 4000 + 88; +pub const SYS_readdir: ::c_long = 4000 + 89; +pub const SYS_mmap: ::c_long = 4000 + 90; +pub const SYS_munmap: ::c_long = 4000 + 91; +pub const SYS_truncate: ::c_long = 4000 + 92; +pub const SYS_ftruncate: ::c_long = 4000 + 93; +pub const SYS_fchmod: ::c_long = 4000 + 94; +pub const SYS_fchown: ::c_long = 4000 + 95; +pub const SYS_getpriority: ::c_long = 4000 + 96; +pub const SYS_setpriority: ::c_long = 4000 + 97; +pub const SYS_profil: ::c_long = 4000 + 98; +pub const SYS_statfs: ::c_long = 4000 + 99; +pub const SYS_fstatfs: ::c_long = 4000 + 100; +pub const SYS_ioperm: ::c_long = 4000 + 101; +pub const SYS_socketcall: ::c_long = 4000 + 102; +pub const SYS_syslog: ::c_long = 4000 + 103; +pub const SYS_setitimer: ::c_long = 4000 + 104; +pub const SYS_getitimer: ::c_long = 4000 + 105; +pub const SYS_stat: ::c_long = 4000 + 106; +pub const SYS_lstat: ::c_long = 4000 + 107; +pub const SYS_fstat: ::c_long = 4000 + 108; +pub const SYS_iopl: ::c_long = 4000 + 110; +pub const SYS_vhangup: ::c_long = 4000 + 111; +pub const SYS_idle: ::c_long = 4000 + 112; +pub const SYS_vm86: ::c_long = 4000 + 113; +pub const SYS_wait4: ::c_long = 4000 + 114; +pub const SYS_swapoff: ::c_long = 4000 + 115; +pub const SYS_sysinfo: ::c_long = 4000 + 116; +pub const SYS_ipc: ::c_long = 4000 + 117; +pub const SYS_fsync: ::c_long = 4000 + 118; +pub const SYS_sigreturn: ::c_long = 4000 + 119; +pub const SYS_clone: ::c_long = 4000 + 120; +pub const SYS_setdomainname: ::c_long = 4000 + 121; +pub const SYS_uname: ::c_long = 4000 + 122; +pub const SYS_modify_ldt: ::c_long = 4000 + 123; +pub const SYS_adjtimex: ::c_long = 4000 + 124; +pub const SYS_mprotect: ::c_long = 4000 + 125; +pub const SYS_sigprocmask: ::c_long = 4000 + 126; +pub const SYS_create_module: ::c_long = 4000 + 127; +pub const SYS_init_module: ::c_long = 4000 + 128; +pub const SYS_delete_module: ::c_long = 4000 + 129; +pub const SYS_get_kernel_syms: ::c_long = 4000 + 130; +pub const SYS_quotactl: ::c_long = 4000 + 131; +pub const SYS_getpgid: ::c_long = 4000 + 132; +pub const SYS_fchdir: ::c_long = 4000 + 133; +pub const SYS_bdflush: ::c_long = 4000 + 134; +pub const SYS_sysfs: ::c_long = 4000 + 135; +pub const SYS_personality: ::c_long = 4000 + 136; +pub const SYS_afs_syscall: ::c_long = 4000 + 137; +pub const SYS_setfsuid: ::c_long = 4000 + 138; +pub const SYS_setfsgid: ::c_long = 4000 + 139; +pub const SYS__llseek: ::c_long = 4000 + 140; +pub const SYS_getdents: ::c_long = 4000 + 141; +pub const SYS__newselect: ::c_long = 4000 + 142; +pub const SYS_flock: ::c_long = 4000 + 143; +pub const SYS_msync: ::c_long = 4000 + 144; +pub const SYS_readv: ::c_long = 4000 + 145; +pub const SYS_writev: ::c_long = 4000 + 146; +pub const SYS_cacheflush: ::c_long = 4000 + 147; +pub const SYS_cachectl: ::c_long = 4000 + 148; +pub const SYS_sysmips: ::c_long = 4000 + 149; +pub const SYS_getsid: ::c_long = 4000 + 151; +pub const SYS_fdatasync: ::c_long = 4000 + 152; +pub const SYS__sysctl: ::c_long = 4000 + 153; +pub const SYS_mlock: ::c_long = 4000 + 154; +pub const SYS_munlock: ::c_long = 4000 + 155; +pub const SYS_mlockall: ::c_long = 4000 + 156; +pub const SYS_munlockall: ::c_long = 4000 + 157; +pub const SYS_sched_setparam: ::c_long = 4000 + 158; +pub const SYS_sched_getparam: ::c_long = 4000 + 159; +pub const SYS_sched_setscheduler: ::c_long = 4000 + 160; +pub const SYS_sched_getscheduler: ::c_long = 4000 + 161; +pub const SYS_sched_yield: ::c_long = 4000 + 162; +pub const SYS_sched_get_priority_max: ::c_long = 4000 + 163; +pub const SYS_sched_get_priority_min: ::c_long = 4000 + 164; +pub const SYS_sched_rr_get_interval: ::c_long = 4000 + 165; +pub const SYS_nanosleep: ::c_long = 4000 + 166; +pub const SYS_mremap: ::c_long = 4000 + 167; +pub const SYS_accept: ::c_long = 4000 + 168; +pub const SYS_bind: ::c_long = 4000 + 169; +pub const SYS_connect: ::c_long = 4000 + 170; +pub const SYS_getpeername: ::c_long = 4000 + 171; +pub const SYS_getsockname: ::c_long = 4000 + 172; +pub const SYS_getsockopt: ::c_long = 4000 + 173; +pub const SYS_listen: ::c_long = 4000 + 174; +pub const SYS_recv: ::c_long = 4000 + 175; +pub const SYS_recvfrom: ::c_long = 4000 + 176; +pub const SYS_recvmsg: ::c_long = 4000 + 177; +pub const SYS_send: ::c_long = 4000 + 178; +pub const SYS_sendmsg: ::c_long = 4000 + 179; +pub const SYS_sendto: ::c_long = 4000 + 180; +pub const SYS_setsockopt: ::c_long = 4000 + 181; +pub const SYS_shutdown: ::c_long = 4000 + 182; +pub const SYS_socket: ::c_long = 4000 + 183; +pub const SYS_socketpair: ::c_long = 4000 + 184; +pub const SYS_setresuid: ::c_long = 4000 + 185; +pub const SYS_getresuid: ::c_long = 4000 + 186; +pub const SYS_query_module: ::c_long = 4000 + 187; +pub const SYS_poll: ::c_long = 4000 + 188; +pub const SYS_nfsservctl: ::c_long = 4000 + 189; +pub const SYS_setresgid: ::c_long = 4000 + 190; +pub const SYS_getresgid: ::c_long = 4000 + 191; +pub const SYS_prctl: ::c_long = 4000 + 192; +pub const SYS_rt_sigreturn: ::c_long = 4000 + 193; +pub const SYS_rt_sigaction: ::c_long = 4000 + 194; +pub const SYS_rt_sigprocmask: ::c_long = 4000 + 195; +pub const SYS_rt_sigpending: ::c_long = 4000 + 196; +pub const SYS_rt_sigtimedwait: ::c_long = 4000 + 197; +pub const SYS_rt_sigqueueinfo: ::c_long = 4000 + 198; +pub const SYS_rt_sigsuspend: ::c_long = 4000 + 199; +pub const SYS_pread64: ::c_long = 4000 + 200; +pub const SYS_pwrite64: ::c_long = 4000 + 201; +pub const SYS_chown: ::c_long = 4000 + 202; +pub const SYS_getcwd: ::c_long = 4000 + 203; +pub const SYS_capget: ::c_long = 4000 + 204; +pub const SYS_capset: ::c_long = 4000 + 205; +pub const SYS_sigaltstack: ::c_long = 4000 + 206; +pub const SYS_sendfile: ::c_long = 4000 + 207; +pub const SYS_getpmsg: ::c_long = 4000 + 208; +pub const SYS_putpmsg: ::c_long = 4000 + 209; +pub const SYS_mmap2: ::c_long = 4000 + 210; +pub const SYS_truncate64: ::c_long = 4000 + 211; +pub const SYS_ftruncate64: ::c_long = 4000 + 212; +pub const SYS_stat64: ::c_long = 4000 + 213; +pub const SYS_lstat64: ::c_long = 4000 + 214; +pub const SYS_fstat64: ::c_long = 4000 + 215; +pub const SYS_pivot_root: ::c_long = 4000 + 216; +pub const SYS_mincore: ::c_long = 4000 + 217; +pub const SYS_madvise: ::c_long = 4000 + 218; +pub const SYS_getdents64: ::c_long = 4000 + 219; +pub const SYS_fcntl64: ::c_long = 4000 + 220; +pub const SYS_gettid: ::c_long = 4000 + 222; +pub const SYS_readahead: ::c_long = 4000 + 223; +pub const SYS_setxattr: ::c_long = 4000 + 224; +pub const SYS_lsetxattr: ::c_long = 4000 + 225; +pub const SYS_fsetxattr: ::c_long = 4000 + 226; +pub const SYS_getxattr: ::c_long = 4000 + 227; +pub const SYS_lgetxattr: ::c_long = 4000 + 228; +pub const SYS_fgetxattr: ::c_long = 4000 + 229; +pub const SYS_listxattr: ::c_long = 4000 + 230; +pub const SYS_llistxattr: ::c_long = 4000 + 231; +pub const SYS_flistxattr: ::c_long = 4000 + 232; +pub const SYS_removexattr: ::c_long = 4000 + 233; +pub const SYS_lremovexattr: ::c_long = 4000 + 234; +pub const SYS_fremovexattr: ::c_long = 4000 + 235; +pub const SYS_tkill: ::c_long = 4000 + 236; +pub const SYS_sendfile64: ::c_long = 4000 + 237; +pub const SYS_futex: ::c_long = 4000 + 238; +pub const SYS_sched_setaffinity: ::c_long = 4000 + 239; +pub const SYS_sched_getaffinity: ::c_long = 4000 + 240; +pub const SYS_io_setup: ::c_long = 4000 + 241; +pub const SYS_io_destroy: ::c_long = 4000 + 242; +pub const SYS_io_getevents: ::c_long = 4000 + 243; +pub const SYS_io_submit: ::c_long = 4000 + 244; +pub const SYS_io_cancel: ::c_long = 4000 + 245; +pub const SYS_exit_group: ::c_long = 4000 + 246; +pub const SYS_lookup_dcookie: ::c_long = 4000 + 247; +pub const SYS_epoll_create: ::c_long = 4000 + 248; +pub const SYS_epoll_ctl: ::c_long = 4000 + 249; +pub const SYS_epoll_wait: ::c_long = 4000 + 250; +pub const SYS_remap_file_pages: ::c_long = 4000 + 251; +pub const SYS_set_tid_address: ::c_long = 4000 + 252; +pub const SYS_restart_syscall: ::c_long = 4000 + 253; +pub const SYS_fadvise64: ::c_long = 4000 + 254; +pub const SYS_statfs64: ::c_long = 4000 + 255; +pub const SYS_fstatfs64: ::c_long = 4000 + 256; +pub const SYS_timer_create: ::c_long = 4000 + 257; +pub const SYS_timer_settime: ::c_long = 4000 + 258; +pub const SYS_timer_gettime: ::c_long = 4000 + 259; +pub const SYS_timer_getoverrun: ::c_long = 4000 + 260; +pub const SYS_timer_delete: ::c_long = 4000 + 261; +pub const SYS_clock_settime: ::c_long = 4000 + 262; +pub const SYS_clock_gettime: ::c_long = 4000 + 263; +pub const SYS_clock_getres: ::c_long = 4000 + 264; +pub const SYS_clock_nanosleep: ::c_long = 4000 + 265; +pub const SYS_tgkill: ::c_long = 4000 + 266; +pub const SYS_utimes: ::c_long = 4000 + 267; +pub const SYS_mbind: ::c_long = 4000 + 268; +pub const SYS_get_mempolicy: ::c_long = 4000 + 269; +pub const SYS_set_mempolicy: ::c_long = 4000 + 270; +pub const SYS_mq_open: ::c_long = 4000 + 271; +pub const SYS_mq_unlink: ::c_long = 4000 + 272; +pub const SYS_mq_timedsend: ::c_long = 4000 + 273; +pub const SYS_mq_timedreceive: ::c_long = 4000 + 274; +pub const SYS_mq_notify: ::c_long = 4000 + 275; +pub const SYS_mq_getsetattr: ::c_long = 4000 + 276; +pub const SYS_vserver: ::c_long = 4000 + 277; +pub const SYS_waitid: ::c_long = 4000 + 278; +/* pub const SYS_sys_setaltroot: ::c_long = 4000 + 279; */ +pub const SYS_add_key: ::c_long = 4000 + 280; +pub const SYS_request_key: ::c_long = 4000 + 281; +pub const SYS_keyctl: ::c_long = 4000 + 282; +pub const SYS_set_thread_area: ::c_long = 4000 + 283; +pub const SYS_inotify_init: ::c_long = 4000 + 284; +pub const SYS_inotify_add_watch: ::c_long = 4000 + 285; +pub const SYS_inotify_rm_watch: ::c_long = 4000 + 286; +pub const SYS_migrate_pages: ::c_long = 4000 + 287; +pub const SYS_openat: ::c_long = 4000 + 288; +pub const SYS_mkdirat: ::c_long = 4000 + 289; +pub const SYS_mknodat: ::c_long = 4000 + 290; +pub const SYS_fchownat: ::c_long = 4000 + 291; +pub const SYS_futimesat: ::c_long = 4000 + 292; +pub const SYS_fstatat64: ::c_long = 4000 + 293; +pub const SYS_unlinkat: ::c_long = 4000 + 294; +pub const SYS_renameat: ::c_long = 4000 + 295; +pub const SYS_linkat: ::c_long = 4000 + 296; +pub const SYS_symlinkat: ::c_long = 4000 + 297; +pub const SYS_readlinkat: ::c_long = 4000 + 298; +pub const SYS_fchmodat: ::c_long = 4000 + 299; +pub const SYS_faccessat: ::c_long = 4000 + 300; +pub const SYS_pselect6: ::c_long = 4000 + 301; +pub const SYS_ppoll: ::c_long = 4000 + 302; +pub const SYS_unshare: ::c_long = 4000 + 303; +pub const SYS_splice: ::c_long = 4000 + 304; +pub const SYS_sync_file_range: ::c_long = 4000 + 305; +pub const SYS_tee: ::c_long = 4000 + 306; +pub const SYS_vmsplice: ::c_long = 4000 + 307; +pub const SYS_move_pages: ::c_long = 4000 + 308; +pub const SYS_set_robust_list: ::c_long = 4000 + 309; +pub const SYS_get_robust_list: ::c_long = 4000 + 310; +pub const SYS_kexec_load: ::c_long = 4000 + 311; +pub const SYS_getcpu: ::c_long = 4000 + 312; +pub const SYS_epoll_pwait: ::c_long = 4000 + 313; +pub const SYS_ioprio_set: ::c_long = 4000 + 314; +pub const SYS_ioprio_get: ::c_long = 4000 + 315; +pub const SYS_utimensat: ::c_long = 4000 + 316; +pub const SYS_signalfd: ::c_long = 4000 + 317; +pub const SYS_timerfd: ::c_long = 4000 + 318; +pub const SYS_eventfd: ::c_long = 4000 + 319; +pub const SYS_fallocate: ::c_long = 4000 + 320; +pub const SYS_timerfd_create: ::c_long = 4000 + 321; +pub const SYS_timerfd_gettime: ::c_long = 4000 + 322; +pub const SYS_timerfd_settime: ::c_long = 4000 + 323; +pub const SYS_signalfd4: ::c_long = 4000 + 324; +pub const SYS_eventfd2: ::c_long = 4000 + 325; +pub const SYS_epoll_create1: ::c_long = 4000 + 326; +pub const SYS_dup3: ::c_long = 4000 + 327; +pub const SYS_pipe2: ::c_long = 4000 + 328; +pub const SYS_inotify_init1: ::c_long = 4000 + 329; +pub const SYS_preadv: ::c_long = 4000 + 330; +pub const SYS_pwritev: ::c_long = 4000 + 331; +pub const SYS_rt_tgsigqueueinfo: ::c_long = 4000 + 332; +pub const SYS_perf_event_open: ::c_long = 4000 + 333; +pub const SYS_accept4: ::c_long = 4000 + 334; +pub const SYS_recvmmsg: ::c_long = 4000 + 335; +pub const SYS_fanotify_init: ::c_long = 4000 + 336; +pub const SYS_fanotify_mark: ::c_long = 4000 + 337; +pub const SYS_prlimit64: ::c_long = 4000 + 338; +pub const SYS_name_to_handle_at: ::c_long = 4000 + 339; +pub const SYS_open_by_handle_at: ::c_long = 4000 + 340; +pub const SYS_clock_adjtime: ::c_long = 4000 + 341; +pub const SYS_syncfs: ::c_long = 4000 + 342; +pub const SYS_sendmmsg: ::c_long = 4000 + 343; +pub const SYS_setns: ::c_long = 4000 + 344; +pub const SYS_process_vm_readv: ::c_long = 4000 + 345; +pub const SYS_process_vm_writev: ::c_long = 4000 + 346; +pub const SYS_kcmp: ::c_long = 4000 + 347; +pub const SYS_finit_module: ::c_long = 4000 + 348; +pub const SYS_sched_setattr: ::c_long = 4000 + 349; +pub const SYS_sched_getattr: ::c_long = 4000 + 350; +pub const SYS_renameat2: ::c_long = 4000 + 351; +pub const SYS_seccomp: ::c_long = 4000 + 352; +pub const SYS_getrandom: ::c_long = 4000 + 353; +pub const SYS_memfd_create: ::c_long = 4000 + 354; +pub const SYS_bpf: ::c_long = 4000 + 355; +pub const SYS_execveat: ::c_long = 4000 + 356; +pub const SYS_userfaultfd: ::c_long = 4000 + 357; +pub const SYS_membarrier: ::c_long = 4000 + 358; +pub const SYS_mlock2: ::c_long = 4000 + 359; +pub const SYS_copy_file_range: ::c_long = 4000 + 360; +pub const SYS_preadv2: ::c_long = 4000 + 361; +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" { + pub fn sysctl( + name: *mut ::c_int, + namelen: ::c_int, + oldp: *mut ::c_void, + oldlenp: *mut ::size_t, + newp: *mut ::c_void, + newlen: ::size_t, + ) -> ::c_int; + pub fn glob64( + pattern: *const ::c_char, + flags: ::c_int, + errfunc: ::Option ::c_int>, + pglob: *mut glob64_t, + ) -> ::c_int; + pub fn globfree64(pglob: *mut glob64_t); + pub fn pthread_attr_getaffinity_np( + attr: *const ::pthread_attr_t, + cpusetsize: ::size_t, + cpuset: *mut ::cpu_set_t, + ) -> ::c_int; + pub fn pthread_attr_setaffinity_np( + attr: *mut ::pthread_attr_t, + cpusetsize: ::size_t, + cpuset: *const ::cpu_set_t, + ) -> ::c_int; +} + +cfg_if! { + if #[cfg(libc_align)] { + mod align; + pub use self::align::*; + } else { + mod no_align; + pub use self::no_align::*; + } +} diff --git a/vendor/libc/src/unix/linux_like/linux/uclibc/mips/mips32/no_align.rs b/vendor/libc/src/unix/linux_like/linux/uclibc/mips/mips32/no_align.rs new file mode 100644 index 0000000..e32bf67 --- /dev/null +++ b/vendor/libc/src/unix/linux_like/linux/uclibc/mips/mips32/no_align.rs @@ -0,0 +1,10 @@ +s! { + // FIXME this is actually a union + pub struct sem_t { + #[cfg(target_pointer_width = "32")] + __size: [::c_char; 16], + #[cfg(target_pointer_width = "64")] + __size: [::c_char; 32], + __align: [::c_long; 0], + } +} diff --git a/vendor/libc/src/unix/linux_like/linux/uclibc/mips/mips64/align.rs b/vendor/libc/src/unix/linux_like/linux/uclibc/mips/mips64/align.rs new file mode 100644 index 0000000..21e2190 --- /dev/null +++ b/vendor/libc/src/unix/linux_like/linux/uclibc/mips/mips64/align.rs @@ -0,0 +1,10 @@ +s! { + // FIXME this is actually a union + #[cfg_attr(target_pointer_width = "32", + repr(align(4)))] + #[cfg_attr(target_pointer_width = "64", + repr(align(8)))] + pub struct sem_t { + __size: [::c_char; 32], + } +} 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 new file mode 100644 index 0000000..8ca100f --- /dev/null +++ b/vendor/libc/src/unix/linux_like/linux/uclibc/mips/mips64/mod.rs @@ -0,0 +1,207 @@ +pub type blkcnt_t = i64; +pub type blksize_t = i64; +pub type c_char = i8; +pub type c_long = i64; +pub type c_ulong = u64; +pub type fsblkcnt_t = ::c_ulong; +pub type fsfilcnt_t = ::c_ulong; +pub type ino_t = u64; +pub type nlink_t = u64; +pub type off_t = i64; +pub type suseconds_t = i64; +pub type time_t = i64; +pub type wchar_t = i32; + +s! { + pub struct stat { + pub st_dev: ::c_ulong, + st_pad1: [::c_long; 2], + 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_ulong, + st_pad2: [::c_ulong; 1], + pub st_size: ::off_t, + st_pad3: ::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, + pub st_blksize: ::blksize_t, + st_pad4: ::c_long, + pub st_blocks: ::blkcnt_t, + st_pad5: [::c_long; 7], + } + + pub struct stat64 { + pub st_dev: ::c_ulong, + st_pad1: [::c_long; 2], + 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: ::c_ulong, + st_pad2: [::c_long; 2], + pub st_size: ::off64_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_blksize: ::blksize_t, + st_pad3: ::c_long, + pub st_blocks: ::blkcnt64_t, + st_pad5: [::c_long; 7], + } + + pub struct pthread_attr_t { + __size: [::c_ulong; 7] + } + + pub struct sigaction { + pub sa_flags: ::c_int, + pub sa_sigaction: ::sighandler_t, + pub sa_mask: sigset_t, + _restorer: *mut ::c_void, + } + + pub struct stack_t { + pub ss_sp: *mut ::c_void, + pub ss_size: ::size_t, + pub ss_flags: ::c_int, + } + + pub struct sigset_t { + __size: [::c_ulong; 16], + } + + pub struct siginfo_t { + pub si_signo: ::c_int, + pub si_code: ::c_int, + pub si_errno: ::c_int, + _pad: ::c_int, + _pad2: [::c_long; 14], + } + + 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, + __pad1: ::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 struct msqid_ds { + pub msg_perm: ::ipc_perm, + pub msg_stime: ::time_t, + pub msg_rtime: ::time_t, + pub msg_ctime: ::time_t, + __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 statfs { + pub f_type: ::c_long, + pub f_bsize: ::c_long, + pub f_frsize: ::c_long, + pub f_blocks: ::fsblkcnt_t, + pub f_bfree: ::fsblkcnt_t, + pub f_files: ::fsblkcnt_t, + pub f_ffree: ::fsblkcnt_t, + pub f_bavail: ::fsblkcnt_t, + pub f_fsid: ::fsid_t, + + pub f_namelen: ::c_long, + f_spare: [::c_long; 6], + } + + pub struct msghdr { + pub msg_name: *mut ::c_void, + pub msg_namelen: ::socklen_t, + pub msg_iov: *mut ::iovec, + pub msg_iovlen: ::size_t, + pub msg_control: *mut ::c_void, + pub msg_controllen: ::size_t, + pub msg_flags: ::c_int, + } + + pub struct cmsghdr { + pub cmsg_len: ::size_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_line: ::cc_t, + pub c_cc: [::cc_t; ::NCCS], + } + + pub struct sysinfo { + pub uptime: ::c_long, + pub loads: [::c_ulong; 3], + pub totalram: ::c_ulong, + pub freeram: ::c_ulong, + pub sharedram: ::c_ulong, + pub bufferram: ::c_ulong, + pub totalswap: ::c_ulong, + pub freeswap: ::c_ulong, + pub procs: ::c_ushort, + pub pad: ::c_ushort, + pub totalhigh: ::c_ulong, + pub freehigh: ::c_ulong, + pub mem_unit: ::c_uint, + pub _f: [::c_char; 0], + } +} + +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; + +pub const SYS_gettid: ::c_long = 5178; // Valid for n64 + +cfg_if! { + if #[cfg(libc_align)] { + mod align; + pub use self::align::*; + } else { + mod no_align; + pub use self::no_align::*; + } +} diff --git a/vendor/libc/src/unix/linux_like/linux/uclibc/mips/mips64/no_align.rs b/vendor/libc/src/unix/linux_like/linux/uclibc/mips/mips64/no_align.rs new file mode 100644 index 0000000..8909114 --- /dev/null +++ b/vendor/libc/src/unix/linux_like/linux/uclibc/mips/mips64/no_align.rs @@ -0,0 +1,7 @@ +s! { + // FIXME this is actually a union + pub struct sem_t { + __size: [::c_char; 32], + __align: [::c_long; 0], + } +} 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 new file mode 100644 index 0000000..56bfcc5 --- /dev/null +++ b/vendor/libc/src/unix/linux_like/linux/uclibc/mips/mod.rs @@ -0,0 +1,310 @@ +pub type pthread_t = ::c_ulong; + +pub const SFD_CLOEXEC: ::c_int = 0x080000; + +pub const NCCS: usize = 32; + +pub const O_TRUNC: ::c_int = 512; + +pub const O_CLOEXEC: ::c_int = 0x80000; + +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 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 EPOLL_CLOEXEC: ::c_int = 0x80000; + +pub const EFD_CLOEXEC: ::c_int = 0x80000; + +pub const TMP_MAX: ::c_uint = 238328; +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 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; +pub const O_EXCL: ::c_int = 1024; +pub const O_NOCTTY: ::c_int = 2048; +pub const O_NONBLOCK: ::c_int = 128; +pub const O_SYNC: ::c_int = 0x10; +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; +pub const ENOLCK: ::c_int = 46; +pub const ENOSYS: ::c_int = 89; +pub const ENOTEMPTY: ::c_int = 93; +pub const ELOOP: ::c_int = 90; +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 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 EMULTIHOP: ::c_int = 74; +pub const EOVERFLOW: ::c_int = 79; +pub const ENOTUNIQ: ::c_int = 80; +pub const EBADFD: ::c_int = 81; +pub const EBADMSG: ::c_int = 77; +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 ERESTART: ::c_int = 91; +pub const ESTRPIPE: ::c_int = 92; +pub const EUSERS: ::c_int = 94; +pub const ENOTSOCK: ::c_int = 95; +pub const EDESTADDRREQ: ::c_int = 96; +pub const EMSGSIZE: ::c_int = 97; +pub const EPROTOTYPE: ::c_int = 98; +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 EPFNOSUPPORT: ::c_int = 123; +pub const EAFNOSUPPORT: ::c_int = 124; +pub const EADDRINUSE: ::c_int = 125; +pub const EADDRNOTAVAIL: ::c_int = 126; +pub const ENETDOWN: ::c_int = 127; +pub const ENETUNREACH: ::c_int = 128; +pub const ENETRESET: ::c_int = 129; +pub const ECONNABORTED: ::c_int = 130; +pub const ECONNRESET: ::c_int = 131; +pub const ENOBUFS: ::c_int = 132; +pub const EISCONN: ::c_int = 133; +pub const ENOTCONN: ::c_int = 134; +pub const ESHUTDOWN: ::c_int = 143; +pub const ETOOMANYREFS: ::c_int = 144; +pub const ETIMEDOUT: ::c_int = 145; +pub const ECONNREFUSED: ::c_int = 146; +pub const EHOSTDOWN: ::c_int = 147; +pub const EHOSTUNREACH: ::c_int = 148; +pub const EALREADY: ::c_int = 149; +pub const EINPROGRESS: ::c_int = 150; +pub const ESTALE: ::c_int = 151; +pub const EUCLEAN: ::c_int = 135; +pub const ENOTNAM: ::c_int = 137; +pub const ENAVAIL: ::c_int = 138; +pub const EISNAM: ::c_int = 139; +pub const EREMOTEIO: ::c_int = 140; +pub const EDQUOT: ::c_int = 1133; +pub const ENOMEDIUM: ::c_int = 159; +pub const EMEDIUMTYPE: ::c_int = 160; +pub const ECANCELED: ::c_int = 158; +pub const ENOKEY: ::c_int = 161; +pub const EKEYEXPIRED: ::c_int = 162; +pub const EKEYREVOKED: ::c_int = 163; +pub const EKEYREJECTED: ::c_int = 164; +pub const EOWNERDEAD: ::c_int = 165; +pub const ENOTRECOVERABLE: ::c_int = 166; +pub const ERFKILL: ::c_int = 167; + +pub const MAP_NORESERVE: ::c_int = 0x400; +pub const MAP_ANON: ::c_int = 0x800; +pub const MAP_ANONYMOUS: ::c_int = 0x800; +pub const MAP_GROWSDOWN: ::c_int = 0x1000; +pub const MAP_DENYWRITE: ::c_int = 0x2000; +pub const MAP_EXECUTABLE: ::c_int = 0x4000; +pub const MAP_LOCKED: ::c_int = 0x8000; +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 SA_ONSTACK: ::c_uint = 0x08000000; +pub const SA_SIGINFO: ::c_uint = 0x00000008; +pub const SA_NOCLDWAIT: ::c_int = 0x00010000; + +pub const SIGCHLD: ::c_int = 18; +pub const SIGBUS: ::c_int = 10; +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 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 = 22; +pub const SIGSYS: ::c_int = 12; +pub const SIGPWR: ::c_int = 19; +pub const SIG_SETMASK: ::c_int = 3; +pub const SIG_BLOCK: ::c_int = 0x1; +pub const SIG_UNBLOCK: ::c_int = 0x2; + +pub const POLLWRNORM: ::c_short = 0x004; +pub const POLLWRBAND: ::c_short = 0x100; + +pub const PTHREAD_STACK_MIN: ::size_t = 16384; + +pub const VEOF: usize = 16; +pub const VEOL: usize = 17; +pub const VEOL2: usize = 6; +pub const VMIN: usize = 4; +pub const IEXTEN: ::tcflag_t = 0x00000100; +pub const TOSTOP: ::tcflag_t = 0x00008000; +pub const FLUSHO: ::tcflag_t = 0x00002000; +pub const TCSANOW: ::c_int = 0x540e; +pub const TCSADRAIN: ::c_int = 0x540f; +pub const TCSAFLUSH: ::c_int = 0x5410; + +pub const CPU_SETSIZE: ::c_int = 0x400; + +pub const EFD_NONBLOCK: ::c_int = 0x80; + +pub const F_GETLK: ::c_int = 14; +pub const F_SETLK: ::c_int = 6; +pub const F_SETLKW: ::c_int = 7; + +pub const SFD_NONBLOCK: ::c_int = 0x80; + +pub const RTLD_GLOBAL: ::c_int = 0x4; + +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; +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 MAP_HUGETLB: ::c_int = 0x80000; + +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 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; + +cfg_if! { + if #[cfg(target_arch = "mips")] { + mod mips32; + pub use self::mips32::*; + } else if #[cfg(target_arch = "mips64")] { + mod mips64; + pub use self::mips64::*; + } else { + // Unknown target_arch + } +} diff --git a/vendor/libc/src/unix/linux_like/linux/uclibc/mod.rs b/vendor/libc/src/unix/linux_like/linux/uclibc/mod.rs new file mode 100644 index 0000000..32c6554 --- /dev/null +++ b/vendor/libc/src/unix/linux_like/linux/uclibc/mod.rs @@ -0,0 +1,450 @@ +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! + 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, + #[cfg(target_endian = "little")] + pub f_fsid: ::c_ulong, + #[cfg(target_pointer_width = "32")] + __f_unused: ::c_int, + #[cfg(target_endian = "big")] + pub f_fsid: ::c_ulong, + pub f_flag: ::c_ulong, + pub f_namemax: ::c_ulong, + __f_spare: [::c_int; 6], + } + + 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 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 + } +} + +// Internal, for casts to access union fields +#[repr(C)] +struct sifields_sigchld { + si_pid: ::pid_t, + si_uid: ::uid_t, + si_status: ::c_int, + si_utime: ::c_long, + si_stime: ::c_long, +} +impl ::Copy for sifields_sigchld {} +impl ::Clone for sifields_sigchld { + fn clone(&self) -> sifields_sigchld { + *self + } +} + +// Internal, for casts to access union fields +#[repr(C)] +union sifields { + _align_pointer: *mut ::c_void, + sigchld: sifields_sigchld, +} + +// Internal, for casts to access union fields. Note that some variants +// of sifields start with a pointer, which makes the alignment of +// sifields vary on 32-bit and 64-bit architectures. +#[repr(C)] +struct siginfo_f { + _siginfo_base: [::c_int; 3], + sifields: sifields, +} + +impl siginfo_t { + unsafe fn sifields(&self) -> &sifields { + &(*(self as *const siginfo_t as *const siginfo_f)).sifields + } + + pub unsafe fn si_pid(&self) -> ::pid_t { + self.sifields().sigchld.si_pid + } + + pub unsafe fn si_uid(&self) -> ::uid_t { + self.sifields().sigchld.si_uid + } + + pub unsafe fn si_status(&self) -> ::c_int { + self.sifields().sigchld.si_status + } + + pub unsafe fn si_utime(&self) -> ::c_long { + self.sifields().sigchld.si_utime + } + + pub unsafe fn si_stime(&self) -> ::c_long { + self.sifields().sigchld.si_stime + } +} + +pub const MCL_CURRENT: ::c_int = 0x0001; +pub const MCL_FUTURE: ::c_int = 0x0002; +pub const MCL_ONFAULT: ::c_int = 0x0004; + +pub const SIGEV_THREAD_ID: ::c_int = 4; + +pub const AF_VSOCK: ::c_int = 40; + +// 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 XFS_SUPER_MAGIC: ::c_long = 0x58465342; + +pub const PTRACE_TRACEME: ::c_int = 0; +pub const PTRACE_PEEKTEXT: ::c_int = 1; +pub const PTRACE_PEEKDATA: ::c_int = 2; +pub const PTRACE_PEEKUSER: ::c_int = 3; +pub const PTRACE_POKETEXT: ::c_int = 4; +pub const PTRACE_POKEDATA: ::c_int = 5; +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_GETFPREGS: ::c_int = 14; +pub const PTRACE_SETFPREGS: ::c_int = 15; +pub const PTRACE_ATTACH: ::c_int = 16; +pub const PTRACE_DETACH: ::c_int = 17; +pub const PTRACE_GETFPXREGS: ::c_int = 18; +pub const PTRACE_SETFPXREGS: ::c_int = 19; +pub const PTRACE_SYSCALL: ::c_int = 24; +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_SEIZE: ::c_int = 0x4206; +pub const PTRACE_INTERRUPT: ::c_int = 0x4207; +pub const PTRACE_LISTEN: ::c_int = 0x4208; + +pub const POSIX_FADV_DONTNEED: ::c_int = 4; +pub const POSIX_FADV_NOREUSE: ::c_int = 5; + +// These are different than GNU! +pub const LC_CTYPE: ::c_int = 0; +pub const LC_NUMERIC: ::c_int = 1; +pub const LC_TIME: ::c_int = 3; +pub const LC_COLLATE: ::c_int = 4; +pub const LC_MONETARY: ::c_int = 2; +pub const LC_MESSAGES: ::c_int = 5; +pub const LC_ALL: ::c_int = 6; +// end different section + +// MS_ flags for mount(2) +pub const MS_RMT_MASK: ::c_ulong = ::MS_RDONLY | ::MS_SYNCHRONOUS | ::MS_MANDLOCK | ::MS_I_VERSION; + +pub const ENOTSUP: ::c_int = EOPNOTSUPP; + +pub const IPV6_JOIN_GROUP: ::c_int = 20; +pub const IPV6_LEAVE_GROUP: ::c_int = 21; + +// These are different from GNU +pub const ABDAY_1: ::nl_item = 0x300; +pub const ABDAY_2: ::nl_item = 0x301; +pub const ABDAY_3: ::nl_item = 0x302; +pub const ABDAY_4: ::nl_item = 0x303; +pub const ABDAY_5: ::nl_item = 0x304; +pub const ABDAY_6: ::nl_item = 0x305; +pub const ABDAY_7: ::nl_item = 0x306; +pub const DAY_1: ::nl_item = 0x307; +pub const DAY_2: ::nl_item = 0x308; +pub const DAY_3: ::nl_item = 0x309; +pub const DAY_4: ::nl_item = 0x30A; +pub const DAY_5: ::nl_item = 0x30B; +pub const DAY_6: ::nl_item = 0x30C; +pub const DAY_7: ::nl_item = 0x30D; +pub const ABMON_1: ::nl_item = 0x30E; +pub const ABMON_2: ::nl_item = 0x30F; +pub const ABMON_3: ::nl_item = 0x310; +pub const ABMON_4: ::nl_item = 0x311; +pub const ABMON_5: ::nl_item = 0x312; +pub const ABMON_6: ::nl_item = 0x313; +pub const ABMON_7: ::nl_item = 0x314; +pub const ABMON_8: ::nl_item = 0x315; +pub const ABMON_9: ::nl_item = 0x316; +pub const ABMON_10: ::nl_item = 0x317; +pub const ABMON_11: ::nl_item = 0x318; +pub const ABMON_12: ::nl_item = 0x319; +pub const MON_1: ::nl_item = 0x31A; +pub const MON_2: ::nl_item = 0x31B; +pub const MON_3: ::nl_item = 0x31C; +pub const MON_4: ::nl_item = 0x31D; +pub const MON_5: ::nl_item = 0x31E; +pub const MON_6: ::nl_item = 0x31F; +pub const MON_7: ::nl_item = 0x320; +pub const MON_8: ::nl_item = 0x321; +pub const MON_9: ::nl_item = 0x322; +pub const MON_10: ::nl_item = 0x323; +pub const MON_11: ::nl_item = 0x324; +pub const MON_12: ::nl_item = 0x325; +pub const AM_STR: ::nl_item = 0x326; +pub const PM_STR: ::nl_item = 0x327; +pub const D_T_FMT: ::nl_item = 0x328; +pub const D_FMT: ::nl_item = 0x329; +pub const T_FMT: ::nl_item = 0x32A; +pub const T_FMT_AMPM: ::nl_item = 0x32B; +pub const ERA: ::nl_item = 0x32C; +pub const ERA_D_FMT: ::nl_item = 0x32E; +pub const ALT_DIGITS: ::nl_item = 0x32F; +pub const ERA_D_T_FMT: ::nl_item = 0x330; +pub const ERA_T_FMT: ::nl_item = 0x331; +pub const CODESET: ::nl_item = 10; +pub const CRNCYSTR: ::nl_item = 0x215; +pub const RADIXCHAR: ::nl_item = 0x100; +pub const THOUSEP: ::nl_item = 0x101; +pub const NOEXPR: ::nl_item = 0x501; +pub const YESSTR: ::nl_item = 0x502; +pub const NOSTR: ::nl_item = 0x503; + +// Different than Gnu. +pub const FILENAME_MAX: ::c_uint = 4095; + +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 = 0o200000; +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 = 0o40000; +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_GETSIGMASK: ::c_uint = 0x420a; +pub const PTRACE_PEEKSIGINFO: ::c_int = 0x4209; +pub const PTRACE_SETSIGMASK: ::c_uint = 0x420b; +pub const RTLD_NOLOAD: ::c_int = 0x00004; +pub const RUSAGE_THREAD: ::c_int = 1; +pub const SHM_EXEC: ::c_int = 0o100000; +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 gettimeofday(tp: *mut ::timeval, tz: *mut ::timezone) -> ::c_int; + + pub fn pthread_rwlockattr_getkind_np( + attr: *const ::pthread_rwlockattr_t, + val: *mut ::c_int, + ) -> ::c_int; + pub fn pthread_rwlockattr_setkind_np( + attr: *mut ::pthread_rwlockattr_t, + val: ::c_int, + ) -> ::c_int; + + pub fn ptrace(request: ::c_uint, ...) -> ::c_long; + + pub fn sendmmsg( + sockfd: ::c_int, + msgvec: *mut ::mmsghdr, + vlen: ::c_uint, + flags: ::c_int, + ) -> ::c_int; + pub fn recvmmsg( + sockfd: ::c_int, + msgvec: *mut ::mmsghdr, + vlen: ::c_uint, + flags: ::c_int, + timeout: *mut ::timespec, + ) -> ::c_int; + + 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 getnameinfo( + sa: *const ::sockaddr, + salen: ::socklen_t, + host: *mut ::c_char, + hostlen: ::socklen_t, + serv: *mut ::c_char, + servlen: ::socklen_t, + flags: ::c_int, + ) -> ::c_int; + + pub fn pwritev( + fd: ::c_int, + iov: *const ::iovec, + iovcnt: ::c_int, + offset: ::off64_t, + ) -> ::ssize_t; + pub fn preadv( + fd: ::c_int, + iov: *const ::iovec, + 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; + pub fn getauxval(type_: ::c_ulong) -> ::c_ulong; +} + +cfg_if! { + if #[cfg(any(target_arch = "mips", target_arch = "mips64"))] { + mod mips; + pub use self::mips::*; + } else if #[cfg(target_arch = "x86_64")] { + mod x86_64; + pub use self::x86_64::*; + } else if #[cfg(target_arch = "arm")] { + mod arm; + pub use self::arm::*; + } else { + pub use unsupported_target; + } +} diff --git a/vendor/libc/src/unix/linux_like/linux/uclibc/no_align.rs b/vendor/libc/src/unix/linux_like/linux/uclibc/no_align.rs new file mode 100644 index 0000000..a73dbde --- /dev/null +++ b/vendor/libc/src/unix/linux_like/linux/uclibc/no_align.rs @@ -0,0 +1,53 @@ +macro_rules! expand_align { + () => { + s! { + pub struct pthread_mutex_t { + #[cfg(any(target_arch = "mips", + target_arch = "arm", + target_arch = "powerpc"))] + __align: [::c_long; 0], + #[cfg(any(libc_align, + target_arch = "mips", + target_arch = "arm", + target_arch = "powerpc"))] + __align: [::c_longlong; 0], + size: [u8; ::__SIZEOF_PTHREAD_MUTEX_T], + } + + pub struct pthread_rwlock_t { + #[cfg(any(target_arch = "mips", + target_arch = "arm", + target_arch = "powerpc"))] + __align: [::c_long; 0], + #[cfg(not(any( + target_arch = "mips", + target_arch = "arm", + target_arch = "powerpc")))] + __align: [::c_longlong; 0], + size: [u8; ::__SIZEOF_PTHREAD_RWLOCK_T], + } + + pub struct pthread_mutexattr_t { + #[cfg(any(target_arch = "x86_64", target_arch = "powerpc64", + target_arch = "mips64", target_arch = "s390x", + target_arch = "sparc64"))] + __align: [::c_int; 0], + #[cfg(not(any(target_arch = "x86_64", target_arch = "powerpc64", + target_arch = "mips64", target_arch = "s390x", + target_arch = "sparc64")))] + __align: [::c_long; 0], + size: [u8; ::__SIZEOF_PTHREAD_MUTEXATTR_T], + } + + pub struct pthread_cond_t { + __align: [::c_longlong; 0], + size: [u8; ::__SIZEOF_PTHREAD_COND_T], + } + + pub struct pthread_condattr_t { + __align: [::c_int; 0], + size: [u8; ::__SIZEOF_PTHREAD_CONDATTR_T], + } + } + } +} 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 new file mode 100644 index 0000000..56a0e37 --- /dev/null +++ b/vendor/libc/src/unix/linux_like/linux/uclibc/x86_64/l4re.rs @@ -0,0 +1,53 @@ +/// L4Re specifics +/// This module contains definitions required by various L4Re libc backends. +/// Some of them are formally not part of the libc, but are a dependency of the +/// libc and hence we should provide them here. + +pub type l4_umword_t = ::c_ulong; // Unsigned machine word. +pub type pthread_t = *mut ::c_void; + +s! { + /// CPU sets. + pub struct l4_sched_cpu_set_t { + // from the L4Re docs + /// Combination of granularity and offset. + /// + /// The granularity defines how many CPUs each bit in map describes. + /// The offset is the number of the first CPU described by the first + /// bit in the bitmap. + /// offset must be a multiple of 2^graularity. + /// + /// | MSB | LSB | + /// | ---------------- | ------------------- | + /// | 8bit granularity | 24bit offset .. | + gran_offset: l4_umword_t , + /// Bitmap of CPUs. + map: l4_umword_t , + } +} + +#[cfg(target_os = "l4re")] +#[allow(missing_debug_implementations)] +pub struct pthread_attr_t { + pub __detachstate: ::c_int, + pub __schedpolicy: ::c_int, + pub __schedparam: super::__sched_param, + pub __inheritsched: ::c_int, + pub __scope: ::c_int, + pub __guardsize: ::size_t, + pub __stackaddr_set: ::c_int, + pub __stackaddr: *mut ::c_void, // better don't use it + pub __stacksize: ::size_t, + // L4Re specifics + pub affinity: l4_sched_cpu_set_t, + pub create_flags: ::c_uint, +} + +// 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 new file mode 100644 index 0000000..c504202 --- /dev/null +++ b/vendor/libc/src/unix/linux_like/linux/uclibc/x86_64/mod.rs @@ -0,0 +1,345 @@ +//! Definitions for uclibc on 64bit systems +pub type blkcnt_t = i64; +pub type blksize_t = i64; +pub type clock_t = i64; +pub type c_char = u8; +pub type c_long = i64; +pub type c_ulong = u64; +pub type fsblkcnt_t = ::c_ulong; +pub type fsfilcnt_t = ::c_ulong; +pub type fsword_t = ::c_long; +pub type ino_t = ::c_ulong; +pub type nlink_t = ::c_uint; +pub type off_t = ::c_long; +// [uClibc docs] Note stat64 has the same shape as stat for x86-64. +pub type stat64 = stat; +pub type suseconds_t = ::c_long; +pub type time_t = ::c_int; +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 { + pub __key: ::key_t, + pub uid: ::uid_t, + pub gid: ::gid_t, + pub cuid: ::uid_t, + pub cgid: ::gid_t, + pub mode: ::c_ushort, // read / write + __pad1: ::c_ushort, + pub __seq: ::c_ushort, + __pad2: ::c_ushort, + __unused1: ::c_ulong, + __unused2: ::c_ulong + } + + #[cfg(not(target_os = "l4re"))] + pub struct pthread_attr_t { + __detachstate: ::c_int, + __schedpolicy: ::c_int, + __schedparam: __sched_param, + __inheritsched: ::c_int, + __scope: ::c_int, + __guardsize: ::size_t, + __stackaddr_set: ::c_int, + __stackaddr: *mut ::c_void, // better don't use it + __stacksize: ::size_t, + } + + pub struct __sched_param { + __sched_priority: ::c_int, + } + + pub struct siginfo_t { + si_signo: ::c_int, // signal number + si_errno: ::c_int, // if not zero: error value of signal, see errno.h + si_code: ::c_int, // signal code + pub _pad: [::c_int; 28], // unported union + _align: [usize; 0], + } + + pub struct shmid_ds { + pub shm_perm: ::ipc_perm, + pub shm_segsz: ::size_t, // segment size in bytes + pub shm_atime: ::time_t, // time of last shmat() + 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, + __unused1: ::c_ulong, + __unused2: ::c_ulong + } + + pub struct msqid_ds { + pub msg_perm: ::ipc_perm, + pub msg_stime: ::time_t, + pub msg_rtime: ::time_t, + pub msg_ctime: ::time_t, + __msg_cbytes: ::c_ulong, + pub msg_qnum: ::msgqnum_t, + pub msg_qbytes: ::msglen_t, + pub msg_lspid: ::pid_t, + pub msg_lrpid: ::pid_t, + __ignored1: ::c_ulong, + __ignored2: ::c_ulong, + } + + pub struct sockaddr { + pub sa_family: ::sa_family_t, + pub sa_data: [::c_char; 14], + } + + pub struct sockaddr_in { + pub sin_family: ::sa_family_t, + pub sin_port: ::in_port_t, + pub sin_addr: ::in_addr, + pub sin_zero: [u8; 8], + } + + 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, + } + + // ------------------------------------------------------------ + // definitions below are *unverified* and might **break** the software +// pub struct in_addr { +// pub s_addr: in_addr_t, +// } +// +// pub struct in6_addr { +// pub s6_addr: [u8; 16], +// #[cfg(not(libc_align))] +// __align: [u32; 0], +// } + + pub struct stat { + pub st_dev: ::c_ulong, + pub st_ino: ::ino_t, + // According to uclibc/libc/sysdeps/linux/x86_64/bits/stat.h, order of + // nlink and mode are swapped on 64 bit systems. + pub st_nlink: ::nlink_t, + pub st_mode: ::mode_t, + pub st_uid: ::uid_t, + pub st_gid: ::gid_t, + pub st_rdev: ::c_ulong, // dev_t + pub st_size: off_t, // file size + pub st_blksize: ::blksize_t, + pub st_blocks: ::blkcnt_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, + st_pad4: [::c_long; 3] + } + + pub struct sigaction { + pub sa_handler: ::sighandler_t, + pub sa_flags: ::c_ulong, + pub sa_restorer: ::Option, + pub sa_mask: ::sigset_t, + } + + pub struct stack_t { // FIXME + pub ss_sp: *mut ::c_void, + pub ss_flags: ::c_int, + pub ss_size: ::size_t + } + + pub struct statfs { // FIXME + 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, + f_spare: [fsword_t; 5], + } + + pub struct statfs64 { + pub f_type: ::c_int, + pub f_bsize: ::c_int, + 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_int, + pub f_frsize: ::c_int, + pub f_flags: ::c_int, + pub f_spare: [::c_int; 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 msghdr { // FIXME + pub msg_name: *mut ::c_void, + pub msg_namelen: ::socklen_t, + pub msg_iov: *mut ::iovec, + pub msg_iovlen: ::size_t, + pub msg_control: *mut ::c_void, + pub msg_controllen: ::size_t, + pub msg_flags: ::c_int, + } + + pub struct termios { // FIXME + pub c_iflag: ::tcflag_t, + pub c_oflag: ::tcflag_t, + pub c_cflag: ::tcflag_t, + pub c_lflag: ::tcflag_t, + pub c_line: ::cc_t, + pub c_cc: [::cc_t; ::NCCS], + } + + pub struct sigset_t { // FIXME + __val: [::c_ulong; 16], + } + + pub struct sysinfo { // FIXME + pub uptime: ::c_long, + pub loads: [::c_ulong; 3], + pub totalram: ::c_ulong, + pub freeram: ::c_ulong, + pub sharedram: ::c_ulong, + pub bufferram: ::c_ulong, + pub totalswap: ::c_ulong, + pub freeswap: ::c_ulong, + pub procs: ::c_ushort, + pub pad: ::c_ushort, + pub totalhigh: ::c_ulong, + pub freehigh: ::c_ulong, + pub mem_unit: ::c_uint, + pub _f: [::c_char; 0], + } + + pub struct glob_t { // FIXME + pub gl_pathc: ::size_t, + pub gl_pathv: *mut *mut c_char, + pub gl_offs: ::size_t, + pub gl_flags: ::c_int, + __unused1: *mut ::c_void, + __unused2: *mut ::c_void, + __unused3: *mut ::c_void, + __unused4: *mut ::c_void, + __unused5: *mut ::c_void, + } + + pub struct cpu_set_t { // FIXME + #[cfg(target_pointer_width = "32")] + bits: [u32; 32], + #[cfg(target_pointer_width = "64")] + bits: [u64; 16], + } + + pub struct fsid_t { // FIXME + __val: [::c_int; 2], + } + + // FIXME this is actually a union + pub struct sem_t { + #[cfg(target_pointer_width = "32")] + __size: [::c_char; 16], + #[cfg(target_pointer_width = "64")] + __size: [::c_char; 32], + __align: [::c_long; 0], + } + + pub struct cmsghdr { + pub cmsg_len: ::size_t, + pub cmsg_level: ::c_int, + pub cmsg_type: ::c_int, + } +} + +s_no_extra_traits! { + #[allow(missing_debug_implementations)] + pub struct dirent { + pub d_ino: ::ino64_t, + pub d_off: ::off64_t, + pub d_reclen: u16, + pub d_type: u8, + pub d_name: [::c_char; 256], + } +} + +// 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 +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 = 0o2000; +pub const O_ACCMODE: ::c_int = 0o003; +pub const O_CLOEXEC: ::c_int = 0x80000; +pub const O_CREAT: ::c_int = 0100; +pub const O_DIRECTORY: ::c_int = 0o200000; +pub const O_EXCL: ::c_int = 0o200; +pub const O_NOFOLLOW: ::c_int = 0x20000; +pub const O_NONBLOCK: ::c_int = 0o4000; +pub const O_TRUNC: ::c_int = 0o1000; +pub const NCCS: usize = 32; +pub const SIG_SETMASK: ::c_int = 2; // Set the set of blocked signals +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 __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 = 0o4000; + +cfg_if! { + if #[cfg(target_os = "l4re")] { + mod l4re; + pub use self::l4re::*; + } else { + mod other; + pub use other::*; + } +} diff --git a/vendor/libc/src/unix/linux_like/linux/uclibc/x86_64/other.rs b/vendor/libc/src/unix/linux_like/linux/uclibc/x86_64/other.rs new file mode 100644 index 0000000..481577c --- /dev/null +++ b/vendor/libc/src/unix/linux_like/linux/uclibc/x86_64/other.rs @@ -0,0 +1,5 @@ +// Thestyle checker discourages the use of #[cfg], so this has to go into a +// separate module +pub type pthread_t = ::c_ulong; + +pub const PTHREAD_STACK_MIN: usize = 16384; diff --git a/vendor/libc/src/unix/linux_like/mod.rs b/vendor/libc/src/unix/linux_like/mod.rs new file mode 100644 index 0000000..749c8a1 --- /dev/null +++ b/vendor/libc/src/unix/linux_like/mod.rs @@ -0,0 +1,1914 @@ +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; + +missing! { + #[cfg_attr(feature = "extra_traits", derive(Debug))] + pub enum timezone {} +} + +s! { + pub struct in_addr { + pub s_addr: ::in_addr_t, + } + + pub struct ip_mreq { + pub imr_multiaddr: in_addr, + pub imr_interface: in_addr, + } + + pub struct 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, + pub imr_sourceaddr: in_addr, + } + + pub struct sockaddr { + pub sa_family: sa_family_t, + pub sa_data: [::c_char; 14], + } + + pub struct sockaddr_in { + pub sin_family: sa_family_t, + pub sin_port: ::in_port_t, + pub sin_addr: ::in_addr, + pub sin_zero: [u8; 8], + } + + 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, + } + + // 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, + + #[cfg(any(target_os = "linux", + target_os = "emscripten"))] + pub ai_addr: *mut ::sockaddr, + + pub ai_canonname: *mut c_char, + + #[cfg(target_os = "android")] + pub ai_addr: *mut ::sockaddr, + + pub ai_next: *mut addrinfo, + } + + pub struct sockaddr_ll { + pub sll_family: ::c_ushort, + pub sll_protocol: ::c_ushort, + pub sll_ifindex: ::c_int, + pub sll_hatype: ::c_ushort, + pub sll_pkttype: ::c_uchar, + pub sll_halen: ::c_uchar, + pub sll_addr: [::c_uchar; 8] + } + + pub struct fd_set { + fds_bits: [::c_ulong; 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, + } + + pub struct sched_param { + pub sched_priority: ::c_int, + #[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", target_env = "ohos"))] + pub sched_ss_repl_period: ::timespec, + #[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", target_env = "ohos"))] + pub sched_ss_max_repl: ::c_int, + } + + 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 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_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 in_pktinfo { + pub ipi_ifindex: ::c_int, + pub ipi_spec_dst: ::in_addr, + pub ipi_addr: ::in_addr, + } + + 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_ifu: *mut ::sockaddr, // FIXME This should be a union + pub ifa_data: *mut ::c_void + } + + pub struct in6_rtmsg { + rtmsg_dst: ::in6_addr, + rtmsg_src: ::in6_addr, + rtmsg_gateway: ::in6_addr, + rtmsg_type: u32, + rtmsg_dst_len: u16, + rtmsg_src_len: u16, + rtmsg_metric: u32, + rtmsg_info: ::c_ulong, + rtmsg_flags: u32, + rtmsg_ifindex: ::c_int, + } + + pub struct arpreq { + pub arp_pa: ::sockaddr, + pub arp_ha: ::sockaddr, + pub arp_flags: ::c_int, + pub arp_netmask: ::sockaddr, + pub arp_dev: [::c_char; 16], + } + + pub struct arpreq_old { + pub arp_pa: ::sockaddr, + pub arp_ha: ::sockaddr, + pub arp_flags: ::c_int, + pub arp_netmask: ::sockaddr, + } + + 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, + } +} + +s_no_extra_traits! { + #[cfg_attr( + any( + all( + target_arch = "x86", + not(target_env = "musl"), + not(target_os = "android")), + target_arch = "x86_64"), + repr(packed))] + pub struct epoll_event { + pub events: u32, + pub u64: u64, + } + + pub struct sockaddr_un { + pub sun_family: sa_family_t, + pub sun_path: [::c_char; 108] + } + + pub struct sockaddr_storage { + pub ss_family: sa_family_t, + #[cfg(target_pointer_width = "32")] + __ss_pad2: [u8; 128 - 2 - 4], + #[cfg(target_pointer_width = "64")] + __ss_pad2: [u8; 128 - 2 - 8], + __ss_align: ::size_t, + } + + pub struct utsname { + pub sysname: [::c_char; 65], + pub nodename: [::c_char; 65], + pub release: [::c_char; 65], + pub version: [::c_char; 65], + pub machine: [::c_char; 65], + pub domainname: [::c_char; 65] + } + + pub struct sigevent { + pub sigev_value: ::sigval, + pub sigev_signo: ::c_int, + pub sigev_notify: ::c_int, + // Actually a union. We only expose sigev_notify_thread_id because it's + // the most useful member + pub sigev_notify_thread_id: ::c_int, + #[cfg(target_pointer_width = "64")] + __unused1: [::c_int; 11], + #[cfg(target_pointer_width = "32")] + __unused1: [::c_int; 12] + } +} + +cfg_if! { + if #[cfg(feature = "extra_traits")] { + impl PartialEq for epoll_event { + fn eq(&self, other: &epoll_event) -> bool { + self.events == other.events + && self.u64 == other.u64 + } + } + impl Eq for epoll_event {} + impl ::fmt::Debug for epoll_event { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + let events = self.events; + let u64 = self.u64; + f.debug_struct("epoll_event") + .field("events", &events) + .field("u64", &u64) + .finish() + } + } + impl ::hash::Hash for epoll_event { + fn hash(&self, state: &mut H) { + let events = self.events; + let u64 = self.u64; + events.hash(state); + u64.hash(state); + } + } + + impl PartialEq for sockaddr_un { + fn eq(&self, other: &sockaddr_un) -> bool { + self.sun_family == other.sun_family + && self + .sun_path + .iter() + .zip(other.sun_path.iter()) + .all(|(a, b)| a == b) + } + } + impl Eq for sockaddr_un {} + impl ::fmt::Debug for sockaddr_un { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("sockaddr_un") + .field("sun_family", &self.sun_family) + // FIXME: .field("sun_path", &self.sun_path) + .finish() + } + } + impl ::hash::Hash for sockaddr_un { + fn hash(&self, state: &mut H) { + self.sun_family.hash(state); + self.sun_path.hash(state); + } + } + + impl PartialEq for sockaddr_storage { + fn eq(&self, other: &sockaddr_storage) -> bool { + self.ss_family == other.ss_family + && self + .__ss_pad2 + .iter() + .zip(other.__ss_pad2.iter()) + .all(|(a, b)| a == b) + } + } + + impl Eq for sockaddr_storage {} + + impl ::fmt::Debug for sockaddr_storage { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("sockaddr_storage") + .field("ss_family", &self.ss_family) + .field("__ss_align", &self.__ss_align) + // FIXME: .field("__ss_pad2", &self.__ss_pad2) + .finish() + } + } + + impl ::hash::Hash for sockaddr_storage { + fn hash(&self, state: &mut H) { + self.ss_family.hash(state); + self.__ss_pad2.hash(state); + } + } + + impl PartialEq for utsname { + fn eq(&self, other: &utsname) -> bool { + self.sysname + .iter() + .zip(other.sysname.iter()) + .all(|(a, b)| a == b) + && self + .nodename + .iter() + .zip(other.nodename.iter()) + .all(|(a, b)| a == b) + && self + .release + .iter() + .zip(other.release.iter()) + .all(|(a, b)| a == b) + && self + .version + .iter() + .zip(other.version.iter()) + .all(|(a, b)| a == b) + && self + .machine + .iter() + .zip(other.machine.iter()) + .all(|(a, b)| a == b) + && self + .domainname + .iter() + .zip(other.domainname.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) + // FIXME: .field("domainname", &self.domainname) + .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); + self.domainname.hash(state); + } + } + + impl PartialEq for sigevent { + fn eq(&self, other: &sigevent) -> bool { + self.sigev_value == other.sigev_value + && self.sigev_signo == other.sigev_signo + && self.sigev_notify == other.sigev_notify + && 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_value", &self.sigev_value) + .field("sigev_signo", &self.sigev_signo) + .field("sigev_notify", &self.sigev_notify) + .field("sigev_notify_thread_id", + &self.sigev_notify_thread_id) + .finish() + } + } + impl ::hash::Hash for sigevent { + fn hash(&self, state: &mut H) { + self.sigev_value.hash(state); + self.sigev_signo.hash(state); + self.sigev_notify.hash(state); + self.sigev_notify_thread_id.hash(state); + } + } + } +} + +// 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 = 2147483647; +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; + +// Linux-specific fcntls +pub const F_SETLEASE: ::c_int = 1024; +pub const F_GETLEASE: ::c_int = 1025; +pub const F_NOTIFY: ::c_int = 1026; +pub const F_CANCELLK: ::c_int = 1029; +pub const F_DUPFD_CLOEXEC: ::c_int = 1030; +pub const F_SETPIPE_SZ: ::c_int = 1031; +pub const F_GETPIPE_SZ: ::c_int = 1032; +pub const F_ADD_SEALS: ::c_int = 1033; +pub const F_GET_SEALS: ::c_int = 1034; + +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; + +// FIXME(#235): Include file sealing fcntls once we have a way to verify them. + +pub const SIGTRAP: ::c_int = 5; + +pub const PTHREAD_CREATE_JOINABLE: ::c_int = 0; +pub const PTHREAD_CREATE_DETACHED: ::c_int = 1; + +pub const CLOCK_REALTIME: ::clockid_t = 0; +pub const CLOCK_MONOTONIC: ::clockid_t = 1; +pub const CLOCK_PROCESS_CPUTIME_ID: ::clockid_t = 2; +pub const CLOCK_THREAD_CPUTIME_ID: ::clockid_t = 3; +pub const CLOCK_MONOTONIC_RAW: ::clockid_t = 4; +pub const CLOCK_REALTIME_COARSE: ::clockid_t = 5; +pub const CLOCK_MONOTONIC_COARSE: ::clockid_t = 6; +pub const CLOCK_BOOTTIME: ::clockid_t = 7; +pub const CLOCK_REALTIME_ALARM: ::clockid_t = 8; +pub const CLOCK_BOOTTIME_ALARM: ::clockid_t = 9; +pub const CLOCK_TAI: ::clockid_t = 11; +pub const TIMER_ABSTIME: ::c_int = 1; + +pub const RUSAGE_SELF: ::c_int = 0; + +pub const O_RDONLY: ::c_int = 0; +pub const O_WRONLY: ::c_int = 1; +pub const O_RDWR: ::c_int = 2; + +pub const SOCK_CLOEXEC: ::c_int = O_CLOEXEC; + +pub const S_IFIFO: ::mode_t = 4096; +pub const S_IFCHR: ::mode_t = 8192; +pub const S_IFBLK: ::mode_t = 24576; +pub const S_IFDIR: ::mode_t = 16384; +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 = 61440; +pub const S_IRWXU: ::mode_t = 448; +pub const S_IXUSR: ::mode_t = 64; +pub const S_IWUSR: ::mode_t = 128; +pub const S_IRUSR: ::mode_t = 256; +pub const S_IRWXG: ::mode_t = 56; +pub const S_IXGRP: ::mode_t = 8; +pub const S_IWGRP: ::mode_t = 16; +pub const S_IRGRP: ::mode_t = 32; +pub const S_IRWXO: ::mode_t = 7; +pub const S_IXOTH: ::mode_t = 1; +pub const S_IWOTH: ::mode_t = 2; +pub const S_IROTH: ::mode_t = 4; +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; +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 = 0; +pub const PROT_READ: ::c_int = 1; +pub const PROT_WRITE: ::c_int = 2; +pub const PROT_EXEC: ::c_int = 4; + +pub const XATTR_CREATE: ::c_int = 0x1; +pub const XATTR_REPLACE: ::c_int = 0x2; + +cfg_if! { + 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; + pub const LC_COLLATE: ::c_int = 3; + pub const LC_MONETARY: ::c_int = 4; + pub const LC_MESSAGES: ::c_int = 5; + pub const LC_ALL: ::c_int = 6; + } +} + +pub const LC_CTYPE_MASK: ::c_int = 1 << LC_CTYPE; +pub const LC_NUMERIC_MASK: ::c_int = 1 << LC_NUMERIC; +pub const LC_TIME_MASK: ::c_int = 1 << LC_TIME; +pub const LC_COLLATE_MASK: ::c_int = 1 << LC_COLLATE; +pub const LC_MONETARY_MASK: ::c_int = 1 << LC_MONETARY; +pub const LC_MESSAGES_MASK: ::c_int = 1 << LC_MESSAGES; +// LC_ALL_MASK defined per platform + +pub const MAP_FILE: ::c_int = 0x0000; +pub const MAP_SHARED: ::c_int = 0x0001; +pub const MAP_PRIVATE: ::c_int = 0x0002; +pub const MAP_FIXED: ::c_int = 0x0010; + +pub const MAP_FAILED: *mut ::c_void = !0 as *mut ::c_void; + +// MS_ flags for msync(2) +pub const MS_ASYNC: ::c_int = 0x0001; +pub const MS_INVALIDATE: ::c_int = 0x0002; +pub const MS_SYNC: ::c_int = 0x0004; + +// MS_ flags for mount(2) +pub const MS_RDONLY: ::c_ulong = 0x01; +pub const MS_NOSUID: ::c_ulong = 0x02; +pub const MS_NODEV: ::c_ulong = 0x04; +pub const MS_NOEXEC: ::c_ulong = 0x08; +pub const MS_SYNCHRONOUS: ::c_ulong = 0x10; +pub const MS_REMOUNT: ::c_ulong = 0x20; +pub const MS_MANDLOCK: ::c_ulong = 0x40; +pub const MS_DIRSYNC: ::c_ulong = 0x80; +pub const MS_NOATIME: ::c_ulong = 0x0400; +pub const MS_NODIRATIME: ::c_ulong = 0x0800; +pub const MS_BIND: ::c_ulong = 0x1000; +pub const MS_MOVE: ::c_ulong = 0x2000; +pub const MS_REC: ::c_ulong = 0x4000; +pub const MS_SILENT: ::c_ulong = 0x8000; +pub const MS_POSIXACL: ::c_ulong = 0x010000; +pub const MS_UNBINDABLE: ::c_ulong = 0x020000; +pub const MS_PRIVATE: ::c_ulong = 0x040000; +pub const MS_SLAVE: ::c_ulong = 0x080000; +pub const MS_SHARED: ::c_ulong = 0x100000; +pub const MS_RELATIME: ::c_ulong = 0x200000; +pub const MS_KERNMOUNT: ::c_ulong = 0x400000; +pub const MS_I_VERSION: ::c_ulong = 0x800000; +pub const MS_STRICTATIME: ::c_ulong = 0x1000000; +pub const MS_LAZYTIME: ::c_ulong = 0x2000000; +pub const MS_ACTIVE: ::c_ulong = 0x40000000; +pub const MS_MGC_VAL: ::c_ulong = 0xc0ed0000; +pub const MS_MGC_MSK: ::c_ulong = 0xffff0000; + +pub const SCM_RIGHTS: ::c_int = 0x01; +pub const SCM_CREDENTIALS: ::c_int = 0x02; + +pub const PROT_GROWSDOWN: ::c_int = 0x1000000; +pub const PROT_GROWSUP: ::c_int = 0x2000000; + +pub const MAP_TYPE: ::c_int = 0x000f; + +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 MADV_FREE: ::c_int = 8; +pub const MADV_REMOVE: ::c_int = 9; +pub const MADV_DONTFORK: ::c_int = 10; +pub const MADV_DOFORK: ::c_int = 11; +pub const MADV_MERGEABLE: ::c_int = 12; +pub const MADV_UNMERGEABLE: ::c_int = 13; +pub const MADV_HUGEPAGE: ::c_int = 14; +pub const MADV_NOHUGEPAGE: ::c_int = 15; +pub const MADV_DONTDUMP: ::c_int = 16; +pub const MADV_DODUMP: ::c_int = 17; +pub const MADV_WIPEONFORK: ::c_int = 18; +pub const MADV_KEEPONFORK: ::c_int = 19; +pub const MADV_COLD: ::c_int = 20; +pub const MADV_PAGEOUT: ::c_int = 21; +pub const MADV_HWPOISON: ::c_int = 100; +cfg_if! { + if #[cfg(not(target_os = "emscripten"))] { + pub const MADV_POPULATE_READ: ::c_int = 22; + pub const MADV_POPULATE_WRITE: ::c_int = 23; + pub const MADV_DONTNEED_LOCKED: ::c_int = 24; + } +} + +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_MASTER: ::c_int = 0x400; +pub const IFF_SLAVE: ::c_int = 0x800; +pub const IFF_MULTICAST: ::c_int = 0x1000; +pub const IFF_PORTSEL: ::c_int = 0x2000; +pub const IFF_AUTOMEDIA: ::c_int = 0x4000; +pub const IFF_DYNAMIC: ::c_int = 0x8000; + +pub const SOL_IP: ::c_int = 0; +pub const SOL_TCP: ::c_int = 6; +pub const SOL_UDP: ::c_int = 17; +pub const SOL_IPV6: ::c_int = 41; +pub const SOL_ICMPV6: ::c_int = 58; +pub const SOL_RAW: ::c_int = 255; +pub const SOL_DECNET: ::c_int = 261; +pub const SOL_X25: ::c_int = 262; +pub const SOL_PACKET: ::c_int = 263; +pub const SOL_ATM: ::c_int = 264; +pub const SOL_AAL: ::c_int = 265; +pub const SOL_IRDA: ::c_int = 266; +pub const SOL_NETBEUI: ::c_int = 267; +pub const SOL_LLC: ::c_int = 268; +pub const SOL_DCCP: ::c_int = 269; +pub const SOL_NETLINK: ::c_int = 270; +pub const SOL_TIPC: ::c_int = 271; +pub const SOL_BLUETOOTH: ::c_int = 274; +pub const SOL_ALG: ::c_int = 279; + +pub const AF_UNSPEC: ::c_int = 0; +pub const AF_UNIX: ::c_int = 1; +pub const AF_LOCAL: ::c_int = 1; +pub const AF_INET: ::c_int = 2; +pub const AF_AX25: ::c_int = 3; +pub const AF_IPX: ::c_int = 4; +pub const AF_APPLETALK: ::c_int = 5; +pub const AF_NETROM: ::c_int = 6; +pub const AF_BRIDGE: ::c_int = 7; +pub const AF_ATMPVC: ::c_int = 8; +pub const AF_X25: ::c_int = 9; +pub const AF_INET6: ::c_int = 10; +pub const AF_ROSE: ::c_int = 11; +pub const AF_DECnet: ::c_int = 12; +pub const AF_NETBEUI: ::c_int = 13; +pub const AF_SECURITY: ::c_int = 14; +pub const AF_KEY: ::c_int = 15; +pub const AF_NETLINK: ::c_int = 16; +pub const AF_ROUTE: ::c_int = AF_NETLINK; +pub const AF_PACKET: ::c_int = 17; +pub const AF_ASH: ::c_int = 18; +pub const AF_ECONET: ::c_int = 19; +pub const AF_ATMSVC: ::c_int = 20; +pub const AF_RDS: ::c_int = 21; +pub const AF_SNA: ::c_int = 22; +pub const AF_IRDA: ::c_int = 23; +pub const AF_PPPOX: ::c_int = 24; +pub const AF_WANPIPE: ::c_int = 25; +pub const AF_LLC: ::c_int = 26; +pub const AF_CAN: ::c_int = 29; +pub const AF_TIPC: ::c_int = 30; +pub const AF_BLUETOOTH: ::c_int = 31; +pub const AF_IUCV: ::c_int = 32; +pub const AF_RXRPC: ::c_int = 33; +pub const AF_ISDN: ::c_int = 34; +pub const AF_PHONET: ::c_int = 35; +pub const AF_IEEE802154: ::c_int = 36; +pub const AF_CAIF: ::c_int = 37; +pub const AF_ALG: ::c_int = 38; + +pub const PF_UNSPEC: ::c_int = AF_UNSPEC; +pub const PF_UNIX: ::c_int = AF_UNIX; +pub const PF_LOCAL: ::c_int = AF_LOCAL; +pub const PF_INET: ::c_int = AF_INET; +pub const PF_AX25: ::c_int = AF_AX25; +pub const PF_IPX: ::c_int = AF_IPX; +pub const PF_APPLETALK: ::c_int = AF_APPLETALK; +pub const PF_NETROM: ::c_int = AF_NETROM; +pub const PF_BRIDGE: ::c_int = AF_BRIDGE; +pub const PF_ATMPVC: ::c_int = AF_ATMPVC; +pub const PF_X25: ::c_int = AF_X25; +pub const PF_INET6: ::c_int = AF_INET6; +pub const PF_ROSE: ::c_int = AF_ROSE; +pub const PF_DECnet: ::c_int = AF_DECnet; +pub const PF_NETBEUI: ::c_int = AF_NETBEUI; +pub const PF_SECURITY: ::c_int = AF_SECURITY; +pub const PF_KEY: ::c_int = AF_KEY; +pub const PF_NETLINK: ::c_int = AF_NETLINK; +pub const PF_ROUTE: ::c_int = AF_ROUTE; +pub const PF_PACKET: ::c_int = AF_PACKET; +pub const PF_ASH: ::c_int = AF_ASH; +pub const PF_ECONET: ::c_int = AF_ECONET; +pub const PF_ATMSVC: ::c_int = AF_ATMSVC; +pub const PF_RDS: ::c_int = AF_RDS; +pub const PF_SNA: ::c_int = AF_SNA; +pub const PF_IRDA: ::c_int = AF_IRDA; +pub const PF_PPPOX: ::c_int = AF_PPPOX; +pub const PF_WANPIPE: ::c_int = AF_WANPIPE; +pub const PF_LLC: ::c_int = AF_LLC; +pub const PF_CAN: ::c_int = AF_CAN; +pub const PF_TIPC: ::c_int = AF_TIPC; +pub const PF_BLUETOOTH: ::c_int = AF_BLUETOOTH; +pub const PF_IUCV: ::c_int = AF_IUCV; +pub const PF_RXRPC: ::c_int = AF_RXRPC; +pub const PF_ISDN: ::c_int = AF_ISDN; +pub const PF_PHONET: ::c_int = AF_PHONET; +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 MSG_OOB: ::c_int = 1; +pub const MSG_PEEK: ::c_int = 2; +pub const MSG_DONTROUTE: ::c_int = 4; +pub const MSG_CTRUNC: ::c_int = 8; +pub const MSG_TRUNC: ::c_int = 0x20; +pub const MSG_DONTWAIT: ::c_int = 0x40; +pub const MSG_EOR: ::c_int = 0x80; +pub const MSG_WAITALL: ::c_int = 0x100; +pub const MSG_FIN: ::c_int = 0x200; +pub const MSG_SYN: ::c_int = 0x400; +pub const MSG_CONFIRM: ::c_int = 0x800; +pub const MSG_RST: ::c_int = 0x1000; +pub const MSG_ERRQUEUE: ::c_int = 0x2000; +pub const MSG_NOSIGNAL: ::c_int = 0x4000; +pub const MSG_MORE: ::c_int = 0x8000; +pub const MSG_WAITFORONE: ::c_int = 0x10000; +pub const MSG_FASTOPEN: ::c_int = 0x20000000; +pub const MSG_CMSG_CLOEXEC: ::c_int = 0x40000000; + +pub const SCM_TIMESTAMP: ::c_int = SO_TIMESTAMP; + +pub const SOCK_RAW: ::c_int = 3; +pub const SOCK_RDM: ::c_int = 4; +pub const IP_TOS: ::c_int = 1; +pub const IP_TTL: ::c_int = 2; +pub const IP_HDRINCL: ::c_int = 3; +pub const IP_OPTIONS: ::c_int = 4; +pub const IP_ROUTER_ALERT: ::c_int = 5; +pub const IP_RECVOPTS: ::c_int = 6; +pub const IP_RETOPTS: ::c_int = 7; +pub const IP_PKTINFO: ::c_int = 8; +pub const IP_PKTOPTIONS: ::c_int = 9; +pub const IP_MTU_DISCOVER: ::c_int = 10; +pub const IP_RECVERR: ::c_int = 11; +pub const IP_RECVTTL: ::c_int = 12; +pub const IP_RECVTOS: ::c_int = 13; +pub const IP_MTU: ::c_int = 14; +pub const IP_FREEBIND: ::c_int = 15; +pub const IP_IPSEC_POLICY: ::c_int = 16; +pub const IP_XFRM_POLICY: ::c_int = 17; +pub const IP_PASSSEC: ::c_int = 18; +pub const IP_TRANSPARENT: ::c_int = 19; +pub const IP_ORIGDSTADDR: ::c_int = 20; +pub const IP_RECVORIGDSTADDR: ::c_int = IP_ORIGDSTADDR; +pub const IP_MINTTL: ::c_int = 21; +pub const IP_NODEFRAG: ::c_int = 22; +pub const IP_CHECKSUM: ::c_int = 23; +pub const IP_BIND_ADDRESS_NO_PORT: ::c_int = 24; +pub const IP_MULTICAST_IF: ::c_int = 32; +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 IP_UNBLOCK_SOURCE: ::c_int = 37; +pub const IP_BLOCK_SOURCE: ::c_int = 38; +pub const IP_ADD_SOURCE_MEMBERSHIP: ::c_int = 39; +pub const IP_DROP_SOURCE_MEMBERSHIP: ::c_int = 40; +pub const IP_MSFILTER: ::c_int = 41; +pub const IP_MULTICAST_ALL: ::c_int = 49; +pub const IP_UNICAST_IF: ::c_int = 50; + +pub const IP_DEFAULT_MULTICAST_TTL: ::c_int = 1; +pub const IP_DEFAULT_MULTICAST_LOOP: ::c_int = 1; + +pub const IP_PMTUDISC_DONT: ::c_int = 0; +pub const IP_PMTUDISC_WANT: ::c_int = 1; +pub const IP_PMTUDISC_DO: ::c_int = 2; +pub const IP_PMTUDISC_PROBE: ::c_int = 3; +pub const IP_PMTUDISC_INTERFACE: ::c_int = 4; +pub const IP_PMTUDISC_OMIT: ::c_int = 5; + +// IPPROTO_IP defined in src/unix/mod.rs +/// Hop-by-hop option header +pub const IPPROTO_HOPOPTS: ::c_int = 0; +// IPPROTO_ICMP defined in src/unix/mod.rs +/// group mgmt protocol +pub const IPPROTO_IGMP: ::c_int = 2; +/// for compatibility +pub const IPPROTO_IPIP: ::c_int = 4; +// IPPROTO_TCP defined in src/unix/mod.rs +/// exterior gateway protocol +pub const IPPROTO_EGP: ::c_int = 8; +/// pup +pub const IPPROTO_PUP: ::c_int = 12; +// IPPROTO_UDP defined in src/unix/mod.rs +/// xns idp +pub const IPPROTO_IDP: ::c_int = 22; +/// tp-4 w/ class negotiation +pub const IPPROTO_TP: ::c_int = 29; +/// DCCP +pub const IPPROTO_DCCP: ::c_int = 33; +// IPPROTO_IPV6 defined in src/unix/mod.rs +/// IP6 routing header +pub const IPPROTO_ROUTING: ::c_int = 43; +/// IP6 fragmentation header +pub const IPPROTO_FRAGMENT: ::c_int = 44; +/// resource reservation +pub const IPPROTO_RSVP: ::c_int = 46; +/// General Routing Encap. +pub const IPPROTO_GRE: ::c_int = 47; +/// IP6 Encap Sec. Payload +pub const IPPROTO_ESP: ::c_int = 50; +/// IP6 Auth Header +pub const IPPROTO_AH: ::c_int = 51; +// IPPROTO_ICMPV6 defined in src/unix/mod.rs +/// IP6 no next header +pub const IPPROTO_NONE: ::c_int = 59; +/// IP6 destination option +pub const IPPROTO_DSTOPTS: ::c_int = 60; +pub const IPPROTO_MTP: ::c_int = 92; +/// encapsulation header +pub const IPPROTO_ENCAP: ::c_int = 98; +/// Protocol indep. multicast +pub const IPPROTO_PIM: ::c_int = 103; +/// IP Payload Comp. Protocol +pub const IPPROTO_COMP: ::c_int = 108; +/// SCTP +pub const IPPROTO_SCTP: ::c_int = 132; +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; +/// Multipath TCP +pub const IPPROTO_MPTCP: ::c_int = 262; +/// Ethernet-within-IPv6 encapsulation. +pub const IPPROTO_ETHERNET: ::c_int = 143; + +pub const MCAST_EXCLUDE: ::c_int = 0; +pub const MCAST_INCLUDE: ::c_int = 1; +pub const MCAST_JOIN_GROUP: ::c_int = 42; +pub const MCAST_BLOCK_SOURCE: ::c_int = 43; +pub const MCAST_UNBLOCK_SOURCE: ::c_int = 44; +pub const MCAST_LEAVE_GROUP: ::c_int = 45; +pub const MCAST_JOIN_SOURCE_GROUP: ::c_int = 46; +pub const MCAST_LEAVE_SOURCE_GROUP: ::c_int = 47; +pub const MCAST_MSFILTER: ::c_int = 48; + +pub const IPV6_ADDRFORM: ::c_int = 1; +pub const IPV6_2292PKTINFO: ::c_int = 2; +pub const IPV6_2292HOPOPTS: ::c_int = 3; +pub const IPV6_2292DSTOPTS: ::c_int = 4; +pub const IPV6_2292RTHDR: ::c_int = 5; +pub const IPV6_2292PKTOPTIONS: ::c_int = 6; +pub const IPV6_CHECKSUM: ::c_int = 7; +pub const IPV6_2292HOPLIMIT: ::c_int = 8; +pub const IPV6_NEXTHOP: ::c_int = 9; +pub const IPV6_AUTHHDR: ::c_int = 10; +pub const IPV6_UNICAST_HOPS: ::c_int = 16; +pub const IPV6_MULTICAST_IF: ::c_int = 17; +pub const IPV6_MULTICAST_HOPS: ::c_int = 18; +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_ROUTER_ALERT: ::c_int = 22; +pub const IPV6_MTU_DISCOVER: ::c_int = 23; +pub const IPV6_MTU: ::c_int = 24; +pub const IPV6_RECVERR: ::c_int = 25; +pub const IPV6_V6ONLY: ::c_int = 26; +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; +pub const IPV6_HOPLIMIT: ::c_int = 52; +pub const IPV6_RECVHOPOPTS: ::c_int = 53; +pub const IPV6_HOPOPTS: ::c_int = 54; +pub const IPV6_RTHDRDSTOPTS: ::c_int = 55; +pub const IPV6_RECVRTHDR: ::c_int = 56; +pub const IPV6_RTHDR: ::c_int = 57; +pub const IPV6_RECVDSTOPTS: ::c_int = 58; +pub const IPV6_DSTOPTS: ::c_int = 59; +pub const IPV6_RECVPATHMTU: ::c_int = 60; +pub const IPV6_PATHMTU: ::c_int = 61; +pub const IPV6_DONTFRAG: ::c_int = 62; +pub const IPV6_RECVTCLASS: ::c_int = 66; +pub const IPV6_TCLASS: ::c_int = 67; +pub const IPV6_AUTOFLOWLABEL: ::c_int = 70; +pub const IPV6_ADDR_PREFERENCES: ::c_int = 72; +pub const IPV6_MINHOPCOUNT: ::c_int = 73; +pub const IPV6_ORIGDSTADDR: ::c_int = 74; +pub const IPV6_RECVORIGDSTADDR: ::c_int = IPV6_ORIGDSTADDR; +pub const IPV6_TRANSPARENT: ::c_int = 75; +pub const IPV6_UNICAST_IF: ::c_int = 76; +pub const IPV6_PREFER_SRC_TMP: ::c_int = 0x0001; +pub const IPV6_PREFER_SRC_PUBLIC: ::c_int = 0x0002; +pub const IPV6_PREFER_SRC_PUBTMP_DEFAULT: ::c_int = 0x0100; +pub const IPV6_PREFER_SRC_COA: ::c_int = 0x0004; +pub const IPV6_PREFER_SRC_HOME: ::c_int = 0x0400; +pub const IPV6_PREFER_SRC_CGA: ::c_int = 0x0008; +pub const IPV6_PREFER_SRC_NONCGA: ::c_int = 0x0800; + +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; +pub const TCP_CORK: ::c_int = 3; +pub const TCP_KEEPIDLE: ::c_int = 4; +pub const TCP_KEEPINTVL: ::c_int = 5; +pub const TCP_KEEPCNT: ::c_int = 6; +pub const TCP_SYNCNT: ::c_int = 7; +pub const TCP_LINGER2: ::c_int = 8; +pub const TCP_DEFER_ACCEPT: ::c_int = 9; +pub const TCP_WINDOW_CLAMP: ::c_int = 10; +pub const TCP_INFO: ::c_int = 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", + target_env = "ohos" + )))] { + // WARN: deprecated + pub const TCP_COOKIE_TRANSACTIONS: ::c_int = 15; + } +} +pub const TCP_THIN_LINEAR_TIMEOUTS: ::c_int = 16; +pub const TCP_THIN_DUPACK: ::c_int = 17; +pub const TCP_USER_TIMEOUT: ::c_int = 18; +pub const TCP_REPAIR: ::c_int = 19; +pub const TCP_REPAIR_QUEUE: ::c_int = 20; +pub const TCP_QUEUE_SEQ: ::c_int = 21; +pub const TCP_REPAIR_OPTIONS: ::c_int = 22; +pub const TCP_FASTOPEN: ::c_int = 23; +pub const TCP_TIMESTAMP: ::c_int = 24; +pub const TCP_NOTSENT_LOWAT: ::c_int = 25; +pub const TCP_CC_INFO: ::c_int = 26; +pub const TCP_SAVE_SYN: ::c_int = 27; +pub const TCP_SAVED_SYN: ::c_int = 28; +cfg_if! { + if #[cfg(not(target_os = "emscripten"))] { + // NOTE: emscripten doesn't support these options yet. + + pub const TCP_REPAIR_WINDOW: ::c_int = 29; + pub const TCP_FASTOPEN_CONNECT: ::c_int = 30; + pub const TCP_ULP: ::c_int = 31; + pub const TCP_MD5SIG_EXT: ::c_int = 32; + pub const TCP_FASTOPEN_KEY: ::c_int = 33; + pub const TCP_FASTOPEN_NO_COOKIE: ::c_int = 34; + pub const TCP_ZEROCOPY_RECEIVE: ::c_int = 35; + pub const TCP_INQ: ::c_int = 36; + 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; + } +} + +pub const SO_DEBUG: ::c_int = 1; + +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 = 1; +pub const LOCK_EX: ::c_int = 2; +pub const LOCK_NB: ::c_int = 4; +pub const LOCK_UN: ::c_int = 8; + +pub const SS_ONSTACK: ::c_int = 1; +pub const SS_DISABLE: ::c_int = 2; + +pub const PATH_MAX: ::c_int = 4096; + +pub const UIO_MAXIOV: ::c_int = 1024; + +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 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; +pub const Q_SETINFO: ::c_int = 0x800006; +pub const QIF_BLIMITS: u32 = 1; +pub const QIF_SPACE: u32 = 2; +pub const QIF_ILIMITS: u32 = 4; +pub const QIF_INODES: u32 = 8; +pub const QIF_BTIME: u32 = 16; +pub const QIF_ITIME: u32 = 32; +pub const QIF_LIMITS: u32 = 5; +pub const QIF_USAGE: u32 = 10; +pub const QIF_TIMES: u32 = 48; +pub const QIF_ALL: u32 = 63; + +pub const Q_SYNC: ::c_int = 0x800001; +pub const Q_QUOTAON: ::c_int = 0x800002; +pub const Q_QUOTAOFF: ::c_int = 0x800003; +pub const Q_GETQUOTA: ::c_int = 0x800007; +pub const Q_SETQUOTA: ::c_int = 0x800008; + +pub const TCIOFF: ::c_int = 2; +pub const TCION: ::c_int = 3; +pub const TCOOFF: ::c_int = 0; +pub const TCOON: ::c_int = 1; +pub const TCIFLUSH: ::c_int = 0; +pub const TCOFLUSH: ::c_int = 1; +pub const TCIOFLUSH: ::c_int = 2; +pub const NL0: ::tcflag_t = 0x00000000; +pub const NL1: ::tcflag_t = 0x00000100; +pub const TAB0: ::tcflag_t = 0x00000000; +pub const CR0: ::tcflag_t = 0x00000000; +pub const FF0: ::tcflag_t = 0x00000000; +pub const BS0: ::tcflag_t = 0x00000000; +pub const VT0: ::tcflag_t = 0x00000000; +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 = 0x1; +pub const CS5: ::tcflag_t = 0x00000000; +pub const CRTSCTS: ::tcflag_t = 0x80000000; +pub const ECHO: ::tcflag_t = 0x00000008; +pub const OCRNL: ::tcflag_t = 0o000010; +pub const ONOCR: ::tcflag_t = 0o000020; +pub const ONLRET: ::tcflag_t = 0o000040; +pub const OFILL: ::tcflag_t = 0o000100; +pub const OFDEL: ::tcflag_t = 0o000200; + +pub const CLONE_VM: ::c_int = 0x100; +pub const CLONE_FS: ::c_int = 0x200; +pub const CLONE_FILES: ::c_int = 0x400; +pub const CLONE_SIGHAND: ::c_int = 0x800; +pub const CLONE_PTRACE: ::c_int = 0x2000; +pub const CLONE_VFORK: ::c_int = 0x4000; +pub const CLONE_PARENT: ::c_int = 0x8000; +pub const CLONE_THREAD: ::c_int = 0x10000; +pub const CLONE_NEWNS: ::c_int = 0x20000; +pub const CLONE_SYSVSEM: ::c_int = 0x40000; +pub const CLONE_SETTLS: ::c_int = 0x80000; +pub const CLONE_PARENT_SETTID: ::c_int = 0x100000; +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; +pub const CLONE_NEWPID: ::c_int = 0x20000000; +pub const CLONE_NEWNET: ::c_int = 0x40000000; +pub const CLONE_IO: ::c_int = 0x80000000; + +pub const WNOHANG: ::c_int = 0x00000001; +pub const WUNTRACED: ::c_int = 0x00000002; +pub const WSTOPPED: ::c_int = WUNTRACED; +pub const WEXITED: ::c_int = 0x00000004; +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; +pub const PTRACE_O_TRACEFORK: ::c_int = 0x00000002; +pub const PTRACE_O_TRACEVFORK: ::c_int = 0x00000004; +pub const PTRACE_O_TRACECLONE: ::c_int = 0x00000008; +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; +pub const PTRACE_EVENT_VFORK: ::c_int = 2; +pub const PTRACE_EVENT_CLONE: ::c_int = 3; +pub const PTRACE_EVENT_EXEC: ::c_int = 4; +pub const PTRACE_EVENT_VFORK_DONE: ::c_int = 5; +pub const PTRACE_EVENT_EXIT: ::c_int = 6; +pub const PTRACE_EVENT_SECCOMP: ::c_int = 7; + +pub const __WNOTHREAD: ::c_int = 0x20000000; +pub const __WALL: ::c_int = 0x40000000; +pub const __WCLONE: ::c_int = 0x80000000; + +pub const SPLICE_F_MOVE: ::c_uint = 0x01; +pub const SPLICE_F_NONBLOCK: ::c_uint = 0x02; +pub const SPLICE_F_MORE: ::c_uint = 0x04; +pub const SPLICE_F_GIFT: ::c_uint = 0x08; + +pub const RTLD_LOCAL: ::c_int = 0; +pub const RTLD_LAZY: ::c_int = 1; + +pub const POSIX_FADV_NORMAL: ::c_int = 0; +pub const POSIX_FADV_RANDOM: ::c_int = 1; +pub const POSIX_FADV_SEQUENTIAL: ::c_int = 2; +pub const POSIX_FADV_WILLNEED: ::c_int = 3; + +pub const AT_FDCWD: ::c_int = -100; +pub const AT_SYMLINK_NOFOLLOW: ::c_int = 0x100; +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; +pub const LOG_FTP: ::c_int = 11 << 3; +pub const LOG_PERROR: ::c_int = 0x20; + +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; +pub const CLD_TRAPPED: ::c_int = 4; +pub const CLD_STOPPED: ::c_int = 5; +pub const CLD_CONTINUED: ::c_int = 6; + +pub const SIGEV_SIGNAL: ::c_int = 0; +pub const SIGEV_NONE: ::c_int = 1; +pub const SIGEV_THREAD: ::c_int = 2; + +pub const P_ALL: idtype_t = 0; +pub const P_PID: idtype_t = 1; +pub const P_PGID: idtype_t = 2; +cfg_if! { + if #[cfg(not(target_os = "emscripten"))] { + pub const P_PIDFD: idtype_t = 3; + } +} + +pub const UTIME_OMIT: c_long = 1073741822; +pub const UTIME_NOW: c_long = 1073741823; + +pub const POLLIN: ::c_short = 0x1; +pub const POLLPRI: ::c_short = 0x2; +pub const POLLOUT: ::c_short = 0x4; +pub const POLLERR: ::c_short = 0x8; +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; +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_COPY: u8 = 0x80; +pub const IPOPT_CLASS_MASK: u8 = 0x60; +pub const IPOPT_NUMBER_MASK: u8 = 0x1f; + +pub const IPOPT_CONTROL: u8 = 0x00; +pub const IPOPT_RESERVED1: u8 = 0x20; +pub const IPOPT_MEASUREMENT: u8 = 0x40; +pub const IPOPT_RESERVED2: u8 = 0x60; +pub const IPOPT_END: u8 = 0 | IPOPT_CONTROL; +pub const IPOPT_NOOP: u8 = 1 | IPOPT_CONTROL; +pub const IPOPT_SEC: u8 = 2 | IPOPT_CONTROL | IPOPT_COPY; +pub const IPOPT_LSRR: u8 = 3 | IPOPT_CONTROL | IPOPT_COPY; +pub const IPOPT_TIMESTAMP: u8 = 4 | IPOPT_MEASUREMENT; +pub const IPOPT_RR: u8 = 7 | IPOPT_CONTROL; +pub const IPOPT_SID: u8 = 8 | IPOPT_CONTROL | IPOPT_COPY; +pub const IPOPT_SSRR: u8 = 9 | IPOPT_CONTROL | IPOPT_COPY; +pub const IPOPT_RA: u8 = 20 | IPOPT_CONTROL | IPOPT_COPY; +pub const IPVERSION: u8 = 4; +pub const MAXTTL: u8 = 255; +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 MAX_IPOPTLEN: u8 = 40; +pub const IPOPT_NOP: u8 = IPOPT_NOOP; +pub const IPOPT_EOL: u8 = IPOPT_END; +pub const IPOPT_TS: u8 = IPOPT_TIMESTAMP; +pub const IPOPT_TS_TSONLY: u8 = 0; +pub const IPOPT_TS_TSANDADDR: u8 = 1; +pub const IPOPT_TS_PRESPEC: u8 = 3; + +pub const ARPOP_RREQUEST: u16 = 3; +pub const ARPOP_RREPLY: u16 = 4; +pub const ARPOP_InREQUEST: u16 = 8; +pub const ARPOP_InREPLY: u16 = 9; +pub const ARPOP_NAK: u16 = 10; + +pub const ATF_NETMASK: ::c_int = 0x20; +pub const ATF_DONTPUB: ::c_int = 0x40; + +pub const ARPHRD_NETROM: u16 = 0; +pub const ARPHRD_ETHER: u16 = 1; +pub const ARPHRD_EETHER: u16 = 2; +pub const ARPHRD_AX25: u16 = 3; +pub const ARPHRD_PRONET: u16 = 4; +pub const ARPHRD_CHAOS: u16 = 5; +pub const ARPHRD_IEEE802: u16 = 6; +pub const ARPHRD_ARCNET: u16 = 7; +pub const ARPHRD_APPLETLK: u16 = 8; +pub const ARPHRD_DLCI: u16 = 15; +pub const ARPHRD_ATM: u16 = 19; +pub const ARPHRD_METRICOM: u16 = 23; +pub const ARPHRD_IEEE1394: u16 = 24; +pub const ARPHRD_EUI64: u16 = 27; +pub const ARPHRD_INFINIBAND: u16 = 32; + +pub const ARPHRD_SLIP: u16 = 256; +pub const ARPHRD_CSLIP: u16 = 257; +pub const ARPHRD_SLIP6: u16 = 258; +pub const ARPHRD_CSLIP6: u16 = 259; +pub const ARPHRD_RSRVD: u16 = 260; +pub const ARPHRD_ADAPT: u16 = 264; +pub const ARPHRD_ROSE: u16 = 270; +pub const ARPHRD_X25: u16 = 271; +pub const ARPHRD_HWX25: u16 = 272; +pub const ARPHRD_CAN: u16 = 280; +pub const ARPHRD_PPP: u16 = 512; +pub const ARPHRD_CISCO: u16 = 513; +pub const ARPHRD_HDLC: u16 = ARPHRD_CISCO; +pub const ARPHRD_LAPB: u16 = 516; +pub const ARPHRD_DDCMP: u16 = 517; +pub const ARPHRD_RAWHDLC: u16 = 518; + +pub const ARPHRD_TUNNEL: u16 = 768; +pub const ARPHRD_TUNNEL6: u16 = 769; +pub const ARPHRD_FRAD: u16 = 770; +pub const ARPHRD_SKIP: u16 = 771; +pub const ARPHRD_LOOPBACK: u16 = 772; +pub const ARPHRD_LOCALTLK: u16 = 773; +pub const ARPHRD_FDDI: u16 = 774; +pub const ARPHRD_BIF: u16 = 775; +pub const ARPHRD_SIT: u16 = 776; +pub const ARPHRD_IPDDP: u16 = 777; +pub const ARPHRD_IPGRE: u16 = 778; +pub const ARPHRD_PIMREG: u16 = 779; +pub const ARPHRD_HIPPI: u16 = 780; +pub const ARPHRD_ASH: u16 = 781; +pub const ARPHRD_ECONET: u16 = 782; +pub const ARPHRD_IRDA: u16 = 783; +pub const ARPHRD_FCPP: u16 = 784; +pub const ARPHRD_FCAL: u16 = 785; +pub const ARPHRD_FCPL: u16 = 786; +pub const ARPHRD_FCFABRIC: u16 = 787; +pub const ARPHRD_IEEE802_TR: u16 = 800; +pub const ARPHRD_IEEE80211: u16 = 801; +pub const ARPHRD_IEEE80211_PRISM: u16 = 802; +pub const ARPHRD_IEEE80211_RADIOTAP: u16 = 803; +pub const ARPHRD_IEEE802154: u16 = 804; + +pub const ARPHRD_VOID: u16 = 0xFFFF; +pub const ARPHRD_NONE: u16 = 0xFFFE; + +cfg_if! { + 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; + } +} + +const_fn! { + {const} fn CMSG_ALIGN(len: usize) -> usize { + len + ::mem::size_of::() - 1 & !(::mem::size_of::() - 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_DATA(cmsg: *const cmsghdr) -> *mut ::c_uchar { + cmsg.offset(1) as *mut ::c_uchar + } + + pub {const} fn CMSG_SPACE(length: ::c_uint) -> ::c_uint { + (CMSG_ALIGN(length as usize) + CMSG_ALIGN(::mem::size_of::())) + as ::c_uint + } + + pub {const} fn CMSG_LEN(length: ::c_uint) -> ::c_uint { + CMSG_ALIGN(::mem::size_of::()) as ::c_uint + length + } + + pub fn FD_CLR(fd: ::c_int, set: *mut fd_set) -> () { + let fd = fd as usize; + let size = ::mem::size_of_val(&(*set).fds_bits[0]) * 8; + (*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; + } + } +} + +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 + } + + 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 W_EXITCODE(ret: ::c_int, sig: ::c_int) -> ::c_int { + (ret << 8) | sig + } + + pub {const} fn W_STOPCODE(sig: ::c_int) -> ::c_int { + (sig << 8) | 0x7f + } + + pub {const} fn QCMD(cmd: ::c_int, type_: ::c_int) -> ::c_int { + (cmd << 8) | (type_ & 0x00ff) + } + + pub {const} fn IPOPT_COPIED(o: u8) -> u8 { + o & IPOPT_COPY + } + + pub {const} fn IPOPT_CLASS(o: u8) -> u8 { + o & IPOPT_CLASS_MASK + } + + pub {const} fn IPOPT_NUMBER(o: u8) -> u8 { + o & IPOPT_NUMBER_MASK + } + + 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; + pub fn mincore(addr: *mut ::c_void, len: ::size_t, vec: *mut ::c_uchar) -> ::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 dirfd(dirp: *mut ::DIR) -> ::c_int; + + pub fn pthread_getattr_np(native: ::pthread_t, attr: *mut ::pthread_attr_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: ::size_t, ptr: *const ::gid_t) -> ::c_int; + pub fn pipe2(fds: *mut ::c_int, flags: ::c_int) -> ::c_int; + 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 memrchr(cx: *const ::c_void, c: ::c_int, n: ::size_t) -> *mut ::c_void; + 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 utimensat( + dirfd: ::c_int, + path: *const ::c_char, + times: *const ::timespec, + flag: ::c_int, + ) -> ::c_int; + pub fn duplocale(base: ::locale_t) -> ::locale_t; + pub fn freelocale(loc: ::locale_t); + 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 mknodat( + dirfd: ::c_int, + pathname: *const ::c_char, + mode: ::mode_t, + dev: dev_t, + ) -> ::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) -> ::c_int; + 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 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; + pub fn brk(addr: *mut ::c_void) -> ::c_int; + pub fn sbrk(increment: ::intptr_t) -> *mut ::c_void; + #[deprecated( + since = "0.2.66", + note = "causes memory corruption, see rust-lang/libc#1596" + )] + pub fn vfork() -> ::pid_t; + 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 wait4( + pid: ::pid_t, + status: *mut ::c_int, + options: ::c_int, + rusage: *mut ::rusage, + ) -> ::pid_t; + pub fn login_tty(fd: ::c_int) -> ::c_int; + pub fn execvpe( + file: *const ::c_char, + argv: *const *const ::c_char, + envp: *const *const ::c_char, + ) -> ::c_int; + pub fn fexecve( + fd: ::c_int, + 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 uname(buf: *mut ::utsname) -> ::c_int; + + pub fn strchrnul(s: *const ::c_char, c: ::c_int) -> *mut ::c_char; + + pub fn strftime( + s: *mut ::c_char, + max: ::size_t, + format: *const ::c_char, + tm: *const ::tm, + ) -> ::size_t; + pub fn strftime_l( + s: *mut ::c_char, + max: ::size_t, + format: *const ::c_char, + tm: *const ::tm, + locale: ::locale_t, + ) -> ::size_t; + pub fn strptime(s: *const ::c_char, format: *const ::c_char, tm: *mut ::tm) -> *mut ::c_char; +} + +// LFS64 extensions +// +// * musl and Emscripten has 64-bit versions only so aliases the LFS64 symbols to the standard ones +// * ulibc doesn't have preadv64/pwritev64 +cfg_if! { + if #[cfg(not(any(target_env = "musl", target_os = "emscripten")))] { + extern "C" { + pub fn fstatfs64(fd: ::c_int, buf: *mut statfs64) -> ::c_int; + pub fn statvfs64(path: *const ::c_char, buf: *mut statvfs64) -> ::c_int; + pub fn fstatvfs64(fd: ::c_int, buf: *mut statvfs64) -> ::c_int; + pub fn statfs64(path: *const ::c_char, buf: *mut statfs64) -> ::c_int; + pub fn creat64(path: *const c_char, mode: mode_t) -> ::c_int; + pub fn fstat64(fildes: ::c_int, buf: *mut stat64) -> ::c_int; + pub fn fstatat64( + dirfd: ::c_int, + pathname: *const c_char, + buf: *mut stat64, + flags: ::c_int, + ) -> ::c_int; + pub fn ftruncate64(fd: ::c_int, length: off64_t) -> ::c_int; + pub fn lseek64(fd: ::c_int, offset: off64_t, whence: ::c_int) -> off64_t; + pub fn lstat64(path: *const c_char, buf: *mut stat64) -> ::c_int; + pub fn mmap64( + addr: *mut ::c_void, + len: ::size_t, + prot: ::c_int, + flags: ::c_int, + fd: ::c_int, + offset: off64_t, + ) -> *mut ::c_void; + pub fn open64(path: *const c_char, oflag: ::c_int, ...) -> ::c_int; + pub fn openat64(fd: ::c_int, path: *const c_char, oflag: ::c_int, ...) -> ::c_int; + pub fn posix_fadvise64( + fd: ::c_int, + offset: ::off64_t, + len: ::off64_t, + advise: ::c_int, + ) -> ::c_int; + pub fn pread64( + fd: ::c_int, + buf: *mut ::c_void, + count: ::size_t, + offset: off64_t + ) -> ::ssize_t; + pub fn pwrite64( + fd: ::c_int, + buf: *const ::c_void, + count: ::size_t, + offset: off64_t, + ) -> ::ssize_t; + pub fn readdir64(dirp: *mut ::DIR) -> *mut ::dirent64; + pub fn readdir64_r( + dirp: *mut ::DIR, + entry: *mut ::dirent64, + result: *mut *mut ::dirent64, + ) -> ::c_int; + pub fn stat64(path: *const c_char, buf: *mut stat64) -> ::c_int; + pub fn truncate64(path: *const c_char, length: off64_t) -> ::c_int; + } + } +} + +cfg_if! { + if #[cfg(not(any(target_env = "uclibc", target_env = "musl", target_os = "emscripten")))] { + extern "C" { + pub fn preadv64( + fd: ::c_int, + iov: *const ::iovec, + iovcnt: ::c_int, + offset: ::off64_t, + ) -> ::ssize_t; + pub fn pwritev64( + fd: ::c_int, + iov: *const ::iovec, + iovcnt: ::c_int, + offset: ::off64_t, + ) -> ::ssize_t; + } + } +} + +cfg_if! { + if #[cfg(not(target_env = "uclibc"))] { + extern "C" { + // uclibc has separate non-const version of this function + pub fn forkpty( + amaster: *mut ::c_int, + name: *mut ::c_char, + termp: *const termios, + winp: *const ::winsize, + ) -> ::pid_t; + // uclibc has separate non-const version of this function + pub fn openpty( + amaster: *mut ::c_int, + aslave: *mut ::c_int, + name: *mut ::c_char, + termp: *const termios, + winp: *const ::winsize, + ) -> ::c_int; + } + } +} + +cfg_if! { + if #[cfg(target_os = "emscripten")] { + mod emscripten; + pub use self::emscripten::*; + } else if #[cfg(target_os = "linux")] { + mod linux; + pub use self::linux::*; + } else if #[cfg(target_os = "l4re")] { + mod linux; + pub use self::linux::*; + } else if #[cfg(target_os = "android")] { + mod android; + pub use self::android::*; + } else { + // Unknown target_os + } +} diff --git a/vendor/libc/src/unix/mod.rs b/vendor/libc/src/unix/mod.rs new file mode 100644 index 0000000..04baaba --- /dev/null +++ b/vendor/libc/src/unix/mod.rs @@ -0,0 +1,1682 @@ +//! Definitions found commonly among almost all Unix derivatives +//! +//! More functions and definitions can be found in the more specific modules +//! according to the platform in question. + +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 pid_t = i32; +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", target_os = "vita"))] { + 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; + } +} + +missing! { + #[cfg_attr(feature = "extra_traits", derive(Debug))] + pub enum DIR {} +} +pub type locale_t = *mut ::c_void; + +s! { + pub struct group { + pub gr_name: *mut ::c_char, + pub gr_passwd: *mut ::c_char, + pub gr_gid: ::gid_t, + pub gr_mem: *mut *mut ::c_char, + } + + pub struct utimbuf { + pub actime: time_t, + pub modtime: time_t, + } + + pub struct timeval { + pub tv_sec: time_t, + pub tv_usec: suseconds_t, + } + + // linux x32 compatibility + // See https://sourceware.org/bugzilla/show_bug.cgi?id=16437 + pub struct timespec { + pub tv_sec: time_t, + #[cfg(all(target_arch = "x86_64", target_pointer_width = "32"))] + pub tv_nsec: i64, + #[cfg(not(all(target_arch = "x86_64", target_pointer_width = "32")))] + pub tv_nsec: ::c_long, + } + + pub struct rlimit { + pub rlim_cur: rlim_t, + pub rlim_max: rlim_t, + } + + pub struct rusage { + pub ru_utime: timeval, + pub ru_stime: timeval, + pub ru_maxrss: c_long, + #[cfg(all(target_arch = "x86_64", target_pointer_width = "32"))] + __pad1: u32, + pub ru_ixrss: c_long, + #[cfg(all(target_arch = "x86_64", target_pointer_width = "32"))] + __pad2: u32, + pub ru_idrss: c_long, + #[cfg(all(target_arch = "x86_64", target_pointer_width = "32"))] + __pad3: u32, + pub ru_isrss: c_long, + #[cfg(all(target_arch = "x86_64", target_pointer_width = "32"))] + __pad4: u32, + pub ru_minflt: c_long, + #[cfg(all(target_arch = "x86_64", target_pointer_width = "32"))] + __pad5: u32, + pub ru_majflt: c_long, + #[cfg(all(target_arch = "x86_64", target_pointer_width = "32"))] + __pad6: u32, + pub ru_nswap: c_long, + #[cfg(all(target_arch = "x86_64", target_pointer_width = "32"))] + __pad7: u32, + pub ru_inblock: c_long, + #[cfg(all(target_arch = "x86_64", target_pointer_width = "32"))] + __pad8: u32, + pub ru_oublock: c_long, + #[cfg(all(target_arch = "x86_64", target_pointer_width = "32"))] + __pad9: u32, + pub ru_msgsnd: c_long, + #[cfg(all(target_arch = "x86_64", target_pointer_width = "32"))] + __pad10: u32, + pub ru_msgrcv: c_long, + #[cfg(all(target_arch = "x86_64", target_pointer_width = "32"))] + __pad11: u32, + pub ru_nsignals: c_long, + #[cfg(all(target_arch = "x86_64", target_pointer_width = "32"))] + __pad12: u32, + pub ru_nvcsw: c_long, + #[cfg(all(target_arch = "x86_64", target_pointer_width = "32"))] + __pad13: u32, + pub ru_nivcsw: c_long, + #[cfg(all(target_arch = "x86_64", target_pointer_width = "32"))] + __pad14: u32, + + #[cfg(any(target_env = "musl", target_env = "ohos", target_os = "emscripten"))] + __reserved: [c_long; 16], + } + + pub struct ipv6_mreq { + pub ipv6mr_multiaddr: in6_addr, + #[cfg(target_os = "android")] + pub ipv6mr_interface: ::c_int, + #[cfg(not(target_os = "android"))] + pub ipv6mr_interface: ::c_uint, + } + + pub struct hostent { + pub h_name: *mut ::c_char, + pub h_aliases: *mut *mut ::c_char, + pub h_addrtype: ::c_int, + pub h_length: ::c_int, + pub h_addr_list: *mut *mut ::c_char, + } + + pub struct iovec { + pub iov_base: *mut ::c_void, + pub iov_len: ::size_t, + } + + pub struct pollfd { + pub fd: ::c_int, + pub events: ::c_short, + pub revents: ::c_short, + } + + pub struct winsize { + pub ws_row: ::c_ushort, + pub ws_col: ::c_ushort, + pub ws_xpixel: ::c_ushort, + pub ws_ypixel: ::c_ushort, + } + + pub struct linger { + pub l_onoff: ::c_int, + pub l_linger: ::c_int, + } + + pub struct sigval { + // Actually a union of an int and a void* + pub sival_ptr: *mut ::c_void + } + + // + pub struct itimerval { + pub it_interval: ::timeval, + pub it_value: ::timeval, + } + + // + pub struct tms { + pub tms_utime: ::clock_t, + pub tms_stime: ::clock_t, + pub tms_cutime: ::clock_t, + pub tms_cstime: ::clock_t, + } + + pub struct servent { + pub s_name: *mut ::c_char, + pub s_aliases: *mut *mut ::c_char, + pub s_port: ::c_int, + pub s_proto: *mut ::c_char, + } + + pub struct protoent { + pub p_name: *mut ::c_char, + pub p_aliases: *mut *mut ::c_char, + pub p_proto: ::c_int, + } +} + +pub const INT_MIN: c_int = -2147483648; +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; +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; + } +} + +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; +pub const S_ISGID: ::mode_t = 0x400; +pub const S_ISVTX: ::mode_t = 0x200; + +cfg_if! { + if #[cfg(not(any(target_os = "haiku", target_os = "illumos", + target_os = "solaris")))] { + pub const IF_NAMESIZE: ::size_t = 16; + pub const IFNAMSIZ: ::size_t = IF_NAMESIZE; + } +} + +pub const LOG_EMERG: ::c_int = 0; +pub const LOG_ALERT: ::c_int = 1; +pub const LOG_CRIT: ::c_int = 2; +pub const LOG_ERR: ::c_int = 3; +pub const LOG_WARNING: ::c_int = 4; +pub const LOG_NOTICE: ::c_int = 5; +pub const LOG_INFO: ::c_int = 6; +pub const LOG_DEBUG: ::c_int = 7; + +pub const LOG_KERN: ::c_int = 0; +pub const LOG_USER: ::c_int = 1 << 3; +pub const LOG_MAIL: ::c_int = 2 << 3; +pub const LOG_DAEMON: ::c_int = 3 << 3; +pub const LOG_AUTH: ::c_int = 4 << 3; +pub const LOG_SYSLOG: ::c_int = 5 << 3; +pub const LOG_LPR: ::c_int = 6 << 3; +pub const LOG_NEWS: ::c_int = 7 << 3; +pub const LOG_UUCP: ::c_int = 8 << 3; +pub const LOG_LOCAL0: ::c_int = 16 << 3; +pub const LOG_LOCAL1: ::c_int = 17 << 3; +pub const LOG_LOCAL2: ::c_int = 18 << 3; +pub const LOG_LOCAL3: ::c_int = 19 << 3; +pub const LOG_LOCAL4: ::c_int = 20 << 3; +pub const LOG_LOCAL5: ::c_int = 21 << 3; +pub const LOG_LOCAL6: ::c_int = 22 << 3; +pub const LOG_LOCAL7: ::c_int = 23 << 3; + +cfg_if! { + if #[cfg(not(target_os = "haiku"))] { + pub const LOG_PID: ::c_int = 0x01; + pub const LOG_CONS: ::c_int = 0x02; + pub const LOG_ODELAY: ::c_int = 0x04; + pub const LOG_NDELAY: ::c_int = 0x08; + pub const LOG_NOWAIT: ::c_int = 0x10; + } +} +pub const LOG_PRIMASK: ::c_int = 7; +pub const LOG_FACMASK: ::c_int = 0x3f8; + +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; +pub const IPPROTO_UDP: ::c_int = 17; +pub const IPPROTO_IP: ::c_int = 0; +pub const IPPROTO_IPV6: ::c_int = 41; + +pub const INADDR_LOOPBACK: in_addr_t = 2130706433; +pub const INADDR_ANY: in_addr_t = 0; +pub const INADDR_BROADCAST: in_addr_t = 4294967295; +pub const INADDR_NONE: in_addr_t = 4294967295; + +pub const ARPOP_REQUEST: u16 = 1; +pub const ARPOP_REPLY: u16 = 2; + +pub const ATF_COM: ::c_int = 0x02; +pub const ATF_PERM: ::c_int = 0x04; +pub const ATF_PUBL: ::c_int = 0x08; +pub const ATF_USETRAILERS: ::c_int = 0x10; + +pub const FNM_PERIOD: c_int = 1 << 2; +pub const FNM_CASEFOLD: c_int = 1 << 4; +pub const FNM_NOMATCH: c_int = 1; + +cfg_if! { + if #[cfg(any( + target_os = "macos", + target_os = "freebsd", + target_os = "android", + target_os = "openbsd", + ))] { + pub const FNM_PATHNAME: c_int = 1 << 1; + pub const FNM_NOESCAPE: c_int = 1 << 0; + } else { + pub const FNM_PATHNAME: c_int = 1 << 0; + pub const FNM_NOESCAPE: c_int = 1 << 1; + } +} + +extern "C" { + pub static in6addr_loopback: in6_addr; + pub static in6addr_any: in6_addr; +} + +cfg_if! { + if #[cfg(any(target_os = "l4re", target_os = "espidf", target_os = "nuttx"))] { + // required libraries are linked externally for these platforms: + // * L4Re + // * ESP-IDF + // * NuttX + } else if #[cfg(feature = "std")] { + // cargo build, don't pull in anything extra as the std 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", modifiers = "-bundle", + cfg(target_feature = "crt-static"))] + #[link(name = "rt", kind = "static", modifiers = "-bundle", + cfg(target_feature = "crt-static"))] + #[link(name = "pthread", kind = "static", modifiers = "-bundle", + cfg(target_feature = "crt-static"))] + #[link(name = "m", kind = "static", modifiers = "-bundle", + cfg(target_feature = "crt-static"))] + #[link(name = "dl", kind = "static", modifiers = "-bundle", + cfg(target_feature = "crt-static"))] + #[link(name = "c", kind = "static", modifiers = "-bundle", + cfg(target_feature = "crt-static"))] + #[link(name = "gcc_eh", kind = "static", modifiers = "-bundle", + cfg(target_feature = "crt-static"))] + #[link(name = "gcc", kind = "static", modifiers = "-bundle", + cfg(target_feature = "crt-static"))] + #[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")))] + #[link(name = "pthread", cfg(not(target_feature = "crt-static")))] + #[link(name = "m", cfg(not(target_feature = "crt-static")))] + #[link(name = "dl", cfg(not(target_feature = "crt-static")))] + #[link(name = "c", cfg(not(target_feature = "crt-static")))] + extern {} + } else if #[cfg(any(target_env = "musl", target_env = "ohos"))] { + #[cfg_attr(feature = "rustc-dep-of-std", + 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_os = "emscripten")] { + #[link(name = "c")] + extern {} + } 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 = "visionos", + target_os = "android", + target_os = "openbsd", + target_os = "nto", + ))] { + #[link(name = "c")] + #[link(name = "m")] + extern {} + } else if #[cfg(target_os = "haiku")] { + #[link(name = "root")] + #[link(name = "network")] + extern {} + } else if #[cfg(target_env = "newlib")] { + #[link(name = "c")] + #[link(name = "m")] + extern {} + } else if #[cfg(target_env = "illumos")] { + #[link(name = "c")] + #[link(name = "m")] + extern {} + } else if #[cfg(target_os = "redox")] { + #[cfg_attr(feature = "rustc-dep-of-std", + 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_os = "aix")] { + #[link(name = "c")] + #[link(name = "m")] + #[link(name = "bsd")] + #[link(name = "pthread")] + extern {} + } else { + #[link(name = "c")] + #[link(name = "m")] + #[link(name = "rt")] + #[link(name = "pthread")] + extern {} + } +} + +missing! { + #[cfg_attr(feature = "extra_traits", derive(Debug))] + pub enum FILE {} + #[cfg_attr(feature = "extra_traits", derive(Debug))] + pub enum fpos_t {} // FIXME: fill this out with a struct +} + +extern "C" { + 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; + pub fn qsort( + base: *mut c_void, + num: size_t, + size: size_t, + compar: ::Option c_int>, + ); + pub fn bsearch( + key: *const c_void, + base: *const c_void, + num: size_t, + size: size_t, + compar: ::Option c_int>, + ) -> *mut c_void; + #[cfg_attr( + all(target_os = "macos", target_arch = "x86"), + link_name = "fopen$UNIX2003" + )] + pub fn fopen(filename: *const c_char, mode: *const c_char) -> *mut FILE; + #[cfg_attr( + all(target_os = "macos", target_arch = "x86"), + link_name = "freopen$UNIX2003" + )] + pub fn freopen(filename: *const c_char, mode: *const c_char, file: *mut FILE) -> *mut FILE; + + pub fn fflush(file: *mut FILE) -> c_int; + pub fn fclose(file: *mut FILE) -> c_int; + pub fn remove(filename: *const c_char) -> c_int; + pub fn rename(oldname: *const c_char, newname: *const c_char) -> c_int; + pub fn tmpfile() -> *mut FILE; + 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 getchar() -> c_int; + pub fn putchar(c: c_int) -> c_int; + pub fn fgetc(stream: *mut FILE) -> c_int; + pub fn fgets(buf: *mut c_char, n: c_int, stream: *mut FILE) -> *mut c_char; + pub fn fputc(c: c_int, stream: *mut FILE) -> c_int; + #[cfg_attr( + all(target_os = "macos", target_arch = "x86"), + link_name = "fputs$UNIX2003" + )] + pub fn fputs(s: *const c_char, stream: *mut FILE) -> c_int; + pub fn puts(s: *const c_char) -> c_int; + pub fn ungetc(c: c_int, stream: *mut FILE) -> c_int; + pub fn fread(ptr: *mut c_void, size: size_t, nobj: size_t, stream: *mut FILE) -> size_t; + #[cfg_attr( + all(target_os = "macos", target_arch = "x86"), + link_name = "fwrite$UNIX2003" + )] + pub fn fwrite(ptr: *const c_void, size: size_t, nobj: size_t, stream: *mut FILE) -> size_t; + pub fn fseek(stream: *mut FILE, offset: c_long, whence: c_int) -> c_int; + pub fn ftell(stream: *mut FILE) -> c_long; + pub fn rewind(stream: *mut FILE); + #[cfg_attr(target_os = "netbsd", link_name = "__fgetpos50")] + pub fn fgetpos(stream: *mut FILE, ptr: *mut fpos_t) -> c_int; + #[cfg_attr(target_os = "netbsd", link_name = "__fsetpos50")] + pub fn fsetpos(stream: *mut FILE, ptr: *const fpos_t) -> c_int; + pub fn feof(stream: *mut FILE) -> c_int; + 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; + pub fn free(p: *mut c_void); + pub fn abort() -> !; + pub fn exit(status: c_int) -> !; + pub fn _exit(status: c_int) -> !; + #[cfg_attr( + all(target_os = "macos", target_arch = "x86"), + link_name = "system$UNIX2003" + )] + pub fn system(s: *const c_char) -> c_int; + pub fn getenv(s: *const c_char) -> *mut c_char; + + 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; + pub fn strncmp(cs: *const c_char, ct: *const c_char, n: size_t) -> c_int; + pub fn strcoll(cs: *const c_char, ct: *const c_char) -> c_int; + pub fn strchr(cs: *const c_char, c: c_int) -> *mut c_char; + pub fn strrchr(cs: *const c_char, c: c_int) -> *mut c_char; + pub fn strspn(cs: *const c_char, ct: *const c_char) -> size_t; + pub fn strcspn(cs: *const c_char, ct: *const c_char) -> size_t; + pub fn strdup(cs: *const c_char) -> *mut c_char; + pub fn strndup(cs: *const c_char, n: size_t) -> *mut c_char; + pub fn strpbrk(cs: *const c_char, ct: *const c_char) -> *mut c_char; + pub fn strstr(cs: *const c_char, ct: *const c_char) -> *mut c_char; + pub fn strcasecmp(s1: *const c_char, s2: *const c_char) -> c_int; + pub fn strncasecmp(s1: *const c_char, s2: *const c_char, n: size_t) -> c_int; + pub fn strlen(cs: *const c_char) -> size_t; + pub fn strnlen(cs: *const c_char, maxlen: size_t) -> size_t; + #[cfg_attr( + all(target_os = "macos", target_arch = "x86"), + link_name = "strerror$UNIX2003" + )] + 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; + pub fn wcstombs(dest: *mut c_char, src: *const wchar_t, n: size_t) -> ::size_t; + + pub fn memchr(cx: *const c_void, c: c_int, n: size_t) -> *mut c_void; + pub fn wmemchr(cx: *const wchar_t, c: wchar_t, n: size_t) -> *mut wchar_t; + pub fn memcmp(cx: *const c_void, ct: *const c_void, n: size_t) -> c_int; + pub fn memcpy(dest: *mut c_void, src: *const c_void, n: size_t) -> *mut c_void; + pub fn memmove(dest: *mut c_void, src: *const c_void, n: size_t) -> *mut c_void; + pub fn memset(dest: *mut c_void, c: c_int, n: size_t) -> *mut c_void; +} + +extern "C" { + #[cfg_attr(target_os = "netbsd", link_name = "__getpwnam50")] + pub fn getpwnam(name: *const ::c_char) -> *mut passwd; + #[cfg_attr(target_os = "netbsd", link_name = "__getpwuid50")] + pub fn getpwuid(uid: ::uid_t) -> *mut passwd; + + pub fn fprintf(stream: *mut ::FILE, format: *const ::c_char, ...) -> ::c_int; + pub fn printf(format: *const ::c_char, ...) -> ::c_int; + pub fn snprintf(s: *mut ::c_char, n: ::size_t, format: *const ::c_char, ...) -> ::c_int; + pub fn sprintf(s: *mut ::c_char, format: *const ::c_char, ...) -> ::c_int; + #[cfg_attr( + all(target_os = "linux", not(target_env = "uclibc")), + link_name = "__isoc99_fscanf" + )] + pub fn fscanf(stream: *mut ::FILE, format: *const ::c_char, ...) -> ::c_int; + #[cfg_attr( + all(target_os = "linux", not(target_env = "uclibc")), + link_name = "__isoc99_scanf" + )] + pub fn scanf(format: *const ::c_char, ...) -> ::c_int; + #[cfg_attr( + all(target_os = "linux", not(target_env = "uclibc")), + link_name = "__isoc99_sscanf" + )] + pub fn sscanf(s: *const ::c_char, format: *const ::c_char, ...) -> ::c_int; + pub fn getchar_unlocked() -> ::c_int; + pub fn putchar_unlocked(c: ::c_int) -> ::c_int; + + #[cfg(not(all( + libc_cfg_target_vendor, + target_arch = "powerpc", + target_vendor = "nintendo" + )))] + #[cfg_attr(target_os = "netbsd", link_name = "__socket30")] + #[cfg_attr( + any(target_os = "illumos", target_os = "solaris"), + 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, + target_arch = "powerpc", + target_vendor = "nintendo" + )))] + #[cfg_attr( + all(target_os = "macos", target_arch = "x86"), + link_name = "connect$UNIX2003" + )] + #[cfg_attr( + any(target_os = "illumos", target_os = "solaris"), + 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, + target_arch = "powerpc", + target_vendor = "nintendo" + )))] + #[cfg_attr( + 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, + target_arch = "powerpc", + target_vendor = "nintendo" + )))] + #[cfg_attr( + 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, + address_len: *mut socklen_t, + ) -> ::c_int; + #[cfg(not(all( + libc_cfg_target_vendor, + target_arch = "powerpc", + target_vendor = "nintendo" + )))] + #[cfg_attr( + 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, + name: ::c_int, + value: *const ::c_void, + option_len: socklen_t, + ) -> ::c_int; + #[cfg_attr( + all(target_os = "macos", target_arch = "x86"), + link_name = "socketpair$UNIX2003" + )] + #[cfg_attr( + any(target_os = "illumos", target_os = "solaris"), + link_name = "__xnet_socketpair" + )] + pub fn socketpair( + domain: ::c_int, + type_: ::c_int, + protocol: ::c_int, + socket_vector: *mut ::c_int, + ) -> ::c_int; + #[cfg(not(all( + libc_cfg_target_vendor, + target_arch = "powerpc", + target_vendor = "nintendo" + )))] + #[cfg_attr( + all(target_os = "macos", target_arch = "x86"), + link_name = "sendto$UNIX2003" + )] + #[cfg_attr( + any(target_os = "illumos", target_os = "solaris"), + link_name = "__xnet_sendto" + )] + #[cfg_attr(target_os = "espidf", link_name = "lwip_sendto")] + pub fn sendto( + socket: ::c_int, + buf: *const ::c_void, + len: ::size_t, + flags: ::c_int, + 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( + all(target_os = "macos", target_arch = "x86"), + link_name = "chmod$UNIX2003" + )] + pub fn chmod(path: *const c_char, mode: mode_t) -> ::c_int; + #[cfg_attr( + all(target_os = "macos", target_arch = "x86"), + link_name = "fchmod$UNIX2003" + )] + pub fn fchmod(fd: ::c_int, mode: mode_t) -> ::c_int; + + #[cfg_attr( + all(target_os = "macos", not(target_arch = "aarch64")), + link_name = "fstat$INODE64" + )] + #[cfg_attr(target_os = "netbsd", link_name = "__fstat50")] + #[cfg_attr( + all(target_os = "freebsd", any(freebsd11, freebsd10)), + link_name = "fstat@FBSD_1.0" + )] + pub fn fstat(fildes: ::c_int, buf: *mut stat) -> ::c_int; + + pub fn mkdir(path: *const c_char, mode: mode_t) -> ::c_int; + + #[cfg_attr( + all(target_os = "macos", not(target_arch = "aarch64")), + link_name = "stat$INODE64" + )] + #[cfg_attr(target_os = "netbsd", link_name = "__stat50")] + #[cfg_attr( + all(target_os = "freebsd", any(freebsd11, freebsd10)), + link_name = "stat@FBSD_1.0" + )] + pub fn stat(path: *const c_char, buf: *mut stat) -> ::c_int; + + pub fn pclose(stream: *mut ::FILE) -> ::c_int; + #[cfg_attr( + all(target_os = "macos", target_arch = "x86"), + link_name = "fdopen$UNIX2003" + )] + pub fn fdopen(fd: ::c_int, mode: *const c_char) -> *mut ::FILE; + pub fn fileno(stream: *mut ::FILE) -> ::c_int; + + #[cfg_attr( + all(target_os = "macos", target_arch = "x86"), + link_name = "open$UNIX2003" + )] + pub fn open(path: *const c_char, oflag: ::c_int, ...) -> ::c_int; + #[cfg_attr( + all(target_os = "macos", target_arch = "x86"), + link_name = "creat$UNIX2003" + )] + pub fn creat(path: *const c_char, mode: mode_t) -> ::c_int; + #[cfg_attr( + all(target_os = "macos", target_arch = "x86"), + link_name = "fcntl$UNIX2003" + )] + pub fn fcntl(fd: ::c_int, cmd: ::c_int, ...) -> ::c_int; + + #[cfg_attr( + all(target_os = "macos", target_arch = "x86_64"), + link_name = "opendir$INODE64" + )] + #[cfg_attr( + all(target_os = "macos", target_arch = "x86"), + link_name = "opendir$INODE64$UNIX2003" + )] + #[cfg_attr(target_os = "netbsd", link_name = "__opendir30")] + pub fn opendir(dirname: *const c_char) -> *mut ::DIR; + + #[cfg_attr( + all(target_os = "macos", not(target_arch = "aarch64")), + link_name = "readdir$INODE64" + )] + #[cfg_attr(target_os = "netbsd", link_name = "__readdir30")] + #[cfg_attr( + all(target_os = "freebsd", any(freebsd11, freebsd10)), + link_name = "readdir@FBSD_1.0" + )] + pub fn readdir(dirp: *mut ::DIR) -> *mut ::dirent; + #[cfg_attr( + all(target_os = "macos", target_arch = "x86"), + link_name = "closedir$UNIX2003" + )] + pub fn closedir(dirp: *mut ::DIR) -> ::c_int; + #[cfg_attr( + all(target_os = "macos", target_arch = "x86_64"), + link_name = "rewinddir$INODE64" + )] + #[cfg_attr( + all(target_os = "macos", target_arch = "x86"), + link_name = "rewinddir$INODE64$UNIX2003" + )] + pub fn rewinddir(dirp: *mut ::DIR); + + pub fn fchmodat( + dirfd: ::c_int, + pathname: *const ::c_char, + mode: ::mode_t, + flags: ::c_int, + ) -> ::c_int; + pub fn fchown(fd: ::c_int, owner: ::uid_t, group: ::gid_t) -> ::c_int; + pub fn fchownat( + dirfd: ::c_int, + pathname: *const ::c_char, + owner: ::uid_t, + group: ::gid_t, + flags: ::c_int, + ) -> ::c_int; + #[cfg_attr( + all(target_os = "macos", not(target_arch = "aarch64")), + link_name = "fstatat$INODE64" + )] + #[cfg_attr( + all(target_os = "freebsd", any(freebsd11, freebsd10)), + link_name = "fstatat@FBSD_1.1" + )] + pub fn fstatat( + dirfd: ::c_int, + pathname: *const ::c_char, + buf: *mut stat, + flags: ::c_int, + ) -> ::c_int; + pub fn linkat( + olddirfd: ::c_int, + oldpath: *const ::c_char, + newdirfd: ::c_int, + newpath: *const ::c_char, + flags: ::c_int, + ) -> ::c_int; + pub fn renameat( + olddirfd: ::c_int, + oldpath: *const ::c_char, + newdirfd: ::c_int, + newpath: *const ::c_char, + ) -> ::c_int; + pub fn symlinkat( + target: *const ::c_char, + newdirfd: ::c_int, + linkpath: *const ::c_char, + ) -> ::c_int; + pub fn unlinkat(dirfd: ::c_int, pathname: *const ::c_char, flags: ::c_int) -> ::c_int; + + pub fn access(path: *const c_char, amode: ::c_int) -> ::c_int; + pub fn alarm(seconds: ::c_uint) -> ::c_uint; + pub fn chdir(dir: *const c_char) -> ::c_int; + pub fn fchdir(dirfd: ::c_int) -> ::c_int; + pub fn chown(path: *const c_char, uid: uid_t, gid: gid_t) -> ::c_int; + #[cfg_attr( + all(target_os = "macos", target_arch = "x86"), + link_name = "lchown$UNIX2003" + )] + pub fn lchown(path: *const c_char, uid: uid_t, gid: gid_t) -> ::c_int; + #[cfg_attr( + all(target_os = "macos", target_arch = "x86"), + link_name = "close$NOCANCEL$UNIX2003" + )] + #[cfg_attr( + all(target_os = "macos", target_arch = "x86_64"), + link_name = "close$NOCANCEL" + )] + pub fn close(fd: ::c_int) -> ::c_int; + pub fn dup(fd: ::c_int) -> ::c_int; + pub fn dup2(src: ::c_int, dst: ::c_int) -> ::c_int; + pub fn execl(path: *const c_char, arg0: *const c_char, ...) -> ::c_int; + pub fn execle(path: *const ::c_char, arg0: *const ::c_char, ...) -> ::c_int; + pub fn execlp(file: *const ::c_char, arg0: *const ::c_char, ...) -> ::c_int; + pub fn execv(prog: *const c_char, argv: *const *const c_char) -> ::c_int; + pub fn execve( + prog: *const c_char, + argv: *const *const c_char, + envp: *const *const c_char, + ) -> ::c_int; + pub fn execvp(c: *const c_char, argv: *const *const c_char) -> ::c_int; + pub fn fork() -> pid_t; + pub fn fpathconf(filedes: ::c_int, name: ::c_int) -> c_long; + pub fn getcwd(buf: *mut c_char, size: ::size_t) -> *mut c_char; + pub fn getegid() -> gid_t; + pub fn geteuid() -> uid_t; + pub fn getgid() -> gid_t; + pub fn getgroups(ngroups_max: ::c_int, groups: *mut gid_t) -> ::c_int; + #[cfg_attr(target_os = "illumos", link_name = "getloginx")] + pub fn getlogin() -> *mut c_char; + #[cfg_attr( + all(target_os = "macos", target_arch = "x86"), + link_name = "getopt$UNIX2003" + )] + pub fn getopt(argc: ::c_int, argv: *const *mut c_char, optstr: *const c_char) -> ::c_int; + pub fn getpgid(pid: pid_t) -> pid_t; + pub fn getpgrp() -> pid_t; + pub fn getpid() -> pid_t; + pub fn getppid() -> pid_t; + pub fn getuid() -> uid_t; + pub fn isatty(fd: ::c_int) -> ::c_int; + pub fn link(src: *const c_char, dst: *const c_char) -> ::c_int; + pub fn lseek(fd: ::c_int, offset: off_t, whence: ::c_int) -> off_t; + pub fn pathconf(path: *const c_char, name: ::c_int) -> c_long; + pub fn pipe(fds: *mut ::c_int) -> ::c_int; + pub fn posix_memalign(memptr: *mut *mut ::c_void, align: ::size_t, size: ::size_t) -> ::c_int; + #[cfg_attr( + all(target_os = "macos", target_arch = "x86"), + link_name = "read$UNIX2003" + )] + pub fn read(fd: ::c_int, buf: *mut ::c_void, count: ::size_t) -> ::ssize_t; + pub fn rmdir(path: *const c_char) -> ::c_int; + pub fn seteuid(uid: uid_t) -> ::c_int; + pub fn setegid(gid: gid_t) -> ::c_int; + pub fn setgid(gid: gid_t) -> ::c_int; + 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" + )] + pub fn sleep(secs: ::c_uint) -> ::c_uint; + #[cfg_attr( + all(target_os = "macos", target_arch = "x86"), + link_name = "nanosleep$UNIX2003" + )] + #[cfg_attr(target_os = "netbsd", link_name = "__nanosleep50")] + pub fn nanosleep(rqtp: *const timespec, rmtp: *mut timespec) -> ::c_int; + pub fn tcgetpgrp(fd: ::c_int) -> pid_t; + pub fn tcsetpgrp(fd: ::c_int, pgrp: ::pid_t) -> ::c_int; + pub fn ttyname(fd: ::c_int) -> *mut c_char; + #[cfg_attr( + all(target_os = "macos", target_arch = "x86"), + link_name = "ttyname_r$UNIX2003" + )] + #[cfg_attr(target_os = "illumos", link_name = "__posix_ttyname_r")] + pub fn ttyname_r(fd: ::c_int, buf: *mut c_char, buflen: ::size_t) -> ::c_int; + pub fn unlink(c: *const c_char) -> ::c_int; + #[cfg_attr( + all(target_os = "macos", target_arch = "x86"), + link_name = "wait$UNIX2003" + )] + pub fn wait(status: *mut ::c_int) -> pid_t; + #[cfg_attr( + all(target_os = "macos", target_arch = "x86"), + link_name = "waitpid$UNIX2003" + )] + pub fn waitpid(pid: pid_t, status: *mut ::c_int, options: ::c_int) -> pid_t; + #[cfg_attr( + all(target_os = "macos", target_arch = "x86"), + link_name = "write$UNIX2003" + )] + pub fn write(fd: ::c_int, buf: *const ::c_void, count: ::size_t) -> ::ssize_t; + #[cfg_attr( + all(target_os = "macos", target_arch = "x86"), + link_name = "pread$UNIX2003" + )] + pub fn pread(fd: ::c_int, buf: *mut ::c_void, count: ::size_t, offset: off_t) -> ::ssize_t; + #[cfg_attr( + all(target_os = "macos", target_arch = "x86"), + link_name = "pwrite$UNIX2003" + )] + pub fn pwrite(fd: ::c_int, buf: *const ::c_void, count: ::size_t, offset: off_t) -> ::ssize_t; + pub fn umask(mask: mode_t) -> mode_t; + + #[cfg_attr(target_os = "netbsd", link_name = "__utime50")] + pub fn utime(file: *const c_char, buf: *const utimbuf) -> ::c_int; + + #[cfg_attr( + all(target_os = "macos", target_arch = "x86"), + link_name = "kill$UNIX2003" + )] + pub fn kill(pid: pid_t, sig: ::c_int) -> ::c_int; + #[cfg_attr( + all(target_os = "macos", target_arch = "x86"), + link_name = "killpg$UNIX2003" + )] + pub fn killpg(pgrp: pid_t, sig: ::c_int) -> ::c_int; + + pub fn mlock(addr: *const ::c_void, len: ::size_t) -> ::c_int; + pub fn munlock(addr: *const ::c_void, len: ::size_t) -> ::c_int; + pub fn mlockall(flags: ::c_int) -> ::c_int; + pub fn munlockall() -> ::c_int; + + #[cfg_attr( + all(target_os = "macos", target_arch = "x86"), + link_name = "mmap$UNIX2003" + )] + pub fn mmap( + addr: *mut ::c_void, + len: ::size_t, + prot: ::c_int, + flags: ::c_int, + fd: ::c_int, + offset: off_t, + ) -> *mut ::c_void; + #[cfg_attr( + all(target_os = "macos", target_arch = "x86"), + link_name = "munmap$UNIX2003" + )] + pub fn munmap(addr: *mut ::c_void, len: ::size_t) -> ::c_int; + + pub fn if_nametoindex(ifname: *const c_char) -> ::c_uint; + pub fn if_indextoname(ifindex: ::c_uint, ifname: *mut ::c_char) -> *mut ::c_char; + + #[cfg_attr( + all(target_os = "macos", not(target_arch = "aarch64")), + link_name = "lstat$INODE64" + )] + #[cfg_attr(target_os = "netbsd", link_name = "__lstat50")] + #[cfg_attr( + all(target_os = "freebsd", any(freebsd11, freebsd10)), + link_name = "lstat@FBSD_1.0" + )] + pub fn lstat(path: *const c_char, buf: *mut stat) -> ::c_int; + + #[cfg_attr( + all(target_os = "macos", target_arch = "x86"), + link_name = "fsync$UNIX2003" + )] + pub fn fsync(fd: ::c_int) -> ::c_int; + + #[cfg_attr( + all(target_os = "macos", target_arch = "x86"), + link_name = "setenv$UNIX2003" + )] + pub fn setenv(name: *const c_char, val: *const c_char, overwrite: ::c_int) -> ::c_int; + #[cfg_attr( + all(target_os = "macos", target_arch = "x86"), + link_name = "unsetenv$UNIX2003" + )] + #[cfg_attr(target_os = "netbsd", link_name = "__unsetenv13")] + pub fn unsetenv(name: *const c_char) -> ::c_int; + + 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; + + #[cfg_attr(target_os = "netbsd", link_name = "__getrusage50")] + pub fn getrusage(resource: ::c_int, usage: *mut rusage) -> ::c_int; + + #[cfg_attr( + any( + target_os = "macos", + target_os = "ios", + target_os = "tvos", + target_os = "watchos", + target_os = "visionos" + ), + link_name = "realpath$DARWIN_EXTSN" + )] + pub fn realpath(pathname: *const ::c_char, resolved: *mut ::c_char) -> *mut ::c_char; + + pub fn flock(fd: ::c_int, operation: ::c_int) -> ::c_int; + + #[cfg_attr(target_os = "netbsd", link_name = "__times13")] + pub fn times(buf: *mut ::tms) -> ::clock_t; + + pub fn pthread_self() -> ::pthread_t; + pub fn pthread_equal(t1: ::pthread_t, t2: ::pthread_t) -> ::c_int; + #[cfg_attr( + all(target_os = "macos", target_arch = "x86"), + link_name = "pthread_join$UNIX2003" + )] + pub fn pthread_join(native: ::pthread_t, value: *mut *mut ::c_void) -> ::c_int; + pub fn pthread_exit(value: *mut ::c_void) -> !; + pub fn pthread_attr_init(attr: *mut ::pthread_attr_t) -> ::c_int; + pub fn pthread_attr_destroy(attr: *mut ::pthread_attr_t) -> ::c_int; + pub fn pthread_attr_getstacksize( + attr: *const ::pthread_attr_t, + stacksize: *mut ::size_t, + ) -> ::c_int; + pub fn pthread_attr_setstacksize(attr: *mut ::pthread_attr_t, stack_size: ::size_t) -> ::c_int; + pub fn pthread_attr_setdetachstate(attr: *mut ::pthread_attr_t, state: ::c_int) -> ::c_int; + pub fn pthread_detach(thread: ::pthread_t) -> ::c_int; + #[cfg_attr(target_os = "netbsd", link_name = "__libc_thr_yield")] + pub fn sched_yield() -> ::c_int; + pub fn pthread_key_create( + key: *mut pthread_key_t, + dtor: ::Option, + ) -> ::c_int; + pub fn pthread_key_delete(key: pthread_key_t) -> ::c_int; + pub fn pthread_getspecific(key: pthread_key_t) -> *mut ::c_void; + pub fn pthread_setspecific(key: pthread_key_t, value: *const ::c_void) -> ::c_int; + pub fn pthread_mutex_init( + lock: *mut pthread_mutex_t, + attr: *const pthread_mutexattr_t, + ) -> ::c_int; + pub fn pthread_mutex_destroy(lock: *mut pthread_mutex_t) -> ::c_int; + pub fn pthread_mutex_lock(lock: *mut pthread_mutex_t) -> ::c_int; + pub fn pthread_mutex_trylock(lock: *mut pthread_mutex_t) -> ::c_int; + pub fn pthread_mutex_unlock(lock: *mut pthread_mutex_t) -> ::c_int; + + pub fn pthread_mutexattr_init(attr: *mut pthread_mutexattr_t) -> ::c_int; + #[cfg_attr( + all(target_os = "macos", target_arch = "x86"), + link_name = "pthread_mutexattr_destroy$UNIX2003" + )] + pub fn pthread_mutexattr_destroy(attr: *mut pthread_mutexattr_t) -> ::c_int; + pub fn pthread_mutexattr_settype(attr: *mut pthread_mutexattr_t, _type: ::c_int) -> ::c_int; + + #[cfg_attr( + all(target_os = "macos", target_arch = "x86"), + link_name = "pthread_cond_init$UNIX2003" + )] + pub fn pthread_cond_init(cond: *mut pthread_cond_t, attr: *const pthread_condattr_t) + -> ::c_int; + #[cfg_attr( + all(target_os = "macos", target_arch = "x86"), + link_name = "pthread_cond_wait$UNIX2003" + )] + pub fn pthread_cond_wait(cond: *mut pthread_cond_t, lock: *mut pthread_mutex_t) -> ::c_int; + #[cfg_attr( + all(target_os = "macos", target_arch = "x86"), + link_name = "pthread_cond_timedwait$UNIX2003" + )] + pub fn pthread_cond_timedwait( + cond: *mut pthread_cond_t, + lock: *mut pthread_mutex_t, + abstime: *const ::timespec, + ) -> ::c_int; + pub fn pthread_cond_signal(cond: *mut pthread_cond_t) -> ::c_int; + pub fn pthread_cond_broadcast(cond: *mut pthread_cond_t) -> ::c_int; + pub fn pthread_cond_destroy(cond: *mut pthread_cond_t) -> ::c_int; + pub fn pthread_condattr_init(attr: *mut pthread_condattr_t) -> ::c_int; + pub fn pthread_condattr_destroy(attr: *mut pthread_condattr_t) -> ::c_int; + #[cfg_attr( + all(target_os = "macos", target_arch = "x86"), + link_name = "pthread_rwlock_init$UNIX2003" + )] + pub fn pthread_rwlock_init( + lock: *mut pthread_rwlock_t, + attr: *const pthread_rwlockattr_t, + ) -> ::c_int; + #[cfg_attr( + all(target_os = "macos", target_arch = "x86"), + link_name = "pthread_rwlock_destroy$UNIX2003" + )] + pub fn pthread_rwlock_destroy(lock: *mut pthread_rwlock_t) -> ::c_int; + #[cfg_attr( + all(target_os = "macos", target_arch = "x86"), + link_name = "pthread_rwlock_rdlock$UNIX2003" + )] + pub fn pthread_rwlock_rdlock(lock: *mut pthread_rwlock_t) -> ::c_int; + #[cfg_attr( + all(target_os = "macos", target_arch = "x86"), + link_name = "pthread_rwlock_tryrdlock$UNIX2003" + )] + pub fn pthread_rwlock_tryrdlock(lock: *mut pthread_rwlock_t) -> ::c_int; + #[cfg_attr( + all(target_os = "macos", target_arch = "x86"), + link_name = "pthread_rwlock_wrlock$UNIX2003" + )] + pub fn pthread_rwlock_wrlock(lock: *mut pthread_rwlock_t) -> ::c_int; + #[cfg_attr( + all(target_os = "macos", target_arch = "x86"), + link_name = "pthread_rwlock_trywrlock$UNIX2003" + )] + pub fn pthread_rwlock_trywrlock(lock: *mut pthread_rwlock_t) -> ::c_int; + #[cfg_attr( + all(target_os = "macos", target_arch = "x86"), + link_name = "pthread_rwlock_unlock$UNIX2003" + )] + pub fn pthread_rwlock_unlock(lock: *mut pthread_rwlock_t) -> ::c_int; + pub fn pthread_rwlockattr_init(attr: *mut pthread_rwlockattr_t) -> ::c_int; + pub fn pthread_rwlockattr_destroy(attr: *mut pthread_rwlockattr_t) -> ::c_int; + + #[cfg_attr( + any(target_os = "illumos", target_os = "solaris"), + link_name = "__xnet_getsockopt" + )] + #[cfg_attr(target_os = "espidf", link_name = "lwip_getsockopt")] + pub fn getsockopt( + sockfd: ::c_int, + level: ::c_int, + optname: ::c_int, + optval: *mut ::c_void, + optlen: *mut ::socklen_t, + ) -> ::c_int; + pub fn raise(signum: ::c_int) -> ::c_int; + + #[cfg_attr(target_os = "netbsd", link_name = "__utimes50")] + pub fn utimes(filename: *const ::c_char, times: *const ::timeval) -> ::c_int; + pub fn dlopen(filename: *const ::c_char, flag: ::c_int) -> *mut ::c_void; + 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; + + #[cfg(not(all( + libc_cfg_target_vendor, + target_arch = "powerpc", + target_vendor = "nintendo" + )))] + #[cfg_attr( + any(target_os = "illumos", target_os = "solaris"), + link_name = "__xnet_getaddrinfo" + )] + #[cfg_attr(target_os = "espidf", link_name = "lwip_getaddrinfo")] + pub fn getaddrinfo( + node: *const c_char, + service: *const c_char, + hints: *const addrinfo, + res: *mut *mut addrinfo, + ) -> ::c_int; + #[cfg(not(all( + libc_cfg_target_vendor, + 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(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", + target_os = "tvos", + target_os = "watchos", + target_os = "visionos" + ), + link_name = "res_9_init" + )] + pub fn res_init() -> ::c_int; + + #[cfg_attr(target_os = "netbsd", link_name = "__gmtime_r50")] + #[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(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( + all(target_os = "macos", target_arch = "x86"), + link_name = "mktime$UNIX2003" + )] + #[cfg_attr(target_os = "netbsd", link_name = "__mktime50")] + #[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(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(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(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(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(any(target_env = "musl", target_env = "ohos"), allow(deprecated))] + // FIXME: for `time_t` + pub fn timegm(tm: *mut ::tm) -> time_t; + + #[cfg_attr(target_os = "netbsd", link_name = "__mknod50")] + #[cfg_attr( + all(target_os = "freebsd", any(freebsd11, freebsd10)), + link_name = "mknod@FBSD_1.0" + )] + pub fn mknod(pathname: *const ::c_char, mode: ::mode_t, dev: ::dev_t) -> ::c_int; + pub fn gethostname(name: *mut ::c_char, len: ::size_t) -> ::c_int; + pub fn endservent(); + pub fn getservbyname(name: *const ::c_char, proto: *const ::c_char) -> *mut servent; + pub fn getservbyport(port: ::c_int, proto: *const ::c_char) -> *mut servent; + pub fn getservent() -> *mut servent; + pub fn setservent(stayopen: ::c_int); + pub fn getprotobyname(name: *const ::c_char) -> *mut protoent; + pub fn getprotobynumber(proto: ::c_int) -> *mut protoent; + pub fn chroot(name: *const ::c_char) -> ::c_int; + #[cfg_attr( + all(target_os = "macos", target_arch = "x86"), + link_name = "usleep$UNIX2003" + )] + pub fn usleep(secs: ::c_uint) -> ::c_int; + #[cfg_attr( + 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"), + link_name = "putenv$UNIX2003" + )] + #[cfg_attr(target_os = "netbsd", link_name = "__putenv50")] + pub fn putenv(string: *mut c_char) -> ::c_int; + #[cfg_attr( + all(target_os = "macos", target_arch = "x86"), + link_name = "poll$UNIX2003" + )] + pub fn poll(fds: *mut pollfd, nfds: nfds_t, timeout: ::c_int) -> ::c_int; + #[cfg_attr( + all(target_os = "macos", target_arch = "x86_64"), + link_name = "select$1050" + )] + #[cfg_attr( + all(target_os = "macos", target_arch = "x86"), + link_name = "select$UNIX2003" + )] + #[cfg_attr(target_os = "netbsd", link_name = "__select50")] + pub fn select( + nfds: ::c_int, + readfds: *mut fd_set, + writefds: *mut fd_set, + errorfds: *mut fd_set, + timeout: *mut timeval, + ) -> ::c_int; + #[cfg_attr(target_os = "netbsd", link_name = "__setlocale50")] + pub fn setlocale(category: ::c_int, locale: *const ::c_char) -> *mut ::c_char; + pub fn localeconv() -> *mut lconv; + + #[cfg_attr( + all(target_os = "macos", target_arch = "x86"), + link_name = "sem_wait$UNIX2003" + )] + pub fn sem_wait(sem: *mut sem_t) -> ::c_int; + pub fn sem_trywait(sem: *mut sem_t) -> ::c_int; + pub fn sem_post(sem: *mut sem_t) -> ::c_int; + pub fn statvfs(path: *const c_char, buf: *mut statvfs) -> ::c_int; + pub fn fstatvfs(fd: ::c_int, buf: *mut statvfs) -> ::c_int; + + #[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")] + pub fn sigaddset(set: *mut sigset_t, signum: ::c_int) -> ::c_int; + #[cfg_attr(target_os = "netbsd", link_name = "__sigfillset14")] + pub fn sigfillset(set: *mut sigset_t) -> ::c_int; + #[cfg_attr(target_os = "netbsd", link_name = "__sigdelset14")] + pub fn sigdelset(set: *mut sigset_t, signum: ::c_int) -> ::c_int; + #[cfg_attr(target_os = "netbsd", link_name = "__sigismember14")] + pub fn sigismember(set: *const sigset_t, signum: ::c_int) -> ::c_int; + + #[cfg_attr(target_os = "netbsd", link_name = "__sigprocmask14")] + pub fn sigprocmask(how: ::c_int, set: *const sigset_t, oldset: *mut sigset_t) -> ::c_int; + #[cfg_attr(target_os = "netbsd", link_name = "__sigpending14")] + pub fn sigpending(set: *mut sigset_t) -> ::c_int; + + pub fn sysconf(name: ::c_int) -> ::c_long; + + pub fn mkfifo(path: *const c_char, mode: mode_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( + all(target_os = "macos", target_arch = "x86"), + link_name = "tcdrain$UNIX2003" + )] + pub fn tcdrain(fd: ::c_int) -> ::c_int; + pub fn cfgetispeed(termios: *const ::termios) -> ::speed_t; + pub fn cfgetospeed(termios: *const ::termios) -> ::speed_t; + pub fn cfsetispeed(termios: *mut ::termios, speed: ::speed_t) -> ::c_int; + pub fn cfsetospeed(termios: *mut ::termios, speed: ::speed_t) -> ::c_int; + pub fn tcgetattr(fd: ::c_int, termios: *mut ::termios) -> ::c_int; + pub fn tcsetattr(fd: ::c_int, optional_actions: ::c_int, termios: *const ::termios) -> ::c_int; + pub fn tcflow(fd: ::c_int, action: ::c_int) -> ::c_int; + pub fn tcflush(fd: ::c_int, action: ::c_int) -> ::c_int; + pub fn tcgetsid(fd: ::c_int) -> ::pid_t; + pub fn tcsendbreak(fd: ::c_int, duration: ::c_int) -> ::c_int; + pub fn mkstemp(template: *mut ::c_char) -> ::c_int; + pub fn mkdtemp(template: *mut ::c_char) -> *mut ::c_char; + + pub fn tmpnam(ptr: *mut ::c_char) -> *mut ::c_char; + + pub fn openlog(ident: *const ::c_char, logopt: ::c_int, facility: ::c_int); + pub fn closelog(); + pub fn setlogmask(maskpri: ::c_int) -> ::c_int; + #[cfg_attr(target_os = "macos", link_name = "syslog$DARWIN_EXTSN")] + pub fn syslog(priority: ::c_int, message: *const ::c_char, ...); + #[cfg_attr( + all(target_os = "macos", target_arch = "x86"), + link_name = "nice$UNIX2003" + )] + pub fn nice(incr: ::c_int) -> ::c_int; + + pub fn grantpt(fd: ::c_int) -> ::c_int; + pub fn posix_openpt(flags: ::c_int) -> ::c_int; + pub fn ptsname(fd: ::c_int) -> *mut ::c_char; + pub fn unlockpt(fd: ::c_int) -> ::c_int; + + pub fn strcasestr(cs: *const c_char, ct: *const c_char) -> *mut c_char; + 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; + } + } +} + +cfg_if! { + if #[cfg(not(any(target_os = "emscripten", + target_os = "android", + target_os = "nto")))] { + extern "C" { + pub fn stpncpy(dst: *mut c_char, src: *const c_char, n: size_t) -> *mut c_char; + } + } +} + +cfg_if! { + 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, + sizeloc: *mut size_t, + ) -> *mut FILE; + } + } +} + +cfg_if! { + if #[cfg(not(target_os = "redox"))] { + extern { + pub fn getsid(pid: pid_t) -> pid_t; + #[cfg_attr(all(target_os = "macos", target_arch = "x86"), + link_name = "pause$UNIX2003")] + pub fn pause() -> ::c_int; + + pub fn mkdirat(dirfd: ::c_int, pathname: *const ::c_char, + mode: ::mode_t) -> ::c_int; + pub fn openat(dirfd: ::c_int, pathname: *const ::c_char, + flags: ::c_int, ...) -> ::c_int; + + #[cfg_attr(all(target_os = "macos", target_arch = "x86_64"), + link_name = "fdopendir$INODE64")] + #[cfg_attr(all(target_os = "macos", target_arch = "x86"), + link_name = "fdopendir$INODE64$UNIX2003")] + pub fn fdopendir(fd: ::c_int) -> *mut ::DIR; + + #[cfg_attr(all(target_os = "macos", not(target_arch = "aarch64")), + link_name = "readdir_r$INODE64")] + #[cfg_attr(target_os = "netbsd", link_name = "__readdir_r30")] + #[cfg_attr( + all(target_os = "freebsd", any(freebsd11, freebsd10)), + link_name = "readdir_r@FBSD_1.0" + )] + #[allow(non_autolinks)] // FIXME: `<>` breaks line length limit. + /// The 64-bit libc on Solaris and illumos only has readdir_r. If a + /// 32-bit Solaris or illumos target is ever created, it should use + /// __posix_readdir_r. See libc(3LIB) on Solaris or illumos: + /// https://illumos.org/man/3lib/libc + /// https://docs.oracle.com/cd/E36784_01/html/E36873/libc-3lib.html + /// https://www.unix.com/man-page/opensolaris/3LIB/libc/ + pub fn readdir_r(dirp: *mut ::DIR, entry: *mut ::dirent, + result: *mut *mut ::dirent) -> ::c_int; + } + } +} + +cfg_if! { + 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; + pub fn sigaction( + signum: ::c_int, + act: *const sigaction, + oldact: *mut sigaction + ) -> ::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, + speed: ::speed_t) -> ::c_int; + } + } +} + +extern "C" { + pub fn fnmatch(pattern: *const c_char, name: *const c_char, flags: c_int) -> c_int; +} + +cfg_if! { + if #[cfg(target_env = "newlib")] { + mod newlib; + pub use self::newlib::*; + } else if #[cfg(any(target_os = "linux", + target_os = "l4re", + target_os = "android", + target_os = "emscripten"))] { + mod linux_like; + pub use self::linux_like::*; + } else if #[cfg(any(target_os = "macos", + target_os = "ios", + target_os = "tvos", + target_os = "watchos", + target_os = "visionos", + target_os = "freebsd", + target_os = "dragonfly", + target_os = "openbsd", + target_os = "netbsd"))] { + mod bsd; + pub use self::bsd::*; + } else if #[cfg(any(target_os = "solaris", + target_os = "illumos"))] { + mod solarish; + pub use self::solarish::*; + } else if #[cfg(target_os = "haiku")] { + mod haiku; + pub use self::haiku::*; + } 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 if #[cfg(target_os = "hurd")] { + mod hurd; + pub use self::hurd::*; + } else if #[cfg(target_os = "nuttx")] { + mod nuttx; + pub use self::nuttx::*; + } else { + // Unknown target_os + } +} + +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(libc_align)] { + mod align; + pub use self::align::*; + } else { + mod no_align; + pub use self::no_align::*; + } +} diff --git a/vendor/libc/src/unix/newlib/aarch64/mod.rs b/vendor/libc/src/unix/newlib/aarch64/mod.rs new file mode 100644 index 0000000..2b4713c --- /dev/null +++ b/vendor/libc/src/unix/newlib/aarch64/mod.rs @@ -0,0 +1,54 @@ +pub type clock_t = ::c_long; +pub type c_char = u8; +pub type wchar_t = u32; + +pub type c_long = i64; +pub type c_ulong = u64; + +s! { + pub struct sockaddr { + pub sa_len: u8, + pub sa_family: ::sa_family_t, + pub sa_data: [::c_char; 14], + } + + 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, + } + + 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: [::c_char; 8], + } +} + +pub const AF_INET6: ::c_int = 23; + +pub const FIONBIO: ::c_ulong = 1; + +pub const POLLIN: ::c_short = 0x1; +pub const POLLPRI: ::c_short = 0x2; +pub const POLLOUT: ::c_short = 0x4; +pub const POLLERR: ::c_short = 0x8; +pub const POLLHUP: ::c_short = 0x10; +pub const POLLNVAL: ::c_short = 0x20; + +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 use crate::unix::newlib::generic::{dirent, sigset_t, stat}; diff --git a/vendor/libc/src/unix/newlib/align.rs b/vendor/libc/src/unix/newlib/align.rs new file mode 100644 index 0000000..db9beb8 --- /dev/null +++ b/vendor/libc/src/unix/newlib/align.rs @@ -0,0 +1,61 @@ +macro_rules! expand_align { + () => { + s! { + #[cfg_attr(all(target_pointer_width = "32", + any(target_arch = "mips", + target_arch = "arm", + target_arch = "powerpc")), + repr(align(4)))] + #[cfg_attr(any(target_pointer_width = "64", + not(any(target_arch = "mips", + target_arch = "arm", + target_arch = "powerpc"))), + repr(align(8)))] + pub struct pthread_mutex_t { // Unverified + size: [u8; ::__SIZEOF_PTHREAD_MUTEX_T], + } + + #[cfg_attr(all(target_pointer_width = "32", + any(target_arch = "mips", + target_arch = "arm", + target_arch = "powerpc")), + repr(align(4)))] + #[cfg_attr(any(target_pointer_width = "64", + not(any(target_arch = "mips", + target_arch = "arm", + target_arch = "powerpc"))), + repr(align(8)))] + pub struct pthread_rwlock_t { // Unverified + size: [u8; ::__SIZEOF_PTHREAD_RWLOCK_T], + } + + #[cfg_attr(any(target_pointer_width = "32", + target_arch = "x86_64", + target_arch = "powerpc64", + target_arch = "mips64", + target_arch = "s390x", + target_arch = "sparc64"), + repr(align(4)))] + #[cfg_attr(not(any(target_pointer_width = "32", + target_arch = "x86_64", + target_arch = "powerpc64", + target_arch = "mips64", + target_arch = "s390x", + target_arch = "sparc64")), + repr(align(8)))] + pub struct pthread_mutexattr_t { // Unverified + size: [u8; ::__SIZEOF_PTHREAD_MUTEXATTR_T], + } + + #[repr(align(8))] + pub struct pthread_cond_t { // Unverified + size: [u8; ::__SIZEOF_PTHREAD_COND_T], + } + + #[repr(align(4))] + pub struct pthread_condattr_t { // Unverified + size: [u8; ::__SIZEOF_PTHREAD_CONDATTR_T], + } + } + }; +} diff --git a/vendor/libc/src/unix/newlib/arm/mod.rs b/vendor/libc/src/unix/newlib/arm/mod.rs new file mode 100644 index 0000000..23b7597 --- /dev/null +++ b/vendor/libc/src/unix/newlib/arm/mod.rs @@ -0,0 +1,56 @@ +pub type clock_t = ::c_long; +pub type c_char = u8; +pub type wchar_t = u32; + +pub type c_long = i32; +pub type c_ulong = u32; + +s! { + pub struct sockaddr { + pub sa_family: ::sa_family_t, + pub sa_data: [::c_char; 14], + } + + 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_in { + pub sin_family: ::sa_family_t, + pub sin_port: ::in_port_t, + pub sin_addr: ::in_addr, + pub sin_zero: [u8; 8], + } + + pub struct sockaddr_storage { + pub ss_family: ::sa_family_t, + pub __ss_padding: [u8; 26], + } +} + +pub const AF_INET6: ::c_int = 23; + +pub const FIONBIO: ::c_ulong = 1; + +pub const POLLIN: ::c_short = 0x1; +pub const POLLPRI: ::c_short = 0x2; +pub const POLLHUP: ::c_short = 0x4; +pub const POLLERR: ::c_short = 0x8; +pub const POLLOUT: ::c_short = 0x10; +pub const POLLNVAL: ::c_short = 0x20; + +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 use crate::unix::newlib::generic::{dirent, sigset_t, stat}; diff --git a/vendor/libc/src/unix/newlib/espidf/mod.rs b/vendor/libc/src/unix/newlib/espidf/mod.rs new file mode 100644 index 0000000..a73e853 --- /dev/null +++ b/vendor/libc/src/unix/newlib/espidf/mod.rs @@ -0,0 +1,120 @@ +pub type clock_t = ::c_ulong; +pub type c_char = i8; +pub type wchar_t = u32; + +pub type c_long = i32; +pub type c_ulong = u32; + +s! { + pub struct cmsghdr { + pub cmsg_len: ::socklen_t, + pub cmsg_level: ::c_int, + pub cmsg_type: ::c_int, + } + + pub struct msghdr { + pub msg_name: *mut ::c_void, + pub msg_namelen: ::socklen_t, + pub msg_iov: *mut ::iovec, + pub msg_iovlen: ::c_int, + pub msg_control: *mut ::c_void, + pub msg_controllen: ::socklen_t, + pub msg_flags: ::c_int, + } + + pub struct sockaddr_un { + pub sun_family: ::sa_family_t, + pub sun_path: [::c_char; 108], + } + + pub struct sockaddr { + pub sa_len: u8, + pub sa_family: ::sa_family_t, + pub sa_data: [::c_char; 14], + } + + 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, + } + + 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: [::c_char; 8], + } + + pub struct sockaddr_storage { + pub s2_len: u8, + pub ss_family: ::sa_family_t, + pub s2_data1: [::c_char; 2], + pub s2_data2: [u32; 3], + pub s2_data3: [u32; 3], + } +} + +pub const AF_UNIX: ::c_int = 1; +pub const AF_INET6: ::c_int = 10; + +pub const FIONBIO: ::c_ulong = 2147772030; + +pub const POLLIN: ::c_short = 1 << 0; +pub const POLLRDNORM: ::c_short = 1 << 1; +pub const POLLRDBAND: ::c_short = 1 << 2; +pub const POLLPRI: ::c_short = POLLRDBAND; +pub const POLLOUT: ::c_short = 1 << 3; +pub const POLLWRNORM: ::c_short = POLLOUT; +pub const POLLWRBAND: ::c_short = 1 << 4; +pub const POLLERR: ::c_short = 1 << 5; +pub const POLLHUP: ::c_short = 1 << 6; + +pub const SOL_SOCKET: ::c_int = 0xfff; + +pub const MSG_OOB: ::c_int = 0x04; +pub const MSG_PEEK: ::c_int = 0x01; +pub const MSG_DONTWAIT: ::c_int = 0x08; +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; + +pub const SIGABRT: ::c_int = 6; +pub const SIGFPE: ::c_int = 8; +pub const SIGILL: ::c_int = 4; +pub const SIGINT: ::c_int = 2; +pub const SIGSEGV: ::c_int = 11; +pub const SIGTERM: ::c_int = 15; +pub const SIGHUP: ::c_int = 1; +pub const SIGQUIT: ::c_int = 3; +pub const NSIG: ::size_t = 32; + +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 eventfd(initval: ::c_uint, flags: ::c_int) -> ::c_int; +} + +pub use crate::unix::newlib::generic::{dirent, 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..d716dec --- /dev/null +++ b/vendor/libc/src/unix/newlib/generic.rs @@ -0,0 +1,36 @@ +//! Common types used by most newlib platforms + +s! { + pub struct sigset_t { + #[cfg(target_os = "horizon")] + __val: [::c_ulong; 16], + #[cfg(not(target_os = "horizon"))] + __val: u32, + } + + 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 dirent { + pub d_ino: ::ino_t, + pub d_type: ::c_uchar, + pub d_name: [::c_char; 256usize], + } +} 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..97e0b18 --- /dev/null +++ b/vendor/libc/src/unix/newlib/horizon/mod.rs @@ -0,0 +1,279 @@ +//! 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 hostent { + pub h_name: *mut ::c_char, + pub h_aliases: *mut *mut ::c_char, + pub h_addrtype: u16, + pub h_length: u16, + pub h_addr_list: *mut *mut ::c_char, + } + + 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 sin_zero: [::c_char; 8], + } + + 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; +} + +pub use crate::unix::newlib::generic::dirent; diff --git a/vendor/libc/src/unix/newlib/mod.rs b/vendor/libc/src/unix/newlib/mod.rs new file mode 100644 index 0000000..78e18d8 --- /dev/null +++ b/vendor/libc/src/unix/newlib/mod.rs @@ -0,0 +1,932 @@ +pub type blkcnt_t = i32; +pub type blksize_t = i32; + +pub type clockid_t = ::c_ulong; + +cfg_if! { + if #[cfg(any(target_os = "espidf"))] { + pub type dev_t = ::c_short; + pub type ino_t = ::c_ushort; + pub type off_t = ::c_long; + } else if #[cfg(any(target_os = "vita"))] { + pub type dev_t = ::c_short; + pub type ino_t = ::c_ushort; + pub type off_t = ::c_int; + } 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 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 pthread_t = ::c_ulong; +pub type pthread_key_t = ::c_uint; +pub type rlim_t = u32; + +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; +cfg_if! { + if #[cfg(target_os = "espidf")] { + pub type tcflag_t = u16; + } else { + pub type tcflag_t = ::c_uint; + } +} +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; + } +} + +cfg_if! { + if #[cfg(not(target_os = "horizon"))] { + s!{ + pub struct hostent { + pub h_name: *mut ::c_char, + pub h_aliases: *mut *mut ::c_char, + pub h_addrtype: ::c_int, + pub h_length: ::c_int, + pub h_addr_list: *mut *mut ::c_char, + pub h_addr: *mut ::c_char, + } + } + } +} + +s! { + // 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, + + #[cfg(target_os = "espidf")] + pub ai_addr: *mut sockaddr, + + pub ai_canonname: *mut ::c_char, + + #[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, + } + + pub struct ip_mreq { + pub imr_multiaddr: in_addr, + pub imr_interface: in_addr, + } + + pub struct linger { + pub l_onoff: ::c_int, + pub l_linger: ::c_int, + } + + pub struct in_addr { + pub s_addr: ::in_addr_t, + } + + pub struct pollfd { + pub fd: ::c_int, + pub events: ::c_int, + pub revents: ::c_int, + } + + 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_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 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 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 struct sigaction { + pub sa_handler: extern fn(arg1: ::c_int), + pub sa_mask: sigset_t, + pub sa_flags: ::c_int, + } + + pub struct stack_t { + pub ss_sp: *mut ::c_void, + pub ss_flags: ::c_int, + pub ss_size: usize, + } + + pub struct fd_set { // Unverified + fds_bits: [::c_ulong; FD_SETSIZE / ULONG_SIZE], + } + + pub struct passwd { // Unverified + 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 termios { // Unverified + pub c_iflag: ::tcflag_t, + pub c_oflag: ::tcflag_t, + pub c_cflag: ::tcflag_t, + pub c_lflag: ::tcflag_t, + pub c_line: ::cc_t, + pub c_cc: [::cc_t; ::NCCS], + #[cfg(target_os = "espidf")] + pub c_ispeed: u32, + #[cfg(target_os = "espidf")] + pub c_ospeed: u32, + } + + pub struct sem_t { // Unverified + __size: [::c_char; 16], + } + + pub struct Dl_info { // Unverified + 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 utsname { // Unverified + pub sysname: [::c_char; 65], + pub nodename: [::c_char; 65], + pub release: [::c_char; 65], + pub version: [::c_char; 65], + pub machine: [::c_char; 65], + pub domainname: [::c_char; 65] + } + + pub struct cpu_set_t { // Unverified + bits: [u32; 32], + } + + pub struct pthread_attr_t { // Unverified + #[cfg(not(target_os = "espidf"))] + __size: [u8; __SIZEOF_PTHREAD_ATTR_T], + #[cfg(target_os = "espidf")] + pub is_initialized: i32, + #[cfg(target_os = "espidf")] + pub stackaddr: *mut crate::c_void, + #[cfg(target_os = "espidf")] + pub stacksize: i32, + #[cfg(target_os = "espidf")] + pub contentionscope: i32, + #[cfg(target_os = "espidf")] + pub inheritsched: i32, + #[cfg(target_os = "espidf")] + pub schedpolicy: i32, + #[cfg(target_os = "espidf")] + pub schedparam: i32, + #[cfg(target_os = "espidf")] + pub detachstate: i32, + } + + pub struct pthread_rwlockattr_t { // Unverified + __size: [u8; __SIZEOF_PTHREAD_RWLOCKATTR_T] + } +} + +// unverified constants +align_const! { + pub const PTHREAD_MUTEX_INITIALIZER: pthread_mutex_t = pthread_mutex_t { + size: [__PTHREAD_INITIALIZER_BYTE; __SIZEOF_PTHREAD_MUTEX_T], + }; + pub const PTHREAD_COND_INITIALIZER: pthread_cond_t = pthread_cond_t { + size: [__PTHREAD_INITIALIZER_BYTE; __SIZEOF_PTHREAD_COND_T], + }; + pub const PTHREAD_RWLOCK_INITIALIZER: pthread_rwlock_t = pthread_rwlock_t { + size: [__PTHREAD_INITIALIZER_BYTE; __SIZEOF_PTHREAD_RWLOCK_T], + }; +} + +cfg_if! { + if #[cfg(target_os = "espidf")] { + pub const NCCS: usize = 11; + } else { + pub const NCCS: usize = 32; + } +} + +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; + pub const __SIZEOF_PTHREAD_BARRIER_T: usize = 32; + } else if #[cfg(target_os = "vita")] { + const __PTHREAD_INITIALIZER_BYTE: u8 = 0xff; + pub const __SIZEOF_PTHREAD_ATTR_T: usize = 4; + pub const __SIZEOF_PTHREAD_MUTEX_T: usize = 4; + pub const __SIZEOF_PTHREAD_MUTEXATTR_T: usize = 4; + pub const __SIZEOF_PTHREAD_COND_T: usize = 4; + pub const __SIZEOF_PTHREAD_CONDATTR_T: usize = 4; + pub const __SIZEOF_PTHREAD_RWLOCK_T: usize = 4; + pub const __SIZEOF_PTHREAD_RWLOCKATTR_T: usize = 4; + pub const __SIZEOF_PTHREAD_BARRIER_T: usize = 4; + } else if #[cfg(target_os = "rtems")] { + const __PTHREAD_INITIALIZER_BYTE: u8 = 0x00; + pub const __SIZEOF_PTHREAD_ATTR_T: usize = 96; + pub const __SIZEOF_PTHREAD_MUTEX_T: usize = 64; + pub const __SIZEOF_PTHREAD_MUTEXATTR_T: usize = 24; + pub const __SIZEOF_PTHREAD_COND_T: usize = 28; + pub const __SIZEOF_PTHREAD_CONDATTR_T: usize = 24; + pub const __SIZEOF_PTHREAD_RWLOCK_T: usize = 32; + pub const __SIZEOF_PTHREAD_RWLOCKATTR_T: usize = 8; + pub const __SIZEOF_PTHREAD_BARRIER_T: usize = 32; + } 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; +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; + +cfg_if! { + if #[cfg(any(target_os = "horizon", target_os = "espidf"))] { + pub const FD_SETSIZE: usize = 64; + } else if #[cfg(target_os = "vita")] { + pub const FD_SETSIZE: usize = 256; + } else { + pub const FD_SETSIZE: usize = 1024; + } +} +// intentionally not public, only used for fd_set +const ULONG_SIZE: usize = 32; + +// Other constants +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 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 EDEADLK: ::c_int = 45; +pub const ENOLCK: ::c_int = 46; +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 ENOLINK: ::c_int = 67; +pub const EPROTO: ::c_int = 71; +pub const EMULTIHOP: ::c_int = 74; +pub const EBADMSG: ::c_int = 77; +pub const EFTYPE: ::c_int = 79; +pub const ENOSYS: ::c_int = 88; +pub const ENOTEMPTY: ::c_int = 90; +pub const ENAMETOOLONG: ::c_int = 91; +pub const ELOOP: ::c_int = 92; +pub const EOPNOTSUPP: ::c_int = 95; +pub const EPFNOSUPPORT: ::c_int = 96; +pub const ECONNRESET: ::c_int = 104; +pub const ENOBUFS: ::c_int = 105; +pub const EAFNOSUPPORT: ::c_int = 106; +pub const EPROTOTYPE: ::c_int = 107; +pub const ENOTSOCK: ::c_int = 108; +pub const ENOPROTOOPT: ::c_int = 109; +pub const ECONNREFUSED: ::c_int = 111; +pub const EADDRINUSE: ::c_int = 112; +pub const ECONNABORTED: ::c_int = 113; +pub const ENETUNREACH: ::c_int = 114; +pub const ENETDOWN: ::c_int = 115; +pub const ETIMEDOUT: ::c_int = 116; +pub const EHOSTDOWN: ::c_int = 117; +pub const EHOSTUNREACH: ::c_int = 118; +pub const EINPROGRESS: ::c_int = 119; +pub const EALREADY: ::c_int = 120; +pub const EDESTADDRREQ: ::c_int = 121; +pub const EMSGSIZE: ::c_int = 122; +pub const EPROTONOSUPPORT: ::c_int = 123; +pub const EADDRNOTAVAIL: ::c_int = 125; +pub const ENETRESET: ::c_int = 126; +pub const EISCONN: ::c_int = 127; +pub const ENOTCONN: ::c_int = 128; +pub const ETOOMANYREFS: ::c_int = 129; +pub const EDQUOT: ::c_int = 132; +pub const ESTALE: ::c_int = 133; +pub const ENOTSUP: ::c_int = 134; +pub const EILSEQ: ::c_int = 138; +pub const EOVERFLOW: ::c_int = 139; +pub const ECANCELED: ::c_int = 140; +pub const ENOTRECOVERABLE: ::c_int = 141; +pub const EOWNERDEAD: ::c_int = 142; +pub const EWOULDBLOCK: ::c_int = 11; + +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_GETOWN: ::c_int = 5; +pub const F_SETOWN: ::c_int = 6; +pub const F_GETLK: ::c_int = 7; +pub const F_SETLK: ::c_int = 8; +pub const F_SETLKW: ::c_int = 9; +pub const F_RGETLK: ::c_int = 10; +pub const F_RSETLK: ::c_int = 11; +pub const F_CNVT: ::c_int = 12; +pub const F_RSETLKW: ::c_int = 13; +pub const F_DUPFD_CLOEXEC: ::c_int = 14; + +pub const O_RDONLY: ::c_int = 0; +pub const O_WRONLY: ::c_int = 1; +pub const O_RDWR: ::c_int = 2; +pub const O_APPEND: ::c_int = 8; +pub const O_CREAT: ::c_int = 512; +pub const O_TRUNC: ::c_int = 1024; +pub const O_EXCL: ::c_int = 2048; +pub const O_SYNC: ::c_int = 8192; +pub const O_NONBLOCK: ::c_int = 16384; + +pub const O_ACCMODE: ::c_int = 3; +cfg_if! { + if #[cfg(target_os = "espidf")] { + pub const O_CLOEXEC: ::c_int = 0x40000; + } else { + pub const O_CLOEXEC: ::c_int = 0x80000; + } +} + +pub const RTLD_LAZY: ::c_int = 0x1; + +pub const STDIN_FILENO: ::c_int = 0; +pub const STDOUT_FILENO: ::c_int = 1; +pub const STDERR_FILENO: ::c_int = 2; + +pub const SEEK_SET: ::c_int = 0; +pub const SEEK_CUR: ::c_int = 1; +pub const SEEK_END: ::c_int = 2; + +pub const FIOCLEX: ::c_ulong = 0x20006601; +pub const FIONCLEX: ::c_ulong = 0x20006602; + +pub const S_BLKSIZE: ::mode_t = 1024; +pub const S_IREAD: ::mode_t = 256; +pub const S_IWRITE: ::mode_t = 128; +pub const S_IEXEC: ::mode_t = 64; +pub const S_ENFMT: ::mode_t = 1024; +pub const S_IFMT: ::mode_t = 61440; +pub const S_IFDIR: ::mode_t = 16384; +pub const S_IFCHR: ::mode_t = 8192; +pub const S_IFBLK: ::mode_t = 24576; +pub const S_IFREG: ::mode_t = 32768; +pub const S_IFLNK: ::mode_t = 40960; +pub const S_IFSOCK: ::mode_t = 49152; +pub const S_IFIFO: ::mode_t = 4096; +pub const S_IRUSR: ::mode_t = 256; +pub const S_IWUSR: ::mode_t = 128; +pub const S_IXUSR: ::mode_t = 64; +pub const S_IRGRP: ::mode_t = 32; +pub const S_IWGRP: ::mode_t = 16; +pub const S_IXGRP: ::mode_t = 8; +pub const S_IROTH: ::mode_t = 4; +pub const S_IWOTH: ::mode_t = 2; +pub const S_IXOTH: ::mode_t = 1; + +pub const SOL_TCP: ::c_int = 6; + +pub const PF_UNSPEC: ::c_int = 0; +pub const PF_INET: ::c_int = 2; +cfg_if! { + if #[cfg(target_os = "espidf")] { + pub const PF_INET6: ::c_int = 10; + } else { + pub const PF_INET6: ::c_int = 23; + } +} + +pub const AF_UNSPEC: ::c_int = 0; +pub const AF_INET: ::c_int = 2; + +pub const CLOCK_REALTIME: ::clockid_t = 1; +pub const CLOCK_MONOTONIC: ::clockid_t = 4; +pub const CLOCK_BOOTTIME: ::clockid_t = 4; + +pub const SOCK_STREAM: ::c_int = 1; +pub const SOCK_DGRAM: ::c_int = 2; + +pub const SHUT_RD: ::c_int = 0; +pub const SHUT_WR: ::c_int = 1; +pub const SHUT_RDWR: ::c_int = 2; + +pub const SO_BINTIME: ::c_int = 0x2000; +pub const SO_NO_OFFLOAD: ::c_int = 0x4000; +pub const SO_NO_DDP: ::c_int = 0x8000; +pub const SO_REUSEPORT_LB: ::c_int = 0x10000; +pub const SO_LABEL: ::c_int = 0x1009; +pub const SO_PEERLABEL: ::c_int = 0x1010; +pub const SO_LISTENQLIMIT: ::c_int = 0x1011; +pub const SO_LISTENQLEN: ::c_int = 0x1012; +pub const SO_LISTENINCQLEN: ::c_int = 0x1013; +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_VENDOR: ::c_int = 0x80000000; +pub const SO_DEBUG: ::c_int = 0x01; +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_TIMESTAMP: ::c_int = 0x0400; +pub const SO_NOSIGPIPE: ::c_int = 0x0800; +pub const SO_ACCEPTFILTER: ::c_int = 0x1000; +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; +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; + +pub const INET_ADDRSTRLEN: ::c_int = 16; + +// https://github.com/bminor/newlib/blob/HEAD/newlib/libc/sys/linux/include/net/if.h#L121 +pub const IFF_UP: ::c_int = 0x1; // interface is up +pub const IFF_BROADCAST: ::c_int = 0x2; // broadcast address valid +pub const IFF_DEBUG: ::c_int = 0x4; // turn on debugging +pub const IFF_LOOPBACK: ::c_int = 0x8; // is a loopback net +pub const IFF_POINTOPOINT: ::c_int = 0x10; // interface is point-to-point link +pub const IFF_NOTRAILERS: ::c_int = 0x20; // avoid use of trailers +pub const IFF_RUNNING: ::c_int = 0x40; // resources allocated +pub const IFF_NOARP: ::c_int = 0x80; // no address resolution protocol +pub const IFF_PROMISC: ::c_int = 0x100; // receive all packets +pub const IFF_ALLMULTI: ::c_int = 0x200; // receive all multicast packets +pub const IFF_OACTIVE: ::c_int = 0x400; // transmission in progress +pub const IFF_SIMPLEX: ::c_int = 0x800; // 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; // supports multicast + +cfg_if! { + if #[cfg(target_os = "vita")] { + pub const TCP_NODELAY: ::c_int = 1; + pub const TCP_MAXSEG: ::c_int = 2; + } else if #[cfg(target_os = "espidf")] { + pub const TCP_NODELAY: ::c_int = 1; + pub const TCP_MAXSEG: ::c_int = 8194; + } else { + pub const TCP_NODELAY: ::c_int = 8193; + pub const TCP_MAXSEG: ::c_int = 8194; + } +} + +pub const TCP_NOPUSH: ::c_int = 4; +pub const TCP_NOOPT: ::c_int = 8; +cfg_if! { + if #[cfg(target_os = "espidf")] { + pub const TCP_KEEPIDLE: ::c_int = 3; + pub const TCP_KEEPINTVL: ::c_int = 4; + pub const TCP_KEEPCNT: ::c_int = 5; + } else { + pub const TCP_KEEPIDLE: ::c_int = 256; + pub const TCP_KEEPINTVL: ::c_int = 512; + pub const TCP_KEEPCNT: ::c_int = 1024; + } +} + +cfg_if! { + if #[cfg(target_os = "horizon")] { + pub const IP_TOS: ::c_int = 7; + } else if #[cfg(target_os = "espidf")] { + pub const IP_TOS: ::c_int = 1; + } else { + pub const IP_TOS: ::c_int = 3; + } +} +cfg_if! { + if #[cfg(target_os = "vita")] { + pub const IP_TTL: ::c_int = 4; + } else if #[cfg(target_os = "espidf")] { + pub const IP_TTL: ::c_int = 2; + } else { + pub const IP_TTL: ::c_int = 8; + } +} + +cfg_if! { + if #[cfg(target_os = "espidf")] { + pub const IP_MULTICAST_IF: ::c_int = 6; + pub const IP_MULTICAST_TTL: ::c_int = 5; + pub const IP_MULTICAST_LOOP: ::c_int = 7; + } else { + pub const IP_MULTICAST_IF: ::c_int = 9; + pub const IP_MULTICAST_TTL: ::c_int = 10; + pub const IP_MULTICAST_LOOP: ::c_int = 11; + } +} + +cfg_if! { + if #[cfg(target_os = "vita")] { + pub const IP_ADD_MEMBERSHIP: ::c_int = 12; + pub const IP_DROP_MEMBERSHIP: ::c_int = 13; + } else if #[cfg(target_os = "espidf")] { + pub const IP_ADD_MEMBERSHIP: ::c_int = 3; + pub const IP_DROP_MEMBERSHIP: ::c_int = 4; + } else { + pub const IP_ADD_MEMBERSHIP: ::c_int = 11; + pub const IP_DROP_MEMBERSHIP: ::c_int = 12; + } +} +pub const IPV6_UNICAST_HOPS: ::c_int = 4; +cfg_if! { + if #[cfg(target_os = "espidf")] { + pub const IPV6_MULTICAST_IF: ::c_int = 768; + pub const IPV6_MULTICAST_HOPS: ::c_int = 769; + pub const IPV6_MULTICAST_LOOP: ::c_int = 770; + } else { + 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_V6ONLY: ::c_int = 27; +pub const IPV6_JOIN_GROUP: ::c_int = 12; +pub const IPV6_LEAVE_GROUP: ::c_int = 13; +pub const IPV6_ADD_MEMBERSHIP: ::c_int = 12; +pub const IPV6_DROP_MEMBERSHIP: ::c_int = 13; + +cfg_if! { + if #[cfg(target_os = "espidf")] { + pub const HOST_NOT_FOUND: ::c_int = 210; + pub const NO_DATA: ::c_int = 211; + pub const NO_RECOVERY: ::c_int = 212; + pub const TRY_AGAIN: ::c_int = 213; + + } else { + pub const HOST_NOT_FOUND: ::c_int = 1; + pub const NO_DATA: ::c_int = 2; + pub const NO_RECOVERY: ::c_int = 3; + pub const TRY_AGAIN: ::c_int = 4; + } +} +pub const NO_ADDRESS: ::c_int = 2; + +pub const AI_PASSIVE: ::c_int = 1; +pub const AI_CANONNAME: ::c_int = 2; +pub const AI_NUMERICHOST: ::c_int = 4; +cfg_if! { + if #[cfg(target_os = "espidf")] { + pub const AI_NUMERICSERV: ::c_int = 8; + pub const AI_ADDRCONFIG: ::c_int = 64; + } else { + pub const AI_NUMERICSERV: ::c_int = 0; + pub const AI_ADDRCONFIG: ::c_int = 0; + } +} + +pub const NI_MAXHOST: ::c_int = 1025; +pub const NI_MAXSERV: ::c_int = 32; +pub const NI_NOFQDN: ::c_int = 1; +pub const NI_NUMERICHOST: ::c_int = 2; +pub const NI_NAMEREQD: ::c_int = 4; +cfg_if! { + if #[cfg(target_os = "espidf")] { + pub const NI_NUMERICSERV: ::c_int = 8; + pub const NI_DGRAM: ::c_int = 16; + } else { + pub const NI_NUMERICSERV: ::c_int = 0; + pub const NI_DGRAM: ::c_int = 0; + } +} + +cfg_if! { + // Defined in vita/mod.rs for "vita" + if #[cfg(target_os = "espidf")] { + pub const EAI_FAMILY: ::c_int = 204; + pub const EAI_MEMORY: ::c_int = 203; + pub const EAI_NONAME: ::c_int = 200; + pub const EAI_SOCKTYPE: ::c_int = 10; + } else if #[cfg(not(target_os = "vita"))] { + pub const EAI_FAMILY: ::c_int = -303; + pub const EAI_MEMORY: ::c_int = -304; + pub const EAI_NONAME: ::c_int = -305; + pub const EAI_SOCKTYPE: ::c_int = -307; + } +} + +pub const EXIT_SUCCESS: ::c_int = 0; +pub const EXIT_FAILURE: ::c_int = 1; + +pub const PRIO_PROCESS: ::c_int = 0; +pub const PRIO_PGRP: ::c_int = 1; +pub const PRIO_USER: ::c_int = 2; + +f! { + pub fn FD_CLR(fd: ::c_int, set: *mut fd_set) -> () { + let bits = ::mem::size_of_val(&(*set).fds_bits[0]) * 8; + let fd = fd as usize; + (*set).fds_bits[fd / bits] &= !(1 << (fd % bits)); + return + } + + pub fn FD_ISSET(fd: ::c_int, set: *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 + } + + pub fn FD_SET(fd: ::c_int, set: *mut fd_set) -> () { + let bits = ::mem::size_of_val(&(*set).fds_bits[0]) * 8; + let fd = fd as usize; + (*set).fds_bits[fd / bits] |= 1 << (fd % bits); + return + } + + pub fn FD_ZERO(set: *mut fd_set) -> () { + for slot in (*set).fds_bits.iter_mut() { + *slot = 0; + } + } +} + +extern "C" { + pub fn getrlimit(resource: ::c_int, rlim: *mut ::rlimit) -> ::c_int; + pub fn setrlimit(resource: ::c_int, rlim: *const ::rlimit) -> ::c_int; + + #[cfg_attr(target_os = "linux", link_name = "__xpg_strerror_r")] + pub fn strerror_r(errnum: ::c_int, buf: *mut c_char, buflen: ::size_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 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); + + #[cfg(not(all( + libc_cfg_target_vendor, + 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( + libc_cfg_target_vendor, + 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, + n: usize, + flags: ::c_int, + addr: *mut sockaddr, + addr_len: *mut socklen_t, + ) -> isize; + #[cfg(not(all( + libc_cfg_target_vendor, + target_arch = "powerpc", + target_vendor = "nintendo" + )))] + pub fn getnameinfo( + sa: *const sockaddr, + salen: socklen_t, + host: *mut ::c_char, + hostlen: socklen_t, + serv: *mut ::c_char, + servlen: socklen_t, + flags: ::c_int, + ) -> ::c_int; + pub fn memalign(align: ::size_t, size: ::size_t) -> *mut ::c_void; + pub fn fexecve( + fd: ::c_int, + argv: *const *const ::c_char, + envp: *const *const ::c_char, + ) -> ::c_int; + pub fn gettimeofday(tp: *mut ::timeval, tz: *mut ::c_void) -> ::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 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; + 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 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 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 popen(command: *const c_char, mode: *const c_char) -> *mut ::FILE; + pub fn uname(buf: *mut ::utsname) -> ::c_int; +} + +mod generic; + +cfg_if! { + 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_os = "vita")] { + mod vita; + pub use self::vita::*; + } 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 = "powerpc")] { + mod powerpc; + pub use self::powerpc::*; + } else { + // Only tested on ARM so far. Other platforms might have different + // definitions for types and constants. + pub use target_arch_not_implemented; + } +} + +cfg_if! { + if #[cfg(target_os = "rtems")] { + mod rtems; + pub use self::rtems::*; + } +} + +cfg_if! { + if #[cfg(libc_align)] { + #[macro_use] + mod align; + } else { + #[macro_use] + mod no_align; + } +} +expand_align!(); diff --git a/vendor/libc/src/unix/newlib/no_align.rs b/vendor/libc/src/unix/newlib/no_align.rs new file mode 100644 index 0000000..ce3aca4 --- /dev/null +++ b/vendor/libc/src/unix/newlib/no_align.rs @@ -0,0 +1,51 @@ +macro_rules! expand_align { + () => { + s! { + pub struct pthread_mutex_t { // Unverified + #[cfg(any(target_arch = "mips", + target_arch = "arm", + target_arch = "powerpc"))] + __align: [::c_long; 0], + #[cfg(not(any(target_arch = "mips", + target_arch = "arm", + target_arch = "powerpc")))] + __align: [::c_longlong; 0], + size: [u8; ::__SIZEOF_PTHREAD_MUTEX_T], + } + + pub struct pthread_rwlock_t { // Unverified + #[cfg(any(target_arch = "mips", + target_arch = "arm", + target_arch = "powerpc"))] + __align: [::c_long; 0], + #[cfg(not(any(target_arch = "mips", + target_arch = "arm", + target_arch = "powerpc")))] + __align: [::c_longlong; 0], + size: [u8; ::__SIZEOF_PTHREAD_RWLOCK_T], + } + + pub struct pthread_mutexattr_t { // Unverified + #[cfg(any(target_arch = "x86_64", target_arch = "powerpc64", + target_arch = "mips64", target_arch = "s390x", + target_arch = "sparc64"))] + __align: [::c_int; 0], + #[cfg(not(any(target_arch = "x86_64", target_arch = "powerpc64", + target_arch = "mips64", target_arch = "s390x", + target_arch = "sparc64")))] + __align: [::c_long; 0], + size: [u8; ::__SIZEOF_PTHREAD_MUTEXATTR_T], + } + + pub struct pthread_cond_t { // Unverified + __align: [::c_longlong; 0], + size: [u8; ::__SIZEOF_PTHREAD_COND_T], + } + + pub struct pthread_condattr_t { // Unverified + __align: [::c_int; 0], + size: [u8; ::__SIZEOF_PTHREAD_CONDATTR_T], + } + } + }; +} diff --git a/vendor/libc/src/unix/newlib/powerpc/mod.rs b/vendor/libc/src/unix/newlib/powerpc/mod.rs new file mode 100644 index 0000000..10faadb --- /dev/null +++ b/vendor/libc/src/unix/newlib/powerpc/mod.rs @@ -0,0 +1,16 @@ +pub type clock_t = ::c_ulong; +pub type c_char = u8; +pub type wchar_t = ::c_int; + +pub type c_long = i32; +pub type c_ulong = u32; + +pub use crate::unix::newlib::generic::{dirent, sigset_t, stat}; + +// the newlib shipped with devkitPPC does not support the following components: +// - sockaddr +// - AF_INET6 +// - FIONBIO +// - POLL* +// - SOL_SOCKET +// - MSG_* diff --git a/vendor/libc/src/unix/newlib/rtems/mod.rs b/vendor/libc/src/unix/newlib/rtems/mod.rs new file mode 100644 index 0000000..0317549 --- /dev/null +++ b/vendor/libc/src/unix/newlib/rtems/mod.rs @@ -0,0 +1,143 @@ +// defined in architecture specific module +use c_long; + +s! { + pub struct sockaddr_un { + pub sun_family: ::sa_family_t, + pub sun_path: [::c_char; 108usize], + } +} + +pub const AF_UNIX: ::c_int = 1; + +pub const RTLD_DEFAULT: *mut ::c_void = -2isize as *mut ::c_void; + +pub const UTIME_OMIT: c_long = -1; +pub const AT_FDCWD: ::c_int = -2; + +pub const O_DIRECTORY: ::c_int = 0x200000; +pub const O_NOFOLLOW: ::c_int = 0x100000; + +pub const AT_EACCESS: ::c_int = 1; +pub const AT_SYMLINK_NOFOLLOW: ::c_int = 2; +pub const AT_SYMLINK_FOLLOW: ::c_int = 4; +pub const AT_REMOVEDIR: ::c_int = 8; + +// signal.h +pub const SIG_BLOCK: ::c_int = 1; +pub const SIG_UNBLOCK: ::c_int = 2; +pub const SIG_SETMASK: ::c_int = 0; +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 SIGWINCH: ::c_int = 24; +pub const SIGUSR1: ::c_int = 25; +pub const SIGUSR2: ::c_int = 26; +pub const SIGRTMIN: ::c_int = 27; +pub const SIGRTMAX: ::c_int = 31; +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 SA_NOCLDSTOP: ::c_ulong = 0x00000001; +pub const SA_SIGINFO: ::c_ulong = 0x00000002; +pub const SA_ONSTACK: ::c_ulong = 0x00000004; + +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_OVERFLOW: ::c_int = 14; + +pub const _SC_PAGESIZE: ::c_int = 8; +pub const _SC_GETPW_R_SIZE_MAX: ::c_int = 51; +pub const PTHREAD_STACK_MIN: ::size_t = 0; + +// sys/wait.h +pub const WNOHANG: ::c_int = 1; +pub const WUNTRACED: ::c_int = 2; + +// sys/socket.h +pub const SOMAXCONN: ::c_int = 128; + +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 + WEXITSTATUS(status) + } + + pub {const} fn WIFSIGNALED(status: ::c_int) -> bool { + ((status & 0x7f) > 0) && ((status & 0x7f) < 0x7f) + } + + pub {const} fn WTERMSIG(status: ::c_int) -> ::c_int { + status & 0x7f + } + + pub {const} fn WIFEXITED(status: ::c_int) -> bool { + (status & 0xff) == 0 + } + + pub {const} fn WEXITSTATUS(status: ::c_int) -> ::c_int { + (status >> 8) & 0xff + } + + // RTEMS doesn't have native WIFCONTINUED. + pub {const} fn WIFCONTINUED(_status: ::c_int) -> bool { + true + } + + // RTEMS doesn't have native WCOREDUMP. + pub {const} fn WCOREDUMP(_status: ::c_int) -> bool { + false + } +} + +extern "C" { + pub fn futimens(fd: ::c_int, times: *const ::timespec) -> ::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 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_condattr_setclock( + attr: *mut ::pthread_condattr_t, + clock_id: ::clockid_t, + ) -> ::c_int; + + pub fn getentropy(buf: *mut ::c_void, buflen: ::size_t) -> ::c_int; + + pub fn setgroups(ngroups: ::c_int, grouplist: *const ::gid_t) -> ::c_int; +} diff --git a/vendor/libc/src/unix/newlib/vita/mod.rs b/vendor/libc/src/unix/newlib/vita/mod.rs new file mode 100644 index 0000000..d4c6955 --- /dev/null +++ b/vendor/libc/src/unix/newlib/vita/mod.rs @@ -0,0 +1,236 @@ +pub type clock_t = ::c_long; + +pub type c_char = i8; +pub type wchar_t = u32; + +pub type c_long = i32; +pub type c_ulong = u32; + +pub type sigset_t = ::c_ulong; + +s! { + 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 sockaddr { + pub sa_len: u8, + pub sa_family: ::sa_family_t, + pub sa_data: [::c_char; 14], + } + + 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_vport: ::in_port_t, + pub sin6_scope_id: u32, + } + + 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_vport: ::in_port_t, + pub sin_zero: [u8; 6], + } + + pub struct sockaddr_un { + pub ss_len: u8, + pub sun_family: ::sa_family_t, + pub sun_path: [::c_char; 108usize], + } + + pub struct sockaddr_storage { + pub ss_len: u8, + pub ss_family: ::sa_family_t, + pub __ss_pad1: [u8; 2], + pub __ss_align: i64, + pub __ss_pad2: [u8; 116], + } + + 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_atime: ::time_t, + pub st_mtime: ::time_t, + pub st_ctime: ::time_t, + pub st_blksize: ::blksize_t, + pub st_blocks: ::blkcnt_t, + pub st_spare4: [::c_long; 2usize], + } + + #[repr(align(8))] + pub struct dirent { + __offset: [u8; 88], + pub d_name: [::c_char; 256usize], + __pad: [u8; 8], + } +} + +pub const AF_UNIX: ::c_int = 1; +pub const AF_INET6: ::c_int = 24; + +pub const SOCK_RAW: ::c_int = 3; +pub const SOCK_RDM: ::c_int = 4; +pub const SOCK_SEQPACKET: ::c_int = 5; + +pub const SOMAXCONN: ::c_int = 128; + +pub const FIONBIO: ::c_ulong = 1; + +pub const POLLIN: ::c_short = 0x0001; +pub const POLLPRI: ::c_short = POLLIN; +pub const POLLOUT: ::c_short = 0x0004; +pub const POLLRDNORM: ::c_short = POLLIN; +pub const POLLRDBAND: ::c_short = POLLIN; +pub const POLLWRNORM: ::c_short = POLLOUT; +pub const POLLWRBAND: ::c_short = POLLOUT; +pub const POLLERR: ::c_short = 0x0008; +pub const POLLHUP: ::c_short = 0x0010; +pub const POLLNVAL: ::c_short = 0x0020; + +pub const RTLD_DEFAULT: *mut ::c_void = 0 as *mut ::c_void; + +pub const SOL_SOCKET: ::c_int = 0xffff; +pub const SO_NONBLOCK: ::c_int = 0x1100; + +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_DONTWAIT: ::c_int = 0x80; +pub const MSG_BCAST: ::c_int = 0x100; +pub const MSG_MCAST: ::c_int = 0x200; + +pub const UTIME_OMIT: c_long = -1; +pub const AT_FDCWD: ::c_int = -2; + +pub const O_DIRECTORY: ::c_int = 0x200000; +pub const O_NOFOLLOW: ::c_int = 0x100000; + +pub const AT_EACCESS: ::c_int = 1; +pub const AT_SYMLINK_NOFOLLOW: ::c_int = 2; +pub const AT_SYMLINK_FOLLOW: ::c_int = 4; +pub const AT_REMOVEDIR: ::c_int = 8; + +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 EAI_BADFLAGS: ::c_int = -1; +pub const EAI_NONAME: ::c_int = -2; +pub const EAI_AGAIN: ::c_int = -3; +pub const EAI_FAIL: ::c_int = -4; +pub const EAI_NODATA: ::c_int = -5; +pub const EAI_FAMILY: ::c_int = -6; +pub const EAI_SOCKTYPE: ::c_int = -7; +pub const EAI_SERVICE: ::c_int = -8; +pub const EAI_ADDRFAMILY: ::c_int = -9; +pub const EAI_MEMORY: ::c_int = -10; +pub const EAI_SYSTEM: ::c_int = -11; +pub const EAI_OVERFLOW: ::c_int = -12; + +pub const _SC_PAGESIZE: ::c_int = 8; +pub const _SC_GETPW_R_SIZE_MAX: ::c_int = 51; +pub const PTHREAD_STACK_MIN: ::size_t = 32 * 1024; + +pub const IP_HDRINCL: ::c_int = 2; + +extern "C" { + pub fn futimens(fd: ::c_int, times: *const ::timespec) -> ::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(s: ::c_int, msg: *const ::msghdr, flags: ::c_int) -> ::ssize_t; + pub fn recvmsg(s: ::c_int, msg: *mut ::msghdr, flags: ::c_int) -> ::ssize_t; + + 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 getentropy(buf: *mut ::c_void, buflen: ::size_t) -> ::c_int; + + pub fn pipe2(fds: *mut ::c_int, flags: ::c_int) -> ::c_int; +} diff --git a/vendor/libc/src/unix/no_align.rs b/vendor/libc/src/unix/no_align.rs new file mode 100644 index 0000000..b435d72 --- /dev/null +++ b/vendor/libc/src/unix/no_align.rs @@ -0,0 +1,16 @@ +s! { + pub struct in6_addr { + pub s6_addr: [u8; 16], + __align: [u32; 0], + } +} + +pub const IN6ADDR_LOOPBACK_INIT: in6_addr = in6_addr { + s6_addr: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], + __align: [0u32; 0], +}; + +pub const IN6ADDR_ANY_INIT: in6_addr = in6_addr { + s6_addr: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + __align: [0u32; 0], +}; 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..001b51a --- /dev/null +++ b/vendor/libc/src/unix/nto/mod.rs @@ -0,0 +1,3512 @@ +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 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 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, + pub __padding1: ::c_int, + pub sigev_signo: ::c_int, // union + pub __padding2: ::c_int, + 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 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")] { + // sigevent + 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_un2 + == other.__sigev_un2 + } + } + 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_un2", + &self.__sigev_un2) + .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_un2.hash(state); + } + } + + 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); + } + } + + // sigset_t + impl PartialEq for sigset_t { + fn eq(&self, other: &sigset_t) -> bool { + self.__val == other.__val + } + } + impl Eq for sigset_t {} + impl ::fmt::Debug for sigset_t { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("sigset_t") + .field("__val", &self.__val) + .finish() + } + } + impl ::hash::Hash for sigset_t { + fn hash(&self, state: &mut H) { + self.__val.hash(state); + } + } + + // msg + impl ::fmt::Debug for msg { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("msg") + .field("msg_next", &self.msg_next) + .field("msg_type", &self.msg_type) + .field("msg_ts", &self.msg_ts) + .field("msg_spot", &self.msg_spot) + .finish() + } + } + + // msqid_ds + impl ::fmt::Debug for msqid_ds { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("msqid_ds") + .field("msg_perm", &self.msg_perm) + .field("msg_first", &self.msg_first) + .field("msg_cbytes", &self.msg_cbytes) + .field("msg_qnum", &self.msg_qnum) + .field("msg_qbytes", &self.msg_qbytes) + .field("msg_lspid", &self.msg_lspid) + .field("msg_lrpid", &self.msg_lrpid) + .field("msg_stime", &self.msg_stime) + .field("msg_rtime", &self.msg_rtime) + .field("msg_ctime", &self.msg_ctime) + .finish() + } + } + + // 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) + .field("sdl_data", &self.sdl_data) + .finish() + } + } + 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 ::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); + } + } + + // sync_t + impl ::fmt::Debug for sync_t { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("sync_t") + .field("__owner", &self.__owner) + .field("__u", &self.__u) + .finish() + } + } + + // 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("__pad", &self.__pad) + .finish() + } + } + + // pthread_rwlock_t + impl ::fmt::Debug for pthread_rwlock_t { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("pthread_rwlock_t") + .field("__active", &self.__active) + .field("__blockedwriters", &self.__blockedwriters) + .field("__blockedreaders", &self.__blockedreaders) + .field("__heavy", &self.__heavy) + .field("__lock", &self.__lock) + .field("__rcond", &self.__rcond) + .field("__wcond", &self.__wcond) + .field("__owner", &self.__owner) + .field("__spare", &self.__spare) + .finish() + } + } + + // syspage_entry + impl ::fmt::Debug for syspage_entry { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("syspage_entry") + .field("size", &self.size) + .field("total_size", &self.total_size) + .field("type_", &self.type_) + .field("num_cpu", &self.num_cpu) + .field("system_private", &self.system_private) + .field("old_asinfo", &self.old_asinfo) + .field("hwinfo", &self.hwinfo) + .field("old_cpuinfo", &self.old_cpuinfo) + .field("old_cacheattr", &self.old_cacheattr) + .field("qtime", &self.qtime) + .field("callout", &self.callout) + .field("callin", &self.callin) + .field("typed_strings", &self.typed_strings) + .field("strings", &self.strings) + .field("old_intrinfo", &self.old_intrinfo) + .field("smp", &self.smp) + .field("pminfo", &self.pminfo) + .field("old_mdriver", &self.old_mdriver) + .field("new_asinfo", &self.new_asinfo) + .field("new_cpuinfo", &self.new_cpuinfo) + .field("new_cacheattr", &self.new_cacheattr) + .field("new_intrinfo", &self.new_intrinfo) + .field("new_mdriver", &self.new_mdriver) + .finish() + } + } + + 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 ::hash::Hash for mq_attr { + fn hash(&self, state: &mut H) { + self.mq_maxmsg.hash(state); + self.mq_msgsize.hash(state); + self.mq_flags.hash(state); + self.mq_curmsgs.hash(state); + self.mq_sendwait.hash(state); + self.mq_recvwait.hash(state); + } + } + + impl PartialEq for sockaddr_storage { + fn eq(&self, other: &sockaddr_storage) -> bool { + self.ss_len == other.ss_len + && self.ss_family == other.ss_family + && self.__ss_pad1 == other.__ss_pad1 + && self.__ss_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; +#[deprecated(since = "0.2.64", note = "Not stable across OS versions")] +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_BARRIER_SERIAL_THREAD: ::c_int = -1; +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 {const} 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 + } + + pub fn major(dev: ::dev_t) -> ::c_uint { + ((dev as ::c_uint) >> 10) & 0x3f + } + + pub fn minor(dev: ::dev_t) -> ::c_uint { + (dev as ::c_uint) & 0x3ff + } +} + +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 + } + + pub {const} fn makedev(major: ::c_uint, minor: ::c_uint) -> ::dev_t { + ((major << 10) | (minor)) as ::dev_t + } +} + +// Network related functions are provided by libsocket and regex +// functions are provided by libregex. +// In QNX <=7.0, libregex functions were included in libc itself. +#[link(name = "socket")] +#[cfg_attr(not(target_env = "nto70"), 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 mknodat( + __fd: ::c_int, + pathname: *const ::c_char, + mode: ::mode_t, + dev: ::dev_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 pthread_attr_setguardsize(attr: *mut ::pthread_attr_t, guardsize: ::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, + servlen: ::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( + // The original .h file declares this as *const, but for consistency with other platforms, + // changing this to *mut to make it easier to use. + // Maybe in v0.3 all platforms should use this as a *const. + info: *mut 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..1a6f7da --- /dev/null +++ b/vendor/libc/src/unix/nto/neutrino.rs @@ -0,0 +1,1288 @@ +pub type nto_job_t = ::sync_t; + +s! { + 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, + } + + 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! { + + #[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/nuttx/mod.rs b/vendor/libc/src/unix/nuttx/mod.rs new file mode 100644 index 0000000..e3a3c15 --- /dev/null +++ b/vendor/libc/src/unix/nuttx/mod.rs @@ -0,0 +1,555 @@ +use c_void; +use in6_addr; +use in_addr_t; +use timespec; +use DIR; + +pub type nlink_t = u16; +pub type ino_t = u16; +pub type blkcnt_t = u64; +pub type blksize_t = i16; +pub type c_char = i8; +pub type c_long = isize; +pub type c_ulong = usize; +pub type cc_t = u8; +pub type clock_t = i64; +pub type dev_t = i32; +pub type fsblkcnt_t = u64; +pub type locale_t = *mut i8; +pub type mode_t = u32; +pub type nfds_t = u32; +pub type off_t = i64; +pub type pthread_key_t = i32; +pub type pthread_mutexattr_t = u8; +pub type pthread_rwlockattr_t = i32; +pub type pthread_t = i32; +pub type rlim_t = i64; +pub type sa_family_t = u16; +pub type socklen_t = u32; +pub type speed_t = usize; +pub type suseconds_t = i32; +pub type tcflag_t = u32; +pub type clockid_t = i32; +pub type time_t = i64; +pub type wchar_t = i32; + +s! { + pub struct stat { + pub st_dev: dev_t, + pub st_ino: ino_t, + pub st_mode: mode_t, + pub st_nlink: u64, + pub st_uid: u32, + pub st_gid: u32, + 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: i64, + __reserved: [usize; __DEFAULT_RESERVED_SIZE__], + } + + pub struct sockaddr { + pub sa_family: sa_family_t, + pub sa_data: [u8; 14], + } + + pub struct passwd { + pub pw_name: *const c_char, + pub pw_uid: u32, + pub pw_gid: u32, + pub pw_gecos: *const c_char, + pub pw_dir: *const c_char, + pub pw_shell: *const c_char, + __reserved: [usize; __DEFAULT_RESERVED_SIZE__] + } + + pub struct sem_t { __val: [usize; __SEM_SIZE__] } + + pub struct pthread_attr_t { __val: [usize; __PTHREAD_ATTR_SIZE__] } + + pub struct pthread_mutex_t { __val: [usize; __PTHREAD_MUTEX_SIZE__] } + + pub struct pthread_cond_t { __val: [usize; __PTHREAD_COND_SIZE__] } + + pub struct pthread_condattr_t { __val: [usize; __PTHREAD_CONDATTR_SIZE__] } + + 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 decimal_point: *const c_char, + pub thousands_sep: *const c_char, + pub grouping: *const c_char, + pub int_curr_symbol: *const c_char, + pub currency_symbol: *const c_char, + pub mon_decimal_point: *const c_char, + pub mon_thousands_sep: *const c_char, + pub mon_grouping: *const c_char, + pub positive_sign: *const c_char, + pub negative_sign: *const c_char, + pub int_frac_digits: i8, + pub frac_digits: i8, + pub p_cs_precedes: i8, + pub p_sep_by_space: i8, + pub n_cs_precedes: i8, + pub n_sep_by_space: i8, + pub p_sign_posn: i8, + pub n_sign_posn: i8, + pub int_n_cs_precedes: i8, + pub int_n_sep_by_space: i8, + pub int_n_sign_posn: i8, + pub int_p_cs_precedes: i8, + pub int_p_sep_by_space: i8, + pub int_p_sign_posn: i8, + __reserved: [usize; __DEFAULT_RESERVED_SIZE__], + } + + pub struct tm { + pub tm_sec: i32, + pub tm_min: i32, + pub tm_hour: i32, + pub tm_mday: i32, + pub tm_mon: i32, + pub tm_year: i32, + pub tm_wday: i32, + pub tm_yday: i32, + pub tm_isdst: i32, + pub tm_gmtoff: isize, + pub tm_zone: *const i8, + __reserved: [usize; __DEFAULT_RESERVED_SIZE__], + } + + pub struct addrinfo { + pub ai_flags: i32, + pub ai_family: i32, + pub ai_socktype: i32, + pub ai_protocol: i32, + pub ai_addrlen: socklen_t, + pub ai_addr: *mut sockaddr, + pub ai_canonname: *mut c_char, + pub ai_next: *mut addrinfo, + __reserved: [usize; __DEFAULT_RESERVED_SIZE__], + } + + pub struct pthread_rwlock_t { + __val: [usize; __PTHREAD_RWLOCK_SIZE__], + } + + pub struct statvfs { + pub f_bsize: usize, + pub f_frsize: usize, + 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_favail: fsblkcnt_t, + pub f_fsid: usize, + pub f_flag: usize, + pub f_namemax: usize, + __reserved: [usize; __DEFAULT_RESERVED_SIZE__], + } + + pub struct dirent { + pub d_type: u8, + pub d_name: [i8; __NAME_MAX__ + 1], + } + + pub struct fd_set { + __val: [u32; __FDSET_SIZE__], + } + + pub struct sigset_t { + __val: [u32; __SIGSET_SIZE__], + } + + pub struct sigaction { + pub sa_handler: usize, + pub sa_mask: sigset_t, + pub sa_flags: i32, + pub sa_user: usize, + __reserved: [usize; __DEFAULT_RESERVED_SIZE__], + } + + 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; 12], + pub c_speed: speed_t, + __reserved: [usize; __DEFAULT_RESERVED_SIZE__], + } + + pub struct in_addr { + pub s_addr: in_addr_t, + } + + pub struct sockaddr_in { + pub sin_family: sa_family_t, + pub sin_port: ::in_port_t, + pub sin_addr: ::in_addr, + pub sin_zero: [u8; 8], + } + + 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_family: sa_family_t, + pub sun_path: [c_char; 108], + } + + pub struct sockaddr_storage { + pub ss_family: sa_family_t, + ss_data: [u32; __SOCKADDR_STORAGE_SIZE__], + } + + pub struct ip_mreq { + pub imr_multiaddr: in_addr, + pub imr_interface: in_addr, + } + + pub struct ipv6_mreq { + pub ipv6mr_multiaddr: in6_addr, + pub ipv6mr_interface: u32, + } + + pub struct timeval { + pub tv_sec: time_t, + pub tv_usec: suseconds_t, + } +} + +// Reserved two pointer size for reserved area for some structures. +// This ensures that the size of these structures is large enough +// if more fields are added in the NuttX side. +// +// These structures are that defined by POSIX but only necessary fields are included, +// for example, struct passwd, https://pubs.opengroup.org/onlinepubs/009695399/basedefs/pwd.h.html, +// POSIX only defines following fields in struct passwd: +// char *pw_name User's login name. +// uid_t pw_uid Numerical user ID. +// gid_t pw_gid Numerical group ID. +// char *pw_dir Initial working directory. +// char *pw_shell Program to use as shell. +// Other fields can be different depending on the implementation. + +const __DEFAULT_RESERVED_SIZE__: usize = 2; + +const __SOCKADDR_STORAGE_SIZE__: usize = 36; +const __PTHREAD_ATTR_SIZE__: usize = 5; +const __PTHREAD_MUTEX_SIZE__: usize = 9; +const __PTHREAD_COND_SIZE__: usize = 7; +const __PTHREAD_CONDATTR_SIZE__: usize = 5; +const __PTHREAD_RWLOCK_SIZE__: usize = 17; +const __SEM_SIZE__: usize = 6; +const __NAME_MAX__: usize = 64; +const __FDSET_SIZE__: usize = 10; +const __SIGSET_SIZE__: usize = 8; + +pub const PTHREAD_COND_INITIALIZER: pthread_cond_t = pthread_cond_t { + __val: [0; __PTHREAD_COND_SIZE__], +}; +pub const PTHREAD_MUTEX_INITIALIZER: pthread_mutex_t = pthread_mutex_t { + __val: [0; __PTHREAD_MUTEX_SIZE__], +}; + +// dlfcn.h +pub const RTLD_DEFAULT: *mut c_void = 0 as *mut c_void; + +// stdlib.h +pub const EXIT_SUCCESS: i32 = 0; +pub const EXIT_FAILURE: i32 = 1; + +// time.h +pub const CLOCK_REALTIME: i32 = 0; +pub const CLOCK_MONOTONIC: i32 = 1; + +// errno.h +pub const EPERM: i32 = 1; +pub const ENOENT: i32 = 2; +pub const ESRCH: i32 = 3; +pub const EINTR: i32 = 4; +pub const EIO: i32 = 5; +pub const ENXIO: i32 = 6; +pub const E2BIG: i32 = 7; +pub const ENOEXEC: i32 = 8; +pub const EBADF: i32 = 9; +pub const ECHILD: i32 = 10; +pub const EAGAIN: i32 = 11; +pub const ENOMEM: i32 = 12; +pub const EACCES: i32 = 13; +pub const EFAULT: i32 = 14; +pub const ENOTBLK: i32 = 15; +pub const EBUSY: i32 = 16; +pub const EEXIST: i32 = 17; +pub const EXDEV: i32 = 18; +pub const ENODEV: i32 = 19; +pub const ENOTDIR: i32 = 20; +pub const EISDIR: i32 = 21; +pub const EINVAL: i32 = 22; +pub const ENFILE: i32 = 23; +pub const EMFILE: i32 = 24; +pub const ENOTTY: i32 = 25; +pub const ETXTBSY: i32 = 26; +pub const EFBIG: i32 = 27; +pub const ENOSPC: i32 = 28; +pub const ESPIPE: i32 = 29; +pub const EROFS: i32 = 30; +pub const EMLINK: i32 = 31; +pub const EPIPE: i32 = 32; +pub const EDOM: i32 = 33; +pub const ERANGE: i32 = 34; +pub const EDEADLK: i32 = 35; +pub const ENAMETOOLONG: i32 = 36; +pub const ENOLCK: i32 = 37; +pub const ENOSYS: i32 = 38; +pub const ENOTEMPTY: i32 = 39; +pub const ELOOP: i32 = 40; +pub const EWOULDBLOCK: i32 = EAGAIN; +pub const ENOMSG: i32 = 42; +pub const EIDRM: i32 = 43; +pub const ECHRNG: i32 = 44; +pub const EL2NSYNC: i32 = 45; +pub const EL3HLT: i32 = 46; +pub const EL3RST: i32 = 47; +pub const ELNRNG: i32 = 48; +pub const EUNATCH: i32 = 49; +pub const ENOCSI: i32 = 50; +pub const EL2HLT: i32 = 51; +pub const EBADE: i32 = 52; +pub const EBADR: i32 = 53; +pub const EXFULL: i32 = 54; +pub const ENOANO: i32 = 55; +pub const EBADRQC: i32 = 56; +pub const EBADSLT: i32 = 57; +pub const EDEADLOCK: i32 = EDEADLK; +pub const EBFONT: i32 = 59; +pub const ENOSTR: i32 = 60; +pub const ENODATA: i32 = 61; +pub const ETIME: i32 = 62; +pub const ENOSR: i32 = 63; +pub const ENONET: i32 = 64; +pub const ENOPKG: i32 = 65; +pub const EREMOTE: i32 = 66; +pub const ENOLINK: i32 = 67; +pub const EADV: i32 = 68; +pub const ESRMNT: i32 = 69; +pub const ECOMM: i32 = 70; +pub const EPROTO: i32 = 71; +pub const EMULTIHOP: i32 = 72; +pub const EDOTDOT: i32 = 73; +pub const EBADMSG: i32 = 74; +pub const EOVERFLOW: i32 = 75; +pub const ENOTUNIQ: i32 = 76; +pub const EBADFD: i32 = 77; +pub const EREMCHG: i32 = 78; +pub const ELIBACC: i32 = 79; +pub const ELIBBAD: i32 = 80; +pub const ELIBSCN: i32 = 81; +pub const ELIBMAX: i32 = 82; +pub const ELIBEXEC: i32 = 83; +pub const EILSEQ: i32 = 84; +pub const ERESTART: i32 = 85; +pub const ESTRPIPE: i32 = 86; +pub const EUSERS: i32 = 87; +pub const ENOTSOCK: i32 = 88; +pub const EDESTADDRREQ: i32 = 89; +pub const EMSGSIZE: i32 = 90; +pub const EPROTOTYPE: i32 = 91; +pub const ENOPROTOOPT: i32 = 92; +pub const EPROTONOSUPPORT: i32 = 93; +pub const ESOCKTNOSUPPORT: i32 = 94; +pub const EOPNOTSUPP: i32 = 95; +pub const EPFNOSUPPORT: i32 = 96; +pub const EAFNOSUPPORT: i32 = 97; +pub const EADDRINUSE: i32 = 98; +pub const EADDRNOTAVAIL: i32 = 99; +pub const ENETDOWN: i32 = 100; +pub const ENETUNREACH: i32 = 101; +pub const ENETRESET: i32 = 102; +pub const ECONNABORTED: i32 = 103; +pub const ECONNRESET: i32 = 104; +pub const ENOBUFS: i32 = 105; +pub const EISCONN: i32 = 106; +pub const ENOTCONN: i32 = 107; +pub const ESHUTDOWN: i32 = 108; +pub const ETOOMANYREFS: i32 = 109; +pub const ETIMEDOUT: i32 = 110; +pub const ECONNREFUSED: i32 = 111; +pub const EHOSTDOWN: i32 = 112; +pub const EHOSTUNREACH: i32 = 113; +pub const EALREADY: i32 = 114; +pub const EINPROGRESS: i32 = 115; +pub const ESTALE: i32 = 116; +pub const EUCLEAN: i32 = 117; +pub const ENOTNAM: i32 = 118; +pub const ENAVAIL: i32 = 119; +pub const EISNAM: i32 = 120; +pub const EREMOTEIO: i32 = 121; +pub const EDQUOT: i32 = 122; +pub const ENOMEDIUM: i32 = 123; +pub const EMEDIUMTYPE: i32 = 124; +pub const ECANCELED: i32 = 125; +pub const ENOKEY: i32 = 126; +pub const EKEYEXPIRED: i32 = 127; +pub const EKEYREVOKED: i32 = 128; +pub const EKEYREJECTED: i32 = 129; +pub const EOWNERDEAD: i32 = 130; +pub const ENOTRECOVERABLE: i32 = 131; +pub const ERFKILL: i32 = 132; +pub const EHWPOISON: i32 = 133; +pub const ELBIN: i32 = 134; +pub const EFTYPE: i32 = 135; +pub const ENMFILE: i32 = 136; +pub const EPROCLIM: i32 = 137; +pub const ENOTSUP: i32 = 138; +pub const ENOSHARE: i32 = 139; +pub const ECASECLASH: i32 = 140; + +// fcntl.h +pub const FIOCLEX: i32 = 0x30b; +pub const F_SETFL: i32 = 0x9; +pub const F_DUPFD_CLOEXEC: i32 = 0x12; +pub const F_GETFD: i32 = 0x1; +pub const F_GETFL: i32 = 0x2; +pub const O_RDONLY: i32 = 0x1; +pub const O_WRONLY: i32 = 0x2; +pub const O_RDWR: i32 = 0x3; +pub const O_CREAT: i32 = 0x4; +pub const O_EXCL: i32 = 0x8; +pub const O_NOCTTY: i32 = 0x0; +pub const O_TRUNC: i32 = 0x20; +pub const O_APPEND: i32 = 0x10; +pub const O_NONBLOCK: i32 = 0x40; +pub const O_DSYNC: i32 = 0x80; +pub const O_DIRECT: i32 = 0x200; +pub const O_LARGEFILE: i32 = 0x2000; +pub const O_DIRECTORY: i32 = 0x800; +pub const O_NOFOLLOW: i32 = 0x1000; +pub const O_NOATIME: i32 = 0x40000; +pub const O_CLOEXEC: i32 = 0x400; +pub const O_ACCMODE: i32 = 0x0003; +pub const AT_FDCWD: i32 = -100; +pub const AT_REMOVEDIR: i32 = 0x200; + +// sys/types.h +pub const SEEK_SET: i32 = 0; +pub const SEEK_CUR: i32 = 1; +pub const SEEK_END: i32 = 2; + +// sys/stat.h +pub const S_IFDIR: u32 = 0x4000; +pub const S_IFLNK: u32 = 0xA000; +pub const S_IFREG: u32 = 0x8000; +pub const S_IFMT: u32 = 0xF000; +pub const S_IFIFO: u32 = 0x1000; +pub const S_IFSOCK: u32 = 0xc000; +pub const S_IFBLK: u32 = 0x6000; +pub const S_IFCHR: u32 = 0x2000; +pub const S_IRUSR: u32 = 0x100; +pub const S_IWUSR: u32 = 0x80; +pub const S_IXUSR: u32 = 0x40; +pub const S_IRGRP: u32 = 0x20; +pub const S_IWGRP: u32 = 0x10; +pub const S_IXGRP: u32 = 0x8; +pub const S_IROTH: u32 = 0x004; +pub const S_IWOTH: u32 = 0x002; +pub const S_IXOTH: u32 = 0x001; + +// sys/poll.h +pub const POLLIN: i16 = 0x01; +pub const POLLOUT: i16 = 0x04; +pub const POLLHUP: i16 = 0x10; +pub const POLLERR: i16 = 0x08; +pub const POLLNVAL: i16 = 0x20; + +// sys/socket.h +pub const AF_UNIX: i32 = 1; +pub const SOCK_DGRAM: i32 = 2; +pub const SOCK_STREAM: i32 = 1; +pub const AF_INET: i32 = 2; +pub const AF_INET6: i32 = 10; +pub const MSG_PEEK: i32 = 0x02; +pub const SOL_SOCKET: i32 = 1; +pub const SHUT_WR: i32 = 2; +pub const SHUT_RD: i32 = 1; +pub const SHUT_RDWR: i32 = 3; +pub const SO_ERROR: i32 = 4; +pub const SO_REUSEADDR: i32 = 11; +pub const SOMAXCONN: i32 = 8; +pub const SO_LINGER: i32 = 6; +pub const SO_RCVTIMEO: i32 = 0xa; +pub const SO_SNDTIMEO: i32 = 0xe; +pub const SO_BROADCAST: i32 = 1; + +// netinet/tcp.h +pub const TCP_NODELAY: i32 = 0x10; + +// nuttx/fs/ioctl.h +pub const FIONBIO: i32 = 0x30a; + +// unistd.h +pub const STDIN_FILENO: i32 = 0; +pub const STDOUT_FILENO: i32 = 1; +pub const STDERR_FILENO: i32 = 2; +pub const _SC_PAGESIZE: i32 = 0x36; +pub const _SC_THREAD_STACK_MIN: i32 = 0x58; +pub const _SC_GETPW_R_SIZE_MAX: i32 = 0x25; + +// signal.h +pub const SIGPIPE: i32 = 13; + +// pthread.h +pub const PTHREAD_MUTEX_NORMAL: i32 = 0; + +// netinet/in.h +pub const IP_TTL: i32 = 0x1e; +pub const IPV6_V6ONLY: i32 = 0x17; +pub const IPV6_JOIN_GROUP: i32 = 0x11; +pub const IPV6_LEAVE_GROUP: i32 = 0x12; +pub const IP_MULTICAST_LOOP: i32 = 0x13; +pub const IPV6_MULTICAST_LOOP: i32 = 0x15; +pub const IP_MULTICAST_TTL: i32 = 0x12; +pub const IP_ADD_MEMBERSHIP: i32 = 0x14; +pub const IP_DROP_MEMBERSHIP: i32 = 0x15; + +extern "C" { + pub fn bind(sockfd: i32, addr: *const sockaddr, addrlen: socklen_t) -> i32; + pub fn ioctl(fd: i32, request: i32, ...) -> i32; + pub fn dirfd(dirp: *mut DIR) -> i32; + pub fn recvfrom( + sockfd: i32, + buf: *mut c_void, + len: usize, + flags: i32, + src_addr: *mut sockaddr, + addrlen: *mut socklen_t, + ) -> i32; + + pub fn pthread_create( + thread: *mut pthread_t, + attr: *const pthread_attr_t, + start_routine: extern "C" fn(*mut c_void) -> *mut c_void, + arg: *mut c_void, + ) -> i32; + + pub fn clock_gettime(clockid: clockid_t, tp: *mut timespec) -> i32; + pub fn futimens(fd: i32, times: *const timespec) -> i32; + pub fn pthread_condattr_setclock(attr: *mut pthread_condattr_t, clock_id: clockid_t) -> i32; + pub fn pthread_set_name_np(thread: pthread_t, name: *const c_char) -> i32; + pub fn getrandom(buf: *mut c_void, buflen: usize, flags: u32) -> isize; +} diff --git a/vendor/libc/src/unix/redox/mod.rs b/vendor/libc/src/unix/redox/mod.rs new file mode 100644 index 0000000..ac092a3 --- /dev/null +++ b/vendor/libc/src/unix/redox/mod.rs @@ -0,0 +1,1416 @@ +pub type c_char = i8; +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; +pub type clockid_t = ::c_int; +pub type dev_t = ::c_long; +pub type fsblkcnt_t = ::c_ulong; +pub type fsfilcnt_t = ::c_ulong; +pub type ino_t = ::c_ulonglong; +pub type mode_t = ::c_int; +pub type nfds_t = ::c_ulong; +pub type nlink_t = ::c_ulong; +pub type off_t = ::c_longlong; +pub type pthread_t = *mut ::c_void; +// Must be usize due to library/std/sys_common/thread_local.rs, +// should technically be *mut ::c_void +pub type pthread_key_t = usize; +pub type rlim_t = ::c_ulonglong; +pub type sa_family_t = u16; +pub type sem_t = *mut ::c_void; +pub type sigset_t = ::c_ulonglong; +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_longlong; +pub type id_t = ::c_uint; +pub type pid_t = usize; +pub type uid_t = u32; +pub type gid_t = u32; + +#[cfg_attr(feature = "extra_traits", derive(Debug))] +pub enum timezone {} +impl ::Copy for timezone {} +impl ::Clone for timezone { + fn clone(&self) -> timezone { + *self + } +} + +s_no_extra_traits! { + #[repr(C)] + pub struct utsname { + pub sysname: [::c_char; UTSLENGTH], + pub nodename: [::c_char; UTSLENGTH], + pub release: [::c_char; UTSLENGTH], + pub version: [::c_char; UTSLENGTH], + pub machine: [::c_char; UTSLENGTH], + pub domainname: [::c_char; UTSLENGTH], + } + + pub struct dirent { + pub d_ino: ::ino_t, + pub d_off: ::off_t, + pub d_reclen: ::c_ushort, + pub d_type: ::c_uchar, + pub d_name: [::c_char; 256], + } + + pub struct sockaddr_un { + pub sun_family: ::sa_family_t, + pub sun_path: [::c_char; 108] + } + + pub struct sockaddr_storage { + pub ss_family: ::sa_family_t, + __ss_padding: [ + u8; + 128 - + ::core::mem::size_of::() - + ::core::mem::size_of::() + ], + __ss_align: ::c_ulong, + } +} + +s! { + 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: ::size_t, + pub ai_canonname: *mut ::c_char, + pub ai_addr: *mut ::sockaddr, + pub ai_next: *mut ::addrinfo, + } + + 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 epoll_event { + pub events: u32, + pub u64: u64, + pub _pad: u64, + } + + pub struct fd_set { + fds_bits: [::c_ulong; ::FD_SETSIZE / ULONG_SIZE], + } + + pub struct in_addr { + pub s_addr: ::in_addr_t, + } + + pub struct ip_mreq { + pub imr_multiaddr: ::in_addr, + pub imr_interface: ::in_addr, + } + + pub struct lconv { + pub currency_symbol: *const ::c_char, + pub decimal_point: *const ::c_char, + pub frac_digits: ::c_char, + pub grouping: *const ::c_char, + pub int_curr_symbol: *const ::c_char, + pub int_frac_digits: ::c_char, + pub mon_decimal_point: *const ::c_char, + pub mon_grouping: *const ::c_char, + pub mon_thousands_sep: *const ::c_char, + pub negative_sign: *const ::c_char, + pub n_cs_precedes: ::c_char, + pub n_sep_by_space: ::c_char, + pub n_sign_posn: ::c_char, + pub positive_sign: *const ::c_char, + pub p_cs_precedes: ::c_char, + pub p_sep_by_space: ::c_char, + pub p_sign_posn: ::c_char, + pub thousands_sep: *const ::c_char, + } + + 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 sigaction { + 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], + } + + pub struct sockaddr_in { + 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_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 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, + 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, + _pad: [::c_char; 24], + } + + 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 struct termios { + pub c_iflag: ::tcflag_t, + pub c_oflag: ::tcflag_t, + pub c_cflag: ::tcflag_t, + pub c_lflag: ::tcflag_t, + pub c_line: ::cc_t, + pub c_cc: [::cc_t; ::NCCS], + pub c_ispeed: ::speed_t, + pub c_ospeed: ::speed_t, + } + + pub struct 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, + } + + pub struct ucred { + pub pid: pid_t, + pub uid: uid_t, + pub gid: gid_t, + } + + #[cfg_attr(target_pointer_width = "32", repr(C, align(4)))] + #[cfg_attr(target_pointer_width = "64", repr(C, align(8)))] + pub struct pthread_attr_t { + bytes: [u8; _PTHREAD_ATTR_SIZE], + } + #[repr(C)] + #[repr(align(4))] + pub struct pthread_barrier_t { + bytes: [u8; _PTHREAD_BARRIER_SIZE], + } + #[repr(C)] + #[repr(align(4))] + pub struct pthread_barrierattr_t { + bytes: [u8; _PTHREAD_BARRIERATTR_SIZE], + } + #[repr(C)] + #[repr(align(4))] + pub struct pthread_mutex_t { + bytes: [u8; _PTHREAD_MUTEX_SIZE], + } + #[repr(C)] + #[repr(align(4))] + pub struct pthread_rwlock_t { + bytes: [u8; _PTHREAD_RWLOCK_SIZE], + } + #[repr(C)] + #[repr(align(4))] + pub struct pthread_mutexattr_t { + bytes: [u8; _PTHREAD_MUTEXATTR_SIZE], + } + #[repr(C)] + #[repr(align(1))] + pub struct pthread_rwlockattr_t { + bytes: [u8; _PTHREAD_RWLOCKATTR_SIZE], + } + #[repr(C)] + #[repr(align(4))] + pub struct pthread_cond_t { + bytes: [u8; _PTHREAD_COND_SIZE], + } + #[repr(C)] + #[repr(align(4))] + pub struct pthread_condattr_t { + bytes: [u8; _PTHREAD_CONDATTR_SIZE], + } + #[repr(C)] + #[repr(align(4))] + pub struct pthread_once_t { + bytes: [u8; _PTHREAD_ONCE_SIZE], + } + #[repr(C)] + #[repr(align(4))] + pub struct pthread_spinlock_t { + bytes: [u8; _PTHREAD_SPINLOCK_SIZE], + } +} +const _PTHREAD_ATTR_SIZE: usize = 32; +const _PTHREAD_RWLOCKATTR_SIZE: usize = 1; +const _PTHREAD_RWLOCK_SIZE: usize = 4; +const _PTHREAD_BARRIER_SIZE: usize = 24; +const _PTHREAD_BARRIERATTR_SIZE: usize = 4; +const _PTHREAD_CONDATTR_SIZE: usize = 8; +const _PTHREAD_COND_SIZE: usize = 8; +const _PTHREAD_MUTEX_SIZE: usize = 12; +const _PTHREAD_MUTEXATTR_SIZE: usize = 20; +const _PTHREAD_ONCE_SIZE: usize = 4; +const _PTHREAD_SPINLOCK_SIZE: usize = 4; + +pub const UTSLENGTH: usize = 65; + +// 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 + } +} + +// limits.h +pub const PATH_MAX: ::c_int = 4096; + +// fcntl.h +pub const F_GETLK: ::c_int = 5; +pub const F_SETLK: ::c_int = 6; +pub const F_SETLKW: ::c_int = 7; +pub const F_ULOCK: ::c_int = 0; +pub const F_LOCK: ::c_int = 1; +pub const F_TLOCK: ::c_int = 2; +pub const F_TEST: ::c_int = 3; + +// FIXME: relibc { +pub const RTLD_DEFAULT: *mut ::c_void = 0i64 as *mut ::c_void; +// } + +// dlfcn.h +pub const RTLD_LAZY: ::c_int = 0x0001; +pub const RTLD_NOW: ::c_int = 0x0002; +pub const RTLD_GLOBAL: ::c_int = 0x0100; +pub const RTLD_LOCAL: ::c_int = 0x0000; + +// errno.h +pub const EPERM: ::c_int = 1; /* Operation not permitted */ +pub const ENOENT: ::c_int = 2; /* No such file or directory */ +pub const ESRCH: ::c_int = 3; /* No such process */ +pub const EINTR: ::c_int = 4; /* Interrupted system call */ +pub const EIO: ::c_int = 5; /* I/O error */ +pub const ENXIO: ::c_int = 6; /* No such device or address */ +pub const E2BIG: ::c_int = 7; /* Argument list too long */ +pub const ENOEXEC: ::c_int = 8; /* Exec format error */ +pub const EBADF: ::c_int = 9; /* Bad file number */ +pub const ECHILD: ::c_int = 10; /* No child processes */ +pub const EAGAIN: ::c_int = 11; /* Try again */ +pub const ENOMEM: ::c_int = 12; /* Out of memory */ +pub const EACCES: ::c_int = 13; /* Permission denied */ +pub const EFAULT: ::c_int = 14; /* Bad address */ +pub const ENOTBLK: ::c_int = 15; /* Block device required */ +pub const EBUSY: ::c_int = 16; /* Device or resource busy */ +pub const EEXIST: ::c_int = 17; /* File exists */ +pub const EXDEV: ::c_int = 18; /* Cross-device link */ +pub const ENODEV: ::c_int = 19; /* No such device */ +pub const ENOTDIR: ::c_int = 20; /* Not a directory */ +pub const EISDIR: ::c_int = 21; /* Is a directory */ +pub const EINVAL: ::c_int = 22; /* Invalid argument */ +pub const ENFILE: ::c_int = 23; /* File table overflow */ +pub const EMFILE: ::c_int = 24; /* Too many open files */ +pub const ENOTTY: ::c_int = 25; /* Not a typewriter */ +pub const ETXTBSY: ::c_int = 26; /* Text file busy */ +pub const EFBIG: ::c_int = 27; /* File too large */ +pub const ENOSPC: ::c_int = 28; /* No space left on device */ +pub const ESPIPE: ::c_int = 29; /* Illegal seek */ +pub const EROFS: ::c_int = 30; /* Read-only file system */ +pub const EMLINK: ::c_int = 31; /* Too many links */ +pub const EPIPE: ::c_int = 32; /* Broken pipe */ +pub const EDOM: ::c_int = 33; /* Math argument out of domain of func */ +pub const ERANGE: ::c_int = 34; /* Math result not representable */ +pub const EDEADLK: ::c_int = 35; /* Resource deadlock would occur */ +pub const ENAMETOOLONG: ::c_int = 36; /* File name too long */ +pub const ENOLCK: ::c_int = 37; /* No record locks available */ +pub const ENOSYS: ::c_int = 38; /* Function not implemented */ +pub const ENOTEMPTY: ::c_int = 39; /* Directory not empty */ +pub const ELOOP: ::c_int = 40; /* Too many symbolic links encountered */ +pub const EWOULDBLOCK: ::c_int = 41; /* Operation would block */ +pub const ENOMSG: ::c_int = 42; /* No message of desired type */ +pub const EIDRM: ::c_int = 43; /* Identifier removed */ +pub const ECHRNG: ::c_int = 44; /* Channel number out of range */ +pub const EL2NSYNC: ::c_int = 45; /* Level 2 not synchronized */ +pub const EL3HLT: ::c_int = 46; /* Level 3 halted */ +pub const EL3RST: ::c_int = 47; /* Level 3 reset */ +pub const ELNRNG: ::c_int = 48; /* Link number out of range */ +pub const EUNATCH: ::c_int = 49; /* Protocol driver not attached */ +pub const ENOCSI: ::c_int = 50; /* No CSI structure available */ +pub const EL2HLT: ::c_int = 51; /* Level 2 halted */ +pub const EBADE: ::c_int = 52; /* Invalid exchange */ +pub const EBADR: ::c_int = 53; /* Invalid request descriptor */ +pub const EXFULL: ::c_int = 54; /* Exchange full */ +pub const ENOANO: ::c_int = 55; /* No anode */ +pub const EBADRQC: ::c_int = 56; /* Invalid request code */ +pub const EBADSLT: ::c_int = 57; /* Invalid slot */ +pub const EDEADLOCK: ::c_int = 58; /* Resource deadlock would occur */ +pub const EBFONT: ::c_int = 59; /* Bad font file format */ +pub const ENOSTR: ::c_int = 60; /* Device not a stream */ +pub const ENODATA: ::c_int = 61; /* No data available */ +pub const ETIME: ::c_int = 62; /* Timer expired */ +pub const ENOSR: ::c_int = 63; /* Out of streams resources */ +pub const ENONET: ::c_int = 64; /* Machine is not on the network */ +pub const ENOPKG: ::c_int = 65; /* Package not installed */ +pub const EREMOTE: ::c_int = 66; /* Object is remote */ +pub const ENOLINK: ::c_int = 67; /* Link has been severed */ +pub const EADV: ::c_int = 68; /* Advertise error */ +pub const ESRMNT: ::c_int = 69; /* Srmount error */ +pub const ECOMM: ::c_int = 70; /* Communication error on send */ +pub const EPROTO: ::c_int = 71; /* Protocol error */ +pub const EMULTIHOP: ::c_int = 72; /* Multihop attempted */ +pub const EDOTDOT: ::c_int = 73; /* RFS specific error */ +pub const EBADMSG: ::c_int = 74; /* Not a data message */ +pub const EOVERFLOW: ::c_int = 75; /* Value too large for defined data type */ +pub const ENOTUNIQ: ::c_int = 76; /* Name not unique on network */ +pub const EBADFD: ::c_int = 77; /* File descriptor in bad state */ +pub const EREMCHG: ::c_int = 78; /* Remote address changed */ +pub const ELIBACC: ::c_int = 79; /* Can not access a needed shared library */ +pub const ELIBBAD: ::c_int = 80; /* Accessing a corrupted shared library */ +pub const ELIBSCN: ::c_int = 81; /* .lib section in a.out corrupted */ +/* Attempting to link in too many shared libraries */ +pub const ELIBMAX: ::c_int = 82; +pub const ELIBEXEC: ::c_int = 83; /* Cannot exec a shared library directly */ +pub const EILSEQ: ::c_int = 84; /* Illegal byte sequence */ +/* Interrupted system call should be restarted */ +pub const ERESTART: ::c_int = 85; +pub const ESTRPIPE: ::c_int = 86; /* Streams pipe error */ +pub const EUSERS: ::c_int = 87; /* Too many users */ +pub const ENOTSOCK: ::c_int = 88; /* Socket operation on non-socket */ +pub const EDESTADDRREQ: ::c_int = 89; /* Destination address required */ +pub const EMSGSIZE: ::c_int = 90; /* Message too long */ +pub const EPROTOTYPE: ::c_int = 91; /* Protocol wrong type for socket */ +pub const ENOPROTOOPT: ::c_int = 92; /* Protocol not available */ +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; +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 */ +/* Network dropped connection because of reset */ +pub const ENETRESET: ::c_int = 102; +pub const ECONNABORTED: ::c_int = 103; /* Software caused connection abort */ +pub const ECONNRESET: ::c_int = 104; /* Connection reset by peer */ +pub const ENOBUFS: ::c_int = 105; /* No buffer space available */ +pub const EISCONN: ::c_int = 106; /* Transport endpoint is already connected */ +pub const ENOTCONN: ::c_int = 107; /* Transport endpoint is not connected */ +/* Cannot send after transport endpoint shutdown */ +pub const ESHUTDOWN: ::c_int = 108; +pub const ETOOMANYREFS: ::c_int = 109; /* Too many references: cannot splice */ +pub const ETIMEDOUT: ::c_int = 110; /* Connection timed out */ +pub const ECONNREFUSED: ::c_int = 111; /* Connection refused */ +pub const EHOSTDOWN: ::c_int = 112; /* Host is down */ +pub const EHOSTUNREACH: ::c_int = 113; /* No route to host */ +pub const EALREADY: ::c_int = 114; /* Operation already in progress */ +pub const EINPROGRESS: ::c_int = 115; /* Operation now in progress */ +pub const ESTALE: ::c_int = 116; /* Stale NFS file handle */ +pub const EUCLEAN: ::c_int = 117; /* Structure needs cleaning */ +pub const ENOTNAM: ::c_int = 118; /* Not a XENIX named type file */ +pub const ENAVAIL: ::c_int = 119; /* No XENIX semaphores available */ +pub const EISNAM: ::c_int = 120; /* Is a named type file */ +pub const EREMOTEIO: ::c_int = 121; /* Remote I/O error */ +pub const EDQUOT: ::c_int = 122; /* Quota exceeded */ +pub const ENOMEDIUM: ::c_int = 123; /* No medium found */ +pub const EMEDIUMTYPE: ::c_int = 124; /* Wrong medium type */ +pub const ECANCELED: ::c_int = 125; /* Operation Canceled */ +pub const ENOKEY: ::c_int = 126; /* Required key not available */ +pub const EKEYEXPIRED: ::c_int = 127; /* Key has expired */ +pub const EKEYREVOKED: ::c_int = 128; /* Key has been revoked */ +pub const EKEYREJECTED: ::c_int = 129; /* Key was rejected by service */ +pub const EOWNERDEAD: ::c_int = 130; /* Owner died */ +pub const ENOTRECOVERABLE: ::c_int = 131; /* State not recoverable */ + +// fcntl.h +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; +// FIXME: relibc { +pub const F_DUPFD_CLOEXEC: ::c_int = ::F_DUPFD; +// } +pub const FD_CLOEXEC: ::c_int = 0x0100_0000; +pub const O_RDONLY: ::c_int = 0x0001_0000; +pub const O_WRONLY: ::c_int = 0x0002_0000; +pub const O_RDWR: ::c_int = 0x0003_0000; +pub const O_ACCMODE: ::c_int = 0x0003_0000; +pub const O_NONBLOCK: ::c_int = 0x0004_0000; +pub const O_APPEND: ::c_int = 0x0008_0000; +pub const O_SHLOCK: ::c_int = 0x0010_0000; +pub const O_EXLOCK: ::c_int = 0x0020_0000; +pub const O_ASYNC: ::c_int = 0x0040_0000; +pub const O_FSYNC: ::c_int = 0x0080_0000; +pub const O_CLOEXEC: ::c_int = 0x0100_0000; +pub const O_CREAT: ::c_int = 0x0200_0000; +pub const O_TRUNC: ::c_int = 0x0400_0000; +pub const O_EXCL: ::c_int = 0x0800_0000; +pub const O_DIRECTORY: ::c_int = 0x1000_0000; +pub const O_PATH: ::c_int = 0x2000_0000; +pub const O_SYMLINK: ::c_int = 0x4000_0000; +// Negative to allow it to be used as int +// 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; +pub const AI_NUMERICHOST: ::c_int = 0x0004; +pub const AI_V4MAPPED: ::c_int = 0x0008; +pub const AI_ALL: ::c_int = 0x0010; +pub const AI_ADDRCONFIG: ::c_int = 0x0020; +pub const AI_NUMERICSERV: ::c_int = 0x0400; +pub const EAI_BADFLAGS: ::c_int = -1; +pub const EAI_NONAME: ::c_int = -2; +pub const EAI_AGAIN: ::c_int = -3; +pub const EAI_FAIL: ::c_int = -4; +pub const EAI_NODATA: ::c_int = -5; +pub const EAI_FAMILY: ::c_int = -6; +pub const EAI_SOCKTYPE: ::c_int = -7; +pub const EAI_SERVICE: ::c_int = -8; +pub const EAI_ADDRFAMILY: ::c_int = -9; +pub const EAI_MEMORY: ::c_int = -10; +pub const EAI_SYSTEM: ::c_int = -11; +pub const EAI_OVERFLOW: ::c_int = -12; +pub const NI_MAXHOST: ::c_int = 1025; +pub const NI_MAXSERV: ::c_int = 32; +pub const NI_NUMERICHOST: ::c_int = 0x0001; +pub const NI_NUMERICSERV: ::c_int = 0x0002; +pub const NI_NOFQDN: ::c_int = 0x0004; +pub const NI_NAMEREQD: ::c_int = 0x0008; +pub const NI_DGRAM: ::c_int = 0x0010; + +// netinet/in.h +// FIXME: relibc { +pub const IP_TTL: ::c_int = 2; +pub const IPV6_UNICAST_HOPS: ::c_int = 16; +pub const IPV6_MULTICAST_IF: ::c_int = 17; +pub const IPV6_MULTICAST_HOPS: ::c_int = 18; +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 IP_MULTICAST_IF: ::c_int = 32; +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 +pub const TCP_NODELAY: ::c_int = 1; +// FIXME: relibc { +pub const TCP_KEEPIDLE: ::c_int = 1; +// } + +// poll.h +pub const POLLIN: ::c_short = 0x001; +pub const POLLPRI: ::c_short = 0x002; +pub const POLLOUT: ::c_short = 0x004; +pub const POLLERR: ::c_short = 0x008; +pub const POLLHUP: ::c_short = 0x010; +pub const POLLNVAL: ::c_short = 0x020; +pub const POLLRDNORM: ::c_short = 0x040; +pub const POLLRDBAND: ::c_short = 0x080; +pub const POLLWRNORM: ::c_short = 0x100; +pub const POLLWRBAND: ::c_short = 0x200; + +// pthread.h +pub const PTHREAD_MUTEX_NORMAL: ::c_int = 0; +pub const PTHREAD_MUTEX_RECURSIVE: ::c_int = 1; +pub const PTHREAD_MUTEX_INITIALIZER: ::pthread_mutex_t = ::pthread_mutex_t { + bytes: [0; _PTHREAD_MUTEX_SIZE], +}; +pub const PTHREAD_COND_INITIALIZER: ::pthread_cond_t = ::pthread_cond_t { + bytes: [0; _PTHREAD_COND_SIZE], +}; +pub const PTHREAD_RWLOCK_INITIALIZER: ::pthread_rwlock_t = ::pthread_rwlock_t { + bytes: [0; _PTHREAD_RWLOCK_SIZE], +}; +pub const PTHREAD_STACK_MIN: ::size_t = 4096; + +// signal.h +pub const SIG_BLOCK: ::c_int = 0; +pub const SIG_UNBLOCK: ::c_int = 1; +pub const SIG_SETMASK: ::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 SIGBUS: ::c_int = 7; +pub const SIGFPE: ::c_int = 8; +pub const SIGKILL: ::c_int = 9; +pub const SIGUSR1: ::c_int = 10; +pub const SIGSEGV: ::c_int = 11; +pub const SIGUSR2: ::c_int = 12; +pub const SIGPIPE: ::c_int = 13; +pub const SIGALRM: ::c_int = 14; +pub const SIGTERM: ::c_int = 15; +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 SIGPWR: ::c_int = 30; +pub const SIGSYS: ::c_int = 31; +pub const NSIG: ::c_int = 32; + +pub const SA_NOCLDSTOP: ::c_ulong = 0x00000001; +pub const SA_NOCLDWAIT: ::c_ulong = 0x00000002; +pub const SA_SIGINFO: ::c_ulong = 0x00000004; +pub const SA_RESTORER: ::c_ulong = 0x04000000; +pub const SA_ONSTACK: ::c_ulong = 0x08000000; +pub const SA_RESTART: ::c_ulong = 0x10000000; +pub const SA_NODEFER: ::c_ulong = 0x40000000; +pub const SA_RESETHAND: ::c_ulong = 0x80000000; + +// 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/epoll.h +pub const EPOLL_CLOEXEC: ::c_int = 0x0100_0000; +pub const EPOLL_CTL_ADD: ::c_int = 1; +pub const EPOLL_CTL_DEL: ::c_int = 2; +pub const EPOLL_CTL_MOD: ::c_int = 3; +pub const EPOLLIN: ::c_int = 0x001; +pub const EPOLLPRI: ::c_int = 0x002; +pub const EPOLLOUT: ::c_int = 0x004; +pub const EPOLLERR: ::c_int = 0x008; +pub const EPOLLHUP: ::c_int = 0x010; +pub const EPOLLNVAL: ::c_int = 0x020; +pub const EPOLLRDNORM: ::c_int = 0x040; +pub const EPOLLRDBAND: ::c_int = 0x080; +pub const EPOLLWRNORM: ::c_int = 0x100; +pub const EPOLLWRBAND: ::c_int = 0x200; +pub const EPOLLMSG: ::c_int = 0x400; +pub const EPOLLRDHUP: ::c_int = 0x2000; +pub const EPOLLEXCLUSIVE: ::c_int = 1 << 28; +pub const EPOLLWAKEUP: ::c_int = 1 << 29; +pub const EPOLLONESHOT: ::c_int = 1 << 30; +pub const EPOLLET: ::c_int = 1 << 31; + +// sys/stat.h +pub const S_IFMT: ::c_int = 0o0_170_000; +pub const S_IFDIR: ::c_int = 0o040_000; +pub const S_IFCHR: ::c_int = 0o020_000; +pub const S_IFBLK: ::c_int = 0o060_000; +pub const S_IFREG: ::c_int = 0o100_000; +pub const S_IFIFO: ::c_int = 0o010_000; +pub const S_IFLNK: ::c_int = 0o120_000; +pub const S_IFSOCK: ::c_int = 0o140_000; +pub const S_IRWXU: ::c_int = 0o0_700; +pub const S_IRUSR: ::c_int = 0o0_400; +pub const S_IWUSR: ::c_int = 0o0_200; +pub const S_IXUSR: ::c_int = 0o0_100; +pub const S_IRWXG: ::c_int = 0o0_070; +pub const S_IRGRP: ::c_int = 0o0_040; +pub const S_IWGRP: ::c_int = 0o0_020; +pub const S_IXGRP: ::c_int = 0o0_010; +pub const S_IRWXO: ::c_int = 0o0_007; +pub const S_IROTH: ::c_int = 0o0_004; +pub const S_IWOTH: ::c_int = 0o0_002; +pub const S_IXOTH: ::c_int = 0o0_001; + +// stdlib.h +pub const EXIT_SUCCESS: ::c_int = 0; +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; +// } +pub const TCGETS: ::c_ulong = 0x5401; +pub const TCSETS: ::c_ulong = 0x5402; +pub const TCFLSH: ::c_ulong = 0x540B; +pub const TIOCSCTTY: ::c_ulong = 0x540E; +pub const TIOCGPGRP: ::c_ulong = 0x540F; +pub const TIOCSPGRP: ::c_ulong = 0x5410; +pub const TIOCGWINSZ: ::c_ulong = 0x5413; +pub const TIOCSWINSZ: ::c_ulong = 0x5414; + +// sys/mman.h +pub const PROT_NONE: ::c_int = 0x0000; +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; +pub const MAP_ANONYMOUS: ::c_int = MAP_ANON; +pub const MAP_FIXED: ::c_int = 0x0010; +pub const MAP_FAILED: *mut ::c_void = !0 as _; + +pub const MS_ASYNC: ::c_int = 0x0001; +pub const MS_INVALIDATE: ::c_int = 0x0002; +pub const MS_SYNC: ::c_int = 0x0004; + +// sys/select.h +pub const FD_SETSIZE: usize = 1024; + +// sys/socket.h +pub const AF_INET: ::c_int = 2; +pub const AF_INET6: ::c_int = 10; +pub const AF_UNIX: ::c_int = 1; +pub const AF_UNSPEC: ::c_int = 0; +pub const PF_INET: ::c_int = 2; +pub const PF_INET6: ::c_int = 10; +pub const PF_UNIX: ::c_int = 1; +pub const PF_UNSPEC: ::c_int = 0; +pub const MSG_CTRUNC: ::c_int = 8; +pub const MSG_DONTROUTE: ::c_int = 4; +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; +pub const SHUT_RDWR: ::c_int = 2; +pub const SO_DEBUG: ::c_int = 1; +pub const SO_REUSEADDR: ::c_int = 2; +pub const SO_TYPE: ::c_int = 3; +pub const SO_ERROR: ::c_int = 4; +pub const SO_DONTROUTE: ::c_int = 5; +pub const SO_BROADCAST: ::c_int = 6; +pub const SO_SNDBUF: ::c_int = 7; +pub const SO_RCVBUF: ::c_int = 8; +pub const SO_KEEPALIVE: ::c_int = 9; +pub const SO_OOBINLINE: ::c_int = 10; +pub const SO_NO_CHECK: ::c_int = 11; +pub const SO_PRIORITY: ::c_int = 12; +pub const SO_LINGER: ::c_int = 13; +pub const SO_BSDCOMPAT: ::c_int = 14; +pub const SO_REUSEPORT: ::c_int = 15; +pub const SO_PASSCRED: ::c_int = 16; +pub const SO_PEERCRED: ::c_int = 17; +pub const SO_RCVLOWAT: ::c_int = 18; +pub const SO_SNDLOWAT: ::c_int = 19; +pub const SO_RCVTIMEO: ::c_int = 20; +pub const SO_SNDTIMEO: ::c_int = 21; +pub const SO_ACCEPTCONN: ::c_int = 30; +pub const SO_PEERSEC: ::c_int = 31; +pub const SO_SNDBUFFORCE: ::c_int = 32; +pub const SO_RCVBUFFORCE: ::c_int = 33; +pub const SO_PROTOCOL: ::c_int = 38; +pub const SO_DOMAIN: ::c_int = 39; +pub const SOCK_STREAM: ::c_int = 1; +pub const SOCK_DGRAM: ::c_int = 2; +pub const SOCK_NONBLOCK: ::c_int = 0o4_000; +pub const SOCK_CLOEXEC: ::c_int = 0o2_000_000; +pub const SOCK_SEQPACKET: ::c_int = 5; +pub const SOL_SOCKET: ::c_int = 1; +pub const SOMAXCONN: ::c_int = 128; + +// sys/termios.h +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 VINTR: usize = 8; +pub const VQUIT: usize = 9; +pub const VSUSP: usize = 10; +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; +pub const IGNPAR: ::tcflag_t = 0o000_004; +pub const PARMRK: ::tcflag_t = 0o000_010; +pub const INPCK: ::tcflag_t = 0o000_020; +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 IXON: ::tcflag_t = 0o001_000; +pub const IXOFF: ::tcflag_t = 0o002_000; + +pub const OPOST: ::tcflag_t = 0o000_001; +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 = 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; +pub const B75: speed_t = 0o000_002; +pub const B110: speed_t = 0o000_003; +pub const B134: speed_t = 0o000_004; +pub const B150: speed_t = 0o000_005; +pub const B200: speed_t = 0o000_006; +pub const B300: speed_t = 0o000_007; +pub const B600: speed_t = 0o000_010; +pub const B1200: speed_t = 0o000_011; +pub const B1800: speed_t = 0o000_012; +pub const B2400: speed_t = 0o000_013; +pub const B4800: speed_t = 0o000_014; +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 = 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_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; +pub const TCIOFF: ::c_int = 2; +pub const TCION: ::c_int = 3; + +pub const TCIFLUSH: ::c_int = 0; +pub const TCOFLUSH: ::c_int = 1; +pub const TCIOFLUSH: ::c_int = 2; + +pub const TCSANOW: ::c_int = 0; +pub const TCSADRAIN: ::c_int = 1; +pub const TCSAFLUSH: ::c_int = 2; + +// sys/wait.h +pub const WNOHANG: ::c_int = 1; +pub const WUNTRACED: ::c_int = 2; + +pub const WSTOPPED: ::c_int = 2; +pub const WEXITED: ::c_int = 4; +pub const WCONTINUED: ::c_int = 8; +pub const WNOWAIT: ::c_int = 0x0100_0000; + +pub const __WNOTHREAD: ::c_int = 0x2000_0000; +pub const __WALL: ::c_int = 0x4000_0000; +#[allow(overflowing_literals)] +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 { +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_STREAM_MAX: ::c_int = 5; +pub const _SC_TZNAME_MAX: ::c_int = 6; +// ... +pub const _SC_VERSION: ::c_int = 29; +pub const _SC_PAGESIZE: ::c_int = 30; +pub const _SC_PAGE_SIZE: ::c_int = 30; +// ... +pub const _SC_RE_DUP_MAX: ::c_int = 44; +// ... +pub const _SC_LOGIN_NAME_MAX: ::c_int = 71; +pub const _SC_TTY_NAME_MAX: ::c_int = 72; +// ... +pub const _SC_SYMLOOP_MAX: ::c_int = 173; +// ... +pub const _SC_HOST_NAME_MAX: ::c_int = 180; +// } POSIX.1 + +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; + +pub const SEEK_SET: ::c_int = 0; +pub const SEEK_CUR: ::c_int = 1; +pub const SEEK_END: ::c_int = 2; +pub const STDIN_FILENO: ::c_int = 0; +pub const STDOUT_FILENO: ::c_int = 1; +pub const STDERR_FILENO: ::c_int = 2; + +pub const _PC_LINK_MAX: ::c_int = 0; +pub const _PC_MAX_CANON: ::c_int = 1; +pub const _PC_MAX_INPUT: ::c_int = 2; +pub const _PC_NAME_MAX: ::c_int = 3; +pub const _PC_PATH_MAX: ::c_int = 4; +pub const _PC_PIPE_BUF: ::c_int = 5; +pub const _PC_CHOWN_RESTRICTED: ::c_int = 6; +pub const _PC_NO_TRUNC: ::c_int = 7; +pub const _PC_VDISABLE: ::c_int = 8; +pub const _PC_SYNC_IO: ::c_int = 9; +pub const _PC_ASYNC_IO: ::c_int = 10; +pub const _PC_PRIO_IO: ::c_int = 11; +pub const _PC_SOCK_MAXBUF: ::c_int = 12; +pub const _PC_FILESIZEBITS: ::c_int = 13; +pub const _PC_REC_INCR_XFER_SIZE: ::c_int = 14; +pub const _PC_REC_MAX_XFER_SIZE: ::c_int = 15; +pub const _PC_REC_MIN_XFER_SIZE: ::c_int = 16; +pub const _PC_REC_XFER_ALIGN: ::c_int = 17; +pub const _PC_ALLOC_SIZE_MIN: ::c_int = 18; +pub const _PC_SYMLINK_MAX: ::c_int = 19; +pub const _PC_2_SYMLINKS: ::c_int = 20; + +pub const PRIO_PROCESS: ::c_int = 0; +pub const PRIO_PGRP: ::c_int = 1; +pub const PRIO_USER: ::c_int = 2; + +// wait.h +f! { + pub fn FD_CLR(fd: ::c_int, set: *mut fd_set) -> () { + let fd = fd as usize; + let size = ::mem::size_of_val(&(*set).fds_bits[0]) * 8; + (*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; + } + } +} + +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 + } +} + +extern "C" { + // errno.h + pub fn __errno_location() -> *mut ::c_int; + pub fn strerror_r(errnum: ::c_int, buf: *mut c_char, buflen: ::size_t) -> ::c_int; + + // unistd.h + pub fn pipe2(fds: *mut ::c_int, flags: ::c_int) -> ::c_int; + pub fn getdtablesize() -> ::c_int; + + // grp.h + pub fn getgrent() -> *mut ::group; + pub fn setgrent(); + pub fn endgrent(); + 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 getgrouplist( + user: *const ::c_char, + group: ::gid_t, + groups: *mut ::gid_t, + ngroups: *mut ::c_int, + ) -> ::c_int; + + // malloc.h + pub fn memalign(align: ::size_t, size: ::size_t) -> *mut ::c_void; + + // netdb.h + pub fn getnameinfo( + addr: *const ::sockaddr, + addrlen: ::socklen_t, + host: *mut ::c_char, + hostlen: ::socklen_t, + serv: *mut ::c_char, + servlen: ::socklen_t, + flags: ::c_int, + ) -> ::c_int; + + // pthread.h + pub fn pthread_atfork( + prepare: ::Option, + parent: ::Option, + child: ::Option, + ) -> ::c_int; + pub fn pthread_create( + tid: *mut ::pthread_t, + attr: *const ::pthread_attr_t, + start: extern "C" fn(*mut ::c_void) -> *mut ::c_void, + arg: *mut ::c_void, + ) -> ::c_int; + pub fn pthread_condattr_setclock( + attr: *mut pthread_condattr_t, + clock_id: ::clockid_t, + ) -> ::c_int; + + //pty.h + pub fn openpty( + amaster: *mut ::c_int, + aslave: *mut ::c_int, + name: *mut ::c_char, + termp: *const termios, + winp: *const ::winsize, + ) -> ::c_int; + + // pwd.h + pub fn getpwent() -> *mut passwd; + pub fn setpwent(); + pub fn endpwent(); + 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; + + // signal.h + pub fn pthread_sigmask( + how: ::c_int, + 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; + pub fn sigtimedwait( + set: *const sigset_t, + sig: *mut siginfo_t, + timeout: *const ::timespec, + ) -> ::c_int; + pub fn sigwait(set: *const sigset_t, sig: *mut ::c_int) -> ::c_int; + + // stdlib.h + pub fn getsubopt( + optionp: *mut *mut c_char, + tokens: *const *mut c_char, + valuep: *mut *mut c_char, + ) -> ::c_int; + pub fn reallocarray(ptr: *mut ::c_void, nmemb: ::size_t, size: ::size_t) -> *mut ::c_void; + + // string.h + pub fn explicit_bzero(p: *mut ::c_void, len: ::size_t); + 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; + pub fn epoll_create1(flags: ::c_int) -> ::c_int; + pub fn epoll_wait( + epfd: ::c_int, + events: *mut ::epoll_event, + maxevents: ::c_int, + timeout: ::c_int, + ) -> ::c_int; + pub fn epoll_ctl(epfd: ::c_int, op: ::c_int, fd: ::c_int, event: *mut ::epoll_event) + -> ::c_int; + + // sys/ioctl.h + 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; + pub fn shm_unlink(name: *const ::c_char) -> ::c_int; + + // sys/resource.h + 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 getrlimit(resource: ::c_int, rlim: *mut ::rlimit) -> ::c_int; + pub fn setrlimit(resource: ::c_int, rlim: *const ::rlimit) -> ::c_int; + + // sys/socket.h + pub fn bind(socket: ::c_int, address: *const ::sockaddr, address_len: ::socklen_t) -> ::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; + + // sys/stat.h + pub fn futimens(fd: ::c_int, times: *const ::timespec) -> ::c_int; + + // sys/uio.h + pub fn readv(fd: ::c_int, iov: *const ::iovec, iovcnt: ::c_int) -> ::ssize_t; + pub fn writev(fd: ::c_int, iov: *const ::iovec, iovcnt: ::c_int) -> ::ssize_t; + + // sys/utsname.h + pub fn uname(utsname: *mut utsname) -> ::c_int; + + // 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; + + // utmp.h + pub fn login_tty(fd: ::c_int) -> ::c_int; +} + +cfg_if! { + if #[cfg(feature = "extra_traits")] { + impl PartialEq for dirent { + fn eq(&self, other: &dirent) -> bool { + self.d_ino == other.d_ino + && self.d_off == other.d_off + && self.d_reclen == other.d_reclen + && self.d_type == other.d_type + && self + .d_name + .iter() + .zip(other.d_name.iter()) + .all(|(a,b)| a == b) + } + } + + impl Eq for dirent {} + + impl ::fmt::Debug for dirent { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("dirent") + .field("d_ino", &self.d_ino) + .field("d_off", &self.d_off) + .field("d_reclen", &self.d_reclen) + .field("d_type", &self.d_type) + // FIXME: .field("d_name", &self.d_name) + .finish() + } + } + + impl ::hash::Hash for dirent { + fn hash(&self, state: &mut H) { + self.d_ino.hash(state); + self.d_off.hash(state); + self.d_reclen.hash(state); + self.d_type.hash(state); + self.d_name.hash(state); + } + } + + impl PartialEq for sockaddr_un { + fn eq(&self, other: &sockaddr_un) -> bool { + self.sun_family == other.sun_family + && self + .sun_path + .iter() + .zip(other.sun_path.iter()) + .all(|(a,b)| a == b) + } + } + + impl Eq for sockaddr_un {} + + impl ::fmt::Debug for sockaddr_un { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("sockaddr_un") + .field("sun_family", &self.sun_family) + // FIXME: .field("sun_path", &self.sun_path) + .finish() + } + } + + impl ::hash::Hash for sockaddr_un { + fn hash(&self, state: &mut H) { + self.sun_family.hash(state); + self.sun_path.hash(state); + } + } + + impl PartialEq for sockaddr_storage { + fn eq(&self, other: &sockaddr_storage) -> bool { + self.ss_family == other.ss_family + && self.__ss_align == self.__ss_align + && self + .__ss_padding + .iter() + .zip(other.__ss_padding.iter()) + .all(|(a,b)| a == b) + } + } + + impl Eq for sockaddr_storage {} + + impl ::fmt::Debug for sockaddr_storage { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("sockaddr_storage") + .field("ss_family", &self.ss_family) + .field("__ss_align", &self.__ss_align) + // FIXME: .field("__ss_padding", &self.__ss_padding) + .finish() + } + } + + impl ::hash::Hash for sockaddr_storage { + fn hash(&self, state: &mut H) { + self.ss_family.hash(state); + self.__ss_padding.hash(state); + self.__ss_align.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) + && self + .domainname + .iter() + .zip(other.domainname.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) + // FIXME: .field("domainname", &self.domainname) + .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); + self.domainname.hash(state); + } + } + } +} diff --git a/vendor/libc/src/unix/solarish/compat.rs b/vendor/libc/src/unix/solarish/compat.rs new file mode 100644 index 0000000..cbf955a --- /dev/null +++ b/vendor/libc/src/unix/solarish/compat.rs @@ -0,0 +1,220 @@ +// 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"; +const LDTERM: &[u8] = b"ldterm\0"; + +pub unsafe fn cfmakeraw(termios: *mut ::termios) { + (*termios).c_iflag &= + !(IMAXBEL | IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL | IXON); + (*termios).c_oflag &= !OPOST; + (*termios).c_lflag &= !(ECHO | ECHONL | ICANON | ISIG | IEXTEN); + (*termios).c_cflag &= !(CSIZE | PARENB); + (*termios).c_cflag |= CS8; + + // By default, most software expects a pending read to block until at + // least one byte becomes available. As per termio(7I), this requires + // setting the MIN and TIME parameters appropriately. + // + // As a somewhat unfortunate artefact of history, the MIN and TIME slots + // in the control character array overlap with the EOF and EOL slots used + // for canonical mode processing. Because the EOF character needs to be + // the ASCII EOT value (aka Control-D), it has the byte value 4. When + // switching to raw mode, this is interpreted as a MIN value of 4; i.e., + // reads will block until at least four bytes have been input. + // + // Other platforms with a distinct MIN slot like Linux and FreeBSD appear + // to default to a MIN value of 1, so we'll force that value here: + (*termios).c_cc[VMIN] = 1; + (*termios).c_cc[VTIME] = 0; +} + +pub unsafe fn cfsetspeed(termios: *mut ::termios, speed: ::speed_t) -> ::c_int { + // Neither of these functions on illumos or Solaris actually ever + // return an error + ::cfsetispeed(termios, speed); + ::cfsetospeed(termios, speed); + 0 +} + +unsafe fn bail(fdm: ::c_int, fds: ::c_int) -> ::c_int { + let e = *___errno(); + if fds >= 0 { + ::close(fds); + } + if fdm >= 0 { + ::close(fdm); + } + *___errno() = e; + return -1; +} + +pub unsafe fn openpty( + amain: *mut ::c_int, + asubord: *mut ::c_int, + name: *mut ::c_char, + termp: *const termios, + winp: *const ::winsize, +) -> ::c_int { + // Open the main pseudo-terminal device, making sure not to set it as the + // controlling terminal for this process: + let fdm = ::posix_openpt(O_RDWR | O_NOCTTY); + if fdm < 0 { + return -1; + } + + // Set permissions and ownership on the subordinate device and unlock it: + if ::grantpt(fdm) < 0 || ::unlockpt(fdm) < 0 { + return bail(fdm, -1); + } + + // Get the path name of the subordinate device: + let subordpath = ::ptsname(fdm); + if subordpath.is_null() { + return bail(fdm, -1); + } + + // Open the subordinate device without setting it as the controlling + // terminal for this process: + let fds = ::open(subordpath, O_RDWR | O_NOCTTY); + if fds < 0 { + return bail(fdm, -1); + } + + // Check if the STREAMS modules are already pushed: + let setup = ::ioctl(fds, I_FIND, LDTERM.as_ptr()); + if setup < 0 { + return bail(fdm, fds); + } else if setup == 0 { + // The line discipline is not present, so push the appropriate STREAMS + // modules for the subordinate device: + if ::ioctl(fds, I_PUSH, PTEM.as_ptr()) < 0 || ::ioctl(fds, I_PUSH, LDTERM.as_ptr()) < 0 { + return bail(fdm, fds); + } + } + + // If provided, set the terminal parameters: + if !termp.is_null() && ::tcsetattr(fds, TCSAFLUSH, termp) != 0 { + return bail(fdm, fds); + } + + // If provided, set the window size: + if !winp.is_null() && ::ioctl(fds, TIOCSWINSZ, winp) < 0 { + return bail(fdm, fds); + } + + // If the caller wants the name of the subordinate device, copy it out. + // + // Note that this is a terrible interface: there appears to be no standard + // upper bound on the copy length for this pointer. Nobody should pass + // anything but NULL here, preferring instead to use ptsname(3C) directly. + if !name.is_null() { + ::strcpy(name, subordpath); + } + + *amain = fdm; + *asubord = fds; + 0 +} + +pub unsafe fn forkpty( + amain: *mut ::c_int, + name: *mut ::c_char, + termp: *const termios, + winp: *const ::winsize, +) -> ::pid_t { + let mut fds = -1; + + if openpty(amain, &mut fds, name, termp, winp) != 0 { + return -1; + } + + let pid = ::fork(); + if pid < 0 { + return bail(*amain, fds); + } else if pid > 0 { + // In the parent process, we close the subordinate device and return the + // process ID of the new child: + ::close(fds); + return pid; + } + + // The rest of this function executes in the child process. + + // Close the main side of the pseudo-terminal pair: + ::close(*amain); + + // Use TIOCSCTTY to set the subordinate device as our controlling + // terminal. This will fail (with ENOTTY) if we are not the leader in + // our own session, so we call setsid() first. Finally, arrange for + // the pseudo-terminal to occupy the standard I/O descriptors. + if ::setsid() < 0 + || ::ioctl(fds, TIOCSCTTY, 0) < 0 + || ::dup2(fds, 0) < 0 + || ::dup2(fds, 1) < 0 + || ::dup2(fds, 2) < 0 + { + // At this stage there are no particularly good ways to handle failure. + // Exit as abruptly as possible, using _exit() to avoid messing with any + // state still shared with the parent process. + ::_exit(EXIT_FAILURE); + } + // Close the inherited descriptor, taking care to avoid closing the standard + // descriptors by mistake: + if fds > 2 { + ::close(fds); + } + + 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 new file mode 100644 index 0000000..614fd12 --- /dev/null +++ b/vendor/libc/src/unix/solarish/illumos.rs @@ -0,0 +1,115 @@ +s! { + pub struct shmid_ds { + pub shm_perm: ::ipc_perm, + pub shm_segsz: ::size_t, + pub shm_amp: *mut ::c_void, + pub shm_lkcnt: ::c_ushort, + pub shm_lpid: ::pid_t, + pub shm_cpid: ::pid_t, + pub shm_nattch: ::shmatt_t, + pub shm_cnattch: ::c_ulong, + pub shm_atime: ::time_t, + pub shm_dtime: ::time_t, + 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 +pub const AF_FILE: ::c_int = 1; // AF_UNIX + +pub const EFD_SEMAPHORE: ::c_int = 0x1; +pub const EFD_NONBLOCK: ::c_int = 0x800; +pub const EFD_CLOEXEC: ::c_int = 0x80000; + +pub const POLLRDHUP: ::c_short = 0x4000; + +pub const TCP_KEEPIDLE: ::c_int = 34; +pub const TCP_KEEPCNT: ::c_int = 35; +pub const TCP_KEEPINTVL: ::c_int = 36; +pub const TCP_CONGESTION: ::c_int = 37; + +// 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 POSIX_FADV_NORMAL: ::c_int = 0; +pub const POSIX_FADV_RANDOM: ::c_int = 1; +pub const POSIX_FADV_SEQUENTIAL: ::c_int = 2; +pub const POSIX_FADV_WILLNEED: ::c_int = 3; +pub const POSIX_FADV_DONTNEED: ::c_int = 4; +pub const POSIX_FADV_NOREUSE: ::c_int = 5; + +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 pthread_attr_get_np(thread: ::pthread_t, attr: *mut ::pthread_attr_t) -> ::c_int; + pub fn pthread_attr_getstackaddr( + attr: *const ::pthread_attr_t, + stackaddr: *mut *mut ::c_void, + ) -> ::c_int; + pub fn pthread_attr_setstack( + attr: *mut ::pthread_attr_t, + stackaddr: *mut ::c_void, + stacksize: ::size_t, + ) -> ::c_int; + pub fn pthread_attr_setstackaddr( + attr: *mut ::pthread_attr_t, + stackaddr: *mut ::c_void, + ) -> ::c_int; + + pub fn posix_fadvise(fd: ::c_int, offset: ::off_t, len: ::off_t, advice: ::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; + + pub fn ptsname_r(fildes: ::c_int, name: *mut ::c_char, namelen: ::size_t) -> ::c_int; +} diff --git a/vendor/libc/src/unix/solarish/mod.rs b/vendor/libc/src/unix/solarish/mod.rs new file mode 100644 index 0000000..1cc6c42 --- /dev/null +++ b/vendor/libc/src/unix/solarish/mod.rs @@ -0,0 +1,3331 @@ +pub type c_char = i8; +pub type c_long = i64; +pub type c_ulong = u64; +pub type caddr_t = *mut ::c_char; + +pub type clockid_t = ::c_int; +pub type blkcnt_t = ::c_long; +pub type clock_t = ::c_long; +pub type daddr_t = ::c_long; +pub type dev_t = ::c_ulong; +pub type fsblkcnt_t = ::c_ulong; +pub type fsfilcnt_t = ::c_ulong; +pub type ino_t = ::c_ulong; +pub type key_t = ::c_int; +pub type major_t = ::c_uint; +pub type minor_t = ::c_uint; +pub type mode_t = ::c_uint; +pub type nlink_t = ::c_uint; +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 timer_t = ::c_int; +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; +pub type useconds_t = ::c_uint; +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; +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 {} +impl ::Clone for timezone { + fn clone(&self) -> timezone { + *self + } +} + +#[cfg_attr(feature = "extra_traits", derive(Debug))] +pub enum ucred_t {} +impl ::Copy for ucred_t {} +impl ::Clone for ucred_t { + fn clone(&self) -> ucred_t { + *self + } +} + +s! { + pub struct in_addr { + pub s_addr: ::in_addr_t, + } + + pub struct ip_mreq { + pub imr_multiaddr: in_addr, + pub imr_interface: in_addr, + } + + pub struct 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, + pub cuid: ::uid_t, + pub cgid: ::gid_t, + pub mode: ::mode_t, + pub seq: ::c_uint, + pub key: ::key_t, + } + + pub struct sockaddr { + pub sa_family: sa_family_t, + pub sa_data: [::c_char; 14], + } + + pub struct sockaddr_in { + 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_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 __sin6_src_id: u32 + } + + pub struct in_pktinfo { + pub ipi_ifindex: ::c_uint, + pub ipi_spec_dst: ::in_addr, + pub ipi_addr: ::in_addr, + } + + pub struct in6_pktinfo { + pub ipi6_addr: ::in6_addr, + pub ipi6_ifindex: ::c_uint, + } + + 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 ifaddrs { + pub ifa_next: *mut ifaddrs, + pub ifa_name: *mut ::c_char, + pub ifa_flags: u64, + pub ifa_addr: *mut ::sockaddr, + pub ifa_netmask: *mut ::sockaddr, + pub ifa_dstaddr: *mut ::sockaddr, + pub ifa_data: *mut ::c_void + } + + pub struct itimerspec { + pub it_interval: ::timespec, + pub it_value: ::timespec, + } + + 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 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 pthread_attr_t { + __pthread_attrp: *mut ::c_void + } + + pub struct pthread_mutex_t { + __pthread_mutex_flag1: u16, + __pthread_mutex_flag2: u8, + __pthread_mutex_ceiling: u8, + __pthread_mutex_type: u16, + __pthread_mutex_magic: u16, + __pthread_mutex_lock: u64, + __pthread_mutex_data: u64 + } + + pub struct pthread_mutexattr_t { + __pthread_mutexattrp: *mut ::c_void + } + + pub struct pthread_cond_t { + __pthread_cond_flag: [u8; 4], + __pthread_cond_type: u16, + __pthread_cond_magic: u16, + __pthread_cond_data: u64 + } + + pub struct pthread_condattr_t { + __pthread_condattrp: *mut ::c_void, + } + + pub struct pthread_rwlock_t { + __pthread_rwlock_readers: i32, + __pthread_rwlock_type: u16, + __pthread_rwlock_magic: u16, + __pthread_rwlock_mutex: ::pthread_mutex_t, + __pthread_rwlock_readercv: ::pthread_cond_t, + __pthread_rwlock_writercv: ::pthread_cond_t + } + + pub struct pthread_rwlockattr_t { + __pthread_rwlockattrp: *mut ::c_void, + } + + pub struct dirent { + pub d_ino: ::ino_t, + pub d_off: ::off_t, + pub d_reclen: u16, + pub d_name: [::c_char; 3] + } + + pub struct glob_t { + pub gl_pathc: ::size_t, + pub gl_pathv: *mut *mut ::c_char, + pub gl_offs: ::size_t, + __unused1: *mut ::c_void, + __unused2: ::c_int, + __unused3: ::c_int, + __unused4: ::c_int, + __unused5: *mut ::c_void, + __unused6: *mut ::c_void, + __unused7: *mut ::c_void, + __unused8: *mut ::c_void, + __unused9: *mut ::c_void, + __unused10: *mut ::c_void, + } + + pub struct addrinfo { + pub ai_flags: ::c_int, + pub ai_family: ::c_int, + pub ai_socktype: ::c_int, + pub ai_protocol: ::c_int, + #[cfg(target_arch = "sparc64")] + __sparcv9_pad: ::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 sigset_t { + bits: [u32; 4], + } + + pub struct sigaction { + pub sa_flags: ::c_int, + pub sa_sigaction: ::sighandler_t, + pub sa_mask: sigset_t, + } + + pub struct stack_t { + pub ss_sp: *mut ::c_void, + pub ss_size: ::size_t, + pub ss_flags: ::c_int, + } + + 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 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] + } + + 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 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_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_blksize: ::blksize_t, + pub st_blocks: ::blkcnt_t, + __unused: [::c_char; 16] + } + + 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 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_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 sem_t { + pub sem_count: u32, + pub sem_type: u16, + pub sem_magic: u16, + pub sem_pad1: [u64; 3], + pub sem_pad2: [u64; 2] + } + + 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_sysid: ::c_int, + pub l_pid: ::pid_t, + pub l_pad: [::c_long; 4] + } + + pub struct if_nameindex { + pub if_index: ::c_uint, + pub if_name: *mut ::c_char, + } + + pub struct mq_attr { + pub mq_flags: ::c_long, + pub mq_maxmsg: ::c_long, + pub mq_msgsize: ::c_long, + pub mq_curmsgs: ::c_long, + _pad: [::c_int; 12] + } + + pub struct port_event { + pub portev_events: ::c_int, + pub portev_source: ::c_ushort, + pub portev_pad: ::c_ushort, + pub portev_object: ::uintptr_t, + pub portev_user: *mut ::c_void, + } + + pub struct port_notify { + pub portnfy_port: ::c_int, + pub portnfy_user: *mut ::c_void, + } + + pub struct exit_status { + e_termination: ::c_short, + e_exit: ::c_short, + } + + pub struct utmp { + pub ut_user: [::c_char; 8], + pub ut_id: [::c_char; 4], + pub ut_line: [::c_char; 12], + pub ut_pid: ::c_short, + pub ut_type: ::c_short, + pub ut_exit: exit_status, + pub ut_time: ::time_t, + } + + pub struct timex { + pub modes: u32, + pub offset: i32, + pub freq: i32, + pub maxerror: i32, + pub esterror: i32, + pub status: i32, + pub constant: i32, + pub precision: i32, + pub tolerance: i32, + pub ppsfreq: i32, + pub jitter: i32, + pub shift: i32, + pub stabil: i32, + pub jitcnt: i32, + pub calcnt: i32, + pub errcnt: i32, + pub stbcnt: i32, + } + + pub struct ntptimeval { + pub time: ::timeval, + pub maxerror: i32, + 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! { + #[cfg_attr(all( + any(target_arch = "x86", target_arch = "x86_64"), + libc_packedN + ), repr(packed(4)))] + #[cfg_attr(all( + any(target_arch = "x86", target_arch = "x86_64"), + not(libc_packedN) + ), repr(packed))] + pub struct epoll_event { + pub events: u32, + pub u64: u64, + } + + pub struct utmpx { + pub ut_user: [::c_char; _UTX_USERSIZE], + pub ut_id: [::c_char; _UTX_IDSIZE], + pub ut_line: [::c_char; _UTX_LINESIZE], + pub ut_pid: ::pid_t, + pub ut_type: ::c_short, + pub ut_exit: exit_status, + pub ut_tv: ::timeval, + pub ut_session: ::c_int, + pub ut_pad: [::c_int; _UTX_PADSIZE], + pub ut_syslen: ::c_short, + pub ut_host: [::c_char; _UTX_HOSTSIZE], + } + + pub struct sockaddr_un { + pub sun_family: sa_family_t, + pub sun_path: [c_char; 108] + } + + pub struct utsname { + pub sysname: [::c_char; 257], + pub nodename: [::c_char; 257], + pub release: [::c_char; 257], + pub version: [::c_char; 257], + pub machine: [::c_char; 257], + } + + pub struct fd_set { + #[cfg(target_pointer_width = "64")] + fds_bits: [i64; FD_SETSIZE / 64], + #[cfg(target_pointer_width = "32")] + fds_bits: [i32; FD_SETSIZE / 32], + } + + pub struct sockaddr_storage { + pub ss_family: ::sa_family_t, + __ss_pad1: [u8; 6], + __ss_align: i64, + __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, + + __data_pad: [::c_int; SIGINFO_DATA_SIZE], + } + + pub struct sockaddr_dl { + pub sdl_family: ::c_ushort, + 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; 244], + } + + pub struct sigevent { + pub sigev_notify: ::c_int, + pub sigev_signo: ::c_int, + pub sigev_value: ::sigval, + pub ss_sp: *mut ::c_void, + 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! { + if #[cfg(feature = "extra_traits")] { + impl PartialEq for utmpx { + fn eq(&self, other: &utmpx) -> bool { + self.ut_type == other.ut_type + && self.ut_pid == other.ut_pid + && self.ut_user == other.ut_user + && self.ut_line == other.ut_line + && self.ut_id == other.ut_id + && self.ut_exit == other.ut_exit + && self.ut_session == other.ut_session + && self.ut_tv == other.ut_tv + && self.ut_syslen == other.ut_syslen + && self.ut_pad == other.ut_pad + && self + .ut_host + .iter() + .zip(other.ut_host.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_user", &self.ut_user) + .field("ut_id", &self.ut_id) + .field("ut_line", &self.ut_line) + .field("ut_pid", &self.ut_pid) + .field("ut_type", &self.ut_type) + .field("ut_exit", &self.ut_exit) + .field("ut_tv", &self.ut_tv) + .field("ut_session", &self.ut_session) + .field("ut_pad", &self.ut_pad) + .field("ut_syslen", &self.ut_syslen) + .field("ut_host", &&self.ut_host[..]) + .finish() + } + } + + impl ::hash::Hash for utmpx { + fn hash(&self, state: &mut H) { + self.ut_user.hash(state); + self.ut_type.hash(state); + self.ut_pid.hash(state); + self.ut_line.hash(state); + self.ut_id.hash(state); + self.ut_host.hash(state); + self.ut_exit.hash(state); + self.ut_session.hash(state); + self.ut_tv.hash(state); + self.ut_syslen.hash(state); + self.ut_pad.hash(state); + } + } + + impl PartialEq for epoll_event { + fn eq(&self, other: &epoll_event) -> bool { + self.events == other.events + && self.u64 == other.u64 + } + } + impl Eq for epoll_event {} + impl ::fmt::Debug for epoll_event { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + let events = self.events; + let u64 = self.u64; + f.debug_struct("epoll_event") + .field("events", &events) + .field("u64", &u64) + .finish() + } + } + impl ::hash::Hash for epoll_event { + fn hash(&self, state: &mut H) { + let events = self.events; + let u64 = self.u64; + events.hash(state); + u64.hash(state); + } + } + + impl PartialEq for sockaddr_un { + fn eq(&self, other: &sockaddr_un) -> bool { + self.sun_family == other.sun_family + && self + .sun_path + .iter() + .zip(other.sun_path.iter()) + .all(|(a, b)| a == b) + } + } + impl Eq for sockaddr_un {} + impl ::fmt::Debug for sockaddr_un { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("sockaddr_un") + .field("sun_family", &self.sun_family) + // FIXME: .field("sun_path", &self.sun_path) + .finish() + } + } + impl ::hash::Hash for sockaddr_un { + fn hash(&self, state: &mut H) { + self.sun_family.hash(state); + self.sun_path.hash(state); + } + } + + impl PartialEq for utsname { + fn eq(&self, other: &utsname) -> bool { + self.sysname + .iter() + .zip(other.sysname.iter()) + .all(|(a, b)| a == b) + && self + .nodename + .iter() + .zip(other.nodename.iter()) + .all(|(a, b)| a == b) + && self + .release + .iter() + .zip(other.release.iter()) + .all(|(a, b)| a == b) + && self + .version + .iter() + .zip(other.version.iter()) + .all(|(a, b)| a == b) + && self + .machine + .iter() + .zip(other.machine.iter()) + .all(|(a, b)| a == b) + } + } + impl Eq for utsname {} + impl ::fmt::Debug for utsname { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("utsname") + // FIXME: .field("sysname", &self.sysname) + // FIXME: .field("nodename", &self.nodename) + // FIXME: .field("release", &self.release) + // FIXME: .field("version", &self.version) + // FIXME: .field("machine", &self.machine) + .finish() + } + } + impl ::hash::Hash for utsname { + fn hash(&self, state: &mut H) { + self.sysname.hash(state); + self.nodename.hash(state); + self.release.hash(state); + self.version.hash(state); + self.machine.hash(state); + } + } + + impl PartialEq for fd_set { + fn eq(&self, other: &fd_set) -> bool { + self.fds_bits + .iter() + .zip(other.fds_bits.iter()) + .all(|(a, b)| a == b) + } + } + impl Eq for fd_set {} + impl ::fmt::Debug for fd_set { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("fd_set") + // FIXME: .field("fds_bits", &self.fds_bits) + .finish() + } + } + impl ::hash::Hash for fd_set { + fn hash(&self, state: &mut H) { + self.fds_bits.hash(state); + } + } + + impl PartialEq for sockaddr_storage { + fn eq(&self, other: &sockaddr_storage) -> bool { + self.ss_family == other.ss_family + && self.__ss_pad1 == other.__ss_pad1 + && self.__ss_align == other.__ss_align + && self + .__ss_pad2 + .iter() + .zip(other.__ss_pad2.iter()) + .all(|(a, b)| a == b) + } + } + impl Eq for sockaddr_storage {} + impl ::fmt::Debug for sockaddr_storage { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("sockaddr_storage") + .field("ss_family", &self.ss_family) + .field("__ss_pad1", &self.__ss_pad1) + .field("__ss_align", &self.__ss_align) + // FIXME: .field("__ss_pad2", &self.__ss_pad2) + .finish() + } + } + impl ::hash::Hash for sockaddr_storage { + fn hash(&self, state: &mut H) { + self.ss_family.hash(state); + self.__ss_pad1.hash(state); + self.__ss_align.hash(state); + self.__ss_pad2.hash(state); + } + } + + impl 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 { + if self.si_signo == other.si_signo + && self.si_code == other.si_code + && 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 {} + impl ::fmt::Debug for siginfo_t { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("siginfo_t") + .field("si_signo", &self.si_signo) + .field("si_code", &self.si_code) + .field("si_errno", &self.si_errno) + // FIXME: .field("__pad", &self.__pad) + .finish() + } + } + impl ::hash::Hash for siginfo_t { + fn hash(&self, state: &mut H) { + self.si_signo.hash(state); + self.si_code.hash(state); + self.si_errno.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) + } + } + + impl PartialEq for sockaddr_dl { + fn eq(&self, other: &sockaddr_dl) -> bool { + self.sdl_family == other.sdl_family + && self.sdl_index == other.sdl_index + && self.sdl_type == other.sdl_type + && self.sdl_nlen == other.sdl_nlen + && self.sdl_alen == other.sdl_alen + && self.sdl_slen == other.sdl_slen + && self + .sdl_data + .iter() + .zip(other.sdl_data.iter()) + .all(|(a,b)| a == b) + } + } + impl Eq for sockaddr_dl {} + impl ::fmt::Debug for sockaddr_dl { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("sockaddr_dl") + .field("sdl_family", &self.sdl_family) + .field("sdl_index", &self.sdl_index) + .field("sdl_type", &self.sdl_type) + .field("sdl_nlen", &self.sdl_nlen) + .field("sdl_alen", &self.sdl_alen) + .field("sdl_slen", &self.sdl_slen) + // FIXME: .field("sdl_data", &self.sdl_data) + .finish() + } + } + impl ::hash::Hash for sockaddr_dl { + fn hash(&self, state: &mut H) { + self.sdl_family.hash(state); + self.sdl_index.hash(state); + self.sdl_type.hash(state); + self.sdl_nlen.hash(state); + self.sdl_alen.hash(state); + self.sdl_slen.hash(state); + self.sdl_data.hash(state); + } + } + + 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.ss_sp == other.ss_sp + && self.sigev_notify_attributes + == other.sigev_notify_attributes + } + } + 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("ss_sp", &self.ss_sp) + .field("sigev_notify_attributes", + &self.sigev_notify_attributes) + .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.ss_sp.hash(state); + self.sigev_notify_attributes.hash(state); + } + } + + #[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 + } +} + +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_ALL: ::c_int = 6; +pub const LC_CTYPE_MASK: ::c_int = 1 << LC_CTYPE; +pub const LC_NUMERIC_MASK: ::c_int = 1 << LC_NUMERIC; +pub const LC_TIME_MASK: ::c_int = 1 << LC_TIME; +pub const LC_COLLATE_MASK: ::c_int = 1 << LC_COLLATE; +pub const LC_MONETARY_MASK: ::c_int = 1 << LC_MONETARY; +pub const LC_MESSAGES_MASK: ::c_int = 1 << LC_MESSAGES; +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; + +pub const DAY_1: ::nl_item = 1; +pub const DAY_2: ::nl_item = 2; +pub const DAY_3: ::nl_item = 3; +pub const DAY_4: ::nl_item = 4; +pub const DAY_5: ::nl_item = 5; +pub const DAY_6: ::nl_item = 6; +pub const DAY_7: ::nl_item = 7; + +pub const ABDAY_1: ::nl_item = 8; +pub const ABDAY_2: ::nl_item = 9; +pub const ABDAY_3: ::nl_item = 10; +pub const ABDAY_4: ::nl_item = 11; +pub const ABDAY_5: ::nl_item = 12; +pub const ABDAY_6: ::nl_item = 13; +pub const ABDAY_7: ::nl_item = 14; + +pub const MON_1: ::nl_item = 15; +pub const MON_2: ::nl_item = 16; +pub const MON_3: ::nl_item = 17; +pub const MON_4: ::nl_item = 18; +pub const MON_5: ::nl_item = 19; +pub const MON_6: ::nl_item = 20; +pub const MON_7: ::nl_item = 21; +pub const MON_8: ::nl_item = 22; +pub const MON_9: ::nl_item = 23; +pub const MON_10: ::nl_item = 24; +pub const MON_11: ::nl_item = 25; +pub const MON_12: ::nl_item = 26; + +pub const ABMON_1: ::nl_item = 27; +pub const ABMON_2: ::nl_item = 28; +pub const ABMON_3: ::nl_item = 29; +pub const ABMON_4: ::nl_item = 30; +pub const ABMON_5: ::nl_item = 31; +pub const ABMON_6: ::nl_item = 32; +pub const ABMON_7: ::nl_item = 33; +pub const ABMON_8: ::nl_item = 34; +pub const ABMON_9: ::nl_item = 35; +pub const ABMON_10: ::nl_item = 36; +pub const ABMON_11: ::nl_item = 37; +pub const ABMON_12: ::nl_item = 38; + +pub const RADIXCHAR: ::nl_item = 39; +pub const THOUSEP: ::nl_item = 40; +pub const YESSTR: ::nl_item = 41; +pub const NOSTR: ::nl_item = 42; +pub const CRNCYSTR: ::nl_item = 43; + +pub const D_T_FMT: ::nl_item = 44; +pub const D_FMT: ::nl_item = 45; +pub const T_FMT: ::nl_item = 46; +pub const AM_STR: ::nl_item = 47; +pub const PM_STR: ::nl_item = 48; + +pub const CODESET: ::nl_item = 49; +pub const T_FMT_AMPM: ::nl_item = 50; +pub const ERA: ::nl_item = 51; +pub const ERA_D_FMT: ::nl_item = 52; +pub const ERA_D_T_FMT: ::nl_item = 53; +pub const ERA_T_FMT: ::nl_item = 54; +pub const ALT_DIGITS: ::nl_item = 55; +pub const YESEXPR: ::nl_item = 56; +pub const NOEXPR: ::nl_item = 57; +pub const _DATE_FMT: ::nl_item = 58; +pub const MAXSTRMSG: ::nl_item = 58; + +pub const PATH_MAX: ::c_int = 1024; + +pub const SA_ONSTACK: ::c_int = 0x00000001; +pub const SA_RESETHAND: ::c_int = 0x00000002; +pub const SA_RESTART: ::c_int = 0x00000004; +pub const SA_SIGINFO: ::c_int = 0x00000008; +pub const SA_NODEFER: ::c_int = 0x00000010; +pub const SA_NOCLDWAIT: ::c_int = 0x00010000; +pub const SA_NOCLDSTOP: ::c_int = 0x00020000; + +pub const SS_ONSTACK: ::c_int = 1; +pub const SS_DISABLE: ::c_int = 2; + +pub const FIOCLEX: ::c_int = 0x20006601; +pub const FIONCLEX: ::c_int = 0x20006602; +pub const FIONREAD: ::c_int = 0x4004667f; +pub const FIONBIO: ::c_int = 0x8004667e; +pub const FIOASYNC: ::c_int = 0x8004667d; +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; +pub const SIG_UNBLOCK: ::c_int = 2; +pub const SIG_SETMASK: ::c_int = 3; + +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_PKTINFO: ::c_int = 0x1a; +pub const IP_DONTFRAG: ::c_int = 0x1b; +pub const IP_SEC_OPT: ::c_int = 0x22; + +pub const IPV6_UNICAST_HOPS: ::c_int = 0x5; +pub const IPV6_MULTICAST_IF: ::c_int = 0x6; +pub const IPV6_MULTICAST_HOPS: ::c_int = 0x7; +pub const IPV6_MULTICAST_LOOP: ::c_int = 0x8; +pub const IPV6_PKTINFO: ::c_int = 0xb; +pub const IPV6_RECVPKTINFO: ::c_int = 0x12; +pub const IPV6_RECVTCLASS: ::c_int = 0x19; +pub const IPV6_DONTFRAG: ::c_int = 0x21; +pub const IPV6_SEC_OPT: ::c_int = 0x22; +pub const IPV6_TCLASS: ::c_int = 0x26; +pub const IPV6_V6ONLY: ::c_int = 0x27; + +cfg_if! { + if #[cfg(target_pointer_width = "64")] { + pub const FD_SETSIZE: usize = 65536; + } else { + pub const FD_SETSIZE: usize = 1024; + } +} + +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; +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 SEEK_DATA: ::c_int = 3; +pub const SEEK_HOLE: ::c_int = 4; +pub const _IOFBF: ::c_int = 0; +pub const _IONBF: ::c_int = 4; +pub const _IOLBF: ::c_int = 64; +pub const BUFSIZ: ::c_uint = 1024; +pub const FOPEN_MAX: ::c_uint = 20; +pub const FILENAME_MAX: ::c_uint = 1024; +pub const L_tmpnam: ::c_uint = 25; +pub const TMP_MAX: ::c_uint = 17576; +pub const PIPE_BUF: ::c_int = 5120; + +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; +pub const O_NDELAY: ::c_int = 0x04; +pub const O_APPEND: ::c_int = 8; +pub const O_DSYNC: ::c_int = 0x40; +pub const O_RSYNC: ::c_int = 0x8000; +pub const O_CREAT: ::c_int = 256; +pub const O_EXCL: ::c_int = 1024; +pub const O_NOCTTY: ::c_int = 2048; +pub const O_TRUNC: ::c_int = 512; +pub const O_NOFOLLOW: ::c_int = 0x20000; +pub const O_SEARCH: ::c_int = 0x200000; +pub const O_EXEC: ::c_int = 0x400000; +pub const O_CLOEXEC: ::c_int = 0x800000; +pub const O_ACCMODE: ::c_int = 0x600003; +pub const O_XATTR: ::c_int = 0x4000; +pub const O_DIRECTORY: ::c_int = 0x1000000; +pub const O_DIRECT: ::c_int = 0x2000000; +pub const S_IFIFO: mode_t = 4096; +pub const S_IFCHR: mode_t = 8192; +pub const S_IFBLK: mode_t = 24576; +pub const S_IFDIR: mode_t = 16384; +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 = 61440; +pub const S_IEXEC: mode_t = 64; +pub const S_IWRITE: mode_t = 128; +pub const S_IREAD: mode_t = 256; +pub const S_IRWXU: mode_t = 448; +pub const S_IXUSR: mode_t = 64; +pub const S_IWUSR: mode_t = 128; +pub const S_IRUSR: mode_t = 256; +pub const S_IRWXG: mode_t = 56; +pub const S_IXGRP: mode_t = 8; +pub const S_IWGRP: mode_t = 16; +pub const S_IRGRP: mode_t = 32; +pub const S_IRWXO: mode_t = 7; +pub const S_IXOTH: mode_t = 1; +pub const S_IWOTH: mode_t = 2; +pub const S_IROTH: mode_t = 4; +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; +pub const STDIN_FILENO: ::c_int = 0; +pub const STDOUT_FILENO: ::c_int = 1; +pub const STDERR_FILENO: ::c_int = 2; +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_SETLK: ::c_int = 6; +pub const F_SETLKW: ::c_int = 7; +pub const F_GETLK: ::c_int = 14; +pub const F_ALLOCSP: ::c_int = 10; +pub const F_FREESP: ::c_int = 11; +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; +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 = 16; +pub const SIGUSR2: ::c_int = 17; +pub const SIGPWR: ::c_int = 19; +pub const SIGWINCH: ::c_int = 20; +pub const SIGURG: ::c_int = 21; +pub const SIGPOLL: ::c_int = 22; +pub const SIGIO: ::c_int = SIGPOLL; +pub const SIGSTOP: ::c_int = 23; +pub const SIGTSTP: ::c_int = 24; +pub const SIGCONT: ::c_int = 25; +pub const SIGTTIN: ::c_int = 26; +pub const SIGTTOU: ::c_int = 27; +pub const SIGVTALRM: ::c_int = 28; +pub const SIGPROF: ::c_int = 29; +pub const SIGXCPU: ::c_int = 30; +pub const SIGXFSZ: ::c_int = 31; + +pub const WNOHANG: ::c_int = 0x40; +pub const WUNTRACED: ::c_int = 0x04; + +pub const WEXITED: ::c_int = 0x01; +pub const WTRAPPED: ::c_int = 0x02; +pub const WSTOPPED: ::c_int = WUNTRACED; +pub const WCONTINUED: ::c_int = 0x08; +pub const WNOWAIT: ::c_int = 0x80; + +pub const AT_FDCWD: ::c_int = 0xffd19553; +pub const AT_SYMLINK_NOFOLLOW: ::c_int = 0x1000; +pub const AT_SYMLINK_FOLLOW: ::c_int = 0x2000; +pub const AT_REMOVEDIR: ::c_int = 0x1; +pub const _AT_TRIGGER: ::c_int = 0x2; +pub const AT_EACCESS: ::c_int = 0x4; + +pub const P_PID: idtype_t = 0; +pub const P_PPID: idtype_t = 1; +pub const P_PGID: idtype_t = 2; +pub const P_SID: idtype_t = 3; +pub const P_CID: idtype_t = 4; +pub const P_UID: idtype_t = 5; +pub const P_GID: idtype_t = 6; +pub const P_ALL: idtype_t = 7; +pub const P_LWPID: idtype_t = 8; +pub const P_TASKID: idtype_t = 9; +pub const P_PROJID: idtype_t = 10; +pub const P_POOLID: idtype_t = 11; +pub const P_ZONEID: idtype_t = 12; +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; + +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 = 0x0001; +pub const MAP_PRIVATE: ::c_int = 0x0002; +pub const MAP_FIXED: ::c_int = 0x0010; +pub const MAP_NORESERVE: ::c_int = 0x40; +pub const MAP_ANON: ::c_int = 0x0100; +pub const MAP_ANONYMOUS: ::c_int = 0x0100; +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; +pub const MCL_FUTURE: ::c_int = 0x0002; + +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; +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 ENOTSUP: ::c_int = 48; +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 ENOTRECOVERABLE: ::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 ELOCKUNMAPPED: ::c_int = 72; +pub const ENOTACTIVE: ::c_int = 73; +pub const EMULTIHOP: ::c_int = 74; +pub const EADI: ::c_int = 75; +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 ENOTSOCK: ::c_int = 95; +pub const EDESTADDRREQ: ::c_int = 96; +pub const EMSGSIZE: ::c_int = 97; +pub const EPROTOTYPE: ::c_int = 98; +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 EPFNOSUPPORT: ::c_int = 123; +pub const EAFNOSUPPORT: ::c_int = 124; +pub const EADDRINUSE: ::c_int = 125; +pub const EADDRNOTAVAIL: ::c_int = 126; +pub const ENETDOWN: ::c_int = 127; +pub const ENETUNREACH: ::c_int = 128; +pub const ENETRESET: ::c_int = 129; +pub const ECONNABORTED: ::c_int = 130; +pub const ECONNRESET: ::c_int = 131; +pub const ENOBUFS: ::c_int = 132; +pub const EISCONN: ::c_int = 133; +pub const ENOTCONN: ::c_int = 134; +pub const ESHUTDOWN: ::c_int = 143; +pub const ETOOMANYREFS: ::c_int = 144; +pub const ETIMEDOUT: ::c_int = 145; +pub const ECONNREFUSED: ::c_int = 146; +pub const EHOSTDOWN: ::c_int = 147; +pub const EHOSTUNREACH: ::c_int = 148; +pub const EWOULDBLOCK: ::c_int = EAGAIN; +pub const EALREADY: ::c_int = 149; +pub const EINPROGRESS: ::c_int = 150; +pub const ESTALE: ::c_int = 151; + +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 = 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_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_GETXFL: ::c_int = 45; + +pub const SIGTRAP: ::c_int = 5; + +pub const GLOB_APPEND: ::c_int = 32; +pub const GLOB_DOOFFS: ::c_int = 16; +pub const GLOB_ERR: ::c_int = 1; +pub const GLOB_MARK: ::c_int = 2; +pub const GLOB_NOCHECK: ::c_int = 8; +pub const GLOB_NOSORT: ::c_int = 4; +pub const GLOB_NOESCAPE: ::c_int = 64; + +pub const GLOB_NOSPACE: ::c_int = -2; +pub const GLOB_ABORTED: ::c_int = -1; +pub const GLOB_NOMATCH: ::c_int = -3; + +pub const POLLIN: ::c_short = 0x1; +pub const POLLPRI: ::c_short = 0x2; +pub const POLLOUT: ::c_short = 0x4; +pub const POLLERR: ::c_short = 0x8; +pub const POLLHUP: ::c_short = 0x10; +pub const POLLNVAL: ::c_short = 0x20; +pub const POLLNORM: ::c_short = 0x0040; +pub const POLLRDNORM: ::c_short = 0x0040; +pub const POLLWRNORM: ::c_short = 0x4; /* POLLOUT */ +pub const POLLRDBAND: ::c_short = 0x0080; +pub const POLLWRBAND: ::c_short = 0x0100; + +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_MADV_DONTNEED: ::c_int = 4; + +pub const PTHREAD_CREATE_JOINABLE: ::c_int = 0; +pub const PTHREAD_CREATE_DETACHED: ::c_int = 0x40; +pub const PTHREAD_PROCESS_SHARED: ::c_int = 1; +pub const PTHREAD_PROCESS_PRIVATE: ::c_ushort = 0; +pub const PTHREAD_STACK_MIN: ::size_t = 4096; + +pub const SIGSTKSZ: ::size_t = 8192; + +// https://illumos.org/man/3c/clock_gettime +// https://github.com/illumos/illumos-gate/ +// blob/HEAD/usr/src/lib/libc/amd64/sys/__clock_gettime.s +// clock_gettime(3c) doesn't seem to accept anything other than CLOCK_REALTIME +// or __CLOCK_REALTIME0 +// +// https://github.com/illumos/illumos-gate/ +// blob/HEAD/usr/src/uts/common/sys/time_impl.h +// Confusing! CLOCK_HIGHRES==CLOCK_MONOTONIC==4 +// __CLOCK_REALTIME0==0 is an obsoleted version of CLOCK_REALTIME==3 +pub const CLOCK_REALTIME: ::clockid_t = 3; +pub const CLOCK_MONOTONIC: ::clockid_t = 4; +pub const TIMER_RELTIME: ::c_int = 0; +pub const TIMER_ABSTIME: ::c_int = 1; + +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_VMEM: ::c_int = 6; +pub const RLIMIT_AS: ::c_int = RLIMIT_VMEM; + +#[deprecated(since = "0.2.64", note = "Not stable across OS versions")] +pub const RLIM_NLIMITS: rlim_t = 7; +pub const RLIM_INFINITY: rlim_t = 0xfffffffffffffffd; + +pub const RUSAGE_SELF: ::c_int = 0; +pub const RUSAGE_CHILDREN: ::c_int = -1; + +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 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; +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_NBS: ::c_int = 7; +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 AF_HYLINK: ::c_int = 15; +pub const AF_APPLETALK: ::c_int = 16; +pub const AF_NIT: ::c_int = 17; +pub const AF_802: ::c_int = 18; +pub const AF_OSI: ::c_int = 19; +pub const AF_X25: ::c_int = 20; +pub const AF_OSINET: ::c_int = 21; +pub const AF_GOSIP: ::c_int = 22; +pub const AF_IPX: ::c_int = 23; +pub const AF_ROUTE: ::c_int = 24; +pub const AF_LINK: ::c_int = 25; +pub const AF_INET6: ::c_int = 26; +pub const AF_KEY: ::c_int = 27; +pub const AF_NCA: ::c_int = 28; +pub const AF_POLICY: ::c_int = 29; +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; +pub const SOCK_RDM: ::c_int = 5; +pub const SOCK_SEQPACKET: ::c_int = 6; +pub const IP_MULTICAST_IF: ::c_int = 16; +pub const IP_MULTICAST_TTL: ::c_int = 17; +pub const IP_MULTICAST_LOOP: ::c_int = 18; +pub const IP_HDRINCL: ::c_int = 2; +pub const IP_TOS: ::c_int = 3; +pub const IP_TTL: ::c_int = 4; +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: +pub const TCP_NODELAY: ::c_int = 0x1; +pub const TCP_MAXSEG: ::c_int = 0x2; +pub const TCP_KEEPALIVE: ::c_int = 0x8; +pub const TCP_NOTIFY_THRESHOLD: ::c_int = 0x10; +pub const TCP_ABORT_THRESHOLD: ::c_int = 0x11; +pub const TCP_CONN_NOTIFY_THRESHOLD: ::c_int = 0x12; +pub const TCP_CONN_ABORT_THRESHOLD: ::c_int = 0x13; +pub const TCP_RECVDSTADDR: ::c_int = 0x14; +pub const TCP_INIT_CWND: ::c_int = 0x15; +pub const TCP_KEEPALIVE_THRESHOLD: ::c_int = 0x16; +pub const TCP_KEEPALIVE_ABORT_THRESHOLD: ::c_int = 0x17; +pub const TCP_CORK: ::c_int = 0x18; +pub const TCP_RTO_INITIAL: ::c_int = 0x19; +pub const TCP_RTO_MIN: ::c_int = 0x1a; +pub const TCP_RTO_MAX: ::c_int = 0x1b; +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; +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_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 SO_PROTOTYPE: ::c_int = 0x1009; +pub const SO_DOMAIN: ::c_int = 0x100c; +pub const SO_TIMESTAMP: ::c_int = 0x1013; +pub const SO_EXCLBIND: ::c_int = 0x1015; + +pub const SCM_RIGHTS: ::c_int = 0x1010; +pub const SCM_UCRED: ::c_int = 0x1012; +pub const SCM_TIMESTAMP: ::c_int = SO_TIMESTAMP; + +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_CTRUNC: ::c_int = 0x10; +pub const MSG_TRUNC: ::c_int = 0x20; +pub const MSG_WAITALL: ::c_int = 0x40; +pub const MSG_DONTWAIT: ::c_int = 0x80; +pub const MSG_NOTIFICATION: ::c_int = 0x100; +pub const MSG_NOSIGNAL: ::c_int = 0x200; +pub const MSG_DUPCTRL: ::c_int = 0x800; +pub const MSG_XPG4_2: ::c_int = 0x8000; +pub const MSG_MAXIOVLEN: ::c_int = 16; + +pub const IF_NAMESIZE: ::size_t = 32; +pub const IFNAMSIZ: ::size_t = 16; + +// https://docs.oracle.com/cd/E23824_01/html/821-1475/if-7p.html +pub const IFF_UP: ::c_int = 0x0000000001; // Address is up +pub const IFF_BROADCAST: ::c_int = 0x0000000002; // Broadcast address valid +pub const IFF_DEBUG: ::c_int = 0x0000000004; // Turn on debugging +pub const IFF_LOOPBACK: ::c_int = 0x0000000008; // Loopback net +pub const IFF_POINTOPOINT: ::c_int = 0x0000000010; // Interface is p-to-p +pub const IFF_NOTRAILERS: ::c_int = 0x0000000020; // Avoid use of trailers +pub const IFF_RUNNING: ::c_int = 0x0000000040; // Resources allocated +pub const IFF_NOARP: ::c_int = 0x0000000080; // No address res. protocol +pub const IFF_PROMISC: ::c_int = 0x0000000100; // Receive all packets +pub const IFF_ALLMULTI: ::c_int = 0x0000000200; // Receive all multicast pkts +pub const IFF_INTELLIGENT: ::c_int = 0x0000000400; // Protocol code on board +pub const IFF_MULTICAST: ::c_int = 0x0000000800; // Supports multicast + +// Multicast using broadcst. add. +pub const IFF_MULTI_BCAST: ::c_int = 0x0000001000; +pub const IFF_UNNUMBERED: ::c_int = 0x0000002000; // Non-unique address +pub const IFF_DHCPRUNNING: ::c_int = 0x0000004000; // DHCP controls interface +pub const IFF_PRIVATE: ::c_int = 0x0000008000; // Do not advertise +pub const IFF_NOXMIT: ::c_int = 0x0000010000; // Do not transmit pkts + +// No address - just on-link subnet +pub const IFF_NOLOCAL: ::c_int = 0x0000020000; +pub const IFF_DEPRECATED: ::c_int = 0x0000040000; // Address is deprecated +pub const IFF_ADDRCONF: ::c_int = 0x0000080000; // Addr. from stateless addrconf +pub const IFF_ROUTER: ::c_int = 0x0000100000; // Router on interface +pub const IFF_NONUD: ::c_int = 0x0000200000; // No NUD on interface +pub const IFF_ANYCAST: ::c_int = 0x0000400000; // Anycast address +pub const IFF_NORTEXCH: ::c_int = 0x0000800000; // Don't xchange rout. info +pub const IFF_IPV4: ::c_int = 0x0001000000; // IPv4 interface +pub const IFF_IPV6: ::c_int = 0x0002000000; // IPv6 interface +pub const IFF_NOFAILOVER: ::c_int = 0x0008000000; // in.mpathd test address +pub const IFF_FAILED: ::c_int = 0x0010000000; // Interface has failed +pub const IFF_STANDBY: ::c_int = 0x0020000000; // Interface is a hot-spare +pub const IFF_INACTIVE: ::c_int = 0x0040000000; // Functioning but not used +pub const IFF_OFFLINE: ::c_int = 0x0080000000; // Interface is offline + // If CoS marking is supported +pub const IFF_COS_ENABLED: ::c_longlong = 0x0200000000; +pub const IFF_PREFERRED: ::c_longlong = 0x0400000000; // Prefer as source addr. +pub const IFF_TEMPORARY: ::c_longlong = 0x0800000000; // RFC3041 +pub const IFF_FIXEDMTU: ::c_longlong = 0x1000000000; // MTU set with SIOCSLIFMTU +pub const IFF_VIRTUAL: ::c_longlong = 0x2000000000; // Cannot send/receive pkts +pub const IFF_DUPLICATE: ::c_longlong = 0x4000000000; // Local address in use +pub const IFF_IPMP: ::c_longlong = 0x8000000000; // IPMP IP interface + +// sys/ipc.h: +pub const IPC_ALLOC: ::c_int = 0x8000; +pub const IPC_CREAT: ::c_int = 0x200; +pub const IPC_EXCL: ::c_int = 0x400; +pub const IPC_NOWAIT: ::c_int = 0x800; +pub const IPC_PRIVATE: key_t = 0; +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; + +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; + +pub const F_RDLCK: ::c_short = 1; +pub const F_WRLCK: ::c_short = 2; +pub const F_UNLCK: ::c_short = 3; + +pub const O_SYNC: ::c_int = 16; +pub const O_NONBLOCK: ::c_int = 128; + +pub const IPPROTO_RAW: ::c_int = 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_NO_TRUNC: ::c_int = 7; +pub const _PC_VDISABLE: ::c_int = 8; +pub const _PC_CHOWN_RESTRICTED: ::c_int = 9; +pub const _PC_ASYNC_IO: ::c_int = 10; +pub const _PC_PRIO_IO: ::c_int = 11; +pub const _PC_SYNC_IO: ::c_int = 12; +pub const _PC_ALLOC_SIZE_MIN: ::c_int = 13; +pub const _PC_REC_INCR_XFER_SIZE: ::c_int = 14; +pub const _PC_REC_MAX_XFER_SIZE: ::c_int = 15; +pub const _PC_REC_MIN_XFER_SIZE: ::c_int = 16; +pub const _PC_REC_XFER_ALIGN: ::c_int = 17; +pub const _PC_SYMLINK_MAX: ::c_int = 18; +pub const _PC_2_SYMLINKS: ::c_int = 19; +pub const _PC_ACL_ENABLED: ::c_int = 20; +pub const _PC_MIN_HOLE_SIZE: ::c_int = 21; +pub const _PC_CASE_BEHAVIOR: ::c_int = 22; +pub const _PC_SATTR_ENABLED: ::c_int = 23; +pub const _PC_SATTR_EXISTS: ::c_int = 24; +pub const _PC_ACCESS_FILTERING: ::c_int = 25; +pub const _PC_TIMESTAMP_RESOLUTION: ::c_int = 26; +pub const _PC_FILESIZEBITS: ::c_int = 67; +pub const _PC_XATTR_ENABLED: ::c_int = 100; +pub const _PC_LAST: ::c_int = 101; +pub const _PC_XATTR_EXISTS: ::c_int = 101; + +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_LOGNAME_MAX: ::c_int = 10; +pub const _SC_PAGESIZE: ::c_int = 11; +pub const _SC_PAGE_SIZE: ::c_int = _SC_PAGESIZE; +pub const _SC_XOPEN_VERSION: ::c_int = 12; +pub const _SC_NPROCESSORS_CONF: ::c_int = 14; +pub const _SC_NPROCESSORS_ONLN: ::c_int = 15; +pub const _SC_STREAM_MAX: ::c_int = 16; +pub const _SC_TZNAME_MAX: ::c_int = 17; +pub const _SC_AIO_LISTIO_MAX: ::c_int = 18; +pub const _SC_AIO_MAX: ::c_int = 19; +pub const _SC_AIO_PRIO_DELTA_MAX: ::c_int = 20; +pub const _SC_ASYNCHRONOUS_IO: ::c_int = 21; +pub const _SC_DELAYTIMER_MAX: ::c_int = 22; +pub const _SC_FSYNC: ::c_int = 23; +pub const _SC_MAPPED_FILES: ::c_int = 24; +pub const _SC_MEMLOCK: ::c_int = 25; +pub const _SC_MEMLOCK_RANGE: ::c_int = 26; +pub const _SC_MEMORY_PROTECTION: ::c_int = 27; +pub const _SC_MESSAGE_PASSING: ::c_int = 28; +pub const _SC_MQ_OPEN_MAX: ::c_int = 29; +pub const _SC_MQ_PRIO_MAX: ::c_int = 30; +pub const _SC_PRIORITIZED_IO: ::c_int = 31; +pub const _SC_PRIORITY_SCHEDULING: ::c_int = 32; +pub const _SC_REALTIME_SIGNALS: ::c_int = 33; +pub const _SC_RTSIG_MAX: ::c_int = 34; +pub const _SC_SEMAPHORES: ::c_int = 35; +pub const _SC_SEM_NSEMS_MAX: ::c_int = 36; +pub const _SC_SEM_VALUE_MAX: ::c_int = 37; +pub const _SC_SHARED_MEMORY_OBJECTS: ::c_int = 38; +pub const _SC_SIGQUEUE_MAX: ::c_int = 39; +pub const _SC_SIGRT_MIN: ::c_int = 40; +pub const _SC_SIGRT_MAX: ::c_int = 41; +pub const _SC_SYNCHRONIZED_IO: ::c_int = 42; +pub const _SC_TIMERS: ::c_int = 43; +pub const _SC_TIMER_MAX: ::c_int = 44; +pub const _SC_2_C_BIND: ::c_int = 45; +pub const _SC_2_C_DEV: ::c_int = 46; +pub const _SC_2_C_VERSION: ::c_int = 47; +pub const _SC_2_FORT_DEV: ::c_int = 48; +pub const _SC_2_FORT_RUN: ::c_int = 49; +pub const _SC_2_LOCALEDEF: ::c_int = 50; +pub const _SC_2_SW_DEV: ::c_int = 51; +pub const _SC_2_UPE: ::c_int = 52; +pub const _SC_2_VERSION: ::c_int = 53; +pub const _SC_BC_BASE_MAX: ::c_int = 54; +pub const _SC_BC_DIM_MAX: ::c_int = 55; +pub const _SC_BC_SCALE_MAX: ::c_int = 56; +pub const _SC_BC_STRING_MAX: ::c_int = 57; +pub const _SC_COLL_WEIGHTS_MAX: ::c_int = 58; +pub const _SC_EXPR_NEST_MAX: ::c_int = 59; +pub const _SC_LINE_MAX: ::c_int = 60; +pub const _SC_RE_DUP_MAX: ::c_int = 61; +pub const _SC_XOPEN_CRYPT: ::c_int = 62; +pub const _SC_XOPEN_ENH_I18N: ::c_int = 63; +pub const _SC_XOPEN_SHM: ::c_int = 64; +pub const _SC_2_CHAR_TERM: ::c_int = 66; +pub const _SC_XOPEN_XCU_VERSION: ::c_int = 67; +pub const _SC_ATEXIT_MAX: ::c_int = 76; +pub const _SC_IOV_MAX: ::c_int = 77; +pub const _SC_XOPEN_UNIX: ::c_int = 78; +pub const _SC_T_IOV_MAX: ::c_int = 79; +pub const _SC_PHYS_PAGES: ::c_int = 500; +pub const _SC_AVPHYS_PAGES: ::c_int = 501; +pub const _SC_COHER_BLKSZ: ::c_int = 503; +pub const _SC_SPLIT_CACHE: ::c_int = 504; +pub const _SC_ICACHE_SZ: ::c_int = 505; +pub const _SC_DCACHE_SZ: ::c_int = 506; +pub const _SC_ICACHE_LINESZ: ::c_int = 507; +pub const _SC_DCACHE_LINESZ: ::c_int = 508; +pub const _SC_ICACHE_BLKSZ: ::c_int = 509; +pub const _SC_DCACHE_BLKSZ: ::c_int = 510; +pub const _SC_DCACHE_TBLKSZ: ::c_int = 511; +pub const _SC_ICACHE_ASSOC: ::c_int = 512; +pub const _SC_DCACHE_ASSOC: ::c_int = 513; +pub const _SC_MAXPID: ::c_int = 514; +pub const _SC_STACK_PROT: ::c_int = 515; +pub const _SC_NPROCESSORS_MAX: ::c_int = 516; +pub const _SC_CPUID_MAX: ::c_int = 517; +pub const _SC_EPHID_MAX: ::c_int = 518; +pub const _SC_THREAD_DESTRUCTOR_ITERATIONS: ::c_int = 568; +pub const _SC_GETGR_R_SIZE_MAX: ::c_int = 569; +pub const _SC_GETPW_R_SIZE_MAX: ::c_int = 570; +pub const _SC_LOGIN_NAME_MAX: ::c_int = 571; +pub const _SC_THREAD_KEYS_MAX: ::c_int = 572; +pub const _SC_THREAD_STACK_MIN: ::c_int = 573; +pub const _SC_THREAD_THREADS_MAX: ::c_int = 574; +pub const _SC_TTY_NAME_MAX: ::c_int = 575; +pub const _SC_THREADS: ::c_int = 576; +pub const _SC_THREAD_ATTR_STACKADDR: ::c_int = 577; +pub const _SC_THREAD_ATTR_STACKSIZE: ::c_int = 578; +pub const _SC_THREAD_PRIORITY_SCHEDULING: ::c_int = 579; +pub const _SC_THREAD_PRIO_INHERIT: ::c_int = 580; +pub const _SC_THREAD_PRIO_PROTECT: ::c_int = 581; +pub const _SC_THREAD_PROCESS_SHARED: ::c_int = 582; +pub const _SC_THREAD_SAFE_FUNCTIONS: ::c_int = 583; +pub const _SC_XOPEN_LEGACY: ::c_int = 717; +pub const _SC_XOPEN_REALTIME: ::c_int = 718; +pub const _SC_XOPEN_REALTIME_THREADS: ::c_int = 719; +pub const _SC_XBS5_ILP32_OFF32: ::c_int = 720; +pub const _SC_XBS5_ILP32_OFFBIG: ::c_int = 721; +pub const _SC_XBS5_LP64_OFF64: ::c_int = 722; +pub const _SC_XBS5_LPBIG_OFFBIG: ::c_int = 723; +pub const _SC_2_PBS: ::c_int = 724; +pub const _SC_2_PBS_ACCOUNTING: ::c_int = 725; +pub const _SC_2_PBS_CHECKPOINT: ::c_int = 726; +pub const _SC_2_PBS_LOCATE: ::c_int = 728; +pub const _SC_2_PBS_MESSAGE: ::c_int = 729; +pub const _SC_2_PBS_TRACK: ::c_int = 730; +pub const _SC_ADVISORY_INFO: ::c_int = 731; +pub const _SC_BARRIERS: ::c_int = 732; +pub const _SC_CLOCK_SELECTION: ::c_int = 733; +pub const _SC_CPUTIME: ::c_int = 734; +pub const _SC_HOST_NAME_MAX: ::c_int = 735; +pub const _SC_MONOTONIC_CLOCK: ::c_int = 736; +pub const _SC_READER_WRITER_LOCKS: ::c_int = 737; +pub const _SC_REGEXP: ::c_int = 738; +pub const _SC_SHELL: ::c_int = 739; +pub const _SC_SPAWN: ::c_int = 740; +pub const _SC_SPIN_LOCKS: ::c_int = 741; +pub const _SC_SPORADIC_SERVER: ::c_int = 742; +pub const _SC_SS_REPL_MAX: ::c_int = 743; +pub const _SC_SYMLOOP_MAX: ::c_int = 744; +pub const _SC_THREAD_CPUTIME: ::c_int = 745; +pub const _SC_THREAD_SPORADIC_SERVER: ::c_int = 746; +pub const _SC_TIMEOUTS: ::c_int = 747; +pub const _SC_TRACE: ::c_int = 748; +pub const _SC_TRACE_EVENT_FILTER: ::c_int = 749; +pub const _SC_TRACE_EVENT_NAME_MAX: ::c_int = 750; +pub const _SC_TRACE_INHERIT: ::c_int = 751; +pub const _SC_TRACE_LOG: ::c_int = 752; +pub const _SC_TRACE_NAME_MAX: ::c_int = 753; +pub const _SC_TRACE_SYS_MAX: ::c_int = 754; +pub const _SC_TRACE_USER_EVENT_MAX: ::c_int = 755; +pub const _SC_TYPED_MEMORY_OBJECTS: ::c_int = 756; +pub const _SC_V6_ILP32_OFF32: ::c_int = 757; +pub const _SC_V6_ILP32_OFFBIG: ::c_int = 758; +pub const _SC_V6_LP64_OFF64: ::c_int = 759; +pub const _SC_V6_LPBIG_OFFBIG: ::c_int = 760; +pub const _SC_XOPEN_STREAMS: ::c_int = 761; +pub const _SC_IPV6: ::c_int = 762; +pub const _SC_RAW_SOCKETS: ::c_int = 763; + +pub const _MUTEX_MAGIC: u16 = 0x4d58; // MX +pub const _COND_MAGIC: u16 = 0x4356; // CV +pub const _RWL_MAGIC: u16 = 0x5257; // RW + +pub const NCCS: usize = 19; + +pub const LOG_CRON: ::c_int = 15 << 3; + +pub const PTHREAD_MUTEX_INITIALIZER: pthread_mutex_t = pthread_mutex_t { + __pthread_mutex_flag1: 0, + __pthread_mutex_flag2: 0, + __pthread_mutex_ceiling: 0, + __pthread_mutex_type: PTHREAD_PROCESS_PRIVATE, + __pthread_mutex_magic: _MUTEX_MAGIC, + __pthread_mutex_lock: 0, + __pthread_mutex_data: 0, +}; +pub const PTHREAD_COND_INITIALIZER: pthread_cond_t = pthread_cond_t { + __pthread_cond_flag: [0; 4], + __pthread_cond_type: PTHREAD_PROCESS_PRIVATE, + __pthread_cond_magic: _COND_MAGIC, + __pthread_cond_data: 0, +}; +pub const PTHREAD_RWLOCK_INITIALIZER: pthread_rwlock_t = pthread_rwlock_t { + __pthread_rwlock_readers: 0, + __pthread_rwlock_type: PTHREAD_PROCESS_PRIVATE, + __pthread_rwlock_magic: _RWL_MAGIC, + __pthread_rwlock_mutex: PTHREAD_MUTEX_INITIALIZER, + __pthread_rwlock_readercv: PTHREAD_COND_INITIALIZER, + __pthread_rwlock_writercv: PTHREAD_COND_INITIALIZER, +}; +pub const PTHREAD_MUTEX_NORMAL: ::c_int = 0; +pub const PTHREAD_MUTEX_ERRORCHECK: ::c_int = 2; +pub const PTHREAD_MUTEX_RECURSIVE: ::c_int = 4; +pub const PTHREAD_MUTEX_DEFAULT: ::c_int = ::PTHREAD_MUTEX_NORMAL; + +pub const RTLD_NEXT: *mut ::c_void = -1isize as *mut ::c_void; +pub const RTLD_DEFAULT: *mut ::c_void = -2isize as *mut ::c_void; +pub const RTLD_SELF: *mut ::c_void = -3isize as *mut ::c_void; +pub const RTLD_PROBE: *mut ::c_void = -4isize as *mut ::c_void; + +pub const RTLD_LAZY: ::c_int = 0x1; +pub const RTLD_NOW: ::c_int = 0x2; +pub const RTLD_NOLOAD: ::c_int = 0x4; +pub const RTLD_GLOBAL: ::c_int = 0x100; +pub const RTLD_LOCAL: ::c_int = 0x0; +pub const RTLD_PARENT: ::c_int = 0x200; +pub const RTLD_GROUP: ::c_int = 0x400; +pub const RTLD_WORLD: ::c_int = 0x800; +pub const RTLD_NODELETE: ::c_int = 0x1000; +pub const RTLD_FIRST: ::c_int = 0x2000; +pub const RTLD_CONFGEN: ::c_int = 0x10000; + +pub const PORT_SOURCE_AIO: ::c_int = 1; +pub const PORT_SOURCE_TIMER: ::c_int = 2; +pub const PORT_SOURCE_USER: ::c_int = 3; +pub const PORT_SOURCE_FD: ::c_int = 4; +pub const PORT_SOURCE_ALERT: ::c_int = 5; +pub const PORT_SOURCE_MQ: ::c_int = 6; +pub const PORT_SOURCE_FILE: ::c_int = 7; + +pub const NONROOT_USR: ::c_short = 2; +pub const _UTX_USERSIZE: usize = 32; +pub const _UTX_LINESIZE: usize = 32; +pub const _UTX_PADSIZE: usize = 5; +pub const _UTX_IDSIZE: usize = 4; +pub const _UTX_HOSTSIZE: usize = 257; +pub const EMPTY: ::c_short = 0; +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; +pub const DOWN_TIME: ::c_short = 10; + +const _TIOC: ::c_int = ('T' as i32) << 8; +const tIOC: ::c_int = ('t' as i32) << 8; +pub const TCGETA: ::c_int = _TIOC | 1; +pub const TCSETA: ::c_int = _TIOC | 2; +pub const TCSETAW: ::c_int = _TIOC | 3; +pub const TCSETAF: ::c_int = _TIOC | 4; +pub const TCSBRK: ::c_int = _TIOC | 5; +pub const TCXONC: ::c_int = _TIOC | 6; +pub const TCFLSH: ::c_int = _TIOC | 7; +pub const TCDSET: ::c_int = _TIOC | 32; +pub const TCGETS: ::c_int = _TIOC | 13; +pub const TCSETS: ::c_int = _TIOC | 14; +pub const TCSANOW: ::c_int = _TIOC | 14; +pub const TCSETSW: ::c_int = _TIOC | 15; +pub const TCSADRAIN: ::c_int = _TIOC | 15; +pub const TCSETSF: ::c_int = _TIOC | 16; +pub const TCSAFLUSH: ::c_int = _TIOC | 16; +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 = _TIOC; +pub const TIOCKBON: ::c_int = _TIOC | 8; +pub const TIOCKBOF: ::c_int = _TIOC | 9; +pub const TIOCGWINSZ: ::c_int = _TIOC | 104; +pub const TIOCSWINSZ: ::c_int = _TIOC | 103; +pub const TIOCGSOFTCAR: ::c_int = _TIOC | 105; +pub const TIOCSSOFTCAR: ::c_int = _TIOC | 106; +pub const TIOCGPPS: ::c_int = _TIOC | 125; +pub const TIOCSPPS: ::c_int = _TIOC | 126; +pub const TIOCGPPSEV: ::c_int = _TIOC | 127; +pub const TIOCGETD: ::c_int = tIOC | 0; +pub const TIOCSETD: ::c_int = tIOC | 1; +pub const TIOCHPCL: ::c_int = tIOC | 2; +pub const TIOCGETP: ::c_int = tIOC | 8; +pub const TIOCSETP: ::c_int = tIOC | 9; +pub const TIOCSETN: ::c_int = tIOC | 10; +pub const TIOCEXCL: ::c_int = tIOC | 13; +pub const TIOCNXCL: ::c_int = tIOC | 14; +pub const TIOCFLUSH: ::c_int = tIOC | 16; +pub const TIOCSETC: ::c_int = tIOC | 17; +pub const TIOCGETC: ::c_int = tIOC | 18; +pub const TIOCLBIS: ::c_int = tIOC | 127; +pub const TIOCLBIC: ::c_int = tIOC | 126; +pub const TIOCLSET: ::c_int = tIOC | 125; +pub const TIOCLGET: ::c_int = tIOC | 124; +pub const TIOCSBRK: ::c_int = tIOC | 123; +pub const TIOCCBRK: ::c_int = tIOC | 122; +pub const TIOCSDTR: ::c_int = tIOC | 121; +pub const TIOCCDTR: ::c_int = tIOC | 120; +pub const TIOCSLTC: ::c_int = tIOC | 117; +pub const TIOCGLTC: ::c_int = tIOC | 116; +pub const TIOCOUTQ: ::c_int = tIOC | 115; +pub const TIOCNOTTY: ::c_int = tIOC | 113; +pub const TIOCSCTTY: ::c_int = tIOC | 132; +pub const TIOCSTOP: ::c_int = tIOC | 111; +pub const TIOCSTART: ::c_int = tIOC | 110; +pub const TIOCSILOOP: ::c_int = tIOC | 109; +pub const TIOCCILOOP: ::c_int = tIOC | 108; +pub const TIOCGPGRP: ::c_int = tIOC | 20; +pub const TIOCSPGRP: ::c_int = tIOC | 21; +pub const TIOCGSID: ::c_int = tIOC | 22; +pub const TIOCSTI: ::c_int = tIOC | 23; +pub const TIOCMSET: ::c_int = tIOC | 26; +pub const TIOCMBIS: ::c_int = tIOC | 27; +pub const TIOCMBIC: ::c_int = tIOC | 28; +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; +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 EPOLLET: ::c_int = 0x80000000; +pub const EPOLLRDHUP: ::c_int = 0x2000; +pub const EPOLLONESHOT: ::c_int = 0x40000000; +pub const EPOLLWAKEUP: ::c_int = 0x20000000; +pub const EPOLLEXCLUSIVE: ::c_int = 0x10000000; +pub const EPOLL_CLOEXEC: ::c_int = 0x80000; +pub const EPOLL_CTL_ADD: ::c_int = 1; +pub const EPOLL_CTL_MOD: ::c_int = 3; +pub const EPOLL_CTL_DEL: ::c_int = 2; + +/* termios */ +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 B57600: speed_t = 16; +pub const B76800: speed_t = 17; +pub const B115200: speed_t = 18; +pub const B153600: speed_t = 19; +pub const B230400: speed_t = 20; +pub const B307200: speed_t = 21; +pub const B460800: speed_t = 22; +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; +pub const CS7: ::tcflag_t = 0o000040; +pub const CS8: ::tcflag_t = 0o000060; +pub const CSTOPB: ::tcflag_t = 0o000100; +pub const ECHO: ::tcflag_t = 0o000010; +pub const ECHOE: ::tcflag_t = 0o000020; +pub const ECHOK: ::tcflag_t = 0o000040; +pub const ECHONL: ::tcflag_t = 0o000100; +pub const ECHOCTL: ::tcflag_t = 0o001000; +pub const ECHOPRT: ::tcflag_t = 0o002000; +pub const ECHOKE: ::tcflag_t = 0o004000; +pub const EXTPROC: ::tcflag_t = 0o200000; +pub const IGNBRK: ::tcflag_t = 0o000001; +pub const BRKINT: ::tcflag_t = 0o000002; +pub const IGNPAR: ::tcflag_t = 0o000004; +pub const PARMRK: ::tcflag_t = 0o000010; +pub const INPCK: ::tcflag_t = 0o000020; +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; +pub const IEXTEN: ::tcflag_t = 0o100000; +pub const TOSTOP: ::tcflag_t = 0o000400; +pub const FLUSHO: ::tcflag_t = 0o020000; +pub const PENDIN: ::tcflag_t = 0o040000; +pub const NOFLSH: ::tcflag_t = 0o000200; +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 VEOL2: usize = 6; +pub const VMIN: usize = 4; +pub const VTIME: usize = 5; +pub const VSWTCH: usize = 7; +pub const VSTART: usize = 8; +pub const VSTOP: usize = 9; +pub const VSUSP: usize = 10; +pub const VDSUSP: usize = 11; +pub const VREPRINT: usize = 12; +pub const VDISCARD: usize = 13; +pub const VWERASE: usize = 14; +pub const VLNEXT: usize = 15; +pub const VSTATUS: usize = 16; +pub const VERASE2: usize = 17; + +// +const STR: ::c_int = (b'S' as ::c_int) << 8; +pub const I_NREAD: ::c_int = STR | 0o1; +pub const I_PUSH: ::c_int = STR | 0o2; +pub const I_POP: ::c_int = STR | 0o3; +pub const I_LOOK: ::c_int = STR | 0o4; +pub const I_FLUSH: ::c_int = STR | 0o5; +pub const I_SRDOPT: ::c_int = STR | 0o6; +pub const I_GRDOPT: ::c_int = STR | 0o7; +pub const I_STR: ::c_int = STR | 0o10; +pub const I_SETSIG: ::c_int = STR | 0o11; +pub const I_GETSIG: ::c_int = STR | 0o12; +pub const I_FIND: ::c_int = STR | 0o13; +pub const I_LINK: ::c_int = STR | 0o14; +pub const I_UNLINK: ::c_int = STR | 0o15; +pub const I_PEEK: ::c_int = STR | 0o17; +pub const I_FDINSERT: ::c_int = STR | 0o20; +pub const I_SENDFD: ::c_int = STR | 0o21; +pub const I_RECVFD: ::c_int = STR | 0o16; +pub const I_SWROPT: ::c_int = STR | 0o23; +pub const I_GWROPT: ::c_int = STR | 0o24; +pub const I_LIST: ::c_int = STR | 0o25; +pub const I_PLINK: ::c_int = STR | 0o26; +pub const I_PUNLINK: ::c_int = STR | 0o27; +pub const I_ANCHOR: ::c_int = STR | 0o30; +pub const I_FLUSHBAND: ::c_int = STR | 0o34; +pub const I_CKBAND: ::c_int = STR | 0o35; +pub const I_GETBAND: ::c_int = STR | 0o36; +pub const I_ATMARK: ::c_int = STR | 0o37; +pub const I_SETCLTIME: ::c_int = STR | 0o40; +pub const I_GETCLTIME: ::c_int = STR | 0o41; +pub const I_CANPUT: ::c_int = STR | 0o42; +pub const I_SERROPT: ::c_int = STR | 0o43; +pub const I_GERROPT: ::c_int = STR | 0o44; +pub const I_ESETSIG: ::c_int = STR | 0o45; +pub const I_EGETSIG: ::c_int = STR | 0o46; +pub const __I_PUSH_NOCTTY: ::c_int = STR | 0o47; + +// 3SOCKET flags +pub const SOCK_CLOEXEC: ::c_int = 0x080000; +pub const SOCK_NONBLOCK: ::c_int = 0x100000; +pub const SOCK_NDELAY: ::c_int = 0x200000; + +// +pub const SCALE_KG: ::c_int = 1 << 6; +pub const SCALE_KF: ::c_int = 1 << 16; +pub const SCALE_KH: ::c_int = 1 << 2; +pub const MAXTC: ::c_int = 1 << 6; +pub const SCALE_PHASE: ::c_int = 1 << 22; +pub const SCALE_USEC: ::c_int = 1 << 16; +pub const SCALE_UPDATE: ::c_int = SCALE_KG * MAXTC; +pub const FINEUSEC: ::c_int = 1 << 22; +pub const MAXPHASE: ::c_int = 512000; +pub const MAXFREQ: ::c_int = 512 * SCALE_USEC; +pub const MAXTIME: ::c_int = 200 << PPS_AVG; +pub const MINSEC: ::c_int = 16; +pub const MAXSEC: ::c_int = 1200; +pub const PPS_AVG: ::c_int = 2; +pub const PPS_SHIFT: ::c_int = 2; +pub const PPS_SHIFTMAX: ::c_int = 8; +pub const PPS_VALID: ::c_int = 120; +pub const MAXGLITCH: ::c_int = 30; +pub const MOD_OFFSET: u32 = 0x0001; +pub const MOD_FREQUENCY: u32 = 0x0002; +pub const MOD_MAXERROR: u32 = 0x0004; +pub const MOD_ESTERROR: u32 = 0x0008; +pub const MOD_STATUS: u32 = 0x0010; +pub const MOD_TIMECONST: u32 = 0x0020; +pub const MOD_CLKB: u32 = 0x4000; +pub const MOD_CLKA: u32 = 0x8000; +pub const STA_PLL: u32 = 0x0001; +pub const STA_PPSFREQ: i32 = 0x0002; +pub const STA_PPSTIME: i32 = 0x0004; +pub const STA_FLL: i32 = 0x0008; +pub const STA_INS: i32 = 0x0010; +pub const STA_DEL: i32 = 0x0020; +pub const STA_UNSYNC: i32 = 0x0040; +pub const STA_FREQHOLD: i32 = 0x0080; +pub const STA_PPSSIGNAL: i32 = 0x0100; +pub const STA_PPSJITTER: i32 = 0x0200; +pub const STA_PPSWANDER: i32 = 0x0400; +pub const STA_PPSERROR: i32 = 0x0800; +pub const STA_CLOCKERR: i32 = 0x1000; +pub const STA_RONLY: i32 = + STA_PPSSIGNAL | STA_PPSJITTER | STA_PPSWANDER | STA_PPSERROR | STA_CLOCKERR; +pub const TIME_OK: i32 = 0; +pub const TIME_INS: i32 = 1; +pub const TIME_DEL: i32 = 2; +pub const TIME_OOP: i32 = 3; +pub const TIME_WAIT: i32 = 4; +pub const TIME_ERROR: i32 = 5; + +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(not(target_arch = "sparc64"))] +const _CMSG_HDR_ALIGNMENT: usize = 4; + +const _CMSG_DATA_ALIGNMENT: usize = ::mem::size_of::<::c_int>(); + +const NEWDEV: ::c_int = 1; + +// sys/sendfile.h +pub const SFV_FD_SELF: ::c_int = -2; + +const_fn! { + {const} fn _CMSG_HDR_ALIGN(p: usize) -> usize { + (p + _CMSG_HDR_ALIGNMENT - 1) & !(_CMSG_HDR_ALIGNMENT - 1) + } + + {const} fn _CMSG_DATA_ALIGN(p: usize) -> usize { + (p + _CMSG_DATA_ALIGNMENT - 1) & !(_CMSG_DATA_ALIGNMENT - 1) + } +} + +f! { + pub fn CMSG_DATA(cmsg: *const ::cmsghdr) -> *mut ::c_uchar { + _CMSG_DATA_ALIGN(cmsg.offset(1) as usize) as *mut ::c_uchar + } + + pub {const} fn CMSG_LEN(length: ::c_uint) -> ::c_uint { + _CMSG_DATA_ALIGN(::mem::size_of::<::cmsghdr>()) as ::c_uint + length + } + + pub fn CMSG_FIRSTHDR(mhdr: *const ::msghdr) -> *mut ::cmsghdr { + if ((*mhdr).msg_controllen as usize) < ::mem::size_of::<::cmsghdr>() { + 0 as *mut ::cmsghdr + } else { + (*mhdr).msg_control as *mut ::cmsghdr + } + } + + pub fn CMSG_NXTHDR(mhdr: *const ::msghdr, cmsg: *const ::cmsghdr) + -> *mut ::cmsghdr + { + if cmsg.is_null() { + return ::CMSG_FIRSTHDR(mhdr); + }; + let next = _CMSG_HDR_ALIGN(cmsg as usize + (*cmsg).cmsg_len as usize + + ::mem::size_of::<::cmsghdr>()); + let max = (*mhdr).msg_control as usize + + (*mhdr).msg_controllen as usize; + if next > max { + 0 as *mut ::cmsghdr + } else { + _CMSG_HDR_ALIGN(cmsg as usize + (*cmsg).cmsg_len as usize) + as *mut ::cmsghdr + } + } + + pub {const} fn CMSG_SPACE(length: ::c_uint) -> ::c_uint { + _CMSG_HDR_ALIGN(::mem::size_of::<::cmsghdr>() as usize + + length as usize) as ::c_uint + } + + pub fn FD_CLR(fd: ::c_int, set: *mut fd_set) -> () { + let bits = ::mem::size_of_val(&(*set).fds_bits[0]) * 8; + let fd = fd as usize; + (*set).fds_bits[fd / bits] &= !(1 << (fd % bits)); + return + } + + pub fn FD_ISSET(fd: ::c_int, set: *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 + } + + pub fn FD_SET(fd: ::c_int, set: *mut fd_set) -> () { + let bits = ::mem::size_of_val(&(*set).fds_bits[0]) * 8; + let fd = fd as usize; + (*set).fds_bits[fd / bits] |= 1 << (fd % bits); + return + } + + pub fn FD_ZERO(set: *mut fd_set) -> () { + for slot in (*set).fds_bits.iter_mut() { + *slot = 0; + } + } +} + +safe_f! { + pub {const} fn WIFEXITED(status: ::c_int) -> bool { + (status & 0xFF) == 0 + } + + pub {const} fn WEXITSTATUS(status: ::c_int) -> ::c_int { + (status >> 8) & 0xFF + } + + pub {const} fn WTERMSIG(status: ::c_int) -> ::c_int { + status & 0x7F + } + + pub {const} fn WIFCONTINUED(status: ::c_int) -> bool { + (status & 0xffff) == 0xffff + } + + pub {const} fn WSTOPSIG(status: ::c_int) -> ::c_int { + (status & 0xff00) >> 8 + } + + pub {const} fn WIFSIGNALED(status: ::c_int) -> bool { + ((status & 0xff) > 0) && (status & 0xff00 == 0) + } + + pub {const} fn WIFSTOPPED(status: ::c_int) -> bool { + ((status & 0xff) == 0x7f) && ((status & 0xff00) != 0) + } + + 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" { + pub fn getrlimit(resource: ::c_int, rlim: *mut ::rlimit) -> ::c_int; + pub fn setrlimit(resource: ::c_int, rlim: *const ::rlimit) -> ::c_int; + + pub fn strerror_r(errnum: ::c_int, buf: *mut c_char, buflen: ::size_t) -> ::c_int; + + pub fn sem_destroy(sem: *mut sem_t) -> ::c_int; + pub fn sem_init(sem: *mut sem_t, pshared: ::c_int, value: ::c_uint) -> ::c_int; + + pub fn abs(i: ::c_int) -> ::c_int; + pub fn acct(filename: *const ::c_char) -> ::c_int; + pub fn 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; + pub fn getifaddrs(ifap: *mut *mut ::ifaddrs) -> ::c_int; + 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; + pub fn mprotect(addr: *const ::c_void, len: ::size_t, prot: ::c_int) -> ::c_int; + pub fn ___errno() -> *mut ::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(clk_id: ::clockid_t, tp: *const ::timespec) -> ::c_int; + pub fn getnameinfo( + sa: *const ::sockaddr, + salen: ::socklen_t, + host: *mut ::c_char, + hostlen: ::socklen_t, + serv: *mut ::c_char, + servlen: ::socklen_t, + flags: ::c_int, + ) -> ::c_int; + pub fn setpwent(); + pub fn endpwent(); + pub fn getpwent() -> *mut passwd; + pub fn fdatasync(fd: ::c_int) -> ::c_int; + pub fn nl_langinfo_l(item: ::nl_item, locale: ::locale_t) -> *mut ::c_char; + pub fn duplocale(base: ::locale_t) -> ::locale_t; + pub fn freelocale(loc: ::locale_t); + 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 getprogname() -> *const ::c_char; + pub fn setprogname(name: *const ::c_char); + pub fn getloadavg(loadavg: *mut ::c_double, nelem: ::c_int) -> ::c_int; + pub fn getpriority(which: ::c_int, who: ::c_int) -> ::c_int; + pub fn setpriority(which: ::c_int, who: ::c_int, prio: ::c_int) -> ::c_int; + + pub fn mknodat( + dirfd: ::c_int, + pathname: *const ::c_char, + mode: ::mode_t, + dev: dev_t, + ) -> ::c_int; + pub fn mkfifoat(dirfd: ::c_int, pathname: *const ::c_char, mode: ::mode_t) -> ::c_int; + pub fn sethostname(name: *const ::c_char, len: ::c_int) -> ::c_int; + pub fn if_nameindex() -> *mut if_nameindex; + pub fn if_freenameindex(ptr: *mut if_nameindex); + 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_getstack( + attr: *const ::pthread_attr_t, + stackaddr: *mut *mut ::c_void, + stacksize: *mut ::size_t, + ) -> ::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 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 pthread_mutex_timedlock( + 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; + + #[cfg_attr(target_os = "illumos", link_name = "_glob_ext")] + pub fn glob( + pattern: *const ::c_char, + flags: ::c_int, + errfunc: ::Option ::c_int>, + pglob: *mut ::glob_t, + ) -> ::c_int; + + #[cfg_attr(target_os = "illumos", link_name = "_globfree_ext")] + pub fn globfree(pglob: *mut ::glob_t); + + pub fn posix_fallocate(fd: ::c_int, offset: ::off_t, len: ::off_t) -> ::c_int; + pub fn posix_madvise(addr: *mut ::c_void, len: ::size_t, advice: ::c_int) -> ::c_int; + + pub fn shmat(shmid: ::c_int, shmaddr: *const ::c_void, shmflg: ::c_int) -> *mut ::c_void; + + pub fn shmctl(shmid: ::c_int, cmd: ::c_int, buf: *mut ::shmid_ds) -> ::c_int; + + pub fn shmdt(shmaddr: *const ::c_void) -> ::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 seekdir(dirp: *mut ::DIR, loc: ::c_long); + + pub fn telldir(dirp: *mut ::DIR) -> ::c_long; + 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 memalign(align: ::size_t, size: ::size_t) -> *mut ::c_void; + + 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 futimesat(fd: ::c_int, path: *const ::c_char, times: *const ::timeval) -> ::c_int; + pub fn futimens(dirfd: ::c_int, times: *const ::timespec) -> ::c_int; + pub fn utimensat( + dirfd: ::c_int, + path: *const ::c_char, + times: *const ::timespec, + flag: ::c_int, + ) -> ::c_int; + pub fn nl_langinfo(item: ::nl_item) -> *mut ::c_char; + + #[link_name = "__xnet_bind"] + 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; + + #[link_name = "__xnet_sendmsg"] + pub fn sendmsg(fd: ::c_int, msg: *const ::msghdr, flags: ::c_int) -> ::ssize_t; + #[link_name = "__xnet_recvmsg"] + pub fn recvmsg(fd: ::c_int, msg: *mut ::msghdr, flags: ::c_int) -> ::ssize_t; + pub fn accept4( + fd: ::c_int, + address: *mut sockaddr, + address_len: *mut socklen_t, + flags: ::c_int, + ) -> ::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 port_create() -> ::c_int; + pub fn port_associate( + port: ::c_int, + source: ::c_int, + object: ::uintptr_t, + events: ::c_int, + user: *mut ::c_void, + ) -> ::c_int; + pub fn port_dissociate(port: ::c_int, source: ::c_int, object: ::uintptr_t) -> ::c_int; + pub fn port_get(port: ::c_int, pe: *mut port_event, timeout: *mut ::timespec) -> ::c_int; + pub fn port_getn( + port: ::c_int, + pe_list: *mut port_event, + max: ::c_uint, + nget: *mut ::c_uint, + timeout: *mut ::timespec, + ) -> ::c_int; + pub fn port_send(port: ::c_int, events: ::c_int, user: *mut ::c_void) -> ::c_int; + pub fn port_sendn( + port_list: *mut ::c_int, + error_list: *mut ::c_int, + nent: ::c_uint, + events: ::c_int, + user: *mut ::c_void, + ) -> ::c_int; + #[cfg_attr( + any(target_os = "solaris", target_os = "illumos"), + link_name = "__posix_getgrgid_r" + )] + 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 sigaltstack(ss: *const stack_t, oss: *mut stack_t) -> ::c_int; + pub fn sigsuspend(mask: *const ::sigset_t) -> ::c_int; + pub fn sem_close(sem: *mut sem_t) -> ::c_int; + pub fn getdtablesize() -> ::c_int; + + // The epoll functions are actually only present on illumos. However, + // there are things using epoll on illumos (built using the + // x86_64-pc-solaris target) which would break until the illumos target is + // present in rustc. + pub fn epoll_pwait( + epfd: ::c_int, + events: *mut ::epoll_event, + maxevents: ::c_int, + timeout: ::c_int, + sigmask: *const ::sigset_t, + ) -> ::c_int; + + pub fn epoll_create(size: ::c_int) -> ::c_int; + pub fn epoll_create1(flags: ::c_int) -> ::c_int; + pub fn epoll_wait( + epfd: ::c_int, + events: *mut ::epoll_event, + maxevents: ::c_int, + timeout: ::c_int, + ) -> ::c_int; + pub fn epoll_ctl(epfd: ::c_int, op: ::c_int, fd: ::c_int, event: *mut ::epoll_event) + -> ::c_int; + + #[cfg_attr( + any(target_os = "solaris", target_os = "illumos"), + link_name = "__posix_getgrnam_r" + )] + 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 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( + any(target_os = "solaris", target_os = "illumos"), + link_name = "__posix_getpwnam_r" + )] + pub fn getpwnam_r( + name: *const ::c_char, + pwd: *mut passwd, + buf: *mut ::c_char, + buflen: ::size_t, + result: *mut *mut passwd, + ) -> ::c_int; + #[cfg_attr( + any(target_os = "solaris", target_os = "illumos"), + link_name = "__posix_getpwuid_r" + )] + pub fn getpwuid_r( + uid: ::uid_t, + pwd: *mut passwd, + buf: *mut ::c_char, + buflen: ::size_t, + result: *mut *mut passwd, + ) -> ::c_int; + #[cfg_attr( + any(target_os = "solaris", target_os = "illumos"), + link_name = "getpwent_r" + )] + 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 = "getgrent_r" + )] + 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" + )] + 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 setgrent(); + pub fn endgrent(); + pub fn getgrent() -> *mut ::group; + pub fn popen(command: *const c_char, mode: *const c_char) -> *mut ::FILE; + + pub fn dup3(src: ::c_int, dst: ::c_int, flags: ::c_int) -> ::c_int; + pub fn uname(buf: *mut ::utsname) -> ::c_int; + pub fn pipe2(fds: *mut ::c_int, flags: ::c_int) -> ::c_int; + + pub fn makeutx(ux: *const utmpx) -> *mut utmpx; + pub fn modutx(ux: *const utmpx) -> *mut utmpx; + pub fn updwtmpx(file: *const ::c_char, ut: *const utmpx) -> ::c_int; + pub fn utmpxname(file: *const ::c_char) -> ::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 endutent(); + pub fn getutent() -> *mut utmp; + pub fn getutid(u: *const utmp) -> *mut utmp; + pub fn getutline(u: *const utmp) -> *mut utmp; + pub fn pututline(u: *const utmp) -> *mut utmp; + pub fn setutent(); + pub fn utmpname(file: *const ::c_char) -> ::c_int; + + pub fn getutmp(ux: *const utmpx, u: *mut utmp); + pub fn getutmpx(u: *const utmp, ux: *mut utmpx); + pub fn updwtmp(file: *const ::c_char, u: *mut utmp); + + pub fn ntp_adjtime(buf: *mut timex) -> ::c_int; + pub fn ntp_gettime(buf: *mut ntptimeval) -> ::c_int; + + 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; + + pub fn ucred_get(pid: ::pid_t) -> *mut ucred_t; + pub fn getpeerucred(fd: ::c_int, ucred: *mut *mut ucred_t) -> ::c_int; + + pub fn ucred_free(ucred: *mut ucred_t); + + pub fn ucred_geteuid(ucred: *const ucred_t) -> ::uid_t; + pub fn ucred_getruid(ucred: *const ucred_t) -> ::uid_t; + pub fn ucred_getsuid(ucred: *const ucred_t) -> ::uid_t; + pub fn ucred_getegid(ucred: *const ucred_t) -> ::gid_t; + pub fn ucred_getrgid(ucred: *const ucred_t) -> ::gid_t; + pub fn ucred_getsgid(ucred: *const ucred_t) -> ::gid_t; + pub fn ucred_getgroups(ucred: *const ucred_t, groups: *mut *const ::gid_t) -> ::c_int; + pub fn ucred_getpid(ucred: *const ucred_t) -> ::pid_t; + pub fn ucred_getprojid(ucred: *const ucred_t) -> projid_t; + pub fn ucred_getzoneid(ucred: *const ucred_t) -> zoneid_t; + 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(); + + pub fn __major(version: ::c_int, devnum: ::dev_t) -> ::major_t; + pub fn __minor(version: ::c_int, devnum: ::dev_t) -> ::minor_t; + pub fn __makedev(version: ::c_int, majdev: ::major_t, mindev: ::minor_t) -> ::dev_t; +} + +#[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; +} + +pub unsafe fn major(device: ::dev_t) -> ::major_t { + __major(NEWDEV, device) +} + +pub unsafe fn minor(device: ::dev_t) -> ::minor_t { + __minor(NEWDEV, device) +} + +pub unsafe fn makedev(maj: ::major_t, min: ::minor_t) -> ::dev_t { + __makedev(NEWDEV, maj, min) +} + +mod compat; +pub use self::compat::*; + +cfg_if! { + if #[cfg(target_os = "illumos")] { + mod illumos; + pub use self::illumos::*; + } else if #[cfg(target_os = "solaris")] { + mod solaris; + pub use self::solaris::*; + } else { + // 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 new file mode 100644 index 0000000..80bad28 --- /dev/null +++ b/vendor/libc/src/unix/solarish/solaris.rs @@ -0,0 +1,101 @@ +pub type door_attr_t = ::c_uint; +pub type door_id_t = ::c_ulonglong; + +s! { + pub struct shmid_ds { + pub shm_perm: ::ipc_perm, + pub shm_segsz: ::size_t, + pub shm_flags: ::uintptr_t, + pub shm_lkcnt: ::c_ushort, + pub shm_lpid: ::pid_t, + pub shm_cpid: ::pid_t, + pub shm_nattch: ::shmatt_t, + pub shm_cnattch: ::c_ulong, + pub shm_atime: ::time_t, + pub shm_dtime: ::time_t, + pub shm_ctime: ::time_t, + pub shm_amp: *mut ::c_void, + pub shm_gransize: u64, + pub shm_allocated: u64, + pub shm_pad4: [i64; 1], + } + + pub struct door_desc_t__d_data__d_desc { + pub d_descriptor: ::c_int, + pub d_id: ::door_id_t + } +} + +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; + +pub const AF_LOCAL: ::c_int = 0; +pub const AF_FILE: ::c_int = 0; + +pub const TCP_KEEPIDLE: ::c_int = 0x1d; +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( + fd: ::c_int, + argv: *const *const ::c_char, + envp: *const *const ::c_char, + ) -> ::c_int; + + pub fn mincore(addr: *const ::c_void, len: ::size_t, vec: *mut ::c_char) -> ::c_int; + + pub fn door_call(d: ::c_int, params: *const door_arg_t) -> ::c_int; + pub fn door_return( + data_ptr: *const ::c_char, + data_size: ::size_t, + desc_ptr: *const door_desc_t, + num_desc: ::c_uint, + ); + pub fn door_create( + server_procedure: extern "C" fn( + cookie: *const ::c_void, + argp: *const ::c_char, + arg_size: ::size_t, + dp: *const door_desc_t, + n_desc: ::c_uint, + ), + cookie: *const ::c_void, + attributes: door_attr_t, + ) -> ::c_int; + + 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; + + 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/aarch64.rs b/vendor/libc/src/vxworks/aarch64.rs new file mode 100644 index 0000000..4032488 --- /dev/null +++ b/vendor/libc/src/vxworks/aarch64.rs @@ -0,0 +1,4 @@ +pub type c_char = u8; +pub type wchar_t = u32; +pub type c_long = i64; +pub type c_ulong = u64; diff --git a/vendor/libc/src/vxworks/arm.rs b/vendor/libc/src/vxworks/arm.rs new file mode 100644 index 0000000..5524006 --- /dev/null +++ b/vendor/libc/src/vxworks/arm.rs @@ -0,0 +1,4 @@ +pub type c_char = u8; +pub type wchar_t = u32; +pub type c_long = i32; +pub type c_ulong = u32; diff --git a/vendor/libc/src/vxworks/mod.rs b/vendor/libc/src/vxworks/mod.rs new file mode 100644 index 0000000..f7adb5d --- /dev/null +++ b/vendor/libc/src/vxworks/mod.rs @@ -0,0 +1,2054 @@ +//! Interface to VxWorks C library + +use core::mem::size_of; +use core::ptr::null_mut; + +#[cfg_attr(feature = "extra_traits", derive(Debug))] +pub enum DIR {} +impl ::Copy for DIR {} +impl ::Clone for DIR { + fn clone(&self) -> DIR { + *self + } +} + +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 pid_t = ::c_int; +pub type in_addr_t = u32; +pub type sighandler_t = ::size_t; +pub type cpuset_t = u32; + +pub type blkcnt_t = ::c_long; +pub type blksize_t = ::c_long; +pub type ino_t = ::c_ulong; + +pub type rlim_t = ::c_ulong; +pub type suseconds_t = ::c_long; +pub type time_t = ::c_long; + +pub type errno_t = ::c_int; + +pub type useconds_t = ::c_ulong; + +pub type socklen_t = ::c_uint; + +pub type pthread_t = ::c_ulong; + +pub type clockid_t = ::c_int; + +//defined for the structs +pub type dev_t = ::c_ulong; +pub type mode_t = ::c_int; +pub type nlink_t = ::c_ulong; +pub type uid_t = ::c_ushort; +pub type gid_t = ::c_ushort; +pub type sigset_t = ::c_ulonglong; +pub type key_t = ::c_long; + +pub type nfds_t = ::c_uint; +pub type stat64 = ::stat; + +pub type pthread_key_t = ::c_ulong; + +// From b_off_t.h +pub type off_t = ::c_longlong; +pub type off64_t = off_t; + +// From b_BOOL.h +pub type BOOL = ::c_int; + +// From vxWind.h .. +pub type _Vx_OBJ_HANDLE = ::c_int; +pub type _Vx_TASK_ID = ::_Vx_OBJ_HANDLE; +pub type _Vx_MSG_Q_ID = ::_Vx_OBJ_HANDLE; +pub type _Vx_SEM_ID_KERNEL = ::_Vx_OBJ_HANDLE; +pub type _Vx_RTP_ID = ::_Vx_OBJ_HANDLE; +pub type _Vx_SD_ID = ::_Vx_OBJ_HANDLE; +pub type _Vx_CONDVAR_ID = ::_Vx_OBJ_HANDLE; +pub type _Vx_SEM_ID = *mut ::_Vx_semaphore; +pub type OBJ_HANDLE = ::_Vx_OBJ_HANDLE; +pub type TASK_ID = ::OBJ_HANDLE; +pub type MSG_Q_ID = ::OBJ_HANDLE; +pub type SEM_ID_KERNEL = ::OBJ_HANDLE; +pub type RTP_ID = ::OBJ_HANDLE; +pub type SD_ID = ::OBJ_HANDLE; +pub type CONDVAR_ID = ::OBJ_HANDLE; +pub type STATUS = ::OBJ_HANDLE; + +// From vxTypes.h +pub type _Vx_usr_arg_t = isize; +pub type _Vx_exit_code_t = isize; +pub type _Vx_ticks_t = ::c_uint; +pub type _Vx_ticks64_t = ::c_ulonglong; + +pub type sa_family_t = ::c_uchar; + +// mqueue.h +pub type mqd_t = ::c_int; + +#[cfg_attr(feature = "extra_traits", derive(Debug))] +pub enum _Vx_semaphore {} +impl ::Copy for _Vx_semaphore {} +impl ::Clone for _Vx_semaphore { + fn clone(&self) -> _Vx_semaphore { + *self + } +} + +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 + } +} + +s! { + // b_pthread_condattr_t.h + pub struct pthread_condattr_t { + pub condAttrStatus: ::c_int, + pub condAttrPshared: ::c_int, + pub condAttrClockId: ::clockid_t, + } + + // b_pthread_cond_t.h + pub struct pthread_cond_t{ + pub condSemId: ::_Vx_SEM_ID, + pub condValid: ::c_int, + pub condInitted: ::c_int, + pub condRefCount: ::c_int, + pub condMutex: *mut ::pthread_mutex_t, + pub condAttr: ::pthread_condattr_t, + pub condSemName: [::c_char; _PTHREAD_SHARED_SEM_NAME_MAX] + } + + // b_pthread_rwlockattr_t.h + pub struct pthread_rwlockattr_t { + pub rwlockAttrStatus: ::c_int, + pub rwlockAttrPshared: ::c_int, + pub rwlockAttrMaxReaders: ::c_uint, + pub rwlockAttrConformOpt: ::c_uint, + } + + // b_pthread_rwlock_t.h + pub struct pthread_rwlock_t { + pub rwlockSemId: :: _Vx_SEM_ID, + pub rwlockReadersRefCount: ::c_uint, + pub rwlockValid: ::c_int, + pub rwlockInitted: ::c_int, + pub rwlockAttr: ::pthread_rwlockattr_t, + pub rwlockSemName: [::c_char; _PTHREAD_SHARED_SEM_NAME_MAX] + } + + // b_struct_timeval.h + pub struct timeval { + pub tv_sec: ::time_t, + pub tv_usec: ::suseconds_t, + } + + // socket.h + pub struct linger { + pub l_onoff: ::c_int, + pub l_linger: ::c_int, + } + + pub struct sockaddr { + pub sa_len : ::c_uchar, + pub sa_family : sa_family_t, + pub sa_data : [::c_char; 14], + } + + pub struct iovec { + pub iov_base: *mut ::c_void, + pub iov_len: ::size_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, + } + + // poll.h + pub struct pollfd { + pub fd : ::c_int, + pub events : ::c_short, + pub revents : ::c_short, + } + + // resource.h + pub struct rlimit { + pub rlim_cur : ::rlim_t, + pub rlim_max : ::rlim_t, + } + + // stat.h + 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_mtime : ::time_t, + pub st_ctime : ::time_t, + pub st_blksize : ::blksize_t, + pub st_blocks : ::blkcnt_t, + pub st_attrib : ::c_uchar, + pub st_reserved1 : ::c_int, + pub st_reserved2 : ::c_int, + pub st_reserved3 : ::c_int, + pub st_reserved4 : ::c_int, + } + + //b_struct__Timespec.h + pub struct _Timespec { + pub tv_sec : ::time_t, + pub tv_nsec : ::c_long, + } + + // b_struct__Sched_param.h + pub struct sched_param { + pub sched_priority: ::c_int, /* scheduling priority */ + pub sched_ss_low_priority: ::c_int, /* low scheduling priority */ + pub sched_ss_repl_period: ::_Timespec, /* replenishment period */ + pub sched_ss_init_budget: ::_Timespec, /* initial budget */ + pub sched_ss_max_repl: ::c_int, /* max pending replenishment */ + + } + + // b_pthread_attr_t.h + pub struct pthread_attr_t { + pub threadAttrStatus : ::c_int, + pub threadAttrStacksize : ::size_t, + pub threadAttrStackaddr : *mut ::c_void, + pub threadAttrGuardsize : ::size_t, + pub threadAttrDetachstate : ::c_int, + pub threadAttrContentionscope : ::c_int, + pub threadAttrInheritsched : ::c_int, + pub threadAttrSchedpolicy : ::c_int, + pub threadAttrName : *mut ::c_char, + pub threadAttrOptions : ::c_int, + pub threadAttrSchedparam : ::sched_param, + } + + // signal.h + + pub struct sigaction { + pub sa_u : ::sa_u_t, + pub sa_mask : ::sigset_t, + pub sa_flags : ::c_int, + } + + // b_stack_t.h + pub struct stack_t { + pub ss_sp : *mut ::c_void, + pub ss_size : ::size_t, + pub ss_flags : ::c_int, + } + + // signal.h + pub struct siginfo_t { + pub si_signo : ::c_int, + pub si_code : ::c_int, + pub si_value : ::sigval, + pub si_errno : ::c_int, + pub si_status: ::c_int, + pub si_addr: *mut ::c_void, + pub si_uid: ::uid_t, + pub si_pid: ::pid_t, + } + + // pthread.h (krnl) + // b_pthread_mutexattr_t.h (usr) + pub struct pthread_mutexattr_t { + mutexAttrStatus : ::c_int, + mutexAttrPshared : ::c_int, + mutexAttrProtocol : ::c_int, + mutexAttrPrioceiling : ::c_int, + mutexAttrType : ::c_int, + } + + // pthread.h (krnl) + // b_pthread_mutex_t.h (usr) + pub struct pthread_mutex_t { + pub mutexSemId: ::_Vx_SEM_ID, /*_Vx_SEM_ID ..*/ + pub mutexValid: ::c_int, + pub mutexInitted: ::c_int, + pub mutexCondRefCount: ::c_int, + pub mutexSavPriority: ::c_int, + pub mutexAttr: ::pthread_mutexattr_t, + pub mutexSemName: [::c_char; _PTHREAD_SHARED_SEM_NAME_MAX], + } + + // b_struct_timespec.h + pub struct timespec { + pub tv_sec: ::time_t, + pub tv_nsec: ::c_long, + } + + // 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, + } + + // in.h + pub struct in_addr { + pub s_addr: in_addr_t, + } + + // in.h + pub struct ip_mreq { + pub imr_multiaddr: in_addr, + pub imr_interface: in_addr, + } + + // in6.h + #[repr(align(4))] + pub struct in6_addr { + pub s6_addr: [u8; 16], + } + + // in6.h + pub struct ipv6_mreq { + pub ipv6mr_multiaddr: in6_addr, + pub ipv6mr_interface: ::c_uint, + } + + // netdb.h + 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 : ::size_t, + pub ai_canonname: *mut ::c_char, + pub ai_addr : *mut ::sockaddr, + pub ai_next : *mut ::addrinfo, + } + + // in.h + pub struct sockaddr_in { + pub sin_len : u8, + pub sin_family: u8, + pub sin_port : u16, + pub sin_addr : ::in_addr, + pub sin_zero : [::c_char; 8], + } + + // in6.h + pub struct sockaddr_in6 { + pub sin6_len : u8, + pub sin6_family : u8, + pub sin6_port : u16, + pub sin6_flowinfo: u32, + pub sin6_addr : ::in6_addr, + pub sin6_scope_id: u32, + } + + 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 mq_attr { + pub mq_maxmsg: ::c_long, + pub mq_msgsize: ::c_long, + pub mq_flags: ::c_long, + pub mq_curmsgs: ::c_long, + } +} + +s_no_extra_traits! { + // dirent.h + pub struct dirent { + pub d_ino : ::ino_t, + pub d_name : [::c_char; _PARM_NAME_MAX as usize + 1], + } + + pub struct sockaddr_un { + pub sun_len: u8, + pub sun_family: sa_family_t, + pub sun_path: [::c_char; 104] + } + + // rtpLibCommon.h + pub struct RTP_DESC { + pub status : ::c_int, + pub options : u32, + pub entrAddr : *mut ::c_void, + pub initTaskId: ::TASK_ID, + pub parentId : ::RTP_ID, + pub pathName : [::c_char; VX_RTP_NAME_LENGTH as usize + 1], + pub taskCnt : ::c_int, + pub textStart : *mut ::c_void, + pub textEnd : *mut ::c_void, + } + // socket.h + pub struct sockaddr_storage { + pub ss_len : ::c_uchar, + pub ss_family : ::sa_family_t, + pub __ss_pad1 : [::c_char; _SS_PAD1SIZE], + pub __ss_align : i32, + pub __ss_pad2 : [::c_char; _SS_PAD2SIZE], + } + + pub union sa_u_t { + pub sa_handler : ::Option !>, + pub sa_sigaction: ::Option !>, + } + + pub union sigval { + pub sival_int : ::c_int, + pub sival_ptr : *mut ::c_void, + } +} + +cfg_if! { + if #[cfg(feature = "extra_traits")] { + 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_name", &&self.d_name[..]) + .finish() + } + } + + 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) + .field("sun_path", &&self.sun_path[..]) + .finish() + } + } + + impl ::fmt::Debug for RTP_DESC { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("RTP_DESC") + .field("status", &self.status) + .field("options", &self.options) + .field("entrAddr", &self.entrAddr) + .field("initTaskId", &self.initTaskId) + .field("parentId", &self.parentId) + .field("pathName", &&self.pathName[..]) + .field("taskCnt", &self.taskCnt) + .field("textStart", &self.textStart) + .field("textEnd", &self.textEnd) + .finish() + } + } + 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) + .field("__ss_pad2", &&self.__ss_pad2[..]) + .finish() + } + } + + impl PartialEq for sa_u_t { + fn eq(&self, other: &sa_u_t) -> bool { + unsafe { + let h1 = match self.sa_handler { + Some(handler) => handler as usize, + None => 0 as usize, + }; + let h2 = match other.sa_handler { + Some(handler) => handler as usize, + None => 0 as usize, + }; + h1 == h2 + } + } + } + impl Eq for sa_u_t {} + impl ::fmt::Debug for sa_u_t { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + unsafe { + let h = match self.sa_handler { + Some(handler) => handler as usize, + None => 0 as usize, + }; + + f.debug_struct("sa_u_t") + .field("sa_handler", &h) + .finish() + } + } + } + impl ::hash::Hash for sa_u_t { + fn hash(&self, state: &mut H) { + unsafe { + let h = match self.sa_handler { + Some(handler) => handler as usize, + None => 0 as usize, + }; + h.hash(state) + } + } + } + + impl PartialEq for sigval { + fn eq(&self, other: &sigval) -> bool { + unsafe { self.sival_ptr as usize == other.sival_ptr as usize } + } + } + impl Eq for sigval {} + impl ::fmt::Debug for sigval { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("sigval") + .field("sival_ptr", unsafe { &(self.sival_ptr as usize) }) + .finish() + } + } + impl ::hash::Hash for sigval { + fn hash(&self, state: &mut H) { + unsafe { (self.sival_ptr as usize).hash(state) }; + } + } + } +} + +pub const STDIN_FILENO: ::c_int = 0; +pub const STDOUT_FILENO: ::c_int = 1; +pub const STDERR_FILENO: ::c_int = 2; + +pub const EXIT_SUCCESS: ::c_int = 0; +pub const EXIT_FAILURE: ::c_int = 1; + +pub const EAI_SERVICE: ::c_int = 9; +pub const EAI_SOCKTYPE: ::c_int = 10; +pub const EAI_SYSTEM: ::c_int = 11; + +// FIXME: This is not defined in vxWorks, but we have to define it here +// to make the building pass for getrandom and std +pub const RTLD_DEFAULT: *mut ::c_void = 0i64 as *mut ::c_void; + +//Clock Lib Stuff +pub const CLOCK_REALTIME: ::c_int = 0x0; +pub const CLOCK_MONOTONIC: ::c_int = 0x1; +pub const CLOCK_PROCESS_CPUTIME_ID: ::c_int = 0x2; +pub const CLOCK_THREAD_CPUTIME_ID: ::c_int = 0x3; +pub const TIMER_ABSTIME: ::c_int = 0x1; +pub const TIMER_RELTIME: ::c_int = 0x0; + +// PTHREAD STUFF +pub const PTHREAD_INITIALIZED_OBJ: ::c_int = 0xF70990EF; +pub const PTHREAD_DESTROYED_OBJ: ::c_int = -1; +pub const PTHREAD_VALID_OBJ: ::c_int = 0xEC542A37; +pub const PTHREAD_INVALID_OBJ: ::c_int = -1; +pub const PTHREAD_UNUSED_YET_OBJ: ::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_MUTEX_NORMAL: ::c_int = 0; +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 PTHREAD_STACK_MIN: usize = 4096; +pub const _PTHREAD_SHARED_SEM_NAME_MAX: usize = 30; + +//sched.h +pub const SCHED_FIFO: ::c_int = 0x01; +pub const SCHED_RR: ::c_int = 0x02; +pub const SCHED_OTHER: ::c_int = 0x04; +pub const SCHED_SPORADIC: ::c_int = 0x08; +pub const PRIO_PROCESS: ::c_uint = 0; +pub const SCHED_FIFO_HIGH_PRI: ::c_int = 255; +pub const SCHED_FIFO_LOW_PRI: ::c_int = 0; +pub const SCHED_RR_HIGH_PRI: ::c_int = 255; +pub const SCHED_RR_LOW_PRI: ::c_int = 0; +pub const SCHED_SPORADIC_HIGH_PRI: ::c_int = 255; +pub const SCHED_SPORADIC_LOW_PRI: ::c_int = 0; + +// ERRNO STUFF +pub const ERROR: ::c_int = -1; +pub const OK: ::c_int = 0; +pub const EPERM: ::c_int = 1; /* Not owner */ +pub const ENOENT: ::c_int = 2; /* No such file or directory */ +pub const ESRCH: ::c_int = 3; /* No such process */ +pub const EINTR: ::c_int = 4; /* Interrupted system call */ +pub const EIO: ::c_int = 5; /* I/O error */ +pub const ENXIO: ::c_int = 6; /* No such device or address */ +pub const E2BIG: ::c_int = 7; /* Arg list too long */ +pub const ENOEXEC: ::c_int = 8; /* Exec format error */ +pub const EBADF: ::c_int = 9; /* Bad file number */ +pub const ECHILD: ::c_int = 10; /* No children */ +pub const EAGAIN: ::c_int = 11; /* No more processes */ +pub const ENOMEM: ::c_int = 12; /* Not enough core */ +pub const EACCES: ::c_int = 13; /* Permission denied */ +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; +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; +pub const EDESTADDRREQ: ::c_int = 40; +pub const EPROTOTYPE: ::c_int = 41; +pub const ENOPROTOOPT: ::c_int = 42; +pub const EPROTONOSUPPORT: ::c_int = 43; +pub const ESOCKTNOSUPPORT: ::c_int = 44; +pub const EOPNOTSUPP: ::c_int = 45; +pub const EPFNOSUPPORT: ::c_int = 46; +pub const EAFNOSUPPORT: ::c_int = 47; +pub const EADDRINUSE: ::c_int = 48; +pub const EADDRNOTAVAIL: ::c_int = 49; +pub const ENOTSOCK: ::c_int = 50; +pub const ENETUNREACH: ::c_int = 51; +pub const ENETRESET: ::c_int = 52; +pub const ECONNABORTED: ::c_int = 53; +pub const ECONNRESET: ::c_int = 54; +pub const ENOBUFS: ::c_int = 55; +pub const EISCONN: ::c_int = 56; +pub const ENOTCONN: ::c_int = 57; +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; +pub const ENOSYS: ::c_int = 71; +pub const EDQUOT: ::c_int = 83; +pub const ESTALE: ::c_int = 88; + +// NFS errnos: Refer to pkgs_v2/storage/fs/nfs/h/nfs/nfsCommon.h +const M_nfsStat: ::c_int = 48 << 16; +enum nfsstat { + NFSERR_REMOTE = 71, + NFSERR_WFLUSH = 99, + NFSERR_BADHANDLE = 10001, + NFSERR_NOT_SYNC = 10002, + NFSERR_BAD_COOKIE = 10003, + NFSERR_TOOSMALL = 10005, + NFSERR_BADTYPE = 10007, + NFSERR_JUKEBOX = 10008, +} + +pub const S_nfsLib_NFS_OK: ::c_int = OK; +pub const S_nfsLib_NFSERR_PERM: ::c_int = EPERM; +pub const S_nfsLib_NFSERR_NOENT: ::c_int = ENOENT; +pub const S_nfsLib_NFSERR_IO: ::c_int = EIO; +pub const S_nfsLib_NFSERR_NXIO: ::c_int = ENXIO; +pub const S_nfsLib_NFSERR_ACCESS: ::c_int = EACCES; +pub const S_nfsLib_NFSERR_EXIST: ::c_int = EEXIST; +pub const S_nfsLib_NFSERR_ENODEV: ::c_int = ENODEV; +pub const S_nfsLib_NFSERR_NOTDIR: ::c_int = ENOTDIR; +pub const S_nfsLib_NFSERR_ISDIR: ::c_int = EISDIR; +pub const S_nfsLib_NFSERR_INVAL: ::c_int = EINVAL; +pub const S_nfsLib_NFSERR_FBIG: ::c_int = EFBIG; +pub const S_nfsLib_NFSERR_NOSPC: ::c_int = ENOSPC; +pub const S_nfsLib_NFSERR_ROFS: ::c_int = EROFS; +pub const S_nfsLib_NFSERR_NAMETOOLONG: ::c_int = ENAMETOOLONG; +pub const S_nfsLib_NFSERR_NOTEMPTY: ::c_int = ENOTEMPTY; +pub const S_nfsLib_NFSERR_DQUOT: ::c_int = EDQUOT; +pub const S_nfsLib_NFSERR_STALE: ::c_int = ESTALE; +pub const S_nfsLib_NFSERR_WFLUSH: ::c_int = M_nfsStat | nfsstat::NFSERR_WFLUSH as ::c_int; +pub const S_nfsLib_NFSERR_REMOTE: ::c_int = M_nfsStat | nfsstat::NFSERR_REMOTE as ::c_int; +pub const S_nfsLib_NFSERR_BADHANDLE: ::c_int = M_nfsStat | nfsstat::NFSERR_BADHANDLE as ::c_int; +pub const S_nfsLib_NFSERR_NOT_SYNC: ::c_int = M_nfsStat | nfsstat::NFSERR_NOT_SYNC as ::c_int; +pub const S_nfsLib_NFSERR_BAD_COOKIE: ::c_int = M_nfsStat | nfsstat::NFSERR_BAD_COOKIE as ::c_int; +pub const S_nfsLib_NFSERR_NOTSUPP: ::c_int = EOPNOTSUPP; +pub const S_nfsLib_NFSERR_TOOSMALL: ::c_int = M_nfsStat | nfsstat::NFSERR_TOOSMALL as ::c_int; +pub const S_nfsLib_NFSERR_SERVERFAULT: ::c_int = EIO; +pub const S_nfsLib_NFSERR_BADTYPE: ::c_int = M_nfsStat | nfsstat::NFSERR_BADTYPE as ::c_int; +pub const S_nfsLib_NFSERR_JUKEBOX: ::c_int = M_nfsStat | nfsstat::NFSERR_JUKEBOX as ::c_int; + +// internal offset values for below constants +const taskErrorBase: ::c_int = 0x00030000; +const semErrorBase: ::c_int = 0x00160000; +const objErrorBase: ::c_int = 0x003d0000; + +// taskLibCommon.h +pub const S_taskLib_NAME_NOT_FOUND: ::c_int = taskErrorBase + 0x0065; +pub const S_taskLib_TASK_HOOK_TABLE_FULL: ::c_int = taskErrorBase + 0x0066; +pub const S_taskLib_TASK_HOOK_NOT_FOUND: ::c_int = taskErrorBase + 0x0067; +pub const S_taskLib_ILLEGAL_PRIORITY: ::c_int = taskErrorBase + 0x0068; + +// FIXME: could also be useful for TASK_DESC type +pub const VX_TASK_NAME_LENGTH: ::c_int = 31; + +// semLibCommon.h +pub const S_semLib_INVALID_STATE: ::c_int = semErrorBase + 0x0065; +pub const S_semLib_INVALID_OPTION: ::c_int = semErrorBase + 0x0066; +pub const S_semLib_INVALID_QUEUE_TYPE: ::c_int = semErrorBase + 0x0067; +pub const S_semLib_INVALID_OPERATION: ::c_int = semErrorBase + 0x0068; + +// objLibCommon.h +pub const S_objLib_OBJ_ID_ERROR: ::c_int = objErrorBase + 0x0001; +pub const S_objLib_OBJ_UNAVAILABLE: ::c_int = objErrorBase + 0x0002; +pub const S_objLib_OBJ_DELETED: ::c_int = objErrorBase + 0x0003; +pub const S_objLib_OBJ_TIMEOUT: ::c_int = objErrorBase + 0x0004; +pub const S_objLib_OBJ_NO_METHOD: ::c_int = objErrorBase + 0x0005; + +// in.h +pub const IPPROTO_IP: ::c_int = 0; +pub const IPPROTO_IPV6: ::c_int = 41; + +pub const IP_TTL: ::c_int = 4; +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; + +// in6.h +pub const IPV6_V6ONLY: ::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_ADD_MEMBERSHIP: ::c_int = 12; +pub const IPV6_DROP_MEMBERSHIP: ::c_int = 13; + +// STAT Stuff +pub const S_IFMT: ::c_int = 0xf000; +pub const S_IFIFO: ::c_int = 0x1000; +pub const S_IFCHR: ::c_int = 0x2000; +pub const S_IFDIR: ::c_int = 0x4000; +pub const S_IFBLK: ::c_int = 0x6000; +pub const S_IFREG: ::c_int = 0x8000; +pub const S_IFLNK: ::c_int = 0xa000; +pub const S_IFSHM: ::c_int = 0xb000; +pub const S_IFSOCK: ::c_int = 0xc000; +pub const S_ISUID: ::c_int = 0x0800; +pub const S_ISGID: ::c_int = 0x0400; +pub const S_ISTXT: ::c_int = 0x0200; +pub const S_ISVTX: ::c_int = 0o1000; +pub const S_IRUSR: ::c_int = 0x0100; +pub const S_IWUSR: ::c_int = 0x0080; +pub const S_IXUSR: ::c_int = 0x0040; +pub const S_IRWXU: ::c_int = 0x01c0; +pub const S_IRGRP: ::c_int = 0x0020; +pub const S_IWGRP: ::c_int = 0x0010; +pub const S_IXGRP: ::c_int = 0x0008; +pub const S_IRWXG: ::c_int = 0x0038; +pub const S_IROTH: ::c_int = 0x0004; +pub const S_IWOTH: ::c_int = 0x0002; +pub const S_IXOTH: ::c_int = 0x0001; +pub const S_IRWXO: ::c_int = 0x0007; + +// socket.h +pub const SOL_SOCKET: ::c_int = 0xffff; +pub const SOMAXCONN: ::c_int = 128; + +pub const SO_DEBUG: ::c_int = 0x0001; +pub const SO_REUSEADDR: ::c_int = 0x0004; +pub const SO_KEEPALIVE: ::c_int = 0x0008; +pub const SO_DONTROUTE: ::c_int = 0x0010; +pub const SO_RCVLOWAT: ::c_int = 0x0012; +pub const SO_SNDLOWAT: ::c_int = 0x0013; +pub const SO_SNDTIMEO: ::c_int = 0x1005; +pub const SO_ACCEPTCONN: ::c_int = 0x001e; +pub const SO_BROADCAST: ::c_int = 0x0020; +pub const SO_USELOOPBACK: ::c_int = 0x0040; +pub const SO_LINGER: ::c_int = 0x0080; +pub const SO_REUSEPORT: ::c_int = 0x0200; + +pub const SO_VLAN: ::c_int = 0x8000; + +pub const SO_SNDBUF: ::c_int = 0x1001; +pub const SO_RCVBUF: ::c_int = 0x1002; +pub const SO_RCVTIMEO: ::c_int = 0x1006; +pub const SO_ERROR: ::c_int = 0x1007; +pub const SO_TYPE: ::c_int = 0x1008; +pub const SO_BINDTODEVICE: ::c_int = 0x1010; +pub const SO_OOBINLINE: ::c_int = 0x1011; +pub const SO_CONNTIMEO: ::c_int = 0x100a; + +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_SEQPACKET: ::c_int = 5; +pub const SOCK_PACKET: ::c_int = 10; + +pub const _SS_MAXSIZE: usize = 128; +pub const _SS_ALIGNSIZE: usize = size_of::(); +pub const _SS_PAD1SIZE: usize = _SS_ALIGNSIZE - size_of::<::c_uchar>() - size_of::<::sa_family_t>(); +pub const _SS_PAD2SIZE: usize = _SS_MAXSIZE + - size_of::<::c_uchar>() + - size_of::<::sa_family_t>() + - _SS_PAD1SIZE + - _SS_ALIGNSIZE; + +pub const MSG_OOB: ::c_int = 0x0001; +pub const MSG_PEEK: ::c_int = 0x0002; +pub const MSG_DONTROUTE: ::c_int = 0x0004; +pub const MSG_EOR: ::c_int = 0x0008; +pub const MSG_TRUNC: ::c_int = 0x0010; +pub const MSG_CTRUNC: ::c_int = 0x0020; +pub const MSG_WAITALL: ::c_int = 0x0040; +pub const MSG_DONTWAIT: ::c_int = 0x0080; +pub const MSG_EOF: ::c_int = 0x0100; +pub const MSG_EXP: ::c_int = 0x0200; +pub const MSG_MBUF: ::c_int = 0x0400; +pub const MSG_NOTIFICATION: ::c_int = 0x0800; +pub const MSG_COMPAT: ::c_int = 0x8000; + +pub const AF_UNSPEC: ::c_int = 0; +pub const AF_LOCAL: ::c_int = 1; +pub const AF_UNIX: ::c_int = AF_LOCAL; +pub const AF_INET: ::c_int = 2; +pub const AF_NETLINK: ::c_int = 16; +pub const AF_ROUTE: ::c_int = 17; +pub const AF_LINK: ::c_int = 18; +pub const AF_PACKET: ::c_int = 19; +pub const pseudo_AF_KEY: ::c_int = 27; +pub const AF_KEY: ::c_int = pseudo_AF_KEY; +pub const AF_INET6: ::c_int = 28; +pub const AF_SOCKDEV: ::c_int = 31; +pub const AF_TIPC: ::c_int = 33; +pub const AF_MIPC: ::c_int = 34; +pub const AF_MIPC_SAFE: ::c_int = 35; +pub const AF_MAX: ::c_int = 37; + +pub const SHUT_RD: ::c_int = 0; +pub const SHUT_WR: ::c_int = 1; +pub const SHUT_RDWR: ::c_int = 2; + +pub const IPPROTO_TCP: ::c_int = 6; +pub const TCP_NODELAY: ::c_int = 1; +pub const TCP_MAXSEG: ::c_int = 2; +pub const TCP_NOPUSH: ::c_int = 3; +pub const TCP_KEEPIDLE: ::c_int = 4; +pub const TCP_KEEPINTVL: ::c_int = 5; +pub const TCP_KEEPCNT: ::c_int = 6; + +// ioLib.h +pub const FIONREAD: ::c_int = 0x40040001; +pub const FIOFLUSH: ::c_int = 2; +pub const FIOOPTIONS: ::c_int = 3; +pub const FIOBAUDRATE: ::c_int = 4; +pub const FIODISKFORMAT: ::c_int = 5; +pub const FIODISKINIT: ::c_int = 6; +pub const FIOSEEK: ::c_int = 7; +pub const FIOWHERE: ::c_int = 8; +pub const FIODIRENTRY: ::c_int = 9; +pub const FIORENAME: ::c_int = 10; +pub const FIOREADYCHANGE: ::c_int = 11; +pub const FIODISKCHANGE: ::c_int = 13; +pub const FIOCANCEL: ::c_int = 14; +pub const FIOSQUEEZE: ::c_int = 15; +pub const FIOGETNAME: ::c_int = 18; +pub const FIONBIO: ::c_int = 0x90040010; + +// limits.h +pub const PATH_MAX: ::c_int = _PARM_PATH_MAX; +pub const _POSIX_PATH_MAX: ::c_int = 256; + +// Some poll stuff +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; + +// fnctlcom.h +pub const FD_CLOEXEC: ::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_GETOWN: ::c_int = 5; +pub const F_SETOWN: ::c_int = 6; +pub const F_GETLK: ::c_int = 7; +pub const F_SETLK: ::c_int = 8; +pub const F_SETLKW: ::c_int = 9; +pub const F_DUPFD_CLOEXEC: ::c_int = 14; + +// signal.h +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 = -1 as isize as sighandler_t; + +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 SIGFMT: ::c_int = 12; +pub const SIGPIPE: ::c_int = 13; +pub const SIGALRM: ::c_int = 14; +pub const SIGTERM: ::c_int = 15; +pub const SIGCNCL: ::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 SIG_BLOCK: ::c_int = 1; +pub const SIG_UNBLOCK: ::c_int = 2; +pub const SIG_SETMASK: ::c_int = 3; + +pub const SI_SYNC: ::c_int = 0; +pub const SI_USER: ::c_int = -1; +pub const SI_QUEUE: ::c_int = -2; +pub const SI_TIMER: ::c_int = -3; +pub const SI_ASYNCIO: ::c_int = -4; +pub const SI_MESGQ: ::c_int = -5; +pub const SI_CHILD: ::c_int = -6; +pub const SI_KILL: ::c_int = SI_USER; + +// vxParams.h definitions +pub const _PARM_NAME_MAX: ::c_int = 255; +pub const _PARM_PATH_MAX: ::c_int = 1024; + +// WAIT STUFF +pub const WNOHANG: ::c_int = 0x01; +pub const WUNTRACED: ::c_int = 0x02; + +const PTHREAD_MUTEXATTR_INITIALIZER: pthread_mutexattr_t = pthread_mutexattr_t { + mutexAttrStatus: PTHREAD_INITIALIZED_OBJ, + mutexAttrProtocol: PTHREAD_PRIO_NONE, + mutexAttrPrioceiling: 0, + mutexAttrType: PTHREAD_MUTEX_DEFAULT, + mutexAttrPshared: 1, +}; +pub const PTHREAD_MUTEX_INITIALIZER: pthread_mutex_t = pthread_mutex_t { + mutexSemId: null_mut(), + mutexValid: PTHREAD_VALID_OBJ, + mutexInitted: PTHREAD_UNUSED_YET_OBJ, + mutexCondRefCount: 0, + mutexSavPriority: -1, + mutexAttr: PTHREAD_MUTEXATTR_INITIALIZER, + mutexSemName: [0; _PTHREAD_SHARED_SEM_NAME_MAX], +}; + +const PTHREAD_CONDATTR_INITIALIZER: pthread_condattr_t = pthread_condattr_t { + condAttrStatus: 0xf70990ef, + condAttrPshared: 1, + condAttrClockId: CLOCK_REALTIME, +}; +pub const PTHREAD_COND_INITIALIZER: pthread_cond_t = pthread_cond_t { + condSemId: null_mut(), + condValid: PTHREAD_VALID_OBJ, + condInitted: PTHREAD_UNUSED_YET_OBJ, + condRefCount: 0, + condMutex: null_mut(), + condAttr: PTHREAD_CONDATTR_INITIALIZER, + condSemName: [0; _PTHREAD_SHARED_SEM_NAME_MAX], +}; + +const PTHREAD_RWLOCKATTR_INITIALIZER: pthread_rwlockattr_t = pthread_rwlockattr_t { + rwlockAttrStatus: PTHREAD_INITIALIZED_OBJ, + rwlockAttrPshared: 1, + rwlockAttrMaxReaders: 0, + rwlockAttrConformOpt: 1, +}; +pub const PTHREAD_RWLOCK_INITIALIZER: pthread_rwlock_t = pthread_rwlock_t { + rwlockSemId: null_mut(), + rwlockReadersRefCount: 0, + rwlockValid: PTHREAD_VALID_OBJ, + rwlockInitted: PTHREAD_UNUSED_YET_OBJ, + rwlockAttr: PTHREAD_RWLOCKATTR_INITIALIZER, + rwlockSemName: [0; _PTHREAD_SHARED_SEM_NAME_MAX], +}; + +pub const SEEK_SET: ::c_int = 0; +pub const SEEK_CUR: ::c_int = 1; +pub const SEEK_END: ::c_int = 2; + +// rtpLibCommon.h +pub const VX_RTP_NAME_LENGTH: ::c_int = 255; +pub const RTP_ID_ERROR: ::RTP_ID = -1; + +// h/public/unistd.h +pub const _SC_GETPW_R_SIZE_MAX: ::c_int = 21; // Via unistd.h +pub const _SC_PAGESIZE: ::c_int = 39; +pub const O_ACCMODE: ::c_int = 3; +pub const O_CLOEXEC: ::c_int = 0x100000; // fcntlcom +pub const O_EXCL: ::c_int = 0x0800; +pub const O_CREAT: ::c_int = 0x0200; +pub const O_TRUNC: ::c_int = 0x0400; +pub const O_APPEND: ::c_int = 0x0008; +pub const O_RDWR: ::c_int = 0x0002; +pub const O_WRONLY: ::c_int = 0x0001; +pub const O_RDONLY: ::c_int = 0; +pub const O_NONBLOCK: ::c_int = 0x4000; + +// mman.h +pub const PROT_NONE: ::c_int = 0x0000; +pub const PROT_READ: ::c_int = 0x0001; +pub const PROT_WRITE: ::c_int = 0x0002; +pub const PROT_EXEC: ::c_int = 0x0004; + +pub const MAP_SHARED: ::c_int = 0x0001; +pub const MAP_PRIVATE: ::c_int = 0x0002; +pub const MAP_ANON: ::c_int = 0x0004; +pub const MAP_ANONYMOUS: ::c_int = MAP_ANON; +pub const MAP_FIXED: ::c_int = 0x0010; +pub const MAP_CONTIG: ::c_int = 0x0020; + +pub const MAP_FAILED: *mut ::c_void = !0 as *mut ::c_void; + +#[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 {} // FIXME: fill this out with a struct +impl ::Copy for fpos_t {} +impl ::Clone for fpos_t { + fn clone(&self) -> fpos_t { + *self + } +} + +f! { + pub {const} fn CMSG_ALIGN(len: usize) -> usize { + len + ::mem::size_of::() - 1 & !(::mem::size_of::() - 1) + } + + pub fn CMSG_NXTHDR(mhdr: *const msghdr, + cmsg: *const cmsghdr) -> *mut cmsghdr { + let next = cmsg as usize + CMSG_ALIGN((*cmsg).cmsg_len as usize) + + CMSG_ALIGN(::mem::size_of::<::cmsghdr>()); + let max = (*mhdr).msg_control as usize + + (*mhdr).msg_controllen as usize; + if next <= max { + (cmsg as usize + CMSG_ALIGN((*cmsg).cmsg_len as usize)) + as *mut ::cmsghdr + } else { + 0 as *mut ::cmsghdr + } + } + + pub fn CMSG_FIRSTHDR(mhdr: *const msghdr) -> *mut cmsghdr { + if (*mhdr).msg_controllen as usize > 0 { + (*mhdr).msg_control as *mut cmsghdr + } else { + 0 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 {const} fn CMSG_SPACE(length: ::c_uint) -> ::c_uint { + (CMSG_ALIGN(length as usize) + CMSG_ALIGN(::mem::size_of::())) + as ::c_uint + } + + pub {const} fn CMSG_LEN(length: ::c_uint) -> ::c_uint { + CMSG_ALIGN(::mem::size_of::()) as ::c_uint + length + } +} + +extern "C" { + 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; + pub fn fopen(filename: *const c_char, mode: *const c_char) -> *mut FILE; + pub fn freopen(filename: *const c_char, mode: *const c_char, file: *mut FILE) -> *mut FILE; + pub fn fflush(file: *mut FILE) -> c_int; + pub fn fclose(file: *mut FILE) -> c_int; + pub fn remove(filename: *const c_char) -> c_int; + pub fn rename(oldname: *const c_char, newname: *const c_char) -> c_int; + pub fn tmpfile() -> *mut FILE; + 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 getchar() -> c_int; + pub fn putchar(c: c_int) -> c_int; + pub fn fgetc(stream: *mut FILE) -> c_int; + pub fn fgets(buf: *mut c_char, n: c_int, stream: *mut FILE) -> *mut c_char; + pub fn fputc(c: c_int, stream: *mut FILE) -> c_int; + pub fn fputs(s: *const c_char, stream: *mut FILE) -> c_int; + pub fn puts(s: *const c_char) -> c_int; + pub fn ungetc(c: c_int, stream: *mut FILE) -> c_int; + pub fn fread(ptr: *mut c_void, size: size_t, nobj: size_t, stream: *mut FILE) -> size_t; + pub fn fwrite(ptr: *const c_void, size: size_t, nobj: size_t, stream: *mut FILE) -> size_t; + pub fn fseek(stream: *mut FILE, offset: c_long, whence: c_int) -> c_int; + pub fn ftell(stream: *mut FILE) -> c_long; + pub fn rewind(stream: *mut FILE); + pub fn fgetpos(stream: *mut FILE, ptr: *mut fpos_t) -> c_int; + pub fn fsetpos(stream: *mut FILE, ptr: *const fpos_t) -> c_int; + 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; + pub fn free(p: *mut c_void); + pub fn abort() -> !; + pub fn exit(status: c_int) -> !; + pub fn atexit(cb: extern "C" fn()) -> c_int; + pub fn system(s: *const c_char) -> c_int; + pub fn getenv(s: *const c_char) -> *mut c_char; + + 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 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; + pub fn strncmp(cs: *const c_char, ct: *const c_char, n: size_t) -> c_int; + pub fn strcoll(cs: *const c_char, ct: *const c_char) -> c_int; + pub fn strchr(cs: *const c_char, c: c_int) -> *mut c_char; + pub fn strrchr(cs: *const c_char, c: c_int) -> *mut c_char; + pub fn strspn(cs: *const c_char, ct: *const c_char) -> size_t; + pub fn strcspn(cs: *const c_char, ct: *const c_char) -> size_t; + pub fn strdup(cs: *const c_char) -> *mut c_char; + pub fn strpbrk(cs: *const c_char, ct: *const c_char) -> *mut c_char; + pub fn strstr(cs: *const c_char, ct: *const c_char) -> *mut c_char; + pub fn strcasecmp(s1: *const c_char, s2: *const c_char) -> c_int; + pub fn strncasecmp(s1: *const c_char, s2: *const c_char, n: size_t) -> c_int; + pub fn strlen(cs: *const c_char) -> size_t; + 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 strxfrm(s: *mut c_char, ct: *const c_char, n: size_t) -> size_t; + pub fn wcslen(buf: *const wchar_t) -> size_t; + pub fn wcstombs(dest: *mut c_char, src: *const wchar_t, n: size_t) -> ::size_t; + + pub fn memchr(cx: *const c_void, c: c_int, n: size_t) -> *mut c_void; + pub fn wmemchr(cx: *const wchar_t, c: wchar_t, n: size_t) -> *mut wchar_t; + pub fn memcmp(cx: *const c_void, ct: *const c_void, n: size_t) -> c_int; + pub fn memcpy(dest: *mut c_void, src: *const c_void, n: size_t) -> *mut c_void; + pub fn memmove(dest: *mut c_void, src: *const c_void, n: size_t) -> *mut c_void; + pub fn memset(dest: *mut c_void, c: c_int, n: size_t) -> *mut c_void; +} + +extern "C" { + pub fn fprintf(stream: *mut ::FILE, format: *const ::c_char, ...) -> ::c_int; + pub fn printf(format: *const ::c_char, ...) -> ::c_int; + pub fn snprintf(s: *mut ::c_char, n: ::size_t, format: *const ::c_char, ...) -> ::c_int; + pub fn sprintf(s: *mut ::c_char, format: *const ::c_char, ...) -> ::c_int; + pub fn fscanf(stream: *mut ::FILE, format: *const ::c_char, ...) -> ::c_int; + pub fn scanf(format: *const ::c_char, ...) -> ::c_int; + pub fn sscanf(s: *const ::c_char, format: *const ::c_char, ...) -> ::c_int; + pub fn getchar_unlocked() -> ::c_int; + pub fn putchar_unlocked(c: ::c_int) -> ::c_int; + pub fn stat(path: *const c_char, buf: *mut stat) -> ::c_int; + pub fn fdopen(fd: ::c_int, mode: *const c_char) -> *mut ::FILE; + pub fn fileno(stream: *mut ::FILE) -> ::c_int; + pub fn creat(path: *const c_char, mode: mode_t) -> ::c_int; + pub fn rewinddir(dirp: *mut ::DIR); + pub fn fchown(fd: ::c_int, owner: ::uid_t, group: ::gid_t) -> ::c_int; + pub fn access(path: *const c_char, amode: ::c_int) -> ::c_int; + pub fn alarm(seconds: ::c_uint) -> ::c_uint; + pub fn fchdir(dirfd: ::c_int) -> ::c_int; + pub fn chown(path: *const c_char, uid: uid_t, gid: gid_t) -> ::c_int; + pub fn fpathconf(filedes: ::c_int, name: ::c_int) -> c_long; + pub fn getegid() -> gid_t; + pub fn geteuid() -> uid_t; + pub fn getgroups(ngroups_max: ::c_int, groups: *mut gid_t) -> ::c_int; + pub fn getlogin() -> *mut c_char; + pub fn getopt(argc: ::c_int, argv: *const *mut c_char, optstr: *const c_char) -> ::c_int; + pub fn pathconf(path: *const c_char, name: ::c_int) -> c_long; + pub fn pause() -> ::c_int; + pub fn seteuid(uid: uid_t) -> ::c_int; + pub fn setegid(gid: gid_t) -> ::c_int; + pub fn sleep(secs: ::c_uint) -> ::c_uint; + pub fn ttyname(fd: ::c_int) -> *mut c_char; + pub fn wait(status: *mut ::c_int) -> pid_t; + pub fn umask(mask: mode_t) -> mode_t; + pub fn mlock(addr: *const ::c_void, len: ::size_t) -> ::c_int; + pub fn mlockall(flags: ::c_int) -> ::c_int; + pub fn munlockall() -> ::c_int; + + pub fn mmap( + addr: *mut ::c_void, + len: ::size_t, + prot: ::c_int, + flags: ::c_int, + fd: ::c_int, + offset: off_t, + ) -> *mut ::c_void; + pub fn munmap(addr: *mut ::c_void, len: ::size_t) -> ::c_int; + pub fn truncate(path: *const c_char, length: 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; + + pub fn gettimeofday(tp: *mut ::timeval, tz: *mut ::c_void) -> ::c_int; + pub fn pthread_exit(value: *mut ::c_void) -> !; + pub fn pthread_attr_setdetachstate(attr: *mut ::pthread_attr_t, state: ::c_int) -> ::c_int; + + 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; + + #[link_name = "_rtld_dlopen"] + pub fn dlopen(filename: *const ::c_char, flag: ::c_int) -> *mut ::c_void; + + #[link_name = "_rtld_dlerror"] + pub fn dlerror() -> *mut ::c_char; + + #[link_name = "_rtld_dlsym"] + pub fn dlsym(handle: *mut ::c_void, symbol: *const ::c_char) -> *mut ::c_void; + + #[link_name = "_rtld_dlclose"] + pub fn dlclose(handle: *mut ::c_void) -> ::c_int; + + #[link_name = "_rtld_dladdr"] + pub fn dladdr(addr: *mut ::c_void, info: *mut Dl_info) -> ::c_int; + + // time.h + pub fn gmtime_r(time_p: *const time_t, result: *mut tm) -> *mut tm; + pub fn localtime_r(time_p: *const time_t, result: *mut tm) -> *mut tm; + pub fn mktime(tm: *mut tm) -> time_t; + pub fn time(time: *mut time_t) -> time_t; + pub fn gmtime(time_p: *const time_t) -> *mut tm; + pub fn localtime(time_p: *const time_t) -> *mut tm; + pub fn timegm(tm: *mut tm) -> time_t; + pub fn difftime(time1: time_t, time0: time_t) -> ::c_double; + pub fn gethostname(name: *mut ::c_char, len: ::size_t) -> ::c_int; + pub fn usleep(secs: ::useconds_t) -> ::c_int; + pub fn putenv(string: *mut c_char) -> ::c_int; + pub fn setlocale(category: ::c_int, locale: *const ::c_char) -> *mut ::c_char; + + pub fn sigprocmask(how: ::c_int, set: *const sigset_t, oldset: *mut sigset_t) -> ::c_int; + pub fn sigpending(set: *mut sigset_t) -> ::c_int; + + pub fn mkfifo(path: *const c_char, mode: mode_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; + pub fn mkstemp(template: *mut ::c_char) -> ::c_int; + + pub fn tmpnam(ptr: *mut ::c_char) -> *mut ::c_char; + + pub fn openlog(ident: *const ::c_char, logopt: ::c_int, facility: ::c_int); + pub fn closelog(); + pub fn setlogmask(maskpri: ::c_int) -> ::c_int; + pub fn syslog(priority: ::c_int, message: *const ::c_char, ...); + pub fn getline(lineptr: *mut *mut c_char, n: *mut size_t, stream: *mut FILE) -> ssize_t; + +} + +extern "C" { + // stdlib.h + pub fn memalign(block_size: ::size_t, size_arg: ::size_t) -> *mut ::c_void; + + // ioLib.h + pub fn getcwd(buf: *mut ::c_char, size: ::size_t) -> *mut ::c_char; + + // ioLib.h + pub fn chdir(attr: *const ::c_char) -> ::c_int; + + // pthread.h + pub fn pthread_mutexattr_init(attr: *mut pthread_mutexattr_t) -> ::c_int; + + // pthread.h + pub fn pthread_mutexattr_destroy(attr: *mut pthread_mutexattr_t) -> ::c_int; + + // pthread.h + pub fn pthread_mutexattr_settype(pAttr: *mut ::pthread_mutexattr_t, pType: ::c_int) -> ::c_int; + + // pthread.h + pub fn pthread_mutex_init( + mutex: *mut pthread_mutex_t, + attr: *const pthread_mutexattr_t, + ) -> ::c_int; + + // pthread.h + pub fn pthread_mutex_destroy(mutex: *mut pthread_mutex_t) -> ::c_int; + + // pthread.h + pub fn pthread_mutex_lock(mutex: *mut pthread_mutex_t) -> ::c_int; + + // pthread.h + pub fn pthread_mutex_trylock(mutex: *mut pthread_mutex_t) -> ::c_int; + + // pthread.h + pub fn pthread_mutex_timedlock(attr: *mut pthread_mutex_t, spec: *const timespec) -> ::c_int; + + // pthread.h + pub fn pthread_mutex_unlock(mutex: *mut pthread_mutex_t) -> ::c_int; + + // pthread.h + pub fn pthread_attr_setname(pAttr: *mut ::pthread_attr_t, name: *mut ::c_char) -> ::c_int; + + // pthread.h + pub fn pthread_attr_setstacksize(attr: *mut ::pthread_attr_t, stacksize: ::size_t) -> ::c_int; + + // pthread.h + pub fn pthread_attr_getstacksize(attr: *const ::pthread_attr_t, size: *mut ::size_t) + -> ::c_int; + + // pthread.h + pub fn pthread_attr_init(attr: *mut ::pthread_attr_t) -> ::c_int; + + // pthread.h + pub fn pthread_create( + pThread: *mut ::pthread_t, + pAttr: *const ::pthread_attr_t, + start_routine: extern "C" fn(*mut ::c_void) -> *mut ::c_void, + value: *mut ::c_void, + ) -> ::c_int; + + //pthread.h + pub fn pthread_setschedparam( + native: ::pthread_t, + policy: ::c_int, + param: *const ::sched_param, + ) -> ::c_int; + + //pthread.h + pub fn pthread_getschedparam( + native: ::pthread_t, + policy: *mut ::c_int, + param: *mut ::sched_param, + ) -> ::c_int; + + //pthread.h + pub fn pthread_attr_setinheritsched( + attr: *mut ::pthread_attr_t, + inheritsched: ::c_int, + ) -> ::c_int; + + //pthread.h + pub fn pthread_attr_setschedpolicy(attr: *mut ::pthread_attr_t, policy: ::c_int) -> ::c_int; + + // pthread.h + pub fn pthread_attr_destroy(thread: *mut ::pthread_attr_t) -> ::c_int; + + // pthread.h + pub fn pthread_detach(thread: ::pthread_t) -> ::c_int; + + // int pthread_atfork (void (*)(void), void (*)(void), void (*)(void)); + pub fn pthread_atfork( + prepare: ::Option, + parent: ::Option, + child: ::Option, + ) -> ::c_int; + + // stat.h + pub fn fstat(fildes: ::c_int, buf: *mut stat) -> ::c_int; + + // stat.h + pub fn lstat(path: *const ::c_char, buf: *mut stat) -> ::c_int; + + // unistd.h + pub fn ftruncate(fd: ::c_int, length: off_t) -> ::c_int; + + // dirent.h + pub fn readdir_r(pDir: *mut ::DIR, entry: *mut ::dirent, result: *mut *mut ::dirent) + -> ::c_int; + + // dirent.h + pub fn readdir(pDir: *mut ::DIR) -> *mut ::dirent; + + // fcntl.h or + // ioLib.h + pub fn open(path: *const ::c_char, oflag: ::c_int, ...) -> ::c_int; + + // poll.h + pub fn poll(fds: *mut pollfd, nfds: nfds_t, timeout: ::c_int) -> ::c_int; + + // pthread.h + pub fn pthread_condattr_init(attr: *mut ::pthread_condattr_t) -> ::c_int; + + // pthread.h + pub fn pthread_condattr_destroy(attr: *mut ::pthread_condattr_t) -> ::c_int; + + // pthread.h + pub fn pthread_condattr_getclock( + pAttr: *const ::pthread_condattr_t, + pClockId: *mut ::clockid_t, + ) -> ::c_int; + + // pthread.h + pub fn pthread_condattr_setclock( + pAttr: *mut ::pthread_condattr_t, + clockId: ::clockid_t, + ) -> ::c_int; + + // pthread.h + pub fn pthread_cond_init( + cond: *mut ::pthread_cond_t, + attr: *const ::pthread_condattr_t, + ) -> ::c_int; + + // pthread.h + pub fn pthread_cond_destroy(cond: *mut pthread_cond_t) -> ::c_int; + + // pthread.h + pub fn pthread_cond_signal(cond: *mut ::pthread_cond_t) -> ::c_int; + + // pthread.h + pub fn pthread_cond_broadcast(cond: *mut ::pthread_cond_t) -> ::c_int; + + // pthread.h + pub fn pthread_cond_wait(cond: *mut ::pthread_cond_t, mutex: *mut ::pthread_mutex_t) + -> ::c_int; + + // pthread.h + pub fn pthread_rwlockattr_init(attr: *mut ::pthread_rwlockattr_t) -> ::c_int; + + // pthread.h + pub fn pthread_rwlockattr_destroy(attr: *mut ::pthread_rwlockattr_t) -> ::c_int; + + // pthread.h + pub fn pthread_rwlockattr_setmaxreaders( + attr: *mut ::pthread_rwlockattr_t, + attr2: ::c_uint, + ) -> ::c_int; + + // pthread.h + pub fn pthread_rwlock_init( + attr: *mut ::pthread_rwlock_t, + host: *const ::pthread_rwlockattr_t, + ) -> ::c_int; + + // pthread.h + pub fn pthread_rwlock_destroy(attr: *mut ::pthread_rwlock_t) -> ::c_int; + + // pthread.h + pub fn pthread_rwlock_rdlock(attr: *mut ::pthread_rwlock_t) -> ::c_int; + + // pthread.h + pub fn pthread_rwlock_tryrdlock(attr: *mut ::pthread_rwlock_t) -> ::c_int; + + // pthread.h + pub fn pthread_rwlock_timedrdlock( + attr: *mut ::pthread_rwlock_t, + host: *const ::timespec, + ) -> ::c_int; + + // pthread.h + pub fn pthread_rwlock_wrlock(attr: *mut ::pthread_rwlock_t) -> ::c_int; + + // pthread.h + pub fn pthread_rwlock_trywrlock(attr: *mut ::pthread_rwlock_t) -> ::c_int; + + // pthread.h + pub fn pthread_rwlock_timedwrlock( + attr: *mut ::pthread_rwlock_t, + host: *const ::timespec, + ) -> ::c_int; + + // pthread.h + pub fn pthread_rwlock_unlock(attr: *mut ::pthread_rwlock_t) -> ::c_int; + + // pthread.h + pub fn pthread_key_create( + key: *mut ::pthread_key_t, + dtor: ::Option, + ) -> ::c_int; + + // pthread.h + pub fn pthread_key_delete(key: ::pthread_key_t) -> ::c_int; + + // pthread.h + pub fn pthread_setspecific(key: ::pthread_key_t, value: *const ::c_void) -> ::c_int; + + // pthread.h + pub fn pthread_getspecific(key: ::pthread_key_t) -> *mut ::c_void; + + // pthread.h + pub fn pthread_cond_timedwait( + cond: *mut ::pthread_cond_t, + mutex: *mut ::pthread_mutex_t, + abstime: *const ::timespec, + ) -> ::c_int; + + // pthread.h + pub fn pthread_attr_getname(attr: *mut ::pthread_attr_t, name: *mut *mut ::c_char) -> ::c_int; + + // pthread.h + pub fn pthread_join(thread: ::pthread_t, status: *mut *mut ::c_void) -> ::c_int; + + // pthread.h + pub fn pthread_self() -> ::pthread_t; + + // clockLib.h + pub fn clock_gettime(clock_id: ::clockid_t, tp: *mut ::timespec) -> ::c_int; + + // clockLib.h + pub fn clock_settime(clock_id: ::clockid_t, tp: *const ::timespec) -> ::c_int; + + // clockLib.h + pub fn clock_getres(clock_id: ::clockid_t, res: *mut ::timespec) -> ::c_int; + + // clockLib.h + pub fn clock_nanosleep( + clock_id: ::clockid_t, + flags: ::c_int, + rqtp: *const ::timespec, + rmtp: *mut ::timespec, + ) -> ::c_int; + + // timerLib.h + pub fn nanosleep(rqtp: *const ::timespec, rmtp: *mut ::timespec) -> ::c_int; + + // socket.h + pub fn accept(s: ::c_int, addr: *mut ::sockaddr, addrlen: *mut ::socklen_t) -> ::c_int; + + // socket.h + pub fn bind(fd: ::c_int, addr: *const sockaddr, len: socklen_t) -> ::c_int; + + // socket.h + pub fn connect(s: ::c_int, name: *const ::sockaddr, namelen: ::socklen_t) -> ::c_int; + + // socket.h + pub fn getpeername(s: ::c_int, name: *mut ::sockaddr, namelen: *mut ::socklen_t) -> ::c_int; + + // socket.h + pub fn getsockname( + socket: ::c_int, + address: *mut sockaddr, + address_len: *mut socklen_t, + ) -> ::c_int; + + // socket.h + pub fn getsockopt( + sockfd: ::c_int, + level: ::c_int, + optname: ::c_int, + optval: *mut ::c_void, + optlen: *mut ::socklen_t, + ) -> ::c_int; + + // socket.h + pub fn listen(socket: ::c_int, backlog: ::c_int) -> ::c_int; + + // socket.h + pub fn recv(s: ::c_int, buf: *mut ::c_void, bufLen: ::size_t, flags: ::c_int) -> ::ssize_t; + + // socket.h + pub fn recvfrom( + s: ::c_int, + buf: *mut ::c_void, + bufLen: ::size_t, + flags: ::c_int, + from: *mut ::sockaddr, + pFromLen: *mut ::socklen_t, + ) -> ::ssize_t; + + pub fn recvmsg(socket: ::c_int, mp: *mut ::msghdr, flags: ::c_int) -> ::ssize_t; + + // socket.h + pub fn send(socket: ::c_int, buf: *const ::c_void, len: ::size_t, flags: ::c_int) -> ::ssize_t; + + pub fn sendmsg(socket: ::c_int, mp: *const ::msghdr, flags: ::c_int) -> ::ssize_t; + + // socket.h + pub fn sendto( + socket: ::c_int, + buf: *const ::c_void, + len: ::size_t, + flags: ::c_int, + addr: *const sockaddr, + addrlen: socklen_t, + ) -> ::ssize_t; + + // socket.h + pub fn setsockopt( + socket: ::c_int, + level: ::c_int, + name: ::c_int, + value: *const ::c_void, + option_len: socklen_t, + ) -> ::c_int; + + // socket.h + pub fn shutdown(s: ::c_int, how: ::c_int) -> ::c_int; + + // socket.h + pub fn socket(domain: ::c_int, _type: ::c_int, protocol: ::c_int) -> ::c_int; + + // icotl.h + pub fn ioctl(fd: ::c_int, request: ::c_int, ...) -> ::c_int; + + // fcntl.h + pub fn fcntl(fd: ::c_int, cmd: ::c_int, ...) -> ::c_int; + + // ntp_rfc2553.h for kernel + // netdb.h for user + pub fn gai_strerror(errcode: ::c_int) -> *mut ::c_char; + + // ioLib.h or + // unistd.h + pub fn close(fd: ::c_int) -> ::c_int; + + // ioLib.h or + // unistd.h + pub fn read(fd: ::c_int, buf: *mut ::c_void, count: ::size_t) -> ::ssize_t; + + // ioLib.h or + // unistd.h + pub fn write(fd: ::c_int, buf: *const ::c_void, count: ::size_t) -> ::ssize_t; + + // ioLib.h or + // unistd.h + pub fn isatty(fd: ::c_int) -> ::c_int; + + // ioLib.h or + // unistd.h + pub fn dup(src: ::c_int) -> ::c_int; + + // ioLib.h or + // unistd.h + pub fn dup2(src: ::c_int, dst: ::c_int) -> ::c_int; + + // ioLib.h or + // unistd.h + pub fn pipe(fds: *mut ::c_int) -> ::c_int; + + // ioLib.h or + // unistd.h + pub fn unlink(pathname: *const ::c_char) -> ::c_int; + + // unistd.h and + // ioLib.h + pub fn lseek(fd: ::c_int, offset: off_t, whence: ::c_int) -> off_t; + + // netdb.h + pub fn getaddrinfo( + node: *const ::c_char, + service: *const ::c_char, + hints: *const addrinfo, + res: *mut *mut addrinfo, + ) -> ::c_int; + + // netdb.h + pub fn freeaddrinfo(res: *mut addrinfo); + + // signal.h + pub fn signal(signum: ::c_int, handler: sighandler_t) -> sighandler_t; + + // unistd.h + pub fn getpid() -> pid_t; + + // unistd.h + pub fn getppid() -> pid_t; + + // wait.h + pub fn waitpid(pid: pid_t, status: *mut ::c_int, optons: ::c_int) -> pid_t; + + // unistd.h + pub fn sysconf(attr: ::c_int) -> ::c_long; + + // stdlib.h + pub fn setenv( + // setenv.c + envVarName: *const ::c_char, + envVarValue: *const ::c_char, + overwrite: ::c_int, + ) -> ::c_int; + + // stdlib.h + pub fn unsetenv( + // setenv.c + envVarName: *const ::c_char, + ) -> ::c_int; + + // stdlib.h + pub fn realpath(fileName: *const ::c_char, resolvedName: *mut ::c_char) -> *mut ::c_char; + + // unistd.h + pub fn link(src: *const ::c_char, dst: *const ::c_char) -> ::c_int; + + // unistd.h + pub fn readlink(path: *const ::c_char, buf: *mut ::c_char, bufsize: ::size_t) -> ::ssize_t; + + // unistd.h + pub fn symlink(path1: *const ::c_char, path2: *const ::c_char) -> ::c_int; + + // dirent.h + pub fn opendir(name: *const ::c_char) -> *mut ::DIR; + + // unistd.h + pub fn rmdir(path: *const ::c_char) -> ::c_int; + + // stat.h + pub fn mkdir(dirName: *const ::c_char, mode: ::mode_t) -> ::c_int; + + // stat.h + pub fn chmod(path: *const ::c_char, mode: ::mode_t) -> ::c_int; + + // stat.h + pub fn fchmod(attr1: ::c_int, attr2: ::mode_t) -> ::c_int; + + // unistd.h + pub fn fsync(fd: ::c_int) -> ::c_int; + + // dirent.h + pub fn closedir(ptr: *mut ::DIR) -> ::c_int; + + //sched.h + pub fn sched_get_priority_max(policy: ::c_int) -> ::c_int; + + //sched.h + pub fn sched_get_priority_min(policy: ::c_int) -> ::c_int; + + //sched.h + pub fn sched_setparam(pid: ::pid_t, param: *const ::sched_param) -> ::c_int; + + //sched.h + pub fn sched_getparam(pid: ::pid_t, param: *mut ::sched_param) -> ::c_int; + + //sched.h + pub fn sched_setscheduler( + pid: ::pid_t, + policy: ::c_int, + param: *const ::sched_param, + ) -> ::c_int; + + //sched.h + pub fn sched_getscheduler(pid: ::pid_t) -> ::c_int; + + //sched.h + pub fn sched_rr_get_interval(pid: ::pid_t, tp: *mut ::timespec) -> ::c_int; + + // sched.h + pub fn sched_yield() -> ::c_int; + + // errnoLib.h + pub fn errnoSet(err: ::c_int) -> ::c_int; + + // errnoLib.h + pub fn errnoGet() -> ::c_int; + + // unistd.h + pub fn _exit(status: ::c_int) -> !; + + // unistd.h + pub fn setgid(gid: ::gid_t) -> ::c_int; + + // unistd.h + pub fn getgid() -> ::gid_t; + + // unistd.h + pub fn setuid(uid: ::uid_t) -> ::c_int; + + // unistd.h + pub fn getuid() -> ::uid_t; + + // signal.h + pub fn sigemptyset(__set: *mut sigset_t) -> ::c_int; + + // pthread.h for kernel + // signal.h for user + pub fn pthread_sigmask( + __how: ::c_int, + __set: *const sigset_t, + __oset: *mut sigset_t, + ) -> ::c_int; + + // signal.h for user + pub fn kill(__pid: pid_t, __signo: ::c_int) -> ::c_int; + + // signal.h for user + pub fn sigqueue(__pid: pid_t, __signo: ::c_int, __value: ::sigval) -> ::c_int; + + // signal.h for user + pub fn _sigqueue( + rtpId: ::RTP_ID, + signo: ::c_int, + pValue: *const ::sigval, + sigCode: ::c_int, + ) -> ::c_int; + + // signal.h + pub fn taskKill(taskId: ::TASK_ID, signo: ::c_int) -> ::c_int; + + // signal.h + pub fn raise(__signo: ::c_int) -> ::c_int; + + // taskLibCommon.h + pub fn taskIdSelf() -> ::TASK_ID; + pub fn taskDelay(ticks: ::_Vx_ticks_t) -> ::c_int; + + // taskLib.h + pub fn taskNameSet(task_id: ::TASK_ID, task_name: *mut ::c_char) -> ::c_int; + pub fn taskNameGet(task_id: ::TASK_ID, buf_name: *mut ::c_char, bufsize: ::size_t) -> ::c_int; + + // rtpLibCommon.h + pub fn rtpInfoGet(rtpId: ::RTP_ID, rtpStruct: *mut ::RTP_DESC) -> ::c_int; + pub fn rtpSpawn( + pubrtpFileName: *const ::c_char, + argv: *mut *const ::c_char, + envp: *mut *const ::c_char, + priority: ::c_int, + uStackSize: ::size_t, + options: ::c_int, + taskOptions: ::c_int, + ) -> RTP_ID; + + // ioLib.h + pub fn _realpath(fileName: *const ::c_char, resolvedName: *mut ::c_char) -> *mut ::c_char; + + // pathLib.h + pub fn _pathIsAbsolute(filepath: *const ::c_char, pNameTail: *mut *const ::c_char) -> BOOL; + + 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; + + // randomNumGen.h + pub fn randBytes(buf: *mut c_uchar, length: c_int) -> c_int; + pub fn randABytes(buf: *mut c_uchar, length: c_int) -> c_int; + pub fn randUBytes(buf: *mut c_uchar, length: c_int) -> c_int; + pub fn randSecure() -> c_int; + + // mqueue.h + 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; + + // vxCpuLib.h + pub fn vxCpuEnabledGet() -> ::cpuset_t; // Get set of running CPU's in the system + pub fn vxCpuConfiguredGet() -> ::cpuset_t; // Get set of Configured CPU's in the system +} + +//Dummy functions, these don't really exist in VxWorks. + +// wait.h macros +safe_f! { + pub {const} fn WIFEXITED(status: ::c_int) -> bool { + (status & 0xFF00) == 0 + } + pub {const} fn WIFSIGNALED(status: ::c_int) -> bool { + (status & 0xFF00) != 0 + } + pub {const} fn WIFSTOPPED(status: ::c_int) -> bool { + (status & 0xFF0000) != 0 + } + pub {const} fn WEXITSTATUS(status: ::c_int) -> ::c_int { + status & 0xFF + } + pub {const} fn WTERMSIG(status: ::c_int) -> ::c_int { + (status >> 8) & 0xFF + } + pub {const} fn WSTOPSIG(status: ::c_int) -> ::c_int { + (status >> 16) & 0xFF + } +} + +pub fn pread(_fd: ::c_int, _buf: *mut ::c_void, _count: ::size_t, _offset: off64_t) -> ::ssize_t { + -1 +} + +pub fn pwrite( + _fd: ::c_int, + _buf: *const ::c_void, + _count: ::size_t, + _offset: off64_t, +) -> ::ssize_t { + -1 +} +pub fn posix_memalign(memptr: *mut *mut ::c_void, align: ::size_t, size: ::size_t) -> ::c_int { + // check to see if align is a power of 2 and if align is a multiple + // of sizeof(void *) + if (align & align - 1 != 0) || (align as usize % size_of::<::size_t>() != 0) { + return ::EINVAL; + } + + unsafe { + // posix_memalign should not set errno + let e = ::errnoGet(); + + let temp = memalign(align, size); + ::errnoSet(e as ::c_int); + + if temp.is_null() { + ::ENOMEM + } else { + *memptr = temp; + 0 + } + } +} + +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(target_arch = "arm")] { + mod arm; + pub use self::arm::*; + } 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 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 = "riscv32")] { + mod riscv32; + pub use self::riscv32::*; + } else if #[cfg(target_arch = "riscv64")] { + mod riscv64; + pub use self::riscv64::*; + } else { + // Unknown target_arch + } +} diff --git a/vendor/libc/src/vxworks/powerpc.rs b/vendor/libc/src/vxworks/powerpc.rs new file mode 100644 index 0000000..5524006 --- /dev/null +++ b/vendor/libc/src/vxworks/powerpc.rs @@ -0,0 +1,4 @@ +pub type c_char = u8; +pub type wchar_t = u32; +pub type c_long = i32; +pub type c_ulong = u32; diff --git a/vendor/libc/src/vxworks/powerpc64.rs b/vendor/libc/src/vxworks/powerpc64.rs new file mode 100644 index 0000000..4032488 --- /dev/null +++ b/vendor/libc/src/vxworks/powerpc64.rs @@ -0,0 +1,4 @@ +pub type c_char = u8; +pub type wchar_t = u32; +pub type c_long = i64; +pub type c_ulong = u64; diff --git a/vendor/libc/src/vxworks/riscv32.rs b/vendor/libc/src/vxworks/riscv32.rs new file mode 100644 index 0000000..e617bb8 --- /dev/null +++ b/vendor/libc/src/vxworks/riscv32.rs @@ -0,0 +1,4 @@ +pub type c_char = i8; +pub type wchar_t = i32; +pub type c_long = i32; +pub type c_ulong = u32; diff --git a/vendor/libc/src/vxworks/riscv64.rs b/vendor/libc/src/vxworks/riscv64.rs new file mode 100644 index 0000000..5e95ea2 --- /dev/null +++ b/vendor/libc/src/vxworks/riscv64.rs @@ -0,0 +1,4 @@ +pub type c_char = i8; +pub type wchar_t = i32; +pub type c_long = i64; +pub type c_ulong = u64; diff --git a/vendor/libc/src/vxworks/x86.rs b/vendor/libc/src/vxworks/x86.rs new file mode 100644 index 0000000..e617bb8 --- /dev/null +++ b/vendor/libc/src/vxworks/x86.rs @@ -0,0 +1,4 @@ +pub type c_char = i8; +pub type wchar_t = i32; +pub type c_long = i32; +pub type c_ulong = u32; diff --git a/vendor/libc/src/vxworks/x86_64.rs b/vendor/libc/src/vxworks/x86_64.rs new file mode 100644 index 0000000..5e95ea2 --- /dev/null +++ b/vendor/libc/src/vxworks/x86_64.rs @@ -0,0 +1,4 @@ +pub type c_char = i8; +pub type wchar_t = i32; +pub type c_long = i64; +pub type c_ulong = u64; diff --git a/vendor/libc/src/wasi/mod.rs b/vendor/libc/src/wasi/mod.rs new file mode 100644 index 0000000..d47d407 --- /dev/null +++ b/vendor/libc/src/wasi/mod.rs @@ -0,0 +1,888 @@ +use super::{Send, Sync}; +use core::iter::Iterator; + +pub use ffi::c_void; + +pub type c_char = i8; +pub type c_uchar = u8; +pub type c_schar = i8; +pub type c_int = i32; +pub type c_uint = u32; +pub type c_short = i16; +pub type c_ushort = u16; +pub type c_long = i32; +pub type c_ulong = u32; +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 ssize_t = isize; +pub type ptrdiff_t = isize; +pub type intptr_t = isize; +pub type uintptr_t = usize; +pub type off_t = i64; +pub type pid_t = i32; +pub type clock_t = c_longlong; +pub type time_t = c_longlong; +pub type c_double = f64; +pub type c_float = f32; +pub type ino_t = u64; +pub type sigset_t = c_uchar; +pub type suseconds_t = c_longlong; +pub type mode_t = u32; +pub type dev_t = u64; +pub type uid_t = u32; +pub type gid_t = u32; +pub type nlink_t = u64; +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 {} +#[allow(missing_copy_implementations)] +#[cfg_attr(feature = "extra_traits", derive(Debug))] +pub enum DIR {} +#[allow(missing_copy_implementations)] +#[cfg_attr(feature = "extra_traits", derive(Debug))] +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)] + #[allow(dead_code)] + 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 { + data: [u8; 16], + } + + 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_int, + pub __tm_zone: *const c_char, + pub __tm_nsec: c_int, + } + + pub struct timeval { + pub tv_sec: time_t, + pub tv_usec: suseconds_t, + } + + pub struct timespec { + pub tv_sec: time_t, + pub tv_nsec: c_long, + } + + pub struct tms { + pub tms_utime: clock_t, + pub tms_stime: clock_t, + pub tms_cutime: clock_t, + pub tms_cstime: clock_t, + } + + pub struct itimerspec { + pub it_interval: timespec, + pub it_value: timespec, + } + + pub struct iovec { + pub iov_base: *mut c_void, + pub iov_len: size_t, + } + + 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_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 pollfd { + pub fd: c_int, + pub events: c_short, + pub revents: c_short, + } + + pub struct rusage { + pub ru_utime: timeval, + pub ru_stime: timeval, + } + + 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_uint, + pub st_rdev: dev_t, + pub st_size: off_t, + pub st_blksize: blksize_t, + pub st_blocks: blkcnt_t, + pub st_atim: timespec, + pub st_mtim: timespec, + pub st_ctim: timespec, + __reserved: [c_longlong; 3], + } + + pub struct fd_set { + __nfds: usize, + __fds: [c_int; FD_SETSIZE as usize], + } +} + +// Declare dirent outside of s! so that it doesn't implement Copy, Eq, Hash, +// etc., since it contains a flexible array member with a dynamic size. +#[repr(C)] +#[allow(missing_copy_implementations)] +#[cfg_attr(feature = "extra_traits", derive(Debug))] +pub struct dirent { + pub d_ino: ino_t, + pub d_type: c_uchar, + /// d_name is declared in WASI libc as a flexible array member, which + /// can't be directly expressed in Rust. As an imperfect workaround, + /// declare it as a zero-length array instead. + pub d_name: [c_char; 0], +} + +pub const EXIT_SUCCESS: c_int = 0; +pub const EXIT_FAILURE: c_int = 1; +pub const STDIN_FILENO: c_int = 0; +pub const STDOUT_FILENO: c_int = 1; +pub const STDERR_FILENO: c_int = 2; +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_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 FD_CLOEXEC: c_int = 1; +pub const FD_SETSIZE: size_t = 1024; +pub const O_APPEND: c_int = 0x0001; +pub const O_DSYNC: c_int = 0x0002; +pub const O_NONBLOCK: c_int = 0x0004; +pub const O_RSYNC: c_int = 0x0008; +pub const O_SYNC: c_int = 0x0010; +pub const O_CREAT: c_int = 0x0001 << 12; +pub const O_DIRECTORY: c_int = 0x0002 << 12; +pub const O_EXCL: c_int = 0x0004 << 12; +pub const O_TRUNC: c_int = 0x0008 << 12; +pub const O_NOFOLLOW: c_int = 0x01000000; +pub const O_EXEC: c_int = 0x02000000; +pub const O_RDONLY: c_int = 0x04000000; +pub const O_SEARCH: c_int = 0x08000000; +pub const O_WRONLY: c_int = 0x10000000; +pub const O_CLOEXEC: c_int = 0x0; +pub const O_RDWR: c_int = O_WRONLY | O_RDONLY; +pub const O_ACCMODE: c_int = O_EXEC | O_RDWR | O_SEARCH; +pub const O_NOCTTY: c_int = 0x0; +pub const POSIX_FADV_DONTNEED: c_int = 4; +pub const POSIX_FADV_NOREUSE: c_int = 5; +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 = -2; +pub const AT_EACCESS: c_int = 0x0; +pub const AT_SYMLINK_NOFOLLOW: c_int = 0x1; +pub const AT_SYMLINK_FOLLOW: c_int = 0x2; +pub const AT_REMOVEDIR: c_int = 0x4; +pub const UTIME_OMIT: c_long = 0xfffffffe; +pub const UTIME_NOW: c_long = 0xffffffff; +pub const S_IFIFO: mode_t = 0o1_0000; +pub const S_IFCHR: mode_t = 8192; +pub const S_IFBLK: mode_t = 24576; +pub const S_IFDIR: mode_t = 16384; +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 = 0o17_0000; +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; +pub const DT_DIR: u8 = 3; +pub const DT_REG: u8 = 4; +pub const DT_LNK: u8 = 7; +pub const FIONREAD: c_int = 1; +pub const FIONBIO: c_int = 2; +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; +pub const POLLIN: ::c_short = 0x1; +pub const POLLOUT: ::c_short = 0x2; +pub const POLLERR: ::c_short = 0x1000; +pub const POLLHUP: ::c_short = 0x2000; +pub const POLLNVAL: ::c_short = 0x4000; +pub const POLLRDNORM: ::c_short = 0x1; +pub const POLLWRNORM: ::c_short = 0x2; + +pub const E2BIG: c_int = 1; +pub const EACCES: c_int = 2; +pub const EADDRINUSE: c_int = 3; +pub const EADDRNOTAVAIL: c_int = 4; +pub const EAFNOSUPPORT: c_int = 5; +pub const EAGAIN: c_int = 6; +pub const EALREADY: c_int = 7; +pub const EBADF: c_int = 8; +pub const EBADMSG: c_int = 9; +pub const EBUSY: c_int = 10; +pub const ECANCELED: c_int = 11; +pub const ECHILD: c_int = 12; +pub const ECONNABORTED: c_int = 13; +pub const ECONNREFUSED: c_int = 14; +pub const ECONNRESET: c_int = 15; +pub const EDEADLK: c_int = 16; +pub const EDESTADDRREQ: c_int = 17; +pub const EDOM: c_int = 18; +pub const EDQUOT: c_int = 19; +pub const EEXIST: c_int = 20; +pub const EFAULT: c_int = 21; +pub const EFBIG: c_int = 22; +pub const EHOSTUNREACH: c_int = 23; +pub const EIDRM: c_int = 24; +pub const EILSEQ: c_int = 25; +pub const EINPROGRESS: c_int = 26; +pub const EINTR: c_int = 27; +pub const EINVAL: c_int = 28; +pub const EIO: c_int = 29; +pub const EISCONN: c_int = 30; +pub const EISDIR: c_int = 31; +pub const ELOOP: c_int = 32; +pub const EMFILE: c_int = 33; +pub const EMLINK: c_int = 34; +pub const EMSGSIZE: c_int = 35; +pub const EMULTIHOP: c_int = 36; +pub const ENAMETOOLONG: c_int = 37; +pub const ENETDOWN: c_int = 38; +pub const ENETRESET: c_int = 39; +pub const ENETUNREACH: c_int = 40; +pub const ENFILE: c_int = 41; +pub const ENOBUFS: c_int = 42; +pub const ENODEV: c_int = 43; +pub const ENOENT: c_int = 44; +pub const ENOEXEC: c_int = 45; +pub const ENOLCK: c_int = 46; +pub const ENOLINK: c_int = 47; +pub const ENOMEM: c_int = 48; +pub const ENOMSG: c_int = 49; +pub const ENOPROTOOPT: c_int = 50; +pub const ENOSPC: c_int = 51; +pub const ENOSYS: c_int = 52; +pub const ENOTCONN: c_int = 53; +pub const ENOTDIR: c_int = 54; +pub const ENOTEMPTY: c_int = 55; +pub const ENOTRECOVERABLE: c_int = 56; +pub const ENOTSOCK: c_int = 57; +pub const ENOTSUP: c_int = 58; +pub const ENOTTY: c_int = 59; +pub const ENXIO: c_int = 60; +pub const EOVERFLOW: c_int = 61; +pub const EOWNERDEAD: c_int = 62; +pub const EPERM: c_int = 63; +pub const EPIPE: c_int = 64; +pub const EPROTO: c_int = 65; +pub const EPROTONOSUPPORT: c_int = 66; +pub const EPROTOTYPE: c_int = 67; +pub const ERANGE: c_int = 68; +pub const EROFS: c_int = 69; +pub const ESPIPE: c_int = 70; +pub const ESRCH: c_int = 71; +pub const ESTALE: c_int = 72; +pub const ETIMEDOUT: c_int = 73; +pub const ETXTBSY: c_int = 74; +pub const EXDEV: c_int = 75; +pub const ENOTCAPABLE: c_int = 76; +pub const EOPNOTSUPP: c_int = ENOTSUP; +pub const EWOULDBLOCK: c_int = EAGAIN; + +pub const _SC_PAGESIZE: c_int = 30; +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; + +cfg_if! { + if #[cfg(libc_ctest)] { + // skip these constants when this is active because `ctest` currently + // panics on parsing the constants below + } else { + // `addr_of!(EXTERN_STATIC)` is now safe; remove `unsafe` when MSRV >= 1.82 + #[allow(unused_unsafe)] + pub static CLOCK_MONOTONIC: clockid_t = + unsafe { clockid_t(ptr_addr_of!(_CLOCK_MONOTONIC)) }; + #[allow(unused_unsafe)] + pub static CLOCK_PROCESS_CPUTIME_ID: clockid_t = + unsafe { clockid_t(ptr_addr_of!(_CLOCK_PROCESS_CPUTIME_ID)) }; + #[allow(unused_unsafe)] + pub static CLOCK_REALTIME: clockid_t = + unsafe { clockid_t(ptr_addr_of!(_CLOCK_REALTIME)) }; + #[allow(unused_unsafe)] + 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; + +f! { + pub fn FD_ISSET(fd: ::c_int, set: *const fd_set) -> bool { + let set = &*set; + let n = set.__nfds; + return set.__fds[..n].iter().any(|p| *p == fd) + } + + pub fn FD_SET(fd: ::c_int, set: *mut fd_set) -> () { + let set = &mut *set; + let n = set.__nfds; + if !set.__fds[..n].iter().any(|p| *p == fd) { + set.__nfds = n + 1; + set.__fds[n] = fd; + } + } + + pub fn FD_ZERO(set: *mut fd_set) -> () { + (*set).__nfds = 0; + return + } +} + +#[cfg_attr( + feature = "rustc-dep-of-std", + 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 "C" { + pub fn _Exit(code: c_int) -> !; + pub fn _exit(code: c_int) -> !; + pub fn abort() -> !; + pub fn aligned_alloc(a: size_t, b: size_t) -> *mut c_void; + pub fn calloc(amt: size_t, amt2: size_t) -> *mut c_void; + pub fn exit(code: c_int) -> !; + pub fn free(ptr: *mut c_void); + pub fn getenv(s: *const c_char) -> *mut c_char; + pub fn malloc(amt: size_t) -> *mut c_void; + pub fn malloc_usable_size(ptr: *mut c_void) -> size_t; + pub fn sbrk(increment: ::intptr_t) -> *mut ::c_void; + pub fn rand() -> c_int; + pub fn read(fd: c_int, ptr: *mut c_void, size: size_t) -> ssize_t; + pub fn realloc(ptr: *mut c_void, amt: size_t) -> *mut c_void; + pub fn setenv(k: *const c_char, v: *const c_char, a: c_int) -> c_int; + pub fn unsetenv(k: *const c_char) -> c_int; + pub fn clearenv() -> ::c_int; + pub fn write(fd: c_int, ptr: *const c_void, size: size_t) -> ssize_t; + pub static mut environ: *mut *mut c_char; + pub fn fopen(a: *const c_char, b: *const c_char) -> *mut FILE; + pub fn freopen(a: *const c_char, b: *const c_char, f: *mut FILE) -> *mut FILE; + pub fn fclose(f: *mut FILE) -> c_int; + pub fn remove(a: *const c_char) -> c_int; + pub fn rename(a: *const c_char, b: *const c_char) -> c_int; + pub fn feof(f: *mut FILE) -> c_int; + pub fn ferror(f: *mut FILE) -> c_int; + pub fn fflush(f: *mut FILE) -> c_int; + pub fn clearerr(f: *mut FILE); + pub fn fseek(f: *mut FILE, b: c_long, c: c_int) -> c_int; + pub fn ftell(f: *mut FILE) -> c_long; + pub fn rewind(f: *mut FILE); + pub fn fgetpos(f: *mut FILE, pos: *mut fpos_t) -> c_int; + pub fn fsetpos(f: *mut FILE, pos: *const fpos_t) -> c_int; + pub fn fread(buf: *mut c_void, a: size_t, b: size_t, f: *mut FILE) -> size_t; + pub fn fwrite(buf: *const c_void, a: size_t, b: size_t, f: *mut FILE) -> size_t; + pub fn fgetc(f: *mut FILE) -> c_int; + pub fn getc(f: *mut FILE) -> c_int; + pub fn getchar() -> c_int; + pub fn ungetc(a: c_int, f: *mut FILE) -> c_int; + pub fn fputc(a: c_int, f: *mut FILE) -> c_int; + pub fn putc(a: c_int, f: *mut FILE) -> c_int; + pub fn putchar(a: c_int) -> c_int; + pub fn fputs(a: *const c_char, f: *mut FILE) -> c_int; + pub fn puts(a: *const c_char) -> c_int; + pub fn perror(a: *const c_char); + pub fn srand(a: c_uint); + pub fn atexit(a: extern "C" fn()) -> c_int; + pub fn at_quick_exit(a: extern "C" fn()) -> c_int; + pub fn quick_exit(a: c_int) -> !; + pub fn posix_memalign(a: *mut *mut c_void, b: size_t, c: size_t) -> c_int; + pub fn rand_r(a: *mut c_uint) -> c_int; + pub fn random() -> c_long; + pub fn srandom(a: c_uint); + pub fn putenv(a: *mut c_char) -> c_int; + pub fn clock() -> clock_t; + pub fn time(a: *mut time_t) -> time_t; + pub fn difftime(a: time_t, b: time_t) -> c_double; + pub fn mktime(a: *mut tm) -> time_t; + pub fn strftime(a: *mut c_char, b: size_t, c: *const c_char, d: *const tm) -> size_t; + pub fn gmtime(a: *const time_t) -> *mut tm; + pub fn gmtime_r(a: *const time_t, b: *mut tm) -> *mut tm; + pub fn localtime(a: *const time_t) -> *mut tm; + pub fn localtime_r(a: *const time_t, b: *mut tm) -> *mut tm; + 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 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; + 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 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; + 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; + pub fn strncmp(cs: *const c_char, ct: *const c_char, n: size_t) -> c_int; + pub fn strcoll(cs: *const c_char, ct: *const c_char) -> c_int; + pub fn strchr(cs: *const c_char, c: c_int) -> *mut c_char; + pub fn strrchr(cs: *const c_char, c: c_int) -> *mut c_char; + pub fn strspn(cs: *const c_char, ct: *const c_char) -> size_t; + pub fn strcspn(cs: *const c_char, ct: *const c_char) -> size_t; + pub fn strdup(cs: *const c_char) -> *mut c_char; + pub fn strndup(cs: *const c_char, n: size_t) -> *mut c_char; + pub fn strpbrk(cs: *const c_char, ct: *const c_char) -> *mut c_char; + pub fn strstr(cs: *const c_char, ct: *const c_char) -> *mut c_char; + pub fn strcasecmp(s1: *const c_char, s2: *const c_char) -> c_int; + pub fn strncasecmp(s1: *const c_char, s2: *const c_char, n: size_t) -> c_int; + pub fn strlen(cs: *const c_char) -> size_t; + pub fn strnlen(cs: *const c_char, maxlen: size_t) -> size_t; + 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 strxfrm(s: *mut c_char, ct: *const c_char, n: size_t) -> size_t; + + pub fn memchr(cx: *const c_void, c: c_int, n: size_t) -> *mut c_void; + pub fn memcmp(cx: *const c_void, ct: *const c_void, n: size_t) -> c_int; + pub fn memcpy(dest: *mut c_void, src: *const c_void, n: size_t) -> *mut c_void; + pub fn memmove(dest: *mut c_void, src: *const c_void, n: size_t) -> *mut c_void; + pub fn memset(dest: *mut c_void, c: c_int, n: size_t) -> *mut c_void; + + pub fn fprintf(stream: *mut ::FILE, format: *const ::c_char, ...) -> ::c_int; + pub fn printf(format: *const ::c_char, ...) -> ::c_int; + pub fn snprintf(s: *mut ::c_char, n: ::size_t, format: *const ::c_char, ...) -> ::c_int; + pub fn sprintf(s: *mut ::c_char, format: *const ::c_char, ...) -> ::c_int; + pub fn fscanf(stream: *mut ::FILE, format: *const ::c_char, ...) -> ::c_int; + pub fn scanf(format: *const ::c_char, ...) -> ::c_int; + pub fn sscanf(s: *const ::c_char, format: *const ::c_char, ...) -> ::c_int; + pub fn getchar_unlocked() -> ::c_int; + pub fn putchar_unlocked(c: ::c_int) -> ::c_int; + + pub fn shutdown(socket: ::c_int, how: ::c_int) -> ::c_int; + pub fn fstat(fildes: ::c_int, buf: *mut stat) -> ::c_int; + pub fn mkdir(path: *const c_char, mode: mode_t) -> ::c_int; + pub fn stat(path: *const c_char, buf: *mut stat) -> ::c_int; + pub fn fdopen(fd: ::c_int, mode: *const c_char) -> *mut ::FILE; + pub fn fileno(stream: *mut ::FILE) -> ::c_int; + pub fn open(path: *const c_char, oflag: ::c_int, ...) -> ::c_int; + pub fn creat(path: *const c_char, mode: mode_t) -> ::c_int; + pub fn fcntl(fd: ::c_int, cmd: ::c_int, ...) -> ::c_int; + pub fn opendir(dirname: *const c_char) -> *mut ::DIR; + pub fn fdopendir(fd: ::c_int) -> *mut ::DIR; + pub fn readdir(dirp: *mut ::DIR) -> *mut ::dirent; + pub fn closedir(dirp: *mut ::DIR) -> ::c_int; + pub fn rewinddir(dirp: *mut ::DIR); + pub fn dirfd(dirp: *mut ::DIR) -> ::c_int; + pub fn seekdir(dirp: *mut ::DIR, loc: ::c_long); + pub fn telldir(dirp: *mut ::DIR) -> ::c_long; + + pub fn openat(dirfd: ::c_int, pathname: *const ::c_char, flags: ::c_int, ...) -> ::c_int; + pub fn fstatat( + dirfd: ::c_int, + pathname: *const ::c_char, + buf: *mut stat, + flags: ::c_int, + ) -> ::c_int; + pub fn linkat( + olddirfd: ::c_int, + oldpath: *const ::c_char, + newdirfd: ::c_int, + newpath: *const ::c_char, + flags: ::c_int, + ) -> ::c_int; + pub fn mkdirat(dirfd: ::c_int, pathname: *const ::c_char, mode: ::mode_t) -> ::c_int; + pub fn readlinkat( + dirfd: ::c_int, + pathname: *const ::c_char, + buf: *mut ::c_char, + bufsiz: ::size_t, + ) -> ::ssize_t; + pub fn renameat( + olddirfd: ::c_int, + oldpath: *const ::c_char, + newdirfd: ::c_int, + newpath: *const ::c_char, + ) -> ::c_int; + pub fn symlinkat( + target: *const ::c_char, + newdirfd: ::c_int, + linkpath: *const ::c_char, + ) -> ::c_int; + pub fn unlinkat(dirfd: ::c_int, pathname: *const ::c_char, flags: ::c_int) -> ::c_int; + + pub fn access(path: *const c_char, amode: ::c_int) -> ::c_int; + pub fn close(fd: ::c_int) -> ::c_int; + pub fn fpathconf(filedes: ::c_int, name: ::c_int) -> c_long; + pub fn getopt(argc: ::c_int, argv: *const *mut c_char, optstr: *const c_char) -> ::c_int; + pub fn isatty(fd: ::c_int) -> ::c_int; + pub fn link(src: *const c_char, dst: *const c_char) -> ::c_int; + pub fn lseek(fd: ::c_int, offset: off_t, whence: ::c_int) -> off_t; + pub fn pathconf(path: *const c_char, name: ::c_int) -> c_long; + pub fn rmdir(path: *const c_char) -> ::c_int; + pub fn sleep(secs: ::c_uint) -> ::c_uint; + pub fn unlink(c: *const c_char) -> ::c_int; + pub fn pread(fd: ::c_int, buf: *mut ::c_void, count: ::size_t, offset: off_t) -> ::ssize_t; + pub fn pwrite(fd: ::c_int, buf: *const ::c_void, count: ::size_t, offset: off_t) -> ::ssize_t; + + pub fn lstat(path: *const c_char, buf: *mut stat) -> ::c_int; + + pub fn fsync(fd: ::c_int) -> ::c_int; + pub fn fdatasync(fd: ::c_int) -> ::c_int; + + 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 getrusage(resource: ::c_int, usage: *mut rusage) -> ::c_int; + + pub fn gettimeofday(tp: *mut ::timeval, tz: *mut ::c_void) -> ::c_int; + pub fn times(buf: *mut ::tms) -> ::clock_t; + + pub fn strerror_r(errnum: ::c_int, buf: *mut c_char, buflen: ::size_t) -> ::c_int; + + pub fn usleep(secs: ::c_uint) -> ::c_int; + pub fn send(socket: ::c_int, buf: *const ::c_void, len: ::size_t, flags: ::c_int) -> ::ssize_t; + pub fn recv(socket: ::c_int, buf: *mut ::c_void, len: ::size_t, flags: ::c_int) -> ::ssize_t; + pub fn poll(fds: *mut pollfd, nfds: nfds_t, timeout: ::c_int) -> ::c_int; + pub fn setlocale(category: ::c_int, locale: *const ::c_char) -> *mut ::c_char; + pub fn localeconv() -> *mut lconv; + + pub fn readlink(path: *const c_char, buf: *mut c_char, bufsz: ::size_t) -> ::ssize_t; + + pub fn timegm(tm: *mut ::tm) -> time_t; + + pub fn sysconf(name: ::c_int) -> ::c_long; + + pub fn ioctl(fd: ::c_int, request: ::c_int, ...) -> ::c_int; + + pub fn fseeko(stream: *mut ::FILE, offset: ::off_t, whence: ::c_int) -> ::c_int; + pub fn ftello(stream: *mut ::FILE) -> ::off_t; + pub fn posix_fallocate(fd: ::c_int, offset: ::off_t, len: ::off_t) -> ::c_int; + + pub fn strcasestr(cs: *const c_char, ct: *const c_char) -> *mut c_char; + pub fn getline(lineptr: *mut *mut c_char, n: *mut size_t, stream: *mut FILE) -> ssize_t; + + pub fn faccessat( + dirfd: ::c_int, + pathname: *const ::c_char, + mode: ::c_int, + flags: ::c_int, + ) -> ::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 pwritev(fd: ::c_int, iov: *const ::iovec, iovcnt: ::c_int, offset: ::off_t) + -> ::ssize_t; + pub fn preadv(fd: ::c_int, iov: *const ::iovec, iovcnt: ::c_int, offset: ::off_t) -> ::ssize_t; + 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 utimensat( + dirfd: ::c_int, + path: *const ::c_char, + times: *const ::timespec, + flag: ::c_int, + ) -> ::c_int; + pub fn getentropy(buf: *mut ::c_void, buflen: ::size_t) -> ::c_int; + pub fn memrchr(cx: *const ::c_void, c: ::c_int, n: ::size_t) -> *mut ::c_void; + pub fn abs(i: c_int) -> c_int; + pub fn labs(i: c_long) -> c_long; + pub fn duplocale(base: ::locale_t) -> ::locale_t; + pub fn freelocale(loc: ::locale_t); + 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 select( + nfds: c_int, + readfds: *mut fd_set, + writefds: *mut fd_set, + errorfds: *mut fd_set, + timeout: *const timeval, + ) -> c_int; + + 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; + pub fn __wasilibc_unlinkat(fd: c_int, path: *const c_char) -> c_int; + pub fn __wasilibc_rmdirat(fd: c_int, path: *const c_char) -> c_int; + pub fn __wasilibc_find_relpath( + path: *const c_char, + abs_prefix: *mut *const c_char, + relative_path: *mut *mut c_char, + relative_path_len: usize, + ) -> c_int; + pub fn __wasilibc_tell(fd: c_int) -> ::off_t; + pub fn __wasilibc_nocwd___wasilibc_unlinkat(dirfd: c_int, path: *const c_char) -> c_int; + pub fn __wasilibc_nocwd___wasilibc_rmdirat(dirfd: c_int, path: *const c_char) -> c_int; + pub fn __wasilibc_nocwd_linkat( + olddirfd: c_int, + oldpath: *const c_char, + newdirfd: c_int, + newpath: *const c_char, + flags: c_int, + ) -> c_int; + pub fn __wasilibc_nocwd_symlinkat( + target: *const c_char, + dirfd: c_int, + path: *const c_char, + ) -> c_int; + pub fn __wasilibc_nocwd_readlinkat( + dirfd: c_int, + path: *const c_char, + buf: *mut c_char, + bufsize: usize, + ) -> isize; + pub fn __wasilibc_nocwd_faccessat( + dirfd: c_int, + path: *const c_char, + mode: c_int, + flags: c_int, + ) -> c_int; + pub fn __wasilibc_nocwd_renameat( + olddirfd: c_int, + oldpath: *const c_char, + newdirfd: c_int, + newpath: *const c_char, + ) -> c_int; + pub fn __wasilibc_nocwd_openat_nomode(dirfd: c_int, path: *const c_char, flags: c_int) + -> c_int; + pub fn __wasilibc_nocwd_fstatat( + dirfd: c_int, + path: *const c_char, + buf: *mut stat, + flags: c_int, + ) -> c_int; + pub fn __wasilibc_nocwd_mkdirat_nomode(dirfd: c_int, path: *const c_char) -> c_int; + pub fn __wasilibc_nocwd_utimensat( + dirfd: c_int, + path: *const c_char, + times: *const ::timespec, + flags: c_int, + ) -> c_int; + pub fn __wasilibc_nocwd_opendirat(dirfd: c_int, path: *const c_char) -> *mut ::DIR; + pub fn __wasilibc_access(pathname: *const c_char, mode: c_int, flags: c_int) -> c_int; + pub fn __wasilibc_stat(pathname: *const c_char, buf: *mut stat, flags: c_int) -> c_int; + pub fn __wasilibc_utimens( + pathname: *const c_char, + times: *const ::timespec, + flags: c_int, + ) -> c_int; + pub fn __wasilibc_link(oldpath: *const c_char, newpath: *const c_char, flags: c_int) -> c_int; + pub fn __wasilibc_link_oldat( + olddirfd: c_int, + oldpath: *const c_char, + newpath: *const c_char, + flags: c_int, + ) -> c_int; + pub fn __wasilibc_link_newat( + oldpath: *const c_char, + newdirfd: c_int, + newpath: *const c_char, + flags: c_int, + ) -> c_int; + pub fn __wasilibc_rename_oldat( + olddirfd: c_int, + oldpath: *const c_char, + newpath: *const c_char, + ) -> c_int; + pub fn __wasilibc_rename_newat( + oldpath: *const c_char, + newdirfd: c_int, + newpath: *const c_char, + ) -> c_int; + + 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; +} + +cfg_if! { + if #[cfg(target_env = "p2")] { + mod p2; + pub use self::p2::*; + } +} diff --git a/vendor/libc/src/wasi/p2.rs b/vendor/libc/src/wasi/p2.rs new file mode 100644 index 0000000..3e8eb95 --- /dev/null +++ b/vendor/libc/src/wasi/p2.rs @@ -0,0 +1,161 @@ +pub type sa_family_t = ::c_ushort; +pub type in_port_t = ::c_ushort; +pub type in_addr_t = ::c_uint; + +pub type socklen_t = ::c_uint; + +s! { + #[repr(align(16))] + pub struct sockaddr { + pub sa_family: sa_family_t, + pub sa_data: [::c_char; 0], + } + + pub struct in_addr { + pub s_addr: in_addr_t, + } + + #[repr(align(16))] + pub struct sockaddr_in { + pub sin_family: sa_family_t, + pub sin_port: in_port_t, + pub sin_addr: in_addr, + } + + #[repr(align(4))] + pub struct in6_addr { + pub s6_addr: [::c_uchar; 16], + } + + #[repr(align(16))] + pub struct sockaddr_in6 { + pub sin6_family: sa_family_t, + pub sin6_port: in_port_t, + pub sin6_flowinfo: ::c_uint, + pub sin6_addr: in6_addr, + pub sin6_scope_id: ::c_uint, + } + + #[repr(align(16))] + pub struct sockaddr_storage { + pub ss_family: sa_family_t, + pub __ss_data: [::c_char; 32], + } + + 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_addr: *mut sockaddr, + pub ai_canonname: *mut ::c_char, + pub ai_next: *mut addrinfo, + } + + pub struct ip_mreq { + pub imr_multiaddr: in_addr, + pub imr_interface: in_addr, + } + + pub struct ipv6_mreq { + pub ipv6mr_multiaddr: in6_addr, + pub ipv6mr_interface: ::c_uint, + } +} + +pub const SHUT_RD: ::c_int = 1 << 0; +pub const SHUT_WR: ::c_int = 1 << 1; +pub const SHUT_RDWR: ::c_int = SHUT_RD | SHUT_WR; + +pub const MSG_NOSIGNAL: ::c_int = 0x4000; +pub const MSG_PEEK: ::c_int = 0x0002; + +pub const SO_REUSEADDR: ::c_int = 2; +pub const SO_ERROR: ::c_int = 4; +pub const SO_BROADCAST: ::c_int = 6; +pub const SO_LINGER: ::c_int = 13; +pub const SO_RCVTIMEO: ::c_int = 66; +pub const SO_SNDTIMEO: ::c_int = 67; + +pub const SOCK_DGRAM: ::c_int = 5; +pub const SOCK_STREAM: ::c_int = 6; + +pub const SOL_SOCKET: ::c_int = 0x7fffffff; + +pub const AF_INET: ::c_int = 1; +pub const AF_INET6: ::c_int = 2; + +pub const IPPROTO_IP: ::c_int = 0; +pub const IPPROTO_TCP: ::c_int = 6; +pub const IPPROTO_IPV6: ::c_int = 41; + +pub const IP_TTL: ::c_int = 2; +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 IPV6_MULTICAST_LOOP: ::c_int = 19; +pub const IPV6_JOIN_GROUP: ::c_int = 20; +pub const IPV6_LEAVE_GROUP: ::c_int = 21; +pub const IPV6_V6ONLY: ::c_int = 26; + +pub const IPV6_ADD_MEMBERSHIP: ::c_int = IPV6_JOIN_GROUP; +pub const IPV6_DROP_MEMBERSHIP: ::c_int = IPV6_LEAVE_GROUP; + +pub const TCP_NODELAY: ::c_int = 1; + +pub const EAI_SYSTEM: ::c_int = -11; + +extern "C" { + pub fn socket(domain: ::c_int, type_: ::c_int, protocol: ::c_int) -> ::c_int; + pub fn connect(fd: ::c_int, name: *const sockaddr, addrlen: socklen_t) -> ::c_int; + pub fn bind(socket: ::c_int, addr: *const sockaddr, addrlen: socklen_t) -> ::c_int; + pub fn listen(socket: ::c_int, backlog: ::c_int) -> ::c_int; + pub fn accept(socket: ::c_int, addr: *mut sockaddr, addrlen: *mut socklen_t) -> ::c_int; + + pub fn getsockname(socket: ::c_int, addr: *mut sockaddr, addrlen: *mut socklen_t) -> ::c_int; + pub fn getpeername(socket: ::c_int, addr: *mut sockaddr, addrlen: *mut socklen_t) -> ::c_int; + + pub fn sendto( + socket: ::c_int, + buffer: *const ::c_void, + length: ::size_t, + flags: ::c_int, + addr: *const sockaddr, + addrlen: socklen_t, + ) -> ::ssize_t; + pub fn recvfrom( + socket: ::c_int, + buffer: *mut ::c_void, + length: ::size_t, + flags: ::c_int, + addr: *mut sockaddr, + addrlen: *mut socklen_t, + ) -> ::ssize_t; + + pub fn getsockopt( + sockfd: ::c_int, + level: ::c_int, + optname: ::c_int, + optval: *mut ::c_void, + optlen: *mut socklen_t, + ) -> ::c_int; + pub fn setsockopt( + sockfd: ::c_int, + level: ::c_int, + optname: ::c_int, + optval: *const ::c_void, + optlen: socklen_t, + ) -> ::c_int; + + pub fn getaddrinfo( + host: *const ::c_char, + serv: *const ::c_char, + hint: *const addrinfo, + res: *mut *mut addrinfo, + ) -> ::c_int; + pub fn freeaddrinfo(p: *mut addrinfo); + pub fn gai_strerror(ecode: ::c_int) -> *const ::c_char; +} diff --git a/vendor/libc/src/windows/gnu/align.rs b/vendor/libc/src/windows/gnu/align.rs new file mode 100644 index 0000000..3af99e3 --- /dev/null +++ b/vendor/libc/src/windows/gnu/align.rs @@ -0,0 +1,19 @@ +cfg_if! { + if #[cfg(target_pointer_width = "64")] { + s_no_extra_traits! { + #[allow(missing_debug_implementations)] + #[repr(align(16))] + pub struct max_align_t { + priv_: [f64; 4] + } + } + } else if #[cfg(target_pointer_width = "32")] { + s_no_extra_traits! { + #[allow(missing_debug_implementations)] + #[repr(align(16))] + pub struct max_align_t { + priv_: [i64; 6] + } + } + } +} diff --git a/vendor/libc/src/windows/gnu/mod.rs b/vendor/libc/src/windows/gnu/mod.rs new file mode 100644 index 0000000..3e7d38b --- /dev/null +++ b/vendor/libc/src/windows/gnu/mod.rs @@ -0,0 +1,23 @@ +pub const L_tmpnam: ::c_uint = 14; +pub const TMP_MAX: ::c_uint = 0x7fff; + +// stdio file descriptor numbers +pub const STDIN_FILENO: ::c_int = 0; +pub const STDOUT_FILENO: ::c_int = 1; +pub const STDERR_FILENO: ::c_int = 2; + +extern "C" { + pub fn strcasecmp(s1: *const ::c_char, s2: *const ::c_char) -> ::c_int; + pub fn strncasecmp(s1: *const ::c_char, s2: *const ::c_char, n: ::size_t) -> ::c_int; + + // NOTE: For MSVC target, `wmemchr` is only a inline function in `` + // header file. We cannot find a way to link to that symbol from Rust. + pub fn wmemchr(cx: *const ::wchar_t, c: ::wchar_t, n: ::size_t) -> *mut ::wchar_t; +} + +cfg_if! { + if #[cfg(libc_align)] { + mod align; + pub use self::align::*; + } +} diff --git a/vendor/libc/src/windows/mod.rs b/vendor/libc/src/windows/mod.rs new file mode 100644 index 0000000..196f1f2 --- /dev/null +++ b/vendor/libc/src/windows/mod.rs @@ -0,0 +1,601 @@ +//! Windows CRT 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 sighandler_t = usize; + +pub type c_char = i8; +pub type c_long = i32; +pub type c_ulong = u32; +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; + } else { + pub type time_t = i64; + } +} + +pub type off_t = i32; +pub type dev_t = u32; +pub type ino_t = u16; +#[cfg_attr(feature = "extra_traits", derive(Debug))] +pub enum timezone {} +impl ::Copy for timezone {} +impl ::Clone for timezone { + fn clone(&self) -> timezone { + *self + } +} +pub type time64_t = i64; + +pub type SOCKET = ::uintptr_t; + +s! { + // note this is the struct called stat64 in Windows. Not stat, nor stati64. + pub struct stat { + pub st_dev: dev_t, + pub st_ino: ino_t, + pub st_mode: u16, + pub st_nlink: ::c_short, + pub st_uid: ::c_short, + pub st_gid: ::c_short, + pub st_rdev: dev_t, + pub st_size: i64, + pub st_atime: time64_t, + pub st_mtime: time64_t, + pub st_ctime: time64_t, + } + + // note that this is called utimbuf64 in Windows + pub struct utimbuf { + pub actime: time64_t, + pub modtime: time64_t, + } + + 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 timeval { + pub tv_sec: c_long, + pub tv_usec: c_long, + } + + pub struct timespec { + pub tv_sec: time_t, + pub tv_nsec: c_long, + } + + pub struct sockaddr { + pub sa_family: c_ushort, + pub sa_data: [c_char; 14], + } +} + +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 = 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 = 4; +pub const _IOLBF: ::c_int = 64; +pub const BUFSIZ: ::c_uint = 512; +pub const FOPEN_MAX: ::c_uint = 20; +pub const FILENAME_MAX: ::c_uint = 260; + +// fcntl.h +pub const O_RDONLY: ::c_int = 0x0000; +pub const O_WRONLY: ::c_int = 0x0001; +pub const O_RDWR: ::c_int = 0x0002; +pub const O_APPEND: ::c_int = 0x0008; +pub const O_CREAT: ::c_int = 0x0100; +pub const O_TRUNC: ::c_int = 0x0200; +pub const O_EXCL: ::c_int = 0x0400; +pub const O_TEXT: ::c_int = 0x4000; +pub const O_BINARY: ::c_int = 0x8000; +pub const _O_WTEXT: ::c_int = 0x10000; +pub const _O_U16TEXT: ::c_int = 0x20000; +pub const _O_U8TEXT: ::c_int = 0x40000; +pub const O_RAW: ::c_int = O_BINARY; +pub const O_NOINHERIT: ::c_int = 0x0080; +pub const O_TEMPORARY: ::c_int = 0x0040; +pub const _O_SHORT_LIVED: ::c_int = 0x1000; +pub const _O_OBTAIN_DIR: ::c_int = 0x2000; +pub const O_SEQUENTIAL: ::c_int = 0x0020; +pub const O_RANDOM: ::c_int = 0x0010; + +pub const S_IFCHR: ::c_int = 8192; +pub const S_IFDIR: ::c_int = 16384; +pub const S_IFREG: ::c_int = 32768; +pub const S_IFMT: ::c_int = 61440; +pub const S_IEXEC: ::c_int = 64; +pub const S_IWRITE: ::c_int = 128; +pub const S_IREAD: ::c_int = 256; + +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 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 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 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 = 36; +pub const EDEADLOCK: ::c_int = 36; +pub const ENAMETOOLONG: ::c_int = 38; +pub const ENOLCK: ::c_int = 39; +pub const ENOSYS: ::c_int = 40; +pub const ENOTEMPTY: ::c_int = 41; +pub const EILSEQ: ::c_int = 42; +pub const STRUNCATE: ::c_int = 80; + +// POSIX Supplement (from errno.h) +pub const EADDRINUSE: ::c_int = 100; +pub const EADDRNOTAVAIL: ::c_int = 101; +pub const EAFNOSUPPORT: ::c_int = 102; +pub const EALREADY: ::c_int = 103; +pub const EBADMSG: ::c_int = 104; +pub const ECANCELED: ::c_int = 105; +pub const ECONNABORTED: ::c_int = 106; +pub const ECONNREFUSED: ::c_int = 107; +pub const ECONNRESET: ::c_int = 108; +pub const EDESTADDRREQ: ::c_int = 109; +pub const EHOSTUNREACH: ::c_int = 110; +pub const EIDRM: ::c_int = 111; +pub const EINPROGRESS: ::c_int = 112; +pub const EISCONN: ::c_int = 113; +pub const ELOOP: ::c_int = 114; +pub const EMSGSIZE: ::c_int = 115; +pub const ENETDOWN: ::c_int = 116; +pub const ENETRESET: ::c_int = 117; +pub const ENETUNREACH: ::c_int = 118; +pub const ENOBUFS: ::c_int = 119; +pub const ENODATA: ::c_int = 120; +pub const ENOLINK: ::c_int = 121; +pub const ENOMSG: ::c_int = 122; +pub const ENOPROTOOPT: ::c_int = 123; +pub const ENOSR: ::c_int = 124; +pub const ENOSTR: ::c_int = 125; +pub const ENOTCONN: ::c_int = 126; +pub const ENOTRECOVERABLE: ::c_int = 127; +pub const ENOTSOCK: ::c_int = 128; +pub const ENOTSUP: ::c_int = 129; +pub const EOPNOTSUPP: ::c_int = 130; +pub const EOVERFLOW: ::c_int = 132; +pub const EOWNERDEAD: ::c_int = 133; +pub const EPROTO: ::c_int = 134; +pub const EPROTONOSUPPORT: ::c_int = 135; +pub const EPROTOTYPE: ::c_int = 136; +pub const ETIME: ::c_int = 137; +pub const ETIMEDOUT: ::c_int = 138; +pub const ETXTBSY: ::c_int = 139; +pub const EWOULDBLOCK: ::c_int = 140; + +// signal codes +pub const SIGINT: ::c_int = 2; +pub const SIGILL: ::c_int = 4; +pub const SIGFPE: ::c_int = 8; +pub const SIGSEGV: ::c_int = 11; +pub const SIGTERM: ::c_int = 15; +pub const SIGABRT: ::c_int = 22; +pub const NSIG: ::c_int = 23; + +pub const SIG_ERR: ::c_int = -1; +pub const SIG_DFL: ::sighandler_t = 0; +pub const SIG_IGN: ::sighandler_t = 1; +pub const SIG_GET: ::sighandler_t = 2; +pub const SIG_SGE: ::sighandler_t = 3; +pub const SIG_ACK: ::sighandler_t = 4; + +// inline comment below appeases style checker +#[cfg(all(target_env = "msvc", feature = "rustc-dep-of-std"))] // " if " +#[link(name = "msvcrt", cfg(not(target_feature = "crt-static")))] +#[link(name = "libcmt", cfg(target_feature = "crt-static"))] +extern "C" {} + +#[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 {} // FIXME: fill this out with a struct +impl ::Copy for fpos_t {} +impl ::Clone for fpos_t { + fn clone(&self) -> fpos_t { + *self + } +} + +// Special handling for all print and scan type functions because of https://github.com/rust-lang/libc/issues/2860 +cfg_if! { + if #[cfg(not(feature = "rustc-dep-of-std"))] { + #[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; + 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; + pub fn fopen(filename: *const c_char, mode: *const c_char) -> *mut FILE; + pub fn freopen(filename: *const c_char, mode: *const c_char, file: *mut FILE) -> *mut FILE; + pub fn fflush(file: *mut FILE) -> c_int; + pub fn fclose(file: *mut FILE) -> c_int; + pub fn remove(filename: *const c_char) -> c_int; + pub fn rename(oldname: *const c_char, newname: *const c_char) -> c_int; + pub fn tmpfile() -> *mut FILE; + 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 getchar() -> c_int; + pub fn putchar(c: c_int) -> c_int; + pub fn fgetc(stream: *mut FILE) -> c_int; + pub fn fgets(buf: *mut c_char, n: c_int, stream: *mut FILE) -> *mut c_char; + pub fn fputc(c: c_int, stream: *mut FILE) -> c_int; + pub fn fputs(s: *const c_char, stream: *mut FILE) -> c_int; + pub fn puts(s: *const c_char) -> c_int; + pub fn ungetc(c: c_int, stream: *mut FILE) -> c_int; + pub fn fread(ptr: *mut c_void, size: size_t, nobj: size_t, stream: *mut FILE) -> size_t; + pub fn fwrite(ptr: *const c_void, size: size_t, nobj: size_t, stream: *mut FILE) -> size_t; + pub fn fseek(stream: *mut FILE, offset: c_long, whence: c_int) -> c_int; + pub fn ftell(stream: *mut FILE) -> c_long; + pub fn rewind(stream: *mut FILE); + pub fn fgetpos(stream: *mut FILE, ptr: *mut fpos_t) -> c_int; + pub fn fsetpos(stream: *mut FILE, ptr: *const fpos_t) -> c_int; + 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 _msize(p: *mut c_void) -> size_t; + pub fn realloc(p: *mut c_void, size: size_t) -> *mut c_void; + pub fn free(p: *mut c_void); + pub fn abort() -> !; + pub fn exit(status: c_int) -> !; + pub fn _exit(status: c_int) -> !; + pub fn atexit(cb: extern "C" fn()) -> c_int; + pub fn system(s: *const c_char) -> c_int; + pub fn getenv(s: *const c_char) -> *mut c_char; + + 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 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; + pub fn strncmp(cs: *const c_char, ct: *const c_char, n: size_t) -> c_int; + pub fn strcoll(cs: *const c_char, ct: *const c_char) -> c_int; + pub fn strchr(cs: *const c_char, c: c_int) -> *mut c_char; + pub fn strrchr(cs: *const c_char, c: c_int) -> *mut c_char; + pub fn strspn(cs: *const c_char, ct: *const c_char) -> size_t; + pub fn strcspn(cs: *const c_char, ct: *const c_char) -> size_t; + pub fn strdup(cs: *const c_char) -> *mut c_char; + pub fn strpbrk(cs: *const c_char, ct: *const c_char) -> *mut c_char; + pub fn strstr(cs: *const c_char, ct: *const c_char) -> *mut c_char; + pub fn strlen(cs: *const c_char) -> size_t; + pub fn strnlen(cs: *const c_char, maxlen: size_t) -> size_t; + 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 strxfrm(s: *mut c_char, ct: *const c_char, n: size_t) -> size_t; + pub fn wcslen(buf: *const wchar_t) -> size_t; + pub fn wcstombs(dest: *mut c_char, src: *const wchar_t, n: size_t) -> ::size_t; + + pub fn memchr(cx: *const c_void, c: c_int, n: size_t) -> *mut c_void; + pub fn memcmp(cx: *const c_void, ct: *const c_void, n: size_t) -> c_int; + pub fn memcpy(dest: *mut c_void, src: *const c_void, n: size_t) -> *mut c_void; + pub fn memmove(dest: *mut c_void, src: *const c_void, n: size_t) -> *mut c_void; + 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 labs(i: c_long) -> c_long; + pub fn rand() -> c_int; + pub fn srand(seed: c_uint); + + pub fn signal(signum: c_int, handler: sighandler_t) -> sighandler_t; + pub fn raise(signum: c_int) -> c_int; + + #[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"] + pub fn chmod(path: *const c_char, mode: ::c_int) -> ::c_int; + #[link_name = "_wchmod"] + pub fn wchmod(path: *const wchar_t, mode: ::c_int) -> ::c_int; + #[link_name = "_mkdir"] + pub fn mkdir(path: *const c_char) -> ::c_int; + #[link_name = "_wrmdir"] + pub fn wrmdir(path: *const wchar_t) -> ::c_int; + #[link_name = "_fstat64"] + pub fn fstat(fildes: ::c_int, buf: *mut stat) -> ::c_int; + #[link_name = "_stat64"] + pub fn stat(path: *const c_char, buf: *mut stat) -> ::c_int; + #[link_name = "_wstat64"] + pub fn wstat(path: *const wchar_t, buf: *mut stat) -> ::c_int; + #[link_name = "_wutime64"] + pub fn wutime(file: *const wchar_t, buf: *mut utimbuf) -> ::c_int; + #[link_name = "_popen"] + pub fn popen(command: *const c_char, mode: *const c_char) -> *mut ::FILE; + #[link_name = "_pclose"] + pub fn pclose(stream: *mut ::FILE) -> ::c_int; + #[link_name = "_fdopen"] + pub fn fdopen(fd: ::c_int, mode: *const c_char) -> *mut ::FILE; + #[link_name = "_fileno"] + pub fn fileno(stream: *mut ::FILE) -> ::c_int; + #[link_name = "_open"] + pub fn open(path: *const c_char, oflag: ::c_int, ...) -> ::c_int; + #[link_name = "_wopen"] + pub fn wopen(path: *const wchar_t, oflag: ::c_int, ...) -> ::c_int; + #[link_name = "_creat"] + pub fn creat(path: *const c_char, mode: ::c_int) -> ::c_int; + #[link_name = "_access"] + pub fn access(path: *const c_char, amode: ::c_int) -> ::c_int; + #[link_name = "_chdir"] + pub fn chdir(dir: *const c_char) -> ::c_int; + #[link_name = "_close"] + pub fn close(fd: ::c_int) -> ::c_int; + #[link_name = "_dup"] + pub fn dup(fd: ::c_int) -> ::c_int; + #[link_name = "_dup2"] + pub fn dup2(src: ::c_int, dst: ::c_int) -> ::c_int; + #[link_name = "_execl"] + pub fn execl(path: *const c_char, arg0: *const c_char, ...) -> intptr_t; + #[link_name = "_wexecl"] + pub fn wexecl(path: *const wchar_t, arg0: *const wchar_t, ...) -> intptr_t; + #[link_name = "_execle"] + pub fn execle(path: *const c_char, arg0: *const c_char, ...) -> intptr_t; + #[link_name = "_wexecle"] + pub fn wexecle(path: *const wchar_t, arg0: *const wchar_t, ...) -> intptr_t; + #[link_name = "_execlp"] + pub fn execlp(path: *const c_char, arg0: *const c_char, ...) -> intptr_t; + #[link_name = "_wexeclp"] + pub fn wexeclp(path: *const wchar_t, arg0: *const wchar_t, ...) -> intptr_t; + #[link_name = "_execlpe"] + pub fn execlpe(path: *const c_char, arg0: *const c_char, ...) -> intptr_t; + #[link_name = "_wexeclpe"] + pub fn wexeclpe(path: *const wchar_t, arg0: *const wchar_t, ...) -> intptr_t; + #[link_name = "_execv"] + pub fn execv(prog: *const c_char, argv: *const *const c_char) -> ::intptr_t; + #[link_name = "_execve"] + pub fn execve( + prog: *const c_char, + argv: *const *const c_char, + envp: *const *const c_char, + ) -> ::c_int; + #[link_name = "_execvp"] + pub fn execvp(c: *const c_char, argv: *const *const c_char) -> ::c_int; + #[link_name = "_execvpe"] + pub fn execvpe( + c: *const c_char, + argv: *const *const c_char, + envp: *const *const c_char, + ) -> ::c_int; + #[link_name = "_wexecv"] + pub fn wexecv(prog: *const wchar_t, argv: *const *const wchar_t) -> ::intptr_t; + #[link_name = "_wexecve"] + pub fn wexecve( + prog: *const wchar_t, + argv: *const *const wchar_t, + envp: *const *const wchar_t, + ) -> ::intptr_t; + #[link_name = "_wexecvp"] + pub fn wexecvp(c: *const wchar_t, argv: *const *const wchar_t) -> ::intptr_t; + #[link_name = "_wexecvpe"] + pub fn wexecvpe( + c: *const wchar_t, + argv: *const *const wchar_t, + envp: *const *const wchar_t, + ) -> ::intptr_t; + #[link_name = "_getcwd"] + pub fn getcwd(buf: *mut c_char, size: ::c_int) -> *mut c_char; + #[link_name = "_getpid"] + pub fn getpid() -> ::c_int; + #[link_name = "_isatty"] + pub fn isatty(fd: ::c_int) -> ::c_int; + #[link_name = "_lseek"] + pub fn lseek(fd: ::c_int, offset: c_long, origin: ::c_int) -> c_long; + #[link_name = "_lseeki64"] + pub fn lseek64(fd: ::c_int, offset: c_longlong, origin: ::c_int) -> c_longlong; + #[link_name = "_pipe"] + pub fn pipe(fds: *mut ::c_int, psize: ::c_uint, textmode: ::c_int) -> ::c_int; + #[link_name = "_read"] + pub fn read(fd: ::c_int, buf: *mut ::c_void, count: ::c_uint) -> ::c_int; + #[link_name = "_rmdir"] + pub fn rmdir(path: *const c_char) -> ::c_int; + #[link_name = "_unlink"] + pub fn unlink(c: *const c_char) -> ::c_int; + #[link_name = "_write"] + pub fn write(fd: ::c_int, buf: *const ::c_void, count: ::c_uint) -> ::c_int; + #[link_name = "_commit"] + pub fn commit(fd: ::c_int) -> ::c_int; + #[link_name = "_get_osfhandle"] + pub fn get_osfhandle(fd: ::c_int) -> ::intptr_t; + #[link_name = "_open_osfhandle"] + pub fn open_osfhandle(osfhandle: ::intptr_t, flags: ::c_int) -> ::c_int; + pub fn setlocale(category: ::c_int, locale: *const c_char) -> *mut c_char; + #[link_name = "_wsetlocale"] + 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" { + pub fn listen(s: SOCKET, backlog: ::c_int) -> ::c_int; + pub fn accept(s: SOCKET, addr: *mut ::sockaddr, addrlen: *mut ::c_int) -> SOCKET; + pub fn bind(s: SOCKET, name: *const ::sockaddr, namelen: ::c_int) -> ::c_int; + pub fn connect(s: SOCKET, name: *const ::sockaddr, namelen: ::c_int) -> ::c_int; + pub fn getpeername(s: SOCKET, name: *mut ::sockaddr, nameln: *mut ::c_int) -> ::c_int; + pub fn getsockname(s: SOCKET, name: *mut ::sockaddr, nameln: *mut ::c_int) -> ::c_int; + pub fn getsockopt( + s: SOCKET, + level: ::c_int, + optname: ::c_int, + optval: *mut ::c_char, + optlen: *mut ::c_int, + ) -> ::c_int; + pub fn recvfrom( + s: SOCKET, + buf: *mut ::c_char, + len: ::c_int, + flags: ::c_int, + from: *mut ::sockaddr, + fromlen: *mut ::c_int, + ) -> ::c_int; + pub fn sendto( + s: SOCKET, + buf: *const ::c_char, + len: ::c_int, + flags: ::c_int, + to: *const ::sockaddr, + tolen: ::c_int, + ) -> ::c_int; + pub fn setsockopt( + s: SOCKET, + level: ::c_int, + optname: ::c_int, + optval: *const ::c_char, + optlen: ::c_int, + ) -> ::c_int; + pub fn socket(af: ::c_int, socket_type: ::c_int, protocol: ::c_int) -> SOCKET; +} + +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(all(target_env = "gnu"))] { + mod gnu; + pub use self::gnu::*; + } else if #[cfg(all(target_env = "msvc"))] { + mod msvc; + pub use self::msvc::*; + } else { + // Unknown target_env + } +} diff --git a/vendor/libc/src/windows/msvc/mod.rs b/vendor/libc/src/windows/msvc/mod.rs new file mode 100644 index 0000000..f5a1d95 --- /dev/null +++ b/vendor/libc/src/windows/msvc/mod.rs @@ -0,0 +1,20 @@ +pub const L_tmpnam: ::c_uint = 260; +pub const TMP_MAX: ::c_uint = 0x7fff_ffff; + +// POSIX Supplement (from errno.h) +// This particular error code is only currently available in msvc toolchain +pub const EOTHER: ::c_int = 131; + +extern "C" { + #[link_name = "_stricmp"] + 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/libc/tests/const_fn.rs b/vendor/libc/tests/const_fn.rs new file mode 100644 index 0000000..0e7e186 --- /dev/null +++ b/vendor/libc/tests/const_fn.rs @@ -0,0 +1,5 @@ +#![cfg(libc_const_extern_fn)] // If this does not hold, the file is empty + +#[cfg(target_os = "linux")] +const _FOO: libc::c_uint = unsafe { libc::CMSG_SPACE(1) }; +//^ if CMSG_SPACE is not const, this will fail to compile diff --git a/vendor/memchr/.cargo-checksum.json b/vendor/memchr/.cargo-checksum.json new file mode 100644 index 0000000..ff6d55b --- /dev/null +++ b/vendor/memchr/.cargo-checksum.json @@ -0,0 +1 @@ +{"files":{"COPYING":"01c266bced4a434da0051174d6bee16a4c82cf634e2679b6155d40d75012390f","Cargo.toml":"8333f270d28547eec87c63083418550a6d9d1de14e9adbcba94ebe0f2a40db61","LICENSE-MIT":"0f96a83840e146e43c0ec96a22ec1f392e0680e6c1226e6f3ba87e0740af850f","README.md":"92a74aaffe011bdaa06fbc34a01686a6eba58ca1322e976759417a547fddf734","UNLICENSE":"7e12e5df4bae12cb21581ba157ced20e1986a0508dd10d0e8a4ab9a4cf94e85c","rustfmt.toml":"1ca600239a27401c4a43f363cf3f38183a212affc1f31bff3ae93234bbaec228","src/arch/aarch64/memchr.rs":"5bb70f915084e629d940dbc322f5b9096b2e658cf63fea8a2f6e7550412e73a0","src/arch/aarch64/mod.rs":"44cd1a614bd66f1e66fc86c541d3c3b8d3a14a644c13e8bf816df3f555eac2d4","src/arch/aarch64/neon/memchr.rs":"e8c00b8fb2c7e2711832ae3cedefe59f32ebedd7dfa4d0ec6de2a566c979daea","src/arch/aarch64/neon/mod.rs":"eab6d56c2b2354db4ee395f40282cd49f97e2ab853547be5de6e65fbe1b2f634","src/arch/aarch64/neon/packedpair.rs":"fbdfdbfaf7b76b234db261fbe55a55c4479d32cdc65a654d60417c2d1c237849","src/arch/all/memchr.rs":"029f77c622e59116d2ce011e8b069118c23e21c37e1561c35c82448d4ad4c430","src/arch/all/mod.rs":"05f3fc2b069682eb1545fc6366d167bb620a454365dac8b8dd6cde6cd64de18a","src/arch/all/packedpair/default_rank.rs":"abffd1b5b8b7a3be95c03dd1105b905c246a379854dc56f1e846ea7c4408f2c7","src/arch/all/packedpair/mod.rs":"292b66042c5b5c78bba33db6526aeae6904db803d601fcdd29032b87b3eb3754","src/arch/all/rabinkarp.rs":"236f69c04b90c14c253ae6c8d9b78150b4a56df75bb50af6d63b15145668b7cc","src/arch/all/shiftor.rs":"0d79117f52a1e4795843603a3bb0b45397df4ad5e4184bbc923658dab9dc3b5f","src/arch/all/twoway.rs":"47c97a265bfbafde90a618946643d3e97dfd9a85f01aa4ac758cd4c1573a450d","src/arch/generic/memchr.rs":"88290761bab740878401e914d71866da6501cdcef53d1249ec6fda4c7f9c12ae","src/arch/generic/mod.rs":"1dd75f61e0ea2563b8205a08aaa7b55500130aa331d18b9e9f995724b66c7a39","src/arch/generic/packedpair.rs":"a4a6efb29877ced9cf4c4e5ae9f36a79f019a16b831f2b9424899a1513d458ad","src/arch/mod.rs":"ca3960b7e2ed28d1b3c121710a870430531aad792f64d4dcb4ca4709d6cbda30","src/arch/wasm32/memchr.rs":"d88ac79f891d8530f505f5035062d3da274a05d66c611480c75430d52709d052","src/arch/wasm32/mod.rs":"a20377aa8fe07d68594879101dc73061e4f51d9c8d812b593b1f376e3c8add79","src/arch/wasm32/simd128/memchr.rs":"bac2c4c43fe710c83a6f2b1118fede043be89dd821d4b532907f129f09fdb5cf","src/arch/wasm32/simd128/mod.rs":"c157b373faedbfd65323be432e25bc411d97aa1b7bc58e76048614c7b2bf3bf6","src/arch/wasm32/simd128/packedpair.rs":"288ba6e5eee6a7a8e5e45c64cff1aa5d72d996c2a6bc228be372c75789f08e45","src/arch/x86_64/avx2/memchr.rs":"576ec0c30f49874f7fd9f6caeb490d56132c0fbbaa4d877b1aa532cafce19323","src/arch/x86_64/avx2/mod.rs":"0033d1b712d0b10f0f273ef9aa8caa53e05e49f4c56a64f39af0b9df97eec584","src/arch/x86_64/avx2/packedpair.rs":"87b69cb4301815906127db4f6370f572c7c5d5dad35c0946c00ad888dbcaec8c","src/arch/x86_64/memchr.rs":"99a1dbe4156d498e6f910d06d3d3b31e7f6d06dff7d13a4c51b33a02b7e2fba9","src/arch/x86_64/mod.rs":"61b2aa876942fd3e78714c2ae21e356c8634545c06995020f443fa50218df027","src/arch/x86_64/sse2/memchr.rs":"68fc3b8f9eddf82192979c3aa11e5141f085cbb993c49c340558719a904679dc","src/arch/x86_64/sse2/mod.rs":"38b70ae52a64ec974dbb91d04d6ca8013d9e06d1fe4af852206bbc2faf1c59aa","src/arch/x86_64/sse2/packedpair.rs":"241ea981d8eea6024769f1c9375f726a9bb9700160c5857781d4befd9f5ef55d","src/cow.rs":"34eddd02cb82cc2d5a2c640891d64efe332dabcc1eea5115764200d8f46b66f7","src/ext.rs":"210f89d1e32211bc64414cbd56e97b4f56ce8a8832d321d77a9fe519634e27ea","src/lib.rs":"614f778a41e88a29ea0ceb8e92c839dbb6b5a61c967f8bfd962975e18f932c71","src/macros.rs":"3e4b39252bfa471fad384160a43f113ebfec7bec46a85d16f006622881dd2081","src/memchr.rs":"6ae779ec5d00f443075316e0105edf30b489a38e2e96325bec14ccecd014145b","src/memmem/mod.rs":"1b0a9d6a681fd0887c677c4fc8d4c8f9719ddde250bdd5ea545365c1a7fb9094","src/memmem/searcher.rs":"7763472d43c66df596ca0697c07db0b4666d38a6a14f64f9f298aaf756c4a715","src/tests/memchr/mod.rs":"269f8e4b4f7f5ea458f27a3c174eb1020ffb2484eeba9464170beb51747df69b","src/tests/memchr/naive.rs":"6a0bee033e5edfb5b1d5769a5fa1c78388f7e9ff7bb91cb67f0ad029289e00e7","src/tests/memchr/prop.rs":"7bf7435087fbf08c5014c216b76575349735590d6b1d0e448921a1dc17bc0ea7","src/tests/mod.rs":"7cec8f809e279310a465c6a7725087970f219a676cc76c83de30c695bb490740","src/tests/packedpair.rs":"b02ec4fbb61a8653cb5f2268c31bc9168b8043347f2abdcc74081acf83b98e15","src/tests/substring/mod.rs":"c7660d10749363ac4687e7da2b5fda60768230425df8ba416c0c28b8d56a5c74","src/tests/substring/naive.rs":"df6f55d165382b8a53762ba4c324926cac13ebc62cde1805f4ce08740b326483","src/tests/substring/prop.rs":"38c15992609b5681a95d838ae6f2933e00a1219f2c971bfba245f96e0729fcdc","src/vector.rs":"3b15d5cb9715f26e655598eacbb8bbba74cbe8ddb2fb969d13aa75f216a118dd"},"package":"78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3"} \ No newline at end of file diff --git a/vendor/memchr/COPYING b/vendor/memchr/COPYING new file mode 100644 index 0000000..bb9c20a --- /dev/null +++ b/vendor/memchr/COPYING @@ -0,0 +1,3 @@ +This project is dual-licensed under the Unlicense and MIT licenses. + +You may use this code under the terms of either license. diff --git a/vendor/memchr/Cargo.toml b/vendor/memchr/Cargo.toml new file mode 100644 index 0000000..3e5a1f4 --- /dev/null +++ b/vendor/memchr/Cargo.toml @@ -0,0 +1,95 @@ +# 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] +edition = "2021" +rust-version = "1.61" +name = "memchr" +version = "2.7.4" +authors = [ + "Andrew Gallant ", + "bluss", +] +build = false +exclude = [ + "/.github", + "/benchmarks", + "/fuzz", + "/scripts", + "/tmp", +] +autobins = false +autoexamples = false +autotests = false +autobenches = false +description = """ +Provides extremely fast (uses SIMD on x86_64, aarch64 and wasm32) routines for +1, 2 or 3 byte search and single substring search. +""" +homepage = "https://github.com/BurntSushi/memchr" +documentation = "https://docs.rs/memchr/" +readme = "README.md" +keywords = [ + "memchr", + "memmem", + "substring", + "find", + "search", +] +license = "Unlicense OR MIT" +repository = "https://github.com/BurntSushi/memchr" + +[package.metadata.docs.rs] +rustdoc-args = ["--generate-link-to-definition"] + +[profile.bench] +debug = 2 + +[profile.release] +debug = 2 + +[profile.test] +opt-level = 3 +debug = 2 + +[lib] +name = "memchr" +path = "src/lib.rs" +bench = false + +[dependencies.compiler_builtins] +version = "0.1.2" +optional = true + +[dependencies.core] +version = "1.0.0" +optional = true +package = "rustc-std-workspace-core" + +[dependencies.log] +version = "0.4.20" +optional = true + +[dev-dependencies.quickcheck] +version = "1.0.3" +default-features = false + +[features] +alloc = [] +default = ["std"] +libc = [] +logging = ["dep:log"] +rustc-dep-of-std = [ + "core", + "compiler_builtins", +] +std = ["alloc"] +use_std = ["std"] diff --git a/vendor/memchr/LICENSE-MIT b/vendor/memchr/LICENSE-MIT new file mode 100644 index 0000000..3b0a5dc --- /dev/null +++ b/vendor/memchr/LICENSE-MIT @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2015 Andrew Gallant + +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/memchr/README.md b/vendor/memchr/README.md new file mode 100644 index 0000000..db00ebb --- /dev/null +++ b/vendor/memchr/README.md @@ -0,0 +1,196 @@ +memchr +====== +This library provides heavily optimized routines for string search primitives. + +[![Build status](https://github.com/BurntSushi/memchr/workflows/ci/badge.svg)](https://github.com/BurntSushi/memchr/actions) +[![Crates.io](https://img.shields.io/crates/v/memchr.svg)](https://crates.io/crates/memchr) + +Dual-licensed under MIT or the [UNLICENSE](https://unlicense.org/). + + +### Documentation + +[https://docs.rs/memchr](https://docs.rs/memchr) + + +### Overview + +* The top-level module provides routines for searching for 1, 2 or 3 bytes + in the forward or reverse direction. When searching for more than one byte, + positions are considered a match if the byte at that position matches any + of the bytes. +* The `memmem` sub-module provides forward and reverse substring search + routines. + +In all such cases, routines operate on `&[u8]` without regard to encoding. This +is exactly what you want when searching either UTF-8 or arbitrary bytes. + +### Compiling without the standard library + +memchr links to the standard library by default, but you can disable the +`std` feature if you want to use it in a `#![no_std]` crate: + +```toml +[dependencies] +memchr = { version = "2", default-features = false } +``` + +On `x86_64` platforms, when the `std` feature is disabled, the SSE2 accelerated +implementations will be used. When `std` is enabled, AVX2 accelerated +implementations will be used if the CPU is determined to support it at runtime. + +SIMD accelerated routines are also available on the `wasm32` and `aarch64` +targets. The `std` feature is not required to use them. + +When a SIMD version is not available, then this crate falls back to +[SWAR](https://en.wikipedia.org/wiki/SWAR) techniques. + +### Minimum Rust version policy + +This crate's minimum supported `rustc` version is `1.61.0`. + +The current policy is that the minimum Rust version required to use this crate +can be increased in minor version updates. For example, if `crate 1.0` requires +Rust 1.20.0, then `crate 1.0.z` for all values of `z` will also require Rust +1.20.0 or newer. However, `crate 1.y` for `y > 0` may require a newer minimum +version of Rust. + +In general, this crate will be conservative with respect to the minimum +supported version of Rust. + + +### Testing strategy + +Given the complexity of the code in this crate, along with the pervasive use +of `unsafe`, this crate has an extensive testing strategy. It combines multiple +approaches: + +* Hand-written tests. +* Exhaustive-style testing meant to exercise all possible branching and offset + calculations. +* Property based testing through [`quickcheck`](https://github.com/BurntSushi/quickcheck). +* Fuzz testing through [`cargo fuzz`](https://github.com/rust-fuzz/cargo-fuzz). +* A huge suite of benchmarks that are also run as tests. Benchmarks always + confirm that the expected result occurs. + +Improvements to the testing infrastructure are very welcome. + + +### Algorithms used + +At time of writing, this crate's implementation of substring search actually +has a few different algorithms to choose from depending on the situation. + +* For very small haystacks, + [Rabin-Karp](https://en.wikipedia.org/wiki/Rabin%E2%80%93Karp_algorithm) + is used to reduce latency. Rabin-Karp has very small overhead and can often + complete before other searchers have even been constructed. +* For small needles, a variant of the + ["Generic SIMD"](http://0x80.pl/articles/simd-strfind.html#algorithm-1-generic-simd) + algorithm is used. Instead of using the first and last bytes, a heuristic is + used to select bytes based on a background distribution of byte frequencies. +* In all other cases, + [Two-Way](https://en.wikipedia.org/wiki/Two-way_string-matching_algorithm) + is used. If possible, a prefilter based on the "Generic SIMD" algorithm + linked above is used to find candidates quickly. A dynamic heuristic is used + to detect if the prefilter is ineffective, and if so, disables it. + + +### Why is the standard library's substring search so much slower? + +We'll start by establishing what the difference in performance actually +is. There are two relevant benchmark classes to consider: `prebuilt` and +`oneshot`. The `prebuilt` benchmarks are designed to measure---to the extent +possible---search time only. That is, the benchmark first starts by building a +searcher and then only tracking the time for _using_ the searcher: + +``` +$ rebar rank benchmarks/record/x86_64/2023-08-26.csv --intersection -e memchr/memmem/prebuilt -e std/memmem/prebuilt +Engine Version Geometric mean of speed ratios Benchmark count +------ ------- ------------------------------ --------------- +rust/memchr/memmem/prebuilt 2.5.0 1.03 53 +rust/std/memmem/prebuilt 1.73.0-nightly 180dffba1 6.50 53 +``` + +Conversely, the `oneshot` benchmark class measures the time it takes to both +build the searcher _and_ use it: + +``` +$ rebar rank benchmarks/record/x86_64/2023-08-26.csv --intersection -e memchr/memmem/oneshot -e std/memmem/oneshot +Engine Version Geometric mean of speed ratios Benchmark count +------ ------- ------------------------------ --------------- +rust/memchr/memmem/oneshot 2.5.0 1.04 53 +rust/std/memmem/oneshot 1.73.0-nightly 180dffba1 5.26 53 +``` + +**NOTE:** Replace `rebar rank` with `rebar cmp` in the above commands to +explore the specific benchmarks and their differences. + +So in both cases, this crate is quite a bit faster over a broad sampling of +benchmarks regardless of whether you measure only search time or search time +plus construction time. The difference is a little smaller when you include +construction time in your measurements. + +These two different types of benchmark classes make for a nice segue into +one reason why the standard library's substring search can be slower: API +design. In the standard library, the only APIs available to you require +one to re-construct the searcher for every search. While you can benefit +from building a searcher once and iterating over all matches in a single +string, you cannot reuse that searcher to search other strings. This might +come up when, for example, searching a file one line at a time. You'll need +to re-build the searcher for every line searched, and this can [really +matter][burntsushi-bstr-blog]. + +**NOTE:** The `prebuilt` benchmark for the standard library can't actually +avoid measuring searcher construction at some level, because there is no API +for it. Instead, the benchmark consists of building the searcher once and then +finding all matches in a single string via an iterator. This tends to +approximate a benchmark where searcher construction isn't measured, but it +isn't perfect. While this means the comparison is not strictly +apples-to-apples, it does reflect what is maximally possible with the standard +library, and thus reflects the best that one could do in a real world scenario. + +While there is more to the story than just API design here, it's important to +point out that even if the standard library's substring search were a precise +clone of this crate internally, it would still be at a disadvantage in some +workloads because of its API. (The same also applies to C's standard library +`memmem` function. There is no way to amortize construction of the searcher. +You need to pay for it on every call.) + +The other reason for the difference in performance is that +the standard library has trouble using SIMD. In particular, substring search +is implemented in the `core` library, where platform specific code generally +can't exist. That's an issue because in order to utilize SIMD beyond SSE2 +while maintaining portable binaries, one needs to use [dynamic CPU feature +detection][dynamic-cpu], and that in turn requires platform specific code. +While there is [an RFC for enabling target feature detection in +`core`][core-feature], it doesn't yet exist. + +The bottom line here is that `core`'s substring search implementation is +limited to making use of SSE2, but not AVX. + +Still though, this crate does accelerate substring search even when only SSE2 +is available. The standard library could therefore adopt the techniques in this +crate just for SSE2. The reason why that hasn't happened yet isn't totally +clear to me. It likely needs a champion to push it through. The standard +library tends to be more conservative in these things. With that said, the +standard library does use some [SSE2 acceleration on `x86-64`][std-sse2] added +in [this PR][std-sse2-pr]. However, at the time of writing, it is only used +for short needles and doesn't use the frequency based heuristics found in this +crate. + +**NOTE:** Another thing worth mentioning is that the standard library's +substring search routine requires that both the needle and haystack have type +`&str`. Unless you can assume that your data is valid UTF-8, building a `&str` +will come with the overhead of UTF-8 validation. This may in turn result in +overall slower searching depending on your workload. In contrast, the `memchr` +crate permits both the needle and the haystack to have type `&[u8]`, where +`&[u8]` can be created from a `&str` with zero cost. Therefore, the substring +search in this crate is strictly more flexible than what the standard library +provides. + +[burntsushi-bstr-blog]: https://blog.burntsushi.net/bstr/#motivation-based-on-performance +[dynamic-cpu]: https://doc.rust-lang.org/std/arch/index.html#dynamic-cpu-feature-detection +[core-feature]: https://github.com/rust-lang/rfcs/pull/3469 +[std-sse2]: https://github.com/rust-lang/rust/blob/bf9229a2e366b4c311f059014a4aa08af16de5d8/library/core/src/str/pattern.rs#L1719-L1857 +[std-sse2-pr]: https://github.com/rust-lang/rust/pull/103779 diff --git a/vendor/memchr/UNLICENSE b/vendor/memchr/UNLICENSE new file mode 100644 index 0000000..68a49da --- /dev/null +++ b/vendor/memchr/UNLICENSE @@ -0,0 +1,24 @@ +This is free and unencumbered software released into the public domain. + +Anyone is free to copy, modify, publish, use, compile, sell, or +distribute this software, either in source code form or as a compiled +binary, for any purpose, commercial or non-commercial, and by any +means. + +In jurisdictions that recognize copyright laws, the author or authors +of this software dedicate any and all copyright interest in the +software to the public domain. We make this dedication for the benefit +of the public at large and to the detriment of our heirs and +successors. We intend this dedication to be an overt act of +relinquishment in perpetuity of all present and future rights to this +software under copyright law. + +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 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. + +For more information, please refer to diff --git a/vendor/memchr/rustfmt.toml b/vendor/memchr/rustfmt.toml new file mode 100644 index 0000000..aa37a21 --- /dev/null +++ b/vendor/memchr/rustfmt.toml @@ -0,0 +1,2 @@ +max_width = 79 +use_small_heuristics = "max" diff --git a/vendor/memchr/src/arch/aarch64/memchr.rs b/vendor/memchr/src/arch/aarch64/memchr.rs new file mode 100644 index 0000000..e0053b2 --- /dev/null +++ b/vendor/memchr/src/arch/aarch64/memchr.rs @@ -0,0 +1,137 @@ +/*! +Wrapper routines for `memchr` and friends. + +These routines choose the best implementation at compile time. (This is +different from `x86_64` because it is expected that `neon` is almost always +available for `aarch64` targets.) +*/ + +macro_rules! defraw { + ($ty:ident, $find:ident, $start:ident, $end:ident, $($needles:ident),+) => {{ + #[cfg(target_feature = "neon")] + { + use crate::arch::aarch64::neon::memchr::$ty; + + debug!("chose neon for {}", stringify!($ty)); + debug_assert!($ty::is_available()); + // SAFETY: We know that wasm memchr is always available whenever + // code is compiled for `aarch64` with the `neon` target feature + // enabled. + $ty::new_unchecked($($needles),+).$find($start, $end) + } + #[cfg(not(target_feature = "neon"))] + { + use crate::arch::all::memchr::$ty; + + debug!( + "no neon feature available, using fallback for {}", + stringify!($ty), + ); + $ty::new($($needles),+).$find($start, $end) + } + }} +} + +/// memchr, but using raw pointers to represent the haystack. +/// +/// # Safety +/// +/// Pointers must be valid. See `One::find_raw`. +#[inline(always)] +pub(crate) unsafe fn memchr_raw( + n1: u8, + start: *const u8, + end: *const u8, +) -> Option<*const u8> { + defraw!(One, find_raw, start, end, n1) +} + +/// memrchr, but using raw pointers to represent the haystack. +/// +/// # Safety +/// +/// Pointers must be valid. See `One::rfind_raw`. +#[inline(always)] +pub(crate) unsafe fn memrchr_raw( + n1: u8, + start: *const u8, + end: *const u8, +) -> Option<*const u8> { + defraw!(One, rfind_raw, start, end, n1) +} + +/// memchr2, but using raw pointers to represent the haystack. +/// +/// # Safety +/// +/// Pointers must be valid. See `Two::find_raw`. +#[inline(always)] +pub(crate) unsafe fn memchr2_raw( + n1: u8, + n2: u8, + start: *const u8, + end: *const u8, +) -> Option<*const u8> { + defraw!(Two, find_raw, start, end, n1, n2) +} + +/// memrchr2, but using raw pointers to represent the haystack. +/// +/// # Safety +/// +/// Pointers must be valid. See `Two::rfind_raw`. +#[inline(always)] +pub(crate) unsafe fn memrchr2_raw( + n1: u8, + n2: u8, + start: *const u8, + end: *const u8, +) -> Option<*const u8> { + defraw!(Two, rfind_raw, start, end, n1, n2) +} + +/// memchr3, but using raw pointers to represent the haystack. +/// +/// # Safety +/// +/// Pointers must be valid. See `Three::find_raw`. +#[inline(always)] +pub(crate) unsafe fn memchr3_raw( + n1: u8, + n2: u8, + n3: u8, + start: *const u8, + end: *const u8, +) -> Option<*const u8> { + defraw!(Three, find_raw, start, end, n1, n2, n3) +} + +/// memrchr3, but using raw pointers to represent the haystack. +/// +/// # Safety +/// +/// Pointers must be valid. See `Three::rfind_raw`. +#[inline(always)] +pub(crate) unsafe fn memrchr3_raw( + n1: u8, + n2: u8, + n3: u8, + start: *const u8, + end: *const u8, +) -> Option<*const u8> { + defraw!(Three, rfind_raw, start, end, n1, n2, n3) +} + +/// Count all matching bytes, but using raw pointers to represent the haystack. +/// +/// # Safety +/// +/// Pointers must be valid. See `One::count_raw`. +#[inline(always)] +pub(crate) unsafe fn count_raw( + n1: u8, + start: *const u8, + end: *const u8, +) -> usize { + defraw!(One, count_raw, start, end, n1) +} diff --git a/vendor/memchr/src/arch/aarch64/mod.rs b/vendor/memchr/src/arch/aarch64/mod.rs new file mode 100644 index 0000000..7b32912 --- /dev/null +++ b/vendor/memchr/src/arch/aarch64/mod.rs @@ -0,0 +1,7 @@ +/*! +Vector algorithms for the `aarch64` target. +*/ + +pub mod neon; + +pub(crate) mod memchr; diff --git a/vendor/memchr/src/arch/aarch64/neon/memchr.rs b/vendor/memchr/src/arch/aarch64/neon/memchr.rs new file mode 100644 index 0000000..5fcc762 --- /dev/null +++ b/vendor/memchr/src/arch/aarch64/neon/memchr.rs @@ -0,0 +1,1031 @@ +/*! +This module defines 128-bit vector implementations of `memchr` and friends. + +The main types in this module are [`One`], [`Two`] and [`Three`]. They are for +searching for one, two or three distinct bytes, respectively, in a haystack. +Each type also has corresponding double ended iterators. These searchers are +typically much faster than scalar routines accomplishing the same task. + +The `One` searcher also provides a [`One::count`] routine for efficiently +counting the number of times a single byte occurs in a haystack. This is +useful, for example, for counting the number of lines in a haystack. This +routine exists because it is usually faster, especially with a high match +count, then using [`One::find`] repeatedly. ([`OneIter`] specializes its +`Iterator::count` implementation to use this routine.) + +Only one, two and three bytes are supported because three bytes is about +the point where one sees diminishing returns. Beyond this point and it's +probably (but not necessarily) better to just use a simple `[bool; 256]` array +or similar. However, it depends mightily on the specific work-load and the +expected match frequency. +*/ + +use core::arch::aarch64::uint8x16_t; + +use crate::{arch::generic::memchr as generic, ext::Pointer, vector::Vector}; + +/// Finds all occurrences of a single byte in a haystack. +#[derive(Clone, Copy, Debug)] +pub struct One(generic::One); + +impl One { + /// Create a new searcher that finds occurrences of the needle byte given. + /// + /// This particular searcher is specialized to use neon vector instructions + /// that typically make it quite fast. + /// + /// If neon is unavailable in the current environment, then `None` is + /// returned. + #[inline] + pub fn new(needle: u8) -> Option { + if One::is_available() { + // SAFETY: we check that neon is available above. + unsafe { Some(One::new_unchecked(needle)) } + } else { + None + } + } + + /// Create a new finder specific to neon vectors and routines without + /// checking that neon is available. + /// + /// # Safety + /// + /// Callers must guarantee that it is safe to execute `neon` instructions + /// in the current environment. + /// + /// Note that it is a common misconception that if one compiles for an + /// `x86_64` target, then they therefore automatically have access to neon + /// instructions. While this is almost always the case, it isn't true in + /// 100% of cases. + #[target_feature(enable = "neon")] + #[inline] + pub unsafe fn new_unchecked(needle: u8) -> One { + One(generic::One::new(needle)) + } + + /// Returns true when this implementation is available in the current + /// environment. + /// + /// When this is true, it is guaranteed that [`One::new`] will return + /// a `Some` value. Similarly, when it is false, it is guaranteed that + /// `One::new` will return a `None` value. + /// + /// Note also that for the lifetime of a single program, if this returns + /// true then it will always return true. + #[inline] + pub fn is_available() -> bool { + #[cfg(target_feature = "neon")] + { + true + } + #[cfg(not(target_feature = "neon"))] + { + false + } + } + + /// Return the first occurrence of one of the needle bytes in the given + /// haystack. If no such occurrence exists, then `None` is returned. + /// + /// The occurrence is reported as an offset into `haystack`. Its maximum + /// value is `haystack.len() - 1`. + #[inline] + pub fn find(&self, haystack: &[u8]) -> Option { + // SAFETY: `find_raw` guarantees that if a pointer is returned, it + // falls within the bounds of the start and end pointers. + unsafe { + generic::search_slice_with_raw(haystack, |s, e| { + self.find_raw(s, e) + }) + } + } + + /// Return the last occurrence of one of the needle bytes in the given + /// haystack. If no such occurrence exists, then `None` is returned. + /// + /// The occurrence is reported as an offset into `haystack`. Its maximum + /// value is `haystack.len() - 1`. + #[inline] + pub fn rfind(&self, haystack: &[u8]) -> Option { + // SAFETY: `rfind_raw` guarantees that if a pointer is returned, it + // falls within the bounds of the start and end pointers. + unsafe { + generic::search_slice_with_raw(haystack, |s, e| { + self.rfind_raw(s, e) + }) + } + } + + /// Counts all occurrences of this byte in the given haystack. + #[inline] + pub fn count(&self, haystack: &[u8]) -> usize { + // SAFETY: All of our pointers are derived directly from a borrowed + // slice, which is guaranteed to be valid. + unsafe { + let start = haystack.as_ptr(); + let end = start.add(haystack.len()); + self.count_raw(start, end) + } + } + + /// Like `find`, but accepts and returns raw pointers. + /// + /// When a match is found, the pointer returned is guaranteed to be + /// `>= start` and `< end`. + /// + /// This routine is useful if you're already using raw pointers and would + /// like to avoid converting back to a slice before executing a search. + /// + /// # Safety + /// + /// * Both `start` and `end` must be valid for reads. + /// * Both `start` and `end` must point to an initialized value. + /// * Both `start` and `end` must point to the same allocated object and + /// must either be in bounds or at most one byte past the end of the + /// allocated object. + /// * Both `start` and `end` must be _derived from_ a pointer to the same + /// object. + /// * The distance between `start` and `end` must not overflow `isize`. + /// * The distance being in bounds must not rely on "wrapping around" the + /// address space. + /// + /// Note that callers may pass a pair of pointers such that `start >= end`. + /// In that case, `None` will always be returned. + #[inline] + pub unsafe fn find_raw( + &self, + start: *const u8, + end: *const u8, + ) -> Option<*const u8> { + if start >= end { + return None; + } + if end.distance(start) < uint8x16_t::BYTES { + // SAFETY: We require the caller to pass valid start/end pointers. + return generic::fwd_byte_by_byte(start, end, |b| { + b == self.0.needle1() + }); + } + // SAFETY: Building a `One` means it's safe to call 'neon' routines. + // Also, we've checked that our haystack is big enough to run on the + // vector routine. Pointer validity is caller's responsibility. + self.find_raw_impl(start, end) + } + + /// Like `rfind`, but accepts and returns raw pointers. + /// + /// When a match is found, the pointer returned is guaranteed to be + /// `>= start` and `< end`. + /// + /// This routine is useful if you're already using raw pointers and would + /// like to avoid converting back to a slice before executing a search. + /// + /// # Safety + /// + /// * Both `start` and `end` must be valid for reads. + /// * Both `start` and `end` must point to an initialized value. + /// * Both `start` and `end` must point to the same allocated object and + /// must either be in bounds or at most one byte past the end of the + /// allocated object. + /// * Both `start` and `end` must be _derived from_ a pointer to the same + /// object. + /// * The distance between `start` and `end` must not overflow `isize`. + /// * The distance being in bounds must not rely on "wrapping around" the + /// address space. + /// + /// Note that callers may pass a pair of pointers such that `start >= end`. + /// In that case, `None` will always be returned. + #[inline] + pub unsafe fn rfind_raw( + &self, + start: *const u8, + end: *const u8, + ) -> Option<*const u8> { + if start >= end { + return None; + } + if end.distance(start) < uint8x16_t::BYTES { + // SAFETY: We require the caller to pass valid start/end pointers. + return generic::rev_byte_by_byte(start, end, |b| { + b == self.0.needle1() + }); + } + // SAFETY: Building a `One` means it's safe to call 'neon' routines. + // Also, we've checked that our haystack is big enough to run on the + // vector routine. Pointer validity is caller's responsibility. + self.rfind_raw_impl(start, end) + } + + /// Like `count`, but accepts and returns raw pointers. + /// + /// This routine is useful if you're already using raw pointers and would + /// like to avoid converting back to a slice before executing a search. + /// + /// # Safety + /// + /// * Both `start` and `end` must be valid for reads. + /// * Both `start` and `end` must point to an initialized value. + /// * Both `start` and `end` must point to the same allocated object and + /// must either be in bounds or at most one byte past the end of the + /// allocated object. + /// * Both `start` and `end` must be _derived from_ a pointer to the same + /// object. + /// * The distance between `start` and `end` must not overflow `isize`. + /// * The distance being in bounds must not rely on "wrapping around" the + /// address space. + /// + /// Note that callers may pass a pair of pointers such that `start >= end`. + /// In that case, `None` will always be returned. + #[inline] + pub unsafe fn count_raw(&self, start: *const u8, end: *const u8) -> usize { + if start >= end { + return 0; + } + if end.distance(start) < uint8x16_t::BYTES { + // SAFETY: We require the caller to pass valid start/end pointers. + return generic::count_byte_by_byte(start, end, |b| { + b == self.0.needle1() + }); + } + // SAFETY: Building a `One` means it's safe to call 'neon' routines. + // Also, we've checked that our haystack is big enough to run on the + // vector routine. Pointer validity is caller's responsibility. + self.count_raw_impl(start, end) + } + + /// Execute a search using neon vectors and routines. + /// + /// # Safety + /// + /// Same as [`One::find_raw`], except the distance between `start` and + /// `end` must be at least the size of a neon vector (in bytes). + /// + /// (The target feature safety obligation is automatically fulfilled by + /// virtue of being a method on `One`, which can only be constructed + /// when it is safe to call `neon` routines.) + #[target_feature(enable = "neon")] + #[inline] + unsafe fn find_raw_impl( + &self, + start: *const u8, + end: *const u8, + ) -> Option<*const u8> { + self.0.find_raw(start, end) + } + + /// Execute a search using neon vectors and routines. + /// + /// # Safety + /// + /// Same as [`One::rfind_raw`], except the distance between `start` and + /// `end` must be at least the size of a neon vector (in bytes). + /// + /// (The target feature safety obligation is automatically fulfilled by + /// virtue of being a method on `One`, which can only be constructed + /// when it is safe to call `neon` routines.) + #[target_feature(enable = "neon")] + #[inline] + unsafe fn rfind_raw_impl( + &self, + start: *const u8, + end: *const u8, + ) -> Option<*const u8> { + self.0.rfind_raw(start, end) + } + + /// Execute a count using neon vectors and routines. + /// + /// # Safety + /// + /// Same as [`One::count_raw`], except the distance between `start` and + /// `end` must be at least the size of a neon vector (in bytes). + /// + /// (The target feature safety obligation is automatically fulfilled by + /// virtue of being a method on `One`, which can only be constructed + /// when it is safe to call `neon` routines.) + #[target_feature(enable = "neon")] + #[inline] + unsafe fn count_raw_impl( + &self, + start: *const u8, + end: *const u8, + ) -> usize { + self.0.count_raw(start, end) + } + + /// Returns an iterator over all occurrences of the needle byte in the + /// given haystack. + /// + /// The iterator returned implements `DoubleEndedIterator`. This means it + /// can also be used to find occurrences in reverse order. + #[inline] + pub fn iter<'a, 'h>(&'a self, haystack: &'h [u8]) -> OneIter<'a, 'h> { + OneIter { searcher: self, it: generic::Iter::new(haystack) } + } +} + +/// An iterator over all occurrences of a single byte in a haystack. +/// +/// This iterator implements `DoubleEndedIterator`, which means it can also be +/// used to find occurrences in reverse order. +/// +/// This iterator is created by the [`One::iter`] method. +/// +/// The lifetime parameters are as follows: +/// +/// * `'a` refers to the lifetime of the underlying [`One`] searcher. +/// * `'h` refers to the lifetime of the haystack being searched. +#[derive(Clone, Debug)] +pub struct OneIter<'a, 'h> { + searcher: &'a One, + it: generic::Iter<'h>, +} + +impl<'a, 'h> Iterator for OneIter<'a, 'h> { + type Item = usize; + + #[inline] + fn next(&mut self) -> Option { + // SAFETY: We rely on the generic iterator to provide valid start + // and end pointers, but we guarantee that any pointer returned by + // 'find_raw' falls within the bounds of the start and end pointer. + unsafe { self.it.next(|s, e| self.searcher.find_raw(s, e)) } + } + + #[inline] + fn count(self) -> usize { + self.it.count(|s, e| { + // SAFETY: We rely on our generic iterator to return valid start + // and end pointers. + unsafe { self.searcher.count_raw(s, e) } + }) + } + + #[inline] + fn size_hint(&self) -> (usize, Option) { + self.it.size_hint() + } +} + +impl<'a, 'h> DoubleEndedIterator for OneIter<'a, 'h> { + #[inline] + fn next_back(&mut self) -> Option { + // SAFETY: We rely on the generic iterator to provide valid start + // and end pointers, but we guarantee that any pointer returned by + // 'rfind_raw' falls within the bounds of the start and end pointer. + unsafe { self.it.next_back(|s, e| self.searcher.rfind_raw(s, e)) } + } +} + +impl<'a, 'h> core::iter::FusedIterator for OneIter<'a, 'h> {} + +/// Finds all occurrences of two bytes in a haystack. +/// +/// That is, this reports matches of one of two possible bytes. For example, +/// searching for `a` or `b` in `afoobar` would report matches at offsets `0`, +/// `4` and `5`. +#[derive(Clone, Copy, Debug)] +pub struct Two(generic::Two); + +impl Two { + /// Create a new searcher that finds occurrences of the needle bytes given. + /// + /// This particular searcher is specialized to use neon vector instructions + /// that typically make it quite fast. + /// + /// If neon is unavailable in the current environment, then `None` is + /// returned. + #[inline] + pub fn new(needle1: u8, needle2: u8) -> Option { + if Two::is_available() { + // SAFETY: we check that neon is available above. + unsafe { Some(Two::new_unchecked(needle1, needle2)) } + } else { + None + } + } + + /// Create a new finder specific to neon vectors and routines without + /// checking that neon is available. + /// + /// # Safety + /// + /// Callers must guarantee that it is safe to execute `neon` instructions + /// in the current environment. + /// + /// Note that it is a common misconception that if one compiles for an + /// `x86_64` target, then they therefore automatically have access to neon + /// instructions. While this is almost always the case, it isn't true in + /// 100% of cases. + #[target_feature(enable = "neon")] + #[inline] + pub unsafe fn new_unchecked(needle1: u8, needle2: u8) -> Two { + Two(generic::Two::new(needle1, needle2)) + } + + /// Returns true when this implementation is available in the current + /// environment. + /// + /// When this is true, it is guaranteed that [`Two::new`] will return + /// a `Some` value. Similarly, when it is false, it is guaranteed that + /// `Two::new` will return a `None` value. + /// + /// Note also that for the lifetime of a single program, if this returns + /// true then it will always return true. + #[inline] + pub fn is_available() -> bool { + #[cfg(target_feature = "neon")] + { + true + } + #[cfg(not(target_feature = "neon"))] + { + false + } + } + + /// Return the first occurrence of one of the needle bytes in the given + /// haystack. If no such occurrence exists, then `None` is returned. + /// + /// The occurrence is reported as an offset into `haystack`. Its maximum + /// value is `haystack.len() - 1`. + #[inline] + pub fn find(&self, haystack: &[u8]) -> Option { + // SAFETY: `find_raw` guarantees that if a pointer is returned, it + // falls within the bounds of the start and end pointers. + unsafe { + generic::search_slice_with_raw(haystack, |s, e| { + self.find_raw(s, e) + }) + } + } + + /// Return the last occurrence of one of the needle bytes in the given + /// haystack. If no such occurrence exists, then `None` is returned. + /// + /// The occurrence is reported as an offset into `haystack`. Its maximum + /// value is `haystack.len() - 1`. + #[inline] + pub fn rfind(&self, haystack: &[u8]) -> Option { + // SAFETY: `rfind_raw` guarantees that if a pointer is returned, it + // falls within the bounds of the start and end pointers. + unsafe { + generic::search_slice_with_raw(haystack, |s, e| { + self.rfind_raw(s, e) + }) + } + } + + /// Like `find`, but accepts and returns raw pointers. + /// + /// When a match is found, the pointer returned is guaranteed to be + /// `>= start` and `< end`. + /// + /// This routine is useful if you're already using raw pointers and would + /// like to avoid converting back to a slice before executing a search. + /// + /// # Safety + /// + /// * Both `start` and `end` must be valid for reads. + /// * Both `start` and `end` must point to an initialized value. + /// * Both `start` and `end` must point to the same allocated object and + /// must either be in bounds or at most one byte past the end of the + /// allocated object. + /// * Both `start` and `end` must be _derived from_ a pointer to the same + /// object. + /// * The distance between `start` and `end` must not overflow `isize`. + /// * The distance being in bounds must not rely on "wrapping around" the + /// address space. + /// + /// Note that callers may pass a pair of pointers such that `start >= end`. + /// In that case, `None` will always be returned. + #[inline] + pub unsafe fn find_raw( + &self, + start: *const u8, + end: *const u8, + ) -> Option<*const u8> { + if start >= end { + return None; + } + if end.distance(start) < uint8x16_t::BYTES { + // SAFETY: We require the caller to pass valid start/end pointers. + return generic::fwd_byte_by_byte(start, end, |b| { + b == self.0.needle1() || b == self.0.needle2() + }); + } + // SAFETY: Building a `Two` means it's safe to call 'neon' routines. + // Also, we've checked that our haystack is big enough to run on the + // vector routine. Pointer validity is caller's responsibility. + self.find_raw_impl(start, end) + } + + /// Like `rfind`, but accepts and returns raw pointers. + /// + /// When a match is found, the pointer returned is guaranteed to be + /// `>= start` and `< end`. + /// + /// This routine is useful if you're already using raw pointers and would + /// like to avoid converting back to a slice before executing a search. + /// + /// # Safety + /// + /// * Both `start` and `end` must be valid for reads. + /// * Both `start` and `end` must point to an initialized value. + /// * Both `start` and `end` must point to the same allocated object and + /// must either be in bounds or at most one byte past the end of the + /// allocated object. + /// * Both `start` and `end` must be _derived from_ a pointer to the same + /// object. + /// * The distance between `start` and `end` must not overflow `isize`. + /// * The distance being in bounds must not rely on "wrapping around" the + /// address space. + /// + /// Note that callers may pass a pair of pointers such that `start >= end`. + /// In that case, `None` will always be returned. + #[inline] + pub unsafe fn rfind_raw( + &self, + start: *const u8, + end: *const u8, + ) -> Option<*const u8> { + if start >= end { + return None; + } + if end.distance(start) < uint8x16_t::BYTES { + // SAFETY: We require the caller to pass valid start/end pointers. + return generic::rev_byte_by_byte(start, end, |b| { + b == self.0.needle1() || b == self.0.needle2() + }); + } + // SAFETY: Building a `Two` means it's safe to call 'neon' routines. + // Also, we've checked that our haystack is big enough to run on the + // vector routine. Pointer validity is caller's responsibility. + self.rfind_raw_impl(start, end) + } + + /// Execute a search using neon vectors and routines. + /// + /// # Safety + /// + /// Same as [`Two::find_raw`], except the distance between `start` and + /// `end` must be at least the size of a neon vector (in bytes). + /// + /// (The target feature safety obligation is automatically fulfilled by + /// virtue of being a method on `Two`, which can only be constructed + /// when it is safe to call `neon` routines.) + #[target_feature(enable = "neon")] + #[inline] + unsafe fn find_raw_impl( + &self, + start: *const u8, + end: *const u8, + ) -> Option<*const u8> { + self.0.find_raw(start, end) + } + + /// Execute a search using neon vectors and routines. + /// + /// # Safety + /// + /// Same as [`Two::rfind_raw`], except the distance between `start` and + /// `end` must be at least the size of a neon vector (in bytes). + /// + /// (The target feature safety obligation is automatically fulfilled by + /// virtue of being a method on `Two`, which can only be constructed + /// when it is safe to call `neon` routines.) + #[target_feature(enable = "neon")] + #[inline] + unsafe fn rfind_raw_impl( + &self, + start: *const u8, + end: *const u8, + ) -> Option<*const u8> { + self.0.rfind_raw(start, end) + } + + /// Returns an iterator over all occurrences of the needle bytes in the + /// given haystack. + /// + /// The iterator returned implements `DoubleEndedIterator`. This means it + /// can also be used to find occurrences in reverse order. + #[inline] + pub fn iter<'a, 'h>(&'a self, haystack: &'h [u8]) -> TwoIter<'a, 'h> { + TwoIter { searcher: self, it: generic::Iter::new(haystack) } + } +} + +/// An iterator over all occurrences of two possible bytes in a haystack. +/// +/// This iterator implements `DoubleEndedIterator`, which means it can also be +/// used to find occurrences in reverse order. +/// +/// This iterator is created by the [`Two::iter`] method. +/// +/// The lifetime parameters are as follows: +/// +/// * `'a` refers to the lifetime of the underlying [`Two`] searcher. +/// * `'h` refers to the lifetime of the haystack being searched. +#[derive(Clone, Debug)] +pub struct TwoIter<'a, 'h> { + searcher: &'a Two, + it: generic::Iter<'h>, +} + +impl<'a, 'h> Iterator for TwoIter<'a, 'h> { + type Item = usize; + + #[inline] + fn next(&mut self) -> Option { + // SAFETY: We rely on the generic iterator to provide valid start + // and end pointers, but we guarantee that any pointer returned by + // 'find_raw' falls within the bounds of the start and end pointer. + unsafe { self.it.next(|s, e| self.searcher.find_raw(s, e)) } + } + + #[inline] + fn size_hint(&self) -> (usize, Option) { + self.it.size_hint() + } +} + +impl<'a, 'h> DoubleEndedIterator for TwoIter<'a, 'h> { + #[inline] + fn next_back(&mut self) -> Option { + // SAFETY: We rely on the generic iterator to provide valid start + // and end pointers, but we guarantee that any pointer returned by + // 'rfind_raw' falls within the bounds of the start and end pointer. + unsafe { self.it.next_back(|s, e| self.searcher.rfind_raw(s, e)) } + } +} + +impl<'a, 'h> core::iter::FusedIterator for TwoIter<'a, 'h> {} + +/// Finds all occurrences of three bytes in a haystack. +/// +/// That is, this reports matches of one of three possible bytes. For example, +/// searching for `a`, `b` or `o` in `afoobar` would report matches at offsets +/// `0`, `2`, `3`, `4` and `5`. +#[derive(Clone, Copy, Debug)] +pub struct Three(generic::Three); + +impl Three { + /// Create a new searcher that finds occurrences of the needle bytes given. + /// + /// This particular searcher is specialized to use neon vector instructions + /// that typically make it quite fast. + /// + /// If neon is unavailable in the current environment, then `None` is + /// returned. + #[inline] + pub fn new(needle1: u8, needle2: u8, needle3: u8) -> Option { + if Three::is_available() { + // SAFETY: we check that neon is available above. + unsafe { Some(Three::new_unchecked(needle1, needle2, needle3)) } + } else { + None + } + } + + /// Create a new finder specific to neon vectors and routines without + /// checking that neon is available. + /// + /// # Safety + /// + /// Callers must guarantee that it is safe to execute `neon` instructions + /// in the current environment. + /// + /// Note that it is a common misconception that if one compiles for an + /// `x86_64` target, then they therefore automatically have access to neon + /// instructions. While this is almost always the case, it isn't true in + /// 100% of cases. + #[target_feature(enable = "neon")] + #[inline] + pub unsafe fn new_unchecked( + needle1: u8, + needle2: u8, + needle3: u8, + ) -> Three { + Three(generic::Three::new(needle1, needle2, needle3)) + } + + /// Returns true when this implementation is available in the current + /// environment. + /// + /// When this is true, it is guaranteed that [`Three::new`] will return + /// a `Some` value. Similarly, when it is false, it is guaranteed that + /// `Three::new` will return a `None` value. + /// + /// Note also that for the lifetime of a single program, if this returns + /// true then it will always return true. + #[inline] + pub fn is_available() -> bool { + #[cfg(target_feature = "neon")] + { + true + } + #[cfg(not(target_feature = "neon"))] + { + false + } + } + + /// Return the first occurrence of one of the needle bytes in the given + /// haystack. If no such occurrence exists, then `None` is returned. + /// + /// The occurrence is reported as an offset into `haystack`. Its maximum + /// value is `haystack.len() - 1`. + #[inline] + pub fn find(&self, haystack: &[u8]) -> Option { + // SAFETY: `find_raw` guarantees that if a pointer is returned, it + // falls within the bounds of the start and end pointers. + unsafe { + generic::search_slice_with_raw(haystack, |s, e| { + self.find_raw(s, e) + }) + } + } + + /// Return the last occurrence of one of the needle bytes in the given + /// haystack. If no such occurrence exists, then `None` is returned. + /// + /// The occurrence is reported as an offset into `haystack`. Its maximum + /// value is `haystack.len() - 1`. + #[inline] + pub fn rfind(&self, haystack: &[u8]) -> Option { + // SAFETY: `rfind_raw` guarantees that if a pointer is returned, it + // falls within the bounds of the start and end pointers. + unsafe { + generic::search_slice_with_raw(haystack, |s, e| { + self.rfind_raw(s, e) + }) + } + } + + /// Like `find`, but accepts and returns raw pointers. + /// + /// When a match is found, the pointer returned is guaranteed to be + /// `>= start` and `< end`. + /// + /// This routine is useful if you're already using raw pointers and would + /// like to avoid converting back to a slice before executing a search. + /// + /// # Safety + /// + /// * Both `start` and `end` must be valid for reads. + /// * Both `start` and `end` must point to an initialized value. + /// * Both `start` and `end` must point to the same allocated object and + /// must either be in bounds or at most one byte past the end of the + /// allocated object. + /// * Both `start` and `end` must be _derived from_ a pointer to the same + /// object. + /// * The distance between `start` and `end` must not overflow `isize`. + /// * The distance being in bounds must not rely on "wrapping around" the + /// address space. + /// + /// Note that callers may pass a pair of pointers such that `start >= end`. + /// In that case, `None` will always be returned. + #[inline] + pub unsafe fn find_raw( + &self, + start: *const u8, + end: *const u8, + ) -> Option<*const u8> { + if start >= end { + return None; + } + if end.distance(start) < uint8x16_t::BYTES { + // SAFETY: We require the caller to pass valid start/end pointers. + return generic::fwd_byte_by_byte(start, end, |b| { + b == self.0.needle1() + || b == self.0.needle2() + || b == self.0.needle3() + }); + } + // SAFETY: Building a `Three` means it's safe to call 'neon' routines. + // Also, we've checked that our haystack is big enough to run on the + // vector routine. Pointer validity is caller's responsibility. + self.find_raw_impl(start, end) + } + + /// Like `rfind`, but accepts and returns raw pointers. + /// + /// When a match is found, the pointer returned is guaranteed to be + /// `>= start` and `< end`. + /// + /// This routine is useful if you're already using raw pointers and would + /// like to avoid converting back to a slice before executing a search. + /// + /// # Safety + /// + /// * Both `start` and `end` must be valid for reads. + /// * Both `start` and `end` must point to an initialized value. + /// * Both `start` and `end` must point to the same allocated object and + /// must either be in bounds or at most one byte past the end of the + /// allocated object. + /// * Both `start` and `end` must be _derived from_ a pointer to the same + /// object. + /// * The distance between `start` and `end` must not overflow `isize`. + /// * The distance being in bounds must not rely on "wrapping around" the + /// address space. + /// + /// Note that callers may pass a pair of pointers such that `start >= end`. + /// In that case, `None` will always be returned. + #[inline] + pub unsafe fn rfind_raw( + &self, + start: *const u8, + end: *const u8, + ) -> Option<*const u8> { + if start >= end { + return None; + } + if end.distance(start) < uint8x16_t::BYTES { + // SAFETY: We require the caller to pass valid start/end pointers. + return generic::rev_byte_by_byte(start, end, |b| { + b == self.0.needle1() + || b == self.0.needle2() + || b == self.0.needle3() + }); + } + // SAFETY: Building a `Three` means it's safe to call 'neon' routines. + // Also, we've checked that our haystack is big enough to run on the + // vector routine. Pointer validity is caller's responsibility. + self.rfind_raw_impl(start, end) + } + + /// Execute a search using neon vectors and routines. + /// + /// # Safety + /// + /// Same as [`Three::find_raw`], except the distance between `start` and + /// `end` must be at least the size of a neon vector (in bytes). + /// + /// (The target feature safety obligation is automatically fulfilled by + /// virtue of being a method on `Three`, which can only be constructed + /// when it is safe to call `neon` routines.) + #[target_feature(enable = "neon")] + #[inline] + unsafe fn find_raw_impl( + &self, + start: *const u8, + end: *const u8, + ) -> Option<*const u8> { + self.0.find_raw(start, end) + } + + /// Execute a search using neon vectors and routines. + /// + /// # Safety + /// + /// Same as [`Three::rfind_raw`], except the distance between `start` and + /// `end` must be at least the size of a neon vector (in bytes). + /// + /// (The target feature safety obligation is automatically fulfilled by + /// virtue of being a method on `Three`, which can only be constructed + /// when it is safe to call `neon` routines.) + #[target_feature(enable = "neon")] + #[inline] + unsafe fn rfind_raw_impl( + &self, + start: *const u8, + end: *const u8, + ) -> Option<*const u8> { + self.0.rfind_raw(start, end) + } + + /// Returns an iterator over all occurrences of the needle byte in the + /// given haystack. + /// + /// The iterator returned implements `DoubleEndedIterator`. This means it + /// can also be used to find occurrences in reverse order. + #[inline] + pub fn iter<'a, 'h>(&'a self, haystack: &'h [u8]) -> ThreeIter<'a, 'h> { + ThreeIter { searcher: self, it: generic::Iter::new(haystack) } + } +} + +/// An iterator over all occurrences of three possible bytes in a haystack. +/// +/// This iterator implements `DoubleEndedIterator`, which means it can also be +/// used to find occurrences in reverse order. +/// +/// This iterator is created by the [`Three::iter`] method. +/// +/// The lifetime parameters are as follows: +/// +/// * `'a` refers to the lifetime of the underlying [`Three`] searcher. +/// * `'h` refers to the lifetime of the haystack being searched. +#[derive(Clone, Debug)] +pub struct ThreeIter<'a, 'h> { + searcher: &'a Three, + it: generic::Iter<'h>, +} + +impl<'a, 'h> Iterator for ThreeIter<'a, 'h> { + type Item = usize; + + #[inline] + fn next(&mut self) -> Option { + // SAFETY: We rely on the generic iterator to provide valid start + // and end pointers, but we guarantee that any pointer returned by + // 'find_raw' falls within the bounds of the start and end pointer. + unsafe { self.it.next(|s, e| self.searcher.find_raw(s, e)) } + } + + #[inline] + fn size_hint(&self) -> (usize, Option) { + self.it.size_hint() + } +} + +impl<'a, 'h> DoubleEndedIterator for ThreeIter<'a, 'h> { + #[inline] + fn next_back(&mut self) -> Option { + // SAFETY: We rely on the generic iterator to provide valid start + // and end pointers, but we guarantee that any pointer returned by + // 'rfind_raw' falls within the bounds of the start and end pointer. + unsafe { self.it.next_back(|s, e| self.searcher.rfind_raw(s, e)) } + } +} + +impl<'a, 'h> core::iter::FusedIterator for ThreeIter<'a, 'h> {} + +#[cfg(test)] +mod tests { + use super::*; + + define_memchr_quickcheck!(super); + + #[test] + fn forward_one() { + crate::tests::memchr::Runner::new(1).forward_iter( + |haystack, needles| { + Some(One::new(needles[0])?.iter(haystack).collect()) + }, + ) + } + + #[test] + fn reverse_one() { + crate::tests::memchr::Runner::new(1).reverse_iter( + |haystack, needles| { + Some(One::new(needles[0])?.iter(haystack).rev().collect()) + }, + ) + } + + #[test] + fn count_one() { + crate::tests::memchr::Runner::new(1).count_iter(|haystack, needles| { + Some(One::new(needles[0])?.iter(haystack).count()) + }) + } + + #[test] + fn forward_two() { + crate::tests::memchr::Runner::new(2).forward_iter( + |haystack, needles| { + let n1 = needles.get(0).copied()?; + let n2 = needles.get(1).copied()?; + Some(Two::new(n1, n2)?.iter(haystack).collect()) + }, + ) + } + + #[test] + fn reverse_two() { + crate::tests::memchr::Runner::new(2).reverse_iter( + |haystack, needles| { + let n1 = needles.get(0).copied()?; + let n2 = needles.get(1).copied()?; + Some(Two::new(n1, n2)?.iter(haystack).rev().collect()) + }, + ) + } + + #[test] + fn forward_three() { + crate::tests::memchr::Runner::new(3).forward_iter( + |haystack, needles| { + let n1 = needles.get(0).copied()?; + let n2 = needles.get(1).copied()?; + let n3 = needles.get(2).copied()?; + Some(Three::new(n1, n2, n3)?.iter(haystack).collect()) + }, + ) + } + + #[test] + fn reverse_three() { + crate::tests::memchr::Runner::new(3).reverse_iter( + |haystack, needles| { + let n1 = needles.get(0).copied()?; + let n2 = needles.get(1).copied()?; + let n3 = needles.get(2).copied()?; + Some(Three::new(n1, n2, n3)?.iter(haystack).rev().collect()) + }, + ) + } +} diff --git a/vendor/memchr/src/arch/aarch64/neon/mod.rs b/vendor/memchr/src/arch/aarch64/neon/mod.rs new file mode 100644 index 0000000..ccf9cf8 --- /dev/null +++ b/vendor/memchr/src/arch/aarch64/neon/mod.rs @@ -0,0 +1,6 @@ +/*! +Algorithms for the `aarch64` target using 128-bit vectors via NEON. +*/ + +pub mod memchr; +pub mod packedpair; diff --git a/vendor/memchr/src/arch/aarch64/neon/packedpair.rs b/vendor/memchr/src/arch/aarch64/neon/packedpair.rs new file mode 100644 index 0000000..6884882 --- /dev/null +++ b/vendor/memchr/src/arch/aarch64/neon/packedpair.rs @@ -0,0 +1,236 @@ +/*! +A 128-bit vector implementation of the "packed pair" SIMD algorithm. + +The "packed pair" algorithm is based on the [generic SIMD] algorithm. The main +difference is that it (by default) uses a background distribution of byte +frequencies to heuristically select the pair of bytes to search for. + +[generic SIMD]: http://0x80.pl/articles/simd-strfind.html#first-and-last +*/ + +use core::arch::aarch64::uint8x16_t; + +use crate::arch::{all::packedpair::Pair, generic::packedpair}; + +/// A "packed pair" finder that uses 128-bit vector operations. +/// +/// This finder picks two bytes that it believes have high predictive power +/// for indicating an overall match of a needle. Depending on whether +/// `Finder::find` or `Finder::find_prefilter` is used, it reports offsets +/// where the needle matches or could match. In the prefilter case, candidates +/// are reported whenever the [`Pair`] of bytes given matches. +#[derive(Clone, Copy, Debug)] +pub struct Finder(packedpair::Finder); + +/// A "packed pair" finder that uses 128-bit vector operations. +/// +/// This finder picks two bytes that it believes have high predictive power +/// for indicating an overall match of a needle. Depending on whether +/// `Finder::find` or `Finder::find_prefilter` is used, it reports offsets +/// where the needle matches or could match. In the prefilter case, candidates +/// are reported whenever the [`Pair`] of bytes given matches. +impl Finder { + /// Create a new pair searcher. The searcher returned can either report + /// exact matches of `needle` or act as a prefilter and report candidate + /// positions of `needle`. + /// + /// If neon is unavailable in the current environment or if a [`Pair`] + /// could not be constructed from the needle given, then `None` is + /// returned. + #[inline] + pub fn new(needle: &[u8]) -> Option { + Finder::with_pair(needle, Pair::new(needle)?) + } + + /// Create a new "packed pair" finder using the pair of bytes given. + /// + /// This constructor permits callers to control precisely which pair of + /// bytes is used as a predicate. + /// + /// If neon is unavailable in the current environment, then `None` is + /// returned. + #[inline] + pub fn with_pair(needle: &[u8], pair: Pair) -> Option { + if Finder::is_available() { + // SAFETY: we check that sse2 is available above. We are also + // guaranteed to have needle.len() > 1 because we have a valid + // Pair. + unsafe { Some(Finder::with_pair_impl(needle, pair)) } + } else { + None + } + } + + /// Create a new `Finder` specific to neon vectors and routines. + /// + /// # Safety + /// + /// Same as the safety for `packedpair::Finder::new`, and callers must also + /// ensure that neon is available. + #[target_feature(enable = "neon")] + #[inline] + unsafe fn with_pair_impl(needle: &[u8], pair: Pair) -> Finder { + let finder = packedpair::Finder::::new(needle, pair); + Finder(finder) + } + + /// Returns true when this implementation is available in the current + /// environment. + /// + /// When this is true, it is guaranteed that [`Finder::with_pair`] will + /// return a `Some` value. Similarly, when it is false, it is guaranteed + /// that `Finder::with_pair` will return a `None` value. Notice that this + /// does not guarantee that [`Finder::new`] will return a `Finder`. Namely, + /// even when `Finder::is_available` is true, it is not guaranteed that a + /// valid [`Pair`] can be found from the needle given. + /// + /// Note also that for the lifetime of a single program, if this returns + /// true then it will always return true. + #[inline] + pub fn is_available() -> bool { + #[cfg(target_feature = "neon")] + { + true + } + #[cfg(not(target_feature = "neon"))] + { + false + } + } + + /// Execute a search using neon vectors and routines. + /// + /// # Panics + /// + /// When `haystack.len()` is less than [`Finder::min_haystack_len`]. + #[inline] + pub fn find(&self, haystack: &[u8], needle: &[u8]) -> Option { + // SAFETY: Building a `Finder` means it's safe to call 'neon' routines. + unsafe { self.find_impl(haystack, needle) } + } + + /// Execute a search using neon vectors and routines. + /// + /// # Panics + /// + /// When `haystack.len()` is less than [`Finder::min_haystack_len`]. + #[inline] + pub fn find_prefilter(&self, haystack: &[u8]) -> Option { + // SAFETY: Building a `Finder` means it's safe to call 'neon' routines. + unsafe { self.find_prefilter_impl(haystack) } + } + + /// Execute a search using neon vectors and routines. + /// + /// # Panics + /// + /// When `haystack.len()` is less than [`Finder::min_haystack_len`]. + /// + /// # Safety + /// + /// (The target feature safety obligation is automatically fulfilled by + /// virtue of being a method on `Finder`, which can only be constructed + /// when it is safe to call `neon` routines.) + #[target_feature(enable = "neon")] + #[inline] + unsafe fn find_impl( + &self, + haystack: &[u8], + needle: &[u8], + ) -> Option { + self.0.find(haystack, needle) + } + + /// Execute a prefilter search using neon vectors and routines. + /// + /// # Panics + /// + /// When `haystack.len()` is less than [`Finder::min_haystack_len`]. + /// + /// # Safety + /// + /// (The target feature safety obligation is automatically fulfilled by + /// virtue of being a method on `Finder`, which can only be constructed + /// when it is safe to call `neon` routines.) + #[target_feature(enable = "neon")] + #[inline] + unsafe fn find_prefilter_impl(&self, haystack: &[u8]) -> Option { + self.0.find_prefilter(haystack) + } + + /// Returns the pair of offsets (into the needle) used to check as a + /// predicate before confirming whether a needle exists at a particular + /// position. + #[inline] + pub fn pair(&self) -> &Pair { + self.0.pair() + } + + /// Returns the minimum haystack length that this `Finder` can search. + /// + /// Using a haystack with length smaller than this in a search will result + /// in a panic. The reason for this restriction is that this finder is + /// meant to be a low-level component that is part of a larger substring + /// strategy. In that sense, it avoids trying to handle all cases and + /// instead only handles the cases that it can handle very well. + #[inline] + pub fn min_haystack_len(&self) -> usize { + self.0.min_haystack_len() + } +} + +#[cfg(test)] +mod tests { + use super::*; + + fn find(haystack: &[u8], needle: &[u8]) -> Option> { + let f = Finder::new(needle)?; + if haystack.len() < f.min_haystack_len() { + return None; + } + Some(f.find(haystack, needle)) + } + + define_substring_forward_quickcheck!(find); + + #[test] + fn forward_substring() { + crate::tests::substring::Runner::new().fwd(find).run() + } + + #[test] + fn forward_packedpair() { + fn find( + haystack: &[u8], + needle: &[u8], + index1: u8, + index2: u8, + ) -> Option> { + let pair = Pair::with_indices(needle, index1, index2)?; + let f = Finder::with_pair(needle, pair)?; + if haystack.len() < f.min_haystack_len() { + return None; + } + Some(f.find(haystack, needle)) + } + crate::tests::packedpair::Runner::new().fwd(find).run() + } + + #[test] + fn forward_packedpair_prefilter() { + fn find( + haystack: &[u8], + needle: &[u8], + index1: u8, + index2: u8, + ) -> Option> { + let pair = Pair::with_indices(needle, index1, index2)?; + let f = Finder::with_pair(needle, pair)?; + if haystack.len() < f.min_haystack_len() { + return None; + } + Some(f.find_prefilter(haystack)) + } + crate::tests::packedpair::Runner::new().fwd(find).run() + } +} diff --git a/vendor/memchr/src/arch/all/memchr.rs b/vendor/memchr/src/arch/all/memchr.rs new file mode 100644 index 0000000..62fe2a3 --- /dev/null +++ b/vendor/memchr/src/arch/all/memchr.rs @@ -0,0 +1,1022 @@ +/*! +Provides architecture independent implementations of `memchr` and friends. + +The main types in this module are [`One`], [`Two`] and [`Three`]. They are for +searching for one, two or three distinct bytes, respectively, in a haystack. +Each type also has corresponding double ended iterators. These searchers +are typically slower than hand-coded vector routines accomplishing the same +task, but are also typically faster than naive scalar code. These routines +effectively work by treating a `usize` as a vector of 8-bit lanes, and thus +achieves some level of data parallelism even without explicit vector support. + +The `One` searcher also provides a [`One::count`] routine for efficiently +counting the number of times a single byte occurs in a haystack. This is +useful, for example, for counting the number of lines in a haystack. This +routine exists because it is usually faster, especially with a high match +count, then using [`One::find`] repeatedly. ([`OneIter`] specializes its +`Iterator::count` implementation to use this routine.) + +Only one, two and three bytes are supported because three bytes is about +the point where one sees diminishing returns. Beyond this point and it's +probably (but not necessarily) better to just use a simple `[bool; 256]` array +or similar. However, it depends mightily on the specific work-load and the +expected match frequency. +*/ + +use crate::{arch::generic::memchr as generic, ext::Pointer}; + +/// The number of bytes in a single `usize` value. +const USIZE_BYTES: usize = (usize::BITS / 8) as usize; +/// The bits that must be zero for a `*const usize` to be properly aligned. +const USIZE_ALIGN: usize = USIZE_BYTES - 1; + +/// Finds all occurrences of a single byte in a haystack. +#[derive(Clone, Copy, Debug)] +pub struct One { + s1: u8, + v1: usize, +} + +impl One { + /// The number of bytes we examine per each iteration of our search loop. + const LOOP_BYTES: usize = 2 * USIZE_BYTES; + + /// Create a new searcher that finds occurrences of the byte given. + #[inline] + pub fn new(needle: u8) -> One { + One { s1: needle, v1: splat(needle) } + } + + /// A test-only routine so that we can bundle a bunch of quickcheck + /// properties into a single macro. Basically, this provides a constructor + /// that makes it identical to most other memchr implementations, which + /// have fallible constructors. + #[cfg(test)] + pub(crate) fn try_new(needle: u8) -> Option { + Some(One::new(needle)) + } + + /// Return the first occurrence of the needle in the given haystack. If no + /// such occurrence exists, then `None` is returned. + /// + /// The occurrence is reported as an offset into `haystack`. Its maximum + /// value for a non-empty haystack is `haystack.len() - 1`. + #[inline] + pub fn find(&self, haystack: &[u8]) -> Option { + // SAFETY: `find_raw` guarantees that if a pointer is returned, it + // falls within the bounds of the start and end pointers. + unsafe { + generic::search_slice_with_raw(haystack, |s, e| { + self.find_raw(s, e) + }) + } + } + + /// Return the last occurrence of the needle in the given haystack. If no + /// such occurrence exists, then `None` is returned. + /// + /// The occurrence is reported as an offset into `haystack`. Its maximum + /// value for a non-empty haystack is `haystack.len() - 1`. + #[inline] + pub fn rfind(&self, haystack: &[u8]) -> Option { + // SAFETY: `find_raw` guarantees that if a pointer is returned, it + // falls within the bounds of the start and end pointers. + unsafe { + generic::search_slice_with_raw(haystack, |s, e| { + self.rfind_raw(s, e) + }) + } + } + + /// Counts all occurrences of this byte in the given haystack. + #[inline] + pub fn count(&self, haystack: &[u8]) -> usize { + // SAFETY: All of our pointers are derived directly from a borrowed + // slice, which is guaranteed to be valid. + unsafe { + let start = haystack.as_ptr(); + let end = start.add(haystack.len()); + self.count_raw(start, end) + } + } + + /// Like `find`, but accepts and returns raw pointers. + /// + /// When a match is found, the pointer returned is guaranteed to be + /// `>= start` and `< end`. + /// + /// This routine is useful if you're already using raw pointers and would + /// like to avoid converting back to a slice before executing a search. + /// + /// # Safety + /// + /// * Both `start` and `end` must be valid for reads. + /// * Both `start` and `end` must point to an initialized value. + /// * Both `start` and `end` must point to the same allocated object and + /// must either be in bounds or at most one byte past the end of the + /// allocated object. + /// * Both `start` and `end` must be _derived from_ a pointer to the same + /// object. + /// * The distance between `start` and `end` must not overflow `isize`. + /// * The distance being in bounds must not rely on "wrapping around" the + /// address space. + /// + /// Note that callers may pass a pair of pointers such that `start >= end`. + /// In that case, `None` will always be returned. + #[inline] + pub unsafe fn find_raw( + &self, + start: *const u8, + end: *const u8, + ) -> Option<*const u8> { + if start >= end { + return None; + } + let confirm = |b| self.confirm(b); + let len = end.distance(start); + if len < USIZE_BYTES { + return generic::fwd_byte_by_byte(start, end, confirm); + } + + // The start of the search may not be aligned to `*const usize`, + // so we do an unaligned load here. + let chunk = start.cast::().read_unaligned(); + if self.has_needle(chunk) { + return generic::fwd_byte_by_byte(start, end, confirm); + } + + // And now we start our search at a guaranteed aligned position. + // The first iteration of the loop below will overlap with the the + // unaligned chunk above in cases where the search starts at an + // unaligned offset, but that's okay as we're only here if that + // above didn't find a match. + let mut cur = + start.add(USIZE_BYTES - (start.as_usize() & USIZE_ALIGN)); + debug_assert!(cur > start); + if len <= One::LOOP_BYTES { + return generic::fwd_byte_by_byte(cur, end, confirm); + } + debug_assert!(end.sub(One::LOOP_BYTES) >= start); + while cur <= end.sub(One::LOOP_BYTES) { + debug_assert_eq!(0, cur.as_usize() % USIZE_BYTES); + + let a = cur.cast::().read(); + let b = cur.add(USIZE_BYTES).cast::().read(); + if self.has_needle(a) || self.has_needle(b) { + break; + } + cur = cur.add(One::LOOP_BYTES); + } + generic::fwd_byte_by_byte(cur, end, confirm) + } + + /// Like `rfind`, but accepts and returns raw pointers. + /// + /// When a match is found, the pointer returned is guaranteed to be + /// `>= start` and `< end`. + /// + /// This routine is useful if you're already using raw pointers and would + /// like to avoid converting back to a slice before executing a search. + /// + /// # Safety + /// + /// * Both `start` and `end` must be valid for reads. + /// * Both `start` and `end` must point to an initialized value. + /// * Both `start` and `end` must point to the same allocated object and + /// must either be in bounds or at most one byte past the end of the + /// allocated object. + /// * Both `start` and `end` must be _derived from_ a pointer to the same + /// object. + /// * The distance between `start` and `end` must not overflow `isize`. + /// * The distance being in bounds must not rely on "wrapping around" the + /// address space. + /// + /// Note that callers may pass a pair of pointers such that `start >= end`. + /// In that case, `None` will always be returned. + #[inline] + pub unsafe fn rfind_raw( + &self, + start: *const u8, + end: *const u8, + ) -> Option<*const u8> { + if start >= end { + return None; + } + let confirm = |b| self.confirm(b); + let len = end.distance(start); + if len < USIZE_BYTES { + return generic::rev_byte_by_byte(start, end, confirm); + } + + let chunk = end.sub(USIZE_BYTES).cast::().read_unaligned(); + if self.has_needle(chunk) { + return generic::rev_byte_by_byte(start, end, confirm); + } + + let mut cur = end.sub(end.as_usize() & USIZE_ALIGN); + debug_assert!(start <= cur && cur <= end); + if len <= One::LOOP_BYTES { + return generic::rev_byte_by_byte(start, cur, confirm); + } + while cur >= start.add(One::LOOP_BYTES) { + debug_assert_eq!(0, cur.as_usize() % USIZE_BYTES); + + let a = cur.sub(2 * USIZE_BYTES).cast::().read(); + let b = cur.sub(1 * USIZE_BYTES).cast::().read(); + if self.has_needle(a) || self.has_needle(b) { + break; + } + cur = cur.sub(One::LOOP_BYTES); + } + generic::rev_byte_by_byte(start, cur, confirm) + } + + /// Counts all occurrences of this byte in the given haystack represented + /// by raw pointers. + /// + /// This routine is useful if you're already using raw pointers and would + /// like to avoid converting back to a slice before executing a search. + /// + /// # Safety + /// + /// * Both `start` and `end` must be valid for reads. + /// * Both `start` and `end` must point to an initialized value. + /// * Both `start` and `end` must point to the same allocated object and + /// must either be in bounds or at most one byte past the end of the + /// allocated object. + /// * Both `start` and `end` must be _derived from_ a pointer to the same + /// object. + /// * The distance between `start` and `end` must not overflow `isize`. + /// * The distance being in bounds must not rely on "wrapping around" the + /// address space. + /// + /// Note that callers may pass a pair of pointers such that `start >= end`. + /// In that case, `0` will always be returned. + #[inline] + pub unsafe fn count_raw(&self, start: *const u8, end: *const u8) -> usize { + if start >= end { + return 0; + } + // Sadly I couldn't get the SWAR approach to work here, so we just do + // one byte at a time for now. PRs to improve this are welcome. + let mut ptr = start; + let mut count = 0; + while ptr < end { + count += (ptr.read() == self.s1) as usize; + ptr = ptr.offset(1); + } + count + } + + /// Returns an iterator over all occurrences of the needle byte in the + /// given haystack. + /// + /// The iterator returned implements `DoubleEndedIterator`. This means it + /// can also be used to find occurrences in reverse order. + pub fn iter<'a, 'h>(&'a self, haystack: &'h [u8]) -> OneIter<'a, 'h> { + OneIter { searcher: self, it: generic::Iter::new(haystack) } + } + + #[inline(always)] + fn has_needle(&self, chunk: usize) -> bool { + has_zero_byte(self.v1 ^ chunk) + } + + #[inline(always)] + fn confirm(&self, haystack_byte: u8) -> bool { + self.s1 == haystack_byte + } +} + +/// An iterator over all occurrences of a single byte in a haystack. +/// +/// This iterator implements `DoubleEndedIterator`, which means it can also be +/// used to find occurrences in reverse order. +/// +/// This iterator is created by the [`One::iter`] method. +/// +/// The lifetime parameters are as follows: +/// +/// * `'a` refers to the lifetime of the underlying [`One`] searcher. +/// * `'h` refers to the lifetime of the haystack being searched. +#[derive(Clone, Debug)] +pub struct OneIter<'a, 'h> { + /// The underlying memchr searcher. + searcher: &'a One, + /// Generic iterator implementation. + it: generic::Iter<'h>, +} + +impl<'a, 'h> Iterator for OneIter<'a, 'h> { + type Item = usize; + + #[inline] + fn next(&mut self) -> Option { + // SAFETY: We rely on the generic iterator to provide valid start + // and end pointers, but we guarantee that any pointer returned by + // 'find_raw' falls within the bounds of the start and end pointer. + unsafe { self.it.next(|s, e| self.searcher.find_raw(s, e)) } + } + + #[inline] + fn count(self) -> usize { + self.it.count(|s, e| { + // SAFETY: We rely on our generic iterator to return valid start + // and end pointers. + unsafe { self.searcher.count_raw(s, e) } + }) + } + + #[inline] + fn size_hint(&self) -> (usize, Option) { + self.it.size_hint() + } +} + +impl<'a, 'h> DoubleEndedIterator for OneIter<'a, 'h> { + #[inline] + fn next_back(&mut self) -> Option { + // SAFETY: We rely on the generic iterator to provide valid start + // and end pointers, but we guarantee that any pointer returned by + // 'rfind_raw' falls within the bounds of the start and end pointer. + unsafe { self.it.next_back(|s, e| self.searcher.rfind_raw(s, e)) } + } +} + +/// Finds all occurrences of two bytes in a haystack. +/// +/// That is, this reports matches of one of two possible bytes. For example, +/// searching for `a` or `b` in `afoobar` would report matches at offsets `0`, +/// `4` and `5`. +#[derive(Clone, Copy, Debug)] +pub struct Two { + s1: u8, + s2: u8, + v1: usize, + v2: usize, +} + +impl Two { + /// Create a new searcher that finds occurrences of the two needle bytes + /// given. + #[inline] + pub fn new(needle1: u8, needle2: u8) -> Two { + Two { + s1: needle1, + s2: needle2, + v1: splat(needle1), + v2: splat(needle2), + } + } + + /// A test-only routine so that we can bundle a bunch of quickcheck + /// properties into a single macro. Basically, this provides a constructor + /// that makes it identical to most other memchr implementations, which + /// have fallible constructors. + #[cfg(test)] + pub(crate) fn try_new(needle1: u8, needle2: u8) -> Option { + Some(Two::new(needle1, needle2)) + } + + /// Return the first occurrence of one of the needle bytes in the given + /// haystack. If no such occurrence exists, then `None` is returned. + /// + /// The occurrence is reported as an offset into `haystack`. Its maximum + /// value for a non-empty haystack is `haystack.len() - 1`. + #[inline] + pub fn find(&self, haystack: &[u8]) -> Option { + // SAFETY: `find_raw` guarantees that if a pointer is returned, it + // falls within the bounds of the start and end pointers. + unsafe { + generic::search_slice_with_raw(haystack, |s, e| { + self.find_raw(s, e) + }) + } + } + + /// Return the last occurrence of one of the needle bytes in the given + /// haystack. If no such occurrence exists, then `None` is returned. + /// + /// The occurrence is reported as an offset into `haystack`. Its maximum + /// value for a non-empty haystack is `haystack.len() - 1`. + #[inline] + pub fn rfind(&self, haystack: &[u8]) -> Option { + // SAFETY: `find_raw` guarantees that if a pointer is returned, it + // falls within the bounds of the start and end pointers. + unsafe { + generic::search_slice_with_raw(haystack, |s, e| { + self.rfind_raw(s, e) + }) + } + } + + /// Like `find`, but accepts and returns raw pointers. + /// + /// When a match is found, the pointer returned is guaranteed to be + /// `>= start` and `< end`. + /// + /// This routine is useful if you're already using raw pointers and would + /// like to avoid converting back to a slice before executing a search. + /// + /// # Safety + /// + /// * Both `start` and `end` must be valid for reads. + /// * Both `start` and `end` must point to an initialized value. + /// * Both `start` and `end` must point to the same allocated object and + /// must either be in bounds or at most one byte past the end of the + /// allocated object. + /// * Both `start` and `end` must be _derived from_ a pointer to the same + /// object. + /// * The distance between `start` and `end` must not overflow `isize`. + /// * The distance being in bounds must not rely on "wrapping around" the + /// address space. + /// + /// Note that callers may pass a pair of pointers such that `start >= end`. + /// In that case, `None` will always be returned. + #[inline] + pub unsafe fn find_raw( + &self, + start: *const u8, + end: *const u8, + ) -> Option<*const u8> { + if start >= end { + return None; + } + let confirm = |b| self.confirm(b); + let len = end.distance(start); + if len < USIZE_BYTES { + return generic::fwd_byte_by_byte(start, end, confirm); + } + + // The start of the search may not be aligned to `*const usize`, + // so we do an unaligned load here. + let chunk = start.cast::().read_unaligned(); + if self.has_needle(chunk) { + return generic::fwd_byte_by_byte(start, end, confirm); + } + + // And now we start our search at a guaranteed aligned position. + // The first iteration of the loop below will overlap with the the + // unaligned chunk above in cases where the search starts at an + // unaligned offset, but that's okay as we're only here if that + // above didn't find a match. + let mut cur = + start.add(USIZE_BYTES - (start.as_usize() & USIZE_ALIGN)); + debug_assert!(cur > start); + debug_assert!(end.sub(USIZE_BYTES) >= start); + while cur <= end.sub(USIZE_BYTES) { + debug_assert_eq!(0, cur.as_usize() % USIZE_BYTES); + + let chunk = cur.cast::().read(); + if self.has_needle(chunk) { + break; + } + cur = cur.add(USIZE_BYTES); + } + generic::fwd_byte_by_byte(cur, end, confirm) + } + + /// Like `rfind`, but accepts and returns raw pointers. + /// + /// When a match is found, the pointer returned is guaranteed to be + /// `>= start` and `< end`. + /// + /// This routine is useful if you're already using raw pointers and would + /// like to avoid converting back to a slice before executing a search. + /// + /// # Safety + /// + /// * Both `start` and `end` must be valid for reads. + /// * Both `start` and `end` must point to an initialized value. + /// * Both `start` and `end` must point to the same allocated object and + /// must either be in bounds or at most one byte past the end of the + /// allocated object. + /// * Both `start` and `end` must be _derived from_ a pointer to the same + /// object. + /// * The distance between `start` and `end` must not overflow `isize`. + /// * The distance being in bounds must not rely on "wrapping around" the + /// address space. + /// + /// Note that callers may pass a pair of pointers such that `start >= end`. + /// In that case, `None` will always be returned. + #[inline] + pub unsafe fn rfind_raw( + &self, + start: *const u8, + end: *const u8, + ) -> Option<*const u8> { + if start >= end { + return None; + } + let confirm = |b| self.confirm(b); + let len = end.distance(start); + if len < USIZE_BYTES { + return generic::rev_byte_by_byte(start, end, confirm); + } + + let chunk = end.sub(USIZE_BYTES).cast::().read_unaligned(); + if self.has_needle(chunk) { + return generic::rev_byte_by_byte(start, end, confirm); + } + + let mut cur = end.sub(end.as_usize() & USIZE_ALIGN); + debug_assert!(start <= cur && cur <= end); + while cur >= start.add(USIZE_BYTES) { + debug_assert_eq!(0, cur.as_usize() % USIZE_BYTES); + + let chunk = cur.sub(USIZE_BYTES).cast::().read(); + if self.has_needle(chunk) { + break; + } + cur = cur.sub(USIZE_BYTES); + } + generic::rev_byte_by_byte(start, cur, confirm) + } + + /// Returns an iterator over all occurrences of one of the needle bytes in + /// the given haystack. + /// + /// The iterator returned implements `DoubleEndedIterator`. This means it + /// can also be used to find occurrences in reverse order. + pub fn iter<'a, 'h>(&'a self, haystack: &'h [u8]) -> TwoIter<'a, 'h> { + TwoIter { searcher: self, it: generic::Iter::new(haystack) } + } + + #[inline(always)] + fn has_needle(&self, chunk: usize) -> bool { + has_zero_byte(self.v1 ^ chunk) || has_zero_byte(self.v2 ^ chunk) + } + + #[inline(always)] + fn confirm(&self, haystack_byte: u8) -> bool { + self.s1 == haystack_byte || self.s2 == haystack_byte + } +} + +/// An iterator over all occurrences of two possible bytes in a haystack. +/// +/// This iterator implements `DoubleEndedIterator`, which means it can also be +/// used to find occurrences in reverse order. +/// +/// This iterator is created by the [`Two::iter`] method. +/// +/// The lifetime parameters are as follows: +/// +/// * `'a` refers to the lifetime of the underlying [`Two`] searcher. +/// * `'h` refers to the lifetime of the haystack being searched. +#[derive(Clone, Debug)] +pub struct TwoIter<'a, 'h> { + /// The underlying memchr searcher. + searcher: &'a Two, + /// Generic iterator implementation. + it: generic::Iter<'h>, +} + +impl<'a, 'h> Iterator for TwoIter<'a, 'h> { + type Item = usize; + + #[inline] + fn next(&mut self) -> Option { + // SAFETY: We rely on the generic iterator to provide valid start + // and end pointers, but we guarantee that any pointer returned by + // 'find_raw' falls within the bounds of the start and end pointer. + unsafe { self.it.next(|s, e| self.searcher.find_raw(s, e)) } + } + + #[inline] + fn size_hint(&self) -> (usize, Option) { + self.it.size_hint() + } +} + +impl<'a, 'h> DoubleEndedIterator for TwoIter<'a, 'h> { + #[inline] + fn next_back(&mut self) -> Option { + // SAFETY: We rely on the generic iterator to provide valid start + // and end pointers, but we guarantee that any pointer returned by + // 'rfind_raw' falls within the bounds of the start and end pointer. + unsafe { self.it.next_back(|s, e| self.searcher.rfind_raw(s, e)) } + } +} + +/// Finds all occurrences of three bytes in a haystack. +/// +/// That is, this reports matches of one of three possible bytes. For example, +/// searching for `a`, `b` or `o` in `afoobar` would report matches at offsets +/// `0`, `2`, `3`, `4` and `5`. +#[derive(Clone, Copy, Debug)] +pub struct Three { + s1: u8, + s2: u8, + s3: u8, + v1: usize, + v2: usize, + v3: usize, +} + +impl Three { + /// Create a new searcher that finds occurrences of the three needle bytes + /// given. + #[inline] + pub fn new(needle1: u8, needle2: u8, needle3: u8) -> Three { + Three { + s1: needle1, + s2: needle2, + s3: needle3, + v1: splat(needle1), + v2: splat(needle2), + v3: splat(needle3), + } + } + + /// A test-only routine so that we can bundle a bunch of quickcheck + /// properties into a single macro. Basically, this provides a constructor + /// that makes it identical to most other memchr implementations, which + /// have fallible constructors. + #[cfg(test)] + pub(crate) fn try_new( + needle1: u8, + needle2: u8, + needle3: u8, + ) -> Option { + Some(Three::new(needle1, needle2, needle3)) + } + + /// Return the first occurrence of one of the needle bytes in the given + /// haystack. If no such occurrence exists, then `None` is returned. + /// + /// The occurrence is reported as an offset into `haystack`. Its maximum + /// value for a non-empty haystack is `haystack.len() - 1`. + #[inline] + pub fn find(&self, haystack: &[u8]) -> Option { + // SAFETY: `find_raw` guarantees that if a pointer is returned, it + // falls within the bounds of the start and end pointers. + unsafe { + generic::search_slice_with_raw(haystack, |s, e| { + self.find_raw(s, e) + }) + } + } + + /// Return the last occurrence of one of the needle bytes in the given + /// haystack. If no such occurrence exists, then `None` is returned. + /// + /// The occurrence is reported as an offset into `haystack`. Its maximum + /// value for a non-empty haystack is `haystack.len() - 1`. + #[inline] + pub fn rfind(&self, haystack: &[u8]) -> Option { + // SAFETY: `find_raw` guarantees that if a pointer is returned, it + // falls within the bounds of the start and end pointers. + unsafe { + generic::search_slice_with_raw(haystack, |s, e| { + self.rfind_raw(s, e) + }) + } + } + + /// Like `find`, but accepts and returns raw pointers. + /// + /// When a match is found, the pointer returned is guaranteed to be + /// `>= start` and `< end`. + /// + /// This routine is useful if you're already using raw pointers and would + /// like to avoid converting back to a slice before executing a search. + /// + /// # Safety + /// + /// * Both `start` and `end` must be valid for reads. + /// * Both `start` and `end` must point to an initialized value. + /// * Both `start` and `end` must point to the same allocated object and + /// must either be in bounds or at most one byte past the end of the + /// allocated object. + /// * Both `start` and `end` must be _derived from_ a pointer to the same + /// object. + /// * The distance between `start` and `end` must not overflow `isize`. + /// * The distance being in bounds must not rely on "wrapping around" the + /// address space. + /// + /// Note that callers may pass a pair of pointers such that `start >= end`. + /// In that case, `None` will always be returned. + #[inline] + pub unsafe fn find_raw( + &self, + start: *const u8, + end: *const u8, + ) -> Option<*const u8> { + if start >= end { + return None; + } + let confirm = |b| self.confirm(b); + let len = end.distance(start); + if len < USIZE_BYTES { + return generic::fwd_byte_by_byte(start, end, confirm); + } + + // The start of the search may not be aligned to `*const usize`, + // so we do an unaligned load here. + let chunk = start.cast::().read_unaligned(); + if self.has_needle(chunk) { + return generic::fwd_byte_by_byte(start, end, confirm); + } + + // And now we start our search at a guaranteed aligned position. + // The first iteration of the loop below will overlap with the the + // unaligned chunk above in cases where the search starts at an + // unaligned offset, but that's okay as we're only here if that + // above didn't find a match. + let mut cur = + start.add(USIZE_BYTES - (start.as_usize() & USIZE_ALIGN)); + debug_assert!(cur > start); + debug_assert!(end.sub(USIZE_BYTES) >= start); + while cur <= end.sub(USIZE_BYTES) { + debug_assert_eq!(0, cur.as_usize() % USIZE_BYTES); + + let chunk = cur.cast::().read(); + if self.has_needle(chunk) { + break; + } + cur = cur.add(USIZE_BYTES); + } + generic::fwd_byte_by_byte(cur, end, confirm) + } + + /// Like `rfind`, but accepts and returns raw pointers. + /// + /// When a match is found, the pointer returned is guaranteed to be + /// `>= start` and `< end`. + /// + /// This routine is useful if you're already using raw pointers and would + /// like to avoid converting back to a slice before executing a search. + /// + /// # Safety + /// + /// * Both `start` and `end` must be valid for reads. + /// * Both `start` and `end` must point to an initialized value. + /// * Both `start` and `end` must point to the same allocated object and + /// must either be in bounds or at most one byte past the end of the + /// allocated object. + /// * Both `start` and `end` must be _derived from_ a pointer to the same + /// object. + /// * The distance between `start` and `end` must not overflow `isize`. + /// * The distance being in bounds must not rely on "wrapping around" the + /// address space. + /// + /// Note that callers may pass a pair of pointers such that `start >= end`. + /// In that case, `None` will always be returned. + #[inline] + pub unsafe fn rfind_raw( + &self, + start: *const u8, + end: *const u8, + ) -> Option<*const u8> { + if start >= end { + return None; + } + let confirm = |b| self.confirm(b); + let len = end.distance(start); + if len < USIZE_BYTES { + return generic::rev_byte_by_byte(start, end, confirm); + } + + let chunk = end.sub(USIZE_BYTES).cast::().read_unaligned(); + if self.has_needle(chunk) { + return generic::rev_byte_by_byte(start, end, confirm); + } + + let mut cur = end.sub(end.as_usize() & USIZE_ALIGN); + debug_assert!(start <= cur && cur <= end); + while cur >= start.add(USIZE_BYTES) { + debug_assert_eq!(0, cur.as_usize() % USIZE_BYTES); + + let chunk = cur.sub(USIZE_BYTES).cast::().read(); + if self.has_needle(chunk) { + break; + } + cur = cur.sub(USIZE_BYTES); + } + generic::rev_byte_by_byte(start, cur, confirm) + } + + /// Returns an iterator over all occurrences of one of the needle bytes in + /// the given haystack. + /// + /// The iterator returned implements `DoubleEndedIterator`. This means it + /// can also be used to find occurrences in reverse order. + pub fn iter<'a, 'h>(&'a self, haystack: &'h [u8]) -> ThreeIter<'a, 'h> { + ThreeIter { searcher: self, it: generic::Iter::new(haystack) } + } + + #[inline(always)] + fn has_needle(&self, chunk: usize) -> bool { + has_zero_byte(self.v1 ^ chunk) + || has_zero_byte(self.v2 ^ chunk) + || has_zero_byte(self.v3 ^ chunk) + } + + #[inline(always)] + fn confirm(&self, haystack_byte: u8) -> bool { + self.s1 == haystack_byte + || self.s2 == haystack_byte + || self.s3 == haystack_byte + } +} + +/// An iterator over all occurrences of three possible bytes in a haystack. +/// +/// This iterator implements `DoubleEndedIterator`, which means it can also be +/// used to find occurrences in reverse order. +/// +/// This iterator is created by the [`Three::iter`] method. +/// +/// The lifetime parameters are as follows: +/// +/// * `'a` refers to the lifetime of the underlying [`Three`] searcher. +/// * `'h` refers to the lifetime of the haystack being searched. +#[derive(Clone, Debug)] +pub struct ThreeIter<'a, 'h> { + /// The underlying memchr searcher. + searcher: &'a Three, + /// Generic iterator implementation. + it: generic::Iter<'h>, +} + +impl<'a, 'h> Iterator for ThreeIter<'a, 'h> { + type Item = usize; + + #[inline] + fn next(&mut self) -> Option { + // SAFETY: We rely on the generic iterator to provide valid start + // and end pointers, but we guarantee that any pointer returned by + // 'find_raw' falls within the bounds of the start and end pointer. + unsafe { self.it.next(|s, e| self.searcher.find_raw(s, e)) } + } + + #[inline] + fn size_hint(&self) -> (usize, Option) { + self.it.size_hint() + } +} + +impl<'a, 'h> DoubleEndedIterator for ThreeIter<'a, 'h> { + #[inline] + fn next_back(&mut self) -> Option { + // SAFETY: We rely on the generic iterator to provide valid start + // and end pointers, but we guarantee that any pointer returned by + // 'rfind_raw' falls within the bounds of the start and end pointer. + unsafe { self.it.next_back(|s, e| self.searcher.rfind_raw(s, e)) } + } +} + +/// Return `true` if `x` contains any zero byte. +/// +/// That is, this routine treats `x` as a register of 8-bit lanes and returns +/// true when any of those lanes is `0`. +/// +/// From "Matters Computational" by J. Arndt. +#[inline(always)] +fn has_zero_byte(x: usize) -> bool { + // "The idea is to subtract one from each of the bytes and then look for + // bytes where the borrow propagated all the way to the most significant + // bit." + const LO: usize = splat(0x01); + const HI: usize = splat(0x80); + + (x.wrapping_sub(LO) & !x & HI) != 0 +} + +/// Repeat the given byte into a word size number. That is, every 8 bits +/// is equivalent to the given byte. For example, if `b` is `\x4E` or +/// `01001110` in binary, then the returned value on a 32-bit system would be: +/// `01001110_01001110_01001110_01001110`. +#[inline(always)] +const fn splat(b: u8) -> usize { + // TODO: use `usize::from` once it can be used in const context. + (b as usize) * (usize::MAX / 255) +} + +#[cfg(test)] +mod tests { + use super::*; + + define_memchr_quickcheck!(super, try_new); + + #[test] + fn forward_one() { + crate::tests::memchr::Runner::new(1).forward_iter( + |haystack, needles| { + Some(One::new(needles[0]).iter(haystack).collect()) + }, + ) + } + + #[test] + fn reverse_one() { + crate::tests::memchr::Runner::new(1).reverse_iter( + |haystack, needles| { + Some(One::new(needles[0]).iter(haystack).rev().collect()) + }, + ) + } + + #[test] + fn count_one() { + crate::tests::memchr::Runner::new(1).count_iter(|haystack, needles| { + Some(One::new(needles[0]).iter(haystack).count()) + }) + } + + #[test] + fn forward_two() { + crate::tests::memchr::Runner::new(2).forward_iter( + |haystack, needles| { + let n1 = needles.get(0).copied()?; + let n2 = needles.get(1).copied()?; + Some(Two::new(n1, n2).iter(haystack).collect()) + }, + ) + } + + #[test] + fn reverse_two() { + crate::tests::memchr::Runner::new(2).reverse_iter( + |haystack, needles| { + let n1 = needles.get(0).copied()?; + let n2 = needles.get(1).copied()?; + Some(Two::new(n1, n2).iter(haystack).rev().collect()) + }, + ) + } + + #[test] + fn forward_three() { + crate::tests::memchr::Runner::new(3).forward_iter( + |haystack, needles| { + let n1 = needles.get(0).copied()?; + let n2 = needles.get(1).copied()?; + let n3 = needles.get(2).copied()?; + Some(Three::new(n1, n2, n3).iter(haystack).collect()) + }, + ) + } + + #[test] + fn reverse_three() { + crate::tests::memchr::Runner::new(3).reverse_iter( + |haystack, needles| { + let n1 = needles.get(0).copied()?; + let n2 = needles.get(1).copied()?; + let n3 = needles.get(2).copied()?; + Some(Three::new(n1, n2, n3).iter(haystack).rev().collect()) + }, + ) + } + + // This was found by quickcheck in the course of refactoring this crate + // after memchr 2.5.0. + #[test] + fn regression_double_ended_iterator() { + let finder = One::new(b'a'); + let haystack = "a"; + let mut it = finder.iter(haystack.as_bytes()); + assert_eq!(Some(0), it.next()); + assert_eq!(None, it.next_back()); + } + + // This regression test was caught by ripgrep's test suite on i686 when + // upgrading to memchr 2.6. Namely, something about the \x0B bytes here + // screws with the SWAR counting approach I was using. This regression test + // prompted me to remove the SWAR counting approach and just replace it + // with a byte-at-a-time loop. + #[test] + fn regression_count_new_lines() { + let haystack = "01234567\x0b\n\x0b\n\x0b\n\x0b\nx"; + let count = One::new(b'\n').count(haystack.as_bytes()); + assert_eq!(4, count); + } + + // A test[1] that failed on some big endian targets after a perf + // improvement was merged[2]. + // + // At first it seemed like the test suite somehow missed the regression, + // but in actuality, CI was not running tests with `cross` but instead with + // `cargo` specifically. This is because those steps were using `cargo` + // instead of `${{ env.CARGO }}`. So adding this regression test doesn't + // really help catch that class of failure, but we add it anyway for good + // measure. + // + // [1]: https://github.com/BurntSushi/memchr/issues/152 + // [2]: https://github.com/BurntSushi/memchr/pull/151 + #[test] + fn regression_big_endian1() { + assert_eq!(One::new(b':').find(b"1:23"), Some(1)); + } + + // Interestingly, I couldn't get `regression_big_endian1` to fail for me + // on the `powerpc64-unknown-linux-gnu` target. But I found another case + // through quickcheck that does. + #[test] + fn regression_big_endian2() { + let data = [0, 0, 0, 0, 0, 0, 0, 0]; + assert_eq!(One::new(b'\x00').find(&data), Some(0)); + } +} diff --git a/vendor/memchr/src/arch/all/mod.rs b/vendor/memchr/src/arch/all/mod.rs new file mode 100644 index 0000000..559cb75 --- /dev/null +++ b/vendor/memchr/src/arch/all/mod.rs @@ -0,0 +1,234 @@ +/*! +Contains architecture independent routines. + +These routines are often used as a "fallback" implementation when the more +specialized architecture dependent routines are unavailable. +*/ + +pub mod memchr; +pub mod packedpair; +pub mod rabinkarp; +#[cfg(feature = "alloc")] +pub mod shiftor; +pub mod twoway; + +/// Returns true if and only if `needle` is a prefix of `haystack`. +/// +/// This uses a latency optimized variant of `memcmp` internally which *might* +/// make this faster for very short strings. +/// +/// # Inlining +/// +/// This routine is marked `inline(always)`. If you want to call this function +/// in a way that is not always inlined, you'll need to wrap a call to it in +/// another function that is marked as `inline(never)` or just `inline`. +#[inline(always)] +pub fn is_prefix(haystack: &[u8], needle: &[u8]) -> bool { + needle.len() <= haystack.len() + && is_equal(&haystack[..needle.len()], needle) +} + +/// Returns true if and only if `needle` is a suffix of `haystack`. +/// +/// This uses a latency optimized variant of `memcmp` internally which *might* +/// make this faster for very short strings. +/// +/// # Inlining +/// +/// This routine is marked `inline(always)`. If you want to call this function +/// in a way that is not always inlined, you'll need to wrap a call to it in +/// another function that is marked as `inline(never)` or just `inline`. +#[inline(always)] +pub fn is_suffix(haystack: &[u8], needle: &[u8]) -> bool { + needle.len() <= haystack.len() + && is_equal(&haystack[haystack.len() - needle.len()..], needle) +} + +/// Compare corresponding bytes in `x` and `y` for equality. +/// +/// That is, this returns true if and only if `x.len() == y.len()` and +/// `x[i] == y[i]` for all `0 <= i < x.len()`. +/// +/// # Inlining +/// +/// This routine is marked `inline(always)`. If you want to call this function +/// in a way that is not always inlined, you'll need to wrap a call to it in +/// another function that is marked as `inline(never)` or just `inline`. +/// +/// # Motivation +/// +/// Why not use slice equality instead? Well, slice equality usually results in +/// a call out to the current platform's `libc` which might not be inlineable +/// or have other overhead. This routine isn't guaranteed to be a win, but it +/// might be in some cases. +#[inline(always)] +pub fn is_equal(x: &[u8], y: &[u8]) -> bool { + if x.len() != y.len() { + return false; + } + // SAFETY: Our pointers are derived directly from borrowed slices which + // uphold all of our safety guarantees except for length. We account for + // length with the check above. + unsafe { is_equal_raw(x.as_ptr(), y.as_ptr(), x.len()) } +} + +/// Compare `n` bytes at the given pointers for equality. +/// +/// This returns true if and only if `*x.add(i) == *y.add(i)` for all +/// `0 <= i < n`. +/// +/// # Inlining +/// +/// This routine is marked `inline(always)`. If you want to call this function +/// in a way that is not always inlined, you'll need to wrap a call to it in +/// another function that is marked as `inline(never)` or just `inline`. +/// +/// # Motivation +/// +/// Why not use slice equality instead? Well, slice equality usually results in +/// a call out to the current platform's `libc` which might not be inlineable +/// or have other overhead. This routine isn't guaranteed to be a win, but it +/// might be in some cases. +/// +/// # Safety +/// +/// * Both `x` and `y` must be valid for reads of up to `n` bytes. +/// * Both `x` and `y` must point to an initialized value. +/// * Both `x` and `y` must each point to an allocated object and +/// must either be in bounds or at most one byte past the end of the +/// allocated object. `x` and `y` do not need to point to the same allocated +/// object, but they may. +/// * Both `x` and `y` must be _derived from_ a pointer to their respective +/// allocated objects. +/// * The distance between `x` and `x+n` must not overflow `isize`. Similarly +/// for `y` and `y+n`. +/// * The distance being in bounds must not rely on "wrapping around" the +/// address space. +#[inline(always)] +pub unsafe fn is_equal_raw( + mut x: *const u8, + mut y: *const u8, + mut n: usize, +) -> bool { + // When we have 4 or more bytes to compare, then proceed in chunks of 4 at + // a time using unaligned loads. + // + // Also, why do 4 byte loads instead of, say, 8 byte loads? The reason is + // that this particular version of memcmp is likely to be called with tiny + // needles. That means that if we do 8 byte loads, then a higher proportion + // of memcmp calls will use the slower variant above. With that said, this + // is a hypothesis and is only loosely supported by benchmarks. There's + // likely some improvement that could be made here. The main thing here + // though is to optimize for latency, not throughput. + + // SAFETY: The caller is responsible for ensuring the pointers we get are + // valid and readable for at least `n` bytes. We also do unaligned loads, + // so there's no need to ensure we're aligned. (This is justified by this + // routine being specifically for short strings.) + while n >= 4 { + let vx = x.cast::().read_unaligned(); + let vy = y.cast::().read_unaligned(); + if vx != vy { + return false; + } + x = x.add(4); + y = y.add(4); + n -= 4; + } + // If we don't have enough bytes to do 4-byte at a time loads, then + // do partial loads. Note that I used to have a byte-at-a-time + // loop here and that turned out to be quite a bit slower for the + // memmem/pathological/defeat-simple-vector-alphabet benchmark. + if n >= 2 { + let vx = x.cast::().read_unaligned(); + let vy = y.cast::().read_unaligned(); + if vx != vy { + return false; + } + x = x.add(2); + y = y.add(2); + n -= 2; + } + if n > 0 { + if x.read() != y.read() { + return false; + } + } + true +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn equals_different_lengths() { + assert!(!is_equal(b"", b"a")); + assert!(!is_equal(b"a", b"")); + assert!(!is_equal(b"ab", b"a")); + assert!(!is_equal(b"a", b"ab")); + } + + #[test] + fn equals_mismatch() { + let one_mismatch = [ + (&b"a"[..], &b"x"[..]), + (&b"ab"[..], &b"ax"[..]), + (&b"abc"[..], &b"abx"[..]), + (&b"abcd"[..], &b"abcx"[..]), + (&b"abcde"[..], &b"abcdx"[..]), + (&b"abcdef"[..], &b"abcdex"[..]), + (&b"abcdefg"[..], &b"abcdefx"[..]), + (&b"abcdefgh"[..], &b"abcdefgx"[..]), + (&b"abcdefghi"[..], &b"abcdefghx"[..]), + (&b"abcdefghij"[..], &b"abcdefghix"[..]), + (&b"abcdefghijk"[..], &b"abcdefghijx"[..]), + (&b"abcdefghijkl"[..], &b"abcdefghijkx"[..]), + (&b"abcdefghijklm"[..], &b"abcdefghijklx"[..]), + (&b"abcdefghijklmn"[..], &b"abcdefghijklmx"[..]), + ]; + for (x, y) in one_mismatch { + assert_eq!(x.len(), y.len(), "lengths should match"); + assert!(!is_equal(x, y)); + assert!(!is_equal(y, x)); + } + } + + #[test] + fn equals_yes() { + assert!(is_equal(b"", b"")); + assert!(is_equal(b"a", b"a")); + assert!(is_equal(b"ab", b"ab")); + assert!(is_equal(b"abc", b"abc")); + assert!(is_equal(b"abcd", b"abcd")); + assert!(is_equal(b"abcde", b"abcde")); + assert!(is_equal(b"abcdef", b"abcdef")); + assert!(is_equal(b"abcdefg", b"abcdefg")); + assert!(is_equal(b"abcdefgh", b"abcdefgh")); + assert!(is_equal(b"abcdefghi", b"abcdefghi")); + } + + #[test] + fn prefix() { + assert!(is_prefix(b"", b"")); + assert!(is_prefix(b"a", b"")); + assert!(is_prefix(b"ab", b"")); + assert!(is_prefix(b"foo", b"foo")); + assert!(is_prefix(b"foobar", b"foo")); + + assert!(!is_prefix(b"foo", b"fob")); + assert!(!is_prefix(b"foobar", b"fob")); + } + + #[test] + fn suffix() { + assert!(is_suffix(b"", b"")); + assert!(is_suffix(b"a", b"")); + assert!(is_suffix(b"ab", b"")); + assert!(is_suffix(b"foo", b"foo")); + assert!(is_suffix(b"foobar", b"bar")); + + assert!(!is_suffix(b"foo", b"goo")); + assert!(!is_suffix(b"foobar", b"gar")); + } +} diff --git a/vendor/memchr/src/arch/all/packedpair/default_rank.rs b/vendor/memchr/src/arch/all/packedpair/default_rank.rs new file mode 100644 index 0000000..6aa3895 --- /dev/null +++ b/vendor/memchr/src/arch/all/packedpair/default_rank.rs @@ -0,0 +1,258 @@ +pub(crate) const RANK: [u8; 256] = [ + 55, // '\x00' + 52, // '\x01' + 51, // '\x02' + 50, // '\x03' + 49, // '\x04' + 48, // '\x05' + 47, // '\x06' + 46, // '\x07' + 45, // '\x08' + 103, // '\t' + 242, // '\n' + 66, // '\x0b' + 67, // '\x0c' + 229, // '\r' + 44, // '\x0e' + 43, // '\x0f' + 42, // '\x10' + 41, // '\x11' + 40, // '\x12' + 39, // '\x13' + 38, // '\x14' + 37, // '\x15' + 36, // '\x16' + 35, // '\x17' + 34, // '\x18' + 33, // '\x19' + 56, // '\x1a' + 32, // '\x1b' + 31, // '\x1c' + 30, // '\x1d' + 29, // '\x1e' + 28, // '\x1f' + 255, // ' ' + 148, // '!' + 164, // '"' + 149, // '#' + 136, // '$' + 160, // '%' + 155, // '&' + 173, // "'" + 221, // '(' + 222, // ')' + 134, // '*' + 122, // '+' + 232, // ',' + 202, // '-' + 215, // '.' + 224, // '/' + 208, // '0' + 220, // '1' + 204, // '2' + 187, // '3' + 183, // '4' + 179, // '5' + 177, // '6' + 168, // '7' + 178, // '8' + 200, // '9' + 226, // ':' + 195, // ';' + 154, // '<' + 184, // '=' + 174, // '>' + 126, // '?' + 120, // '@' + 191, // 'A' + 157, // 'B' + 194, // 'C' + 170, // 'D' + 189, // 'E' + 162, // 'F' + 161, // 'G' + 150, // 'H' + 193, // 'I' + 142, // 'J' + 137, // 'K' + 171, // 'L' + 176, // 'M' + 185, // 'N' + 167, // 'O' + 186, // 'P' + 112, // 'Q' + 175, // 'R' + 192, // 'S' + 188, // 'T' + 156, // 'U' + 140, // 'V' + 143, // 'W' + 123, // 'X' + 133, // 'Y' + 128, // 'Z' + 147, // '[' + 138, // '\\' + 146, // ']' + 114, // '^' + 223, // '_' + 151, // '`' + 249, // 'a' + 216, // 'b' + 238, // 'c' + 236, // 'd' + 253, // 'e' + 227, // 'f' + 218, // 'g' + 230, // 'h' + 247, // 'i' + 135, // 'j' + 180, // 'k' + 241, // 'l' + 233, // 'm' + 246, // 'n' + 244, // 'o' + 231, // 'p' + 139, // 'q' + 245, // 'r' + 243, // 's' + 251, // 't' + 235, // 'u' + 201, // 'v' + 196, // 'w' + 240, // 'x' + 214, // 'y' + 152, // 'z' + 182, // '{' + 205, // '|' + 181, // '}' + 127, // '~' + 27, // '\x7f' + 212, // '\x80' + 211, // '\x81' + 210, // '\x82' + 213, // '\x83' + 228, // '\x84' + 197, // '\x85' + 169, // '\x86' + 159, // '\x87' + 131, // '\x88' + 172, // '\x89' + 105, // '\x8a' + 80, // '\x8b' + 98, // '\x8c' + 96, // '\x8d' + 97, // '\x8e' + 81, // '\x8f' + 207, // '\x90' + 145, // '\x91' + 116, // '\x92' + 115, // '\x93' + 144, // '\x94' + 130, // '\x95' + 153, // '\x96' + 121, // '\x97' + 107, // '\x98' + 132, // '\x99' + 109, // '\x9a' + 110, // '\x9b' + 124, // '\x9c' + 111, // '\x9d' + 82, // '\x9e' + 108, // '\x9f' + 118, // '\xa0' + 141, // '¡' + 113, // '¢' + 129, // '£' + 119, // '¤' + 125, // '¥' + 165, // '¦' + 117, // '§' + 92, // '¨' + 106, // '©' + 83, // 'ª' + 72, // '«' + 99, // '¬' + 93, // '\xad' + 65, // '®' + 79, // '¯' + 166, // '°' + 237, // '±' + 163, // '²' + 199, // '³' + 190, // '´' + 225, // 'µ' + 209, // '¶' + 203, // '·' + 198, // '¸' + 217, // '¹' + 219, // 'º' + 206, // '»' + 234, // '¼' + 248, // '½' + 158, // '¾' + 239, // '¿' + 255, // 'À' + 255, // 'Á' + 255, // 'Â' + 255, // 'Ã' + 255, // 'Ä' + 255, // 'Å' + 255, // 'Æ' + 255, // 'Ç' + 255, // 'È' + 255, // 'É' + 255, // 'Ê' + 255, // 'Ë' + 255, // 'Ì' + 255, // 'Í' + 255, // 'Î' + 255, // 'Ï' + 255, // 'Ð' + 255, // 'Ñ' + 255, // 'Ò' + 255, // 'Ó' + 255, // 'Ô' + 255, // 'Õ' + 255, // 'Ö' + 255, // '×' + 255, // 'Ø' + 255, // 'Ù' + 255, // 'Ú' + 255, // 'Û' + 255, // 'Ü' + 255, // 'Ý' + 255, // 'Þ' + 255, // 'ß' + 255, // 'à' + 255, // 'á' + 255, // 'â' + 255, // 'ã' + 255, // 'ä' + 255, // 'å' + 255, // 'æ' + 255, // 'ç' + 255, // 'è' + 255, // 'é' + 255, // 'ê' + 255, // 'ë' + 255, // 'ì' + 255, // 'í' + 255, // 'î' + 255, // 'ï' + 255, // 'ð' + 255, // 'ñ' + 255, // 'ò' + 255, // 'ó' + 255, // 'ô' + 255, // 'õ' + 255, // 'ö' + 255, // '÷' + 255, // 'ø' + 255, // 'ù' + 255, // 'ú' + 255, // 'û' + 255, // 'ü' + 255, // 'ý' + 255, // 'þ' + 255, // 'ÿ' +]; diff --git a/vendor/memchr/src/arch/all/packedpair/mod.rs b/vendor/memchr/src/arch/all/packedpair/mod.rs new file mode 100644 index 0000000..148a985 --- /dev/null +++ b/vendor/memchr/src/arch/all/packedpair/mod.rs @@ -0,0 +1,359 @@ +/*! +Provides an architecture independent implementation of the "packed pair" +algorithm. + +The "packed pair" algorithm is based on the [generic SIMD] algorithm. The main +difference is that it (by default) uses a background distribution of byte +frequencies to heuristically select the pair of bytes to search for. Note that +this module provides an architecture independent version that doesn't do as +good of a job keeping the search for candidates inside a SIMD hot path. It +however can be good enough in many circumstances. + +[generic SIMD]: http://0x80.pl/articles/simd-strfind.html#first-and-last +*/ + +use crate::memchr; + +mod default_rank; + +/// An architecture independent "packed pair" finder. +/// +/// This finder picks two bytes that it believes have high predictive power for +/// indicating an overall match of a needle. At search time, it reports offsets +/// where the needle could match based on whether the pair of bytes it chose +/// match. +/// +/// This is architecture independent because it utilizes `memchr` to find the +/// occurrence of one of the bytes in the pair, and then checks whether the +/// second byte matches. If it does, in the case of [`Finder::find_prefilter`], +/// the location at which the needle could match is returned. +/// +/// It is generally preferred to use architecture specific routines for a +/// "packed pair" prefilter, but this can be a useful fallback when the +/// architecture independent routines are unavailable. +#[derive(Clone, Copy, Debug)] +pub struct Finder { + pair: Pair, + byte1: u8, + byte2: u8, +} + +impl Finder { + /// Create a new prefilter that reports possible locations where the given + /// needle matches. + #[inline] + pub fn new(needle: &[u8]) -> Option { + Finder::with_pair(needle, Pair::new(needle)?) + } + + /// Create a new prefilter using the pair given. + /// + /// If the prefilter could not be constructed, then `None` is returned. + /// + /// This constructor permits callers to control precisely which pair of + /// bytes is used as a predicate. + #[inline] + pub fn with_pair(needle: &[u8], pair: Pair) -> Option { + let byte1 = needle[usize::from(pair.index1())]; + let byte2 = needle[usize::from(pair.index2())]; + // Currently this can never fail so we could just return a Finder, + // but it's conceivable this could change. + Some(Finder { pair, byte1, byte2 }) + } + + /// Run this finder on the given haystack as a prefilter. + /// + /// If a candidate match is found, then an offset where the needle *could* + /// begin in the haystack is returned. + #[inline] + pub fn find_prefilter(&self, haystack: &[u8]) -> Option { + let mut i = 0; + let index1 = usize::from(self.pair.index1()); + let index2 = usize::from(self.pair.index2()); + loop { + // Use a fast vectorized implementation to skip to the next + // occurrence of the rarest byte (heuristically chosen) in the + // needle. + i += memchr(self.byte1, &haystack[i..])?; + let found = i; + i += 1; + + // If we can't align our first byte match with the haystack, then a + // match is impossible. + let aligned1 = match found.checked_sub(index1) { + None => continue, + Some(aligned1) => aligned1, + }; + + // Now align the second byte match with the haystack. A mismatch + // means that a match is impossible. + let aligned2 = match aligned1.checked_add(index2) { + None => continue, + Some(aligned_index2) => aligned_index2, + }; + if haystack.get(aligned2).map_or(true, |&b| b != self.byte2) { + continue; + } + + // We've done what we can. There might be a match here. + return Some(aligned1); + } + } + + /// Returns the pair of offsets (into the needle) used to check as a + /// predicate before confirming whether a needle exists at a particular + /// position. + #[inline] + pub fn pair(&self) -> &Pair { + &self.pair + } +} + +/// A pair of byte offsets into a needle to use as a predicate. +/// +/// This pair is used as a predicate to quickly filter out positions in a +/// haystack in which a needle cannot match. In some cases, this pair can even +/// be used in vector algorithms such that the vector algorithm only switches +/// over to scalar code once this pair has been found. +/// +/// A pair of offsets can be used in both substring search implementations and +/// in prefilters. The former will report matches of a needle in a haystack +/// where as the latter will only report possible matches of a needle. +/// +/// The offsets are limited each to a maximum of 255 to keep memory usage low. +/// Moreover, it's rarely advantageous to create a predicate using offsets +/// greater than 255 anyway. +/// +/// The only guarantee enforced on the pair of offsets is that they are not +/// equivalent. It is not necessarily the case that `index1 < index2` for +/// example. By convention, `index1` corresponds to the byte in the needle +/// that is believed to be most the predictive. Note also that because of the +/// requirement that the indices be both valid for the needle used to build +/// the pair and not equal, it follows that a pair can only be constructed for +/// needles with length at least 2. +#[derive(Clone, Copy, Debug)] +pub struct Pair { + index1: u8, + index2: u8, +} + +impl Pair { + /// Create a new pair of offsets from the given needle. + /// + /// If a pair could not be created (for example, if the needle is too + /// short), then `None` is returned. + /// + /// This chooses the pair in the needle that is believed to be as + /// predictive of an overall match of the needle as possible. + #[inline] + pub fn new(needle: &[u8]) -> Option { + Pair::with_ranker(needle, DefaultFrequencyRank) + } + + /// Create a new pair of offsets from the given needle and ranker. + /// + /// This permits the caller to choose a background frequency distribution + /// with which bytes are selected. The idea is to select a pair of bytes + /// that is believed to strongly predict a match in the haystack. This + /// usually means selecting bytes that occur rarely in a haystack. + /// + /// If a pair could not be created (for example, if the needle is too + /// short), then `None` is returned. + #[inline] + pub fn with_ranker( + needle: &[u8], + ranker: R, + ) -> Option { + if needle.len() <= 1 { + return None; + } + // Find the rarest two bytes. We make them distinct indices by + // construction. (The actual byte value may be the same in degenerate + // cases, but that's OK.) + let (mut rare1, mut index1) = (needle[0], 0); + let (mut rare2, mut index2) = (needle[1], 1); + if ranker.rank(rare2) < ranker.rank(rare1) { + core::mem::swap(&mut rare1, &mut rare2); + core::mem::swap(&mut index1, &mut index2); + } + let max = usize::from(core::u8::MAX); + for (i, &b) in needle.iter().enumerate().take(max).skip(2) { + if ranker.rank(b) < ranker.rank(rare1) { + rare2 = rare1; + index2 = index1; + rare1 = b; + index1 = u8::try_from(i).unwrap(); + } else if b != rare1 && ranker.rank(b) < ranker.rank(rare2) { + rare2 = b; + index2 = u8::try_from(i).unwrap(); + } + } + // While not strictly required for how a Pair is normally used, we + // really don't want these to be equivalent. If they were, it would + // reduce the effectiveness of candidate searching using these rare + // bytes by increasing the rate of false positives. + assert_ne!(index1, index2); + Some(Pair { index1, index2 }) + } + + /// Create a new pair using the offsets given for the needle given. + /// + /// This bypasses any sort of heuristic process for choosing the offsets + /// and permits the caller to choose the offsets themselves. + /// + /// Indices are limited to valid `u8` values so that a `Pair` uses less + /// memory. It is not possible to create a `Pair` with offsets bigger than + /// `u8::MAX`. It's likely that such a thing is not needed, but if it is, + /// it's suggested to build your own bespoke algorithm because you're + /// likely working on a very niche case. (File an issue if this suggestion + /// does not make sense to you.) + /// + /// If a pair could not be created (for example, if the needle is too + /// short), then `None` is returned. + #[inline] + pub fn with_indices( + needle: &[u8], + index1: u8, + index2: u8, + ) -> Option { + // While not strictly required for how a Pair is normally used, we + // really don't want these to be equivalent. If they were, it would + // reduce the effectiveness of candidate searching using these rare + // bytes by increasing the rate of false positives. + if index1 == index2 { + return None; + } + // Similarly, invalid indices means the Pair is invalid too. + if usize::from(index1) >= needle.len() { + return None; + } + if usize::from(index2) >= needle.len() { + return None; + } + Some(Pair { index1, index2 }) + } + + /// Returns the first offset of the pair. + #[inline] + pub fn index1(&self) -> u8 { + self.index1 + } + + /// Returns the second offset of the pair. + #[inline] + pub fn index2(&self) -> u8 { + self.index2 + } +} + +/// This trait allows the user to customize the heuristic used to determine the +/// relative frequency of a given byte in the dataset being searched. +/// +/// The use of this trait can have a dramatic impact on performance depending +/// on the type of data being searched. The details of why are explained in the +/// docs of [`crate::memmem::Prefilter`]. To summarize, the core algorithm uses +/// a prefilter to quickly identify candidate matches that are later verified +/// more slowly. This prefilter is implemented in terms of trying to find +/// `rare` bytes at specific offsets that will occur less frequently in the +/// dataset. While the concept of a `rare` byte is similar for most datasets, +/// there are some specific datasets (like binary executables) that have +/// dramatically different byte distributions. For these datasets customizing +/// the byte frequency heuristic can have a massive impact on performance, and +/// might even need to be done at runtime. +/// +/// The default implementation of `HeuristicFrequencyRank` reads from the +/// static frequency table defined in `src/memmem/byte_frequencies.rs`. This +/// is optimal for most inputs, so if you are unsure of the impact of using a +/// custom `HeuristicFrequencyRank` you should probably just use the default. +/// +/// # Example +/// +/// ``` +/// use memchr::{ +/// arch::all::packedpair::HeuristicFrequencyRank, +/// memmem::FinderBuilder, +/// }; +/// +/// /// A byte-frequency table that is good for scanning binary executables. +/// struct Binary; +/// +/// impl HeuristicFrequencyRank for Binary { +/// fn rank(&self, byte: u8) -> u8 { +/// const TABLE: [u8; 256] = [ +/// 255, 128, 61, 43, 50, 41, 27, 28, 57, 15, 21, 13, 24, 17, 17, +/// 89, 58, 16, 11, 7, 14, 23, 7, 6, 24, 9, 6, 5, 9, 4, 7, 16, +/// 68, 11, 9, 6, 88, 7, 4, 4, 23, 9, 4, 8, 8, 5, 10, 4, 30, 11, +/// 9, 24, 11, 5, 5, 5, 19, 11, 6, 17, 9, 9, 6, 8, +/// 48, 58, 11, 14, 53, 40, 9, 9, 254, 35, 3, 6, 52, 23, 6, 6, 27, +/// 4, 7, 11, 14, 13, 10, 11, 11, 5, 2, 10, 16, 12, 6, 19, +/// 19, 20, 5, 14, 16, 31, 19, 7, 14, 20, 4, 4, 19, 8, 18, 20, 24, +/// 1, 25, 19, 58, 29, 10, 5, 15, 20, 2, 2, 9, 4, 3, 5, +/// 51, 11, 4, 53, 23, 39, 6, 4, 13, 81, 4, 186, 5, 67, 3, 2, 15, +/// 0, 0, 1, 3, 2, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, +/// 12, 2, 1, 1, 3, 1, 1, 1, 6, 1, 2, 1, 3, 1, 1, 2, 9, 1, 1, 0, +/// 2, 2, 4, 4, 11, 6, 7, 3, 6, 9, 4, 5, +/// 46, 18, 8, 18, 17, 3, 8, 20, 16, 10, 3, 7, 175, 4, 6, 7, 13, +/// 3, 7, 3, 3, 1, 3, 3, 10, 3, 1, 5, 2, 0, 1, 2, +/// 16, 3, 5, 1, 6, 1, 1, 2, 58, 20, 3, 14, 12, 2, 1, 3, 16, 3, 5, +/// 8, 3, 1, 8, 6, 17, 6, 5, 3, 8, 6, 13, 175, +/// ]; +/// TABLE[byte as usize] +/// } +/// } +/// // Create a new finder with the custom heuristic. +/// let finder = FinderBuilder::new() +/// .build_forward_with_ranker(Binary, b"\x00\x00\xdd\xdd"); +/// // Find needle with custom heuristic. +/// assert!(finder.find(b"\x00\x00\x00\xdd\xdd").is_some()); +/// ``` +pub trait HeuristicFrequencyRank { + /// Return the heuristic frequency rank of the given byte. A lower rank + /// means the byte is believed to occur less frequently in the haystack. + /// + /// Some uses of this heuristic may treat arbitrary absolute rank values as + /// significant. For example, an implementation detail in this crate may + /// determine that heuristic prefilters are inappropriate if every byte in + /// the needle has a "high" rank. + fn rank(&self, byte: u8) -> u8; +} + +/// The default byte frequency heuristic that is good for most haystacks. +pub(crate) struct DefaultFrequencyRank; + +impl HeuristicFrequencyRank for DefaultFrequencyRank { + fn rank(&self, byte: u8) -> u8 { + self::default_rank::RANK[usize::from(byte)] + } +} + +/// This permits passing any implementation of `HeuristicFrequencyRank` as a +/// borrowed version of itself. +impl<'a, R> HeuristicFrequencyRank for &'a R +where + R: HeuristicFrequencyRank, +{ + fn rank(&self, byte: u8) -> u8 { + (**self).rank(byte) + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn forward_packedpair() { + fn find( + haystack: &[u8], + needle: &[u8], + _index1: u8, + _index2: u8, + ) -> Option> { + // We ignore the index positions requested since it winds up making + // this test too slow overall. + let f = Finder::new(needle)?; + Some(f.find_prefilter(haystack)) + } + crate::tests::packedpair::Runner::new().fwd(find).run() + } +} diff --git a/vendor/memchr/src/arch/all/rabinkarp.rs b/vendor/memchr/src/arch/all/rabinkarp.rs new file mode 100644 index 0000000..e0bafba --- /dev/null +++ b/vendor/memchr/src/arch/all/rabinkarp.rs @@ -0,0 +1,390 @@ +/*! +An implementation of the [Rabin-Karp substring search algorithm][rabinkarp]. + +Rabin-Karp works by creating a hash of the needle provided and then computing +a rolling hash for each needle sized window in the haystack. When the rolling +hash matches the hash of the needle, a byte-wise comparison is done to check +if a match exists. The worst case time complexity of Rabin-Karp is `O(m * +n)` where `m ~ len(needle)` and `n ~ len(haystack)`. Its worst case space +complexity is constant. + +The main utility of Rabin-Karp is that the searcher can be constructed very +quickly with very little memory. This makes it especially useful when searching +for small needles in small haystacks, as it might finish its search before a +beefier algorithm (like Two-Way) even starts. + +[rabinkarp]: https://en.wikipedia.org/wiki/Rabin%E2%80%93Karp_algorithm +*/ + +/* +(This was the comment I wrote for this module originally when it was not +exposed. The comment still looks useful, but it's a bit in the weeds, so it's +not public itself.) + +This module implements the classical Rabin-Karp substring search algorithm, +with no extra frills. While its use would seem to break our time complexity +guarantee of O(m+n) (RK's time complexity is O(mn)), we are careful to only +ever use RK on a constant subset of haystacks. The main point here is that +RK has good latency properties for small needles/haystacks. It's very quick +to compute a needle hash and zip through the haystack when compared to +initializing Two-Way, for example. And this is especially useful for cases +where the haystack is just too short for vector instructions to do much good. + +The hashing function used here is the same one recommended by ESMAJ. + +Another choice instead of Rabin-Karp would be Shift-Or. But its latency +isn't quite as good since its preprocessing time is a bit more expensive +(both in practice and in theory). However, perhaps Shift-Or has a place +somewhere else for short patterns. I think the main problem is that it +requires space proportional to the alphabet and the needle. If we, for +example, supported needles up to length 16, then the total table size would be +len(alphabet)*size_of::()==512 bytes. Which isn't exactly small, and it's +probably bad to put that on the stack. So ideally, we'd throw it on the heap, +but we'd really like to write as much code without using alloc/std as possible. +But maybe it's worth the special casing. It's a TODO to benchmark. + +Wikipedia has a decent explanation, if a bit heavy on the theory: +https://en.wikipedia.org/wiki/Rabin%E2%80%93Karp_algorithm + +But ESMAJ provides something a bit more concrete: +http://www-igm.univ-mlv.fr/~lecroq/string/node5.html + +Finally, aho-corasick uses Rabin-Karp for multiple pattern match in some cases: +https://github.com/BurntSushi/aho-corasick/blob/3852632f10587db0ff72ef29e88d58bf305a0946/src/packed/rabinkarp.rs +*/ + +use crate::ext::Pointer; + +/// A forward substring searcher using the Rabin-Karp algorithm. +/// +/// Note that, as a lower level API, a `Finder` does not have access to the +/// needle it was constructed with. For this reason, executing a search +/// with a `Finder` requires passing both the needle and the haystack, +/// where the needle is exactly equivalent to the one given to the `Finder` +/// at construction time. This design was chosen so that callers can have +/// more precise control over where and how many times a needle is stored. +/// For example, in cases where Rabin-Karp is just one of several possible +/// substring search algorithms. +#[derive(Clone, Debug)] +pub struct Finder { + /// The actual hash. + hash: Hash, + /// The factor needed to multiply a byte by in order to subtract it from + /// the hash. It is defined to be 2^(n-1) (using wrapping exponentiation), + /// where n is the length of the needle. This is how we "remove" a byte + /// from the hash once the hash window rolls past it. + hash_2pow: u32, +} + +impl Finder { + /// Create a new Rabin-Karp forward searcher for the given `needle`. + /// + /// The needle may be empty. The empty needle matches at every byte offset. + /// + /// Note that callers must pass the same needle to all search calls using + /// this `Finder`. + #[inline] + pub fn new(needle: &[u8]) -> Finder { + let mut s = Finder { hash: Hash::new(), hash_2pow: 1 }; + let first_byte = match needle.get(0) { + None => return s, + Some(&first_byte) => first_byte, + }; + s.hash.add(first_byte); + for b in needle.iter().copied().skip(1) { + s.hash.add(b); + s.hash_2pow = s.hash_2pow.wrapping_shl(1); + } + s + } + + /// Return the first occurrence of the `needle` in the `haystack` + /// given. If no such occurrence exists, then `None` is returned. + /// + /// The `needle` provided must match the needle given to this finder at + /// construction time. + /// + /// The maximum value this can return is `haystack.len()`, which can only + /// occur when the needle and haystack both have length zero. Otherwise, + /// for non-empty haystacks, the maximum value is `haystack.len() - 1`. + #[inline] + pub fn find(&self, haystack: &[u8], needle: &[u8]) -> Option { + unsafe { + let hstart = haystack.as_ptr(); + let hend = hstart.add(haystack.len()); + let nstart = needle.as_ptr(); + let nend = nstart.add(needle.len()); + let found = self.find_raw(hstart, hend, nstart, nend)?; + Some(found.distance(hstart)) + } + } + + /// Like `find`, but accepts and returns raw pointers. + /// + /// When a match is found, the pointer returned is guaranteed to be + /// `>= start` and `<= end`. The pointer returned is only ever equivalent + /// to `end` when both the needle and haystack are empty. (That is, the + /// empty string matches the empty string.) + /// + /// This routine is useful if you're already using raw pointers and would + /// like to avoid converting back to a slice before executing a search. + /// + /// # Safety + /// + /// Note that `start` and `end` below refer to both pairs of pointers given + /// to this routine. That is, the conditions apply to both `hstart`/`hend` + /// and `nstart`/`nend`. + /// + /// * Both `start` and `end` must be valid for reads. + /// * Both `start` and `end` must point to an initialized value. + /// * Both `start` and `end` must point to the same allocated object and + /// must either be in bounds or at most one byte past the end of the + /// allocated object. + /// * Both `start` and `end` must be _derived from_ a pointer to the same + /// object. + /// * The distance between `start` and `end` must not overflow `isize`. + /// * The distance being in bounds must not rely on "wrapping around" the + /// address space. + /// * It must be the case that `start <= end`. + #[inline] + pub unsafe fn find_raw( + &self, + hstart: *const u8, + hend: *const u8, + nstart: *const u8, + nend: *const u8, + ) -> Option<*const u8> { + let hlen = hend.distance(hstart); + let nlen = nend.distance(nstart); + if nlen > hlen { + return None; + } + let mut cur = hstart; + let end = hend.sub(nlen); + let mut hash = Hash::forward(cur, cur.add(nlen)); + loop { + if self.hash == hash && is_equal_raw(cur, nstart, nlen) { + return Some(cur); + } + if cur >= end { + return None; + } + hash.roll(self, cur.read(), cur.add(nlen).read()); + cur = cur.add(1); + } + } +} + +/// A reverse substring searcher using the Rabin-Karp algorithm. +#[derive(Clone, Debug)] +pub struct FinderRev(Finder); + +impl FinderRev { + /// Create a new Rabin-Karp reverse searcher for the given `needle`. + #[inline] + pub fn new(needle: &[u8]) -> FinderRev { + let mut s = FinderRev(Finder { hash: Hash::new(), hash_2pow: 1 }); + let last_byte = match needle.last() { + None => return s, + Some(&last_byte) => last_byte, + }; + s.0.hash.add(last_byte); + for b in needle.iter().rev().copied().skip(1) { + s.0.hash.add(b); + s.0.hash_2pow = s.0.hash_2pow.wrapping_shl(1); + } + s + } + + /// Return the last occurrence of the `needle` in the `haystack` + /// given. If no such occurrence exists, then `None` is returned. + /// + /// The `needle` provided must match the needle given to this finder at + /// construction time. + /// + /// The maximum value this can return is `haystack.len()`, which can only + /// occur when the needle and haystack both have length zero. Otherwise, + /// for non-empty haystacks, the maximum value is `haystack.len() - 1`. + #[inline] + pub fn rfind(&self, haystack: &[u8], needle: &[u8]) -> Option { + unsafe { + let hstart = haystack.as_ptr(); + let hend = hstart.add(haystack.len()); + let nstart = needle.as_ptr(); + let nend = nstart.add(needle.len()); + let found = self.rfind_raw(hstart, hend, nstart, nend)?; + Some(found.distance(hstart)) + } + } + + /// Like `rfind`, but accepts and returns raw pointers. + /// + /// When a match is found, the pointer returned is guaranteed to be + /// `>= start` and `<= end`. The pointer returned is only ever equivalent + /// to `end` when both the needle and haystack are empty. (That is, the + /// empty string matches the empty string.) + /// + /// This routine is useful if you're already using raw pointers and would + /// like to avoid converting back to a slice before executing a search. + /// + /// # Safety + /// + /// Note that `start` and `end` below refer to both pairs of pointers given + /// to this routine. That is, the conditions apply to both `hstart`/`hend` + /// and `nstart`/`nend`. + /// + /// * Both `start` and `end` must be valid for reads. + /// * Both `start` and `end` must point to an initialized value. + /// * Both `start` and `end` must point to the same allocated object and + /// must either be in bounds or at most one byte past the end of the + /// allocated object. + /// * Both `start` and `end` must be _derived from_ a pointer to the same + /// object. + /// * The distance between `start` and `end` must not overflow `isize`. + /// * The distance being in bounds must not rely on "wrapping around" the + /// address space. + /// * It must be the case that `start <= end`. + #[inline] + pub unsafe fn rfind_raw( + &self, + hstart: *const u8, + hend: *const u8, + nstart: *const u8, + nend: *const u8, + ) -> Option<*const u8> { + let hlen = hend.distance(hstart); + let nlen = nend.distance(nstart); + if nlen > hlen { + return None; + } + let mut cur = hend.sub(nlen); + let start = hstart; + let mut hash = Hash::reverse(cur, cur.add(nlen)); + loop { + if self.0.hash == hash && is_equal_raw(cur, nstart, nlen) { + return Some(cur); + } + if cur <= start { + return None; + } + cur = cur.sub(1); + hash.roll(&self.0, cur.add(nlen).read(), cur.read()); + } + } +} + +/// Whether RK is believed to be very fast for the given needle/haystack. +#[inline] +pub(crate) fn is_fast(haystack: &[u8], _needle: &[u8]) -> bool { + haystack.len() < 16 +} + +/// A Rabin-Karp hash. This might represent the hash of a needle, or the hash +/// of a rolling window in the haystack. +#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)] +struct Hash(u32); + +impl Hash { + /// Create a new hash that represents the empty string. + #[inline(always)] + fn new() -> Hash { + Hash(0) + } + + /// Create a new hash from the bytes given for use in forward searches. + /// + /// # Safety + /// + /// The given pointers must be valid to read from within their range. + #[inline(always)] + unsafe fn forward(mut start: *const u8, end: *const u8) -> Hash { + let mut hash = Hash::new(); + while start < end { + hash.add(start.read()); + start = start.add(1); + } + hash + } + + /// Create a new hash from the bytes given for use in reverse searches. + /// + /// # Safety + /// + /// The given pointers must be valid to read from within their range. + #[inline(always)] + unsafe fn reverse(start: *const u8, mut end: *const u8) -> Hash { + let mut hash = Hash::new(); + while start < end { + end = end.sub(1); + hash.add(end.read()); + } + hash + } + + /// Add 'new' and remove 'old' from this hash. The given needle hash should + /// correspond to the hash computed for the needle being searched for. + /// + /// This is meant to be used when the rolling window of the haystack is + /// advanced. + #[inline(always)] + fn roll(&mut self, finder: &Finder, old: u8, new: u8) { + self.del(finder, old); + self.add(new); + } + + /// Add a byte to this hash. + #[inline(always)] + fn add(&mut self, byte: u8) { + self.0 = self.0.wrapping_shl(1).wrapping_add(u32::from(byte)); + } + + /// Remove a byte from this hash. The given needle hash should correspond + /// to the hash computed for the needle being searched for. + #[inline(always)] + fn del(&mut self, finder: &Finder, byte: u8) { + let factor = finder.hash_2pow; + self.0 = self.0.wrapping_sub(u32::from(byte).wrapping_mul(factor)); + } +} + +/// Returns true when `x[i] == y[i]` for all `0 <= i < n`. +/// +/// We forcefully don't inline this to hint at the compiler that it is unlikely +/// to be called. This causes the inner rabinkarp loop above to be a bit +/// tighter and leads to some performance improvement. See the +/// memmem/krate/prebuilt/sliceslice-words/words benchmark. +/// +/// # Safety +/// +/// Same as `crate::arch::all::is_equal_raw`. +#[cold] +#[inline(never)] +unsafe fn is_equal_raw(x: *const u8, y: *const u8, n: usize) -> bool { + crate::arch::all::is_equal_raw(x, y, n) +} + +#[cfg(test)] +mod tests { + use super::*; + + define_substring_forward_quickcheck!(|h, n| Some( + Finder::new(n).find(h, n) + )); + define_substring_reverse_quickcheck!(|h, n| Some( + FinderRev::new(n).rfind(h, n) + )); + + #[test] + fn forward() { + crate::tests::substring::Runner::new() + .fwd(|h, n| Some(Finder::new(n).find(h, n))) + .run(); + } + + #[test] + fn reverse() { + crate::tests::substring::Runner::new() + .rev(|h, n| Some(FinderRev::new(n).rfind(h, n))) + .run(); + } +} diff --git a/vendor/memchr/src/arch/all/shiftor.rs b/vendor/memchr/src/arch/all/shiftor.rs new file mode 100644 index 0000000..b690564 --- /dev/null +++ b/vendor/memchr/src/arch/all/shiftor.rs @@ -0,0 +1,89 @@ +/*! +An implementation of the [Shift-Or substring search algorithm][shiftor]. + +[shiftor]: https://en.wikipedia.org/wiki/Bitap_algorithm +*/ + +use alloc::boxed::Box; + +/// The type of our mask. +/// +/// While we don't expose anyway to configure this in the public API, if one +/// really needs less memory usage or support for longer needles, then it is +/// suggested to copy the code from this module and modify it to fit your +/// needs. The code below is written to be correct regardless of whether Mask +/// is a u8, u16, u32, u64 or u128. +type Mask = u16; + +/// A forward substring searcher using the Shift-Or algorithm. +#[derive(Debug)] +pub struct Finder { + masks: Box<[Mask; 256]>, + needle_len: usize, +} + +impl Finder { + const MAX_NEEDLE_LEN: usize = (Mask::BITS - 1) as usize; + + /// Create a new Shift-Or forward searcher for the given `needle`. + /// + /// The needle may be empty. The empty needle matches at every byte offset. + #[inline] + pub fn new(needle: &[u8]) -> Option { + let needle_len = needle.len(); + if needle_len > Finder::MAX_NEEDLE_LEN { + // A match is found when bit 7 is set in 'result' in the search + // routine below. So our needle can't be bigger than 7. We could + // permit bigger needles by using u16, u32 or u64 for our mask + // entries. But this is all we need for this example. + return None; + } + let mut searcher = Finder { masks: Box::from([!0; 256]), needle_len }; + for (i, &byte) in needle.iter().enumerate() { + searcher.masks[usize::from(byte)] &= !(1 << i); + } + Some(searcher) + } + + /// Return the first occurrence of the needle given to `Finder::new` in + /// the `haystack` given. If no such occurrence exists, then `None` is + /// returned. + /// + /// Unlike most other substring search implementations in this crate, this + /// finder does not require passing the needle at search time. A match can + /// be determined without the needle at all since the required information + /// is already encoded into this finder at construction time. + /// + /// The maximum value this can return is `haystack.len()`, which can only + /// occur when the needle and haystack both have length zero. Otherwise, + /// for non-empty haystacks, the maximum value is `haystack.len() - 1`. + #[inline] + pub fn find(&self, haystack: &[u8]) -> Option { + if self.needle_len == 0 { + return Some(0); + } + let mut result = !1; + for (i, &byte) in haystack.iter().enumerate() { + result |= self.masks[usize::from(byte)]; + result <<= 1; + if result & (1 << self.needle_len) == 0 { + return Some(i + 1 - self.needle_len); + } + } + None + } +} + +#[cfg(test)] +mod tests { + use super::*; + + define_substring_forward_quickcheck!(|h, n| Some(Finder::new(n)?.find(h))); + + #[test] + fn forward() { + crate::tests::substring::Runner::new() + .fwd(|h, n| Some(Finder::new(n)?.find(h))) + .run(); + } +} diff --git a/vendor/memchr/src/arch/all/twoway.rs b/vendor/memchr/src/arch/all/twoway.rs new file mode 100644 index 0000000..0df3b4a --- /dev/null +++ b/vendor/memchr/src/arch/all/twoway.rs @@ -0,0 +1,877 @@ +/*! +An implementation of the [Two-Way substring search algorithm][two-way]. + +[`Finder`] can be built for forward searches, while [`FinderRev`] can be built +for reverse searches. + +Two-Way makes for a nice general purpose substring search algorithm because of +its time and space complexity properties. It also performs well in practice. +Namely, with `m = len(needle)` and `n = len(haystack)`, Two-Way takes `O(m)` +time to create a finder, `O(1)` space and `O(n)` search time. In other words, +the preprocessing step is quick, doesn't require any heap memory and the worst +case search time is guaranteed to be linear in the haystack regardless of the +size of the needle. + +While vector algorithms will usually beat Two-Way handedly, vector algorithms +also usually have pathological or edge cases that are better handled by Two-Way. +Moreover, not all targets support vector algorithms or implementations for them +simply may not exist yet. + +Two-Way can be found in the `memmem` implementations in at least [GNU libc] and +[musl]. + +[two-way]: https://en.wikipedia.org/wiki/Two-way_string-matching_algorithm +[GNU libc]: https://www.gnu.org/software/libc/ +[musl]: https://www.musl-libc.org/ +*/ + +use core::cmp; + +use crate::{ + arch::all::{is_prefix, is_suffix}, + memmem::Pre, +}; + +/// A forward substring searcher that uses the Two-Way algorithm. +#[derive(Clone, Copy, Debug)] +pub struct Finder(TwoWay); + +/// A reverse substring searcher that uses the Two-Way algorithm. +#[derive(Clone, Copy, Debug)] +pub struct FinderRev(TwoWay); + +/// An implementation of the TwoWay substring search algorithm. +/// +/// This searcher supports forward and reverse search, although not +/// simultaneously. It runs in `O(n + m)` time and `O(1)` space, where +/// `n ~ len(needle)` and `m ~ len(haystack)`. +/// +/// The implementation here roughly matches that which was developed by +/// Crochemore and Perrin in their 1991 paper "Two-way string-matching." The +/// changes in this implementation are 1) the use of zero-based indices, 2) a +/// heuristic skip table based on the last byte (borrowed from Rust's standard +/// library) and 3) the addition of heuristics for a fast skip loop. For (3), +/// callers can pass any kind of prefilter they want, but usually it's one +/// based on a heuristic that uses an approximate background frequency of bytes +/// to choose rare bytes to quickly look for candidate match positions. Note +/// though that currently, this prefilter functionality is not exposed directly +/// in the public API. (File an issue if you want it and provide a use case +/// please.) +/// +/// The heuristic for fast skipping is automatically shut off if it's +/// detected to be ineffective at search time. Generally, this only occurs in +/// pathological cases. But this is generally necessary in order to preserve +/// a `O(n + m)` time bound. +/// +/// The code below is fairly complex and not obviously correct at all. It's +/// likely necessary to read the Two-Way paper cited above in order to fully +/// grok this code. The essence of it is: +/// +/// 1. Do something to detect a "critical" position in the needle. +/// 2. For the current position in the haystack, look if `needle[critical..]` +/// matches at that position. +/// 3. If so, look if `needle[..critical]` matches. +/// 4. If a mismatch occurs, shift the search by some amount based on the +/// critical position and a pre-computed shift. +/// +/// This type is wrapped in the forward and reverse finders that expose +/// consistent forward or reverse APIs. +#[derive(Clone, Copy, Debug)] +struct TwoWay { + /// A small bitset used as a quick prefilter (in addition to any prefilter + /// given by the caller). Namely, a bit `i` is set if and only if `b%64==i` + /// for any `b == needle[i]`. + /// + /// When used as a prefilter, if the last byte at the current candidate + /// position is NOT in this set, then we can skip that entire candidate + /// position (the length of the needle). This is essentially the shift + /// trick found in Boyer-Moore, but only applied to bytes that don't appear + /// in the needle. + /// + /// N.B. This trick was inspired by something similar in std's + /// implementation of Two-Way. + byteset: ApproximateByteSet, + /// A critical position in needle. Specifically, this position corresponds + /// to beginning of either the minimal or maximal suffix in needle. (N.B. + /// See SuffixType below for why "minimal" isn't quite the correct word + /// here.) + /// + /// This is the position at which every search begins. Namely, search + /// starts by scanning text to the right of this position, and only if + /// there's a match does the text to the left of this position get scanned. + critical_pos: usize, + /// The amount we shift by in the Two-Way search algorithm. This + /// corresponds to the "small period" and "large period" cases. + shift: Shift, +} + +impl Finder { + /// Create a searcher that finds occurrences of the given `needle`. + /// + /// An empty `needle` results in a match at every position in a haystack, + /// including at `haystack.len()`. + #[inline] + pub fn new(needle: &[u8]) -> Finder { + let byteset = ApproximateByteSet::new(needle); + let min_suffix = Suffix::forward(needle, SuffixKind::Minimal); + let max_suffix = Suffix::forward(needle, SuffixKind::Maximal); + let (period_lower_bound, critical_pos) = + if min_suffix.pos > max_suffix.pos { + (min_suffix.period, min_suffix.pos) + } else { + (max_suffix.period, max_suffix.pos) + }; + let shift = Shift::forward(needle, period_lower_bound, critical_pos); + Finder(TwoWay { byteset, critical_pos, shift }) + } + + /// Returns the first occurrence of `needle` in the given `haystack`, or + /// `None` if no such occurrence could be found. + /// + /// The `needle` given must be the same as the `needle` provided to + /// [`Finder::new`]. + /// + /// An empty `needle` results in a match at every position in a haystack, + /// including at `haystack.len()`. + #[inline] + pub fn find(&self, haystack: &[u8], needle: &[u8]) -> Option { + self.find_with_prefilter(None, haystack, needle) + } + + /// This is like [`Finder::find`], but it accepts a prefilter for + /// accelerating searches. + /// + /// Currently this is not exposed in the public API because, at the time + /// of writing, I didn't want to spend time thinking about how to expose + /// the prefilter infrastructure (if at all). If you have a compelling use + /// case for exposing this routine, please create an issue. Do *not* open + /// a PR that just exposes `Pre` and friends. Exporting this routine will + /// require API design. + #[inline(always)] + pub(crate) fn find_with_prefilter( + &self, + pre: Option>, + haystack: &[u8], + needle: &[u8], + ) -> Option { + match self.0.shift { + Shift::Small { period } => { + self.find_small_imp(pre, haystack, needle, period) + } + Shift::Large { shift } => { + self.find_large_imp(pre, haystack, needle, shift) + } + } + } + + // Each of the two search implementations below can be accelerated by a + // prefilter, but it is not always enabled. To avoid its overhead when + // its disabled, we explicitly inline each search implementation based on + // whether a prefilter will be used or not. The decision on which to use + // is made in the parent meta searcher. + + #[inline(always)] + fn find_small_imp( + &self, + mut pre: Option>, + haystack: &[u8], + needle: &[u8], + period: usize, + ) -> Option { + let mut pos = 0; + let mut shift = 0; + let last_byte_pos = match needle.len().checked_sub(1) { + None => return Some(pos), + Some(last_byte) => last_byte, + }; + while pos + needle.len() <= haystack.len() { + let mut i = cmp::max(self.0.critical_pos, shift); + if let Some(pre) = pre.as_mut() { + if pre.is_effective() { + pos += pre.find(&haystack[pos..])?; + shift = 0; + i = self.0.critical_pos; + if pos + needle.len() > haystack.len() { + return None; + } + } + } + if !self.0.byteset.contains(haystack[pos + last_byte_pos]) { + pos += needle.len(); + shift = 0; + continue; + } + while i < needle.len() && needle[i] == haystack[pos + i] { + i += 1; + } + if i < needle.len() { + pos += i - self.0.critical_pos + 1; + shift = 0; + } else { + let mut j = self.0.critical_pos; + while j > shift && needle[j] == haystack[pos + j] { + j -= 1; + } + if j <= shift && needle[shift] == haystack[pos + shift] { + return Some(pos); + } + pos += period; + shift = needle.len() - period; + } + } + None + } + + #[inline(always)] + fn find_large_imp( + &self, + mut pre: Option>, + haystack: &[u8], + needle: &[u8], + shift: usize, + ) -> Option { + let mut pos = 0; + let last_byte_pos = match needle.len().checked_sub(1) { + None => return Some(pos), + Some(last_byte) => last_byte, + }; + 'outer: while pos + needle.len() <= haystack.len() { + if let Some(pre) = pre.as_mut() { + if pre.is_effective() { + pos += pre.find(&haystack[pos..])?; + if pos + needle.len() > haystack.len() { + return None; + } + } + } + + if !self.0.byteset.contains(haystack[pos + last_byte_pos]) { + pos += needle.len(); + continue; + } + let mut i = self.0.critical_pos; + while i < needle.len() && needle[i] == haystack[pos + i] { + i += 1; + } + if i < needle.len() { + pos += i - self.0.critical_pos + 1; + } else { + for j in (0..self.0.critical_pos).rev() { + if needle[j] != haystack[pos + j] { + pos += shift; + continue 'outer; + } + } + return Some(pos); + } + } + None + } +} + +impl FinderRev { + /// Create a searcher that finds occurrences of the given `needle`. + /// + /// An empty `needle` results in a match at every position in a haystack, + /// including at `haystack.len()`. + #[inline] + pub fn new(needle: &[u8]) -> FinderRev { + let byteset = ApproximateByteSet::new(needle); + let min_suffix = Suffix::reverse(needle, SuffixKind::Minimal); + let max_suffix = Suffix::reverse(needle, SuffixKind::Maximal); + let (period_lower_bound, critical_pos) = + if min_suffix.pos < max_suffix.pos { + (min_suffix.period, min_suffix.pos) + } else { + (max_suffix.period, max_suffix.pos) + }; + let shift = Shift::reverse(needle, period_lower_bound, critical_pos); + FinderRev(TwoWay { byteset, critical_pos, shift }) + } + + /// Returns the last occurrence of `needle` in the given `haystack`, or + /// `None` if no such occurrence could be found. + /// + /// The `needle` given must be the same as the `needle` provided to + /// [`FinderRev::new`]. + /// + /// An empty `needle` results in a match at every position in a haystack, + /// including at `haystack.len()`. + #[inline] + pub fn rfind(&self, haystack: &[u8], needle: &[u8]) -> Option { + // For the reverse case, we don't use a prefilter. It's plausible that + // perhaps we should, but it's a lot of additional code to do it, and + // it's not clear that it's actually worth it. If you have a really + // compelling use case for this, please file an issue. + match self.0.shift { + Shift::Small { period } => { + self.rfind_small_imp(haystack, needle, period) + } + Shift::Large { shift } => { + self.rfind_large_imp(haystack, needle, shift) + } + } + } + + #[inline(always)] + fn rfind_small_imp( + &self, + haystack: &[u8], + needle: &[u8], + period: usize, + ) -> Option { + let nlen = needle.len(); + let mut pos = haystack.len(); + let mut shift = nlen; + let first_byte = match needle.get(0) { + None => return Some(pos), + Some(&first_byte) => first_byte, + }; + while pos >= nlen { + if !self.0.byteset.contains(haystack[pos - nlen]) { + pos -= nlen; + shift = nlen; + continue; + } + let mut i = cmp::min(self.0.critical_pos, shift); + while i > 0 && needle[i - 1] == haystack[pos - nlen + i - 1] { + i -= 1; + } + if i > 0 || first_byte != haystack[pos - nlen] { + pos -= self.0.critical_pos - i + 1; + shift = nlen; + } else { + let mut j = self.0.critical_pos; + while j < shift && needle[j] == haystack[pos - nlen + j] { + j += 1; + } + if j >= shift { + return Some(pos - nlen); + } + pos -= period; + shift = period; + } + } + None + } + + #[inline(always)] + fn rfind_large_imp( + &self, + haystack: &[u8], + needle: &[u8], + shift: usize, + ) -> Option { + let nlen = needle.len(); + let mut pos = haystack.len(); + let first_byte = match needle.get(0) { + None => return Some(pos), + Some(&first_byte) => first_byte, + }; + while pos >= nlen { + if !self.0.byteset.contains(haystack[pos - nlen]) { + pos -= nlen; + continue; + } + let mut i = self.0.critical_pos; + while i > 0 && needle[i - 1] == haystack[pos - nlen + i - 1] { + i -= 1; + } + if i > 0 || first_byte != haystack[pos - nlen] { + pos -= self.0.critical_pos - i + 1; + } else { + let mut j = self.0.critical_pos; + while j < nlen && needle[j] == haystack[pos - nlen + j] { + j += 1; + } + if j == nlen { + return Some(pos - nlen); + } + pos -= shift; + } + } + None + } +} + +/// A representation of the amount we're allowed to shift by during Two-Way +/// search. +/// +/// When computing a critical factorization of the needle, we find the position +/// of the critical factorization by finding the needle's maximal (or minimal) +/// suffix, along with the period of that suffix. It turns out that the period +/// of that suffix is a lower bound on the period of the needle itself. +/// +/// This lower bound is equivalent to the actual period of the needle in +/// some cases. To describe that case, we denote the needle as `x` where +/// `x = uv` and `v` is the lexicographic maximal suffix of `v`. The lower +/// bound given here is always the period of `v`, which is `<= period(x)`. The +/// case where `period(v) == period(x)` occurs when `len(u) < (len(x) / 2)` and +/// where `u` is a suffix of `v[0..period(v)]`. +/// +/// This case is important because the search algorithm for when the +/// periods are equivalent is slightly different than the search algorithm +/// for when the periods are not equivalent. In particular, when they aren't +/// equivalent, we know that the period of the needle is no less than half its +/// length. In this case, we shift by an amount less than or equal to the +/// period of the needle (determined by the maximum length of the components +/// of the critical factorization of `x`, i.e., `max(len(u), len(v))`).. +/// +/// The above two cases are represented by the variants below. Each entails +/// a different instantiation of the Two-Way search algorithm. +/// +/// N.B. If we could find a way to compute the exact period in all cases, +/// then we could collapse this case analysis and simplify the algorithm. The +/// Two-Way paper suggests this is possible, but more reading is required to +/// grok why the authors didn't pursue that path. +#[derive(Clone, Copy, Debug)] +enum Shift { + Small { period: usize }, + Large { shift: usize }, +} + +impl Shift { + /// Compute the shift for a given needle in the forward direction. + /// + /// This requires a lower bound on the period and a critical position. + /// These can be computed by extracting both the minimal and maximal + /// lexicographic suffixes, and choosing the right-most starting position. + /// The lower bound on the period is then the period of the chosen suffix. + fn forward( + needle: &[u8], + period_lower_bound: usize, + critical_pos: usize, + ) -> Shift { + let large = cmp::max(critical_pos, needle.len() - critical_pos); + if critical_pos * 2 >= needle.len() { + return Shift::Large { shift: large }; + } + + let (u, v) = needle.split_at(critical_pos); + if !is_suffix(&v[..period_lower_bound], u) { + return Shift::Large { shift: large }; + } + Shift::Small { period: period_lower_bound } + } + + /// Compute the shift for a given needle in the reverse direction. + /// + /// This requires a lower bound on the period and a critical position. + /// These can be computed by extracting both the minimal and maximal + /// lexicographic suffixes, and choosing the left-most starting position. + /// The lower bound on the period is then the period of the chosen suffix. + fn reverse( + needle: &[u8], + period_lower_bound: usize, + critical_pos: usize, + ) -> Shift { + let large = cmp::max(critical_pos, needle.len() - critical_pos); + if (needle.len() - critical_pos) * 2 >= needle.len() { + return Shift::Large { shift: large }; + } + + let (v, u) = needle.split_at(critical_pos); + if !is_prefix(&v[v.len() - period_lower_bound..], u) { + return Shift::Large { shift: large }; + } + Shift::Small { period: period_lower_bound } + } +} + +/// A suffix extracted from a needle along with its period. +#[derive(Debug)] +struct Suffix { + /// The starting position of this suffix. + /// + /// If this is a forward suffix, then `&bytes[pos..]` can be used. If this + /// is a reverse suffix, then `&bytes[..pos]` can be used. That is, for + /// forward suffixes, this is an inclusive starting position, where as for + /// reverse suffixes, this is an exclusive ending position. + pos: usize, + /// The period of this suffix. + /// + /// Note that this is NOT necessarily the period of the string from which + /// this suffix comes from. (It is always less than or equal to the period + /// of the original string.) + period: usize, +} + +impl Suffix { + fn forward(needle: &[u8], kind: SuffixKind) -> Suffix { + // suffix represents our maximal (or minimal) suffix, along with + // its period. + let mut suffix = Suffix { pos: 0, period: 1 }; + // The start of a suffix in `needle` that we are considering as a + // more maximal (or minimal) suffix than what's in `suffix`. + let mut candidate_start = 1; + // The current offset of our suffixes that we're comparing. + // + // When the characters at this offset are the same, then we mush on + // to the next position since no decision is possible. When the + // candidate's character is greater (or lesser) than the corresponding + // character than our current maximal (or minimal) suffix, then the + // current suffix is changed over to the candidate and we restart our + // search. Otherwise, the candidate suffix is no good and we restart + // our search on the next candidate. + // + // The three cases above correspond to the three cases in the loop + // below. + let mut offset = 0; + + while candidate_start + offset < needle.len() { + let current = needle[suffix.pos + offset]; + let candidate = needle[candidate_start + offset]; + match kind.cmp(current, candidate) { + SuffixOrdering::Accept => { + suffix = Suffix { pos: candidate_start, period: 1 }; + candidate_start += 1; + offset = 0; + } + SuffixOrdering::Skip => { + candidate_start += offset + 1; + offset = 0; + suffix.period = candidate_start - suffix.pos; + } + SuffixOrdering::Push => { + if offset + 1 == suffix.period { + candidate_start += suffix.period; + offset = 0; + } else { + offset += 1; + } + } + } + } + suffix + } + + fn reverse(needle: &[u8], kind: SuffixKind) -> Suffix { + // See the comments in `forward` for how this works. + let mut suffix = Suffix { pos: needle.len(), period: 1 }; + if needle.len() == 1 { + return suffix; + } + let mut candidate_start = match needle.len().checked_sub(1) { + None => return suffix, + Some(candidate_start) => candidate_start, + }; + let mut offset = 0; + + while offset < candidate_start { + let current = needle[suffix.pos - offset - 1]; + let candidate = needle[candidate_start - offset - 1]; + match kind.cmp(current, candidate) { + SuffixOrdering::Accept => { + suffix = Suffix { pos: candidate_start, period: 1 }; + candidate_start -= 1; + offset = 0; + } + SuffixOrdering::Skip => { + candidate_start -= offset + 1; + offset = 0; + suffix.period = suffix.pos - candidate_start; + } + SuffixOrdering::Push => { + if offset + 1 == suffix.period { + candidate_start -= suffix.period; + offset = 0; + } else { + offset += 1; + } + } + } + } + suffix + } +} + +/// The kind of suffix to extract. +#[derive(Clone, Copy, Debug)] +enum SuffixKind { + /// Extract the smallest lexicographic suffix from a string. + /// + /// Technically, this doesn't actually pick the smallest lexicographic + /// suffix. e.g., Given the choice between `a` and `aa`, this will choose + /// the latter over the former, even though `a < aa`. The reasoning for + /// this isn't clear from the paper, but it still smells like a minimal + /// suffix. + Minimal, + /// Extract the largest lexicographic suffix from a string. + /// + /// Unlike `Minimal`, this really does pick the maximum suffix. e.g., Given + /// the choice between `z` and `zz`, this will choose the latter over the + /// former. + Maximal, +} + +/// The result of comparing corresponding bytes between two suffixes. +#[derive(Clone, Copy, Debug)] +enum SuffixOrdering { + /// This occurs when the given candidate byte indicates that the candidate + /// suffix is better than the current maximal (or minimal) suffix. That is, + /// the current candidate suffix should supplant the current maximal (or + /// minimal) suffix. + Accept, + /// This occurs when the given candidate byte excludes the candidate suffix + /// from being better than the current maximal (or minimal) suffix. That + /// is, the current candidate suffix should be dropped and the next one + /// should be considered. + Skip, + /// This occurs when no decision to accept or skip the candidate suffix + /// can be made, e.g., when corresponding bytes are equivalent. In this + /// case, the next corresponding bytes should be compared. + Push, +} + +impl SuffixKind { + /// Returns true if and only if the given candidate byte indicates that + /// it should replace the current suffix as the maximal (or minimal) + /// suffix. + fn cmp(self, current: u8, candidate: u8) -> SuffixOrdering { + use self::SuffixOrdering::*; + + match self { + SuffixKind::Minimal if candidate < current => Accept, + SuffixKind::Minimal if candidate > current => Skip, + SuffixKind::Minimal => Push, + SuffixKind::Maximal if candidate > current => Accept, + SuffixKind::Maximal if candidate < current => Skip, + SuffixKind::Maximal => Push, + } + } +} + +/// A bitset used to track whether a particular byte exists in a needle or not. +/// +/// Namely, bit 'i' is set if and only if byte%64==i for any byte in the +/// needle. If a particular byte in the haystack is NOT in this set, then one +/// can conclude that it is also not in the needle, and thus, one can advance +/// in the haystack by needle.len() bytes. +#[derive(Clone, Copy, Debug)] +struct ApproximateByteSet(u64); + +impl ApproximateByteSet { + /// Create a new set from the given needle. + fn new(needle: &[u8]) -> ApproximateByteSet { + let mut bits = 0; + for &b in needle { + bits |= 1 << (b % 64); + } + ApproximateByteSet(bits) + } + + /// Return true if and only if the given byte might be in this set. This + /// may return a false positive, but will never return a false negative. + #[inline(always)] + fn contains(&self, byte: u8) -> bool { + self.0 & (1 << (byte % 64)) != 0 + } +} + +#[cfg(test)] +mod tests { + use alloc::vec::Vec; + + use super::*; + + /// Convenience wrapper for computing the suffix as a byte string. + fn get_suffix_forward(needle: &[u8], kind: SuffixKind) -> (&[u8], usize) { + let s = Suffix::forward(needle, kind); + (&needle[s.pos..], s.period) + } + + /// Convenience wrapper for computing the reverse suffix as a byte string. + fn get_suffix_reverse(needle: &[u8], kind: SuffixKind) -> (&[u8], usize) { + let s = Suffix::reverse(needle, kind); + (&needle[..s.pos], s.period) + } + + /// Return all of the non-empty suffixes in the given byte string. + fn suffixes(bytes: &[u8]) -> Vec<&[u8]> { + (0..bytes.len()).map(|i| &bytes[i..]).collect() + } + + /// Return the lexicographically maximal suffix of the given byte string. + fn naive_maximal_suffix_forward(needle: &[u8]) -> &[u8] { + let mut sufs = suffixes(needle); + sufs.sort(); + sufs.pop().unwrap() + } + + /// Return the lexicographically maximal suffix of the reverse of the given + /// byte string. + fn naive_maximal_suffix_reverse(needle: &[u8]) -> Vec { + let mut reversed = needle.to_vec(); + reversed.reverse(); + let mut got = naive_maximal_suffix_forward(&reversed).to_vec(); + got.reverse(); + got + } + + define_substring_forward_quickcheck!(|h, n| Some( + Finder::new(n).find(h, n) + )); + define_substring_reverse_quickcheck!(|h, n| Some( + FinderRev::new(n).rfind(h, n) + )); + + #[test] + fn forward() { + crate::tests::substring::Runner::new() + .fwd(|h, n| Some(Finder::new(n).find(h, n))) + .run(); + } + + #[test] + fn reverse() { + crate::tests::substring::Runner::new() + .rev(|h, n| Some(FinderRev::new(n).rfind(h, n))) + .run(); + } + + #[test] + fn suffix_forward() { + macro_rules! assert_suffix_min { + ($given:expr, $expected:expr, $period:expr) => { + let (got_suffix, got_period) = + get_suffix_forward($given.as_bytes(), SuffixKind::Minimal); + let got_suffix = core::str::from_utf8(got_suffix).unwrap(); + assert_eq!(($expected, $period), (got_suffix, got_period)); + }; + } + + macro_rules! assert_suffix_max { + ($given:expr, $expected:expr, $period:expr) => { + let (got_suffix, got_period) = + get_suffix_forward($given.as_bytes(), SuffixKind::Maximal); + let got_suffix = core::str::from_utf8(got_suffix).unwrap(); + assert_eq!(($expected, $period), (got_suffix, got_period)); + }; + } + + assert_suffix_min!("a", "a", 1); + assert_suffix_max!("a", "a", 1); + + assert_suffix_min!("ab", "ab", 2); + assert_suffix_max!("ab", "b", 1); + + assert_suffix_min!("ba", "a", 1); + assert_suffix_max!("ba", "ba", 2); + + assert_suffix_min!("abc", "abc", 3); + assert_suffix_max!("abc", "c", 1); + + assert_suffix_min!("acb", "acb", 3); + assert_suffix_max!("acb", "cb", 2); + + assert_suffix_min!("cba", "a", 1); + assert_suffix_max!("cba", "cba", 3); + + assert_suffix_min!("abcabc", "abcabc", 3); + assert_suffix_max!("abcabc", "cabc", 3); + + assert_suffix_min!("abcabcabc", "abcabcabc", 3); + assert_suffix_max!("abcabcabc", "cabcabc", 3); + + assert_suffix_min!("abczz", "abczz", 5); + assert_suffix_max!("abczz", "zz", 1); + + assert_suffix_min!("zzabc", "abc", 3); + assert_suffix_max!("zzabc", "zzabc", 5); + + assert_suffix_min!("aaa", "aaa", 1); + assert_suffix_max!("aaa", "aaa", 1); + + assert_suffix_min!("foobar", "ar", 2); + assert_suffix_max!("foobar", "r", 1); + } + + #[test] + fn suffix_reverse() { + macro_rules! assert_suffix_min { + ($given:expr, $expected:expr, $period:expr) => { + let (got_suffix, got_period) = + get_suffix_reverse($given.as_bytes(), SuffixKind::Minimal); + let got_suffix = core::str::from_utf8(got_suffix).unwrap(); + assert_eq!(($expected, $period), (got_suffix, got_period)); + }; + } + + macro_rules! assert_suffix_max { + ($given:expr, $expected:expr, $period:expr) => { + let (got_suffix, got_period) = + get_suffix_reverse($given.as_bytes(), SuffixKind::Maximal); + let got_suffix = core::str::from_utf8(got_suffix).unwrap(); + assert_eq!(($expected, $period), (got_suffix, got_period)); + }; + } + + assert_suffix_min!("a", "a", 1); + assert_suffix_max!("a", "a", 1); + + assert_suffix_min!("ab", "a", 1); + assert_suffix_max!("ab", "ab", 2); + + assert_suffix_min!("ba", "ba", 2); + assert_suffix_max!("ba", "b", 1); + + assert_suffix_min!("abc", "a", 1); + assert_suffix_max!("abc", "abc", 3); + + assert_suffix_min!("acb", "a", 1); + assert_suffix_max!("acb", "ac", 2); + + assert_suffix_min!("cba", "cba", 3); + assert_suffix_max!("cba", "c", 1); + + assert_suffix_min!("abcabc", "abca", 3); + assert_suffix_max!("abcabc", "abcabc", 3); + + assert_suffix_min!("abcabcabc", "abcabca", 3); + assert_suffix_max!("abcabcabc", "abcabcabc", 3); + + assert_suffix_min!("abczz", "a", 1); + assert_suffix_max!("abczz", "abczz", 5); + + assert_suffix_min!("zzabc", "zza", 3); + assert_suffix_max!("zzabc", "zz", 1); + + assert_suffix_min!("aaa", "aaa", 1); + assert_suffix_max!("aaa", "aaa", 1); + } + + #[cfg(not(miri))] + quickcheck::quickcheck! { + fn qc_suffix_forward_maximal(bytes: Vec) -> bool { + if bytes.is_empty() { + return true; + } + + let (got, _) = get_suffix_forward(&bytes, SuffixKind::Maximal); + let expected = naive_maximal_suffix_forward(&bytes); + got == expected + } + + fn qc_suffix_reverse_maximal(bytes: Vec) -> bool { + if bytes.is_empty() { + return true; + } + + let (got, _) = get_suffix_reverse(&bytes, SuffixKind::Maximal); + let expected = naive_maximal_suffix_reverse(&bytes); + expected == got + } + } + + // This is a regression test caught by quickcheck that exercised a bug in + // the reverse small period handling. The bug was that we were using 'if j + // == shift' to determine if a match occurred, but the correct guard is 'if + // j >= shift', which matches the corresponding guard in the forward impl. + #[test] + fn regression_rev_small_period() { + let rfind = |h, n| FinderRev::new(n).rfind(h, n); + let haystack = "ababaz"; + let needle = "abab"; + assert_eq!(Some(0), rfind(haystack.as_bytes(), needle.as_bytes())); + } +} diff --git a/vendor/memchr/src/arch/generic/memchr.rs b/vendor/memchr/src/arch/generic/memchr.rs new file mode 100644 index 0000000..580b3cc --- /dev/null +++ b/vendor/memchr/src/arch/generic/memchr.rs @@ -0,0 +1,1214 @@ +/*! +Generic crate-internal routines for the `memchr` family of functions. +*/ + +// What follows is a vector algorithm generic over the specific vector +// type to detect the position of one, two or three needles in a haystack. +// From what I know, this is a "classic" algorithm, although I don't +// believe it has been published in any peer reviewed journal. I believe +// it can be found in places like glibc and Go's standard library. It +// appears to be well known and is elaborated on in more detail here: +// https://gms.tf/stdfind-and-memchr-optimizations.html +// +// While the routine below is fairly long and perhaps intimidating, the basic +// idea is actually very simple and can be expressed straight-forwardly in +// pseudo code. The psuedo code below is written for 128 bit vectors, but the +// actual code below works for anything that implements the Vector trait. +// +// needle = (n1 << 15) | (n1 << 14) | ... | (n1 << 1) | n1 +// // Note: shift amount is in bytes +// +// while i <= haystack.len() - 16: +// // A 16 byte vector. Each byte in chunk corresponds to a byte in +// // the haystack. +// chunk = haystack[i:i+16] +// // Compare bytes in needle with bytes in chunk. The result is a 16 +// // byte chunk where each byte is 0xFF if the corresponding bytes +// // in needle and chunk were equal, or 0x00 otherwise. +// eqs = cmpeq(needle, chunk) +// // Return a 32 bit integer where the most significant 16 bits +// // are always 0 and the lower 16 bits correspond to whether the +// // most significant bit in the correspond byte in `eqs` is set. +// // In other words, `mask as u16` has bit i set if and only if +// // needle[i] == chunk[i]. +// mask = movemask(eqs) +// +// // Mask is 0 if there is no match, and non-zero otherwise. +// if mask != 0: +// // trailing_zeros tells us the position of the least significant +// // bit that is set. +// return i + trailing_zeros(mask) +// +// // haystack length may not be a multiple of 16, so search the rest. +// while i < haystack.len(): +// if haystack[i] == n1: +// return i +// +// // No match found. +// return NULL +// +// In fact, we could loosely translate the above code to Rust line-for-line +// and it would be a pretty fast algorithm. But, we pull out all the stops +// to go as fast as possible: +// +// 1. We use aligned loads. That is, we do some finagling to make sure our +// primary loop not only proceeds in increments of 16 bytes, but that +// the address of haystack's pointer that we dereference is aligned to +// 16 bytes. 16 is a magic number here because it is the size of SSE2 +// 128-bit vector. (For the AVX2 algorithm, 32 is the magic number.) +// Therefore, to get aligned loads, our pointer's address must be evenly +// divisible by 16. +// 2. Our primary loop proceeds 64 bytes at a time instead of 16. It's +// kind of like loop unrolling, but we combine the equality comparisons +// using a vector OR such that we only need to extract a single mask to +// determine whether a match exists or not. If so, then we do some +// book-keeping to determine the precise location but otherwise mush on. +// 3. We use our "chunk" comparison routine in as many places as possible, +// even if it means using unaligned loads. In particular, if haystack +// starts with an unaligned address, then we do an unaligned load to +// search the first 16 bytes. We then start our primary loop at the +// smallest subsequent aligned address, which will actually overlap with +// previously searched bytes. But we're OK with that. We do a similar +// dance at the end of our primary loop. Finally, to avoid a +// byte-at-a-time loop at the end, we do a final 16 byte unaligned load +// that may overlap with a previous load. This is OK because it converts +// a loop into a small number of very fast vector instructions. The overlap +// is OK because we know the place where the overlap occurs does not +// contain a match. +// +// And that's pretty all there is to it. Note that since the below is +// generic and since it's meant to be inlined into routines with a +// `#[target_feature(enable = "...")]` annotation, we must mark all routines as +// both unsafe and `#[inline(always)]`. +// +// The fact that the code below is generic does somewhat inhibit us. For +// example, I've noticed that introducing an unlineable `#[cold]` function to +// handle the match case in the loop generates tighter assembly, but there is +// no way to do this in the generic code below because the generic code doesn't +// know what `target_feature` annotation to apply to the unlineable function. +// We could make such functions part of the `Vector` trait, but we instead live +// with the slightly sub-optimal codegen for now since it doesn't seem to have +// a noticeable perf difference. + +use crate::{ + ext::Pointer, + vector::{MoveMask, Vector}, +}; + +/// Finds all occurrences of a single byte in a haystack. +#[derive(Clone, Copy, Debug)] +pub(crate) struct One { + s1: u8, + v1: V, +} + +impl One { + /// The number of bytes we examine per each iteration of our search loop. + const LOOP_SIZE: usize = 4 * V::BYTES; + + /// Create a new searcher that finds occurrences of the byte given. + #[inline(always)] + pub(crate) unsafe fn new(needle: u8) -> One { + One { s1: needle, v1: V::splat(needle) } + } + + /// Returns the needle given to `One::new`. + #[inline(always)] + pub(crate) fn needle1(&self) -> u8 { + self.s1 + } + + /// Return a pointer to the first occurrence of the needle in the given + /// haystack. If no such occurrence exists, then `None` is returned. + /// + /// When a match is found, the pointer returned is guaranteed to be + /// `>= start` and `< end`. + /// + /// # Safety + /// + /// * It must be the case that `start < end` and that the distance between + /// them is at least equal to `V::BYTES`. That is, it must always be valid + /// to do at least an unaligned load of `V` at `start`. + /// * Both `start` and `end` must be valid for reads. + /// * Both `start` and `end` must point to an initialized value. + /// * Both `start` and `end` must point to the same allocated object and + /// must either be in bounds or at most one byte past the end of the + /// allocated object. + /// * Both `start` and `end` must be _derived from_ a pointer to the same + /// object. + /// * The distance between `start` and `end` must not overflow `isize`. + /// * The distance being in bounds must not rely on "wrapping around" the + /// address space. + #[inline(always)] + pub(crate) unsafe fn find_raw( + &self, + start: *const u8, + end: *const u8, + ) -> Option<*const u8> { + // If we want to support vectors bigger than 256 bits, we probably + // need to move up to using a u64 for the masks used below. Currently + // they are 32 bits, which means we're SOL for vectors that need masks + // bigger than 32 bits. Overall unclear until there's a use case. + debug_assert!(V::BYTES <= 32, "vector cannot be bigger than 32 bytes"); + + let topos = V::Mask::first_offset; + let len = end.distance(start); + debug_assert!( + len >= V::BYTES, + "haystack has length {}, but must be at least {}", + len, + V::BYTES + ); + + // Search a possibly unaligned chunk at `start`. This covers any part + // of the haystack prior to where aligned loads can start. + if let Some(cur) = self.search_chunk(start, topos) { + return Some(cur); + } + // Set `cur` to the first V-aligned pointer greater than `start`. + let mut cur = start.add(V::BYTES - (start.as_usize() & V::ALIGN)); + debug_assert!(cur > start && end.sub(V::BYTES) >= start); + if len >= Self::LOOP_SIZE { + while cur <= end.sub(Self::LOOP_SIZE) { + debug_assert_eq!(0, cur.as_usize() % V::BYTES); + + let a = V::load_aligned(cur); + let b = V::load_aligned(cur.add(1 * V::BYTES)); + let c = V::load_aligned(cur.add(2 * V::BYTES)); + let d = V::load_aligned(cur.add(3 * V::BYTES)); + let eqa = self.v1.cmpeq(a); + let eqb = self.v1.cmpeq(b); + let eqc = self.v1.cmpeq(c); + let eqd = self.v1.cmpeq(d); + let or1 = eqa.or(eqb); + let or2 = eqc.or(eqd); + let or3 = or1.or(or2); + if or3.movemask_will_have_non_zero() { + let mask = eqa.movemask(); + if mask.has_non_zero() { + return Some(cur.add(topos(mask))); + } + + let mask = eqb.movemask(); + if mask.has_non_zero() { + return Some(cur.add(1 * V::BYTES).add(topos(mask))); + } + + let mask = eqc.movemask(); + if mask.has_non_zero() { + return Some(cur.add(2 * V::BYTES).add(topos(mask))); + } + + let mask = eqd.movemask(); + debug_assert!(mask.has_non_zero()); + return Some(cur.add(3 * V::BYTES).add(topos(mask))); + } + cur = cur.add(Self::LOOP_SIZE); + } + } + // Handle any leftovers after the aligned loop above. We use unaligned + // loads here, but I believe we are guaranteed that they are aligned + // since `cur` is aligned. + while cur <= end.sub(V::BYTES) { + debug_assert!(end.distance(cur) >= V::BYTES); + if let Some(cur) = self.search_chunk(cur, topos) { + return Some(cur); + } + cur = cur.add(V::BYTES); + } + // Finally handle any remaining bytes less than the size of V. In this + // case, our pointer may indeed be unaligned and the load may overlap + // with the previous one. But that's okay since we know the previous + // load didn't lead to a match (otherwise we wouldn't be here). + if cur < end { + debug_assert!(end.distance(cur) < V::BYTES); + cur = cur.sub(V::BYTES - end.distance(cur)); + debug_assert_eq!(end.distance(cur), V::BYTES); + return self.search_chunk(cur, topos); + } + None + } + + /// Return a pointer to the last occurrence of the needle in the given + /// haystack. If no such occurrence exists, then `None` is returned. + /// + /// When a match is found, the pointer returned is guaranteed to be + /// `>= start` and `< end`. + /// + /// # Safety + /// + /// * It must be the case that `start < end` and that the distance between + /// them is at least equal to `V::BYTES`. That is, it must always be valid + /// to do at least an unaligned load of `V` at `start`. + /// * Both `start` and `end` must be valid for reads. + /// * Both `start` and `end` must point to an initialized value. + /// * Both `start` and `end` must point to the same allocated object and + /// must either be in bounds or at most one byte past the end of the + /// allocated object. + /// * Both `start` and `end` must be _derived from_ a pointer to the same + /// object. + /// * The distance between `start` and `end` must not overflow `isize`. + /// * The distance being in bounds must not rely on "wrapping around" the + /// address space. + #[inline(always)] + pub(crate) unsafe fn rfind_raw( + &self, + start: *const u8, + end: *const u8, + ) -> Option<*const u8> { + // If we want to support vectors bigger than 256 bits, we probably + // need to move up to using a u64 for the masks used below. Currently + // they are 32 bits, which means we're SOL for vectors that need masks + // bigger than 32 bits. Overall unclear until there's a use case. + debug_assert!(V::BYTES <= 32, "vector cannot be bigger than 32 bytes"); + + let topos = V::Mask::last_offset; + let len = end.distance(start); + debug_assert!( + len >= V::BYTES, + "haystack has length {}, but must be at least {}", + len, + V::BYTES + ); + + if let Some(cur) = self.search_chunk(end.sub(V::BYTES), topos) { + return Some(cur); + } + let mut cur = end.sub(end.as_usize() & V::ALIGN); + debug_assert!(start <= cur && cur <= end); + if len >= Self::LOOP_SIZE { + while cur >= start.add(Self::LOOP_SIZE) { + debug_assert_eq!(0, cur.as_usize() % V::BYTES); + + cur = cur.sub(Self::LOOP_SIZE); + let a = V::load_aligned(cur); + let b = V::load_aligned(cur.add(1 * V::BYTES)); + let c = V::load_aligned(cur.add(2 * V::BYTES)); + let d = V::load_aligned(cur.add(3 * V::BYTES)); + let eqa = self.v1.cmpeq(a); + let eqb = self.v1.cmpeq(b); + let eqc = self.v1.cmpeq(c); + let eqd = self.v1.cmpeq(d); + let or1 = eqa.or(eqb); + let or2 = eqc.or(eqd); + let or3 = or1.or(or2); + if or3.movemask_will_have_non_zero() { + let mask = eqd.movemask(); + if mask.has_non_zero() { + return Some(cur.add(3 * V::BYTES).add(topos(mask))); + } + + let mask = eqc.movemask(); + if mask.has_non_zero() { + return Some(cur.add(2 * V::BYTES).add(topos(mask))); + } + + let mask = eqb.movemask(); + if mask.has_non_zero() { + return Some(cur.add(1 * V::BYTES).add(topos(mask))); + } + + let mask = eqa.movemask(); + debug_assert!(mask.has_non_zero()); + return Some(cur.add(topos(mask))); + } + } + } + while cur >= start.add(V::BYTES) { + debug_assert!(cur.distance(start) >= V::BYTES); + cur = cur.sub(V::BYTES); + if let Some(cur) = self.search_chunk(cur, topos) { + return Some(cur); + } + } + if cur > start { + debug_assert!(cur.distance(start) < V::BYTES); + return self.search_chunk(start, topos); + } + None + } + + /// Return a count of all matching bytes in the given haystack. + /// + /// # Safety + /// + /// * It must be the case that `start < end` and that the distance between + /// them is at least equal to `V::BYTES`. That is, it must always be valid + /// to do at least an unaligned load of `V` at `start`. + /// * Both `start` and `end` must be valid for reads. + /// * Both `start` and `end` must point to an initialized value. + /// * Both `start` and `end` must point to the same allocated object and + /// must either be in bounds or at most one byte past the end of the + /// allocated object. + /// * Both `start` and `end` must be _derived from_ a pointer to the same + /// object. + /// * The distance between `start` and `end` must not overflow `isize`. + /// * The distance being in bounds must not rely on "wrapping around" the + /// address space. + #[inline(always)] + pub(crate) unsafe fn count_raw( + &self, + start: *const u8, + end: *const u8, + ) -> usize { + debug_assert!(V::BYTES <= 32, "vector cannot be bigger than 32 bytes"); + + let confirm = |b| b == self.needle1(); + let len = end.distance(start); + debug_assert!( + len >= V::BYTES, + "haystack has length {}, but must be at least {}", + len, + V::BYTES + ); + + // Set `cur` to the first V-aligned pointer greater than `start`. + let mut cur = start.add(V::BYTES - (start.as_usize() & V::ALIGN)); + // Count any matching bytes before we start our aligned loop. + let mut count = count_byte_by_byte(start, cur, confirm); + debug_assert!(cur > start && end.sub(V::BYTES) >= start); + if len >= Self::LOOP_SIZE { + while cur <= end.sub(Self::LOOP_SIZE) { + debug_assert_eq!(0, cur.as_usize() % V::BYTES); + + let a = V::load_aligned(cur); + let b = V::load_aligned(cur.add(1 * V::BYTES)); + let c = V::load_aligned(cur.add(2 * V::BYTES)); + let d = V::load_aligned(cur.add(3 * V::BYTES)); + let eqa = self.v1.cmpeq(a); + let eqb = self.v1.cmpeq(b); + let eqc = self.v1.cmpeq(c); + let eqd = self.v1.cmpeq(d); + count += eqa.movemask().count_ones(); + count += eqb.movemask().count_ones(); + count += eqc.movemask().count_ones(); + count += eqd.movemask().count_ones(); + cur = cur.add(Self::LOOP_SIZE); + } + } + // Handle any leftovers after the aligned loop above. We use unaligned + // loads here, but I believe we are guaranteed that they are aligned + // since `cur` is aligned. + while cur <= end.sub(V::BYTES) { + debug_assert!(end.distance(cur) >= V::BYTES); + let chunk = V::load_unaligned(cur); + count += self.v1.cmpeq(chunk).movemask().count_ones(); + cur = cur.add(V::BYTES); + } + // And finally count any leftovers that weren't caught above. + count += count_byte_by_byte(cur, end, confirm); + count + } + + /// Search `V::BYTES` starting at `cur` via an unaligned load. + /// + /// `mask_to_offset` should be a function that converts a `movemask` to + /// an offset such that `cur.add(offset)` corresponds to a pointer to the + /// match location if one is found. Generally it is expected to use either + /// `mask_to_first_offset` or `mask_to_last_offset`, depending on whether + /// one is implementing a forward or reverse search, respectively. + /// + /// # Safety + /// + /// `cur` must be a valid pointer and it must be valid to do an unaligned + /// load of size `V::BYTES` at `cur`. + #[inline(always)] + unsafe fn search_chunk( + &self, + cur: *const u8, + mask_to_offset: impl Fn(V::Mask) -> usize, + ) -> Option<*const u8> { + let chunk = V::load_unaligned(cur); + let mask = self.v1.cmpeq(chunk).movemask(); + if mask.has_non_zero() { + Some(cur.add(mask_to_offset(mask))) + } else { + None + } + } +} + +/// Finds all occurrences of two bytes in a haystack. +/// +/// That is, this reports matches of one of two possible bytes. For example, +/// searching for `a` or `b` in `afoobar` would report matches at offsets `0`, +/// `4` and `5`. +#[derive(Clone, Copy, Debug)] +pub(crate) struct Two { + s1: u8, + s2: u8, + v1: V, + v2: V, +} + +impl Two { + /// The number of bytes we examine per each iteration of our search loop. + const LOOP_SIZE: usize = 2 * V::BYTES; + + /// Create a new searcher that finds occurrences of the byte given. + #[inline(always)] + pub(crate) unsafe fn new(needle1: u8, needle2: u8) -> Two { + Two { + s1: needle1, + s2: needle2, + v1: V::splat(needle1), + v2: V::splat(needle2), + } + } + + /// Returns the first needle given to `Two::new`. + #[inline(always)] + pub(crate) fn needle1(&self) -> u8 { + self.s1 + } + + /// Returns the second needle given to `Two::new`. + #[inline(always)] + pub(crate) fn needle2(&self) -> u8 { + self.s2 + } + + /// Return a pointer to the first occurrence of one of the needles in the + /// given haystack. If no such occurrence exists, then `None` is returned. + /// + /// When a match is found, the pointer returned is guaranteed to be + /// `>= start` and `< end`. + /// + /// # Safety + /// + /// * It must be the case that `start < end` and that the distance between + /// them is at least equal to `V::BYTES`. That is, it must always be valid + /// to do at least an unaligned load of `V` at `start`. + /// * Both `start` and `end` must be valid for reads. + /// * Both `start` and `end` must point to an initialized value. + /// * Both `start` and `end` must point to the same allocated object and + /// must either be in bounds or at most one byte past the end of the + /// allocated object. + /// * Both `start` and `end` must be _derived from_ a pointer to the same + /// object. + /// * The distance between `start` and `end` must not overflow `isize`. + /// * The distance being in bounds must not rely on "wrapping around" the + /// address space. + #[inline(always)] + pub(crate) unsafe fn find_raw( + &self, + start: *const u8, + end: *const u8, + ) -> Option<*const u8> { + // If we want to support vectors bigger than 256 bits, we probably + // need to move up to using a u64 for the masks used below. Currently + // they are 32 bits, which means we're SOL for vectors that need masks + // bigger than 32 bits. Overall unclear until there's a use case. + debug_assert!(V::BYTES <= 32, "vector cannot be bigger than 32 bytes"); + + let topos = V::Mask::first_offset; + let len = end.distance(start); + debug_assert!( + len >= V::BYTES, + "haystack has length {}, but must be at least {}", + len, + V::BYTES + ); + + // Search a possibly unaligned chunk at `start`. This covers any part + // of the haystack prior to where aligned loads can start. + if let Some(cur) = self.search_chunk(start, topos) { + return Some(cur); + } + // Set `cur` to the first V-aligned pointer greater than `start`. + let mut cur = start.add(V::BYTES - (start.as_usize() & V::ALIGN)); + debug_assert!(cur > start && end.sub(V::BYTES) >= start); + if len >= Self::LOOP_SIZE { + while cur <= end.sub(Self::LOOP_SIZE) { + debug_assert_eq!(0, cur.as_usize() % V::BYTES); + + let a = V::load_aligned(cur); + let b = V::load_aligned(cur.add(V::BYTES)); + let eqa1 = self.v1.cmpeq(a); + let eqb1 = self.v1.cmpeq(b); + let eqa2 = self.v2.cmpeq(a); + let eqb2 = self.v2.cmpeq(b); + let or1 = eqa1.or(eqb1); + let or2 = eqa2.or(eqb2); + let or3 = or1.or(or2); + if or3.movemask_will_have_non_zero() { + let mask = eqa1.movemask().or(eqa2.movemask()); + if mask.has_non_zero() { + return Some(cur.add(topos(mask))); + } + + let mask = eqb1.movemask().or(eqb2.movemask()); + debug_assert!(mask.has_non_zero()); + return Some(cur.add(V::BYTES).add(topos(mask))); + } + cur = cur.add(Self::LOOP_SIZE); + } + } + // Handle any leftovers after the aligned loop above. We use unaligned + // loads here, but I believe we are guaranteed that they are aligned + // since `cur` is aligned. + while cur <= end.sub(V::BYTES) { + debug_assert!(end.distance(cur) >= V::BYTES); + if let Some(cur) = self.search_chunk(cur, topos) { + return Some(cur); + } + cur = cur.add(V::BYTES); + } + // Finally handle any remaining bytes less than the size of V. In this + // case, our pointer may indeed be unaligned and the load may overlap + // with the previous one. But that's okay since we know the previous + // load didn't lead to a match (otherwise we wouldn't be here). + if cur < end { + debug_assert!(end.distance(cur) < V::BYTES); + cur = cur.sub(V::BYTES - end.distance(cur)); + debug_assert_eq!(end.distance(cur), V::BYTES); + return self.search_chunk(cur, topos); + } + None + } + + /// Return a pointer to the last occurrence of the needle in the given + /// haystack. If no such occurrence exists, then `None` is returned. + /// + /// When a match is found, the pointer returned is guaranteed to be + /// `>= start` and `< end`. + /// + /// # Safety + /// + /// * It must be the case that `start < end` and that the distance between + /// them is at least equal to `V::BYTES`. That is, it must always be valid + /// to do at least an unaligned load of `V` at `start`. + /// * Both `start` and `end` must be valid for reads. + /// * Both `start` and `end` must point to an initialized value. + /// * Both `start` and `end` must point to the same allocated object and + /// must either be in bounds or at most one byte past the end of the + /// allocated object. + /// * Both `start` and `end` must be _derived from_ a pointer to the same + /// object. + /// * The distance between `start` and `end` must not overflow `isize`. + /// * The distance being in bounds must not rely on "wrapping around" the + /// address space. + #[inline(always)] + pub(crate) unsafe fn rfind_raw( + &self, + start: *const u8, + end: *const u8, + ) -> Option<*const u8> { + // If we want to support vectors bigger than 256 bits, we probably + // need to move up to using a u64 for the masks used below. Currently + // they are 32 bits, which means we're SOL for vectors that need masks + // bigger than 32 bits. Overall unclear until there's a use case. + debug_assert!(V::BYTES <= 32, "vector cannot be bigger than 32 bytes"); + + let topos = V::Mask::last_offset; + let len = end.distance(start); + debug_assert!( + len >= V::BYTES, + "haystack has length {}, but must be at least {}", + len, + V::BYTES + ); + + if let Some(cur) = self.search_chunk(end.sub(V::BYTES), topos) { + return Some(cur); + } + let mut cur = end.sub(end.as_usize() & V::ALIGN); + debug_assert!(start <= cur && cur <= end); + if len >= Self::LOOP_SIZE { + while cur >= start.add(Self::LOOP_SIZE) { + debug_assert_eq!(0, cur.as_usize() % V::BYTES); + + cur = cur.sub(Self::LOOP_SIZE); + let a = V::load_aligned(cur); + let b = V::load_aligned(cur.add(V::BYTES)); + let eqa1 = self.v1.cmpeq(a); + let eqb1 = self.v1.cmpeq(b); + let eqa2 = self.v2.cmpeq(a); + let eqb2 = self.v2.cmpeq(b); + let or1 = eqa1.or(eqb1); + let or2 = eqa2.or(eqb2); + let or3 = or1.or(or2); + if or3.movemask_will_have_non_zero() { + let mask = eqb1.movemask().or(eqb2.movemask()); + if mask.has_non_zero() { + return Some(cur.add(V::BYTES).add(topos(mask))); + } + + let mask = eqa1.movemask().or(eqa2.movemask()); + debug_assert!(mask.has_non_zero()); + return Some(cur.add(topos(mask))); + } + } + } + while cur >= start.add(V::BYTES) { + debug_assert!(cur.distance(start) >= V::BYTES); + cur = cur.sub(V::BYTES); + if let Some(cur) = self.search_chunk(cur, topos) { + return Some(cur); + } + } + if cur > start { + debug_assert!(cur.distance(start) < V::BYTES); + return self.search_chunk(start, topos); + } + None + } + + /// Search `V::BYTES` starting at `cur` via an unaligned load. + /// + /// `mask_to_offset` should be a function that converts a `movemask` to + /// an offset such that `cur.add(offset)` corresponds to a pointer to the + /// match location if one is found. Generally it is expected to use either + /// `mask_to_first_offset` or `mask_to_last_offset`, depending on whether + /// one is implementing a forward or reverse search, respectively. + /// + /// # Safety + /// + /// `cur` must be a valid pointer and it must be valid to do an unaligned + /// load of size `V::BYTES` at `cur`. + #[inline(always)] + unsafe fn search_chunk( + &self, + cur: *const u8, + mask_to_offset: impl Fn(V::Mask) -> usize, + ) -> Option<*const u8> { + let chunk = V::load_unaligned(cur); + let eq1 = self.v1.cmpeq(chunk); + let eq2 = self.v2.cmpeq(chunk); + let mask = eq1.or(eq2).movemask(); + if mask.has_non_zero() { + let mask1 = eq1.movemask(); + let mask2 = eq2.movemask(); + Some(cur.add(mask_to_offset(mask1.or(mask2)))) + } else { + None + } + } +} + +/// Finds all occurrences of two bytes in a haystack. +/// +/// That is, this reports matches of one of two possible bytes. For example, +/// searching for `a` or `b` in `afoobar` would report matches at offsets `0`, +/// `4` and `5`. +#[derive(Clone, Copy, Debug)] +pub(crate) struct Three { + s1: u8, + s2: u8, + s3: u8, + v1: V, + v2: V, + v3: V, +} + +impl Three { + /// The number of bytes we examine per each iteration of our search loop. + const LOOP_SIZE: usize = 2 * V::BYTES; + + /// Create a new searcher that finds occurrences of the byte given. + #[inline(always)] + pub(crate) unsafe fn new( + needle1: u8, + needle2: u8, + needle3: u8, + ) -> Three { + Three { + s1: needle1, + s2: needle2, + s3: needle3, + v1: V::splat(needle1), + v2: V::splat(needle2), + v3: V::splat(needle3), + } + } + + /// Returns the first needle given to `Three::new`. + #[inline(always)] + pub(crate) fn needle1(&self) -> u8 { + self.s1 + } + + /// Returns the second needle given to `Three::new`. + #[inline(always)] + pub(crate) fn needle2(&self) -> u8 { + self.s2 + } + + /// Returns the third needle given to `Three::new`. + #[inline(always)] + pub(crate) fn needle3(&self) -> u8 { + self.s3 + } + + /// Return a pointer to the first occurrence of one of the needles in the + /// given haystack. If no such occurrence exists, then `None` is returned. + /// + /// When a match is found, the pointer returned is guaranteed to be + /// `>= start` and `< end`. + /// + /// # Safety + /// + /// * It must be the case that `start < end` and that the distance between + /// them is at least equal to `V::BYTES`. That is, it must always be valid + /// to do at least an unaligned load of `V` at `start`. + /// * Both `start` and `end` must be valid for reads. + /// * Both `start` and `end` must point to an initialized value. + /// * Both `start` and `end` must point to the same allocated object and + /// must either be in bounds or at most one byte past the end of the + /// allocated object. + /// * Both `start` and `end` must be _derived from_ a pointer to the same + /// object. + /// * The distance between `start` and `end` must not overflow `isize`. + /// * The distance being in bounds must not rely on "wrapping around" the + /// address space. + #[inline(always)] + pub(crate) unsafe fn find_raw( + &self, + start: *const u8, + end: *const u8, + ) -> Option<*const u8> { + // If we want to support vectors bigger than 256 bits, we probably + // need to move up to using a u64 for the masks used below. Currently + // they are 32 bits, which means we're SOL for vectors that need masks + // bigger than 32 bits. Overall unclear until there's a use case. + debug_assert!(V::BYTES <= 32, "vector cannot be bigger than 32 bytes"); + + let topos = V::Mask::first_offset; + let len = end.distance(start); + debug_assert!( + len >= V::BYTES, + "haystack has length {}, but must be at least {}", + len, + V::BYTES + ); + + // Search a possibly unaligned chunk at `start`. This covers any part + // of the haystack prior to where aligned loads can start. + if let Some(cur) = self.search_chunk(start, topos) { + return Some(cur); + } + // Set `cur` to the first V-aligned pointer greater than `start`. + let mut cur = start.add(V::BYTES - (start.as_usize() & V::ALIGN)); + debug_assert!(cur > start && end.sub(V::BYTES) >= start); + if len >= Self::LOOP_SIZE { + while cur <= end.sub(Self::LOOP_SIZE) { + debug_assert_eq!(0, cur.as_usize() % V::BYTES); + + let a = V::load_aligned(cur); + let b = V::load_aligned(cur.add(V::BYTES)); + let eqa1 = self.v1.cmpeq(a); + let eqb1 = self.v1.cmpeq(b); + let eqa2 = self.v2.cmpeq(a); + let eqb2 = self.v2.cmpeq(b); + let eqa3 = self.v3.cmpeq(a); + let eqb3 = self.v3.cmpeq(b); + let or1 = eqa1.or(eqb1); + let or2 = eqa2.or(eqb2); + let or3 = eqa3.or(eqb3); + let or4 = or1.or(or2); + let or5 = or3.or(or4); + if or5.movemask_will_have_non_zero() { + let mask = eqa1 + .movemask() + .or(eqa2.movemask()) + .or(eqa3.movemask()); + if mask.has_non_zero() { + return Some(cur.add(topos(mask))); + } + + let mask = eqb1 + .movemask() + .or(eqb2.movemask()) + .or(eqb3.movemask()); + debug_assert!(mask.has_non_zero()); + return Some(cur.add(V::BYTES).add(topos(mask))); + } + cur = cur.add(Self::LOOP_SIZE); + } + } + // Handle any leftovers after the aligned loop above. We use unaligned + // loads here, but I believe we are guaranteed that they are aligned + // since `cur` is aligned. + while cur <= end.sub(V::BYTES) { + debug_assert!(end.distance(cur) >= V::BYTES); + if let Some(cur) = self.search_chunk(cur, topos) { + return Some(cur); + } + cur = cur.add(V::BYTES); + } + // Finally handle any remaining bytes less than the size of V. In this + // case, our pointer may indeed be unaligned and the load may overlap + // with the previous one. But that's okay since we know the previous + // load didn't lead to a match (otherwise we wouldn't be here). + if cur < end { + debug_assert!(end.distance(cur) < V::BYTES); + cur = cur.sub(V::BYTES - end.distance(cur)); + debug_assert_eq!(end.distance(cur), V::BYTES); + return self.search_chunk(cur, topos); + } + None + } + + /// Return a pointer to the last occurrence of the needle in the given + /// haystack. If no such occurrence exists, then `None` is returned. + /// + /// When a match is found, the pointer returned is guaranteed to be + /// `>= start` and `< end`. + /// + /// # Safety + /// + /// * It must be the case that `start < end` and that the distance between + /// them is at least equal to `V::BYTES`. That is, it must always be valid + /// to do at least an unaligned load of `V` at `start`. + /// * Both `start` and `end` must be valid for reads. + /// * Both `start` and `end` must point to an initialized value. + /// * Both `start` and `end` must point to the same allocated object and + /// must either be in bounds or at most one byte past the end of the + /// allocated object. + /// * Both `start` and `end` must be _derived from_ a pointer to the same + /// object. + /// * The distance between `start` and `end` must not overflow `isize`. + /// * The distance being in bounds must not rely on "wrapping around" the + /// address space. + #[inline(always)] + pub(crate) unsafe fn rfind_raw( + &self, + start: *const u8, + end: *const u8, + ) -> Option<*const u8> { + // If we want to support vectors bigger than 256 bits, we probably + // need to move up to using a u64 for the masks used below. Currently + // they are 32 bits, which means we're SOL for vectors that need masks + // bigger than 32 bits. Overall unclear until there's a use case. + debug_assert!(V::BYTES <= 32, "vector cannot be bigger than 32 bytes"); + + let topos = V::Mask::last_offset; + let len = end.distance(start); + debug_assert!( + len >= V::BYTES, + "haystack has length {}, but must be at least {}", + len, + V::BYTES + ); + + if let Some(cur) = self.search_chunk(end.sub(V::BYTES), topos) { + return Some(cur); + } + let mut cur = end.sub(end.as_usize() & V::ALIGN); + debug_assert!(start <= cur && cur <= end); + if len >= Self::LOOP_SIZE { + while cur >= start.add(Self::LOOP_SIZE) { + debug_assert_eq!(0, cur.as_usize() % V::BYTES); + + cur = cur.sub(Self::LOOP_SIZE); + let a = V::load_aligned(cur); + let b = V::load_aligned(cur.add(V::BYTES)); + let eqa1 = self.v1.cmpeq(a); + let eqb1 = self.v1.cmpeq(b); + let eqa2 = self.v2.cmpeq(a); + let eqb2 = self.v2.cmpeq(b); + let eqa3 = self.v3.cmpeq(a); + let eqb3 = self.v3.cmpeq(b); + let or1 = eqa1.or(eqb1); + let or2 = eqa2.or(eqb2); + let or3 = eqa3.or(eqb3); + let or4 = or1.or(or2); + let or5 = or3.or(or4); + if or5.movemask_will_have_non_zero() { + let mask = eqb1 + .movemask() + .or(eqb2.movemask()) + .or(eqb3.movemask()); + if mask.has_non_zero() { + return Some(cur.add(V::BYTES).add(topos(mask))); + } + + let mask = eqa1 + .movemask() + .or(eqa2.movemask()) + .or(eqa3.movemask()); + debug_assert!(mask.has_non_zero()); + return Some(cur.add(topos(mask))); + } + } + } + while cur >= start.add(V::BYTES) { + debug_assert!(cur.distance(start) >= V::BYTES); + cur = cur.sub(V::BYTES); + if let Some(cur) = self.search_chunk(cur, topos) { + return Some(cur); + } + } + if cur > start { + debug_assert!(cur.distance(start) < V::BYTES); + return self.search_chunk(start, topos); + } + None + } + + /// Search `V::BYTES` starting at `cur` via an unaligned load. + /// + /// `mask_to_offset` should be a function that converts a `movemask` to + /// an offset such that `cur.add(offset)` corresponds to a pointer to the + /// match location if one is found. Generally it is expected to use either + /// `mask_to_first_offset` or `mask_to_last_offset`, depending on whether + /// one is implementing a forward or reverse search, respectively. + /// + /// # Safety + /// + /// `cur` must be a valid pointer and it must be valid to do an unaligned + /// load of size `V::BYTES` at `cur`. + #[inline(always)] + unsafe fn search_chunk( + &self, + cur: *const u8, + mask_to_offset: impl Fn(V::Mask) -> usize, + ) -> Option<*const u8> { + let chunk = V::load_unaligned(cur); + let eq1 = self.v1.cmpeq(chunk); + let eq2 = self.v2.cmpeq(chunk); + let eq3 = self.v3.cmpeq(chunk); + let mask = eq1.or(eq2).or(eq3).movemask(); + if mask.has_non_zero() { + let mask1 = eq1.movemask(); + let mask2 = eq2.movemask(); + let mask3 = eq3.movemask(); + Some(cur.add(mask_to_offset(mask1.or(mask2).or(mask3)))) + } else { + None + } + } +} + +/// An iterator over all occurrences of a set of bytes in a haystack. +/// +/// This iterator implements the routines necessary to provide a +/// `DoubleEndedIterator` impl, which means it can also be used to find +/// occurrences in reverse order. +/// +/// The lifetime parameters are as follows: +/// +/// * `'h` refers to the lifetime of the haystack being searched. +/// +/// This type is intended to be used to implement all iterators for the +/// `memchr` family of functions. It handles a tiny bit of marginally tricky +/// raw pointer math, but otherwise expects the caller to provide `find_raw` +/// and `rfind_raw` routines for each call of `next` and `next_back`, +/// respectively. +#[derive(Clone, Debug)] +pub(crate) struct Iter<'h> { + /// The original starting point into the haystack. We use this to convert + /// pointers to offsets. + original_start: *const u8, + /// The current starting point into the haystack. That is, where the next + /// search will begin. + start: *const u8, + /// The current ending point into the haystack. That is, where the next + /// reverse search will begin. + end: *const u8, + /// A marker for tracking the lifetime of the start/cur_start/cur_end + /// pointers above, which all point into the haystack. + haystack: core::marker::PhantomData<&'h [u8]>, +} + +// SAFETY: Iter contains no shared references to anything that performs any +// interior mutations. Also, the lifetime guarantees that Iter will not outlive +// the haystack. +unsafe impl<'h> Send for Iter<'h> {} + +// SAFETY: Iter perform no interior mutations, therefore no explicit +// synchronization is necessary. Also, the lifetime guarantees that Iter will +// not outlive the haystack. +unsafe impl<'h> Sync for Iter<'h> {} + +impl<'h> Iter<'h> { + /// Create a new generic memchr iterator. + #[inline(always)] + pub(crate) fn new(haystack: &'h [u8]) -> Iter<'h> { + Iter { + original_start: haystack.as_ptr(), + start: haystack.as_ptr(), + end: haystack.as_ptr().wrapping_add(haystack.len()), + haystack: core::marker::PhantomData, + } + } + + /// Returns the next occurrence in the forward direction. + /// + /// # Safety + /// + /// Callers must ensure that if a pointer is returned from the closure + /// provided, then it must be greater than or equal to the start pointer + /// and less than the end pointer. + #[inline(always)] + pub(crate) unsafe fn next( + &mut self, + mut find_raw: impl FnMut(*const u8, *const u8) -> Option<*const u8>, + ) -> Option { + // SAFETY: Pointers are derived directly from the same &[u8] haystack. + // We only ever modify start/end corresponding to a matching offset + // found between start and end. Thus all changes to start/end maintain + // our safety requirements. + // + // The only other assumption we rely on is that the pointer returned + // by `find_raw` satisfies `self.start <= found < self.end`, and that + // safety contract is forwarded to the caller. + let found = find_raw(self.start, self.end)?; + let result = found.distance(self.original_start); + self.start = found.add(1); + Some(result) + } + + /// Returns the number of remaining elements in this iterator. + #[inline(always)] + pub(crate) fn count( + self, + mut count_raw: impl FnMut(*const u8, *const u8) -> usize, + ) -> usize { + // SAFETY: Pointers are derived directly from the same &[u8] haystack. + // We only ever modify start/end corresponding to a matching offset + // found between start and end. Thus all changes to start/end maintain + // our safety requirements. + count_raw(self.start, self.end) + } + + /// Returns the next occurrence in reverse. + /// + /// # Safety + /// + /// Callers must ensure that if a pointer is returned from the closure + /// provided, then it must be greater than or equal to the start pointer + /// and less than the end pointer. + #[inline(always)] + pub(crate) unsafe fn next_back( + &mut self, + mut rfind_raw: impl FnMut(*const u8, *const u8) -> Option<*const u8>, + ) -> Option { + // SAFETY: Pointers are derived directly from the same &[u8] haystack. + // We only ever modify start/end corresponding to a matching offset + // found between start and end. Thus all changes to start/end maintain + // our safety requirements. + // + // The only other assumption we rely on is that the pointer returned + // by `rfind_raw` satisfies `self.start <= found < self.end`, and that + // safety contract is forwarded to the caller. + let found = rfind_raw(self.start, self.end)?; + let result = found.distance(self.original_start); + self.end = found; + Some(result) + } + + /// Provides an implementation of `Iterator::size_hint`. + #[inline(always)] + pub(crate) fn size_hint(&self) -> (usize, Option) { + (0, Some(self.end.as_usize().saturating_sub(self.start.as_usize()))) + } +} + +/// Search a slice using a function that operates on raw pointers. +/// +/// Given a function to search a contiguous sequence of memory for the location +/// of a non-empty set of bytes, this will execute that search on a slice of +/// bytes. The pointer returned by the given function will be converted to an +/// offset relative to the starting point of the given slice. That is, if a +/// match is found, the offset returned by this routine is guaranteed to be a +/// valid index into `haystack`. +/// +/// Callers may use this for a forward or reverse search. +/// +/// # Safety +/// +/// Callers must ensure that if a pointer is returned by `find_raw`, then the +/// pointer must be greater than or equal to the starting pointer and less than +/// the end pointer. +#[inline(always)] +pub(crate) unsafe fn search_slice_with_raw( + haystack: &[u8], + mut find_raw: impl FnMut(*const u8, *const u8) -> Option<*const u8>, +) -> Option { + // SAFETY: We rely on `find_raw` to return a correct and valid pointer, but + // otherwise, `start` and `end` are valid due to the guarantees provided by + // a &[u8]. + let start = haystack.as_ptr(); + let end = start.add(haystack.len()); + let found = find_raw(start, end)?; + Some(found.distance(start)) +} + +/// Performs a forward byte-at-a-time loop until either `ptr >= end_ptr` or +/// until `confirm(*ptr)` returns `true`. If the former occurs, then `None` is +/// returned. If the latter occurs, then the pointer at which `confirm` returns +/// `true` is returned. +/// +/// # Safety +/// +/// Callers must provide valid pointers and they must satisfy `start_ptr <= +/// ptr` and `ptr <= end_ptr`. +#[inline(always)] +pub(crate) unsafe fn fwd_byte_by_byte bool>( + start: *const u8, + end: *const u8, + confirm: F, +) -> Option<*const u8> { + debug_assert!(start <= end); + let mut ptr = start; + while ptr < end { + if confirm(*ptr) { + return Some(ptr); + } + ptr = ptr.offset(1); + } + None +} + +/// Performs a reverse byte-at-a-time loop until either `ptr < start_ptr` or +/// until `confirm(*ptr)` returns `true`. If the former occurs, then `None` is +/// returned. If the latter occurs, then the pointer at which `confirm` returns +/// `true` is returned. +/// +/// # Safety +/// +/// Callers must provide valid pointers and they must satisfy `start_ptr <= +/// ptr` and `ptr <= end_ptr`. +#[inline(always)] +pub(crate) unsafe fn rev_byte_by_byte bool>( + start: *const u8, + end: *const u8, + confirm: F, +) -> Option<*const u8> { + debug_assert!(start <= end); + + let mut ptr = end; + while ptr > start { + ptr = ptr.offset(-1); + if confirm(*ptr) { + return Some(ptr); + } + } + None +} + +/// Performs a forward byte-at-a-time loop until `ptr >= end_ptr` and returns +/// the number of times `confirm(*ptr)` returns `true`. +/// +/// # Safety +/// +/// Callers must provide valid pointers and they must satisfy `start_ptr <= +/// ptr` and `ptr <= end_ptr`. +#[inline(always)] +pub(crate) unsafe fn count_byte_by_byte bool>( + start: *const u8, + end: *const u8, + confirm: F, +) -> usize { + debug_assert!(start <= end); + let mut ptr = start; + let mut count = 0; + while ptr < end { + if confirm(*ptr) { + count += 1; + } + ptr = ptr.offset(1); + } + count +} diff --git a/vendor/memchr/src/arch/generic/mod.rs b/vendor/memchr/src/arch/generic/mod.rs new file mode 100644 index 0000000..63ee3f0 --- /dev/null +++ b/vendor/memchr/src/arch/generic/mod.rs @@ -0,0 +1,14 @@ +/*! +This module defines "generic" routines that can be specialized to specific +architectures. + +We don't expose this module primarily because it would require exposing all +of the internal infrastructure required to write these generic routines. +That infrastructure should be treated as an implementation detail so that +it is allowed to evolve. Instead, what we expose are architecture specific +instantiations of these generic implementations. The generic code just lets us +write the code once (usually). +*/ + +pub(crate) mod memchr; +pub(crate) mod packedpair; diff --git a/vendor/memchr/src/arch/generic/packedpair.rs b/vendor/memchr/src/arch/generic/packedpair.rs new file mode 100644 index 0000000..8d97cf2 --- /dev/null +++ b/vendor/memchr/src/arch/generic/packedpair.rs @@ -0,0 +1,317 @@ +/*! +Generic crate-internal routines for the "packed pair" SIMD algorithm. + +The "packed pair" algorithm is based on the [generic SIMD] algorithm. The main +difference is that it (by default) uses a background distribution of byte +frequencies to heuristically select the pair of bytes to search for. + +[generic SIMD]: http://0x80.pl/articles/simd-strfind.html#first-and-last +*/ + +use crate::{ + arch::all::{is_equal_raw, packedpair::Pair}, + ext::Pointer, + vector::{MoveMask, Vector}, +}; + +/// A generic architecture dependent "packed pair" finder. +/// +/// This finder picks two bytes that it believes have high predictive power +/// for indicating an overall match of a needle. Depending on whether +/// `Finder::find` or `Finder::find_prefilter` is used, it reports offsets +/// where the needle matches or could match. In the prefilter case, candidates +/// are reported whenever the [`Pair`] of bytes given matches. +/// +/// This is architecture dependent because it uses specific vector operations +/// to look for occurrences of the pair of bytes. +/// +/// This type is not meant to be exported and is instead meant to be used as +/// the implementation for architecture specific facades. Why? Because it's a +/// bit of a quirky API that requires `inline(always)` annotations. And pretty +/// much everything has safety obligations due (at least) to the caller needing +/// to inline calls into routines marked with +/// `#[target_feature(enable = "...")]`. +#[derive(Clone, Copy, Debug)] +pub(crate) struct Finder { + pair: Pair, + v1: V, + v2: V, + min_haystack_len: usize, +} + +impl Finder { + /// Create a new pair searcher. The searcher returned can either report + /// exact matches of `needle` or act as a prefilter and report candidate + /// positions of `needle`. + /// + /// # Safety + /// + /// Callers must ensure that whatever vector type this routine is called + /// with is supported by the current environment. + /// + /// Callers must also ensure that `needle.len() >= 2`. + #[inline(always)] + pub(crate) unsafe fn new(needle: &[u8], pair: Pair) -> Finder { + let max_index = pair.index1().max(pair.index2()); + let min_haystack_len = + core::cmp::max(needle.len(), usize::from(max_index) + V::BYTES); + let v1 = V::splat(needle[usize::from(pair.index1())]); + let v2 = V::splat(needle[usize::from(pair.index2())]); + Finder { pair, v1, v2, min_haystack_len } + } + + /// Searches the given haystack for the given needle. The needle given + /// should be the same as the needle that this finder was initialized + /// with. + /// + /// # Panics + /// + /// When `haystack.len()` is less than [`Finder::min_haystack_len`]. + /// + /// # Safety + /// + /// Since this is meant to be used with vector functions, callers need to + /// specialize this inside of a function with a `target_feature` attribute. + /// Therefore, callers must ensure that whatever target feature is being + /// used supports the vector functions that this function is specialized + /// for. (For the specific vector functions used, see the Vector trait + /// implementations.) + #[inline(always)] + pub(crate) unsafe fn find( + &self, + haystack: &[u8], + needle: &[u8], + ) -> Option { + assert!( + haystack.len() >= self.min_haystack_len, + "haystack too small, should be at least {} but got {}", + self.min_haystack_len, + haystack.len(), + ); + + let all = V::Mask::all_zeros_except_least_significant(0); + let start = haystack.as_ptr(); + let end = start.add(haystack.len()); + let max = end.sub(self.min_haystack_len); + let mut cur = start; + + // N.B. I did experiment with unrolling the loop to deal with size(V) + // bytes at a time and 2*size(V) bytes at a time. The double unroll + // was marginally faster while the quadruple unroll was unambiguously + // slower. In the end, I decided the complexity from unrolling wasn't + // worth it. I used the memmem/krate/prebuilt/huge-en/ benchmarks to + // compare. + while cur <= max { + if let Some(chunki) = self.find_in_chunk(needle, cur, end, all) { + return Some(matched(start, cur, chunki)); + } + cur = cur.add(V::BYTES); + } + if cur < end { + let remaining = end.distance(cur); + debug_assert!( + remaining < self.min_haystack_len, + "remaining bytes should be smaller than the minimum haystack \ + length of {}, but there are {} bytes remaining", + self.min_haystack_len, + remaining, + ); + if remaining < needle.len() { + return None; + } + debug_assert!( + max < cur, + "after main loop, cur should have exceeded max", + ); + let overlap = cur.distance(max); + debug_assert!( + overlap > 0, + "overlap ({}) must always be non-zero", + overlap, + ); + debug_assert!( + overlap < V::BYTES, + "overlap ({}) cannot possibly be >= than a vector ({})", + overlap, + V::BYTES, + ); + // The mask has all of its bits set except for the first N least + // significant bits, where N=overlap. This way, any matches that + // occur in find_in_chunk within the overlap are automatically + // ignored. + let mask = V::Mask::all_zeros_except_least_significant(overlap); + cur = max; + let m = self.find_in_chunk(needle, cur, end, mask); + if let Some(chunki) = m { + return Some(matched(start, cur, chunki)); + } + } + None + } + + /// Searches the given haystack for offsets that represent candidate + /// matches of the `needle` given to this finder's constructor. The offsets + /// returned, if they are a match, correspond to the starting offset of + /// `needle` in the given `haystack`. + /// + /// # Panics + /// + /// When `haystack.len()` is less than [`Finder::min_haystack_len`]. + /// + /// # Safety + /// + /// Since this is meant to be used with vector functions, callers need to + /// specialize this inside of a function with a `target_feature` attribute. + /// Therefore, callers must ensure that whatever target feature is being + /// used supports the vector functions that this function is specialized + /// for. (For the specific vector functions used, see the Vector trait + /// implementations.) + #[inline(always)] + pub(crate) unsafe fn find_prefilter( + &self, + haystack: &[u8], + ) -> Option { + assert!( + haystack.len() >= self.min_haystack_len, + "haystack too small, should be at least {} but got {}", + self.min_haystack_len, + haystack.len(), + ); + + let start = haystack.as_ptr(); + let end = start.add(haystack.len()); + let max = end.sub(self.min_haystack_len); + let mut cur = start; + + // N.B. I did experiment with unrolling the loop to deal with size(V) + // bytes at a time and 2*size(V) bytes at a time. The double unroll + // was marginally faster while the quadruple unroll was unambiguously + // slower. In the end, I decided the complexity from unrolling wasn't + // worth it. I used the memmem/krate/prebuilt/huge-en/ benchmarks to + // compare. + while cur <= max { + if let Some(chunki) = self.find_prefilter_in_chunk(cur) { + return Some(matched(start, cur, chunki)); + } + cur = cur.add(V::BYTES); + } + if cur < end { + // This routine immediately quits if a candidate match is found. + // That means that if we're here, no candidate matches have been + // found at or before 'ptr'. Thus, we don't need to mask anything + // out even though we might technically search part of the haystack + // that we've already searched (because we know it can't match). + cur = max; + if let Some(chunki) = self.find_prefilter_in_chunk(cur) { + return Some(matched(start, cur, chunki)); + } + } + None + } + + /// Search for an occurrence of our byte pair from the needle in the chunk + /// pointed to by cur, with the end of the haystack pointed to by end. + /// When an occurrence is found, memcmp is run to check if a match occurs + /// at the corresponding position. + /// + /// `mask` should have bits set corresponding the positions in the chunk + /// in which matches are considered. This is only used for the last vector + /// load where the beginning of the vector might have overlapped with the + /// last load in the main loop. The mask lets us avoid visiting positions + /// that have already been discarded as matches. + /// + /// # Safety + /// + /// It must be safe to do an unaligned read of size(V) bytes starting at + /// both (cur + self.index1) and (cur + self.index2). It must also be safe + /// to do unaligned loads on cur up to (end - needle.len()). + #[inline(always)] + unsafe fn find_in_chunk( + &self, + needle: &[u8], + cur: *const u8, + end: *const u8, + mask: V::Mask, + ) -> Option { + let index1 = usize::from(self.pair.index1()); + let index2 = usize::from(self.pair.index2()); + let chunk1 = V::load_unaligned(cur.add(index1)); + let chunk2 = V::load_unaligned(cur.add(index2)); + let eq1 = chunk1.cmpeq(self.v1); + let eq2 = chunk2.cmpeq(self.v2); + + let mut offsets = eq1.and(eq2).movemask().and(mask); + while offsets.has_non_zero() { + let offset = offsets.first_offset(); + let cur = cur.add(offset); + if end.sub(needle.len()) < cur { + return None; + } + if is_equal_raw(needle.as_ptr(), cur, needle.len()) { + return Some(offset); + } + offsets = offsets.clear_least_significant_bit(); + } + None + } + + /// Search for an occurrence of our byte pair from the needle in the chunk + /// pointed to by cur, with the end of the haystack pointed to by end. + /// When an occurrence is found, memcmp is run to check if a match occurs + /// at the corresponding position. + /// + /// # Safety + /// + /// It must be safe to do an unaligned read of size(V) bytes starting at + /// both (cur + self.index1) and (cur + self.index2). It must also be safe + /// to do unaligned reads on cur up to (end - needle.len()). + #[inline(always)] + unsafe fn find_prefilter_in_chunk(&self, cur: *const u8) -> Option { + let index1 = usize::from(self.pair.index1()); + let index2 = usize::from(self.pair.index2()); + let chunk1 = V::load_unaligned(cur.add(index1)); + let chunk2 = V::load_unaligned(cur.add(index2)); + let eq1 = chunk1.cmpeq(self.v1); + let eq2 = chunk2.cmpeq(self.v2); + + let offsets = eq1.and(eq2).movemask(); + if !offsets.has_non_zero() { + return None; + } + Some(offsets.first_offset()) + } + + /// Returns the pair of offsets (into the needle) used to check as a + /// predicate before confirming whether a needle exists at a particular + /// position. + #[inline] + pub(crate) fn pair(&self) -> &Pair { + &self.pair + } + + /// Returns the minimum haystack length that this `Finder` can search. + /// + /// Providing a haystack to this `Finder` shorter than this length is + /// guaranteed to result in a panic. + #[inline(always)] + pub(crate) fn min_haystack_len(&self) -> usize { + self.min_haystack_len + } +} + +/// Accepts a chunk-relative offset and returns a haystack relative offset. +/// +/// This used to be marked `#[cold]` and `#[inline(never)]`, but I couldn't +/// observe a consistent measureable difference between that and just inlining +/// it. So we go with inlining it. +/// +/// # Safety +/// +/// Same at `ptr::offset_from` in addition to `cur >= start`. +#[inline(always)] +unsafe fn matched(start: *const u8, cur: *const u8, chunki: usize) -> usize { + cur.distance(start) + chunki +} + +// If you're looking for tests, those are run for each instantiation of the +// above code. So for example, see arch::x86_64::sse2::packedpair. diff --git a/vendor/memchr/src/arch/mod.rs b/vendor/memchr/src/arch/mod.rs new file mode 100644 index 0000000..10332b6 --- /dev/null +++ b/vendor/memchr/src/arch/mod.rs @@ -0,0 +1,16 @@ +/*! +A module with low-level architecture dependent routines. + +These routines are useful as primitives for tasks not covered by the higher +level crate API. +*/ + +pub mod all; +pub(crate) mod generic; + +#[cfg(target_arch = "aarch64")] +pub mod aarch64; +#[cfg(all(target_arch = "wasm32", target_feature = "simd128"))] +pub mod wasm32; +#[cfg(target_arch = "x86_64")] +pub mod x86_64; diff --git a/vendor/memchr/src/arch/wasm32/memchr.rs b/vendor/memchr/src/arch/wasm32/memchr.rs new file mode 100644 index 0000000..55c1c1b --- /dev/null +++ b/vendor/memchr/src/arch/wasm32/memchr.rs @@ -0,0 +1,124 @@ +/*! +Wrapper routines for `memchr` and friends. + +These routines choose the best implementation at compile time. (This is +different from `x86_64` because it is expected that `simd128` is almost always +available for `wasm32` targets.) +*/ + +macro_rules! defraw { + ($ty:ident, $find:ident, $start:ident, $end:ident, $($needles:ident),+) => {{ + use crate::arch::wasm32::simd128::memchr::$ty; + + debug!("chose simd128 for {}", stringify!($ty)); + debug_assert!($ty::is_available()); + // SAFETY: We know that wasm memchr is always available whenever + // code is compiled for `wasm32` with the `simd128` target feature + // enabled. + $ty::new_unchecked($($needles),+).$find($start, $end) + }} +} + +/// memchr, but using raw pointers to represent the haystack. +/// +/// # Safety +/// +/// Pointers must be valid. See `One::find_raw`. +#[inline(always)] +pub(crate) unsafe fn memchr_raw( + n1: u8, + start: *const u8, + end: *const u8, +) -> Option<*const u8> { + defraw!(One, find_raw, start, end, n1) +} + +/// memrchr, but using raw pointers to represent the haystack. +/// +/// # Safety +/// +/// Pointers must be valid. See `One::rfind_raw`. +#[inline(always)] +pub(crate) unsafe fn memrchr_raw( + n1: u8, + start: *const u8, + end: *const u8, +) -> Option<*const u8> { + defraw!(One, rfind_raw, start, end, n1) +} + +/// memchr2, but using raw pointers to represent the haystack. +/// +/// # Safety +/// +/// Pointers must be valid. See `Two::find_raw`. +#[inline(always)] +pub(crate) unsafe fn memchr2_raw( + n1: u8, + n2: u8, + start: *const u8, + end: *const u8, +) -> Option<*const u8> { + defraw!(Two, find_raw, start, end, n1, n2) +} + +/// memrchr2, but using raw pointers to represent the haystack. +/// +/// # Safety +/// +/// Pointers must be valid. See `Two::rfind_raw`. +#[inline(always)] +pub(crate) unsafe fn memrchr2_raw( + n1: u8, + n2: u8, + start: *const u8, + end: *const u8, +) -> Option<*const u8> { + defraw!(Two, rfind_raw, start, end, n1, n2) +} + +/// memchr3, but using raw pointers to represent the haystack. +/// +/// # Safety +/// +/// Pointers must be valid. See `Three::find_raw`. +#[inline(always)] +pub(crate) unsafe fn memchr3_raw( + n1: u8, + n2: u8, + n3: u8, + start: *const u8, + end: *const u8, +) -> Option<*const u8> { + defraw!(Three, find_raw, start, end, n1, n2, n3) +} + +/// memrchr3, but using raw pointers to represent the haystack. +/// +/// # Safety +/// +/// Pointers must be valid. See `Three::rfind_raw`. +#[inline(always)] +pub(crate) unsafe fn memrchr3_raw( + n1: u8, + n2: u8, + n3: u8, + start: *const u8, + end: *const u8, +) -> Option<*const u8> { + defraw!(Three, rfind_raw, start, end, n1, n2, n3) +} + +/// Count all matching bytes, but using raw pointers to represent the haystack. +/// +/// # Safety +/// +/// Pointers must be valid. See `One::count_raw`. +#[inline(always)] +pub(crate) unsafe fn count_raw( + n1: u8, + start: *const u8, + end: *const u8, +) -> usize { + defraw!(One, count_raw, start, end, n1) +} diff --git a/vendor/memchr/src/arch/wasm32/mod.rs b/vendor/memchr/src/arch/wasm32/mod.rs new file mode 100644 index 0000000..209f876 --- /dev/null +++ b/vendor/memchr/src/arch/wasm32/mod.rs @@ -0,0 +1,7 @@ +/*! +Vector algorithms for the `wasm32` target. +*/ + +pub mod simd128; + +pub(crate) mod memchr; diff --git a/vendor/memchr/src/arch/wasm32/simd128/memchr.rs b/vendor/memchr/src/arch/wasm32/simd128/memchr.rs new file mode 100644 index 0000000..fa314c9 --- /dev/null +++ b/vendor/memchr/src/arch/wasm32/simd128/memchr.rs @@ -0,0 +1,1020 @@ +/*! +This module defines 128-bit vector implementations of `memchr` and friends. + +The main types in this module are [`One`], [`Two`] and [`Three`]. They are for +searching for one, two or three distinct bytes, respectively, in a haystack. +Each type also has corresponding double ended iterators. These searchers are +typically much faster than scalar routines accomplishing the same task. + +The `One` searcher also provides a [`One::count`] routine for efficiently +counting the number of times a single byte occurs in a haystack. This is +useful, for example, for counting the number of lines in a haystack. This +routine exists because it is usually faster, especially with a high match +count, then using [`One::find`] repeatedly. ([`OneIter`] specializes its +`Iterator::count` implementation to use this routine.) + +Only one, two and three bytes are supported because three bytes is about +the point where one sees diminishing returns. Beyond this point and it's +probably (but not necessarily) better to just use a simple `[bool; 256]` array +or similar. However, it depends mightily on the specific work-load and the +expected match frequency. +*/ + +use core::arch::wasm32::v128; + +use crate::{arch::generic::memchr as generic, ext::Pointer, vector::Vector}; + +/// Finds all occurrences of a single byte in a haystack. +#[derive(Clone, Copy, Debug)] +pub struct One(generic::One); + +impl One { + /// Create a new searcher that finds occurrences of the needle byte given. + /// + /// This particular searcher is specialized to use simd128 vector + /// instructions that typically make it quite fast. + /// + /// If simd128 is unavailable in the current environment, then `None` is + /// returned. + #[inline] + pub fn new(needle: u8) -> Option { + if One::is_available() { + // SAFETY: we check that simd128 is available above. + unsafe { Some(One::new_unchecked(needle)) } + } else { + None + } + } + + /// Create a new finder specific to simd128 vectors and routines without + /// checking that simd128 is available. + /// + /// # Safety + /// + /// Callers must guarantee that it is safe to execute `simd128` + /// instructions in the current environment. + #[target_feature(enable = "simd128")] + #[inline] + pub unsafe fn new_unchecked(needle: u8) -> One { + One(generic::One::new(needle)) + } + + /// Returns true when this implementation is available in the current + /// environment. + /// + /// When this is true, it is guaranteed that [`One::new`] will return + /// a `Some` value. Similarly, when it is false, it is guaranteed that + /// `One::new` will return a `None` value. + /// + /// Note also that for the lifetime of a single program, if this returns + /// true then it will always return true. + #[inline] + pub fn is_available() -> bool { + #[cfg(target_feature = "simd128")] + { + true + } + #[cfg(not(target_feature = "simd128"))] + { + false + } + } + + /// Return the first occurrence of one of the needle bytes in the given + /// haystack. If no such occurrence exists, then `None` is returned. + /// + /// The occurrence is reported as an offset into `haystack`. Its maximum + /// value is `haystack.len() - 1`. + #[inline] + pub fn find(&self, haystack: &[u8]) -> Option { + // SAFETY: `find_raw` guarantees that if a pointer is returned, it + // falls within the bounds of the start and end pointers. + unsafe { + generic::search_slice_with_raw(haystack, |s, e| { + self.find_raw(s, e) + }) + } + } + + /// Return the last occurrence of one of the needle bytes in the given + /// haystack. If no such occurrence exists, then `None` is returned. + /// + /// The occurrence is reported as an offset into `haystack`. Its maximum + /// value is `haystack.len() - 1`. + #[inline] + pub fn rfind(&self, haystack: &[u8]) -> Option { + // SAFETY: `rfind_raw` guarantees that if a pointer is returned, it + // falls within the bounds of the start and end pointers. + unsafe { + generic::search_slice_with_raw(haystack, |s, e| { + self.rfind_raw(s, e) + }) + } + } + + /// Counts all occurrences of this byte in the given haystack. + #[inline] + pub fn count(&self, haystack: &[u8]) -> usize { + // SAFETY: All of our pointers are derived directly from a borrowed + // slice, which is guaranteed to be valid. + unsafe { + let start = haystack.as_ptr(); + let end = start.add(haystack.len()); + self.count_raw(start, end) + } + } + + /// Like `find`, but accepts and returns raw pointers. + /// + /// When a match is found, the pointer returned is guaranteed to be + /// `>= start` and `< end`. + /// + /// This routine is useful if you're already using raw pointers and would + /// like to avoid converting back to a slice before executing a search. + /// + /// # Safety + /// + /// * Both `start` and `end` must be valid for reads. + /// * Both `start` and `end` must point to an initialized value. + /// * Both `start` and `end` must point to the same allocated object and + /// must either be in bounds or at most one byte past the end of the + /// allocated object. + /// * Both `start` and `end` must be _derived from_ a pointer to the same + /// object. + /// * The distance between `start` and `end` must not overflow `isize`. + /// * The distance being in bounds must not rely on "wrapping around" the + /// address space. + /// + /// Note that callers may pass a pair of pointers such that `start >= end`. + /// In that case, `None` will always be returned. + #[inline] + pub unsafe fn find_raw( + &self, + start: *const u8, + end: *const u8, + ) -> Option<*const u8> { + if start >= end { + return None; + } + if end.distance(start) < v128::BYTES { + // SAFETY: We require the caller to pass valid start/end pointers. + return generic::fwd_byte_by_byte(start, end, |b| { + b == self.0.needle1() + }); + } + // SAFETY: Building a `One` means it's safe to call 'simd128' routines. + // Also, we've checked that our haystack is big enough to run on the + // vector routine. Pointer validity is caller's responsibility. + self.find_raw_impl(start, end) + } + + /// Like `rfind`, but accepts and returns raw pointers. + /// + /// When a match is found, the pointer returned is guaranteed to be + /// `>= start` and `< end`. + /// + /// This routine is useful if you're already using raw pointers and would + /// like to avoid converting back to a slice before executing a search. + /// + /// # Safety + /// + /// * Both `start` and `end` must be valid for reads. + /// * Both `start` and `end` must point to an initialized value. + /// * Both `start` and `end` must point to the same allocated object and + /// must either be in bounds or at most one byte past the end of the + /// allocated object. + /// * Both `start` and `end` must be _derived from_ a pointer to the same + /// object. + /// * The distance between `start` and `end` must not overflow `isize`. + /// * The distance being in bounds must not rely on "wrapping around" the + /// address space. + /// + /// Note that callers may pass a pair of pointers such that `start >= end`. + /// In that case, `None` will always be returned. + #[inline] + pub unsafe fn rfind_raw( + &self, + start: *const u8, + end: *const u8, + ) -> Option<*const u8> { + if start >= end { + return None; + } + if end.distance(start) < v128::BYTES { + // SAFETY: We require the caller to pass valid start/end pointers. + return generic::rev_byte_by_byte(start, end, |b| { + b == self.0.needle1() + }); + } + // SAFETY: Building a `One` means it's safe to call 'simd128' routines. + // Also, we've checked that our haystack is big enough to run on the + // vector routine. Pointer validity is caller's responsibility. + self.rfind_raw_impl(start, end) + } + + /// Counts all occurrences of this byte in the given haystack represented + /// by raw pointers. + /// + /// When a match is found, the pointer returned is guaranteed to be + /// `>= start` and `< end`. + /// + /// This routine is useful if you're already using raw pointers and would + /// like to avoid converting back to a slice before executing a search. + /// + /// # Safety + /// + /// * Both `start` and `end` must be valid for reads. + /// * Both `start` and `end` must point to an initialized value. + /// * Both `start` and `end` must point to the same allocated object and + /// must either be in bounds or at most one byte past the end of the + /// allocated object. + /// * Both `start` and `end` must be _derived from_ a pointer to the same + /// object. + /// * The distance between `start` and `end` must not overflow `isize`. + /// * The distance being in bounds must not rely on "wrapping around" the + /// address space. + /// + /// Note that callers may pass a pair of pointers such that `start >= end`. + /// In that case, `None` will always be returned. + #[inline] + pub unsafe fn count_raw(&self, start: *const u8, end: *const u8) -> usize { + if start >= end { + return 0; + } + if end.distance(start) < v128::BYTES { + // SAFETY: We require the caller to pass valid start/end pointers. + return generic::count_byte_by_byte(start, end, |b| { + b == self.0.needle1() + }); + } + // SAFETY: Building a `One` means it's safe to call 'simd128' routines. + // Also, we've checked that our haystack is big enough to run on the + // vector routine. Pointer validity is caller's responsibility. + self.count_raw_impl(start, end) + } + + /// Execute a search using simd128 vectors and routines. + /// + /// # Safety + /// + /// Same as [`One::find_raw`], except the distance between `start` and + /// `end` must be at least the size of a simd128 vector (in bytes). + /// + /// (The target feature safety obligation is automatically fulfilled by + /// virtue of being a method on `One`, which can only be constructed + /// when it is safe to call `simd128` routines.) + #[target_feature(enable = "simd128")] + #[inline] + unsafe fn find_raw_impl( + &self, + start: *const u8, + end: *const u8, + ) -> Option<*const u8> { + self.0.find_raw(start, end) + } + + /// Execute a search using simd128 vectors and routines. + /// + /// # Safety + /// + /// Same as [`One::rfind_raw`], except the distance between `start` and + /// `end` must be at least the size of a simd128 vector (in bytes). + /// + /// (The target feature safety obligation is automatically fulfilled by + /// virtue of being a method on `One`, which can only be constructed + /// when it is safe to call `simd128` routines.) + #[target_feature(enable = "simd128")] + #[inline] + unsafe fn rfind_raw_impl( + &self, + start: *const u8, + end: *const u8, + ) -> Option<*const u8> { + self.0.rfind_raw(start, end) + } + + /// Execute a count using simd128 vectors and routines. + /// + /// # Safety + /// + /// Same as [`One::count_raw`], except the distance between `start` and + /// `end` must be at least the size of a simd128 vector (in bytes). + /// + /// (The target feature safety obligation is automatically fulfilled by + /// virtue of being a method on `One`, which can only be constructed + /// when it is safe to call `simd128` routines.) + #[target_feature(enable = "simd128")] + #[inline] + unsafe fn count_raw_impl( + &self, + start: *const u8, + end: *const u8, + ) -> usize { + self.0.count_raw(start, end) + } + + /// Returns an iterator over all occurrences of the needle byte in the + /// given haystack. + /// + /// The iterator returned implements `DoubleEndedIterator`. This means it + /// can also be used to find occurrences in reverse order. + #[inline] + pub fn iter<'a, 'h>(&'a self, haystack: &'h [u8]) -> OneIter<'a, 'h> { + OneIter { searcher: self, it: generic::Iter::new(haystack) } + } +} + +/// An iterator over all occurrences of a single byte in a haystack. +/// +/// This iterator implements `DoubleEndedIterator`, which means it can also be +/// used to find occurrences in reverse order. +/// +/// This iterator is created by the [`One::iter`] method. +/// +/// The lifetime parameters are as follows: +/// +/// * `'a` refers to the lifetime of the underlying [`One`] searcher. +/// * `'h` refers to the lifetime of the haystack being searched. +#[derive(Clone, Debug)] +pub struct OneIter<'a, 'h> { + searcher: &'a One, + it: generic::Iter<'h>, +} + +impl<'a, 'h> Iterator for OneIter<'a, 'h> { + type Item = usize; + + #[inline] + fn next(&mut self) -> Option { + // SAFETY: We rely on the generic iterator to provide valid start + // and end pointers, but we guarantee that any pointer returned by + // 'find_raw' falls within the bounds of the start and end pointer. + unsafe { self.it.next(|s, e| self.searcher.find_raw(s, e)) } + } + + #[inline] + fn count(self) -> usize { + self.it.count(|s, e| { + // SAFETY: We rely on our generic iterator to return valid start + // and end pointers. + unsafe { self.searcher.count_raw(s, e) } + }) + } + + #[inline] + fn size_hint(&self) -> (usize, Option) { + self.it.size_hint() + } +} + +impl<'a, 'h> DoubleEndedIterator for OneIter<'a, 'h> { + #[inline] + fn next_back(&mut self) -> Option { + // SAFETY: We rely on the generic iterator to provide valid start + // and end pointers, but we guarantee that any pointer returned by + // 'rfind_raw' falls within the bounds of the start and end pointer. + unsafe { self.it.next_back(|s, e| self.searcher.rfind_raw(s, e)) } + } +} + +impl<'a, 'h> core::iter::FusedIterator for OneIter<'a, 'h> {} + +/// Finds all occurrences of two bytes in a haystack. +/// +/// That is, this reports matches of one of two possible bytes. For example, +/// searching for `a` or `b` in `afoobar` would report matches at offsets `0`, +/// `4` and `5`. +#[derive(Clone, Copy, Debug)] +pub struct Two(generic::Two); + +impl Two { + /// Create a new searcher that finds occurrences of the needle bytes given. + /// + /// This particular searcher is specialized to use simd128 vector + /// instructions that typically make it quite fast. + /// + /// If simd128 is unavailable in the current environment, then `None` is + /// returned. + #[inline] + pub fn new(needle1: u8, needle2: u8) -> Option { + if Two::is_available() { + // SAFETY: we check that simd128 is available above. + unsafe { Some(Two::new_unchecked(needle1, needle2)) } + } else { + None + } + } + + /// Create a new finder specific to simd128 vectors and routines without + /// checking that simd128 is available. + /// + /// # Safety + /// + /// Callers must guarantee that it is safe to execute `simd128` + /// instructions in the current environment. + #[target_feature(enable = "simd128")] + #[inline] + pub unsafe fn new_unchecked(needle1: u8, needle2: u8) -> Two { + Two(generic::Two::new(needle1, needle2)) + } + + /// Returns true when this implementation is available in the current + /// environment. + /// + /// When this is true, it is guaranteed that [`Two::new`] will return + /// a `Some` value. Similarly, when it is false, it is guaranteed that + /// `Two::new` will return a `None` value. + /// + /// Note also that for the lifetime of a single program, if this returns + /// true then it will always return true. + #[inline] + pub fn is_available() -> bool { + #[cfg(target_feature = "simd128")] + { + true + } + #[cfg(not(target_feature = "simd128"))] + { + false + } + } + + /// Return the first occurrence of one of the needle bytes in the given + /// haystack. If no such occurrence exists, then `None` is returned. + /// + /// The occurrence is reported as an offset into `haystack`. Its maximum + /// value is `haystack.len() - 1`. + #[inline] + pub fn find(&self, haystack: &[u8]) -> Option { + // SAFETY: `find_raw` guarantees that if a pointer is returned, it + // falls within the bounds of the start and end pointers. + unsafe { + generic::search_slice_with_raw(haystack, |s, e| { + self.find_raw(s, e) + }) + } + } + + /// Return the last occurrence of one of the needle bytes in the given + /// haystack. If no such occurrence exists, then `None` is returned. + /// + /// The occurrence is reported as an offset into `haystack`. Its maximum + /// value is `haystack.len() - 1`. + #[inline] + pub fn rfind(&self, haystack: &[u8]) -> Option { + // SAFETY: `rfind_raw` guarantees that if a pointer is returned, it + // falls within the bounds of the start and end pointers. + unsafe { + generic::search_slice_with_raw(haystack, |s, e| { + self.rfind_raw(s, e) + }) + } + } + + /// Like `find`, but accepts and returns raw pointers. + /// + /// When a match is found, the pointer returned is guaranteed to be + /// `>= start` and `< end`. + /// + /// This routine is useful if you're already using raw pointers and would + /// like to avoid converting back to a slice before executing a search. + /// + /// # Safety + /// + /// * Both `start` and `end` must be valid for reads. + /// * Both `start` and `end` must point to an initialized value. + /// * Both `start` and `end` must point to the same allocated object and + /// must either be in bounds or at most one byte past the end of the + /// allocated object. + /// * Both `start` and `end` must be _derived from_ a pointer to the same + /// object. + /// * The distance between `start` and `end` must not overflow `isize`. + /// * The distance being in bounds must not rely on "wrapping around" the + /// address space. + /// + /// Note that callers may pass a pair of pointers such that `start >= end`. + /// In that case, `None` will always be returned. + #[inline] + pub unsafe fn find_raw( + &self, + start: *const u8, + end: *const u8, + ) -> Option<*const u8> { + if start >= end { + return None; + } + if end.distance(start) < v128::BYTES { + // SAFETY: We require the caller to pass valid start/end pointers. + return generic::fwd_byte_by_byte(start, end, |b| { + b == self.0.needle1() || b == self.0.needle2() + }); + } + // SAFETY: Building a `Two` means it's safe to call 'simd128' routines. + // Also, we've checked that our haystack is big enough to run on the + // vector routine. Pointer validity is caller's responsibility. + self.find_raw_impl(start, end) + } + + /// Like `rfind`, but accepts and returns raw pointers. + /// + /// When a match is found, the pointer returned is guaranteed to be + /// `>= start` and `< end`. + /// + /// This routine is useful if you're already using raw pointers and would + /// like to avoid converting back to a slice before executing a search. + /// + /// # Safety + /// + /// * Both `start` and `end` must be valid for reads. + /// * Both `start` and `end` must point to an initialized value. + /// * Both `start` and `end` must point to the same allocated object and + /// must either be in bounds or at most one byte past the end of the + /// allocated object. + /// * Both `start` and `end` must be _derived from_ a pointer to the same + /// object. + /// * The distance between `start` and `end` must not overflow `isize`. + /// * The distance being in bounds must not rely on "wrapping around" the + /// address space. + /// + /// Note that callers may pass a pair of pointers such that `start >= end`. + /// In that case, `None` will always be returned. + #[inline] + pub unsafe fn rfind_raw( + &self, + start: *const u8, + end: *const u8, + ) -> Option<*const u8> { + if start >= end { + return None; + } + if end.distance(start) < v128::BYTES { + // SAFETY: We require the caller to pass valid start/end pointers. + return generic::rev_byte_by_byte(start, end, |b| { + b == self.0.needle1() || b == self.0.needle2() + }); + } + // SAFETY: Building a `Two` means it's safe to call 'simd128' routines. + // Also, we've checked that our haystack is big enough to run on the + // vector routine. Pointer validity is caller's responsibility. + self.rfind_raw_impl(start, end) + } + + /// Execute a search using simd128 vectors and routines. + /// + /// # Safety + /// + /// Same as [`Two::find_raw`], except the distance between `start` and + /// `end` must be at least the size of a simd128 vector (in bytes). + /// + /// (The target feature safety obligation is automatically fulfilled by + /// virtue of being a method on `Two`, which can only be constructed + /// when it is safe to call `simd128` routines.) + #[target_feature(enable = "simd128")] + #[inline] + unsafe fn find_raw_impl( + &self, + start: *const u8, + end: *const u8, + ) -> Option<*const u8> { + self.0.find_raw(start, end) + } + + /// Execute a search using simd128 vectors and routines. + /// + /// # Safety + /// + /// Same as [`Two::rfind_raw`], except the distance between `start` and + /// `end` must be at least the size of a simd128 vector (in bytes). + /// + /// (The target feature safety obligation is automatically fulfilled by + /// virtue of being a method on `Two`, which can only be constructed + /// when it is safe to call `simd128` routines.) + #[target_feature(enable = "simd128")] + #[inline] + unsafe fn rfind_raw_impl( + &self, + start: *const u8, + end: *const u8, + ) -> Option<*const u8> { + self.0.rfind_raw(start, end) + } + + /// Returns an iterator over all occurrences of the needle bytes in the + /// given haystack. + /// + /// The iterator returned implements `DoubleEndedIterator`. This means it + /// can also be used to find occurrences in reverse order. + #[inline] + pub fn iter<'a, 'h>(&'a self, haystack: &'h [u8]) -> TwoIter<'a, 'h> { + TwoIter { searcher: self, it: generic::Iter::new(haystack) } + } +} + +/// An iterator over all occurrences of two possible bytes in a haystack. +/// +/// This iterator implements `DoubleEndedIterator`, which means it can also be +/// used to find occurrences in reverse order. +/// +/// This iterator is created by the [`Two::iter`] method. +/// +/// The lifetime parameters are as follows: +/// +/// * `'a` refers to the lifetime of the underlying [`Two`] searcher. +/// * `'h` refers to the lifetime of the haystack being searched. +#[derive(Clone, Debug)] +pub struct TwoIter<'a, 'h> { + searcher: &'a Two, + it: generic::Iter<'h>, +} + +impl<'a, 'h> Iterator for TwoIter<'a, 'h> { + type Item = usize; + + #[inline] + fn next(&mut self) -> Option { + // SAFETY: We rely on the generic iterator to provide valid start + // and end pointers, but we guarantee that any pointer returned by + // 'find_raw' falls within the bounds of the start and end pointer. + unsafe { self.it.next(|s, e| self.searcher.find_raw(s, e)) } + } + + #[inline] + fn size_hint(&self) -> (usize, Option) { + self.it.size_hint() + } +} + +impl<'a, 'h> DoubleEndedIterator for TwoIter<'a, 'h> { + #[inline] + fn next_back(&mut self) -> Option { + // SAFETY: We rely on the generic iterator to provide valid start + // and end pointers, but we guarantee that any pointer returned by + // 'rfind_raw' falls within the bounds of the start and end pointer. + unsafe { self.it.next_back(|s, e| self.searcher.rfind_raw(s, e)) } + } +} + +impl<'a, 'h> core::iter::FusedIterator for TwoIter<'a, 'h> {} + +/// Finds all occurrences of three bytes in a haystack. +/// +/// That is, this reports matches of one of three possible bytes. For example, +/// searching for `a`, `b` or `o` in `afoobar` would report matches at offsets +/// `0`, `2`, `3`, `4` and `5`. +#[derive(Clone, Copy, Debug)] +pub struct Three(generic::Three); + +impl Three { + /// Create a new searcher that finds occurrences of the needle bytes given. + /// + /// This particular searcher is specialized to use simd128 vector + /// instructions that typically make it quite fast. + /// + /// If simd128 is unavailable in the current environment, then `None` is + /// returned. + #[inline] + pub fn new(needle1: u8, needle2: u8, needle3: u8) -> Option { + if Three::is_available() { + // SAFETY: we check that simd128 is available above. + unsafe { Some(Three::new_unchecked(needle1, needle2, needle3)) } + } else { + None + } + } + + /// Create a new finder specific to simd128 vectors and routines without + /// checking that simd128 is available. + /// + /// # Safety + /// + /// Callers must guarantee that it is safe to execute `simd128` + /// instructions in the current environment. + #[target_feature(enable = "simd128")] + #[inline] + pub unsafe fn new_unchecked( + needle1: u8, + needle2: u8, + needle3: u8, + ) -> Three { + Three(generic::Three::new(needle1, needle2, needle3)) + } + + /// Returns true when this implementation is available in the current + /// environment. + /// + /// When this is true, it is guaranteed that [`Three::new`] will return + /// a `Some` value. Similarly, when it is false, it is guaranteed that + /// `Three::new` will return a `None` value. + /// + /// Note also that for the lifetime of a single program, if this returns + /// true then it will always return true. + #[inline] + pub fn is_available() -> bool { + #[cfg(target_feature = "simd128")] + { + true + } + #[cfg(not(target_feature = "simd128"))] + { + false + } + } + + /// Return the first occurrence of one of the needle bytes in the given + /// haystack. If no such occurrence exists, then `None` is returned. + /// + /// The occurrence is reported as an offset into `haystack`. Its maximum + /// value is `haystack.len() - 1`. + #[inline] + pub fn find(&self, haystack: &[u8]) -> Option { + // SAFETY: `find_raw` guarantees that if a pointer is returned, it + // falls within the bounds of the start and end pointers. + unsafe { + generic::search_slice_with_raw(haystack, |s, e| { + self.find_raw(s, e) + }) + } + } + + /// Return the last occurrence of one of the needle bytes in the given + /// haystack. If no such occurrence exists, then `None` is returned. + /// + /// The occurrence is reported as an offset into `haystack`. Its maximum + /// value is `haystack.len() - 1`. + #[inline] + pub fn rfind(&self, haystack: &[u8]) -> Option { + // SAFETY: `rfind_raw` guarantees that if a pointer is returned, it + // falls within the bounds of the start and end pointers. + unsafe { + generic::search_slice_with_raw(haystack, |s, e| { + self.rfind_raw(s, e) + }) + } + } + + /// Like `find`, but accepts and returns raw pointers. + /// + /// When a match is found, the pointer returned is guaranteed to be + /// `>= start` and `< end`. + /// + /// This routine is useful if you're already using raw pointers and would + /// like to avoid converting back to a slice before executing a search. + /// + /// # Safety + /// + /// * Both `start` and `end` must be valid for reads. + /// * Both `start` and `end` must point to an initialized value. + /// * Both `start` and `end` must point to the same allocated object and + /// must either be in bounds or at most one byte past the end of the + /// allocated object. + /// * Both `start` and `end` must be _derived from_ a pointer to the same + /// object. + /// * The distance between `start` and `end` must not overflow `isize`. + /// * The distance being in bounds must not rely on "wrapping around" the + /// address space. + /// + /// Note that callers may pass a pair of pointers such that `start >= end`. + /// In that case, `None` will always be returned. + #[inline] + pub unsafe fn find_raw( + &self, + start: *const u8, + end: *const u8, + ) -> Option<*const u8> { + if start >= end { + return None; + } + if end.distance(start) < v128::BYTES { + // SAFETY: We require the caller to pass valid start/end pointers. + return generic::fwd_byte_by_byte(start, end, |b| { + b == self.0.needle1() + || b == self.0.needle2() + || b == self.0.needle3() + }); + } + // SAFETY: Building a `Three` means it's safe to call 'simd128' + // routines. Also, we've checked that our haystack is big enough to run + // on the vector routine. Pointer validity is caller's responsibility. + self.find_raw_impl(start, end) + } + + /// Like `rfind`, but accepts and returns raw pointers. + /// + /// When a match is found, the pointer returned is guaranteed to be + /// `>= start` and `< end`. + /// + /// This routine is useful if you're already using raw pointers and would + /// like to avoid converting back to a slice before executing a search. + /// + /// # Safety + /// + /// * Both `start` and `end` must be valid for reads. + /// * Both `start` and `end` must point to an initialized value. + /// * Both `start` and `end` must point to the same allocated object and + /// must either be in bounds or at most one byte past the end of the + /// allocated object. + /// * Both `start` and `end` must be _derived from_ a pointer to the same + /// object. + /// * The distance between `start` and `end` must not overflow `isize`. + /// * The distance being in bounds must not rely on "wrapping around" the + /// address space. + /// + /// Note that callers may pass a pair of pointers such that `start >= end`. + /// In that case, `None` will always be returned. + #[inline] + pub unsafe fn rfind_raw( + &self, + start: *const u8, + end: *const u8, + ) -> Option<*const u8> { + if start >= end { + return None; + } + if end.distance(start) < v128::BYTES { + // SAFETY: We require the caller to pass valid start/end pointers. + return generic::rev_byte_by_byte(start, end, |b| { + b == self.0.needle1() + || b == self.0.needle2() + || b == self.0.needle3() + }); + } + // SAFETY: Building a `Three` means it's safe to call 'simd128' + // routines. Also, we've checked that our haystack is big enough to run + // on the vector routine. Pointer validity is caller's responsibility. + self.rfind_raw_impl(start, end) + } + + /// Execute a search using simd128 vectors and routines. + /// + /// # Safety + /// + /// Same as [`Three::find_raw`], except the distance between `start` and + /// `end` must be at least the size of a simd128 vector (in bytes). + /// + /// (The target feature safety obligation is automatically fulfilled by + /// virtue of being a method on `Three`, which can only be constructed + /// when it is safe to call `simd128` routines.) + #[target_feature(enable = "simd128")] + #[inline] + unsafe fn find_raw_impl( + &self, + start: *const u8, + end: *const u8, + ) -> Option<*const u8> { + self.0.find_raw(start, end) + } + + /// Execute a search using simd128 vectors and routines. + /// + /// # Safety + /// + /// Same as [`Three::rfind_raw`], except the distance between `start` and + /// `end` must be at least the size of a simd128 vector (in bytes). + /// + /// (The target feature safety obligation is automatically fulfilled by + /// virtue of being a method on `Three`, which can only be constructed + /// when it is safe to call `simd128` routines.) + #[target_feature(enable = "simd128")] + #[inline] + unsafe fn rfind_raw_impl( + &self, + start: *const u8, + end: *const u8, + ) -> Option<*const u8> { + self.0.rfind_raw(start, end) + } + + /// Returns an iterator over all occurrences of the needle byte in the + /// given haystack. + /// + /// The iterator returned implements `DoubleEndedIterator`. This means it + /// can also be used to find occurrences in reverse order. + #[inline] + pub fn iter<'a, 'h>(&'a self, haystack: &'h [u8]) -> ThreeIter<'a, 'h> { + ThreeIter { searcher: self, it: generic::Iter::new(haystack) } + } +} + +/// An iterator over all occurrences of three possible bytes in a haystack. +/// +/// This iterator implements `DoubleEndedIterator`, which means it can also be +/// used to find occurrences in reverse order. +/// +/// This iterator is created by the [`Three::iter`] method. +/// +/// The lifetime parameters are as follows: +/// +/// * `'a` refers to the lifetime of the underlying [`Three`] searcher. +/// * `'h` refers to the lifetime of the haystack being searched. +#[derive(Clone, Debug)] +pub struct ThreeIter<'a, 'h> { + searcher: &'a Three, + it: generic::Iter<'h>, +} + +impl<'a, 'h> Iterator for ThreeIter<'a, 'h> { + type Item = usize; + + #[inline] + fn next(&mut self) -> Option { + // SAFETY: We rely on the generic iterator to provide valid start + // and end pointers, but we guarantee that any pointer returned by + // 'find_raw' falls within the bounds of the start and end pointer. + unsafe { self.it.next(|s, e| self.searcher.find_raw(s, e)) } + } + + #[inline] + fn size_hint(&self) -> (usize, Option) { + self.it.size_hint() + } +} + +impl<'a, 'h> DoubleEndedIterator for ThreeIter<'a, 'h> { + #[inline] + fn next_back(&mut self) -> Option { + // SAFETY: We rely on the generic iterator to provide valid start + // and end pointers, but we guarantee that any pointer returned by + // 'rfind_raw' falls within the bounds of the start and end pointer. + unsafe { self.it.next_back(|s, e| self.searcher.rfind_raw(s, e)) } + } +} + +impl<'a, 'h> core::iter::FusedIterator for ThreeIter<'a, 'h> {} + +#[cfg(test)] +mod tests { + use super::*; + + define_memchr_quickcheck!(super); + + #[test] + fn forward_one() { + crate::tests::memchr::Runner::new(1).forward_iter( + |haystack, needles| { + Some(One::new(needles[0])?.iter(haystack).collect()) + }, + ) + } + + #[test] + fn reverse_one() { + crate::tests::memchr::Runner::new(1).reverse_iter( + |haystack, needles| { + Some(One::new(needles[0])?.iter(haystack).rev().collect()) + }, + ) + } + + #[test] + fn count_one() { + crate::tests::memchr::Runner::new(1).count_iter(|haystack, needles| { + Some(One::new(needles[0])?.iter(haystack).count()) + }) + } + + #[test] + fn forward_two() { + crate::tests::memchr::Runner::new(2).forward_iter( + |haystack, needles| { + let n1 = needles.get(0).copied()?; + let n2 = needles.get(1).copied()?; + Some(Two::new(n1, n2)?.iter(haystack).collect()) + }, + ) + } + + #[test] + fn reverse_two() { + crate::tests::memchr::Runner::new(2).reverse_iter( + |haystack, needles| { + let n1 = needles.get(0).copied()?; + let n2 = needles.get(1).copied()?; + Some(Two::new(n1, n2)?.iter(haystack).rev().collect()) + }, + ) + } + + #[test] + fn forward_three() { + crate::tests::memchr::Runner::new(3).forward_iter( + |haystack, needles| { + let n1 = needles.get(0).copied()?; + let n2 = needles.get(1).copied()?; + let n3 = needles.get(2).copied()?; + Some(Three::new(n1, n2, n3)?.iter(haystack).collect()) + }, + ) + } + + #[test] + fn reverse_three() { + crate::tests::memchr::Runner::new(3).reverse_iter( + |haystack, needles| { + let n1 = needles.get(0).copied()?; + let n2 = needles.get(1).copied()?; + let n3 = needles.get(2).copied()?; + Some(Three::new(n1, n2, n3)?.iter(haystack).rev().collect()) + }, + ) + } +} diff --git a/vendor/memchr/src/arch/wasm32/simd128/mod.rs b/vendor/memchr/src/arch/wasm32/simd128/mod.rs new file mode 100644 index 0000000..b55d1f0 --- /dev/null +++ b/vendor/memchr/src/arch/wasm32/simd128/mod.rs @@ -0,0 +1,6 @@ +/*! +Algorithms for the `wasm32` target using 128-bit vectors via simd128. +*/ + +pub mod memchr; +pub mod packedpair; diff --git a/vendor/memchr/src/arch/wasm32/simd128/packedpair.rs b/vendor/memchr/src/arch/wasm32/simd128/packedpair.rs new file mode 100644 index 0000000..e8cf745 --- /dev/null +++ b/vendor/memchr/src/arch/wasm32/simd128/packedpair.rs @@ -0,0 +1,228 @@ +/*! +A 128-bit vector implementation of the "packed pair" SIMD algorithm. + +The "packed pair" algorithm is based on the [generic SIMD] algorithm. The main +difference is that it (by default) uses a background distribution of byte +frequencies to heuristically select the pair of bytes to search for. + +[generic SIMD]: http://0x80.pl/articles/simd-strfind.html#first-and-last +*/ + +use core::arch::wasm32::v128; + +use crate::arch::{all::packedpair::Pair, generic::packedpair}; + +/// A "packed pair" finder that uses 128-bit vector operations. +/// +/// This finder picks two bytes that it believes have high predictive power +/// for indicating an overall match of a needle. Depending on whether +/// `Finder::find` or `Finder::find_prefilter` is used, it reports offsets +/// where the needle matches or could match. In the prefilter case, candidates +/// are reported whenever the [`Pair`] of bytes given matches. +#[derive(Clone, Copy, Debug)] +pub struct Finder(packedpair::Finder); + +impl Finder { + /// Create a new pair searcher. The searcher returned can either report + /// exact matches of `needle` or act as a prefilter and report candidate + /// positions of `needle`. + /// + /// If simd128 is unavailable in the current environment or if a [`Pair`] + /// could not be constructed from the needle given, then `None` is + /// returned. + #[inline] + pub fn new(needle: &[u8]) -> Option { + Finder::with_pair(needle, Pair::new(needle)?) + } + + /// Create a new "packed pair" finder using the pair of bytes given. + /// + /// This constructor permits callers to control precisely which pair of + /// bytes is used as a predicate. + /// + /// If simd128 is unavailable in the current environment, then `None` is + /// returned. + #[inline] + pub fn with_pair(needle: &[u8], pair: Pair) -> Option { + if Finder::is_available() { + // SAFETY: we check that simd128 is available above. We are also + // guaranteed to have needle.len() > 1 because we have a valid + // Pair. + unsafe { Some(Finder::with_pair_impl(needle, pair)) } + } else { + None + } + } + + /// Create a new `Finder` specific to simd128 vectors and routines. + /// + /// # Safety + /// + /// Same as the safety for `packedpair::Finder::new`, and callers must also + /// ensure that simd128 is available. + #[target_feature(enable = "simd128")] + #[inline] + unsafe fn with_pair_impl(needle: &[u8], pair: Pair) -> Finder { + let finder = packedpair::Finder::::new(needle, pair); + Finder(finder) + } + + /// Returns true when this implementation is available in the current + /// environment. + /// + /// When this is true, it is guaranteed that [`Finder::with_pair`] will + /// return a `Some` value. Similarly, when it is false, it is guaranteed + /// that `Finder::with_pair` will return a `None` value. Notice that this + /// does not guarantee that [`Finder::new`] will return a `Finder`. Namely, + /// even when `Finder::is_available` is true, it is not guaranteed that a + /// valid [`Pair`] can be found from the needle given. + /// + /// Note also that for the lifetime of a single program, if this returns + /// true then it will always return true. + #[inline] + pub fn is_available() -> bool { + // We used to gate on `cfg(target_feature = "simd128")` here, but + // we've since required the feature to be enabled at compile time to + // even include this module at all. Therefore, it is always enabled + // in this context. See the linked issue for why this was changed. + // + // Ref: https://github.com/BurntSushi/memchr/issues/144 + true + } + + /// Execute a search using wasm32 v128 vectors and routines. + /// + /// # Panics + /// + /// When `haystack.len()` is less than [`Finder::min_haystack_len`]. + #[inline] + pub fn find(&self, haystack: &[u8], needle: &[u8]) -> Option { + self.find_impl(haystack, needle) + } + + /// Execute a search using wasm32 v128 vectors and routines. + /// + /// # Panics + /// + /// When `haystack.len()` is less than [`Finder::min_haystack_len`]. + #[inline] + pub fn find_prefilter(&self, haystack: &[u8]) -> Option { + self.find_prefilter_impl(haystack) + } + + /// Execute a search using wasm32 v128 vectors and routines. + /// + /// # Panics + /// + /// When `haystack.len()` is less than [`Finder::min_haystack_len`]. + /// + /// # Safety + /// + /// (The target feature safety obligation is automatically fulfilled by + /// virtue of being a method on `Finder`, which can only be constructed + /// when it is safe to call `simd128` routines.) + #[target_feature(enable = "simd128")] + #[inline] + fn find_impl(&self, haystack: &[u8], needle: &[u8]) -> Option { + // SAFETY: The target feature safety obligation is automatically + // fulfilled by virtue of being a method on `Finder`, which can only be + // constructed when it is safe to call `simd128` routines. + unsafe { self.0.find(haystack, needle) } + } + + /// Execute a prefilter search using wasm32 v128 vectors and routines. + /// + /// # Panics + /// + /// When `haystack.len()` is less than [`Finder::min_haystack_len`]. + /// + /// # Safety + /// + /// (The target feature safety obligation is automatically fulfilled by + /// virtue of being a method on `Finder`, which can only be constructed + /// when it is safe to call `simd128` routines.) + #[target_feature(enable = "simd128")] + #[inline] + fn find_prefilter_impl(&self, haystack: &[u8]) -> Option { + // SAFETY: The target feature safety obligation is automatically + // fulfilled by virtue of being a method on `Finder`, which can only be + // constructed when it is safe to call `simd128` routines. + unsafe { self.0.find_prefilter(haystack) } + } + + /// Returns the pair of offsets (into the needle) used to check as a + /// predicate before confirming whether a needle exists at a particular + /// position. + #[inline] + pub fn pair(&self) -> &Pair { + self.0.pair() + } + + /// Returns the minimum haystack length that this `Finder` can search. + /// + /// Using a haystack with length smaller than this in a search will result + /// in a panic. The reason for this restriction is that this finder is + /// meant to be a low-level component that is part of a larger substring + /// strategy. In that sense, it avoids trying to handle all cases and + /// instead only handles the cases that it can handle very well. + #[inline] + pub fn min_haystack_len(&self) -> usize { + self.0.min_haystack_len() + } +} + +#[cfg(test)] +mod tests { + use super::*; + + fn find(haystack: &[u8], needle: &[u8]) -> Option> { + let f = Finder::new(needle)?; + if haystack.len() < f.min_haystack_len() { + return None; + } + Some(f.find(haystack, needle)) + } + + define_substring_forward_quickcheck!(find); + + #[test] + fn forward_substring() { + crate::tests::substring::Runner::new().fwd(find).run() + } + + #[test] + fn forward_packedpair() { + fn find( + haystack: &[u8], + needle: &[u8], + index1: u8, + index2: u8, + ) -> Option> { + let pair = Pair::with_indices(needle, index1, index2)?; + let f = Finder::with_pair(needle, pair)?; + if haystack.len() < f.min_haystack_len() { + return None; + } + Some(f.find(haystack, needle)) + } + crate::tests::packedpair::Runner::new().fwd(find).run() + } + + #[test] + fn forward_packedpair_prefilter() { + fn find( + haystack: &[u8], + needle: &[u8], + index1: u8, + index2: u8, + ) -> Option> { + let pair = Pair::with_indices(needle, index1, index2)?; + let f = Finder::with_pair(needle, pair)?; + if haystack.len() < f.min_haystack_len() { + return None; + } + Some(f.find_prefilter(haystack)) + } + crate::tests::packedpair::Runner::new().fwd(find).run() + } +} diff --git a/vendor/memchr/src/arch/x86_64/avx2/memchr.rs b/vendor/memchr/src/arch/x86_64/avx2/memchr.rs new file mode 100644 index 0000000..59f8c7f --- /dev/null +++ b/vendor/memchr/src/arch/x86_64/avx2/memchr.rs @@ -0,0 +1,1352 @@ +/*! +This module defines 256-bit vector implementations of `memchr` and friends. + +The main types in this module are [`One`], [`Two`] and [`Three`]. They are for +searching for one, two or three distinct bytes, respectively, in a haystack. +Each type also has corresponding double ended iterators. These searchers are +typically much faster than scalar routines accomplishing the same task. + +The `One` searcher also provides a [`One::count`] routine for efficiently +counting the number of times a single byte occurs in a haystack. This is +useful, for example, for counting the number of lines in a haystack. This +routine exists because it is usually faster, especially with a high match +count, then using [`One::find`] repeatedly. ([`OneIter`] specializes its +`Iterator::count` implementation to use this routine.) + +Only one, two and three bytes are supported because three bytes is about +the point where one sees diminishing returns. Beyond this point and it's +probably (but not necessarily) better to just use a simple `[bool; 256]` array +or similar. However, it depends mightily on the specific work-load and the +expected match frequency. +*/ + +use core::arch::x86_64::{__m128i, __m256i}; + +use crate::{arch::generic::memchr as generic, ext::Pointer, vector::Vector}; + +/// Finds all occurrences of a single byte in a haystack. +#[derive(Clone, Copy, Debug)] +pub struct One { + /// Used for haystacks less than 32 bytes. + sse2: generic::One<__m128i>, + /// Used for haystacks bigger than 32 bytes. + avx2: generic::One<__m256i>, +} + +impl One { + /// Create a new searcher that finds occurrences of the needle byte given. + /// + /// This particular searcher is specialized to use AVX2 vector instructions + /// that typically make it quite fast. (SSE2 is used for haystacks that + /// are too short to accommodate an AVX2 vector.) + /// + /// If either SSE2 or AVX2 is unavailable in the current environment, then + /// `None` is returned. + #[inline] + pub fn new(needle: u8) -> Option { + if One::is_available() { + // SAFETY: we check that sse2 and avx2 are available above. + unsafe { Some(One::new_unchecked(needle)) } + } else { + None + } + } + + /// Create a new finder specific to AVX2 vectors and routines without + /// checking that either SSE2 or AVX2 is available. + /// + /// # Safety + /// + /// Callers must guarantee that it is safe to execute both `sse2` and + /// `avx2` instructions in the current environment. + /// + /// Note that it is a common misconception that if one compiles for an + /// `x86_64` target, then they therefore automatically have access to SSE2 + /// instructions. While this is almost always the case, it isn't true in + /// 100% of cases. + #[target_feature(enable = "sse2", enable = "avx2")] + #[inline] + pub unsafe fn new_unchecked(needle: u8) -> One { + One { + sse2: generic::One::new(needle), + avx2: generic::One::new(needle), + } + } + + /// Returns true when this implementation is available in the current + /// environment. + /// + /// When this is true, it is guaranteed that [`One::new`] will return + /// a `Some` value. Similarly, when it is false, it is guaranteed that + /// `One::new` will return a `None` value. + /// + /// Note also that for the lifetime of a single program, if this returns + /// true then it will always return true. + #[inline] + pub fn is_available() -> bool { + #[cfg(not(target_feature = "sse2"))] + { + false + } + #[cfg(target_feature = "sse2")] + { + #[cfg(target_feature = "avx2")] + { + true + } + #[cfg(not(target_feature = "avx2"))] + { + #[cfg(feature = "std")] + { + std::is_x86_feature_detected!("avx2") + } + #[cfg(not(feature = "std"))] + { + false + } + } + } + } + + /// Return the first occurrence of one of the needle bytes in the given + /// haystack. If no such occurrence exists, then `None` is returned. + /// + /// The occurrence is reported as an offset into `haystack`. Its maximum + /// value is `haystack.len() - 1`. + #[inline] + pub fn find(&self, haystack: &[u8]) -> Option { + // SAFETY: `find_raw` guarantees that if a pointer is returned, it + // falls within the bounds of the start and end pointers. + unsafe { + generic::search_slice_with_raw(haystack, |s, e| { + self.find_raw(s, e) + }) + } + } + + /// Return the last occurrence of one of the needle bytes in the given + /// haystack. If no such occurrence exists, then `None` is returned. + /// + /// The occurrence is reported as an offset into `haystack`. Its maximum + /// value is `haystack.len() - 1`. + #[inline] + pub fn rfind(&self, haystack: &[u8]) -> Option { + // SAFETY: `find_raw` guarantees that if a pointer is returned, it + // falls within the bounds of the start and end pointers. + unsafe { + generic::search_slice_with_raw(haystack, |s, e| { + self.rfind_raw(s, e) + }) + } + } + + /// Counts all occurrences of this byte in the given haystack. + #[inline] + pub fn count(&self, haystack: &[u8]) -> usize { + // SAFETY: All of our pointers are derived directly from a borrowed + // slice, which is guaranteed to be valid. + unsafe { + let start = haystack.as_ptr(); + let end = start.add(haystack.len()); + self.count_raw(start, end) + } + } + + /// Like `find`, but accepts and returns raw pointers. + /// + /// When a match is found, the pointer returned is guaranteed to be + /// `>= start` and `< end`. + /// + /// This routine is useful if you're already using raw pointers and would + /// like to avoid converting back to a slice before executing a search. + /// + /// # Safety + /// + /// * Both `start` and `end` must be valid for reads. + /// * Both `start` and `end` must point to an initialized value. + /// * Both `start` and `end` must point to the same allocated object and + /// must either be in bounds or at most one byte past the end of the + /// allocated object. + /// * Both `start` and `end` must be _derived from_ a pointer to the same + /// object. + /// * The distance between `start` and `end` must not overflow `isize`. + /// * The distance being in bounds must not rely on "wrapping around" the + /// address space. + /// + /// Note that callers may pass a pair of pointers such that `start >= end`. + /// In that case, `None` will always be returned. + #[inline] + pub unsafe fn find_raw( + &self, + start: *const u8, + end: *const u8, + ) -> Option<*const u8> { + if start >= end { + return None; + } + let len = end.distance(start); + if len < __m256i::BYTES { + return if len < __m128i::BYTES { + // SAFETY: We require the caller to pass valid start/end + // pointers. + generic::fwd_byte_by_byte(start, end, |b| { + b == self.sse2.needle1() + }) + } else { + // SAFETY: We require the caller to pass valid start/end + // pointers. + self.find_raw_sse2(start, end) + }; + } + // SAFETY: Building a `One` means it's safe to call both 'sse2' and + // 'avx2' routines. Also, we've checked that our haystack is big + // enough to run on the vector routine. Pointer validity is caller's + // responsibility. + // + // Note that we could call `self.avx2.find_raw` directly here. But that + // means we'd have to annotate this routine with `target_feature`. + // Which is fine, because this routine is `unsafe` anyway and the + // `target_feature` obligation is met by virtue of building a `One`. + // The real problem is that a routine with a `target_feature` + // annotation generally can't be inlined into caller code unless + // the caller code has the same target feature annotations. Namely, + // the common case (at time of writing) is for calling code to not + // have the `avx2` target feature enabled *at compile time*. Without + // `target_feature` on this routine, it can be inlined which will + // handle some of the short-haystack cases above without touching the + // architecture specific code. + self.find_raw_avx2(start, end) + } + + /// Like `rfind`, but accepts and returns raw pointers. + /// + /// When a match is found, the pointer returned is guaranteed to be + /// `>= start` and `< end`. + /// + /// This routine is useful if you're already using raw pointers and would + /// like to avoid converting back to a slice before executing a search. + /// + /// # Safety + /// + /// * Both `start` and `end` must be valid for reads. + /// * Both `start` and `end` must point to an initialized value. + /// * Both `start` and `end` must point to the same allocated object and + /// must either be in bounds or at most one byte past the end of the + /// allocated object. + /// * Both `start` and `end` must be _derived from_ a pointer to the same + /// object. + /// * The distance between `start` and `end` must not overflow `isize`. + /// * The distance being in bounds must not rely on "wrapping around" the + /// address space. + /// + /// Note that callers may pass a pair of pointers such that `start >= end`. + /// In that case, `None` will always be returned. + #[inline] + pub unsafe fn rfind_raw( + &self, + start: *const u8, + end: *const u8, + ) -> Option<*const u8> { + if start >= end { + return None; + } + let len = end.distance(start); + if len < __m256i::BYTES { + return if len < __m128i::BYTES { + // SAFETY: We require the caller to pass valid start/end + // pointers. + generic::rev_byte_by_byte(start, end, |b| { + b == self.sse2.needle1() + }) + } else { + // SAFETY: We require the caller to pass valid start/end + // pointers. + self.rfind_raw_sse2(start, end) + }; + } + // SAFETY: Building a `One` means it's safe to call both 'sse2' and + // 'avx2' routines. Also, we've checked that our haystack is big + // enough to run on the vector routine. Pointer validity is caller's + // responsibility. + // + // See note in forward routine above for why we don't just call + // `self.avx2.rfind_raw` directly here. + self.rfind_raw_avx2(start, end) + } + + /// Counts all occurrences of this byte in the given haystack represented + /// by raw pointers. + /// + /// This routine is useful if you're already using raw pointers and would + /// like to avoid converting back to a slice before executing a search. + /// + /// # Safety + /// + /// * Both `start` and `end` must be valid for reads. + /// * Both `start` and `end` must point to an initialized value. + /// * Both `start` and `end` must point to the same allocated object and + /// must either be in bounds or at most one byte past the end of the + /// allocated object. + /// * Both `start` and `end` must be _derived from_ a pointer to the same + /// object. + /// * The distance between `start` and `end` must not overflow `isize`. + /// * The distance being in bounds must not rely on "wrapping around" the + /// address space. + /// + /// Note that callers may pass a pair of pointers such that `start >= end`. + /// In that case, `0` will always be returned. + #[inline] + pub unsafe fn count_raw(&self, start: *const u8, end: *const u8) -> usize { + if start >= end { + return 0; + } + let len = end.distance(start); + if len < __m256i::BYTES { + return if len < __m128i::BYTES { + // SAFETY: We require the caller to pass valid start/end + // pointers. + generic::count_byte_by_byte(start, end, |b| { + b == self.sse2.needle1() + }) + } else { + // SAFETY: We require the caller to pass valid start/end + // pointers. + self.count_raw_sse2(start, end) + }; + } + // SAFETY: Building a `One` means it's safe to call both 'sse2' and + // 'avx2' routines. Also, we've checked that our haystack is big + // enough to run on the vector routine. Pointer validity is caller's + // responsibility. + self.count_raw_avx2(start, end) + } + + /// Execute a search using SSE2 vectors and routines. + /// + /// # Safety + /// + /// Same as [`One::find_raw`], except the distance between `start` and + /// `end` must be at least the size of an SSE2 vector (in bytes). + /// + /// (The target feature safety obligation is automatically fulfilled by + /// virtue of being a method on `One`, which can only be constructed + /// when it is safe to call `sse2`/`avx2` routines.) + #[target_feature(enable = "sse2")] + #[inline] + unsafe fn find_raw_sse2( + &self, + start: *const u8, + end: *const u8, + ) -> Option<*const u8> { + self.sse2.find_raw(start, end) + } + + /// Execute a search using SSE2 vectors and routines. + /// + /// # Safety + /// + /// Same as [`One::rfind_raw`], except the distance between `start` and + /// `end` must be at least the size of an SSE2 vector (in bytes). + /// + /// (The target feature safety obligation is automatically fulfilled by + /// virtue of being a method on `One`, which can only be constructed + /// when it is safe to call `sse2`/`avx2` routines.) + #[target_feature(enable = "sse2")] + #[inline] + unsafe fn rfind_raw_sse2( + &self, + start: *const u8, + end: *const u8, + ) -> Option<*const u8> { + self.sse2.rfind_raw(start, end) + } + + /// Execute a count using SSE2 vectors and routines. + /// + /// # Safety + /// + /// Same as [`One::count_raw`], except the distance between `start` and + /// `end` must be at least the size of an SSE2 vector (in bytes). + /// + /// (The target feature safety obligation is automatically fulfilled by + /// virtue of being a method on `One`, which can only be constructed + /// when it is safe to call `sse2`/`avx2` routines.) + #[target_feature(enable = "sse2")] + #[inline] + unsafe fn count_raw_sse2( + &self, + start: *const u8, + end: *const u8, + ) -> usize { + self.sse2.count_raw(start, end) + } + + /// Execute a search using AVX2 vectors and routines. + /// + /// # Safety + /// + /// Same as [`One::find_raw`], except the distance between `start` and + /// `end` must be at least the size of an AVX2 vector (in bytes). + /// + /// (The target feature safety obligation is automatically fulfilled by + /// virtue of being a method on `One`, which can only be constructed + /// when it is safe to call `sse2`/`avx2` routines.) + #[target_feature(enable = "avx2")] + #[inline] + unsafe fn find_raw_avx2( + &self, + start: *const u8, + end: *const u8, + ) -> Option<*const u8> { + self.avx2.find_raw(start, end) + } + + /// Execute a search using AVX2 vectors and routines. + /// + /// # Safety + /// + /// Same as [`One::rfind_raw`], except the distance between `start` and + /// `end` must be at least the size of an AVX2 vector (in bytes). + /// + /// (The target feature safety obligation is automatically fulfilled by + /// virtue of being a method on `One`, which can only be constructed + /// when it is safe to call `sse2`/`avx2` routines.) + #[target_feature(enable = "avx2")] + #[inline] + unsafe fn rfind_raw_avx2( + &self, + start: *const u8, + end: *const u8, + ) -> Option<*const u8> { + self.avx2.rfind_raw(start, end) + } + + /// Execute a count using AVX2 vectors and routines. + /// + /// # Safety + /// + /// Same as [`One::count_raw`], except the distance between `start` and + /// `end` must be at least the size of an AVX2 vector (in bytes). + /// + /// (The target feature safety obligation is automatically fulfilled by + /// virtue of being a method on `One`, which can only be constructed + /// when it is safe to call `sse2`/`avx2` routines.) + #[target_feature(enable = "avx2")] + #[inline] + unsafe fn count_raw_avx2( + &self, + start: *const u8, + end: *const u8, + ) -> usize { + self.avx2.count_raw(start, end) + } + + /// Returns an iterator over all occurrences of the needle byte in the + /// given haystack. + /// + /// The iterator returned implements `DoubleEndedIterator`. This means it + /// can also be used to find occurrences in reverse order. + #[inline] + pub fn iter<'a, 'h>(&'a self, haystack: &'h [u8]) -> OneIter<'a, 'h> { + OneIter { searcher: self, it: generic::Iter::new(haystack) } + } +} + +/// An iterator over all occurrences of a single byte in a haystack. +/// +/// This iterator implements `DoubleEndedIterator`, which means it can also be +/// used to find occurrences in reverse order. +/// +/// This iterator is created by the [`One::iter`] method. +/// +/// The lifetime parameters are as follows: +/// +/// * `'a` refers to the lifetime of the underlying [`One`] searcher. +/// * `'h` refers to the lifetime of the haystack being searched. +#[derive(Clone, Debug)] +pub struct OneIter<'a, 'h> { + searcher: &'a One, + it: generic::Iter<'h>, +} + +impl<'a, 'h> Iterator for OneIter<'a, 'h> { + type Item = usize; + + #[inline] + fn next(&mut self) -> Option { + // SAFETY: We rely on the generic iterator to provide valid start + // and end pointers, but we guarantee that any pointer returned by + // 'find_raw' falls within the bounds of the start and end pointer. + unsafe { self.it.next(|s, e| self.searcher.find_raw(s, e)) } + } + + #[inline] + fn count(self) -> usize { + self.it.count(|s, e| { + // SAFETY: We rely on our generic iterator to return valid start + // and end pointers. + unsafe { self.searcher.count_raw(s, e) } + }) + } + + #[inline] + fn size_hint(&self) -> (usize, Option) { + self.it.size_hint() + } +} + +impl<'a, 'h> DoubleEndedIterator for OneIter<'a, 'h> { + #[inline] + fn next_back(&mut self) -> Option { + // SAFETY: We rely on the generic iterator to provide valid start + // and end pointers, but we guarantee that any pointer returned by + // 'rfind_raw' falls within the bounds of the start and end pointer. + unsafe { self.it.next_back(|s, e| self.searcher.rfind_raw(s, e)) } + } +} + +impl<'a, 'h> core::iter::FusedIterator for OneIter<'a, 'h> {} + +/// Finds all occurrences of two bytes in a haystack. +/// +/// That is, this reports matches of one of two possible bytes. For example, +/// searching for `a` or `b` in `afoobar` would report matches at offsets `0`, +/// `4` and `5`. +#[derive(Clone, Copy, Debug)] +pub struct Two { + /// Used for haystacks less than 32 bytes. + sse2: generic::Two<__m128i>, + /// Used for haystacks bigger than 32 bytes. + avx2: generic::Two<__m256i>, +} + +impl Two { + /// Create a new searcher that finds occurrences of the needle bytes given. + /// + /// This particular searcher is specialized to use AVX2 vector instructions + /// that typically make it quite fast. (SSE2 is used for haystacks that + /// are too short to accommodate an AVX2 vector.) + /// + /// If either SSE2 or AVX2 is unavailable in the current environment, then + /// `None` is returned. + #[inline] + pub fn new(needle1: u8, needle2: u8) -> Option { + if Two::is_available() { + // SAFETY: we check that sse2 and avx2 are available above. + unsafe { Some(Two::new_unchecked(needle1, needle2)) } + } else { + None + } + } + + /// Create a new finder specific to AVX2 vectors and routines without + /// checking that either SSE2 or AVX2 is available. + /// + /// # Safety + /// + /// Callers must guarantee that it is safe to execute both `sse2` and + /// `avx2` instructions in the current environment. + /// + /// Note that it is a common misconception that if one compiles for an + /// `x86_64` target, then they therefore automatically have access to SSE2 + /// instructions. While this is almost always the case, it isn't true in + /// 100% of cases. + #[target_feature(enable = "sse2", enable = "avx2")] + #[inline] + pub unsafe fn new_unchecked(needle1: u8, needle2: u8) -> Two { + Two { + sse2: generic::Two::new(needle1, needle2), + avx2: generic::Two::new(needle1, needle2), + } + } + + /// Returns true when this implementation is available in the current + /// environment. + /// + /// When this is true, it is guaranteed that [`Two::new`] will return + /// a `Some` value. Similarly, when it is false, it is guaranteed that + /// `Two::new` will return a `None` value. + /// + /// Note also that for the lifetime of a single program, if this returns + /// true then it will always return true. + #[inline] + pub fn is_available() -> bool { + #[cfg(not(target_feature = "sse2"))] + { + false + } + #[cfg(target_feature = "sse2")] + { + #[cfg(target_feature = "avx2")] + { + true + } + #[cfg(not(target_feature = "avx2"))] + { + #[cfg(feature = "std")] + { + std::is_x86_feature_detected!("avx2") + } + #[cfg(not(feature = "std"))] + { + false + } + } + } + } + + /// Return the first occurrence of one of the needle bytes in the given + /// haystack. If no such occurrence exists, then `None` is returned. + /// + /// The occurrence is reported as an offset into `haystack`. Its maximum + /// value is `haystack.len() - 1`. + #[inline] + pub fn find(&self, haystack: &[u8]) -> Option { + // SAFETY: `find_raw` guarantees that if a pointer is returned, it + // falls within the bounds of the start and end pointers. + unsafe { + generic::search_slice_with_raw(haystack, |s, e| { + self.find_raw(s, e) + }) + } + } + + /// Return the last occurrence of one of the needle bytes in the given + /// haystack. If no such occurrence exists, then `None` is returned. + /// + /// The occurrence is reported as an offset into `haystack`. Its maximum + /// value is `haystack.len() - 1`. + #[inline] + pub fn rfind(&self, haystack: &[u8]) -> Option { + // SAFETY: `find_raw` guarantees that if a pointer is returned, it + // falls within the bounds of the start and end pointers. + unsafe { + generic::search_slice_with_raw(haystack, |s, e| { + self.rfind_raw(s, e) + }) + } + } + + /// Like `find`, but accepts and returns raw pointers. + /// + /// When a match is found, the pointer returned is guaranteed to be + /// `>= start` and `< end`. + /// + /// This routine is useful if you're already using raw pointers and would + /// like to avoid converting back to a slice before executing a search. + /// + /// # Safety + /// + /// * Both `start` and `end` must be valid for reads. + /// * Both `start` and `end` must point to an initialized value. + /// * Both `start` and `end` must point to the same allocated object and + /// must either be in bounds or at most one byte past the end of the + /// allocated object. + /// * Both `start` and `end` must be _derived from_ a pointer to the same + /// object. + /// * The distance between `start` and `end` must not overflow `isize`. + /// * The distance being in bounds must not rely on "wrapping around" the + /// address space. + /// + /// Note that callers may pass a pair of pointers such that `start >= end`. + /// In that case, `None` will always be returned. + #[inline] + pub unsafe fn find_raw( + &self, + start: *const u8, + end: *const u8, + ) -> Option<*const u8> { + if start >= end { + return None; + } + let len = end.distance(start); + if len < __m256i::BYTES { + return if len < __m128i::BYTES { + // SAFETY: We require the caller to pass valid start/end + // pointers. + generic::fwd_byte_by_byte(start, end, |b| { + b == self.sse2.needle1() || b == self.sse2.needle2() + }) + } else { + // SAFETY: We require the caller to pass valid start/end + // pointers. + self.find_raw_sse2(start, end) + }; + } + // SAFETY: Building a `Two` means it's safe to call both 'sse2' and + // 'avx2' routines. Also, we've checked that our haystack is big + // enough to run on the vector routine. Pointer validity is caller's + // responsibility. + // + // Note that we could call `self.avx2.find_raw` directly here. But that + // means we'd have to annotate this routine with `target_feature`. + // Which is fine, because this routine is `unsafe` anyway and the + // `target_feature` obligation is met by virtue of building a `Two`. + // The real problem is that a routine with a `target_feature` + // annotation generally can't be inlined into caller code unless + // the caller code has the same target feature annotations. Namely, + // the common case (at time of writing) is for calling code to not + // have the `avx2` target feature enabled *at compile time*. Without + // `target_feature` on this routine, it can be inlined which will + // handle some of the short-haystack cases above without touching the + // architecture specific code. + self.find_raw_avx2(start, end) + } + + /// Like `rfind`, but accepts and returns raw pointers. + /// + /// When a match is found, the pointer returned is guaranteed to be + /// `>= start` and `< end`. + /// + /// This routine is useful if you're already using raw pointers and would + /// like to avoid converting back to a slice before executing a search. + /// + /// # Safety + /// + /// * Both `start` and `end` must be valid for reads. + /// * Both `start` and `end` must point to an initialized value. + /// * Both `start` and `end` must point to the same allocated object and + /// must either be in bounds or at most one byte past the end of the + /// allocated object. + /// * Both `start` and `end` must be _derived from_ a pointer to the same + /// object. + /// * The distance between `start` and `end` must not overflow `isize`. + /// * The distance being in bounds must not rely on "wrapping around" the + /// address space. + /// + /// Note that callers may pass a pair of pointers such that `start >= end`. + /// In that case, `None` will always be returned. + #[inline] + pub unsafe fn rfind_raw( + &self, + start: *const u8, + end: *const u8, + ) -> Option<*const u8> { + if start >= end { + return None; + } + let len = end.distance(start); + if len < __m256i::BYTES { + return if len < __m128i::BYTES { + // SAFETY: We require the caller to pass valid start/end + // pointers. + generic::rev_byte_by_byte(start, end, |b| { + b == self.sse2.needle1() || b == self.sse2.needle2() + }) + } else { + // SAFETY: We require the caller to pass valid start/end + // pointers. + self.rfind_raw_sse2(start, end) + }; + } + // SAFETY: Building a `Two` means it's safe to call both 'sse2' and + // 'avx2' routines. Also, we've checked that our haystack is big + // enough to run on the vector routine. Pointer validity is caller's + // responsibility. + // + // See note in forward routine above for why we don't just call + // `self.avx2.rfind_raw` directly here. + self.rfind_raw_avx2(start, end) + } + + /// Execute a search using SSE2 vectors and routines. + /// + /// # Safety + /// + /// Same as [`Two::find_raw`], except the distance between `start` and + /// `end` must be at least the size of an SSE2 vector (in bytes). + /// + /// (The target feature safety obligation is automatically fulfilled by + /// virtue of being a method on `Two`, which can only be constructed + /// when it is safe to call `sse2`/`avx2` routines.) + #[target_feature(enable = "sse2")] + #[inline] + unsafe fn find_raw_sse2( + &self, + start: *const u8, + end: *const u8, + ) -> Option<*const u8> { + self.sse2.find_raw(start, end) + } + + /// Execute a search using SSE2 vectors and routines. + /// + /// # Safety + /// + /// Same as [`Two::rfind_raw`], except the distance between `start` and + /// `end` must be at least the size of an SSE2 vector (in bytes). + /// + /// (The target feature safety obligation is automatically fulfilled by + /// virtue of being a method on `Two`, which can only be constructed + /// when it is safe to call `sse2`/`avx2` routines.) + #[target_feature(enable = "sse2")] + #[inline] + unsafe fn rfind_raw_sse2( + &self, + start: *const u8, + end: *const u8, + ) -> Option<*const u8> { + self.sse2.rfind_raw(start, end) + } + + /// Execute a search using AVX2 vectors and routines. + /// + /// # Safety + /// + /// Same as [`Two::find_raw`], except the distance between `start` and + /// `end` must be at least the size of an AVX2 vector (in bytes). + /// + /// (The target feature safety obligation is automatically fulfilled by + /// virtue of being a method on `Two`, which can only be constructed + /// when it is safe to call `sse2`/`avx2` routines.) + #[target_feature(enable = "avx2")] + #[inline] + unsafe fn find_raw_avx2( + &self, + start: *const u8, + end: *const u8, + ) -> Option<*const u8> { + self.avx2.find_raw(start, end) + } + + /// Execute a search using AVX2 vectors and routines. + /// + /// # Safety + /// + /// Same as [`Two::rfind_raw`], except the distance between `start` and + /// `end` must be at least the size of an AVX2 vector (in bytes). + /// + /// (The target feature safety obligation is automatically fulfilled by + /// virtue of being a method on `Two`, which can only be constructed + /// when it is safe to call `sse2`/`avx2` routines.) + #[target_feature(enable = "avx2")] + #[inline] + unsafe fn rfind_raw_avx2( + &self, + start: *const u8, + end: *const u8, + ) -> Option<*const u8> { + self.avx2.rfind_raw(start, end) + } + + /// Returns an iterator over all occurrences of the needle bytes in the + /// given haystack. + /// + /// The iterator returned implements `DoubleEndedIterator`. This means it + /// can also be used to find occurrences in reverse order. + #[inline] + pub fn iter<'a, 'h>(&'a self, haystack: &'h [u8]) -> TwoIter<'a, 'h> { + TwoIter { searcher: self, it: generic::Iter::new(haystack) } + } +} + +/// An iterator over all occurrences of two possible bytes in a haystack. +/// +/// This iterator implements `DoubleEndedIterator`, which means it can also be +/// used to find occurrences in reverse order. +/// +/// This iterator is created by the [`Two::iter`] method. +/// +/// The lifetime parameters are as follows: +/// +/// * `'a` refers to the lifetime of the underlying [`Two`] searcher. +/// * `'h` refers to the lifetime of the haystack being searched. +#[derive(Clone, Debug)] +pub struct TwoIter<'a, 'h> { + searcher: &'a Two, + it: generic::Iter<'h>, +} + +impl<'a, 'h> Iterator for TwoIter<'a, 'h> { + type Item = usize; + + #[inline] + fn next(&mut self) -> Option { + // SAFETY: We rely on the generic iterator to provide valid start + // and end pointers, but we guarantee that any pointer returned by + // 'find_raw' falls within the bounds of the start and end pointer. + unsafe { self.it.next(|s, e| self.searcher.find_raw(s, e)) } + } + + #[inline] + fn size_hint(&self) -> (usize, Option) { + self.it.size_hint() + } +} + +impl<'a, 'h> DoubleEndedIterator for TwoIter<'a, 'h> { + #[inline] + fn next_back(&mut self) -> Option { + // SAFETY: We rely on the generic iterator to provide valid start + // and end pointers, but we guarantee that any pointer returned by + // 'rfind_raw' falls within the bounds of the start and end pointer. + unsafe { self.it.next_back(|s, e| self.searcher.rfind_raw(s, e)) } + } +} + +impl<'a, 'h> core::iter::FusedIterator for TwoIter<'a, 'h> {} + +/// Finds all occurrences of three bytes in a haystack. +/// +/// That is, this reports matches of one of three possible bytes. For example, +/// searching for `a`, `b` or `o` in `afoobar` would report matches at offsets +/// `0`, `2`, `3`, `4` and `5`. +#[derive(Clone, Copy, Debug)] +pub struct Three { + /// Used for haystacks less than 32 bytes. + sse2: generic::Three<__m128i>, + /// Used for haystacks bigger than 32 bytes. + avx2: generic::Three<__m256i>, +} + +impl Three { + /// Create a new searcher that finds occurrences of the needle bytes given. + /// + /// This particular searcher is specialized to use AVX2 vector instructions + /// that typically make it quite fast. (SSE2 is used for haystacks that + /// are too short to accommodate an AVX2 vector.) + /// + /// If either SSE2 or AVX2 is unavailable in the current environment, then + /// `None` is returned. + #[inline] + pub fn new(needle1: u8, needle2: u8, needle3: u8) -> Option { + if Three::is_available() { + // SAFETY: we check that sse2 and avx2 are available above. + unsafe { Some(Three::new_unchecked(needle1, needle2, needle3)) } + } else { + None + } + } + + /// Create a new finder specific to AVX2 vectors and routines without + /// checking that either SSE2 or AVX2 is available. + /// + /// # Safety + /// + /// Callers must guarantee that it is safe to execute both `sse2` and + /// `avx2` instructions in the current environment. + /// + /// Note that it is a common misconception that if one compiles for an + /// `x86_64` target, then they therefore automatically have access to SSE2 + /// instructions. While this is almost always the case, it isn't true in + /// 100% of cases. + #[target_feature(enable = "sse2", enable = "avx2")] + #[inline] + pub unsafe fn new_unchecked( + needle1: u8, + needle2: u8, + needle3: u8, + ) -> Three { + Three { + sse2: generic::Three::new(needle1, needle2, needle3), + avx2: generic::Three::new(needle1, needle2, needle3), + } + } + + /// Returns true when this implementation is available in the current + /// environment. + /// + /// When this is true, it is guaranteed that [`Three::new`] will return + /// a `Some` value. Similarly, when it is false, it is guaranteed that + /// `Three::new` will return a `None` value. + /// + /// Note also that for the lifetime of a single program, if this returns + /// true then it will always return true. + #[inline] + pub fn is_available() -> bool { + #[cfg(not(target_feature = "sse2"))] + { + false + } + #[cfg(target_feature = "sse2")] + { + #[cfg(target_feature = "avx2")] + { + true + } + #[cfg(not(target_feature = "avx2"))] + { + #[cfg(feature = "std")] + { + std::is_x86_feature_detected!("avx2") + } + #[cfg(not(feature = "std"))] + { + false + } + } + } + } + + /// Return the first occurrence of one of the needle bytes in the given + /// haystack. If no such occurrence exists, then `None` is returned. + /// + /// The occurrence is reported as an offset into `haystack`. Its maximum + /// value is `haystack.len() - 1`. + #[inline] + pub fn find(&self, haystack: &[u8]) -> Option { + // SAFETY: `find_raw` guarantees that if a pointer is returned, it + // falls within the bounds of the start and end pointers. + unsafe { + generic::search_slice_with_raw(haystack, |s, e| { + self.find_raw(s, e) + }) + } + } + + /// Return the last occurrence of one of the needle bytes in the given + /// haystack. If no such occurrence exists, then `None` is returned. + /// + /// The occurrence is reported as an offset into `haystack`. Its maximum + /// value is `haystack.len() - 1`. + #[inline] + pub fn rfind(&self, haystack: &[u8]) -> Option { + // SAFETY: `find_raw` guarantees that if a pointer is returned, it + // falls within the bounds of the start and end pointers. + unsafe { + generic::search_slice_with_raw(haystack, |s, e| { + self.rfind_raw(s, e) + }) + } + } + + /// Like `find`, but accepts and returns raw pointers. + /// + /// When a match is found, the pointer returned is guaranteed to be + /// `>= start` and `< end`. + /// + /// This routine is useful if you're already using raw pointers and would + /// like to avoid converting back to a slice before executing a search. + /// + /// # Safety + /// + /// * Both `start` and `end` must be valid for reads. + /// * Both `start` and `end` must point to an initialized value. + /// * Both `start` and `end` must point to the same allocated object and + /// must either be in bounds or at most one byte past the end of the + /// allocated object. + /// * Both `start` and `end` must be _derived from_ a pointer to the same + /// object. + /// * The distance between `start` and `end` must not overflow `isize`. + /// * The distance being in bounds must not rely on "wrapping around" the + /// address space. + /// + /// Note that callers may pass a pair of pointers such that `start >= end`. + /// In that case, `None` will always be returned. + #[inline] + pub unsafe fn find_raw( + &self, + start: *const u8, + end: *const u8, + ) -> Option<*const u8> { + if start >= end { + return None; + } + let len = end.distance(start); + if len < __m256i::BYTES { + return if len < __m128i::BYTES { + // SAFETY: We require the caller to pass valid start/end + // pointers. + generic::fwd_byte_by_byte(start, end, |b| { + b == self.sse2.needle1() + || b == self.sse2.needle2() + || b == self.sse2.needle3() + }) + } else { + // SAFETY: We require the caller to pass valid start/end + // pointers. + self.find_raw_sse2(start, end) + }; + } + // SAFETY: Building a `Three` means it's safe to call both 'sse2' and + // 'avx2' routines. Also, we've checked that our haystack is big + // enough to run on the vector routine. Pointer validity is caller's + // responsibility. + // + // Note that we could call `self.avx2.find_raw` directly here. But that + // means we'd have to annotate this routine with `target_feature`. + // Which is fine, because this routine is `unsafe` anyway and the + // `target_feature` obligation is met by virtue of building a `Three`. + // The real problem is that a routine with a `target_feature` + // annotation generally can't be inlined into caller code unless + // the caller code has the same target feature annotations. Namely, + // the common case (at time of writing) is for calling code to not + // have the `avx2` target feature enabled *at compile time*. Without + // `target_feature` on this routine, it can be inlined which will + // handle some of the short-haystack cases above without touching the + // architecture specific code. + self.find_raw_avx2(start, end) + } + + /// Like `rfind`, but accepts and returns raw pointers. + /// + /// When a match is found, the pointer returned is guaranteed to be + /// `>= start` and `< end`. + /// + /// This routine is useful if you're already using raw pointers and would + /// like to avoid converting back to a slice before executing a search. + /// + /// # Safety + /// + /// * Both `start` and `end` must be valid for reads. + /// * Both `start` and `end` must point to an initialized value. + /// * Both `start` and `end` must point to the same allocated object and + /// must either be in bounds or at most one byte past the end of the + /// allocated object. + /// * Both `start` and `end` must be _derived from_ a pointer to the same + /// object. + /// * The distance between `start` and `end` must not overflow `isize`. + /// * The distance being in bounds must not rely on "wrapping around" the + /// address space. + /// + /// Note that callers may pass a pair of pointers such that `start >= end`. + /// In that case, `None` will always be returned. + #[inline] + pub unsafe fn rfind_raw( + &self, + start: *const u8, + end: *const u8, + ) -> Option<*const u8> { + if start >= end { + return None; + } + let len = end.distance(start); + if len < __m256i::BYTES { + return if len < __m128i::BYTES { + // SAFETY: We require the caller to pass valid start/end + // pointers. + generic::rev_byte_by_byte(start, end, |b| { + b == self.sse2.needle1() + || b == self.sse2.needle2() + || b == self.sse2.needle3() + }) + } else { + // SAFETY: We require the caller to pass valid start/end + // pointers. + self.rfind_raw_sse2(start, end) + }; + } + // SAFETY: Building a `Three` means it's safe to call both 'sse2' and + // 'avx2' routines. Also, we've checked that our haystack is big + // enough to run on the vector routine. Pointer validity is caller's + // responsibility. + // + // See note in forward routine above for why we don't just call + // `self.avx2.rfind_raw` directly here. + self.rfind_raw_avx2(start, end) + } + + /// Execute a search using SSE2 vectors and routines. + /// + /// # Safety + /// + /// Same as [`Three::find_raw`], except the distance between `start` and + /// `end` must be at least the size of an SSE2 vector (in bytes). + /// + /// (The target feature safety obligation is automatically fulfilled by + /// virtue of being a method on `Three`, which can only be constructed + /// when it is safe to call `sse2`/`avx2` routines.) + #[target_feature(enable = "sse2")] + #[inline] + unsafe fn find_raw_sse2( + &self, + start: *const u8, + end: *const u8, + ) -> Option<*const u8> { + self.sse2.find_raw(start, end) + } + + /// Execute a search using SSE2 vectors and routines. + /// + /// # Safety + /// + /// Same as [`Three::rfind_raw`], except the distance between `start` and + /// `end` must be at least the size of an SSE2 vector (in bytes). + /// + /// (The target feature safety obligation is automatically fulfilled by + /// virtue of being a method on `Three`, which can only be constructed + /// when it is safe to call `sse2`/`avx2` routines.) + #[target_feature(enable = "sse2")] + #[inline] + unsafe fn rfind_raw_sse2( + &self, + start: *const u8, + end: *const u8, + ) -> Option<*const u8> { + self.sse2.rfind_raw(start, end) + } + + /// Execute a search using AVX2 vectors and routines. + /// + /// # Safety + /// + /// Same as [`Three::find_raw`], except the distance between `start` and + /// `end` must be at least the size of an AVX2 vector (in bytes). + /// + /// (The target feature safety obligation is automatically fulfilled by + /// virtue of being a method on `Three`, which can only be constructed + /// when it is safe to call `sse2`/`avx2` routines.) + #[target_feature(enable = "avx2")] + #[inline] + unsafe fn find_raw_avx2( + &self, + start: *const u8, + end: *const u8, + ) -> Option<*const u8> { + self.avx2.find_raw(start, end) + } + + /// Execute a search using AVX2 vectors and routines. + /// + /// # Safety + /// + /// Same as [`Three::rfind_raw`], except the distance between `start` and + /// `end` must be at least the size of an AVX2 vector (in bytes). + /// + /// (The target feature safety obligation is automatically fulfilled by + /// virtue of being a method on `Three`, which can only be constructed + /// when it is safe to call `sse2`/`avx2` routines.) + #[target_feature(enable = "avx2")] + #[inline] + unsafe fn rfind_raw_avx2( + &self, + start: *const u8, + end: *const u8, + ) -> Option<*const u8> { + self.avx2.rfind_raw(start, end) + } + + /// Returns an iterator over all occurrences of the needle bytes in the + /// given haystack. + /// + /// The iterator returned implements `DoubleEndedIterator`. This means it + /// can also be used to find occurrences in reverse order. + #[inline] + pub fn iter<'a, 'h>(&'a self, haystack: &'h [u8]) -> ThreeIter<'a, 'h> { + ThreeIter { searcher: self, it: generic::Iter::new(haystack) } + } +} + +/// An iterator over all occurrences of three possible bytes in a haystack. +/// +/// This iterator implements `DoubleEndedIterator`, which means it can also be +/// used to find occurrences in reverse order. +/// +/// This iterator is created by the [`Three::iter`] method. +/// +/// The lifetime parameters are as follows: +/// +/// * `'a` refers to the lifetime of the underlying [`Three`] searcher. +/// * `'h` refers to the lifetime of the haystack being searched. +#[derive(Clone, Debug)] +pub struct ThreeIter<'a, 'h> { + searcher: &'a Three, + it: generic::Iter<'h>, +} + +impl<'a, 'h> Iterator for ThreeIter<'a, 'h> { + type Item = usize; + + #[inline] + fn next(&mut self) -> Option { + // SAFETY: We rely on the generic iterator to provide valid start + // and end pointers, but we guarantee that any pointer returned by + // 'find_raw' falls within the bounds of the start and end pointer. + unsafe { self.it.next(|s, e| self.searcher.find_raw(s, e)) } + } + + #[inline] + fn size_hint(&self) -> (usize, Option) { + self.it.size_hint() + } +} + +impl<'a, 'h> DoubleEndedIterator for ThreeIter<'a, 'h> { + #[inline] + fn next_back(&mut self) -> Option { + // SAFETY: We rely on the generic iterator to provide valid start + // and end pointers, but we guarantee that any pointer returned by + // 'rfind_raw' falls within the bounds of the start and end pointer. + unsafe { self.it.next_back(|s, e| self.searcher.rfind_raw(s, e)) } + } +} + +impl<'a, 'h> core::iter::FusedIterator for ThreeIter<'a, 'h> {} + +#[cfg(test)] +mod tests { + use super::*; + + define_memchr_quickcheck!(super); + + #[test] + fn forward_one() { + crate::tests::memchr::Runner::new(1).forward_iter( + |haystack, needles| { + Some(One::new(needles[0])?.iter(haystack).collect()) + }, + ) + } + + #[test] + fn reverse_one() { + crate::tests::memchr::Runner::new(1).reverse_iter( + |haystack, needles| { + Some(One::new(needles[0])?.iter(haystack).rev().collect()) + }, + ) + } + + #[test] + fn count_one() { + crate::tests::memchr::Runner::new(1).count_iter(|haystack, needles| { + Some(One::new(needles[0])?.iter(haystack).count()) + }) + } + + #[test] + fn forward_two() { + crate::tests::memchr::Runner::new(2).forward_iter( + |haystack, needles| { + let n1 = needles.get(0).copied()?; + let n2 = needles.get(1).copied()?; + Some(Two::new(n1, n2)?.iter(haystack).collect()) + }, + ) + } + + #[test] + fn reverse_two() { + crate::tests::memchr::Runner::new(2).reverse_iter( + |haystack, needles| { + let n1 = needles.get(0).copied()?; + let n2 = needles.get(1).copied()?; + Some(Two::new(n1, n2)?.iter(haystack).rev().collect()) + }, + ) + } + + #[test] + fn forward_three() { + crate::tests::memchr::Runner::new(3).forward_iter( + |haystack, needles| { + let n1 = needles.get(0).copied()?; + let n2 = needles.get(1).copied()?; + let n3 = needles.get(2).copied()?; + Some(Three::new(n1, n2, n3)?.iter(haystack).collect()) + }, + ) + } + + #[test] + fn reverse_three() { + crate::tests::memchr::Runner::new(3).reverse_iter( + |haystack, needles| { + let n1 = needles.get(0).copied()?; + let n2 = needles.get(1).copied()?; + let n3 = needles.get(2).copied()?; + Some(Three::new(n1, n2, n3)?.iter(haystack).rev().collect()) + }, + ) + } +} diff --git a/vendor/memchr/src/arch/x86_64/avx2/mod.rs b/vendor/memchr/src/arch/x86_64/avx2/mod.rs new file mode 100644 index 0000000..ee4097d --- /dev/null +++ b/vendor/memchr/src/arch/x86_64/avx2/mod.rs @@ -0,0 +1,6 @@ +/*! +Algorithms for the `x86_64` target using 256-bit vectors via AVX2. +*/ + +pub mod memchr; +pub mod packedpair; diff --git a/vendor/memchr/src/arch/x86_64/avx2/packedpair.rs b/vendor/memchr/src/arch/x86_64/avx2/packedpair.rs new file mode 100644 index 0000000..efae7b6 --- /dev/null +++ b/vendor/memchr/src/arch/x86_64/avx2/packedpair.rs @@ -0,0 +1,272 @@ +/*! +A 256-bit vector implementation of the "packed pair" SIMD algorithm. + +The "packed pair" algorithm is based on the [generic SIMD] algorithm. The main +difference is that it (by default) uses a background distribution of byte +frequencies to heuristically select the pair of bytes to search for. + +[generic SIMD]: http://0x80.pl/articles/simd-strfind.html#first-and-last +*/ + +use core::arch::x86_64::{__m128i, __m256i}; + +use crate::arch::{all::packedpair::Pair, generic::packedpair}; + +/// A "packed pair" finder that uses 256-bit vector operations. +/// +/// This finder picks two bytes that it believes have high predictive power +/// for indicating an overall match of a needle. Depending on whether +/// `Finder::find` or `Finder::find_prefilter` is used, it reports offsets +/// where the needle matches or could match. In the prefilter case, candidates +/// are reported whenever the [`Pair`] of bytes given matches. +#[derive(Clone, Copy, Debug)] +pub struct Finder { + sse2: packedpair::Finder<__m128i>, + avx2: packedpair::Finder<__m256i>, +} + +impl Finder { + /// Create a new pair searcher. The searcher returned can either report + /// exact matches of `needle` or act as a prefilter and report candidate + /// positions of `needle`. + /// + /// If AVX2 is unavailable in the current environment or if a [`Pair`] + /// could not be constructed from the needle given, then `None` is + /// returned. + #[inline] + pub fn new(needle: &[u8]) -> Option { + Finder::with_pair(needle, Pair::new(needle)?) + } + + /// Create a new "packed pair" finder using the pair of bytes given. + /// + /// This constructor permits callers to control precisely which pair of + /// bytes is used as a predicate. + /// + /// If AVX2 is unavailable in the current environment, then `None` is + /// returned. + #[inline] + pub fn with_pair(needle: &[u8], pair: Pair) -> Option { + if Finder::is_available() { + // SAFETY: we check that sse2/avx2 is available above. We are also + // guaranteed to have needle.len() > 1 because we have a valid + // Pair. + unsafe { Some(Finder::with_pair_impl(needle, pair)) } + } else { + None + } + } + + /// Create a new `Finder` specific to SSE2 vectors and routines. + /// + /// # Safety + /// + /// Same as the safety for `packedpair::Finder::new`, and callers must also + /// ensure that both SSE2 and AVX2 are available. + #[target_feature(enable = "sse2", enable = "avx2")] + #[inline] + unsafe fn with_pair_impl(needle: &[u8], pair: Pair) -> Finder { + let sse2 = packedpair::Finder::<__m128i>::new(needle, pair); + let avx2 = packedpair::Finder::<__m256i>::new(needle, pair); + Finder { sse2, avx2 } + } + + /// Returns true when this implementation is available in the current + /// environment. + /// + /// When this is true, it is guaranteed that [`Finder::with_pair`] will + /// return a `Some` value. Similarly, when it is false, it is guaranteed + /// that `Finder::with_pair` will return a `None` value. Notice that this + /// does not guarantee that [`Finder::new`] will return a `Finder`. Namely, + /// even when `Finder::is_available` is true, it is not guaranteed that a + /// valid [`Pair`] can be found from the needle given. + /// + /// Note also that for the lifetime of a single program, if this returns + /// true then it will always return true. + #[inline] + pub fn is_available() -> bool { + #[cfg(not(target_feature = "sse2"))] + { + false + } + #[cfg(target_feature = "sse2")] + { + #[cfg(target_feature = "avx2")] + { + true + } + #[cfg(not(target_feature = "avx2"))] + { + #[cfg(feature = "std")] + { + std::is_x86_feature_detected!("avx2") + } + #[cfg(not(feature = "std"))] + { + false + } + } + } + } + + /// Execute a search using AVX2 vectors and routines. + /// + /// # Panics + /// + /// When `haystack.len()` is less than [`Finder::min_haystack_len`]. + #[inline] + pub fn find(&self, haystack: &[u8], needle: &[u8]) -> Option { + // SAFETY: Building a `Finder` means it's safe to call 'sse2' routines. + unsafe { self.find_impl(haystack, needle) } + } + + /// Run this finder on the given haystack as a prefilter. + /// + /// If a candidate match is found, then an offset where the needle *could* + /// begin in the haystack is returned. + /// + /// # Panics + /// + /// When `haystack.len()` is less than [`Finder::min_haystack_len`]. + #[inline] + pub fn find_prefilter(&self, haystack: &[u8]) -> Option { + // SAFETY: Building a `Finder` means it's safe to call 'sse2' routines. + unsafe { self.find_prefilter_impl(haystack) } + } + + /// Execute a search using AVX2 vectors and routines. + /// + /// # Panics + /// + /// When `haystack.len()` is less than [`Finder::min_haystack_len`]. + /// + /// # Safety + /// + /// (The target feature safety obligation is automatically fulfilled by + /// virtue of being a method on `Finder`, which can only be constructed + /// when it is safe to call `sse2` and `avx2` routines.) + #[target_feature(enable = "sse2", enable = "avx2")] + #[inline] + unsafe fn find_impl( + &self, + haystack: &[u8], + needle: &[u8], + ) -> Option { + if haystack.len() < self.avx2.min_haystack_len() { + self.sse2.find(haystack, needle) + } else { + self.avx2.find(haystack, needle) + } + } + + /// Execute a prefilter search using AVX2 vectors and routines. + /// + /// # Panics + /// + /// When `haystack.len()` is less than [`Finder::min_haystack_len`]. + /// + /// # Safety + /// + /// (The target feature safety obligation is automatically fulfilled by + /// virtue of being a method on `Finder`, which can only be constructed + /// when it is safe to call `sse2` and `avx2` routines.) + #[target_feature(enable = "sse2", enable = "avx2")] + #[inline] + unsafe fn find_prefilter_impl(&self, haystack: &[u8]) -> Option { + if haystack.len() < self.avx2.min_haystack_len() { + self.sse2.find_prefilter(haystack) + } else { + self.avx2.find_prefilter(haystack) + } + } + + /// Returns the pair of offsets (into the needle) used to check as a + /// predicate before confirming whether a needle exists at a particular + /// position. + #[inline] + pub fn pair(&self) -> &Pair { + self.avx2.pair() + } + + /// Returns the minimum haystack length that this `Finder` can search. + /// + /// Using a haystack with length smaller than this in a search will result + /// in a panic. The reason for this restriction is that this finder is + /// meant to be a low-level component that is part of a larger substring + /// strategy. In that sense, it avoids trying to handle all cases and + /// instead only handles the cases that it can handle very well. + #[inline] + pub fn min_haystack_len(&self) -> usize { + // The caller doesn't need to care about AVX2's min_haystack_len + // since this implementation will automatically switch to the SSE2 + // implementation if the haystack is too short for AVX2. Therefore, the + // caller only needs to care about SSE2's min_haystack_len. + // + // This does assume that SSE2's min_haystack_len is less than or + // equal to AVX2's min_haystack_len. In practice, this is true and + // there is no way it could be false based on how this Finder is + // implemented. Namely, both SSE2 and AVX2 use the same `Pair`. If + // they used different pairs, then it's possible (although perhaps + // pathological) for SSE2's min_haystack_len to be bigger than AVX2's. + self.sse2.min_haystack_len() + } +} + +#[cfg(test)] +mod tests { + use super::*; + + fn find(haystack: &[u8], needle: &[u8]) -> Option> { + let f = Finder::new(needle)?; + if haystack.len() < f.min_haystack_len() { + return None; + } + Some(f.find(haystack, needle)) + } + + define_substring_forward_quickcheck!(find); + + #[test] + fn forward_substring() { + crate::tests::substring::Runner::new().fwd(find).run() + } + + #[test] + fn forward_packedpair() { + fn find( + haystack: &[u8], + needle: &[u8], + index1: u8, + index2: u8, + ) -> Option> { + let pair = Pair::with_indices(needle, index1, index2)?; + let f = Finder::with_pair(needle, pair)?; + if haystack.len() < f.min_haystack_len() { + return None; + } + Some(f.find(haystack, needle)) + } + crate::tests::packedpair::Runner::new().fwd(find).run() + } + + #[test] + fn forward_packedpair_prefilter() { + fn find( + haystack: &[u8], + needle: &[u8], + index1: u8, + index2: u8, + ) -> Option> { + if !cfg!(target_feature = "sse2") { + return None; + } + let pair = Pair::with_indices(needle, index1, index2)?; + let f = Finder::with_pair(needle, pair)?; + if haystack.len() < f.min_haystack_len() { + return None; + } + Some(f.find_prefilter(haystack)) + } + crate::tests::packedpair::Runner::new().fwd(find).run() + } +} diff --git a/vendor/memchr/src/arch/x86_64/memchr.rs b/vendor/memchr/src/arch/x86_64/memchr.rs new file mode 100644 index 0000000..fcb1399 --- /dev/null +++ b/vendor/memchr/src/arch/x86_64/memchr.rs @@ -0,0 +1,335 @@ +/*! +Wrapper routines for `memchr` and friends. + +These routines efficiently dispatch to the best implementation based on what +the CPU supports. +*/ + +/// Provides a way to run a memchr-like function while amortizing the cost of +/// runtime CPU feature detection. +/// +/// This works by loading a function pointer from an atomic global. Initially, +/// this global is set to a function that does CPU feature detection. For +/// example, if AVX2 is enabled, then the AVX2 implementation is used. +/// Otherwise, at least on x86_64, the SSE2 implementation is used. (And +/// in some niche cases, if SSE2 isn't available, then the architecture +/// independent fallback implementation is used.) +/// +/// After the first call to this function, the atomic global is replaced with +/// the specific AVX2, SSE2 or fallback routine chosen. Subsequent calls then +/// will directly call the chosen routine instead of needing to go through the +/// CPU feature detection branching again. +/// +/// This particular macro is specifically written to provide the implementation +/// of functions with the following signature: +/// +/// ```ignore +/// fn memchr(needle1: u8, start: *const u8, end: *const u8) -> Option; +/// ``` +/// +/// Where you can also have `memchr2` and `memchr3`, but with `needle2` and +/// `needle3`, respectively. The `start` and `end` parameters correspond to the +/// start and end of the haystack, respectively. +/// +/// We use raw pointers here instead of the more obvious `haystack: &[u8]` so +/// that the function is compatible with our lower level iterator logic that +/// operates on raw pointers. We use this macro to implement "raw" memchr +/// routines with the signature above, and then define memchr routines using +/// regular slices on top of them. +/// +/// Note that we use `#[cfg(target_feature = "sse2")]` below even though +/// it shouldn't be strictly necessary because without it, it seems to +/// cause the compiler to blow up. I guess it can't handle a function +/// pointer being created with a sse target feature? Dunno. See the +/// `build-for-x86-64-but-non-sse-target` CI job if you want to experiment with +/// this. +/// +/// # Safety +/// +/// Primarily callers must that `$fnty` is a correct function pointer type and +/// not something else. +/// +/// Callers must also ensure that `$memchrty::$memchrfind` corresponds to a +/// routine that returns a valid function pointer when a match is found. That +/// is, a pointer that is `>= start` and `< end`. +/// +/// Callers must also ensure that the `$hay_start` and `$hay_end` identifiers +/// correspond to valid pointers. +macro_rules! unsafe_ifunc { + ( + $memchrty:ident, + $memchrfind:ident, + $fnty:ty, + $retty:ty, + $hay_start:ident, + $hay_end:ident, + $($needle:ident),+ + ) => {{ + #![allow(unused_unsafe)] + + use core::sync::atomic::{AtomicPtr, Ordering}; + + type Fn = *mut (); + type RealFn = $fnty; + static FN: AtomicPtr<()> = AtomicPtr::new(detect as Fn); + + #[cfg(target_feature = "sse2")] + #[target_feature(enable = "sse2", enable = "avx2")] + unsafe fn find_avx2( + $($needle: u8),+, + $hay_start: *const u8, + $hay_end: *const u8, + ) -> $retty { + use crate::arch::x86_64::avx2::memchr::$memchrty; + $memchrty::new_unchecked($($needle),+) + .$memchrfind($hay_start, $hay_end) + } + + #[cfg(target_feature = "sse2")] + #[target_feature(enable = "sse2")] + unsafe fn find_sse2( + $($needle: u8),+, + $hay_start: *const u8, + $hay_end: *const u8, + ) -> $retty { + use crate::arch::x86_64::sse2::memchr::$memchrty; + $memchrty::new_unchecked($($needle),+) + .$memchrfind($hay_start, $hay_end) + } + + unsafe fn find_fallback( + $($needle: u8),+, + $hay_start: *const u8, + $hay_end: *const u8, + ) -> $retty { + use crate::arch::all::memchr::$memchrty; + $memchrty::new($($needle),+).$memchrfind($hay_start, $hay_end) + } + + unsafe fn detect( + $($needle: u8),+, + $hay_start: *const u8, + $hay_end: *const u8, + ) -> $retty { + let fun = { + #[cfg(not(target_feature = "sse2"))] + { + debug!( + "no sse2 feature available, using fallback for {}", + stringify!($memchrty), + ); + find_fallback as RealFn + } + #[cfg(target_feature = "sse2")] + { + use crate::arch::x86_64::{sse2, avx2}; + if avx2::memchr::$memchrty::is_available() { + debug!("chose AVX2 for {}", stringify!($memchrty)); + find_avx2 as RealFn + } else if sse2::memchr::$memchrty::is_available() { + debug!("chose SSE2 for {}", stringify!($memchrty)); + find_sse2 as RealFn + } else { + debug!("chose fallback for {}", stringify!($memchrty)); + find_fallback as RealFn + } + } + }; + FN.store(fun as Fn, Ordering::Relaxed); + // SAFETY: The only thing we need to uphold here is the + // `#[target_feature]` requirements. Since we check is_available + // above before using the corresponding implementation, we are + // guaranteed to only call code that is supported on the current + // CPU. + fun($($needle),+, $hay_start, $hay_end) + } + + // SAFETY: By virtue of the caller contract, RealFn is a function + // pointer, which is always safe to transmute with a *mut (). Also, + // since we use $memchrty::is_available, it is guaranteed to be safe + // to call $memchrty::$memchrfind. + unsafe { + let fun = FN.load(Ordering::Relaxed); + core::mem::transmute::(fun)( + $($needle),+, + $hay_start, + $hay_end, + ) + } + }}; +} + +// The routines below dispatch to AVX2, SSE2 or a fallback routine based on +// what's available in the current environment. The secret sauce here is that +// we only check for which one to use approximately once, and then "cache" that +// choice into a global function pointer. Subsequent invocations then just call +// the appropriate function directly. + +/// memchr, but using raw pointers to represent the haystack. +/// +/// # Safety +/// +/// Pointers must be valid. See `One::find_raw`. +#[inline(always)] +pub(crate) fn memchr_raw( + n1: u8, + start: *const u8, + end: *const u8, +) -> Option<*const u8> { + // SAFETY: We provide a valid function pointer type. + unsafe_ifunc!( + One, + find_raw, + unsafe fn(u8, *const u8, *const u8) -> Option<*const u8>, + Option<*const u8>, + start, + end, + n1 + ) +} + +/// memrchr, but using raw pointers to represent the haystack. +/// +/// # Safety +/// +/// Pointers must be valid. See `One::rfind_raw`. +#[inline(always)] +pub(crate) fn memrchr_raw( + n1: u8, + start: *const u8, + end: *const u8, +) -> Option<*const u8> { + // SAFETY: We provide a valid function pointer type. + unsafe_ifunc!( + One, + rfind_raw, + unsafe fn(u8, *const u8, *const u8) -> Option<*const u8>, + Option<*const u8>, + start, + end, + n1 + ) +} + +/// memchr2, but using raw pointers to represent the haystack. +/// +/// # Safety +/// +/// Pointers must be valid. See `Two::find_raw`. +#[inline(always)] +pub(crate) fn memchr2_raw( + n1: u8, + n2: u8, + start: *const u8, + end: *const u8, +) -> Option<*const u8> { + // SAFETY: We provide a valid function pointer type. + unsafe_ifunc!( + Two, + find_raw, + unsafe fn(u8, u8, *const u8, *const u8) -> Option<*const u8>, + Option<*const u8>, + start, + end, + n1, + n2 + ) +} + +/// memrchr2, but using raw pointers to represent the haystack. +/// +/// # Safety +/// +/// Pointers must be valid. See `Two::rfind_raw`. +#[inline(always)] +pub(crate) fn memrchr2_raw( + n1: u8, + n2: u8, + start: *const u8, + end: *const u8, +) -> Option<*const u8> { + // SAFETY: We provide a valid function pointer type. + unsafe_ifunc!( + Two, + rfind_raw, + unsafe fn(u8, u8, *const u8, *const u8) -> Option<*const u8>, + Option<*const u8>, + start, + end, + n1, + n2 + ) +} + +/// memchr3, but using raw pointers to represent the haystack. +/// +/// # Safety +/// +/// Pointers must be valid. See `Three::find_raw`. +#[inline(always)] +pub(crate) fn memchr3_raw( + n1: u8, + n2: u8, + n3: u8, + start: *const u8, + end: *const u8, +) -> Option<*const u8> { + // SAFETY: We provide a valid function pointer type. + unsafe_ifunc!( + Three, + find_raw, + unsafe fn(u8, u8, u8, *const u8, *const u8) -> Option<*const u8>, + Option<*const u8>, + start, + end, + n1, + n2, + n3 + ) +} + +/// memrchr3, but using raw pointers to represent the haystack. +/// +/// # Safety +/// +/// Pointers must be valid. See `Three::rfind_raw`. +#[inline(always)] +pub(crate) fn memrchr3_raw( + n1: u8, + n2: u8, + n3: u8, + start: *const u8, + end: *const u8, +) -> Option<*const u8> { + // SAFETY: We provide a valid function pointer type. + unsafe_ifunc!( + Three, + rfind_raw, + unsafe fn(u8, u8, u8, *const u8, *const u8) -> Option<*const u8>, + Option<*const u8>, + start, + end, + n1, + n2, + n3 + ) +} + +/// Count all matching bytes, but using raw pointers to represent the haystack. +/// +/// # Safety +/// +/// Pointers must be valid. See `One::count_raw`. +#[inline(always)] +pub(crate) fn count_raw(n1: u8, start: *const u8, end: *const u8) -> usize { + // SAFETY: We provide a valid function pointer type. + unsafe_ifunc!( + One, + count_raw, + unsafe fn(u8, *const u8, *const u8) -> usize, + usize, + start, + end, + n1 + ) +} diff --git a/vendor/memchr/src/arch/x86_64/mod.rs b/vendor/memchr/src/arch/x86_64/mod.rs new file mode 100644 index 0000000..5dad721 --- /dev/null +++ b/vendor/memchr/src/arch/x86_64/mod.rs @@ -0,0 +1,8 @@ +/*! +Vector algorithms for the `x86_64` target. +*/ + +pub mod avx2; +pub mod sse2; + +pub(crate) mod memchr; diff --git a/vendor/memchr/src/arch/x86_64/sse2/memchr.rs b/vendor/memchr/src/arch/x86_64/sse2/memchr.rs new file mode 100644 index 0000000..c6f75df --- /dev/null +++ b/vendor/memchr/src/arch/x86_64/sse2/memchr.rs @@ -0,0 +1,1077 @@ +/*! +This module defines 128-bit vector implementations of `memchr` and friends. + +The main types in this module are [`One`], [`Two`] and [`Three`]. They are for +searching for one, two or three distinct bytes, respectively, in a haystack. +Each type also has corresponding double ended iterators. These searchers are +typically much faster than scalar routines accomplishing the same task. + +The `One` searcher also provides a [`One::count`] routine for efficiently +counting the number of times a single byte occurs in a haystack. This is +useful, for example, for counting the number of lines in a haystack. This +routine exists because it is usually faster, especially with a high match +count, then using [`One::find`] repeatedly. ([`OneIter`] specializes its +`Iterator::count` implementation to use this routine.) + +Only one, two and three bytes are supported because three bytes is about +the point where one sees diminishing returns. Beyond this point and it's +probably (but not necessarily) better to just use a simple `[bool; 256]` array +or similar. However, it depends mightily on the specific work-load and the +expected match frequency. +*/ + +use core::arch::x86_64::__m128i; + +use crate::{arch::generic::memchr as generic, ext::Pointer, vector::Vector}; + +/// Finds all occurrences of a single byte in a haystack. +#[derive(Clone, Copy, Debug)] +pub struct One(generic::One<__m128i>); + +impl One { + /// Create a new searcher that finds occurrences of the needle byte given. + /// + /// This particular searcher is specialized to use SSE2 vector instructions + /// that typically make it quite fast. + /// + /// If SSE2 is unavailable in the current environment, then `None` is + /// returned. + #[inline] + pub fn new(needle: u8) -> Option { + if One::is_available() { + // SAFETY: we check that sse2 is available above. + unsafe { Some(One::new_unchecked(needle)) } + } else { + None + } + } + + /// Create a new finder specific to SSE2 vectors and routines without + /// checking that SSE2 is available. + /// + /// # Safety + /// + /// Callers must guarantee that it is safe to execute `sse2` instructions + /// in the current environment. + /// + /// Note that it is a common misconception that if one compiles for an + /// `x86_64` target, then they therefore automatically have access to SSE2 + /// instructions. While this is almost always the case, it isn't true in + /// 100% of cases. + #[target_feature(enable = "sse2")] + #[inline] + pub unsafe fn new_unchecked(needle: u8) -> One { + One(generic::One::new(needle)) + } + + /// Returns true when this implementation is available in the current + /// environment. + /// + /// When this is true, it is guaranteed that [`One::new`] will return + /// a `Some` value. Similarly, when it is false, it is guaranteed that + /// `One::new` will return a `None` value. + /// + /// Note also that for the lifetime of a single program, if this returns + /// true then it will always return true. + #[inline] + pub fn is_available() -> bool { + #[cfg(target_feature = "sse2")] + { + true + } + #[cfg(not(target_feature = "sse2"))] + { + false + } + } + + /// Return the first occurrence of one of the needle bytes in the given + /// haystack. If no such occurrence exists, then `None` is returned. + /// + /// The occurrence is reported as an offset into `haystack`. Its maximum + /// value is `haystack.len() - 1`. + #[inline] + pub fn find(&self, haystack: &[u8]) -> Option { + // SAFETY: `find_raw` guarantees that if a pointer is returned, it + // falls within the bounds of the start and end pointers. + unsafe { + generic::search_slice_with_raw(haystack, |s, e| { + self.find_raw(s, e) + }) + } + } + + /// Return the last occurrence of one of the needle bytes in the given + /// haystack. If no such occurrence exists, then `None` is returned. + /// + /// The occurrence is reported as an offset into `haystack`. Its maximum + /// value is `haystack.len() - 1`. + #[inline] + pub fn rfind(&self, haystack: &[u8]) -> Option { + // SAFETY: `rfind_raw` guarantees that if a pointer is returned, it + // falls within the bounds of the start and end pointers. + unsafe { + generic::search_slice_with_raw(haystack, |s, e| { + self.rfind_raw(s, e) + }) + } + } + + /// Counts all occurrences of this byte in the given haystack. + #[inline] + pub fn count(&self, haystack: &[u8]) -> usize { + // SAFETY: All of our pointers are derived directly from a borrowed + // slice, which is guaranteed to be valid. + unsafe { + let start = haystack.as_ptr(); + let end = start.add(haystack.len()); + self.count_raw(start, end) + } + } + + /// Like `find`, but accepts and returns raw pointers. + /// + /// When a match is found, the pointer returned is guaranteed to be + /// `>= start` and `< end`. + /// + /// This routine is useful if you're already using raw pointers and would + /// like to avoid converting back to a slice before executing a search. + /// + /// # Safety + /// + /// * Both `start` and `end` must be valid for reads. + /// * Both `start` and `end` must point to an initialized value. + /// * Both `start` and `end` must point to the same allocated object and + /// must either be in bounds or at most one byte past the end of the + /// allocated object. + /// * Both `start` and `end` must be _derived from_ a pointer to the same + /// object. + /// * The distance between `start` and `end` must not overflow `isize`. + /// * The distance being in bounds must not rely on "wrapping around" the + /// address space. + /// + /// Note that callers may pass a pair of pointers such that `start >= end`. + /// In that case, `None` will always be returned. + #[inline] + pub unsafe fn find_raw( + &self, + start: *const u8, + end: *const u8, + ) -> Option<*const u8> { + if start >= end { + return None; + } + if end.distance(start) < __m128i::BYTES { + // SAFETY: We require the caller to pass valid start/end pointers. + return generic::fwd_byte_by_byte(start, end, |b| { + b == self.0.needle1() + }); + } + // SAFETY: Building a `One` means it's safe to call 'sse2' routines. + // Also, we've checked that our haystack is big enough to run on the + // vector routine. Pointer validity is caller's responsibility. + // + // Note that we could call `self.0.find_raw` directly here. But that + // means we'd have to annotate this routine with `target_feature`. + // Which is fine, because this routine is `unsafe` anyway and the + // `target_feature` obligation is met by virtue of building a `One`. + // The real problem is that a routine with a `target_feature` + // annotation generally can't be inlined into caller code unless the + // caller code has the same target feature annotations. Which is maybe + // okay for SSE2, but we do the same thing for AVX2 where caller code + // probably usually doesn't have AVX2 enabled. That means that this + // routine can be inlined which will handle some of the short-haystack + // cases above without touching the architecture specific code. + self.find_raw_impl(start, end) + } + + /// Like `rfind`, but accepts and returns raw pointers. + /// + /// When a match is found, the pointer returned is guaranteed to be + /// `>= start` and `< end`. + /// + /// This routine is useful if you're already using raw pointers and would + /// like to avoid converting back to a slice before executing a search. + /// + /// # Safety + /// + /// * Both `start` and `end` must be valid for reads. + /// * Both `start` and `end` must point to an initialized value. + /// * Both `start` and `end` must point to the same allocated object and + /// must either be in bounds or at most one byte past the end of the + /// allocated object. + /// * Both `start` and `end` must be _derived from_ a pointer to the same + /// object. + /// * The distance between `start` and `end` must not overflow `isize`. + /// * The distance being in bounds must not rely on "wrapping around" the + /// address space. + /// + /// Note that callers may pass a pair of pointers such that `start >= end`. + /// In that case, `None` will always be returned. + #[inline] + pub unsafe fn rfind_raw( + &self, + start: *const u8, + end: *const u8, + ) -> Option<*const u8> { + if start >= end { + return None; + } + if end.distance(start) < __m128i::BYTES { + // SAFETY: We require the caller to pass valid start/end pointers. + return generic::rev_byte_by_byte(start, end, |b| { + b == self.0.needle1() + }); + } + // SAFETY: Building a `One` means it's safe to call 'sse2' routines. + // Also, we've checked that our haystack is big enough to run on the + // vector routine. Pointer validity is caller's responsibility. + // + // See note in forward routine above for why we don't just call + // `self.0.rfind_raw` directly here. + self.rfind_raw_impl(start, end) + } + + /// Counts all occurrences of this byte in the given haystack represented + /// by raw pointers. + /// + /// This routine is useful if you're already using raw pointers and would + /// like to avoid converting back to a slice before executing a search. + /// + /// # Safety + /// + /// * Both `start` and `end` must be valid for reads. + /// * Both `start` and `end` must point to an initialized value. + /// * Both `start` and `end` must point to the same allocated object and + /// must either be in bounds or at most one byte past the end of the + /// allocated object. + /// * Both `start` and `end` must be _derived from_ a pointer to the same + /// object. + /// * The distance between `start` and `end` must not overflow `isize`. + /// * The distance being in bounds must not rely on "wrapping around" the + /// address space. + /// + /// Note that callers may pass a pair of pointers such that `start >= end`. + /// In that case, `0` will always be returned. + #[inline] + pub unsafe fn count_raw(&self, start: *const u8, end: *const u8) -> usize { + if start >= end { + return 0; + } + if end.distance(start) < __m128i::BYTES { + // SAFETY: We require the caller to pass valid start/end pointers. + return generic::count_byte_by_byte(start, end, |b| { + b == self.0.needle1() + }); + } + // SAFETY: Building a `One` means it's safe to call 'sse2' routines. + // Also, we've checked that our haystack is big enough to run on the + // vector routine. Pointer validity is caller's responsibility. + self.count_raw_impl(start, end) + } + + /// Execute a search using SSE2 vectors and routines. + /// + /// # Safety + /// + /// Same as [`One::find_raw`], except the distance between `start` and + /// `end` must be at least the size of an SSE2 vector (in bytes). + /// + /// (The target feature safety obligation is automatically fulfilled by + /// virtue of being a method on `One`, which can only be constructed + /// when it is safe to call `sse2` routines.) + #[target_feature(enable = "sse2")] + #[inline] + unsafe fn find_raw_impl( + &self, + start: *const u8, + end: *const u8, + ) -> Option<*const u8> { + self.0.find_raw(start, end) + } + + /// Execute a search using SSE2 vectors and routines. + /// + /// # Safety + /// + /// Same as [`One::rfind_raw`], except the distance between `start` and + /// `end` must be at least the size of an SSE2 vector (in bytes). + /// + /// (The target feature safety obligation is automatically fulfilled by + /// virtue of being a method on `One`, which can only be constructed + /// when it is safe to call `sse2` routines.) + #[target_feature(enable = "sse2")] + #[inline] + unsafe fn rfind_raw_impl( + &self, + start: *const u8, + end: *const u8, + ) -> Option<*const u8> { + self.0.rfind_raw(start, end) + } + + /// Execute a count using SSE2 vectors and routines. + /// + /// # Safety + /// + /// Same as [`One::count_raw`], except the distance between `start` and + /// `end` must be at least the size of an SSE2 vector (in bytes). + /// + /// (The target feature safety obligation is automatically fulfilled by + /// virtue of being a method on `One`, which can only be constructed + /// when it is safe to call `sse2` routines.) + #[target_feature(enable = "sse2")] + #[inline] + unsafe fn count_raw_impl( + &self, + start: *const u8, + end: *const u8, + ) -> usize { + self.0.count_raw(start, end) + } + + /// Returns an iterator over all occurrences of the needle byte in the + /// given haystack. + /// + /// The iterator returned implements `DoubleEndedIterator`. This means it + /// can also be used to find occurrences in reverse order. + #[inline] + pub fn iter<'a, 'h>(&'a self, haystack: &'h [u8]) -> OneIter<'a, 'h> { + OneIter { searcher: self, it: generic::Iter::new(haystack) } + } +} + +/// An iterator over all occurrences of a single byte in a haystack. +/// +/// This iterator implements `DoubleEndedIterator`, which means it can also be +/// used to find occurrences in reverse order. +/// +/// This iterator is created by the [`One::iter`] method. +/// +/// The lifetime parameters are as follows: +/// +/// * `'a` refers to the lifetime of the underlying [`One`] searcher. +/// * `'h` refers to the lifetime of the haystack being searched. +#[derive(Clone, Debug)] +pub struct OneIter<'a, 'h> { + searcher: &'a One, + it: generic::Iter<'h>, +} + +impl<'a, 'h> Iterator for OneIter<'a, 'h> { + type Item = usize; + + #[inline] + fn next(&mut self) -> Option { + // SAFETY: We rely on the generic iterator to provide valid start + // and end pointers, but we guarantee that any pointer returned by + // 'find_raw' falls within the bounds of the start and end pointer. + unsafe { self.it.next(|s, e| self.searcher.find_raw(s, e)) } + } + + #[inline] + fn count(self) -> usize { + self.it.count(|s, e| { + // SAFETY: We rely on our generic iterator to return valid start + // and end pointers. + unsafe { self.searcher.count_raw(s, e) } + }) + } + + #[inline] + fn size_hint(&self) -> (usize, Option) { + self.it.size_hint() + } +} + +impl<'a, 'h> DoubleEndedIterator for OneIter<'a, 'h> { + #[inline] + fn next_back(&mut self) -> Option { + // SAFETY: We rely on the generic iterator to provide valid start + // and end pointers, but we guarantee that any pointer returned by + // 'rfind_raw' falls within the bounds of the start and end pointer. + unsafe { self.it.next_back(|s, e| self.searcher.rfind_raw(s, e)) } + } +} + +impl<'a, 'h> core::iter::FusedIterator for OneIter<'a, 'h> {} + +/// Finds all occurrences of two bytes in a haystack. +/// +/// That is, this reports matches of one of two possible bytes. For example, +/// searching for `a` or `b` in `afoobar` would report matches at offsets `0`, +/// `4` and `5`. +#[derive(Clone, Copy, Debug)] +pub struct Two(generic::Two<__m128i>); + +impl Two { + /// Create a new searcher that finds occurrences of the needle bytes given. + /// + /// This particular searcher is specialized to use SSE2 vector instructions + /// that typically make it quite fast. + /// + /// If SSE2 is unavailable in the current environment, then `None` is + /// returned. + #[inline] + pub fn new(needle1: u8, needle2: u8) -> Option { + if Two::is_available() { + // SAFETY: we check that sse2 is available above. + unsafe { Some(Two::new_unchecked(needle1, needle2)) } + } else { + None + } + } + + /// Create a new finder specific to SSE2 vectors and routines without + /// checking that SSE2 is available. + /// + /// # Safety + /// + /// Callers must guarantee that it is safe to execute `sse2` instructions + /// in the current environment. + /// + /// Note that it is a common misconception that if one compiles for an + /// `x86_64` target, then they therefore automatically have access to SSE2 + /// instructions. While this is almost always the case, it isn't true in + /// 100% of cases. + #[target_feature(enable = "sse2")] + #[inline] + pub unsafe fn new_unchecked(needle1: u8, needle2: u8) -> Two { + Two(generic::Two::new(needle1, needle2)) + } + + /// Returns true when this implementation is available in the current + /// environment. + /// + /// When this is true, it is guaranteed that [`Two::new`] will return + /// a `Some` value. Similarly, when it is false, it is guaranteed that + /// `Two::new` will return a `None` value. + /// + /// Note also that for the lifetime of a single program, if this returns + /// true then it will always return true. + #[inline] + pub fn is_available() -> bool { + #[cfg(target_feature = "sse2")] + { + true + } + #[cfg(not(target_feature = "sse2"))] + { + false + } + } + + /// Return the first occurrence of one of the needle bytes in the given + /// haystack. If no such occurrence exists, then `None` is returned. + /// + /// The occurrence is reported as an offset into `haystack`. Its maximum + /// value is `haystack.len() - 1`. + #[inline] + pub fn find(&self, haystack: &[u8]) -> Option { + // SAFETY: `find_raw` guarantees that if a pointer is returned, it + // falls within the bounds of the start and end pointers. + unsafe { + generic::search_slice_with_raw(haystack, |s, e| { + self.find_raw(s, e) + }) + } + } + + /// Return the last occurrence of one of the needle bytes in the given + /// haystack. If no such occurrence exists, then `None` is returned. + /// + /// The occurrence is reported as an offset into `haystack`. Its maximum + /// value is `haystack.len() - 1`. + #[inline] + pub fn rfind(&self, haystack: &[u8]) -> Option { + // SAFETY: `rfind_raw` guarantees that if a pointer is returned, it + // falls within the bounds of the start and end pointers. + unsafe { + generic::search_slice_with_raw(haystack, |s, e| { + self.rfind_raw(s, e) + }) + } + } + + /// Like `find`, but accepts and returns raw pointers. + /// + /// When a match is found, the pointer returned is guaranteed to be + /// `>= start` and `< end`. + /// + /// This routine is useful if you're already using raw pointers and would + /// like to avoid converting back to a slice before executing a search. + /// + /// # Safety + /// + /// * Both `start` and `end` must be valid for reads. + /// * Both `start` and `end` must point to an initialized value. + /// * Both `start` and `end` must point to the same allocated object and + /// must either be in bounds or at most one byte past the end of the + /// allocated object. + /// * Both `start` and `end` must be _derived from_ a pointer to the same + /// object. + /// * The distance between `start` and `end` must not overflow `isize`. + /// * The distance being in bounds must not rely on "wrapping around" the + /// address space. + /// + /// Note that callers may pass a pair of pointers such that `start >= end`. + /// In that case, `None` will always be returned. + #[inline] + pub unsafe fn find_raw( + &self, + start: *const u8, + end: *const u8, + ) -> Option<*const u8> { + if start >= end { + return None; + } + if end.distance(start) < __m128i::BYTES { + // SAFETY: We require the caller to pass valid start/end pointers. + return generic::fwd_byte_by_byte(start, end, |b| { + b == self.0.needle1() || b == self.0.needle2() + }); + } + // SAFETY: Building a `Two` means it's safe to call 'sse2' routines. + // Also, we've checked that our haystack is big enough to run on the + // vector routine. Pointer validity is caller's responsibility. + // + // Note that we could call `self.0.find_raw` directly here. But that + // means we'd have to annotate this routine with `target_feature`. + // Which is fine, because this routine is `unsafe` anyway and the + // `target_feature` obligation is met by virtue of building a `Two`. + // The real problem is that a routine with a `target_feature` + // annotation generally can't be inlined into caller code unless the + // caller code has the same target feature annotations. Which is maybe + // okay for SSE2, but we do the same thing for AVX2 where caller code + // probably usually doesn't have AVX2 enabled. That means that this + // routine can be inlined which will handle some of the short-haystack + // cases above without touching the architecture specific code. + self.find_raw_impl(start, end) + } + + /// Like `rfind`, but accepts and returns raw pointers. + /// + /// When a match is found, the pointer returned is guaranteed to be + /// `>= start` and `< end`. + /// + /// This routine is useful if you're already using raw pointers and would + /// like to avoid converting back to a slice before executing a search. + /// + /// # Safety + /// + /// * Both `start` and `end` must be valid for reads. + /// * Both `start` and `end` must point to an initialized value. + /// * Both `start` and `end` must point to the same allocated object and + /// must either be in bounds or at most one byte past the end of the + /// allocated object. + /// * Both `start` and `end` must be _derived from_ a pointer to the same + /// object. + /// * The distance between `start` and `end` must not overflow `isize`. + /// * The distance being in bounds must not rely on "wrapping around" the + /// address space. + /// + /// Note that callers may pass a pair of pointers such that `start >= end`. + /// In that case, `None` will always be returned. + #[inline] + pub unsafe fn rfind_raw( + &self, + start: *const u8, + end: *const u8, + ) -> Option<*const u8> { + if start >= end { + return None; + } + if end.distance(start) < __m128i::BYTES { + // SAFETY: We require the caller to pass valid start/end pointers. + return generic::rev_byte_by_byte(start, end, |b| { + b == self.0.needle1() || b == self.0.needle2() + }); + } + // SAFETY: Building a `Two` means it's safe to call 'sse2' routines. + // Also, we've checked that our haystack is big enough to run on the + // vector routine. Pointer validity is caller's responsibility. + // + // See note in forward routine above for why we don't just call + // `self.0.rfind_raw` directly here. + self.rfind_raw_impl(start, end) + } + + /// Execute a search using SSE2 vectors and routines. + /// + /// # Safety + /// + /// Same as [`Two::find_raw`], except the distance between `start` and + /// `end` must be at least the size of an SSE2 vector (in bytes). + /// + /// (The target feature safety obligation is automatically fulfilled by + /// virtue of being a method on `Two`, which can only be constructed + /// when it is safe to call `sse2` routines.) + #[target_feature(enable = "sse2")] + #[inline] + unsafe fn find_raw_impl( + &self, + start: *const u8, + end: *const u8, + ) -> Option<*const u8> { + self.0.find_raw(start, end) + } + + /// Execute a search using SSE2 vectors and routines. + /// + /// # Safety + /// + /// Same as [`Two::rfind_raw`], except the distance between `start` and + /// `end` must be at least the size of an SSE2 vector (in bytes). + /// + /// (The target feature safety obligation is automatically fulfilled by + /// virtue of being a method on `Two`, which can only be constructed + /// when it is safe to call `sse2` routines.) + #[target_feature(enable = "sse2")] + #[inline] + unsafe fn rfind_raw_impl( + &self, + start: *const u8, + end: *const u8, + ) -> Option<*const u8> { + self.0.rfind_raw(start, end) + } + + /// Returns an iterator over all occurrences of the needle bytes in the + /// given haystack. + /// + /// The iterator returned implements `DoubleEndedIterator`. This means it + /// can also be used to find occurrences in reverse order. + #[inline] + pub fn iter<'a, 'h>(&'a self, haystack: &'h [u8]) -> TwoIter<'a, 'h> { + TwoIter { searcher: self, it: generic::Iter::new(haystack) } + } +} + +/// An iterator over all occurrences of two possible bytes in a haystack. +/// +/// This iterator implements `DoubleEndedIterator`, which means it can also be +/// used to find occurrences in reverse order. +/// +/// This iterator is created by the [`Two::iter`] method. +/// +/// The lifetime parameters are as follows: +/// +/// * `'a` refers to the lifetime of the underlying [`Two`] searcher. +/// * `'h` refers to the lifetime of the haystack being searched. +#[derive(Clone, Debug)] +pub struct TwoIter<'a, 'h> { + searcher: &'a Two, + it: generic::Iter<'h>, +} + +impl<'a, 'h> Iterator for TwoIter<'a, 'h> { + type Item = usize; + + #[inline] + fn next(&mut self) -> Option { + // SAFETY: We rely on the generic iterator to provide valid start + // and end pointers, but we guarantee that any pointer returned by + // 'find_raw' falls within the bounds of the start and end pointer. + unsafe { self.it.next(|s, e| self.searcher.find_raw(s, e)) } + } + + #[inline] + fn size_hint(&self) -> (usize, Option) { + self.it.size_hint() + } +} + +impl<'a, 'h> DoubleEndedIterator for TwoIter<'a, 'h> { + #[inline] + fn next_back(&mut self) -> Option { + // SAFETY: We rely on the generic iterator to provide valid start + // and end pointers, but we guarantee that any pointer returned by + // 'rfind_raw' falls within the bounds of the start and end pointer. + unsafe { self.it.next_back(|s, e| self.searcher.rfind_raw(s, e)) } + } +} + +impl<'a, 'h> core::iter::FusedIterator for TwoIter<'a, 'h> {} + +/// Finds all occurrences of three bytes in a haystack. +/// +/// That is, this reports matches of one of three possible bytes. For example, +/// searching for `a`, `b` or `o` in `afoobar` would report matches at offsets +/// `0`, `2`, `3`, `4` and `5`. +#[derive(Clone, Copy, Debug)] +pub struct Three(generic::Three<__m128i>); + +impl Three { + /// Create a new searcher that finds occurrences of the needle bytes given. + /// + /// This particular searcher is specialized to use SSE2 vector instructions + /// that typically make it quite fast. + /// + /// If SSE2 is unavailable in the current environment, then `None` is + /// returned. + #[inline] + pub fn new(needle1: u8, needle2: u8, needle3: u8) -> Option { + if Three::is_available() { + // SAFETY: we check that sse2 is available above. + unsafe { Some(Three::new_unchecked(needle1, needle2, needle3)) } + } else { + None + } + } + + /// Create a new finder specific to SSE2 vectors and routines without + /// checking that SSE2 is available. + /// + /// # Safety + /// + /// Callers must guarantee that it is safe to execute `sse2` instructions + /// in the current environment. + /// + /// Note that it is a common misconception that if one compiles for an + /// `x86_64` target, then they therefore automatically have access to SSE2 + /// instructions. While this is almost always the case, it isn't true in + /// 100% of cases. + #[target_feature(enable = "sse2")] + #[inline] + pub unsafe fn new_unchecked( + needle1: u8, + needle2: u8, + needle3: u8, + ) -> Three { + Three(generic::Three::new(needle1, needle2, needle3)) + } + + /// Returns true when this implementation is available in the current + /// environment. + /// + /// When this is true, it is guaranteed that [`Three::new`] will return + /// a `Some` value. Similarly, when it is false, it is guaranteed that + /// `Three::new` will return a `None` value. + /// + /// Note also that for the lifetime of a single program, if this returns + /// true then it will always return true. + #[inline] + pub fn is_available() -> bool { + #[cfg(target_feature = "sse2")] + { + true + } + #[cfg(not(target_feature = "sse2"))] + { + false + } + } + + /// Return the first occurrence of one of the needle bytes in the given + /// haystack. If no such occurrence exists, then `None` is returned. + /// + /// The occurrence is reported as an offset into `haystack`. Its maximum + /// value is `haystack.len() - 1`. + #[inline] + pub fn find(&self, haystack: &[u8]) -> Option { + // SAFETY: `find_raw` guarantees that if a pointer is returned, it + // falls within the bounds of the start and end pointers. + unsafe { + generic::search_slice_with_raw(haystack, |s, e| { + self.find_raw(s, e) + }) + } + } + + /// Return the last occurrence of one of the needle bytes in the given + /// haystack. If no such occurrence exists, then `None` is returned. + /// + /// The occurrence is reported as an offset into `haystack`. Its maximum + /// value is `haystack.len() - 1`. + #[inline] + pub fn rfind(&self, haystack: &[u8]) -> Option { + // SAFETY: `rfind_raw` guarantees that if a pointer is returned, it + // falls within the bounds of the start and end pointers. + unsafe { + generic::search_slice_with_raw(haystack, |s, e| { + self.rfind_raw(s, e) + }) + } + } + + /// Like `find`, but accepts and returns raw pointers. + /// + /// When a match is found, the pointer returned is guaranteed to be + /// `>= start` and `< end`. + /// + /// This routine is useful if you're already using raw pointers and would + /// like to avoid converting back to a slice before executing a search. + /// + /// # Safety + /// + /// * Both `start` and `end` must be valid for reads. + /// * Both `start` and `end` must point to an initialized value. + /// * Both `start` and `end` must point to the same allocated object and + /// must either be in bounds or at most one byte past the end of the + /// allocated object. + /// * Both `start` and `end` must be _derived from_ a pointer to the same + /// object. + /// * The distance between `start` and `end` must not overflow `isize`. + /// * The distance being in bounds must not rely on "wrapping around" the + /// address space. + /// + /// Note that callers may pass a pair of pointers such that `start >= end`. + /// In that case, `None` will always be returned. + #[inline] + pub unsafe fn find_raw( + &self, + start: *const u8, + end: *const u8, + ) -> Option<*const u8> { + if start >= end { + return None; + } + if end.distance(start) < __m128i::BYTES { + // SAFETY: We require the caller to pass valid start/end pointers. + return generic::fwd_byte_by_byte(start, end, |b| { + b == self.0.needle1() + || b == self.0.needle2() + || b == self.0.needle3() + }); + } + // SAFETY: Building a `Three` means it's safe to call 'sse2' routines. + // Also, we've checked that our haystack is big enough to run on the + // vector routine. Pointer validity is caller's responsibility. + // + // Note that we could call `self.0.find_raw` directly here. But that + // means we'd have to annotate this routine with `target_feature`. + // Which is fine, because this routine is `unsafe` anyway and the + // `target_feature` obligation is met by virtue of building a `Three`. + // The real problem is that a routine with a `target_feature` + // annotation generally can't be inlined into caller code unless the + // caller code has the same target feature annotations. Which is maybe + // okay for SSE2, but we do the same thing for AVX2 where caller code + // probably usually doesn't have AVX2 enabled. That means that this + // routine can be inlined which will handle some of the short-haystack + // cases above without touching the architecture specific code. + self.find_raw_impl(start, end) + } + + /// Like `rfind`, but accepts and returns raw pointers. + /// + /// When a match is found, the pointer returned is guaranteed to be + /// `>= start` and `< end`. + /// + /// This routine is useful if you're already using raw pointers and would + /// like to avoid converting back to a slice before executing a search. + /// + /// # Safety + /// + /// * Both `start` and `end` must be valid for reads. + /// * Both `start` and `end` must point to an initialized value. + /// * Both `start` and `end` must point to the same allocated object and + /// must either be in bounds or at most one byte past the end of the + /// allocated object. + /// * Both `start` and `end` must be _derived from_ a pointer to the same + /// object. + /// * The distance between `start` and `end` must not overflow `isize`. + /// * The distance being in bounds must not rely on "wrapping around" the + /// address space. + /// + /// Note that callers may pass a pair of pointers such that `start >= end`. + /// In that case, `None` will always be returned. + #[inline] + pub unsafe fn rfind_raw( + &self, + start: *const u8, + end: *const u8, + ) -> Option<*const u8> { + if start >= end { + return None; + } + if end.distance(start) < __m128i::BYTES { + // SAFETY: We require the caller to pass valid start/end pointers. + return generic::rev_byte_by_byte(start, end, |b| { + b == self.0.needle1() + || b == self.0.needle2() + || b == self.0.needle3() + }); + } + // SAFETY: Building a `Three` means it's safe to call 'sse2' routines. + // Also, we've checked that our haystack is big enough to run on the + // vector routine. Pointer validity is caller's responsibility. + // + // See note in forward routine above for why we don't just call + // `self.0.rfind_raw` directly here. + self.rfind_raw_impl(start, end) + } + + /// Execute a search using SSE2 vectors and routines. + /// + /// # Safety + /// + /// Same as [`Three::find_raw`], except the distance between `start` and + /// `end` must be at least the size of an SSE2 vector (in bytes). + /// + /// (The target feature safety obligation is automatically fulfilled by + /// virtue of being a method on `Three`, which can only be constructed + /// when it is safe to call `sse2` routines.) + #[target_feature(enable = "sse2")] + #[inline] + unsafe fn find_raw_impl( + &self, + start: *const u8, + end: *const u8, + ) -> Option<*const u8> { + self.0.find_raw(start, end) + } + + /// Execute a search using SSE2 vectors and routines. + /// + /// # Safety + /// + /// Same as [`Three::rfind_raw`], except the distance between `start` and + /// `end` must be at least the size of an SSE2 vector (in bytes). + /// + /// (The target feature safety obligation is automatically fulfilled by + /// virtue of being a method on `Three`, which can only be constructed + /// when it is safe to call `sse2` routines.) + #[target_feature(enable = "sse2")] + #[inline] + unsafe fn rfind_raw_impl( + &self, + start: *const u8, + end: *const u8, + ) -> Option<*const u8> { + self.0.rfind_raw(start, end) + } + + /// Returns an iterator over all occurrences of the needle byte in the + /// given haystack. + /// + /// The iterator returned implements `DoubleEndedIterator`. This means it + /// can also be used to find occurrences in reverse order. + #[inline] + pub fn iter<'a, 'h>(&'a self, haystack: &'h [u8]) -> ThreeIter<'a, 'h> { + ThreeIter { searcher: self, it: generic::Iter::new(haystack) } + } +} + +/// An iterator over all occurrences of three possible bytes in a haystack. +/// +/// This iterator implements `DoubleEndedIterator`, which means it can also be +/// used to find occurrences in reverse order. +/// +/// This iterator is created by the [`Three::iter`] method. +/// +/// The lifetime parameters are as follows: +/// +/// * `'a` refers to the lifetime of the underlying [`Three`] searcher. +/// * `'h` refers to the lifetime of the haystack being searched. +#[derive(Clone, Debug)] +pub struct ThreeIter<'a, 'h> { + searcher: &'a Three, + it: generic::Iter<'h>, +} + +impl<'a, 'h> Iterator for ThreeIter<'a, 'h> { + type Item = usize; + + #[inline] + fn next(&mut self) -> Option { + // SAFETY: We rely on the generic iterator to provide valid start + // and end pointers, but we guarantee that any pointer returned by + // 'find_raw' falls within the bounds of the start and end pointer. + unsafe { self.it.next(|s, e| self.searcher.find_raw(s, e)) } + } + + #[inline] + fn size_hint(&self) -> (usize, Option) { + self.it.size_hint() + } +} + +impl<'a, 'h> DoubleEndedIterator for ThreeIter<'a, 'h> { + #[inline] + fn next_back(&mut self) -> Option { + // SAFETY: We rely on the generic iterator to provide valid start + // and end pointers, but we guarantee that any pointer returned by + // 'rfind_raw' falls within the bounds of the start and end pointer. + unsafe { self.it.next_back(|s, e| self.searcher.rfind_raw(s, e)) } + } +} + +impl<'a, 'h> core::iter::FusedIterator for ThreeIter<'a, 'h> {} + +#[cfg(test)] +mod tests { + use super::*; + + define_memchr_quickcheck!(super); + + #[test] + fn forward_one() { + crate::tests::memchr::Runner::new(1).forward_iter( + |haystack, needles| { + Some(One::new(needles[0])?.iter(haystack).collect()) + }, + ) + } + + #[test] + fn reverse_one() { + crate::tests::memchr::Runner::new(1).reverse_iter( + |haystack, needles| { + Some(One::new(needles[0])?.iter(haystack).rev().collect()) + }, + ) + } + + #[test] + fn count_one() { + crate::tests::memchr::Runner::new(1).count_iter(|haystack, needles| { + Some(One::new(needles[0])?.iter(haystack).count()) + }) + } + + #[test] + fn forward_two() { + crate::tests::memchr::Runner::new(2).forward_iter( + |haystack, needles| { + let n1 = needles.get(0).copied()?; + let n2 = needles.get(1).copied()?; + Some(Two::new(n1, n2)?.iter(haystack).collect()) + }, + ) + } + + #[test] + fn reverse_two() { + crate::tests::memchr::Runner::new(2).reverse_iter( + |haystack, needles| { + let n1 = needles.get(0).copied()?; + let n2 = needles.get(1).copied()?; + Some(Two::new(n1, n2)?.iter(haystack).rev().collect()) + }, + ) + } + + #[test] + fn forward_three() { + crate::tests::memchr::Runner::new(3).forward_iter( + |haystack, needles| { + let n1 = needles.get(0).copied()?; + let n2 = needles.get(1).copied()?; + let n3 = needles.get(2).copied()?; + Some(Three::new(n1, n2, n3)?.iter(haystack).collect()) + }, + ) + } + + #[test] + fn reverse_three() { + crate::tests::memchr::Runner::new(3).reverse_iter( + |haystack, needles| { + let n1 = needles.get(0).copied()?; + let n2 = needles.get(1).copied()?; + let n3 = needles.get(2).copied()?; + Some(Three::new(n1, n2, n3)?.iter(haystack).rev().collect()) + }, + ) + } +} diff --git a/vendor/memchr/src/arch/x86_64/sse2/mod.rs b/vendor/memchr/src/arch/x86_64/sse2/mod.rs new file mode 100644 index 0000000..bcb8307 --- /dev/null +++ b/vendor/memchr/src/arch/x86_64/sse2/mod.rs @@ -0,0 +1,6 @@ +/*! +Algorithms for the `x86_64` target using 128-bit vectors via SSE2. +*/ + +pub mod memchr; +pub mod packedpair; diff --git a/vendor/memchr/src/arch/x86_64/sse2/packedpair.rs b/vendor/memchr/src/arch/x86_64/sse2/packedpair.rs new file mode 100644 index 0000000..c8b5b99 --- /dev/null +++ b/vendor/memchr/src/arch/x86_64/sse2/packedpair.rs @@ -0,0 +1,232 @@ +/*! +A 128-bit vector implementation of the "packed pair" SIMD algorithm. + +The "packed pair" algorithm is based on the [generic SIMD] algorithm. The main +difference is that it (by default) uses a background distribution of byte +frequencies to heuristically select the pair of bytes to search for. + +[generic SIMD]: http://0x80.pl/articles/simd-strfind.html#first-and-last +*/ + +use core::arch::x86_64::__m128i; + +use crate::arch::{all::packedpair::Pair, generic::packedpair}; + +/// A "packed pair" finder that uses 128-bit vector operations. +/// +/// This finder picks two bytes that it believes have high predictive power +/// for indicating an overall match of a needle. Depending on whether +/// `Finder::find` or `Finder::find_prefilter` is used, it reports offsets +/// where the needle matches or could match. In the prefilter case, candidates +/// are reported whenever the [`Pair`] of bytes given matches. +#[derive(Clone, Copy, Debug)] +pub struct Finder(packedpair::Finder<__m128i>); + +impl Finder { + /// Create a new pair searcher. The searcher returned can either report + /// exact matches of `needle` or act as a prefilter and report candidate + /// positions of `needle`. + /// + /// If SSE2 is unavailable in the current environment or if a [`Pair`] + /// could not be constructed from the needle given, then `None` is + /// returned. + #[inline] + pub fn new(needle: &[u8]) -> Option { + Finder::with_pair(needle, Pair::new(needle)?) + } + + /// Create a new "packed pair" finder using the pair of bytes given. + /// + /// This constructor permits callers to control precisely which pair of + /// bytes is used as a predicate. + /// + /// If SSE2 is unavailable in the current environment, then `None` is + /// returned. + #[inline] + pub fn with_pair(needle: &[u8], pair: Pair) -> Option { + if Finder::is_available() { + // SAFETY: we check that sse2 is available above. We are also + // guaranteed to have needle.len() > 1 because we have a valid + // Pair. + unsafe { Some(Finder::with_pair_impl(needle, pair)) } + } else { + None + } + } + + /// Create a new `Finder` specific to SSE2 vectors and routines. + /// + /// # Safety + /// + /// Same as the safety for `packedpair::Finder::new`, and callers must also + /// ensure that SSE2 is available. + #[target_feature(enable = "sse2")] + #[inline] + unsafe fn with_pair_impl(needle: &[u8], pair: Pair) -> Finder { + let finder = packedpair::Finder::<__m128i>::new(needle, pair); + Finder(finder) + } + + /// Returns true when this implementation is available in the current + /// environment. + /// + /// When this is true, it is guaranteed that [`Finder::with_pair`] will + /// return a `Some` value. Similarly, when it is false, it is guaranteed + /// that `Finder::with_pair` will return a `None` value. Notice that this + /// does not guarantee that [`Finder::new`] will return a `Finder`. Namely, + /// even when `Finder::is_available` is true, it is not guaranteed that a + /// valid [`Pair`] can be found from the needle given. + /// + /// Note also that for the lifetime of a single program, if this returns + /// true then it will always return true. + #[inline] + pub fn is_available() -> bool { + #[cfg(not(target_feature = "sse2"))] + { + false + } + #[cfg(target_feature = "sse2")] + { + true + } + } + + /// Execute a search using SSE2 vectors and routines. + /// + /// # Panics + /// + /// When `haystack.len()` is less than [`Finder::min_haystack_len`]. + #[inline] + pub fn find(&self, haystack: &[u8], needle: &[u8]) -> Option { + // SAFETY: Building a `Finder` means it's safe to call 'sse2' routines. + unsafe { self.find_impl(haystack, needle) } + } + + /// Run this finder on the given haystack as a prefilter. + /// + /// If a candidate match is found, then an offset where the needle *could* + /// begin in the haystack is returned. + /// + /// # Panics + /// + /// When `haystack.len()` is less than [`Finder::min_haystack_len`]. + #[inline] + pub fn find_prefilter(&self, haystack: &[u8]) -> Option { + // SAFETY: Building a `Finder` means it's safe to call 'sse2' routines. + unsafe { self.find_prefilter_impl(haystack) } + } + + /// Execute a search using SSE2 vectors and routines. + /// + /// # Panics + /// + /// When `haystack.len()` is less than [`Finder::min_haystack_len`]. + /// + /// # Safety + /// + /// (The target feature safety obligation is automatically fulfilled by + /// virtue of being a method on `Finder`, which can only be constructed + /// when it is safe to call `sse2` routines.) + #[target_feature(enable = "sse2")] + #[inline] + unsafe fn find_impl( + &self, + haystack: &[u8], + needle: &[u8], + ) -> Option { + self.0.find(haystack, needle) + } + + /// Execute a prefilter search using SSE2 vectors and routines. + /// + /// # Panics + /// + /// When `haystack.len()` is less than [`Finder::min_haystack_len`]. + /// + /// # Safety + /// + /// (The target feature safety obligation is automatically fulfilled by + /// virtue of being a method on `Finder`, which can only be constructed + /// when it is safe to call `sse2` routines.) + #[target_feature(enable = "sse2")] + #[inline] + unsafe fn find_prefilter_impl(&self, haystack: &[u8]) -> Option { + self.0.find_prefilter(haystack) + } + + /// Returns the pair of offsets (into the needle) used to check as a + /// predicate before confirming whether a needle exists at a particular + /// position. + #[inline] + pub fn pair(&self) -> &Pair { + self.0.pair() + } + + /// Returns the minimum haystack length that this `Finder` can search. + /// + /// Using a haystack with length smaller than this in a search will result + /// in a panic. The reason for this restriction is that this finder is + /// meant to be a low-level component that is part of a larger substring + /// strategy. In that sense, it avoids trying to handle all cases and + /// instead only handles the cases that it can handle very well. + #[inline] + pub fn min_haystack_len(&self) -> usize { + self.0.min_haystack_len() + } +} + +#[cfg(test)] +mod tests { + use super::*; + + fn find(haystack: &[u8], needle: &[u8]) -> Option> { + let f = Finder::new(needle)?; + if haystack.len() < f.min_haystack_len() { + return None; + } + Some(f.find(haystack, needle)) + } + + define_substring_forward_quickcheck!(find); + + #[test] + fn forward_substring() { + crate::tests::substring::Runner::new().fwd(find).run() + } + + #[test] + fn forward_packedpair() { + fn find( + haystack: &[u8], + needle: &[u8], + index1: u8, + index2: u8, + ) -> Option> { + let pair = Pair::with_indices(needle, index1, index2)?; + let f = Finder::with_pair(needle, pair)?; + if haystack.len() < f.min_haystack_len() { + return None; + } + Some(f.find(haystack, needle)) + } + crate::tests::packedpair::Runner::new().fwd(find).run() + } + + #[test] + fn forward_packedpair_prefilter() { + fn find( + haystack: &[u8], + needle: &[u8], + index1: u8, + index2: u8, + ) -> Option> { + let pair = Pair::with_indices(needle, index1, index2)?; + let f = Finder::with_pair(needle, pair)?; + if haystack.len() < f.min_haystack_len() { + return None; + } + Some(f.find_prefilter(haystack)) + } + crate::tests::packedpair::Runner::new().fwd(find).run() + } +} diff --git a/vendor/memchr/src/cow.rs b/vendor/memchr/src/cow.rs new file mode 100644 index 0000000..f291645 --- /dev/null +++ b/vendor/memchr/src/cow.rs @@ -0,0 +1,107 @@ +use core::ops; + +/// A specialized copy-on-write byte string. +/// +/// The purpose of this type is to permit usage of a "borrowed or owned +/// byte string" in a way that keeps std/no-std compatibility. That is, in +/// no-std/alloc mode, this type devolves into a simple &[u8] with no owned +/// variant available. We can't just use a plain Cow because Cow is not in +/// core. +#[derive(Clone, Debug)] +pub struct CowBytes<'a>(Imp<'a>); + +// N.B. We don't use alloc::borrow::Cow here since we can get away with a +// Box<[u8]> for our use case, which is 1/3 smaller than the Vec that +// a Cow<[u8]> would use. +#[cfg(feature = "alloc")] +#[derive(Clone, Debug)] +enum Imp<'a> { + Borrowed(&'a [u8]), + Owned(alloc::boxed::Box<[u8]>), +} + +#[cfg(not(feature = "alloc"))] +#[derive(Clone, Debug)] +struct Imp<'a>(&'a [u8]); + +impl<'a> ops::Deref for CowBytes<'a> { + type Target = [u8]; + + #[inline(always)] + fn deref(&self) -> &[u8] { + self.as_slice() + } +} + +impl<'a> CowBytes<'a> { + /// Create a new borrowed CowBytes. + #[inline(always)] + pub(crate) fn new>(bytes: &'a B) -> CowBytes<'a> { + CowBytes(Imp::new(bytes.as_ref())) + } + + /// Create a new owned CowBytes. + #[cfg(feature = "alloc")] + #[inline(always)] + fn new_owned(bytes: alloc::boxed::Box<[u8]>) -> CowBytes<'static> { + CowBytes(Imp::Owned(bytes)) + } + + /// Return a borrowed byte string, regardless of whether this is an owned + /// or borrowed byte string internally. + #[inline(always)] + pub(crate) fn as_slice(&self) -> &[u8] { + self.0.as_slice() + } + + /// Return an owned version of this copy-on-write byte string. + /// + /// If this is already an owned byte string internally, then this is a + /// no-op. Otherwise, the internal byte string is copied. + #[cfg(feature = "alloc")] + #[inline(always)] + pub(crate) fn into_owned(self) -> CowBytes<'static> { + match self.0 { + Imp::Borrowed(b) => { + CowBytes::new_owned(alloc::boxed::Box::from(b)) + } + Imp::Owned(b) => CowBytes::new_owned(b), + } + } +} + +impl<'a> Imp<'a> { + #[inline(always)] + pub fn new(bytes: &'a [u8]) -> Imp<'a> { + #[cfg(feature = "alloc")] + { + Imp::Borrowed(bytes) + } + #[cfg(not(feature = "alloc"))] + { + Imp(bytes) + } + } + + #[cfg(feature = "alloc")] + #[inline(always)] + pub fn as_slice(&self) -> &[u8] { + #[cfg(feature = "alloc")] + { + match self { + Imp::Owned(ref x) => x, + Imp::Borrowed(x) => x, + } + } + #[cfg(not(feature = "alloc"))] + { + self.0 + } + } + + #[cfg(not(feature = "alloc"))] + #[inline(always)] + pub fn as_slice(&self) -> &[u8] { + self.0 + } +} diff --git a/vendor/memchr/src/ext.rs b/vendor/memchr/src/ext.rs new file mode 100644 index 0000000..802697a --- /dev/null +++ b/vendor/memchr/src/ext.rs @@ -0,0 +1,54 @@ +/// A trait for adding some helper routines to pointers. +pub(crate) trait Pointer { + /// Returns the distance, in units of `T`, between `self` and `origin`. + /// + /// # Safety + /// + /// Same as `ptr::offset_from` in addition to `self >= origin`. + unsafe fn distance(self, origin: Self) -> usize; + + /// Casts this pointer to `usize`. + /// + /// Callers should not convert the `usize` back to a pointer if at all + /// possible. (And if you believe it's necessary, open an issue to discuss + /// why. Otherwise, it has the potential to violate pointer provenance.) + /// The purpose of this function is just to be able to do arithmetic, i.e., + /// computing offsets or alignments. + fn as_usize(self) -> usize; +} + +impl Pointer for *const T { + unsafe fn distance(self, origin: *const T) -> usize { + // TODO: Replace with `ptr::sub_ptr` once stabilized. + usize::try_from(self.offset_from(origin)).unwrap_unchecked() + } + + fn as_usize(self) -> usize { + self as usize + } +} + +impl Pointer for *mut T { + unsafe fn distance(self, origin: *mut T) -> usize { + (self as *const T).distance(origin as *const T) + } + + fn as_usize(self) -> usize { + (self as *const T).as_usize() + } +} + +/// A trait for adding some helper routines to raw bytes. +#[cfg(test)] +pub(crate) trait Byte { + /// Converts this byte to a `char` if it's ASCII. Otherwise panics. + fn to_char(self) -> char; +} + +#[cfg(test)] +impl Byte for u8 { + fn to_char(self) -> char { + assert!(self.is_ascii()); + char::from(self) + } +} diff --git a/vendor/memchr/src/lib.rs b/vendor/memchr/src/lib.rs new file mode 100644 index 0000000..b310516 --- /dev/null +++ b/vendor/memchr/src/lib.rs @@ -0,0 +1,221 @@ +/*! +This library provides heavily optimized routines for string search primitives. + +# Overview + +This section gives a brief high level overview of what this crate offers. + +* The top-level module provides routines for searching for 1, 2 or 3 bytes + in the forward or reverse direction. When searching for more than one byte, + positions are considered a match if the byte at that position matches any + of the bytes. +* The [`memmem`] sub-module provides forward and reverse substring search + routines. + +In all such cases, routines operate on `&[u8]` without regard to encoding. This +is exactly what you want when searching either UTF-8 or arbitrary bytes. + +# Example: using `memchr` + +This example shows how to use `memchr` to find the first occurrence of `z` in +a haystack: + +``` +use memchr::memchr; + +let haystack = b"foo bar baz quuz"; +assert_eq!(Some(10), memchr(b'z', haystack)); +``` + +# Example: matching one of three possible bytes + +This examples shows how to use `memrchr3` to find occurrences of `a`, `b` or +`c`, starting at the end of the haystack. + +``` +use memchr::memchr3_iter; + +let haystack = b"xyzaxyzbxyzc"; + +let mut it = memchr3_iter(b'a', b'b', b'c', haystack).rev(); +assert_eq!(Some(11), it.next()); +assert_eq!(Some(7), it.next()); +assert_eq!(Some(3), it.next()); +assert_eq!(None, it.next()); +``` + +# Example: iterating over substring matches + +This example shows how to use the [`memmem`] sub-module to find occurrences of +a substring in a haystack. + +``` +use memchr::memmem; + +let haystack = b"foo bar foo baz foo"; + +let mut it = memmem::find_iter(haystack, "foo"); +assert_eq!(Some(0), it.next()); +assert_eq!(Some(8), it.next()); +assert_eq!(Some(16), it.next()); +assert_eq!(None, it.next()); +``` + +# Example: repeating a search for the same needle + +It may be possible for the overhead of constructing a substring searcher to be +measurable in some workloads. In cases where the same needle is used to search +many haystacks, it is possible to do construction once and thus to avoid it for +subsequent searches. This can be done with a [`memmem::Finder`]: + +``` +use memchr::memmem; + +let finder = memmem::Finder::new("foo"); + +assert_eq!(Some(4), finder.find(b"baz foo quux")); +assert_eq!(None, finder.find(b"quux baz bar")); +``` + +# Why use this crate? + +At first glance, the APIs provided by this crate might seem weird. Why provide +a dedicated routine like `memchr` for something that could be implemented +clearly and trivially in one line: + +``` +fn memchr(needle: u8, haystack: &[u8]) -> Option { + haystack.iter().position(|&b| b == needle) +} +``` + +Or similarly, why does this crate provide substring search routines when Rust's +core library already provides them? + +``` +fn search(haystack: &str, needle: &str) -> Option { + haystack.find(needle) +} +``` + +The primary reason for both of them to exist is performance. When it comes to +performance, at a high level at least, there are two primary ways to look at +it: + +* **Throughput**: For this, think about it as, "given some very large haystack + and a byte that never occurs in that haystack, how long does it take to + search through it and determine that it, in fact, does not occur?" +* **Latency**: For this, think about it as, "given a tiny haystack---just a + few bytes---how long does it take to determine if a byte is in it?" + +The `memchr` routine in this crate has _slightly_ worse latency than the +solution presented above, however, its throughput can easily be over an +order of magnitude faster. This is a good general purpose trade off to make. +You rarely lose, but often gain big. + +**NOTE:** The name `memchr` comes from the corresponding routine in `libc`. A +key advantage of using this library is that its performance is not tied to its +quality of implementation in the `libc` you happen to be using, which can vary +greatly from platform to platform. + +But what about substring search? This one is a bit more complicated. The +primary reason for its existence is still indeed performance, but it's also +useful because Rust's core library doesn't actually expose any substring +search routine on arbitrary bytes. The only substring search routine that +exists works exclusively on valid UTF-8. + +So if you have valid UTF-8, is there a reason to use this over the standard +library substring search routine? Yes. This routine is faster on almost every +metric, including latency. The natural question then, is why isn't this +implementation in the standard library, even if only for searching on UTF-8? +The reason is that the implementation details for using SIMD in the standard +library haven't quite been worked out yet. + +**NOTE:** Currently, only `x86_64`, `wasm32` and `aarch64` targets have vector +accelerated implementations of `memchr` (and friends) and `memmem`. + +# Crate features + +* **std** - When enabled (the default), this will permit features specific to +the standard library. Currently, the only thing used from the standard library +is runtime SIMD CPU feature detection. This means that this feature must be +enabled to get AVX2 accelerated routines on `x86_64` targets without enabling +the `avx2` feature at compile time, for example. When `std` is not enabled, +this crate will still attempt to use SSE2 accelerated routines on `x86_64`. It +will also use AVX2 accelerated routines when the `avx2` feature is enabled at +compile time. In general, enable this feature if you can. +* **alloc** - When enabled (the default), APIs in this crate requiring some +kind of allocation will become available. For example, the +[`memmem::Finder::into_owned`](crate::memmem::Finder::into_owned) API and the +[`arch::all::shiftor`](crate::arch::all::shiftor) substring search +implementation. Otherwise, this crate is designed from the ground up to be +usable in core-only contexts, so the `alloc` feature doesn't add much +currently. Notably, disabling `std` but enabling `alloc` will **not** result +in the use of AVX2 on `x86_64` targets unless the `avx2` feature is enabled +at compile time. (With `std` enabled, AVX2 can be used even without the `avx2` +feature enabled at compile time by way of runtime CPU feature detection.) +* **logging** - When enabled (disabled by default), the `log` crate is used +to emit log messages about what kinds of `memchr` and `memmem` algorithms +are used. Namely, both `memchr` and `memmem` have a number of different +implementation choices depending on the target and CPU, and the log messages +can help show what specific implementations are being used. Generally, this is +useful for debugging performance issues. +* **libc** - **DEPRECATED**. Previously, this enabled the use of the target's +`memchr` function from whatever `libc` was linked into the program. This +feature is now a no-op because this crate's implementation of `memchr` should +now be sufficiently fast on a number of platforms that `libc` should no longer +be needed. (This feature is somewhat of a holdover from this crate's origins. +Originally, this crate was literally just a safe wrapper function around the +`memchr` function from `libc`.) +*/ + +#![deny(missing_docs)] +#![no_std] +// It's just not worth trying to squash all dead code warnings. Pretty +// unfortunate IMO. Not really sure how to fix this other than to either +// live with it or sprinkle a whole mess of `cfg` annotations everywhere. +#![cfg_attr( + not(any( + all(target_arch = "x86_64", target_feature = "sse2"), + all(target_arch = "wasm32", target_feature = "simd128"), + target_arch = "aarch64", + )), + allow(dead_code) +)] +// Same deal for miri. +#![cfg_attr(miri, allow(dead_code, unused_macros))] + +// Supporting 8-bit (or others) would be fine. If you need it, please submit a +// bug report at https://github.com/BurntSushi/memchr +#[cfg(not(any( + target_pointer_width = "16", + target_pointer_width = "32", + target_pointer_width = "64" +)))] +compile_error!("memchr currently not supported on non-{16,32,64}"); + +#[cfg(any(test, feature = "std"))] +extern crate std; + +#[cfg(any(test, feature = "alloc"))] +extern crate alloc; + +pub use crate::memchr::{ + memchr, memchr2, memchr2_iter, memchr3, memchr3_iter, memchr_iter, + memrchr, memrchr2, memrchr2_iter, memrchr3, memrchr3_iter, memrchr_iter, + Memchr, Memchr2, Memchr3, +}; + +#[macro_use] +mod macros; + +#[cfg(test)] +#[macro_use] +mod tests; + +pub mod arch; +mod cow; +mod ext; +mod memchr; +pub mod memmem; +mod vector; diff --git a/vendor/memchr/src/macros.rs b/vendor/memchr/src/macros.rs new file mode 100644 index 0000000..31b4ca3 --- /dev/null +++ b/vendor/memchr/src/macros.rs @@ -0,0 +1,20 @@ +// Some feature combinations result in some of these macros never being used. +// Which is fine. Just squash the warnings. +#![allow(unused_macros)] + +macro_rules! log { + ($($tt:tt)*) => { + #[cfg(feature = "logging")] + { + $($tt)* + } + } +} + +macro_rules! debug { + ($($tt:tt)*) => { log!(log::debug!($($tt)*)) } +} + +macro_rules! trace { + ($($tt:tt)*) => { log!(log::trace!($($tt)*)) } +} diff --git a/vendor/memchr/src/memchr.rs b/vendor/memchr/src/memchr.rs new file mode 100644 index 0000000..92a18bd --- /dev/null +++ b/vendor/memchr/src/memchr.rs @@ -0,0 +1,903 @@ +use core::iter::Rev; + +use crate::arch::generic::memchr as generic; + +/// Search for the first occurrence of a byte in a slice. +/// +/// This returns the index corresponding to the first occurrence of `needle` in +/// `haystack`, or `None` if one is not found. If an index is returned, it is +/// guaranteed to be less than `haystack.len()`. +/// +/// While this is semantically the same as something like +/// `haystack.iter().position(|&b| b == needle)`, this routine will attempt to +/// use highly optimized vector operations that can be an order of magnitude +/// faster (or more). +/// +/// # Example +/// +/// This shows how to find the first position of a byte in a byte string. +/// +/// ``` +/// use memchr::memchr; +/// +/// let haystack = b"the quick brown fox"; +/// assert_eq!(memchr(b'k', haystack), Some(8)); +/// ``` +#[inline] +pub fn memchr(needle: u8, haystack: &[u8]) -> Option { + // SAFETY: memchr_raw, when a match is found, always returns a valid + // pointer between start and end. + unsafe { + generic::search_slice_with_raw(haystack, |start, end| { + memchr_raw(needle, start, end) + }) + } +} + +/// Search for the last occurrence of a byte in a slice. +/// +/// This returns the index corresponding to the last occurrence of `needle` in +/// `haystack`, or `None` if one is not found. If an index is returned, it is +/// guaranteed to be less than `haystack.len()`. +/// +/// While this is semantically the same as something like +/// `haystack.iter().rposition(|&b| b == needle)`, this routine will attempt to +/// use highly optimized vector operations that can be an order of magnitude +/// faster (or more). +/// +/// # Example +/// +/// This shows how to find the last position of a byte in a byte string. +/// +/// ``` +/// use memchr::memrchr; +/// +/// let haystack = b"the quick brown fox"; +/// assert_eq!(memrchr(b'o', haystack), Some(17)); +/// ``` +#[inline] +pub fn memrchr(needle: u8, haystack: &[u8]) -> Option { + // SAFETY: memrchr_raw, when a match is found, always returns a valid + // pointer between start and end. + unsafe { + generic::search_slice_with_raw(haystack, |start, end| { + memrchr_raw(needle, start, end) + }) + } +} + +/// Search for the first occurrence of two possible bytes in a haystack. +/// +/// This returns the index corresponding to the first occurrence of one of the +/// needle bytes in `haystack`, or `None` if one is not found. If an index is +/// returned, it is guaranteed to be less than `haystack.len()`. +/// +/// While this is semantically the same as something like +/// `haystack.iter().position(|&b| b == needle1 || b == needle2)`, this routine +/// will attempt to use highly optimized vector operations that can be an order +/// of magnitude faster (or more). +/// +/// # Example +/// +/// This shows how to find the first position of one of two possible bytes in a +/// haystack. +/// +/// ``` +/// use memchr::memchr2; +/// +/// let haystack = b"the quick brown fox"; +/// assert_eq!(memchr2(b'k', b'q', haystack), Some(4)); +/// ``` +#[inline] +pub fn memchr2(needle1: u8, needle2: u8, haystack: &[u8]) -> Option { + // SAFETY: memchr2_raw, when a match is found, always returns a valid + // pointer between start and end. + unsafe { + generic::search_slice_with_raw(haystack, |start, end| { + memchr2_raw(needle1, needle2, start, end) + }) + } +} + +/// Search for the last occurrence of two possible bytes in a haystack. +/// +/// This returns the index corresponding to the last occurrence of one of the +/// needle bytes in `haystack`, or `None` if one is not found. If an index is +/// returned, it is guaranteed to be less than `haystack.len()`. +/// +/// While this is semantically the same as something like +/// `haystack.iter().rposition(|&b| b == needle1 || b == needle2)`, this +/// routine will attempt to use highly optimized vector operations that can be +/// an order of magnitude faster (or more). +/// +/// # Example +/// +/// This shows how to find the last position of one of two possible bytes in a +/// haystack. +/// +/// ``` +/// use memchr::memrchr2; +/// +/// let haystack = b"the quick brown fox"; +/// assert_eq!(memrchr2(b'k', b'o', haystack), Some(17)); +/// ``` +#[inline] +pub fn memrchr2(needle1: u8, needle2: u8, haystack: &[u8]) -> Option { + // SAFETY: memrchr2_raw, when a match is found, always returns a valid + // pointer between start and end. + unsafe { + generic::search_slice_with_raw(haystack, |start, end| { + memrchr2_raw(needle1, needle2, start, end) + }) + } +} + +/// Search for the first occurrence of three possible bytes in a haystack. +/// +/// This returns the index corresponding to the first occurrence of one of the +/// needle bytes in `haystack`, or `None` if one is not found. If an index is +/// returned, it is guaranteed to be less than `haystack.len()`. +/// +/// While this is semantically the same as something like +/// `haystack.iter().position(|&b| b == needle1 || b == needle2 || b == needle3)`, +/// this routine will attempt to use highly optimized vector operations that +/// can be an order of magnitude faster (or more). +/// +/// # Example +/// +/// This shows how to find the first position of one of three possible bytes in +/// a haystack. +/// +/// ``` +/// use memchr::memchr3; +/// +/// let haystack = b"the quick brown fox"; +/// assert_eq!(memchr3(b'k', b'q', b'u', haystack), Some(4)); +/// ``` +#[inline] +pub fn memchr3( + needle1: u8, + needle2: u8, + needle3: u8, + haystack: &[u8], +) -> Option { + // SAFETY: memchr3_raw, when a match is found, always returns a valid + // pointer between start and end. + unsafe { + generic::search_slice_with_raw(haystack, |start, end| { + memchr3_raw(needle1, needle2, needle3, start, end) + }) + } +} + +/// Search for the last occurrence of three possible bytes in a haystack. +/// +/// This returns the index corresponding to the last occurrence of one of the +/// needle bytes in `haystack`, or `None` if one is not found. If an index is +/// returned, it is guaranteed to be less than `haystack.len()`. +/// +/// While this is semantically the same as something like +/// `haystack.iter().rposition(|&b| b == needle1 || b == needle2 || b == needle3)`, +/// this routine will attempt to use highly optimized vector operations that +/// can be an order of magnitude faster (or more). +/// +/// # Example +/// +/// This shows how to find the last position of one of three possible bytes in +/// a haystack. +/// +/// ``` +/// use memchr::memrchr3; +/// +/// let haystack = b"the quick brown fox"; +/// assert_eq!(memrchr3(b'k', b'o', b'n', haystack), Some(17)); +/// ``` +#[inline] +pub fn memrchr3( + needle1: u8, + needle2: u8, + needle3: u8, + haystack: &[u8], +) -> Option { + // SAFETY: memrchr3_raw, when a match is found, always returns a valid + // pointer between start and end. + unsafe { + generic::search_slice_with_raw(haystack, |start, end| { + memrchr3_raw(needle1, needle2, needle3, start, end) + }) + } +} + +/// Returns an iterator over all occurrences of the needle in a haystack. +/// +/// The iterator returned implements `DoubleEndedIterator`. This means it +/// can also be used to find occurrences in reverse order. +#[inline] +pub fn memchr_iter<'h>(needle: u8, haystack: &'h [u8]) -> Memchr<'h> { + Memchr::new(needle, haystack) +} + +/// Returns an iterator over all occurrences of the needle in a haystack, in +/// reverse. +#[inline] +pub fn memrchr_iter(needle: u8, haystack: &[u8]) -> Rev> { + Memchr::new(needle, haystack).rev() +} + +/// Returns an iterator over all occurrences of the needles in a haystack. +/// +/// The iterator returned implements `DoubleEndedIterator`. This means it +/// can also be used to find occurrences in reverse order. +#[inline] +pub fn memchr2_iter<'h>( + needle1: u8, + needle2: u8, + haystack: &'h [u8], +) -> Memchr2<'h> { + Memchr2::new(needle1, needle2, haystack) +} + +/// Returns an iterator over all occurrences of the needles in a haystack, in +/// reverse. +#[inline] +pub fn memrchr2_iter( + needle1: u8, + needle2: u8, + haystack: &[u8], +) -> Rev> { + Memchr2::new(needle1, needle2, haystack).rev() +} + +/// Returns an iterator over all occurrences of the needles in a haystack. +/// +/// The iterator returned implements `DoubleEndedIterator`. This means it +/// can also be used to find occurrences in reverse order. +#[inline] +pub fn memchr3_iter<'h>( + needle1: u8, + needle2: u8, + needle3: u8, + haystack: &'h [u8], +) -> Memchr3<'h> { + Memchr3::new(needle1, needle2, needle3, haystack) +} + +/// Returns an iterator over all occurrences of the needles in a haystack, in +/// reverse. +#[inline] +pub fn memrchr3_iter( + needle1: u8, + needle2: u8, + needle3: u8, + haystack: &[u8], +) -> Rev> { + Memchr3::new(needle1, needle2, needle3, haystack).rev() +} + +/// An iterator over all occurrences of a single byte in a haystack. +/// +/// This iterator implements `DoubleEndedIterator`, which means it can also be +/// used to find occurrences in reverse order. +/// +/// This iterator is created by the [`memchr_iter`] or `[memrchr_iter`] +/// functions. It can also be created with the [`Memchr::new`] method. +/// +/// The lifetime parameter `'h` refers to the lifetime of the haystack being +/// searched. +#[derive(Clone, Debug)] +pub struct Memchr<'h> { + needle1: u8, + it: crate::arch::generic::memchr::Iter<'h>, +} + +impl<'h> Memchr<'h> { + /// Returns an iterator over all occurrences of the needle byte in the + /// given haystack. + /// + /// The iterator returned implements `DoubleEndedIterator`. This means it + /// can also be used to find occurrences in reverse order. + #[inline] + pub fn new(needle1: u8, haystack: &'h [u8]) -> Memchr<'h> { + Memchr { + needle1, + it: crate::arch::generic::memchr::Iter::new(haystack), + } + } +} + +impl<'h> Iterator for Memchr<'h> { + type Item = usize; + + #[inline] + fn next(&mut self) -> Option { + // SAFETY: All of our implementations of memchr ensure that any + // pointers returns will fall within the start and end bounds, and this + // upholds the safety contract of `self.it.next`. + unsafe { + // NOTE: I attempted to define an enum of previously created + // searchers and then switch on those here instead of just + // calling `memchr_raw` (or `One::new(..).find_raw(..)`). But + // that turned out to have a fair bit of extra overhead when + // searching very small haystacks. + self.it.next(|s, e| memchr_raw(self.needle1, s, e)) + } + } + + #[inline] + fn count(self) -> usize { + self.it.count(|s, e| { + // SAFETY: We rely on our generic iterator to return valid start + // and end pointers. + unsafe { count_raw(self.needle1, s, e) } + }) + } + + #[inline] + fn size_hint(&self) -> (usize, Option) { + self.it.size_hint() + } +} + +impl<'h> DoubleEndedIterator for Memchr<'h> { + #[inline] + fn next_back(&mut self) -> Option { + // SAFETY: All of our implementations of memchr ensure that any + // pointers returns will fall within the start and end bounds, and this + // upholds the safety contract of `self.it.next_back`. + unsafe { self.it.next_back(|s, e| memrchr_raw(self.needle1, s, e)) } + } +} + +impl<'h> core::iter::FusedIterator for Memchr<'h> {} + +/// An iterator over all occurrences of two possible bytes in a haystack. +/// +/// This iterator implements `DoubleEndedIterator`, which means it can also be +/// used to find occurrences in reverse order. +/// +/// This iterator is created by the [`memchr2_iter`] or `[memrchr2_iter`] +/// functions. It can also be created with the [`Memchr2::new`] method. +/// +/// The lifetime parameter `'h` refers to the lifetime of the haystack being +/// searched. +#[derive(Clone, Debug)] +pub struct Memchr2<'h> { + needle1: u8, + needle2: u8, + it: crate::arch::generic::memchr::Iter<'h>, +} + +impl<'h> Memchr2<'h> { + /// Returns an iterator over all occurrences of the needle bytes in the + /// given haystack. + /// + /// The iterator returned implements `DoubleEndedIterator`. This means it + /// can also be used to find occurrences in reverse order. + #[inline] + pub fn new(needle1: u8, needle2: u8, haystack: &'h [u8]) -> Memchr2<'h> { + Memchr2 { + needle1, + needle2, + it: crate::arch::generic::memchr::Iter::new(haystack), + } + } +} + +impl<'h> Iterator for Memchr2<'h> { + type Item = usize; + + #[inline] + fn next(&mut self) -> Option { + // SAFETY: All of our implementations of memchr ensure that any + // pointers returns will fall within the start and end bounds, and this + // upholds the safety contract of `self.it.next`. + unsafe { + self.it.next(|s, e| memchr2_raw(self.needle1, self.needle2, s, e)) + } + } + + #[inline] + fn size_hint(&self) -> (usize, Option) { + self.it.size_hint() + } +} + +impl<'h> DoubleEndedIterator for Memchr2<'h> { + #[inline] + fn next_back(&mut self) -> Option { + // SAFETY: All of our implementations of memchr ensure that any + // pointers returns will fall within the start and end bounds, and this + // upholds the safety contract of `self.it.next_back`. + unsafe { + self.it.next_back(|s, e| { + memrchr2_raw(self.needle1, self.needle2, s, e) + }) + } + } +} + +impl<'h> core::iter::FusedIterator for Memchr2<'h> {} + +/// An iterator over all occurrences of three possible bytes in a haystack. +/// +/// This iterator implements `DoubleEndedIterator`, which means it can also be +/// used to find occurrences in reverse order. +/// +/// This iterator is created by the [`memchr2_iter`] or `[memrchr2_iter`] +/// functions. It can also be created with the [`Memchr3::new`] method. +/// +/// The lifetime parameter `'h` refers to the lifetime of the haystack being +/// searched. +#[derive(Clone, Debug)] +pub struct Memchr3<'h> { + needle1: u8, + needle2: u8, + needle3: u8, + it: crate::arch::generic::memchr::Iter<'h>, +} + +impl<'h> Memchr3<'h> { + /// Returns an iterator over all occurrences of the needle bytes in the + /// given haystack. + /// + /// The iterator returned implements `DoubleEndedIterator`. This means it + /// can also be used to find occurrences in reverse order. + #[inline] + pub fn new( + needle1: u8, + needle2: u8, + needle3: u8, + haystack: &'h [u8], + ) -> Memchr3<'h> { + Memchr3 { + needle1, + needle2, + needle3, + it: crate::arch::generic::memchr::Iter::new(haystack), + } + } +} + +impl<'h> Iterator for Memchr3<'h> { + type Item = usize; + + #[inline] + fn next(&mut self) -> Option { + // SAFETY: All of our implementations of memchr ensure that any + // pointers returns will fall within the start and end bounds, and this + // upholds the safety contract of `self.it.next`. + unsafe { + self.it.next(|s, e| { + memchr3_raw(self.needle1, self.needle2, self.needle3, s, e) + }) + } + } + + #[inline] + fn size_hint(&self) -> (usize, Option) { + self.it.size_hint() + } +} + +impl<'h> DoubleEndedIterator for Memchr3<'h> { + #[inline] + fn next_back(&mut self) -> Option { + // SAFETY: All of our implementations of memchr ensure that any + // pointers returns will fall within the start and end bounds, and this + // upholds the safety contract of `self.it.next_back`. + unsafe { + self.it.next_back(|s, e| { + memrchr3_raw(self.needle1, self.needle2, self.needle3, s, e) + }) + } + } +} + +impl<'h> core::iter::FusedIterator for Memchr3<'h> {} + +/// memchr, but using raw pointers to represent the haystack. +/// +/// # Safety +/// +/// Pointers must be valid. See `One::find_raw`. +#[inline] +unsafe fn memchr_raw( + needle: u8, + start: *const u8, + end: *const u8, +) -> Option<*const u8> { + #[cfg(target_arch = "x86_64")] + { + // x86_64 does CPU feature detection at runtime in order to use AVX2 + // instructions even when the `avx2` feature isn't enabled at compile + // time. This function also handles using a fallback if neither AVX2 + // nor SSE2 (unusual) are available. + crate::arch::x86_64::memchr::memchr_raw(needle, start, end) + } + #[cfg(all(target_arch = "wasm32", target_feature = "simd128"))] + { + crate::arch::wasm32::memchr::memchr_raw(needle, start, end) + } + #[cfg(target_arch = "aarch64")] + { + crate::arch::aarch64::memchr::memchr_raw(needle, start, end) + } + #[cfg(not(any( + target_arch = "x86_64", + all(target_arch = "wasm32", target_feature = "simd128"), + target_arch = "aarch64" + )))] + { + crate::arch::all::memchr::One::new(needle).find_raw(start, end) + } +} + +/// memrchr, but using raw pointers to represent the haystack. +/// +/// # Safety +/// +/// Pointers must be valid. See `One::rfind_raw`. +#[inline] +unsafe fn memrchr_raw( + needle: u8, + start: *const u8, + end: *const u8, +) -> Option<*const u8> { + #[cfg(target_arch = "x86_64")] + { + crate::arch::x86_64::memchr::memrchr_raw(needle, start, end) + } + #[cfg(all(target_arch = "wasm32", target_feature = "simd128"))] + { + crate::arch::wasm32::memchr::memrchr_raw(needle, start, end) + } + #[cfg(target_arch = "aarch64")] + { + crate::arch::aarch64::memchr::memrchr_raw(needle, start, end) + } + #[cfg(not(any( + target_arch = "x86_64", + all(target_arch = "wasm32", target_feature = "simd128"), + target_arch = "aarch64" + )))] + { + crate::arch::all::memchr::One::new(needle).rfind_raw(start, end) + } +} + +/// memchr2, but using raw pointers to represent the haystack. +/// +/// # Safety +/// +/// Pointers must be valid. See `Two::find_raw`. +#[inline] +unsafe fn memchr2_raw( + needle1: u8, + needle2: u8, + start: *const u8, + end: *const u8, +) -> Option<*const u8> { + #[cfg(target_arch = "x86_64")] + { + crate::arch::x86_64::memchr::memchr2_raw(needle1, needle2, start, end) + } + #[cfg(all(target_arch = "wasm32", target_feature = "simd128"))] + { + crate::arch::wasm32::memchr::memchr2_raw(needle1, needle2, start, end) + } + #[cfg(target_arch = "aarch64")] + { + crate::arch::aarch64::memchr::memchr2_raw(needle1, needle2, start, end) + } + #[cfg(not(any( + target_arch = "x86_64", + all(target_arch = "wasm32", target_feature = "simd128"), + target_arch = "aarch64" + )))] + { + crate::arch::all::memchr::Two::new(needle1, needle2) + .find_raw(start, end) + } +} + +/// memrchr2, but using raw pointers to represent the haystack. +/// +/// # Safety +/// +/// Pointers must be valid. See `Two::rfind_raw`. +#[inline] +unsafe fn memrchr2_raw( + needle1: u8, + needle2: u8, + start: *const u8, + end: *const u8, +) -> Option<*const u8> { + #[cfg(target_arch = "x86_64")] + { + crate::arch::x86_64::memchr::memrchr2_raw(needle1, needle2, start, end) + } + #[cfg(all(target_arch = "wasm32", target_feature = "simd128"))] + { + crate::arch::wasm32::memchr::memrchr2_raw(needle1, needle2, start, end) + } + #[cfg(target_arch = "aarch64")] + { + crate::arch::aarch64::memchr::memrchr2_raw( + needle1, needle2, start, end, + ) + } + #[cfg(not(any( + target_arch = "x86_64", + all(target_arch = "wasm32", target_feature = "simd128"), + target_arch = "aarch64" + )))] + { + crate::arch::all::memchr::Two::new(needle1, needle2) + .rfind_raw(start, end) + } +} + +/// memchr3, but using raw pointers to represent the haystack. +/// +/// # Safety +/// +/// Pointers must be valid. See `Three::find_raw`. +#[inline] +unsafe fn memchr3_raw( + needle1: u8, + needle2: u8, + needle3: u8, + start: *const u8, + end: *const u8, +) -> Option<*const u8> { + #[cfg(target_arch = "x86_64")] + { + crate::arch::x86_64::memchr::memchr3_raw( + needle1, needle2, needle3, start, end, + ) + } + #[cfg(all(target_arch = "wasm32", target_feature = "simd128"))] + { + crate::arch::wasm32::memchr::memchr3_raw( + needle1, needle2, needle3, start, end, + ) + } + #[cfg(target_arch = "aarch64")] + { + crate::arch::aarch64::memchr::memchr3_raw( + needle1, needle2, needle3, start, end, + ) + } + #[cfg(not(any( + target_arch = "x86_64", + all(target_arch = "wasm32", target_feature = "simd128"), + target_arch = "aarch64" + )))] + { + crate::arch::all::memchr::Three::new(needle1, needle2, needle3) + .find_raw(start, end) + } +} + +/// memrchr3, but using raw pointers to represent the haystack. +/// +/// # Safety +/// +/// Pointers must be valid. See `Three::rfind_raw`. +#[inline] +unsafe fn memrchr3_raw( + needle1: u8, + needle2: u8, + needle3: u8, + start: *const u8, + end: *const u8, +) -> Option<*const u8> { + #[cfg(target_arch = "x86_64")] + { + crate::arch::x86_64::memchr::memrchr3_raw( + needle1, needle2, needle3, start, end, + ) + } + #[cfg(all(target_arch = "wasm32", target_feature = "simd128"))] + { + crate::arch::wasm32::memchr::memrchr3_raw( + needle1, needle2, needle3, start, end, + ) + } + #[cfg(target_arch = "aarch64")] + { + crate::arch::aarch64::memchr::memrchr3_raw( + needle1, needle2, needle3, start, end, + ) + } + #[cfg(not(any( + target_arch = "x86_64", + all(target_arch = "wasm32", target_feature = "simd128"), + target_arch = "aarch64" + )))] + { + crate::arch::all::memchr::Three::new(needle1, needle2, needle3) + .rfind_raw(start, end) + } +} + +/// Count all matching bytes, but using raw pointers to represent the haystack. +/// +/// # Safety +/// +/// Pointers must be valid. See `One::count_raw`. +#[inline] +unsafe fn count_raw(needle: u8, start: *const u8, end: *const u8) -> usize { + #[cfg(target_arch = "x86_64")] + { + crate::arch::x86_64::memchr::count_raw(needle, start, end) + } + #[cfg(all(target_arch = "wasm32", target_feature = "simd128"))] + { + crate::arch::wasm32::memchr::count_raw(needle, start, end) + } + #[cfg(target_arch = "aarch64")] + { + crate::arch::aarch64::memchr::count_raw(needle, start, end) + } + #[cfg(not(any( + target_arch = "x86_64", + all(target_arch = "wasm32", target_feature = "simd128"), + target_arch = "aarch64" + )))] + { + crate::arch::all::memchr::One::new(needle).count_raw(start, end) + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn forward1_iter() { + crate::tests::memchr::Runner::new(1).forward_iter( + |haystack, needles| { + Some(memchr_iter(needles[0], haystack).collect()) + }, + ) + } + + #[test] + fn forward1_oneshot() { + crate::tests::memchr::Runner::new(1).forward_oneshot( + |haystack, needles| Some(memchr(needles[0], haystack)), + ) + } + + #[test] + fn reverse1_iter() { + crate::tests::memchr::Runner::new(1).reverse_iter( + |haystack, needles| { + Some(memrchr_iter(needles[0], haystack).collect()) + }, + ) + } + + #[test] + fn reverse1_oneshot() { + crate::tests::memchr::Runner::new(1).reverse_oneshot( + |haystack, needles| Some(memrchr(needles[0], haystack)), + ) + } + + #[test] + fn count1_iter() { + crate::tests::memchr::Runner::new(1).count_iter(|haystack, needles| { + Some(memchr_iter(needles[0], haystack).count()) + }) + } + + #[test] + fn forward2_iter() { + crate::tests::memchr::Runner::new(2).forward_iter( + |haystack, needles| { + let n1 = needles.get(0).copied()?; + let n2 = needles.get(1).copied()?; + Some(memchr2_iter(n1, n2, haystack).collect()) + }, + ) + } + + #[test] + fn forward2_oneshot() { + crate::tests::memchr::Runner::new(2).forward_oneshot( + |haystack, needles| { + let n1 = needles.get(0).copied()?; + let n2 = needles.get(1).copied()?; + Some(memchr2(n1, n2, haystack)) + }, + ) + } + + #[test] + fn reverse2_iter() { + crate::tests::memchr::Runner::new(2).reverse_iter( + |haystack, needles| { + let n1 = needles.get(0).copied()?; + let n2 = needles.get(1).copied()?; + Some(memrchr2_iter(n1, n2, haystack).collect()) + }, + ) + } + + #[test] + fn reverse2_oneshot() { + crate::tests::memchr::Runner::new(2).reverse_oneshot( + |haystack, needles| { + let n1 = needles.get(0).copied()?; + let n2 = needles.get(1).copied()?; + Some(memrchr2(n1, n2, haystack)) + }, + ) + } + + #[test] + fn forward3_iter() { + crate::tests::memchr::Runner::new(3).forward_iter( + |haystack, needles| { + let n1 = needles.get(0).copied()?; + let n2 = needles.get(1).copied()?; + let n3 = needles.get(2).copied()?; + Some(memchr3_iter(n1, n2, n3, haystack).collect()) + }, + ) + } + + #[test] + fn forward3_oneshot() { + crate::tests::memchr::Runner::new(3).forward_oneshot( + |haystack, needles| { + let n1 = needles.get(0).copied()?; + let n2 = needles.get(1).copied()?; + let n3 = needles.get(2).copied()?; + Some(memchr3(n1, n2, n3, haystack)) + }, + ) + } + + #[test] + fn reverse3_iter() { + crate::tests::memchr::Runner::new(3).reverse_iter( + |haystack, needles| { + let n1 = needles.get(0).copied()?; + let n2 = needles.get(1).copied()?; + let n3 = needles.get(2).copied()?; + Some(memrchr3_iter(n1, n2, n3, haystack).collect()) + }, + ) + } + + #[test] + fn reverse3_oneshot() { + crate::tests::memchr::Runner::new(3).reverse_oneshot( + |haystack, needles| { + let n1 = needles.get(0).copied()?; + let n2 = needles.get(1).copied()?; + let n3 = needles.get(2).copied()?; + Some(memrchr3(n1, n2, n3, haystack)) + }, + ) + } + + // Prior to memchr 2.6, the memchr iterators both implemented Send and + // Sync. But in memchr 2.6, the iterator changed to use raw pointers + // internally and I didn't add explicit Send/Sync impls. This ended up + // regressing the API. This test ensures we don't do that again. + // + // See: https://github.com/BurntSushi/memchr/issues/133 + #[test] + fn sync_regression() { + use core::panic::{RefUnwindSafe, UnwindSafe}; + + fn assert_send_sync() {} + assert_send_sync::(); + assert_send_sync::(); + assert_send_sync::() + } +} diff --git a/vendor/memchr/src/memmem/mod.rs b/vendor/memchr/src/memmem/mod.rs new file mode 100644 index 0000000..4f04943 --- /dev/null +++ b/vendor/memchr/src/memmem/mod.rs @@ -0,0 +1,737 @@ +/*! +This module provides forward and reverse substring search routines. + +Unlike the standard library's substring search routines, these work on +arbitrary bytes. For all non-empty needles, these routines will report exactly +the same values as the corresponding routines in the standard library. For +the empty needle, the standard library reports matches only at valid UTF-8 +boundaries, where as these routines will report matches at every position. + +Other than being able to work on arbitrary bytes, the primary reason to prefer +these routines over the standard library routines is that these will generally +be faster. In some cases, significantly so. + +# Example: iterating over substring matches + +This example shows how to use [`find_iter`] to find occurrences of a substring +in a haystack. + +``` +use memchr::memmem; + +let haystack = b"foo bar foo baz foo"; + +let mut it = memmem::find_iter(haystack, "foo"); +assert_eq!(Some(0), it.next()); +assert_eq!(Some(8), it.next()); +assert_eq!(Some(16), it.next()); +assert_eq!(None, it.next()); +``` + +# Example: iterating over substring matches in reverse + +This example shows how to use [`rfind_iter`] to find occurrences of a substring +in a haystack starting from the end of the haystack. + +**NOTE:** This module does not implement double ended iterators, so reverse +searches aren't done by calling `rev` on a forward iterator. + +``` +use memchr::memmem; + +let haystack = b"foo bar foo baz foo"; + +let mut it = memmem::rfind_iter(haystack, "foo"); +assert_eq!(Some(16), it.next()); +assert_eq!(Some(8), it.next()); +assert_eq!(Some(0), it.next()); +assert_eq!(None, it.next()); +``` + +# Example: repeating a search for the same needle + +It may be possible for the overhead of constructing a substring searcher to be +measurable in some workloads. In cases where the same needle is used to search +many haystacks, it is possible to do construction once and thus to avoid it for +subsequent searches. This can be done with a [`Finder`] (or a [`FinderRev`] for +reverse searches). + +``` +use memchr::memmem; + +let finder = memmem::Finder::new("foo"); + +assert_eq!(Some(4), finder.find(b"baz foo quux")); +assert_eq!(None, finder.find(b"quux baz bar")); +``` +*/ + +pub use crate::memmem::searcher::PrefilterConfig as Prefilter; + +// This is exported here for use in the crate::arch::all::twoway +// implementation. This is essentially an abstraction breaker. Namely, the +// public API of twoway doesn't support providing a prefilter, but its crate +// internal API does. The main reason for this is that I didn't want to do the +// API design required to support it without a concrete use case. +pub(crate) use crate::memmem::searcher::Pre; + +use crate::{ + arch::all::{ + packedpair::{DefaultFrequencyRank, HeuristicFrequencyRank}, + rabinkarp, + }, + cow::CowBytes, + memmem::searcher::{PrefilterState, Searcher, SearcherRev}, +}; + +mod searcher; + +/// Returns an iterator over all non-overlapping occurrences of a substring in +/// a haystack. +/// +/// # Complexity +/// +/// This routine is guaranteed to have worst case linear time complexity +/// with respect to both the needle and the haystack. That is, this runs +/// in `O(needle.len() + haystack.len())` time. +/// +/// This routine is also guaranteed to have worst case constant space +/// complexity. +/// +/// # Examples +/// +/// Basic usage: +/// +/// ``` +/// use memchr::memmem; +/// +/// let haystack = b"foo bar foo baz foo"; +/// let mut it = memmem::find_iter(haystack, b"foo"); +/// assert_eq!(Some(0), it.next()); +/// assert_eq!(Some(8), it.next()); +/// assert_eq!(Some(16), it.next()); +/// assert_eq!(None, it.next()); +/// ``` +#[inline] +pub fn find_iter<'h, 'n, N: 'n + ?Sized + AsRef<[u8]>>( + haystack: &'h [u8], + needle: &'n N, +) -> FindIter<'h, 'n> { + FindIter::new(haystack, Finder::new(needle)) +} + +/// Returns a reverse iterator over all non-overlapping occurrences of a +/// substring in a haystack. +/// +/// # Complexity +/// +/// This routine is guaranteed to have worst case linear time complexity +/// with respect to both the needle and the haystack. That is, this runs +/// in `O(needle.len() + haystack.len())` time. +/// +/// This routine is also guaranteed to have worst case constant space +/// complexity. +/// +/// # Examples +/// +/// Basic usage: +/// +/// ``` +/// use memchr::memmem; +/// +/// let haystack = b"foo bar foo baz foo"; +/// let mut it = memmem::rfind_iter(haystack, b"foo"); +/// assert_eq!(Some(16), it.next()); +/// assert_eq!(Some(8), it.next()); +/// assert_eq!(Some(0), it.next()); +/// assert_eq!(None, it.next()); +/// ``` +#[inline] +pub fn rfind_iter<'h, 'n, N: 'n + ?Sized + AsRef<[u8]>>( + haystack: &'h [u8], + needle: &'n N, +) -> FindRevIter<'h, 'n> { + FindRevIter::new(haystack, FinderRev::new(needle)) +} + +/// Returns the index of the first occurrence of the given needle. +/// +/// Note that if you're are searching for the same needle in many different +/// small haystacks, it may be faster to initialize a [`Finder`] once, +/// and reuse it for each search. +/// +/// # Complexity +/// +/// This routine is guaranteed to have worst case linear time complexity +/// with respect to both the needle and the haystack. That is, this runs +/// in `O(needle.len() + haystack.len())` time. +/// +/// This routine is also guaranteed to have worst case constant space +/// complexity. +/// +/// # Examples +/// +/// Basic usage: +/// +/// ``` +/// use memchr::memmem; +/// +/// let haystack = b"foo bar baz"; +/// assert_eq!(Some(0), memmem::find(haystack, b"foo")); +/// assert_eq!(Some(4), memmem::find(haystack, b"bar")); +/// assert_eq!(None, memmem::find(haystack, b"quux")); +/// ``` +#[inline] +pub fn find(haystack: &[u8], needle: &[u8]) -> Option { + if haystack.len() < 64 { + rabinkarp::Finder::new(needle).find(haystack, needle) + } else { + Finder::new(needle).find(haystack) + } +} + +/// Returns the index of the last occurrence of the given needle. +/// +/// Note that if you're are searching for the same needle in many different +/// small haystacks, it may be faster to initialize a [`FinderRev`] once, +/// and reuse it for each search. +/// +/// # Complexity +/// +/// This routine is guaranteed to have worst case linear time complexity +/// with respect to both the needle and the haystack. That is, this runs +/// in `O(needle.len() + haystack.len())` time. +/// +/// This routine is also guaranteed to have worst case constant space +/// complexity. +/// +/// # Examples +/// +/// Basic usage: +/// +/// ``` +/// use memchr::memmem; +/// +/// let haystack = b"foo bar baz"; +/// assert_eq!(Some(0), memmem::rfind(haystack, b"foo")); +/// assert_eq!(Some(4), memmem::rfind(haystack, b"bar")); +/// assert_eq!(Some(8), memmem::rfind(haystack, b"ba")); +/// assert_eq!(None, memmem::rfind(haystack, b"quux")); +/// ``` +#[inline] +pub fn rfind(haystack: &[u8], needle: &[u8]) -> Option { + if haystack.len() < 64 { + rabinkarp::FinderRev::new(needle).rfind(haystack, needle) + } else { + FinderRev::new(needle).rfind(haystack) + } +} + +/// An iterator over non-overlapping substring matches. +/// +/// Matches are reported by the byte offset at which they begin. +/// +/// `'h` is the lifetime of the haystack while `'n` is the lifetime of the +/// needle. +#[derive(Debug, Clone)] +pub struct FindIter<'h, 'n> { + haystack: &'h [u8], + prestate: PrefilterState, + finder: Finder<'n>, + pos: usize, +} + +impl<'h, 'n> FindIter<'h, 'n> { + #[inline(always)] + pub(crate) fn new( + haystack: &'h [u8], + finder: Finder<'n>, + ) -> FindIter<'h, 'n> { + let prestate = PrefilterState::new(); + FindIter { haystack, prestate, finder, pos: 0 } + } + + /// Convert this iterator into its owned variant, such that it no longer + /// borrows the finder and needle. + /// + /// If this is already an owned iterator, then this is a no-op. Otherwise, + /// this copies the needle. + /// + /// This is only available when the `alloc` feature is enabled. + #[cfg(feature = "alloc")] + #[inline] + pub fn into_owned(self) -> FindIter<'h, 'static> { + FindIter { + haystack: self.haystack, + prestate: self.prestate, + finder: self.finder.into_owned(), + pos: self.pos, + } + } +} + +impl<'h, 'n> Iterator for FindIter<'h, 'n> { + type Item = usize; + + fn next(&mut self) -> Option { + let needle = self.finder.needle(); + let haystack = self.haystack.get(self.pos..)?; + let idx = + self.finder.searcher.find(&mut self.prestate, haystack, needle)?; + + let pos = self.pos + idx; + self.pos = pos + needle.len().max(1); + + Some(pos) + } + + fn size_hint(&self) -> (usize, Option) { + // The largest possible number of non-overlapping matches is the + // quotient of the haystack and the needle (or the length of the + // haystack, if the needle is empty) + match self.haystack.len().checked_sub(self.pos) { + None => (0, Some(0)), + Some(haystack_len) => match self.finder.needle().len() { + // Empty needles always succeed and match at every point + // (including the very end) + 0 => ( + haystack_len.saturating_add(1), + haystack_len.checked_add(1), + ), + needle_len => (0, Some(haystack_len / needle_len)), + }, + } + } +} + +/// An iterator over non-overlapping substring matches in reverse. +/// +/// Matches are reported by the byte offset at which they begin. +/// +/// `'h` is the lifetime of the haystack while `'n` is the lifetime of the +/// needle. +#[derive(Clone, Debug)] +pub struct FindRevIter<'h, 'n> { + haystack: &'h [u8], + finder: FinderRev<'n>, + /// When searching with an empty needle, this gets set to `None` after + /// we've yielded the last element at `0`. + pos: Option, +} + +impl<'h, 'n> FindRevIter<'h, 'n> { + #[inline(always)] + pub(crate) fn new( + haystack: &'h [u8], + finder: FinderRev<'n>, + ) -> FindRevIter<'h, 'n> { + let pos = Some(haystack.len()); + FindRevIter { haystack, finder, pos } + } + + /// Convert this iterator into its owned variant, such that it no longer + /// borrows the finder and needle. + /// + /// If this is already an owned iterator, then this is a no-op. Otherwise, + /// this copies the needle. + /// + /// This is only available when the `std` feature is enabled. + #[cfg(feature = "alloc")] + #[inline] + pub fn into_owned(self) -> FindRevIter<'h, 'static> { + FindRevIter { + haystack: self.haystack, + finder: self.finder.into_owned(), + pos: self.pos, + } + } +} + +impl<'h, 'n> Iterator for FindRevIter<'h, 'n> { + type Item = usize; + + fn next(&mut self) -> Option { + let pos = match self.pos { + None => return None, + Some(pos) => pos, + }; + let result = self.finder.rfind(&self.haystack[..pos]); + match result { + None => None, + Some(i) => { + if pos == i { + self.pos = pos.checked_sub(1); + } else { + self.pos = Some(i); + } + Some(i) + } + } + } +} + +/// A single substring searcher fixed to a particular needle. +/// +/// The purpose of this type is to permit callers to construct a substring +/// searcher that can be used to search haystacks without the overhead of +/// constructing the searcher in the first place. This is a somewhat niche +/// concern when it's necessary to re-use the same needle to search multiple +/// different haystacks with as little overhead as possible. In general, using +/// [`find`] is good enough, but `Finder` is useful when you can meaningfully +/// observe searcher construction time in a profile. +/// +/// When the `std` feature is enabled, then this type has an `into_owned` +/// version which permits building a `Finder` that is not connected to +/// the lifetime of its needle. +#[derive(Clone, Debug)] +pub struct Finder<'n> { + needle: CowBytes<'n>, + searcher: Searcher, +} + +impl<'n> Finder<'n> { + /// Create a new finder for the given needle. + #[inline] + pub fn new>(needle: &'n B) -> Finder<'n> { + FinderBuilder::new().build_forward(needle) + } + + /// Returns the index of the first occurrence of this needle in the given + /// haystack. + /// + /// # Complexity + /// + /// This routine is guaranteed to have worst case linear time complexity + /// with respect to both the needle and the haystack. That is, this runs + /// in `O(needle.len() + haystack.len())` time. + /// + /// This routine is also guaranteed to have worst case constant space + /// complexity. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// use memchr::memmem::Finder; + /// + /// let haystack = b"foo bar baz"; + /// assert_eq!(Some(0), Finder::new("foo").find(haystack)); + /// assert_eq!(Some(4), Finder::new("bar").find(haystack)); + /// assert_eq!(None, Finder::new("quux").find(haystack)); + /// ``` + #[inline] + pub fn find(&self, haystack: &[u8]) -> Option { + let mut prestate = PrefilterState::new(); + let needle = self.needle.as_slice(); + self.searcher.find(&mut prestate, haystack, needle) + } + + /// Returns an iterator over all occurrences of a substring in a haystack. + /// + /// # Complexity + /// + /// This routine is guaranteed to have worst case linear time complexity + /// with respect to both the needle and the haystack. That is, this runs + /// in `O(needle.len() + haystack.len())` time. + /// + /// This routine is also guaranteed to have worst case constant space + /// complexity. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// use memchr::memmem::Finder; + /// + /// let haystack = b"foo bar foo baz foo"; + /// let finder = Finder::new(b"foo"); + /// let mut it = finder.find_iter(haystack); + /// assert_eq!(Some(0), it.next()); + /// assert_eq!(Some(8), it.next()); + /// assert_eq!(Some(16), it.next()); + /// assert_eq!(None, it.next()); + /// ``` + #[inline] + pub fn find_iter<'a, 'h>( + &'a self, + haystack: &'h [u8], + ) -> FindIter<'h, 'a> { + FindIter::new(haystack, self.as_ref()) + } + + /// Convert this finder into its owned variant, such that it no longer + /// borrows the needle. + /// + /// If this is already an owned finder, then this is a no-op. Otherwise, + /// this copies the needle. + /// + /// This is only available when the `alloc` feature is enabled. + #[cfg(feature = "alloc")] + #[inline] + pub fn into_owned(self) -> Finder<'static> { + Finder { + needle: self.needle.into_owned(), + searcher: self.searcher.clone(), + } + } + + /// Convert this finder into its borrowed variant. + /// + /// This is primarily useful if your finder is owned and you'd like to + /// store its borrowed variant in some intermediate data structure. + /// + /// Note that the lifetime parameter of the returned finder is tied to the + /// lifetime of `self`, and may be shorter than the `'n` lifetime of the + /// needle itself. Namely, a finder's needle can be either borrowed or + /// owned, so the lifetime of the needle returned must necessarily be the + /// shorter of the two. + #[inline] + pub fn as_ref(&self) -> Finder<'_> { + Finder { + needle: CowBytes::new(self.needle()), + searcher: self.searcher.clone(), + } + } + + /// Returns the needle that this finder searches for. + /// + /// Note that the lifetime of the needle returned is tied to the lifetime + /// of the finder, and may be shorter than the `'n` lifetime. Namely, a + /// finder's needle can be either borrowed or owned, so the lifetime of the + /// needle returned must necessarily be the shorter of the two. + #[inline] + pub fn needle(&self) -> &[u8] { + self.needle.as_slice() + } +} + +/// A single substring reverse searcher fixed to a particular needle. +/// +/// The purpose of this type is to permit callers to construct a substring +/// searcher that can be used to search haystacks without the overhead of +/// constructing the searcher in the first place. This is a somewhat niche +/// concern when it's necessary to re-use the same needle to search multiple +/// different haystacks with as little overhead as possible. In general, +/// using [`rfind`] is good enough, but `FinderRev` is useful when you can +/// meaningfully observe searcher construction time in a profile. +/// +/// When the `std` feature is enabled, then this type has an `into_owned` +/// version which permits building a `FinderRev` that is not connected to +/// the lifetime of its needle. +#[derive(Clone, Debug)] +pub struct FinderRev<'n> { + needle: CowBytes<'n>, + searcher: SearcherRev, +} + +impl<'n> FinderRev<'n> { + /// Create a new reverse finder for the given needle. + #[inline] + pub fn new>(needle: &'n B) -> FinderRev<'n> { + FinderBuilder::new().build_reverse(needle) + } + + /// Returns the index of the last occurrence of this needle in the given + /// haystack. + /// + /// The haystack may be any type that can be cheaply converted into a + /// `&[u8]`. This includes, but is not limited to, `&str` and `&[u8]`. + /// + /// # Complexity + /// + /// This routine is guaranteed to have worst case linear time complexity + /// with respect to both the needle and the haystack. That is, this runs + /// in `O(needle.len() + haystack.len())` time. + /// + /// This routine is also guaranteed to have worst case constant space + /// complexity. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// use memchr::memmem::FinderRev; + /// + /// let haystack = b"foo bar baz"; + /// assert_eq!(Some(0), FinderRev::new("foo").rfind(haystack)); + /// assert_eq!(Some(4), FinderRev::new("bar").rfind(haystack)); + /// assert_eq!(None, FinderRev::new("quux").rfind(haystack)); + /// ``` + pub fn rfind>(&self, haystack: B) -> Option { + self.searcher.rfind(haystack.as_ref(), self.needle.as_slice()) + } + + /// Returns a reverse iterator over all occurrences of a substring in a + /// haystack. + /// + /// # Complexity + /// + /// This routine is guaranteed to have worst case linear time complexity + /// with respect to both the needle and the haystack. That is, this runs + /// in `O(needle.len() + haystack.len())` time. + /// + /// This routine is also guaranteed to have worst case constant space + /// complexity. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// use memchr::memmem::FinderRev; + /// + /// let haystack = b"foo bar foo baz foo"; + /// let finder = FinderRev::new(b"foo"); + /// let mut it = finder.rfind_iter(haystack); + /// assert_eq!(Some(16), it.next()); + /// assert_eq!(Some(8), it.next()); + /// assert_eq!(Some(0), it.next()); + /// assert_eq!(None, it.next()); + /// ``` + #[inline] + pub fn rfind_iter<'a, 'h>( + &'a self, + haystack: &'h [u8], + ) -> FindRevIter<'h, 'a> { + FindRevIter::new(haystack, self.as_ref()) + } + + /// Convert this finder into its owned variant, such that it no longer + /// borrows the needle. + /// + /// If this is already an owned finder, then this is a no-op. Otherwise, + /// this copies the needle. + /// + /// This is only available when the `std` feature is enabled. + #[cfg(feature = "alloc")] + #[inline] + pub fn into_owned(self) -> FinderRev<'static> { + FinderRev { + needle: self.needle.into_owned(), + searcher: self.searcher.clone(), + } + } + + /// Convert this finder into its borrowed variant. + /// + /// This is primarily useful if your finder is owned and you'd like to + /// store its borrowed variant in some intermediate data structure. + /// + /// Note that the lifetime parameter of the returned finder is tied to the + /// lifetime of `self`, and may be shorter than the `'n` lifetime of the + /// needle itself. Namely, a finder's needle can be either borrowed or + /// owned, so the lifetime of the needle returned must necessarily be the + /// shorter of the two. + #[inline] + pub fn as_ref(&self) -> FinderRev<'_> { + FinderRev { + needle: CowBytes::new(self.needle()), + searcher: self.searcher.clone(), + } + } + + /// Returns the needle that this finder searches for. + /// + /// Note that the lifetime of the needle returned is tied to the lifetime + /// of the finder, and may be shorter than the `'n` lifetime. Namely, a + /// finder's needle can be either borrowed or owned, so the lifetime of the + /// needle returned must necessarily be the shorter of the two. + #[inline] + pub fn needle(&self) -> &[u8] { + self.needle.as_slice() + } +} + +/// A builder for constructing non-default forward or reverse memmem finders. +/// +/// A builder is primarily useful for configuring a substring searcher. +/// Currently, the only configuration exposed is the ability to disable +/// heuristic prefilters used to speed up certain searches. +#[derive(Clone, Debug, Default)] +pub struct FinderBuilder { + prefilter: Prefilter, +} + +impl FinderBuilder { + /// Create a new finder builder with default settings. + pub fn new() -> FinderBuilder { + FinderBuilder::default() + } + + /// Build a forward finder using the given needle from the current + /// settings. + pub fn build_forward<'n, B: ?Sized + AsRef<[u8]>>( + &self, + needle: &'n B, + ) -> Finder<'n> { + self.build_forward_with_ranker(DefaultFrequencyRank, needle) + } + + /// Build a forward finder using the given needle and a custom heuristic for + /// determining the frequency of a given byte in the dataset. + /// See [`HeuristicFrequencyRank`] for more details. + pub fn build_forward_with_ranker< + 'n, + R: HeuristicFrequencyRank, + B: ?Sized + AsRef<[u8]>, + >( + &self, + ranker: R, + needle: &'n B, + ) -> Finder<'n> { + let needle = needle.as_ref(); + Finder { + needle: CowBytes::new(needle), + searcher: Searcher::new(self.prefilter, ranker, needle), + } + } + + /// Build a reverse finder using the given needle from the current + /// settings. + pub fn build_reverse<'n, B: ?Sized + AsRef<[u8]>>( + &self, + needle: &'n B, + ) -> FinderRev<'n> { + let needle = needle.as_ref(); + FinderRev { + needle: CowBytes::new(needle), + searcher: SearcherRev::new(needle), + } + } + + /// Configure the prefilter setting for the finder. + /// + /// See the documentation for [`Prefilter`] for more discussion on why + /// you might want to configure this. + pub fn prefilter(&mut self, prefilter: Prefilter) -> &mut FinderBuilder { + self.prefilter = prefilter; + self + } +} + +#[cfg(test)] +mod tests { + use super::*; + + define_substring_forward_quickcheck!(|h, n| Some(Finder::new(n).find(h))); + define_substring_reverse_quickcheck!(|h, n| Some( + FinderRev::new(n).rfind(h) + )); + + #[test] + fn forward() { + crate::tests::substring::Runner::new() + .fwd(|h, n| Some(Finder::new(n).find(h))) + .run(); + } + + #[test] + fn reverse() { + crate::tests::substring::Runner::new() + .rev(|h, n| Some(FinderRev::new(n).rfind(h))) + .run(); + } +} diff --git a/vendor/memchr/src/memmem/searcher.rs b/vendor/memchr/src/memmem/searcher.rs new file mode 100644 index 0000000..2a533e0 --- /dev/null +++ b/vendor/memchr/src/memmem/searcher.rs @@ -0,0 +1,1030 @@ +use crate::arch::all::{ + packedpair::{HeuristicFrequencyRank, Pair}, + rabinkarp, twoway, +}; + +#[cfg(target_arch = "aarch64")] +use crate::arch::aarch64::neon::packedpair as neon; +#[cfg(all(target_arch = "wasm32", target_feature = "simd128"))] +use crate::arch::wasm32::simd128::packedpair as simd128; +#[cfg(all(target_arch = "x86_64", target_feature = "sse2"))] +use crate::arch::x86_64::{ + avx2::packedpair as avx2, sse2::packedpair as sse2, +}; + +/// A "meta" substring searcher. +/// +/// To a first approximation, this chooses what it believes to be the "best" +/// substring search implemnetation based on the needle at construction time. +/// Then, every call to `find` will execute that particular implementation. To +/// a second approximation, multiple substring search algorithms may be used, +/// depending on the haystack. For example, for supremely short haystacks, +/// Rabin-Karp is typically used. +/// +/// See the documentation on `Prefilter` for an explanation of the dispatching +/// mechanism. The quick summary is that an enum has too much overhead and +/// we can't use dynamic dispatch via traits because we need to work in a +/// core-only environment. (Dynamic dispatch works in core-only, but you +/// need `&dyn Trait` and we really need a `Box` here. The latter +/// requires `alloc`.) So instead, we use a union and an appropriately paired +/// free function to read from the correct field on the union and execute the +/// chosen substring search implementation. +#[derive(Clone)] +pub(crate) struct Searcher { + call: SearcherKindFn, + kind: SearcherKind, + rabinkarp: rabinkarp::Finder, +} + +impl Searcher { + /// Creates a new "meta" substring searcher that attempts to choose the + /// best algorithm based on the needle, heuristics and what the current + /// target supports. + #[inline] + pub(crate) fn new( + prefilter: PrefilterConfig, + ranker: R, + needle: &[u8], + ) -> Searcher { + let rabinkarp = rabinkarp::Finder::new(needle); + if needle.len() <= 1 { + return if needle.is_empty() { + trace!("building empty substring searcher"); + Searcher { + call: searcher_kind_empty, + kind: SearcherKind { empty: () }, + rabinkarp, + } + } else { + trace!("building one-byte substring searcher"); + debug_assert_eq!(1, needle.len()); + Searcher { + call: searcher_kind_one_byte, + kind: SearcherKind { one_byte: needle[0] }, + rabinkarp, + } + }; + } + let pair = match Pair::with_ranker(needle, &ranker) { + Some(pair) => pair, + None => return Searcher::twoway(needle, rabinkarp, None), + }; + debug_assert_ne!( + pair.index1(), + pair.index2(), + "pair offsets should not be equivalent" + ); + #[cfg(all(target_arch = "x86_64", target_feature = "sse2"))] + { + if let Some(pp) = avx2::Finder::with_pair(needle, pair) { + if do_packed_search(needle) { + trace!("building x86_64 AVX2 substring searcher"); + let kind = SearcherKind { avx2: pp }; + Searcher { call: searcher_kind_avx2, kind, rabinkarp } + } else if prefilter.is_none() { + Searcher::twoway(needle, rabinkarp, None) + } else { + let prestrat = Prefilter::avx2(pp, needle); + Searcher::twoway(needle, rabinkarp, Some(prestrat)) + } + } else if let Some(pp) = sse2::Finder::with_pair(needle, pair) { + if do_packed_search(needle) { + trace!("building x86_64 SSE2 substring searcher"); + let kind = SearcherKind { sse2: pp }; + Searcher { call: searcher_kind_sse2, kind, rabinkarp } + } else if prefilter.is_none() { + Searcher::twoway(needle, rabinkarp, None) + } else { + let prestrat = Prefilter::sse2(pp, needle); + Searcher::twoway(needle, rabinkarp, Some(prestrat)) + } + } else if prefilter.is_none() { + Searcher::twoway(needle, rabinkarp, None) + } else { + // We're pretty unlikely to get to this point, but it is + // possible to be running on x86_64 without SSE2. Namely, it's + // really up to the OS whether it wants to support vector + // registers or not. + let prestrat = Prefilter::fallback(ranker, pair, needle); + Searcher::twoway(needle, rabinkarp, prestrat) + } + } + #[cfg(all(target_arch = "wasm32", target_feature = "simd128"))] + { + if let Some(pp) = simd128::Finder::with_pair(needle, pair) { + if do_packed_search(needle) { + trace!("building wasm32 simd128 substring searcher"); + let kind = SearcherKind { simd128: pp }; + Searcher { call: searcher_kind_simd128, kind, rabinkarp } + } else if prefilter.is_none() { + Searcher::twoway(needle, rabinkarp, None) + } else { + let prestrat = Prefilter::simd128(pp, needle); + Searcher::twoway(needle, rabinkarp, Some(prestrat)) + } + } else if prefilter.is_none() { + Searcher::twoway(needle, rabinkarp, None) + } else { + let prestrat = Prefilter::fallback(ranker, pair, needle); + Searcher::twoway(needle, rabinkarp, prestrat) + } + } + #[cfg(target_arch = "aarch64")] + { + if let Some(pp) = neon::Finder::with_pair(needle, pair) { + if do_packed_search(needle) { + trace!("building aarch64 neon substring searcher"); + let kind = SearcherKind { neon: pp }; + Searcher { call: searcher_kind_neon, kind, rabinkarp } + } else if prefilter.is_none() { + Searcher::twoway(needle, rabinkarp, None) + } else { + let prestrat = Prefilter::neon(pp, needle); + Searcher::twoway(needle, rabinkarp, Some(prestrat)) + } + } else if prefilter.is_none() { + Searcher::twoway(needle, rabinkarp, None) + } else { + let prestrat = Prefilter::fallback(ranker, pair, needle); + Searcher::twoway(needle, rabinkarp, prestrat) + } + } + #[cfg(not(any( + all(target_arch = "x86_64", target_feature = "sse2"), + all(target_arch = "wasm32", target_feature = "simd128"), + target_arch = "aarch64" + )))] + { + if prefilter.is_none() { + Searcher::twoway(needle, rabinkarp, None) + } else { + let prestrat = Prefilter::fallback(ranker, pair, needle); + Searcher::twoway(needle, rabinkarp, prestrat) + } + } + } + + /// Creates a new searcher that always uses the Two-Way algorithm. This is + /// typically used when vector algorithms are unavailable or inappropriate. + /// (For example, when the needle is "too long.") + /// + /// If a prefilter is given, then the searcher returned will be accelerated + /// by the prefilter. + #[inline] + fn twoway( + needle: &[u8], + rabinkarp: rabinkarp::Finder, + prestrat: Option, + ) -> Searcher { + let finder = twoway::Finder::new(needle); + match prestrat { + None => { + trace!("building scalar two-way substring searcher"); + let kind = SearcherKind { two_way: finder }; + Searcher { call: searcher_kind_two_way, kind, rabinkarp } + } + Some(prestrat) => { + trace!( + "building scalar two-way \ + substring searcher with a prefilter" + ); + let two_way_with_prefilter = + TwoWayWithPrefilter { finder, prestrat }; + let kind = SearcherKind { two_way_with_prefilter }; + Searcher { + call: searcher_kind_two_way_with_prefilter, + kind, + rabinkarp, + } + } + } + } + + /// Searches the given haystack for the given needle. The needle given + /// should be the same as the needle that this finder was initialized + /// with. + /// + /// Inlining this can lead to big wins for latency, and #[inline] doesn't + /// seem to be enough in some cases. + #[inline(always)] + pub(crate) fn find( + &self, + prestate: &mut PrefilterState, + haystack: &[u8], + needle: &[u8], + ) -> Option { + if haystack.len() < needle.len() { + None + } else { + // SAFETY: By construction, we've ensured that the function + // in `self.call` is properly paired with the union used in + // `self.kind`. + unsafe { (self.call)(self, prestate, haystack, needle) } + } + } +} + +impl core::fmt::Debug for Searcher { + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + f.debug_struct("Searcher") + .field("call", &"") + .field("kind", &"") + .field("rabinkarp", &self.rabinkarp) + .finish() + } +} + +/// A union indicating one of several possible substring search implementations +/// that are in active use. +/// +/// This union should only be read by one of the functions prefixed with +/// `searcher_kind_`. Namely, the correct function is meant to be paired with +/// the union by the caller, such that the function always reads from the +/// designated union field. +#[derive(Clone, Copy)] +union SearcherKind { + empty: (), + one_byte: u8, + two_way: twoway::Finder, + two_way_with_prefilter: TwoWayWithPrefilter, + #[cfg(all(target_arch = "x86_64", target_feature = "sse2"))] + sse2: crate::arch::x86_64::sse2::packedpair::Finder, + #[cfg(all(target_arch = "x86_64", target_feature = "sse2"))] + avx2: crate::arch::x86_64::avx2::packedpair::Finder, + #[cfg(all(target_arch = "wasm32", target_feature = "simd128"))] + simd128: crate::arch::wasm32::simd128::packedpair::Finder, + #[cfg(target_arch = "aarch64")] + neon: crate::arch::aarch64::neon::packedpair::Finder, +} + +/// A two-way substring searcher with a prefilter. +#[derive(Copy, Clone, Debug)] +struct TwoWayWithPrefilter { + finder: twoway::Finder, + prestrat: Prefilter, +} + +/// The type of a substring search function. +/// +/// # Safety +/// +/// When using a function of this type, callers must ensure that the correct +/// function is paired with the value populated in `SearcherKind` union. +type SearcherKindFn = unsafe fn( + searcher: &Searcher, + prestate: &mut PrefilterState, + haystack: &[u8], + needle: &[u8], +) -> Option; + +/// Reads from the `empty` field of `SearcherKind` to handle the case of +/// searching for the empty needle. Works on all platforms. +/// +/// # Safety +/// +/// Callers must ensure that the `searcher.kind.empty` union field is set. +unsafe fn searcher_kind_empty( + _searcher: &Searcher, + _prestate: &mut PrefilterState, + _haystack: &[u8], + _needle: &[u8], +) -> Option { + Some(0) +} + +/// Reads from the `one_byte` field of `SearcherKind` to handle the case of +/// searching for a single byte needle. Works on all platforms. +/// +/// # Safety +/// +/// Callers must ensure that the `searcher.kind.one_byte` union field is set. +unsafe fn searcher_kind_one_byte( + searcher: &Searcher, + _prestate: &mut PrefilterState, + haystack: &[u8], + _needle: &[u8], +) -> Option { + let needle = searcher.kind.one_byte; + crate::memchr(needle, haystack) +} + +/// Reads from the `two_way` field of `SearcherKind` to handle the case of +/// searching for an arbitrary needle without prefilter acceleration. Works on +/// all platforms. +/// +/// # Safety +/// +/// Callers must ensure that the `searcher.kind.two_way` union field is set. +unsafe fn searcher_kind_two_way( + searcher: &Searcher, + _prestate: &mut PrefilterState, + haystack: &[u8], + needle: &[u8], +) -> Option { + if rabinkarp::is_fast(haystack, needle) { + searcher.rabinkarp.find(haystack, needle) + } else { + searcher.kind.two_way.find(haystack, needle) + } +} + +/// Reads from the `two_way_with_prefilter` field of `SearcherKind` to handle +/// the case of searching for an arbitrary needle with prefilter acceleration. +/// Works on all platforms. +/// +/// # Safety +/// +/// Callers must ensure that the `searcher.kind.two_way_with_prefilter` union +/// field is set. +unsafe fn searcher_kind_two_way_with_prefilter( + searcher: &Searcher, + prestate: &mut PrefilterState, + haystack: &[u8], + needle: &[u8], +) -> Option { + if rabinkarp::is_fast(haystack, needle) { + searcher.rabinkarp.find(haystack, needle) + } else { + let TwoWayWithPrefilter { ref finder, ref prestrat } = + searcher.kind.two_way_with_prefilter; + let pre = Pre { prestate, prestrat }; + finder.find_with_prefilter(Some(pre), haystack, needle) + } +} + +/// Reads from the `sse2` field of `SearcherKind` to execute the x86_64 SSE2 +/// vectorized substring search implementation. +/// +/// # Safety +/// +/// Callers must ensure that the `searcher.kind.sse2` union field is set. +#[cfg(all(target_arch = "x86_64", target_feature = "sse2"))] +unsafe fn searcher_kind_sse2( + searcher: &Searcher, + _prestate: &mut PrefilterState, + haystack: &[u8], + needle: &[u8], +) -> Option { + let finder = &searcher.kind.sse2; + if haystack.len() < finder.min_haystack_len() { + searcher.rabinkarp.find(haystack, needle) + } else { + finder.find(haystack, needle) + } +} + +/// Reads from the `avx2` field of `SearcherKind` to execute the x86_64 AVX2 +/// vectorized substring search implementation. +/// +/// # Safety +/// +/// Callers must ensure that the `searcher.kind.avx2` union field is set. +#[cfg(all(target_arch = "x86_64", target_feature = "sse2"))] +unsafe fn searcher_kind_avx2( + searcher: &Searcher, + _prestate: &mut PrefilterState, + haystack: &[u8], + needle: &[u8], +) -> Option { + let finder = &searcher.kind.avx2; + if haystack.len() < finder.min_haystack_len() { + searcher.rabinkarp.find(haystack, needle) + } else { + finder.find(haystack, needle) + } +} + +/// Reads from the `simd128` field of `SearcherKind` to execute the wasm32 +/// simd128 vectorized substring search implementation. +/// +/// # Safety +/// +/// Callers must ensure that the `searcher.kind.simd128` union field is set. +#[cfg(all(target_arch = "wasm32", target_feature = "simd128"))] +unsafe fn searcher_kind_simd128( + searcher: &Searcher, + _prestate: &mut PrefilterState, + haystack: &[u8], + needle: &[u8], +) -> Option { + let finder = &searcher.kind.simd128; + if haystack.len() < finder.min_haystack_len() { + searcher.rabinkarp.find(haystack, needle) + } else { + finder.find(haystack, needle) + } +} + +/// Reads from the `neon` field of `SearcherKind` to execute the aarch64 neon +/// vectorized substring search implementation. +/// +/// # Safety +/// +/// Callers must ensure that the `searcher.kind.neon` union field is set. +#[cfg(target_arch = "aarch64")] +unsafe fn searcher_kind_neon( + searcher: &Searcher, + _prestate: &mut PrefilterState, + haystack: &[u8], + needle: &[u8], +) -> Option { + let finder = &searcher.kind.neon; + if haystack.len() < finder.min_haystack_len() { + searcher.rabinkarp.find(haystack, needle) + } else { + finder.find(haystack, needle) + } +} + +/// A reverse substring searcher. +#[derive(Clone, Debug)] +pub(crate) struct SearcherRev { + kind: SearcherRevKind, + rabinkarp: rabinkarp::FinderRev, +} + +/// The kind of the reverse searcher. +/// +/// For the reverse case, we don't do any SIMD acceleration or prefilters. +/// There is no specific technical reason why we don't, but rather don't do it +/// because it's not clear it's worth the extra code to do so. If you have a +/// use case for it, please file an issue. +/// +/// We also don't do the union trick as we do with the forward case and +/// prefilters. Basically for the same reason we don't have prefilters or +/// vector algorithms for reverse searching: it's not clear it's worth doing. +/// Please file an issue if you have a compelling use case for fast reverse +/// substring search. +#[derive(Clone, Debug)] +enum SearcherRevKind { + Empty, + OneByte { needle: u8 }, + TwoWay { finder: twoway::FinderRev }, +} + +impl SearcherRev { + /// Creates a new searcher for finding occurrences of the given needle in + /// reverse. That is, it reports the last (instead of the first) occurrence + /// of a needle in a haystack. + #[inline] + pub(crate) fn new(needle: &[u8]) -> SearcherRev { + let kind = if needle.len() <= 1 { + if needle.is_empty() { + trace!("building empty reverse substring searcher"); + SearcherRevKind::Empty + } else { + trace!("building one-byte reverse substring searcher"); + debug_assert_eq!(1, needle.len()); + SearcherRevKind::OneByte { needle: needle[0] } + } + } else { + trace!("building scalar two-way reverse substring searcher"); + let finder = twoway::FinderRev::new(needle); + SearcherRevKind::TwoWay { finder } + }; + let rabinkarp = rabinkarp::FinderRev::new(needle); + SearcherRev { kind, rabinkarp } + } + + /// Searches the given haystack for the last occurrence of the given + /// needle. The needle given should be the same as the needle that this + /// finder was initialized with. + #[inline] + pub(crate) fn rfind( + &self, + haystack: &[u8], + needle: &[u8], + ) -> Option { + if haystack.len() < needle.len() { + return None; + } + match self.kind { + SearcherRevKind::Empty => Some(haystack.len()), + SearcherRevKind::OneByte { needle } => { + crate::memrchr(needle, haystack) + } + SearcherRevKind::TwoWay { ref finder } => { + if rabinkarp::is_fast(haystack, needle) { + self.rabinkarp.rfind(haystack, needle) + } else { + finder.rfind(haystack, needle) + } + } + } + } +} + +/// Prefilter controls whether heuristics are used to accelerate searching. +/// +/// A prefilter refers to the idea of detecting candidate matches very quickly, +/// and then confirming whether those candidates are full matches. This +/// idea can be quite effective since it's often the case that looking for +/// candidates can be a lot faster than running a complete substring search +/// over the entire input. Namely, looking for candidates can be done with +/// extremely fast vectorized code. +/// +/// The downside of a prefilter is that it assumes false positives (which are +/// candidates generated by a prefilter that aren't matches) are somewhat rare +/// relative to the frequency of full matches. That is, if a lot of false +/// positives are generated, then it's possible for search time to be worse +/// than if the prefilter wasn't enabled in the first place. +/// +/// Another downside of a prefilter is that it can result in highly variable +/// performance, where some cases are extraordinarily fast and others aren't. +/// Typically, variable performance isn't a problem, but it may be for your use +/// case. +/// +/// The use of prefilters in this implementation does use a heuristic to detect +/// when a prefilter might not be carrying its weight, and will dynamically +/// disable its use. Nevertheless, this configuration option gives callers +/// the ability to disable prefilters if you have knowledge that they won't be +/// useful. +#[derive(Clone, Copy, Debug)] +#[non_exhaustive] +pub enum PrefilterConfig { + /// Never used a prefilter in substring search. + None, + /// Automatically detect whether a heuristic prefilter should be used. If + /// it is used, then heuristics will be used to dynamically disable the + /// prefilter if it is believed to not be carrying its weight. + Auto, +} + +impl Default for PrefilterConfig { + fn default() -> PrefilterConfig { + PrefilterConfig::Auto + } +} + +impl PrefilterConfig { + /// Returns true when this prefilter is set to the `None` variant. + fn is_none(&self) -> bool { + matches!(*self, PrefilterConfig::None) + } +} + +/// The implementation of a prefilter. +/// +/// This type encapsulates dispatch to one of several possible choices for a +/// prefilter. Generally speaking, all prefilters have the same approximate +/// algorithm: they choose a couple of bytes from the needle that are believed +/// to be rare, use a fast vector algorithm to look for those bytes and return +/// positions as candidates for some substring search algorithm (currently only +/// Two-Way) to confirm as a match or not. +/// +/// The differences between the algorithms are actually at the vector +/// implementation level. Namely, we need different routines based on both +/// which target architecture we're on and what CPU features are supported. +/// +/// The straight-forwardly obvious approach here is to use an enum, and make +/// `Prefilter::find` do case analysis to determine which algorithm was +/// selected and invoke it. However, I've observed that this leads to poor +/// codegen in some cases, especially in latency sensitive benchmarks. That is, +/// this approach comes with overhead that I wasn't able to eliminate. +/// +/// The second obvious approach is to use dynamic dispatch with traits. Doing +/// that in this context where `Prefilter` owns the selection generally +/// requires heap allocation, and this code is designed to run in core-only +/// environments. +/// +/// So we settle on using a union (that's `PrefilterKind`) and a function +/// pointer (that's `PrefilterKindFn`). We select the right function pointer +/// based on which field in the union we set, and that function in turn +/// knows which field of the union to access. The downside of this approach +/// is that it forces us to think about safety, but the upside is that +/// there are some nice latency improvements to benchmarks. (Especially the +/// `memmem/sliceslice/short` benchmark.) +/// +/// In cases where we've selected a vector algorithm and the haystack given +/// is too short, we fallback to the scalar version of `memchr` on the +/// `rarest_byte`. (The scalar version of `memchr` is still better than a naive +/// byte-at-a-time loop because it will read in `usize`-sized chunks at a +/// time.) +#[derive(Clone, Copy)] +struct Prefilter { + call: PrefilterKindFn, + kind: PrefilterKind, + rarest_byte: u8, + rarest_offset: u8, +} + +impl Prefilter { + /// Return a "fallback" prefilter, but only if it is believed to be + /// effective. + #[inline] + fn fallback( + ranker: R, + pair: Pair, + needle: &[u8], + ) -> Option { + /// The maximum frequency rank permitted for the fallback prefilter. + /// If the rarest byte in the needle has a frequency rank above this + /// value, then no prefilter is used if the fallback prefilter would + /// otherwise be selected. + const MAX_FALLBACK_RANK: u8 = 250; + + trace!("building fallback prefilter"); + let rarest_offset = pair.index1(); + let rarest_byte = needle[usize::from(rarest_offset)]; + let rarest_rank = ranker.rank(rarest_byte); + if rarest_rank > MAX_FALLBACK_RANK { + None + } else { + let finder = crate::arch::all::packedpair::Finder::with_pair( + needle, + pair.clone(), + )?; + let call = prefilter_kind_fallback; + let kind = PrefilterKind { fallback: finder }; + Some(Prefilter { call, kind, rarest_byte, rarest_offset }) + } + } + + /// Return a prefilter using a x86_64 SSE2 vector algorithm. + #[cfg(all(target_arch = "x86_64", target_feature = "sse2"))] + #[inline] + fn sse2(finder: sse2::Finder, needle: &[u8]) -> Prefilter { + trace!("building x86_64 SSE2 prefilter"); + let rarest_offset = finder.pair().index1(); + let rarest_byte = needle[usize::from(rarest_offset)]; + Prefilter { + call: prefilter_kind_sse2, + kind: PrefilterKind { sse2: finder }, + rarest_byte, + rarest_offset, + } + } + + /// Return a prefilter using a x86_64 AVX2 vector algorithm. + #[cfg(all(target_arch = "x86_64", target_feature = "sse2"))] + #[inline] + fn avx2(finder: avx2::Finder, needle: &[u8]) -> Prefilter { + trace!("building x86_64 AVX2 prefilter"); + let rarest_offset = finder.pair().index1(); + let rarest_byte = needle[usize::from(rarest_offset)]; + Prefilter { + call: prefilter_kind_avx2, + kind: PrefilterKind { avx2: finder }, + rarest_byte, + rarest_offset, + } + } + + /// Return a prefilter using a wasm32 simd128 vector algorithm. + #[cfg(all(target_arch = "wasm32", target_feature = "simd128"))] + #[inline] + fn simd128(finder: simd128::Finder, needle: &[u8]) -> Prefilter { + trace!("building wasm32 simd128 prefilter"); + let rarest_offset = finder.pair().index1(); + let rarest_byte = needle[usize::from(rarest_offset)]; + Prefilter { + call: prefilter_kind_simd128, + kind: PrefilterKind { simd128: finder }, + rarest_byte, + rarest_offset, + } + } + + /// Return a prefilter using a aarch64 neon vector algorithm. + #[cfg(target_arch = "aarch64")] + #[inline] + fn neon(finder: neon::Finder, needle: &[u8]) -> Prefilter { + trace!("building aarch64 neon prefilter"); + let rarest_offset = finder.pair().index1(); + let rarest_byte = needle[usize::from(rarest_offset)]; + Prefilter { + call: prefilter_kind_neon, + kind: PrefilterKind { neon: finder }, + rarest_byte, + rarest_offset, + } + } + + /// Return a *candidate* position for a match. + /// + /// When this returns an offset, it implies that a match could begin at + /// that offset, but it may not. That is, it is possible for a false + /// positive to be returned. + /// + /// When `None` is returned, then it is guaranteed that there are no + /// matches for the needle in the given haystack. That is, it is impossible + /// for a false negative to be returned. + /// + /// The purpose of this routine is to look for candidate matching positions + /// as quickly as possible before running a (likely) slower confirmation + /// step. + #[inline] + fn find(&self, haystack: &[u8]) -> Option { + // SAFETY: By construction, we've ensured that the function in + // `self.call` is properly paired with the union used in `self.kind`. + unsafe { (self.call)(self, haystack) } + } + + /// A "simple" prefilter that just looks for the occurrence of the rarest + /// byte from the needle. This is generally only used for very small + /// haystacks. + #[inline] + fn find_simple(&self, haystack: &[u8]) -> Option { + // We don't use crate::memchr here because the haystack should be small + // enough that memchr won't be able to use vector routines anyway. So + // we just skip straight to the fallback implementation which is likely + // faster. (A byte-at-a-time loop is only used when the haystack is + // smaller than `size_of::()`.) + crate::arch::all::memchr::One::new(self.rarest_byte) + .find(haystack) + .map(|i| i.saturating_sub(usize::from(self.rarest_offset))) + } +} + +impl core::fmt::Debug for Prefilter { + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + f.debug_struct("Prefilter") + .field("call", &"") + .field("kind", &"") + .field("rarest_byte", &self.rarest_byte) + .field("rarest_offset", &self.rarest_offset) + .finish() + } +} + +/// A union indicating one of several possible prefilters that are in active +/// use. +/// +/// This union should only be read by one of the functions prefixed with +/// `prefilter_kind_`. Namely, the correct function is meant to be paired with +/// the union by the caller, such that the function always reads from the +/// designated union field. +#[derive(Clone, Copy)] +union PrefilterKind { + fallback: crate::arch::all::packedpair::Finder, + #[cfg(all(target_arch = "x86_64", target_feature = "sse2"))] + sse2: crate::arch::x86_64::sse2::packedpair::Finder, + #[cfg(all(target_arch = "x86_64", target_feature = "sse2"))] + avx2: crate::arch::x86_64::avx2::packedpair::Finder, + #[cfg(all(target_arch = "wasm32", target_feature = "simd128"))] + simd128: crate::arch::wasm32::simd128::packedpair::Finder, + #[cfg(target_arch = "aarch64")] + neon: crate::arch::aarch64::neon::packedpair::Finder, +} + +/// The type of a prefilter function. +/// +/// # Safety +/// +/// When using a function of this type, callers must ensure that the correct +/// function is paired with the value populated in `PrefilterKind` union. +type PrefilterKindFn = + unsafe fn(strat: &Prefilter, haystack: &[u8]) -> Option; + +/// Reads from the `fallback` field of `PrefilterKind` to execute the fallback +/// prefilter. Works on all platforms. +/// +/// # Safety +/// +/// Callers must ensure that the `strat.kind.fallback` union field is set. +unsafe fn prefilter_kind_fallback( + strat: &Prefilter, + haystack: &[u8], +) -> Option { + strat.kind.fallback.find_prefilter(haystack) +} + +/// Reads from the `sse2` field of `PrefilterKind` to execute the x86_64 SSE2 +/// prefilter. +/// +/// # Safety +/// +/// Callers must ensure that the `strat.kind.sse2` union field is set. +#[cfg(all(target_arch = "x86_64", target_feature = "sse2"))] +unsafe fn prefilter_kind_sse2( + strat: &Prefilter, + haystack: &[u8], +) -> Option { + let finder = &strat.kind.sse2; + if haystack.len() < finder.min_haystack_len() { + strat.find_simple(haystack) + } else { + finder.find_prefilter(haystack) + } +} + +/// Reads from the `avx2` field of `PrefilterKind` to execute the x86_64 AVX2 +/// prefilter. +/// +/// # Safety +/// +/// Callers must ensure that the `strat.kind.avx2` union field is set. +#[cfg(all(target_arch = "x86_64", target_feature = "sse2"))] +unsafe fn prefilter_kind_avx2( + strat: &Prefilter, + haystack: &[u8], +) -> Option { + let finder = &strat.kind.avx2; + if haystack.len() < finder.min_haystack_len() { + strat.find_simple(haystack) + } else { + finder.find_prefilter(haystack) + } +} + +/// Reads from the `simd128` field of `PrefilterKind` to execute the wasm32 +/// simd128 prefilter. +/// +/// # Safety +/// +/// Callers must ensure that the `strat.kind.simd128` union field is set. +#[cfg(all(target_arch = "wasm32", target_feature = "simd128"))] +unsafe fn prefilter_kind_simd128( + strat: &Prefilter, + haystack: &[u8], +) -> Option { + let finder = &strat.kind.simd128; + if haystack.len() < finder.min_haystack_len() { + strat.find_simple(haystack) + } else { + finder.find_prefilter(haystack) + } +} + +/// Reads from the `neon` field of `PrefilterKind` to execute the aarch64 neon +/// prefilter. +/// +/// # Safety +/// +/// Callers must ensure that the `strat.kind.neon` union field is set. +#[cfg(target_arch = "aarch64")] +unsafe fn prefilter_kind_neon( + strat: &Prefilter, + haystack: &[u8], +) -> Option { + let finder = &strat.kind.neon; + if haystack.len() < finder.min_haystack_len() { + strat.find_simple(haystack) + } else { + finder.find_prefilter(haystack) + } +} + +/// PrefilterState tracks state associated with the effectiveness of a +/// prefilter. It is used to track how many bytes, on average, are skipped by +/// the prefilter. If this average dips below a certain threshold over time, +/// then the state renders the prefilter inert and stops using it. +/// +/// A prefilter state should be created for each search. (Where creating an +/// iterator is treated as a single search.) A prefilter state should only be +/// created from a `Freqy`. e.g., An inert `Freqy` will produce an inert +/// `PrefilterState`. +#[derive(Clone, Copy, Debug)] +pub(crate) struct PrefilterState { + /// The number of skips that has been executed. This is always 1 greater + /// than the actual number of skips. The special sentinel value of 0 + /// indicates that the prefilter is inert. This is useful to avoid + /// additional checks to determine whether the prefilter is still + /// "effective." Once a prefilter becomes inert, it should no longer be + /// used (according to our heuristics). + skips: u32, + /// The total number of bytes that have been skipped. + skipped: u32, +} + +impl PrefilterState { + /// The minimum number of skip attempts to try before considering whether + /// a prefilter is effective or not. + const MIN_SKIPS: u32 = 50; + + /// The minimum amount of bytes that skipping must average. + /// + /// This value was chosen based on varying it and checking + /// the microbenchmarks. In particular, this can impact the + /// pathological/repeated-{huge,small} benchmarks quite a bit if it's set + /// too low. + const MIN_SKIP_BYTES: u32 = 8; + + /// Create a fresh prefilter state. + #[inline] + pub(crate) fn new() -> PrefilterState { + PrefilterState { skips: 1, skipped: 0 } + } + + /// Update this state with the number of bytes skipped on the last + /// invocation of the prefilter. + #[inline] + fn update(&mut self, skipped: usize) { + self.skips = self.skips.saturating_add(1); + // We need to do this dance since it's technically possible for + // `skipped` to overflow a `u32`. (And we use a `u32` to reduce the + // size of a prefilter state.) + self.skipped = match u32::try_from(skipped) { + Err(_) => core::u32::MAX, + Ok(skipped) => self.skipped.saturating_add(skipped), + }; + } + + /// Return true if and only if this state indicates that a prefilter is + /// still effective. + #[inline] + fn is_effective(&mut self) -> bool { + if self.is_inert() { + return false; + } + if self.skips() < PrefilterState::MIN_SKIPS { + return true; + } + if self.skipped >= PrefilterState::MIN_SKIP_BYTES * self.skips() { + return true; + } + + // We're inert. + self.skips = 0; + false + } + + /// Returns true if the prefilter this state represents should no longer + /// be used. + #[inline] + fn is_inert(&self) -> bool { + self.skips == 0 + } + + /// Returns the total number of times the prefilter has been used. + #[inline] + fn skips(&self) -> u32 { + // Remember, `0` is a sentinel value indicating inertness, so we + // always need to subtract `1` to get our actual number of skips. + self.skips.saturating_sub(1) + } +} + +/// A combination of prefilter effectiveness state and the prefilter itself. +#[derive(Debug)] +pub(crate) struct Pre<'a> { + /// State that tracks the effectiveness of a prefilter. + prestate: &'a mut PrefilterState, + /// The actual prefilter. + prestrat: &'a Prefilter, +} + +impl<'a> Pre<'a> { + /// Call this prefilter on the given haystack with the given needle. + #[inline] + pub(crate) fn find(&mut self, haystack: &[u8]) -> Option { + let result = self.prestrat.find(haystack); + self.prestate.update(result.unwrap_or(haystack.len())); + result + } + + /// Return true if and only if this prefilter should be used. + #[inline] + pub(crate) fn is_effective(&mut self) -> bool { + self.prestate.is_effective() + } +} + +/// Returns true if the needle has the right characteristics for a vector +/// algorithm to handle the entirety of substring search. +/// +/// Vector algorithms can be used for prefilters for other substring search +/// algorithms (like Two-Way), but they can also be used for substring search +/// on their own. When used for substring search, vector algorithms will +/// quickly identify candidate match positions (just like in the prefilter +/// case), but instead of returning the candidate position they will try to +/// confirm the match themselves. Confirmation happens via `memcmp`. This +/// works well for short needles, but can break down when many false candidate +/// positions are generated for large needles. Thus, we only permit vector +/// algorithms to own substring search when the needle is of a certain length. +#[inline] +fn do_packed_search(needle: &[u8]) -> bool { + /// The minimum length of a needle required for this algorithm. The minimum + /// is 2 since a length of 1 should just use memchr and a length of 0 isn't + /// a case handled by this searcher. + const MIN_LEN: usize = 2; + + /// The maximum length of a needle required for this algorithm. + /// + /// In reality, there is no hard max here. The code below can handle any + /// length needle. (Perhaps that suggests there are missing optimizations.) + /// Instead, this is a heuristic and a bound guaranteeing our linear time + /// complexity. + /// + /// It is a heuristic because when a candidate match is found, memcmp is + /// run. For very large needles with lots of false positives, memcmp can + /// make the code run quite slow. + /// + /// It is a bound because the worst case behavior with memcmp is + /// multiplicative in the size of the needle and haystack, and we want + /// to keep that additive. This bound ensures we still meet that bound + /// theoretically, since it's just a constant. We aren't acting in bad + /// faith here, memcmp on tiny needles is so fast that even in pathological + /// cases (see pathological vector benchmarks), this is still just as fast + /// or faster in practice. + /// + /// This specific number was chosen by tweaking a bit and running + /// benchmarks. The rare-medium-needle, for example, gets about 5% faster + /// by using this algorithm instead of a prefilter-accelerated Two-Way. + /// There's also a theoretical desire to keep this number reasonably + /// low, to mitigate the impact of pathological cases. I did try 64, and + /// some benchmarks got a little better, and others (particularly the + /// pathological ones), got a lot worse. So... 32 it is? + const MAX_LEN: usize = 32; + MIN_LEN <= needle.len() && needle.len() <= MAX_LEN +} diff --git a/vendor/memchr/src/tests/memchr/mod.rs b/vendor/memchr/src/tests/memchr/mod.rs new file mode 100644 index 0000000..0564ad4 --- /dev/null +++ b/vendor/memchr/src/tests/memchr/mod.rs @@ -0,0 +1,307 @@ +use alloc::{ + string::{String, ToString}, + vec, + vec::Vec, +}; + +use crate::ext::Byte; + +pub(crate) mod naive; +#[macro_use] +pub(crate) mod prop; + +const SEEDS: &'static [Seed] = &[ + Seed { haystack: "a", needles: &[b'a'], positions: &[0] }, + Seed { haystack: "aa", needles: &[b'a'], positions: &[0, 1] }, + Seed { haystack: "aaa", needles: &[b'a'], positions: &[0, 1, 2] }, + Seed { haystack: "", needles: &[b'a'], positions: &[] }, + Seed { haystack: "z", needles: &[b'a'], positions: &[] }, + Seed { haystack: "zz", needles: &[b'a'], positions: &[] }, + Seed { haystack: "zza", needles: &[b'a'], positions: &[2] }, + Seed { haystack: "zaza", needles: &[b'a'], positions: &[1, 3] }, + Seed { haystack: "zzza", needles: &[b'a'], positions: &[3] }, + Seed { haystack: "\x00a", needles: &[b'a'], positions: &[1] }, + Seed { haystack: "\x00", needles: &[b'\x00'], positions: &[0] }, + Seed { haystack: "\x00\x00", needles: &[b'\x00'], positions: &[0, 1] }, + Seed { haystack: "\x00a\x00", needles: &[b'\x00'], positions: &[0, 2] }, + Seed { haystack: "zzzzzzzzzzzzzzzza", needles: &[b'a'], positions: &[16] }, + Seed { + haystack: "zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzza", + needles: &[b'a'], + positions: &[32], + }, + // two needles (applied to memchr2 + memchr3) + Seed { haystack: "az", needles: &[b'a', b'z'], positions: &[0, 1] }, + Seed { haystack: "az", needles: &[b'a', b'z'], positions: &[0, 1] }, + Seed { haystack: "az", needles: &[b'x', b'y'], positions: &[] }, + Seed { haystack: "az", needles: &[b'a', b'y'], positions: &[0] }, + Seed { haystack: "az", needles: &[b'x', b'z'], positions: &[1] }, + Seed { haystack: "yyyyaz", needles: &[b'a', b'z'], positions: &[4, 5] }, + Seed { haystack: "yyyyaz", needles: &[b'z', b'a'], positions: &[4, 5] }, + // three needles (applied to memchr3) + Seed { + haystack: "xyz", + needles: &[b'x', b'y', b'z'], + positions: &[0, 1, 2], + }, + Seed { + haystack: "zxy", + needles: &[b'x', b'y', b'z'], + positions: &[0, 1, 2], + }, + Seed { haystack: "zxy", needles: &[b'x', b'a', b'z'], positions: &[0, 1] }, + Seed { haystack: "zxy", needles: &[b't', b'a', b'z'], positions: &[0] }, + Seed { haystack: "yxz", needles: &[b't', b'a', b'z'], positions: &[2] }, +]; + +/// Runs a host of substring search tests. +/// +/// This has support for "partial" substring search implementations only work +/// for a subset of needles/haystacks. For example, the "packed pair" substring +/// search implementation only works for haystacks of some minimum length based +/// of the pair of bytes selected and the size of the vector used. +pub(crate) struct Runner { + needle_len: usize, +} + +impl Runner { + /// Create a new test runner for forward and reverse byte search + /// implementations. + /// + /// The `needle_len` given must be at most `3` and at least `1`. It + /// corresponds to the number of needle bytes to search for. + pub(crate) fn new(needle_len: usize) -> Runner { + assert!(needle_len >= 1, "needle_len must be at least 1"); + assert!(needle_len <= 3, "needle_len must be at most 3"); + Runner { needle_len } + } + + /// Run all tests. This panics on the first failure. + /// + /// If the implementation being tested returns `None` for a particular + /// haystack/needle combination, then that test is skipped. + pub(crate) fn forward_iter(self, mut test: F) + where + F: FnMut(&[u8], &[u8]) -> Option> + 'static, + { + for seed in SEEDS.iter() { + if seed.needles.len() > self.needle_len { + continue; + } + for t in seed.generate() { + let results = match test(t.haystack.as_bytes(), &t.needles) { + None => continue, + Some(results) => results, + }; + assert_eq!( + t.expected, + results, + "needles: {:?}, haystack: {:?}", + t.needles + .iter() + .map(|&b| b.to_char()) + .collect::>(), + t.haystack, + ); + } + } + } + + /// Run all tests in the reverse direction. This panics on the first + /// failure. + /// + /// If the implementation being tested returns `None` for a particular + /// haystack/needle combination, then that test is skipped. + pub(crate) fn reverse_iter(self, mut test: F) + where + F: FnMut(&[u8], &[u8]) -> Option> + 'static, + { + for seed in SEEDS.iter() { + if seed.needles.len() > self.needle_len { + continue; + } + for t in seed.generate() { + let mut results = match test(t.haystack.as_bytes(), &t.needles) + { + None => continue, + Some(results) => results, + }; + results.reverse(); + assert_eq!( + t.expected, + results, + "needles: {:?}, haystack: {:?}", + t.needles + .iter() + .map(|&b| b.to_char()) + .collect::>(), + t.haystack, + ); + } + } + } + + /// Run all tests as counting tests. This panics on the first failure. + /// + /// That is, this only checks that the number of matches is correct and + /// not whether the offsets of each match are. + pub(crate) fn count_iter(self, mut test: F) + where + F: FnMut(&[u8], &[u8]) -> Option + 'static, + { + for seed in SEEDS.iter() { + if seed.needles.len() > self.needle_len { + continue; + } + for t in seed.generate() { + let got = match test(t.haystack.as_bytes(), &t.needles) { + None => continue, + Some(got) => got, + }; + assert_eq!( + t.expected.len(), + got, + "needles: {:?}, haystack: {:?}", + t.needles + .iter() + .map(|&b| b.to_char()) + .collect::>(), + t.haystack, + ); + } + } + } + + /// Like `Runner::forward`, but for a function that returns only the next + /// match and not all matches. + /// + /// If the function returns `None`, then it is skipped. + pub(crate) fn forward_oneshot(self, mut test: F) + where + F: FnMut(&[u8], &[u8]) -> Option> + 'static, + { + self.forward_iter(move |haystack, needles| { + let mut start = 0; + let mut results = vec![]; + while let Some(i) = test(&haystack[start..], needles)? { + results.push(start + i); + start += i + 1; + } + Some(results) + }) + } + + /// Like `Runner::reverse`, but for a function that returns only the last + /// match and not all matches. + /// + /// If the function returns `None`, then it is skipped. + pub(crate) fn reverse_oneshot(self, mut test: F) + where + F: FnMut(&[u8], &[u8]) -> Option> + 'static, + { + self.reverse_iter(move |haystack, needles| { + let mut end = haystack.len(); + let mut results = vec![]; + while let Some(i) = test(&haystack[..end], needles)? { + results.push(i); + end = i; + } + Some(results) + }) + } +} + +/// A single test for memr?chr{,2,3}. +#[derive(Clone, Debug)] +struct Test { + /// The string to search in. + haystack: String, + /// The needles to look for. + needles: Vec, + /// The offsets that are expected to be found for all needles in the + /// forward direction. + expected: Vec, +} + +impl Test { + fn new(seed: &Seed) -> Test { + Test { + haystack: seed.haystack.to_string(), + needles: seed.needles.to_vec(), + expected: seed.positions.to_vec(), + } + } +} + +/// Data that can be expanded into many memchr tests by padding out the corpus. +#[derive(Clone, Debug)] +struct Seed { + /// The thing to search. We use `&str` instead of `&[u8]` because they + /// are nicer to write in tests, and we don't miss much since memchr + /// doesn't care about UTF-8. + /// + /// Corpora cannot contain either '%' or '#'. We use these bytes when + /// expanding test cases into many test cases, and we assume they are not + /// used. If they are used, `memchr_tests` will panic. + haystack: &'static str, + /// The needles to search for. This is intended to be an alternation of + /// needles. The number of needles may cause this test to be skipped for + /// some memchr variants. For example, a test with 2 needles cannot be used + /// to test `memchr`, but can be used to test `memchr2` and `memchr3`. + /// However, a test with only 1 needle can be used to test all of `memchr`, + /// `memchr2` and `memchr3`. We achieve this by filling in the needles with + /// bytes that we never used in the corpus (such as '#'). + needles: &'static [u8], + /// The positions expected to match for all of the needles. + positions: &'static [usize], +} + +impl Seed { + /// Controls how much we expand the haystack on either side for each test. + /// We lower this on Miri because otherwise running the tests would take + /// forever. + const EXPAND_LEN: usize = { + #[cfg(not(miri))] + { + 515 + } + #[cfg(miri)] + { + 6 + } + }; + + /// Expand this test into many variations of the same test. + /// + /// In particular, this will generate more tests with larger corpus sizes. + /// The expected positions are updated to maintain the integrity of the + /// test. + /// + /// This is important in testing a memchr implementation, because there are + /// often different cases depending on the length of the corpus. + /// + /// Note that we extend the corpus by adding `%` bytes, which we + /// don't otherwise use as a needle. + fn generate(&self) -> impl Iterator { + let mut more = vec![]; + + // Add bytes to the start of the corpus. + for i in 0..Seed::EXPAND_LEN { + let mut t = Test::new(self); + let mut new: String = core::iter::repeat('%').take(i).collect(); + new.push_str(&t.haystack); + t.haystack = new; + t.expected = t.expected.into_iter().map(|p| p + i).collect(); + more.push(t); + } + // Add bytes to the end of the corpus. + for i in 1..Seed::EXPAND_LEN { + let mut t = Test::new(self); + let padding: String = core::iter::repeat('%').take(i).collect(); + t.haystack.push_str(&padding); + more.push(t); + } + + more.into_iter() + } +} diff --git a/vendor/memchr/src/tests/memchr/naive.rs b/vendor/memchr/src/tests/memchr/naive.rs new file mode 100644 index 0000000..6ebcdae --- /dev/null +++ b/vendor/memchr/src/tests/memchr/naive.rs @@ -0,0 +1,33 @@ +pub(crate) fn memchr(n1: u8, haystack: &[u8]) -> Option { + haystack.iter().position(|&b| b == n1) +} + +pub(crate) fn memchr2(n1: u8, n2: u8, haystack: &[u8]) -> Option { + haystack.iter().position(|&b| b == n1 || b == n2) +} + +pub(crate) fn memchr3( + n1: u8, + n2: u8, + n3: u8, + haystack: &[u8], +) -> Option { + haystack.iter().position(|&b| b == n1 || b == n2 || b == n3) +} + +pub(crate) fn memrchr(n1: u8, haystack: &[u8]) -> Option { + haystack.iter().rposition(|&b| b == n1) +} + +pub(crate) fn memrchr2(n1: u8, n2: u8, haystack: &[u8]) -> Option { + haystack.iter().rposition(|&b| b == n1 || b == n2) +} + +pub(crate) fn memrchr3( + n1: u8, + n2: u8, + n3: u8, + haystack: &[u8], +) -> Option { + haystack.iter().rposition(|&b| b == n1 || b == n2 || b == n3) +} diff --git a/vendor/memchr/src/tests/memchr/prop.rs b/vendor/memchr/src/tests/memchr/prop.rs new file mode 100644 index 0000000..b988260 --- /dev/null +++ b/vendor/memchr/src/tests/memchr/prop.rs @@ -0,0 +1,321 @@ +#[cfg(miri)] +#[macro_export] +macro_rules! define_memchr_quickcheck { + ($($tt:tt)*) => {}; +} + +#[cfg(not(miri))] +#[macro_export] +macro_rules! define_memchr_quickcheck { + ($mod:ident) => { + define_memchr_quickcheck!($mod, new); + }; + ($mod:ident, $cons:ident) => { + use alloc::vec::Vec; + + use quickcheck::TestResult; + + use crate::tests::memchr::{ + naive, + prop::{double_ended_take, naive1_iter, naive2_iter, naive3_iter}, + }; + + quickcheck::quickcheck! { + fn qc_memchr_matches_naive(n1: u8, corpus: Vec) -> TestResult { + let expected = naive::memchr(n1, &corpus); + let got = match $mod::One::$cons(n1) { + None => return TestResult::discard(), + Some(f) => f.find(&corpus), + }; + TestResult::from_bool(expected == got) + } + + fn qc_memrchr_matches_naive(n1: u8, corpus: Vec) -> TestResult { + let expected = naive::memrchr(n1, &corpus); + let got = match $mod::One::$cons(n1) { + None => return TestResult::discard(), + Some(f) => f.rfind(&corpus), + }; + TestResult::from_bool(expected == got) + } + + fn qc_memchr2_matches_naive(n1: u8, n2: u8, corpus: Vec) -> TestResult { + let expected = naive::memchr2(n1, n2, &corpus); + let got = match $mod::Two::$cons(n1, n2) { + None => return TestResult::discard(), + Some(f) => f.find(&corpus), + }; + TestResult::from_bool(expected == got) + } + + fn qc_memrchr2_matches_naive(n1: u8, n2: u8, corpus: Vec) -> TestResult { + let expected = naive::memrchr2(n1, n2, &corpus); + let got = match $mod::Two::$cons(n1, n2) { + None => return TestResult::discard(), + Some(f) => f.rfind(&corpus), + }; + TestResult::from_bool(expected == got) + } + + fn qc_memchr3_matches_naive( + n1: u8, n2: u8, n3: u8, + corpus: Vec + ) -> TestResult { + let expected = naive::memchr3(n1, n2, n3, &corpus); + let got = match $mod::Three::$cons(n1, n2, n3) { + None => return TestResult::discard(), + Some(f) => f.find(&corpus), + }; + TestResult::from_bool(expected == got) + } + + fn qc_memrchr3_matches_naive( + n1: u8, n2: u8, n3: u8, + corpus: Vec + ) -> TestResult { + let expected = naive::memrchr3(n1, n2, n3, &corpus); + let got = match $mod::Three::$cons(n1, n2, n3) { + None => return TestResult::discard(), + Some(f) => f.rfind(&corpus), + }; + TestResult::from_bool(expected == got) + } + + fn qc_memchr_double_ended_iter( + needle: u8, data: Vec, take_side: Vec + ) -> TestResult { + // make nonempty + let mut take_side = take_side; + if take_side.is_empty() { take_side.push(true) }; + + let finder = match $mod::One::$cons(needle) { + None => return TestResult::discard(), + Some(finder) => finder, + }; + let iter = finder.iter(&data); + let got = double_ended_take( + iter, + take_side.iter().cycle().cloned(), + ); + let expected = naive1_iter(needle, &data); + + TestResult::from_bool(got.iter().cloned().eq(expected)) + } + + fn qc_memchr2_double_ended_iter( + needle1: u8, needle2: u8, data: Vec, take_side: Vec + ) -> TestResult { + // make nonempty + let mut take_side = take_side; + if take_side.is_empty() { take_side.push(true) }; + + let finder = match $mod::Two::$cons(needle1, needle2) { + None => return TestResult::discard(), + Some(finder) => finder, + }; + let iter = finder.iter(&data); + let got = double_ended_take( + iter, + take_side.iter().cycle().cloned(), + ); + let expected = naive2_iter(needle1, needle2, &data); + + TestResult::from_bool(got.iter().cloned().eq(expected)) + } + + fn qc_memchr3_double_ended_iter( + needle1: u8, needle2: u8, needle3: u8, + data: Vec, take_side: Vec + ) -> TestResult { + // make nonempty + let mut take_side = take_side; + if take_side.is_empty() { take_side.push(true) }; + + let finder = match $mod::Three::$cons(needle1, needle2, needle3) { + None => return TestResult::discard(), + Some(finder) => finder, + }; + let iter = finder.iter(&data); + let got = double_ended_take( + iter, + take_side.iter().cycle().cloned(), + ); + let expected = naive3_iter(needle1, needle2, needle3, &data); + + TestResult::from_bool(got.iter().cloned().eq(expected)) + } + + fn qc_memchr1_iter(data: Vec) -> TestResult { + let needle = 0; + let finder = match $mod::One::$cons(needle) { + None => return TestResult::discard(), + Some(finder) => finder, + }; + let got = finder.iter(&data); + let expected = naive1_iter(needle, &data); + TestResult::from_bool(got.eq(expected)) + } + + fn qc_memchr1_rev_iter(data: Vec) -> TestResult { + let needle = 0; + + let finder = match $mod::One::$cons(needle) { + None => return TestResult::discard(), + Some(finder) => finder, + }; + let got = finder.iter(&data).rev(); + let expected = naive1_iter(needle, &data).rev(); + TestResult::from_bool(got.eq(expected)) + } + + fn qc_memchr2_iter(data: Vec) -> TestResult { + let needle1 = 0; + let needle2 = 1; + + let finder = match $mod::Two::$cons(needle1, needle2) { + None => return TestResult::discard(), + Some(finder) => finder, + }; + let got = finder.iter(&data); + let expected = naive2_iter(needle1, needle2, &data); + TestResult::from_bool(got.eq(expected)) + } + + fn qc_memchr2_rev_iter(data: Vec) -> TestResult { + let needle1 = 0; + let needle2 = 1; + + let finder = match $mod::Two::$cons(needle1, needle2) { + None => return TestResult::discard(), + Some(finder) => finder, + }; + let got = finder.iter(&data).rev(); + let expected = naive2_iter(needle1, needle2, &data).rev(); + TestResult::from_bool(got.eq(expected)) + } + + fn qc_memchr3_iter(data: Vec) -> TestResult { + let needle1 = 0; + let needle2 = 1; + let needle3 = 2; + + let finder = match $mod::Three::$cons(needle1, needle2, needle3) { + None => return TestResult::discard(), + Some(finder) => finder, + }; + let got = finder.iter(&data); + let expected = naive3_iter(needle1, needle2, needle3, &data); + TestResult::from_bool(got.eq(expected)) + } + + fn qc_memchr3_rev_iter(data: Vec) -> TestResult { + let needle1 = 0; + let needle2 = 1; + let needle3 = 2; + + let finder = match $mod::Three::$cons(needle1, needle2, needle3) { + None => return TestResult::discard(), + Some(finder) => finder, + }; + let got = finder.iter(&data).rev(); + let expected = naive3_iter(needle1, needle2, needle3, &data).rev(); + TestResult::from_bool(got.eq(expected)) + } + + fn qc_memchr1_iter_size_hint(data: Vec) -> TestResult { + // test that the size hint is within reasonable bounds + let needle = 0; + let finder = match $mod::One::$cons(needle) { + None => return TestResult::discard(), + Some(finder) => finder, + }; + let mut iter = finder.iter(&data); + let mut real_count = data + .iter() + .filter(|&&elt| elt == needle) + .count(); + + while let Some(index) = iter.next() { + real_count -= 1; + let (lower, upper) = iter.size_hint(); + assert!(lower <= real_count); + assert!(upper.unwrap() >= real_count); + assert!(upper.unwrap() <= data.len() - index); + } + TestResult::passed() + } + } + }; +} + +// take items from a DEI, taking front for each true and back for each false. +// Return a vector with the concatenation of the fronts and the reverse of the +// backs. +#[cfg(not(miri))] +pub(crate) fn double_ended_take( + mut iter: I, + take_side: J, +) -> alloc::vec::Vec +where + I: DoubleEndedIterator, + J: Iterator, +{ + let mut found_front = alloc::vec![]; + let mut found_back = alloc::vec![]; + + for take_front in take_side { + if take_front { + if let Some(pos) = iter.next() { + found_front.push(pos); + } else { + break; + } + } else { + if let Some(pos) = iter.next_back() { + found_back.push(pos); + } else { + break; + } + }; + } + + let mut all_found = found_front; + all_found.extend(found_back.into_iter().rev()); + all_found +} + +// return an iterator of the 0-based indices of haystack that match the needle +#[cfg(not(miri))] +pub(crate) fn naive1_iter<'a>( + n1: u8, + haystack: &'a [u8], +) -> impl DoubleEndedIterator + 'a { + haystack.iter().enumerate().filter(move |&(_, &b)| b == n1).map(|t| t.0) +} + +#[cfg(not(miri))] +pub(crate) fn naive2_iter<'a>( + n1: u8, + n2: u8, + haystack: &'a [u8], +) -> impl DoubleEndedIterator + 'a { + haystack + .iter() + .enumerate() + .filter(move |&(_, &b)| b == n1 || b == n2) + .map(|t| t.0) +} + +#[cfg(not(miri))] +pub(crate) fn naive3_iter<'a>( + n1: u8, + n2: u8, + n3: u8, + haystack: &'a [u8], +) -> impl DoubleEndedIterator + 'a { + haystack + .iter() + .enumerate() + .filter(move |&(_, &b)| b == n1 || b == n2 || b == n3) + .map(|t| t.0) +} diff --git a/vendor/memchr/src/tests/mod.rs b/vendor/memchr/src/tests/mod.rs new file mode 100644 index 0000000..259b678 --- /dev/null +++ b/vendor/memchr/src/tests/mod.rs @@ -0,0 +1,15 @@ +#[macro_use] +pub(crate) mod memchr; +pub(crate) mod packedpair; +#[macro_use] +pub(crate) mod substring; + +// For debugging, particularly in CI, print out the byte order of the current +// target. +#[test] +fn byte_order() { + #[cfg(target_endian = "little")] + std::eprintln!("LITTLE ENDIAN"); + #[cfg(target_endian = "big")] + std::eprintln!("BIG ENDIAN"); +} diff --git a/vendor/memchr/src/tests/packedpair.rs b/vendor/memchr/src/tests/packedpair.rs new file mode 100644 index 0000000..204635b --- /dev/null +++ b/vendor/memchr/src/tests/packedpair.rs @@ -0,0 +1,216 @@ +use alloc::{boxed::Box, vec, vec::Vec}; + +/// A set of "packed pair" test seeds. Each seed serves as the base for the +/// generation of many other tests. In essence, the seed captures the pair of +/// bytes we used for a predicate and first byte among our needle. The tests +/// generated from each seed essentially vary the length of the needle and +/// haystack, while using the rare/first byte configuration from the seed. +/// +/// The purpose of this is to test many different needle/haystack lengths. +/// In particular, some of the vector optimizations might only have bugs +/// in haystacks of a certain size. +const SEEDS: &[Seed] = &[ + // Why not use different 'first' bytes? It seemed like a good idea to be + // able to configure it, but when I wrote the test generator below, it + // didn't seem necessary to use for reasons that I forget. + Seed { first: b'x', index1: b'y', index2: b'z' }, + Seed { first: b'x', index1: b'x', index2: b'z' }, + Seed { first: b'x', index1: b'y', index2: b'x' }, + Seed { first: b'x', index1: b'x', index2: b'x' }, + Seed { first: b'x', index1: b'y', index2: b'y' }, +]; + +/// Runs a host of "packed pair" search tests. +/// +/// These tests specifically look for the occurrence of a possible substring +/// match based on a pair of bytes matching at the right offsets. +pub(crate) struct Runner { + fwd: Option< + Box< + dyn FnMut(&[u8], &[u8], u8, u8) -> Option> + 'static, + >, + >, +} + +impl Runner { + /// Create a new test runner for "packed pair" substring search. + pub(crate) fn new() -> Runner { + Runner { fwd: None } + } + + /// Run all tests. This panics on the first failure. + /// + /// If the implementation being tested returns `None` for a particular + /// haystack/needle combination, then that test is skipped. + /// + /// This runs tests on both the forward and reverse implementations given. + /// If either (or both) are missing, then tests for that implementation are + /// skipped. + pub(crate) fn run(self) { + if let Some(mut fwd) = self.fwd { + for seed in SEEDS.iter() { + for t in seed.generate() { + match fwd(&t.haystack, &t.needle, t.index1, t.index2) { + None => continue, + Some(result) => { + assert_eq!( + t.fwd, result, + "FORWARD, needle: {:?}, haystack: {:?}, \ + index1: {:?}, index2: {:?}", + t.needle, t.haystack, t.index1, t.index2, + ) + } + } + } + } + } + } + + /// Set the implementation for forward "packed pair" substring search. + /// + /// If the closure returns `None`, then it is assumed that the given + /// test cannot be applied to the particular implementation and it is + /// skipped. For example, if a particular implementation only supports + /// needles or haystacks for some minimum length. + /// + /// If this is not set, then forward "packed pair" search is not tested. + pub(crate) fn fwd( + mut self, + search: impl FnMut(&[u8], &[u8], u8, u8) -> Option> + 'static, + ) -> Runner { + self.fwd = Some(Box::new(search)); + self + } +} + +/// A test that represents the input and expected output to a "packed pair" +/// search function. The test should be able to run with any "packed pair" +/// implementation and get the expected output. +struct Test { + haystack: Vec, + needle: Vec, + index1: u8, + index2: u8, + fwd: Option, +} + +impl Test { + /// Create a new "packed pair" test from a seed and some given offsets to + /// the pair of bytes to use as a predicate in the seed's needle. + /// + /// If a valid test could not be constructed, then None is returned. + /// (Currently, we take the approach of massaging tests to be valid + /// instead of rejecting them outright.) + fn new( + seed: Seed, + index1: usize, + index2: usize, + haystack_len: usize, + needle_len: usize, + fwd: Option, + ) -> Option { + let mut index1: u8 = index1.try_into().unwrap(); + let mut index2: u8 = index2.try_into().unwrap(); + // The '#' byte is never used in a haystack (unless we're expecting + // a match), while the '@' byte is never used in a needle. + let mut haystack = vec![b'@'; haystack_len]; + let mut needle = vec![b'#'; needle_len]; + needle[0] = seed.first; + needle[index1 as usize] = seed.index1; + needle[index2 as usize] = seed.index2; + // If we're expecting a match, then make sure the needle occurs + // in the haystack at the expected position. + if let Some(i) = fwd { + haystack[i..i + needle.len()].copy_from_slice(&needle); + } + // If the operations above lead to rare offsets pointing to the + // non-first occurrence of a byte, then adjust it. This might lead + // to redundant tests, but it's simpler than trying to change the + // generation process I think. + if let Some(i) = crate::memchr(seed.index1, &needle) { + index1 = u8::try_from(i).unwrap(); + } + if let Some(i) = crate::memchr(seed.index2, &needle) { + index2 = u8::try_from(i).unwrap(); + } + Some(Test { haystack, needle, index1, index2, fwd }) + } +} + +/// Data that describes a single prefilter test seed. +#[derive(Clone, Copy)] +struct Seed { + first: u8, + index1: u8, + index2: u8, +} + +impl Seed { + const NEEDLE_LENGTH_LIMIT: usize = { + #[cfg(not(miri))] + { + 33 + } + #[cfg(miri)] + { + 5 + } + }; + + const HAYSTACK_LENGTH_LIMIT: usize = { + #[cfg(not(miri))] + { + 65 + } + #[cfg(miri)] + { + 8 + } + }; + + /// Generate a series of prefilter tests from this seed. + fn generate(self) -> impl Iterator { + let len_start = 2; + // The iterator below generates *a lot* of tests. The number of + // tests was chosen somewhat empirically to be "bearable" when + // running the test suite. + // + // We use an iterator here because the collective haystacks of all + // these test cases add up to enough memory to OOM a conservative + // sandbox or a small laptop. + (len_start..=Seed::NEEDLE_LENGTH_LIMIT).flat_map(move |needle_len| { + let index_start = len_start - 1; + (index_start..needle_len).flat_map(move |index1| { + (index1..needle_len).flat_map(move |index2| { + (needle_len..=Seed::HAYSTACK_LENGTH_LIMIT).flat_map( + move |haystack_len| { + Test::new( + self, + index1, + index2, + haystack_len, + needle_len, + None, + ) + .into_iter() + .chain( + (0..=(haystack_len - needle_len)).flat_map( + move |output| { + Test::new( + self, + index1, + index2, + haystack_len, + needle_len, + Some(output), + ) + }, + ), + ) + }, + ) + }) + }) + }) + } +} diff --git a/vendor/memchr/src/tests/substring/mod.rs b/vendor/memchr/src/tests/substring/mod.rs new file mode 100644 index 0000000..dd10cbd --- /dev/null +++ b/vendor/memchr/src/tests/substring/mod.rs @@ -0,0 +1,232 @@ +/*! +This module defines tests and test helpers for substring implementations. +*/ + +use alloc::{ + boxed::Box, + format, + string::{String, ToString}, +}; + +pub(crate) mod naive; +#[macro_use] +pub(crate) mod prop; + +const SEEDS: &'static [Seed] = &[ + Seed::new("", "", Some(0), Some(0)), + Seed::new("", "a", Some(0), Some(1)), + Seed::new("", "ab", Some(0), Some(2)), + Seed::new("", "abc", Some(0), Some(3)), + Seed::new("a", "", None, None), + Seed::new("a", "a", Some(0), Some(0)), + Seed::new("a", "aa", Some(0), Some(1)), + Seed::new("a", "ba", Some(1), Some(1)), + Seed::new("a", "bba", Some(2), Some(2)), + Seed::new("a", "bbba", Some(3), Some(3)), + Seed::new("a", "bbbab", Some(3), Some(3)), + Seed::new("a", "bbbabb", Some(3), Some(3)), + Seed::new("a", "bbbabbb", Some(3), Some(3)), + Seed::new("a", "bbbbbb", None, None), + Seed::new("ab", "", None, None), + Seed::new("ab", "a", None, None), + Seed::new("ab", "b", None, None), + Seed::new("ab", "ab", Some(0), Some(0)), + Seed::new("ab", "aab", Some(1), Some(1)), + Seed::new("ab", "aaab", Some(2), Some(2)), + Seed::new("ab", "abaab", Some(0), Some(3)), + Seed::new("ab", "baaab", Some(3), Some(3)), + Seed::new("ab", "acb", None, None), + Seed::new("ab", "abba", Some(0), Some(0)), + Seed::new("abc", "ab", None, None), + Seed::new("abc", "abc", Some(0), Some(0)), + Seed::new("abc", "abcz", Some(0), Some(0)), + Seed::new("abc", "abczz", Some(0), Some(0)), + Seed::new("abc", "zabc", Some(1), Some(1)), + Seed::new("abc", "zzabc", Some(2), Some(2)), + Seed::new("abc", "azbc", None, None), + Seed::new("abc", "abzc", None, None), + Seed::new("abczdef", "abczdefzzzzzzzzzzzzzzzzzzzz", Some(0), Some(0)), + Seed::new("abczdef", "zzzzzzzzzzzzzzzzzzzzabczdef", Some(20), Some(20)), + Seed::new( + "xyz", + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaxyz", + Some(32), + Some(32), + ), + Seed::new("\u{0}\u{15}", "\u{0}\u{15}\u{15}\u{0}", Some(0), Some(0)), + Seed::new("\u{0}\u{1e}", "\u{1e}\u{0}", None, None), +]; + +/// Runs a host of substring search tests. +/// +/// This has support for "partial" substring search implementations only work +/// for a subset of needles/haystacks. For example, the "packed pair" substring +/// search implementation only works for haystacks of some minimum length based +/// of the pair of bytes selected and the size of the vector used. +pub(crate) struct Runner { + fwd: Option< + Box Option> + 'static>, + >, + rev: Option< + Box Option> + 'static>, + >, +} + +impl Runner { + /// Create a new test runner for forward and reverse substring search + /// implementations. + pub(crate) fn new() -> Runner { + Runner { fwd: None, rev: None } + } + + /// Run all tests. This panics on the first failure. + /// + /// If the implementation being tested returns `None` for a particular + /// haystack/needle combination, then that test is skipped. + /// + /// This runs tests on both the forward and reverse implementations given. + /// If either (or both) are missing, then tests for that implementation are + /// skipped. + pub(crate) fn run(self) { + if let Some(mut fwd) = self.fwd { + for seed in SEEDS.iter() { + for t in seed.generate() { + match fwd(t.haystack.as_bytes(), t.needle.as_bytes()) { + None => continue, + Some(result) => { + assert_eq!( + t.fwd, result, + "FORWARD, needle: {:?}, haystack: {:?}", + t.needle, t.haystack, + ); + } + } + } + } + } + if let Some(mut rev) = self.rev { + for seed in SEEDS.iter() { + for t in seed.generate() { + match rev(t.haystack.as_bytes(), t.needle.as_bytes()) { + None => continue, + Some(result) => { + assert_eq!( + t.rev, result, + "REVERSE, needle: {:?}, haystack: {:?}", + t.needle, t.haystack, + ); + } + } + } + } + } + } + + /// Set the implementation for forward substring search. + /// + /// If the closure returns `None`, then it is assumed that the given + /// test cannot be applied to the particular implementation and it is + /// skipped. For example, if a particular implementation only supports + /// needles or haystacks for some minimum length. + /// + /// If this is not set, then forward substring search is not tested. + pub(crate) fn fwd( + mut self, + search: impl FnMut(&[u8], &[u8]) -> Option> + 'static, + ) -> Runner { + self.fwd = Some(Box::new(search)); + self + } + + /// Set the implementation for reverse substring search. + /// + /// If the closure returns `None`, then it is assumed that the given + /// test cannot be applied to the particular implementation and it is + /// skipped. For example, if a particular implementation only supports + /// needles or haystacks for some minimum length. + /// + /// If this is not set, then reverse substring search is not tested. + pub(crate) fn rev( + mut self, + search: impl FnMut(&[u8], &[u8]) -> Option> + 'static, + ) -> Runner { + self.rev = Some(Box::new(search)); + self + } +} + +/// A single substring test for forward and reverse searches. +#[derive(Clone, Debug)] +struct Test { + needle: String, + haystack: String, + fwd: Option, + rev: Option, +} + +/// A single substring test for forward and reverse searches. +/// +/// Each seed is valid on its own, but it also serves as a starting point +/// to generate more tests. Namely, we pad out the haystacks with other +/// characters so that we get more complete coverage. This is especially useful +/// for testing vector algorithms that tend to have weird special cases for +/// alignment and loop unrolling. +/// +/// Padding works by assuming certain characters never otherwise appear in a +/// needle or a haystack. Neither should contain a `#` character. +#[derive(Clone, Copy, Debug)] +struct Seed { + needle: &'static str, + haystack: &'static str, + fwd: Option, + rev: Option, +} + +impl Seed { + const MAX_PAD: usize = 34; + + const fn new( + needle: &'static str, + haystack: &'static str, + fwd: Option, + rev: Option, + ) -> Seed { + Seed { needle, haystack, fwd, rev } + } + + fn generate(self) -> impl Iterator { + assert!(!self.needle.contains('#'), "needle must not contain '#'"); + assert!(!self.haystack.contains('#'), "haystack must not contain '#'"); + (0..=Seed::MAX_PAD) + // Generate tests for padding at the beginning of haystack. + .map(move |pad| { + let needle = self.needle.to_string(); + let prefix = "#".repeat(pad); + let haystack = format!("{}{}", prefix, self.haystack); + let fwd = if needle.is_empty() { + Some(0) + } else { + self.fwd.map(|i| pad + i) + }; + let rev = if needle.is_empty() { + Some(haystack.len()) + } else { + self.rev.map(|i| pad + i) + }; + Test { needle, haystack, fwd, rev } + }) + // Generate tests for padding at the end of haystack. + .chain((1..=Seed::MAX_PAD).map(move |pad| { + let needle = self.needle.to_string(); + let suffix = "#".repeat(pad); + let haystack = format!("{}{}", self.haystack, suffix); + let fwd = if needle.is_empty() { Some(0) } else { self.fwd }; + let rev = if needle.is_empty() { + Some(haystack.len()) + } else { + self.rev + }; + Test { needle, haystack, fwd, rev } + })) + } +} diff --git a/vendor/memchr/src/tests/substring/naive.rs b/vendor/memchr/src/tests/substring/naive.rs new file mode 100644 index 0000000..1bc6009 --- /dev/null +++ b/vendor/memchr/src/tests/substring/naive.rs @@ -0,0 +1,45 @@ +/*! +This module defines "naive" implementations of substring search. + +These are sometimes useful to compare with "real" substring implementations. +The idea is that they are so simple that they are unlikely to be incorrect. +*/ + +/// Naively search forwards for the given needle in the given haystack. +pub(crate) fn find(haystack: &[u8], needle: &[u8]) -> Option { + let end = haystack.len().checked_sub(needle.len()).map_or(0, |i| i + 1); + for i in 0..end { + if needle == &haystack[i..i + needle.len()] { + return Some(i); + } + } + None +} + +/// Naively search in reverse for the given needle in the given haystack. +pub(crate) fn rfind(haystack: &[u8], needle: &[u8]) -> Option { + let end = haystack.len().checked_sub(needle.len()).map_or(0, |i| i + 1); + for i in (0..end).rev() { + if needle == &haystack[i..i + needle.len()] { + return Some(i); + } + } + None +} + +#[cfg(test)] +mod tests { + use crate::tests::substring; + + use super::*; + + #[test] + fn forward() { + substring::Runner::new().fwd(|h, n| Some(find(h, n))).run() + } + + #[test] + fn reverse() { + substring::Runner::new().rev(|h, n| Some(rfind(h, n))).run() + } +} diff --git a/vendor/memchr/src/tests/substring/prop.rs b/vendor/memchr/src/tests/substring/prop.rs new file mode 100644 index 0000000..a8352ec --- /dev/null +++ b/vendor/memchr/src/tests/substring/prop.rs @@ -0,0 +1,126 @@ +/*! +This module defines a few quickcheck properties for substring search. + +It also provides a forward and reverse macro for conveniently defining +quickcheck tests that run these properties over any substring search +implementation. +*/ + +use crate::tests::substring::naive; + +/// $fwd is a `impl FnMut(haystack, needle) -> Option>`. When the +/// routine returns `None`, then it's skipped, which is useful for substring +/// implementations that don't work for all inputs. +#[macro_export] +macro_rules! define_substring_forward_quickcheck { + ($fwd:expr) => { + #[cfg(not(miri))] + quickcheck::quickcheck! { + fn qc_fwd_prefix_is_substring(bs: alloc::vec::Vec) -> bool { + crate::tests::substring::prop::prefix_is_substring(&bs, $fwd) + } + + fn qc_fwd_suffix_is_substring(bs: alloc::vec::Vec) -> bool { + crate::tests::substring::prop::suffix_is_substring(&bs, $fwd) + } + + fn qc_fwd_matches_naive( + haystack: alloc::vec::Vec, + needle: alloc::vec::Vec + ) -> bool { + crate::tests::substring::prop::same_as_naive( + false, + &haystack, + &needle, + $fwd, + ) + } + } + }; +} + +/// $rev is a `impl FnMut(haystack, needle) -> Option>`. When the +/// routine returns `None`, then it's skipped, which is useful for substring +/// implementations that don't work for all inputs. +#[macro_export] +macro_rules! define_substring_reverse_quickcheck { + ($rev:expr) => { + #[cfg(not(miri))] + quickcheck::quickcheck! { + fn qc_rev_prefix_is_substring(bs: alloc::vec::Vec) -> bool { + crate::tests::substring::prop::prefix_is_substring(&bs, $rev) + } + + fn qc_rev_suffix_is_substring(bs: alloc::vec::Vec) -> bool { + crate::tests::substring::prop::suffix_is_substring(&bs, $rev) + } + + fn qc_rev_matches_naive( + haystack: alloc::vec::Vec, + needle: alloc::vec::Vec + ) -> bool { + crate::tests::substring::prop::same_as_naive( + true, + &haystack, + &needle, + $rev, + ) + } + } + }; +} + +/// Check that every prefix of the given byte string is a substring. +pub(crate) fn prefix_is_substring( + bs: &[u8], + mut search: impl FnMut(&[u8], &[u8]) -> Option>, +) -> bool { + for i in 0..bs.len().saturating_sub(1) { + let prefix = &bs[..i]; + let result = match search(bs, prefix) { + None => continue, + Some(result) => result, + }; + if !result.is_some() { + return false; + } + } + true +} + +/// Check that every suffix of the given byte string is a substring. +pub(crate) fn suffix_is_substring( + bs: &[u8], + mut search: impl FnMut(&[u8], &[u8]) -> Option>, +) -> bool { + for i in 0..bs.len().saturating_sub(1) { + let suffix = &bs[i..]; + let result = match search(bs, suffix) { + None => continue, + Some(result) => result, + }; + if !result.is_some() { + return false; + } + } + true +} + +/// Check that naive substring search matches the result of the given search +/// algorithm. +pub(crate) fn same_as_naive( + reverse: bool, + haystack: &[u8], + needle: &[u8], + mut search: impl FnMut(&[u8], &[u8]) -> Option>, +) -> bool { + let result = match search(haystack, needle) { + None => return true, + Some(result) => result, + }; + if reverse { + result == naive::rfind(haystack, needle) + } else { + result == naive::find(haystack, needle) + } +} diff --git a/vendor/memchr/src/vector.rs b/vendor/memchr/src/vector.rs new file mode 100644 index 0000000..d86fbca --- /dev/null +++ b/vendor/memchr/src/vector.rs @@ -0,0 +1,509 @@ +/// A trait for describing vector operations used by vectorized searchers. +/// +/// The trait is highly constrained to low level vector operations needed. +/// In general, it was invented mostly to be generic over x86's __m128i and +/// __m256i types. At time of writing, it also supports wasm and aarch64 +/// 128-bit vector types as well. +/// +/// # Safety +/// +/// All methods are not safe since they are intended to be implemented using +/// vendor intrinsics, which are also not safe. Callers must ensure that the +/// appropriate target features are enabled in the calling function, and that +/// the current CPU supports them. All implementations should avoid marking the +/// routines with #[target_feature] and instead mark them as #[inline(always)] +/// to ensure they get appropriately inlined. (inline(always) cannot be used +/// with target_feature.) +pub(crate) trait Vector: Copy + core::fmt::Debug { + /// The number of bytes in the vector. That is, this is the size of the + /// vector in memory. + const BYTES: usize; + /// The bits that must be zero in order for a `*const u8` pointer to be + /// correctly aligned to read vector values. + const ALIGN: usize; + + /// The type of the value returned by `Vector::movemask`. + /// + /// This supports abstracting over the specific representation used in + /// order to accommodate different representations in different ISAs. + type Mask: MoveMask; + + /// Create a vector with 8-bit lanes with the given byte repeated into each + /// lane. + unsafe fn splat(byte: u8) -> Self; + + /// Read a vector-size number of bytes from the given pointer. The pointer + /// must be aligned to the size of the vector. + /// + /// # Safety + /// + /// Callers must guarantee that at least `BYTES` bytes are readable from + /// `data` and that `data` is aligned to a `BYTES` boundary. + unsafe fn load_aligned(data: *const u8) -> Self; + + /// Read a vector-size number of bytes from the given pointer. The pointer + /// does not need to be aligned. + /// + /// # Safety + /// + /// Callers must guarantee that at least `BYTES` bytes are readable from + /// `data`. + unsafe fn load_unaligned(data: *const u8) -> Self; + + /// _mm_movemask_epi8 or _mm256_movemask_epi8 + unsafe fn movemask(self) -> Self::Mask; + /// _mm_cmpeq_epi8 or _mm256_cmpeq_epi8 + unsafe fn cmpeq(self, vector2: Self) -> Self; + /// _mm_and_si128 or _mm256_and_si256 + unsafe fn and(self, vector2: Self) -> Self; + /// _mm_or or _mm256_or_si256 + unsafe fn or(self, vector2: Self) -> Self; + /// Returns true if and only if `Self::movemask` would return a mask that + /// contains at least one non-zero bit. + unsafe fn movemask_will_have_non_zero(self) -> bool { + self.movemask().has_non_zero() + } +} + +/// A trait that abstracts over a vector-to-scalar operation called +/// "move mask." +/// +/// On x86-64, this is `_mm_movemask_epi8` for SSE2 and `_mm256_movemask_epi8` +/// for AVX2. It takes a vector of `u8` lanes and returns a scalar where the +/// `i`th bit is set if and only if the most significant bit in the `i`th lane +/// of the vector is set. The simd128 ISA for wasm32 also supports this +/// exact same operation natively. +/// +/// ... But aarch64 doesn't. So we have to fake it with more instructions and +/// a slightly different representation. We could do extra work to unify the +/// representations, but then would require additional costs in the hot path +/// for `memchr` and `packedpair`. So instead, we abstraction over the specific +/// representation with this trait an ddefine the operations we actually need. +pub(crate) trait MoveMask: Copy + core::fmt::Debug { + /// Return a mask that is all zeros except for the least significant `n` + /// lanes in a corresponding vector. + fn all_zeros_except_least_significant(n: usize) -> Self; + + /// Returns true if and only if this mask has a a non-zero bit anywhere. + fn has_non_zero(self) -> bool; + + /// Returns the number of bits set to 1 in this mask. + fn count_ones(self) -> usize; + + /// Does a bitwise `and` operation between `self` and `other`. + fn and(self, other: Self) -> Self; + + /// Does a bitwise `or` operation between `self` and `other`. + fn or(self, other: Self) -> Self; + + /// Returns a mask that is equivalent to `self` but with the least + /// significant 1-bit set to 0. + fn clear_least_significant_bit(self) -> Self; + + /// Returns the offset of the first non-zero lane this mask represents. + fn first_offset(self) -> usize; + + /// Returns the offset of the last non-zero lane this mask represents. + fn last_offset(self) -> usize; +} + +/// This is a "sensible" movemask implementation where each bit represents +/// whether the most significant bit is set in each corresponding lane of a +/// vector. This is used on x86-64 and wasm, but such a mask is more expensive +/// to get on aarch64 so we use something a little different. +/// +/// We call this "sensible" because this is what we get using native sse/avx +/// movemask instructions. But neon has no such native equivalent. +#[derive(Clone, Copy, Debug)] +pub(crate) struct SensibleMoveMask(u32); + +impl SensibleMoveMask { + /// Get the mask in a form suitable for computing offsets. + /// + /// Basically, this normalizes to little endian. On big endian, this swaps + /// the bytes. + #[inline(always)] + fn get_for_offset(self) -> u32 { + #[cfg(target_endian = "big")] + { + self.0.swap_bytes() + } + #[cfg(target_endian = "little")] + { + self.0 + } + } +} + +impl MoveMask for SensibleMoveMask { + #[inline(always)] + fn all_zeros_except_least_significant(n: usize) -> SensibleMoveMask { + debug_assert!(n < 32); + SensibleMoveMask(!((1 << n) - 1)) + } + + #[inline(always)] + fn has_non_zero(self) -> bool { + self.0 != 0 + } + + #[inline(always)] + fn count_ones(self) -> usize { + self.0.count_ones() as usize + } + + #[inline(always)] + fn and(self, other: SensibleMoveMask) -> SensibleMoveMask { + SensibleMoveMask(self.0 & other.0) + } + + #[inline(always)] + fn or(self, other: SensibleMoveMask) -> SensibleMoveMask { + SensibleMoveMask(self.0 | other.0) + } + + #[inline(always)] + fn clear_least_significant_bit(self) -> SensibleMoveMask { + SensibleMoveMask(self.0 & (self.0 - 1)) + } + + #[inline(always)] + fn first_offset(self) -> usize { + // We are dealing with little endian here (and if we aren't, we swap + // the bytes so we are in practice), where the most significant byte + // is at a higher address. That means the least significant bit that + // is set corresponds to the position of our first matching byte. + // That position corresponds to the number of zeros after the least + // significant bit. + self.get_for_offset().trailing_zeros() as usize + } + + #[inline(always)] + fn last_offset(self) -> usize { + // We are dealing with little endian here (and if we aren't, we swap + // the bytes so we are in practice), where the most significant byte is + // at a higher address. That means the most significant bit that is set + // corresponds to the position of our last matching byte. The position + // from the end of the mask is therefore the number of leading zeros + // in a 32 bit integer, and the position from the start of the mask is + // therefore 32 - (leading zeros) - 1. + 32 - self.get_for_offset().leading_zeros() as usize - 1 + } +} + +#[cfg(target_arch = "x86_64")] +mod x86sse2 { + use core::arch::x86_64::*; + + use super::{SensibleMoveMask, Vector}; + + impl Vector for __m128i { + const BYTES: usize = 16; + const ALIGN: usize = Self::BYTES - 1; + + type Mask = SensibleMoveMask; + + #[inline(always)] + unsafe fn splat(byte: u8) -> __m128i { + _mm_set1_epi8(byte as i8) + } + + #[inline(always)] + unsafe fn load_aligned(data: *const u8) -> __m128i { + _mm_load_si128(data as *const __m128i) + } + + #[inline(always)] + unsafe fn load_unaligned(data: *const u8) -> __m128i { + _mm_loadu_si128(data as *const __m128i) + } + + #[inline(always)] + unsafe fn movemask(self) -> SensibleMoveMask { + SensibleMoveMask(_mm_movemask_epi8(self) as u32) + } + + #[inline(always)] + unsafe fn cmpeq(self, vector2: Self) -> __m128i { + _mm_cmpeq_epi8(self, vector2) + } + + #[inline(always)] + unsafe fn and(self, vector2: Self) -> __m128i { + _mm_and_si128(self, vector2) + } + + #[inline(always)] + unsafe fn or(self, vector2: Self) -> __m128i { + _mm_or_si128(self, vector2) + } + } +} + +#[cfg(target_arch = "x86_64")] +mod x86avx2 { + use core::arch::x86_64::*; + + use super::{SensibleMoveMask, Vector}; + + impl Vector for __m256i { + const BYTES: usize = 32; + const ALIGN: usize = Self::BYTES - 1; + + type Mask = SensibleMoveMask; + + #[inline(always)] + unsafe fn splat(byte: u8) -> __m256i { + _mm256_set1_epi8(byte as i8) + } + + #[inline(always)] + unsafe fn load_aligned(data: *const u8) -> __m256i { + _mm256_load_si256(data as *const __m256i) + } + + #[inline(always)] + unsafe fn load_unaligned(data: *const u8) -> __m256i { + _mm256_loadu_si256(data as *const __m256i) + } + + #[inline(always)] + unsafe fn movemask(self) -> SensibleMoveMask { + SensibleMoveMask(_mm256_movemask_epi8(self) as u32) + } + + #[inline(always)] + unsafe fn cmpeq(self, vector2: Self) -> __m256i { + _mm256_cmpeq_epi8(self, vector2) + } + + #[inline(always)] + unsafe fn and(self, vector2: Self) -> __m256i { + _mm256_and_si256(self, vector2) + } + + #[inline(always)] + unsafe fn or(self, vector2: Self) -> __m256i { + _mm256_or_si256(self, vector2) + } + } +} + +#[cfg(target_arch = "aarch64")] +mod aarch64neon { + use core::arch::aarch64::*; + + use super::{MoveMask, Vector}; + + impl Vector for uint8x16_t { + const BYTES: usize = 16; + const ALIGN: usize = Self::BYTES - 1; + + type Mask = NeonMoveMask; + + #[inline(always)] + unsafe fn splat(byte: u8) -> uint8x16_t { + vdupq_n_u8(byte) + } + + #[inline(always)] + unsafe fn load_aligned(data: *const u8) -> uint8x16_t { + // I've tried `data.cast::().read()` instead, but + // couldn't observe any benchmark differences. + Self::load_unaligned(data) + } + + #[inline(always)] + unsafe fn load_unaligned(data: *const u8) -> uint8x16_t { + vld1q_u8(data) + } + + #[inline(always)] + unsafe fn movemask(self) -> NeonMoveMask { + let asu16s = vreinterpretq_u16_u8(self); + let mask = vshrn_n_u16(asu16s, 4); + let asu64 = vreinterpret_u64_u8(mask); + let scalar64 = vget_lane_u64(asu64, 0); + NeonMoveMask(scalar64 & 0x8888888888888888) + } + + #[inline(always)] + unsafe fn cmpeq(self, vector2: Self) -> uint8x16_t { + vceqq_u8(self, vector2) + } + + #[inline(always)] + unsafe fn and(self, vector2: Self) -> uint8x16_t { + vandq_u8(self, vector2) + } + + #[inline(always)] + unsafe fn or(self, vector2: Self) -> uint8x16_t { + vorrq_u8(self, vector2) + } + + /// This is the only interesting implementation of this routine. + /// Basically, instead of doing the "shift right narrow" dance, we use + /// adajacent folding max to determine whether there are any non-zero + /// bytes in our mask. If there are, *then* we'll do the "shift right + /// narrow" dance. In benchmarks, this does lead to slightly better + /// throughput, but the win doesn't appear huge. + #[inline(always)] + unsafe fn movemask_will_have_non_zero(self) -> bool { + let low = vreinterpretq_u64_u8(vpmaxq_u8(self, self)); + vgetq_lane_u64(low, 0) != 0 + } + } + + /// Neon doesn't have a `movemask` that works like the one in x86-64, so we + /// wind up using a different method[1]. The different method also produces + /// a mask, but 4 bits are set in the neon case instead of a single bit set + /// in the x86-64 case. We do an extra step to zero out 3 of the 4 bits, + /// but we still wind up with at least 3 zeroes between each set bit. This + /// generally means that we need to do some division by 4 before extracting + /// offsets. + /// + /// In fact, the existence of this type is the entire reason that we have + /// the `MoveMask` trait in the first place. This basically lets us keep + /// the different representations of masks without being forced to unify + /// them into a single representation, which could result in extra and + /// unnecessary work. + /// + /// [1]: https://community.arm.com/arm-community-blogs/b/infrastructure-solutions-blog/posts/porting-x86-vector-bitmask-optimizations-to-arm-neon + #[derive(Clone, Copy, Debug)] + pub(crate) struct NeonMoveMask(u64); + + impl NeonMoveMask { + /// Get the mask in a form suitable for computing offsets. + /// + /// Basically, this normalizes to little endian. On big endian, this + /// swaps the bytes. + #[inline(always)] + fn get_for_offset(self) -> u64 { + #[cfg(target_endian = "big")] + { + self.0.swap_bytes() + } + #[cfg(target_endian = "little")] + { + self.0 + } + } + } + + impl MoveMask for NeonMoveMask { + #[inline(always)] + fn all_zeros_except_least_significant(n: usize) -> NeonMoveMask { + debug_assert!(n < 16); + NeonMoveMask(!(((1 << n) << 2) - 1)) + } + + #[inline(always)] + fn has_non_zero(self) -> bool { + self.0 != 0 + } + + #[inline(always)] + fn count_ones(self) -> usize { + self.0.count_ones() as usize + } + + #[inline(always)] + fn and(self, other: NeonMoveMask) -> NeonMoveMask { + NeonMoveMask(self.0 & other.0) + } + + #[inline(always)] + fn or(self, other: NeonMoveMask) -> NeonMoveMask { + NeonMoveMask(self.0 | other.0) + } + + #[inline(always)] + fn clear_least_significant_bit(self) -> NeonMoveMask { + NeonMoveMask(self.0 & (self.0 - 1)) + } + + #[inline(always)] + fn first_offset(self) -> usize { + // We are dealing with little endian here (and if we aren't, + // we swap the bytes so we are in practice), where the most + // significant byte is at a higher address. That means the least + // significant bit that is set corresponds to the position of our + // first matching byte. That position corresponds to the number of + // zeros after the least significant bit. + // + // Note that unlike `SensibleMoveMask`, this mask has its bits + // spread out over 64 bits instead of 16 bits (for a 128 bit + // vector). Namely, where as x86-64 will turn + // + // 0x00 0xFF 0x00 0x00 0xFF + // + // into 10010, our neon approach will turn it into + // + // 10000000000010000000 + // + // And this happens because neon doesn't have a native `movemask` + // instruction, so we kind of fake it[1]. Thus, we divide the + // number of trailing zeros by 4 to get the "real" offset. + // + // [1]: https://community.arm.com/arm-community-blogs/b/infrastructure-solutions-blog/posts/porting-x86-vector-bitmask-optimizations-to-arm-neon + (self.get_for_offset().trailing_zeros() >> 2) as usize + } + + #[inline(always)] + fn last_offset(self) -> usize { + // See comment in `first_offset` above. This is basically the same, + // but coming from the other direction. + 16 - (self.get_for_offset().leading_zeros() >> 2) as usize - 1 + } + } +} + +#[cfg(all(target_arch = "wasm32", target_feature = "simd128"))] +mod wasm_simd128 { + use core::arch::wasm32::*; + + use super::{SensibleMoveMask, Vector}; + + impl Vector for v128 { + const BYTES: usize = 16; + const ALIGN: usize = Self::BYTES - 1; + + type Mask = SensibleMoveMask; + + #[inline(always)] + unsafe fn splat(byte: u8) -> v128 { + u8x16_splat(byte) + } + + #[inline(always)] + unsafe fn load_aligned(data: *const u8) -> v128 { + *data.cast() + } + + #[inline(always)] + unsafe fn load_unaligned(data: *const u8) -> v128 { + v128_load(data.cast()) + } + + #[inline(always)] + unsafe fn movemask(self) -> SensibleMoveMask { + SensibleMoveMask(u8x16_bitmask(self).into()) + } + + #[inline(always)] + unsafe fn cmpeq(self, vector2: Self) -> v128 { + u8x16_eq(self, vector2) + } + + #[inline(always)] + unsafe fn and(self, vector2: Self) -> v128 { + v128_and(self, vector2) + } + + #[inline(always)] + unsafe fn or(self, vector2: Self) -> v128 { + v128_or(self, vector2) + } + } +} diff --git a/vendor/once_cell/.cargo-checksum.json b/vendor/once_cell/.cargo-checksum.json new file mode 100644 index 0000000..959c377 --- /dev/null +++ b/vendor/once_cell/.cargo-checksum.json @@ -0,0 +1 @@ +{"files":{"CHANGELOG.md":"fdba39ef21a1dfd59b6b888572e519c40fc4bae2c0e9e284d4ff58f3e0d21431","Cargo.lock":"ac5867961892a63b1c7e79ebb54393d0ef2b961771273c57b9e07998ec680de9","Cargo.toml":"02488f31ca3f853d09435bbe57187ee9871250c4b448d4fbaa770c11c854cd1a","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"23f18e03dc49df91622fe2a76176497404e46ced8a715d9d2b67a7446571cca3","README.md":"2331182c8b5a6971fd0d04a0ca711d5839e93b3de6b2003108940a8c93850aaf","bors.toml":"ebd69f714a49dceb8fd10ebadfea6e2767be4732fdef49eddf6239151b4bc78c","examples/bench.rs":"1597a52529f75d6c5ad0b86759a775b1d723dfa810e2016317283b13594219da","examples/bench_acquire.rs":"9f4912ca262194cb55e893c33739c85c2f4868d07905b9dd3238552b6ce8a6e4","examples/lazy_static.rs":"8bca1b264da21eceb1ccaf30477fc941bc71bedd030f1c6982ed3a7804abfb4f","examples/reentrant_init_deadlocks.rs":"ff84929de27a848e5b155549caa96db5db5f030afca975f8ba3f3da640083001","examples/regex.rs":"4a2e0fb093c7f5bbe0fff8689fc0c670c5334344a1bfda376f5faa98a05d459f","examples/test_synchronization.rs":"88abd5c16275bb2f2d77eaecf369d97681404a77b8edd0021f24bfd377c46be3","src/imp_cs.rs":"9eb73c340931f642664a8ee7a823af318c1118fab87b1aa63489e10a73c30945","src/imp_pl.rs":"6a97f60a91ab44192dcaf028e987f6be0328b5d4d69216dcdaec93bc39401f68","src/imp_std.rs":"1c130f83be5c1360dfd379911f97797c1e4c730b845f465c8c2630467ca317d2","src/lib.rs":"60fe685113e11203ec32876b5dad9c8e1eb705da5854eff8f044d3f4651a7d0f","src/race.rs":"c61fa54fdd801949ea47cedcd6f7b563550e7ca73819b51e7a23fe39a0885c37","tests/it/main.rs":"e6e9987e053af84b9d76052602995b1e777efb5bc06cd5f49009e6f03b18626c","tests/it/race.rs":"8dfe38563b6d0be890ab076be1fc1122d41a7c7792354cd7f60bc4454666b968","tests/it/race_once_box.rs":"1c2fe9e2988ec38d60c93c797fceb4c7a65d1b2e48a6a1e78db78ab91388e844","tests/it/sync_lazy.rs":"a36c5d66340b3d6d20aad331a499858a2125dfdfd624c5bf3b4b06a0b157c75c","tests/it/sync_once_cell.rs":"0d04beeb394eb53dd3fc0309fcfc382d56350e72b89d22356e0047d6c7bfef58","tests/it/unsync_lazy.rs":"51a1ffd411770d1e32399ec23feb5f61be362bbed34e100eb7509f8496224e1a","tests/it/unsync_once_cell.rs":"82b72936d7bd4090db25cfc543c01ef3206d6917ac56f09d17d4110a65deb30a"},"package":"1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775"} \ No newline at end of file diff --git a/vendor/once_cell/CHANGELOG.md b/vendor/once_cell/CHANGELOG.md new file mode 100644 index 0000000..38c3bfc --- /dev/null +++ b/vendor/once_cell/CHANGELOG.md @@ -0,0 +1,238 @@ +# Changelog + +## Unreleased + +## 1.20.2 + +- Remove `portable_atomic` from Cargo.lock if it is not, in fact, used: [#267](https://github.com/matklad/once_cell/pull/267) + This is a work-around for this cargo bug: https://github.com/rust-lang/cargo/issues/10801. + +## 1.20.1 + +- Allow using `race` module using just `portable_atomic`, without `critical_section` and provide + better error messages on targets without atomic CAS instruction, + [#265](https://github.com/matklad/once_cell/pull/265). + +## 1.19.0 + +- Use `portable-atomic` instead of `atomic-polyfill`, [#251](https://github.com/matklad/once_cell/pull/251). + +## 1.18.0 + +- `MSRV` is updated to 1.60.0 to take advantage of `dep:` syntax for cargo features, + removing "implementation details" from publicly visible surface. + +## 1.17.2 + +- Avoid unnecessary synchronization in `Lazy::{force,deref}_mut()`, [#231](https://github.com/matklad/once_cell/pull/231). + +## 1.17.1 + +- Make `OnceRef` implementation compliant with [strict provenance](https://github.com/rust-lang/rust/issues/95228). + +## 1.17.0 + +- Add `race::OnceRef` for storing a `&'a T`. + +## 1.16.0 + +- Add `no_std` implementation based on `critical-section`, + [#195](https://github.com/matklad/once_cell/pull/195). +- Deprecate `atomic-polyfill` feature (use the new `critical-section` instead) + +## 1.15.0 + +- Increase minimal supported Rust version to 1.56.0. +- Implement `UnwindSafe` even if the `std` feature is disabled. + +## 1.14.0 + +- Add extension to `unsync` and `sync` `Lazy` mut API: + - `force_mut` + - `get_mut` + + +## 1.13.1 + +- Make implementation compliant with [strict provenance](https://github.com/rust-lang/rust/issues/95228). +- Upgrade `atomic-polyfill` to `1.0` + +## 1.13.0 + +- Add `Lazy::get`, similar to `OnceCell::get`. + +## 1.12.1 + +- Remove incorrect `debug_assert`. + +## 1.12.0 + +- Add `OnceCell::wait`, a blocking variant of `get`. + +## 1.11.0 + +- Add `OnceCell::with_value` to create initialized `OnceCell` in `const` context. +- Improve `Clone` implementation for `OnceCell`. +- Rewrite `parking_lot` version on top of `parking_lot_core`, for even smaller cells! + +## 1.10.0 + +- upgrade `parking_lot` to `0.12.0` (note that this bumps MSRV with `parking_lot` feature enabled to `1.49.0`). + +## 1.9.0 + +- Added an `atomic-polyfill` optional dependency to compile `race` on platforms without atomics + +## 1.8.0 + +- Add `try_insert` API -- a version of `set` that returns a reference. + +## 1.7.2 + +- Improve code size when using parking_lot feature. + +## 1.7.1 + +- Fix `race::OnceBox` to also impl `Default` even if `T` doesn't impl `Default`. + +## 1.7.0 + +- Hide the `race` module behind (default) `race` feature. + Turns out that adding `race` by default was a breaking change on some platforms without atomics. + In this release, we make the module opt-out. + Technically, this is a breaking change for those who use `race` with `no_default_features`. + Given that the `race` module itself only several days old, the breakage is deemed acceptable. + +## 1.6.0 + +- Add `Lazy::into_value` +- Stabilize `once_cell::race` module for "first one wins" no_std-compatible initialization flavor. +- Migrate from deprecated `compare_and_swap` to `compare_exchange`. + +## 1.5.2 + +- `OnceBox` API uses `Box`. + This a breaking change to unstable API. + +## 1.5.1 + +- MSRV is increased to `1.36.0`. +- document `once_cell::race` module. +- introduce `alloc` feature for `OnceBox`. +- fix `OnceBox::set`. + +## 1.5.0 + +- add new `once_cell::race` module for "first one wins" no_std-compatible initialization flavor. + The API is provisional, subject to change and is gated by the `unstable` cargo feature. + +## 1.4.1 + +- upgrade `parking_lot` to `0.11.0` +- make `sync::OnceCell` pass https://doc.rust-lang.org/nomicon/dropck.html#an-escape-hatch[dropck] with `parking_lot` feature enabled. + This fixes a (minor) semver-incompatible changed introduced in `1.4.0` + +## 1.4.0 + +- upgrade `parking_lot` to `0.10` (note that this bumps MSRV with `parking_lot` feature enabled to `1.36.0`). +- add `OnceCell::take`. +- upgrade crossbeam utils (private dependency) to `0.7`. + +## 1.3.1 + +- remove unnecessary `F: fmt::Debug` bound from `impl fmt::Debug for Lazy`. + +## 1.3.0 + +- `Lazy` now implements `DerefMut`. +- update implementation according to the latest changes in `std`. + +## 1.2.0 + +- add `sync::OnceCell::get_unchecked`. + +## 1.1.0 + +- implement `Default` for `Lazy`: it creates an empty `Lazy` which is initialized with `T::default` on first access. +- add `OnceCell::get_mut`. + +## 1.0.2 + +- actually add `#![no_std]` attribute if std feature is not enabled. + +## 1.0.1 + +- fix unsoundness in `Lazy` if the initializing function panics. Thanks [@xfix](https://github.com/xfix)! +- implement `RefUnwindSafe` for `Lazy`. +- share more code between `std` and `parking_lot` implementations. +- add F.A.Q section to the docs. + +## 1.0.0 + +- remove `parking_lot` from the list of default features. +- add `std` default feature. Without `std`, only `unsync` module is supported. +- implement `Eq` for `OnceCell`. +- fix wrong `Sync` bound on `sync::Lazy`. +- run the whole test suite with miri. + +## 0.2.7 + +- New implementation of `sync::OnceCell` if `parking_lot` feature is disabled. + It now employs a hand-rolled variant of `std::sync::Once`. +- `sync::OnceCell::get_or_try_init` works without `parking_lot` as well! +- document the effects of `parking_lot` feature: same performance but smaller types. + +## 0.2.6 + +- Updated `Lazy`'s `Deref` impl to requires only `FnOnce` instead of `Fn` + +## 0.2.5 + +- `Lazy` requires only `FnOnce` instead of `Fn` + +## 0.2.4 + +- nicer `fmt::Debug` implementation + +## 0.2.3 + +- update `parking_lot` to `0.9.0` +- fix stacked borrows violation in `unsync::OnceCell::get` +- implement `Clone` for `sync::OnceCell where T: Clone` + +## 0.2.2 + +- add `OnceCell::into_inner` which consumes a cell and returns an option + +## 0.2.1 + +- implement `sync::OnceCell::get_or_try_init` if `parking_lot` feature is enabled +- switch internal `unsafe` implementation of `sync::OnceCell` from `Once` to `Mutex` +- `sync::OnceCell::get_or_init` is twice as fast if cell is already initialized +- implement `std::panic::RefUnwindSafe` and `std::panic::UnwindSafe` for `OnceCell` +- better document behavior around panics + +## 0.2.0 + +- MSRV is now 1.31.1 +- `Lazy::new` and `OnceCell::new` are now const-fns +- `unsync_lazy` and `sync_lazy` macros are removed + +## 0.1.8 + +- update crossbeam-utils to 0.6 +- enable bors-ng + +## 0.1.7 + +- cells implement `PartialEq` and `From` +- MSRV is down to 1.24.1 +- update `parking_lot` to `0.7.1` + +## 0.1.6 + +- `unsync::OnceCell` is `Clone` if `T` is `Clone`. + +## 0.1.5 + +- No changelog until this point :( diff --git a/vendor/once_cell/Cargo.toml b/vendor/once_cell/Cargo.toml new file mode 100644 index 0000000..7e67695 --- /dev/null +++ b/vendor/once_cell/Cargo.toml @@ -0,0 +1,118 @@ +# 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] +edition = "2021" +rust-version = "1.60" +name = "once_cell" +version = "1.20.2" +authors = ["Aleksey Kladov "] +build = false +exclude = [ + "*.png", + "*.svg", + "/Cargo.lock.msrv", + "rustfmt.toml", +] +autobins = false +autoexamples = false +autotests = false +autobenches = false +description = "Single assignment cells and lazy values." +documentation = "https://docs.rs/once_cell" +readme = "README.md" +keywords = [ + "lazy", + "static", +] +categories = [ + "rust-patterns", + "memory-management", +] +license = "MIT OR Apache-2.0" +repository = "https://github.com/matklad/once_cell" + +[package.metadata.docs.rs] +all-features = true +rustdoc-args = ["--generate-link-to-definition"] + +[lib] +name = "once_cell" +path = "src/lib.rs" + +[[example]] +name = "bench" +path = "examples/bench.rs" +required-features = ["std"] + +[[example]] +name = "bench_acquire" +path = "examples/bench_acquire.rs" +required-features = ["std"] + +[[example]] +name = "lazy_static" +path = "examples/lazy_static.rs" +required-features = ["std"] + +[[example]] +name = "reentrant_init_deadlocks" +path = "examples/reentrant_init_deadlocks.rs" +required-features = ["std"] + +[[example]] +name = "regex" +path = "examples/regex.rs" +required-features = ["std"] + +[[example]] +name = "test_synchronization" +path = "examples/test_synchronization.rs" +required-features = ["std"] + +[[test]] +name = "it" +path = "tests/it/main.rs" + +[dependencies.critical-section] +version = "1.1.3" +optional = true + +[dependencies.parking_lot_core] +version = "0.9.10" +optional = true +default-features = false + +[dependencies.portable-atomic] +version = "1.8" +optional = true +default-features = false + +[dev-dependencies.critical-section] +version = "1.1.3" +features = ["std"] + +[dev-dependencies.regex] +version = "1.10.6" + +[features] +alloc = ["race"] +atomic-polyfill = ["critical-section"] +critical-section = [ + "dep:critical-section", + "portable-atomic", +] +default = ["std"] +parking_lot = ["dep:parking_lot_core"] +portable-atomic = ["dep:portable-atomic"] +race = [] +std = ["alloc"] +unstable = [] diff --git a/vendor/once_cell/LICENSE-APACHE b/vendor/once_cell/LICENSE-APACHE new file mode 100644 index 0000000..16fe87b --- /dev/null +++ b/vendor/once_cell/LICENSE-APACHE @@ -0,0 +1,201 @@ + 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/once_cell/LICENSE-MIT b/vendor/once_cell/LICENSE-MIT new file mode 100644 index 0000000..31aa793 --- /dev/null +++ b/vendor/once_cell/LICENSE-MIT @@ -0,0 +1,23 @@ +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/once_cell/README.md b/vendor/once_cell/README.md new file mode 100644 index 0000000..2ac9b53 --- /dev/null +++ b/vendor/once_cell/README.md @@ -0,0 +1,57 @@ +

once_cell

+ + +[![Build Status](https://github.com/matklad/once_cell/actions/workflows/ci.yaml/badge.svg)](https://github.com/matklad/once_cell/actions) +[![Crates.io](https://img.shields.io/crates/v/once_cell.svg)](https://crates.io/crates/once_cell) +[![API reference](https://docs.rs/once_cell/badge.svg)](https://docs.rs/once_cell/) + +# Overview + +`once_cell` provides two new cell-like types, `unsync::OnceCell` and `sync::OnceCell`. `OnceCell` +might store arbitrary non-`Copy` types, can be assigned to at most once and provide direct access +to the stored contents. In a nutshell, API looks *roughly* like this: + +```rust +impl OnceCell { + fn new() -> OnceCell { ... } + fn set(&self, value: T) -> Result<(), T> { ... } + fn get(&self) -> Option<&T> { ... } +} +``` + +Note that, like with `RefCell` and `Mutex`, the `set` method requires only a shared reference. +Because of the single assignment restriction `get` can return an `&T` instead of `Ref` +or `MutexGuard`. + +`once_cell` also has a `Lazy` type, build on top of `OnceCell` which provides the same API as +the `lazy_static!` macro, but without using any macros: + +```rust +use std::{sync::Mutex, collections::HashMap}; +use once_cell::sync::Lazy; + +static GLOBAL_DATA: Lazy>> = Lazy::new(|| { + let mut m = HashMap::new(); + m.insert(13, "Spica".to_string()); + m.insert(74, "Hoyten".to_string()); + Mutex::new(m) +}); + +fn main() { + println!("{:?}", GLOBAL_DATA.lock().unwrap()); +} +``` + +More patterns and use-cases are in the [docs](https://docs.rs/once_cell/)! + +# Related crates + +* [double-checked-cell](https://github.com/niklasf/double-checked-cell) +* [lazy-init](https://crates.io/crates/lazy-init) +* [lazycell](https://crates.io/crates/lazycell) +* [mitochondria](https://crates.io/crates/mitochondria) +* [lazy_static](https://crates.io/crates/lazy_static) +* [async_once_cell](https://crates.io/crates/async_once_cell) +* [generic_once_cell](https://crates.io/crates/generic_once_cell) (bring your own mutex) + +Parts of `once_cell` API are included into `std` [as of Rust 1.70.0](https://github.com/rust-lang/rust/pull/105587). diff --git a/vendor/once_cell/bors.toml b/vendor/once_cell/bors.toml new file mode 100644 index 0000000..b92b99a --- /dev/null +++ b/vendor/once_cell/bors.toml @@ -0,0 +1,2 @@ +status = [ "Rust" ] +delete_merged_branches = true diff --git a/vendor/once_cell/examples/bench.rs b/vendor/once_cell/examples/bench.rs new file mode 100644 index 0000000..e680125 --- /dev/null +++ b/vendor/once_cell/examples/bench.rs @@ -0,0 +1,28 @@ +use std::mem::size_of; + +use once_cell::sync::OnceCell; + +const N_THREADS: usize = 32; +const N_ROUNDS: usize = 100_000_000; + +static CELL: OnceCell = OnceCell::new(); + +fn main() { + let start = std::time::Instant::now(); + let threads = + (0..N_THREADS).map(|i| std::thread::spawn(move || thread_main(i))).collect::>(); + for thread in threads { + thread.join().unwrap(); + } + println!("{:?}", start.elapsed()); + println!("size_of::>() = {:?}", size_of::>()); + println!("size_of::>() = {:?}", size_of::>()); + println!("size_of::>() = {:?}", size_of::>()); +} + +fn thread_main(i: usize) { + for _ in 0..N_ROUNDS { + let &value = CELL.get_or_init(|| i); + assert!(value < N_THREADS) + } +} diff --git a/vendor/once_cell/examples/bench_acquire.rs b/vendor/once_cell/examples/bench_acquire.rs new file mode 100644 index 0000000..1518047 --- /dev/null +++ b/vendor/once_cell/examples/bench_acquire.rs @@ -0,0 +1,39 @@ +//! Benchmark the overhead that the synchronization of `OnceCell::get` causes. +//! We do some other operations that write to memory to get an imprecise but somewhat realistic +//! measurement. + +use once_cell::sync::OnceCell; +use std::sync::atomic::{AtomicUsize, Ordering}; + +const N_THREADS: usize = 16; +const N_ROUNDS: usize = 1_000_000; + +static CELL: OnceCell = OnceCell::new(); +static OTHER: AtomicUsize = AtomicUsize::new(0); + +fn main() { + let start = std::time::Instant::now(); + let threads = + (0..N_THREADS).map(|i| std::thread::spawn(move || thread_main(i))).collect::>(); + for thread in threads { + thread.join().unwrap(); + } + println!("{:?}", start.elapsed()); + println!("{:?}", OTHER.load(Ordering::Relaxed)); +} + +#[inline(never)] +fn thread_main(i: usize) { + // The operations we do here don't really matter, as long as we do multiple writes, and + // everything is messy enough to prevent the compiler from optimizing the loop away. + let mut data = [i; 128]; + let mut accum = 0usize; + for _ in 0..N_ROUNDS { + let _value = CELL.get_or_init(|| i + 1); + let k = OTHER.fetch_add(data[accum & 0x7F] as usize, Ordering::Relaxed); + for j in data.iter_mut() { + *j = (*j).wrapping_add(accum); + accum = accum.wrapping_add(k); + } + } +} diff --git a/vendor/once_cell/examples/lazy_static.rs b/vendor/once_cell/examples/lazy_static.rs new file mode 100644 index 0000000..3cdb19f --- /dev/null +++ b/vendor/once_cell/examples/lazy_static.rs @@ -0,0 +1,36 @@ +extern crate once_cell; + +use once_cell::sync::{Lazy, OnceCell}; +use std::collections::HashMap; + +static HASHMAP: Lazy> = Lazy::new(|| { + let mut m = HashMap::new(); + m.insert(0, "foo"); + m.insert(1, "bar"); + m.insert(2, "baz"); + m +}); + +// Same, but completely without macros +fn hashmap() -> &'static HashMap { + static INSTANCE: OnceCell> = OnceCell::new(); + INSTANCE.get_or_init(|| { + let mut m = HashMap::new(); + m.insert(0, "foo"); + m.insert(1, "bar"); + m.insert(2, "baz"); + m + }) +} + +fn main() { + // First access to `HASHMAP` initializes it + println!("The entry for `0` is \"{}\".", HASHMAP.get(&0).unwrap()); + + // Any further access to `HASHMAP` just returns the computed value + println!("The entry for `1` is \"{}\".", HASHMAP.get(&1).unwrap()); + + // The same works for function-style: + assert_eq!(hashmap().get(&0), Some(&"foo")); + assert_eq!(hashmap().get(&1), Some(&"bar")); +} diff --git a/vendor/once_cell/examples/reentrant_init_deadlocks.rs b/vendor/once_cell/examples/reentrant_init_deadlocks.rs new file mode 100644 index 0000000..af4b5b7 --- /dev/null +++ b/vendor/once_cell/examples/reentrant_init_deadlocks.rs @@ -0,0 +1,14 @@ +fn main() { + let cell = once_cell::sync::OnceCell::::new(); + cell.get_or_init(|| { + cell.get_or_init(|| 1); + 2 + }); +} + +/// Dummy test to make it seem hang when compiled as `--test` +/// See https://github.com/matklad/once_cell/issues/79 +#[test] +fn dummy_test() { + std::thread::sleep(std::time::Duration::from_secs(4)); +} diff --git a/vendor/once_cell/examples/regex.rs b/vendor/once_cell/examples/regex.rs new file mode 100644 index 0000000..4c4c2ea --- /dev/null +++ b/vendor/once_cell/examples/regex.rs @@ -0,0 +1,49 @@ +use std::{str::FromStr, time::Instant}; + +use regex::Regex; + +macro_rules! regex { + ($re:literal $(,)?) => {{ + static RE: once_cell::sync::OnceCell = once_cell::sync::OnceCell::new(); + RE.get_or_init(|| regex::Regex::new($re).unwrap()) + }}; +} + +fn slow() { + let s = r##"13.28.24.13 - - [10/Mar/2016:19:29:25 +0100] "GET /etc/lib/pChart2/examples/index.php?Action=View&Script=../../../../cnf/db.php HTTP/1.1" 404 151 "-" "HTTP_Request2/2.2.1 (http://pear.php.net/package/http_request2) PHP/5.3.16""##; + + let mut total = 0; + for _ in 0..1000 { + let re = Regex::new( + r##"^(\S+) (\S+) (\S+) \[([^]]+)\] "([^"]*)" (\d+) (\d+) "([^"]*)" "([^"]*)"$"##, + ) + .unwrap(); + let size = usize::from_str(re.captures(s).unwrap().get(7).unwrap().as_str()).unwrap(); + total += size; + } + println!("{}", total); +} + +fn fast() { + let s = r##"13.28.24.13 - - [10/Mar/2016:19:29:25 +0100] "GET /etc/lib/pChart2/examples/index.php?Action=View&Script=../../../../cnf/db.php HTTP/1.1" 404 151 "-" "HTTP_Request2/2.2.1 (http://pear.php.net/package/http_request2) PHP/5.3.16""##; + + let mut total = 0; + for _ in 0..1000 { + let re: &Regex = regex!( + r##"^(\S+) (\S+) (\S+) \[([^]]+)\] "([^"]*)" (\d+) (\d+) "([^"]*)" "([^"]*)"$"##, + ); + let size = usize::from_str(re.captures(s).unwrap().get(7).unwrap().as_str()).unwrap(); + total += size; + } + println!("{}", total); +} + +fn main() { + let t = Instant::now(); + slow(); + println!("slow: {:?}", t.elapsed()); + + let t = Instant::now(); + fast(); + println!("fast: {:?}", t.elapsed()); +} diff --git a/vendor/once_cell/examples/test_synchronization.rs b/vendor/once_cell/examples/test_synchronization.rs new file mode 100644 index 0000000..0d54f98 --- /dev/null +++ b/vendor/once_cell/examples/test_synchronization.rs @@ -0,0 +1,38 @@ +//! Test if the OnceCell properly synchronizes. +//! Needs to be run in release mode. +//! +//! We create a `Vec` with `N_ROUNDS` of `OnceCell`s. All threads will walk the `Vec`, and race to +//! be the first one to initialize a cell. +//! Every thread adds the results of the cells it sees to an accumulator, which is compared at the +//! end. +//! All threads should end up with the same result. + +use once_cell::sync::OnceCell; + +const N_THREADS: usize = 32; +const N_ROUNDS: usize = 1_000_000; + +static CELLS: OnceCell>> = OnceCell::new(); +static RESULT: OnceCell = OnceCell::new(); + +fn main() { + let start = std::time::Instant::now(); + CELLS.get_or_init(|| vec![OnceCell::new(); N_ROUNDS]); + let threads = + (0..N_THREADS).map(|i| std::thread::spawn(move || thread_main(i))).collect::>(); + for thread in threads { + thread.join().unwrap(); + } + println!("{:?}", start.elapsed()); + println!("No races detected"); +} + +fn thread_main(i: usize) { + let cells = CELLS.get().unwrap(); + let mut accum = 0; + for cell in cells.iter() { + let &value = cell.get_or_init(|| i); + accum += value; + } + assert_eq!(RESULT.get_or_init(|| accum), &accum); +} diff --git a/vendor/once_cell/src/imp_cs.rs b/vendor/once_cell/src/imp_cs.rs new file mode 100644 index 0000000..6b8d53d --- /dev/null +++ b/vendor/once_cell/src/imp_cs.rs @@ -0,0 +1,78 @@ +use core::panic::{RefUnwindSafe, UnwindSafe}; + +use critical_section::{CriticalSection, Mutex}; +use portable_atomic::{AtomicBool, Ordering}; + +use crate::unsync; + +pub(crate) struct OnceCell { + initialized: AtomicBool, + // Use `unsync::OnceCell` internally since `Mutex` does not provide + // interior mutability and to be able to re-use `get_or_try_init`. + value: Mutex>, +} + +// Why do we need `T: Send`? +// Thread A creates a `OnceCell` and shares it with +// scoped thread B, which fills the cell, which is +// then destroyed by A. That is, destructor observes +// a sent value. +unsafe impl Sync for OnceCell {} +unsafe impl Send for OnceCell {} + +impl RefUnwindSafe for OnceCell {} +impl UnwindSafe for OnceCell {} + +impl OnceCell { + pub(crate) const fn new() -> OnceCell { + OnceCell { initialized: AtomicBool::new(false), value: Mutex::new(unsync::OnceCell::new()) } + } + + pub(crate) const fn with_value(value: T) -> OnceCell { + OnceCell { + initialized: AtomicBool::new(true), + value: Mutex::new(unsync::OnceCell::with_value(value)), + } + } + + #[inline] + pub(crate) fn is_initialized(&self) -> bool { + self.initialized.load(Ordering::Acquire) + } + + #[cold] + pub(crate) fn initialize(&self, f: F) -> Result<(), E> + where + F: FnOnce() -> Result, + { + critical_section::with(|cs| { + let cell = self.value.borrow(cs); + cell.get_or_try_init(f).map(|_| { + self.initialized.store(true, Ordering::Release); + }) + }) + } + + /// Get the reference to the underlying value, without checking if the cell + /// is initialized. + /// + /// # Safety + /// + /// Caller must ensure that the cell is in initialized state, and that + /// the contents are acquired by (synchronized to) this thread. + pub(crate) unsafe fn get_unchecked(&self) -> &T { + debug_assert!(self.is_initialized()); + // SAFETY: The caller ensures that the value is initialized and access synchronized. + self.value.borrow(CriticalSection::new()).get().unwrap_unchecked() + } + + #[inline] + pub(crate) fn get_mut(&mut self) -> Option<&mut T> { + self.value.get_mut().get_mut() + } + + #[inline] + pub(crate) fn into_inner(self) -> Option { + self.value.into_inner().into_inner() + } +} diff --git a/vendor/once_cell/src/imp_pl.rs b/vendor/once_cell/src/imp_pl.rs new file mode 100644 index 0000000..37a8554 --- /dev/null +++ b/vendor/once_cell/src/imp_pl.rs @@ -0,0 +1,174 @@ +use std::{ + cell::UnsafeCell, + panic::{RefUnwindSafe, UnwindSafe}, + sync::atomic::{AtomicU8, Ordering}, +}; + +pub(crate) struct OnceCell { + state: AtomicU8, + value: UnsafeCell>, +} + +const INCOMPLETE: u8 = 0x0; +const RUNNING: u8 = 0x1; +const COMPLETE: u8 = 0x2; + +// Why do we need `T: Send`? +// Thread A creates a `OnceCell` and shares it with +// scoped thread B, which fills the cell, which is +// then destroyed by A. That is, destructor observes +// a sent value. +unsafe impl Sync for OnceCell {} +unsafe impl Send for OnceCell {} + +impl RefUnwindSafe for OnceCell {} +impl UnwindSafe for OnceCell {} + +impl OnceCell { + pub(crate) const fn new() -> OnceCell { + OnceCell { state: AtomicU8::new(INCOMPLETE), value: UnsafeCell::new(None) } + } + + pub(crate) const fn with_value(value: T) -> OnceCell { + OnceCell { state: AtomicU8::new(COMPLETE), value: UnsafeCell::new(Some(value)) } + } + + /// Safety: synchronizes with store to value via Release/Acquire. + #[inline] + pub(crate) fn is_initialized(&self) -> bool { + self.state.load(Ordering::Acquire) == COMPLETE + } + + /// Safety: synchronizes with store to value via `is_initialized` or mutex + /// lock/unlock, writes value only once because of the mutex. + #[cold] + pub(crate) fn initialize(&self, f: F) -> Result<(), E> + where + F: FnOnce() -> Result, + { + let mut f = Some(f); + let mut res: Result<(), E> = Ok(()); + let slot: *mut Option = self.value.get(); + initialize_inner(&self.state, &mut || { + // We are calling user-supplied function and need to be careful. + // - if it returns Err, we unlock mutex and return without touching anything + // - if it panics, we unlock mutex and propagate panic without touching anything + // - if it calls `set` or `get_or_try_init` re-entrantly, we get a deadlock on + // mutex, which is important for safety. We *could* detect this and panic, + // but that is more complicated + // - finally, if it returns Ok, we store the value and store the flag with + // `Release`, which synchronizes with `Acquire`s. + let f = unsafe { f.take().unwrap_unchecked() }; + match f() { + Ok(value) => unsafe { + // Safe b/c we have a unique access and no panic may happen + // until the cell is marked as initialized. + debug_assert!((*slot).is_none()); + *slot = Some(value); + true + }, + Err(err) => { + res = Err(err); + false + } + } + }); + res + } + + #[cold] + pub(crate) fn wait(&self) { + let key = &self.state as *const _ as usize; + unsafe { + parking_lot_core::park( + key, + || self.state.load(Ordering::Acquire) != COMPLETE, + || (), + |_, _| (), + parking_lot_core::DEFAULT_PARK_TOKEN, + None, + ); + } + } + + /// Get the reference to the underlying value, without checking if the cell + /// is initialized. + /// + /// # Safety + /// + /// Caller must ensure that the cell is in initialized state, and that + /// the contents are acquired by (synchronized to) this thread. + pub(crate) unsafe fn get_unchecked(&self) -> &T { + debug_assert!(self.is_initialized()); + let slot = &*self.value.get(); + slot.as_ref().unwrap_unchecked() + } + + /// Gets the mutable reference to the underlying value. + /// Returns `None` if the cell is empty. + pub(crate) fn get_mut(&mut self) -> Option<&mut T> { + // Safe b/c we have an exclusive access + let slot: &mut Option = unsafe { &mut *self.value.get() }; + slot.as_mut() + } + + /// Consumes this `OnceCell`, returning the wrapped value. + /// Returns `None` if the cell was empty. + pub(crate) fn into_inner(self) -> Option { + self.value.into_inner() + } +} + +struct Guard<'a> { + state: &'a AtomicU8, + new_state: u8, +} + +impl<'a> Drop for Guard<'a> { + fn drop(&mut self) { + self.state.store(self.new_state, Ordering::Release); + unsafe { + let key = self.state as *const AtomicU8 as usize; + parking_lot_core::unpark_all(key, parking_lot_core::DEFAULT_UNPARK_TOKEN); + } + } +} + +// Note: this is intentionally monomorphic +#[inline(never)] +fn initialize_inner(state: &AtomicU8, init: &mut dyn FnMut() -> bool) { + loop { + let exchange = + state.compare_exchange_weak(INCOMPLETE, RUNNING, Ordering::Acquire, Ordering::Acquire); + match exchange { + Ok(_) => { + let mut guard = Guard { state, new_state: INCOMPLETE }; + if init() { + guard.new_state = COMPLETE; + } + return; + } + Err(COMPLETE) => return, + Err(RUNNING) => unsafe { + let key = state as *const AtomicU8 as usize; + parking_lot_core::park( + key, + || state.load(Ordering::Relaxed) == RUNNING, + || (), + |_, _| (), + parking_lot_core::DEFAULT_PARK_TOKEN, + None, + ); + }, + Err(INCOMPLETE) => (), + Err(_) => debug_assert!(false), + } + } +} + +#[test] +fn test_size() { + use std::mem::size_of; + + assert_eq!(size_of::>(), 1 * size_of::() + size_of::()); +} diff --git a/vendor/once_cell/src/imp_std.rs b/vendor/once_cell/src/imp_std.rs new file mode 100644 index 0000000..3b9e6d2 --- /dev/null +++ b/vendor/once_cell/src/imp_std.rs @@ -0,0 +1,415 @@ +// There's a lot of scary concurrent code in this module, but it is copied from +// `std::sync::Once` with two changes: +// * no poisoning +// * init function can fail + +use std::{ + cell::{Cell, UnsafeCell}, + panic::{RefUnwindSafe, UnwindSafe}, + sync::atomic::{AtomicBool, AtomicPtr, Ordering}, + thread::{self, Thread}, +}; + +#[derive(Debug)] +pub(crate) struct OnceCell { + // This `queue` field is the core of the implementation. It encodes two + // pieces of information: + // + // * The current state of the cell (`INCOMPLETE`, `RUNNING`, `COMPLETE`) + // * Linked list of threads waiting for the current cell. + // + // State is encoded in two low bits. Only `INCOMPLETE` and `RUNNING` states + // allow waiters. + queue: AtomicPtr, + value: UnsafeCell>, +} + +// Why do we need `T: Send`? +// Thread A creates a `OnceCell` and shares it with +// scoped thread B, which fills the cell, which is +// then destroyed by A. That is, destructor observes +// a sent value. +unsafe impl Sync for OnceCell {} +unsafe impl Send for OnceCell {} + +impl RefUnwindSafe for OnceCell {} +impl UnwindSafe for OnceCell {} + +impl OnceCell { + pub(crate) const fn new() -> OnceCell { + OnceCell { queue: AtomicPtr::new(INCOMPLETE_PTR), value: UnsafeCell::new(None) } + } + + pub(crate) const fn with_value(value: T) -> OnceCell { + OnceCell { queue: AtomicPtr::new(COMPLETE_PTR), value: UnsafeCell::new(Some(value)) } + } + + /// Safety: synchronizes with store to value via Release/(Acquire|SeqCst). + #[inline] + pub(crate) fn is_initialized(&self) -> bool { + // An `Acquire` load is enough because that makes all the initialization + // operations visible to us, and, this being a fast path, weaker + // ordering helps with performance. This `Acquire` synchronizes with + // `SeqCst` operations on the slow path. + self.queue.load(Ordering::Acquire) == COMPLETE_PTR + } + + /// Safety: synchronizes with store to value via SeqCst read from state, + /// writes value only once because we never get to INCOMPLETE state after a + /// successful write. + #[cold] + pub(crate) fn initialize(&self, f: F) -> Result<(), E> + where + F: FnOnce() -> Result, + { + let mut f = Some(f); + let mut res: Result<(), E> = Ok(()); + let slot: *mut Option = self.value.get(); + initialize_or_wait( + &self.queue, + Some(&mut || { + let f = unsafe { f.take().unwrap_unchecked() }; + match f() { + Ok(value) => { + unsafe { *slot = Some(value) }; + true + } + Err(err) => { + res = Err(err); + false + } + } + }), + ); + res + } + + #[cold] + pub(crate) fn wait(&self) { + initialize_or_wait(&self.queue, None); + } + + /// Get the reference to the underlying value, without checking if the cell + /// is initialized. + /// + /// # Safety + /// + /// Caller must ensure that the cell is in initialized state, and that + /// the contents are acquired by (synchronized to) this thread. + pub(crate) unsafe fn get_unchecked(&self) -> &T { + debug_assert!(self.is_initialized()); + let slot = &*self.value.get(); + slot.as_ref().unwrap_unchecked() + } + + /// Gets the mutable reference to the underlying value. + /// Returns `None` if the cell is empty. + pub(crate) fn get_mut(&mut self) -> Option<&mut T> { + // Safe b/c we have a unique access. + unsafe { &mut *self.value.get() }.as_mut() + } + + /// Consumes this `OnceCell`, returning the wrapped value. + /// Returns `None` if the cell was empty. + #[inline] + pub(crate) fn into_inner(self) -> Option { + // Because `into_inner` takes `self` by value, the compiler statically + // verifies that it is not currently borrowed. + // So, it is safe to move out `Option`. + self.value.into_inner() + } +} + +// Three states that a OnceCell can be in, encoded into the lower bits of `queue` in +// the OnceCell structure. +const INCOMPLETE: usize = 0x0; +const RUNNING: usize = 0x1; +const COMPLETE: usize = 0x2; +const INCOMPLETE_PTR: *mut Waiter = INCOMPLETE as *mut Waiter; +const COMPLETE_PTR: *mut Waiter = COMPLETE as *mut Waiter; + +// Mask to learn about the state. All other bits are the queue of waiters if +// this is in the RUNNING state. +const STATE_MASK: usize = 0x3; + +/// Representation of a node in the linked list of waiters in the RUNNING state. +/// A waiters is stored on the stack of the waiting threads. +#[repr(align(4))] // Ensure the two lower bits are free to use as state bits. +struct Waiter { + thread: Cell>, + signaled: AtomicBool, + next: *mut Waiter, +} + +/// Drains and notifies the queue of waiters on drop. +struct Guard<'a> { + queue: &'a AtomicPtr, + new_queue: *mut Waiter, +} + +impl Drop for Guard<'_> { + fn drop(&mut self) { + let queue = self.queue.swap(self.new_queue, Ordering::AcqRel); + + let state = strict::addr(queue) & STATE_MASK; + assert_eq!(state, RUNNING); + + unsafe { + let mut waiter = strict::map_addr(queue, |q| q & !STATE_MASK); + while !waiter.is_null() { + let next = (*waiter).next; + let thread = (*waiter).thread.take().unwrap(); + (*waiter).signaled.store(true, Ordering::Release); + waiter = next; + thread.unpark(); + } + } + } +} + +// Corresponds to `std::sync::Once::call_inner`. +// +// Originally copied from std, but since modified to remove poisoning and to +// support wait. +// +// Note: this is intentionally monomorphic +#[inline(never)] +fn initialize_or_wait(queue: &AtomicPtr, mut init: Option<&mut dyn FnMut() -> bool>) { + let mut curr_queue = queue.load(Ordering::Acquire); + + loop { + let curr_state = strict::addr(curr_queue) & STATE_MASK; + match (curr_state, &mut init) { + (COMPLETE, _) => return, + (INCOMPLETE, Some(init)) => { + let exchange = queue.compare_exchange( + curr_queue, + strict::map_addr(curr_queue, |q| (q & !STATE_MASK) | RUNNING), + Ordering::Acquire, + Ordering::Acquire, + ); + if let Err(new_queue) = exchange { + curr_queue = new_queue; + continue; + } + let mut guard = Guard { queue, new_queue: INCOMPLETE_PTR }; + if init() { + guard.new_queue = COMPLETE_PTR; + } + return; + } + (INCOMPLETE, None) | (RUNNING, _) => { + wait(queue, curr_queue); + curr_queue = queue.load(Ordering::Acquire); + } + _ => debug_assert!(false), + } + } +} + +fn wait(queue: &AtomicPtr, mut curr_queue: *mut Waiter) { + let curr_state = strict::addr(curr_queue) & STATE_MASK; + loop { + let node = Waiter { + thread: Cell::new(Some(thread::current())), + signaled: AtomicBool::new(false), + next: strict::map_addr(curr_queue, |q| q & !STATE_MASK), + }; + let me = &node as *const Waiter as *mut Waiter; + + let exchange = queue.compare_exchange( + curr_queue, + strict::map_addr(me, |q| q | curr_state), + Ordering::Release, + Ordering::Relaxed, + ); + if let Err(new_queue) = exchange { + if strict::addr(new_queue) & STATE_MASK != curr_state { + return; + } + curr_queue = new_queue; + continue; + } + + while !node.signaled.load(Ordering::Acquire) { + thread::park(); + } + break; + } +} + +// Polyfill of strict provenance from https://crates.io/crates/sptr. +// +// Use free-standing function rather than a trait to keep things simple and +// avoid any potential conflicts with future stabile std API. +mod strict { + #[must_use] + #[inline] + pub(crate) fn addr(ptr: *mut T) -> usize + where + T: Sized, + { + // FIXME(strict_provenance_magic): I am magic and should be a compiler intrinsic. + // SAFETY: Pointer-to-integer transmutes are valid (if you are okay with losing the + // provenance). + unsafe { core::mem::transmute(ptr) } + } + + #[must_use] + #[inline] + pub(crate) fn with_addr(ptr: *mut T, addr: usize) -> *mut T + where + T: Sized, + { + // FIXME(strict_provenance_magic): I am magic and should be a compiler intrinsic. + // + // In the mean-time, this operation is defined to be "as if" it was + // a wrapping_offset, so we can emulate it as such. This should properly + // restore pointer provenance even under today's compiler. + let self_addr = self::addr(ptr) as isize; + let dest_addr = addr as isize; + let offset = dest_addr.wrapping_sub(self_addr); + + // This is the canonical desugarring of this operation, + // but `pointer::cast` was only stabilized in 1.38. + // self.cast::().wrapping_offset(offset).cast::() + (ptr as *mut u8).wrapping_offset(offset) as *mut T + } + + #[must_use] + #[inline] + pub(crate) fn map_addr(ptr: *mut T, f: impl FnOnce(usize) -> usize) -> *mut T + where + T: Sized, + { + self::with_addr(ptr, f(addr(ptr))) + } +} + +// These test are snatched from std as well. +#[cfg(test)] +mod tests { + use std::panic; + use std::{sync::mpsc::channel, thread}; + + use super::OnceCell; + + impl OnceCell { + fn init(&self, f: impl FnOnce() -> T) { + enum Void {} + let _ = self.initialize(|| Ok::(f())); + } + } + + #[test] + fn smoke_once() { + static O: OnceCell<()> = OnceCell::new(); + let mut a = 0; + O.init(|| a += 1); + assert_eq!(a, 1); + O.init(|| a += 1); + assert_eq!(a, 1); + } + + #[test] + fn stampede_once() { + static O: OnceCell<()> = OnceCell::new(); + static mut RUN: bool = false; + + let (tx, rx) = channel(); + for _ in 0..10 { + let tx = tx.clone(); + thread::spawn(move || { + for _ in 0..4 { + thread::yield_now() + } + unsafe { + O.init(|| { + assert!(!RUN); + RUN = true; + }); + assert!(RUN); + } + tx.send(()).unwrap(); + }); + } + + unsafe { + O.init(|| { + assert!(!RUN); + RUN = true; + }); + assert!(RUN); + } + + for _ in 0..10 { + rx.recv().unwrap(); + } + } + + #[test] + fn poison_bad() { + static O: OnceCell<()> = OnceCell::new(); + + // poison the once + let t = panic::catch_unwind(|| { + O.init(|| panic!()); + }); + assert!(t.is_err()); + + // we can subvert poisoning, however + let mut called = false; + O.init(|| { + called = true; + }); + assert!(called); + + // once any success happens, we stop propagating the poison + O.init(|| {}); + } + + #[test] + fn wait_for_force_to_finish() { + static O: OnceCell<()> = OnceCell::new(); + + // poison the once + let t = panic::catch_unwind(|| { + O.init(|| panic!()); + }); + assert!(t.is_err()); + + // make sure someone's waiting inside the once via a force + let (tx1, rx1) = channel(); + let (tx2, rx2) = channel(); + let t1 = thread::spawn(move || { + O.init(|| { + tx1.send(()).unwrap(); + rx2.recv().unwrap(); + }); + }); + + rx1.recv().unwrap(); + + // put another waiter on the once + let t2 = thread::spawn(|| { + let mut called = false; + O.init(|| { + called = true; + }); + assert!(!called); + }); + + tx2.send(()).unwrap(); + + assert!(t1.join().is_ok()); + assert!(t2.join().is_ok()); + } + + #[test] + #[cfg(target_pointer_width = "64")] + fn test_size() { + use std::mem::size_of; + + assert_eq!(size_of::>(), 4 * size_of::()); + } +} diff --git a/vendor/once_cell/src/lib.rs b/vendor/once_cell/src/lib.rs new file mode 100644 index 0000000..90d3657 --- /dev/null +++ b/vendor/once_cell/src/lib.rs @@ -0,0 +1,1412 @@ +//! # Overview +//! +//! `once_cell` provides two new cell-like types, [`unsync::OnceCell`] and +//! [`sync::OnceCell`]. A `OnceCell` might store arbitrary non-`Copy` types, can +//! be assigned to at most once and provides direct access to the stored +//! contents. The core API looks *roughly* like this (and there's much more +//! inside, read on!): +//! +//! ```rust,ignore +//! impl OnceCell { +//! const fn new() -> OnceCell { ... } +//! fn set(&self, value: T) -> Result<(), T> { ... } +//! fn get(&self) -> Option<&T> { ... } +//! } +//! ``` +//! +//! Note that, like with [`RefCell`] and [`Mutex`], the `set` method requires +//! only a shared reference. Because of the single assignment restriction `get` +//! can return a `&T` instead of `Ref` or `MutexGuard`. +//! +//! The `sync` flavor is thread-safe (that is, implements the [`Sync`] trait), +//! while the `unsync` one is not. +//! +//! [`unsync::OnceCell`]: unsync/struct.OnceCell.html +//! [`sync::OnceCell`]: sync/struct.OnceCell.html +//! [`RefCell`]: https://doc.rust-lang.org/std/cell/struct.RefCell.html +//! [`Mutex`]: https://doc.rust-lang.org/std/sync/struct.Mutex.html +//! [`Sync`]: https://doc.rust-lang.org/std/marker/trait.Sync.html +//! +//! # Recipes +//! +//! `OnceCell` might be useful for a variety of patterns. +//! +//! ## Safe Initialization of Global Data +//! +//! ```rust +//! use std::{env, io}; +//! +//! use once_cell::sync::OnceCell; +//! +//! #[derive(Debug)] +//! pub struct Logger { +//! // ... +//! } +//! static INSTANCE: OnceCell = OnceCell::new(); +//! +//! impl Logger { +//! pub fn global() -> &'static Logger { +//! INSTANCE.get().expect("logger is not initialized") +//! } +//! +//! fn from_cli(args: env::Args) -> Result { +//! // ... +//! # Ok(Logger {}) +//! } +//! } +//! +//! fn main() { +//! let logger = Logger::from_cli(env::args()).unwrap(); +//! INSTANCE.set(logger).unwrap(); +//! // use `Logger::global()` from now on +//! } +//! ``` +//! +//! ## Lazy Initialized Global Data +//! +//! This is essentially the `lazy_static!` macro, but without a macro. +//! +//! ```rust +//! use std::{sync::Mutex, collections::HashMap}; +//! +//! use once_cell::sync::OnceCell; +//! +//! fn global_data() -> &'static Mutex> { +//! static INSTANCE: OnceCell>> = OnceCell::new(); +//! INSTANCE.get_or_init(|| { +//! let mut m = HashMap::new(); +//! m.insert(13, "Spica".to_string()); +//! m.insert(74, "Hoyten".to_string()); +//! Mutex::new(m) +//! }) +//! } +//! ``` +//! +//! There are also the [`sync::Lazy`] and [`unsync::Lazy`] convenience types to +//! streamline this pattern: +//! +//! ```rust +//! use std::{sync::Mutex, collections::HashMap}; +//! use once_cell::sync::Lazy; +//! +//! static GLOBAL_DATA: Lazy>> = Lazy::new(|| { +//! let mut m = HashMap::new(); +//! m.insert(13, "Spica".to_string()); +//! m.insert(74, "Hoyten".to_string()); +//! Mutex::new(m) +//! }); +//! +//! fn main() { +//! println!("{:?}", GLOBAL_DATA.lock().unwrap()); +//! } +//! ``` +//! +//! Note that the variable that holds `Lazy` is declared as `static`, *not* +//! `const`. This is important: using `const` instead compiles, but works wrong. +//! +//! [`sync::Lazy`]: sync/struct.Lazy.html +//! [`unsync::Lazy`]: unsync/struct.Lazy.html +//! +//! ## General purpose lazy evaluation +//! +//! Unlike `lazy_static!`, `Lazy` works with local variables. +//! +//! ```rust +//! use once_cell::unsync::Lazy; +//! +//! fn main() { +//! let ctx = vec![1, 2, 3]; +//! let thunk = Lazy::new(|| { +//! ctx.iter().sum::() +//! }); +//! assert_eq!(*thunk, 6); +//! } +//! ``` +//! +//! If you need a lazy field in a struct, you probably should use `OnceCell` +//! directly, because that will allow you to access `self` during +//! initialization. +//! +//! ```rust +//! use std::{fs, path::PathBuf}; +//! +//! use once_cell::unsync::OnceCell; +//! +//! struct Ctx { +//! config_path: PathBuf, +//! config: OnceCell, +//! } +//! +//! impl Ctx { +//! pub fn get_config(&self) -> Result<&str, std::io::Error> { +//! let cfg = self.config.get_or_try_init(|| { +//! fs::read_to_string(&self.config_path) +//! })?; +//! Ok(cfg.as_str()) +//! } +//! } +//! ``` +//! +//! ## Lazily Compiled Regex +//! +//! This is a `regex!` macro which takes a string literal and returns an +//! *expression* that evaluates to a `&'static Regex`: +//! +//! ``` +//! macro_rules! regex { +//! ($re:literal $(,)?) => {{ +//! static RE: once_cell::sync::OnceCell = once_cell::sync::OnceCell::new(); +//! RE.get_or_init(|| regex::Regex::new($re).unwrap()) +//! }}; +//! } +//! ``` +//! +//! This macro can be useful to avoid the "compile regex on every loop +//! iteration" problem. +//! +//! ## Runtime `include_bytes!` +//! +//! The `include_bytes` macro is useful to include test resources, but it slows +//! down test compilation a lot. An alternative is to load the resources at +//! runtime: +//! +//! ``` +//! use std::path::Path; +//! +//! use once_cell::sync::OnceCell; +//! +//! pub struct TestResource { +//! path: &'static str, +//! cell: OnceCell>, +//! } +//! +//! impl TestResource { +//! pub const fn new(path: &'static str) -> TestResource { +//! TestResource { path, cell: OnceCell::new() } +//! } +//! pub fn bytes(&self) -> &[u8] { +//! self.cell.get_or_init(|| { +//! let dir = std::env::var("CARGO_MANIFEST_DIR").unwrap(); +//! let path = Path::new(dir.as_str()).join(self.path); +//! std::fs::read(&path).unwrap_or_else(|_err| { +//! panic!("failed to load test resource: {}", path.display()) +//! }) +//! }).as_slice() +//! } +//! } +//! +//! static TEST_IMAGE: TestResource = TestResource::new("test_data/lena.png"); +//! +//! #[test] +//! fn test_sobel_filter() { +//! let rgb: &[u8] = TEST_IMAGE.bytes(); +//! // ... +//! # drop(rgb); +//! } +//! ``` +//! +//! ## `lateinit` +//! +//! `LateInit` type for delayed initialization. It is reminiscent of Kotlin's +//! `lateinit` keyword and allows construction of cyclic data structures: +//! +//! +//! ``` +//! use once_cell::sync::OnceCell; +//! +//! pub struct LateInit { cell: OnceCell } +//! +//! impl LateInit { +//! pub fn init(&self, value: T) { +//! assert!(self.cell.set(value).is_ok()) +//! } +//! } +//! +//! impl Default for LateInit { +//! fn default() -> Self { LateInit { cell: OnceCell::default() } } +//! } +//! +//! impl std::ops::Deref for LateInit { +//! type Target = T; +//! fn deref(&self) -> &T { +//! self.cell.get().unwrap() +//! } +//! } +//! +//! #[derive(Default)] +//! struct A<'a> { +//! b: LateInit<&'a B<'a>>, +//! } +//! +//! #[derive(Default)] +//! struct B<'a> { +//! a: LateInit<&'a A<'a>> +//! } +//! +//! +//! fn build_cycle() { +//! let a = A::default(); +//! let b = B::default(); +//! a.b.init(&b); +//! b.a.init(&a); +//! +//! let _a = &a.b.a.b.a; +//! } +//! ``` +//! +//! # Comparison with std +//! +//! |`!Sync` types | Access Mode | Drawbacks | +//! |----------------------|------------------------|-----------------------------------------------| +//! |`Cell` | `T` | requires `T: Copy` for `get` | +//! |`RefCell` | `RefMut` / `Ref` | may panic at runtime | +//! |`unsync::OnceCell` | `&T` | assignable only once | +//! +//! |`Sync` types | Access Mode | Drawbacks | +//! |----------------------|------------------------|-----------------------------------------------| +//! |`AtomicT` | `T` | works only with certain `Copy` types | +//! |`Mutex` | `MutexGuard` | may deadlock at runtime, may block the thread | +//! |`sync::OnceCell` | `&T` | assignable only once, may block the thread | +//! +//! Technically, calling `get_or_init` will also cause a panic or a deadlock if +//! it recursively calls itself. However, because the assignment can happen only +//! once, such cases should be more rare than equivalents with `RefCell` and +//! `Mutex`. +//! +//! # Minimum Supported `rustc` Version +//! +//! If only the `std`, `alloc`, or `race` features are enabled, MSRV will be +//! updated conservatively, supporting at least latest 8 versions of the compiler. +//! When using other features, like `parking_lot`, MSRV might be updated more +//! frequently, up to the latest stable. In both cases, increasing MSRV is *not* +//! considered a semver-breaking change and requires only a minor version bump. +//! +//! # Implementation details +//! +//! The implementation is based on the +//! [`lazy_static`](https://github.com/rust-lang-nursery/lazy-static.rs/) and +//! [`lazy_cell`](https://github.com/indiv0/lazycell/) crates and +//! [`std::sync::Once`]. In some sense, `once_cell` just streamlines and unifies +//! those APIs. +//! +//! To implement a sync flavor of `OnceCell`, this crates uses either a custom +//! re-implementation of `std::sync::Once` or `parking_lot::Mutex`. This is +//! controlled by the `parking_lot` feature (disabled by default). Performance +//! is the same for both cases, but the `parking_lot` based `OnceCell` is +//! smaller by up to 16 bytes. +//! +//! This crate uses `unsafe`. +//! +//! [`std::sync::Once`]: https://doc.rust-lang.org/std/sync/struct.Once.html +//! +//! # F.A.Q. +//! +//! **Should I use the sync or unsync flavor?** +//! +//! Because Rust compiler checks thread safety for you, it's impossible to +//! accidentally use `unsync` where `sync` is required. So, use `unsync` in +//! single-threaded code and `sync` in multi-threaded. It's easy to switch +//! between the two if code becomes multi-threaded later. +//! +//! At the moment, `unsync` has an additional benefit that reentrant +//! initialization causes a panic, which might be easier to debug than a +//! deadlock. +//! +//! **Does this crate support async?** +//! +//! No, but you can use +//! [`async_once_cell`](https://crates.io/crates/async_once_cell) instead. +//! +//! **Does this crate support `no_std`?** +//! +//! Yes, but with caveats. `OnceCell` is a synchronization primitive which +//! _semantically_ relies on blocking. `OnceCell` guarantees that at most one +//! `f` will be called to compute the value. If two threads of execution call +//! `get_or_init` concurrently, one of them has to wait. +//! +//! Waiting fundamentally requires OS support. Execution environment needs to +//! understand who waits on whom to prevent deadlocks due to priority inversion. +//! You _could_ make code to compile by blindly using pure spinlocks, but the +//! runtime behavior would be subtly wrong. +//! +//! Given these constraints, `once_cell` provides the following options: +//! +//! - The `race` module provides similar, but distinct synchronization primitive +//! which is compatible with `no_std`. With `race`, the `f` function can be +//! called multiple times by different threads, but only one thread will win +//! to install the value. +//! - `critical-section` feature (with a `-`, not `_`) uses `critical_section` +//! to implement blocking. +//! +//! **Can I bring my own mutex?** +//! +//! There is [generic_once_cell](https://crates.io/crates/generic_once_cell) to +//! allow just that. +//! +//! **Should I use `std::cell::OnceCell`, `once_cell`, or `lazy_static`?** +//! +//! If you can use `std` version (your MSRV is at least 1.70, and you don't need +//! extra features `once_cell` provides), use `std`. Otherwise, use `once_cell`. +//! Don't use `lazy_static`. +//! +//! # Related crates +//! +//! * Most of this crate's functionality is available in `std` starting with +//! Rust 1.70. See `std::cell::OnceCell` and `std::sync::OnceLock`. +//! * [double-checked-cell](https://github.com/niklasf/double-checked-cell) +//! * [lazy-init](https://crates.io/crates/lazy-init) +//! * [lazycell](https://crates.io/crates/lazycell) +//! * [mitochondria](https://crates.io/crates/mitochondria) +//! * [lazy_static](https://crates.io/crates/lazy_static) +//! * [async_once_cell](https://crates.io/crates/async_once_cell) +//! * [generic_once_cell](https://crates.io/crates/generic_once_cell) (bring +//! your own mutex) + +#![cfg_attr(not(feature = "std"), no_std)] + +#[cfg(feature = "alloc")] +extern crate alloc; + +#[cfg(all(feature = "critical-section", not(feature = "std")))] +#[path = "imp_cs.rs"] +mod imp; + +#[cfg(all(feature = "std", feature = "parking_lot"))] +#[path = "imp_pl.rs"] +mod imp; + +#[cfg(all(feature = "std", not(feature = "parking_lot")))] +#[path = "imp_std.rs"] +mod imp; + +/// Single-threaded version of `OnceCell`. +pub mod unsync { + use core::{ + cell::{Cell, UnsafeCell}, + fmt, mem, + ops::{Deref, DerefMut}, + panic::{RefUnwindSafe, UnwindSafe}, + }; + + /// A cell which can be written to only once. It is not thread safe. + /// + /// Unlike [`std::cell::RefCell`], a `OnceCell` provides simple `&` + /// references to the contents. + /// + /// [`std::cell::RefCell`]: https://doc.rust-lang.org/std/cell/struct.RefCell.html + /// + /// # Example + /// ``` + /// use once_cell::unsync::OnceCell; + /// + /// let cell = OnceCell::new(); + /// assert!(cell.get().is_none()); + /// + /// let value: &String = cell.get_or_init(|| { + /// "Hello, World!".to_string() + /// }); + /// assert_eq!(value, "Hello, World!"); + /// assert!(cell.get().is_some()); + /// ``` + pub struct OnceCell { + // Invariant: written to at most once. + inner: UnsafeCell>, + } + + // Similarly to a `Sync` bound on `sync::OnceCell`, we can use + // `&unsync::OnceCell` to sneak a `T` through `catch_unwind`, + // by initializing the cell in closure and extracting the value in the + // `Drop`. + impl RefUnwindSafe for OnceCell {} + impl UnwindSafe for OnceCell {} + + impl Default for OnceCell { + fn default() -> Self { + Self::new() + } + } + + impl fmt::Debug for OnceCell { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match self.get() { + Some(v) => f.debug_tuple("OnceCell").field(v).finish(), + None => f.write_str("OnceCell(Uninit)"), + } + } + } + + impl Clone for OnceCell { + fn clone(&self) -> OnceCell { + match self.get() { + Some(value) => OnceCell::with_value(value.clone()), + None => OnceCell::new(), + } + } + + fn clone_from(&mut self, source: &Self) { + match (self.get_mut(), source.get()) { + (Some(this), Some(source)) => this.clone_from(source), + _ => *self = source.clone(), + } + } + } + + impl PartialEq for OnceCell { + fn eq(&self, other: &Self) -> bool { + self.get() == other.get() + } + } + + impl Eq for OnceCell {} + + impl From for OnceCell { + fn from(value: T) -> Self { + OnceCell::with_value(value) + } + } + + impl OnceCell { + /// Creates a new empty cell. + pub const fn new() -> OnceCell { + OnceCell { inner: UnsafeCell::new(None) } + } + + /// Creates a new initialized cell. + pub const fn with_value(value: T) -> OnceCell { + OnceCell { inner: UnsafeCell::new(Some(value)) } + } + + /// Gets a reference to the underlying value. + /// + /// Returns `None` if the cell is empty. + #[inline] + pub fn get(&self) -> Option<&T> { + // Safe due to `inner`'s invariant of being written to at most once. + // Had multiple writes to `inner` been allowed, a reference to the + // value we return now would become dangling by a write of a + // different value later. + unsafe { &*self.inner.get() }.as_ref() + } + + /// Gets a mutable reference to the underlying value. + /// + /// Returns `None` if the cell is empty. + /// + /// This method is allowed to violate the invariant of writing to a `OnceCell` + /// at most once because it requires `&mut` access to `self`. As with all + /// interior mutability, `&mut` access permits arbitrary modification: + /// + /// ``` + /// use once_cell::unsync::OnceCell; + /// + /// let mut cell: OnceCell = OnceCell::new(); + /// cell.set(92).unwrap(); + /// *cell.get_mut().unwrap() = 93; + /// assert_eq!(cell.get(), Some(&93)); + /// ``` + #[inline] + pub fn get_mut(&mut self) -> Option<&mut T> { + // Safe because we have unique access + unsafe { &mut *self.inner.get() }.as_mut() + } + + /// Sets the contents of this cell to `value`. + /// + /// Returns `Ok(())` if the cell was empty and `Err(value)` if it was + /// full. + /// + /// # Example + /// ``` + /// use once_cell::unsync::OnceCell; + /// + /// let cell = OnceCell::new(); + /// assert!(cell.get().is_none()); + /// + /// assert_eq!(cell.set(92), Ok(())); + /// assert_eq!(cell.set(62), Err(62)); + /// + /// assert!(cell.get().is_some()); + /// ``` + pub fn set(&self, value: T) -> Result<(), T> { + match self.try_insert(value) { + Ok(_) => Ok(()), + Err((_, value)) => Err(value), + } + } + + /// Like [`set`](Self::set), but also returns a reference to the final cell value. + /// + /// # Example + /// ``` + /// use once_cell::unsync::OnceCell; + /// + /// let cell = OnceCell::new(); + /// assert!(cell.get().is_none()); + /// + /// assert_eq!(cell.try_insert(92), Ok(&92)); + /// assert_eq!(cell.try_insert(62), Err((&92, 62))); + /// + /// assert!(cell.get().is_some()); + /// ``` + pub fn try_insert(&self, value: T) -> Result<&T, (&T, T)> { + if let Some(old) = self.get() { + return Err((old, value)); + } + + let slot = unsafe { &mut *self.inner.get() }; + // This is the only place where we set the slot, no races + // due to reentrancy/concurrency are possible, and we've + // checked that slot is currently `None`, so this write + // maintains the `inner`'s invariant. + *slot = Some(value); + Ok(unsafe { slot.as_ref().unwrap_unchecked() }) + } + + /// Gets the contents of the cell, initializing it with `f` + /// if the cell was empty. + /// + /// # Panics + /// + /// If `f` panics, the panic is propagated to the caller, and the cell + /// remains uninitialized. + /// + /// It is an error to reentrantly initialize the cell from `f`. Doing + /// so results in a panic. + /// + /// # Example + /// ``` + /// use once_cell::unsync::OnceCell; + /// + /// let cell = OnceCell::new(); + /// let value = cell.get_or_init(|| 92); + /// assert_eq!(value, &92); + /// let value = cell.get_or_init(|| unreachable!()); + /// assert_eq!(value, &92); + /// ``` + pub fn get_or_init(&self, f: F) -> &T + where + F: FnOnce() -> T, + { + enum Void {} + match self.get_or_try_init(|| Ok::(f())) { + Ok(val) => val, + Err(void) => match void {}, + } + } + + /// Gets the contents of the cell, initializing it with `f` if + /// the cell was empty. If the cell was empty and `f` failed, an + /// error is returned. + /// + /// # Panics + /// + /// If `f` panics, the panic is propagated to the caller, and the cell + /// remains uninitialized. + /// + /// It is an error to reentrantly initialize the cell from `f`. Doing + /// so results in a panic. + /// + /// # Example + /// ``` + /// use once_cell::unsync::OnceCell; + /// + /// let cell = OnceCell::new(); + /// assert_eq!(cell.get_or_try_init(|| Err(())), Err(())); + /// assert!(cell.get().is_none()); + /// let value = cell.get_or_try_init(|| -> Result { + /// Ok(92) + /// }); + /// assert_eq!(value, Ok(&92)); + /// assert_eq!(cell.get(), Some(&92)) + /// ``` + pub fn get_or_try_init(&self, f: F) -> Result<&T, E> + where + F: FnOnce() -> Result, + { + if let Some(val) = self.get() { + return Ok(val); + } + let val = f()?; + // Note that *some* forms of reentrant initialization might lead to + // UB (see `reentrant_init` test). I believe that just removing this + // `assert`, while keeping `set/get` would be sound, but it seems + // better to panic, rather than to silently use an old value. + assert!(self.set(val).is_ok(), "reentrant init"); + Ok(unsafe { self.get().unwrap_unchecked() }) + } + + /// Takes the value out of this `OnceCell`, moving it back to an uninitialized state. + /// + /// Has no effect and returns `None` if the `OnceCell` hasn't been initialized. + /// + /// # Examples + /// + /// ``` + /// use once_cell::unsync::OnceCell; + /// + /// let mut cell: OnceCell = OnceCell::new(); + /// assert_eq!(cell.take(), None); + /// + /// let mut cell = OnceCell::new(); + /// cell.set("hello".to_string()).unwrap(); + /// assert_eq!(cell.take(), Some("hello".to_string())); + /// assert_eq!(cell.get(), None); + /// ``` + /// + /// This method is allowed to violate the invariant of writing to a `OnceCell` + /// at most once because it requires `&mut` access to `self`. As with all + /// interior mutability, `&mut` access permits arbitrary modification: + /// + /// ``` + /// use once_cell::unsync::OnceCell; + /// + /// let mut cell: OnceCell = OnceCell::new(); + /// cell.set(92).unwrap(); + /// cell = OnceCell::new(); + /// ``` + pub fn take(&mut self) -> Option { + mem::take(self).into_inner() + } + + /// Consumes the `OnceCell`, returning the wrapped value. + /// + /// Returns `None` if the cell was empty. + /// + /// # Examples + /// + /// ``` + /// use once_cell::unsync::OnceCell; + /// + /// let cell: OnceCell = OnceCell::new(); + /// assert_eq!(cell.into_inner(), None); + /// + /// let cell = OnceCell::new(); + /// cell.set("hello".to_string()).unwrap(); + /// assert_eq!(cell.into_inner(), Some("hello".to_string())); + /// ``` + pub fn into_inner(self) -> Option { + // Because `into_inner` takes `self` by value, the compiler statically verifies + // that it is not currently borrowed. So it is safe to move out `Option`. + self.inner.into_inner() + } + } + + /// A value which is initialized on the first access. + /// + /// # Example + /// ``` + /// use once_cell::unsync::Lazy; + /// + /// let lazy: Lazy = Lazy::new(|| { + /// println!("initializing"); + /// 92 + /// }); + /// println!("ready"); + /// println!("{}", *lazy); + /// println!("{}", *lazy); + /// + /// // Prints: + /// // ready + /// // initializing + /// // 92 + /// // 92 + /// ``` + pub struct Lazy T> { + cell: OnceCell, + init: Cell>, + } + + impl RefUnwindSafe for Lazy where OnceCell: RefUnwindSafe {} + + impl fmt::Debug for Lazy { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.debug_struct("Lazy").field("cell", &self.cell).field("init", &"..").finish() + } + } + + impl Lazy { + /// Creates a new lazy value with the given initializing function. + /// + /// # Example + /// ``` + /// # fn main() { + /// use once_cell::unsync::Lazy; + /// + /// let hello = "Hello, World!".to_string(); + /// + /// let lazy = Lazy::new(|| hello.to_uppercase()); + /// + /// assert_eq!(&*lazy, "HELLO, WORLD!"); + /// # } + /// ``` + pub const fn new(init: F) -> Lazy { + Lazy { cell: OnceCell::new(), init: Cell::new(Some(init)) } + } + + /// Consumes this `Lazy` returning the stored value. + /// + /// Returns `Ok(value)` if `Lazy` is initialized and `Err(f)` otherwise. + pub fn into_value(this: Lazy) -> Result { + let cell = this.cell; + let init = this.init; + cell.into_inner().ok_or_else(|| { + init.take().unwrap_or_else(|| panic!("Lazy instance has previously been poisoned")) + }) + } + } + + impl T> Lazy { + /// Forces the evaluation of this lazy value and returns a reference to + /// the result. + /// + /// This is equivalent to the `Deref` impl, but is explicit. + /// + /// # Example + /// ``` + /// use once_cell::unsync::Lazy; + /// + /// let lazy = Lazy::new(|| 92); + /// + /// assert_eq!(Lazy::force(&lazy), &92); + /// assert_eq!(&*lazy, &92); + /// ``` + pub fn force(this: &Lazy) -> &T { + this.cell.get_or_init(|| match this.init.take() { + Some(f) => f(), + None => panic!("Lazy instance has previously been poisoned"), + }) + } + + /// Forces the evaluation of this lazy value and returns a mutable reference to + /// the result. + /// + /// This is equivalent to the `DerefMut` impl, but is explicit. + /// + /// # Example + /// ``` + /// use once_cell::unsync::Lazy; + /// + /// let mut lazy = Lazy::new(|| 92); + /// + /// assert_eq!(Lazy::force_mut(&mut lazy), &92); + /// assert_eq!(*lazy, 92); + /// ``` + pub fn force_mut(this: &mut Lazy) -> &mut T { + if this.cell.get_mut().is_none() { + let value = match this.init.get_mut().take() { + Some(f) => f(), + None => panic!("Lazy instance has previously been poisoned"), + }; + this.cell = OnceCell::with_value(value); + } + this.cell.get_mut().unwrap_or_else(|| unreachable!()) + } + + /// Gets the reference to the result of this lazy value if + /// it was initialized, otherwise returns `None`. + /// + /// # Example + /// ``` + /// use once_cell::unsync::Lazy; + /// + /// let lazy = Lazy::new(|| 92); + /// + /// assert_eq!(Lazy::get(&lazy), None); + /// assert_eq!(&*lazy, &92); + /// assert_eq!(Lazy::get(&lazy), Some(&92)); + /// ``` + pub fn get(this: &Lazy) -> Option<&T> { + this.cell.get() + } + + /// Gets the mutable reference to the result of this lazy value if + /// it was initialized, otherwise returns `None`. + /// + /// # Example + /// ``` + /// use once_cell::unsync::Lazy; + /// + /// let mut lazy = Lazy::new(|| 92); + /// + /// assert_eq!(Lazy::get_mut(&mut lazy), None); + /// assert_eq!(*lazy, 92); + /// assert_eq!(Lazy::get_mut(&mut lazy), Some(&mut 92)); + /// ``` + pub fn get_mut(this: &mut Lazy) -> Option<&mut T> { + this.cell.get_mut() + } + } + + impl T> Deref for Lazy { + type Target = T; + fn deref(&self) -> &T { + Lazy::force(self) + } + } + + impl T> DerefMut for Lazy { + fn deref_mut(&mut self) -> &mut T { + Lazy::force_mut(self) + } + } + + impl Default for Lazy { + /// Creates a new lazy value using `Default` as the initializing function. + fn default() -> Lazy { + Lazy::new(T::default) + } + } +} + +/// Thread-safe, blocking version of `OnceCell`. +#[cfg(any(feature = "std", feature = "critical-section"))] +pub mod sync { + use core::{ + cell::Cell, + fmt, mem, + ops::{Deref, DerefMut}, + panic::RefUnwindSafe, + }; + + use super::imp::OnceCell as Imp; + + /// A thread-safe cell which can be written to only once. + /// + /// `OnceCell` provides `&` references to the contents without RAII guards. + /// + /// Reading a non-`None` value out of `OnceCell` establishes a + /// happens-before relationship with a corresponding write. For example, if + /// thread A initializes the cell with `get_or_init(f)`, and thread B + /// subsequently reads the result of this call, B also observes all the side + /// effects of `f`. + /// + /// # Example + /// ``` + /// use once_cell::sync::OnceCell; + /// + /// static CELL: OnceCell = OnceCell::new(); + /// assert!(CELL.get().is_none()); + /// + /// std::thread::spawn(|| { + /// let value: &String = CELL.get_or_init(|| { + /// "Hello, World!".to_string() + /// }); + /// assert_eq!(value, "Hello, World!"); + /// }).join().unwrap(); + /// + /// let value: Option<&String> = CELL.get(); + /// assert!(value.is_some()); + /// assert_eq!(value.unwrap().as_str(), "Hello, World!"); + /// ``` + pub struct OnceCell(Imp); + + impl Default for OnceCell { + fn default() -> OnceCell { + OnceCell::new() + } + } + + impl fmt::Debug for OnceCell { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match self.get() { + Some(v) => f.debug_tuple("OnceCell").field(v).finish(), + None => f.write_str("OnceCell(Uninit)"), + } + } + } + + impl Clone for OnceCell { + fn clone(&self) -> OnceCell { + match self.get() { + Some(value) => Self::with_value(value.clone()), + None => Self::new(), + } + } + + fn clone_from(&mut self, source: &Self) { + match (self.get_mut(), source.get()) { + (Some(this), Some(source)) => this.clone_from(source), + _ => *self = source.clone(), + } + } + } + + impl From for OnceCell { + fn from(value: T) -> Self { + Self::with_value(value) + } + } + + impl PartialEq for OnceCell { + fn eq(&self, other: &OnceCell) -> bool { + self.get() == other.get() + } + } + + impl Eq for OnceCell {} + + impl OnceCell { + /// Creates a new empty cell. + pub const fn new() -> OnceCell { + OnceCell(Imp::new()) + } + + /// Creates a new initialized cell. + pub const fn with_value(value: T) -> OnceCell { + OnceCell(Imp::with_value(value)) + } + + /// Gets the reference to the underlying value. + /// + /// Returns `None` if the cell is empty, or being initialized. This + /// method never blocks. + pub fn get(&self) -> Option<&T> { + if self.0.is_initialized() { + // Safe b/c value is initialized. + Some(unsafe { self.get_unchecked() }) + } else { + None + } + } + + /// Gets the reference to the underlying value, blocking the current + /// thread until it is set. + /// + /// ``` + /// use once_cell::sync::OnceCell; + /// + /// let mut cell = std::sync::Arc::new(OnceCell::new()); + /// let t = std::thread::spawn({ + /// let cell = std::sync::Arc::clone(&cell); + /// move || cell.set(92).unwrap() + /// }); + /// + /// // Returns immediately, but might return None. + /// let _value_or_none = cell.get(); + /// + /// // Will return 92, but might block until the other thread does `.set`. + /// let value: &u32 = cell.wait(); + /// assert_eq!(*value, 92); + /// t.join().unwrap(); + /// ``` + #[cfg(feature = "std")] + pub fn wait(&self) -> &T { + if !self.0.is_initialized() { + self.0.wait() + } + debug_assert!(self.0.is_initialized()); + // Safe b/c of the wait call above and the fact that we didn't + // relinquish our borrow. + unsafe { self.get_unchecked() } + } + + /// Gets the mutable reference to the underlying value. + /// + /// Returns `None` if the cell is empty. + /// + /// This method is allowed to violate the invariant of writing to a `OnceCell` + /// at most once because it requires `&mut` access to `self`. As with all + /// interior mutability, `&mut` access permits arbitrary modification: + /// + /// ``` + /// use once_cell::sync::OnceCell; + /// + /// let mut cell: OnceCell = OnceCell::new(); + /// cell.set(92).unwrap(); + /// cell = OnceCell::new(); + /// ``` + #[inline] + pub fn get_mut(&mut self) -> Option<&mut T> { + self.0.get_mut() + } + + /// Get the reference to the underlying value, without checking if the + /// cell is initialized. + /// + /// # Safety + /// + /// Caller must ensure that the cell is in initialized state, and that + /// the contents are acquired by (synchronized to) this thread. + #[inline] + pub unsafe fn get_unchecked(&self) -> &T { + self.0.get_unchecked() + } + + /// Sets the contents of this cell to `value`. + /// + /// Returns `Ok(())` if the cell was empty and `Err(value)` if it was + /// full. + /// + /// # Example + /// + /// ``` + /// use once_cell::sync::OnceCell; + /// + /// static CELL: OnceCell = OnceCell::new(); + /// + /// fn main() { + /// assert!(CELL.get().is_none()); + /// + /// std::thread::spawn(|| { + /// assert_eq!(CELL.set(92), Ok(())); + /// }).join().unwrap(); + /// + /// assert_eq!(CELL.set(62), Err(62)); + /// assert_eq!(CELL.get(), Some(&92)); + /// } + /// ``` + pub fn set(&self, value: T) -> Result<(), T> { + match self.try_insert(value) { + Ok(_) => Ok(()), + Err((_, value)) => Err(value), + } + } + + /// Like [`set`](Self::set), but also returns a reference to the final cell value. + /// + /// # Example + /// + /// ``` + /// use once_cell::unsync::OnceCell; + /// + /// let cell = OnceCell::new(); + /// assert!(cell.get().is_none()); + /// + /// assert_eq!(cell.try_insert(92), Ok(&92)); + /// assert_eq!(cell.try_insert(62), Err((&92, 62))); + /// + /// assert!(cell.get().is_some()); + /// ``` + pub fn try_insert(&self, value: T) -> Result<&T, (&T, T)> { + let mut value = Some(value); + let res = self.get_or_init(|| unsafe { value.take().unwrap_unchecked() }); + match value { + None => Ok(res), + Some(value) => Err((res, value)), + } + } + + /// Gets the contents of the cell, initializing it with `f` if the cell + /// was empty. + /// + /// Many threads may call `get_or_init` concurrently with different + /// initializing functions, but it is guaranteed that only one function + /// will be executed. + /// + /// # Panics + /// + /// If `f` panics, the panic is propagated to the caller, and the cell + /// remains uninitialized. + /// + /// It is an error to reentrantly initialize the cell from `f`. The + /// exact outcome is unspecified. Current implementation deadlocks, but + /// this may be changed to a panic in the future. + /// + /// # Example + /// ``` + /// use once_cell::sync::OnceCell; + /// + /// let cell = OnceCell::new(); + /// let value = cell.get_or_init(|| 92); + /// assert_eq!(value, &92); + /// let value = cell.get_or_init(|| unreachable!()); + /// assert_eq!(value, &92); + /// ``` + pub fn get_or_init(&self, f: F) -> &T + where + F: FnOnce() -> T, + { + enum Void {} + match self.get_or_try_init(|| Ok::(f())) { + Ok(val) => val, + Err(void) => match void {}, + } + } + + /// Gets the contents of the cell, initializing it with `f` if + /// the cell was empty. If the cell was empty and `f` failed, an + /// error is returned. + /// + /// # Panics + /// + /// If `f` panics, the panic is propagated to the caller, and + /// the cell remains uninitialized. + /// + /// It is an error to reentrantly initialize the cell from `f`. + /// The exact outcome is unspecified. Current implementation + /// deadlocks, but this may be changed to a panic in the future. + /// + /// # Example + /// ``` + /// use once_cell::sync::OnceCell; + /// + /// let cell = OnceCell::new(); + /// assert_eq!(cell.get_or_try_init(|| Err(())), Err(())); + /// assert!(cell.get().is_none()); + /// let value = cell.get_or_try_init(|| -> Result { + /// Ok(92) + /// }); + /// assert_eq!(value, Ok(&92)); + /// assert_eq!(cell.get(), Some(&92)) + /// ``` + pub fn get_or_try_init(&self, f: F) -> Result<&T, E> + where + F: FnOnce() -> Result, + { + // Fast path check + if let Some(value) = self.get() { + return Ok(value); + } + + self.0.initialize(f)?; + + // Safe b/c value is initialized. + debug_assert!(self.0.is_initialized()); + Ok(unsafe { self.get_unchecked() }) + } + + /// Takes the value out of this `OnceCell`, moving it back to an uninitialized state. + /// + /// Has no effect and returns `None` if the `OnceCell` hasn't been initialized. + /// + /// # Examples + /// + /// ``` + /// use once_cell::sync::OnceCell; + /// + /// let mut cell: OnceCell = OnceCell::new(); + /// assert_eq!(cell.take(), None); + /// + /// let mut cell = OnceCell::new(); + /// cell.set("hello".to_string()).unwrap(); + /// assert_eq!(cell.take(), Some("hello".to_string())); + /// assert_eq!(cell.get(), None); + /// ``` + /// + /// This method is allowed to violate the invariant of writing to a `OnceCell` + /// at most once because it requires `&mut` access to `self`. As with all + /// interior mutability, `&mut` access permits arbitrary modification: + /// + /// ``` + /// use once_cell::sync::OnceCell; + /// + /// let mut cell: OnceCell = OnceCell::new(); + /// cell.set(92).unwrap(); + /// cell = OnceCell::new(); + /// ``` + pub fn take(&mut self) -> Option { + mem::take(self).into_inner() + } + + /// Consumes the `OnceCell`, returning the wrapped value. Returns + /// `None` if the cell was empty. + /// + /// # Examples + /// + /// ``` + /// use once_cell::sync::OnceCell; + /// + /// let cell: OnceCell = OnceCell::new(); + /// assert_eq!(cell.into_inner(), None); + /// + /// let cell = OnceCell::new(); + /// cell.set("hello".to_string()).unwrap(); + /// assert_eq!(cell.into_inner(), Some("hello".to_string())); + /// ``` + #[inline] + pub fn into_inner(self) -> Option { + self.0.into_inner() + } + } + + /// A value which is initialized on the first access. + /// + /// This type is thread-safe and can be used in statics. + /// + /// # Example + /// + /// ``` + /// use std::collections::HashMap; + /// + /// use once_cell::sync::Lazy; + /// + /// static HASHMAP: Lazy> = Lazy::new(|| { + /// println!("initializing"); + /// let mut m = HashMap::new(); + /// m.insert(13, "Spica".to_string()); + /// m.insert(74, "Hoyten".to_string()); + /// m + /// }); + /// + /// fn main() { + /// println!("ready"); + /// std::thread::spawn(|| { + /// println!("{:?}", HASHMAP.get(&13)); + /// }).join().unwrap(); + /// println!("{:?}", HASHMAP.get(&74)); + /// + /// // Prints: + /// // ready + /// // initializing + /// // Some("Spica") + /// // Some("Hoyten") + /// } + /// ``` + pub struct Lazy T> { + cell: OnceCell, + init: Cell>, + } + + impl fmt::Debug for Lazy { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.debug_struct("Lazy").field("cell", &self.cell).field("init", &"..").finish() + } + } + + // We never create a `&F` from a `&Lazy` so it is fine to not impl + // `Sync` for `F`. We do create a `&mut Option` in `force`, but this is + // properly synchronized, so it only happens once so it also does not + // contribute to this impl. + unsafe impl Sync for Lazy where OnceCell: Sync {} + // auto-derived `Send` impl is OK. + + impl RefUnwindSafe for Lazy where OnceCell: RefUnwindSafe {} + + impl Lazy { + /// Creates a new lazy value with the given initializing + /// function. + pub const fn new(f: F) -> Lazy { + Lazy { cell: OnceCell::new(), init: Cell::new(Some(f)) } + } + + /// Consumes this `Lazy` returning the stored value. + /// + /// Returns `Ok(value)` if `Lazy` is initialized and `Err(f)` otherwise. + pub fn into_value(this: Lazy) -> Result { + let cell = this.cell; + let init = this.init; + cell.into_inner().ok_or_else(|| { + init.take().unwrap_or_else(|| panic!("Lazy instance has previously been poisoned")) + }) + } + } + + impl T> Lazy { + /// Forces the evaluation of this lazy value and + /// returns a reference to the result. This is equivalent + /// to the `Deref` impl, but is explicit. + /// + /// # Example + /// ``` + /// use once_cell::sync::Lazy; + /// + /// let lazy = Lazy::new(|| 92); + /// + /// assert_eq!(Lazy::force(&lazy), &92); + /// assert_eq!(&*lazy, &92); + /// ``` + pub fn force(this: &Lazy) -> &T { + this.cell.get_or_init(|| match this.init.take() { + Some(f) => f(), + None => panic!("Lazy instance has previously been poisoned"), + }) + } + + /// Forces the evaluation of this lazy value and + /// returns a mutable reference to the result. This is equivalent + /// to the `Deref` impl, but is explicit. + /// + /// # Example + /// ``` + /// use once_cell::sync::Lazy; + /// + /// let mut lazy = Lazy::new(|| 92); + /// + /// assert_eq!(Lazy::force_mut(&mut lazy), &mut 92); + /// ``` + pub fn force_mut(this: &mut Lazy) -> &mut T { + if this.cell.get_mut().is_none() { + let value = match this.init.get_mut().take() { + Some(f) => f(), + None => panic!("Lazy instance has previously been poisoned"), + }; + this.cell = OnceCell::with_value(value); + } + this.cell.get_mut().unwrap_or_else(|| unreachable!()) + } + + /// Gets the reference to the result of this lazy value if + /// it was initialized, otherwise returns `None`. + /// + /// # Example + /// ``` + /// use once_cell::sync::Lazy; + /// + /// let lazy = Lazy::new(|| 92); + /// + /// assert_eq!(Lazy::get(&lazy), None); + /// assert_eq!(&*lazy, &92); + /// assert_eq!(Lazy::get(&lazy), Some(&92)); + /// ``` + pub fn get(this: &Lazy) -> Option<&T> { + this.cell.get() + } + + /// Gets the reference to the result of this lazy value if + /// it was initialized, otherwise returns `None`. + /// + /// # Example + /// ``` + /// use once_cell::sync::Lazy; + /// + /// let mut lazy = Lazy::new(|| 92); + /// + /// assert_eq!(Lazy::get_mut(&mut lazy), None); + /// assert_eq!(&*lazy, &92); + /// assert_eq!(Lazy::get_mut(&mut lazy), Some(&mut 92)); + /// ``` + pub fn get_mut(this: &mut Lazy) -> Option<&mut T> { + this.cell.get_mut() + } + } + + impl T> Deref for Lazy { + type Target = T; + fn deref(&self) -> &T { + Lazy::force(self) + } + } + + impl T> DerefMut for Lazy { + fn deref_mut(&mut self) -> &mut T { + Lazy::force_mut(self) + } + } + + impl Default for Lazy { + /// Creates a new lazy value using `Default` as the initializing function. + fn default() -> Lazy { + Lazy::new(T::default) + } + } + + /// ```compile_fail + /// struct S(*mut ()); + /// unsafe impl Sync for S {} + /// + /// fn share(_: &T) {} + /// share(&once_cell::sync::OnceCell::::new()); + /// ``` + /// + /// ```compile_fail + /// struct S(*mut ()); + /// unsafe impl Sync for S {} + /// + /// fn share(_: &T) {} + /// share(&once_cell::sync::Lazy::::new(|| unimplemented!())); + /// ``` + fn _dummy() {} +} + +#[cfg(feature = "race")] +pub mod race; diff --git a/vendor/once_cell/src/race.rs b/vendor/once_cell/src/race.rs new file mode 100644 index 0000000..9c09323 --- /dev/null +++ b/vendor/once_cell/src/race.rs @@ -0,0 +1,419 @@ +//! Thread-safe, non-blocking, "first one wins" flavor of `OnceCell`. +//! +//! If two threads race to initialize a type from the `race` module, they +//! don't block, execute initialization function together, but only one of +//! them stores the result. +//! +//! This module does not require `std` feature. +//! +//! # Atomic orderings +//! +//! All types in this module use `Acquire` and `Release` +//! [atomic orderings](Ordering) for all their operations. While this is not +//! strictly necessary for types other than `OnceBox`, it is useful for users as +//! it allows them to be certain that after `get` or `get_or_init` returns on +//! one thread, any side-effects caused by the setter thread prior to them +//! calling `set` or `get_or_init` will be made visible to that thread; without +//! it, it's possible for it to appear as if they haven't happened yet from the +//! getter thread's perspective. This is an acceptable tradeoff to make since +//! `Acquire` and `Release` have very little performance overhead on most +//! architectures versus `Relaxed`. + +#[cfg(not(feature = "portable-atomic"))] +use core::sync::atomic; +#[cfg(feature = "portable-atomic")] +use portable_atomic as atomic; + +use atomic::{AtomicPtr, AtomicUsize, Ordering}; +use core::cell::UnsafeCell; +use core::marker::PhantomData; +use core::num::NonZeroUsize; +use core::ptr; + +/// A thread-safe cell which can be written to only once. +#[derive(Default, Debug)] +pub struct OnceNonZeroUsize { + inner: AtomicUsize, +} + +impl OnceNonZeroUsize { + /// Creates a new empty cell. + #[inline] + pub const fn new() -> OnceNonZeroUsize { + OnceNonZeroUsize { inner: AtomicUsize::new(0) } + } + + /// Gets the underlying value. + #[inline] + pub fn get(&self) -> Option { + let val = self.inner.load(Ordering::Acquire); + NonZeroUsize::new(val) + } + + /// Sets the contents of this cell to `value`. + /// + /// Returns `Ok(())` if the cell was empty and `Err(())` if it was + /// full. + #[inline] + pub fn set(&self, value: NonZeroUsize) -> Result<(), ()> { + let exchange = + self.inner.compare_exchange(0, value.get(), Ordering::AcqRel, Ordering::Acquire); + match exchange { + Ok(_) => Ok(()), + Err(_) => Err(()), + } + } + + /// Gets the contents of the cell, initializing it with `f` if the cell was + /// empty. + /// + /// If several threads concurrently run `get_or_init`, more than one `f` can + /// be called. However, all threads will return the same value, produced by + /// some `f`. + pub fn get_or_init(&self, f: F) -> NonZeroUsize + where + F: FnOnce() -> NonZeroUsize, + { + enum Void {} + match self.get_or_try_init(|| Ok::(f())) { + Ok(val) => val, + Err(void) => match void {}, + } + } + + /// Gets the contents of the cell, initializing it with `f` if + /// the cell was empty. If the cell was empty and `f` failed, an + /// error is returned. + /// + /// If several threads concurrently run `get_or_init`, more than one `f` can + /// be called. However, all threads will return the same value, produced by + /// some `f`. + pub fn get_or_try_init(&self, f: F) -> Result + where + F: FnOnce() -> Result, + { + let val = self.inner.load(Ordering::Acquire); + let res = match NonZeroUsize::new(val) { + Some(it) => it, + None => { + let mut val = f()?.get(); + let exchange = + self.inner.compare_exchange(0, val, Ordering::AcqRel, Ordering::Acquire); + if let Err(old) = exchange { + val = old; + } + unsafe { NonZeroUsize::new_unchecked(val) } + } + }; + Ok(res) + } +} + +/// A thread-safe cell which can be written to only once. +#[derive(Default, Debug)] +pub struct OnceBool { + inner: OnceNonZeroUsize, +} + +impl OnceBool { + /// Creates a new empty cell. + #[inline] + pub const fn new() -> OnceBool { + OnceBool { inner: OnceNonZeroUsize::new() } + } + + /// Gets the underlying value. + #[inline] + pub fn get(&self) -> Option { + self.inner.get().map(OnceBool::from_usize) + } + + /// Sets the contents of this cell to `value`. + /// + /// Returns `Ok(())` if the cell was empty and `Err(())` if it was + /// full. + #[inline] + pub fn set(&self, value: bool) -> Result<(), ()> { + self.inner.set(OnceBool::to_usize(value)) + } + + /// Gets the contents of the cell, initializing it with `f` if the cell was + /// empty. + /// + /// If several threads concurrently run `get_or_init`, more than one `f` can + /// be called. However, all threads will return the same value, produced by + /// some `f`. + pub fn get_or_init(&self, f: F) -> bool + where + F: FnOnce() -> bool, + { + OnceBool::from_usize(self.inner.get_or_init(|| OnceBool::to_usize(f()))) + } + + /// Gets the contents of the cell, initializing it with `f` if + /// the cell was empty. If the cell was empty and `f` failed, an + /// error is returned. + /// + /// If several threads concurrently run `get_or_init`, more than one `f` can + /// be called. However, all threads will return the same value, produced by + /// some `f`. + pub fn get_or_try_init(&self, f: F) -> Result + where + F: FnOnce() -> Result, + { + self.inner.get_or_try_init(|| f().map(OnceBool::to_usize)).map(OnceBool::from_usize) + } + + #[inline] + fn from_usize(value: NonZeroUsize) -> bool { + value.get() == 1 + } + + #[inline] + fn to_usize(value: bool) -> NonZeroUsize { + unsafe { NonZeroUsize::new_unchecked(if value { 1 } else { 2 }) } + } +} + +/// A thread-safe cell which can be written to only once. +pub struct OnceRef<'a, T> { + inner: AtomicPtr, + ghost: PhantomData>, +} + +// TODO: Replace UnsafeCell with SyncUnsafeCell once stabilized +unsafe impl<'a, T: Sync> Sync for OnceRef<'a, T> {} + +impl<'a, T> core::fmt::Debug for OnceRef<'a, T> { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + write!(f, "OnceRef({:?})", self.inner) + } +} + +impl<'a, T> Default for OnceRef<'a, T> { + fn default() -> Self { + Self::new() + } +} + +impl<'a, T> OnceRef<'a, T> { + /// Creates a new empty cell. + pub const fn new() -> OnceRef<'a, T> { + OnceRef { inner: AtomicPtr::new(ptr::null_mut()), ghost: PhantomData } + } + + /// Gets a reference to the underlying value. + pub fn get(&self) -> Option<&'a T> { + let ptr = self.inner.load(Ordering::Acquire); + unsafe { ptr.as_ref() } + } + + /// Sets the contents of this cell to `value`. + /// + /// Returns `Ok(())` if the cell was empty and `Err(value)` if it was + /// full. + pub fn set(&self, value: &'a T) -> Result<(), ()> { + let ptr = value as *const T as *mut T; + let exchange = + self.inner.compare_exchange(ptr::null_mut(), ptr, Ordering::AcqRel, Ordering::Acquire); + match exchange { + Ok(_) => Ok(()), + Err(_) => Err(()), + } + } + + /// Gets the contents of the cell, initializing it with `f` if the cell was + /// empty. + /// + /// If several threads concurrently run `get_or_init`, more than one `f` can + /// be called. However, all threads will return the same value, produced by + /// some `f`. + pub fn get_or_init(&self, f: F) -> &'a T + where + F: FnOnce() -> &'a T, + { + enum Void {} + match self.get_or_try_init(|| Ok::<&'a T, Void>(f())) { + Ok(val) => val, + Err(void) => match void {}, + } + } + + /// Gets the contents of the cell, initializing it with `f` if + /// the cell was empty. If the cell was empty and `f` failed, an + /// error is returned. + /// + /// If several threads concurrently run `get_or_init`, more than one `f` can + /// be called. However, all threads will return the same value, produced by + /// some `f`. + pub fn get_or_try_init(&self, f: F) -> Result<&'a T, E> + where + F: FnOnce() -> Result<&'a T, E>, + { + let mut ptr = self.inner.load(Ordering::Acquire); + + if ptr.is_null() { + // TODO replace with `cast_mut` when MSRV reaches 1.65.0 (also in `set`) + ptr = f()? as *const T as *mut T; + let exchange = self.inner.compare_exchange( + ptr::null_mut(), + ptr, + Ordering::AcqRel, + Ordering::Acquire, + ); + if let Err(old) = exchange { + ptr = old; + } + } + + Ok(unsafe { &*ptr }) + } + + /// ```compile_fail + /// use once_cell::race::OnceRef; + /// + /// let mut l = OnceRef::new(); + /// + /// { + /// let y = 2; + /// let mut r = OnceRef::new(); + /// r.set(&y).unwrap(); + /// core::mem::swap(&mut l, &mut r); + /// } + /// + /// // l now contains a dangling reference to y + /// eprintln!("uaf: {}", l.get().unwrap()); + /// ``` + fn _dummy() {} +} + +#[cfg(feature = "alloc")] +pub use self::once_box::OnceBox; + +#[cfg(feature = "alloc")] +mod once_box { + use super::atomic::{AtomicPtr, Ordering}; + use core::{marker::PhantomData, ptr}; + + use alloc::boxed::Box; + + /// A thread-safe cell which can be written to only once. + pub struct OnceBox { + inner: AtomicPtr, + ghost: PhantomData>>, + } + + impl core::fmt::Debug for OnceBox { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + write!(f, "OnceBox({:?})", self.inner.load(Ordering::Relaxed)) + } + } + + impl Default for OnceBox { + fn default() -> Self { + Self::new() + } + } + + impl Drop for OnceBox { + fn drop(&mut self) { + let ptr = *self.inner.get_mut(); + if !ptr.is_null() { + drop(unsafe { Box::from_raw(ptr) }) + } + } + } + + impl OnceBox { + /// Creates a new empty cell. + pub const fn new() -> OnceBox { + OnceBox { inner: AtomicPtr::new(ptr::null_mut()), ghost: PhantomData } + } + + /// Gets a reference to the underlying value. + pub fn get(&self) -> Option<&T> { + let ptr = self.inner.load(Ordering::Acquire); + if ptr.is_null() { + return None; + } + Some(unsafe { &*ptr }) + } + + /// Sets the contents of this cell to `value`. + /// + /// Returns `Ok(())` if the cell was empty and `Err(value)` if it was + /// full. + pub fn set(&self, value: Box) -> Result<(), Box> { + let ptr = Box::into_raw(value); + let exchange = self.inner.compare_exchange( + ptr::null_mut(), + ptr, + Ordering::AcqRel, + Ordering::Acquire, + ); + if exchange.is_err() { + let value = unsafe { Box::from_raw(ptr) }; + return Err(value); + } + Ok(()) + } + + /// Gets the contents of the cell, initializing it with `f` if the cell was + /// empty. + /// + /// If several threads concurrently run `get_or_init`, more than one `f` can + /// be called. However, all threads will return the same value, produced by + /// some `f`. + pub fn get_or_init(&self, f: F) -> &T + where + F: FnOnce() -> Box, + { + enum Void {} + match self.get_or_try_init(|| Ok::, Void>(f())) { + Ok(val) => val, + Err(void) => match void {}, + } + } + + /// Gets the contents of the cell, initializing it with `f` if + /// the cell was empty. If the cell was empty and `f` failed, an + /// error is returned. + /// + /// If several threads concurrently run `get_or_init`, more than one `f` can + /// be called. However, all threads will return the same value, produced by + /// some `f`. + pub fn get_or_try_init(&self, f: F) -> Result<&T, E> + where + F: FnOnce() -> Result, E>, + { + let mut ptr = self.inner.load(Ordering::Acquire); + + if ptr.is_null() { + let val = f()?; + ptr = Box::into_raw(val); + let exchange = self.inner.compare_exchange( + ptr::null_mut(), + ptr, + Ordering::AcqRel, + Ordering::Acquire, + ); + if let Err(old) = exchange { + drop(unsafe { Box::from_raw(ptr) }); + ptr = old; + } + }; + Ok(unsafe { &*ptr }) + } + } + + unsafe impl Sync for OnceBox {} + + /// ```compile_fail + /// struct S(*mut ()); + /// unsafe impl Sync for S {} + /// + /// fn share(_: &T) {} + /// share(&once_cell::race::OnceBox::::new()); + /// ``` + fn _dummy() {} +} diff --git a/vendor/once_cell/tests/it/main.rs b/vendor/once_cell/tests/it/main.rs new file mode 100644 index 0000000..b8e56cc --- /dev/null +++ b/vendor/once_cell/tests/it/main.rs @@ -0,0 +1,12 @@ +mod unsync_once_cell; +#[cfg(any(feature = "std", feature = "critical-section"))] +mod sync_once_cell; + +mod unsync_lazy; +#[cfg(any(feature = "std", feature = "critical-section"))] +mod sync_lazy; + +#[cfg(feature = "race")] +mod race; +#[cfg(all(feature = "race", feature = "alloc"))] +mod race_once_box; diff --git a/vendor/once_cell/tests/it/race.rs b/vendor/once_cell/tests/it/race.rs new file mode 100644 index 0000000..24884dd --- /dev/null +++ b/vendor/once_cell/tests/it/race.rs @@ -0,0 +1,128 @@ +#[cfg(feature = "std")] +use std::sync::Barrier; +use std::{ + num::NonZeroUsize, + sync::atomic::{AtomicUsize, Ordering::SeqCst}, + thread::scope, +}; + +use once_cell::race::{OnceBool, OnceNonZeroUsize}; + +#[test] +fn once_non_zero_usize_smoke_test() { + let cnt = AtomicUsize::new(0); + let cell = OnceNonZeroUsize::new(); + let val = NonZeroUsize::new(92).unwrap(); + scope(|s| { + s.spawn(|| { + assert_eq!( + cell.get_or_init(|| { + cnt.fetch_add(1, SeqCst); + val + }), + val + ); + assert_eq!(cnt.load(SeqCst), 1); + + assert_eq!( + cell.get_or_init(|| { + cnt.fetch_add(1, SeqCst); + val + }), + val + ); + assert_eq!(cnt.load(SeqCst), 1); + }); + }); + assert_eq!(cell.get(), Some(val)); + assert_eq!(cnt.load(SeqCst), 1); +} + +#[test] +fn once_non_zero_usize_set() { + let val1 = NonZeroUsize::new(92).unwrap(); + let val2 = NonZeroUsize::new(62).unwrap(); + + let cell = OnceNonZeroUsize::new(); + + assert!(cell.set(val1).is_ok()); + assert_eq!(cell.get(), Some(val1)); + + assert!(cell.set(val2).is_err()); + assert_eq!(cell.get(), Some(val1)); +} + +#[cfg(feature = "std")] +#[test] +fn once_non_zero_usize_first_wins() { + let val1 = NonZeroUsize::new(92).unwrap(); + let val2 = NonZeroUsize::new(62).unwrap(); + + let cell = OnceNonZeroUsize::new(); + + let b1 = Barrier::new(2); + let b2 = Barrier::new(2); + let b3 = Barrier::new(2); + scope(|s| { + s.spawn(|| { + let r1 = cell.get_or_init(|| { + b1.wait(); + b2.wait(); + val1 + }); + assert_eq!(r1, val1); + b3.wait(); + }); + b1.wait(); + s.spawn(|| { + let r2 = cell.get_or_init(|| { + b2.wait(); + b3.wait(); + val2 + }); + assert_eq!(r2, val1); + }); + }); + + assert_eq!(cell.get(), Some(val1)); +} + +#[test] +fn once_bool_smoke_test() { + let cnt = AtomicUsize::new(0); + let cell = OnceBool::new(); + scope(|s| { + s.spawn(|| { + assert_eq!( + cell.get_or_init(|| { + cnt.fetch_add(1, SeqCst); + false + }), + false + ); + assert_eq!(cnt.load(SeqCst), 1); + + assert_eq!( + cell.get_or_init(|| { + cnt.fetch_add(1, SeqCst); + false + }), + false + ); + assert_eq!(cnt.load(SeqCst), 1); + }); + }); + assert_eq!(cell.get(), Some(false)); + assert_eq!(cnt.load(SeqCst), 1); +} + +#[test] +fn once_bool_set() { + let cell = OnceBool::new(); + + assert!(cell.set(false).is_ok()); + assert_eq!(cell.get(), Some(false)); + + assert!(cell.set(true).is_err()); + assert_eq!(cell.get(), Some(false)); +} diff --git a/vendor/once_cell/tests/it/race_once_box.rs b/vendor/once_cell/tests/it/race_once_box.rs new file mode 100644 index 0000000..0bf3852 --- /dev/null +++ b/vendor/once_cell/tests/it/race_once_box.rs @@ -0,0 +1,145 @@ +#[cfg(feature = "std")] +use std::sync::Barrier; +use std::sync::{ + atomic::{AtomicUsize, Ordering::SeqCst}, + Arc, +}; + +use once_cell::race::OnceBox; + +#[derive(Default)] +struct Heap { + total: Arc, +} + +#[derive(Debug)] +struct Pebble { + val: T, + total: Arc, +} + +impl Drop for Pebble { + fn drop(&mut self) { + self.total.fetch_sub(1, SeqCst); + } +} + +impl Heap { + fn total(&self) -> usize { + self.total.load(SeqCst) + } + fn new_pebble(&self, val: T) -> Pebble { + self.total.fetch_add(1, SeqCst); + Pebble { val, total: Arc::clone(&self.total) } + } +} + +#[cfg(feature = "std")] +#[test] +fn once_box_smoke_test() { + use std::thread::scope; + + let heap = Heap::default(); + let global_cnt = AtomicUsize::new(0); + let cell = OnceBox::new(); + let b = Barrier::new(128); + scope(|s| { + for _ in 0..128 { + s.spawn(|| { + let local_cnt = AtomicUsize::new(0); + cell.get_or_init(|| { + global_cnt.fetch_add(1, SeqCst); + local_cnt.fetch_add(1, SeqCst); + b.wait(); + Box::new(heap.new_pebble(())) + }); + assert_eq!(local_cnt.load(SeqCst), 1); + + cell.get_or_init(|| { + global_cnt.fetch_add(1, SeqCst); + local_cnt.fetch_add(1, SeqCst); + Box::new(heap.new_pebble(())) + }); + assert_eq!(local_cnt.load(SeqCst), 1); + }); + } + }); + assert!(cell.get().is_some()); + assert!(global_cnt.load(SeqCst) > 10); + + assert_eq!(heap.total(), 1); + drop(cell); + assert_eq!(heap.total(), 0); +} + +#[test] +fn once_box_set() { + let heap = Heap::default(); + let cell = OnceBox::new(); + assert!(cell.get().is_none()); + + assert!(cell.set(Box::new(heap.new_pebble("hello"))).is_ok()); + assert_eq!(cell.get().unwrap().val, "hello"); + assert_eq!(heap.total(), 1); + + assert!(cell.set(Box::new(heap.new_pebble("world"))).is_err()); + assert_eq!(cell.get().unwrap().val, "hello"); + assert_eq!(heap.total(), 1); + + drop(cell); + assert_eq!(heap.total(), 0); +} + +#[cfg(feature = "std")] +#[test] +fn once_box_first_wins() { + use std::thread::scope; + + let cell = OnceBox::new(); + let val1 = 92; + let val2 = 62; + + let b1 = Barrier::new(2); + let b2 = Barrier::new(2); + let b3 = Barrier::new(2); + scope(|s| { + s.spawn(|| { + let r1 = cell.get_or_init(|| { + b1.wait(); + b2.wait(); + Box::new(val1) + }); + assert_eq!(*r1, val1); + b3.wait(); + }); + b1.wait(); + s.spawn(|| { + let r2 = cell.get_or_init(|| { + b2.wait(); + b3.wait(); + Box::new(val2) + }); + assert_eq!(*r2, val1); + }); + }); + + assert_eq!(cell.get(), Some(&val1)); +} + +#[test] +fn once_box_reentrant() { + let cell = OnceBox::new(); + let res = cell.get_or_init(|| { + cell.get_or_init(|| Box::new("hello".to_string())); + Box::new("world".to_string()) + }); + assert_eq!(res, "hello"); +} + +#[test] +fn once_box_default() { + struct Foo; + + let cell: OnceBox = Default::default(); + assert!(cell.get().is_none()); +} diff --git a/vendor/once_cell/tests/it/sync_lazy.rs b/vendor/once_cell/tests/it/sync_lazy.rs new file mode 100644 index 0000000..44d70fa --- /dev/null +++ b/vendor/once_cell/tests/it/sync_lazy.rs @@ -0,0 +1,176 @@ +use std::{ + cell::Cell, + sync::atomic::{AtomicUsize, Ordering::SeqCst}, + thread::scope, +}; + +use once_cell::sync::{Lazy, OnceCell}; + +#[test] +fn lazy_new() { + let called = AtomicUsize::new(0); + let x = Lazy::new(|| { + called.fetch_add(1, SeqCst); + 92 + }); + + assert_eq!(called.load(SeqCst), 0); + + scope(|s| { + s.spawn(|| { + let y = *x - 30; + assert_eq!(y, 62); + assert_eq!(called.load(SeqCst), 1); + }); + }); + + let y = *x - 30; + assert_eq!(y, 62); + assert_eq!(called.load(SeqCst), 1); +} + +#[test] +fn lazy_deref_mut() { + let called = AtomicUsize::new(0); + let mut x = Lazy::new(|| { + called.fetch_add(1, SeqCst); + 92 + }); + + assert_eq!(called.load(SeqCst), 0); + + let y = *x - 30; + assert_eq!(y, 62); + assert_eq!(called.load(SeqCst), 1); + + *x /= 2; + assert_eq!(*x, 46); + assert_eq!(called.load(SeqCst), 1); +} + +#[test] +fn lazy_force_mut() { + let called = Cell::new(0); + let mut x = Lazy::new(|| { + called.set(called.get() + 1); + 92 + }); + assert_eq!(called.get(), 0); + let v = Lazy::force_mut(&mut x); + assert_eq!(called.get(), 1); + + *v /= 2; + assert_eq!(*x, 46); + assert_eq!(called.get(), 1); +} + +#[test] +fn lazy_get_mut() { + let called = Cell::new(0); + let mut x: Lazy = Lazy::new(|| { + called.set(called.get() + 1); + 92 + }); + + assert_eq!(called.get(), 0); + assert_eq!(*x, 92); + + let mut_ref: &mut u32 = Lazy::get_mut(&mut x).unwrap(); + assert_eq!(called.get(), 1); + + *mut_ref /= 2; + assert_eq!(*x, 46); + assert_eq!(called.get(), 1); +} + +#[test] +fn lazy_default() { + static CALLED: AtomicUsize = AtomicUsize::new(0); + + struct Foo(u8); + impl Default for Foo { + fn default() -> Self { + CALLED.fetch_add(1, SeqCst); + Foo(42) + } + } + + let lazy: Lazy> = <_>::default(); + + assert_eq!(CALLED.load(SeqCst), 0); + + assert_eq!(lazy.lock().unwrap().0, 42); + assert_eq!(CALLED.load(SeqCst), 1); + + lazy.lock().unwrap().0 = 21; + + assert_eq!(lazy.lock().unwrap().0, 21); + assert_eq!(CALLED.load(SeqCst), 1); +} + +#[test] +fn static_lazy() { + static XS: Lazy> = Lazy::new(|| { + let mut xs = Vec::new(); + xs.push(1); + xs.push(2); + xs.push(3); + xs + }); + scope(|s| { + s.spawn(|| { + assert_eq!(&*XS, &vec![1, 2, 3]); + }); + }); + assert_eq!(&*XS, &vec![1, 2, 3]); +} + +#[test] +fn static_lazy_via_fn() { + fn xs() -> &'static Vec { + static XS: OnceCell> = OnceCell::new(); + XS.get_or_init(|| { + let mut xs = Vec::new(); + xs.push(1); + xs.push(2); + xs.push(3); + xs + }) + } + assert_eq!(xs(), &vec![1, 2, 3]); +} + +#[test] +fn lazy_into_value() { + let l: Lazy = Lazy::new(|| panic!()); + assert!(matches!(Lazy::into_value(l), Err(_))); + let l = Lazy::new(|| -> i32 { 92 }); + Lazy::force(&l); + assert!(matches!(Lazy::into_value(l), Ok(92))); +} + +#[test] +fn lazy_poisoning() { + let x: Lazy = Lazy::new(|| panic!("kaboom")); + for _ in 0..2 { + let res = std::panic::catch_unwind(|| x.len()); + assert!(res.is_err()); + } +} + +#[test] +// https://github.com/rust-lang/rust/issues/34761#issuecomment-256320669 +fn arrrrrrrrrrrrrrrrrrrrrr() { + let lazy: Lazy<&String, _>; + { + let s = String::new(); + lazy = Lazy::new(|| &s); + _ = *lazy; + } +} + +#[test] +fn lazy_is_sync_send() { + fn assert_traits() {} + assert_traits::>(); +} diff --git a/vendor/once_cell/tests/it/sync_once_cell.rs b/vendor/once_cell/tests/it/sync_once_cell.rs new file mode 100644 index 0000000..252adea --- /dev/null +++ b/vendor/once_cell/tests/it/sync_once_cell.rs @@ -0,0 +1,309 @@ +use std::{ + sync::atomic::{AtomicUsize, Ordering::SeqCst}, + thread::scope, +}; + +#[cfg(feature = "std")] +use std::sync::Barrier; + +#[cfg(not(feature = "std"))] +use core::cell::Cell; + +use once_cell::sync::{Lazy, OnceCell}; + +#[test] +fn once_cell() { + let c = OnceCell::new(); + assert!(c.get().is_none()); + scope(|s| { + s.spawn(|| { + c.get_or_init(|| 92); + assert_eq!(c.get(), Some(&92)); + }); + }); + c.get_or_init(|| panic!("Kabom!")); + assert_eq!(c.get(), Some(&92)); +} + +#[test] +fn once_cell_with_value() { + static CELL: OnceCell = OnceCell::with_value(12); + assert_eq!(CELL.get(), Some(&12)); +} + +#[test] +fn once_cell_get_mut() { + let mut c = OnceCell::new(); + assert!(c.get_mut().is_none()); + c.set(90).unwrap(); + *c.get_mut().unwrap() += 2; + assert_eq!(c.get_mut(), Some(&mut 92)); +} + +#[test] +fn once_cell_get_unchecked() { + let c = OnceCell::new(); + c.set(92).unwrap(); + unsafe { + assert_eq!(c.get_unchecked(), &92); + } +} + +#[test] +fn once_cell_drop() { + static DROP_CNT: AtomicUsize = AtomicUsize::new(0); + struct Dropper; + impl Drop for Dropper { + fn drop(&mut self) { + DROP_CNT.fetch_add(1, SeqCst); + } + } + + let x = OnceCell::new(); + scope(|s| { + s.spawn(|| { + x.get_or_init(|| Dropper); + assert_eq!(DROP_CNT.load(SeqCst), 0); + drop(x); + }); + }); + assert_eq!(DROP_CNT.load(SeqCst), 1); +} + +#[test] +fn once_cell_drop_empty() { + let x = OnceCell::::new(); + drop(x); +} + +#[test] +fn clone() { + let s = OnceCell::new(); + let c = s.clone(); + assert!(c.get().is_none()); + + s.set("hello".to_string()).unwrap(); + let c = s.clone(); + assert_eq!(c.get().map(String::as_str), Some("hello")); +} + +#[test] +fn get_or_try_init() { + let cell: OnceCell = OnceCell::new(); + assert!(cell.get().is_none()); + + let res = std::panic::catch_unwind(|| cell.get_or_try_init(|| -> Result<_, ()> { panic!() })); + assert!(res.is_err()); + assert!(cell.get().is_none()); + + assert_eq!(cell.get_or_try_init(|| Err(())), Err(())); + + assert_eq!(cell.get_or_try_init(|| Ok::<_, ()>("hello".to_string())), Ok(&"hello".to_string())); + assert_eq!(cell.get(), Some(&"hello".to_string())); +} + +#[cfg(feature = "std")] +#[test] +fn wait() { + let cell: OnceCell = OnceCell::new(); + scope(|s| { + s.spawn(|| cell.set("hello".to_string())); + let greeting = cell.wait(); + assert_eq!(greeting, "hello") + }); +} + +#[cfg(feature = "std")] +#[test] +fn get_or_init_stress() { + let n_threads = if cfg!(miri) { 30 } else { 1_000 }; + let n_cells = if cfg!(miri) { 30 } else { 1_000 }; + let cells: Vec<_> = std::iter::repeat_with(|| (Barrier::new(n_threads), OnceCell::new())) + .take(n_cells) + .collect(); + scope(|s| { + for t in 0..n_threads { + let cells = &cells; + s.spawn(move || { + for (i, (b, s)) in cells.iter().enumerate() { + b.wait(); + let j = if t % 2 == 0 { s.wait() } else { s.get_or_init(|| i) }; + assert_eq!(*j, i); + } + }); + } + }); +} + +#[test] +fn from_impl() { + assert_eq!(OnceCell::from("value").get(), Some(&"value")); + assert_ne!(OnceCell::from("foo").get(), Some(&"bar")); +} + +#[test] +fn partialeq_impl() { + assert!(OnceCell::from("value") == OnceCell::from("value")); + assert!(OnceCell::from("foo") != OnceCell::from("bar")); + + assert!(OnceCell::::new() == OnceCell::new()); + assert!(OnceCell::::new() != OnceCell::from("value".to_owned())); +} + +#[test] +fn into_inner() { + let cell: OnceCell = OnceCell::new(); + assert_eq!(cell.into_inner(), None); + let cell = OnceCell::new(); + cell.set("hello".to_string()).unwrap(); + assert_eq!(cell.into_inner(), Some("hello".to_string())); +} + +#[test] +fn debug_impl() { + let cell = OnceCell::new(); + assert_eq!(format!("{:#?}", cell), "OnceCell(Uninit)"); + cell.set(vec!["hello", "world"]).unwrap(); + assert_eq!( + format!("{:#?}", cell), + r#"OnceCell( + [ + "hello", + "world", + ], +)"# + ); +} + +#[test] +#[cfg_attr(miri, ignore)] // miri doesn't support processes +#[cfg(feature = "std")] +fn reentrant_init() { + let examples_dir = { + let mut exe = std::env::current_exe().unwrap(); + exe.pop(); + exe.pop(); + exe.push("examples"); + exe + }; + let bin = examples_dir + .join("reentrant_init_deadlocks") + .with_extension(std::env::consts::EXE_EXTENSION); + let mut guard = Guard { child: std::process::Command::new(bin).spawn().unwrap() }; + std::thread::sleep(std::time::Duration::from_secs(2)); + let status = guard.child.try_wait().unwrap(); + assert!(status.is_none()); + + struct Guard { + child: std::process::Child, + } + + impl Drop for Guard { + fn drop(&mut self) { + let _ = self.child.kill(); + } + } +} + +#[cfg(not(feature = "std"))] +#[test] +#[should_panic(expected = "reentrant init")] +fn reentrant_init() { + let x: OnceCell> = OnceCell::new(); + let dangling_ref: Cell> = Cell::new(None); + x.get_or_init(|| { + let r = x.get_or_init(|| Box::new(92)); + dangling_ref.set(Some(r)); + Box::new(62) + }); + eprintln!("use after free: {:?}", dangling_ref.get().unwrap()); +} + +#[test] +fn eval_once_macro() { + macro_rules! eval_once { + (|| -> $ty:ty { + $($body:tt)* + }) => {{ + static ONCE_CELL: OnceCell<$ty> = OnceCell::new(); + fn init() -> $ty { + $($body)* + } + ONCE_CELL.get_or_init(init) + }}; + } + + let fib: &'static Vec = eval_once! { + || -> Vec { + let mut res = vec![1, 1]; + for i in 0..10 { + let next = res[i] + res[i + 1]; + res.push(next); + } + res + } + }; + assert_eq!(fib[5], 8) +} + +#[test] +fn once_cell_does_not_leak_partially_constructed_boxes() { + let n_tries = if cfg!(miri) { 10 } else { 100 }; + let n_readers = 10; + let n_writers = 3; + const MSG: &str = "Hello, World"; + + for _ in 0..n_tries { + let cell: OnceCell = OnceCell::new(); + scope(|scope| { + for _ in 0..n_readers { + scope.spawn(|| loop { + if let Some(msg) = cell.get() { + assert_eq!(msg, MSG); + break; + } + }); + } + for _ in 0..n_writers { + let _ = scope.spawn(|| cell.set(MSG.to_owned())); + } + }); + } +} + +#[cfg(feature = "std")] +#[test] +fn get_does_not_block() { + let cell = OnceCell::new(); + let barrier = Barrier::new(2); + scope(|scope| { + scope.spawn(|| { + cell.get_or_init(|| { + barrier.wait(); + barrier.wait(); + "hello".to_string() + }); + }); + barrier.wait(); + assert_eq!(cell.get(), None); + barrier.wait(); + }); + assert_eq!(cell.get(), Some(&"hello".to_string())); +} + +#[test] +// https://github.com/rust-lang/rust/issues/34761#issuecomment-256320669 +fn arrrrrrrrrrrrrrrrrrrrrr() { + let cell = OnceCell::new(); + { + let s = String::new(); + cell.set(&s).unwrap(); + } +} + +#[test] +fn once_cell_is_sync_send() { + fn assert_traits() {} + assert_traits::>(); + assert_traits::>(); +} diff --git a/vendor/once_cell/tests/it/unsync_lazy.rs b/vendor/once_cell/tests/it/unsync_lazy.rs new file mode 100644 index 0000000..0c308ca --- /dev/null +++ b/vendor/once_cell/tests/it/unsync_lazy.rs @@ -0,0 +1,134 @@ +use core::{ + cell::Cell, + sync::atomic::{AtomicUsize, Ordering::SeqCst}, +}; + +use once_cell::unsync::Lazy; + +#[test] +fn lazy_new() { + let called = Cell::new(0); + let x = Lazy::new(|| { + called.set(called.get() + 1); + 92 + }); + + assert_eq!(called.get(), 0); + + let y = *x - 30; + assert_eq!(y, 62); + assert_eq!(called.get(), 1); + + let y = *x - 30; + assert_eq!(y, 62); + assert_eq!(called.get(), 1); +} + +#[test] +fn lazy_deref_mut() { + let called = Cell::new(0); + let mut x = Lazy::new(|| { + called.set(called.get() + 1); + 92 + }); + + assert_eq!(called.get(), 0); + + let y = *x - 30; + assert_eq!(y, 62); + assert_eq!(called.get(), 1); + + *x /= 2; + assert_eq!(*x, 46); + assert_eq!(called.get(), 1); +} + +#[test] +fn lazy_force_mut() { + let called = Cell::new(0); + let mut x = Lazy::new(|| { + called.set(called.get() + 1); + 92 + }); + assert_eq!(called.get(), 0); + let v = Lazy::force_mut(&mut x); + assert_eq!(called.get(), 1); + + *v /= 2; + assert_eq!(*x, 46); + assert_eq!(called.get(), 1); +} + +#[test] +fn lazy_get_mut() { + let called = Cell::new(0); + let mut x: Lazy = Lazy::new(|| { + called.set(called.get() + 1); + 92 + }); + + assert_eq!(called.get(), 0); + assert_eq!(*x, 92); + + let mut_ref: &mut u32 = Lazy::get_mut(&mut x).unwrap(); + assert_eq!(called.get(), 1); + + *mut_ref /= 2; + assert_eq!(*x, 46); + assert_eq!(called.get(), 1); +} + +#[test] +fn lazy_default() { + static CALLED: AtomicUsize = AtomicUsize::new(0); + + struct Foo(u8); + impl Default for Foo { + fn default() -> Self { + CALLED.fetch_add(1, SeqCst); + Foo(42) + } + } + + let lazy: Lazy> = <_>::default(); + + assert_eq!(CALLED.load(SeqCst), 0); + + assert_eq!(lazy.lock().unwrap().0, 42); + assert_eq!(CALLED.load(SeqCst), 1); + + lazy.lock().unwrap().0 = 21; + + assert_eq!(lazy.lock().unwrap().0, 21); + assert_eq!(CALLED.load(SeqCst), 1); +} + +#[test] +fn lazy_into_value() { + let l: Lazy = Lazy::new(|| panic!()); + assert!(matches!(Lazy::into_value(l), Err(_))); + let l = Lazy::new(|| -> i32 { 92 }); + Lazy::force(&l); + assert!(matches!(Lazy::into_value(l), Ok(92))); +} + +#[test] +#[cfg(feature = "std")] +fn lazy_poisoning() { + let x: Lazy = Lazy::new(|| panic!("kaboom")); + for _ in 0..2 { + let res = std::panic::catch_unwind(|| x.len()); + assert!(res.is_err()); + } +} + +#[test] +// https://github.com/rust-lang/rust/issues/34761#issuecomment-256320669 +fn arrrrrrrrrrrrrrrrrrrrrr() { + let lazy: Lazy<&String, _>; + { + let s = String::new(); + lazy = Lazy::new(|| &s); + _ = *lazy; + } +} diff --git a/vendor/once_cell/tests/it/unsync_once_cell.rs b/vendor/once_cell/tests/it/unsync_once_cell.rs new file mode 100644 index 0000000..124cc3e --- /dev/null +++ b/vendor/once_cell/tests/it/unsync_once_cell.rs @@ -0,0 +1,154 @@ +use core::{ + cell::Cell, + sync::atomic::{AtomicUsize, Ordering::SeqCst}, +}; + +use once_cell::unsync::OnceCell; + +#[test] +fn once_cell() { + let c = OnceCell::new(); + assert!(c.get().is_none()); + c.get_or_init(|| 92); + assert_eq!(c.get(), Some(&92)); + + c.get_or_init(|| panic!("Kabom!")); + assert_eq!(c.get(), Some(&92)); +} + +#[test] +fn once_cell_with_value() { + const CELL: OnceCell = OnceCell::with_value(12); + let cell = CELL; + assert_eq!(cell.get(), Some(&12)); +} + +#[test] +fn once_cell_get_mut() { + let mut c = OnceCell::new(); + assert!(c.get_mut().is_none()); + c.set(90).unwrap(); + *c.get_mut().unwrap() += 2; + assert_eq!(c.get_mut(), Some(&mut 92)); +} + +#[test] +fn once_cell_drop() { + static DROP_CNT: AtomicUsize = AtomicUsize::new(0); + struct Dropper; + impl Drop for Dropper { + fn drop(&mut self) { + DROP_CNT.fetch_add(1, SeqCst); + } + } + + let x = OnceCell::new(); + x.get_or_init(|| Dropper); + assert_eq!(DROP_CNT.load(SeqCst), 0); + drop(x); + assert_eq!(DROP_CNT.load(SeqCst), 1); +} + +#[test] +fn once_cell_drop_empty() { + let x = OnceCell::::new(); + drop(x); +} + +#[test] +fn clone() { + let s = OnceCell::new(); + let c = s.clone(); + assert!(c.get().is_none()); + + s.set("hello".to_string()).unwrap(); + let c = s.clone(); + assert_eq!(c.get().map(String::as_str), Some("hello")); +} + +#[test] +fn get_or_try_init() { + let cell: OnceCell = OnceCell::new(); + assert!(cell.get().is_none()); + + let res = std::panic::catch_unwind(|| cell.get_or_try_init(|| -> Result<_, ()> { panic!() })); + assert!(res.is_err()); + assert!(cell.get().is_none()); + + assert_eq!(cell.get_or_try_init(|| Err(())), Err(())); + + assert_eq!(cell.get_or_try_init(|| Ok::<_, ()>("hello".to_string())), Ok(&"hello".to_string())); + assert_eq!(cell.get(), Some(&"hello".to_string())); +} + +#[test] +fn from_impl() { + assert_eq!(OnceCell::from("value").get(), Some(&"value")); + assert_ne!(OnceCell::from("foo").get(), Some(&"bar")); +} + +#[test] +fn partialeq_impl() { + assert!(OnceCell::from("value") == OnceCell::from("value")); + assert!(OnceCell::from("foo") != OnceCell::from("bar")); + + assert!(OnceCell::::new() == OnceCell::new()); + assert!(OnceCell::::new() != OnceCell::from("value".to_owned())); +} + +#[test] +fn into_inner() { + let cell: OnceCell = OnceCell::new(); + assert_eq!(cell.into_inner(), None); + let cell = OnceCell::new(); + cell.set("hello".to_string()).unwrap(); + assert_eq!(cell.into_inner(), Some("hello".to_string())); +} + +#[test] +fn debug_impl() { + let cell = OnceCell::new(); + assert_eq!(format!("{:#?}", cell), "OnceCell(Uninit)"); + cell.set(vec!["hello", "world"]).unwrap(); + assert_eq!( + format!("{:#?}", cell), + r#"OnceCell( + [ + "hello", + "world", + ], +)"# + ); +} + +#[test] +#[should_panic(expected = "reentrant init")] +fn reentrant_init() { + let x: OnceCell> = OnceCell::new(); + let dangling_ref: Cell> = Cell::new(None); + x.get_or_init(|| { + let r = x.get_or_init(|| Box::new(92)); + dangling_ref.set(Some(r)); + Box::new(62) + }); + eprintln!("use after free: {:?}", dangling_ref.get().unwrap()); +} + +#[test] +fn aliasing_in_get() { + let x = OnceCell::new(); + x.set(42).unwrap(); + let at_x = x.get().unwrap(); // --- (shared) borrow of inner `Option` --+ + let _ = x.set(27); // <-- temporary (unique) borrow of inner `Option` | + println!("{}", at_x); // <------- up until here ---------------------------+ +} + +#[test] +// https://github.com/rust-lang/rust/issues/34761#issuecomment-256320669 +fn arrrrrrrrrrrrrrrrrrrrrr() { + let cell = OnceCell::new(); + { + let s = String::new(); + cell.set(&s).unwrap(); + } +} diff --git a/vendor/openssl-macros/.cargo-checksum.json b/vendor/openssl-macros/.cargo-checksum.json new file mode 100644 index 0000000..8d99014 --- /dev/null +++ b/vendor/openssl-macros/.cargo-checksum.json @@ -0,0 +1 @@ +{"files":{"Cargo.toml":"a0f4f5f613ead670c0512bf5f42c0426c8c3ab119f3737c6119190a5a34b657d","LICENSE-APACHE":"c6596eb7be8581c18be736c846fb9173b69eccf6ef94c5135893ec56bd92ba08","LICENSE-MIT":"ea5ab440900ab271811d5c2dc02a9de6e03a6956ac5727e85c11d76df5883d30","src/lib.rs":"a53de10a52f0870e854ed7575d35eba46165f9eaf9f69d1abfff141d2e2aaf33"},"package":"a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c"} \ No newline at end of file diff --git a/vendor/openssl-macros/Cargo.toml b/vendor/openssl-macros/Cargo.toml new file mode 100644 index 0000000..5dac6cb --- /dev/null +++ b/vendor/openssl-macros/Cargo.toml @@ -0,0 +1,30 @@ +# 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] +edition = "2018" +name = "openssl-macros" +version = "0.1.1" +description = "Internal macros used by the openssl crate." +license = "MIT/Apache-2.0" + +[lib] +proc-macro = true + +[dependencies.proc-macro2] +version = "1" + +[dependencies.quote] +version = "1" + +[dependencies.syn] +version = "2" +features = ["full"] diff --git a/vendor/openssl-macros/LICENSE-APACHE b/vendor/openssl-macros/LICENSE-APACHE new file mode 100644 index 0000000..8f71f43 --- /dev/null +++ b/vendor/openssl-macros/LICENSE-APACHE @@ -0,0 +1,202 @@ + 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/openssl-macros/LICENSE-MIT b/vendor/openssl-macros/LICENSE-MIT new file mode 100644 index 0000000..743bbf8 --- /dev/null +++ b/vendor/openssl-macros/LICENSE-MIT @@ -0,0 +1,19 @@ +Copyright (c) 2022 Steven Fackler + +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/openssl-macros/src/lib.rs b/vendor/openssl-macros/src/lib.rs new file mode 100644 index 0000000..99db988 --- /dev/null +++ b/vendor/openssl-macros/src/lib.rs @@ -0,0 +1,32 @@ +#![allow(clippy::uninlined_format_args)] + +use proc_macro::TokenStream; +use proc_macro2::Ident; +use quote::quote; +use syn::{parse_macro_input, ItemFn}; + +#[proc_macro_attribute] +pub fn corresponds(attr: TokenStream, item: TokenStream) -> TokenStream { + let function = parse_macro_input!(attr as Ident); + let item = parse_macro_input!(item as ItemFn); + + let function = function.to_string(); + let line = format!( + "This corresponds to [`{0}`](https://www.openssl.org/docs/manmaster/man3/{0}.html).", + function + ); + + let attrs = item.attrs; + let vis = item.vis; + let sig = item.sig; + let block = item.block; + + let out = quote! { + #(#attrs)* + #[doc = ""] + #[doc = #line] + #[doc(alias = #function)] + #vis #sig #block + }; + out.into() +} diff --git a/vendor/openssl-sys/.cargo-checksum.json b/vendor/openssl-sys/.cargo-checksum.json new file mode 100644 index 0000000..d0bd71e --- /dev/null +++ b/vendor/openssl-sys/.cargo-checksum.json @@ -0,0 +1 @@ +{"files":{"CHANGELOG.md":"a7c13cbfc4a52bf895378b8fc91bef0e51d6dc9a19ee8c77abdd5354578097e6","Cargo.toml":"ac6f02a5e4ccfbe7a7722ab7dcf54270fc15619a3238d205f562759d9c5cda30","LICENSE-MIT":"378f5840b258e2779c39418f3f2d7b2ba96f1c7917dd6be0713f88305dbda397","README.md":"c5ddde25c2756a1115daaa671fb4297cdc83bf23009c8356ba65b5311d0dd30d","build/cfgs.rs":"3115a57f8a78bb445f58ef8707c654f8c2aec65d0c69e0bb37348cb8ea63a0f4","build/expando.c":"70183c7062c6bf4808376e9e9ef81ee76eface58616bbeea2abf7cd1bbda50ba","build/find_normal.rs":"a0d47c624273b43b4250cff5fa2f9b75e4199ca76897608563b526aedcdf3a16","build/find_vendored.rs":"2d565046018a6855b6fbffa47dc6a28b027704ba234b1a00c1fe336b88e3745f","build/main.rs":"5e3e9861a88383f594ea2e7b76cb5e45c025914dbc8ab4c9427207ec8209b734","build/run_bindgen.rs":"f7dc59ede912e3eb6eefbfb80797c1e16652236b9ceb1eb6a8d00068ed1d5263","src/aes.rs":"e744b2d608216fb98d365dced84e044951939b6e1868ab52226bf0eeaac3c0f5","src/asn1.rs":"88ce843ffd803b9c6768869d179ddc38b8c1225b092272fdfddd9bd1bdcb3c44","src/bio.rs":"1f11cfaf6fe1e12c9541f609b5c2fbdf4e2be8db48ee7fe11b48fb08ea96e364","src/bn.rs":"d1b7578c0ec448e3f8ebe68d5048f2761e46715619d81173a5aa89205b9ba8b2","src/cms.rs":"6dbd69d39da588ece53fabdb3a1e2136602eb24ed26106f59c8b852bce0d1a84","src/crypto.rs":"465609c7ad3dfaff9402412b6b3eb555a02921638cb4c4e0c1820b9517efadf7","src/dtls1.rs":"0477022d5bcf2b7a620c70ece4da08a2958be3eca5a57127c89d79525c692ebd","src/ec.rs":"2fa5d9a495bc80bf583064c2a0671e13051da2e11bfd725accf2f32e1dabfb0b","src/err.rs":"5b0ae1dcccb4e44e9d0c35b03e1b203affb441e8a4854a2485ff558a0c048057","src/evp.rs":"6a3b0b6110adf70ceb3d8a7fb4a908aaef032c8cd1309b4bb3eb5c0883a73e3e","src/handwritten/aes.rs":"31d07045f63d7ea88d1d182487f6cbd42a613119bed32f12affef37bcba26879","src/handwritten/asn1.rs":"218fd7b3f14a374f7585ed665a68a240a4e3f2422b809255770bc0412c5c9924","src/handwritten/bio.rs":"63f04c4925a700f7549c8da9811bbdca85ec56d5ee0e9ace018d483288f15a02","src/handwritten/bn.rs":"ee4370b17e313996f63e0d525caab3271cb6c489ac055b54feb73a207a19f7c2","src/handwritten/cmac.rs":"0ec98c75d6f3d5b097a435a651af101f0e6bde003d0913f62009aff1f51c1f0c","src/handwritten/cms.rs":"2aeff50ca7061f8cba7d0cf9d5da7e17e38909aff0295e5b6301aaa7655c5bfd","src/handwritten/conf.rs":"6c7f8077206c0afcb3d61d8fbfa6203ff0f7099bcd25c6f52773e3403047a285","src/handwritten/crypto.rs":"a4b93d79a1db7afc9213ab9df3d33d50cce05a2ecbc1bd5e71cbc22fdba004b7","src/handwritten/dh.rs":"d062c91151f3687186c642d709957a2dca6440f95200b8b9e4e4a91c8d425008","src/handwritten/dsa.rs":"69da4a548c4bcde09cf1b7ca9d0fb20185fd95d1728638a3efcaf7e4c25fc0e4","src/handwritten/ec.rs":"46ce0880b27ce5d1f7df28ab464cdef144028c9b32477d95d499f1e54ebc44fc","src/handwritten/err.rs":"391a867241db4656411b3da5cc8b30ab23dcc9e928a290f6f215caeeb498403d","src/handwritten/evp.rs":"0c73246afc8d438cdda0b5b171e40c327827c36719692afb5505b52a9c57138b","src/handwritten/hmac.rs":"f31cb39769625adb3bcaf5689a0666801ebea4bf5383077b1e76747451a4d07b","src/handwritten/kdf.rs":"5834da41c95ade70671e26edeed5818029da240293bae8a3aa5e64038bfe02ce","src/handwritten/mod.rs":"e09194245e37ce007a6f7e40e3e730a4cf669e7f12d0367be6bfe0750f238eea","src/handwritten/object.rs":"3a91e4b03fa4f84b5211cddd5a02cc908ccf9ea5f4413d8ef2c503884592f368","src/handwritten/ocsp.rs":"27979cc0439dff61f4c21c68e3d585c0221bd025425ff9bc181c8e870d44f1a7","src/handwritten/params.rs":"dbaf7d40e96da7780ca651a201088c1ba1b4dba237890e86623c215b2ffe21b4","src/handwritten/pem.rs":"1d04f7b600f7422a24e81705d8f9467fdf63a5fa4c61468178da4b71c85ea429","src/handwritten/pkcs12.rs":"65534ca2844850576e08113990be3a3241ac54c486c48ceae77b382a657facc0","src/handwritten/pkcs7.rs":"9614eb04fdaa430f219cb13df116d6874cb8ca7d6a88ff66d0f6f649670221c2","src/handwritten/poly1305.rs":"3c96081a77ea69441d572a4845d2fccb0bb17dc31006bc936f96e8531e6caa4c","src/handwritten/provider.rs":"86d1dbfd1147fcd3bb7ecde52c5b694e7beb599cd5a26754c5af1b179b170f5d","src/handwritten/rand.rs":"fb65a8669ca31664c996aa7d975f02bc01d7b60b192f8e4a3cb31e8aa7e04e25","src/handwritten/rsa.rs":"64c34e9d207bb562514e6b7fa9892777b2fb1df32a49d4672bf4eb33345a6e30","src/handwritten/safestack.rs":"6c39e28565d34efad707d77561d4caa99e3f028fcac3a2ef6fd403a78de1190c","src/handwritten/sha.rs":"7107e2e7e09e9f8b10433b0005a3f4aafead896d7d35949b607dc42b76e24d44","src/handwritten/srtp.rs":"0e9693c840c696cb31774c35c5af55f197de675a6c7e3326a19d7c79958f1e78","src/handwritten/ssl.rs":"1bf896644e103566fce64416c281449a3433962f5dbdcf282a971dcb2fac81d5","src/handwritten/stack.rs":"a139a7291a302d73feea267d756f8245fe0d9ad4453368e9e9f0b48b839e2f55","src/handwritten/thread.rs":"2e626eb74feee9f77ce699b1360160163ff9d7a1dc9c0385eb3f51d2b9d9b062","src/handwritten/tls1.rs":"eccb78cf777389a975ec79d5efa634a44802fc963a6a392888640c1cfb00da11","src/handwritten/types.rs":"1e62caed330c38199b22c64a677733a172546539d12e10dd9f111002342588e2","src/handwritten/x509.rs":"ac2ba51ec3a81af4ca50884d750aa4be0d9c8af2b351a19ce9668068c613b866","src/handwritten/x509_vfy.rs":"553eb0d9a5bf60d63941c17582edd44ba97b5e91c8cf2ed4bff9e4ad7ed9d8dd","src/handwritten/x509v3.rs":"5296c824fbe4fe2c176281395a7f83e916219cf70a1c03d5491ec248d807c747","src/lib.rs":"b9ba62ea8fd44f47a38b02f952f02b415450f6491363201f871ce6b590f50345","src/macros.rs":"aca43e8c1d2eb93d10a53c475d2ac5b1c0f82dea8856f6cfc706a992dec56321","src/obj_mac.rs":"a858271fdb39ed63f4a3ed7d0d3abe760d32145da9d952669acb756508397036","src/ocsp.rs":"63c9ce598f67eb0bb162d4c8d78cb5049c53c4baa41988328b42f7b1bd982ac8","src/pem.rs":"3a0197173331d8b6143d8036a6b121e6b59cac260107d8f42f9b1a1a3426d6fe","src/pkcs7.rs":"f77db0a26e5546d752001701ea43cd55a0c1f7c317425e1f7529ff92590c5076","src/rsa.rs":"8ac9c7a88687ecc8035d56e57c69ba400b3779fd434993c9f53b3e26acd928f0","src/sha.rs":"a5c50aee5fe7a9ba6287129836fce23b9cb35b18de331778d4edbf500b1163b7","src/srtp.rs":"2829d69f64a7c64635340b5e8db48af1d32678b42e7c3b8266c29e26f5b83838","src/ssl.rs":"198663148a119061ba76bef7d90aacade342d0bdb5d953830cc10651f15b78b0","src/ssl3.rs":"9336c816e00847d552dea22587d4ac72ff3cbd469fa5ff750423a19ea11e68eb","src/tls1.rs":"f5a669239bc7981129ef2fdc49f32fed71c57feea4251a35f60f685c6d514ee9","src/types.rs":"e201d386731c7d20ee827acab33d10d0fe8aa65559f3e61efbf465e468fb34eb","src/x509.rs":"3193e9e0de000571468ec7467887ed931fede88de54584f8823a789fdb1edd58","src/x509_vfy.rs":"eb4a8f36623bafc40ccba26ba3eada5c57fd1f4e780bfc0e6210e4d772ce09fc","src/x509v3.rs":"bbaca7754f6a5f587f2213204eeaa10ea1afddc3c837b3cf7a6da915d2413742"},"package":"45abf306cbf99debc8195b66b7346498d7b10c210de50418b5ccd7ceba08c741"} \ No newline at end of file diff --git a/vendor/openssl-sys/CHANGELOG.md b/vendor/openssl-sys/CHANGELOG.md new file mode 100644 index 0000000..641f0d4 --- /dev/null +++ b/vendor/openssl-sys/CHANGELOG.md @@ -0,0 +1,688 @@ +# Change Log + +## [Unreleased] + +## [v0.9.104] - 2024-10-15 + +### Added + +* Added support for LibreSSL 4.0.x. +* Added `EVP_KDF_*` and `EVP_KDF_CTX_*` bindings. +* Added `EVP_DigestSqueeze`. +* Added `OSSL_PARAM_construct_octet_string`. +* Added `OSSL_set_max_threads` and `OSSL_get_max_threads`. + +### Changed + +* `openssl-sys` is now a 2021 edition crate +* Explicitly specify the MSRV in `Cargo.toml` +* Raised the `bindgen` (optional) dependency from 0.65 to 0.69 + +## [v0.9.103] - 2024-07-20 + +### Added + +* Added several functions and constants for datagram `BIO`s. +* Added `EVP_PKEY_set1_DSA`, `EVP_PKEY_set1_DH`, and `EVP_PKEY_set1_EC_KEY`. +* Added several functions related to QUIC support. + +## [v0.9.102] - 2024-03-28 + +### Added + +* Added support for LibreSSL 3.9.x. + +## [v0.9.101] - 2024-02-21 + +### Fixed + +* Fixed a bug where, when building with the `vendored` feature, this crate always needed to be rebuilt. + +## [v0.9.100] - 2024-02-19 + +### Added + +* Added `OSSL_PARAM`, `OSSL_PARAM_construct_uint` , `OSSL_PARAM_construct_end`. +* Added `EVP_PKEY_CTX_set_params` and `EVP_PKEY_CTX_get_params`. +* Added `X509_alias_get0`. +* Added `EVP_default_properties_enable_fips`. + +## [v0.9.99] - 2024-01-19 + +### Added + +* On macOS added Homebrew's `openssl@3.0` to the list of candidates to build against. +* `NID_brainpoolP256r1`, `NID_brainpoolP320r1`, `NID_brainpoolP384r1`, and `NID_brainpoolP512r1` are now available on LibreSSL. + +### Changed + +* `X509_PURPOSE` is now opaque on LibreSSL 3.9.0+. + +## [v0.9.98] - 2023-12-22 + +### Added + +* Added `RAND_priv_bytes`. +* Added `NID_brainpoolP320r1`. + +### Changed + +* `X509_PURPOSE_get0` now returns a `const` pointer on LibreSSL 3.9.0+. +* `X509V3_EXT_add_alias` is removed on LibreSSL 3.9.0+. + +## [v0.9.97] - 2023-12-04 + +### Changed + +* libatomic is no longer dynamically linked for 32 bit ARM targets. + +### Added + +* Added `SSL_read_ex`, `SSL_peek_ex`, and `SSL_write_ex`. + +## [v0.9.96] - 2023-11-22 + +### Changed + +* `EVP_chacha20` is now available on LibreSSL + +### Added + +* Added `EVP_des_ede3_ecb`, `EVP_des_ede3_cfb8`, `EVP_des_ede3_ofb`, `EVP_camellia_128_ofb`, `EVP_camellia_192_ofb`, `EVP_camellia_256_ofb`, `EVP_cast5_ofb`, `EVP_idea_ofb` +* Added `X509_STORE_get1_all_certs` +* Added `SSL_CTRL_GET_PEER_TMP_KEY`, `SSL_CTRL_GET_TMP_KEY`, `SSL_get_peer_tmp_key`, `SSL_get_tmp_key` + +## [v0.9.95] - 2023-11-03 + +### Changed + +* Fixed the availability of `EVP_PKEY_RSA_PSS` on OpenSSL + +### Added + +* Added support for LibreSSL 3.8.x. +* Added `NID_chacha20_poly1305` + +## [v0.9.94] - 2023-11-01 + +### Changed + +* `X509_ALGOR` is now opaque on new LibreSSL releases + +### Added + +* Added support for building with `OPENSSL_NO_SCRYPT` +* Added `EVP_PKEY_RSA_PSS` and `EVP_PKEY_DHX` +* Functions and constants for using HKDF `EVP_PKEY` are now available on LibreSSL. +* Added `SSL_CTX_set_security_level`, `SSL_set_security_level`, `SSL_CTX_get_security_level`, `SSL_get_security_level` +* Added `X509_check_host`, `X509_check_email`, `X509_check_ip`, `X509_check_ip_asc` + +## [v0.9.93] - 2023-09-04 + +### Changed + +* The `vendored` Cargo feature now builds OpenSSL 3.1, as 1.1.1 is reaching its EOL. + +### Added + +* Added support for LibreSSL 3.8.1. + +## [v0.9.92] - 2023-08-27 + +### Added + +* Added `EVP_CIPHER_CTX_copy` +* Expose `EVP_chacha20_poly1305` on LibreSSL +* Added `X509_VERIFY_PARAM_set1_email` + +## [v0.9.91] - 2023-08-06 + +### Added + +* Expose `poly1305_state`, `CRYPTO_poly1305_init`, `CRYPTO_poly1305_update`, and `CRYPTO_poly1305_finish` on BoringSSL and LibreSSL. +* Fix detection of libraries on OpenBSD. +* Added `EC_POINT_point2hex` and `EC_POINT_hex2point`. +* Added `EVP_PKEY_verify_recover_init`, `EVP_PKEY_verify_recover`, and `EVP_PKEY_CTX_set_signature_md`. +* Added `EVP_CIPHER_CTX_FLAG_WRAP_ALLOW` and `EVP_CTX_set_flags`. +* Added `BN_mod_sqrt`. + +## [v0.9.90] - 2023-06-20 + +### Fixed + +* Fixed compilation with BoringSSL when building with the bindgen CLI. + +## [v0.9.89] - 2023-06-20 + +### Fixed + +* Fixed compilation with recent versions of BoringSSL. + +### Added + +* Added support for detecting OpenSSL compiled with `OPENSSL_NO_OCB`. +* Added `EVP_PKEY_SM2` and `NID_sm2`. +* Added `EVP_PKEY_assign_RSA`, `EVP_PKEY_assign_DSA`, `EVP_PKEY_assign_DH`, and `EVP_PKEY_assign_EC_KEY`. +* Added `EC_GROUP_get_asn1_flag`. +* Expose `EC_POINT_get_affine_coordinates` on BoringSSL and LibreSSL. +* Added `EVP_PKEY_derive_set_peer_ex`. + +## [v0.9.88] - 2023-05-30 + +### Added + +* Added support for the LibreSSL 3.8.0. +* Added support for detecting `OPENSSL_NO_RC4`. +* Added `OBJ_dup`. +* Added `ASN1_TYPE_new`, `ASN1_TYPE_set`, `d2i_ASN1_TYPE`, and `i2d_ASN1_TYPE`. +* Added `SSL_bytes_to_cipher_list`, `SSL_CTX_get_num_tickets`, and `SSL_get_num_tickets`. +* Added `GENERAL_NAME_set0_othername`. +* Added `X509_get_pathlen`. + +## [v0.9.87] - 2023-04-24 + +### Added + +* Added `DH_CHECK`. +* Added `CMAC_CTX_new`, `CMAC_CTX_free`, `CMAC_Init`, `CMAC_Update`, `CMAC_Final`, and `CMAC_CTX_copy`. +* Added `EVP_default_properties_is_fips_enabled`. +* Added `X509_get0_subject_key_id`, `X509_get0_authority_key_id`, `X509_get0_authority_issuer`, and `X509_get0_authority_serial`. +* Added `NID_poly1305`. + + +## [v0.9.86] - 2023-04-20 + +### Fixed + +* Fixed BoringSSL support with the latest bindgen release. + +### Added + +* Added bindings for PKCS#7 functions and more X.509 functions. + + +## [v0.9.85] - 2023-04-09 + +### Added + +* Added support for LibreSSL 3.7.x. + +## [v0.9.84] - 2023-04-01 + +### Added + +* Added `ASN1_INTEGER_dup` and `ASN1_INTEGER_cmp`. +* Added `stack_st_X509_NAME_ENTRY`. +* Added `DIST_POINT_NAME`, `DIST_POINT`, `stack_st_DIST_POINT`, `DIST_POINT_free`, and `DIST_POINT_NAME_free`. + +## [v0.9.83] - 2023-03-23 + +### Fixed + +* Fixed version checks for LibreSSL. + +### Added + +* Added `i2d_X509_EXTENSION`. +* Added `GENERAL_NAME_new`. + +## [v0.9.82] - 2023-03-19 + +### Added + +* Added support for LibreSSL 3.7.1. +* Added support for X25519 and Ed25519 on LibreSSL and BoringSSL. + +## [v0.9.81] - 2023-03-14 + +### Fixed + +Fixed builds against OpenSSL built with `no-cast`. + +### Added + +* Added experimental bindgen support for BoringSSL. +* Added `X509_VERIFY_PARAM_set_auth_level`, `X509_VERIFY_PARAM_get_auth_level`, and `X509_VERIFY_PARAM_set_purpose`. +* Added `X509_PURPOSE_*` consts. +* Added `X509_NAME_add_entry`. +* Added `X509_load_crl_file`. +* Added `SSL_set_cipher_list`, `SSL_set_ssl_method`, `SSL_use_PrivateKey_file`, `SSL_use_PrivateKey`, `SSL_use_certificate`, `SSL_use_certificate_chain_file`, `SSL_set_client_CA_list`, `SSL_add_client_CA`, and `SSL_set0_verify_cert_store`. +* Added `X509_PURPOSE`, `X509_STORE_set_purpose`, and `X509_STORE_set_trust`. +* Added `SSL_CTX_set_num_tickets`, `SSL_set_num_tickets`, `SSL_CTX_get_num_tickets`, and `SSL_get_num_tickets`. +* Added `CMS_verify`. + +### Removed + +* Removed an unnecessary link to libatomic for 32-bit android targets. + +## [v0.9.80] - 2022-12-20 + +### Fixed + +* Added `NO_DEPRECATED_3_0` cfg checks for more APIs. + +### Added + +* Added support for LibreSSL 3.7.0. +* Added `SSL_CTRL_CHAIN_CERT` and `SSL_add0_chain_cert`. +* Added `EVP_PKEY_get_security_bits` and `EVP_PKEY_security_bits`. +* Added `OSSL_PROVIDER_set_default_search_path`. + +## [v0.9.79] - 2022-12-06 + +### Added + +* Added `EVP_CIPHER_CTX_num`. +* Added `X509_LOOKUP_file` and `X509_load_cert_file`. + +## [v0.9.78] - 2022-11-23 + +### Added + +* Added support for LibreSSL 3.6.x. +* Added `NID_brainpoolP256r1`, `NID_brainpoolP384r1`, and `NID_brainpool512r1`. +* Added `EVP_camellia_128_cfb128`, `EVP_camellia_128_ecb`, `EVP_camellia_192_cfb128`, `EVP_camellia_192_ecb`, + `EVP_camellia_256_cfb128`, and `EVP_camellia_256_ecb`. +* Added `EVP_cast5_cfb64` and `EVP_cast5_ecb`. +* Added `EVP_idea_cfb64` and `EVP_idea_ecb`. +* Added `DSA_SIG`, `d2i_DSA_SIG`, `i2d_DSA_SIG`, `DSA_SIG_new`, `DSA_SIG_free`, `DSA_SIG_get0`, and `DSA_SIG_set0`. +* Added `X509_STORE_set1_param`, `X509_VERIFY_PARAM_new`, `X509_VERIFY_PARAM_set_time`, and + `X509_VERIFY_PARAM_set_depth`. + +## [v0.9.77] - 2022-10-22 + +### Added + +* Added support for LibreSSL 3.6.0 +* Added `assume_init`. + +## [v0.9.76] - 2022-09-26 + +### Added + +* Added `SSL_get_psk_identity_hint` and `SSL_get_psk_identity`. +* Added SHA-3 NID constants. +* Added `SSL_OP_PRIORITIZE_CHACHA`. +* Added `X509_REQ_print`. +* Added `EVP_MD_CTX_size` and `EVP_MD_CTX_get_size` +* Added `EVP_MD_CTX_reset`. +* Added experimental, unstable support for BoringSSL. + +### Fixed + +* Fixed the deprecation note on `SSL_CTX_set_alpn_select_cb`. + +## [v0.9.75] - 2022-07-09 + +### Added + +* Added SM4 bindings. +* Added `EC_GROUP_set_generator` and `EC_POINT_set_affine_coordinates_GFp`. + +## [v0.9.74] - 2022-06-01 + +### Added + +* Added `EVP_MD_block_size`. +* Added `X509V3_EXT_add_alias`. +* Added `X509_V_ERR_INVALID_CA` back when building against OpenSSL 3.0. + +## [v0.9.73] - 2022-05-02 + +### Added + +* Added support for installations that place libraries in `$OPENSSL_DIR/lib64` in addition to `$OPENSSL_DIR/lib`. +* Added `X509_issuer_name_hash`. +* Added `ASN1_string_set`. +* Added `X509_CRL_dup`, `X509_REQ_dup`, `X509_NAME_dup`, and `X509_dup`. +* Added `X509_print`. +* Added support for LibreSSL 3.5.x. + +## [v0.9.72] - 2021-12-11 + +### Changed + +* Temporarily downgraded the vendored OpenSSL back to 1.1.1 due to significant performance regressions. We will move + back to 3.0.0 when a future release resolves those issues. + +### Added + +* Added `PKCS12_set_mac`. +* Added `EVP_PKEY_sign_init`, `EVP_PKEY_sign`, `EVP_PKEY_verify_init`, and `EVP_PKEY_verify`. +* Added support for LibreSSL 3.4.x. + +## [v0.9.71] + +### Fixed + +* Fixed linkage to static OpenSSL 3.0.0 libraries on some 32 bit Android targets. + +### Added + +* Added support for LibreSSL 3.4.1. +* Added `SSL_get_extms_support` and `SSL_CTRL_GET_EXTMS_SUPPORT`. +* Added `OBJ_create`. +* Added `EVP_CIPHER_CTX_get0_cipher`, `EVP_CIPHER_CTX_get_block_size`, `EVP_CIPHER_CTX_get_key_length`, + `EVP_CIPHER_CTX_get_iv_length`, and `EVP_CIPHER_CTX_get_tag_length`. +* Added `EVP_CIPHER_free`. +* Added `EVP_CIPHER_CTX_rand_key`. +* Added `OSSL_LIB_CTX_new` and `OSSL_LIB_CTX_free`. +* Added `EVP_CIPHER_fetch`. +* Added `EVP_MD_fetch` and `EVP_MD_free`. +* Added `OPENSSL_malloc` and `OPENSSL_free`. +* Added `EVP_DigestSignUpdate` and `EVP_DigestVerifyUpdate`. + +## [v0.9.70] - 2021-10-31 + +### Fixed + +* Fixed linkage to static 3.0.0 OpenSSL libraries on some 32 bit architectures. + +## [v0.9.69] - 2021-10-31 + +### Changed + +* Upgraded the vendored OpenSSL to 3.0.0. + +### Added + +* Added support for automatic detection of Homebrew `openssl@3` installs. +* Added `EVP_PKEY_Q_keygen` and `EVP_EC_gen`. + +## [v0.9.68] - 2021-10-27 + +### Added + +* Added `BN_bn2binpad`. +* Added `i2d_X509_NAME` and `d2i_X509_NAME`. +* Added `BN_FLG_MALLOCED`, `BN_FLG_STATIC_DATA`, `BN_FLG_CONSTTIME`, and `BN_FLG_SECURE`. +* Added `BN_CTX_secure_new`, `BN_secure_new`, `BN_set_flags`, and `BN_get_flags`. + +## [v0.9.67] - 2021-09-21 + +### Added + +* Added support for LibreSSL 3.4.0 + +## [v0.9.66] - 2021-08-17 + +### Added + +* Added `EVP_seed_cbc`, `EVP_seed_cfb128`, `EVP_seed_ecb`, and `EVP_seed_ofb`. +* Added `OBJ_length` and `OBJ_get0_data`. +* Added `i2d_PKCS8PrivateKey_bio`. + +## [v0.9.65] - 2021-06-21 + +### Fixed + +* Restored the accidentally deleted `PEM_read_bio_X509_CRL` function. + +## [v0.9.64] - 2021-06-18 + +### Added + +* Added support for OpenSSL 3.x.x. +* Added `SSL_peek`. +* Added `ERR_LIB_ASN1` and `ASN1_R_HEADER_TOO_LONG`. +* Added `d2i_X509_bio`. +* Added `OBJ_nid2obj`. +* Added `RAND_add`. +* Added `SSL_CTX_set_post_handshake_auth`. +* Added `COMP_get_type`. +* Added `X509_get_default_cert_file_env`, `X509_get_default_cert_file`, `X509_get_default_cert_dir_env`, and + `X509_get_default_cirt_dir`. + +## [v0.9.63] - 2021-05-06 + +### Added + +* Added support for LibreSSL 3.3.x. + +## [v0.9.62] - 2021-04-28 + +### Added + +* Added support for LibreSSL 3.3.2. +* Added `DH_set0_key`. +* Added `EC_POINT_get_affine_coordinates`. + +## [v0.9.61] - 2021-03-13 + +### Added + +* Added support for automatic detection of OpenSSL installations via pkgsrc and MacPorts on macOS. +* Added various `V_ASN1_*` constants. +* Added `DH_generate_parameters_ex`. +* Added `EC_POINT_is_at_infinity` and `EC_POINT_is_on_curve`. +* Added `EVP_CIPHER_nid`. +* Added `EVP_sm3`. +* Added `NID_*` constants related to SM3. +* Added `PKCS7_get0_signers`. +* Added `EVP_PKEY_CTX_set0_rsa_oaep_label`. +* Added `ACCESS_DESCRIPTION` and `ACCESS_DESCRIPTION_free`. + +## [v0.9.60] - 2020-12-24 + +### Added + +* Added support for the default Homebrew install directory on ARM. +* Added `EVP_PKEY_CTX_set_rsa_oaep_md` and `EVP_PKEY_CTRL_RSA_OAEP_MD`. + +## [v0.9.59] - 2020-12-09 + +### Added + +* Added support for LibreSSL 3.2.x, 3.3.0, and 3.3.1. +* Added `DH_generate_parameters`, `DH_generate_key`, `DH_compute_key`, and `DH_size`. +* Added `NID_X25519`, `NID_X448`, `EVP_PKEY_x25519` and `EVP_PKEY_x448`. +* Added `OBJ_txt2obj`. +* Added `d2i_PKCS7` and `i2d_PKCS7`. +* Added `SRTP_AEAD_AES_128_GCM` and `SRTP_AEAD_AES_256_GCM`. + +## [v0.9.58] - 2020-06-05 + +### Added + +* Added `SSL_set_mtu`. +* Added support for LibreSSL 3.2.0. +* Added `PEM_read_bio_EC_PUBKEY`, `PEM_write_bio_EC_PUBKEY`, `d2i_EC_PUBKEY`, and `i2d_EC_PUBKEY`. +* Added `EVP_PKEY_encrypt_init`, `EVP_PKEY_encrypt`, `EVP_PKEY_decrypt_init`, `EVP_PKEY_decrypt`, + `EVP_PKEY_get_raw_public_key`, `EVP_PKEY_new_raw_public_key`, `EVP_PKEY_get_raw_private_key`, + and `EVP_PKEY_new_raw_private_key`. +* Added `OBJ_sn2nid`. + +## [v0.9.57] - 2020-05-24 + +### Added + +* Added support for LibreSSL 3.1.x. + +## [v0.9.56] - 2020-05-07 + +### Fixed + +* Fixed vendored builds on windows-gnu targets. + +### Added + +* Added support for LibreSSL 3.0.0. + +## [v0.9.55] - 2020-04-07 + +### Fixed + +* Fixed windows-msvc library names when using OpenSSL from vcpkg. + +### Added + +* If the `OPENSSL_NO_VENDOR` environment variable is set, vendoring will not be used even if enabled. +* Added `SSL_CTX_get_verify_mode` and `SSL_get_verify_mode`. +* Added `SSL_is_init_finished`. +* Added `SSL_CTX_set_cert_store`. +* Added `TLS_server_method` and `TLS_client_method`. +* Added `X509_STORE_get0_objects`. +* Added `X509_OBJECT_free`, `X509_OBJECT_get_type`, and `X509_OBJECT_get0_X509`. + +## [v0.9.54] - 2020-01-29 + +### Added + +* Added `BIO_CTRL_DGRAM_QUERY_MTU`. +* Added `EVP_EncryptInit_ex`, `EVP_EncryptFinal_ex`, `EVP_DecryptInit_ex`, and `EVP_DecryptFinal_ex`. +* Added `EVP_md_null`. +* Added `EVP_PKCS82PKEY`. +* Added `PKCS8_PRIV_KEY_INFO`, `d2i_PKCS8_PRIV_KEY_INFO`, and `PKCS8_PRIV_KEY_INFO_free`. +* Added `SSL_OP_NO_RENEGOTIATION`. + +## [v0.9.53] - 2019-11-22 + +### Added + +* Added `ASN1_TIME_diff`. +* Added `EC_GROUP_order_bits`. +* Added `EVP_EncodeBlock` and `EVP_DecodeBlock`. +* Added `SSL_CTRL_SET_GROUPS_LIST`, `SSL_CTRL_SET_SIGALGS_LIST`, `SSL_CTX_set1_groups_list`, and + `SSL_CTX_set1_sigalgs_list`. +* Added `Clone` implementations to `SHA_CTX`, `SHA256_CTX`, and `SHA512_CTX`. + +## [v0.9.52] - 2019-10-19 + +### Added + +* Added support for LibreSSL 3.0.x. + +## [v0.9.51] - 2019-10-02 + +### Added + +* Added support for LibreSSL 3.0.1. + +## [v0.9.50] - 2019-10-02 + +### Added + +* Added `CRYPTO_LOCK_EVP_PKEY`. +* Added `EVP_PKEY_ED25519` and `EVP_PKEY_ED448`. +* Added `EVP_DigestSign` and `EVP_DigestVerify`. +* Added `EVP_PKEY_up_ref`. +* Added `NID_ED25519` and `NID_ED448`. + +## [v0.9.49] - 2019-08-15 + +### Added + +* Added support for LibreSSL 3.0.0. + +## [v0.9.48] - 2019-07-19 + +### Added + +* Added `AES_wrap_key` and `AES_unwrap_key`. +* Added `EC_GROUP_get_cofactor`, `EC_GROUP_get0_generator`, and `EC_POINT_dup`. +* Added `EVP_aes_128_ofb`, `EVP_aes_192_ecb`, `EVP_aes_192_cbc`, `EVP_aes_192_cfb1`, `EVP_aes_192_cfb8`, + `EVP_aes_192_cfb_128`, `EVP_aes_192_ctr`, `EVP_aes_192_ccm`, `EVP_aes_192_gcm`, `EVP_aes_192_ofb`, and + `EVP_aes_256_ofb`. +* Added `PEM_read_bio_CMS` and `PEM_write_bio_CMS`. + +## [v0.9.47] - 2019-05-18 + +### Added + +* Added `SSL_CTX_add_client_CA`. + +## [v0.9.46] - 2019-05-08 + +### Added + +* Added support for the LibreSSL 2.9.x series. + +## [v0.9.45] - 2019-05-03 + +### Fixed + +* Reverted a change to windows-gnu library names that caused regressions. + +## [v0.9.44] - 2019-04-30 + +### Added + +* The `DEP_OPENSSL_VENDORED` environment variable tells downstream build scripts if the vendored feature was enabled. +* Added `EVP_SealInit`, `EVP_SealFinal`, `EVP_EncryptUpdate`, `EVP_OpenInit`, `EVP_OpenFinal`, and `EVP_DecryptUpdate`. +* Added `EVP_PKEY_size`. + +### Fixed + +* Fixed library names when targeting windows-gnu and pkg-config fails. + +## [v0.9.43] - 2019-03-20 + +### Added + +* Added `d2i_CMS_ContentInfo` and `CMS_encrypt`. +* Added `X509_verify` and `X509_REQ_verify`. +* Added `EVP_MD_type` and `EVP_GROUP_get_curve_name`. + +[Unreleased]: https://github.com/sfackler/rust-openssl/compare/openssl-sys-v0.9.104..master +[v0.9.104]: https://github.com/sfackler/rust-openssl/compare/openssl-sys-v0.9.103...openssl-sys-v0.9.104 +[v0.9.103]: https://github.com/sfackler/rust-openssl/compare/openssl-sys-v0.9.102...openssl-sys-v0.9.103 +[v0.9.102]: https://github.com/sfackler/rust-openssl/compare/openssl-sys-v0.9.101...openssl-sys-v0.9.102 +[v0.9.101]: https://github.com/sfackler/rust-openssl/compare/openssl-sys-v0.9.100...openssl-sys-v0.9.101 +[v0.9.100]: https://github.com/sfackler/rust-openssl/compare/openssl-sys-v0.9.99...openssl-sys-v0.9.100 +[v0.9.99]: https://github.com/sfackler/rust-openssl/compare/openssl-sys-v0.9.98...openssl-sys-v0.9.99 +[v0.9.98]: https://github.com/sfackler/rust-openssl/compare/openssl-sys-v0.9.97...openssl-sys-v0.9.98 +[v0.9.97]: https://github.com/sfackler/rust-openssl/compare/openssl-sys-v0.9.96...openssl-sys-v0.9.97 +[v0.9.96]: https://github.com/sfackler/rust-openssl/compare/openssl-sys-v0.9.95...openssl-sys-v0.9.96 +[v0.9.95]: https://github.com/sfackler/rust-openssl/compare/openssl-sys-v0.9.94...openssl-sys-v0.9.95 +[v0.9.94]: https://github.com/sfackler/rust-openssl/compare/openssl-sys-v0.9.93...openssl-sys-v0.9.94 +[v0.9.93]: https://github.com/sfackler/rust-openssl/compare/openssl-sys-v0.9.92...openssl-sys-v0.9.93 +[v0.9.92]: https://github.com/sfackler/rust-openssl/compare/openssl-sys-v0.9.91...openssl-sys-v0.9.92 +[v0.9.91]: https://github.com/sfackler/rust-openssl/compare/openssl-sys-v0.9.90...openssl-sys-v0.9.91 +[v0.9.90]: https://github.com/sfackler/rust-openssl/compare/openssl-sys-v0.9.89...openssl-sys-v0.9.90 +[v0.9.89]: https://github.com/sfackler/rust-openssl/compare/openssl-sys-v0.9.88...openssl-sys-v0.9.89 +[v0.9.88]: https://github.com/sfackler/rust-openssl/compare/openssl-sys-v0.9.87...openssl-sys-v0.9.88 +[v0.9.87]: https://github.com/sfackler/rust-openssl/compare/openssl-sys-v0.9.86...openssl-sys-v0.9.87 +[v0.9.86]: https://github.com/sfackler/rust-openssl/compare/openssl-sys-v0.9.85...openssl-sys-v0.9.86 +[v0.9.85]: https://github.com/sfackler/rust-openssl/compare/openssl-sys-v0.9.84...openssl-sys-v0.9.85 +[v0.9.84]: https://github.com/sfackler/rust-openssl/compare/openssl-sys-v0.9.83...openssl-sys-v0.9.84 +[v0.9.83]: https://github.com/sfackler/rust-openssl/compare/openssl-sys-v0.9.82...openssl-sys-v0.9.83 +[v0.9.82]: https://github.com/sfackler/rust-openssl/compare/openssl-sys-v0.9.81...openssl-sys-v0.9.82 +[v0.9.81]: https://github.com/sfackler/rust-openssl/compare/openssl-sys-v0.9.80...openssl-sys-v0.9.81 +[v0.9.80]: https://github.com/sfackler/rust-openssl/compare/openssl-sys-v0.9.79...openssl-sys-v0.9.80 +[v0.9.79]: https://github.com/sfackler/rust-openssl/compare/openssl-sys-v0.9.78...openssl-sys-v0.9.79 +[v0.9.78]: https://github.com/sfackler/rust-openssl/compare/openssl-sys-v0.9.77...openssl-sys-v0.9.78 +[v0.9.77]: https://github.com/sfackler/rust-openssl/compare/openssl-sys-v0.9.76...openssl-sys-v0.9.77 +[v0.9.76]: https://github.com/sfackler/rust-openssl/compare/openssl-sys-v0.9.75...openssl-sys-v0.9.76 +[v0.9.75]: https://github.com/sfackler/rust-openssl/compare/openssl-sys-v0.9.74...openssl-sys-v0.9.75 +[v0.9.74]: https://github.com/sfackler/rust-openssl/compare/openssl-sys-v0.9.73...openssl-sys-v0.9.74 +[v0.9.73]: https://github.com/sfackler/rust-openssl/compare/openssl-sys-v0.9.72...openssl-sys-v0.9.73 +[v0.9.72]: https://github.com/sfackler/rust-openssl/compare/openssl-sys-v0.9.71...openssl-sys-v0.9.72 +[v0.9.71]: https://github.com/sfackler/rust-openssl/compare/openssl-sys-v0.9.70...openssl-sys-v0.9.71 +[v0.9.70]: https://github.com/sfackler/rust-openssl/compare/openssl-sys-v0.9.69...openssl-sys-v0.9.70 +[v0.9.69]: https://github.com/sfackler/rust-openssl/compare/openssl-sys-v0.9.68...openssl-sys-v0.9.69 +[v0.9.68]: https://github.com/sfackler/rust-openssl/compare/openssl-sys-v0.9.67...openssl-sys-v0.9.68 +[v0.9.67]: https://github.com/sfackler/rust-openssl/compare/openssl-sys-v0.9.66...openssl-sys-v0.9.67 +[v0.9.66]: https://github.com/sfackler/rust-openssl/compare/openssl-sys-v0.9.65...openssl-sys-v0.9.66 +[v0.9.65]: https://github.com/sfackler/rust-openssl/compare/openssl-sys-v0.9.64...openssl-sys-v0.9.65 +[v0.9.64]: https://github.com/sfackler/rust-openssl/compare/openssl-sys-v0.9.63...openssl-sys-v0.9.64 +[v0.9.63]: https://github.com/sfackler/rust-openssl/compare/openssl-sys-v0.9.62...openssl-sys-v0.9.63 +[v0.9.62]: https://github.com/sfackler/rust-openssl/compare/openssl-sys-v0.9.61...openssl-sys-v0.9.62 +[v0.9.61]: https://github.com/sfackler/rust-openssl/compare/openssl-sys-v0.9.60...openssl-sys-v0.9.61 +[v0.9.60]: https://github.com/sfackler/rust-openssl/compare/openssl-sys-v0.9.59...openssl-sys-v0.9.60 +[v0.9.59]: https://github.com/sfackler/rust-openssl/compare/openssl-sys-v0.9.58...openssl-sys-v0.9.59 +[v0.9.58]: https://github.com/sfackler/rust-openssl/compare/openssl-sys-v0.9.57...openssl-sys-v0.9.58 +[v0.9.57]: https://github.com/sfackler/rust-openssl/compare/openssl-sys-v0.9.56...openssl-sys-v0.9.57 +[v0.9.56]: https://github.com/sfackler/rust-openssl/compare/openssl-sys-v0.9.55...openssl-sys-v0.9.56 +[v0.9.55]: https://github.com/sfackler/rust-openssl/compare/openssl-sys-v0.9.54...openssl-sys-v0.9.55 +[v0.9.54]: https://github.com/sfackler/rust-openssl/compare/openssl-sys-v0.9.53...openssl-sys-v0.9.54 +[v0.9.53]: https://github.com/sfackler/rust-openssl/compare/openssl-sys-v0.9.52...openssl-sys-v0.9.53 +[v0.9.52]: https://github.com/sfackler/rust-openssl/compare/openssl-sys-v0.9.51...openssl-sys-v0.9.52 +[v0.9.51]: https://github.com/sfackler/rust-openssl/compare/openssl-sys-v0.9.50...openssl-sys-v0.9.51 +[v0.9.50]: https://github.com/sfackler/rust-openssl/compare/openssl-sys-v0.9.49...openssl-sys-v0.9.50 +[v0.9.49]: https://github.com/sfackler/rust-openssl/compare/openssl-sys-v0.9.48...openssl-sys-v0.9.49 +[v0.9.48]: https://github.com/sfackler/rust-openssl/compare/openssl-sys-v0.9.47...openssl-sys-v0.9.48 +[v0.9.47]: https://github.com/sfackler/rust-openssl/compare/openssl-sys-v0.9.46...openssl-sys-v0.9.47 +[v0.9.46]: https://github.com/sfackler/rust-openssl/compare/openssl-sys-v0.9.45...openssl-sys-v0.9.46 +[v0.9.45]: https://github.com/sfackler/rust-openssl/compare/openssl-sys-v0.9.44...openssl-sys-v0.9.45 +[v0.9.44]: https://github.com/sfackler/rust-openssl/compare/openssl-sys-v0.9.43...openssl-sys-v0.9.44 +[v0.9.43]: https://github.com/sfackler/rust-openssl/compare/openssl-sys-v0.9.42...openssl-sys-v0.9.43 diff --git a/vendor/openssl-sys/Cargo.toml b/vendor/openssl-sys/Cargo.toml new file mode 100644 index 0000000..3241722 --- /dev/null +++ b/vendor/openssl-sys/Cargo.toml @@ -0,0 +1,71 @@ +# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO +# +# When uploading crates to the registry Cargo will automatically +# "normalize" Cargo.toml files for maximal compatibility +# with all versions of Cargo and also rewrite `path` dependencies +# to registry (e.g., crates.io) dependencies. +# +# If you 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 = "2021" +rust-version = "1.63.0" +name = "openssl-sys" +version = "0.9.104" +authors = [ + "Alex Crichton ", + "Steven Fackler ", +] +build = "build/main.rs" +links = "openssl" +autobins = false +autoexamples = false +autotests = false +autobenches = false +description = "FFI bindings to OpenSSL" +readme = "README.md" +categories = [ + "cryptography", + "external-ffi-bindings", +] +license = "MIT" +repository = "https://github.com/sfackler/rust-openssl" + +[package.metadata.pkg-config] +openssl = "1.0.1" + +[lib] +name = "openssl_sys" +path = "src/lib.rs" + +[dependencies.bssl-sys] +version = "0.1.0" +optional = true + +[dependencies.libc] +version = "0.2" + +[build-dependencies.bindgen] +version = "0.69.0" +features = ["experimental"] +optional = true + +[build-dependencies.cc] +version = "1.0.61" + +[build-dependencies.openssl-src] +version = "300.2.0" +features = ["legacy"] +optional = true + +[build-dependencies.pkg-config] +version = "0.3.9" + +[build-dependencies.vcpkg] +version = "0.2.8" + +[features] +unstable_boringssl = ["bssl-sys"] +vendored = ["openssl-src"] diff --git a/vendor/openssl-sys/LICENSE-MIT b/vendor/openssl-sys/LICENSE-MIT new file mode 100644 index 0000000..39e0ed6 --- /dev/null +++ b/vendor/openssl-sys/LICENSE-MIT @@ -0,0 +1,25 @@ +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/openssl-sys/README.md b/vendor/openssl-sys/README.md new file mode 100644 index 0000000..50c6d57 --- /dev/null +++ b/vendor/openssl-sys/README.md @@ -0,0 +1,22 @@ +# rust-openssl + +[![crates.io](https://img.shields.io/crates/v/openssl.svg)](https://crates.io/crates/openssl) + +OpenSSL bindings for the Rust programming language. + +[Documentation](https://docs.rs/openssl). + +## Release Support + +The current supported release of `openssl` is 0.10 and `openssl-sys` is 0.9. + +New major versions will be published at most once per year. After a new +release, the previous major version will be partially supported with bug +fixes for 3 months, after which support will be dropped entirely. + +### Contribution + +Unless you explicitly state otherwise, any contribution intentionally +submitted for inclusion in the work by you, as defined in the Apache-2.0 +license, shall be dual licensed under the terms of both the Apache License, +Version 2.0 and the MIT license without any additional terms or conditions. diff --git a/vendor/openssl-sys/build/cfgs.rs b/vendor/openssl-sys/build/cfgs.rs new file mode 100644 index 0000000..cd03888 --- /dev/null +++ b/vendor/openssl-sys/build/cfgs.rs @@ -0,0 +1,125 @@ +#[allow(clippy::unusual_byte_groupings)] +pub fn get(openssl_version: Option, libressl_version: Option) -> Vec<&'static str> { + let mut cfgs = vec![]; + + if let Some(libressl_version) = libressl_version { + cfgs.push("libressl"); + + if libressl_version >= 0x2_05_01_00_0 { + cfgs.push("libressl251"); + } + if libressl_version >= 0x2_05_02_00_0 { + cfgs.push("libressl252"); + } + if libressl_version >= 0x2_06_01_00_0 { + cfgs.push("libressl261"); + } + if libressl_version >= 0x2_07_00_00_0 { + cfgs.push("libressl270"); + } + if libressl_version >= 0x2_07_01_00_0 { + cfgs.push("libressl271"); + } + if libressl_version >= 0x2_07_03_00_0 { + cfgs.push("libressl273"); + } + if libressl_version >= 0x2_08_00_00_0 { + cfgs.push("libressl280"); + } + if libressl_version >= 0x2_08_01_00_0 { + cfgs.push("libressl281"); + } + if libressl_version >= 0x2_09_01_00_0 { + cfgs.push("libressl291"); + } + if libressl_version >= 0x3_01_00_00_0 { + cfgs.push("libressl310"); + } + if libressl_version >= 0x3_02_01_00_0 { + cfgs.push("libressl321"); + } + if libressl_version >= 0x3_03_02_00_0 { + cfgs.push("libressl332"); + } + if libressl_version >= 0x3_04_00_00_0 { + cfgs.push("libressl340"); + } + if libressl_version >= 0x3_05_00_00_0 { + cfgs.push("libressl350"); + } + if libressl_version >= 0x3_06_00_00_0 { + cfgs.push("libressl360"); + } + if libressl_version >= 0x3_07_00_00_0 { + cfgs.push("libressl370"); + } + if libressl_version >= 0x3_08_00_00_0 { + cfgs.push("libressl380"); + } + if libressl_version >= 0x3_08_01_00_0 { + cfgs.push("libressl381"); + } + if libressl_version >= 0x3_08_02_00_0 { + cfgs.push("libressl382"); + } + if libressl_version >= 0x3_09_00_00_0 { + cfgs.push("libressl390"); + } + if libressl_version >= 0x4_00_00_00_0 { + cfgs.push("libressl400"); + } + } else { + let openssl_version = openssl_version.unwrap(); + + if openssl_version >= 0x3_04_00_00_0 { + cfgs.push("ossl340"); + } + if openssl_version >= 0x3_03_00_00_0 { + cfgs.push("ossl330"); + } + if openssl_version >= 0x3_02_00_00_0 { + cfgs.push("ossl320"); + } + if openssl_version >= 0x3_00_00_00_0 { + cfgs.push("ossl300"); + } + if openssl_version >= 0x1_00_01_00_0 { + cfgs.push("ossl101"); + } + if openssl_version >= 0x1_00_02_00_0 { + cfgs.push("ossl102"); + } + if openssl_version >= 0x1_00_02_06_0 { + cfgs.push("ossl102f"); + } + if openssl_version >= 0x1_00_02_08_0 { + cfgs.push("ossl102h"); + } + if openssl_version >= 0x1_01_00_00_0 { + cfgs.push("ossl110"); + } + if openssl_version >= 0x1_01_00_06_0 { + cfgs.push("ossl110f"); + } + if openssl_version >= 0x1_01_00_07_0 { + cfgs.push("ossl110g"); + } + if openssl_version >= 0x1_01_00_08_0 { + cfgs.push("ossl110h"); + } + if openssl_version >= 0x1_01_01_00_0 { + cfgs.push("ossl111"); + } + if openssl_version >= 0x1_01_01_02_0 { + cfgs.push("ossl111b"); + } + if openssl_version >= 0x1_01_01_03_0 { + cfgs.push("ossl111c"); + } + if openssl_version >= 0x1_01_01_04_0 { + cfgs.push("ossl111d"); + } + } + + cfgs +} diff --git a/vendor/openssl-sys/build/expando.c b/vendor/openssl-sys/build/expando.c new file mode 100644 index 0000000..e171621 --- /dev/null +++ b/vendor/openssl-sys/build/expando.c @@ -0,0 +1,140 @@ +#include +#include + +#define VERSION2(n, v) RUST_VERSION_##n##_##v +#define VERSION(n, v) VERSION2(n, v) + +#define NEW_VERSION2(a, b, c) RUST_VERSION_NEW_OPENSSL_##a##_##b##_##c +#define NEW_VERSION(a, b, c) NEW_VERSION2(a, b, c) + +#ifdef LIBRESSL_VERSION_NUMBER +VERSION(LIBRESSL, LIBRESSL_VERSION_NUMBER) +#elif defined OPENSSL_VERSION_MAJOR +NEW_VERSION(OPENSSL_VERSION_MAJOR, OPENSSL_VERSION_MINOR, OPENSSL_VERSION_PATCH) +#else +VERSION(OPENSSL, OPENSSL_VERSION_NUMBER) +#endif + +#ifdef OPENSSL_IS_BORINGSSL +RUST_OPENSSL_IS_BORINGSSL +#endif + +#ifdef OPENSSL_NO_BF +RUST_CONF_OPENSSL_NO_BF +#endif + +#ifdef OPENSSL_NO_BUF_FREELISTS +RUST_CONF_OPENSSL_NO_BUF_FREELISTS +#endif + +#ifdef OPENSSL_NO_CHACHA +RUST_CONF_OPENSSL_NO_CHACHA +#endif + +#ifdef OPENSSL_NO_IDEA +RUST_CONF_OPENSSL_NO_IDEA +#endif + +#ifdef OPENSSL_NO_CAMELLIA +RUST_CONF_OPENSSL_NO_CAMELLIA +#endif + +#ifdef OPENSSL_NO_CAST +RUST_CONF_OPENSSL_NO_CAST +#endif + +#ifdef OPENSSL_NO_CMS +RUST_CONF_OPENSSL_NO_CMS +#endif + +#ifdef OPENSSL_NO_COMP +RUST_CONF_OPENSSL_NO_COMP +#endif + +#ifdef OPENSSL_NO_EC +RUST_CONF_OPENSSL_NO_EC +#endif + +#ifdef OPENSSL_NO_EC2M +RUST_CONF_OPENSSL_NO_EC2M +#endif + +#ifdef OPENSSL_NO_ENGINE +RUST_CONF_OPENSSL_NO_ENGINE +#endif + +#ifdef OPENSSL_NO_KRB5 +RUST_CONF_OPENSSL_NO_KRB5 +#endif + +#ifdef OPENSSL_NO_NEXTPROTONEG +RUST_CONF_OPENSSL_NO_NEXTPROTONEG +#endif + +#ifdef OPENSSL_NO_OCSP +RUST_CONF_OPENSSL_NO_OCSP +#endif + +#ifdef OPENSSL_NO_OCB +RUST_CONF_OPENSSL_NO_OCB +#endif + +#ifdef OPENSSL_NO_PSK +RUST_CONF_OPENSSL_NO_PSK +#endif + +#ifdef OPENSSL_NO_RC4 +RUST_CONF_OPENSSL_NO_RC4 +#endif + +#ifdef OPENSSL_NO_RFC3779 +RUST_CONF_OPENSSL_NO_RFC3779 +#endif + +#ifdef OPENSSL_NO_RMD160 +RUST_CONF_OPENSSL_NO_RMD160 +#endif + +#ifdef OPENSSL_NO_SHA +RUST_CONF_OPENSSL_NO_SHA +#endif + +#ifdef OPENSSL_NO_SRP +RUST_CONF_OPENSSL_NO_SRP +#endif + +#ifdef OPENSSL_NO_SSL3_METHOD +RUST_CONF_OPENSSL_NO_SSL3_METHOD +#endif + +#ifdef OPENSSL_NO_TLSEXT +RUST_CONF_OPENSSL_NO_TLSEXT +#endif + +#ifdef OPENSSL_NO_SOCK +RUST_CONF_OPENSSL_NO_SOCK +#endif + +#ifdef OPENSSL_NO_STDIO +RUST_CONF_OPENSSL_NO_STDIO +#endif + +#ifdef OPENSSL_NO_SM3 +RUST_CONF_OPENSSL_NO_SM3 +#endif + +#ifdef OPENSSL_NO_SM4 +RUST_CONF_OPENSSL_NO_SM4 +#endif + +#ifdef OPENSSL_NO_DEPRECATED_3_0 +RUST_CONF_OPENSSL_NO_DEPRECATED_3_0 +#endif + +#ifdef OPENSSL_NO_SEED +RUST_CONF_OPENSSL_NO_SEED +#endif + +#ifdef OPENSSL_NO_SCRYPT +RUST_CONF_OPENSSL_NO_SCRYPT +#endif diff --git a/vendor/openssl-sys/build/find_normal.rs b/vendor/openssl-sys/build/find_normal.rs new file mode 100644 index 0000000..1439e9a --- /dev/null +++ b/vendor/openssl-sys/build/find_normal.rs @@ -0,0 +1,284 @@ +use std::ffi::OsString; +use std::path::{Path, PathBuf}; +use std::process::{self, Command}; + +use super::env; + +pub fn get_openssl(target: &str) -> (Vec, PathBuf) { + let lib_dir = env("OPENSSL_LIB_DIR").map(PathBuf::from); + let include_dir = env("OPENSSL_INCLUDE_DIR").map(PathBuf::from); + + match (lib_dir, include_dir) { + (Some(lib_dir), Some(include_dir)) => (vec![lib_dir], include_dir), + (lib_dir, include_dir) => { + let openssl_dir = env("OPENSSL_DIR").unwrap_or_else(|| find_openssl_dir(target)); + let openssl_dir = Path::new(&openssl_dir); + let lib_dir = lib_dir.map(|d| vec![d]).unwrap_or_else(|| { + let mut lib_dirs = vec![]; + // OpenSSL 3.0 now puts it's libraries in lib64/ by default, + // check for both it and lib/. + if openssl_dir.join("lib64").exists() { + lib_dirs.push(openssl_dir.join("lib64")); + } + if openssl_dir.join("lib").exists() { + lib_dirs.push(openssl_dir.join("lib")); + } + lib_dirs + }); + let include_dir = include_dir.unwrap_or_else(|| openssl_dir.join("include")); + (lib_dir, include_dir) + } + } +} + +fn resolve_with_wellknown_homebrew_location(dir: &str) -> Option { + let versions = ["openssl@3", "openssl@3.0", "openssl@1.1"]; + + // Check up default aarch 64 Homebrew installation location first + // for quick resolution if possible. + // `pkg-config` on brew doesn't necessarily contain settings for openssl apparently. + for version in &versions { + let homebrew = Path::new(dir).join(format!("opt/{}", version)); + if homebrew.exists() { + return Some(homebrew); + } + } + + for version in &versions { + // Calling `brew --prefix ` command usually slow and + // takes seconds, and will be used only as a last resort. + let output = execute_command_and_get_output("brew", &["--prefix", version]); + if let Some(ref output) = output { + let homebrew = Path::new(&output); + if homebrew.exists() { + return Some(homebrew.to_path_buf()); + } + } + } + + None +} + +fn resolve_with_wellknown_location(dir: &str) -> Option { + let root_dir = Path::new(dir); + let include_openssl = root_dir.join("include/openssl"); + if include_openssl.exists() { + Some(root_dir.to_path_buf()) + } else { + None + } +} + +fn find_openssl_dir(target: &str) -> OsString { + let host = env::var("HOST").unwrap(); + + if host == target && target.ends_with("-apple-darwin") { + let homebrew_dir = match target { + "aarch64-apple-darwin" => "/opt/homebrew", + _ => "/usr/local", + }; + + if let Some(dir) = resolve_with_wellknown_homebrew_location(homebrew_dir) { + return dir.into(); + } else if let Some(dir) = resolve_with_wellknown_location("/opt/pkg") { + // pkgsrc + return dir.into(); + } else if let Some(dir) = resolve_with_wellknown_location("/opt/local") { + // MacPorts + return dir.into(); + } + } + + try_pkg_config(); + try_vcpkg(); + + // FreeBSD and OpenBSD ship with Libre|OpenSSL but don't include a pkg-config file + if host == target && (target.contains("freebsd") || target.contains("openbsd")) { + return OsString::from("/usr"); + } + + // DragonFly has libressl (or openssl) in ports, but this doesn't include a pkg-config file + if host == target && target.contains("dragonfly") { + return OsString::from("/usr/local"); + } + + let msg_header = + "Could not find directory of OpenSSL installation, and this `-sys` crate cannot +proceed without this knowledge. If OpenSSL is installed and this crate had +trouble finding it, you can set the `OPENSSL_DIR` environment variable for the +compilation process."; + + println!( + "cargo:warning={} See stderr section below for further information.", + msg_header.replace('\n', " ") + ); + + let mut msg = format!( + " + +{} + +Make sure you also have the development packages of openssl installed. +For example, `libssl-dev` on Ubuntu or `openssl-devel` on Fedora. + +If you're in a situation where you think the directory *should* be found +automatically, please open a bug at https://github.com/sfackler/rust-openssl +and include information about your system as well as this message. + +$HOST = {} +$TARGET = {} +openssl-sys = {} + +", + msg_header, + host, + target, + env!("CARGO_PKG_VERSION") + ); + + if host.contains("apple-darwin") && target.contains("apple-darwin") { + let system = Path::new("/usr/lib/libssl.0.9.8.dylib"); + if system.exists() { + msg.push_str( + " + +openssl-sys crate build failed: no supported version of OpenSSL found. + +Ways to fix it: +- Use the `vendored` feature of openssl-sys crate to build OpenSSL from source. +- Use Homebrew to install the `openssl` package. + +", + ); + } + } + + if host.contains("unknown-linux") + && target.contains("unknown-linux-gnu") + && Command::new("pkg-config").output().is_err() + { + msg.push_str( + " +It looks like you're compiling on Linux and also targeting Linux. Currently this +requires the `pkg-config` utility to find OpenSSL but unfortunately `pkg-config` +could not be found. If you have OpenSSL installed you can likely fix this by +installing `pkg-config`. + +", + ); + } + + if host.contains("windows") && target.contains("windows-gnu") { + msg.push_str( + " +It looks like you're compiling for MinGW but you may not have either OpenSSL or +pkg-config installed. You can install these two dependencies with: + +pacman -S openssl-devel pkgconf + +and try building this crate again. + +", + ); + } + + if host.contains("windows") && target.contains("windows-msvc") { + msg.push_str( + " +It looks like you're compiling for MSVC but we couldn't detect an OpenSSL +installation. If there isn't one installed then you can try the rust-openssl +README for more information about how to download precompiled binaries of +OpenSSL: + +https://github.com/sfackler/rust-openssl#windows + +", + ); + } + + eprintln!("{}", msg); + std::process::exit(101); // same as panic previously +} + +/// Attempt to find OpenSSL through pkg-config. +/// +/// Note that if this succeeds then the function does not return as pkg-config +/// typically tells us all the information that we need. +fn try_pkg_config() { + let target = env::var("TARGET").unwrap(); + let host = env::var("HOST").unwrap(); + + // FIXME we really shouldn't be automatically enabling this + if target.contains("windows-gnu") && host.contains("windows") { + env::set_var("PKG_CONFIG_ALLOW_CROSS", "1"); + } else if target.contains("windows-msvc") { + // MSVC targets use vcpkg instead. + return; + } + + let lib = match pkg_config::Config::new() + .print_system_libs(false) + .probe("openssl") + { + Ok(lib) => lib, + Err(e) => { + println!("\n\nCould not find openssl via pkg-config:\n{}\n", e); + return; + } + }; + + super::postprocess(&lib.include_paths); + + for include in lib.include_paths.iter() { + println!("cargo:include={}", include.display()); + } + + process::exit(0); +} + +/// Attempt to find OpenSSL through vcpkg. +/// +/// Note that if this succeeds then the function does not return as vcpkg +/// should emit all of the cargo metadata that we need. +fn try_vcpkg() { + let target = env::var("TARGET").unwrap(); + if !target.contains("windows") { + return; + } + + // vcpkg will not emit any metadata if it can not find libraries + // appropriate for the target triple with the desired linkage. + + let lib = match vcpkg::Config::new() + .emit_includes(true) + .find_package("openssl") + { + Ok(lib) => lib, + Err(e) => { + println!("note: vcpkg did not find openssl: {}", e); + return; + } + }; + + super::postprocess(&lib.include_paths); + + println!("cargo:rustc-link-lib=user32"); + println!("cargo:rustc-link-lib=gdi32"); + println!("cargo:rustc-link-lib=crypt32"); + + process::exit(0); +} + +fn execute_command_and_get_output(cmd: &str, args: &[&str]) -> Option { + let out = Command::new(cmd).args(args).output(); + if let Ok(ref r1) = out { + if r1.status.success() { + let r2 = String::from_utf8(r1.stdout.clone()); + if let Ok(r3) = r2 { + return Some(r3.trim().to_string()); + } + } + } + + None +} diff --git a/vendor/openssl-sys/build/find_vendored.rs b/vendor/openssl-sys/build/find_vendored.rs new file mode 100644 index 0000000..fd21ed6 --- /dev/null +++ b/vendor/openssl-sys/build/find_vendored.rs @@ -0,0 +1,25 @@ +use openssl_src; +use std::path::PathBuf; + +use super::env; + +pub fn get_openssl(_target: &str) -> (Vec, PathBuf) { + let openssl_config_dir = env("OPENSSL_CONFIG_DIR"); + + let mut openssl_src_build = openssl_src::Build::new(); + if let Some(value) = openssl_config_dir { + openssl_src_build.openssl_dir(PathBuf::from(value)); + } + + let artifacts = openssl_src_build.build(); + println!("cargo:vendored=1"); + println!( + "cargo:root={}", + artifacts.lib_dir().parent().unwrap().display() + ); + + ( + vec![artifacts.lib_dir().to_path_buf()], + artifacts.include_dir().to_path_buf(), + ) +} diff --git a/vendor/openssl-sys/build/main.rs b/vendor/openssl-sys/build/main.rs new file mode 100644 index 0000000..f379e1e --- /dev/null +++ b/vendor/openssl-sys/build/main.rs @@ -0,0 +1,508 @@ +#[cfg(feature = "bindgen")] +extern crate bindgen; +extern crate cc; +#[cfg(feature = "vendored")] +extern crate openssl_src; +extern crate pkg_config; +extern crate vcpkg; + +use std::collections::HashSet; +use std::env; +use std::ffi::OsString; +use std::path::PathBuf; +mod cfgs; + +mod find_normal; +#[cfg(feature = "vendored")] +mod find_vendored; +mod run_bindgen; + +#[derive(PartialEq)] +enum Version { + Openssl3xx, + Openssl11x, + Openssl10x, + Libressl, + Boringssl, +} + +fn env_inner(name: &str) -> Option { + let var = env::var_os(name); + println!("cargo:rerun-if-env-changed={}", name); + + match var { + Some(ref v) => println!("{} = {}", name, v.to_string_lossy()), + None => println!("{} unset", name), + } + + var +} + +fn env(name: &str) -> Option { + let prefix = env::var("TARGET").unwrap().to_uppercase().replace('-', "_"); + let prefixed = format!("{}_{}", prefix, name); + env_inner(&prefixed).or_else(|| env_inner(name)) +} + +fn find_openssl(target: &str) -> (Vec, PathBuf) { + #[cfg(feature = "vendored")] + { + // vendor if the feature is present, unless + // OPENSSL_NO_VENDOR exists and isn't `0` + if env("OPENSSL_NO_VENDOR").map_or(true, |s| s == "0") { + return find_vendored::get_openssl(target); + } + } + find_normal::get_openssl(target) +} + +fn check_ssl_kind() { + if cfg!(feature = "unstable_boringssl") { + println!("cargo:rustc-cfg=boringssl"); + println!("cargo:boringssl=true"); + + if let Ok(vars) = env::var("DEP_BSSL_CONF") { + for var in vars.split(',') { + println!("cargo:rustc-cfg=osslconf=\"{}\"", var); + } + println!("cargo:conf={}", vars); + } + + // BoringSSL does not have any build logic, exit early + std::process::exit(0); + } +} + +fn main() { + println!("cargo:rustc-check-cfg=cfg(osslconf, values(\"OPENSSL_NO_OCB\", \"OPENSSL_NO_SM4\", \"OPENSSL_NO_SEED\", \"OPENSSL_NO_CHACHA\", \"OPENSSL_NO_CAST\", \"OPENSSL_NO_IDEA\", \"OPENSSL_NO_CAMELLIA\", \"OPENSSL_NO_RC4\", \"OPENSSL_NO_BF\", \"OPENSSL_NO_PSK\", \"OPENSSL_NO_DEPRECATED_3_0\", \"OPENSSL_NO_SCRYPT\", \"OPENSSL_NO_SM3\", \"OPENSSL_NO_RMD160\", \"OPENSSL_NO_EC2M\", \"OPENSSL_NO_OCSP\", \"OPENSSL_NO_CMS\", \"OPENSSL_NO_COMP\", \"OPENSSL_NO_SOCK\", \"OPENSSL_NO_STDIO\", \"OPENSSL_NO_EC\", \"OPENSSL_NO_SSL3_METHOD\", \"OPENSSL_NO_KRB5\", \"OPENSSL_NO_TLSEXT\", \"OPENSSL_NO_SRP\", \"OPENSSL_NO_RFC3779\", \"OPENSSL_NO_SHA\", \"OPENSSL_NO_NEXTPROTONEG\", \"OPENSSL_NO_ENGINE\", \"OPENSSL_NO_BUF_FREELISTS\"))"); + + println!("cargo:rustc-check-cfg=cfg(openssl)"); + println!("cargo:rustc-check-cfg=cfg(libressl)"); + println!("cargo:rustc-check-cfg=cfg(boringssl)"); + + println!("cargo:rustc-check-cfg=cfg(libressl250)"); + println!("cargo:rustc-check-cfg=cfg(libressl251)"); + println!("cargo:rustc-check-cfg=cfg(libressl252)"); + println!("cargo:rustc-check-cfg=cfg(libressl261)"); + println!("cargo:rustc-check-cfg=cfg(libressl270)"); + println!("cargo:rustc-check-cfg=cfg(libressl271)"); + println!("cargo:rustc-check-cfg=cfg(libressl273)"); + println!("cargo:rustc-check-cfg=cfg(libressl280)"); + println!("cargo:rustc-check-cfg=cfg(libressl281)"); + println!("cargo:rustc-check-cfg=cfg(libressl291)"); + println!("cargo:rustc-check-cfg=cfg(libressl310)"); + println!("cargo:rustc-check-cfg=cfg(libressl321)"); + println!("cargo:rustc-check-cfg=cfg(libressl332)"); + println!("cargo:rustc-check-cfg=cfg(libressl340)"); + println!("cargo:rustc-check-cfg=cfg(libressl350)"); + println!("cargo:rustc-check-cfg=cfg(libressl360)"); + println!("cargo:rustc-check-cfg=cfg(libressl361)"); + println!("cargo:rustc-check-cfg=cfg(libressl370)"); + println!("cargo:rustc-check-cfg=cfg(libressl380)"); + println!("cargo:rustc-check-cfg=cfg(libressl381)"); + println!("cargo:rustc-check-cfg=cfg(libressl382)"); + println!("cargo:rustc-check-cfg=cfg(libressl390)"); + println!("cargo:rustc-check-cfg=cfg(libressl400)"); + + println!("cargo:rustc-check-cfg=cfg(ossl101)"); + println!("cargo:rustc-check-cfg=cfg(ossl102)"); + println!("cargo:rustc-check-cfg=cfg(ossl102f)"); + println!("cargo:rustc-check-cfg=cfg(ossl102h)"); + println!("cargo:rustc-check-cfg=cfg(ossl110)"); + println!("cargo:rustc-check-cfg=cfg(ossl110f)"); + println!("cargo:rustc-check-cfg=cfg(ossl110g)"); + println!("cargo:rustc-check-cfg=cfg(ossl110h)"); + println!("cargo:rustc-check-cfg=cfg(ossl111)"); + println!("cargo:rustc-check-cfg=cfg(ossl111b)"); + println!("cargo:rustc-check-cfg=cfg(ossl111c)"); + println!("cargo:rustc-check-cfg=cfg(ossl111d)"); + println!("cargo:rustc-check-cfg=cfg(ossl300)"); + println!("cargo:rustc-check-cfg=cfg(ossl310)"); + println!("cargo:rustc-check-cfg=cfg(ossl320)"); + println!("cargo:rustc-check-cfg=cfg(ossl330)"); + println!("cargo:rustc-check-cfg=cfg(ossl340)"); + + check_ssl_kind(); + + let target = env::var("TARGET").unwrap(); + + let (lib_dirs, include_dir) = find_openssl(&target); + // rerun-if-changed causes openssl-sys to rebuild if the openssl include + // dir has changed since the last build. However, this causes a rebuild + // every time when vendoring so we disable it. + let potential_path = include_dir.join("openssl"); + if potential_path.exists() && !cfg!(feature = "vendored") { + if let Some(printable_include) = potential_path.to_str() { + println!("cargo:rerun-if-changed={}", printable_include); + } + } + + if !lib_dirs.iter().all(|p| p.exists()) { + panic!("OpenSSL library directory does not exist: {:?}", lib_dirs); + } + if !include_dir.exists() { + panic!( + "OpenSSL include directory does not exist: {}", + include_dir.to_string_lossy() + ); + } + + for lib_dir in lib_dirs.iter() { + println!( + "cargo:rustc-link-search=native={}", + lib_dir.to_string_lossy() + ); + } + println!("cargo:include={}", include_dir.to_string_lossy()); + + let version = postprocess(&[include_dir]); + + let libs_env = env("OPENSSL_LIBS"); + let libs = match libs_env.as_ref().and_then(|s| s.to_str()) { + Some(v) => { + if v.is_empty() { + vec![] + } else { + v.split(':').collect() + } + } + None => match version { + Version::Openssl10x if target.contains("windows") => vec!["ssleay32", "libeay32"], + Version::Openssl3xx | Version::Openssl11x if target.contains("windows-msvc") => { + vec!["libssl", "libcrypto"] + } + _ => vec!["ssl", "crypto"], + }, + }; + + let kind = determine_mode(&lib_dirs, &libs); + for lib in libs.into_iter() { + println!("cargo:rustc-link-lib={}={}", kind, lib); + } + + // libssl in BoringSSL requires the C++ runtime, and static libraries do + // not carry dependency information. On unix-like platforms, the C++ + // runtime and standard library are typically picked up by default via the + // C++ compiler, which has a platform-specific default. (See implementations + // of `GetDefaultCXXStdlibType` in Clang.) Builds may also choose to + // override this and specify their own with `-nostdinc++` and `-nostdlib++` + // flags. Some compilers also provide options like `-stdlib=libc++`. + // + // Typically, such information is carried all the way up the build graph, + // but Cargo is not an integrated cross-language build system, so it cannot + // safely handle any of these situations. As a result, we need to make + // guesses. Getting this wrong may result in symbol conflicts and memory + // errors, but this unsafety is inherent to driving builds with + // externally-built libraries using Cargo. + // + // For now, we guess that the build was made with the defaults. This too is + // difficult because Rust does not expose this information from Clang, but + // try to match the behavior for common platforms. For a more robust option, + // this likely needs to be deferred to the caller with an environment + // variable. + if version == Version::Boringssl && kind == "static" && env::var("CARGO_CFG_UNIX").is_ok() { + let cpp_lib = match env::var("CARGO_CFG_TARGET_OS").unwrap().as_ref() { + "macos" => "c++", + _ => "stdc++", + }; + println!("cargo:rustc-link-lib={}", cpp_lib); + } + + // https://github.com/openssl/openssl/pull/15086 + if version == Version::Openssl3xx + && kind == "static" + && (env::var("CARGO_CFG_TARGET_OS").unwrap() == "linux" + || env::var("CARGO_CFG_TARGET_OS").unwrap() == "android") + && env::var("CARGO_CFG_TARGET_POINTER_WIDTH").unwrap() == "32" + { + println!("cargo:rustc-link-lib=atomic"); + } + + if kind == "static" && target.contains("windows") { + println!("cargo:rustc-link-lib=dylib=gdi32"); + println!("cargo:rustc-link-lib=dylib=user32"); + println!("cargo:rustc-link-lib=dylib=crypt32"); + println!("cargo:rustc-link-lib=dylib=ws2_32"); + println!("cargo:rustc-link-lib=dylib=advapi32"); + } +} + +fn postprocess(include_dirs: &[PathBuf]) -> Version { + let version = validate_headers(include_dirs); + + // Never run bindgen for BoringSSL, if it was needed we already ran it. + if version != Version::Boringssl { + #[cfg(feature = "bindgen")] + run_bindgen::run(&include_dirs); + } + + version +} + +/// Validates the header files found in `include_dir` and then returns the +/// version string of OpenSSL. +#[allow(clippy::unusual_byte_groupings)] +fn validate_headers(include_dirs: &[PathBuf]) -> Version { + // This `*-sys` crate only works with OpenSSL 1.0.1, 1.0.2, 1.1.0, 1.1.1 and 3.0.0. + // To correctly expose the right API from this crate, take a look at + // `opensslv.h` to see what version OpenSSL claims to be. + // + // OpenSSL has a number of build-time configuration options which affect + // various structs and such. Since OpenSSL 1.1.0 this isn't really a problem + // as the library is much more FFI-friendly, but 1.0.{1,2} suffer this problem. + // + // To handle all this conditional compilation we slurp up the configuration + // file of OpenSSL, `opensslconf.h`, and then dump out everything it defines + // as our own #[cfg] directives. That way the `ossl10x.rs` bindings can + // account for compile differences and such. + println!("cargo:rerun-if-changed=build/expando.c"); + let mut gcc = cc::Build::new(); + gcc.includes(include_dirs); + let expanded = match gcc.file("build/expando.c").try_expand() { + Ok(expanded) => expanded, + Err(e) => { + panic!( + " +Header expansion error: +{:?} + +Failed to find OpenSSL development headers. + +You can try fixing this setting the `OPENSSL_DIR` environment variable +pointing to your OpenSSL installation or installing OpenSSL headers package +specific to your distribution: + + # On Ubuntu + sudo apt-get install pkg-config libssl-dev + # On Arch Linux + sudo pacman -S pkgconf openssl + # On Fedora + sudo dnf install pkgconf perl-FindBin perl-IPC-Cmd openssl-devel + # On Alpine Linux + apk add pkgconf openssl-dev + +See rust-openssl documentation for more information: + + https://docs.rs/openssl +", + e + ); + } + }; + let expanded = String::from_utf8(expanded).unwrap(); + + let mut enabled = vec![]; + let mut openssl_version = None; + let mut libressl_version = None; + let mut is_boringssl = false; + for line in expanded.lines() { + let line = line.trim(); + + let openssl_prefix = "RUST_VERSION_OPENSSL_"; + let new_openssl_prefix = "RUST_VERSION_NEW_OPENSSL_"; + let libressl_prefix = "RUST_VERSION_LIBRESSL_"; + let boringsl_prefix = "RUST_OPENSSL_IS_BORINGSSL"; + let conf_prefix = "RUST_CONF_"; + if let Some(version) = line.strip_prefix(openssl_prefix) { + openssl_version = Some(parse_version(version)); + } else if let Some(version) = line.strip_prefix(new_openssl_prefix) { + openssl_version = Some(parse_new_version(version)); + } else if let Some(version) = line.strip_prefix(libressl_prefix) { + libressl_version = Some(parse_version(version)); + } else if let Some(conf) = line.strip_prefix(conf_prefix) { + enabled.push(conf); + } else if line.starts_with(boringsl_prefix) { + is_boringssl = true; + } + } + + for enabled in &enabled { + println!("cargo:rustc-cfg=osslconf=\"{}\"", enabled); + } + println!("cargo:conf={}", enabled.join(",")); + + if is_boringssl { + println!("cargo:rustc-cfg=boringssl"); + println!("cargo:boringssl=true"); + run_bindgen::run_boringssl(include_dirs); + return Version::Boringssl; + } + + // We set this for any non-BoringSSL lib. + println!("cargo:rustc-cfg=openssl"); + + for cfg in cfgs::get(openssl_version, libressl_version) { + println!("cargo:rustc-cfg={}", cfg); + } + + if let Some(libressl_version) = libressl_version { + println!("cargo:libressl_version_number={:x}", libressl_version); + + let major = (libressl_version >> 28) as u8; + let minor = (libressl_version >> 20) as u8; + let fix = (libressl_version >> 12) as u8; + let (major, minor, fix) = match (major, minor, fix) { + (2, 5, 0) => ('2', '5', '0'), + (2, 5, 1) => ('2', '5', '1'), + (2, 5, 2) => ('2', '5', '2'), + (2, 5, _) => ('2', '5', 'x'), + (2, 6, 0) => ('2', '6', '0'), + (2, 6, 1) => ('2', '6', '1'), + (2, 6, 2) => ('2', '6', '2'), + (2, 6, _) => ('2', '6', 'x'), + (2, 7, _) => ('2', '7', 'x'), + (2, 8, 0) => ('2', '8', '0'), + (2, 8, 1) => ('2', '8', '1'), + (2, 8, _) => ('2', '8', 'x'), + (2, 9, 0) => ('2', '9', '0'), + (2, 9, _) => ('2', '9', 'x'), + (3, 0, 0) => ('3', '0', '0'), + (3, 0, 1) => ('3', '0', '1'), + (3, 0, _) => ('3', '0', 'x'), + (3, 1, 0) => ('3', '1', '0'), + (3, 1, _) => ('3', '1', 'x'), + (3, 2, 0) => ('3', '2', '0'), + (3, 2, 1) => ('3', '2', '1'), + (3, 2, _) => ('3', '2', 'x'), + (3, 3, 0) => ('3', '3', '0'), + (3, 3, 1) => ('3', '3', '1'), + (3, 3, _) => ('3', '3', 'x'), + (3, 4, 0) => ('3', '4', '0'), + (3, 4, _) => ('3', '4', 'x'), + (3, 5, _) => ('3', '5', 'x'), + (3, 6, 0) => ('3', '6', '0'), + (3, 6, _) => ('3', '6', 'x'), + (3, 7, 0) => ('3', '7', '0'), + (3, 7, 1) => ('3', '7', '1'), + (3, 7, _) => ('3', '7', 'x'), + (3, 8, 0) => ('3', '8', '0'), + (3, 8, 1) => ('3', '8', '1'), + (3, 8, _) => ('3', '8', 'x'), + (3, 9, 0) => ('3', '9', '0'), + (3, 9, _) => ('3', '9', 'x'), + (4, 0, 0) => ('4', '0', '0'), + (4, 0, _) => ('4', '0', 'x'), + _ => version_error(), + }; + + println!("cargo:libressl=true"); + println!("cargo:libressl_version={}{}{}", major, minor, fix); + println!("cargo:version=101"); + Version::Libressl + } else { + let openssl_version = openssl_version.unwrap(); + println!("cargo:version_number={:x}", openssl_version); + + if openssl_version >= 0x4_00_00_00_0 { + version_error() + } else if openssl_version >= 0x3_00_00_00_0 { + Version::Openssl3xx + } else if openssl_version >= 0x1_01_01_00_0 { + println!("cargo:version=111"); + Version::Openssl11x + } else if openssl_version >= 0x1_01_00_06_0 { + println!("cargo:version=110"); + println!("cargo:patch=f"); + Version::Openssl11x + } else if openssl_version >= 0x1_01_00_00_0 { + println!("cargo:version=110"); + Version::Openssl11x + } else if openssl_version >= 0x1_00_02_00_0 { + println!("cargo:version=102"); + Version::Openssl10x + } else if openssl_version >= 0x1_00_01_00_0 { + println!("cargo:version=101"); + Version::Openssl10x + } else { + version_error() + } + } +} + +fn version_error() -> ! { + panic!( + " + +This crate is only compatible with OpenSSL (version 1.0.1 through 1.1.1, or 3), or LibreSSL 2.5 +through 4.0.x, but a different version of OpenSSL was found. The build is now aborting +due to this version mismatch. + +" + ); +} + +// parses a string that looks like "0x100020cfL" +fn parse_version(version: &str) -> u64 { + // cut off the 0x prefix + assert!(version.starts_with("0x")); + let version = &version[2..]; + + // and the type specifier suffix + let version = version.trim_end_matches(|c: char| !c.is_ascii_hexdigit()); + + u64::from_str_radix(version, 16).unwrap() +} + +// parses a string that looks like 3_0_0 +fn parse_new_version(version: &str) -> u64 { + println!("version: {}", version); + let mut it = version.split('_'); + let major = it.next().unwrap().parse::().unwrap(); + let minor = it.next().unwrap().parse::().unwrap(); + let patch = it.next().unwrap().parse::().unwrap(); + + (major << 28) | (minor << 20) | (patch << 4) +} + +/// Given a libdir for OpenSSL (where artifacts are located) as well as the name +/// of the libraries we're linking to, figure out whether we should link them +/// statically or dynamically. +fn determine_mode(libdirs: &[PathBuf], libs: &[&str]) -> &'static str { + // First see if a mode was explicitly requested + let kind = env("OPENSSL_STATIC"); + match kind.as_ref().and_then(|s| s.to_str()) { + Some("0") => return "dylib", + Some(_) => return "static", + None => {} + } + + // Next, see what files we actually have to link against, and see what our + // possibilities even are. + let mut files = HashSet::new(); + for dir in libdirs { + for path in dir + .read_dir() + .unwrap() + .map(|e| e.unwrap()) + .map(|e| e.file_name()) + .filter_map(|e| e.into_string().ok()) + { + files.insert(path); + } + } + let can_static = libs + .iter() + .all(|l| files.contains(&format!("lib{}.a", l)) || files.contains(&format!("{}.lib", l))); + let can_dylib = libs.iter().all(|l| { + files.contains(&format!("lib{}.so", l)) + || files.contains(&format!("{}.dll", l)) + || files.contains(&format!("lib{}.dylib", l)) + }); + match (can_static, can_dylib) { + (true, false) => return "static", + (false, true) => return "dylib", + (false, false) => { + panic!( + "OpenSSL libdir at `{:?}` does not contain the required files \ + to either statically or dynamically link OpenSSL", + libdirs + ); + } + (true, true) => {} + } + + // Ok, we've got not explicit preference and can *either* link statically or + // link dynamically. In the interest of "security upgrades" and/or "best + // practices with security libs", let's link dynamically. + "dylib" +} diff --git a/vendor/openssl-sys/build/run_bindgen.rs b/vendor/openssl-sys/build/run_bindgen.rs new file mode 100644 index 0000000..27bd482 --- /dev/null +++ b/vendor/openssl-sys/build/run_bindgen.rs @@ -0,0 +1,253 @@ +#[cfg(feature = "bindgen")] +use bindgen::callbacks::{MacroParsingBehavior, ParseCallbacks}; +#[cfg(feature = "bindgen")] +use bindgen::{MacroTypeVariation, RustTarget}; +use std::io::Write; +use std::path::PathBuf; +#[cfg(not(feature = "bindgen"))] +use std::process; +use std::{env, fs}; + +const INCLUDES: &str = " +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// this must be included after ssl.h for libressl! +#include + +#if !defined(LIBRESSL_VERSION_NUMBER) && !defined(OPENSSL_IS_BORINGSSL) +#include +#endif + +#if !defined(OPENSSL_IS_BORINGSSL) +#include +#include +#endif + +#if !defined(LIBRESSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= 0x10100000 +#include +#endif + +#if OPENSSL_VERSION_NUMBER >= 0x30000000 +#include +#endif + +#if OPENSSL_VERSION_NUMBER >= 0x30200000 +#include +#endif + +#if defined(LIBRESSL_VERSION_NUMBER) || defined(OPENSSL_IS_BORINGSSL) +#include +#endif + +#if OPENSSL_VERSION_NUMBER >= 0x30200000 +#include +#endif +"; + +#[cfg(feature = "bindgen")] +pub fn run(include_dirs: &[PathBuf]) { + let out_dir = PathBuf::from(env::var_os("OUT_DIR").unwrap()); + + let mut builder = bindgen::builder() + .parse_callbacks(Box::new(OpensslCallbacks)) + .rust_target(RustTarget::Stable_1_47) + .ctypes_prefix("::libc") + .raw_line("use libc::*;") + .raw_line("#[cfg(windows)] use std::os::windows::raw::HANDLE;") + .raw_line("type evp_pkey_st = EVP_PKEY;") + .allowlist_file(".*[/\\\\]openssl/[^/\\\\]+\\.h") + .allowlist_recursively(false) + // libc is missing pthread_once_t on macOS + .blocklist_type("CRYPTO_ONCE") + .blocklist_function("CRYPTO_THREAD_run_once") + // we don't want to mess with va_list + .blocklist_function("BIO_vprintf") + .blocklist_function("BIO_vsnprintf") + .blocklist_function("ERR_vset_error") + .blocklist_function("ERR_add_error_vdata") + .blocklist_function("EVP_KDF_vctrl") + .blocklist_type("OSSL_FUNC_core_vset_error_fn") + .blocklist_type("OSSL_FUNC_BIO_vprintf_fn") + .blocklist_type("OSSL_FUNC_BIO_vsnprintf_fn") + // struct hostent * does not exist on Windows + .blocklist_function("BIO_gethostbyname") + // Maintain compatibility for existing enum definitions + .rustified_enum("point_conversion_form_t") + // Maintain compatibility for pre-union definitions + .blocklist_type("GENERAL_NAME") + .blocklist_type("GENERAL_NAME_st") + .blocklist_type("EVP_PKEY") + .blocklist_type("evp_pkey_st") + .layout_tests(false) + .header_contents("includes.h", INCLUDES); + + for include_dir in include_dirs { + builder = builder + .clang_arg("-I") + .clang_arg(include_dir.display().to_string()); + } + + builder + .generate() + .unwrap() + .write_to_file(out_dir.join("bindgen.rs")) + .unwrap(); +} + +#[cfg(feature = "bindgen")] +pub fn run_boringssl(include_dirs: &[PathBuf]) { + let out_dir = PathBuf::from(env::var_os("OUT_DIR").unwrap()); + + fs::File::create(out_dir.join("boring_static_wrapper.h")) + .expect("Failed to create boring_static_wrapper.h") + .write_all(INCLUDES.as_bytes()) + .expect("Failed to write contents to boring_static_wrapper.h"); + + let mut builder = bindgen::builder() + .rust_target(RustTarget::Stable_1_47) + .ctypes_prefix("::libc") + .raw_line("use libc::*;") + .derive_default(false) + .enable_function_attribute_detection() + .default_macro_constant_type(MacroTypeVariation::Signed) + .rustified_enum("point_conversion_form_t") + .allowlist_file(".*[/\\\\]openssl/[^/]+\\.h") + .allowlist_recursively(false) + .blocklist_function("BIO_vsnprintf") + .blocklist_function("OPENSSL_vasprintf") + .wrap_static_fns(true) + .wrap_static_fns_path(out_dir.join("boring_static_wrapper").display().to_string()) + .layout_tests(false) + .header( + out_dir + .join("boring_static_wrapper.h") + .display() + .to_string(), + ); + + for include_dir in include_dirs { + builder = builder + .clang_arg("-I") + .clang_arg(include_dir.display().to_string()); + } + + builder + .generate() + .unwrap() + .write_to_file(out_dir.join("bindgen.rs")) + .unwrap(); + + cc::Build::new() + .file(out_dir.join("boring_static_wrapper.c")) + .includes(include_dirs) + .compile("boring_static_wrapper"); +} + +#[cfg(not(feature = "bindgen"))] +pub fn run_boringssl(include_dirs: &[PathBuf]) { + let out_dir = PathBuf::from(env::var_os("OUT_DIR").unwrap()); + + fs::File::create(out_dir.join("boring_static_wrapper.h")) + .expect("Failed to create boring_static_wrapper.h") + .write_all(INCLUDES.as_bytes()) + .expect("Failed to write contents to boring_static_wrapper.h"); + + let mut bindgen_cmd = process::Command::new("bindgen"); + bindgen_cmd + .arg("-o") + .arg(out_dir.join("bindgen.rs")) + // Must be a valid version from + // https://docs.rs/bindgen/latest/bindgen/enum.RustTarget.html + .arg("--rust-target=1.47") + .arg("--ctypes-prefix=::libc") + .arg("--raw-line=use libc::*;") + .arg("--no-derive-default") + .arg("--enable-function-attribute-detection") + .arg("--default-macro-constant-type=signed") + .arg("--rustified-enum=point_conversion_form_t") + .arg("--allowlist-file=.*[/\\\\]openssl/[^/]+\\.h") + .arg("--no-recursive-allowlist") + .arg("--blocklist-function=BIO_vsnprintf") + .arg("--blocklist-function=OPENSSL_vasprintf") + .arg("--experimental") + .arg("--wrap-static-fns") + .arg("--wrap-static-fns-path") + .arg(out_dir.join("boring_static_wrapper").display().to_string()) + .arg("--no-layout-tests") + .arg(out_dir.join("boring_static_wrapper.h")) + .arg("--") + .arg(format!("--target={}", env::var("TARGET").unwrap())); + + for include_dir in include_dirs { + bindgen_cmd.arg("-I").arg(include_dir.display().to_string()); + } + + let result = bindgen_cmd.status().expect("bindgen failed to execute"); + assert!(result.success()); + + cc::Build::new() + .file(out_dir.join("boring_static_wrapper.c")) + .includes(include_dirs) + .compile("boring_static_wrapper"); +} + +#[cfg(feature = "bindgen")] +#[derive(Debug)] +struct OpensslCallbacks; + +#[cfg(feature = "bindgen")] +impl ParseCallbacks for OpensslCallbacks { + // for now we'll continue hand-writing constants + fn will_parse_macro(&self, _name: &str) -> MacroParsingBehavior { + MacroParsingBehavior::Ignore + } + + fn item_name(&self, original_item_name: &str) -> Option { + match original_item_name { + // Our original definitions of these are wrong, so rename to avoid breakage + "CRYPTO_EX_new" + | "CRYPTO_EX_dup" + | "CRYPTO_EX_free" + | "BIO_meth_set_write" + | "BIO_meth_set_read" + | "BIO_meth_set_puts" + | "BIO_meth_set_ctrl" + | "BIO_meth_set_create" + | "BIO_meth_set_destroy" + | "CRYPTO_set_locking_callback" + | "CRYPTO_set_id_callback" + | "SSL_CTX_set_tmp_dh_callback" + | "SSL_set_tmp_dh_callback" + | "SSL_CTX_set_tmp_ecdh_callback" + | "SSL_set_tmp_ecdh_callback" + | "SSL_CTX_callback_ctrl" + | "SSL_CTX_set_alpn_select_cb" => Some(format!("{}__fixed_rust", original_item_name)), + _ => None, + } + } +} diff --git a/vendor/openssl-sys/src/aes.rs b/vendor/openssl-sys/src/aes.rs new file mode 100644 index 0000000..ade6e84 --- /dev/null +++ b/vendor/openssl-sys/src/aes.rs @@ -0,0 +1,7 @@ +use libc::*; + +pub const AES_ENCRYPT: c_int = 1; +pub const AES_DECRYPT: c_int = 0; + +pub const AES_MAXNR: c_int = 14; +pub const AES_BLOCK_SIZE: c_int = 16; diff --git a/vendor/openssl-sys/src/asn1.rs b/vendor/openssl-sys/src/asn1.rs new file mode 100644 index 0000000..caf14f7 --- /dev/null +++ b/vendor/openssl-sys/src/asn1.rs @@ -0,0 +1,39 @@ +use libc::*; + +use super::*; + +// ASN.1 tag values +pub const V_ASN1_EOC: c_int = 0; +pub const V_ASN1_BOOLEAN: c_int = 1; +pub const V_ASN1_INTEGER: c_int = 2; +pub const V_ASN1_BIT_STRING: c_int = 3; +pub const V_ASN1_OCTET_STRING: c_int = 4; +pub const V_ASN1_NULL: c_int = 5; +pub const V_ASN1_OBJECT: c_int = 6; +pub const V_ASN1_OBJECT_DESCRIPTOR: c_int = 7; +pub const V_ASN1_EXTERNAL: c_int = 8; +pub const V_ASN1_REAL: c_int = 9; +pub const V_ASN1_ENUMERATED: c_int = 10; +pub const V_ASN1_UTF8STRING: c_int = 12; +pub const V_ASN1_SEQUENCE: c_int = 16; +pub const V_ASN1_SET: c_int = 17; +pub const V_ASN1_NUMERICSTRING: c_int = 18; +pub const V_ASN1_PRINTABLESTRING: c_int = 19; +pub const V_ASN1_T61STRING: c_int = 20; +pub const V_ASN1_TELETEXSTRING: c_int = 20; // alias +pub const V_ASN1_VIDEOTEXSTRING: c_int = 21; +pub const V_ASN1_IA5STRING: c_int = 22; +pub const V_ASN1_UTCTIME: c_int = 23; +pub const V_ASN1_GENERALIZEDTIME: c_int = 24; +pub const V_ASN1_GRAPHICSTRING: c_int = 25; +pub const V_ASN1_ISO64STRING: c_int = 26; +pub const V_ASN1_VISIBLESTRING: c_int = 26; // alias +pub const V_ASN1_GENERALSTRING: c_int = 27; +pub const V_ASN1_UNIVERSALSTRING: c_int = 28; +pub const V_ASN1_BMPSTRING: c_int = 30; + +pub const MBSTRING_FLAG: c_int = 0x1000; +pub const MBSTRING_UTF8: c_int = MBSTRING_FLAG; +pub const MBSTRING_ASC: c_int = MBSTRING_FLAG | 1; +pub const MBSTRING_BMP: c_int = MBSTRING_FLAG | 2; +pub const MBSTRING_UNIV: c_int = MBSTRING_FLAG | 4; diff --git a/vendor/openssl-sys/src/bio.rs b/vendor/openssl-sys/src/bio.rs new file mode 100644 index 0000000..f6ec71d --- /dev/null +++ b/vendor/openssl-sys/src/bio.rs @@ -0,0 +1,116 @@ +use libc::*; + +use super::*; + +pub const BIO_TYPE_NONE: c_int = 0; + +pub const BIO_CTRL_EOF: c_int = 2; +pub const BIO_CTRL_INFO: c_int = 3; +pub const BIO_CTRL_FLUSH: c_int = 11; +pub const BIO_CTRL_DGRAM_QUERY_MTU: c_int = 40; +pub const BIO_C_SET_BUF_MEM_EOF_RETURN: c_int = 130; + +pub unsafe fn BIO_set_retry_read(b: *mut BIO) { + BIO_set_flags(b, BIO_FLAGS_READ | BIO_FLAGS_SHOULD_RETRY) +} + +pub unsafe fn BIO_set_retry_write(b: *mut BIO) { + BIO_set_flags(b, BIO_FLAGS_WRITE | BIO_FLAGS_SHOULD_RETRY) +} + +pub unsafe fn BIO_clear_retry_flags(b: *mut BIO) { + BIO_clear_flags(b, BIO_FLAGS_RWS | BIO_FLAGS_SHOULD_RETRY) +} + +pub const BIO_FLAGS_READ: c_int = 0x01; +pub const BIO_FLAGS_WRITE: c_int = 0x02; +pub const BIO_FLAGS_IO_SPECIAL: c_int = 0x04; +pub const BIO_FLAGS_RWS: c_int = BIO_FLAGS_READ | BIO_FLAGS_WRITE | BIO_FLAGS_IO_SPECIAL; +pub const BIO_FLAGS_SHOULD_RETRY: c_int = 0x08; + +pub unsafe fn BIO_get_mem_data(b: *mut BIO, pp: *mut *mut c_char) -> c_long { + BIO_ctrl(b, BIO_CTRL_INFO, 0, pp as *mut c_void) +} + +extern "C" { + #[deprecated(note = "use BIO_meth_set_write__fixed_rust instead")] + #[cfg(any(ossl110, libressl273))] + pub fn BIO_meth_set_write( + biom: *mut BIO_METHOD, + write: unsafe extern "C" fn(*mut BIO, *const c_char, c_int) -> c_int, + ) -> c_int; + #[deprecated(note = "use BIO_meth_set_read__fixed_rust instead")] + #[cfg(any(ossl110, libressl273))] + pub fn BIO_meth_set_read( + biom: *mut BIO_METHOD, + read: unsafe extern "C" fn(*mut BIO, *mut c_char, c_int) -> c_int, + ) -> c_int; + #[deprecated(note = "use BIO_meth_set_puts__fixed_rust instead")] + #[cfg(any(ossl110, libressl273))] + pub fn BIO_meth_set_puts( + biom: *mut BIO_METHOD, + read: unsafe extern "C" fn(*mut BIO, *const c_char) -> c_int, + ) -> c_int; + #[deprecated(note = "use BIO_meth_set_ctrl__fixed_rust instead")] + #[cfg(any(ossl110, libressl273))] + pub fn BIO_meth_set_ctrl( + biom: *mut BIO_METHOD, + read: unsafe extern "C" fn(*mut BIO, c_int, c_long, *mut c_void) -> c_long, + ) -> c_int; + #[deprecated(note = "use BIO_meth_set_create__fixed_rust instead")] + #[cfg(any(ossl110, libressl273))] + pub fn BIO_meth_set_create( + biom: *mut BIO_METHOD, + create: unsafe extern "C" fn(*mut BIO) -> c_int, + ) -> c_int; + #[deprecated(note = "use BIO_meth_set_destroy__fixed_rust instead")] + #[cfg(any(ossl110, libressl273))] + pub fn BIO_meth_set_destroy( + biom: *mut BIO_METHOD, + destroy: unsafe extern "C" fn(*mut BIO) -> c_int, + ) -> c_int; +} + +cfg_if! { + if #[cfg(ossl320)] { + use std::ptr; + + pub const BIO_CTRL_DGRAM_GET_MTU: c_int = 41; + pub const BIO_CTRL_DGRAM_SET_MTU: c_int = 42; + pub const BIO_CTRL_DGRAM_GET_LOCAL_ADDR_CAP: c_int = 82; + pub const BIO_CTRL_DGRAM_GET_LOCAL_ADDR_ENABLE: c_int = 83; + pub const BIO_CTRL_DGRAM_SET_LOCAL_ADDR_ENABLE: c_int = 84; + pub const BIO_CTRL_DGRAM_GET_CAPS: c_int = 86; + pub const BIO_CTRL_DGRAM_SET_CAPS: c_int = 87; + pub const BIO_CTRL_DGRAM_GET_NO_TRUNC: c_int = 88; + pub const BIO_CTRL_DGRAM_SET_NO_TRUNC: c_int = 89; + + pub unsafe fn BIO_dgram_get_no_trunc(bio: *mut BIO) -> c_int { + BIO_ctrl(bio, BIO_CTRL_DGRAM_GET_NO_TRUNC, 0, ptr::null_mut()) as c_int + } + pub unsafe fn BIO_dgram_set_no_trunc(bio: *mut BIO, enable: c_int) -> c_int { + BIO_ctrl(bio, BIO_CTRL_DGRAM_SET_NO_TRUNC, enable as c_long, ptr::null_mut()) as c_int + } + pub unsafe fn BIO_dgram_get_cap(bio: *mut BIO) -> u32 { + BIO_ctrl(bio, BIO_CTRL_DGRAM_GET_CAPS, 0, ptr::null_mut()) as u32 + } + pub unsafe fn BIO_dgram_set_cap(bio: *mut BIO, cap: u32) -> c_int { + BIO_ctrl(bio, BIO_CTRL_DGRAM_SET_CAPS, cap as c_long, ptr::null_mut()) as c_int + } + pub unsafe fn BIO_dgram_get_local_addr_cap(bio: *mut BIO) -> c_int { + BIO_ctrl(bio, BIO_CTRL_DGRAM_GET_LOCAL_ADDR_CAP, 0, ptr::null_mut()) as c_int + } + pub unsafe fn BIO_dgram_get_local_addr_enable(bio: *mut BIO, enable: *mut c_int) -> c_int { + BIO_ctrl(bio, BIO_CTRL_DGRAM_GET_LOCAL_ADDR_ENABLE, 0, enable as *mut c_void) as c_int + } + pub unsafe fn BIO_dgram_set_local_addr_enable(bio: *mut BIO, enable: c_int) -> c_int { + BIO_ctrl(bio, BIO_CTRL_DGRAM_SET_LOCAL_ADDR_ENABLE, enable as c_long, ptr::null_mut()) as c_int + } + pub unsafe fn BIO_dgram_get_mtu(bio: *mut BIO) -> c_uint { + BIO_ctrl(bio, BIO_CTRL_DGRAM_GET_MTU, 0, ptr::null_mut()) as c_uint + } + pub unsafe fn BIO_dgram_set_mtu(bio: *mut BIO, mtu: c_uint) -> c_int { + BIO_ctrl(bio, BIO_CTRL_DGRAM_SET_MTU, mtu as c_long, ptr::null_mut()) as c_int + } + } +} diff --git a/vendor/openssl-sys/src/bn.rs b/vendor/openssl-sys/src/bn.rs new file mode 100644 index 0000000..a6bbcce --- /dev/null +++ b/vendor/openssl-sys/src/bn.rs @@ -0,0 +1,15 @@ +use libc::*; + +#[cfg(target_pointer_width = "64")] +pub type BN_ULONG = c_ulonglong; +#[cfg(target_pointer_width = "32")] +pub type BN_ULONG = c_uint; + +#[cfg(ossl110)] +pub const BN_FLG_MALLOCED: c_int = 0x01; +#[cfg(ossl110)] +pub const BN_FLG_STATIC_DATA: c_int = 0x02; +#[cfg(ossl110)] +pub const BN_FLG_CONSTTIME: c_int = 0x04; +#[cfg(ossl110)] +pub const BN_FLG_SECURE: c_int = 0x08; diff --git a/vendor/openssl-sys/src/cms.rs b/vendor/openssl-sys/src/cms.rs new file mode 100644 index 0000000..f008adb --- /dev/null +++ b/vendor/openssl-sys/src/cms.rs @@ -0,0 +1,46 @@ +use libc::*; + +#[cfg(ossl101)] +pub const CMS_TEXT: c_uint = 0x1; +#[cfg(ossl101)] +pub const CMS_NOCERTS: c_uint = 0x2; +#[cfg(ossl101)] +pub const CMS_NO_CONTENT_VERIFY: c_uint = 0x4; +#[cfg(ossl101)] +pub const CMS_NO_ATTR_VERIFY: c_uint = 0x8; +#[cfg(ossl101)] +pub const CMS_NOSIGS: c_uint = 0x4 | 0x8; +#[cfg(ossl101)] +pub const CMS_NOINTERN: c_uint = 0x10; +#[cfg(ossl101)] +pub const CMS_NO_SIGNER_CERT_VERIFY: c_uint = 0x20; +#[cfg(ossl101)] +pub const CMS_NOVERIFY: c_uint = 0x20; +#[cfg(ossl101)] +pub const CMS_DETACHED: c_uint = 0x40; +#[cfg(ossl101)] +pub const CMS_BINARY: c_uint = 0x80; +#[cfg(ossl101)] +pub const CMS_NOATTR: c_uint = 0x100; +#[cfg(ossl101)] +pub const CMS_NOSMIMECAP: c_uint = 0x200; +#[cfg(ossl101)] +pub const CMS_NOOLDMIMETYPE: c_uint = 0x400; +#[cfg(ossl101)] +pub const CMS_CRLFEOL: c_uint = 0x800; +#[cfg(ossl101)] +pub const CMS_STREAM: c_uint = 0x1000; +#[cfg(ossl101)] +pub const CMS_NOCRL: c_uint = 0x2000; +#[cfg(ossl101)] +pub const CMS_PARTIAL: c_uint = 0x4000; +#[cfg(ossl101)] +pub const CMS_REUSE_DIGEST: c_uint = 0x8000; +#[cfg(ossl101)] +pub const CMS_USE_KEYID: c_uint = 0x10000; +#[cfg(ossl101)] +pub const CMS_DEBUG_DECRYPT: c_uint = 0x20000; +#[cfg(ossl102)] +pub const CMS_KEY_PARAM: c_uint = 0x40000; +#[cfg(ossl110)] +pub const CMS_ASCIICRLF: c_uint = 0x80000; diff --git a/vendor/openssl-sys/src/crypto.rs b/vendor/openssl-sys/src/crypto.rs new file mode 100644 index 0000000..7eff6a8 --- /dev/null +++ b/vendor/openssl-sys/src/crypto.rs @@ -0,0 +1,134 @@ +use super::*; +use libc::*; + +extern "C" { + #[deprecated(note = "use CRYPTO_set_locking_callback__fixed_rust instead")] + #[cfg(not(ossl110))] + pub fn CRYPTO_set_locking_callback( + func: unsafe extern "C" fn(mode: c_int, n: c_int, file: *const c_char, line: c_int), + ); + + #[deprecated(note = "use CRYPTO_set_id_callback__fixed_rust instead")] + #[cfg(not(ossl110))] + pub fn CRYPTO_set_id_callback(func: unsafe extern "C" fn() -> c_ulong); +} + +cfg_if! { + if #[cfg(ossl110)] { + type CRYPTO_EX_new_ret = (); + type CRYPTO_EX_dup_from = *const CRYPTO_EX_DATA; + } else { + type CRYPTO_EX_new_ret = c_int; + type CRYPTO_EX_dup_from = *mut CRYPTO_EX_DATA; + } +} + +cfg_if! { + if #[cfg(ossl300)] { + type CRYPTO_EX_dup_from_d = *mut *mut c_void; + } else { + type CRYPTO_EX_dup_from_d = *mut c_void; + } +} + +// FIXME should be options +pub type CRYPTO_EX_new = unsafe extern "C" fn( + parent: *mut c_void, + ptr: *mut c_void, + ad: *mut CRYPTO_EX_DATA, + idx: c_int, + argl: c_long, + argp: *mut c_void, +) -> CRYPTO_EX_new_ret; +pub type CRYPTO_EX_dup = unsafe extern "C" fn( + to: *mut CRYPTO_EX_DATA, + from: CRYPTO_EX_dup_from, + from_d: CRYPTO_EX_dup_from_d, + idx: c_int, + argl: c_long, + argp: *mut c_void, +) -> c_int; +pub type CRYPTO_EX_free = unsafe extern "C" fn( + parent: *mut c_void, + ptr: *mut c_void, + ad: *mut CRYPTO_EX_DATA, + idx: c_int, + argl: c_long, + argp: *mut c_void, +); + +#[cfg(any(ossl110, libressl390))] +#[inline] +#[track_caller] +pub unsafe fn OPENSSL_malloc(num: usize) -> *mut c_void { + CRYPTO_malloc( + num, + concat!(file!(), "\0").as_ptr() as *const _, + line!() as _, + ) +} + +#[cfg(not(any(ossl110, libressl390)))] +#[inline] +#[track_caller] +pub unsafe fn OPENSSL_malloc(num: c_int) -> *mut c_void { + CRYPTO_malloc( + num, + concat!(file!(), "\0").as_ptr() as *const _, + line!() as _, + ) +} + +#[cfg(any(ossl110, libressl390))] +#[inline] +#[track_caller] +pub unsafe fn OPENSSL_free(addr: *mut c_void) { + CRYPTO_free( + addr, + concat!(file!(), "\0").as_ptr() as *const _, + line!() as _, + ) +} + +#[cfg(not(any(ossl110, libressl390)))] +#[inline] +pub unsafe fn OPENSSL_free(addr: *mut c_void) { + CRYPTO_free(addr) +} + +#[cfg(not(ossl110))] +pub const CRYPTO_LOCK_X509: c_int = 3; +#[cfg(not(ossl110))] +pub const CRYPTO_LOCK_EVP_PKEY: c_int = 10; +#[cfg(not(ossl110))] +pub const CRYPTO_LOCK_SSL_CTX: c_int = 12; +#[cfg(not(ossl110))] +pub const CRYPTO_LOCK_SSL_SESSION: c_int = 14; + +cfg_if! { + if #[cfg(any(ossl110, libressl381))] { + pub const CRYPTO_EX_INDEX_SSL: c_int = 0; + pub const CRYPTO_EX_INDEX_SSL_CTX: c_int = 1; + } else if #[cfg(libressl)] { + pub const CRYPTO_EX_INDEX_SSL: c_int = 1; + pub const CRYPTO_EX_INDEX_SSL_CTX: c_int = 2; + } +} + +cfg_if! { + if #[cfg(any(ossl110, libressl271))] { + pub const OPENSSL_VERSION: c_int = 0; + pub const OPENSSL_CFLAGS: c_int = 1; + pub const OPENSSL_BUILT_ON: c_int = 2; + pub const OPENSSL_PLATFORM: c_int = 3; + pub const OPENSSL_DIR: c_int = 4; + } else { + pub const SSLEAY_VERSION: c_int = 0; + pub const SSLEAY_CFLAGS: c_int = 2; + pub const SSLEAY_BUILT_ON: c_int = 3; + pub const SSLEAY_PLATFORM: c_int = 4; + pub const SSLEAY_DIR: c_int = 5; + } +} + +pub const CRYPTO_LOCK: c_int = 1; diff --git a/vendor/openssl-sys/src/dtls1.rs b/vendor/openssl-sys/src/dtls1.rs new file mode 100644 index 0000000..9ef5e77 --- /dev/null +++ b/vendor/openssl-sys/src/dtls1.rs @@ -0,0 +1,9 @@ +use libc::*; + +cfg_if! { + if #[cfg(ossl300)] { + pub const DTLS1_COOKIE_LENGTH: c_uint = 255; + } else { + pub const DTLS1_COOKIE_LENGTH: c_uint = 256; + } +} diff --git a/vendor/openssl-sys/src/ec.rs b/vendor/openssl-sys/src/ec.rs new file mode 100644 index 0000000..995a84f --- /dev/null +++ b/vendor/openssl-sys/src/ec.rs @@ -0,0 +1,16 @@ +use libc::*; +use std::ptr; + +use super::*; + +pub const OPENSSL_EC_NAMED_CURVE: c_int = 1; + +#[cfg(ossl300)] +pub unsafe fn EVP_EC_gen(curve: *const c_char) -> *mut EVP_PKEY { + EVP_PKEY_Q_keygen( + ptr::null_mut(), + ptr::null_mut(), + "EC\0".as_ptr().cast(), + curve, + ) +} diff --git a/vendor/openssl-sys/src/err.rs b/vendor/openssl-sys/src/err.rs new file mode 100644 index 0000000..a2c0f0f --- /dev/null +++ b/vendor/openssl-sys/src/err.rs @@ -0,0 +1,66 @@ +use libc::*; + +pub const ERR_TXT_MALLOCED: c_int = 0x01; +pub const ERR_TXT_STRING: c_int = 0x02; + +pub const ERR_LIB_SYS: c_int = 2; +pub const ERR_LIB_PEM: c_int = 9; +pub const ERR_LIB_ASN1: c_int = 13; + +cfg_if! { + if #[cfg(ossl300)] { + pub const ERR_SYSTEM_FLAG: c_ulong = c_int::MAX as c_ulong + 1; + pub const ERR_SYSTEM_MASK: c_ulong = c_int::MAX as c_ulong; + + pub const ERR_LIB_OFFSET: c_ulong = 23; + pub const ERR_LIB_MASK: c_ulong = 0xff; + pub const ERR_RFLAGS_OFFSET: c_ulong = 18; + pub const ERR_RFLAGS_MASK: c_ulong = 0x1f; + pub const ERR_REASON_MASK: c_ulong = 0x7FFFFF; + + pub const ERR_RFLAG_FATAL: c_ulong = 0x1 << ERR_RFLAGS_OFFSET; + + pub const fn ERR_SYSTEM_ERROR(errcode: c_ulong) -> bool { + errcode & ERR_SYSTEM_FLAG != 0 + } + + pub const fn ERR_GET_LIB(errcode: c_ulong) -> c_int { + // hacks since `if` isn't yet stable in const functions :( + ((ERR_LIB_SYS as c_ulong * (ERR_SYSTEM_ERROR(errcode) as c_ulong)) | + (((errcode >> ERR_LIB_OFFSET) & ERR_LIB_MASK) * (!ERR_SYSTEM_ERROR(errcode) as c_ulong))) as c_int + } + + pub const fn ERR_GET_FUNC(_errcode: c_ulong) -> c_int { + 0 + } + + pub const fn ERR_GET_REASON(errcode: c_ulong) -> c_int { + // hacks since `if` isn't yet stable in const functions :( + ((ERR_LIB_SYS as c_ulong * (ERR_SYSTEM_ERROR(errcode) as c_ulong)) | + ((errcode & ERR_REASON_MASK) * (!ERR_SYSTEM_ERROR(errcode) as c_ulong))) as c_int + } + + pub const fn ERR_PACK(lib: c_int, _func: c_int, reason: c_int) -> c_ulong { + ((lib as c_ulong & ERR_LIB_MASK) << ERR_LIB_OFFSET) | + (reason as c_ulong & ERR_REASON_MASK) + } + } else { + pub const fn ERR_PACK(l: c_int, f: c_int, r: c_int) -> c_ulong { + ((l as c_ulong & 0x0FF) << 24) | + ((f as c_ulong & 0xFFF) << 12) | + (r as c_ulong & 0xFFF) + } + + pub const fn ERR_GET_LIB(l: c_ulong) -> c_int { + ((l >> 24) & 0x0FF) as c_int + } + + pub const fn ERR_GET_FUNC(l: c_ulong) -> c_int { + ((l >> 12) & 0xFFF) as c_int + } + + pub const fn ERR_GET_REASON(l: c_ulong) -> c_int { + (l & 0xFFF) as c_int + } + } +} diff --git a/vendor/openssl-sys/src/evp.rs b/vendor/openssl-sys/src/evp.rs new file mode 100644 index 0000000..4d26f0f --- /dev/null +++ b/vendor/openssl-sys/src/evp.rs @@ -0,0 +1,342 @@ +use super::*; +use libc::*; + +pub const EVP_MAX_MD_SIZE: c_uint = 64; + +pub const PKCS5_SALT_LEN: c_int = 8; +pub const PKCS12_DEFAULT_ITER: c_int = 2048; + +pub const EVP_PKEY_RSA: c_int = NID_rsaEncryption; +#[cfg(any(ossl111, libressl310, boringssl))] +pub const EVP_PKEY_RSA_PSS: c_int = NID_rsassaPss; +pub const EVP_PKEY_DSA: c_int = NID_dsa; +pub const EVP_PKEY_DH: c_int = NID_dhKeyAgreement; +#[cfg(ossl110)] +pub const EVP_PKEY_DHX: c_int = NID_dhpublicnumber; +pub const EVP_PKEY_EC: c_int = NID_X9_62_id_ecPublicKey; +#[cfg(ossl111)] +pub const EVP_PKEY_SM2: c_int = NID_sm2; +#[cfg(any(ossl111, libressl370))] +pub const EVP_PKEY_X25519: c_int = NID_X25519; +#[cfg(any(ossl111, libressl370))] +pub const EVP_PKEY_ED25519: c_int = NID_ED25519; +#[cfg(ossl111)] +pub const EVP_PKEY_X448: c_int = NID_X448; +#[cfg(ossl111)] +pub const EVP_PKEY_ED448: c_int = NID_ED448; +pub const EVP_PKEY_HMAC: c_int = NID_hmac; +pub const EVP_PKEY_CMAC: c_int = NID_cmac; +#[cfg(ossl111)] +pub const EVP_PKEY_POLY1305: c_int = NID_poly1305; +#[cfg(any(ossl110, libressl360))] +pub const EVP_PKEY_HKDF: c_int = NID_hkdf; + +#[cfg(ossl102)] +pub const EVP_CIPHER_CTX_FLAG_WRAP_ALLOW: c_int = 0x1; + +pub const EVP_CTRL_GCM_SET_IVLEN: c_int = 0x9; +pub const EVP_CTRL_GCM_GET_TAG: c_int = 0x10; +pub const EVP_CTRL_GCM_SET_TAG: c_int = 0x11; + +pub unsafe fn EVP_get_digestbynid(type_: c_int) -> *const EVP_MD { + EVP_get_digestbyname(OBJ_nid2sn(type_)) +} + +cfg_if! { + if #[cfg(ossl300)] { + #[inline] + pub unsafe fn EVP_MD_CTX_md(ctx: *const EVP_MD_CTX) -> *const EVP_MD { + EVP_MD_CTX_get0_md(ctx) + } + + #[inline] + pub unsafe fn EVP_MD_CTX_get_size(ctx: *const EVP_MD_CTX) -> c_int { + EVP_MD_get_size(EVP_MD_CTX_get0_md(ctx)) + } + + #[inline] + pub unsafe fn EVP_MD_CTX_size(ctx: *const EVP_MD_CTX) -> c_int { + EVP_MD_CTX_get_size(ctx) + } + + #[inline] + pub unsafe fn EVP_MD_block_size(md: *const EVP_MD) -> c_int { + EVP_MD_get_block_size(md) + } + + #[inline] + pub unsafe fn EVP_MD_size(md: *const EVP_MD) -> c_int { + EVP_MD_get_size(md) + } + + #[inline] + pub unsafe fn EVP_MD_type(md: *const EVP_MD) -> c_int { + EVP_MD_get_type(md) + } + + #[inline] + pub unsafe fn EVP_CIPHER_key_length(cipher: *const EVP_CIPHER) -> c_int { + EVP_CIPHER_get_key_length(cipher) + } + + #[inline] + pub unsafe fn EVP_CIPHER_block_size(cipher: *const EVP_CIPHER) -> c_int { + EVP_CIPHER_get_block_size(cipher) + } + + #[inline] + pub unsafe fn EVP_CIPHER_iv_length(cipher: *const EVP_CIPHER) -> c_int { + EVP_CIPHER_get_iv_length(cipher) + } + + #[inline] + pub unsafe fn EVP_CIPHER_nid(cipher: *const EVP_CIPHER) -> c_int { + EVP_CIPHER_get_nid(cipher) + } + + #[inline] + pub unsafe fn EVP_CIPHER_CTX_block_size(ctx: *const EVP_CIPHER_CTX) -> c_int { + EVP_CIPHER_CTX_get_block_size(ctx) + } + + #[inline] + pub unsafe fn EVP_CIPHER_CTX_key_length(ctx: *const EVP_CIPHER_CTX) -> c_int { + EVP_CIPHER_CTX_get_key_length(ctx) + } + + #[inline] + pub unsafe fn EVP_CIPHER_CTX_iv_length(ctx: *const EVP_CIPHER_CTX) -> c_int { + EVP_CIPHER_CTX_get_iv_length(ctx) + } + + #[inline] + pub unsafe fn EVP_CIPHER_CTX_num(ctx: *const EVP_CIPHER_CTX) -> c_int { + EVP_CIPHER_CTX_get_num(ctx) + } + } else { + pub unsafe fn EVP_MD_CTX_size(ctx: *const EVP_MD_CTX) -> c_int { + EVP_MD_size(EVP_MD_CTX_md(ctx)) + } + } +} +#[cfg(not(ossl300))] +#[inline] +pub unsafe fn EVP_DigestSignUpdate( + ctx: *mut EVP_MD_CTX, + data: *const c_void, + dsize: size_t, +) -> c_int { + EVP_DigestUpdate(ctx, data, dsize) +} +#[cfg(not(ossl300))] +#[inline] +pub unsafe fn EVP_DigestVerifyUpdate( + ctx: *mut EVP_MD_CTX, + data: *const c_void, + dsize: size_t, +) -> c_int { + EVP_DigestUpdate(ctx, data, dsize) +} +#[cfg(ossl300)] +#[inline] +pub unsafe fn EVP_PKEY_size(pkey: *const EVP_PKEY) -> c_int { + EVP_PKEY_get_size(pkey) +} + +cfg_if! { + if #[cfg(ossl300)] { + #[inline] + pub unsafe fn EVP_PKEY_id(pkey: *const EVP_PKEY) -> c_int { + EVP_PKEY_get_id(pkey) + } + + #[inline] + pub unsafe fn EVP_PKEY_bits(pkey: *const EVP_PKEY) -> c_int { + EVP_PKEY_get_bits(pkey) + } + + #[inline] + pub unsafe fn EVP_PKEY_security_bits(pkey: *const EVP_PKEY) -> c_int { + EVP_PKEY_get_security_bits(pkey) + } + } +} + +pub const EVP_PKEY_OP_KEYGEN: c_int = 1 << 2; +cfg_if! { + if #[cfg(ossl300)] { + pub const EVP_PKEY_OP_SIGN: c_int = 1 << 4; + pub const EVP_PKEY_OP_VERIFY: c_int = 1 << 5; + pub const EVP_PKEY_OP_VERIFYRECOVER: c_int = 1 << 6; + pub const EVP_PKEY_OP_SIGNCTX: c_int = 1 << 7; + pub const EVP_PKEY_OP_VERIFYCTX: c_int = 1 << 8; + pub const EVP_PKEY_OP_ENCRYPT: c_int = 1 << 9; + pub const EVP_PKEY_OP_DECRYPT: c_int = 1 << 10; + pub const EVP_PKEY_OP_DERIVE: c_int = 1 << 11; + } else { + pub const EVP_PKEY_OP_SIGN: c_int = 1 << 3; + pub const EVP_PKEY_OP_VERIFY: c_int = 1 << 4; + pub const EVP_PKEY_OP_VERIFYRECOVER: c_int = 1 << 5; + pub const EVP_PKEY_OP_SIGNCTX: c_int = 1 << 6; + pub const EVP_PKEY_OP_VERIFYCTX: c_int = 1 << 7; + pub const EVP_PKEY_OP_ENCRYPT: c_int = 1 << 8; + pub const EVP_PKEY_OP_DECRYPT: c_int = 1 << 9; + pub const EVP_PKEY_OP_DERIVE: c_int = 1 << 10; + } +} +#[cfg(ossl340)] +pub const EVP_PKEY_OP_SIGNMSG: c_int = 1 << 14; +#[cfg(ossl340)] +pub const EVP_PKEY_OP_VERIFYMSG: c_int = 1 << 15; + +cfg_if! { + if #[cfg(ossl340)] { + pub const EVP_PKEY_OP_TYPE_SIG: c_int = EVP_PKEY_OP_SIGN + | EVP_PKEY_OP_SIGNMSG + | EVP_PKEY_OP_VERIFY + | EVP_PKEY_OP_VERIFYMSG + | EVP_PKEY_OP_VERIFYRECOVER + | EVP_PKEY_OP_SIGNCTX + | EVP_PKEY_OP_VERIFYCTX; + } else { + pub const EVP_PKEY_OP_TYPE_SIG: c_int = EVP_PKEY_OP_SIGN + | EVP_PKEY_OP_VERIFY + | EVP_PKEY_OP_VERIFYRECOVER + | EVP_PKEY_OP_SIGNCTX + | EVP_PKEY_OP_VERIFYCTX; + } +} + +pub const EVP_PKEY_OP_TYPE_CRYPT: c_int = EVP_PKEY_OP_ENCRYPT | EVP_PKEY_OP_DECRYPT; + +pub const EVP_PKEY_CTRL_MD: c_int = 1; + +pub const EVP_PKEY_CTRL_SET_MAC_KEY: c_int = 6; + +pub const EVP_PKEY_CTRL_CIPHER: c_int = 12; + +pub const EVP_PKEY_ALG_CTRL: c_int = 0x1000; + +#[cfg(any(ossl111, libressl360))] +pub const EVP_PKEY_HKDEF_MODE_EXTRACT_AND_EXPAND: c_int = 0; + +#[cfg(any(ossl111, libressl360))] +pub const EVP_PKEY_HKDEF_MODE_EXTRACT_ONLY: c_int = 1; + +#[cfg(any(ossl111, libressl360))] +pub const EVP_PKEY_HKDEF_MODE_EXPAND_ONLY: c_int = 2; + +#[cfg(any(ossl110, libressl360))] +pub const EVP_PKEY_CTRL_HKDF_MD: c_int = EVP_PKEY_ALG_CTRL + 3; + +#[cfg(any(ossl110, libressl360))] +pub const EVP_PKEY_CTRL_HKDF_SALT: c_int = EVP_PKEY_ALG_CTRL + 4; + +#[cfg(any(ossl110, libressl360))] +pub const EVP_PKEY_CTRL_HKDF_KEY: c_int = EVP_PKEY_ALG_CTRL + 5; + +#[cfg(any(ossl110, libressl360))] +pub const EVP_PKEY_CTRL_HKDF_INFO: c_int = EVP_PKEY_ALG_CTRL + 6; + +#[cfg(any(ossl111, libressl360))] +pub const EVP_PKEY_CTRL_HKDF_MODE: c_int = EVP_PKEY_ALG_CTRL + 7; + +#[cfg(any(all(ossl111, not(ossl300)), libressl360))] +pub unsafe fn EVP_PKEY_CTX_set_hkdf_mode(ctx: *mut EVP_PKEY_CTX, mode: c_int) -> c_int { + EVP_PKEY_CTX_ctrl( + ctx, + -1, + EVP_PKEY_OP_DERIVE, + EVP_PKEY_CTRL_HKDF_MODE, + mode, + std::ptr::null_mut(), + ) +} + +#[cfg(any(all(ossl110, not(ossl300)), libressl360))] +pub unsafe fn EVP_PKEY_CTX_set_hkdf_md(ctx: *mut EVP_PKEY_CTX, md: *const EVP_MD) -> c_int { + EVP_PKEY_CTX_ctrl( + ctx, + -1, + EVP_PKEY_OP_DERIVE, + EVP_PKEY_CTRL_HKDF_MD, + 0, + md as *mut c_void, + ) +} + +#[cfg(any(all(ossl110, not(ossl300)), libressl360))] +pub unsafe fn EVP_PKEY_CTX_set1_hkdf_salt( + ctx: *mut EVP_PKEY_CTX, + salt: *const u8, + saltlen: c_int, +) -> c_int { + EVP_PKEY_CTX_ctrl( + ctx, + -1, + EVP_PKEY_OP_DERIVE, + EVP_PKEY_CTRL_HKDF_SALT, + saltlen, + salt as *mut c_void, + ) +} + +#[cfg(any(all(ossl110, not(ossl300)), libressl360))] +pub unsafe fn EVP_PKEY_CTX_set1_hkdf_key( + ctx: *mut EVP_PKEY_CTX, + key: *const u8, + keylen: c_int, +) -> c_int { + EVP_PKEY_CTX_ctrl( + ctx, + -1, + EVP_PKEY_OP_DERIVE, + EVP_PKEY_CTRL_HKDF_KEY, + keylen, + key as *mut c_void, + ) +} + +#[cfg(any(all(ossl110, not(ossl300)), libressl360))] +pub unsafe fn EVP_PKEY_CTX_add1_hkdf_info( + ctx: *mut EVP_PKEY_CTX, + info: *const u8, + infolen: c_int, +) -> c_int { + EVP_PKEY_CTX_ctrl( + ctx, + -1, + EVP_PKEY_OP_DERIVE, + EVP_PKEY_CTRL_HKDF_INFO, + infolen, + info as *mut c_void, + ) +} + +#[cfg(all(not(ossl300), not(boringssl)))] +pub unsafe fn EVP_PKEY_CTX_set_signature_md(cxt: *mut EVP_PKEY_CTX, md: *mut EVP_MD) -> c_int { + EVP_PKEY_CTX_ctrl( + cxt, + -1, + EVP_PKEY_OP_TYPE_SIG, + EVP_PKEY_CTRL_MD, + 0, + md as *mut c_void, + ) +} + +pub unsafe fn EVP_PKEY_assign_RSA(pkey: *mut EVP_PKEY, rsa: *mut RSA) -> c_int { + EVP_PKEY_assign(pkey, EVP_PKEY_RSA, rsa as *mut c_void) +} + +pub unsafe fn EVP_PKEY_assign_DSA(pkey: *mut EVP_PKEY, dsa: *mut DSA) -> c_int { + EVP_PKEY_assign(pkey, EVP_PKEY_DSA, dsa as *mut c_void) +} + +pub unsafe fn EVP_PKEY_assign_DH(pkey: *mut EVP_PKEY, dh: *mut DH) -> c_int { + EVP_PKEY_assign(pkey, EVP_PKEY_DH, dh as *mut c_void) +} + +pub unsafe fn EVP_PKEY_assign_EC_KEY(pkey: *mut EVP_PKEY, ec_key: *mut EC_KEY) -> c_int { + EVP_PKEY_assign(pkey, EVP_PKEY_EC, ec_key as *mut c_void) +} diff --git a/vendor/openssl-sys/src/handwritten/aes.rs b/vendor/openssl-sys/src/handwritten/aes.rs new file mode 100644 index 0000000..ba24936 --- /dev/null +++ b/vendor/openssl-sys/src/handwritten/aes.rs @@ -0,0 +1,40 @@ +use super::super::*; +use libc::*; + +#[repr(C)] +pub struct AES_KEY { + // There is some business with AES_LONG which is there to ensure the values here are 32 bits + rd_key: [u32; 4 * (AES_MAXNR as usize + 1)], + rounds: c_int, +} + +extern "C" { + pub fn AES_set_encrypt_key(userKey: *const c_uchar, bits: c_int, key: *mut AES_KEY) -> c_int; + pub fn AES_set_decrypt_key(userKey: *const c_uchar, bits: c_int, key: *mut AES_KEY) -> c_int; + + #[cfg(not(osslconf = "OPENSSL_NO_DEPRECATED_3_0"))] + pub fn AES_ige_encrypt( + in_: *const c_uchar, + out: *mut c_uchar, + length: size_t, + key: *const AES_KEY, + ivec: *mut c_uchar, + enc: c_int, + ); + + pub fn AES_wrap_key( + key: *mut AES_KEY, + iv: *const c_uchar, + out: *mut c_uchar, + in_: *const c_uchar, + inlen: c_uint, + ) -> c_int; + + pub fn AES_unwrap_key( + key: *mut AES_KEY, + iv: *const c_uchar, + out: *mut c_uchar, + in_: *const c_uchar, + inlen: c_uint, + ) -> c_int; +} diff --git a/vendor/openssl-sys/src/handwritten/asn1.rs b/vendor/openssl-sys/src/handwritten/asn1.rs new file mode 100644 index 0000000..16ffccc --- /dev/null +++ b/vendor/openssl-sys/src/handwritten/asn1.rs @@ -0,0 +1,115 @@ +use super::super::*; +use libc::*; + +#[repr(C)] +pub struct ASN1_ENCODING { + pub enc: *mut c_uchar, + pub len: c_long, + pub modified: c_int, +} + +extern "C" { + pub fn ASN1_OBJECT_free(x: *mut ASN1_OBJECT); + pub fn OBJ_dup(x: *const ASN1_OBJECT) -> *mut ASN1_OBJECT; +} + +stack!(stack_st_ASN1_OBJECT); + +#[repr(C)] +pub struct ASN1_TYPE { + pub type_: c_int, + pub value: ASN1_TYPE_value, +} +#[repr(C)] +pub union ASN1_TYPE_value { + pub ptr: *mut c_char, + pub boolean: ASN1_BOOLEAN, + pub asn1_string: *mut ASN1_STRING, + pub object: *mut ASN1_OBJECT, + pub integer: *mut ASN1_INTEGER, + pub enumerated: *mut ASN1_ENUMERATED, + pub bit_string: *mut ASN1_BIT_STRING, + pub octet_string: *mut ASN1_OCTET_STRING, + pub printablestring: *mut ASN1_PRINTABLESTRING, + pub t61string: *mut ASN1_T61STRING, + pub ia5string: *mut ASN1_IA5STRING, + pub generalstring: *mut ASN1_GENERALSTRING, + pub bmpstring: *mut ASN1_BMPSTRING, + pub universalstring: *mut ASN1_UNIVERSALSTRING, + pub utctime: *mut ASN1_UTCTIME, + pub generalizedtime: *mut ASN1_GENERALIZEDTIME, + pub visiblestring: *mut ASN1_VISIBLESTRING, + pub utf8string: *mut ASN1_UTF8STRING, + pub set: *mut ASN1_STRING, + pub sequence: *mut ASN1_STRING, + pub asn1_value: *mut ASN1_VALUE, +} + +extern "C" { + pub fn ASN1_STRING_type_new(ty: c_int) -> *mut ASN1_STRING; + #[cfg(any(ossl110, libressl273))] + pub fn ASN1_STRING_get0_data(x: *const ASN1_STRING) -> *const c_uchar; + #[cfg(any(all(ossl101, not(ossl110)), libressl))] + pub fn ASN1_STRING_data(x: *mut ASN1_STRING) -> *mut c_uchar; + pub fn ASN1_STRING_new() -> *mut ASN1_STRING; + pub fn ASN1_OCTET_STRING_new() -> *mut ASN1_OCTET_STRING; + pub fn ASN1_STRING_free(x: *mut ASN1_STRING); + pub fn ASN1_STRING_length(x: *const ASN1_STRING) -> c_int; + pub fn ASN1_STRING_set(x: *mut ASN1_STRING, data: *const c_void, len_in: c_int) -> c_int; + pub fn ASN1_OCTET_STRING_set( + x: *mut ASN1_OCTET_STRING, + data: *const c_uchar, + len_in: c_int, + ) -> c_int; + + pub fn ASN1_BIT_STRING_free(x: *mut ASN1_BIT_STRING); + pub fn ASN1_OCTET_STRING_free(x: *mut ASN1_OCTET_STRING); + + pub fn ASN1_GENERALIZEDTIME_free(tm: *mut ASN1_GENERALIZEDTIME); + pub fn ASN1_GENERALIZEDTIME_print(b: *mut BIO, tm: *const ASN1_GENERALIZEDTIME) -> c_int; + pub fn ASN1_TIME_new() -> *mut ASN1_TIME; + #[cfg(ossl102)] + pub fn ASN1_TIME_diff( + pday: *mut c_int, + psec: *mut c_int, + from: *const ASN1_TIME, + to: *const ASN1_TIME, + ) -> c_int; + pub fn ASN1_TIME_free(tm: *mut ASN1_TIME); + pub fn ASN1_TIME_print(b: *mut BIO, tm: *const ASN1_TIME) -> c_int; + pub fn ASN1_TIME_set(from: *mut ASN1_TIME, to: time_t) -> *mut ASN1_TIME; + + pub fn ASN1_INTEGER_free(x: *mut ASN1_INTEGER); + pub fn ASN1_INTEGER_dup(a: *const ASN1_INTEGER) -> *mut ASN1_INTEGER; + pub fn ASN1_INTEGER_get(dest: *const ASN1_INTEGER) -> c_long; + pub fn ASN1_INTEGER_set(dest: *mut ASN1_INTEGER, value: c_long) -> c_int; + pub fn ASN1_INTEGER_cmp(a: *const ASN1_INTEGER, b: *const ASN1_INTEGER) -> c_int; + pub fn BN_to_ASN1_INTEGER(bn: *const BIGNUM, ai: *mut ASN1_INTEGER) -> *mut ASN1_INTEGER; + pub fn ASN1_INTEGER_to_BN(ai: *const ASN1_INTEGER, bn: *mut BIGNUM) -> *mut BIGNUM; + + pub fn ASN1_TIME_set_string(s: *mut ASN1_TIME, str: *const c_char) -> c_int; + #[cfg(ossl111)] + pub fn ASN1_TIME_set_string_X509(s: *mut ASN1_TIME, str: *const c_char) -> c_int; + + pub fn ASN1_ENUMERATED_free(a: *mut ASN1_ENUMERATED); + #[cfg(ossl110)] + pub fn ASN1_ENUMERATED_get_int64(pr: *mut i64, a: *const ASN1_ENUMERATED) -> c_int; + + pub fn ASN1_TYPE_new() -> *mut ASN1_TYPE; + pub fn ASN1_TYPE_set(a: *mut ASN1_TYPE, type_: c_int, value: *mut c_void); + pub fn ASN1_TYPE_free(x: *mut ASN1_TYPE); + pub fn d2i_ASN1_TYPE( + k: *mut *mut ASN1_TYPE, + buf: *mut *const u8, + len: c_long, + ) -> *mut ASN1_TYPE; +} + +const_ptr_api! { + extern "C" { + pub fn ASN1_STRING_to_UTF8(out: *mut *mut c_uchar, s: #[const_ptr_if(any(ossl110, libressl280))] ASN1_STRING) -> c_int; + pub fn ASN1_STRING_type(x: #[const_ptr_if(any(ossl110, libressl280))] ASN1_STRING) -> c_int; + pub fn ASN1_generate_v3(str: #[const_ptr_if(any(ossl110, libressl280))] c_char, cnf: *mut X509V3_CTX) -> *mut ASN1_TYPE; + pub fn i2d_ASN1_TYPE(a: #[const_ptr_if(ossl300)] ASN1_TYPE, pp: *mut *mut c_uchar) -> c_int; + } +} diff --git a/vendor/openssl-sys/src/handwritten/bio.rs b/vendor/openssl-sys/src/handwritten/bio.rs new file mode 100644 index 0000000..9461d71 --- /dev/null +++ b/vendor/openssl-sys/src/handwritten/bio.rs @@ -0,0 +1,165 @@ +use super::super::*; +use libc::*; + +extern "C" { + pub fn BIO_set_flags(b: *mut BIO, flags: c_int); + pub fn BIO_clear_flags(b: *mut BIO, flags: c_int); +} + +pub type bio_info_cb = + Option; + +cfg_if! { + if #[cfg(any(ossl110, libressl280))] { + pub enum BIO_METHOD {} + } else { + #[repr(C)] + pub struct BIO_METHOD { + pub type_: c_int, + pub name: *const c_char, + pub bwrite: Option c_int>, + pub bread: Option c_int>, + pub bputs: Option c_int>, + pub bgets: Option c_int>, + pub ctrl: Option c_long>, + pub create: Option c_int>, + pub destroy: Option c_int>, + pub callback_ctrl: Option c_long>, + } + } +} + +const_ptr_api! { + extern "C" { + pub fn BIO_s_file() -> #[const_ptr_if(any(ossl110, libressl280))] BIO_METHOD; + pub fn BIO_new(type_: #[const_ptr_if(any(ossl110, libressl280))] BIO_METHOD) -> *mut BIO; + } +} +extern "C" { + #[cfg(not(osslconf = "OPENSSL_NO_STDIO"))] + pub fn BIO_new_fp(stream: *mut FILE, close_flag: c_int) -> *mut BIO; + #[cfg(any(ossl110, libressl273))] + pub fn BIO_set_data(a: *mut BIO, data: *mut c_void); + #[cfg(any(ossl110, libressl273))] + pub fn BIO_get_data(a: *mut BIO) -> *mut c_void; + #[cfg(any(ossl110, libressl273))] + pub fn BIO_set_init(a: *mut BIO, init: c_int); + pub fn BIO_write(b: *mut BIO, buf: *const c_void, len: c_int) -> c_int; + pub fn BIO_read(b: *mut BIO, buf: *mut c_void, len: c_int) -> c_int; + pub fn BIO_ctrl(b: *mut BIO, cmd: c_int, larg: c_long, parg: *mut c_void) -> c_long; + pub fn BIO_free_all(b: *mut BIO); +} + +const_ptr_api! { + extern "C" { + pub fn BIO_s_mem() -> #[const_ptr_if(any(ossl110, libressl280))] BIO_METHOD; + pub fn BIO_new_mem_buf(buf: #[const_ptr_if(any(ossl102, libressl280))] c_void, len: c_int) -> *mut BIO; + } +} + +extern "C" { + #[cfg(not(osslconf = "OPENSSL_NO_SOCK"))] + pub fn BIO_new_socket(sock: c_int, close_flag: c_int) -> *mut BIO; + + #[cfg(any(ossl110, libressl273))] + pub fn BIO_meth_new(type_: c_int, name: *const c_char) -> *mut BIO_METHOD; + #[cfg(any(ossl110, libressl273))] + pub fn BIO_meth_free(biom: *mut BIO_METHOD); +} + +#[allow(clashing_extern_declarations)] +extern "C" { + #[cfg(any(ossl110, libressl273))] + #[link_name = "BIO_meth_set_write"] + pub fn BIO_meth_set_write__fixed_rust( + biom: *mut BIO_METHOD, + write: Option c_int>, + ) -> c_int; + #[cfg(any(ossl110, libressl273))] + #[link_name = "BIO_meth_set_read"] + pub fn BIO_meth_set_read__fixed_rust( + biom: *mut BIO_METHOD, + read: Option c_int>, + ) -> c_int; + #[cfg(any(ossl110, libressl273))] + #[link_name = "BIO_meth_set_puts"] + pub fn BIO_meth_set_puts__fixed_rust( + biom: *mut BIO_METHOD, + read: Option c_int>, + ) -> c_int; + #[cfg(any(ossl110, libressl273))] + #[link_name = "BIO_meth_set_ctrl"] + pub fn BIO_meth_set_ctrl__fixed_rust( + biom: *mut BIO_METHOD, + read: Option c_long>, + ) -> c_int; + #[cfg(any(ossl110, libressl273))] + #[link_name = "BIO_meth_set_create"] + pub fn BIO_meth_set_create__fixed_rust( + biom: *mut BIO_METHOD, + create: Option c_int>, + ) -> c_int; + #[cfg(any(ossl110, libressl273))] + #[link_name = "BIO_meth_set_destroy"] + pub fn BIO_meth_set_destroy__fixed_rust( + biom: *mut BIO_METHOD, + destroy: Option c_int>, + ) -> c_int; +} + +#[cfg(ossl320)] +extern "C" { + pub fn BIO_meth_set_sendmmsg( + biom: *mut BIO_METHOD, + f: Option< + unsafe extern "C" fn( + arg1: *mut BIO, + arg2: *mut BIO_MSG, + arg3: usize, + arg4: usize, + arg5: u64, + arg6: *mut usize, + ) -> c_int, + >, + ) -> c_int; + pub fn BIO_meth_set_recvmmsg( + biom: *mut BIO_METHOD, + f: Option< + unsafe extern "C" fn( + arg1: *mut BIO, + arg2: *mut BIO_MSG, + arg3: usize, + arg4: usize, + arg5: u64, + arg6: *mut usize, + ) -> c_int, + >, + ) -> c_int; + pub fn BIO_new_bio_dgram_pair( + bio1: *mut *mut BIO, + writebuf1: usize, + bio2: *mut *mut BIO, + writebuf2: usize, + ) -> c_int; + pub fn BIO_s_dgram_pair() -> *const BIO_METHOD; + pub fn BIO_s_datagram() -> *const BIO_METHOD; + pub fn BIO_get_rpoll_descriptor(b: *mut BIO, desc: *mut BIO_POLL_DESCRIPTOR) -> c_int; + pub fn BIO_get_wpoll_descriptor(b: *mut BIO, desc: *mut BIO_POLL_DESCRIPTOR) -> c_int; + pub fn BIO_sendmmsg( + b: *mut BIO, + msg: *mut BIO_MSG, + stride: usize, + num_msg: usize, + flags: u64, + msgs_processed: *mut usize, + ) -> c_int; + pub fn BIO_recvmmsg( + b: *mut BIO, + msg: *mut BIO_MSG, + stride: usize, + num_msg: usize, + flags: u64, + msgs_processed: *mut usize, + ) -> c_int; + pub fn BIO_err_is_non_fatal(errcode: c_uint) -> c_int; +} diff --git a/vendor/openssl-sys/src/handwritten/bn.rs b/vendor/openssl-sys/src/handwritten/bn.rs new file mode 100644 index 0000000..fb55f6b --- /dev/null +++ b/vendor/openssl-sys/src/handwritten/bn.rs @@ -0,0 +1,176 @@ +use super::super::*; +use libc::*; + +extern "C" { + pub fn BN_CTX_new() -> *mut BN_CTX; + #[cfg(ossl110)] + pub fn BN_CTX_secure_new() -> *mut BN_CTX; + pub fn BN_CTX_free(ctx: *mut BN_CTX); + pub fn BN_rand(r: *mut BIGNUM, bits: c_int, top: c_int, bottom: c_int) -> c_int; + #[cfg(not(osslconf = "OPENSSL_NO_DEPRECATED_3_0"))] + pub fn BN_pseudo_rand(r: *mut BIGNUM, bits: c_int, top: c_int, bottom: c_int) -> c_int; + pub fn BN_rand_range(r: *mut BIGNUM, range: *const BIGNUM) -> c_int; + #[cfg(not(osslconf = "OPENSSL_NO_DEPRECATED_3_0"))] + pub fn BN_pseudo_rand_range(r: *mut BIGNUM, range: *const BIGNUM) -> c_int; + pub fn BN_new() -> *mut BIGNUM; + #[cfg(ossl110)] + pub fn BN_secure_new() -> *mut BIGNUM; + #[cfg(ossl110)] + pub fn BN_set_flags(b: *mut BIGNUM, n: c_int); + #[cfg(ossl110)] + pub fn BN_get_flags(b: *const BIGNUM, n: c_int) -> c_int; + pub fn BN_num_bits(bn: *const BIGNUM) -> c_int; + pub fn BN_clear_free(bn: *mut BIGNUM); + pub fn BN_bin2bn(s: *const u8, size: c_int, ret: *mut BIGNUM) -> *mut BIGNUM; + pub fn BN_bn2bin(a: *const BIGNUM, to: *mut u8) -> c_int; + #[cfg(any(ossl110, libressl340))] + pub fn BN_bn2binpad(a: *const BIGNUM, to: *mut u8, tolen: c_int) -> c_int; + pub fn BN_sub(r: *mut BIGNUM, a: *const BIGNUM, b: *const BIGNUM) -> c_int; + pub fn BN_add(r: *mut BIGNUM, a: *const BIGNUM, b: *const BIGNUM) -> c_int; + pub fn BN_mul(r: *mut BIGNUM, a: *const BIGNUM, b: *const BIGNUM, ctx: *mut BN_CTX) -> c_int; + pub fn BN_sqr(r: *mut BIGNUM, a: *const BIGNUM, ctx: *mut BN_CTX) -> c_int; + pub fn BN_set_negative(bn: *mut BIGNUM, n: c_int); + #[cfg(any(ossl110, libressl350))] + pub fn BN_is_negative(b: *const BIGNUM) -> c_int; + #[cfg(any(ossl110, libressl350))] + pub fn BN_is_odd(b: *const BIGNUM) -> c_int; + + pub fn BN_div( + dv: *mut BIGNUM, + rem: *mut BIGNUM, + a: *const BIGNUM, + b: *const BIGNUM, + ctx: *mut BN_CTX, + ) -> c_int; + pub fn BN_nnmod( + rem: *mut BIGNUM, + a: *const BIGNUM, + m: *const BIGNUM, + ctx: *mut BN_CTX, + ) -> c_int; + pub fn BN_mod_add( + r: *mut BIGNUM, + a: *const BIGNUM, + b: *const BIGNUM, + m: *const BIGNUM, + ctx: *mut BN_CTX, + ) -> c_int; + pub fn BN_mod_sub( + r: *mut BIGNUM, + a: *const BIGNUM, + b: *const BIGNUM, + m: *const BIGNUM, + ctx: *mut BN_CTX, + ) -> c_int; + pub fn BN_mod_mul( + r: *mut BIGNUM, + a: *const BIGNUM, + b: *const BIGNUM, + m: *const BIGNUM, + ctx: *mut BN_CTX, + ) -> c_int; + pub fn BN_mod_sqr( + r: *mut BIGNUM, + a: *const BIGNUM, + m: *const BIGNUM, + ctx: *mut BN_CTX, + ) -> c_int; + pub fn BN_mod_sqrt( + ret: *mut BIGNUM, + a: *const BIGNUM, + p: *const BIGNUM, + ctx: *mut BN_CTX, + ) -> *mut BIGNUM; + + pub fn BN_mod_word(r: *const BIGNUM, w: BN_ULONG) -> BN_ULONG; + pub fn BN_div_word(r: *mut BIGNUM, w: BN_ULONG) -> BN_ULONG; + pub fn BN_mul_word(r: *mut BIGNUM, w: BN_ULONG) -> c_int; + pub fn BN_add_word(r: *mut BIGNUM, w: BN_ULONG) -> c_int; + pub fn BN_sub_word(r: *mut BIGNUM, w: BN_ULONG) -> c_int; + pub fn BN_set_word(bn: *mut BIGNUM, n: BN_ULONG) -> c_int; + + pub fn BN_cmp(a: *const BIGNUM, b: *const BIGNUM) -> c_int; + pub fn BN_free(bn: *mut BIGNUM); + pub fn BN_is_bit_set(a: *const BIGNUM, n: c_int) -> c_int; + pub fn BN_lshift(r: *mut BIGNUM, a: *const BIGNUM, n: c_int) -> c_int; + pub fn BN_lshift1(r: *mut BIGNUM, a: *const BIGNUM) -> c_int; + pub fn BN_exp(r: *mut BIGNUM, a: *const BIGNUM, p: *const BIGNUM, ctx: *mut BN_CTX) -> c_int; + + pub fn BN_mod_exp( + r: *mut BIGNUM, + a: *const BIGNUM, + p: *const BIGNUM, + m: *const BIGNUM, + ctx: *mut BN_CTX, + ) -> c_int; + + pub fn BN_mask_bits(a: *mut BIGNUM, n: c_int) -> c_int; + pub fn BN_rshift(r: *mut BIGNUM, a: *const BIGNUM, n: c_int) -> c_int; + pub fn BN_rshift1(r: *mut BIGNUM, a: *const BIGNUM) -> c_int; + pub fn BN_bn2hex(a: *const BIGNUM) -> *mut c_char; + pub fn BN_bn2dec(a: *const BIGNUM) -> *mut c_char; + pub fn BN_hex2bn(a: *mut *mut BIGNUM, s: *const c_char) -> c_int; + pub fn BN_dec2bn(a: *mut *mut BIGNUM, s: *const c_char) -> c_int; + pub fn BN_gcd(r: *mut BIGNUM, a: *const BIGNUM, b: *const BIGNUM, ctx: *mut BN_CTX) -> c_int; + pub fn BN_mod_inverse( + r: *mut BIGNUM, + a: *const BIGNUM, + n: *const BIGNUM, + ctx: *mut BN_CTX, + ) -> *mut BIGNUM; + pub fn BN_clear(bn: *mut BIGNUM); + pub fn BN_dup(n: *const BIGNUM) -> *mut BIGNUM; + pub fn BN_ucmp(a: *const BIGNUM, b: *const BIGNUM) -> c_int; + pub fn BN_set_bit(a: *mut BIGNUM, n: c_int) -> c_int; + pub fn BN_clear_bit(a: *mut BIGNUM, n: c_int) -> c_int; + + pub fn BN_generate_prime_ex( + r: *mut BIGNUM, + bits: c_int, + safe: c_int, + add: *const BIGNUM, + rem: *const BIGNUM, + cb: *mut BN_GENCB, + ) -> c_int; + #[cfg(not(osslconf = "OPENSSL_NO_DEPRECATED_3_0"))] + pub fn BN_is_prime_ex( + p: *const BIGNUM, + checks: c_int, + ctx: *mut BN_CTX, + cb: *mut BN_GENCB, + ) -> c_int; + #[cfg(not(osslconf = "OPENSSL_NO_DEPRECATED_3_0"))] + pub fn BN_is_prime_fasttest_ex( + p: *const BIGNUM, + checks: c_int, + ctx: *mut BN_CTX, + do_trial_division: c_int, + cb: *mut BN_GENCB, + ) -> c_int; +} + +cfg_if! { + if #[cfg(any(ossl110, libressl350))] { + extern "C" { + pub fn BN_get_rfc2409_prime_768(bn: *mut BIGNUM) -> *mut BIGNUM; + pub fn BN_get_rfc2409_prime_1024(bn: *mut BIGNUM) -> *mut BIGNUM; + pub fn BN_get_rfc3526_prime_1536(bn: *mut BIGNUM) -> *mut BIGNUM; + pub fn BN_get_rfc3526_prime_2048(bn: *mut BIGNUM) -> *mut BIGNUM; + pub fn BN_get_rfc3526_prime_3072(bn: *mut BIGNUM) -> *mut BIGNUM; + pub fn BN_get_rfc3526_prime_4096(bn: *mut BIGNUM) -> *mut BIGNUM; + pub fn BN_get_rfc3526_prime_6144(bn: *mut BIGNUM) -> *mut BIGNUM; + pub fn BN_get_rfc3526_prime_8192(bn: *mut BIGNUM) -> *mut BIGNUM; + } + } else { + extern "C" { + pub fn get_rfc2409_prime_768(bn: *mut BIGNUM) -> *mut BIGNUM; + pub fn get_rfc2409_prime_1024(bn: *mut BIGNUM) -> *mut BIGNUM; + pub fn get_rfc3526_prime_1536(bn: *mut BIGNUM) -> *mut BIGNUM; + pub fn get_rfc3526_prime_2048(bn: *mut BIGNUM) -> *mut BIGNUM; + pub fn get_rfc3526_prime_3072(bn: *mut BIGNUM) -> *mut BIGNUM; + pub fn get_rfc3526_prime_4096(bn: *mut BIGNUM) -> *mut BIGNUM; + pub fn get_rfc3526_prime_6144(bn: *mut BIGNUM) -> *mut BIGNUM; + pub fn get_rfc3526_prime_8192(bn: *mut BIGNUM) -> *mut BIGNUM; + } + } +} diff --git a/vendor/openssl-sys/src/handwritten/cmac.rs b/vendor/openssl-sys/src/handwritten/cmac.rs new file mode 100644 index 0000000..e44094d --- /dev/null +++ b/vendor/openssl-sys/src/handwritten/cmac.rs @@ -0,0 +1,18 @@ +use libc::*; + +use super::super::*; + +extern "C" { + pub fn CMAC_CTX_new() -> *mut CMAC_CTX; + pub fn CMAC_CTX_free(ctx: *mut CMAC_CTX); + pub fn CMAC_Init( + ctx: *mut CMAC_CTX, + key: *const c_void, + len: size_t, + cipher: *const EVP_CIPHER, + impl_: *mut ENGINE, + ) -> c_int; + pub fn CMAC_Update(ctx: *mut CMAC_CTX, data: *const c_void, len: size_t) -> c_int; + pub fn CMAC_Final(ctx: *mut CMAC_CTX, out: *mut c_uchar, len: *mut size_t) -> c_int; + pub fn CMAC_CTX_copy(dst: *mut CMAC_CTX, src: *const CMAC_CTX) -> c_int; +} diff --git a/vendor/openssl-sys/src/handwritten/cms.rs b/vendor/openssl-sys/src/handwritten/cms.rs new file mode 100644 index 0000000..a13ea42 --- /dev/null +++ b/vendor/openssl-sys/src/handwritten/cms.rs @@ -0,0 +1,65 @@ +use super::super::*; +use libc::*; + +pub enum CMS_ContentInfo {} + +extern "C" { + #[cfg(ossl101)] + pub fn CMS_ContentInfo_free(cms: *mut CMS_ContentInfo); +} + +const_ptr_api! { + extern "C" { + #[cfg(ossl101)] + pub fn i2d_CMS_ContentInfo(a: #[const_ptr_if(ossl300)] CMS_ContentInfo, pp: *mut *mut c_uchar) -> c_int; + } +} + +extern "C" { + #[cfg(ossl101)] + pub fn d2i_CMS_ContentInfo( + a: *mut *mut CMS_ContentInfo, + pp: *mut *const c_uchar, + length: c_long, + ) -> *mut CMS_ContentInfo; + + #[cfg(ossl101)] + pub fn SMIME_read_CMS(bio: *mut BIO, bcont: *mut *mut BIO) -> *mut CMS_ContentInfo; + + #[cfg(ossl101)] + pub fn CMS_sign( + signcert: *mut X509, + pkey: *mut EVP_PKEY, + certs: *mut stack_st_X509, + data: *mut BIO, + flags: c_uint, + ) -> *mut CMS_ContentInfo; + + #[cfg(ossl101)] + pub fn CMS_verify( + cms: *mut CMS_ContentInfo, + certs: *mut stack_st_X509, + store: *mut X509_STORE, + detached_data: *mut BIO, + out: *mut BIO, + flags: c_uint, + ) -> c_int; + + #[cfg(ossl101)] + pub fn CMS_encrypt( + certs: *mut stack_st_X509, + data: *mut BIO, + cipher: *const EVP_CIPHER, + flags: c_uint, + ) -> *mut CMS_ContentInfo; + + #[cfg(ossl101)] + pub fn CMS_decrypt( + cms: *mut CMS_ContentInfo, + pkey: *mut EVP_PKEY, + cert: *mut X509, + dcont: *mut BIO, + out: *mut BIO, + flags: c_uint, + ) -> c_int; +} diff --git a/vendor/openssl-sys/src/handwritten/conf.rs b/vendor/openssl-sys/src/handwritten/conf.rs new file mode 100644 index 0000000..fa05c55 --- /dev/null +++ b/vendor/openssl-sys/src/handwritten/conf.rs @@ -0,0 +1,13 @@ +use super::super::*; + +const_ptr_api! { + extern "C" { + pub fn NCONF_new(meth: #[const_ptr_if(libressl400)] CONF_METHOD) -> *mut CONF; + } +} + +extern "C" { + #[cfg(not(libressl400))] + pub fn NCONF_default() -> *mut CONF_METHOD; + pub fn NCONF_free(conf: *mut CONF); +} diff --git a/vendor/openssl-sys/src/handwritten/crypto.rs b/vendor/openssl-sys/src/handwritten/crypto.rs new file mode 100644 index 0000000..0b3f24a --- /dev/null +++ b/vendor/openssl-sys/src/handwritten/crypto.rs @@ -0,0 +1,85 @@ +use super::super::*; +use libc::*; + +stack!(stack_st_void); + +cfg_if! { + if #[cfg(any(ossl110, libressl271))] { + extern "C" { + pub fn OpenSSL_version_num() -> c_ulong; + pub fn OpenSSL_version(key: c_int) -> *const c_char; + } + } else { + extern "C" { + pub fn SSLeay() -> c_ulong; + pub fn SSLeay_version(key: c_int) -> *const c_char; + } + } +} + +extern "C" { + #[cfg(any(ossl110, libressl))] + pub fn CRYPTO_get_ex_new_index( + class_index: c_int, + argl: c_long, + argp: *mut c_void, + new_func: Option, + dup_func: Option, + free_func: Option, + ) -> c_int; + + #[cfg(not(ossl110))] + pub fn CRYPTO_num_locks() -> c_int; +} + +#[allow(clashing_extern_declarations)] +extern "C" { + #[cfg(not(ossl110))] + #[link_name = "CRYPTO_set_locking_callback"] + pub fn CRYPTO_set_locking_callback__fixed_rust( + func: Option, + ); + + #[cfg(not(ossl110))] + #[link_name = "CRYPTO_set_id_callback"] + pub fn CRYPTO_set_id_callback__fixed_rust(func: Option c_ulong>); +} + +extern "C" { + #[cfg(not(ossl110))] + pub fn CRYPTO_add_lock( + pointer: *mut c_int, + amount: c_int, + type_: c_int, + file: *const c_char, + line: c_int, + ) -> c_int; +} + +cfg_if! { + if #[cfg(any(ossl110, libressl390))] { + extern "C" { + pub fn CRYPTO_malloc(num: size_t, file: *const c_char, line: c_int) -> *mut c_void; + pub fn CRYPTO_free(buf: *mut c_void, file: *const c_char, line: c_int); + } + } else { + extern "C" { + pub fn CRYPTO_malloc(num: c_int, file: *const c_char, line: c_int) -> *mut c_void; + pub fn CRYPTO_free(buf: *mut c_void); + } + } +} + +extern "C" { + #[cfg(all(ossl101, not(ossl300)))] + pub fn FIPS_mode() -> c_int; + #[cfg(all(ossl101, not(ossl300)))] + pub fn FIPS_mode_set(onoff: c_int) -> c_int; + + pub fn CRYPTO_memcmp(a: *const c_void, b: *const c_void, len: size_t) -> c_int; + + #[cfg(ossl300)] + pub fn OSSL_LIB_CTX_new() -> *mut OSSL_LIB_CTX; + #[cfg(ossl300)] + pub fn OSSL_LIB_CTX_free(libcts: *mut OSSL_LIB_CTX); +} diff --git a/vendor/openssl-sys/src/handwritten/dh.rs b/vendor/openssl-sys/src/handwritten/dh.rs new file mode 100644 index 0000000..c4671c9 --- /dev/null +++ b/vendor/openssl-sys/src/handwritten/dh.rs @@ -0,0 +1,52 @@ +use super::super::*; + +extern "C" { + pub fn DH_new() -> *mut DH; + pub fn DH_free(dh: *mut DH); + pub fn DH_check(dh: *const DH, codes: *mut c_int) -> c_int; + + #[cfg(not(libressl382))] + pub fn DH_generate_parameters( + prime_len: c_int, + generator: c_int, + callback: Option, + cb_arg: *mut c_void, + ) -> *mut DH; + + pub fn DH_generate_parameters_ex( + dh: *mut DH, + prime_len: c_int, + generator: c_int, + cb: *mut BN_GENCB, + ) -> c_int; + + pub fn DH_generate_key(dh: *mut DH) -> c_int; + pub fn DH_compute_key(key: *mut c_uchar, pub_key: *const BIGNUM, dh: *mut DH) -> c_int; + pub fn DH_size(dh: *const DH) -> c_int; + + pub fn d2i_DHparams(k: *mut *mut DH, pp: *mut *const c_uchar, length: c_long) -> *mut DH; + pub fn i2d_DHparams(dh: *const DH, pp: *mut *mut c_uchar) -> c_int; + + #[cfg(ossl102)] + pub fn DH_get_1024_160() -> *mut DH; + #[cfg(ossl102)] + pub fn DH_get_2048_224() -> *mut DH; + #[cfg(ossl102)] + pub fn DH_get_2048_256() -> *mut DH; + + #[cfg(any(ossl110, libressl270))] + pub fn DH_set0_pqg(dh: *mut DH, p: *mut BIGNUM, q: *mut BIGNUM, g: *mut BIGNUM) -> c_int; + #[cfg(any(ossl110, libressl270))] + pub fn DH_get0_pqg( + dh: *const DH, + p: *mut *const BIGNUM, + q: *mut *const BIGNUM, + g: *mut *const BIGNUM, + ); + + #[cfg(any(ossl110, libressl270))] + pub fn DH_set0_key(dh: *mut DH, pub_key: *mut BIGNUM, priv_key: *mut BIGNUM) -> c_int; + + #[cfg(any(ossl110, libressl270))] + pub fn DH_get0_key(dh: *const DH, pub_key: *mut *const BIGNUM, priv_key: *mut *const BIGNUM); +} diff --git a/vendor/openssl-sys/src/handwritten/dsa.rs b/vendor/openssl-sys/src/handwritten/dsa.rs new file mode 100644 index 0000000..be25f23 --- /dev/null +++ b/vendor/openssl-sys/src/handwritten/dsa.rs @@ -0,0 +1,85 @@ +use libc::*; + +use super::super::*; + +cfg_if! { + if #[cfg(any(ossl110, libressl280))] { + pub enum DSA_SIG {} + } else { + #[repr(C)] + pub struct DSA_SIG { + pub r: *mut BIGNUM, + pub s: *mut BIGNUM, + } + } +} + +extern "C" { + pub fn DSA_new() -> *mut DSA; + pub fn DSA_free(dsa: *mut DSA); + pub fn DSA_up_ref(dsa: *mut DSA) -> c_int; + pub fn DSA_size(dsa: *const DSA) -> c_int; + pub fn DSA_sign( + dummy: c_int, + dgst: *const c_uchar, + len: c_int, + sigret: *mut c_uchar, + siglen: *mut c_uint, + dsa: *mut DSA, + ) -> c_int; + pub fn DSA_verify( + dummy: c_int, + dgst: *const c_uchar, + len: c_int, + sigbuf: *const c_uchar, + siglen: c_int, + dsa: *mut DSA, + ) -> c_int; + + pub fn d2i_DSAPublicKey(a: *mut *mut DSA, pp: *mut *const c_uchar, length: c_long) -> *mut DSA; + pub fn d2i_DSAPrivateKey(a: *mut *mut DSA, pp: *mut *const c_uchar, length: c_long) + -> *mut DSA; + + pub fn DSA_generate_parameters_ex( + dsa: *mut DSA, + bits: c_int, + seed: *const c_uchar, + seed_len: c_int, + counter_ref: *mut c_int, + h_ret: *mut c_ulong, + cb: *mut BN_GENCB, + ) -> c_int; + + pub fn DSA_generate_key(dsa: *mut DSA) -> c_int; + pub fn i2d_DSAPublicKey(a: *const DSA, pp: *mut *mut c_uchar) -> c_int; + pub fn i2d_DSAPrivateKey(a: *const DSA, pp: *mut *mut c_uchar) -> c_int; + + #[cfg(any(ossl110, libressl273))] + pub fn DSA_get0_pqg( + d: *const DSA, + p: *mut *const BIGNUM, + q: *mut *const BIGNUM, + q: *mut *const BIGNUM, + ); + #[cfg(any(ossl110, libressl273))] + pub fn DSA_set0_pqg(d: *mut DSA, p: *mut BIGNUM, q: *mut BIGNUM, q: *mut BIGNUM) -> c_int; + #[cfg(any(ossl110, libressl273))] + pub fn DSA_get0_key(d: *const DSA, pub_key: *mut *const BIGNUM, priv_key: *mut *const BIGNUM); + #[cfg(any(ossl110, libressl273))] + pub fn DSA_set0_key(d: *mut DSA, pub_key: *mut BIGNUM, priv_key: *mut BIGNUM) -> c_int; + pub fn d2i_DSA_SIG( + sig: *mut *mut DSA_SIG, + pp: *mut *const c_uchar, + length: c_long, + ) -> *mut DSA_SIG; + pub fn i2d_DSA_SIG(a: *const DSA_SIG, pp: *mut *mut c_uchar) -> c_int; + + pub fn DSA_SIG_new() -> *mut DSA_SIG; + pub fn DSA_SIG_free(sig: *mut DSA_SIG); + + #[cfg(any(ossl110, libressl273))] + pub fn DSA_SIG_get0(sig: *const DSA_SIG, pr: *mut *const BIGNUM, ps: *mut *const BIGNUM); + + #[cfg(any(ossl110, libressl273))] + pub fn DSA_SIG_set0(sig: *mut DSA_SIG, pr: *mut BIGNUM, ps: *mut BIGNUM) -> c_int; +} diff --git a/vendor/openssl-sys/src/handwritten/ec.rs b/vendor/openssl-sys/src/handwritten/ec.rs new file mode 100644 index 0000000..f199bc8 --- /dev/null +++ b/vendor/openssl-sys/src/handwritten/ec.rs @@ -0,0 +1,271 @@ +use super::super::*; +use libc::*; + +#[repr(C)] +#[derive(Copy, Clone)] +pub enum point_conversion_form_t { + POINT_CONVERSION_COMPRESSED = 2, + POINT_CONVERSION_UNCOMPRESSED = 4, + POINT_CONVERSION_HYBRID = 6, +} + +pub enum EC_METHOD {} +pub enum EC_GROUP {} +pub enum EC_POINT {} + +extern "C" { + #[cfg(not(osslconf = "OPENSSL_NO_EC2M"))] + pub fn EC_GF2m_simple_method() -> *const EC_METHOD; + + pub fn EC_GROUP_new(meth: *const EC_METHOD) -> *mut EC_GROUP; + + pub fn EC_GROUP_free(group: *mut EC_GROUP); + + pub fn EC_GROUP_get_order( + group: *const EC_GROUP, + order: *mut BIGNUM, + ctx: *mut BN_CTX, + ) -> c_int; + + pub fn EC_GROUP_get_cofactor( + group: *const EC_GROUP, + cofactor: *mut BIGNUM, + ctx: *mut BN_CTX, + ) -> c_int; + + pub fn EC_GROUP_get0_generator(group: *const EC_GROUP) -> *const EC_POINT; + + pub fn EC_GROUP_set_generator( + group: *mut EC_GROUP, + generator: *const EC_POINT, + order: *const BIGNUM, + cofactor: *const BIGNUM, + ) -> c_int; + + pub fn EC_GROUP_get_curve_name(group: *const EC_GROUP) -> c_int; + + pub fn EC_GROUP_set_asn1_flag(key: *mut EC_GROUP, flag: c_int); + + pub fn EC_GROUP_get_asn1_flag(group: *const EC_GROUP) -> c_int; + + pub fn EC_GROUP_get_curve_GFp( + group: *const EC_GROUP, + p: *mut BIGNUM, + a: *mut BIGNUM, + b: *mut BIGNUM, + ctx: *mut BN_CTX, + ) -> c_int; + + #[cfg(not(osslconf = "OPENSSL_NO_EC2M"))] + pub fn EC_GROUP_get_curve_GF2m( + group: *const EC_GROUP, + p: *mut BIGNUM, + a: *mut BIGNUM, + b: *mut BIGNUM, + ctx: *mut BN_CTX, + ) -> c_int; + + pub fn EC_GROUP_get_degree(group: *const EC_GROUP) -> c_int; + + #[cfg(ossl110)] + pub fn EC_GROUP_order_bits(group: *const EC_GROUP) -> c_int; + + pub fn EC_GROUP_new_curve_GFp( + p: *const BIGNUM, + a: *const BIGNUM, + b: *const BIGNUM, + ctx: *mut BN_CTX, + ) -> *mut EC_GROUP; + + #[cfg(not(osslconf = "OPENSSL_NO_EC2M"))] + pub fn EC_GROUP_new_curve_GF2m( + p: *const BIGNUM, + a: *const BIGNUM, + b: *const BIGNUM, + ctx: *mut BN_CTX, + ) -> *mut EC_GROUP; + + pub fn EC_GROUP_new_by_curve_name(nid: c_int) -> *mut EC_GROUP; + + pub fn EC_POINT_is_at_infinity(group: *const EC_GROUP, point: *const EC_POINT) -> c_int; + + pub fn EC_POINT_is_on_curve( + group: *const EC_GROUP, + point: *const EC_POINT, + ctx: *mut BN_CTX, + ) -> c_int; + + pub fn EC_POINT_new(group: *const EC_GROUP) -> *mut EC_POINT; + + pub fn EC_POINT_free(point: *mut EC_POINT); + + pub fn EC_POINT_dup(p: *const EC_POINT, group: *const EC_GROUP) -> *mut EC_POINT; + + #[cfg(any(ossl111, boringssl, libressl350))] + pub fn EC_POINT_get_affine_coordinates( + group: *const EC_GROUP, + p: *const EC_POINT, + x: *mut BIGNUM, + y: *mut BIGNUM, + ctx: *mut BN_CTX, + ) -> c_int; + + pub fn EC_POINT_get_affine_coordinates_GFp( + group: *const EC_GROUP, + p: *const EC_POINT, + x: *mut BIGNUM, + y: *mut BIGNUM, + ctx: *mut BN_CTX, + ) -> c_int; + + pub fn EC_POINT_set_affine_coordinates_GFp( + group: *const EC_GROUP, + p: *mut EC_POINT, + x: *const BIGNUM, + y: *const BIGNUM, + ctx: *mut BN_CTX, + ) -> c_int; + + #[cfg(not(osslconf = "OPENSSL_NO_EC2M"))] + pub fn EC_POINT_get_affine_coordinates_GF2m( + group: *const EC_GROUP, + p: *const EC_POINT, + x: *mut BIGNUM, + y: *mut BIGNUM, + ctx: *mut BN_CTX, + ) -> c_int; + + pub fn EC_POINT_point2oct( + group: *const EC_GROUP, + p: *const EC_POINT, + form: point_conversion_form_t, + buf: *mut c_uchar, + len: size_t, + ctx: *mut BN_CTX, + ) -> size_t; + + pub fn EC_POINT_oct2point( + group: *const EC_GROUP, + p: *mut EC_POINT, + buf: *const c_uchar, + len: size_t, + ctx: *mut BN_CTX, + ) -> c_int; + + pub fn EC_POINT_point2hex( + group: *const EC_GROUP, + p: *const EC_POINT, + form: point_conversion_form_t, + ctx: *mut BN_CTX, + ) -> *mut c_char; + + pub fn EC_POINT_hex2point( + group: *const EC_GROUP, + s: *const c_char, + p: *mut EC_POINT, + ctx: *mut BN_CTX, + ) -> *mut EC_POINT; + + pub fn EC_POINT_add( + group: *const EC_GROUP, + r: *mut EC_POINT, + a: *const EC_POINT, + b: *const EC_POINT, + ctx: *mut BN_CTX, + ) -> c_int; + + pub fn EC_POINT_invert(group: *const EC_GROUP, r: *mut EC_POINT, ctx: *mut BN_CTX) -> c_int; + + pub fn EC_POINT_cmp( + group: *const EC_GROUP, + a: *const EC_POINT, + b: *const EC_POINT, + ctx: *mut BN_CTX, + ) -> c_int; + + pub fn EC_POINT_mul( + group: *const EC_GROUP, + r: *mut EC_POINT, + n: *const BIGNUM, + q: *const EC_POINT, + m: *const BIGNUM, + ctx: *mut BN_CTX, + ) -> c_int; + + pub fn EC_KEY_new() -> *mut EC_KEY; + + pub fn EC_KEY_new_by_curve_name(nid: c_int) -> *mut EC_KEY; + + pub fn EC_KEY_free(key: *mut EC_KEY); + + pub fn EC_KEY_dup(key: *const EC_KEY) -> *mut EC_KEY; + + pub fn EC_KEY_up_ref(key: *mut EC_KEY) -> c_int; + + pub fn EC_KEY_get0_group(key: *const EC_KEY) -> *const EC_GROUP; + + pub fn EC_KEY_set_group(key: *mut EC_KEY, group: *const EC_GROUP) -> c_int; + + pub fn EC_KEY_get0_private_key(key: *const EC_KEY) -> *const BIGNUM; + + pub fn EC_KEY_set_private_key(key: *mut EC_KEY, key: *const BIGNUM) -> c_int; + + pub fn EC_KEY_get0_public_key(key: *const EC_KEY) -> *const EC_POINT; + + pub fn EC_KEY_set_public_key(key: *mut EC_KEY, key: *const EC_POINT) -> c_int; + + pub fn EC_KEY_generate_key(key: *mut EC_KEY) -> c_int; + + pub fn EC_KEY_check_key(key: *const EC_KEY) -> c_int; + + pub fn EC_KEY_set_public_key_affine_coordinates( + key: *mut EC_KEY, + x: *mut BIGNUM, + y: *mut BIGNUM, + ) -> c_int; +} + +cfg_if! { + if #[cfg(any(ossl110, libressl280))] { + pub enum ECDSA_SIG {} + } else { + #[repr(C)] + pub struct ECDSA_SIG { + pub r: *mut BIGNUM, + pub s: *mut BIGNUM, + } + } +} + +extern "C" { + pub fn ECDSA_SIG_new() -> *mut ECDSA_SIG; + + pub fn ECDSA_SIG_free(sig: *mut ECDSA_SIG); + + #[cfg(any(ossl110, libressl273))] + pub fn ECDSA_SIG_get0(sig: *const ECDSA_SIG, pr: *mut *const BIGNUM, ps: *mut *const BIGNUM); + + #[cfg(any(ossl110, libressl273))] + pub fn ECDSA_SIG_set0(sig: *mut ECDSA_SIG, pr: *mut BIGNUM, ps: *mut BIGNUM) -> c_int; + + pub fn ECDSA_do_sign( + dgst: *const c_uchar, + dgst_len: c_int, + eckey: *mut EC_KEY, + ) -> *mut ECDSA_SIG; + + pub fn ECDSA_do_verify( + dgst: *const c_uchar, + dgst_len: c_int, + sig: *const ECDSA_SIG, + eckey: *mut EC_KEY, + ) -> c_int; + + pub fn d2i_ECDSA_SIG( + sig: *mut *mut ECDSA_SIG, + inp: *mut *const c_uchar, + length: c_long, + ) -> *mut ECDSA_SIG; + + pub fn i2d_ECDSA_SIG(sig: *const ECDSA_SIG, out: *mut *mut c_uchar) -> c_int; +} diff --git a/vendor/openssl-sys/src/handwritten/err.rs b/vendor/openssl-sys/src/handwritten/err.rs new file mode 100644 index 0000000..5653c1d --- /dev/null +++ b/vendor/openssl-sys/src/handwritten/err.rs @@ -0,0 +1,55 @@ +use super::super::*; +use libc::*; + +#[repr(C)] +pub struct ERR_STRING_DATA { + pub error: c_ulong, + pub string: *const c_char, +} + +cfg_if! { + if #[cfg(ossl300)] { + extern "C" { + pub fn ERR_new(); + pub fn ERR_set_debug(file: *const c_char, line: c_int, func: *const c_char); + pub fn ERR_set_error(lib: c_int, reason: c_int, fmt: *const c_char, ...); + } + } else { + extern "C" { + pub fn ERR_put_error(lib: c_int, func: c_int, reason: c_int, file: *const c_char, line: c_int); + } + } +} + +extern "C" { + pub fn ERR_set_error_data(data: *mut c_char, flags: c_int); + + pub fn ERR_get_error() -> c_ulong; + #[cfg(ossl300)] + pub fn ERR_get_error_all( + file: *mut *const c_char, + line: *mut c_int, + func: *mut *const c_char, + data: *mut *const c_char, + flags: *mut c_int, + ) -> c_ulong; + pub fn ERR_get_error_line_data( + file: *mut *const c_char, + line: *mut c_int, + data: *mut *const c_char, + flags: *mut c_int, + ) -> c_ulong; + pub fn ERR_peek_last_error() -> c_ulong; + pub fn ERR_clear_error(); + pub fn ERR_lib_error_string(err: c_ulong) -> *const c_char; + pub fn ERR_func_error_string(err: c_ulong) -> *const c_char; + pub fn ERR_reason_error_string(err: c_ulong) -> *const c_char; + #[cfg(ossl110)] + pub fn ERR_load_strings(lib: c_int, str: *mut ERR_STRING_DATA) -> c_int; + #[cfg(not(ossl110))] + pub fn ERR_load_strings(lib: c_int, str: *mut ERR_STRING_DATA); + #[cfg(not(ossl110))] + pub fn ERR_load_crypto_strings(); + + pub fn ERR_get_next_error_library() -> c_int; +} diff --git a/vendor/openssl-sys/src/handwritten/evp.rs b/vendor/openssl-sys/src/handwritten/evp.rs new file mode 100644 index 0000000..aa83c92 --- /dev/null +++ b/vendor/openssl-sys/src/handwritten/evp.rs @@ -0,0 +1,660 @@ +use super::super::*; +use libc::*; + +cfg_if! { + if #[cfg(ossl300)] { + extern "C" { + pub fn EVP_MD_get_block_size(md: *const EVP_MD) -> c_int; + pub fn EVP_MD_get_size(md: *const EVP_MD) -> c_int; + pub fn EVP_MD_get_type(md: *const EVP_MD) -> c_int; + + pub fn EVP_MD_CTX_get0_md(ctx: *const EVP_MD_CTX) -> *const EVP_MD; + + pub fn EVP_CIPHER_get_key_length(cipher: *const EVP_CIPHER) -> c_int; + pub fn EVP_CIPHER_get_block_size(cipher: *const EVP_CIPHER) -> c_int; + pub fn EVP_CIPHER_get_iv_length(cipher: *const EVP_CIPHER) -> c_int; + pub fn EVP_CIPHER_get_nid(cipher: *const EVP_CIPHER) -> c_int; + pub fn EVP_CIPHER_fetch( + ctx: *mut OSSL_LIB_CTX, + algorithm: *const c_char, + properties: *const c_char, + ) -> *mut EVP_CIPHER; + pub fn EVP_CIPHER_free(cipher: *mut EVP_CIPHER); + + pub fn EVP_CIPHER_CTX_get0_cipher(ctx: *const EVP_CIPHER_CTX) -> *const EVP_CIPHER; + pub fn EVP_CIPHER_CTX_get_block_size(ctx: *const EVP_CIPHER_CTX) -> c_int; + pub fn EVP_CIPHER_CTX_get_key_length(ctx: *const EVP_CIPHER_CTX) -> c_int; + pub fn EVP_CIPHER_CTX_get_iv_length(ctx: *const EVP_CIPHER_CTX) -> c_int; + pub fn EVP_CIPHER_CTX_get_tag_length(ctx: *const EVP_CIPHER_CTX) -> c_int; + pub fn EVP_CIPHER_CTX_get_num(ctx: *const EVP_CIPHER_CTX) -> c_int; + } + } else { + extern "C" { + pub fn EVP_MD_block_size(md: *const EVP_MD) -> c_int; + pub fn EVP_MD_size(md: *const EVP_MD) -> c_int; + pub fn EVP_MD_type(md: *const EVP_MD) -> c_int; + + pub fn EVP_MD_CTX_md(ctx: *const EVP_MD_CTX) -> *const EVP_MD; + + pub fn EVP_CIPHER_key_length(cipher: *const EVP_CIPHER) -> c_int; + pub fn EVP_CIPHER_block_size(cipher: *const EVP_CIPHER) -> c_int; + pub fn EVP_CIPHER_iv_length(cipher: *const EVP_CIPHER) -> c_int; + pub fn EVP_CIPHER_nid(cipher: *const EVP_CIPHER) -> c_int; + + pub fn EVP_CIPHER_CTX_cipher(ctx: *const EVP_CIPHER_CTX) -> *const EVP_CIPHER; + pub fn EVP_CIPHER_CTX_block_size(ctx: *const EVP_CIPHER_CTX) -> c_int; + pub fn EVP_CIPHER_CTX_key_length(ctx: *const EVP_CIPHER_CTX) -> c_int; + pub fn EVP_CIPHER_CTX_iv_length(ctx: *const EVP_CIPHER_CTX) -> c_int; + #[cfg(ossl110)] + pub fn EVP_CIPHER_CTX_num(ctx: *const EVP_CIPHER_CTX) -> c_int; + } + } +} + +cfg_if! { + if #[cfg(any(ossl110, libressl382))] { + extern "C" { + pub fn EVP_MD_CTX_new() -> *mut EVP_MD_CTX; + pub fn EVP_MD_CTX_free(ctx: *mut EVP_MD_CTX); + } + } else { + extern "C" { + pub fn EVP_MD_CTX_create() -> *mut EVP_MD_CTX; + pub fn EVP_MD_CTX_destroy(ctx: *mut EVP_MD_CTX); + } + } +} + +cfg_if! { + if #[cfg(ossl300)] { + extern "C" { + pub fn EVP_default_properties_is_fips_enabled(libctx: *mut OSSL_LIB_CTX) -> c_int; + pub fn EVP_default_properties_enable_fips(libctx: *mut OSSL_LIB_CTX, enable: c_int) -> c_int; + } + } +} + +extern "C" { + pub fn EVP_DigestInit_ex(ctx: *mut EVP_MD_CTX, typ: *const EVP_MD, imple: *mut ENGINE) + -> c_int; + pub fn EVP_DigestUpdate(ctx: *mut EVP_MD_CTX, data: *const c_void, n: size_t) -> c_int; + pub fn EVP_DigestFinal_ex(ctx: *mut EVP_MD_CTX, res: *mut u8, n: *mut u32) -> c_int; + #[cfg(ossl300)] + pub fn EVP_Q_digest( + libctx: *mut OSSL_LIB_CTX, + name: *const c_char, + propq: *const c_char, + data: *const c_void, + count: size_t, + md: *mut c_uchar, + size: *mut size_t, + ) -> c_int; + pub fn EVP_DigestInit(ctx: *mut EVP_MD_CTX, typ: *const EVP_MD) -> c_int; + pub fn EVP_DigestFinal(ctx: *mut EVP_MD_CTX, res: *mut u8, n: *mut u32) -> c_int; + #[cfg(ossl111)] + pub fn EVP_DigestFinalXOF(ctx: *mut EVP_MD_CTX, res: *mut u8, len: usize) -> c_int; + #[cfg(ossl330)] + pub fn EVP_DigestSqueeze(ctx: *mut EVP_MD_CTX, res: *mut u8, len: usize) -> c_int; + + #[cfg(ossl300)] + pub fn EVP_MD_fetch( + ctx: *mut OSSL_LIB_CTX, + algorithm: *const c_char, + properties: *const c_char, + ) -> *mut EVP_MD; + + #[cfg(ossl300)] + pub fn EVP_MD_free(md: *mut EVP_MD); + + pub fn EVP_BytesToKey( + typ: *const EVP_CIPHER, + md: *const EVP_MD, + salt: *const u8, + data: *const u8, + datalen: c_int, + count: c_int, + key: *mut u8, + iv: *mut u8, + ) -> c_int; + + pub fn EVP_CipherInit( + ctx: *mut EVP_CIPHER_CTX, + evp: *const EVP_CIPHER, + key: *const u8, + iv: *const u8, + mode: c_int, + ) -> c_int; + pub fn EVP_CipherInit_ex( + ctx: *mut EVP_CIPHER_CTX, + type_: *const EVP_CIPHER, + impl_: *mut ENGINE, + key: *const c_uchar, + iv: *const c_uchar, + enc: c_int, + ) -> c_int; + pub fn EVP_CipherUpdate( + ctx: *mut EVP_CIPHER_CTX, + outbuf: *mut u8, + outlen: *mut c_int, + inbuf: *const u8, + inlen: c_int, + ) -> c_int; + pub fn EVP_CipherFinal(ctx: *mut EVP_CIPHER_CTX, res: *mut u8, len: *mut c_int) -> c_int; + + pub fn EVP_DigestSignInit( + ctx: *mut EVP_MD_CTX, + pctx: *mut *mut EVP_PKEY_CTX, + type_: *const EVP_MD, + e: *mut ENGINE, + pkey: *mut EVP_PKEY, + ) -> c_int; + + #[cfg(ossl300)] + pub fn EVP_DigestSignUpdate(ctx: *mut EVP_MD_CTX, data: *const c_void, dsize: size_t) -> c_int; + pub fn EVP_DigestSignFinal( + ctx: *mut EVP_MD_CTX, + sig: *mut c_uchar, + siglen: *mut size_t, + ) -> c_int; + pub fn EVP_DigestVerifyInit( + ctx: *mut EVP_MD_CTX, + pctx: *mut *mut EVP_PKEY_CTX, + type_: *const EVP_MD, + e: *mut ENGINE, + pkey: *mut EVP_PKEY, + ) -> c_int; + #[cfg(ossl300)] + pub fn EVP_DigestVerifyUpdate( + ctx: *mut EVP_MD_CTX, + data: *const c_void, + dsize: size_t, + ) -> c_int; + pub fn EVP_SealInit( + ctx: *mut EVP_CIPHER_CTX, + type_: *const EVP_CIPHER, + ek: *mut *mut c_uchar, + ekl: *mut c_int, + iv: *mut c_uchar, + pubk: *mut *mut EVP_PKEY, + npubk: c_int, + ) -> c_int; + pub fn EVP_SealFinal(ctx: *mut EVP_CIPHER_CTX, out: *mut c_uchar, outl: *mut c_int) -> c_int; + pub fn EVP_EncryptInit_ex( + ctx: *mut EVP_CIPHER_CTX, + cipher: *const EVP_CIPHER, + impl_: *mut ENGINE, + key: *const c_uchar, + iv: *const c_uchar, + ) -> c_int; + pub fn EVP_EncryptUpdate( + ctx: *mut EVP_CIPHER_CTX, + out: *mut c_uchar, + outl: *mut c_int, + in_: *const u8, + inl: c_int, + ) -> c_int; + pub fn EVP_EncryptFinal_ex( + ctx: *mut EVP_CIPHER_CTX, + out: *mut c_uchar, + outl: *mut c_int, + ) -> c_int; + pub fn EVP_OpenInit( + ctx: *mut EVP_CIPHER_CTX, + type_: *const EVP_CIPHER, + ek: *const c_uchar, + ekl: c_int, + iv: *const c_uchar, + priv_: *mut EVP_PKEY, + ) -> c_int; + pub fn EVP_OpenFinal(ctx: *mut EVP_CIPHER_CTX, out: *mut c_uchar, outl: *mut c_int) -> c_int; + pub fn EVP_DecryptInit_ex( + ctx: *mut EVP_CIPHER_CTX, + cipher: *const EVP_CIPHER, + impl_: *mut ENGINE, + key: *const c_uchar, + iv: *const c_uchar, + ) -> c_int; + pub fn EVP_DecryptUpdate( + ctx: *mut EVP_CIPHER_CTX, + out: *mut c_uchar, + outl: *mut c_int, + in_: *const u8, + inl: c_int, + ) -> c_int; + pub fn EVP_DecryptFinal_ex( + ctx: *mut EVP_CIPHER_CTX, + outm: *mut c_uchar, + outl: *mut c_int, + ) -> c_int; +} +cfg_if! { + if #[cfg(ossl300)] { + extern "C" { + pub fn EVP_PKEY_get_size(pkey: *const EVP_PKEY) -> c_int; + } + } else { + const_ptr_api! { + extern "C" { + pub fn EVP_PKEY_size(pkey: #[const_ptr_if(any(ossl111b, libressl280))] EVP_PKEY) -> c_int; + } + } + } +} +cfg_if! { + if #[cfg(any(ossl111, libressl370))] { + extern "C" { + pub fn EVP_DigestSign( + ctx: *mut EVP_MD_CTX, + sigret: *mut c_uchar, + siglen: *mut size_t, + tbs: *const c_uchar, + tbslen: size_t + ) -> c_int; + + pub fn EVP_DigestVerify( + ctx: *mut EVP_MD_CTX, + sigret: *const c_uchar, + siglen: size_t, + tbs: *const c_uchar, + tbslen: size_t + ) -> c_int; + } + } +} +const_ptr_api! { + extern "C" { + pub fn EVP_DigestVerifyFinal( + ctx: *mut EVP_MD_CTX, + sigret: #[const_ptr_if(any(ossl102, libressl280))] c_uchar, + siglen: size_t, + ) -> c_int; + } +} + +extern "C" { + pub fn EVP_CIPHER_CTX_new() -> *mut EVP_CIPHER_CTX; + pub fn EVP_CIPHER_CTX_free(ctx: *mut EVP_CIPHER_CTX); + pub fn EVP_CIPHER_CTX_copy(dst: *mut EVP_CIPHER_CTX, src: *const EVP_CIPHER_CTX) -> c_int; + + pub fn EVP_MD_CTX_copy_ex(dst: *mut EVP_MD_CTX, src: *const EVP_MD_CTX) -> c_int; + #[cfg(ossl111)] + pub fn EVP_MD_CTX_reset(ctx: *mut EVP_MD_CTX) -> c_int; + pub fn EVP_CIPHER_CTX_set_key_length(ctx: *mut EVP_CIPHER_CTX, keylen: c_int) -> c_int; + pub fn EVP_CIPHER_CTX_set_padding(ctx: *mut EVP_CIPHER_CTX, padding: c_int) -> c_int; + pub fn EVP_CIPHER_CTX_ctrl( + ctx: *mut EVP_CIPHER_CTX, + type_: c_int, + arg: c_int, + ptr: *mut c_void, + ) -> c_int; + pub fn EVP_CIPHER_CTX_rand_key(ctx: *mut EVP_CIPHER_CTX, key: *mut c_uchar) -> c_int; + pub fn EVP_CIPHER_CTX_set_flags(ctx: *mut EVP_CIPHER_CTX, flags: c_int); + + pub fn EVP_md_null() -> *const EVP_MD; + pub fn EVP_md5() -> *const EVP_MD; + pub fn EVP_sha1() -> *const EVP_MD; + pub fn EVP_sha224() -> *const EVP_MD; + pub fn EVP_sha256() -> *const EVP_MD; + pub fn EVP_sha384() -> *const EVP_MD; + pub fn EVP_sha512() -> *const EVP_MD; + #[cfg(any(ossl111, libressl380))] + pub fn EVP_sha3_224() -> *const EVP_MD; + #[cfg(any(ossl111, libressl380))] + pub fn EVP_sha3_256() -> *const EVP_MD; + #[cfg(any(ossl111, libressl380))] + pub fn EVP_sha3_384() -> *const EVP_MD; + #[cfg(any(ossl111, libressl380))] + pub fn EVP_sha3_512() -> *const EVP_MD; + #[cfg(ossl111)] + pub fn EVP_shake128() -> *const EVP_MD; + #[cfg(ossl111)] + pub fn EVP_shake256() -> *const EVP_MD; + pub fn EVP_ripemd160() -> *const EVP_MD; + #[cfg(all(any(ossl111, libressl291), not(osslconf = "OPENSSL_NO_SM3")))] + pub fn EVP_sm3() -> *const EVP_MD; + pub fn EVP_des_ecb() -> *const EVP_CIPHER; + pub fn EVP_des_ede3() -> *const EVP_CIPHER; + pub fn EVP_des_ede3_cbc() -> *const EVP_CIPHER; + pub fn EVP_des_ede3_ecb() -> *const EVP_CIPHER; + pub fn EVP_des_ede3_cfb64() -> *const EVP_CIPHER; + pub fn EVP_des_ede3_cfb8() -> *const EVP_CIPHER; + pub fn EVP_des_ede3_ofb() -> *const EVP_CIPHER; + pub fn EVP_des_cbc() -> *const EVP_CIPHER; + #[cfg(not(osslconf = "OPENSSL_NO_RC4"))] + pub fn EVP_rc4() -> *const EVP_CIPHER; + pub fn EVP_bf_ecb() -> *const EVP_CIPHER; + pub fn EVP_bf_cbc() -> *const EVP_CIPHER; + pub fn EVP_bf_cfb64() -> *const EVP_CIPHER; + pub fn EVP_bf_ofb() -> *const EVP_CIPHER; + pub fn EVP_aes_128_ecb() -> *const EVP_CIPHER; + pub fn EVP_aes_128_cbc() -> *const EVP_CIPHER; + pub fn EVP_aes_128_cfb1() -> *const EVP_CIPHER; + pub fn EVP_aes_128_cfb8() -> *const EVP_CIPHER; + pub fn EVP_aes_128_cfb128() -> *const EVP_CIPHER; + pub fn EVP_aes_128_ctr() -> *const EVP_CIPHER; + pub fn EVP_aes_128_ccm() -> *const EVP_CIPHER; + pub fn EVP_aes_128_gcm() -> *const EVP_CIPHER; + pub fn EVP_aes_128_xts() -> *const EVP_CIPHER; + pub fn EVP_aes_128_ofb() -> *const EVP_CIPHER; + #[cfg(ossl110)] + pub fn EVP_aes_128_ocb() -> *const EVP_CIPHER; + #[cfg(ossl102)] + pub fn EVP_aes_128_wrap() -> *const EVP_CIPHER; + #[cfg(ossl110)] + pub fn EVP_aes_128_wrap_pad() -> *const EVP_CIPHER; + pub fn EVP_aes_192_ecb() -> *const EVP_CIPHER; + pub fn EVP_aes_192_cbc() -> *const EVP_CIPHER; + pub fn EVP_aes_192_cfb1() -> *const EVP_CIPHER; + pub fn EVP_aes_192_cfb8() -> *const EVP_CIPHER; + pub fn EVP_aes_192_cfb128() -> *const EVP_CIPHER; + pub fn EVP_aes_192_ctr() -> *const EVP_CIPHER; + pub fn EVP_aes_192_ccm() -> *const EVP_CIPHER; + pub fn EVP_aes_192_gcm() -> *const EVP_CIPHER; + pub fn EVP_aes_192_ofb() -> *const EVP_CIPHER; + #[cfg(ossl110)] + pub fn EVP_aes_192_ocb() -> *const EVP_CIPHER; + #[cfg(ossl102)] + pub fn EVP_aes_192_wrap() -> *const EVP_CIPHER; + #[cfg(ossl110)] + pub fn EVP_aes_192_wrap_pad() -> *const EVP_CIPHER; + pub fn EVP_aes_256_ecb() -> *const EVP_CIPHER; + pub fn EVP_aes_256_cbc() -> *const EVP_CIPHER; + pub fn EVP_aes_256_cfb1() -> *const EVP_CIPHER; + pub fn EVP_aes_256_cfb8() -> *const EVP_CIPHER; + pub fn EVP_aes_256_cfb128() -> *const EVP_CIPHER; + pub fn EVP_aes_256_ctr() -> *const EVP_CIPHER; + pub fn EVP_aes_256_ccm() -> *const EVP_CIPHER; + pub fn EVP_aes_256_gcm() -> *const EVP_CIPHER; + pub fn EVP_aes_256_xts() -> *const EVP_CIPHER; + pub fn EVP_aes_256_ofb() -> *const EVP_CIPHER; + #[cfg(ossl110)] + pub fn EVP_aes_256_ocb() -> *const EVP_CIPHER; + #[cfg(ossl102)] + pub fn EVP_aes_256_wrap() -> *const EVP_CIPHER; + #[cfg(ossl110)] + pub fn EVP_aes_256_wrap_pad() -> *const EVP_CIPHER; + #[cfg(all(any(ossl110, libressl310), not(osslconf = "OPENSSL_NO_CHACHA")))] + pub fn EVP_chacha20() -> *const EVP_CIPHER; + #[cfg(all(any(ossl110, libressl360), not(osslconf = "OPENSSL_NO_CHACHA")))] + pub fn EVP_chacha20_poly1305() -> *const EVP_CIPHER; + #[cfg(not(osslconf = "OPENSSL_NO_SEED"))] + pub fn EVP_seed_cbc() -> *const EVP_CIPHER; + #[cfg(not(osslconf = "OPENSSL_NO_SEED"))] + pub fn EVP_seed_cfb128() -> *const EVP_CIPHER; + #[cfg(not(osslconf = "OPENSSL_NO_SEED"))] + pub fn EVP_seed_ecb() -> *const EVP_CIPHER; + #[cfg(not(osslconf = "OPENSSL_NO_SEED"))] + pub fn EVP_seed_ofb() -> *const EVP_CIPHER; + + #[cfg(all(any(ossl111, libressl291), not(osslconf = "OPENSSL_NO_SM4")))] + pub fn EVP_sm4_ecb() -> *const EVP_CIPHER; + #[cfg(all(any(ossl111, libressl291), not(osslconf = "OPENSSL_NO_SM4")))] + pub fn EVP_sm4_cbc() -> *const EVP_CIPHER; + #[cfg(all(any(ossl111, libressl291), not(osslconf = "OPENSSL_NO_SM4")))] + pub fn EVP_sm4_cfb128() -> *const EVP_CIPHER; + #[cfg(all(any(ossl111, libressl291), not(osslconf = "OPENSSL_NO_SM4")))] + pub fn EVP_sm4_ofb() -> *const EVP_CIPHER; + #[cfg(all(any(ossl111, libressl291), not(osslconf = "OPENSSL_NO_SM4")))] + pub fn EVP_sm4_ctr() -> *const EVP_CIPHER; + + #[cfg(not(osslconf = "OPENSSL_NO_CAMELLIA"))] + pub fn EVP_camellia_128_cfb128() -> *const EVP_CIPHER; + #[cfg(not(osslconf = "OPENSSL_NO_CAMELLIA"))] + pub fn EVP_camellia_128_ecb() -> *const EVP_CIPHER; + #[cfg(not(osslconf = "OPENSSL_NO_CAMELLIA"))] + pub fn EVP_camellia_128_cbc() -> *const EVP_CIPHER; + #[cfg(not(osslconf = "OPENSSL_NO_CAMELLIA"))] + pub fn EVP_camellia_128_ofb() -> *const EVP_CIPHER; + #[cfg(not(osslconf = "OPENSSL_NO_CAMELLIA"))] + pub fn EVP_camellia_192_cfb128() -> *const EVP_CIPHER; + #[cfg(not(osslconf = "OPENSSL_NO_CAMELLIA"))] + pub fn EVP_camellia_192_ecb() -> *const EVP_CIPHER; + #[cfg(not(osslconf = "OPENSSL_NO_CAMELLIA"))] + pub fn EVP_camellia_192_cbc() -> *const EVP_CIPHER; + #[cfg(not(osslconf = "OPENSSL_NO_CAMELLIA"))] + pub fn EVP_camellia_192_ofb() -> *const EVP_CIPHER; + #[cfg(not(osslconf = "OPENSSL_NO_CAMELLIA"))] + pub fn EVP_camellia_256_cfb128() -> *const EVP_CIPHER; + #[cfg(not(osslconf = "OPENSSL_NO_CAMELLIA"))] + pub fn EVP_camellia_256_ecb() -> *const EVP_CIPHER; + #[cfg(not(osslconf = "OPENSSL_NO_CAMELLIA"))] + pub fn EVP_camellia_256_cbc() -> *const EVP_CIPHER; + #[cfg(not(osslconf = "OPENSSL_NO_CAMELLIA"))] + pub fn EVP_camellia_256_ofb() -> *const EVP_CIPHER; + + #[cfg(not(osslconf = "OPENSSL_NO_CAST"))] + pub fn EVP_cast5_cfb64() -> *const EVP_CIPHER; + #[cfg(not(osslconf = "OPENSSL_NO_CAST"))] + pub fn EVP_cast5_ecb() -> *const EVP_CIPHER; + #[cfg(not(osslconf = "OPENSSL_NO_CAST"))] + pub fn EVP_cast5_cbc() -> *const EVP_CIPHER; + #[cfg(not(osslconf = "OPENSSL_NO_CAST"))] + pub fn EVP_cast5_ofb() -> *const EVP_CIPHER; + + #[cfg(not(osslconf = "OPENSSL_NO_IDEA"))] + pub fn EVP_idea_cfb64() -> *const EVP_CIPHER; + #[cfg(not(osslconf = "OPENSSL_NO_IDEA"))] + pub fn EVP_idea_ecb() -> *const EVP_CIPHER; + #[cfg(not(osslconf = "OPENSSL_NO_IDEA"))] + pub fn EVP_idea_cbc() -> *const EVP_CIPHER; + #[cfg(not(osslconf = "OPENSSL_NO_IDEA"))] + pub fn EVP_idea_ofb() -> *const EVP_CIPHER; + + #[cfg(not(ossl110))] + pub fn OPENSSL_add_all_algorithms_noconf(); + + pub fn EVP_get_digestbyname(name: *const c_char) -> *const EVP_MD; + pub fn EVP_get_cipherbyname(name: *const c_char) -> *const EVP_CIPHER; +} + +cfg_if! { + if #[cfg(ossl300)] { + extern "C" { + pub fn EVP_PKEY_get_id(pkey: *const EVP_PKEY) -> c_int; + pub fn EVP_PKEY_get_bits(key: *const EVP_PKEY) -> c_int; + pub fn EVP_PKEY_get_security_bits(key: *const EVP_PKEY) -> c_int; + } + } else { + extern "C" { + pub fn EVP_PKEY_id(pkey: *const EVP_PKEY) -> c_int; + } + const_ptr_api! { + extern "C" { + pub fn EVP_PKEY_bits(key: #[const_ptr_if(any(ossl110, libressl280))] EVP_PKEY) -> c_int; + #[cfg(any(ossl110, libressl360))] + pub fn EVP_PKEY_security_bits(pkey: #[const_ptr_if(any(ossl110, libressl280))] EVP_PKEY) -> c_int; + } + } + } +} +extern "C" { + pub fn EVP_PKEY_assign(pkey: *mut EVP_PKEY, typ: c_int, key: *mut c_void) -> c_int; + + pub fn EVP_PKEY_set1_RSA(k: *mut EVP_PKEY, r: *mut RSA) -> c_int; + pub fn EVP_PKEY_get1_RSA(k: *mut EVP_PKEY) -> *mut RSA; + pub fn EVP_PKEY_set1_DSA(k: *mut EVP_PKEY, k: *mut DSA) -> c_int; + pub fn EVP_PKEY_get1_DSA(k: *mut EVP_PKEY) -> *mut DSA; + pub fn EVP_PKEY_set1_DH(k: *mut EVP_PKEY, k: *mut DH) -> c_int; + pub fn EVP_PKEY_get1_DH(k: *mut EVP_PKEY) -> *mut DH; + pub fn EVP_PKEY_set1_EC_KEY(k: *mut EVP_PKEY, k: *mut EC_KEY) -> c_int; + pub fn EVP_PKEY_get1_EC_KEY(k: *mut EVP_PKEY) -> *mut EC_KEY; + + pub fn EVP_PKEY_new() -> *mut EVP_PKEY; + pub fn EVP_PKEY_free(k: *mut EVP_PKEY); + #[cfg(any(ossl110, libressl270))] + pub fn EVP_PKEY_up_ref(pkey: *mut EVP_PKEY) -> c_int; + + pub fn d2i_AutoPrivateKey( + a: *mut *mut EVP_PKEY, + pp: *mut *const c_uchar, + length: c_long, + ) -> *mut EVP_PKEY; + + pub fn EVP_PKEY_cmp(a: *const EVP_PKEY, b: *const EVP_PKEY) -> c_int; + + pub fn EVP_PKEY_copy_parameters(to: *mut EVP_PKEY, from: *const EVP_PKEY) -> c_int; + + pub fn PKCS5_PBKDF2_HMAC_SHA1( + pass: *const c_char, + passlen: c_int, + salt: *const u8, + saltlen: c_int, + iter: c_int, + keylen: c_int, + out: *mut u8, + ) -> c_int; + pub fn PKCS5_PBKDF2_HMAC( + pass: *const c_char, + passlen: c_int, + salt: *const c_uchar, + saltlen: c_int, + iter: c_int, + digest: *const EVP_MD, + keylen: c_int, + out: *mut u8, + ) -> c_int; + + #[cfg(ossl110)] + pub fn EVP_PBE_scrypt( + pass: *const c_char, + passlen: size_t, + salt: *const c_uchar, + saltlen: size_t, + N: u64, + r: u64, + p: u64, + maxmem: u64, + key: *mut c_uchar, + keylen: size_t, + ) -> c_int; + + pub fn EVP_PKEY_CTX_new(k: *mut EVP_PKEY, e: *mut ENGINE) -> *mut EVP_PKEY_CTX; + pub fn EVP_PKEY_CTX_new_id(id: c_int, e: *mut ENGINE) -> *mut EVP_PKEY_CTX; + pub fn EVP_PKEY_CTX_free(ctx: *mut EVP_PKEY_CTX); + + pub fn EVP_PKEY_CTX_ctrl( + ctx: *mut EVP_PKEY_CTX, + keytype: c_int, + optype: c_int, + cmd: c_int, + p1: c_int, + p2: *mut c_void, + ) -> c_int; + + #[cfg(ossl300)] + pub fn EVP_PKEY_CTX_set_signature_md(ctx: *mut EVP_PKEY_CTX, md: *const EVP_MD) -> c_int; + + #[cfg(ossl300)] + pub fn EVP_PKEY_CTX_set_params(ctx: *mut EVP_PKEY_CTX, params: *const OSSL_PARAM) -> c_int; + + #[cfg(ossl300)] + pub fn EVP_PKEY_CTX_get_params(ctx: *mut EVP_PKEY_CTX, params: *mut OSSL_PARAM) -> c_int; + + pub fn EVP_PKEY_new_mac_key( + type_: c_int, + e: *mut ENGINE, + key: *const c_uchar, + keylen: c_int, + ) -> *mut EVP_PKEY; + + pub fn EVP_PKEY_derive_init(ctx: *mut EVP_PKEY_CTX) -> c_int; + pub fn EVP_PKEY_derive_set_peer(ctx: *mut EVP_PKEY_CTX, peer: *mut EVP_PKEY) -> c_int; + #[cfg(ossl300)] + pub fn EVP_PKEY_derive_set_peer_ex( + ctx: *mut EVP_PKEY_CTX, + peer: *mut EVP_PKEY, + validate_peer: c_int, + ) -> c_int; + pub fn EVP_PKEY_derive(ctx: *mut EVP_PKEY_CTX, key: *mut c_uchar, size: *mut size_t) -> c_int; + + #[cfg(ossl300)] + pub fn EVP_PKEY_Q_keygen( + libctx: *mut OSSL_LIB_CTX, + propq: *const c_char, + type_: *const c_char, + ... + ) -> *mut EVP_PKEY; + pub fn EVP_PKEY_keygen_init(ctx: *mut EVP_PKEY_CTX) -> c_int; + pub fn EVP_PKEY_keygen(ctx: *mut EVP_PKEY_CTX, key: *mut *mut EVP_PKEY) -> c_int; + + pub fn EVP_PKEY_sign_init(ctx: *mut EVP_PKEY_CTX) -> c_int; + pub fn EVP_PKEY_sign( + ctx: *mut EVP_PKEY_CTX, + sig: *mut c_uchar, + siglen: *mut size_t, + tbs: *const c_uchar, + tbslen: size_t, + ) -> c_int; + pub fn EVP_PKEY_verify_init(ctx: *mut EVP_PKEY_CTX) -> c_int; + pub fn EVP_PKEY_verify( + ctx: *mut EVP_PKEY_CTX, + sig: *const c_uchar, + siglen: size_t, + tbs: *const c_uchar, + tbslen: size_t, + ) -> c_int; + pub fn EVP_PKEY_encrypt_init(ctx: *mut EVP_PKEY_CTX) -> c_int; + pub fn EVP_PKEY_encrypt( + ctx: *mut EVP_PKEY_CTX, + pout: *mut c_uchar, + poutlen: *mut size_t, + pin: *const c_uchar, + pinlen: size_t, + ) -> c_int; + pub fn EVP_PKEY_decrypt_init(ctx: *mut EVP_PKEY_CTX) -> c_int; + pub fn EVP_PKEY_decrypt( + ctx: *mut EVP_PKEY_CTX, + pout: *mut c_uchar, + poutlen: *mut size_t, + pin: *const c_uchar, + pinlen: size_t, + ) -> c_int; + pub fn EVP_PKEY_verify_recover_init(ctx: *mut EVP_PKEY_CTX) -> c_int; + pub fn EVP_PKEY_verify_recover( + ctx: *mut EVP_PKEY_CTX, + rout: *mut c_uchar, + routlen: *mut size_t, + sig: *const c_uchar, + siglen: size_t, + ) -> c_int; +} + +const_ptr_api! { + extern "C" { + pub fn EVP_PKCS82PKEY(p8: #[const_ptr_if(any(ossl110, libressl280))] PKCS8_PRIV_KEY_INFO) -> *mut EVP_PKEY; + } +} + +cfg_if! { + if #[cfg(any(ossl111, libressl370))] { + extern "C" { + pub fn EVP_PKEY_get_raw_public_key( + pkey: *const EVP_PKEY, + ppub: *mut c_uchar, + len: *mut size_t, + ) -> c_int; + pub fn EVP_PKEY_new_raw_public_key( + ttype: c_int, + e: *mut ENGINE, + key: *const c_uchar, + keylen: size_t, + ) -> *mut EVP_PKEY; + pub fn EVP_PKEY_get_raw_private_key( + pkey: *const EVP_PKEY, + ppriv: *mut c_uchar, + len: *mut size_t, + ) -> c_int; + pub fn EVP_PKEY_new_raw_private_key( + ttype: c_int, + e: *mut ENGINE, + key: *const c_uchar, + keylen: size_t, + ) -> *mut EVP_PKEY; + } + } +} + +extern "C" { + pub fn EVP_EncodeBlock(dst: *mut c_uchar, src: *const c_uchar, src_len: c_int) -> c_int; + pub fn EVP_DecodeBlock(dst: *mut c_uchar, src: *const c_uchar, src_len: c_int) -> c_int; +} diff --git a/vendor/openssl-sys/src/handwritten/hmac.rs b/vendor/openssl-sys/src/handwritten/hmac.rs new file mode 100644 index 0000000..b52d63f --- /dev/null +++ b/vendor/openssl-sys/src/handwritten/hmac.rs @@ -0,0 +1,30 @@ +use libc::*; + +use super::super::*; + +cfg_if! { + if #[cfg(any(ossl110, libressl350))] { + extern "C" { + pub fn HMAC_CTX_new() -> *mut HMAC_CTX; + pub fn HMAC_CTX_free(ctx: *mut HMAC_CTX); + } + } else { + extern "C" { + pub fn HMAC_CTX_init(ctx: *mut HMAC_CTX); + pub fn HMAC_CTX_cleanup(ctx: *mut HMAC_CTX); + } + } +} + +extern "C" { + pub fn HMAC_Init_ex( + ctx: *mut HMAC_CTX, + key: *const c_void, + len: c_int, + md: *const EVP_MD, + impl_: *mut ENGINE, + ) -> c_int; + pub fn HMAC_Update(ctx: *mut HMAC_CTX, data: *const c_uchar, len: size_t) -> c_int; + pub fn HMAC_Final(ctx: *mut HMAC_CTX, md: *mut c_uchar, len: *mut c_uint) -> c_int; + pub fn HMAC_CTX_copy(dst: *mut HMAC_CTX, src: *mut HMAC_CTX) -> c_int; +} diff --git a/vendor/openssl-sys/src/handwritten/kdf.rs b/vendor/openssl-sys/src/handwritten/kdf.rs new file mode 100644 index 0000000..d34f274 --- /dev/null +++ b/vendor/openssl-sys/src/handwritten/kdf.rs @@ -0,0 +1,34 @@ +use super::super::*; +use libc::*; + +cfg_if! { + if #[cfg(ossl300)] { + extern "C" { + pub fn EVP_PKEY_CTX_set_hkdf_mode(ctx: *mut EVP_PKEY_CTX, mode: c_int) -> c_int; + pub fn EVP_PKEY_CTX_set_hkdf_md(ctx: *mut EVP_PKEY_CTX, md: *const EVP_MD) -> c_int; + pub fn EVP_PKEY_CTX_set1_hkdf_salt( + ctx: *mut EVP_PKEY_CTX, + salt: *const u8, + saltlen: c_int, + ) -> c_int; + pub fn EVP_PKEY_CTX_set1_hkdf_key( + ctx: *mut EVP_PKEY_CTX, + key: *const u8, + keylen: c_int, + ) -> c_int; + pub fn EVP_PKEY_CTX_add1_hkdf_info( + ctx: *mut EVP_PKEY_CTX, + info: *const u8, + infolen: c_int, + ) -> c_int; + pub fn EVP_KDF_CTX_new(kdf: *mut EVP_KDF) -> *mut EVP_KDF_CTX; + pub fn EVP_KDF_CTX_free(ctx: *mut EVP_KDF_CTX); + pub fn EVP_KDF_CTX_reset(ctx: *mut EVP_KDF_CTX); + pub fn EVP_KDF_CTX_get_kdf_size(ctx: *mut EVP_KDF_CTX) -> size_t; + pub fn EVP_KDF_derive(ctx: *mut EVP_KDF_CTX, key: *mut u8, keylen: size_t, params: *const OSSL_PARAM) -> c_int; + pub fn EVP_KDF_fetch(ctx: *mut OSSL_LIB_CTX, algorithm: *const c_char, properties: *const c_char) -> *mut EVP_KDF; + pub fn EVP_KDF_free(kdf: *mut EVP_KDF); + } + + } +} diff --git a/vendor/openssl-sys/src/handwritten/mod.rs b/vendor/openssl-sys/src/handwritten/mod.rs new file mode 100644 index 0000000..47b3360 --- /dev/null +++ b/vendor/openssl-sys/src/handwritten/mod.rs @@ -0,0 +1,77 @@ +pub use self::aes::*; +pub use self::asn1::*; +pub use self::bio::*; +pub use self::bn::*; +pub use self::cmac::*; +pub use self::cms::*; +pub use self::conf::*; +pub use self::crypto::*; +pub use self::dh::*; +pub use self::dsa::*; +pub use self::ec::*; +pub use self::err::*; +pub use self::evp::*; +pub use self::hmac::*; +pub use self::kdf::*; +pub use self::object::*; +pub use self::ocsp::*; +pub use self::params::*; +pub use self::pem::*; +pub use self::pkcs12::*; +pub use self::pkcs7::*; +#[cfg(libressl)] +pub use self::poly1305::*; +pub use self::provider::*; +pub use self::rand::*; +pub use self::rsa::*; +pub use self::safestack::*; +pub use self::sha::*; +pub use self::srtp::*; +pub use self::ssl::*; +pub use self::stack::*; +#[cfg(ossl320)] +pub use self::thread::*; +pub use self::tls1::*; +pub use self::types::*; +pub use self::x509::*; +pub use self::x509_vfy::*; +pub use self::x509v3::*; + +mod aes; +mod asn1; +mod bio; +mod bn; +mod cmac; +mod cms; +mod conf; +mod crypto; +mod dh; +mod dsa; +mod ec; +mod err; +mod evp; +mod hmac; +mod kdf; +mod object; +mod ocsp; +mod params; +mod pem; +mod pkcs12; +mod pkcs7; +#[cfg(libressl)] +mod poly1305; +mod provider; +mod rand; +mod rsa; +mod safestack; +mod sha; +mod srtp; +mod ssl; +mod stack; +#[cfg(ossl320)] +mod thread; +mod tls1; +mod types; +mod x509; +mod x509_vfy; +mod x509v3; diff --git a/vendor/openssl-sys/src/handwritten/object.rs b/vendor/openssl-sys/src/handwritten/object.rs new file mode 100644 index 0000000..6160fad --- /dev/null +++ b/vendor/openssl-sys/src/handwritten/object.rs @@ -0,0 +1,31 @@ +use libc::*; + +use super::super::*; + +extern "C" { + pub fn OBJ_nid2ln(nid: c_int) -> *const c_char; + pub fn OBJ_nid2sn(nid: c_int) -> *const c_char; + pub fn OBJ_nid2obj(n: c_int) -> *mut ASN1_OBJECT; + pub fn OBJ_obj2nid(o: *const ASN1_OBJECT) -> c_int; + pub fn OBJ_obj2txt( + buf: *mut c_char, + buf_len: c_int, + a: *const ASN1_OBJECT, + no_name: c_int, + ) -> c_int; + + pub fn OBJ_find_sigid_algs(signid: c_int, pdig_nid: *mut c_int, ppkey_nid: *mut c_int) + -> c_int; + pub fn OBJ_sn2nid(sn: *const libc::c_char) -> libc::c_int; + pub fn OBJ_txt2obj(s: *const libc::c_char, no_name: libc::c_int) -> *mut ASN1_OBJECT; + pub fn OBJ_create( + oid: *const libc::c_char, + sn: *const libc::c_char, + ln: *const libc::c_char, + ) -> c_int; + #[cfg(ossl111)] + pub fn OBJ_length(obj: *const ASN1_OBJECT) -> libc::size_t; + #[cfg(ossl111)] + pub fn OBJ_get0_data(obj: *const ASN1_OBJECT) -> *const c_uchar; + pub fn OBJ_cmp(a: *const ASN1_OBJECT, b: *const ASN1_OBJECT) -> c_int; +} diff --git a/vendor/openssl-sys/src/handwritten/ocsp.rs b/vendor/openssl-sys/src/handwritten/ocsp.rs new file mode 100644 index 0000000..c194a83 --- /dev/null +++ b/vendor/openssl-sys/src/handwritten/ocsp.rs @@ -0,0 +1,89 @@ +use super::super::*; +use libc::*; + +pub enum OCSP_CERTID {} + +pub enum OCSP_ONEREQ {} + +pub enum OCSP_REQUEST {} + +pub enum OCSP_BASICRESP {} + +const_ptr_api! { + extern "C" { + pub fn OCSP_cert_to_id( + dgst: *const EVP_MD, + subject: #[const_ptr_if(any(ossl110, libressl281))] X509, + issuer: #[const_ptr_if(any(ossl110, libressl281))] X509, + ) -> *mut OCSP_CERTID; + } +} + +extern "C" { + pub fn OCSP_request_add0_id(r: *mut OCSP_REQUEST, id: *mut OCSP_CERTID) -> *mut OCSP_ONEREQ; + + pub fn OCSP_resp_find_status( + bs: *mut OCSP_BASICRESP, + id: *mut OCSP_CERTID, + status: *mut c_int, + reason: *mut c_int, + revtime: *mut *mut ASN1_GENERALIZEDTIME, + thisupd: *mut *mut ASN1_GENERALIZEDTIME, + nextupd: *mut *mut ASN1_GENERALIZEDTIME, + ) -> c_int; + pub fn OCSP_check_validity( + thisupd: *mut ASN1_GENERALIZEDTIME, + nextupd: *mut ASN1_GENERALIZEDTIME, + sec: c_long, + maxsec: c_long, + ) -> c_int; + + pub fn OCSP_response_status(resp: *mut OCSP_RESPONSE) -> c_int; + pub fn OCSP_response_get1_basic(resp: *mut OCSP_RESPONSE) -> *mut OCSP_BASICRESP; + + pub fn OCSP_response_create(status: c_int, bs: *mut OCSP_BASICRESP) -> *mut OCSP_RESPONSE; + + pub fn OCSP_BASICRESP_new() -> *mut OCSP_BASICRESP; + pub fn OCSP_BASICRESP_free(r: *mut OCSP_BASICRESP); + pub fn OCSP_RESPONSE_new() -> *mut OCSP_RESPONSE; + pub fn OCSP_RESPONSE_free(r: *mut OCSP_RESPONSE); +} + +const_ptr_api! { + extern "C" { + pub fn i2d_OCSP_RESPONSE(a: #[const_ptr_if(ossl300)] OCSP_RESPONSE, pp: *mut *mut c_uchar) -> c_int; + } +} + +extern "C" { + pub fn d2i_OCSP_RESPONSE( + a: *mut *mut OCSP_RESPONSE, + pp: *mut *const c_uchar, + length: c_long, + ) -> *mut OCSP_RESPONSE; + pub fn OCSP_ONEREQ_free(r: *mut OCSP_ONEREQ); + pub fn OCSP_CERTID_free(id: *mut OCSP_CERTID); + pub fn OCSP_REQUEST_new() -> *mut OCSP_REQUEST; + pub fn OCSP_REQUEST_free(r: *mut OCSP_REQUEST); +} + +const_ptr_api! { + extern "C" { + pub fn i2d_OCSP_REQUEST(a: #[const_ptr_if(ossl300)] OCSP_REQUEST, pp: *mut *mut c_uchar) -> c_int; + } +} + +extern "C" { + pub fn d2i_OCSP_REQUEST( + a: *mut *mut OCSP_REQUEST, + pp: *mut *const c_uchar, + length: c_long, + ) -> *mut OCSP_REQUEST; + + pub fn OCSP_basic_verify( + bs: *mut OCSP_BASICRESP, + certs: *mut stack_st_X509, + st: *mut X509_STORE, + flags: c_ulong, + ) -> c_int; +} diff --git a/vendor/openssl-sys/src/handwritten/params.rs b/vendor/openssl-sys/src/handwritten/params.rs new file mode 100644 index 0000000..542cef3 --- /dev/null +++ b/vendor/openssl-sys/src/handwritten/params.rs @@ -0,0 +1,16 @@ +use super::super::*; +use libc::*; + +extern "C" { + #[cfg(ossl300)] + pub fn OSSL_PARAM_construct_uint(key: *const c_char, buf: *mut c_uint) -> OSSL_PARAM; + #[cfg(ossl300)] + pub fn OSSL_PARAM_construct_end() -> OSSL_PARAM; + #[cfg(ossl300)] + pub fn OSSL_PARAM_construct_octet_string( + key: *const c_char, + buf: *mut c_void, + bsize: size_t, + ) -> OSSL_PARAM; + +} diff --git a/vendor/openssl-sys/src/handwritten/pem.rs b/vendor/openssl-sys/src/handwritten/pem.rs new file mode 100644 index 0000000..4299717 --- /dev/null +++ b/vendor/openssl-sys/src/handwritten/pem.rs @@ -0,0 +1,191 @@ +use super::super::*; +use libc::*; + +pub type pem_password_cb = Option< + unsafe extern "C" fn( + buf: *mut c_char, + size: c_int, + rwflag: c_int, + user_data: *mut c_void, + ) -> c_int, +>; + +const_ptr_api! { + extern "C" { + pub fn PEM_write_bio_X509(bio: *mut BIO, x509: #[const_ptr_if(ossl300)] X509) -> c_int; + pub fn PEM_write_bio_X509_REQ(bio: *mut BIO, x509: #[const_ptr_if(ossl300)] X509_REQ) -> c_int; + pub fn PEM_write_bio_X509_CRL(bio: *mut BIO, x509: #[const_ptr_if(ossl300)] X509_CRL) -> c_int; + pub fn PEM_write_bio_RSAPrivateKey( + bp: *mut BIO, + rsa: #[const_ptr_if(ossl300)] RSA, + cipher: *const EVP_CIPHER, + kstr: #[const_ptr_if(ossl300)] c_uchar, + klen: c_int, + callback: pem_password_cb, + user_data: *mut c_void, + ) -> c_int; + pub fn PEM_write_bio_RSA_PUBKEY(bp: *mut BIO, rsa: #[const_ptr_if(ossl300)] RSA) -> c_int; + pub fn PEM_write_bio_DSAPrivateKey( + bp: *mut BIO, + dsa: #[const_ptr_if(ossl300)] DSA, + cipher: *const EVP_CIPHER, + kstr: #[const_ptr_if(ossl300)] c_uchar, + klen: c_int, + callback: pem_password_cb, + user_data: *mut c_void, + ) -> c_int; + pub fn PEM_write_bio_ECPrivateKey( + bio: *mut BIO, + key: #[const_ptr_if(ossl300)] EC_KEY, + cipher: *const EVP_CIPHER, + kstr: #[const_ptr_if(ossl300)] c_uchar, + klen: c_int, + callback: pem_password_cb, + user_data: *mut c_void, + ) -> c_int; + pub fn PEM_write_bio_DSA_PUBKEY(bp: *mut BIO, dsa: #[const_ptr_if(ossl300)] DSA) -> c_int; + pub fn PEM_write_bio_PrivateKey( + bio: *mut BIO, + pkey: #[const_ptr_if(ossl300)] EVP_PKEY, + cipher: *const EVP_CIPHER, + kstr: #[const_ptr_if(ossl300)] c_uchar, + klen: c_int, + callback: pem_password_cb, + user_data: *mut c_void, + ) -> c_int; + pub fn PEM_write_bio_PUBKEY(bp: *mut BIO, x: #[const_ptr_if(ossl300)] EVP_PKEY) -> c_int; + pub fn PEM_write_bio_PKCS8PrivateKey( + bio: *mut BIO, + pkey: #[const_ptr_if(ossl300)] EVP_PKEY, + cipher: *const EVP_CIPHER, + kstr: #[const_ptr_if(ossl300)] c_char, + klen: c_int, + callback: pem_password_cb, + user_data: *mut c_void, + ) -> c_int; + pub fn PEM_write_bio_PKCS7(bp: *mut BIO, x: #[const_ptr_if(ossl300)] PKCS7) -> c_int; + pub fn PEM_write_bio_EC_PUBKEY(bp: *mut BIO, ec: #[const_ptr_if(ossl300)] EC_KEY) -> c_int; + pub fn i2d_PKCS8PrivateKey_bio( + bp: *mut BIO, + x: #[const_ptr_if(ossl300)] EVP_PKEY, + enc: *const EVP_CIPHER, + kstr: #[const_ptr_if(ossl300)] c_char, + klen: c_int, + cb: pem_password_cb, + u: *mut c_void, + ) -> c_int; + } +} + +extern "C" { + pub fn PEM_read_bio_X509( + bio: *mut BIO, + out: *mut *mut X509, + callback: pem_password_cb, + user_data: *mut c_void, + ) -> *mut X509; + pub fn PEM_read_bio_X509_REQ( + bio: *mut BIO, + out: *mut *mut X509_REQ, + callback: pem_password_cb, + user_data: *mut c_void, + ) -> *mut X509_REQ; + pub fn PEM_read_bio_X509_CRL( + bio: *mut BIO, + out: *mut *mut X509_CRL, + callback: pem_password_cb, + user_data: *mut c_void, + ) -> *mut X509_CRL; + pub fn PEM_read_bio_RSAPrivateKey( + bio: *mut BIO, + rsa: *mut *mut RSA, + callback: pem_password_cb, + user_data: *mut c_void, + ) -> *mut RSA; + pub fn PEM_read_bio_RSAPublicKey( + bio: *mut BIO, + rsa: *mut *mut RSA, + callback: pem_password_cb, + user_data: *mut c_void, + ) -> *mut RSA; + pub fn PEM_write_bio_RSAPublicKey(bp: *mut BIO, rsa: *const RSA) -> c_int; + pub fn PEM_read_bio_RSA_PUBKEY( + bio: *mut BIO, + rsa: *mut *mut RSA, + callback: pem_password_cb, + user_data: *mut c_void, + ) -> *mut RSA; + pub fn PEM_read_bio_DSAPrivateKey( + bp: *mut BIO, + dsa: *mut *mut DSA, + callback: pem_password_cb, + user_data: *mut c_void, + ) -> *mut DSA; + pub fn PEM_read_bio_DSA_PUBKEY( + bp: *mut BIO, + dsa: *mut *mut DSA, + callback: pem_password_cb, + user_data: *mut c_void, + ) -> *mut DSA; + pub fn PEM_read_bio_ECPrivateKey( + bio: *mut BIO, + key: *mut *mut EC_KEY, + callback: pem_password_cb, + user_data: *mut c_void, + ) -> *mut EC_KEY; + pub fn PEM_read_bio_EC_PUBKEY( + bp: *mut BIO, + ec: *mut *mut EC_KEY, + callback: pem_password_cb, + user_data: *mut c_void, + ) -> *mut EC_KEY; + pub fn PEM_read_bio_DHparams( + bio: *mut BIO, + out: *mut *mut DH, + callback: pem_password_cb, + user_data: *mut c_void, + ) -> *mut DH; + pub fn PEM_write_bio_DHparams(bio: *mut BIO, x: *const DH) -> c_int; + pub fn PEM_read_bio_PrivateKey( + bio: *mut BIO, + out: *mut *mut EVP_PKEY, + callback: pem_password_cb, + user_data: *mut c_void, + ) -> *mut EVP_PKEY; + pub fn PEM_read_bio_PUBKEY( + bio: *mut BIO, + out: *mut *mut EVP_PKEY, + callback: pem_password_cb, + user_data: *mut c_void, + ) -> *mut EVP_PKEY; + + pub fn d2i_PKCS8PrivateKey_bio( + bp: *mut BIO, + x: *mut *mut EVP_PKEY, + cb: pem_password_cb, + u: *mut c_void, + ) -> *mut EVP_PKEY; + pub fn d2i_PKCS8_PRIV_KEY_INFO( + k: *mut *mut PKCS8_PRIV_KEY_INFO, + buf: *mut *const u8, + length: c_long, + ) -> *mut PKCS8_PRIV_KEY_INFO; + pub fn PKCS8_PRIV_KEY_INFO_free(p8inf: *mut PKCS8_PRIV_KEY_INFO); + + pub fn PEM_read_bio_PKCS7( + bio: *mut BIO, + out: *mut *mut PKCS7, + cb: pem_password_cb, + u: *mut c_void, + ) -> *mut PKCS7; + + #[cfg(ossl101)] + pub fn PEM_read_bio_CMS( + bio: *mut BIO, + out: *mut *mut CMS_ContentInfo, + callback: pem_password_cb, + user_data: *mut c_void, + ) -> *mut CMS_ContentInfo; + #[cfg(ossl101)] + pub fn PEM_write_bio_CMS(bio: *mut BIO, cms: *const CMS_ContentInfo) -> c_int; +} diff --git a/vendor/openssl-sys/src/handwritten/pkcs12.rs b/vendor/openssl-sys/src/handwritten/pkcs12.rs new file mode 100644 index 0000000..728c333 --- /dev/null +++ b/vendor/openssl-sys/src/handwritten/pkcs12.rs @@ -0,0 +1,53 @@ +use libc::*; + +use super::super::*; + +pub enum PKCS12 {} + +extern "C" { + pub fn PKCS12_free(p12: *mut PKCS12); +} +const_ptr_api! { + extern "C" { + pub fn i2d_PKCS12(a: #[const_ptr_if(ossl300)] PKCS12, buf: *mut *mut u8) -> c_int; + } +} +extern "C" { + pub fn d2i_PKCS12(a: *mut *mut PKCS12, pp: *mut *const u8, length: c_long) -> *mut PKCS12; + + pub fn PKCS12_parse( + p12: *mut PKCS12, + pass: *const c_char, + pkey: *mut *mut EVP_PKEY, + cert: *mut *mut X509, + ca: *mut *mut stack_st_X509, + ) -> c_int; + + pub fn PKCS12_set_mac( + p12: *mut PKCS12, + pass: *const c_char, + passlen: c_int, + salt: *mut c_uchar, + saltlen: c_int, + iter: c_int, + md_type: *const EVP_MD, + ) -> c_int; +} +const_ptr_api! { + extern "C" { + pub fn PKCS12_create( + pass: #[const_ptr_if(any(ossl110, libressl280))] c_char, + friendly_name: #[const_ptr_if(any(ossl110, libressl280))] c_char, + pkey: *mut EVP_PKEY, + cert: *mut X509, + ca: *mut stack_st_X509, + nid_key: c_int, + nid_cert: c_int, + iter: c_int, + mac_iter: c_int, + keytype: c_int, + ) -> *mut PKCS12; + + pub fn i2d_PKCS12_bio(b: *mut BIO, a: #[const_ptr_if(ossl300)] PKCS12) -> c_int; + } +} diff --git a/vendor/openssl-sys/src/handwritten/pkcs7.rs b/vendor/openssl-sys/src/handwritten/pkcs7.rs new file mode 100644 index 0000000..f46922d --- /dev/null +++ b/vendor/openssl-sys/src/handwritten/pkcs7.rs @@ -0,0 +1,257 @@ +use super::super::*; +use libc::*; + +#[cfg(ossl300)] +#[repr(C)] +pub struct PKCS7_CTX { + libctx: *mut OSSL_LIB_CTX, + propq: *mut c_char, +} + +#[repr(C)] +pub struct PKCS7_SIGNED { + pub version: *mut ASN1_INTEGER, /* version 1 */ + pub md_algs: *mut stack_st_X509_ALGOR, /* md used */ + pub cert: *mut stack_st_X509, /* [ 0 ] */ + pub crl: *mut stack_st_X509_CRL, /* [ 1 ] */ + pub signer_info: *mut stack_st_PKCS7_SIGNER_INFO, + pub contents: *mut PKCS7, +} +#[repr(C)] +pub struct PKCS7_ENC_CONTENT { + pub content_type: *mut ASN1_OBJECT, + pub algorithm: *mut X509_ALGOR, + pub enc_data: *mut ASN1_OCTET_STRING, /* [ 0 ] */ + pub cipher: *const EVP_CIPHER, + #[cfg(ossl300)] + pub ctx: *const PKCS7_CTX, +} +#[repr(C)] +pub struct PKCS7_ENVELOPE { + pub version: *mut ASN1_INTEGER, /* version 0 */ + pub recipientinfo: *mut stack_st_PKCS7_RECIP_INFO, + pub enc_data: *mut PKCS7_ENC_CONTENT, +} +#[repr(C)] +pub struct PKCS7_SIGN_ENVELOPE { + pub version: *mut ASN1_INTEGER, /* version 1 */ + pub md_algs: *mut stack_st_X509_ALGOR, /* md used */ + pub cert: *mut stack_st_X509, /* [ 0 ] */ + pub crl: *mut stack_st_X509_CRL, /* [ 1 ] */ + pub signer_info: *mut stack_st_PKCS7_SIGNER_INFO, + pub enc_data: *mut PKCS7_ENC_CONTENT, + pub recipientinfo: *mut stack_st_PKCS7_RECIP_INFO, +} +#[repr(C)] +pub struct PKCS7_DIGEST { + pub version: *mut ASN1_INTEGER, /* version 0 */ + pub md: *mut X509_ALGOR, /* md used */ + pub contents: *mut PKCS7, + pub digest: *mut ASN1_OCTET_STRING, +} +#[repr(C)] +pub struct PKCS7_ENCRYPT { + pub version: *mut ASN1_INTEGER, /* version 0 */ + pub enc_data: *mut PKCS7_ENC_CONTENT, +} + +extern "C" { + pub fn PKCS7_SIGNED_free(info: *mut PKCS7_SIGNED); + pub fn PKCS7_ENC_CONTENT_free(info: *mut PKCS7_ENC_CONTENT); + pub fn PKCS7_ENVELOPE_free(info: *mut PKCS7_ENVELOPE); + pub fn PKCS7_SIGN_ENVELOPE_free(info: *mut PKCS7_SIGN_ENVELOPE); + pub fn PKCS7_DIGEST_free(info: *mut PKCS7_DIGEST); + pub fn PKCS7_SIGNER_INFO_free(info: *mut PKCS7_SIGNER_INFO); + pub fn PKCS7_ENCRYPT_free(enc: *mut PKCS7_ENCRYPT); + pub fn PKCS7_ISSUER_AND_SERIAL_free(ias: *mut PKCS7_ISSUER_AND_SERIAL); + pub fn PKCS7_RECIP_INFO_free(info: *mut PKCS7_RECIP_INFO); +} + +#[repr(C)] +pub struct PKCS7 { + /* + * The following is non NULL if it contains ASN1 encoding of this + * structure + */ + pub asn1: *mut c_uchar, + pub length: c_long, + // # define PKCS7_S_HEADER 0 + // # define PKCS7_S_BODY 1 + // # define PKCS7_S_TAIL 2 + pub state: c_int, /* used during processing */ + pub detached: c_int, + pub type_: *mut ASN1_OBJECT, + /* content as defined by the type */ + /* + * all encryption/message digests are applied to the 'contents', leaving + * out the 'type' field. + */ + pub d: PKCS7_data, + #[cfg(ossl300)] + pub ctx: PKCS7_CTX, +} + +#[repr(C)] +pub union PKCS7_data { + pub ptr: *mut c_char, + /* NID_pkcs7_data */ + pub data: *mut ASN1_OCTET_STRING, + /* NID_pkcs7_signed */ + pub sign: *mut PKCS7_SIGNED, + /* NID_pkcs7_enveloped */ + pub enveloped: *mut PKCS7_ENVELOPE, + /* NID_pkcs7_signedAndEnveloped */ + pub signed_and_enveloped: *mut PKCS7_SIGN_ENVELOPE, + /* NID_pkcs7_digest */ + pub digest: *mut PKCS7_DIGEST, + /* NID_pkcs7_encrypted */ + pub encrypted: *mut PKCS7_ENCRYPT, + /* Anything else */ + pub other: *mut ASN1_TYPE, +} + +#[repr(C)] +pub struct PKCS7_ISSUER_AND_SERIAL { + pub issuer: *mut X509_NAME, + pub serial: *mut ASN1_INTEGER, +} + +#[repr(C)] +pub struct PKCS7_SIGNER_INFO { + pub version: *mut ASN1_INTEGER, /* version 1 */ + pub issuer_and_serial: *mut PKCS7_ISSUER_AND_SERIAL, + pub digest_alg: *mut X509_ALGOR, + pub auth_attr: *mut stack_st_X509_ATTRIBUTE, /* [ 0 ] */ + pub digest_enc_alg: *mut X509_ALGOR, + pub enc_digest: *mut ASN1_OCTET_STRING, + pub unauth_attr: *mut stack_st_X509_ATTRIBUTE, /* [ 1 ] */ + pub pkey: *mut EVP_PKEY, /* The private key to sign with */ + #[cfg(ossl300)] + pub ctx: *const PKCS7_CTX, +} + +stack!(stack_st_PKCS7_SIGNER_INFO); + +#[repr(C)] +pub struct PKCS7_RECIP_INFO { + pub version: *mut ASN1_INTEGER, /* version 0 */ + pub issuer_and_serial: *mut PKCS7_ISSUER_AND_SERIAL, + pub key_enc_algor: *mut X509_ALGOR, + pub enc_key: *mut ASN1_OCTET_STRING, + pub cert: *mut X509, /* get the pub-key from this */ + #[cfg(ossl300)] + pub ctx: *const PKCS7_CTX, +} + +stack!(stack_st_PKCS7_RECIP_INFO); + +extern "C" { + pub fn d2i_PKCS7(a: *mut *mut PKCS7, pp: *mut *const c_uchar, length: c_long) -> *mut PKCS7; +} + +const_ptr_api! { + extern "C" { + pub fn i2d_PKCS7(a: #[const_ptr_if(ossl300)] PKCS7, buf: *mut *mut u8) -> c_int; + pub fn i2d_PKCS7_bio(bio: *mut BIO, p7: #[const_ptr_if(ossl300)] PKCS7) -> c_int; + } +} + +extern "C" { + pub fn PKCS7_encrypt( + certs: *mut stack_st_X509, + b: *mut BIO, + cipher: *const EVP_CIPHER, + flags: c_int, + ) -> *mut PKCS7; + + pub fn PKCS7_verify( + pkcs7: *mut PKCS7, + certs: *mut stack_st_X509, + store: *mut X509_STORE, + indata: *mut BIO, + out: *mut BIO, + flags: c_int, + ) -> c_int; + + pub fn PKCS7_get0_signers( + pkcs7: *mut PKCS7, + certs: *mut stack_st_X509, + flags: c_int, + ) -> *mut stack_st_X509; + + pub fn PKCS7_sign( + signcert: *mut X509, + pkey: *mut EVP_PKEY, + certs: *mut stack_st_X509, + data: *mut BIO, + flags: c_int, + ) -> *mut PKCS7; + + pub fn PKCS7_decrypt( + pkcs7: *mut PKCS7, + pkey: *mut EVP_PKEY, + cert: *mut X509, + data: *mut BIO, + flags: c_int, + ) -> c_int; + + pub fn PKCS7_free(pkcs7: *mut PKCS7); + + pub fn SMIME_write_PKCS7( + out: *mut BIO, + pkcs7: *mut PKCS7, + data: *mut BIO, + flags: c_int, + ) -> c_int; + + pub fn SMIME_read_PKCS7(bio: *mut BIO, bcont: *mut *mut BIO) -> *mut PKCS7; + + pub fn PKCS7_new() -> *mut PKCS7; + + pub fn PKCS7_set_type(p7: *mut PKCS7, nid_pkcs7: c_int) -> c_int; + + pub fn PKCS7_add_certificate(p7: *mut PKCS7, x509: *mut X509) -> c_int; + + pub fn PKCS7_add_signature( + p7: *mut PKCS7, + x509: *mut X509, + pkey: *mut EVP_PKEY, + digest: *const EVP_MD, + ) -> *mut PKCS7_SIGNER_INFO; + + pub fn PKCS7_set_signed_attributes( + p7si: *mut PKCS7_SIGNER_INFO, + attributes: *mut stack_st_X509_ATTRIBUTE, + ) -> c_int; + + pub fn PKCS7_add_signed_attribute( + p7si: *mut PKCS7_SIGNER_INFO, + nid: c_int, + attrtype: c_int, + data: *mut c_void, + ) -> c_int; + + pub fn PKCS7_content_new(p7: *mut PKCS7, nid_pkcs7: c_int) -> c_int; + + pub fn PKCS7_dataInit(p7: *mut PKCS7, bio: *mut BIO) -> *mut BIO; + + pub fn PKCS7_dataFinal(p7: *mut PKCS7, bio: *mut BIO) -> c_int; + + pub fn PKCS7_get_signer_info(p7: *mut PKCS7) -> *mut stack_st_PKCS7_SIGNER_INFO; + + pub fn PKCS7_SIGNER_INFO_get0_algs( + si: *mut PKCS7_SIGNER_INFO, + pk: *mut *mut EVP_PKEY, + pdig: *mut *mut X509_ALGOR, + psig: *mut *mut X509_ALGOR, + ); +} + +const_ptr_api! { + extern "C" { + pub fn PKCS7_get_signed_attribute( + si: #[const_ptr_if(ossl300)] PKCS7_SIGNER_INFO, + nid: c_int + ) -> *mut ASN1_TYPE; + } +} diff --git a/vendor/openssl-sys/src/handwritten/poly1305.rs b/vendor/openssl-sys/src/handwritten/poly1305.rs new file mode 100644 index 0000000..8ff22f3 --- /dev/null +++ b/vendor/openssl-sys/src/handwritten/poly1305.rs @@ -0,0 +1,23 @@ +use super::super::*; +use libc::*; + +cfg_if! { + if #[cfg(libressl)] { + #[repr(C)] + #[derive(Debug, Copy, Clone)] + pub struct poly1305_context { + pub aligner: usize, + pub opaque: [::libc::c_uchar; 136usize], + } + pub type poly1305_state = poly1305_context; + extern "C" { + pub fn CRYPTO_poly1305_init(ctx: *mut poly1305_context, key: *const ::libc::c_uchar); + pub fn CRYPTO_poly1305_update( + ctx: *mut poly1305_context, + in_: *const ::libc::c_uchar, + len: usize, + ); + pub fn CRYPTO_poly1305_finish(ctx: *mut poly1305_context, mac: *mut ::libc::c_uchar); + } + } +} diff --git a/vendor/openssl-sys/src/handwritten/provider.rs b/vendor/openssl-sys/src/handwritten/provider.rs new file mode 100644 index 0000000..3e18a02 --- /dev/null +++ b/vendor/openssl-sys/src/handwritten/provider.rs @@ -0,0 +1,20 @@ +use super::super::*; +use libc::*; + +extern "C" { + #[cfg(ossl300)] + pub fn OSSL_PROVIDER_load(ctx: *mut OSSL_LIB_CTX, name: *const c_char) -> *mut OSSL_PROVIDER; + #[cfg(ossl300)] + pub fn OSSL_PROVIDER_try_load( + ctx: *mut OSSL_LIB_CTX, + name: *const c_char, + retain_fallbacks: c_int, + ) -> *mut OSSL_PROVIDER; + #[cfg(ossl300)] + pub fn OSSL_PROVIDER_unload(prov: *mut OSSL_PROVIDER) -> c_int; + #[cfg(ossl300)] + pub fn OSSL_PROVIDER_set_default_search_path( + ctx: *mut OSSL_LIB_CTX, + path: *const c_char, + ) -> c_int; +} diff --git a/vendor/openssl-sys/src/handwritten/rand.rs b/vendor/openssl-sys/src/handwritten/rand.rs new file mode 100644 index 0000000..df553bd --- /dev/null +++ b/vendor/openssl-sys/src/handwritten/rand.rs @@ -0,0 +1,15 @@ +use libc::*; + +extern "C" { + pub fn RAND_bytes(buf: *mut u8, num: c_int) -> c_int; + + #[cfg(ossl111)] + pub fn RAND_priv_bytes(buf: *mut u8, num: c_int) -> c_int; + + #[cfg(ossl111)] + pub fn RAND_keep_random_devices_open(keep: c_int); + + pub fn RAND_status() -> c_int; + + pub fn RAND_add(buf: *const c_void, num: c_int, randomness: c_double); +} diff --git a/vendor/openssl-sys/src/handwritten/rsa.rs b/vendor/openssl-sys/src/handwritten/rsa.rs new file mode 100644 index 0000000..d05edfc --- /dev/null +++ b/vendor/openssl-sys/src/handwritten/rsa.rs @@ -0,0 +1,124 @@ +use super::super::*; +use libc::*; + +cfg_if! { + if #[cfg(ossl300)] { + extern "C" { + pub fn EVP_PKEY_CTX_set_rsa_padding(ctx: *mut EVP_PKEY_CTX, pad_mode: c_int) -> c_int; + pub fn EVP_PKEY_CTX_get_rsa_padding(ctx: *mut EVP_PKEY_CTX, pad_mode: *mut c_int) -> c_int; + + pub fn EVP_PKEY_CTX_set_rsa_pss_saltlen(ctx: *mut EVP_PKEY_CTX, len: c_int) -> c_int; + pub fn EVP_PKEY_CTX_set_rsa_mgf1_md(ctx: *mut EVP_PKEY_CTX, md: *const EVP_MD) -> c_int; + } + } +} + +extern "C" { + pub fn RSA_new() -> *mut RSA; + pub fn RSA_size(k: *const RSA) -> c_int; + + #[cfg(any(ossl110, libressl273))] + pub fn RSA_set0_key(r: *mut RSA, n: *mut BIGNUM, e: *mut BIGNUM, d: *mut BIGNUM) -> c_int; + #[cfg(any(ossl110, libressl273))] + pub fn RSA_set0_factors(r: *mut RSA, p: *mut BIGNUM, q: *mut BIGNUM) -> c_int; + #[cfg(any(ossl110, libressl273))] + pub fn RSA_set0_crt_params( + r: *mut RSA, + dmp1: *mut BIGNUM, + dmq1: *mut BIGNUM, + iqmp: *mut BIGNUM, + ) -> c_int; + #[cfg(any(ossl110, libressl273))] + pub fn RSA_get0_key( + r: *const RSA, + n: *mut *const BIGNUM, + e: *mut *const BIGNUM, + d: *mut *const BIGNUM, + ); + #[cfg(any(ossl110, libressl273))] + pub fn RSA_get0_factors(r: *const RSA, p: *mut *const BIGNUM, q: *mut *const BIGNUM); + #[cfg(any(ossl110, libressl273))] + pub fn RSA_get0_crt_params( + r: *const RSA, + dmp1: *mut *const BIGNUM, + dmq1: *mut *const BIGNUM, + iqmp: *mut *const BIGNUM, + ); + + #[cfg(not(ossl110))] + pub fn RSA_generate_key( + modsz: c_int, + e: c_ulong, + cb: Option, + cbarg: *mut c_void, + ) -> *mut RSA; + + pub fn RSA_generate_key_ex( + rsa: *mut RSA, + bits: c_int, + e: *mut BIGNUM, + cb: *mut BN_GENCB, + ) -> c_int; + + pub fn RSA_public_encrypt( + flen: c_int, + from: *const u8, + to: *mut u8, + k: *mut RSA, + pad: c_int, + ) -> c_int; + pub fn RSA_private_encrypt( + flen: c_int, + from: *const u8, + to: *mut u8, + k: *mut RSA, + pad: c_int, + ) -> c_int; + pub fn RSA_public_decrypt( + flen: c_int, + from: *const u8, + to: *mut u8, + k: *mut RSA, + pad: c_int, + ) -> c_int; + pub fn RSA_private_decrypt( + flen: c_int, + from: *const u8, + to: *mut u8, + k: *mut RSA, + pad: c_int, + ) -> c_int; + pub fn RSA_check_key(r: *const RSA) -> c_int; + pub fn RSA_free(rsa: *mut RSA); + pub fn RSA_up_ref(rsa: *mut RSA) -> c_int; + + pub fn i2d_RSAPublicKey(k: *const RSA, buf: *mut *mut u8) -> c_int; + pub fn d2i_RSAPublicKey(k: *mut *mut RSA, buf: *mut *const u8, len: c_long) -> *mut RSA; + pub fn i2d_RSAPrivateKey(k: *const RSA, buf: *mut *mut u8) -> c_int; + pub fn d2i_RSAPrivateKey(k: *mut *mut RSA, buf: *mut *const u8, len: c_long) -> *mut RSA; + + pub fn RSA_sign( + t: c_int, + m: *const u8, + mlen: c_uint, + sig: *mut u8, + siglen: *mut c_uint, + k: *mut RSA, + ) -> c_int; + pub fn RSA_verify( + t: c_int, + m: *const u8, + mlen: c_uint, + sig: *const u8, + siglen: c_uint, + k: *mut RSA, + ) -> c_int; + + pub fn RSA_padding_check_PKCS1_type_2( + to: *mut c_uchar, + tlen: c_int, + f: *const c_uchar, + fl: c_int, + rsa_len: c_int, + ) -> c_int; +} diff --git a/vendor/openssl-sys/src/handwritten/safestack.rs b/vendor/openssl-sys/src/handwritten/safestack.rs new file mode 100644 index 0000000..0bee90d --- /dev/null +++ b/vendor/openssl-sys/src/handwritten/safestack.rs @@ -0,0 +1 @@ +stack!(stack_st_OPENSSL_STRING); diff --git a/vendor/openssl-sys/src/handwritten/sha.rs b/vendor/openssl-sys/src/handwritten/sha.rs new file mode 100644 index 0000000..7d00b59 --- /dev/null +++ b/vendor/openssl-sys/src/handwritten/sha.rs @@ -0,0 +1,101 @@ +use super::super::*; +use libc::*; + +cfg_if! { + if #[cfg(not(osslconf = "OPENSSL_NO_DEPRECATED_3_0"))] { + #[repr(C)] + #[derive(Clone)] + pub struct SHA_CTX { + pub h0: SHA_LONG, + pub h1: SHA_LONG, + pub h2: SHA_LONG, + pub h3: SHA_LONG, + pub h4: SHA_LONG, + pub Nl: SHA_LONG, + pub Nh: SHA_LONG, + pub data: [SHA_LONG; SHA_LBLOCK as usize], + pub num: c_uint, + } + + extern "C" { + pub fn SHA1_Init(c: *mut SHA_CTX) -> c_int; + pub fn SHA1_Update(c: *mut SHA_CTX, data: *const c_void, len: size_t) -> c_int; + pub fn SHA1_Final(md: *mut c_uchar, c: *mut SHA_CTX) -> c_int; + } + } +} + +cfg_if! { + if #[cfg(not(ossl300))] { + extern "C" { + pub fn SHA1(d: *const c_uchar, n: size_t, md: *mut c_uchar) -> *mut c_uchar; + } + } +} + +cfg_if! { + if #[cfg(not(osslconf = "OPENSSL_NO_DEPRECATED_3_0"))] { + #[repr(C)] + #[derive(Clone)] + pub struct SHA256_CTX { + pub h: [SHA_LONG; 8], + pub Nl: SHA_LONG, + pub Nh: SHA_LONG, + pub data: [SHA_LONG; SHA_LBLOCK as usize], + pub num: c_uint, + pub md_len: c_uint, + } + + extern "C" { + pub fn SHA224_Init(c: *mut SHA256_CTX) -> c_int; + pub fn SHA224_Update(c: *mut SHA256_CTX, data: *const c_void, len: size_t) -> c_int; + pub fn SHA224_Final(md: *mut c_uchar, c: *mut SHA256_CTX) -> c_int; + pub fn SHA256_Init(c: *mut SHA256_CTX) -> c_int; + pub fn SHA256_Update(c: *mut SHA256_CTX, data: *const c_void, len: size_t) -> c_int; + pub fn SHA256_Final(md: *mut c_uchar, c: *mut SHA256_CTX) -> c_int; + } + } +} + +cfg_if! { + if #[cfg(not(ossl300))] { + extern "C" { + pub fn SHA224(d: *const c_uchar, n: size_t, md: *mut c_uchar) -> *mut c_uchar; + pub fn SHA256(d: *const c_uchar, n: size_t, md: *mut c_uchar) -> *mut c_uchar; + } + } +} + +cfg_if! { + if #[cfg(not(osslconf = "OPENSSL_NO_DEPRECATED_3_0"))] { + #[repr(C)] + #[derive(Clone)] + pub struct SHA512_CTX { + pub h: [SHA_LONG64; 8], + pub Nl: SHA_LONG64, + pub Nh: SHA_LONG64, + // this is a union but we don't want to require 1.19 + u: [SHA_LONG64; SHA_LBLOCK as usize], + pub num: c_uint, + pub md_len: c_uint, + } + + extern "C" { + pub fn SHA384_Init(c: *mut SHA512_CTX) -> c_int; + pub fn SHA384_Update(c: *mut SHA512_CTX, data: *const c_void, len: size_t) -> c_int; + pub fn SHA384_Final(md: *mut c_uchar, c: *mut SHA512_CTX) -> c_int; + pub fn SHA512_Init(c: *mut SHA512_CTX) -> c_int; + pub fn SHA512_Update(c: *mut SHA512_CTX, data: *const c_void, len: size_t) -> c_int; + pub fn SHA512_Final(md: *mut c_uchar, c: *mut SHA512_CTX) -> c_int; + } + } +} + +cfg_if! { + if #[cfg(not(ossl300))] { + extern "C" { + pub fn SHA384(d: *const c_uchar, n: size_t, md: *mut c_uchar) -> *mut c_uchar; + pub fn SHA512(d: *const c_uchar, n: size_t, md: *mut c_uchar) -> *mut c_uchar; + } + } +} diff --git a/vendor/openssl-sys/src/handwritten/srtp.rs b/vendor/openssl-sys/src/handwritten/srtp.rs new file mode 100644 index 0000000..d4c7af8 --- /dev/null +++ b/vendor/openssl-sys/src/handwritten/srtp.rs @@ -0,0 +1,10 @@ +use super::super::*; +use libc::*; + +extern "C" { + pub fn SSL_CTX_set_tlsext_use_srtp(ctx: *mut SSL_CTX, profiles: *const c_char) -> c_int; + pub fn SSL_set_tlsext_use_srtp(ssl: *mut SSL, profiles: *const c_char) -> c_int; + + pub fn SSL_get_srtp_profiles(ssl: *mut SSL) -> *mut stack_st_SRTP_PROTECTION_PROFILE; + pub fn SSL_get_selected_srtp_profile(ssl: *mut SSL) -> *mut SRTP_PROTECTION_PROFILE; +} diff --git a/vendor/openssl-sys/src/handwritten/ssl.rs b/vendor/openssl-sys/src/handwritten/ssl.rs new file mode 100644 index 0000000..b86a54c --- /dev/null +++ b/vendor/openssl-sys/src/handwritten/ssl.rs @@ -0,0 +1,1009 @@ +use super::super::*; +use libc::*; + +pub enum SSL_METHOD {} +pub enum SSL_CIPHER {} +cfg_if! { + if #[cfg(any(ossl110, libressl280))] { + pub enum SSL_SESSION {} + } else if #[cfg(libressl251)] { + #[repr(C)] + pub struct SSL_SESSION { + ssl_version: c_int, + pub master_key_length: c_int, + pub master_key: [c_uchar; 48], + session_id_length: c_uint, + session_id: [c_uchar; SSL_MAX_SSL_SESSION_ID_LENGTH as usize], + sid_ctx_length: c_uint, + sid_ctx: [c_uchar; SSL_MAX_SID_CTX_LENGTH as usize], + peer: *mut X509, + verify_result: c_long, + timeout: c_long, + time: time_t, + pub references: c_int, + cipher: *const SSL_CIPHER, + cipher_id: c_long, + ciphers: *mut stack_st_SSL_CIPHER, + tlsext_hostname: *mut c_char, + tlsext_tick: *mut c_uchar, + tlsext_ticklen: size_t, + tlsext_tick_lifetime_int: c_long, + internal: *mut c_void, + } + } else if #[cfg(libressl)] { + #[repr(C)] + pub struct SSL_SESSION { + ssl_version: c_int, + pub master_key_length: c_int, + pub master_key: [c_uchar; 48], + session_id_length: c_uint, + session_id: [c_uchar; SSL_MAX_SSL_SESSION_ID_LENGTH as usize], + sid_ctx_length: c_uint, + sid_ctx: [c_uchar; SSL_MAX_SID_CTX_LENGTH as usize], + not_resumable: c_int, + sess_cert: *mut c_void, + peer: *mut X509, + verify_result: c_long, + timeout: c_long, + time: time_t, + pub references: c_int, + cipher: *const c_void, + cipher_id: c_ulong, + ciphers: *mut c_void, + ex_data: CRYPTO_EX_DATA, + prev: *mut c_void, + next: *mut c_void, + tlsext_hostname: *mut c_char, + tlsext_ecpointformatlist_length: size_t, + tlsext_ecpointformatlist: *mut u8, + tlsext_ellipticcurvelist_length: size_t, + tlsext_ellipticcurvelist: *mut u16, + tlsext_tick: *mut c_uchar, + tlsext_ticklen: size_t, + tlsext_tick_lifetime_hint: c_long, + } + } else { + #[repr(C)] + pub struct SSL_SESSION { + ssl_version: c_int, + key_arg_length: c_uint, + key_arg: [c_uchar; SSL_MAX_KEY_ARG_LENGTH as usize], + pub master_key_length: c_int, + pub master_key: [c_uchar; 48], + session_id_length: c_uint, + session_id: [c_uchar; SSL_MAX_SSL_SESSION_ID_LENGTH as usize], + sid_ctx_length: c_uint, + sid_ctx: [c_uchar; SSL_MAX_SID_CTX_LENGTH as usize], + #[cfg(not(osslconf = "OPENSSL_NO_KRB5"))] + krb5_client_princ_len: c_uint, + #[cfg(not(osslconf = "OPENSSL_NO_KRB5"))] + krb5_client_princ: [c_uchar; SSL_MAX_KRB5_PRINCIPAL_LENGTH as usize], + #[cfg(not(osslconf = "OPENSSL_NO_PSK"))] + psk_identity_hint: *mut c_char, + #[cfg(not(osslconf = "OPENSSL_NO_PSK"))] + psk_identity: *mut c_char, + not_resumable: c_int, + sess_cert: *mut c_void, + peer: *mut X509, + verify_result: c_long, + pub references: c_int, + timeout: c_long, + time: c_long, + compress_meth: c_uint, + cipher: *const c_void, + cipher_id: c_ulong, + ciphers: *mut c_void, + ex_data: CRYPTO_EX_DATA, + prev: *mut c_void, + next: *mut c_void, + #[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))] + tlsext_hostname: *mut c_char, + #[cfg(all( + not(osslconf = "OPENSSL_NO_TLSEXT"), + not(osslconf = "OPENSSL_NO_EC") + ))] + tlsext_ecpointformatlist_length: size_t, + #[cfg(all( + not(osslconf = "OPENSSL_NO_TLSEXT"), + not(osslconf = "OPENSSL_NO_EC") + ))] + tlsext_ecpointformatlist: *mut c_uchar, + #[cfg(all( + not(osslconf = "OPENSSL_NO_TLSEXT"), + not(osslconf = "OPENSSL_NO_EC") + ))] + tlsext_ellipticcurvelist_length: size_t, + #[cfg(all( + not(osslconf = "OPENSSL_NO_TLSEXT"), + not(osslconf = "OPENSSL_NO_EC") + ))] + tlsext_ellipticcurvelist: *mut c_uchar, + #[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))] + tlsext_tick: *mut c_uchar, + #[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))] + tlsext_ticklen: size_t, + #[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))] + tlsext_tick_lifetime_hint: c_long, + #[cfg(not(osslconf = "OPENSSL_NO_SRP"))] + srp_username: *mut c_char, + } + } +} + +stack!(stack_st_SSL_CIPHER); + +#[repr(C)] +pub struct SRTP_PROTECTION_PROFILE { + pub name: *const c_char, + pub id: c_ulong, +} + +stack!(stack_st_SRTP_PROTECTION_PROFILE); + +pub type tls_session_ticket_ext_cb_fn = + Option c_int>; +pub type tls_session_secret_cb_fn = Option< + unsafe extern "C" fn( + *mut SSL, + *mut c_void, + *mut c_int, + *mut stack_st_SSL_CIPHER, + *mut *mut SSL_CIPHER, + *mut c_void, + ) -> c_int, +>; + +#[cfg(ossl111)] +pub type SSL_custom_ext_add_cb_ex = Option< + unsafe extern "C" fn( + ssl: *mut SSL, + ext_type: c_uint, + context: c_uint, + out: *mut *const c_uchar, + outlen: *mut size_t, + x: *mut X509, + chainidx: size_t, + al: *mut c_int, + add_arg: *mut c_void, + ) -> c_int, +>; + +#[cfg(ossl111)] +pub type SSL_custom_ext_free_cb_ex = Option< + unsafe extern "C" fn( + ssl: *mut SSL, + ext_type: c_uint, + context: c_uint, + out: *const c_uchar, + add_arg: *mut c_void, + ), +>; + +#[cfg(ossl111)] +pub type SSL_custom_ext_parse_cb_ex = Option< + unsafe extern "C" fn( + ssl: *mut SSL, + ext_type: c_uint, + context: c_uint, + input: *const c_uchar, + inlen: size_t, + x: *mut X509, + chainidx: size_t, + al: *mut c_int, + parse_arg: *mut c_void, + ) -> c_int, +>; + +cfg_if! { + if #[cfg(ossl300)] { + extern "C" { + pub fn SSL_CTX_get_options(ctx: *const SSL_CTX) -> u64; + pub fn SSL_CTX_set_options(ctx: *mut SSL_CTX, op: u64) -> u64; + pub fn SSL_CTX_clear_options(ctx: *mut SSL_CTX, op: u64) -> u64; + } + } else if #[cfg(ossl110)] { + extern "C" { + pub fn SSL_CTX_get_options(ctx: *const SSL_CTX) -> c_ulong; + pub fn SSL_CTX_set_options(ctx: *mut SSL_CTX, op: c_ulong) -> c_ulong; + pub fn SSL_CTX_clear_options(ctx: *mut SSL_CTX, op: c_ulong) -> c_ulong; + } + } +} + +pub type GEN_SESSION_CB = + Option c_int>; + +extern "C" { + pub fn SSL_CTX_sess_set_new_cb( + ctx: *mut SSL_CTX, + new_session_cb: Option c_int>, + ); + pub fn SSL_CTX_sess_set_remove_cb( + ctx: *mut SSL_CTX, + remove_session_cb: Option, + ); +} +cfg_if! { + // const change in passed function pointer signature + if #[cfg(any(ossl110, libressl280))] { + extern "C" { + pub fn SSL_CTX_sess_set_get_cb( + ctx: *mut SSL_CTX, + get_session_cb: Option< + unsafe extern "C" fn(*mut SSL, *const c_uchar, c_int, *mut c_int) -> *mut SSL_SESSION, + >, + ); + } + } else { + extern "C" { + pub fn SSL_CTX_sess_set_get_cb( + ctx: *mut SSL_CTX, + get_session_cb: Option< + unsafe extern "C" fn(*mut SSL, *mut c_uchar, c_int, *mut c_int) -> *mut SSL_SESSION, + >, + ); + } + } +} +extern "C" { + // FIXME change to unsafe extern "C" fn + pub fn SSL_CTX_set_cookie_generate_cb( + s: *mut SSL_CTX, + cb: Option< + extern "C" fn(ssl: *mut SSL, cookie: *mut c_uchar, cookie_len: *mut c_uint) -> c_int, + >, + ); +} + +cfg_if! { + // const change in passed function pointer signature + if #[cfg(any(ossl110, libressl280))] { + extern "C" { + pub fn SSL_CTX_set_cookie_verify_cb( + s: *mut SSL_CTX, + cb: Option< + extern "C" fn(ssl: *mut SSL, cookie: *const c_uchar, cookie_len: c_uint) -> c_int, + >, + ); + } + } else { + extern "C" { + pub fn SSL_CTX_set_cookie_verify_cb( + s: *mut SSL_CTX, + cb: Option c_int>, + ); + } + } +} + +extern "C" { + #[cfg(ossl111)] + pub fn SSL_CTX_set_stateless_cookie_generate_cb( + s: *mut SSL_CTX, + cb: Option< + unsafe extern "C" fn( + ssl: *mut SSL, + cookie: *mut c_uchar, + cookie_len: *mut size_t, + ) -> c_int, + >, + ); + #[cfg(ossl111)] + pub fn SSL_CTX_set_stateless_cookie_verify_cb( + s: *mut SSL_CTX, + cb: Option< + unsafe extern "C" fn( + ssl: *mut SSL, + cookie: *const c_uchar, + cookie_len: size_t, + ) -> c_int, + >, + ); + + pub fn SSL_CTX_set_next_protos_advertised_cb( + ssl: *mut SSL_CTX, + cb: extern "C" fn( + ssl: *mut SSL, + out: *mut *const c_uchar, + outlen: *mut c_uint, + arg: *mut c_void, + ) -> c_int, + arg: *mut c_void, + ); + pub fn SSL_CTX_set_next_proto_select_cb( + ssl: *mut SSL_CTX, + cb: extern "C" fn( + ssl: *mut SSL, + out: *mut *mut c_uchar, + outlen: *mut c_uchar, + inbuf: *const c_uchar, + inlen: c_uint, + arg: *mut c_void, + ) -> c_int, + arg: *mut c_void, + ); + pub fn SSL_get0_next_proto_negotiated( + s: *const SSL, + data: *mut *const c_uchar, + len: *mut c_uint, + ); + + pub fn SSL_select_next_proto( + out: *mut *mut c_uchar, + outlen: *mut c_uchar, + inbuf: *const c_uchar, + inlen: c_uint, + client: *const c_uchar, + client_len: c_uint, + ) -> c_int; +} + +extern "C" { + #[cfg(any(ossl102, libressl261))] + pub fn SSL_CTX_set_alpn_protos(s: *mut SSL_CTX, data: *const c_uchar, len: c_uint) -> c_int; + #[cfg(any(ossl102, libressl261))] + pub fn SSL_set_alpn_protos(s: *mut SSL, data: *const c_uchar, len: c_uint) -> c_int; + #[cfg(any(ossl102, libressl261))] + #[link_name = "SSL_CTX_set_alpn_select_cb"] + pub fn SSL_CTX_set_alpn_select_cb__fixed_rust( + ssl: *mut SSL_CTX, + cb: Option< + unsafe extern "C" fn( + ssl: *mut SSL, + out: *mut *const c_uchar, + outlen: *mut c_uchar, + inbuf: *const c_uchar, + inlen: c_uint, + arg: *mut c_void, + ) -> c_int, + >, + arg: *mut c_void, + ); + #[cfg(any(ossl102, libressl261))] + pub fn SSL_get0_alpn_selected(s: *const SSL, data: *mut *const c_uchar, len: *mut c_uint); +} + +#[cfg(not(osslconf = "OPENSSL_NO_PSK"))] +extern "C" { + pub fn SSL_CTX_set_psk_client_callback( + ssl: *mut SSL_CTX, + psk_client_cb: Option< + extern "C" fn( + *mut SSL, + *const c_char, + *mut c_char, + c_uint, + *mut c_uchar, + c_uint, + ) -> c_uint, + >, + ); + pub fn SSL_CTX_set_psk_server_callback( + ssl: *mut SSL_CTX, + psk_server_cb: Option< + extern "C" fn(*mut SSL, *const c_char, *mut c_uchar, c_uint) -> c_uint, + >, + ); + pub fn SSL_get_psk_identity_hint(ssl: *const SSL) -> *const c_char; + pub fn SSL_get_psk_identity(ssl: *const SSL) -> *const c_char; +} + +extern "C" { + #[cfg(ossl111)] + pub fn SSL_CTX_add_custom_ext( + ctx: *mut SSL_CTX, + ext_type: c_uint, + context: c_uint, + add_cb: SSL_custom_ext_add_cb_ex, + free_cb: SSL_custom_ext_free_cb_ex, + add_arg: *mut c_void, + parse_cb: SSL_custom_ext_parse_cb_ex, + parse_arg: *mut c_void, + ) -> c_int; + + #[cfg(ossl102)] + pub fn SSL_extension_supported(ext_type: c_uint) -> c_int; +} + +#[cfg(ossl111)] +pub type SSL_CTX_keylog_cb_func = + Option; + +extern "C" { + #[cfg(ossl111)] + pub fn SSL_CTX_set_keylog_callback(ctx: *mut SSL_CTX, cb: SSL_CTX_keylog_cb_func); + + #[cfg(any(ossl111, libressl340))] + pub fn SSL_CTX_set_max_early_data(ctx: *mut SSL_CTX, max_early_data: u32) -> c_int; + #[cfg(any(ossl111, libressl340))] + pub fn SSL_CTX_get_max_early_data(ctx: *const SSL_CTX) -> u32; + #[cfg(any(ossl111, libressl340))] + pub fn SSL_set_max_early_data(ctx: *mut SSL, max_early_data: u32) -> c_int; + #[cfg(any(ossl111, libressl340))] + pub fn SSL_get_max_early_data(ctx: *const SSL) -> u32; + + pub fn SSL_get_finished(s: *const SSL, buf: *mut c_void, count: size_t) -> size_t; + pub fn SSL_get_peer_finished(s: *const SSL, buf: *mut c_void, count: size_t) -> size_t; + + pub fn SSL_CTX_get_verify_mode(ctx: *const SSL_CTX) -> c_int; + pub fn SSL_get_verify_mode(s: *const SSL) -> c_int; +} + +const_ptr_api! { + extern "C" { + #[cfg(ossl110)] + pub fn SSL_is_init_finished(s: #[const_ptr_if(ossl111)] SSL) -> c_int; + } +} + +cfg_if! { + if #[cfg(libressl261)] { + extern "C" { + pub fn SSL_CTX_set_min_proto_version(ctx: *mut SSL_CTX, version: u16) -> c_int; + pub fn SSL_CTX_set_max_proto_version(ctx: *mut SSL_CTX, version: u16) -> c_int; + pub fn SSL_set_min_proto_version(s: *mut SSL, version: u16) -> c_int; + pub fn SSL_set_max_proto_version(s: *mut SSL, version: u16) -> c_int; + } + } +} + +cfg_if! { + if #[cfg(libressl270)] { + extern "C" { + pub fn SSL_CTX_get_min_proto_version(ctx: *mut SSL_CTX) -> c_int; + pub fn SSL_CTX_get_max_proto_version(ctx: *mut SSL_CTX) -> c_int; + pub fn SSL_get_min_proto_version(s: *mut SSL) -> c_int; + pub fn SSL_get_max_proto_version(s: *mut SSL) -> c_int; + } + } +} + +extern "C" { + pub fn SSL_CTX_set_cipher_list(ssl: *mut SSL_CTX, s: *const c_char) -> c_int; + pub fn SSL_CTX_new(method: *const SSL_METHOD) -> *mut SSL_CTX; + pub fn SSL_CTX_free(ctx: *mut SSL_CTX); + #[cfg(any(ossl110, libressl273))] + pub fn SSL_CTX_up_ref(x: *mut SSL_CTX) -> c_int; + pub fn SSL_CTX_get_cert_store(ctx: *const SSL_CTX) -> *mut X509_STORE; + pub fn SSL_CTX_set_cert_store(ctx: *mut SSL_CTX, store: *mut X509_STORE); + + pub fn SSL_get_current_cipher(ssl: *const SSL) -> *const SSL_CIPHER; + pub fn SSL_CIPHER_get_bits(cipher: *const SSL_CIPHER, alg_bits: *mut c_int) -> c_int; +} +const_ptr_api! { + extern "C" { + pub fn SSL_CIPHER_get_version(cipher: *const SSL_CIPHER) -> #[const_ptr_if(any(ossl110, libressl280))] c_char; + } +} +extern "C" { + #[cfg(ossl111)] + pub fn SSL_CIPHER_get_handshake_digest(cipher: *const SSL_CIPHER) -> *const EVP_MD; + pub fn SSL_CIPHER_get_name(cipher: *const SSL_CIPHER) -> *const c_char; + #[cfg(ossl111)] + pub fn SSL_CIPHER_standard_name(cipher: *const SSL_CIPHER) -> *const c_char; + #[cfg(ossl111)] + pub fn OPENSSL_cipher_name(rfc_name: *const c_char) -> *const c_char; + + pub fn SSL_pending(ssl: *const SSL) -> c_int; + pub fn SSL_set_bio(ssl: *mut SSL, rbio: *mut BIO, wbio: *mut BIO); + pub fn SSL_get_rbio(ssl: *const SSL) -> *mut BIO; + pub fn SSL_get_wbio(ssl: *const SSL) -> *mut BIO; + #[cfg(any(ossl111, libressl340))] + pub fn SSL_CTX_set_ciphersuites(ctx: *mut SSL_CTX, str: *const c_char) -> c_int; + #[cfg(any(ossl111, libressl340))] + pub fn SSL_set_ciphersuites(ssl: *mut SSL, str: *const c_char) -> c_int; + pub fn SSL_set_cipher_list(ssl: *mut SSL, s: *const c_char) -> c_int; + pub fn SSL_set_ssl_method(s: *mut SSL, method: *const SSL_METHOD) -> c_int; + pub fn SSL_set_verify( + ssl: *mut SSL, + mode: c_int, + // FIXME should be unsafe + verify_callback: Option c_int>, + ); + pub fn SSL_CTX_use_PrivateKey(ctx: *mut SSL_CTX, key: *mut EVP_PKEY) -> c_int; + pub fn SSL_CTX_use_certificate(ctx: *mut SSL_CTX, cert: *mut X509) -> c_int; + + pub fn SSL_CTX_use_PrivateKey_file( + ctx: *mut SSL_CTX, + key_file: *const c_char, + file_type: c_int, + ) -> c_int; + pub fn SSL_CTX_use_certificate_file( + ctx: *mut SSL_CTX, + cert_file: *const c_char, + file_type: c_int, + ) -> c_int; + pub fn SSL_CTX_use_certificate_chain_file( + ctx: *mut SSL_CTX, + cert_chain_file: *const c_char, + ) -> c_int; + pub fn SSL_use_PrivateKey_file(ssl: *mut SSL, file: *const c_char, type_: c_int) -> c_int; + pub fn SSL_use_PrivateKey(ssl: *mut SSL, pkey: *mut EVP_PKEY) -> c_int; + pub fn SSL_use_certificate(ssl: *mut SSL, x: *mut X509) -> c_int; + #[cfg(any(ossl110, libressl332))] + pub fn SSL_use_certificate_chain_file(ssl: *mut SSL, file: *const c_char) -> c_int; + pub fn SSL_set_client_CA_list(s: *mut SSL, name_list: *mut stack_st_X509_NAME); + pub fn SSL_add_client_CA(ssl: *mut SSL, x: *mut X509) -> c_int; + pub fn SSL_load_client_CA_file(file: *const c_char) -> *mut stack_st_X509_NAME; + + #[cfg(not(ossl110))] + pub fn SSL_load_error_strings(); + pub fn SSL_state_string(ssl: *const SSL) -> *const c_char; + pub fn SSL_state_string_long(ssl: *const SSL) -> *const c_char; + + pub fn SSL_SESSION_get_time(s: *const SSL_SESSION) -> c_long; + pub fn SSL_SESSION_get_timeout(s: *const SSL_SESSION) -> c_long; + #[cfg(any(ossl110, libressl270))] + pub fn SSL_SESSION_get_protocol_version(s: *const SSL_SESSION) -> c_int; + + #[cfg(any(ossl111, libressl340))] + pub fn SSL_SESSION_set_max_early_data(ctx: *mut SSL_SESSION, max_early_data: u32) -> c_int; + #[cfg(any(ossl111, libressl340))] + pub fn SSL_SESSION_get_max_early_data(ctx: *const SSL_SESSION) -> u32; + + pub fn SSL_SESSION_get_id(s: *const SSL_SESSION, len: *mut c_uint) -> *const c_uchar; + #[cfg(any(ossl110, libressl273))] + pub fn SSL_SESSION_up_ref(ses: *mut SSL_SESSION) -> c_int; + pub fn SSL_SESSION_free(s: *mut SSL_SESSION); +} +const_ptr_api! { + extern "C" { + pub fn i2d_SSL_SESSION(s: #[const_ptr_if(ossl300)] SSL_SESSION, pp: *mut *mut c_uchar) -> c_int; + } +} +extern "C" { + pub fn SSL_set_session(ssl: *mut SSL, session: *mut SSL_SESSION) -> c_int; + pub fn SSL_CTX_add_session(ctx: *mut SSL_CTX, session: *mut SSL_SESSION) -> c_int; + pub fn SSL_CTX_remove_session(ctx: *mut SSL_CTX, session: *mut SSL_SESSION) -> c_int; + pub fn d2i_SSL_SESSION( + a: *mut *mut SSL_SESSION, + pp: *mut *const c_uchar, + len: c_long, + ) -> *mut SSL_SESSION; + + #[cfg(not(ossl300))] + pub fn SSL_get_peer_certificate(ssl: *const SSL) -> *mut X509; + #[cfg(ossl300)] + pub fn SSL_get1_peer_certificate(ssl: *const SSL) -> *mut X509; + + pub fn SSL_get_peer_cert_chain(ssl: *const SSL) -> *mut stack_st_X509; + + pub fn SSL_CTX_set_verify( + ctx: *mut SSL_CTX, + mode: c_int, + verify_callback: Option c_int>, + ); + pub fn SSL_CTX_set_verify_depth(ctx: *mut SSL_CTX, depth: c_int); + + #[cfg(any(ossl111, libressl340))] + pub fn SSL_CTX_set_post_handshake_auth(ctx: *mut SSL_CTX, val: c_int); + + pub fn SSL_CTX_check_private_key(ctx: *const SSL_CTX) -> c_int; + + pub fn SSL_CTX_set_session_id_context( + ssl: *mut SSL_CTX, + sid_ctx: *const c_uchar, + sid_ctx_len: c_uint, + ) -> c_int; + + pub fn SSL_new(ctx: *mut SSL_CTX) -> *mut SSL; + + #[cfg(any(ossl102, libressl261))] + pub fn SSL_CTX_get0_param(ctx: *mut SSL_CTX) -> *mut X509_VERIFY_PARAM; + + #[cfg(any(ossl102, libressl261))] + pub fn SSL_get0_param(ssl: *mut SSL) -> *mut X509_VERIFY_PARAM; +} + +#[cfg(ossl111)] +pub type SSL_client_hello_cb_fn = + Option c_int>; +extern "C" { + #[cfg(ossl111)] + pub fn SSL_CTX_set_client_hello_cb( + c: *mut SSL_CTX, + cb: SSL_client_hello_cb_fn, + arg: *mut c_void, + ); + #[cfg(ossl111)] + pub fn SSL_client_hello_isv2(s: *mut SSL) -> c_int; + #[cfg(ossl111)] + pub fn SSL_client_hello_get0_legacy_version(s: *mut SSL) -> c_uint; + #[cfg(ossl111)] + pub fn SSL_client_hello_get0_random(s: *mut SSL, out: *mut *const c_uchar) -> size_t; + #[cfg(ossl111)] + pub fn SSL_client_hello_get0_session_id(s: *mut SSL, out: *mut *const c_uchar) -> size_t; + #[cfg(ossl111)] + pub fn SSL_client_hello_get0_ciphers(s: *mut SSL, out: *mut *const c_uchar) -> size_t; + #[cfg(ossl111)] + pub fn SSL_client_hello_get0_compression_methods( + s: *mut SSL, + out: *mut *const c_uchar, + ) -> size_t; + #[cfg(ossl111)] + pub fn SSL_client_hello_get1_extensions_present( + s: *mut SSL, + out: *mut *mut c_int, + outlen: *mut size_t, + ) -> c_int; + #[cfg(ossl111)] + pub fn SSL_client_hello_get0_ext( + s: *mut SSL, + type_: c_uint, + out: *mut *const c_uchar, + outlen: *mut size_t, + ) -> c_int; + + pub fn SSL_free(ssl: *mut SSL); + pub fn SSL_accept(ssl: *mut SSL) -> c_int; + #[cfg(ossl111)] + pub fn SSL_stateless(s: *mut SSL) -> c_int; + pub fn SSL_connect(ssl: *mut SSL) -> c_int; + pub fn SSL_read(ssl: *mut SSL, buf: *mut c_void, num: c_int) -> c_int; + #[cfg(any(ossl111, libressl350))] + pub fn SSL_read_ex(ssl: *mut SSL, buf: *mut c_void, num: usize, readbytes: *mut usize) + -> c_int; + pub fn SSL_peek(ssl: *mut SSL, buf: *mut c_void, num: c_int) -> c_int; + #[cfg(any(ossl111, libressl350))] + pub fn SSL_peek_ex(ssl: *mut SSL, buf: *mut c_void, num: usize, readbytes: *mut usize) + -> c_int; + #[cfg(any(ossl111, libressl340))] + pub fn SSL_read_early_data( + s: *mut SSL, + buf: *mut c_void, + num: size_t, + readbytes: *mut size_t, + ) -> c_int; + #[cfg(ossl111)] + pub fn SSL_bytes_to_cipher_list( + s: *mut SSL, + bytes: *const c_uchar, + len: size_t, + isv2format: c_int, + sk: *mut *mut stack_st_SSL_CIPHER, + scsvs: *mut *mut stack_st_SSL_CIPHER, + ) -> c_int; +} + +extern "C" { + pub fn SSL_write(ssl: *mut SSL, buf: *const c_void, num: c_int) -> c_int; + #[cfg(any(ossl111, libressl350))] + pub fn SSL_write_ex( + ssl: *mut SSL, + buf: *const c_void, + num: size_t, + written: *mut size_t, + ) -> c_int; + #[cfg(any(ossl111, libressl340))] + pub fn SSL_write_early_data( + s: *mut SSL, + buf: *const c_void, + num: size_t, + written: *mut size_t, + ) -> c_int; + pub fn SSL_ctrl(ssl: *mut SSL, cmd: c_int, larg: c_long, parg: *mut c_void) -> c_long; + pub fn SSL_CTX_ctrl(ctx: *mut SSL_CTX, cmd: c_int, larg: c_long, parg: *mut c_void) -> c_long; + #[link_name = "SSL_CTX_callback_ctrl"] + pub fn SSL_CTX_callback_ctrl__fixed_rust( + ctx: *mut SSL_CTX, + cmd: c_int, + fp: Option, + ) -> c_long; +} + +cfg_if! { + if #[cfg(any(ossl110, libressl291))] { + extern "C" { + pub fn TLS_method() -> *const SSL_METHOD; + + pub fn DTLS_method() -> *const SSL_METHOD; + + pub fn TLS_server_method() -> *const SSL_METHOD; + + pub fn TLS_client_method() -> *const SSL_METHOD; + } + } else { + extern "C" { + #[cfg(not(osslconf = "OPENSSL_NO_SSL3_METHOD"))] + pub fn SSLv3_method() -> *const SSL_METHOD; + + pub fn SSLv23_method() -> *const SSL_METHOD; + + pub fn SSLv23_client_method() -> *const SSL_METHOD; + + pub fn SSLv23_server_method() -> *const SSL_METHOD; + + pub fn TLSv1_method() -> *const SSL_METHOD; + + pub fn TLSv1_1_method() -> *const SSL_METHOD; + + pub fn TLSv1_2_method() -> *const SSL_METHOD; + + pub fn DTLSv1_method() -> *const SSL_METHOD; + + #[cfg(ossl102)] + pub fn DTLSv1_2_method() -> *const SSL_METHOD; + } + } +} + +extern "C" { + pub fn SSL_get_error(ssl: *const SSL, ret: c_int) -> c_int; + pub fn SSL_get_version(ssl: *const SSL) -> *const c_char; + + pub fn SSL_do_handshake(ssl: *mut SSL) -> c_int; + pub fn SSL_shutdown(ssl: *mut SSL) -> c_int; + + pub fn SSL_CTX_set_client_CA_list(ctx: *mut SSL_CTX, list: *mut stack_st_X509_NAME); + + pub fn SSL_CTX_add_client_CA(ctx: *mut SSL_CTX, cacert: *mut X509) -> c_int; + + pub fn SSL_CTX_set_default_verify_paths(ctx: *mut SSL_CTX) -> c_int; + pub fn SSL_CTX_load_verify_locations( + ctx: *mut SSL_CTX, + CAfile: *const c_char, + CApath: *const c_char, + ) -> c_int; +} + +const_ptr_api! { + extern "C" { + pub fn SSL_get_ssl_method(ssl: #[const_ptr_if(ossl111b)] SSL) -> *const SSL_METHOD; + } +} + +extern "C" { + pub fn SSL_set_connect_state(s: *mut SSL); + pub fn SSL_set_accept_state(s: *mut SSL); + + #[cfg(not(ossl110))] + pub fn SSL_library_init() -> c_int; + + pub fn SSL_CIPHER_description( + cipher: *const SSL_CIPHER, + buf: *mut c_char, + size: c_int, + ) -> *mut c_char; + + pub fn SSL_get_certificate(ssl: *const SSL) -> *mut X509; +} +const_ptr_api! { + extern "C" { + pub fn SSL_get_privatekey(ssl: #[const_ptr_if(any(ossl102, libressl280))] SSL) -> *mut EVP_PKEY; + } +} + +extern "C" { + #[cfg(any(ossl102, libressl270))] + pub fn SSL_CTX_get0_certificate(ctx: *const SSL_CTX) -> *mut X509; + #[cfg(any(ossl102, libressl340))] + pub fn SSL_CTX_get0_privatekey(ctx: *const SSL_CTX) -> *mut EVP_PKEY; + + pub fn SSL_set_shutdown(ss: *mut SSL, mode: c_int); + pub fn SSL_get_shutdown(ssl: *const SSL) -> c_int; + pub fn SSL_version(ssl: *const SSL) -> c_int; + pub fn SSL_get_session(s: *const SSL) -> *mut SSL_SESSION; + pub fn SSL_get_SSL_CTX(ssl: *const SSL) -> *mut SSL_CTX; + pub fn SSL_set_SSL_CTX(ssl: *mut SSL, ctx: *mut SSL_CTX) -> *mut SSL_CTX; + + pub fn SSL_get_verify_result(ssl: *const SSL) -> c_long; + #[cfg(ossl110)] + pub fn SSL_get0_verified_chain(ssl: *const SSL) -> *mut stack_st_X509; + + #[cfg(any(ossl110, libressl270))] + pub fn SSL_get_client_random(ssl: *const SSL, out: *mut c_uchar, len: size_t) -> size_t; + #[cfg(any(ossl110, libressl270))] + pub fn SSL_get_server_random(ssl: *const SSL, out: *mut c_uchar, len: size_t) -> size_t; + #[cfg(any(ossl110, libressl273))] + pub fn SSL_SESSION_get_master_key( + session: *const SSL_SESSION, + out: *mut c_uchar, + outlen: size_t, + ) -> size_t; +} + +extern "C" { + #[cfg(not(ossl110))] + pub fn SSL_get_ex_new_index( + argl: c_long, + argp: *mut c_void, + new_func: Option, + dup_func: Option, + free_func: Option, + ) -> c_int; + + pub fn SSL_set_ex_data(ssl: *mut SSL, idx: c_int, data: *mut c_void) -> c_int; + pub fn SSL_get_ex_data(ssl: *const SSL, idx: c_int) -> *mut c_void; + + #[cfg(not(ossl110))] + pub fn SSL_CTX_get_ex_new_index( + argl: c_long, + argp: *mut c_void, + new_func: Option, + dup_func: Option, + free_func: Option, + ) -> c_int; + + pub fn SSL_CTX_set_ex_data(ctx: *mut SSL_CTX, idx: c_int, data: *mut c_void) -> c_int; + pub fn SSL_CTX_get_ex_data(ctx: *const SSL_CTX, idx: c_int) -> *mut c_void; + + pub fn SSL_get_ex_data_X509_STORE_CTX_idx() -> c_int; +} + +extern "C" { + #[link_name = "SSL_CTX_set_tmp_dh_callback"] + pub fn SSL_CTX_set_tmp_dh_callback__fixed_rust( + ctx: *mut SSL_CTX, + dh: Option< + unsafe extern "C" fn(ssl: *mut SSL, is_export: c_int, keylength: c_int) -> *mut DH, + >, + ); + #[link_name = "SSL_set_tmp_dh_callback"] + pub fn SSL_set_tmp_dh_callback__fixed_rust( + ctx: *mut SSL, + dh: Option< + unsafe extern "C" fn(ssl: *mut SSL, is_export: c_int, keylength: c_int) -> *mut DH, + >, + ); + #[cfg(not(ossl110))] + #[link_name = "SSL_CTX_set_tmp_ecdh_callback"] + pub fn SSL_CTX_set_tmp_ecdh_callback__fixed_rust( + ctx: *mut SSL_CTX, + ecdh: Option< + unsafe extern "C" fn(ssl: *mut SSL, is_export: c_int, keylength: c_int) -> *mut EC_KEY, + >, + ); + #[cfg(not(ossl110))] + #[link_name = "SSL_set_tmp_ecdh_callback"] + pub fn SSL_set_tmp_ecdh_callback__fixed_rust( + ssl: *mut SSL, + ecdh: Option< + unsafe extern "C" fn(ssl: *mut SSL, is_export: c_int, keylength: c_int) -> *mut EC_KEY, + >, + ); +} + +cfg_if! { + if #[cfg(libressl)] { + extern "C" { + pub fn SSL_get_current_compression(ssl: *mut SSL) -> *const libc::c_void; + } + } else if #[cfg(not(osslconf = "OPENSSL_NO_COMP"))] { + const_ptr_api! { + extern "C" { + pub fn SSL_get_current_compression(ssl: #[const_ptr_if(ossl111b)] SSL) -> *const COMP_METHOD; + } + } + } +} +cfg_if! { + if #[cfg(libressl)] { + extern "C" { + pub fn SSL_COMP_get_name(comp: *const libc::c_void) -> *const c_char; + } + } else if #[cfg(not(osslconf = "OPENSSL_NO_COMP"))] { + extern "C" { + pub fn SSL_COMP_get_name(comp: *const COMP_METHOD) -> *const c_char; + } + } +} + +#[cfg(not(osslconf = "OPENSSL_NO_COMP"))] +extern "C" { + #[cfg(ossl110)] + pub fn COMP_get_type(meth: *const COMP_METHOD) -> i32; +} + +extern "C" { + #[cfg(any(ossl110, libressl270))] + pub fn SSL_CIPHER_get_cipher_nid(c: *const SSL_CIPHER) -> c_int; + #[cfg(any(ossl110, libressl270))] + pub fn SSL_CIPHER_get_digest_nid(c: *const SSL_CIPHER) -> c_int; +} + +const_ptr_api! { + extern "C" { + #[cfg(ossl110)] + pub fn SSL_session_reused(ssl: #[const_ptr_if(ossl111c)] SSL) -> c_int; + } +} + +const_ptr_api! { + extern "C" { + #[cfg(any(ossl102, libressl273))] + pub fn SSL_is_server(s: #[const_ptr_if(any(ossl110f, libressl273))] SSL) -> c_int; + } +} + +extern "C" { + #[cfg(ossl110)] + pub fn OPENSSL_init_ssl(opts: u64, settings: *const OPENSSL_INIT_SETTINGS) -> c_int; +} + +extern "C" { + #[cfg(ossl111)] + pub fn SSL_CTX_set_num_tickets(ctx: *mut SSL_CTX, num_tickets: size_t) -> c_int; + + #[cfg(ossl111)] + pub fn SSL_set_num_tickets(s: *mut SSL, num_tickets: size_t) -> c_int; + + #[cfg(ossl111b)] + pub fn SSL_CTX_get_num_tickets(ctx: *const SSL_CTX) -> size_t; + #[cfg(all(ossl111, not(ossl111b)))] + pub fn SSL_CTX_get_num_tickets(ctx: *mut SSL_CTX) -> size_t; + + #[cfg(ossl111b)] + pub fn SSL_get_num_tickets(s: *const SSL) -> size_t; + #[cfg(all(ossl111, not(ossl111b)))] + pub fn SSL_get_num_tickets(s: *mut SSL) -> size_t; +} + +extern "C" { + #[cfg(any(ossl110, libressl360))] + pub fn SSL_CTX_set_security_level(ctx: *mut SSL_CTX, level: c_int); + + #[cfg(any(ossl110, libressl360))] + pub fn SSL_set_security_level(s: *mut SSL, level: c_int); + + #[cfg(any(ossl110, libressl360))] + pub fn SSL_CTX_get_security_level(ctx: *const SSL_CTX) -> c_int; + + #[cfg(any(ossl110, libressl360))] + pub fn SSL_get_security_level(s: *const SSL) -> c_int; +} + +#[cfg(ossl320)] +extern "C" { + pub fn OSSL_QUIC_client_method() -> *const SSL_METHOD; + pub fn OSSL_QUIC_client_thread_method() -> *const SSL_METHOD; + pub fn SSL_get_event_timeout(s: *mut SSL, tv: *mut timeval, is_infinite: *mut c_int) -> c_int; + pub fn SSL_handle_events(s: *mut SSL) -> c_int; + pub fn SSL_get_blocking_mode(s: *mut SSL) -> c_int; + pub fn SSL_set_blocking_mode(s: *mut SSL, blocking: c_int) -> c_int; + pub fn SSL_get_rpoll_descriptor(s: *mut SSL, desc: *mut BIO_POLL_DESCRIPTOR) -> c_int; + pub fn SSL_get_wpoll_descriptor(s: *mut SSL, desc: *mut BIO_POLL_DESCRIPTOR) -> c_int; + pub fn SSL_net_read_desired(s: *mut SSL) -> c_int; + pub fn SSL_net_write_desired(s: *mut SSL) -> c_int; + pub fn SSL_set1_initial_peer_addr(s: *mut SSL, peer_addr: *const BIO_ADDR) -> c_int; + pub fn SSL_shutdown_ex( + ssl: *mut SSL, + flags: u64, + args: *const SSL_SHUTDOWN_EX_ARGS, + args_len: usize, + ) -> c_int; + pub fn SSL_stream_conclude(ssl: *mut SSL, flags: u64) -> c_int; + pub fn SSL_stream_reset( + ssl: *mut SSL, + args: *const SSL_STREAM_RESET_ARGS, + args_len: usize, + ) -> c_int; + pub fn SSL_get_stream_read_state(ssl: *mut SSL) -> c_int; + pub fn SSL_get_stream_write_state(ssl: *mut SSL) -> c_int; + pub fn SSL_get_conn_close_info( + ssl: *mut SSL, + info: *mut SSL_CONN_CLOSE_INFO, + info_len: usize, + ) -> c_int; + pub fn SSL_get0_connection(s: *mut SSL) -> *mut SSL; + pub fn SSL_is_connection(s: *mut SSL) -> c_int; + pub fn SSL_get_stream_type(s: *mut SSL) -> c_int; + pub fn SSL_get_stream_id(s: *mut SSL) -> u64; + pub fn SSL_new_stream(s: *mut SSL, flags: u64) -> *mut SSL; + pub fn SSL_accept_stream(s: *mut SSL, flags: u64) -> *mut SSL; + pub fn SSL_set_incoming_stream_policy(s: *mut SSL, policy: c_int, aec: u64) -> c_int; + pub fn SSL_get_accept_stream_queue_len(s: *mut SSL) -> usize; + pub fn SSL_set_default_stream_mode(s: *mut SSL, mode: u32) -> c_int; +} + +#[cfg(ossl330)] +extern "C" { + pub fn SSL_write_ex2( + s: *mut SSL, + buf: *const c_void, + num: usize, + flags: u64, + written: *mut usize, + ) -> c_int; + pub fn SSL_get_value_uint(s: *mut SSL, class_: u32, id: u32, v: *mut u64) -> c_int; + pub fn SSL_set_value_uint(s: *mut SSL, class_: u32, id: u32, v: u64) -> c_int; +} diff --git a/vendor/openssl-sys/src/handwritten/stack.rs b/vendor/openssl-sys/src/handwritten/stack.rs new file mode 100644 index 0000000..7bc8135 --- /dev/null +++ b/vendor/openssl-sys/src/handwritten/stack.rs @@ -0,0 +1,47 @@ +use libc::*; + +cfg_if! { + if #[cfg(ossl110)] { + pub enum OPENSSL_STACK {} + } else if #[cfg(libressl390)] { + pub enum _STACK {} + } else { + #[repr(C)] + pub struct _STACK { + pub num: c_int, + pub data: *mut *mut c_char, + pub sorted: c_int, + pub num_alloc: c_int, + pub comp: Option c_int>, + } + } +} + +cfg_if! { + if #[cfg(ossl110)] { + extern "C" { + pub fn OPENSSL_sk_num(stack: *const OPENSSL_STACK) -> c_int; + pub fn OPENSSL_sk_value(stack: *const OPENSSL_STACK, idx: c_int) -> *mut c_void; + + pub fn OPENSSL_sk_new_null() -> *mut OPENSSL_STACK; + pub fn OPENSSL_sk_free(st: *mut OPENSSL_STACK); + pub fn OPENSSL_sk_pop_free( + st: *mut OPENSSL_STACK, + free: Option, + ); + pub fn OPENSSL_sk_push(st: *mut OPENSSL_STACK, data: *const c_void) -> c_int; + pub fn OPENSSL_sk_pop(st: *mut OPENSSL_STACK) -> *mut c_void; + } + } else { + extern "C" { + pub fn sk_num(st: *const _STACK) -> c_int; + pub fn sk_value(st: *const _STACK, n: c_int) -> *mut c_void; + + pub fn sk_new_null() -> *mut _STACK; + pub fn sk_free(st: *mut _STACK); + pub fn sk_pop_free(st: *mut _STACK, free: Option); + pub fn sk_push(st: *mut _STACK, data: *mut c_void) -> c_int; + pub fn sk_pop(st: *mut _STACK) -> *mut c_void; + } + } +} diff --git a/vendor/openssl-sys/src/handwritten/thread.rs b/vendor/openssl-sys/src/handwritten/thread.rs new file mode 100644 index 0000000..de661e1 --- /dev/null +++ b/vendor/openssl-sys/src/handwritten/thread.rs @@ -0,0 +1,7 @@ +use super::super::*; +use libc::*; + +extern "C" { + pub fn OSSL_set_max_threads(ctx: *mut OSSL_LIB_CTX, max_threads: u64) -> c_int; + pub fn OSSL_get_max_threads(ctx: *mut OSSL_LIB_CTX) -> u64; +} diff --git a/vendor/openssl-sys/src/handwritten/tls1.rs b/vendor/openssl-sys/src/handwritten/tls1.rs new file mode 100644 index 0000000..8cf992f --- /dev/null +++ b/vendor/openssl-sys/src/handwritten/tls1.rs @@ -0,0 +1,28 @@ +use super::super::*; +use libc::*; + +extern "C" { + pub fn SSL_get_servername(ssl: *const SSL, name_type: c_int) -> *const c_char; + + pub fn SSL_export_keying_material( + s: *mut SSL, + out: *mut c_uchar, + olen: size_t, + label: *const c_char, + llen: size_t, + context: *const c_uchar, + contextlen: size_t, + use_context: c_int, + ) -> c_int; + + #[cfg(ossl111)] + pub fn SSL_export_keying_material_early( + s: *mut SSL, + out: *mut c_uchar, + olen: size_t, + label: *const c_char, + llen: size_t, + context: *const c_uchar, + contextlen: size_t, + ) -> c_int; +} diff --git a/vendor/openssl-sys/src/handwritten/types.rs b/vendor/openssl-sys/src/handwritten/types.rs new file mode 100644 index 0000000..d465a44 --- /dev/null +++ b/vendor/openssl-sys/src/handwritten/types.rs @@ -0,0 +1,1146 @@ +use libc::*; + +#[allow(unused_imports)] +use super::super::*; + +pub enum ASN1_OBJECT {} +pub enum ASN1_VALUE {} + +pub type ASN1_BOOLEAN = c_int; +pub enum ASN1_INTEGER {} +pub enum ASN1_ENUMERATED {} +pub enum ASN1_GENERALIZEDTIME {} +pub enum ASN1_STRING {} +pub enum ASN1_BIT_STRING {} +pub enum ASN1_TIME {} +pub enum ASN1_OCTET_STRING {} +pub enum ASN1_NULL {} +pub enum ASN1_PRINTABLESTRING {} +pub enum ASN1_T61STRING {} +pub enum ASN1_IA5STRING {} +pub enum ASN1_GENERALSTRING {} +pub enum ASN1_BMPSTRING {} +pub enum ASN1_UNIVERSALSTRING {} +pub enum ASN1_UTCTIME {} +pub enum ASN1_VISIBLESTRING {} +pub enum ASN1_UTF8STRING {} + +pub enum bio_st {} // FIXME remove +cfg_if! { + if #[cfg(any(ossl110, libressl280))] { + pub enum BIO {} + } else { + #[repr(C)] + pub struct BIO { + pub method: *mut BIO_METHOD, + pub callback: Option< + unsafe extern "C" fn(*mut BIO, c_int, *const c_char, c_int, c_long, c_long) -> c_long, + >, + pub cb_arg: *mut c_char, + pub init: c_int, + pub shutdown: c_int, + pub flags: c_int, + pub retry_reason: c_int, + pub num: c_int, + pub ptr: *mut c_void, + pub next_bio: *mut BIO, + pub prev_bio: *mut BIO, + pub references: c_int, + pub num_read: c_ulong, + pub num_write: c_ulong, + pub ex_data: CRYPTO_EX_DATA, + } + } +} +cfg_if! { + if #[cfg(ossl320)] { + pub enum BIO_ADDR {} + pub enum BIO_POLL_DESCRIPTOR {} + #[repr(C)] + pub struct BIO_MSG { + pub data: *mut c_void, + pub data_len: usize, + pub peer: *mut BIO_ADDR, + pub local: *mut BIO_ADDR, + pub flags: u64, + } + } +} +cfg_if! { + if #[cfg(any(ossl110, libressl350))] { + pub enum BIGNUM {} + } else { + #[repr(C)] + pub struct BIGNUM { + pub d: *mut BN_ULONG, + pub top: c_int, + pub dmax: c_int, + pub neg: c_int, + pub flags: c_int, + } + } +} +pub enum BN_BLINDING {} +pub enum BN_MONT_CTX {} + +pub enum BN_CTX {} +pub enum BN_GENCB {} + +cfg_if! { + if #[cfg(any(ossl110, libressl280))] { + pub enum EVP_CIPHER {} + } else { + #[repr(C)] + pub struct EVP_CIPHER { + pub nid: c_int, + pub block_size: c_int, + pub key_len: c_int, + pub iv_len: c_int, + pub flags: c_ulong, + pub init: Option< + unsafe extern "C" fn(*mut EVP_CIPHER_CTX, *const c_uchar, *const c_uchar, c_int) -> c_int, + >, + pub do_cipher: Option< + unsafe extern "C" fn(*mut EVP_CIPHER_CTX, *mut c_uchar, *const c_uchar, size_t) -> c_int, + >, + pub cleanup: Option c_int>, + pub ctx_size: c_int, + pub set_asn1_parameters: + Option c_int>, + pub get_asn1_parameters: + Option c_int>, + pub ctrl: + Option c_int>, + pub app_data: *mut c_void, + } + } +} +pub enum EVP_CIPHER_CTX {} +pub enum EVP_MD {} +cfg_if! { + if #[cfg(any(ossl110, libressl280))] { + pub enum EVP_MD_CTX {} + } else { + #[repr(C)] + pub struct EVP_MD_CTX { + digest: *mut EVP_MD, + engine: *mut ENGINE, + flags: c_ulong, + md_data: *mut c_void, + pctx: *mut EVP_PKEY_CTX, + update: *mut c_void, + } + } +} + +pub enum PKCS8_PRIV_KEY_INFO {} + +pub enum EVP_PKEY_ASN1_METHOD {} + +pub enum EVP_PKEY_CTX {} + +pub enum CMAC_CTX {} + +cfg_if! { + if #[cfg(any(ossl110, libressl280))] { + pub enum HMAC_CTX {} + } else { + #[repr(C)] + pub struct HMAC_CTX { + md: *mut EVP_MD, + md_ctx: EVP_MD_CTX, + i_ctx: EVP_MD_CTX, + o_ctx: EVP_MD_CTX, + key_length: c_uint, + key: [c_uchar; 128], + } + } +} + +cfg_if! { + if #[cfg(any(ossl110, libressl280))] { + pub enum DH {} + } else { + #[repr(C)] + pub struct DH { + pub pad: c_int, + pub version: c_int, + pub p: *mut BIGNUM, + pub g: *mut BIGNUM, + pub length: c_long, + pub pub_key: *mut BIGNUM, + pub priv_key: *mut BIGNUM, + pub flags: c_int, + pub method_mont_p: *mut BN_MONT_CTX, + pub q: *mut BIGNUM, + pub j: *mut BIGNUM, + pub seed: *mut c_uchar, + pub seedlen: c_int, + pub counter: *mut BIGNUM, + pub references: c_int, + pub ex_data: CRYPTO_EX_DATA, + pub meth: *const DH_METHOD, + pub engine: *mut ENGINE, + } + } +} +pub enum DH_METHOD {} + +cfg_if! { + if #[cfg(any(ossl110, libressl280))] { + pub enum DSA {} + } else { + #[repr(C)] + pub struct DSA { + pub pad: c_int, + pub version: c_long, + pub write_params: c_int, + + pub p: *mut BIGNUM, + pub q: *mut BIGNUM, + pub g: *mut BIGNUM, + pub pub_key: *mut BIGNUM, + pub priv_key: *mut BIGNUM, + pub kinv: *mut BIGNUM, + pub r: *mut BIGNUM, + + pub flags: c_int, + pub method_mont_p: *mut BN_MONT_CTX, + pub references: c_int, + pub ex_data: CRYPTO_EX_DATA, + pub meth: *const DSA_METHOD, + pub engine: *mut ENGINE, + } + } +} +pub enum DSA_METHOD {} + +cfg_if! { + if #[cfg(any(ossl110, libressl280))] { + pub enum RSA {} + } else if #[cfg(libressl)] { + #[repr(C)] + pub struct RSA { + pub pad: c_int, + pub version: c_long, + pub meth: *const RSA_METHOD, + + pub engine: *mut ENGINE, + pub n: *mut BIGNUM, + pub e: *mut BIGNUM, + pub d: *mut BIGNUM, + pub p: *mut BIGNUM, + pub q: *mut BIGNUM, + pub dmp1: *mut BIGNUM, + pub dmq1: *mut BIGNUM, + pub iqmp: *mut BIGNUM, + + pub ex_data: CRYPTO_EX_DATA, + pub references: c_int, + pub flags: c_int, + + pub _method_mod_n: *mut BN_MONT_CTX, + pub _method_mod_p: *mut BN_MONT_CTX, + pub _method_mod_q: *mut BN_MONT_CTX, + + pub blinding: *mut BN_BLINDING, + pub mt_blinding: *mut BN_BLINDING, + } + } else { + #[repr(C)] + pub struct RSA { + pub pad: c_int, + pub version: c_long, + pub meth: *const RSA_METHOD, + + pub engine: *mut ENGINE, + pub n: *mut BIGNUM, + pub e: *mut BIGNUM, + pub d: *mut BIGNUM, + pub p: *mut BIGNUM, + pub q: *mut BIGNUM, + pub dmp1: *mut BIGNUM, + pub dmq1: *mut BIGNUM, + pub iqmp: *mut BIGNUM, + + pub ex_data: CRYPTO_EX_DATA, + pub references: c_int, + pub flags: c_int, + + pub _method_mod_n: *mut BN_MONT_CTX, + pub _method_mod_p: *mut BN_MONT_CTX, + pub _method_mod_q: *mut BN_MONT_CTX, + + pub bignum_data: *mut c_char, + pub blinding: *mut BN_BLINDING, + pub mt_blinding: *mut BN_BLINDING, + } + } +} +pub enum RSA_METHOD {} + +pub enum EC_KEY {} + +cfg_if! { + if #[cfg(any(ossl110, libressl280))] { + pub enum X509 {} + } else if #[cfg(libressl)] { + #[repr(C)] + pub struct X509 { + pub cert_info: *mut X509_CINF, + pub sig_alg: *mut X509_ALGOR, + pub signature: *mut ASN1_BIT_STRING, + pub valid: c_int, + pub references: c_int, + pub name: *mut c_char, + pub ex_data: CRYPTO_EX_DATA, + pub ex_pathlen: c_long, + pub ex_pcpathlen: c_long, + pub ex_flags: c_ulong, + pub ex_kusage: c_ulong, + pub ex_xkusage: c_ulong, + pub ex_nscert: c_ulong, + skid: *mut c_void, + akid: *mut c_void, + policy_cache: *mut c_void, + crldp: *mut c_void, + altname: *mut c_void, + nc: *mut c_void, + #[cfg(not(osslconf = "OPENSSL_NO_SHA"))] + sha1_hash: [c_uchar; 20], + aux: *mut c_void, + } + } else { + #[repr(C)] + pub struct X509 { + pub cert_info: *mut X509_CINF, + pub sig_alg: *mut X509_ALGOR, + pub signature: *mut ASN1_BIT_STRING, + pub valid: c_int, + pub references: c_int, + pub name: *mut c_char, + pub ex_data: CRYPTO_EX_DATA, + pub ex_pathlen: c_long, + pub ex_pcpathlen: c_long, + pub ex_flags: c_ulong, + pub ex_kusage: c_ulong, + pub ex_xkusage: c_ulong, + pub ex_nscert: c_ulong, + skid: *mut c_void, + akid: *mut c_void, + policy_cache: *mut c_void, + crldp: *mut c_void, + altname: *mut c_void, + nc: *mut c_void, + #[cfg(not(osslconf = "OPENSSL_NO_RFC3779"))] + rfc3779_addr: *mut c_void, + #[cfg(not(osslconf = "OPENSSL_NO_RFC3779"))] + rfc3779_asid: *mut c_void, + #[cfg(not(osslconf = "OPENSSL_NO_SHA"))] + sha1_hash: [c_uchar; 20], + aux: *mut c_void, + } + } +} +cfg_if! { + if #[cfg(any(ossl110, libressl382))] { + pub enum X509_ALGOR {} + } else { + #[repr(C)] + pub struct X509_ALGOR { + pub algorithm: *mut ASN1_OBJECT, + parameter: *mut c_void, + } + } +} + +stack!(stack_st_X509_ALGOR); + +pub enum X509_LOOKUP_METHOD {} + +pub enum X509_NAME {} + +cfg_if! { + if #[cfg(any(ossl110, libressl270))] { + pub enum X509_STORE {} + } else { + #[repr(C)] + pub struct X509_STORE { + cache: c_int, + pub objs: *mut stack_st_X509_OBJECT, + get_cert_methods: *mut stack_st_X509_LOOKUP, + param: *mut X509_VERIFY_PARAM, + verify: Option c_int>, + verify_cb: Option c_int>, + get_issuer: Option< + extern "C" fn(issuer: *mut *mut X509, ctx: *mut X509_STORE_CTX, x: *mut X509) -> c_int, + >, + check_issued: + Option c_int>, + check_revocation: Option c_int>, + get_crl: Option< + extern "C" fn(ctx: *mut X509_STORE_CTX, crl: *mut *mut X509_CRL, x: *mut X509) -> c_int, + >, + check_crl: Option c_int>, + cert_crl: + Option c_int>, + lookup_certs: + Option *mut stack_st_X509>, + lookup_crls: Option< + extern "C" fn(ctx: *const X509_STORE_CTX, nm: *const X509_NAME) -> *mut stack_st_X509_CRL, + >, + cleanup: Option c_int>, + ex_data: CRYPTO_EX_DATA, + references: c_int, + } + } +} + +pub enum X509_STORE_CTX {} + +cfg_if! { + if #[cfg(any(ossl110, libressl280))] { + pub enum X509_VERIFY_PARAM {} + } else if #[cfg(libressl251)] { + #[repr(C)] + pub struct X509_VERIFY_PARAM { + pub name: *mut c_char, + pub check_time: time_t, + pub inh_flags: c_ulong, + pub flags: c_ulong, + pub purpose: c_int, + pub trust: c_int, + pub depth: c_int, + pub policies: *mut stack_st_ASN1_OBJECT, + id: *mut c_void, + } + } else if #[cfg(libressl)] { + #[repr(C)] + pub struct X509_VERIFY_PARAM { + pub name: *mut c_char, + pub check_time: time_t, + pub inh_flags: c_ulong, + pub flags: c_ulong, + pub purpose: c_int, + pub trust: c_int, + pub depth: c_int, + pub policies: *mut stack_st_ASN1_OBJECT, + //pub id: *mut X509_VERIFY_PARAM_ID, + } + } else { + #[repr(C)] + pub struct X509_VERIFY_PARAM { + pub name: *mut c_char, + pub check_time: time_t, + pub inh_flags: c_ulong, + pub flags: c_ulong, + pub purpose: c_int, + pub trust: c_int, + pub depth: c_int, + pub policies: *mut stack_st_ASN1_OBJECT, + #[cfg(ossl102)] + pub id: *mut X509_VERIFY_PARAM_ID, + } + } +} + +cfg_if! { + if #[cfg(any(ossl110, libressl270))] { + pub enum X509_OBJECT {} + } else { + #[repr(C)] + pub struct X509_OBJECT { + pub type_: c_int, + pub data: X509_OBJECT_data, + } + #[repr(C)] + pub union X509_OBJECT_data { + pub ptr: *mut c_char, + pub x509: *mut X509, + pub crl: *mut X509_CRL, + pub pkey: *mut EVP_PKEY, + } + } +} + +pub enum X509_LOOKUP {} + +#[repr(C)] +pub struct X509V3_CTX { + flags: c_int, + issuer_cert: *mut c_void, + subject_cert: *mut c_void, + subject_req: *mut c_void, + crl: *mut c_void, + #[cfg(not(libressl400))] + db_meth: *mut c_void, + db: *mut c_void, + #[cfg(ossl300)] + issuer_pkey: *mut c_void, + // I like the last comment line, it is copied from OpenSSL sources: + // Maybe more here +} +pub enum CONF {} +#[cfg(ossl110)] +pub enum OPENSSL_INIT_SETTINGS {} + +pub enum ENGINE {} +cfg_if! { + if #[cfg(any(ossl110, libressl280))] { + pub enum SSL {} + } else if #[cfg(libressl251)] { + #[repr(C)] + pub struct SSL { + version: c_int, + method: *const SSL_METHOD, + rbio: *mut BIO, + wbio: *mut BIO, + bbio: *mut BIO, + pub server: c_int, + s3: *mut c_void, + d1: *mut c_void, + param: *mut c_void, + cipher_list: *mut stack_st_SSL_CIPHER, + cert: *mut c_void, + sid_ctx_length: c_uint, + sid_ctx: [c_uchar; SSL_MAX_SID_CTX_LENGTH as usize], + session: *mut SSL_SESSION, + verify_mode: c_int, + error: c_int, + error_code: c_int, + ctx: *mut SSL_CTX, + verify_result: c_long, + references: c_int, + client_version: c_int, + max_send_fragment: c_uint, + tlsext_hostname: *mut c_char, + tlsext_status_type: c_int, + initial_ctx: *mut SSL_CTX, + enc_read_ctx: *mut EVP_CIPHER_CTX, + read_hash: *mut EVP_MD_CTX, + internal: *mut c_void, + } + } else if #[cfg(libressl)] { + #[repr(C)] + pub struct SSL { + version: c_int, + type_: c_int, + method: *const SSL_METHOD, + rbio: *mut c_void, + wbio: *mut c_void, + bbio: *mut c_void, + rwstate: c_int, + in_handshake: c_int, + handshake_func: Option c_int>, + pub server: c_int, + new_session: c_int, + quiet_shutdown: c_int, + shutdown: c_int, + state: c_int, + rstate: c_int, + init_buf: *mut c_void, + init_msg: *mut c_void, + init_num: c_int, + init_off: c_int, + packet: *mut c_uchar, + packet_length: c_uint, + s3: *mut c_void, + d1: *mut c_void, + read_ahead: c_int, + msg_callback: Option< + unsafe extern "C" fn(c_int, + c_int, + c_int, + *const c_void, + size_t, + *mut SSL, + *mut c_void), + >, + msg_callback_arg: *mut c_void, + hit: c_int, + param: *mut c_void, + cipher_list: *mut stack_st_SSL_CIPHER, + cipher_list_by_id: *mut stack_st_SSL_CIPHER, + mac_flags: c_int, + aead_read_ctx: *mut c_void, + enc_read_ctx: *mut EVP_CIPHER_CTX, + read_hash: *mut EVP_MD_CTX, + aead_write_ctx: *mut c_void, + enc_write_ctx: *mut EVP_CIPHER_CTX, + write_hash: *mut EVP_MD_CTX, + cert: *mut c_void, + sid_ctx_length: c_uint, + sid_ctx: [c_uchar; SSL_MAX_SID_CTX_LENGTH as usize], + session: *mut SSL_SESSION, + generate_session_id: GEN_SESSION_CB, + verify_mode: c_int, + verify_callback: Option c_int>, + info_callback: Option, + error: c_int, + error_code: c_int, + ctx: *mut SSL_CTX, + debug: c_int, + verify_result: c_long, + ex_data: CRYPTO_EX_DATA, + client_CA: *mut stack_st_X509_NAME, + references: c_int, + options: c_ulong, + mode: c_ulong, + max_cert_list: c_long, + first_packet: c_int, + client_version: c_int, + max_send_fragment: c_uint, + tlsext_debug_cb: + Option, + tlsext_debug_arg: *mut c_void, + tlsext_hostname: *mut c_char, + servername_done: c_int, + tlsext_status_type: c_int, + tlsext_status_expected: c_int, + tlsext_ocsp_ids: *mut c_void, + tlsext_ocsp_exts: *mut c_void, + tlsext_ocsp_resp: *mut c_uchar, + tlsext_ocsp_resplen: c_int, + tlsext_ticket_expected: c_int, + tlsext_ecpointformatlist_length: size_t, + tlsext_ecpointformatlist: *mut c_uchar, + tlsext_ellipticcurvelist_length: size_t, + tlsext_ellipticcurvelist: *mut c_uchar, + tlsext_session_ticket: *mut c_void, + tlsext_session_ticket_ext_cb: tls_session_ticket_ext_cb_fn, + tls_session_ticket_ext_cb_arg: *mut c_void, + tls_session_secret_cb: tls_session_secret_cb_fn, + tls_session_secret_cb_arg: *mut c_void, + initial_ctx: *mut SSL_CTX, + next_proto_negotiated: *mut c_uchar, + next_proto_negotiated_len: c_uchar, + srtp_profiles: *mut c_void, + srtp_profile: *mut c_void, + tlsext_heartbeat: c_uint, + tlsext_hb_pending: c_uint, + tlsext_hb_seq: c_uint, + alpn_client_proto_list: *mut c_uchar, + alpn_client_proto_list_len: c_uint, + renegotiate: c_int, + } + } else { + #[repr(C)] + pub struct SSL { + version: c_int, + type_: c_int, + method: *const SSL_METHOD, + rbio: *mut c_void, + wbio: *mut c_void, + bbio: *mut c_void, + rwstate: c_int, + in_handshake: c_int, + handshake_func: Option c_int>, + pub server: c_int, + new_session: c_int, + quiet_session: c_int, + shutdown: c_int, + state: c_int, + rstate: c_int, + init_buf: *mut c_void, + init_msg: *mut c_void, + init_num: c_int, + init_off: c_int, + packet: *mut c_uchar, + packet_length: c_uint, + s2: *mut c_void, + s3: *mut c_void, + d1: *mut c_void, + read_ahead: c_int, + msg_callback: Option< + unsafe extern "C" fn(c_int, c_int, c_int, *const c_void, size_t, *mut SSL, *mut c_void), + >, + msg_callback_arg: *mut c_void, + hit: c_int, + param: *mut c_void, + cipher_list: *mut stack_st_SSL_CIPHER, + cipher_list_by_id: *mut stack_st_SSL_CIPHER, + mac_flags: c_int, + enc_read_ctx: *mut EVP_CIPHER_CTX, + read_hash: *mut EVP_MD_CTX, + expand: *mut c_void, + enc_write_ctx: *mut EVP_CIPHER_CTX, + write_hash: *mut EVP_MD_CTX, + compress: *mut c_void, + cert: *mut c_void, + sid_ctx_length: c_uint, + sid_ctx: [c_uchar; SSL_MAX_SID_CTX_LENGTH as usize], + session: *mut SSL_SESSION, + generate_session_id: GEN_SESSION_CB, + verify_mode: c_int, + verify_callback: Option c_int>, + info_callback: Option, + error: c_int, + error_code: c_int, + #[cfg(not(osslconf = "OPENSSL_NO_KRB5"))] + kssl_ctx: *mut c_void, + #[cfg(not(osslconf = "OPENSSL_NO_PSK"))] + psk_client_callback: Option< + unsafe extern "C" fn(*mut SSL, *const c_char, *mut c_char, c_uint, *mut c_uchar, c_uint) + -> c_uint, + >, + #[cfg(not(osslconf = "OPENSSL_NO_PSK"))] + psk_server_callback: + Option c_uint>, + ctx: *mut SSL_CTX, + debug: c_int, + verify_result: c_long, + ex_data: CRYPTO_EX_DATA, + client_CA: *mut stack_st_X509_NAME, + references: c_int, + options: c_ulong, + mode: c_ulong, + max_cert_list: c_long, + first_packet: c_int, + client_version: c_int, + max_send_fragment: c_uint, + #[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))] + tlsext_debug_cb: + Option, + #[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))] + tlsext_debug_arg: *mut c_void, + #[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))] + tlsext_hostname: *mut c_char, + #[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))] + servername_done: c_int, + #[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))] + tlsext_status_type: c_int, + #[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))] + tlsext_status_expected: c_int, + #[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))] + tlsext_ocsp_ids: *mut c_void, + #[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))] + tlsext_ocsp_exts: *mut c_void, + #[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))] + tlsext_ocsp_resp: *mut c_uchar, + #[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))] + tlsext_ocsp_resplen: c_int, + #[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))] + tlsext_ticket_expected: c_int, + #[cfg(all( + not(osslconf = "OPENSSL_NO_TLSEXT"), + not(osslconf = "OPENSSL_NO_EC") + ))] + tlsext_ecpointformatlist_length: size_t, + #[cfg(all( + not(osslconf = "OPENSSL_NO_TLSEXT"), + not(osslconf = "OPENSSL_NO_EC") + ))] + tlsext_ecpointformatlist: *mut c_uchar, + #[cfg(all( + not(osslconf = "OPENSSL_NO_TLSEXT"), + not(osslconf = "OPENSSL_NO_EC") + ))] + tlsext_ellipticcurvelist_length: size_t, + #[cfg(all( + not(osslconf = "OPENSSL_NO_TLSEXT"), + not(osslconf = "OPENSSL_NO_EC") + ))] + tlsext_ellipticcurvelist: *mut c_uchar, + #[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))] + tlsext_opaque_prf_input: *mut c_void, + #[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))] + tlsext_opaque_prf_input_len: size_t, + #[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))] + tlsext_session_ticket: *mut c_void, + #[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))] + tlsext_session_ticket_ext_cb: tls_session_ticket_ext_cb_fn, + #[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))] + tls_session_ticket_ext_cb_arg: *mut c_void, + #[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))] + tls_session_secret_cb: tls_session_secret_cb_fn, + #[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))] + tls_session_secret_cb_arg: *mut c_void, + #[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))] + initial_ctx: *mut SSL_CTX, + #[cfg(all( + not(osslconf = "OPENSSL_NO_TLSEXT"), + not(osslconf = "OPENSSL_NO_NEXTPROTONEG") + ))] + next_proto_negotiated: *mut c_uchar, + #[cfg(all( + not(osslconf = "OPENSSL_NO_TLSEXT"), + not(osslconf = "OPENSSL_NO_NEXTPROTONEG") + ))] + next_proto_negotiated_len: c_uchar, + #[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))] + srtp_profiles: *mut c_void, + #[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))] + srtp_profile: *mut c_void, + #[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))] + tlsext_heartbeat: c_uint, + #[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))] + tlsext_hb_pending: c_uint, + #[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))] + tlsext_hb_seq: c_uint, + renegotiate: c_int, + #[cfg(not(osslconf = "OPENSSL_NO_SRP"))] + srp_ctx: SRP_CTX, + #[cfg(all(not(osslconf = "OPENSSL_NO_TLSEXT"), ossl102))] + alpn_client_proto_list: *mut c_uchar, + #[cfg(all(not(osslconf = "OPENSSL_NO_TLSEXT"), ossl102))] + alpn_client_proto_list_len: c_uint, + } + } +} +cfg_if! { + if #[cfg(any(ossl110, libressl280))] { + pub enum SSL_CTX {} + } else if #[cfg(libressl251)] { + #[repr(C)] + pub struct SSL_CTX { + method: *const SSL_METHOD, + cipher_list: *mut stack_st_SSL_CIPHER, + cert_store: *mut c_void, + session_timeout: c_long, + pub references: c_int, + extra_certs: *mut stack_st_X509, + verify_mode: c_int, + sid_ctx_length: c_uint, + sid_ctx: [c_uchar; SSL_MAX_SID_CTX_LENGTH as usize], + param: *mut X509_VERIFY_PARAM, + default_passwd_callback: *mut c_void, + default_passwd_callback_userdata: *mut c_void, + internal: *mut c_void, + } + } else if #[cfg(libressl)] { + #[repr(C)] + pub struct SSL_CTX { + method: *mut c_void, + cipher_list: *mut c_void, + cipher_list_by_id: *mut c_void, + cert_store: *mut c_void, + sessions: *mut c_void, + session_cache_size: c_ulong, + session_cache_head: *mut c_void, + session_cache_tail: *mut c_void, + session_cache_mode: c_int, + session_timeout: c_long, + new_session_cb: *mut c_void, + remove_session_cb: *mut c_void, + get_session_cb: *mut c_void, + stats: [c_int; 11], + pub references: c_int, + app_verify_callback: *mut c_void, + app_verify_arg: *mut c_void, + default_passwd_callback: *mut c_void, + default_passwd_callback_userdata: *mut c_void, + client_cert_cb: *mut c_void, + app_gen_cookie_cb: *mut c_void, + app_verify_cookie_cb: *mut c_void, + ex_dat: CRYPTO_EX_DATA, + rsa_md5: *mut c_void, + md5: *mut c_void, + sha1: *mut c_void, + extra_certs: *mut c_void, + comp_methods: *mut c_void, + info_callback: *mut c_void, + client_CA: *mut c_void, + options: c_ulong, + mode: c_ulong, + max_cert_list: c_long, + cert: *mut c_void, + read_ahead: c_int, + msg_callback: *mut c_void, + msg_callback_arg: *mut c_void, + verify_mode: c_int, + sid_ctx_length: c_uint, + sid_ctx: [c_uchar; 32], + default_verify_callback: *mut c_void, + generate_session_id: *mut c_void, + param: *mut c_void, + quiet_shutdown: c_int, + max_send_fragment: c_uint, + + #[cfg(not(osslconf = "OPENSSL_NO_ENGINE"))] + client_cert_engine: *mut c_void, + + tlsext_servername_callback: *mut c_void, + tlsect_servername_arg: *mut c_void, + tlsext_tick_key_name: [c_uchar; 16], + tlsext_tick_hmac_key: [c_uchar; 16], + tlsext_tick_aes_key: [c_uchar; 16], + tlsext_ticket_key_cb: *mut c_void, + tlsext_status_cb: *mut c_void, + tlsext_status_arg: *mut c_void, + tlsext_opaque_prf_input_callback: *mut c_void, + tlsext_opaque_prf_input_callback_arg: *mut c_void, + + next_protos_advertised_cb: *mut c_void, + next_protos_advertised_cb_arg: *mut c_void, + next_proto_select_cb: *mut c_void, + next_proto_select_cb_arg: *mut c_void, + + srtp_profiles: *mut c_void, + } + } else { + #[repr(C)] + pub struct SSL_CTX { + method: *mut c_void, + cipher_list: *mut c_void, + cipher_list_by_id: *mut c_void, + cert_store: *mut c_void, + sessions: *mut c_void, + session_cache_size: c_ulong, + session_cache_head: *mut c_void, + session_cache_tail: *mut c_void, + session_cache_mode: c_int, + session_timeout: c_long, + new_session_cb: *mut c_void, + remove_session_cb: *mut c_void, + get_session_cb: *mut c_void, + stats: [c_int; 11], + pub references: c_int, + app_verify_callback: *mut c_void, + app_verify_arg: *mut c_void, + default_passwd_callback: *mut c_void, + default_passwd_callback_userdata: *mut c_void, + client_cert_cb: *mut c_void, + app_gen_cookie_cb: *mut c_void, + app_verify_cookie_cb: *mut c_void, + ex_dat: CRYPTO_EX_DATA, + rsa_md5: *mut c_void, + md5: *mut c_void, + sha1: *mut c_void, + extra_certs: *mut c_void, + comp_methods: *mut c_void, + info_callback: *mut c_void, + client_CA: *mut c_void, + options: c_ulong, + mode: c_ulong, + max_cert_list: c_long, + cert: *mut c_void, + read_ahead: c_int, + msg_callback: *mut c_void, + msg_callback_arg: *mut c_void, + verify_mode: c_int, + sid_ctx_length: c_uint, + sid_ctx: [c_uchar; 32], + default_verify_callback: *mut c_void, + generate_session_id: *mut c_void, + param: *mut c_void, + quiet_shutdown: c_int, + max_send_fragment: c_uint, + + #[cfg(not(osslconf = "OPENSSL_NO_ENGINE"))] + client_cert_engine: *mut c_void, + + #[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))] + tlsext_servername_callback: *mut c_void, + #[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))] + tlsect_servername_arg: *mut c_void, + #[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))] + tlsext_tick_key_name: [c_uchar; 16], + #[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))] + tlsext_tick_hmac_key: [c_uchar; 16], + #[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))] + tlsext_tick_aes_key: [c_uchar; 16], + #[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))] + tlsext_ticket_key_cb: *mut c_void, + #[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))] + tlsext_status_cb: *mut c_void, + #[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))] + tlsext_status_arg: *mut c_void, + #[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))] + tlsext_opaque_prf_input_callback: *mut c_void, + #[cfg(not(osslconf = "OPENSSL_NO_TLSEXT"))] + tlsext_opaque_prf_input_callback_arg: *mut c_void, + + #[cfg(not(osslconf = "OPENSSL_NO_PSK"))] + psk_identity_hint: *mut c_void, + #[cfg(not(osslconf = "OPENSSL_NO_PSK"))] + psk_client_callback: *mut c_void, + #[cfg(not(osslconf = "OPENSSL_NO_PSK"))] + psk_server_callback: *mut c_void, + + #[cfg(not(osslconf = "OPENSSL_NO_BUF_FREELISTS"))] + freelist_max_len: c_uint, + #[cfg(not(osslconf = "OPENSSL_NO_BUF_FREELISTS"))] + wbuf_freelist: *mut c_void, + #[cfg(not(osslconf = "OPENSSL_NO_BUF_FREELISTS"))] + rbuf_freelist: *mut c_void, + + #[cfg(not(osslconf = "OPENSSL_NO_SRP"))] + srp_ctx: SRP_CTX, + + #[cfg(all( + not(osslconf = "OPENSSL_NO_TLSEXT"), + not(osslconf = "OPENSSL_NO_NEXTPROTONEG") + ))] + next_protos_advertised_cb: *mut c_void, + #[cfg(all( + not(osslconf = "OPENSSL_NO_TLSEXT"), + not(osslconf = "OPENSSL_NO_NEXTPROTONEG") + ))] + next_protos_advertised_cb_arg: *mut c_void, + #[cfg(all( + not(osslconf = "OPENSSL_NO_TLSEXT"), + not(osslconf = "OPENSSL_NO_NEXTPROTONEG") + ))] + next_proto_select_cb: *mut c_void, + #[cfg(all( + not(osslconf = "OPENSSL_NO_TLSEXT"), + not(osslconf = "OPENSSL_NO_NEXTPROTONEG") + ))] + next_proto_select_cb_arg: *mut c_void, + + #[cfg(all(not(osslconf = "OPENSSL_NO_TLSEXT"), ossl101))] + srtp_profiles: *mut c_void, + #[cfg(all(not(osslconf = "OPENSSL_NO_TLSEXT"), ossl102))] + alpn_select_cb: *mut c_void, + #[cfg(all(not(osslconf = "OPENSSL_NO_TLSEXT"), ossl102))] + alpn_select_cb_arg: *mut c_void, + #[cfg(all(not(osslconf = "OPENSSL_NO_TLSEXT"), ossl102))] + alpn_client_proto_list: *mut c_void, + #[cfg(all(not(osslconf = "OPENSSL_NO_TLSEXT"), ossl102))] + alpn_client_proto_list_len: c_uint, + + #[cfg(all( + not(osslconf = "OPENSSL_NO_TLSEXT"), + not(osslconf = "OPENSSL_NO_EC"), + ossl102 + ))] + tlsext_ecpointformatlist_length: size_t, + #[cfg(all( + not(osslconf = "OPENSSL_NO_TLSEXT"), + not(osslconf = "OPENSSL_NO_EC"), + ossl102 + ))] + tlsext_ecpointformatlist: *mut c_uchar, + #[cfg(all( + not(osslconf = "OPENSSL_NO_TLSEXT"), + not(osslconf = "OPENSSL_NO_EC"), + ossl102 + ))] + tlsext_ellipticcurvelist_length: size_t, + #[cfg(all( + not(osslconf = "OPENSSL_NO_TLSEXT"), + not(osslconf = "OPENSSL_NO_EC"), + ossl102 + ))] + tlsext_ellipticcurvelist: *mut c_uchar, + } + + #[repr(C)] + #[cfg(not(osslconf = "OPENSSL_NO_SRP"))] + pub struct SRP_CTX { + SRP_cb_arg: *mut c_void, + TLS_ext_srp_username_callback: *mut c_void, + SRP_verify_param_callback: *mut c_void, + SRP_give_srp_client_pwd_callback: *mut c_void, + login: *mut c_void, + N: *mut c_void, + g: *mut c_void, + s: *mut c_void, + B: *mut c_void, + A: *mut c_void, + a: *mut c_void, + b: *mut c_void, + v: *mut c_void, + info: *mut c_void, + stringth: c_int, + srp_Mask: c_ulong, + } + } +} +cfg_if! { + if #[cfg(ossl320)] { + #[repr(C)] + pub struct SSL_CONN_CLOSE_INFO { + pub error_code: u64, + pub frame_type: u64, + pub reason: *const ::libc::c_char, + pub reason_len: usize, + pub flags: u32, + } + #[repr(C)] + pub struct SSL_SHUTDOWN_EX_ARGS { + pub quic_error_code: u64, + pub quic_reason: *const c_char, + } + #[repr(C)] + pub struct SSL_STREAM_RESET_ARGS { + pub quic_error_code: u64, + } + } +} + +pub enum COMP_CTX {} + +cfg_if! { + if #[cfg(any(ossl110, libressl350))] { + pub enum COMP_METHOD {} + } else { + #[repr(C)] + pub struct COMP_METHOD { + pub type_: c_int, + pub name: *const c_char, + init: Option c_int>, + finish: Option, + compress: Option< + unsafe extern "C" fn( + *mut COMP_CTX, + *mut c_uchar, + c_uint, + *mut c_uchar, + c_uint, + ) -> c_int, + >, + expand: Option< + unsafe extern "C" fn( + *mut COMP_CTX, + *mut c_uchar, + c_uint, + *mut c_uchar, + c_uint, + ) -> c_int, + >, + ctrl: Option c_long>, + callback_ctrl: Option c_long>, + } + } +} + +cfg_if! { + if #[cfg(any(ossl110, libressl280))] { + pub enum CRYPTO_EX_DATA {} + } else if #[cfg(libressl)] { + #[repr(C)] + pub struct CRYPTO_EX_DATA { + pub sk: *mut stack_st_void, + } + } else { + #[repr(C)] + pub struct CRYPTO_EX_DATA { + pub sk: *mut stack_st_void, + pub dummy: c_int, + } + } +} + +pub enum OCSP_RESPONSE {} + +#[cfg(ossl300)] +pub enum OSSL_PROVIDER {} + +#[cfg(ossl300)] +pub enum OSSL_LIB_CTX {} + +#[cfg(ossl300)] +#[repr(C)] +pub struct OSSL_PARAM { + key: *const c_char, + data_type: c_uchar, + data: *mut c_void, + data_size: size_t, + return_size: size_t, +} + +#[cfg(ossl300)] +pub enum EVP_KDF {} +#[cfg(ossl300)] +pub enum EVP_KDF_CTX {} diff --git a/vendor/openssl-sys/src/handwritten/x509.rs b/vendor/openssl-sys/src/handwritten/x509.rs new file mode 100644 index 0000000..0bb6827 --- /dev/null +++ b/vendor/openssl-sys/src/handwritten/x509.rs @@ -0,0 +1,781 @@ +use super::super::*; +use libc::*; + +cfg_if! { + if #[cfg(libressl400)] { + pub enum X509_VAL {} + } else { + #[repr(C)] + pub struct X509_VAL { + pub notBefore: *mut ASN1_TIME, + pub notAfter: *mut ASN1_TIME, + } + } +} + +pub enum X509_NAME_ENTRY {} + +stack!(stack_st_X509_NAME_ENTRY); + +stack!(stack_st_X509_NAME); + +pub enum X509_EXTENSION {} + +stack!(stack_st_X509_EXTENSION); + +pub enum X509_ATTRIBUTE {} + +stack!(stack_st_X509_ATTRIBUTE); + +cfg_if! { + if #[cfg(any(ossl110, libressl350))] { + pub enum X509_REQ_INFO {} + } else { + #[repr(C)] + pub struct X509_REQ_INFO { + pub enc: ASN1_ENCODING, + pub version: *mut ASN1_INTEGER, + pub subject: *mut X509_NAME, + pubkey: *mut c_void, + pub attributes: *mut stack_st_X509_ATTRIBUTE, + } + } +} + +cfg_if! { + if #[cfg(any(ossl110, libressl350))] { + pub enum X509_CRL {} + } else { + #[repr(C)] + pub struct X509_CRL { + pub crl: *mut X509_CRL_INFO, + sig_alg: *mut X509_ALGOR, + signature: *mut c_void, + references: c_int, + flags: c_int, + akid: *mut c_void, + idp: *mut c_void, + idp_flags: c_int, + idp_reasons: c_int, + crl_number: *mut ASN1_INTEGER, + base_crl_number: *mut ASN1_INTEGER, + sha1_hash: [c_uchar; 20], + issuers: *mut c_void, + meth: *const c_void, + meth_data: *mut c_void, + } + } +} + +stack!(stack_st_X509_CRL); + +cfg_if! { + if #[cfg(any(ossl110, libressl350))] { + pub enum X509_CRL_INFO {} + } else { + #[repr(C)] + pub struct X509_CRL_INFO { + version: *mut ASN1_INTEGER, + sig_alg: *mut X509_ALGOR, + pub issuer: *mut X509_NAME, + pub lastUpdate: *mut ASN1_TIME, + pub nextUpdate: *mut ASN1_TIME, + pub revoked: *mut stack_st_X509_REVOKED, + extensions: *mut stack_st_X509_EXTENSION, + enc: ASN1_ENCODING, + } + } +} + +cfg_if! { + if #[cfg(any(ossl110, libressl350))] { + pub enum X509_REVOKED {} + } else { + #[repr(C)] + pub struct X509_REVOKED { + pub serialNumber: *mut ASN1_INTEGER, + pub revocationDate: *mut ASN1_TIME, + pub extensions: *mut stack_st_X509_EXTENSION, + issuer: *mut stack_st_GENERAL_NAME, + reason: c_int, + sequence: c_int, + } + } +} + +stack!(stack_st_X509_REVOKED); + +cfg_if! { + if #[cfg(any(ossl110, libressl350))] { + pub enum X509_REQ {} + } else { + #[repr(C)] + pub struct X509_REQ { + pub req_info: *mut X509_REQ_INFO, + sig_alg: *mut c_void, + signature: *mut c_void, + references: c_int, + } + } +} + +cfg_if! { + if #[cfg(any(ossl110, libressl350))] { + pub enum X509_CINF {} + } else { + #[repr(C)] + pub struct X509_CINF { + version: *mut c_void, + serialNumber: *mut c_void, + signature: *mut c_void, + issuer: *mut c_void, + pub validity: *mut X509_VAL, + subject: *mut c_void, + key: *mut c_void, + issuerUID: *mut c_void, + subjectUID: *mut c_void, + pub extensions: *mut stack_st_X509_EXTENSION, + enc: ASN1_ENCODING, + } + } +} + +stack!(stack_st_X509); + +stack!(stack_st_X509_OBJECT); + +stack!(stack_st_X509_LOOKUP); + +extern "C" { + pub fn X509_verify_cert_error_string(n: c_long) -> *const c_char; + + pub fn X509_sign(x: *mut X509, pkey: *mut EVP_PKEY, md: *const EVP_MD) -> c_int; + + pub fn X509_digest( + x: *const X509, + digest: *const EVP_MD, + buf: *mut c_uchar, + len: *mut c_uint, + ) -> c_int; + + pub fn X509_REQ_sign(x: *mut X509_REQ, pkey: *mut EVP_PKEY, md: *const EVP_MD) -> c_int; +} + +const_ptr_api! { + extern "C" { + pub fn i2d_X509_bio(b: *mut BIO, x: #[const_ptr_if(ossl300)] X509) -> c_int; + pub fn i2d_X509_REQ_bio(b: *mut BIO, x: #[const_ptr_if(ossl300)] X509_REQ) -> c_int; + pub fn i2d_PrivateKey_bio(b: *mut BIO, x: #[const_ptr_if(ossl300)] EVP_PKEY) -> c_int; + pub fn i2d_PUBKEY_bio(b: *mut BIO, x: #[const_ptr_if(ossl300)] EVP_PKEY) -> c_int; + + pub fn i2d_PUBKEY(k: #[const_ptr_if(ossl300)] EVP_PKEY, buf: *mut *mut u8) -> c_int; + pub fn i2d_RSA_PUBKEY(k: #[const_ptr_if(ossl300)] RSA, buf: *mut *mut u8) -> c_int; + pub fn i2d_DSA_PUBKEY(a: #[const_ptr_if(ossl300)] DSA, pp: *mut *mut c_uchar) -> c_int; + pub fn i2d_PrivateKey(k: #[const_ptr_if(ossl300)] EVP_PKEY, buf: *mut *mut u8) -> c_int; + pub fn i2d_ECPrivateKey(ec_key: #[const_ptr_if(ossl300)] EC_KEY, pp: *mut *mut c_uchar) -> c_int; + pub fn i2d_EC_PUBKEY(a: #[const_ptr_if(ossl300)] EC_KEY, pp: *mut *mut c_uchar) -> c_int; + } +} +extern "C" { + pub fn d2i_PUBKEY(k: *mut *mut EVP_PKEY, buf: *mut *const u8, len: c_long) -> *mut EVP_PKEY; + pub fn d2i_RSA_PUBKEY(k: *mut *mut RSA, buf: *mut *const u8, len: c_long) -> *mut RSA; + pub fn d2i_DSA_PUBKEY(k: *mut *mut DSA, pp: *mut *const c_uchar, length: c_long) -> *mut DSA; + pub fn d2i_EC_PUBKEY( + a: *mut *mut EC_KEY, + pp: *mut *const c_uchar, + length: c_long, + ) -> *mut EC_KEY; + + pub fn d2i_ECPrivateKey( + k: *mut *mut EC_KEY, + pp: *mut *const c_uchar, + length: c_long, + ) -> *mut EC_KEY; +} + +const_ptr_api! { + extern "C" { + #[cfg(any(ossl102, libressl350))] + pub fn X509_ALGOR_get0( + paobj: *mut #[const_ptr_if(any(ossl110, libressl350))] ASN1_OBJECT, + pptype: *mut c_int, + ppval: *mut #[const_ptr_if(any(ossl110, libressl350))] c_void, + alg: #[const_ptr_if(any(ossl110, libressl350))] X509_ALGOR, + ); + } +} + +extern "C" { + pub fn X509_gmtime_adj(time: *mut ASN1_TIME, adj: c_long) -> *mut ASN1_TIME; + + pub fn X509_to_X509_REQ(x: *mut X509, pkey: *mut EVP_PKEY, md: *const EVP_MD) -> *mut X509_REQ; + + pub fn X509_ALGOR_free(x: *mut X509_ALGOR); + + pub fn X509_REVOKED_new() -> *mut X509_REVOKED; + pub fn X509_REVOKED_free(x: *mut X509_REVOKED); +} +const_ptr_api! { + extern "C" { + #[cfg(any(ossl110, libressl270))] + pub fn X509_REVOKED_dup(rev: #[const_ptr_if(ossl300)] X509_REVOKED) -> *mut X509_REVOKED; + } +} + +extern "C" { + pub fn d2i_X509_REVOKED( + a: *mut *mut X509_REVOKED, + pp: *mut *const c_uchar, + length: c_long, + ) -> *mut X509_REVOKED; +} +const_ptr_api! { + extern "C" { + pub fn i2d_X509_REVOKED(x: #[const_ptr_if(ossl300)] X509_REVOKED, buf: *mut *mut u8) -> c_int; + } +} +extern "C" { + pub fn X509_CRL_new() -> *mut X509_CRL; + pub fn X509_CRL_free(x: *mut X509_CRL); + pub fn d2i_X509_CRL( + a: *mut *mut X509_CRL, + pp: *mut *const c_uchar, + length: c_long, + ) -> *mut X509_CRL; +} +const_ptr_api! { + extern "C" { + pub fn i2d_X509_CRL(x: #[const_ptr_if(ossl300)] X509_CRL, buf: *mut *mut u8) -> c_int; + #[cfg(any(ossl110, libressl270))] + pub fn X509_CRL_dup(x: #[const_ptr_if(ossl300)] X509_CRL) -> *mut X509_CRL; + } +} + +extern "C" { + pub fn X509_REQ_new() -> *mut X509_REQ; + pub fn X509_REQ_free(x: *mut X509_REQ); + pub fn d2i_X509_REQ( + a: *mut *mut X509_REQ, + pp: *mut *const c_uchar, + length: c_long, + ) -> *mut X509_REQ; +} +const_ptr_api! { + extern "C" { + pub fn i2d_X509_REQ(x: #[const_ptr_if(ossl300)] X509_REQ, buf: *mut *mut u8) -> c_int; + + #[cfg(any(ossl102, libressl273))] + pub fn X509_get0_signature( + psig: *mut #[const_ptr_if(any(ossl110, libressl273))] ASN1_BIT_STRING, + palg: *mut #[const_ptr_if(any(ossl110, libressl273))] X509_ALGOR, + x: *const X509, + ); + + #[cfg(any(ossl110, libressl270))] + pub fn X509_REQ_dup(x: #[const_ptr_if(ossl300)] X509_REQ) -> *mut X509_REQ; + } +} +extern "C" { + #[cfg(ossl102)] + pub fn X509_get_signature_nid(x: *const X509) -> c_int; + + pub fn X509_EXTENSION_free(ext: *mut X509_EXTENSION); + + pub fn X509_NAME_ENTRY_free(x: *mut X509_NAME_ENTRY); + + pub fn X509_NAME_new() -> *mut X509_NAME; + pub fn X509_NAME_cmp(x: *const X509_NAME, y: *const X509_NAME) -> c_int; + pub fn X509_NAME_free(x: *mut X509_NAME); + + pub fn X509_new() -> *mut X509; + pub fn X509_free(x: *mut X509); +} +const_ptr_api! { + extern "C" { + pub fn i2d_X509(x: #[const_ptr_if(ossl300)] X509, buf: *mut *mut u8) -> c_int; + #[cfg(any(ossl110, libressl270))] + pub fn X509_NAME_dup(x: #[const_ptr_if(ossl300)] X509_NAME) -> *mut X509_NAME; + #[cfg(any(ossl110, libressl270))] + pub fn X509_dup(x: #[const_ptr_if(ossl300)] X509) -> *mut X509; + #[cfg(any(ossl101, libressl350))] + pub fn X509_NAME_add_entry( + name: *mut X509_NAME, + ne: #[const_ptr_if(any(ossl110, libressl))] X509_NAME_ENTRY, + loc: c_int, + set: c_int, + ) -> c_int; + } +} +extern "C" { + pub fn d2i_X509(a: *mut *mut X509, pp: *mut *const c_uchar, length: c_long) -> *mut X509; + pub fn d2i_X509_bio(b: *mut BIO, a: *mut *mut X509) -> *mut X509; + + pub fn X509_get_pubkey(x: *mut X509) -> *mut EVP_PKEY; + + pub fn X509_set_version(x: *mut X509, version: c_long) -> c_int; + #[cfg(ossl110)] + pub fn X509_get_version(x: *const X509) -> c_long; + pub fn X509_set_serialNumber(x: *mut X509, sn: *mut ASN1_INTEGER) -> c_int; + pub fn X509_get_serialNumber(x: *mut X509) -> *mut ASN1_INTEGER; + pub fn X509_alias_get0(x: *mut X509, len: *mut c_int) -> *mut c_uchar; +} +const_ptr_api! { + extern "C" { + pub fn X509_set_issuer_name(x: *mut X509, name: #[const_ptr_if(ossl300)] X509_NAME) -> c_int; + } +} +extern "C" { + pub fn X509_issuer_name_hash(x: *mut X509) -> c_ulong; + pub fn X509_subject_name_hash(x: *mut X509) -> c_ulong; +} +const_ptr_api! { + extern "C" { + pub fn X509_get_issuer_name(x: #[const_ptr_if(any(ossl110, libressl280))] X509) -> *mut X509_NAME; + pub fn X509_set_subject_name(x: *mut X509, name: #[const_ptr_if(ossl300)] X509_NAME) -> c_int; + pub fn X509_get_subject_name(x: #[const_ptr_if(any(ossl110, libressl280))] X509) -> *mut X509_NAME; + } +} +cfg_if! { + if #[cfg(any(ossl110, libressl350))] { + extern "C" { + pub fn X509_set1_notBefore(x: *mut X509, tm: *const ASN1_TIME) -> c_int; + pub fn X509_set1_notAfter(x: *mut X509, tm: *const ASN1_TIME) -> c_int; + } + } else { + extern "C" { + pub fn X509_set_notBefore(x: *mut X509, tm: *const ASN1_TIME) -> c_int; + pub fn X509_set_notAfter(x: *mut X509, tm: *const ASN1_TIME) -> c_int; + } + } +} +extern "C" { + #[cfg(any(ossl110, libressl350))] + pub fn X509_REQ_get_version(req: *const X509_REQ) -> c_long; + pub fn X509_REQ_set_version(req: *mut X509_REQ, version: c_long) -> c_int; + #[cfg(any(ossl110, libressl350))] + pub fn X509_REQ_get_subject_name(req: *const X509_REQ) -> *mut X509_NAME; +} +const_ptr_api! { + extern "C" { + pub fn X509_REQ_set_subject_name(req: *mut X509_REQ, name: #[const_ptr_if(ossl300)] X509_NAME) -> c_int; + } +} +extern "C" { + pub fn X509_REQ_set_pubkey(req: *mut X509_REQ, pkey: *mut EVP_PKEY) -> c_int; + pub fn X509_REQ_get_pubkey(req: *mut X509_REQ) -> *mut EVP_PKEY; + pub fn X509_REQ_get_extensions(req: *mut X509_REQ) -> *mut stack_st_X509_EXTENSION; +} +const_ptr_api! { + extern "C" { + pub fn X509_REQ_add_extensions(req: *mut X509_REQ, exts: #[const_ptr_if(ossl300)] stack_st_X509_EXTENSION) + -> c_int; + } +} +extern "C" { + pub fn X509_REQ_get_attr_count(req: *const X509_REQ) -> c_int; + pub fn X509_REQ_get_attr_by_NID(req: *const X509_REQ, nid: c_int, lastpos: c_int) -> c_int; + pub fn X509_REQ_get_attr(req: *const X509_REQ, loc: c_int) -> *mut X509_ATTRIBUTE; + pub fn X509_REQ_delete_attr(req: *mut X509_REQ, loc: c_int) -> *mut X509_ATTRIBUTE; + pub fn X509_REQ_add1_attr_by_txt( + req: *mut X509_REQ, + attrname: *const c_char, + chtype: c_int, + bytes: *const c_uchar, + len: c_int, + ) -> c_int; + pub fn X509_REQ_add1_attr_by_NID( + req: *mut X509_REQ, + nid: c_int, + chtype: c_int, + bytes: *const c_uchar, + len: c_int, + ) -> c_int; + pub fn X509_REQ_add1_attr_by_OBJ( + req: *mut X509_REQ, + obj: *const ASN1_OBJECT, + chtype: c_int, + bytes: *const c_uchar, + len: c_int, + ) -> c_int; +} +extern "C" { + pub fn X509_set_pubkey(x: *mut X509, pkey: *mut EVP_PKEY) -> c_int; + pub fn X509_REQ_verify(req: *mut X509_REQ, pkey: *mut EVP_PKEY) -> c_int; + #[cfg(any(ossl110, libressl273))] + pub fn X509_getm_notBefore(x: *const X509) -> *mut ASN1_TIME; + #[cfg(any(ossl110, libressl273))] + pub fn X509_getm_notAfter(x: *const X509) -> *mut ASN1_TIME; + #[cfg(any(ossl110, libressl273))] + pub fn X509_up_ref(x: *mut X509) -> c_int; + + #[cfg(any(ossl110, libressl270))] + pub fn X509_REVOKED_get0_serialNumber(req: *const X509_REVOKED) -> *const ASN1_INTEGER; + #[cfg(any(ossl110, libressl270))] + pub fn X509_REVOKED_get0_revocationDate(req: *const X509_REVOKED) -> *const ASN1_TIME; + #[cfg(any(ossl110, libressl270))] + pub fn X509_REVOKED_get0_extensions(r: *const X509_REVOKED) -> *const stack_st_X509_EXTENSION; + + pub fn X509_REVOKED_set_serialNumber(r: *mut X509_REVOKED, serial: *mut ASN1_INTEGER) -> c_int; + pub fn X509_REVOKED_set_revocationDate(r: *mut X509_REVOKED, tm: *mut ASN1_TIME) -> c_int; + + pub fn X509_CRL_sign(x: *mut X509_CRL, pkey: *mut EVP_PKEY, md: *const EVP_MD) -> c_int; + pub fn X509_CRL_digest( + x: *const X509_CRL, + digest: *const EVP_MD, + md: *mut c_uchar, + len: *mut c_uint, + ) -> c_int; + pub fn X509_CRL_verify(crl: *mut X509_CRL, pkey: *mut EVP_PKEY) -> c_int; + pub fn X509_CRL_get0_by_cert( + x: *mut X509_CRL, + ret: *mut *mut X509_REVOKED, + cert: *mut X509, + ) -> c_int; +} +const_ptr_api! { + extern "C" { + pub fn X509_CRL_get0_by_serial( + x: *mut X509_CRL, + ret: *mut *mut X509_REVOKED, + serial: #[const_ptr_if(ossl300)] ASN1_INTEGER, + ) -> c_int; + } +} + +extern "C" { + #[cfg(any(ossl110, libressl281))] + pub fn X509_CRL_get_REVOKED(crl: *mut X509_CRL) -> *mut stack_st_X509_REVOKED; + #[cfg(any(ossl110, libressl281))] + pub fn X509_CRL_get0_nextUpdate(x: *const X509_CRL) -> *const ASN1_TIME; + #[cfg(any(ossl110, libressl281))] + pub fn X509_CRL_get0_lastUpdate(x: *const X509_CRL) -> *const ASN1_TIME; + #[cfg(any(ossl110, libressl281))] + pub fn X509_CRL_get_issuer(x: *const X509_CRL) -> *mut X509_NAME; + + #[cfg(ossl110)] + pub fn X509_get0_extensions(req: *const X509) -> *const stack_st_X509_EXTENSION; + + pub fn X509_CRL_set_version(crl: *mut X509_CRL, version: c_long) -> c_int; +} +const_ptr_api! { + extern "C" { + pub fn X509_CRL_set_issuer_name(crl: *mut X509_CRL, name: #[const_ptr_if(ossl300)] X509_NAME) -> c_int; + } +} +extern "C" { + pub fn X509_CRL_sort(crl: *mut X509_CRL) -> c_int; + + #[cfg(any(ossl110, libressl270))] + pub fn X509_CRL_up_ref(crl: *mut X509_CRL) -> c_int; + pub fn X509_CRL_add0_revoked(crl: *mut X509_CRL, rev: *mut X509_REVOKED) -> c_int; +} +cfg_if! { + if #[cfg(any(ossl110, libressl270))] { + extern "C" { + pub fn X509_CRL_set1_lastUpdate(crl: *mut X509_CRL, tm: *const ASN1_TIME) -> c_int; + pub fn X509_CRL_set1_nextUpdate(crl: *mut X509_CRL, tm: *const ASN1_TIME) -> c_int; + } + } else { + // libressl270 kept them, ossl110 "#define"s them to the variants above + extern "C" { + pub fn X509_CRL_set_lastUpdate(crl: *mut X509_CRL, tm: *const ASN1_TIME) -> c_int; + pub fn X509_CRL_set_nextUpdate(crl: *mut X509_CRL, tm: *const ASN1_TIME) -> c_int; + } + } +} + +const_ptr_api! { + extern "C" { + pub fn X509_NAME_entry_count(n: #[const_ptr_if(any(ossl110, libressl280))] X509_NAME) -> c_int; + pub fn X509_NAME_get_index_by_NID(n: #[const_ptr_if(any(ossl300, libressl280))] X509_NAME, nid: c_int, last_pos: c_int) -> c_int; + pub fn X509_NAME_get_entry(n: #[const_ptr_if(any(ossl110, libressl280))] X509_NAME, loc: c_int) -> *mut X509_NAME_ENTRY; + pub fn X509_NAME_add_entry_by_NID( + x: *mut X509_NAME, + field: c_int, + ty: c_int, + bytes: #[const_ptr_if(any(ossl110, libressl280))] c_uchar, + len: c_int, + loc: c_int, + set: c_int, + ) -> c_int; + pub fn i2d_X509_NAME(n: #[const_ptr_if(ossl300)] X509_NAME, buf: *mut *mut u8) -> c_int; + pub fn X509_NAME_ENTRY_get_object(ne: #[const_ptr_if(any(ossl110, libressl280))] X509_NAME_ENTRY) -> *mut ASN1_OBJECT; + pub fn X509_NAME_ENTRY_get_data(ne: #[const_ptr_if(any(ossl110, libressl280))] X509_NAME_ENTRY) -> *mut ASN1_STRING; + } +} +extern "C" { + pub fn X509_NAME_add_entry_by_txt( + x: *mut X509_NAME, + field: *const c_char, + ty: c_int, + bytes: *const c_uchar, + len: c_int, + loc: c_int, + set: c_int, + ) -> c_int; + pub fn d2i_X509_NAME( + n: *mut *mut X509_NAME, + pp: *mut *const c_uchar, + length: c_long, + ) -> *mut X509_NAME; +} + +// "raw" X509_EXTENSION related functions +extern "C" { + // in X509 + pub fn X509_delete_ext(x: *mut X509, loc: c_int) -> *mut X509_EXTENSION; + pub fn X509_add_ext(x: *mut X509, ext: *mut X509_EXTENSION, loc: c_int) -> c_int; + pub fn X509_add1_ext_i2d( + x: *mut X509, + nid: c_int, + value: *mut c_void, + crit: c_int, + flags: c_ulong, + ) -> c_int; + // in X509_CRL + pub fn X509_CRL_delete_ext(x: *mut X509_CRL, loc: c_int) -> *mut X509_EXTENSION; + pub fn X509_CRL_add_ext(x: *mut X509_CRL, ext: *mut X509_EXTENSION, loc: c_int) -> c_int; + pub fn X509_CRL_add1_ext_i2d( + x: *mut X509_CRL, + nid: c_int, + value: *mut c_void, + crit: c_int, + flags: c_ulong, + ) -> c_int; + // in X509_REVOKED + pub fn X509_REVOKED_delete_ext(x: *mut X509_REVOKED, loc: c_int) -> *mut X509_EXTENSION; + pub fn X509_REVOKED_add_ext( + x: *mut X509_REVOKED, + ext: *mut X509_EXTENSION, + loc: c_int, + ) -> c_int; + pub fn X509_REVOKED_add1_ext_i2d( + x: *mut X509_REVOKED, + nid: c_int, + value: *mut c_void, + crit: c_int, + flags: c_ulong, + ) -> c_int; + // X509_EXTENSION stack + // - these getters always used *const STACK + pub fn X509v3_get_ext_count(x: *const stack_st_X509_EXTENSION) -> c_int; + pub fn X509v3_get_ext_by_NID( + x: *const stack_st_X509_EXTENSION, + nid: c_int, + lastpos: c_int, + ) -> c_int; + pub fn X509v3_get_ext_by_critical( + x: *const stack_st_X509_EXTENSION, + crit: c_int, + lastpos: c_int, + ) -> c_int; + pub fn X509v3_get_ext(x: *const stack_st_X509_EXTENSION, loc: c_int) -> *mut X509_EXTENSION; + pub fn X509v3_delete_ext(x: *mut stack_st_X509_EXTENSION, loc: c_int) -> *mut X509_EXTENSION; + pub fn X509v3_add_ext( + x: *mut *mut stack_st_X509_EXTENSION, + ex: *mut X509_EXTENSION, + loc: c_int, + ) -> *mut stack_st_X509_EXTENSION; + // - X509V3_add1_i2d in x509v3.rs + // X509_EXTENSION itself + pub fn X509_EXTENSION_create_by_NID( + ex: *mut *mut X509_EXTENSION, + nid: c_int, + crit: c_int, + data: *mut ASN1_OCTET_STRING, + ) -> *mut X509_EXTENSION; + pub fn X509_EXTENSION_set_critical(ex: *mut X509_EXTENSION, crit: c_int) -> c_int; + pub fn X509_EXTENSION_set_data(ex: *mut X509_EXTENSION, data: *mut ASN1_OCTET_STRING) -> c_int; + pub fn X509_EXTENSION_get_object(ext: *mut X509_EXTENSION) -> *mut ASN1_OBJECT; + pub fn X509_EXTENSION_get_data(ext: *mut X509_EXTENSION) -> *mut ASN1_OCTET_STRING; +} + +const_ptr_api! { + extern "C" { + pub fn i2d_X509_EXTENSION(ext: #[const_ptr_if(ossl300)] X509_EXTENSION, pp: *mut *mut c_uchar) -> c_int; + } +} + +const_ptr_api! { + extern "C" { + // in X509 + pub fn X509_get_ext_count(x: #[const_ptr_if(any(ossl110, libressl280))] X509) -> c_int; + pub fn X509_get_ext_by_NID(x: #[const_ptr_if(any(ossl110, libressl280))] X509, nid: c_int, lastpos: c_int) -> c_int; + pub fn X509_get_ext_by_OBJ(x: #[const_ptr_if(any(ossl110, libressl280))] X509, obj: #[const_ptr_if(any(ossl110, libressl280))] ASN1_OBJECT, lastpos: c_int) -> c_int; + pub fn X509_get_ext_by_critical(x: #[const_ptr_if(any(ossl110, libressl280))] X509, crit: c_int, lastpos: c_int) -> c_int; + pub fn X509_get_ext(x: #[const_ptr_if(any(ossl110, libressl280))] X509, loc: c_int) -> *mut X509_EXTENSION; + pub fn X509_get_ext_d2i( + x: #[const_ptr_if(any(ossl110, libressl280))] X509, + nid: c_int, + crit: *mut c_int, + idx: *mut c_int, + ) -> *mut c_void; + // in X509_CRL + pub fn X509_CRL_get_ext_count(x: #[const_ptr_if(any(ossl110, libressl280))] X509_CRL) -> c_int; + pub fn X509_CRL_get_ext_by_NID(x: #[const_ptr_if(any(ossl110, libressl280))] X509_CRL, nid: c_int, lastpos: c_int) -> c_int; + pub fn X509_CRL_get_ext_by_OBJ(x: #[const_ptr_if(any(ossl110, libressl280))] X509_CRL, obj: #[const_ptr_if(any(ossl110, libressl280))] ASN1_OBJECT, lastpos: c_int) -> c_int; + pub fn X509_CRL_get_ext_by_critical(x: #[const_ptr_if(any(ossl110, libressl280))] X509_CRL, crit: c_int, lastpos: c_int) -> c_int; + pub fn X509_CRL_get_ext(x: #[const_ptr_if(any(ossl110, libressl280))] X509_CRL, loc: c_int) -> *mut X509_EXTENSION; + pub fn X509_CRL_get_ext_d2i( + x: #[const_ptr_if(any(ossl110, libressl280))] X509_CRL, + nid: c_int, + crit: *mut c_int, + idx: *mut c_int, + ) -> *mut c_void; + // in X509_REVOKED + pub fn X509_REVOKED_get_ext_count(x: #[const_ptr_if(any(ossl110, libressl280))] X509_REVOKED) -> c_int; + pub fn X509_REVOKED_get_ext_by_NID(x: #[const_ptr_if(any(ossl110, libressl280))] X509_REVOKED, nid: c_int, lastpos: c_int) -> c_int; + pub fn X509_REVOKED_get_ext_by_OBJ(x: #[const_ptr_if(any(ossl110, libressl280))] X509_REVOKED, obj: #[const_ptr_if(any(ossl110, libressl280))] ASN1_OBJECT, lastpos: c_int) -> c_int; + pub fn X509_REVOKED_get_ext_by_critical(x: #[const_ptr_if(any(ossl110, libressl280))] X509_REVOKED, crit: c_int, lastpos: c_int) -> c_int; + pub fn X509_REVOKED_get_ext(x: #[const_ptr_if(any(ossl110, libressl280))] X509_REVOKED, loc: c_int) -> *mut X509_EXTENSION; + pub fn X509_REVOKED_get_ext_d2i( + x: #[const_ptr_if(any(ossl110, libressl280))] X509_REVOKED, + nid: c_int, + crit: *mut c_int, + idx: *mut c_int, + ) -> *mut c_void; + // X509_EXTENSION stack + pub fn X509v3_get_ext_by_OBJ(x: *const stack_st_X509_EXTENSION, obj: #[const_ptr_if(any(ossl110, libressl280))] ASN1_OBJECT, lastpos: c_int) -> c_int; + // X509_EXTENSION itself + pub fn X509_EXTENSION_create_by_OBJ(ex: *mut *mut X509_EXTENSION, obj: #[const_ptr_if(any(ossl110, libressl280))] ASN1_OBJECT, crit: c_int, data: *mut ASN1_OCTET_STRING) -> *mut X509_EXTENSION; + pub fn X509_EXTENSION_set_object(ex: *mut X509_EXTENSION, obj: #[const_ptr_if(any(ossl110, libressl280))] ASN1_OBJECT) -> c_int; + pub fn X509_EXTENSION_get_critical(ex: #[const_ptr_if(any(ossl110, libressl280))] X509_EXTENSION) -> c_int; + } +} + +extern "C" { + pub fn X509_verify_cert(ctx: *mut X509_STORE_CTX) -> c_int; +} + +const_ptr_api! { + extern "C" { + #[cfg(any(ossl110, libressl270))] + pub fn X509_STORE_get0_objects(ctx: #[const_ptr_if(ossl300)] X509_STORE) -> *mut stack_st_X509_OBJECT; + #[cfg(ossl300)] + pub fn X509_STORE_get1_all_certs(ctx: *mut X509_STORE) -> *mut stack_st_X509; + } +} + +#[cfg(any(ossl110, libressl270))] +extern "C" { + pub fn X509_OBJECT_get0_X509(x: *const X509_OBJECT) -> *mut X509; +} + +cfg_if! { + if #[cfg(any(ossl110, libressl350))] { + extern "C" { + pub fn X509_OBJECT_free(a: *mut X509_OBJECT); + } + } else { + extern "C" { + pub fn X509_OBJECT_free_contents(a: *mut X509_OBJECT); + } + } +} + +extern "C" { + pub fn X509_get_default_cert_file_env() -> *const c_char; + pub fn X509_get_default_cert_file() -> *const c_char; + pub fn X509_get_default_cert_dir_env() -> *const c_char; + pub fn X509_get_default_cert_dir() -> *const c_char; +} + +extern "C" { + pub fn X509_cmp(a: *const X509, b: *const X509) -> c_int; + pub fn X509_issuer_and_serial_cmp(a: *const X509, b: *const X509) -> c_int; + pub fn X509_issuer_name_cmp(a: *const X509, b: *const X509) -> c_int; + pub fn X509_subject_name_cmp(a: *const X509, b: *const X509) -> c_int; + pub fn X509_CRL_cmp(a: *const X509_CRL, b: *const X509_CRL) -> c_int; + pub fn X509_CRL_match(a: *const X509_CRL, b: *const X509_CRL) -> c_int; +} + +extern "C" { + pub fn X509_print(bio: *mut BIO, x509: *mut X509) -> c_int; + pub fn X509_REQ_print(bio: *mut BIO, req: *mut X509_REQ) -> c_int; +} + +cfg_if! { + if #[cfg(libressl390)] { + pub enum X509_PURPOSE {} + } else { + #[repr(C)] + pub struct X509_PURPOSE { + pub purpose: c_int, + pub trust: c_int, // Default trust ID + pub flags: c_int, + pub check_purpose: + Option c_int>, + pub name: *mut c_char, + pub sname: *mut c_char, + pub usr_data: *mut c_void, + } + } +} + +const_ptr_api! { + extern "C" { + pub fn X509_PURPOSE_get_by_sname(sname: #[const_ptr_if(any(ossl110, libressl280))] c_char) -> c_int; + pub fn X509_PURPOSE_get_id(purpose: #[const_ptr_if(any(ossl110, libressl280))] X509_PURPOSE) -> c_int; + pub fn X509_PURPOSE_get0(idx: c_int) -> #[const_ptr_if(libressl390)] X509_PURPOSE; + } +} + +extern "C" { + pub fn X509_ATTRIBUTE_new() -> *mut X509_ATTRIBUTE; + pub fn X509_ATTRIBUTE_free(attr: *mut X509_ATTRIBUTE); + pub fn X509_ATTRIBUTE_create( + nid: c_int, + atrtype: c_int, + value: *mut c_void, + ) -> *mut X509_ATTRIBUTE; + pub fn X509_ATTRIBUTE_create_by_NID( + attr: *mut *mut X509_ATTRIBUTE, + nid: c_int, + atrtype: c_int, + data: *const c_void, + len: c_int, + ) -> *mut X509_ATTRIBUTE; + pub fn X509_ATTRIBUTE_create_by_OBJ( + attr: *mut *mut X509_ATTRIBUTE, + obj: *const ASN1_OBJECT, + atrtype: c_int, + data: *const c_void, + len: c_int, + ) -> *mut X509_ATTRIBUTE; + pub fn X509_ATTRIBUTE_create_by_txt( + attr: *mut *mut X509_ATTRIBUTE, + atrname: *const c_char, + atrtype: c_int, + bytes: *const c_uchar, + len: c_int, + ) -> *mut X509_ATTRIBUTE; + pub fn X509_ATTRIBUTE_set1_object(attr: *mut X509_ATTRIBUTE, obj: *const ASN1_OBJECT) -> c_int; + pub fn X509_ATTRIBUTE_set1_data( + attr: *mut X509_ATTRIBUTE, + attrtype: c_int, + data: *const c_void, + len: c_int, + ) -> c_int; + pub fn X509_ATTRIBUTE_get0_data( + attr: *mut X509_ATTRIBUTE, + idx: c_int, + atrtype: c_int, + data: *mut c_void, + ) -> *mut c_void; + pub fn X509_ATTRIBUTE_get0_object(attr: *mut X509_ATTRIBUTE) -> *mut ASN1_OBJECT; + pub fn X509_ATTRIBUTE_get0_type(attr: *mut X509_ATTRIBUTE, idx: c_int) -> *mut ASN1_TYPE; + pub fn d2i_X509_ATTRIBUTE( + a: *mut *mut X509_ATTRIBUTE, + pp: *mut *const c_uchar, + length: c_long, + ) -> *mut X509_ATTRIBUTE; +} +const_ptr_api! { + extern "C" { + pub fn X509_ATTRIBUTE_count( + attr: #[const_ptr_if(any(ossl110, libressl280))] X509_ATTRIBUTE // const since OpenSSL v1.1.0 + ) -> c_int; + pub fn i2d_X509_ATTRIBUTE(x: #[const_ptr_if(ossl300)] X509_ATTRIBUTE, buf: *mut *mut u8) -> c_int; + pub fn X509_ATTRIBUTE_dup(x: #[const_ptr_if(ossl300)] X509_ATTRIBUTE) -> *mut X509_ATTRIBUTE; + } +} diff --git a/vendor/openssl-sys/src/handwritten/x509_vfy.rs b/vendor/openssl-sys/src/handwritten/x509_vfy.rs new file mode 100644 index 0000000..31928f8 --- /dev/null +++ b/vendor/openssl-sys/src/handwritten/x509_vfy.rs @@ -0,0 +1,141 @@ +use super::super::*; +use libc::*; + +#[cfg(any(libressl, all(ossl102, not(ossl110))))] +pub enum X509_VERIFY_PARAM_ID {} + +extern "C" { + #[cfg(ossl110)] + pub fn X509_LOOKUP_meth_free(method: *mut X509_LOOKUP_METHOD); +} + +const_ptr_api! { + extern "C" { + pub fn X509_LOOKUP_hash_dir() -> #[const_ptr_if(libressl400)] X509_LOOKUP_METHOD; + pub fn X509_LOOKUP_file() -> #[const_ptr_if(libressl400)] X509_LOOKUP_METHOD; + } +} +extern "C" { + pub fn X509_LOOKUP_free(ctx: *mut X509_LOOKUP); + pub fn X509_LOOKUP_ctrl( + ctx: *mut X509_LOOKUP, + cmd: c_int, + argc: *const c_char, + argl: c_long, + ret: *mut *mut c_char, + ) -> c_int; + pub fn X509_load_cert_file(ctx: *mut X509_LOOKUP, file: *const c_char, _type: c_int) -> c_int; + pub fn X509_load_crl_file(ctx: *mut X509_LOOKUP, file: *const c_char, _type: c_int) -> c_int; +} + +extern "C" { + pub fn X509_STORE_new() -> *mut X509_STORE; + pub fn X509_STORE_free(store: *mut X509_STORE); + + pub fn X509_STORE_CTX_new() -> *mut X509_STORE_CTX; + + pub fn X509_STORE_CTX_free(ctx: *mut X509_STORE_CTX); + pub fn X509_STORE_CTX_init( + ctx: *mut X509_STORE_CTX, + store: *mut X509_STORE, + x509: *mut X509, + chain: *mut stack_st_X509, + ) -> c_int; + pub fn X509_STORE_CTX_cleanup(ctx: *mut X509_STORE_CTX); + + pub fn X509_STORE_add_cert(store: *mut X509_STORE, x: *mut X509) -> c_int; + + pub fn X509_STORE_set_default_paths(store: *mut X509_STORE) -> c_int; + pub fn X509_STORE_set_flags(store: *mut X509_STORE, flags: c_ulong) -> c_int; + pub fn X509_STORE_set_purpose(ctx: *mut X509_STORE, purpose: c_int) -> c_int; + pub fn X509_STORE_set_trust(ctx: *mut X509_STORE, trust: c_int) -> c_int; + +} + +const_ptr_api! { + extern "C" { + pub fn X509_STORE_add_lookup( + store: *mut X509_STORE, + meth: #[const_ptr_if(libressl400)] X509_LOOKUP_METHOD, + ) -> *mut X509_LOOKUP; + pub fn X509_STORE_set1_param(store: *mut X509_STORE, pm: #[const_ptr_if(ossl300)] X509_VERIFY_PARAM) -> c_int; + } +} + +const_ptr_api! { + extern "C" { + pub fn X509_STORE_CTX_get_ex_data(ctx: #[const_ptr_if(ossl300)] X509_STORE_CTX, idx: c_int) -> *mut c_void; + pub fn X509_STORE_CTX_get_error(ctx: #[const_ptr_if(ossl300)] X509_STORE_CTX) -> c_int; + pub fn X509_STORE_CTX_get_error_depth(ctx: #[const_ptr_if(ossl300)] X509_STORE_CTX) -> c_int; + pub fn X509_STORE_CTX_get_current_cert(ctx: #[const_ptr_if(ossl300)] X509_STORE_CTX) -> *mut X509; + } +} +extern "C" { + pub fn X509_STORE_CTX_set_error(ctx: *mut X509_STORE_CTX, error: c_int); +} +cfg_if! { + if #[cfg(any(ossl110, libressl350))] { + const_ptr_api! { + extern "C" { + pub fn X509_STORE_CTX_get0_chain(ctx: #[const_ptr_if(ossl300)] X509_STORE_CTX) -> *mut stack_st_X509; + } + } + } else { + extern "C" { + pub fn X509_STORE_CTX_get_chain(ctx: *mut X509_STORE_CTX) -> *mut stack_st_X509; + } + } +} + +extern "C" { + #[cfg(any(ossl102, libressl261))] + pub fn X509_VERIFY_PARAM_new() -> *mut X509_VERIFY_PARAM; + #[cfg(any(ossl102, libressl261))] + pub fn X509_VERIFY_PARAM_free(param: *mut X509_VERIFY_PARAM); + + #[cfg(any(ossl102, libressl261))] + pub fn X509_VERIFY_PARAM_set_flags(param: *mut X509_VERIFY_PARAM, flags: c_ulong) -> c_int; + #[cfg(any(ossl102, libressl261))] + pub fn X509_VERIFY_PARAM_clear_flags(param: *mut X509_VERIFY_PARAM, flags: c_ulong) -> c_int; + + #[cfg(any(ossl102, libressl261))] + pub fn X509_VERIFY_PARAM_set_time(param: *mut X509_VERIFY_PARAM, t: time_t); + + #[cfg(any(ossl102, libressl261))] + pub fn X509_VERIFY_PARAM_set_depth(param: *mut X509_VERIFY_PARAM, depth: c_int); +} +const_ptr_api! { + extern "C" { + #[cfg(any(ossl102, libressl261))] + pub fn X509_VERIFY_PARAM_get_flags(param: #[const_ptr_if(ossl300)] X509_VERIFY_PARAM) -> c_ulong; + } +} + +extern "C" { + #[cfg(any(ossl102, libressl261))] + pub fn X509_VERIFY_PARAM_set1_host( + param: *mut X509_VERIFY_PARAM, + name: *const c_char, + namelen: size_t, + ) -> c_int; + #[cfg(any(ossl102, libressl261))] + pub fn X509_VERIFY_PARAM_set_hostflags(param: *mut X509_VERIFY_PARAM, flags: c_uint); + #[cfg(any(ossl102, libressl261))] + pub fn X509_VERIFY_PARAM_set1_email( + param: *mut X509_VERIFY_PARAM, + email: *const c_char, + emaillen: size_t, + ) -> c_int; + #[cfg(any(ossl102, libressl261))] + pub fn X509_VERIFY_PARAM_set1_ip( + param: *mut X509_VERIFY_PARAM, + ip: *const c_uchar, + iplen: size_t, + ) -> c_int; + #[cfg(ossl110)] + pub fn X509_VERIFY_PARAM_set_auth_level(param: *mut X509_VERIFY_PARAM, lvl: c_int); + #[cfg(ossl110)] + pub fn X509_VERIFY_PARAM_get_auth_level(param: *const X509_VERIFY_PARAM) -> c_int; + #[cfg(ossl102)] + pub fn X509_VERIFY_PARAM_set_purpose(param: *mut X509_VERIFY_PARAM, purpose: c_int) -> c_int; +} diff --git a/vendor/openssl-sys/src/handwritten/x509v3.rs b/vendor/openssl-sys/src/handwritten/x509v3.rs new file mode 100644 index 0000000..1a548c0 --- /dev/null +++ b/vendor/openssl-sys/src/handwritten/x509v3.rs @@ -0,0 +1,167 @@ +use super::super::*; +use libc::*; + +pub enum CONF_METHOD {} + +extern "C" { + pub fn GENERAL_NAME_new() -> *mut GENERAL_NAME; + pub fn GENERAL_NAME_free(name: *mut GENERAL_NAME); + pub fn GENERAL_NAME_set0_othername( + gen: *mut GENERAL_NAME, + oid: *mut ASN1_OBJECT, + value: *mut ASN1_TYPE, + ) -> c_int; +} + +#[repr(C)] +pub struct ACCESS_DESCRIPTION { + pub method: *mut ASN1_OBJECT, + pub location: *mut GENERAL_NAME, +} + +stack!(stack_st_ACCESS_DESCRIPTION); + +extern "C" { + pub fn ACCESS_DESCRIPTION_free(ad: *mut ACCESS_DESCRIPTION); +} + +#[repr(C)] +pub struct AUTHORITY_KEYID { + pub keyid: *mut ASN1_OCTET_STRING, + pub issuer: *mut stack_st_GENERAL_NAME, + pub serial: *mut ASN1_INTEGER, +} + +extern "C" { + pub fn AUTHORITY_KEYID_free(akid: *mut AUTHORITY_KEYID); +} + +const_ptr_api! { + extern "C" { + pub fn X509V3_EXT_nconf_nid( + conf: *mut CONF, + ctx: *mut X509V3_CTX, + ext_nid: c_int, + value: #[const_ptr_if(any(ossl110, libressl280))] c_char, + ) -> *mut X509_EXTENSION; + pub fn X509V3_EXT_nconf( + conf: *mut CONF, + ctx: *mut X509V3_CTX, + name: #[const_ptr_if(any(ossl110, libressl280))] c_char, + value: #[const_ptr_if(any(ossl110, libressl280))] c_char, + ) -> *mut X509_EXTENSION; + } +} + +extern "C" { + pub fn X509_check_issued(issuer: *mut X509, subject: *mut X509) -> c_int; + pub fn X509_verify(req: *mut X509, pkey: *mut EVP_PKEY) -> c_int; + + pub fn X509V3_set_nconf(ctx: *mut X509V3_CTX, conf: *mut CONF); + + pub fn X509V3_set_ctx( + ctx: *mut X509V3_CTX, + issuer: *mut X509, + subject: *mut X509, + req: *mut X509_REQ, + crl: *mut X509_CRL, + flags: c_int, + ); + + pub fn X509_get1_ocsp(x: *mut X509) -> *mut stack_st_OPENSSL_STRING; +} + +const_ptr_api! { + extern "C" { + pub fn X509V3_get_d2i( + x: #[const_ptr_if(any(ossl110, libressl280))] stack_st_X509_EXTENSION, + nid: c_int, + crit: *mut c_int, + idx: *mut c_int, + ) -> *mut c_void; + pub fn X509V3_extensions_print(out: *mut BIO, title: #[const_ptr_if(any(ossl110, libressl280))] c_char, exts: #[const_ptr_if(any(ossl110, libressl280))] stack_st_X509_EXTENSION, flag: c_ulong, indent: c_int) -> c_int; + } +} + +extern "C" { + #[cfg(not(libressl390))] + pub fn X509V3_EXT_add_alias(nid_to: c_int, nid_from: c_int) -> c_int; + pub fn X509V3_EXT_d2i(ext: *mut X509_EXTENSION) -> *mut c_void; + pub fn X509V3_EXT_i2d(ext_nid: c_int, crit: c_int, ext: *mut c_void) -> *mut X509_EXTENSION; + pub fn X509V3_add1_i2d( + x: *mut *mut stack_st_X509_EXTENSION, + nid: c_int, + value: *mut c_void, + crit: c_int, + flags: c_ulong, + ) -> c_int; + pub fn X509V3_EXT_print( + out: *mut BIO, + ext: *mut X509_EXTENSION, + flag: c_ulong, + indent: c_int, + ) -> c_int; + + #[cfg(ossl110)] + pub fn X509_get_pathlen(x: *mut X509) -> c_long; + #[cfg(ossl110)] + pub fn X509_get_extension_flags(x: *mut X509) -> u32; + #[cfg(ossl110)] + pub fn X509_get_key_usage(x: *mut X509) -> u32; + #[cfg(ossl110)] + pub fn X509_get_extended_key_usage(x: *mut X509) -> u32; + #[cfg(ossl110)] + pub fn X509_get0_subject_key_id(x: *mut X509) -> *const ASN1_OCTET_STRING; + #[cfg(ossl110)] + pub fn X509_get0_authority_key_id(x: *mut X509) -> *const ASN1_OCTET_STRING; + #[cfg(ossl111d)] + pub fn X509_get0_authority_issuer(x: *mut X509) -> *const stack_st_GENERAL_NAME; + #[cfg(ossl111d)] + pub fn X509_get0_authority_serial(x: *mut X509) -> *const ASN1_INTEGER; +} + +#[repr(C)] +pub struct DIST_POINT_NAME { + pub type_: c_int, + pub name: DIST_POINT_NAME_st_anon_union, + pub dpname: *mut X509_NAME, +} + +#[repr(C)] +pub union DIST_POINT_NAME_st_anon_union { + pub fullname: *mut stack_st_GENERAL_NAME, + pub relativename: *mut stack_st_X509_NAME_ENTRY, +} + +#[repr(C)] +pub struct DIST_POINT { + pub distpoint: *mut DIST_POINT_NAME, + pub reasons: *mut ASN1_BIT_STRING, + pub CRLissuer: *mut stack_st_GENERAL_NAME, + pub dp_reasons: c_int, +} +stack!(stack_st_DIST_POINT); + +extern "C" { + pub fn DIST_POINT_free(dist_point: *mut DIST_POINT); + pub fn DIST_POINT_NAME_free(dist_point: *mut DIST_POINT_NAME); +} + +#[cfg(ossl102)] +extern "C" { + pub fn X509_check_host( + x: *mut X509, + chk: *const c_char, + chklen: usize, + flags: c_uint, + peername: *mut *mut c_char, + ) -> c_int; + pub fn X509_check_email( + x: *mut X509, + chk: *const c_char, + chklen: usize, + flags: c_uint, + ) -> c_int; + pub fn X509_check_ip(x: *mut X509, chk: *const c_uchar, chklen: usize, flags: c_uint) -> c_int; + pub fn X509_check_ip_asc(x: *mut X509, ipasc: *const c_char, flags: c_uint) -> c_int; +} diff --git a/vendor/openssl-sys/src/lib.rs b/vendor/openssl-sys/src/lib.rs new file mode 100644 index 0000000..0e23386 --- /dev/null +++ b/vendor/openssl-sys/src/lib.rs @@ -0,0 +1,209 @@ +#![allow( + clippy::missing_safety_doc, + dead_code, + non_camel_case_types, + non_snake_case, + non_upper_case_globals, + unused_imports +)] +#![cfg_attr(feature = "unstable_boringssl", allow(ambiguous_glob_reexports))] +#![doc(html_root_url = "https://docs.rs/openssl-sys/0.9")] +#![recursion_limit = "128"] // configure fixed limit across all rust versions + +extern crate libc; +pub use libc::c_int; + +#[cfg(feature = "unstable_boringssl")] +extern crate bssl_sys; +#[cfg(feature = "unstable_boringssl")] +pub use bssl_sys::*; + +#[cfg(all(boringssl, not(feature = "unstable_boringssl")))] +#[path = "."] +mod boringssl { + include!(concat!(env!("OUT_DIR"), "/bindgen.rs")); + + pub fn init() { + unsafe { + CRYPTO_library_init(); + } + } +} +#[cfg(all(boringssl, not(feature = "unstable_boringssl")))] +pub use boringssl::*; + +#[cfg(openssl)] +#[path = "."] +mod openssl { + use libc::*; + + #[cfg(feature = "bindgen")] + include!(concat!(env!("OUT_DIR"), "/bindgen.rs")); + + pub use self::aes::*; + pub use self::asn1::*; + pub use self::bio::*; + pub use self::bn::*; + pub use self::cms::*; + pub use self::crypto::*; + pub use self::dtls1::*; + pub use self::ec::*; + pub use self::err::*; + pub use self::evp::*; + #[cfg(not(feature = "bindgen"))] + pub use self::handwritten::*; + pub use self::obj_mac::*; + pub use self::ocsp::*; + pub use self::pem::*; + pub use self::pkcs7::*; + pub use self::rsa::*; + pub use self::sha::*; + pub use self::srtp::*; + pub use self::ssl::*; + pub use self::ssl3::*; + pub use self::tls1::*; + pub use self::types::*; + pub use self::x509::*; + pub use self::x509_vfy::*; + pub use self::x509v3::*; + + #[macro_use] + mod macros; + + mod aes; + mod asn1; + mod bio; + mod bn; + mod cms; + mod crypto; + mod dtls1; + mod ec; + mod err; + mod evp; + #[cfg(not(feature = "bindgen"))] + mod handwritten; + mod obj_mac; + mod ocsp; + mod pem; + mod pkcs7; + mod rsa; + mod sha; + mod srtp; + mod ssl; + mod ssl3; + mod tls1; + mod types; + mod x509; + mod x509_vfy; + mod x509v3; + + use std::sync::Once; + // explicitly initialize to work around https://github.com/openssl/openssl/issues/3505 + static INIT: Once = Once::new(); + + // FIXME remove + pub type PasswordCallback = unsafe extern "C" fn( + buf: *mut c_char, + size: c_int, + rwflag: c_int, + user_data: *mut c_void, + ) -> c_int; + + #[cfg(ossl110)] + pub fn init() { + use std::ptr; + + #[cfg(not(ossl111b))] + let init_options = OPENSSL_INIT_LOAD_SSL_STRINGS; + #[cfg(ossl111b)] + let init_options = OPENSSL_INIT_LOAD_SSL_STRINGS | OPENSSL_INIT_NO_ATEXIT; + + INIT.call_once(|| unsafe { + OPENSSL_init_ssl(init_options, ptr::null_mut()); + }) + } + + #[cfg(not(ossl110))] + pub fn init() { + use std::io::{self, Write}; + use std::mem; + use std::process; + use std::sync::{Mutex, MutexGuard}; + + static mut MUTEXES: *mut Vec> = 0 as *mut Vec>; + static mut GUARDS: *mut Vec>> = + 0 as *mut Vec>>; + + unsafe extern "C" fn locking_function( + mode: c_int, + n: c_int, + _file: *const c_char, + _line: c_int, + ) { + let mutex = &(*MUTEXES)[n as usize]; + + if mode & CRYPTO_LOCK != 0 { + (*GUARDS)[n as usize] = Some(mutex.lock().unwrap()); + } else { + if let None = (*GUARDS)[n as usize].take() { + let _ = writeln!( + io::stderr(), + "BUG: rust-openssl lock {} already unlocked, aborting", + n + ); + process::abort(); + } + } + } + + cfg_if! { + if #[cfg(unix)] { + fn set_id_callback() { + unsafe extern "C" fn thread_id() -> c_ulong { + ::libc::pthread_self() as c_ulong + } + + unsafe { + CRYPTO_set_id_callback__fixed_rust(Some(thread_id)); + } + } + } else { + fn set_id_callback() {} + } + } + + INIT.call_once(|| unsafe { + SSL_library_init(); + SSL_load_error_strings(); + OPENSSL_add_all_algorithms_noconf(); + + let num_locks = CRYPTO_num_locks(); + let mut mutexes = Box::new(Vec::new()); + for _ in 0..num_locks { + mutexes.push(Mutex::new(())); + } + MUTEXES = mem::transmute(mutexes); + let guards: Box>>> = + Box::new((0..num_locks).map(|_| None).collect()); + GUARDS = mem::transmute(guards); + + CRYPTO_set_locking_callback__fixed_rust(Some(locking_function)); + set_id_callback(); + }) + } + + /// Disable explicit initialization of the openssl libs. + /// + /// This is only appropriate to use if the openssl crate is being consumed by an application + /// that will be performing the initialization explicitly. + /// + /// # Safety + /// + /// In some versions of openssl, skipping initialization will fall back to the default procedure + /// while other will cause difficult to debug errors so care must be taken when calling this. + pub unsafe fn assume_init() { + INIT.call_once(|| {}); + } +} +#[cfg(openssl)] +pub use openssl::*; diff --git a/vendor/openssl-sys/src/macros.rs b/vendor/openssl-sys/src/macros.rs new file mode 100644 index 0000000..e1c1427 --- /dev/null +++ b/vendor/openssl-sys/src/macros.rs @@ -0,0 +1,280 @@ +#![allow(unused_macros)] + +// vendored from the cfg-if crate to avoid breaking ctest +macro_rules! cfg_if { + // match if/else chains with a final `else` + ($( + if #[cfg($($meta:meta),*)] { $($it:item)* } + ) else * else { + $($it2:item)* + }) => { + cfg_if! { + @__items + () ; + $( ( ($($meta),*) ($($it)*) ), )* + ( () ($($it2)*) ), + } + }; + + // match if/else chains lacking a final `else` + ( + if #[cfg($($i_met:meta),*)] { $($i_it:item)* } + $( + else if #[cfg($($e_met:meta),*)] { $($e_it:item)* } + )* + ) => { + cfg_if! { + @__items + () ; + ( ($($i_met),*) ($($i_it)*) ), + $( ( ($($e_met),*) ($($e_it)*) ), )* + ( () () ), + } + }; + + // 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),*) ($($it:item)*) ), $($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_if! { @__apply cfg(all($($m,)* not(any($($not),*)))), $($it)* } + + // 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. + cfg_if! { @__items ($($not,)* $($m,)*) ; $($rest)* } + }; + + // Internal macro to Apply a cfg attribute to a list of items + (@__apply $m:meta, $($it:item)*) => { + $(#[$m] $it)* + }; +} + +macro_rules! stack { + ($t:ident) => { + cfg_if! { + if #[cfg(any(ossl110, libressl390))] { + pub enum $t {} + } else { + #[repr(C)] + pub struct $t { + pub stack: $crate::_STACK, + } + } + } + }; +} + +// openssl changes `*mut` to `*const` in certain parameters in certain versions; +// in C this is ABI and (mostly) API compatible. +// +// We need to handle this explicitly, and this macro helps annotate which +// parameter got converted in which version. +// +// Input is: +// extern "C" { +// #[attributes...] +// pub fn name(args) -> rettype; // `-> rettype` optional +// // more functions... +// } +// +// This macro replaces `#[const_ptr_if(...)]` in types with `*const` or `*mut` +// (depending on the inner cfg flags) +// +// Walks through all argument and return types, but only finds inner types of +// `*const` and `*mut`; doesn't walk arrays or generics. +// +// NOTE: can't abstract `pub` as `$fn_vis:vis`, as ctest macro handling doesn't +// support it (old syntax crate). But we really only need `pub` anyway. +// +// NOTE: ctest seams to simply ignore macros it can't expand (whatever the +// reason) +macro_rules! const_ptr_api { + // ---------------------------------------------------------------- + // (partialarg): partial argument, waiting for "final" argument type + // MAGIC PART 1: hande conditional const ptr in argument type + ( (partialarg) + { $(#[$fn_attr:meta])* pub fn $fn_name:ident } + $args_packed:tt + [ $($part_arg:tt)* ] + [ #[const_ptr_if( $($cfg:tt)* )] $($arg_rem:tt)* ] + $ret_packed:tt + ) => { + const_ptr_api!( (partialarg) { #[cfg($($cfg)*)] $(#[$fn_attr])* pub fn $fn_name } $args_packed [ $($part_arg)* *const ] [ $($arg_rem)* ] $ret_packed ); + const_ptr_api!( (partialarg) { #[cfg(not($($cfg)*))] $(#[$fn_attr])* pub fn $fn_name } $args_packed [ $($part_arg)* *mut ] [ $($arg_rem)* ] $ret_packed ); + }; + // continue partial argument with `*mut` pointer (might need special const handling in inner type) + ( (partialarg) + $def_packed:tt + $args_packed:tt + [ $($part_arg:tt)* ] + [ *mut $($arg_rem:tt)* ] + $ret_packed:tt + ) => { + const_ptr_api!( (partialarg) $def_packed $args_packed [ $($part_arg)* *mut ] [ $($arg_rem)* ] $ret_packed ); + }; + // continue partial argument with `*const` pointer (might need special const handling in inner type) + ( (partialarg) + $def_packed:tt + $args_packed:tt + [ $($part_arg:tt)* ] + [ *const $($arg_rem:tt)* ] + $ret_packed:tt + ) => { + const_ptr_api!( (partialarg) $def_packed $args_packed [ $($part_arg)* *const ] [ $($arg_rem)* ] $ret_packed ); + }; + // finish partial argument with trailing comma + ( (partialarg) + $def_packed:tt + { $($args_tt:tt)* } + [ $($part_arg:tt)* ] + [ $arg_ty:ty, $($arg_rem:tt)* ] + $ret_packed:tt + ) => { + const_ptr_api!( (parseargs) $def_packed { $($args_tt)* { $($part_arg)* $arg_ty } } [ $($arg_rem)* ] $ret_packed ); + }; + // finish final partial argument (no trailing comma) + ( (partialarg) + $def_packed:tt + { $($args_tt:tt)* } + [ $($part_arg:tt)* ] + [ $arg_ty:ty ] + $ret_packed:tt + ) => { + const_ptr_api!( (parseargs) $def_packed { $($args_tt)* { $($part_arg)* $arg_ty } } [ ] $ret_packed ); + }; + + // ---------------------------------------------------------------- + // (parseargs): parsing arguments + // start next argument + ( (parseargs) + $def_packed:tt + $args_packed:tt + [ $arg_name:ident : $($arg_rem:tt)* ] + $ret_packed:tt + ) => { + const_ptr_api!( (partialarg) $def_packed $args_packed [ $arg_name: ] [ $($arg_rem)* ] $ret_packed ); + }; + // end of arguments, there is a return type; start parsing it + ( (parseargs) + $def_packed:tt + $args_packed:tt + [ ] + [ -> $($rem:tt)* ] + ) => { + const_ptr_api!( (partialret) $def_packed $args_packed [] [ $($rem)* ] ); + }; + // end of arguments, no return type + ( (parseargs) + $def_packed:tt + $args_packed:tt + [ ] + [ ] + ) => { + const_ptr_api!( (generate) $def_packed $args_packed { () } ); + }; + + // ---------------------------------------------------------------- + // (partialret): have partial return type, waiting for final return type + // MAGIC PART 2: hande conditional const ptr in return type + ( (partialret) + { $(#[$fn_attr:meta])* pub fn $fn_name:ident } + $args_packed:tt + [ $($part_ret:tt)* ] + [ #[const_ptr_if( $($cfg:tt)* )] $($rem:tt)* ] + ) => { + const_ptr_api!( (partialret) { #[cfg($($cfg)*)] $(#[$fn_attr])* pub fn $fn_name } $args_packed [ $($part_ret)* *const ] [ $($rem)* ] ); + const_ptr_api!( (partialret) { #[cfg(not($($cfg)*))] $(#[$fn_attr])* pub fn $fn_name } $args_packed [ $($part_ret)* *mut ] [ $($rem)* ] ); + }; + // `* mut` part in return type; continue parsing to find inner conditional const ptr + ( (partialret) + $def_packed:tt + $args_packed:tt + [ $($part_ret:tt)* ] + [ *mut $($rem:tt)* ] + ) => { + const_ptr_api!( (partialret) $def_packed $args_packed [ $($part_ret)* *mut ] [ $($rem)* ] ); + }; + // `* const` part in return type; continue parsing to find inner conditional const ptr + ( (partialret) + $def_packed:tt + $args_packed:tt + [ $($part_ret:tt)* ] + [ *const $($rem:tt)* ] + ) => { + const_ptr_api!( (partialret) $def_packed $args_packed [ $($part_ret)* *const ] [ $($rem)* ] ); + }; + // final part of return type + ( (partialret) + $def_packed:tt + $args_packed:tt + [ $($part_ret:tt)* ] + [ $ret_ty:ty ] + ) => { + const_ptr_api!( (generate) $def_packed $args_packed { $($part_ret)* $ret_ty } ); + }; + + // ---------------------------------------------------------------- + // generate + ( (generate) + { $(#[$fn_attr:meta])* pub fn $fn_name:ident } + { $({ $arg_name:ident: $($arg_ty:tt)* })* } + { $ret_ty:ty } + ) => { + extern "C" { + $(#[$fn_attr])* + pub fn $fn_name( $( + $arg_name: $($arg_ty)* + ),* ) -> $ret_ty; + } + }; + + // ---------------------------------------------------------------- + // (fn): gather tokens for return type until ";" + // found end; start parsing current function, and parse remaining functions + ( (fn) + $def_packed:tt + $arg_tts_packed:tt + $ret_packed:tt + [ ; $($rem:tt)* ] + ) => { + const_ptr_api!( (parseargs) $def_packed {} $arg_tts_packed $ret_packed ); + const_ptr_api!( (extern) [ $($rem)* ] ); + }; + // not ";" - all other tokens are part of the return type. + // don't expand return type yet; otherwise we'd have to remember in which branch `rem` needs + // to be used to parse further functions. + ( (fn) + $def_packed:tt + $arg_tts_packed:tt + [ $($ret_tt:tt)* ] + [ $tt:tt $($rem:tt)* ] + ) => { + const_ptr_api!( (fn) $def_packed $arg_tts_packed [ $($ret_tt)* $tt ] [ $($rem)* ] ); + }; + + // ---------------------------------------------------------------- + // (extern): in extern block, find next function + // try to split into functions as fast as possible to reduce recursion depth + ( (extern) [ + $(#[$fn_attr:meta])* + pub fn $fn_name:ident( $($arg_rem:tt)* ) $($rem:tt)* + ] ) => { + const_ptr_api!( (fn) + { $(#[$fn_attr])* pub fn $fn_name } [ $($arg_rem)* ] [] [ $($rem)* ] + ); + }; + // end of extern block + ( (extern) [] ) => {}; + + // ---------------------------------------------------------------- + // macro start; find extern block + ( extern "C" { $($rem:tt)* } ) => { + const_ptr_api!( (extern) [ $($rem)* ] ); + }; +} diff --git a/vendor/openssl-sys/src/obj_mac.rs b/vendor/openssl-sys/src/obj_mac.rs new file mode 100644 index 0000000..8dd720a --- /dev/null +++ b/vendor/openssl-sys/src/obj_mac.rs @@ -0,0 +1,1023 @@ +use libc::*; + +pub const NID_undef: c_int = 0; +pub const NID_itu_t: c_int = 645; +pub const NID_ccitt: c_int = 404; +pub const NID_iso: c_int = 181; +pub const NID_joint_iso_itu_t: c_int = 646; +pub const NID_joint_iso_ccitt: c_int = 393; +pub const NID_member_body: c_int = 182; +pub const NID_identified_organization: c_int = 676; +pub const NID_hmac_md5: c_int = 780; +pub const NID_hmac_sha1: c_int = 781; +pub const NID_certicom_arc: c_int = 677; +pub const NID_international_organizations: c_int = 647; +pub const NID_wap: c_int = 678; +pub const NID_wap_wsg: c_int = 679; +pub const NID_selected_attribute_types: c_int = 394; +pub const NID_clearance: c_int = 395; +pub const NID_ISO_US: c_int = 183; +pub const NID_X9_57: c_int = 184; +pub const NID_X9cm: c_int = 185; +pub const NID_dsa: c_int = 116; +pub const NID_dsaWithSHA1: c_int = 113; +pub const NID_ansi_X9_62: c_int = 405; +pub const NID_X9_62_prime_field: c_int = 406; +pub const NID_X9_62_characteristic_two_field: c_int = 407; +pub const NID_X9_62_id_characteristic_two_basis: c_int = 680; +pub const NID_X9_62_onBasis: c_int = 681; +pub const NID_X9_62_tpBasis: c_int = 682; +pub const NID_X9_62_ppBasis: c_int = 683; +pub const NID_X9_62_id_ecPublicKey: c_int = 408; +pub const NID_X9_62_c2pnb163v1: c_int = 684; +pub const NID_X9_62_c2pnb163v2: c_int = 685; +pub const NID_X9_62_c2pnb163v3: c_int = 686; +pub const NID_X9_62_c2pnb176v1: c_int = 687; +pub const NID_X9_62_c2tnb191v1: c_int = 688; +pub const NID_X9_62_c2tnb191v2: c_int = 689; +pub const NID_X9_62_c2tnb191v3: c_int = 690; +pub const NID_X9_62_c2onb191v4: c_int = 691; +pub const NID_X9_62_c2onb191v5: c_int = 692; +pub const NID_X9_62_c2pnb208w1: c_int = 693; +pub const NID_X9_62_c2tnb239v1: c_int = 694; +pub const NID_X9_62_c2tnb239v2: c_int = 695; +pub const NID_X9_62_c2tnb239v3: c_int = 696; +pub const NID_X9_62_c2onb239v4: c_int = 697; +pub const NID_X9_62_c2onb239v5: c_int = 698; +pub const NID_X9_62_c2pnb272w1: c_int = 699; +pub const NID_X9_62_c2pnb304w1: c_int = 700; +pub const NID_X9_62_c2tnb359v1: c_int = 701; +pub const NID_X9_62_c2pnb368w1: c_int = 702; +pub const NID_X9_62_c2tnb431r1: c_int = 703; +pub const NID_X9_62_prime192v1: c_int = 409; +pub const NID_X9_62_prime192v2: c_int = 410; +pub const NID_X9_62_prime192v3: c_int = 411; +pub const NID_X9_62_prime239v1: c_int = 412; +pub const NID_X9_62_prime239v2: c_int = 413; +pub const NID_X9_62_prime239v3: c_int = 414; +pub const NID_X9_62_prime256v1: c_int = 415; +pub const NID_ecdsa_with_SHA1: c_int = 416; +pub const NID_ecdsa_with_Recommended: c_int = 791; +pub const NID_ecdsa_with_Specified: c_int = 792; +pub const NID_ecdsa_with_SHA224: c_int = 793; +pub const NID_ecdsa_with_SHA256: c_int = 794; +pub const NID_ecdsa_with_SHA384: c_int = 795; +pub const NID_ecdsa_with_SHA512: c_int = 796; +pub const NID_secp112r1: c_int = 704; +pub const NID_secp112r2: c_int = 705; +pub const NID_secp128r1: c_int = 706; +pub const NID_secp128r2: c_int = 707; +pub const NID_secp160k1: c_int = 708; +pub const NID_secp160r1: c_int = 709; +pub const NID_secp160r2: c_int = 710; +pub const NID_secp192k1: c_int = 711; +pub const NID_secp224k1: c_int = 712; +pub const NID_secp224r1: c_int = 713; +pub const NID_secp256k1: c_int = 714; +pub const NID_secp384r1: c_int = 715; +pub const NID_secp521r1: c_int = 716; +pub const NID_sect113r1: c_int = 717; +pub const NID_sect113r2: c_int = 718; +pub const NID_sect131r1: c_int = 719; +pub const NID_sect131r2: c_int = 720; +pub const NID_sect163k1: c_int = 721; +pub const NID_sect163r1: c_int = 722; +pub const NID_sect163r2: c_int = 723; +pub const NID_sect193r1: c_int = 724; +pub const NID_sect193r2: c_int = 725; +pub const NID_sect233k1: c_int = 726; +pub const NID_sect233r1: c_int = 727; +pub const NID_sect239k1: c_int = 728; +pub const NID_sect283k1: c_int = 729; +pub const NID_sect283r1: c_int = 730; +pub const NID_sect409k1: c_int = 731; +pub const NID_sect409r1: c_int = 732; +pub const NID_sect571k1: c_int = 733; +pub const NID_sect571r1: c_int = 734; + +#[cfg(ossl110)] +pub const NID_brainpoolP256r1: c_int = 927; +#[cfg(libressl)] +pub const NID_brainpoolP256r1: c_int = 928; + +#[cfg(ossl110)] +pub const NID_brainpoolP320r1: c_int = 929; +#[cfg(libressl)] +pub const NID_brainpoolP320r1: c_int = 930; + +#[cfg(ossl110)] +pub const NID_brainpoolP384r1: c_int = 931; +#[cfg(libressl)] +pub const NID_brainpoolP384r1: c_int = 932; + +#[cfg(ossl110)] +pub const NID_brainpoolP512r1: c_int = 933; +#[cfg(libressl)] +pub const NID_brainpoolP512r1: c_int = 934; + +pub const NID_wap_wsg_idm_ecid_wtls1: c_int = 735; +pub const NID_wap_wsg_idm_ecid_wtls3: c_int = 736; +pub const NID_wap_wsg_idm_ecid_wtls4: c_int = 737; +pub const NID_wap_wsg_idm_ecid_wtls5: c_int = 738; +pub const NID_wap_wsg_idm_ecid_wtls6: c_int = 739; +pub const NID_wap_wsg_idm_ecid_wtls7: c_int = 740; +pub const NID_wap_wsg_idm_ecid_wtls8: c_int = 741; +pub const NID_wap_wsg_idm_ecid_wtls9: c_int = 742; +pub const NID_wap_wsg_idm_ecid_wtls10: c_int = 743; +pub const NID_wap_wsg_idm_ecid_wtls11: c_int = 744; +pub const NID_wap_wsg_idm_ecid_wtls12: c_int = 745; +pub const NID_cast5_cbc: c_int = 108; +pub const NID_cast5_ecb: c_int = 109; +pub const NID_cast5_cfb64: c_int = 110; +pub const NID_cast5_ofb64: c_int = 111; +pub const NID_pbeWithMD5AndCast5_CBC: c_int = 112; +pub const NID_id_PasswordBasedMAC: c_int = 782; +pub const NID_id_DHBasedMac: c_int = 783; +pub const NID_rsadsi: c_int = 1; +pub const NID_pkcs: c_int = 2; +pub const NID_pkcs1: c_int = 186; +pub const NID_rsaEncryption: c_int = 6; +pub const NID_md2WithRSAEncryption: c_int = 7; +pub const NID_md4WithRSAEncryption: c_int = 396; +pub const NID_md5WithRSAEncryption: c_int = 8; +pub const NID_sha1WithRSAEncryption: c_int = 65; +pub const NID_rsaesOaep: c_int = 919; +pub const NID_mgf1: c_int = 911; +pub const NID_rsassaPss: c_int = 912; +pub const NID_sha256WithRSAEncryption: c_int = 668; +pub const NID_sha384WithRSAEncryption: c_int = 669; +pub const NID_sha512WithRSAEncryption: c_int = 670; +pub const NID_sha224WithRSAEncryption: c_int = 671; +pub const NID_pkcs3: c_int = 27; +pub const NID_dhKeyAgreement: c_int = 28; +#[cfg(ossl110)] +pub const NID_dhpublicnumber: c_int = 920; +pub const NID_pkcs5: c_int = 187; +pub const NID_pbeWithMD2AndDES_CBC: c_int = 9; +pub const NID_pbeWithMD5AndDES_CBC: c_int = 10; +pub const NID_pbeWithMD2AndRC2_CBC: c_int = 168; +pub const NID_pbeWithMD5AndRC2_CBC: c_int = 169; +pub const NID_pbeWithSHA1AndDES_CBC: c_int = 170; +pub const NID_pbeWithSHA1AndRC2_CBC: c_int = 68; +pub const NID_id_pbkdf2: c_int = 69; +pub const NID_pbes2: c_int = 161; +pub const NID_pbmac1: c_int = 162; +pub const NID_pkcs7: c_int = 20; +pub const NID_pkcs7_data: c_int = 21; +pub const NID_pkcs7_signed: c_int = 22; +pub const NID_pkcs7_enveloped: c_int = 23; +pub const NID_pkcs7_signedAndEnveloped: c_int = 24; +pub const NID_pkcs7_digest: c_int = 25; +pub const NID_pkcs7_encrypted: c_int = 26; +pub const NID_pkcs9: c_int = 47; +pub const NID_pkcs9_emailAddress: c_int = 48; +pub const NID_pkcs9_unstructuredName: c_int = 49; +pub const NID_pkcs9_contentType: c_int = 50; +pub const NID_pkcs9_messageDigest: c_int = 51; +pub const NID_pkcs9_signingTime: c_int = 52; +pub const NID_pkcs9_countersignature: c_int = 53; +pub const NID_pkcs9_challengePassword: c_int = 54; +pub const NID_pkcs9_unstructuredAddress: c_int = 55; +pub const NID_pkcs9_extCertAttributes: c_int = 56; +pub const NID_ext_req: c_int = 172; +pub const NID_SMIMECapabilities: c_int = 167; +pub const NID_SMIME: c_int = 188; +pub const NID_id_smime_mod: c_int = 189; +pub const NID_id_smime_ct: c_int = 190; +pub const NID_id_smime_aa: c_int = 191; +pub const NID_id_smime_alg: c_int = 192; +pub const NID_id_smime_cd: c_int = 193; +pub const NID_id_smime_spq: c_int = 194; +pub const NID_id_smime_cti: c_int = 195; +pub const NID_id_smime_mod_cms: c_int = 196; +pub const NID_id_smime_mod_ess: c_int = 197; +pub const NID_id_smime_mod_oid: c_int = 198; +pub const NID_id_smime_mod_msg_v3: c_int = 199; +pub const NID_id_smime_mod_ets_eSignature_88: c_int = 200; +pub const NID_id_smime_mod_ets_eSignature_97: c_int = 201; +pub const NID_id_smime_mod_ets_eSigPolicy_88: c_int = 202; +pub const NID_id_smime_mod_ets_eSigPolicy_97: c_int = 203; +pub const NID_id_smime_ct_receipt: c_int = 204; +pub const NID_id_smime_ct_authData: c_int = 205; +pub const NID_id_smime_ct_publishCert: c_int = 206; +pub const NID_id_smime_ct_TSTInfo: c_int = 207; +pub const NID_id_smime_ct_TDTInfo: c_int = 208; +pub const NID_id_smime_ct_contentInfo: c_int = 209; +pub const NID_id_smime_ct_DVCSRequestData: c_int = 210; +pub const NID_id_smime_ct_DVCSResponseData: c_int = 211; +pub const NID_id_smime_ct_compressedData: c_int = 786; +pub const NID_id_ct_asciiTextWithCRLF: c_int = 787; +pub const NID_id_smime_aa_receiptRequest: c_int = 212; +pub const NID_id_smime_aa_securityLabel: c_int = 213; +pub const NID_id_smime_aa_mlExpandHistory: c_int = 214; +pub const NID_id_smime_aa_contentHint: c_int = 215; +pub const NID_id_smime_aa_msgSigDigest: c_int = 216; +pub const NID_id_smime_aa_encapContentType: c_int = 217; +pub const NID_id_smime_aa_contentIdentifier: c_int = 218; +pub const NID_id_smime_aa_macValue: c_int = 219; +pub const NID_id_smime_aa_equivalentLabels: c_int = 220; +pub const NID_id_smime_aa_contentReference: c_int = 221; +pub const NID_id_smime_aa_encrypKeyPref: c_int = 222; +pub const NID_id_smime_aa_signingCertificate: c_int = 223; +pub const NID_id_smime_aa_smimeEncryptCerts: c_int = 224; +pub const NID_id_smime_aa_timeStampToken: c_int = 225; +pub const NID_id_smime_aa_ets_sigPolicyId: c_int = 226; +pub const NID_id_smime_aa_ets_commitmentType: c_int = 227; +pub const NID_id_smime_aa_ets_signerLocation: c_int = 228; +pub const NID_id_smime_aa_ets_signerAttr: c_int = 229; +pub const NID_id_smime_aa_ets_otherSigCert: c_int = 230; +pub const NID_id_smime_aa_ets_contentTimestamp: c_int = 231; +pub const NID_id_smime_aa_ets_CertificateRefs: c_int = 232; +pub const NID_id_smime_aa_ets_RevocationRefs: c_int = 233; +pub const NID_id_smime_aa_ets_certValues: c_int = 234; +pub const NID_id_smime_aa_ets_revocationValues: c_int = 235; +pub const NID_id_smime_aa_ets_escTimeStamp: c_int = 236; +pub const NID_id_smime_aa_ets_certCRLTimestamp: c_int = 237; +pub const NID_id_smime_aa_ets_archiveTimeStamp: c_int = 238; +pub const NID_id_smime_aa_signatureType: c_int = 239; +pub const NID_id_smime_aa_dvcs_dvc: c_int = 240; +pub const NID_id_smime_alg_ESDHwith3DES: c_int = 241; +pub const NID_id_smime_alg_ESDHwithRC2: c_int = 242; +pub const NID_id_smime_alg_3DESwrap: c_int = 243; +pub const NID_id_smime_alg_RC2wrap: c_int = 244; +pub const NID_id_smime_alg_ESDH: c_int = 245; +pub const NID_id_smime_alg_CMS3DESwrap: c_int = 246; +pub const NID_id_smime_alg_CMSRC2wrap: c_int = 247; +pub const NID_id_alg_PWRI_KEK: c_int = 893; +pub const NID_id_smime_cd_ldap: c_int = 248; +pub const NID_id_smime_spq_ets_sqt_uri: c_int = 249; +pub const NID_id_smime_spq_ets_sqt_unotice: c_int = 250; +pub const NID_id_smime_cti_ets_proofOfOrigin: c_int = 251; +pub const NID_id_smime_cti_ets_proofOfReceipt: c_int = 252; +pub const NID_id_smime_cti_ets_proofOfDelivery: c_int = 253; +pub const NID_id_smime_cti_ets_proofOfSender: c_int = 254; +pub const NID_id_smime_cti_ets_proofOfApproval: c_int = 255; +pub const NID_id_smime_cti_ets_proofOfCreation: c_int = 256; +pub const NID_friendlyName: c_int = 156; +pub const NID_localKeyID: c_int = 157; +pub const NID_ms_csp_name: c_int = 417; +pub const NID_LocalKeySet: c_int = 856; +pub const NID_x509Certificate: c_int = 158; +pub const NID_sdsiCertificate: c_int = 159; +pub const NID_x509Crl: c_int = 160; +pub const NID_pbe_WithSHA1And128BitRC4: c_int = 144; +pub const NID_pbe_WithSHA1And40BitRC4: c_int = 145; +pub const NID_pbe_WithSHA1And3_Key_TripleDES_CBC: c_int = 146; +pub const NID_pbe_WithSHA1And2_Key_TripleDES_CBC: c_int = 147; +pub const NID_pbe_WithSHA1And128BitRC2_CBC: c_int = 148; +pub const NID_pbe_WithSHA1And40BitRC2_CBC: c_int = 149; +pub const NID_keyBag: c_int = 150; +pub const NID_pkcs8ShroudedKeyBag: c_int = 151; +pub const NID_certBag: c_int = 152; +pub const NID_crlBag: c_int = 153; +pub const NID_secretBag: c_int = 154; +pub const NID_safeContentsBag: c_int = 155; +pub const NID_md2: c_int = 3; +pub const NID_md4: c_int = 257; +pub const NID_md5: c_int = 4; +pub const NID_md5_sha1: c_int = 114; +pub const NID_hmacWithMD5: c_int = 797; +pub const NID_hmacWithSHA1: c_int = 163; +pub const NID_hmacWithSHA224: c_int = 798; +pub const NID_hmacWithSHA256: c_int = 799; +pub const NID_hmacWithSHA384: c_int = 800; +pub const NID_hmacWithSHA512: c_int = 801; +pub const NID_rc2_cbc: c_int = 37; +pub const NID_rc2_ecb: c_int = 38; +pub const NID_rc2_cfb64: c_int = 39; +pub const NID_rc2_ofb64: c_int = 40; +pub const NID_rc2_40_cbc: c_int = 98; +pub const NID_rc2_64_cbc: c_int = 166; +pub const NID_rc4: c_int = 5; +pub const NID_rc4_40: c_int = 97; +pub const NID_des_ede3_cbc: c_int = 44; +pub const NID_rc5_cbc: c_int = 120; +pub const NID_rc5_ecb: c_int = 121; +pub const NID_rc5_cfb64: c_int = 122; +pub const NID_rc5_ofb64: c_int = 123; +pub const NID_ms_ext_req: c_int = 171; +pub const NID_ms_code_ind: c_int = 134; +pub const NID_ms_code_com: c_int = 135; +pub const NID_ms_ctl_sign: c_int = 136; +pub const NID_ms_sgc: c_int = 137; +pub const NID_ms_efs: c_int = 138; +pub const NID_ms_smartcard_login: c_int = 648; +pub const NID_ms_upn: c_int = 649; +pub const NID_idea_cbc: c_int = 34; +pub const NID_idea_ecb: c_int = 36; +pub const NID_idea_cfb64: c_int = 35; +pub const NID_idea_ofb64: c_int = 46; +pub const NID_bf_cbc: c_int = 91; +pub const NID_bf_ecb: c_int = 92; +pub const NID_bf_cfb64: c_int = 93; +pub const NID_bf_ofb64: c_int = 94; +pub const NID_id_pkix: c_int = 127; +pub const NID_id_pkix_mod: c_int = 258; +pub const NID_id_pe: c_int = 175; +pub const NID_id_qt: c_int = 259; +pub const NID_id_kp: c_int = 128; +pub const NID_id_it: c_int = 260; +pub const NID_id_pkip: c_int = 261; +pub const NID_id_alg: c_int = 262; +pub const NID_id_cmc: c_int = 263; +pub const NID_id_on: c_int = 264; +pub const NID_id_pda: c_int = 265; +pub const NID_id_aca: c_int = 266; +pub const NID_id_qcs: c_int = 267; +pub const NID_id_cct: c_int = 268; +pub const NID_id_ppl: c_int = 662; +pub const NID_id_ad: c_int = 176; +pub const NID_id_pkix1_explicit_88: c_int = 269; +pub const NID_id_pkix1_implicit_88: c_int = 270; +pub const NID_id_pkix1_explicit_93: c_int = 271; +pub const NID_id_pkix1_implicit_93: c_int = 272; +pub const NID_id_mod_crmf: c_int = 273; +pub const NID_id_mod_cmc: c_int = 274; +pub const NID_id_mod_kea_profile_88: c_int = 275; +pub const NID_id_mod_kea_profile_93: c_int = 276; +pub const NID_id_mod_cmp: c_int = 277; +pub const NID_id_mod_qualified_cert_88: c_int = 278; +pub const NID_id_mod_qualified_cert_93: c_int = 279; +pub const NID_id_mod_attribute_cert: c_int = 280; +pub const NID_id_mod_timestamp_protocol: c_int = 281; +pub const NID_id_mod_ocsp: c_int = 282; +pub const NID_id_mod_dvcs: c_int = 283; +pub const NID_id_mod_cmp2000: c_int = 284; +pub const NID_info_access: c_int = 177; +pub const NID_biometricInfo: c_int = 285; +pub const NID_qcStatements: c_int = 286; +pub const NID_ac_targeting: c_int = 288; +pub const NID_aaControls: c_int = 289; +pub const NID_sbgp_ipAddrBlock: c_int = 290; +pub const NID_sbgp_autonomousSysNum: c_int = 291; +pub const NID_sbgp_routerIdentifier: c_int = 292; +pub const NID_ac_proxying: c_int = 397; +pub const NID_sinfo_access: c_int = 398; +pub const NID_proxyCertInfo: c_int = 663; +pub const NID_id_qt_cps: c_int = 164; +pub const NID_id_qt_unotice: c_int = 165; +pub const NID_textNotice: c_int = 293; +pub const NID_server_auth: c_int = 129; +pub const NID_client_auth: c_int = 130; +pub const NID_code_sign: c_int = 131; +pub const NID_email_protect: c_int = 132; +pub const NID_ipsecEndSystem: c_int = 294; +pub const NID_ipsecTunnel: c_int = 295; +pub const NID_ipsecUser: c_int = 296; +pub const NID_time_stamp: c_int = 133; +pub const NID_OCSP_sign: c_int = 180; +pub const NID_dvcs: c_int = 297; +pub const NID_id_it_caProtEncCert: c_int = 298; +pub const NID_id_it_signKeyPairTypes: c_int = 299; +pub const NID_id_it_encKeyPairTypes: c_int = 300; +pub const NID_id_it_preferredSymmAlg: c_int = 301; +pub const NID_id_it_caKeyUpdateInfo: c_int = 302; +pub const NID_id_it_currentCRL: c_int = 303; +pub const NID_id_it_unsupportedOIDs: c_int = 304; +pub const NID_id_it_subscriptionRequest: c_int = 305; +pub const NID_id_it_subscriptionResponse: c_int = 306; +pub const NID_id_it_keyPairParamReq: c_int = 307; +pub const NID_id_it_keyPairParamRep: c_int = 308; +pub const NID_id_it_revPassphrase: c_int = 309; +pub const NID_id_it_implicitConfirm: c_int = 310; +pub const NID_id_it_confirmWaitTime: c_int = 311; +pub const NID_id_it_origPKIMessage: c_int = 312; +pub const NID_id_it_suppLangTags: c_int = 784; +pub const NID_id_regCtrl: c_int = 313; +pub const NID_id_regInfo: c_int = 314; +pub const NID_id_regCtrl_regToken: c_int = 315; +pub const NID_id_regCtrl_authenticator: c_int = 316; +pub const NID_id_regCtrl_pkiPublicationInfo: c_int = 317; +pub const NID_id_regCtrl_pkiArchiveOptions: c_int = 318; +pub const NID_id_regCtrl_oldCertID: c_int = 319; +pub const NID_id_regCtrl_protocolEncrKey: c_int = 320; +pub const NID_id_regInfo_utf8Pairs: c_int = 321; +pub const NID_id_regInfo_certReq: c_int = 322; +pub const NID_id_alg_des40: c_int = 323; +pub const NID_id_alg_noSignature: c_int = 324; +pub const NID_id_alg_dh_sig_hmac_sha1: c_int = 325; +pub const NID_id_alg_dh_pop: c_int = 326; +pub const NID_id_cmc_statusInfo: c_int = 327; +pub const NID_id_cmc_identification: c_int = 328; +pub const NID_id_cmc_identityProof: c_int = 329; +pub const NID_id_cmc_dataReturn: c_int = 330; +pub const NID_id_cmc_transactionId: c_int = 331; +pub const NID_id_cmc_senderNonce: c_int = 332; +pub const NID_id_cmc_recipientNonce: c_int = 333; +pub const NID_id_cmc_addExtensions: c_int = 334; +pub const NID_id_cmc_encryptedPOP: c_int = 335; +pub const NID_id_cmc_decryptedPOP: c_int = 336; +pub const NID_id_cmc_lraPOPWitness: c_int = 337; +pub const NID_id_cmc_getCert: c_int = 338; +pub const NID_id_cmc_getCRL: c_int = 339; +pub const NID_id_cmc_revokeRequest: c_int = 340; +pub const NID_id_cmc_regInfo: c_int = 341; +pub const NID_id_cmc_responseInfo: c_int = 342; +pub const NID_id_cmc_queryPending: c_int = 343; +pub const NID_id_cmc_popLinkRandom: c_int = 344; +pub const NID_id_cmc_popLinkWitness: c_int = 345; +pub const NID_id_cmc_confirmCertAcceptance: c_int = 346; +pub const NID_id_on_personalData: c_int = 347; +pub const NID_id_on_permanentIdentifier: c_int = 858; +pub const NID_id_pda_dateOfBirth: c_int = 348; +pub const NID_id_pda_placeOfBirth: c_int = 349; +pub const NID_id_pda_gender: c_int = 351; +pub const NID_id_pda_countryOfCitizenship: c_int = 352; +pub const NID_id_pda_countryOfResidence: c_int = 353; +pub const NID_id_aca_authenticationInfo: c_int = 354; +pub const NID_id_aca_accessIdentity: c_int = 355; +pub const NID_id_aca_chargingIdentity: c_int = 356; +pub const NID_id_aca_group: c_int = 357; +pub const NID_id_aca_role: c_int = 358; +pub const NID_id_aca_encAttrs: c_int = 399; +pub const NID_id_qcs_pkixQCSyntax_v1: c_int = 359; +pub const NID_id_cct_crs: c_int = 360; +pub const NID_id_cct_PKIData: c_int = 361; +pub const NID_id_cct_PKIResponse: c_int = 362; +pub const NID_id_ppl_anyLanguage: c_int = 664; +pub const NID_id_ppl_inheritAll: c_int = 665; +pub const NID_Independent: c_int = 667; +pub const NID_ad_OCSP: c_int = 178; +pub const NID_ad_ca_issuers: c_int = 179; +pub const NID_ad_timeStamping: c_int = 363; +pub const NID_ad_dvcs: c_int = 364; +pub const NID_caRepository: c_int = 785; +pub const NID_id_pkix_OCSP_basic: c_int = 365; +pub const NID_id_pkix_OCSP_Nonce: c_int = 366; +pub const NID_id_pkix_OCSP_CrlID: c_int = 367; +pub const NID_id_pkix_OCSP_acceptableResponses: c_int = 368; +pub const NID_id_pkix_OCSP_noCheck: c_int = 369; +pub const NID_id_pkix_OCSP_archiveCutoff: c_int = 370; +pub const NID_id_pkix_OCSP_serviceLocator: c_int = 371; +pub const NID_id_pkix_OCSP_extendedStatus: c_int = 372; +pub const NID_id_pkix_OCSP_valid: c_int = 373; +pub const NID_id_pkix_OCSP_path: c_int = 374; +pub const NID_id_pkix_OCSP_trustRoot: c_int = 375; +pub const NID_algorithm: c_int = 376; +pub const NID_md5WithRSA: c_int = 104; +pub const NID_des_ecb: c_int = 29; +pub const NID_des_cbc: c_int = 31; +pub const NID_des_ofb64: c_int = 45; +pub const NID_des_cfb64: c_int = 30; +pub const NID_rsaSignature: c_int = 377; +pub const NID_dsa_2: c_int = 67; +pub const NID_dsaWithSHA: c_int = 66; +pub const NID_shaWithRSAEncryption: c_int = 42; +pub const NID_des_ede_ecb: c_int = 32; +pub const NID_des_ede3_ecb: c_int = 33; +pub const NID_des_ede_cbc: c_int = 43; +pub const NID_des_ede_cfb64: c_int = 60; +pub const NID_des_ede3_cfb64: c_int = 61; +pub const NID_des_ede_ofb64: c_int = 62; +pub const NID_des_ede3_ofb64: c_int = 63; +pub const NID_desx_cbc: c_int = 80; +pub const NID_sha: c_int = 41; +pub const NID_sha1: c_int = 64; +pub const NID_dsaWithSHA1_2: c_int = 70; +pub const NID_sha1WithRSA: c_int = 115; +pub const NID_ripemd160: c_int = 117; +pub const NID_ripemd160WithRSA: c_int = 119; +pub const NID_sxnet: c_int = 143; +pub const NID_X500: c_int = 11; +pub const NID_X509: c_int = 12; +pub const NID_commonName: c_int = 13; +pub const NID_surname: c_int = 100; +pub const NID_serialNumber: c_int = 105; +pub const NID_countryName: c_int = 14; +pub const NID_localityName: c_int = 15; +pub const NID_stateOrProvinceName: c_int = 16; +pub const NID_streetAddress: c_int = 660; +pub const NID_organizationName: c_int = 17; +pub const NID_organizationalUnitName: c_int = 18; +pub const NID_title: c_int = 106; +pub const NID_description: c_int = 107; +pub const NID_searchGuide: c_int = 859; +pub const NID_businessCategory: c_int = 860; +pub const NID_postalAddress: c_int = 861; +pub const NID_postalCode: c_int = 661; +pub const NID_postOfficeBox: c_int = 862; +pub const NID_physicalDeliveryOfficeName: c_int = 863; +pub const NID_telephoneNumber: c_int = 864; +pub const NID_telexNumber: c_int = 865; +pub const NID_teletexTerminalIdentifier: c_int = 866; +pub const NID_facsimileTelephoneNumber: c_int = 867; +pub const NID_x121Address: c_int = 868; +pub const NID_internationaliSDNNumber: c_int = 869; +pub const NID_registeredAddress: c_int = 870; +pub const NID_destinationIndicator: c_int = 871; +pub const NID_preferredDeliveryMethod: c_int = 872; +pub const NID_presentationAddress: c_int = 873; +pub const NID_supportedApplicationContext: c_int = 874; +pub const NID_member: c_int = 875; +pub const NID_owner: c_int = 876; +pub const NID_roleOccupant: c_int = 877; +pub const NID_seeAlso: c_int = 878; +pub const NID_userPassword: c_int = 879; +pub const NID_userCertificate: c_int = 880; +pub const NID_cACertificate: c_int = 881; +pub const NID_authorityRevocationList: c_int = 882; +pub const NID_certificateRevocationList: c_int = 883; +pub const NID_crossCertificatePair: c_int = 884; +pub const NID_name: c_int = 173; +pub const NID_givenName: c_int = 99; +pub const NID_initials: c_int = 101; +pub const NID_generationQualifier: c_int = 509; +pub const NID_x500UniqueIdentifier: c_int = 503; +pub const NID_dnQualifier: c_int = 174; +pub const NID_enhancedSearchGuide: c_int = 885; +pub const NID_protocolInformation: c_int = 886; +pub const NID_distinguishedName: c_int = 887; +pub const NID_uniqueMember: c_int = 888; +pub const NID_houseIdentifier: c_int = 889; +pub const NID_supportedAlgorithms: c_int = 890; +pub const NID_deltaRevocationList: c_int = 891; +pub const NID_dmdName: c_int = 892; +pub const NID_pseudonym: c_int = 510; +pub const NID_role: c_int = 400; +pub const NID_X500algorithms: c_int = 378; +pub const NID_rsa: c_int = 19; +pub const NID_mdc2WithRSA: c_int = 96; +pub const NID_mdc2: c_int = 95; +pub const NID_id_ce: c_int = 81; +pub const NID_subject_directory_attributes: c_int = 769; +pub const NID_subject_key_identifier: c_int = 82; +pub const NID_key_usage: c_int = 83; +pub const NID_private_key_usage_period: c_int = 84; +pub const NID_subject_alt_name: c_int = 85; +pub const NID_issuer_alt_name: c_int = 86; +pub const NID_basic_constraints: c_int = 87; +pub const NID_crl_number: c_int = 88; +pub const NID_crl_reason: c_int = 141; +pub const NID_invalidity_date: c_int = 142; +pub const NID_delta_crl: c_int = 140; +pub const NID_issuing_distribution_point: c_int = 770; +pub const NID_certificate_issuer: c_int = 771; +pub const NID_name_constraints: c_int = 666; +pub const NID_crl_distribution_points: c_int = 103; +pub const NID_certificate_policies: c_int = 89; +pub const NID_any_policy: c_int = 746; +pub const NID_policy_mappings: c_int = 747; +pub const NID_authority_key_identifier: c_int = 90; +pub const NID_policy_constraints: c_int = 401; +pub const NID_ext_key_usage: c_int = 126; +pub const NID_freshest_crl: c_int = 857; +pub const NID_inhibit_any_policy: c_int = 748; +pub const NID_target_information: c_int = 402; +pub const NID_no_rev_avail: c_int = 403; +pub const NID_anyExtendedKeyUsage: c_int = 910; +pub const NID_netscape: c_int = 57; +pub const NID_netscape_cert_extension: c_int = 58; +pub const NID_netscape_data_type: c_int = 59; +pub const NID_netscape_cert_type: c_int = 71; +pub const NID_netscape_base_url: c_int = 72; +pub const NID_netscape_revocation_url: c_int = 73; +pub const NID_netscape_ca_revocation_url: c_int = 74; +pub const NID_netscape_renewal_url: c_int = 75; +pub const NID_netscape_ca_policy_url: c_int = 76; +pub const NID_netscape_ssl_server_name: c_int = 77; +pub const NID_netscape_comment: c_int = 78; +pub const NID_netscape_cert_sequence: c_int = 79; +pub const NID_ns_sgc: c_int = 139; +pub const NID_org: c_int = 379; +pub const NID_dod: c_int = 380; +pub const NID_iana: c_int = 381; +pub const NID_Directory: c_int = 382; +pub const NID_Management: c_int = 383; +pub const NID_Experimental: c_int = 384; +pub const NID_Private: c_int = 385; +pub const NID_Security: c_int = 386; +pub const NID_SNMPv2: c_int = 387; +pub const NID_Mail: c_int = 388; +pub const NID_Enterprises: c_int = 389; +pub const NID_dcObject: c_int = 390; +pub const NID_mime_mhs: c_int = 504; +pub const NID_mime_mhs_headings: c_int = 505; +pub const NID_mime_mhs_bodies: c_int = 506; +pub const NID_id_hex_partial_message: c_int = 507; +pub const NID_id_hex_multipart_message: c_int = 508; +pub const NID_zlib_compression: c_int = 125; +pub const NID_aes_128_ecb: c_int = 418; +pub const NID_aes_128_cbc: c_int = 419; +pub const NID_aes_128_ofb128: c_int = 420; +pub const NID_aes_128_cfb128: c_int = 421; +pub const NID_id_aes128_wrap: c_int = 788; +pub const NID_aes_128_gcm: c_int = 895; +pub const NID_aes_128_ccm: c_int = 896; +pub const NID_id_aes128_wrap_pad: c_int = 897; +pub const NID_aes_192_ecb: c_int = 422; +pub const NID_aes_192_cbc: c_int = 423; +pub const NID_aes_192_ofb128: c_int = 424; +pub const NID_aes_192_cfb128: c_int = 425; +pub const NID_id_aes192_wrap: c_int = 789; +pub const NID_aes_192_gcm: c_int = 898; +pub const NID_aes_192_ccm: c_int = 899; +pub const NID_id_aes192_wrap_pad: c_int = 900; +pub const NID_aes_256_ecb: c_int = 426; +pub const NID_aes_256_cbc: c_int = 427; +pub const NID_aes_256_ofb128: c_int = 428; +pub const NID_aes_256_cfb128: c_int = 429; +pub const NID_id_aes256_wrap: c_int = 790; +pub const NID_aes_256_gcm: c_int = 901; +pub const NID_aes_256_ccm: c_int = 902; +pub const NID_id_aes256_wrap_pad: c_int = 903; +pub const NID_aes_128_cfb1: c_int = 650; +pub const NID_aes_192_cfb1: c_int = 651; +pub const NID_aes_256_cfb1: c_int = 652; +pub const NID_aes_128_cfb8: c_int = 653; +pub const NID_aes_192_cfb8: c_int = 654; +pub const NID_aes_256_cfb8: c_int = 655; +pub const NID_aes_128_ctr: c_int = 904; +pub const NID_aes_192_ctr: c_int = 905; +pub const NID_aes_256_ctr: c_int = 906; +pub const NID_aes_128_xts: c_int = 913; +pub const NID_aes_256_xts: c_int = 914; +pub const NID_des_cfb1: c_int = 656; +pub const NID_des_cfb8: c_int = 657; +pub const NID_des_ede3_cfb1: c_int = 658; +pub const NID_des_ede3_cfb8: c_int = 659; +pub const NID_sha256: c_int = 672; +pub const NID_sha384: c_int = 673; +pub const NID_sha512: c_int = 674; +pub const NID_sha224: c_int = 675; +pub const NID_dsa_with_SHA224: c_int = 802; +pub const NID_dsa_with_SHA256: c_int = 803; +pub const NID_hold_instruction_code: c_int = 430; +pub const NID_hold_instruction_none: c_int = 431; +pub const NID_hold_instruction_call_issuer: c_int = 432; +pub const NID_hold_instruction_reject: c_int = 433; +pub const NID_data: c_int = 434; +pub const NID_pss: c_int = 435; +pub const NID_ucl: c_int = 436; +pub const NID_pilot: c_int = 437; +pub const NID_pilotAttributeType: c_int = 438; +pub const NID_pilotAttributeSyntax: c_int = 439; +pub const NID_pilotObjectClass: c_int = 440; +pub const NID_pilotGroups: c_int = 441; +pub const NID_iA5StringSyntax: c_int = 442; +pub const NID_caseIgnoreIA5StringSyntax: c_int = 443; +pub const NID_pilotObject: c_int = 444; +pub const NID_pilotPerson: c_int = 445; +pub const NID_account: c_int = 446; +pub const NID_document: c_int = 447; +pub const NID_room: c_int = 448; +pub const NID_documentSeries: c_int = 449; +pub const NID_Domain: c_int = 392; +pub const NID_rFC822localPart: c_int = 450; +pub const NID_dNSDomain: c_int = 451; +pub const NID_domainRelatedObject: c_int = 452; +pub const NID_friendlyCountry: c_int = 453; +pub const NID_simpleSecurityObject: c_int = 454; +pub const NID_pilotOrganization: c_int = 455; +pub const NID_pilotDSA: c_int = 456; +pub const NID_qualityLabelledData: c_int = 457; +pub const NID_userId: c_int = 458; +pub const NID_textEncodedORAddress: c_int = 459; +pub const NID_rfc822Mailbox: c_int = 460; +pub const NID_info: c_int = 461; +pub const NID_favouriteDrink: c_int = 462; +pub const NID_roomNumber: c_int = 463; +pub const NID_photo: c_int = 464; +pub const NID_userClass: c_int = 465; +pub const NID_host: c_int = 466; +pub const NID_manager: c_int = 467; +pub const NID_documentIdentifier: c_int = 468; +pub const NID_documentTitle: c_int = 469; +pub const NID_documentVersion: c_int = 470; +pub const NID_documentAuthor: c_int = 471; +pub const NID_documentLocation: c_int = 472; +pub const NID_homeTelephoneNumber: c_int = 473; +pub const NID_secretary: c_int = 474; +pub const NID_otherMailbox: c_int = 475; +pub const NID_lastModifiedTime: c_int = 476; +pub const NID_lastModifiedBy: c_int = 477; +pub const NID_domainComponent: c_int = 391; +pub const NID_aRecord: c_int = 478; +pub const NID_pilotAttributeType27: c_int = 479; +pub const NID_mXRecord: c_int = 480; +pub const NID_nSRecord: c_int = 481; +pub const NID_sOARecord: c_int = 482; +pub const NID_cNAMERecord: c_int = 483; +pub const NID_associatedDomain: c_int = 484; +pub const NID_associatedName: c_int = 485; +pub const NID_homePostalAddress: c_int = 486; +pub const NID_personalTitle: c_int = 487; +pub const NID_mobileTelephoneNumber: c_int = 488; +pub const NID_pagerTelephoneNumber: c_int = 489; +pub const NID_friendlyCountryName: c_int = 490; +pub const NID_organizationalStatus: c_int = 491; +pub const NID_janetMailbox: c_int = 492; +pub const NID_mailPreferenceOption: c_int = 493; +pub const NID_buildingName: c_int = 494; +pub const NID_dSAQuality: c_int = 495; +pub const NID_singleLevelQuality: c_int = 496; +pub const NID_subtreeMinimumQuality: c_int = 497; +pub const NID_subtreeMaximumQuality: c_int = 498; +pub const NID_personalSignature: c_int = 499; +pub const NID_dITRedirect: c_int = 500; +pub const NID_audio: c_int = 501; +pub const NID_documentPublisher: c_int = 502; +pub const NID_id_set: c_int = 512; +pub const NID_set_ctype: c_int = 513; +pub const NID_set_msgExt: c_int = 514; +pub const NID_set_attr: c_int = 515; +pub const NID_set_policy: c_int = 516; +pub const NID_set_certExt: c_int = 517; +pub const NID_set_brand: c_int = 518; +pub const NID_setct_PANData: c_int = 519; +pub const NID_setct_PANToken: c_int = 520; +pub const NID_setct_PANOnly: c_int = 521; +pub const NID_setct_OIData: c_int = 522; +pub const NID_setct_PI: c_int = 523; +pub const NID_setct_PIData: c_int = 524; +pub const NID_setct_PIDataUnsigned: c_int = 525; +pub const NID_setct_HODInput: c_int = 526; +pub const NID_setct_AuthResBaggage: c_int = 527; +pub const NID_setct_AuthRevReqBaggage: c_int = 528; +pub const NID_setct_AuthRevResBaggage: c_int = 529; +pub const NID_setct_CapTokenSeq: c_int = 530; +pub const NID_setct_PInitResData: c_int = 531; +pub const NID_setct_PI_TBS: c_int = 532; +pub const NID_setct_PResData: c_int = 533; +pub const NID_setct_AuthReqTBS: c_int = 534; +pub const NID_setct_AuthResTBS: c_int = 535; +pub const NID_setct_AuthResTBSX: c_int = 536; +pub const NID_setct_AuthTokenTBS: c_int = 537; +pub const NID_setct_CapTokenData: c_int = 538; +pub const NID_setct_CapTokenTBS: c_int = 539; +pub const NID_setct_AcqCardCodeMsg: c_int = 540; +pub const NID_setct_AuthRevReqTBS: c_int = 541; +pub const NID_setct_AuthRevResData: c_int = 542; +pub const NID_setct_AuthRevResTBS: c_int = 543; +pub const NID_setct_CapReqTBS: c_int = 544; +pub const NID_setct_CapReqTBSX: c_int = 545; +pub const NID_setct_CapResData: c_int = 546; +pub const NID_setct_CapRevReqTBS: c_int = 547; +pub const NID_setct_CapRevReqTBSX: c_int = 548; +pub const NID_setct_CapRevResData: c_int = 549; +pub const NID_setct_CredReqTBS: c_int = 550; +pub const NID_setct_CredReqTBSX: c_int = 551; +pub const NID_setct_CredResData: c_int = 552; +pub const NID_setct_CredRevReqTBS: c_int = 553; +pub const NID_setct_CredRevReqTBSX: c_int = 554; +pub const NID_setct_CredRevResData: c_int = 555; +pub const NID_setct_PCertReqData: c_int = 556; +pub const NID_setct_PCertResTBS: c_int = 557; +pub const NID_setct_BatchAdminReqData: c_int = 558; +pub const NID_setct_BatchAdminResData: c_int = 559; +pub const NID_setct_CardCInitResTBS: c_int = 560; +pub const NID_setct_MeAqCInitResTBS: c_int = 561; +pub const NID_setct_RegFormResTBS: c_int = 562; +pub const NID_setct_CertReqData: c_int = 563; +pub const NID_setct_CertReqTBS: c_int = 564; +pub const NID_setct_CertResData: c_int = 565; +pub const NID_setct_CertInqReqTBS: c_int = 566; +pub const NID_setct_ErrorTBS: c_int = 567; +pub const NID_setct_PIDualSignedTBE: c_int = 568; +pub const NID_setct_PIUnsignedTBE: c_int = 569; +pub const NID_setct_AuthReqTBE: c_int = 570; +pub const NID_setct_AuthResTBE: c_int = 571; +pub const NID_setct_AuthResTBEX: c_int = 572; +pub const NID_setct_AuthTokenTBE: c_int = 573; +pub const NID_setct_CapTokenTBE: c_int = 574; +pub const NID_setct_CapTokenTBEX: c_int = 575; +pub const NID_setct_AcqCardCodeMsgTBE: c_int = 576; +pub const NID_setct_AuthRevReqTBE: c_int = 577; +pub const NID_setct_AuthRevResTBE: c_int = 578; +pub const NID_setct_AuthRevResTBEB: c_int = 579; +pub const NID_setct_CapReqTBE: c_int = 580; +pub const NID_setct_CapReqTBEX: c_int = 581; +pub const NID_setct_CapResTBE: c_int = 582; +pub const NID_setct_CapRevReqTBE: c_int = 583; +pub const NID_setct_CapRevReqTBEX: c_int = 584; +pub const NID_setct_CapRevResTBE: c_int = 585; +pub const NID_setct_CredReqTBE: c_int = 586; +pub const NID_setct_CredReqTBEX: c_int = 587; +pub const NID_setct_CredResTBE: c_int = 588; +pub const NID_setct_CredRevReqTBE: c_int = 589; +pub const NID_setct_CredRevReqTBEX: c_int = 590; +pub const NID_setct_CredRevResTBE: c_int = 591; +pub const NID_setct_BatchAdminReqTBE: c_int = 592; +pub const NID_setct_BatchAdminResTBE: c_int = 593; +pub const NID_setct_RegFormReqTBE: c_int = 594; +pub const NID_setct_CertReqTBE: c_int = 595; +pub const NID_setct_CertReqTBEX: c_int = 596; +pub const NID_setct_CertResTBE: c_int = 597; +pub const NID_setct_CRLNotificationTBS: c_int = 598; +pub const NID_setct_CRLNotificationResTBS: c_int = 599; +pub const NID_setct_BCIDistributionTBS: c_int = 600; +pub const NID_setext_genCrypt: c_int = 601; +pub const NID_setext_miAuth: c_int = 602; +pub const NID_setext_pinSecure: c_int = 603; +pub const NID_setext_pinAny: c_int = 604; +pub const NID_setext_track2: c_int = 605; +pub const NID_setext_cv: c_int = 606; +pub const NID_set_policy_root: c_int = 607; +pub const NID_setCext_hashedRoot: c_int = 608; +pub const NID_setCext_certType: c_int = 609; +pub const NID_setCext_merchData: c_int = 610; +pub const NID_setCext_cCertRequired: c_int = 611; +pub const NID_setCext_tunneling: c_int = 612; +pub const NID_setCext_setExt: c_int = 613; +pub const NID_setCext_setQualf: c_int = 614; +pub const NID_setCext_PGWYcapabilities: c_int = 615; +pub const NID_setCext_TokenIdentifier: c_int = 616; +pub const NID_setCext_Track2Data: c_int = 617; +pub const NID_setCext_TokenType: c_int = 618; +pub const NID_setCext_IssuerCapabilities: c_int = 619; +pub const NID_setAttr_Cert: c_int = 620; +pub const NID_setAttr_PGWYcap: c_int = 621; +pub const NID_setAttr_TokenType: c_int = 622; +pub const NID_setAttr_IssCap: c_int = 623; +pub const NID_set_rootKeyThumb: c_int = 624; +pub const NID_set_addPolicy: c_int = 625; +pub const NID_setAttr_Token_EMV: c_int = 626; +pub const NID_setAttr_Token_B0Prime: c_int = 627; +pub const NID_setAttr_IssCap_CVM: c_int = 628; +pub const NID_setAttr_IssCap_T2: c_int = 629; +pub const NID_setAttr_IssCap_Sig: c_int = 630; +pub const NID_setAttr_GenCryptgrm: c_int = 631; +pub const NID_setAttr_T2Enc: c_int = 632; +pub const NID_setAttr_T2cleartxt: c_int = 633; +pub const NID_setAttr_TokICCsig: c_int = 634; +pub const NID_setAttr_SecDevSig: c_int = 635; +pub const NID_set_brand_IATA_ATA: c_int = 636; +pub const NID_set_brand_Diners: c_int = 637; +pub const NID_set_brand_AmericanExpress: c_int = 638; +pub const NID_set_brand_JCB: c_int = 639; +pub const NID_set_brand_Visa: c_int = 640; +pub const NID_set_brand_MasterCard: c_int = 641; +pub const NID_set_brand_Novus: c_int = 642; +pub const NID_des_cdmf: c_int = 643; +pub const NID_rsaOAEPEncryptionSET: c_int = 644; +pub const NID_ipsec3: c_int = 749; +pub const NID_ipsec4: c_int = 750; +pub const NID_whirlpool: c_int = 804; +pub const NID_cryptopro: c_int = 805; +pub const NID_cryptocom: c_int = 806; +pub const NID_id_GostR3411_94_with_GostR3410_2001: c_int = 807; +pub const NID_id_GostR3411_94_with_GostR3410_94: c_int = 808; +pub const NID_id_GostR3411_94: c_int = 809; +pub const NID_id_HMACGostR3411_94: c_int = 810; +pub const NID_id_GostR3410_2001: c_int = 811; +pub const NID_id_GostR3410_94: c_int = 812; +pub const NID_id_Gost28147_89: c_int = 813; +pub const NID_gost89_cnt: c_int = 814; +pub const NID_id_Gost28147_89_MAC: c_int = 815; +pub const NID_id_GostR3411_94_prf: c_int = 816; +pub const NID_id_GostR3410_2001DH: c_int = 817; +pub const NID_id_GostR3410_94DH: c_int = 818; +pub const NID_id_Gost28147_89_CryptoPro_KeyMeshing: c_int = 819; +pub const NID_id_Gost28147_89_None_KeyMeshing: c_int = 820; +pub const NID_id_GostR3411_94_TestParamSet: c_int = 821; +pub const NID_id_GostR3411_94_CryptoProParamSet: c_int = 822; +pub const NID_id_Gost28147_89_TestParamSet: c_int = 823; +pub const NID_id_Gost28147_89_CryptoPro_A_ParamSet: c_int = 824; +pub const NID_id_Gost28147_89_CryptoPro_B_ParamSet: c_int = 825; +pub const NID_id_Gost28147_89_CryptoPro_C_ParamSet: c_int = 826; +pub const NID_id_Gost28147_89_CryptoPro_D_ParamSet: c_int = 827; +pub const NID_id_Gost28147_89_CryptoPro_Oscar_1_1_ParamSet: c_int = 828; +pub const NID_id_Gost28147_89_CryptoPro_Oscar_1_0_ParamSet: c_int = 829; +pub const NID_id_Gost28147_89_CryptoPro_RIC_1_ParamSet: c_int = 830; +pub const NID_id_GostR3410_94_TestParamSet: c_int = 831; +pub const NID_id_GostR3410_94_CryptoPro_A_ParamSet: c_int = 832; +pub const NID_id_GostR3410_94_CryptoPro_B_ParamSet: c_int = 833; +pub const NID_id_GostR3410_94_CryptoPro_C_ParamSet: c_int = 834; +pub const NID_id_GostR3410_94_CryptoPro_D_ParamSet: c_int = 835; +pub const NID_id_GostR3410_94_CryptoPro_XchA_ParamSet: c_int = 836; +pub const NID_id_GostR3410_94_CryptoPro_XchB_ParamSet: c_int = 837; +pub const NID_id_GostR3410_94_CryptoPro_XchC_ParamSet: c_int = 838; +pub const NID_id_GostR3410_2001_TestParamSet: c_int = 839; +pub const NID_id_GostR3410_2001_CryptoPro_A_ParamSet: c_int = 840; +pub const NID_id_GostR3410_2001_CryptoPro_B_ParamSet: c_int = 841; +pub const NID_id_GostR3410_2001_CryptoPro_C_ParamSet: c_int = 842; +pub const NID_id_GostR3410_2001_CryptoPro_XchA_ParamSet: c_int = 843; +pub const NID_id_GostR3410_2001_CryptoPro_XchB_ParamSet: c_int = 844; +pub const NID_id_GostR3410_94_a: c_int = 845; +pub const NID_id_GostR3410_94_aBis: c_int = 846; +pub const NID_id_GostR3410_94_b: c_int = 847; +pub const NID_id_GostR3410_94_bBis: c_int = 848; +pub const NID_id_Gost28147_89_cc: c_int = 849; +pub const NID_id_GostR3410_94_cc: c_int = 850; +pub const NID_id_GostR3410_2001_cc: c_int = 851; +pub const NID_id_GostR3411_94_with_GostR3410_94_cc: c_int = 852; +pub const NID_id_GostR3411_94_with_GostR3410_2001_cc: c_int = 853; +pub const NID_id_GostR3410_2001_ParamSet_cc: c_int = 854; +pub const NID_camellia_128_cbc: c_int = 751; +pub const NID_camellia_192_cbc: c_int = 752; +pub const NID_camellia_256_cbc: c_int = 753; +pub const NID_id_camellia128_wrap: c_int = 907; +pub const NID_id_camellia192_wrap: c_int = 908; +pub const NID_id_camellia256_wrap: c_int = 909; +pub const NID_camellia_128_ecb: c_int = 754; +pub const NID_camellia_128_ofb128: c_int = 766; +pub const NID_camellia_128_cfb128: c_int = 757; +pub const NID_camellia_192_ecb: c_int = 755; +pub const NID_camellia_192_ofb128: c_int = 767; +pub const NID_camellia_192_cfb128: c_int = 758; +pub const NID_camellia_256_ecb: c_int = 756; +pub const NID_camellia_256_ofb128: c_int = 768; +pub const NID_camellia_256_cfb128: c_int = 759; +pub const NID_camellia_128_cfb1: c_int = 760; +pub const NID_camellia_192_cfb1: c_int = 761; +pub const NID_camellia_256_cfb1: c_int = 762; +pub const NID_camellia_128_cfb8: c_int = 763; +pub const NID_camellia_192_cfb8: c_int = 764; +pub const NID_camellia_256_cfb8: c_int = 765; +pub const NID_kisa: c_int = 773; +pub const NID_seed_ecb: c_int = 776; +pub const NID_seed_cbc: c_int = 777; +pub const NID_seed_cfb128: c_int = 779; +pub const NID_seed_ofb128: c_int = 778; +pub const NID_hmac: c_int = 855; +pub const NID_cmac: c_int = 894; +pub const NID_rc4_hmac_md5: c_int = 915; +pub const NID_aes_128_cbc_hmac_sha1: c_int = 916; +pub const NID_aes_192_cbc_hmac_sha1: c_int = 917; +pub const NID_aes_256_cbc_hmac_sha1: c_int = 918; +#[cfg(ossl111)] +pub const NID_X25519: c_int = 1034; +#[cfg(libressl370)] +pub const NID_X25519: c_int = 950; +#[cfg(ossl111)] +pub const NID_X448: c_int = 1035; +#[cfg(ossl110)] +pub const NID_hkdf: c_int = 1036; +#[cfg(libressl360)] +pub const NID_hkdf: c_int = 1022; +#[cfg(ossl111)] +pub const NID_poly1305: c_int = 1061; +#[cfg(ossl111)] +pub const NID_ED25519: c_int = 1087; +#[cfg(libressl370)] +pub const NID_ED25519: c_int = 952; +#[cfg(ossl111)] +pub const NID_ED448: c_int = 1088; +#[cfg(ossl111)] +pub const NID_sm2: c_int = 1172; +#[cfg(ossl111)] +pub const NID_sm3: c_int = 1143; +#[cfg(libressl291)] +pub const NID_sm3: c_int = 968; +#[cfg(ossl111)] +pub const NID_sm3WithRSAEncryption: c_int = 1144; +#[cfg(libressl291)] +pub const NID_sm3WithRSAEncryption: c_int = 969; +#[cfg(ossl111)] +pub const NID_sm4_ecb: c_int = 1133; +#[cfg(libressl291)] +pub const NID_sm4_ecb: c_int = 973; +#[cfg(ossl111)] +pub const NID_sm4_cbc: c_int = 1134; +#[cfg(libressl291)] +pub const NID_sm4_cbc: c_int = 974; +#[cfg(ossl111)] +pub const NID_sm4_ofb128: c_int = 1135; +#[cfg(libressl291)] +pub const NID_sm4_ofb128: c_int = 975; +#[cfg(ossl111)] +pub const NID_sm4_cfb128: c_int = 1137; +#[cfg(libressl291)] +pub const NID_sm4_cfb128: c_int = 976; +#[cfg(ossl111)] +pub const NID_sm4_cfb1: c_int = 1136; +#[cfg(libressl291)] +pub const NID_sm4_cfb1: c_int = 977; +#[cfg(ossl111)] +pub const NID_sm4_cfb8: c_int = 1138; +#[cfg(libressl291)] +pub const NID_sm4_cfb8: c_int = 978; +#[cfg(ossl111)] +pub const NID_sm4_ctr: c_int = 1139; +#[cfg(libressl291)] +pub const NID_sm4_ctr: c_int = 979; +#[cfg(ossl111)] +pub const NID_sha3_224: c_int = 1096; +#[cfg(libressl380)] +pub const NID_sha3_224: c_int = 1031; +#[cfg(ossl111)] +pub const NID_sha3_256: c_int = 1097; +#[cfg(libressl380)] +pub const NID_sha3_256: c_int = 1032; +#[cfg(ossl111)] +pub const NID_sha3_384: c_int = 1098; +#[cfg(libressl380)] +pub const NID_sha3_384: c_int = 1033; +#[cfg(ossl111)] +pub const NID_sha3_512: c_int = 1099; +#[cfg(libressl380)] +pub const NID_sha3_512: c_int = 1034; +#[cfg(ossl111)] +pub const NID_shake128: c_int = 1100; +#[cfg(ossl111)] +pub const NID_shake256: c_int = 1101; +#[cfg(ossl110)] +pub const NID_chacha20_poly1305: c_int = 1018; +#[cfg(libressl271)] +pub const NID_chacha20_poly1305: c_int = 967; +cfg_if! { + if #[cfg(ossl340)] { + pub const NID_ac_auditEntity: c_int = 1323; + } else { + pub const NID_ac_auditEntity: c_int = 287; + } +} diff --git a/vendor/openssl-sys/src/ocsp.rs b/vendor/openssl-sys/src/ocsp.rs new file mode 100644 index 0000000..fc0db39 --- /dev/null +++ b/vendor/openssl-sys/src/ocsp.rs @@ -0,0 +1,35 @@ +use libc::*; + +pub const OCSP_REVOKED_STATUS_NOSTATUS: c_int = -1; +pub const OCSP_REVOKED_STATUS_UNSPECIFIED: c_int = 0; +pub const OCSP_REVOKED_STATUS_KEYCOMPROMISE: c_int = 1; +pub const OCSP_REVOKED_STATUS_CACOMPROMISE: c_int = 2; +pub const OCSP_REVOKED_STATUS_AFFILIATIONCHANGED: c_int = 3; +pub const OCSP_REVOKED_STATUS_SUPERSEDED: c_int = 4; +pub const OCSP_REVOKED_STATUS_CESSATIONOFOPERATION: c_int = 5; +pub const OCSP_REVOKED_STATUS_CERTIFICATEHOLD: c_int = 6; +pub const OCSP_REVOKED_STATUS_REMOVEFROMCRL: c_int = 8; + +pub const OCSP_NOCERTS: c_ulong = 0x1; +pub const OCSP_NOINTERN: c_ulong = 0x2; +pub const OCSP_NOSIGS: c_ulong = 0x4; +pub const OCSP_NOCHAIN: c_ulong = 0x8; +pub const OCSP_NOVERIFY: c_ulong = 0x10; +pub const OCSP_NOEXPLICIT: c_ulong = 0x20; +pub const OCSP_NOCASIGN: c_ulong = 0x40; +pub const OCSP_NODELEGATED: c_ulong = 0x80; +pub const OCSP_NOCHECKS: c_ulong = 0x100; +pub const OCSP_TRUSTOTHER: c_ulong = 0x200; +pub const OCSP_RESPID_KEY: c_ulong = 0x400; +pub const OCSP_NOTIME: c_ulong = 0x800; + +pub const OCSP_RESPONSE_STATUS_SUCCESSFUL: c_int = 0; +pub const OCSP_RESPONSE_STATUS_MALFORMEDREQUEST: c_int = 1; +pub const OCSP_RESPONSE_STATUS_INTERNALERROR: c_int = 2; +pub const OCSP_RESPONSE_STATUS_TRYLATER: c_int = 3; +pub const OCSP_RESPONSE_STATUS_SIGREQUIRED: c_int = 5; +pub const OCSP_RESPONSE_STATUS_UNAUTHORIZED: c_int = 6; + +pub const V_OCSP_CERTSTATUS_GOOD: c_int = 0; +pub const V_OCSP_CERTSTATUS_REVOKED: c_int = 1; +pub const V_OCSP_CERTSTATUS_UNKNOWN: c_int = 2; diff --git a/vendor/openssl-sys/src/pem.rs b/vendor/openssl-sys/src/pem.rs new file mode 100644 index 0000000..f7dd8ac --- /dev/null +++ b/vendor/openssl-sys/src/pem.rs @@ -0,0 +1,3 @@ +use libc::*; + +pub const PEM_R_NO_START_LINE: c_int = 108; diff --git a/vendor/openssl-sys/src/pkcs7.rs b/vendor/openssl-sys/src/pkcs7.rs new file mode 100644 index 0000000..0a56225 --- /dev/null +++ b/vendor/openssl-sys/src/pkcs7.rs @@ -0,0 +1,20 @@ +use libc::*; + +pub const PKCS7_TEXT: c_int = 0x1; +pub const PKCS7_NOCERTS: c_int = 0x2; +pub const PKCS7_NOSIGS: c_int = 0x4; +pub const PKCS7_NOCHAIN: c_int = 0x8; +pub const PKCS7_NOINTERN: c_int = 0x10; +pub const PKCS7_NOVERIFY: c_int = 0x20; +pub const PKCS7_DETACHED: c_int = 0x40; +pub const PKCS7_BINARY: c_int = 0x80; +pub const PKCS7_NOATTR: c_int = 0x100; +pub const PKCS7_NOSMIMECAP: c_int = 0x200; +pub const PKCS7_NOOLDMIMETYPE: c_int = 0x400; +pub const PKCS7_CRLFEOL: c_int = 0x800; +pub const PKCS7_STREAM: c_int = 0x1000; +pub const PKCS7_NOCRL: c_int = 0x2000; +pub const PKCS7_PARTIAL: c_int = 0x4000; +pub const PKCS7_REUSE_DIGEST: c_int = 0x8000; +#[cfg(not(any(ossl101, ossl102, libressl)))] +pub const PKCS7_NO_DUAL_CONTENT: c_int = 0x10000; diff --git a/vendor/openssl-sys/src/rsa.rs b/vendor/openssl-sys/src/rsa.rs new file mode 100644 index 0000000..64107cd --- /dev/null +++ b/vendor/openssl-sys/src/rsa.rs @@ -0,0 +1,101 @@ +use libc::*; +use std::ptr; + +use super::super::*; + +pub const RSA_F4: c_long = 0x10001; + +cfg_if! { + if #[cfg(not(ossl300))] { + pub unsafe fn EVP_PKEY_CTX_set_rsa_padding(ctx: *mut EVP_PKEY_CTX, pad: c_int) -> c_int { + EVP_PKEY_CTX_ctrl( + ctx, + EVP_PKEY_RSA, + -1, + EVP_PKEY_CTRL_RSA_PADDING, + pad, + ptr::null_mut(), + ) + } + pub unsafe fn EVP_PKEY_CTX_get_rsa_padding(ctx: *mut EVP_PKEY_CTX, ppad: *mut c_int) -> c_int { + EVP_PKEY_CTX_ctrl( + ctx, + EVP_PKEY_RSA, + -1, + EVP_PKEY_CTRL_GET_RSA_PADDING, + 0, + ppad as *mut c_void, + ) + } + + pub unsafe fn EVP_PKEY_CTX_set_rsa_pss_saltlen(ctx: *mut EVP_PKEY_CTX, len: c_int) -> c_int { + EVP_PKEY_CTX_ctrl( + ctx, + EVP_PKEY_RSA, + EVP_PKEY_OP_SIGN | EVP_PKEY_OP_VERIFY, + EVP_PKEY_CTRL_RSA_PSS_SALTLEN, + len, + ptr::null_mut(), + ) + } + + pub unsafe fn EVP_PKEY_CTX_set_rsa_mgf1_md(ctx: *mut EVP_PKEY_CTX, md: *mut EVP_MD) -> c_int { + EVP_PKEY_CTX_ctrl( + ctx, + EVP_PKEY_RSA, + EVP_PKEY_OP_TYPE_SIG | EVP_PKEY_OP_TYPE_CRYPT, + EVP_PKEY_CTRL_RSA_MGF1_MD, + 0, + md as *mut c_void, + ) + } + } +} + +#[cfg(any(ossl102, libressl310))] +pub unsafe fn EVP_PKEY_CTX_set_rsa_oaep_md(ctx: *mut EVP_PKEY_CTX, md: *mut EVP_MD) -> c_int { + EVP_PKEY_CTX_ctrl( + ctx, + EVP_PKEY_RSA, + EVP_PKEY_OP_TYPE_CRYPT, + EVP_PKEY_CTRL_RSA_OAEP_MD, + 0, + md as *mut c_void, + ) +} + +#[cfg(any(ossl102, libressl310))] +pub unsafe fn EVP_PKEY_CTX_set0_rsa_oaep_label( + ctx: *mut EVP_PKEY_CTX, + label: *mut c_void, + len: c_int, +) -> c_int { + EVP_PKEY_CTX_ctrl( + ctx, + EVP_PKEY_RSA, + EVP_PKEY_OP_TYPE_CRYPT, + EVP_PKEY_CTRL_RSA_OAEP_LABEL, + len, + label, + ) +} + +pub const EVP_PKEY_CTRL_RSA_PADDING: c_int = EVP_PKEY_ALG_CTRL + 1; +pub const EVP_PKEY_CTRL_RSA_PSS_SALTLEN: c_int = EVP_PKEY_ALG_CTRL + 2; + +pub const EVP_PKEY_CTRL_RSA_MGF1_MD: c_int = EVP_PKEY_ALG_CTRL + 5; + +pub const EVP_PKEY_CTRL_GET_RSA_PADDING: c_int = EVP_PKEY_ALG_CTRL + 6; + +#[cfg(any(ossl102, libressl310))] +pub const EVP_PKEY_CTRL_RSA_OAEP_MD: c_int = EVP_PKEY_ALG_CTRL + 9; +#[cfg(any(ossl102, libressl310))] +pub const EVP_PKEY_CTRL_RSA_OAEP_LABEL: c_int = EVP_PKEY_ALG_CTRL + 10; + +pub const RSA_PKCS1_PADDING: c_int = 1; +#[cfg(not(ossl300))] +pub const RSA_SSLV23_PADDING: c_int = 2; +pub const RSA_NO_PADDING: c_int = 3; +pub const RSA_PKCS1_OAEP_PADDING: c_int = 4; +pub const RSA_X931_PADDING: c_int = 5; +pub const RSA_PKCS1_PSS_PADDING: c_int = 6; diff --git a/vendor/openssl-sys/src/sha.rs b/vendor/openssl-sys/src/sha.rs new file mode 100644 index 0000000..4ad0c17 --- /dev/null +++ b/vendor/openssl-sys/src/sha.rs @@ -0,0 +1,103 @@ +use super::*; +use libc::*; +use std::ptr; + +#[cfg(not(osslconf = "OPENSSL_NO_DEPRECATED_3_0"))] +pub const SHA_LBLOCK: c_int = 16; + +#[cfg(not(osslconf = "OPENSSL_NO_DEPRECATED_3_0"))] +pub type SHA_LONG = c_uint; + +cfg_if! { + if #[cfg(ossl300)] { + #[cfg(ossl300)] + // Ideally we'd macro define these, but that crashes ctest :( + pub unsafe fn SHA1(d: *const c_uchar, n: size_t, md: *mut c_uchar) -> *mut c_uchar { + if EVP_Q_digest( + ptr::null_mut(), + "SHA1\0".as_ptr() as *const c_char, + ptr::null(), + d as *const c_void, + n, + md, + ptr::null_mut(), + ) != 0 + { + md + } else { + ptr::null_mut() + } + } + + pub unsafe fn SHA224(d: *const c_uchar, n: size_t, md: *mut c_uchar) -> *mut c_uchar { + if EVP_Q_digest( + ptr::null_mut(), + "SHA224\0".as_ptr() as *const c_char, + ptr::null(), + d as *const c_void, + n, + md, + ptr::null_mut(), + ) != 0 { + md + } else { + ptr::null_mut() + } + } + + pub unsafe fn SHA256(d: *const c_uchar, n: size_t, md: *mut c_uchar) -> *mut c_uchar { + if EVP_Q_digest( + ptr::null_mut(), + "SHA256\0".as_ptr() as *const c_char, + ptr::null(), + d as *const c_void, + n, + md, + ptr::null_mut(), + ) != 0 { + md + } else { + ptr::null_mut() + } + } + } +} + +#[cfg(not(osslconf = "OPENSSL_NO_DEPRECATED_3_0"))] +pub type SHA_LONG64 = u64; + +cfg_if! { + if #[cfg(ossl300)] { + pub unsafe fn SHA384(d: *const c_uchar, n: size_t, md: *mut c_uchar) -> *mut c_uchar { + if EVP_Q_digest( + ptr::null_mut(), + "SHA384\0".as_ptr() as *const c_char, + ptr::null(), + d as *const c_void, + n, + md, + ptr::null_mut(), + ) != 0 { + md + } else { + ptr::null_mut() + } + } + + pub unsafe fn SHA512(d: *const c_uchar, n: size_t, md: *mut c_uchar) -> *mut c_uchar { + if EVP_Q_digest( + ptr::null_mut(), + "SHA512\0".as_ptr() as *const c_char, + ptr::null(), + d as *const c_void, + n, + md, + ptr::null_mut(), + ) != 0 { + md + } else { + ptr::null_mut() + } + } + } +} diff --git a/vendor/openssl-sys/src/srtp.rs b/vendor/openssl-sys/src/srtp.rs new file mode 100644 index 0000000..93c7797 --- /dev/null +++ b/vendor/openssl-sys/src/srtp.rs @@ -0,0 +1,14 @@ +use libc::*; + +pub const SRTP_AES128_CM_SHA1_80: c_ulong = 0x0001; +pub const SRTP_AES128_CM_SHA1_32: c_ulong = 0x0002; +pub const SRTP_AES128_F8_SHA1_80: c_ulong = 0x0003; +pub const SRTP_AES128_F8_SHA1_32: c_ulong = 0x0004; +pub const SRTP_NULL_SHA1_80: c_ulong = 0x0005; +pub const SRTP_NULL_SHA1_32: c_ulong = 0x0006; + +/* AEAD SRTP protection profiles from RFC 7714 */ +#[cfg(ossl110)] +pub const SRTP_AEAD_AES_128_GCM: c_ulong = 0x0007; +#[cfg(ossl110)] +pub const SRTP_AEAD_AES_256_GCM: c_ulong = 0x0008; diff --git a/vendor/openssl-sys/src/ssl.rs b/vendor/openssl-sys/src/ssl.rs new file mode 100644 index 0000000..38d2184 --- /dev/null +++ b/vendor/openssl-sys/src/ssl.rs @@ -0,0 +1,716 @@ +use libc::*; +use std::ptr; + +use super::*; + +#[cfg(not(ossl110))] +pub const SSL_MAX_KRB5_PRINCIPAL_LENGTH: c_int = 256; + +#[cfg(not(ossl110))] +pub const SSL_MAX_SSL_SESSION_ID_LENGTH: c_int = 32; +#[cfg(not(ossl110))] +pub const SSL_MAX_SID_CTX_LENGTH: c_int = 32; + +#[cfg(not(ossl110))] +pub const SSL_MAX_KEY_ARG_LENGTH: c_int = 8; +#[cfg(not(ossl110))] +pub const SSL_MAX_MASTER_KEY_LENGTH: c_int = 48; + +pub const SSL_SENT_SHUTDOWN: c_int = 1; +pub const SSL_RECEIVED_SHUTDOWN: c_int = 2; + +pub const SSL_FILETYPE_PEM: c_int = X509_FILETYPE_PEM; +pub const SSL_FILETYPE_ASN1: c_int = X509_FILETYPE_ASN1; + +#[cfg(ossl111)] +pub const SSL_EXT_TLS_ONLY: c_uint = 0x0001; +/* This extension is only allowed in DTLS */ +#[cfg(ossl111)] +pub const SSL_EXT_DTLS_ONLY: c_uint = 0x0002; +/* Some extensions may be allowed in DTLS but we don't implement them for it */ +#[cfg(ossl111)] +pub const SSL_EXT_TLS_IMPLEMENTATION_ONLY: c_uint = 0x0004; +/* Most extensions are not defined for SSLv3 but EXT_TYPE_renegotiate is */ +#[cfg(ossl111)] +pub const SSL_EXT_SSL3_ALLOWED: c_uint = 0x0008; +/* Extension is only defined for TLS1.2 and below */ +#[cfg(ossl111)] +pub const SSL_EXT_TLS1_2_AND_BELOW_ONLY: c_uint = 0x0010; +/* Extension is only defined for TLS1.3 and above */ +#[cfg(ossl111)] +pub const SSL_EXT_TLS1_3_ONLY: c_uint = 0x0020; +/* Ignore this extension during parsing if we are resuming */ +#[cfg(ossl111)] +pub const SSL_EXT_IGNORE_ON_RESUMPTION: c_uint = 0x0040; +#[cfg(ossl111)] +pub const SSL_EXT_CLIENT_HELLO: c_uint = 0x0080; +/* Really means TLS1.2 or below */ +#[cfg(ossl111)] +pub const SSL_EXT_TLS1_2_SERVER_HELLO: c_uint = 0x0100; +#[cfg(ossl111)] +pub const SSL_EXT_TLS1_3_SERVER_HELLO: c_uint = 0x0200; +#[cfg(ossl111)] +pub const SSL_EXT_TLS1_3_ENCRYPTED_EXTENSIONS: c_uint = 0x0400; +#[cfg(ossl111)] +pub const SSL_EXT_TLS1_3_HELLO_RETRY_REQUEST: c_uint = 0x0800; +#[cfg(ossl111)] +pub const SSL_EXT_TLS1_3_CERTIFICATE: c_uint = 0x1000; +#[cfg(ossl111)] +pub const SSL_EXT_TLS1_3_NEW_SESSION_TICKET: c_uint = 0x2000; +#[cfg(ossl111)] +pub const SSL_EXT_TLS1_3_CERTIFICATE_REQUEST: c_uint = 0x4000; + +cfg_if! { + if #[cfg(ossl300)] { + macro_rules! ssl_op_type { + () => {u64}; + } + } else { + macro_rules! ssl_op_type { + () => {c_ulong}; + } + } +} + +pub const SSL_OP_LEGACY_SERVER_CONNECT: ssl_op_type!() = 0x00000004; +cfg_if! { + if #[cfg(libressl261)] { + pub const SSL_OP_TLSEXT_PADDING: ssl_op_type!() = 0x0; + } else if #[cfg(any(ossl102, libressl))] { + pub const SSL_OP_TLSEXT_PADDING: ssl_op_type!() = 0x10; + } +} +#[cfg(ossl101)] +pub const SSL_OP_SAFARI_ECDHE_ECDSA_BUG: ssl_op_type!() = 0x00000040; + +pub const SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS: ssl_op_type!() = 0x00000800; + +pub const SSL_OP_NO_QUERY_MTU: ssl_op_type!() = 0x00001000; +pub const SSL_OP_COOKIE_EXCHANGE: ssl_op_type!() = 0x00002000; +pub const SSL_OP_NO_TICKET: ssl_op_type!() = 0x00004000; +cfg_if! { + if #[cfg(ossl101)] { + pub const SSL_OP_CISCO_ANYCONNECT: ssl_op_type!() = 0x00008000; + } else { + pub const SSL_OP_CISCO_ANYCONNECT: ssl_op_type!() = 0x0; + } +} + +pub const SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION: ssl_op_type!() = 0x00010000; +cfg_if! { + if #[cfg(ossl101)] { + pub const SSL_OP_NO_COMPRESSION: ssl_op_type!() = 0x00020000; + pub const SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION: ssl_op_type!() = 0x00040000; + } else { + pub const SSL_OP_NO_COMPRESSION: ssl_op_type!() = 0x0; + pub const SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION: ssl_op_type!() = 0x0; + } +} + +#[cfg(ossl111)] +pub const SSL_OP_ENABLE_MIDDLEBOX_COMPAT: ssl_op_type!() = 0x00100000; +#[cfg(ossl111)] +pub const SSL_OP_PRIORITIZE_CHACHA: ssl_op_type!() = 0x00200000; + +pub const SSL_OP_CIPHER_SERVER_PREFERENCE: ssl_op_type!() = 0x00400000; +cfg_if! { + if #[cfg(libressl280)] { + pub const SSL_OP_TLS_ROLLBACK_BUG: ssl_op_type!() = 0; + } else { + pub const SSL_OP_TLS_ROLLBACK_BUG: ssl_op_type!() = 0x00800000; + } +} + +cfg_if! { + if #[cfg(ossl101)] { + pub const SSL_OP_NO_SSLv3: ssl_op_type!() = 0x02000000; + } else { + pub const SSL_OP_NO_SSLv3: ssl_op_type!() = 0x0; + } +} +pub const SSL_OP_NO_TLSv1_1: ssl_op_type!() = 0x10000000; +pub const SSL_OP_NO_TLSv1_2: ssl_op_type!() = 0x08000000; + +pub const SSL_OP_NO_TLSv1: ssl_op_type!() = 0x04000000; +cfg_if! { + if #[cfg(ossl102)] { + pub const SSL_OP_NO_DTLSv1: ssl_op_type!() = 0x04000000; + pub const SSL_OP_NO_DTLSv1_2: ssl_op_type!() = 0x08000000; + } else if #[cfg(libressl332)] { + pub const SSL_OP_NO_DTLSv1: ssl_op_type!() = 0x40000000; + pub const SSL_OP_NO_DTLSv1_2: ssl_op_type!() = 0x80000000; + } +} +#[cfg(any(ossl111, libressl340))] +pub const SSL_OP_NO_TLSv1_3: ssl_op_type!() = 0x20000000; + +#[cfg(ossl110h)] +pub const SSL_OP_NO_RENEGOTIATION: ssl_op_type!() = 0x40000000; + +cfg_if! { + if #[cfg(ossl111)] { + pub const SSL_OP_NO_SSL_MASK: ssl_op_type!() = SSL_OP_NO_SSLv2 + | SSL_OP_NO_SSLv3 + | SSL_OP_NO_TLSv1 + | SSL_OP_NO_TLSv1_1 + | SSL_OP_NO_TLSv1_2 + | SSL_OP_NO_TLSv1_3; + } else if #[cfg(ossl102)] { + pub const SSL_OP_NO_SSL_MASK: ssl_op_type!() = + SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 | SSL_OP_NO_TLSv1 | SSL_OP_NO_TLSv1_1 | SSL_OP_NO_TLSv1_2; + } +} + +cfg_if! { + if #[cfg(libressl261)] { + pub const SSL_OP_CRYPTOPRO_TLSEXT_BUG: ssl_op_type!() = 0x0; + } else { + pub const SSL_OP_CRYPTOPRO_TLSEXT_BUG: ssl_op_type!() = 0x80000000; + } +} + +cfg_if! { + if #[cfg(ossl300)] { + pub const SSL_OP_ALL: ssl_op_type!() = SSL_OP_CRYPTOPRO_TLSEXT_BUG + | SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS + | SSL_OP_TLSEXT_PADDING + | SSL_OP_SAFARI_ECDHE_ECDSA_BUG; + } else if #[cfg(ossl110f)] { + pub const SSL_OP_ALL: ssl_op_type!() = SSL_OP_CRYPTOPRO_TLSEXT_BUG + | SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS + | SSL_OP_LEGACY_SERVER_CONNECT + | SSL_OP_TLSEXT_PADDING + | SSL_OP_SAFARI_ECDHE_ECDSA_BUG; + } else if #[cfg(libressl261)] { + pub const SSL_OP_ALL: ssl_op_type!() = 0x4; + } else if #[cfg(libressl)] { + pub const SSL_OP_ALL: ssl_op_type!() = 0x80000014; + } else { + pub const SSL_OP_ALL: ssl_op_type!() = 0x80000BFF; + } +} + +cfg_if! { + if #[cfg(ossl110)] { + pub const SSL_OP_MICROSOFT_SESS_ID_BUG: ssl_op_type!() = 0x00000000; + pub const SSL_OP_NETSCAPE_CHALLENGE_BUG: ssl_op_type!() = 0x00000000; + pub const SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG: ssl_op_type!() = 0x00000000; + pub const SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER: ssl_op_type!() = 0x00000000; + pub const SSL_OP_SSLEAY_080_CLIENT_DH_BUG: ssl_op_type!() = 0x00000000; + pub const SSL_OP_TLS_D5_BUG: ssl_op_type!() = 0x00000000; + pub const SSL_OP_TLS_BLOCK_PADDING_BUG: ssl_op_type!() = 0x00000000; + pub const SSL_OP_SINGLE_ECDH_USE: ssl_op_type!() = 0x00000000; + pub const SSL_OP_SINGLE_DH_USE: ssl_op_type!() = 0x00000000; + pub const SSL_OP_NO_SSLv2: ssl_op_type!() = 0x00000000; + } else if #[cfg(ossl101)] { + pub const SSL_OP_MICROSOFT_SESS_ID_BUG: ssl_op_type!() = 0x00000001; + pub const SSL_OP_NETSCAPE_CHALLENGE_BUG: ssl_op_type!() = 0x00000002; + pub const SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG: ssl_op_type!() = 0x00000008; + pub const SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER: ssl_op_type!() = 0x00000020; + pub const SSL_OP_SSLEAY_080_CLIENT_DH_BUG: ssl_op_type!() = 0x00000080; + pub const SSL_OP_TLS_D5_BUG: ssl_op_type!() = 0x00000100; + pub const SSL_OP_TLS_BLOCK_PADDING_BUG: ssl_op_type!() = 0x00000200; + pub const SSL_OP_SINGLE_ECDH_USE: ssl_op_type!() = 0x00080000; + pub const SSL_OP_SINGLE_DH_USE: ssl_op_type!() = 0x00100000; + pub const SSL_OP_NO_SSLv2: ssl_op_type!() = 0x01000000; + } else { + pub const SSL_OP_MICROSOFT_SESS_ID_BUG: ssl_op_type!() = 0x0; + pub const SSL_OP_NETSCAPE_CHALLENGE_BUG: ssl_op_type!() = 0x0; + pub const SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG: ssl_op_type!() = 0x0; + pub const SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER: ssl_op_type!() = 0x0; + pub const SSL_OP_SSLEAY_080_CLIENT_DH_BUG: ssl_op_type!() = 0x0; + pub const SSL_OP_TLS_D5_BUG: ssl_op_type!() = 0x0; + pub const SSL_OP_TLS_BLOCK_PADDING_BUG: ssl_op_type!() = 0x0; + #[cfg(libressl261)] + pub const SSL_OP_SINGLE_ECDH_USE: ssl_op_type!() = 0x0; + #[cfg(not(libressl261))] + pub const SSL_OP_SINGLE_ECDH_USE: ssl_op_type!() = 0x00080000; + pub const SSL_OP_SINGLE_DH_USE: ssl_op_type!() = 0x00100000; + pub const SSL_OP_NO_SSLv2: ssl_op_type!() = 0x0; + } +} + +pub const SSL_MODE_ENABLE_PARTIAL_WRITE: c_long = 0x1; +pub const SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER: c_long = 0x2; +pub const SSL_MODE_AUTO_RETRY: c_long = 0x4; +pub const SSL_MODE_NO_AUTO_CHAIN: c_long = 0x8; +pub const SSL_MODE_RELEASE_BUFFERS: c_long = 0x10; +#[cfg(ossl101)] +pub const SSL_MODE_SEND_CLIENTHELLO_TIME: c_long = 0x20; +#[cfg(ossl101)] +pub const SSL_MODE_SEND_SERVERHELLO_TIME: c_long = 0x40; +#[cfg(ossl101)] +pub const SSL_MODE_SEND_FALLBACK_SCSV: c_long = 0x80; + +pub unsafe fn SSL_CTX_set_mode(ctx: *mut SSL_CTX, op: c_long) -> c_long { + SSL_CTX_ctrl(ctx, SSL_CTRL_MODE, op, ptr::null_mut()) +} + +#[cfg(ossl111)] +pub const SSL_COOKIE_LENGTH: c_int = 4096; + +cfg_if! { + if #[cfg(not(ossl110))] { + pub unsafe fn SSL_CTX_get_options(ctx: *const SSL_CTX) -> c_ulong { + SSL_CTX_ctrl(ctx as *mut _, SSL_CTRL_OPTIONS, 0, ptr::null_mut()) as c_ulong + } + + pub unsafe fn SSL_CTX_set_options(ctx: *const SSL_CTX, op: c_ulong) -> c_ulong { + SSL_CTX_ctrl( + ctx as *mut _, + SSL_CTRL_OPTIONS, + op as c_long, + ptr::null_mut(), + ) as c_ulong + } + + pub unsafe fn SSL_CTX_clear_options(ctx: *const SSL_CTX, op: c_ulong) -> c_ulong { + SSL_CTX_ctrl( + ctx as *mut _, + SSL_CTRL_CLEAR_OPTIONS, + op as c_long, + ptr::null_mut(), + ) as c_ulong + } + } +} + +pub unsafe fn SSL_set_mtu(ssl: *mut SSL, mtu: c_long) -> c_long { + SSL_ctrl(ssl, SSL_CTRL_SET_MTU, mtu, ptr::null_mut()) +} + +#[cfg(ossl110)] +pub unsafe fn SSL_get_extms_support(ssl: *mut SSL) -> c_long { + SSL_ctrl(ssl, SSL_CTRL_GET_EXTMS_SUPPORT, 0, ptr::null_mut()) +} + +pub const SSL_SESS_CACHE_OFF: c_long = 0x0; +pub const SSL_SESS_CACHE_CLIENT: c_long = 0x1; +pub const SSL_SESS_CACHE_SERVER: c_long = 0x2; +pub const SSL_SESS_CACHE_BOTH: c_long = SSL_SESS_CACHE_CLIENT | SSL_SESS_CACHE_SERVER; +pub const SSL_SESS_CACHE_NO_AUTO_CLEAR: c_long = 0x80; +pub const SSL_SESS_CACHE_NO_INTERNAL_LOOKUP: c_long = 0x100; +pub const SSL_SESS_CACHE_NO_INTERNAL_STORE: c_long = 0x200; +pub const SSL_SESS_CACHE_NO_INTERNAL: c_long = + SSL_SESS_CACHE_NO_INTERNAL_LOOKUP | SSL_SESS_CACHE_NO_INTERNAL_STORE; + +pub const OPENSSL_NPN_UNSUPPORTED: c_int = 0; +pub const OPENSSL_NPN_NEGOTIATED: c_int = 1; +pub const OPENSSL_NPN_NO_OVERLAP: c_int = 2; + +pub const SSL_AD_ILLEGAL_PARAMETER: c_int = SSL3_AD_ILLEGAL_PARAMETER; +pub const SSL_AD_DECODE_ERROR: c_int = TLS1_AD_DECODE_ERROR; +pub const SSL_AD_UNRECOGNIZED_NAME: c_int = TLS1_AD_UNRECOGNIZED_NAME; +pub const SSL_ERROR_NONE: c_int = 0; +pub const SSL_ERROR_SSL: c_int = 1; +pub const SSL_ERROR_SYSCALL: c_int = 5; +pub const SSL_ERROR_WANT_ACCEPT: c_int = 8; +pub const SSL_ERROR_WANT_CONNECT: c_int = 7; +pub const SSL_ERROR_WANT_READ: c_int = 2; +pub const SSL_ERROR_WANT_WRITE: c_int = 3; +pub const SSL_ERROR_WANT_X509_LOOKUP: c_int = 4; +pub const SSL_ERROR_ZERO_RETURN: c_int = 6; +#[cfg(ossl111)] +pub const SSL_ERROR_WANT_CLIENT_HELLO_CB: c_int = 11; +pub const SSL_VERIFY_NONE: c_int = 0; +pub const SSL_VERIFY_PEER: c_int = 1; +pub const SSL_VERIFY_FAIL_IF_NO_PEER_CERT: c_int = 2; +pub const SSL_CTRL_SET_TMP_DH: c_int = 3; +pub const SSL_CTRL_SET_TMP_ECDH: c_int = 4; +#[cfg(any(libressl, all(ossl101, not(ossl110))))] +pub const SSL_CTRL_GET_SESSION_REUSED: c_int = 8; +pub const SSL_CTRL_EXTRA_CHAIN_CERT: c_int = 14; +pub const SSL_CTRL_SET_MTU: c_int = 17; +#[cfg(any(libressl, all(ossl101, not(ossl110))))] +pub const SSL_CTRL_OPTIONS: c_int = 32; +pub const SSL_CTRL_MODE: c_int = 33; +pub const SSL_CTRL_SET_READ_AHEAD: c_int = 41; +pub const SSL_CTRL_SET_SESS_CACHE_SIZE: c_int = 42; +pub const SSL_CTRL_GET_SESS_CACHE_SIZE: c_int = 43; +pub const SSL_CTRL_SET_SESS_CACHE_MODE: c_int = 44; +pub const SSL_CTRL_SET_TLSEXT_SERVERNAME_CB: c_int = 53; +pub const SSL_CTRL_SET_TLSEXT_SERVERNAME_ARG: c_int = 54; +pub const SSL_CTRL_SET_TLSEXT_HOSTNAME: c_int = 55; +pub const SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB: c_int = 63; +pub const SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB_ARG: c_int = 64; +pub const SSL_CTRL_SET_TLSEXT_STATUS_REQ_TYPE: c_int = 65; +pub const SSL_CTRL_GET_TLSEXT_STATUS_REQ_OCSP_RESP: c_int = 70; +pub const SSL_CTRL_SET_TLSEXT_STATUS_REQ_OCSP_RESP: c_int = 71; +#[cfg(any(libressl, all(ossl101, not(ossl110))))] +pub const SSL_CTRL_CLEAR_OPTIONS: c_int = 77; +pub const SSL_CTRL_GET_EXTRA_CHAIN_CERTS: c_int = 82; +#[cfg(ossl102)] +pub const SSL_CTRL_CHAIN_CERT: c_int = 89; +#[cfg(any(ossl111, libressl252))] +pub const SSL_CTRL_SET_GROUPS_LIST: c_int = 92; +#[cfg(any(libressl, all(ossl102, not(ossl110))))] +pub const SSL_CTRL_SET_ECDH_AUTO: c_int = 94; +#[cfg(ossl102)] +pub const SSL_CTRL_SET_SIGALGS_LIST: c_int = 98; +#[cfg(ossl102)] +pub const SSL_CTRL_SET_VERIFY_CERT_STORE: c_int = 106; +#[cfg(ossl300)] +pub const SSL_CTRL_GET_PEER_TMP_KEY: c_int = 109; +#[cfg(ossl110)] +pub const SSL_CTRL_GET_EXTMS_SUPPORT: c_int = 122; +#[cfg(any(ossl110, libressl261))] +pub const SSL_CTRL_SET_MIN_PROTO_VERSION: c_int = 123; +#[cfg(any(ossl110, libressl261))] +pub const SSL_CTRL_SET_MAX_PROTO_VERSION: c_int = 124; +#[cfg(any(ossl110g, libressl270))] +pub const SSL_CTRL_GET_MIN_PROTO_VERSION: c_int = 130; +#[cfg(any(ossl110g, libressl270))] +pub const SSL_CTRL_GET_MAX_PROTO_VERSION: c_int = 131; +#[cfg(ossl300)] +pub const SSL_CTRL_GET_TMP_KEY: c_int = 133; + +pub unsafe fn SSL_CTX_set_tmp_dh(ctx: *mut SSL_CTX, dh: *mut DH) -> c_long { + SSL_CTX_ctrl(ctx, SSL_CTRL_SET_TMP_DH, 0, dh as *mut c_void) +} + +pub unsafe fn SSL_CTX_set_tmp_ecdh(ctx: *mut SSL_CTX, key: *mut EC_KEY) -> c_long { + SSL_CTX_ctrl(ctx, SSL_CTRL_SET_TMP_ECDH, 0, key as *mut c_void) +} + +pub unsafe fn SSL_set_tmp_dh(ssl: *mut SSL, dh: *mut DH) -> c_long { + SSL_ctrl(ssl, SSL_CTRL_SET_TMP_DH, 0, dh as *mut c_void) +} + +pub unsafe fn SSL_set_tmp_ecdh(ssl: *mut SSL, key: *mut EC_KEY) -> c_long { + SSL_ctrl(ssl, SSL_CTRL_SET_TMP_ECDH, 0, key as *mut c_void) +} + +pub unsafe fn SSL_CTX_add_extra_chain_cert(ctx: *mut SSL_CTX, x509: *mut X509) -> c_long { + SSL_CTX_ctrl(ctx, SSL_CTRL_EXTRA_CHAIN_CERT, 0, x509 as *mut c_void) +} + +pub unsafe fn SSL_CTX_get_extra_chain_certs( + ctx: *mut SSL_CTX, + chain: *mut *mut stack_st_X509, +) -> c_long { + SSL_CTX_ctrl(ctx, SSL_CTRL_GET_EXTRA_CHAIN_CERTS, 0, chain as *mut c_void) +} + +#[cfg(ossl102)] +pub unsafe fn SSL_CTX_set0_verify_cert_store(ctx: *mut SSL_CTX, st: *mut X509_STORE) -> c_long { + SSL_CTX_ctrl(ctx, SSL_CTRL_SET_VERIFY_CERT_STORE, 0, st as *mut c_void) +} + +#[cfg(ossl102)] +pub unsafe fn SSL_set0_verify_cert_store(ssl: *mut SSL, st: *mut X509_STORE) -> c_long { + SSL_ctrl(ssl, SSL_CTRL_SET_VERIFY_CERT_STORE, 0, st as *mut c_void) +} + +cfg_if! { + if #[cfg(ossl111)] { + pub unsafe fn SSL_CTX_set1_groups_list(ctx: *mut SSL_CTX, s: *const c_char) -> c_long { + SSL_CTX_ctrl( + ctx, + SSL_CTRL_SET_GROUPS_LIST, + 0, + s as *const c_void as *mut c_void, + ) + } + } else if #[cfg(libressl251)] { + extern "C" { + pub fn SSL_CTX_set1_groups_list(ctx: *mut SSL_CTX, s: *const c_char) -> c_int; + } + } +} + +#[cfg(ossl102)] +pub unsafe fn SSL_add0_chain_cert(ssl: *mut SSL, ptr: *mut X509) -> c_long { + SSL_ctrl(ssl, SSL_CTRL_CHAIN_CERT, 0, ptr as *mut c_void) +} + +#[cfg(ossl102)] +pub unsafe fn SSL_CTX_set1_sigalgs_list(ctx: *mut SSL_CTX, s: *const c_char) -> c_long { + SSL_CTX_ctrl( + ctx, + SSL_CTRL_SET_SIGALGS_LIST, + 0, + s as *const c_void as *mut c_void, + ) +} + +#[cfg(any(libressl, all(ossl102, not(ossl110))))] +pub unsafe fn SSL_CTX_set_ecdh_auto(ctx: *mut SSL_CTX, onoff: c_int) -> c_int { + SSL_CTX_ctrl( + ctx, + SSL_CTRL_SET_ECDH_AUTO, + onoff as c_long, + ptr::null_mut(), + ) as c_int +} + +#[cfg(any(libressl, all(ossl102, not(ossl110))))] +pub unsafe fn SSL_set_ecdh_auto(ssl: *mut SSL, onoff: c_int) -> c_int { + SSL_ctrl( + ssl, + SSL_CTRL_SET_ECDH_AUTO, + onoff as c_long, + ptr::null_mut(), + ) as c_int +} + +cfg_if! { + if #[cfg(ossl110)] { + pub unsafe fn SSL_CTX_set_min_proto_version(ctx: *mut SSL_CTX, version: c_int) -> c_int { + SSL_CTX_ctrl( + ctx, + SSL_CTRL_SET_MIN_PROTO_VERSION, + version as c_long, + ptr::null_mut(), + ) as c_int + } + + pub unsafe fn SSL_CTX_set_max_proto_version(ctx: *mut SSL_CTX, version: c_int) -> c_int { + SSL_CTX_ctrl( + ctx, + SSL_CTRL_SET_MAX_PROTO_VERSION, + version as c_long, + ptr::null_mut(), + ) as c_int + } + + pub unsafe fn SSL_set_min_proto_version(s: *mut SSL, version: c_int) -> c_int { + SSL_ctrl( + s, + SSL_CTRL_SET_MIN_PROTO_VERSION, + version as c_long, + ptr::null_mut(), + ) as c_int + } + + pub unsafe fn SSL_set_max_proto_version(s: *mut SSL, version: c_int) -> c_int { + SSL_ctrl( + s, + SSL_CTRL_SET_MAX_PROTO_VERSION, + version as c_long, + ptr::null_mut(), + ) as c_int + } + } +} + +cfg_if! { + if #[cfg(ossl110g)] { + pub unsafe fn SSL_CTX_get_min_proto_version(ctx: *mut SSL_CTX) -> c_int { + SSL_CTX_ctrl(ctx, SSL_CTRL_GET_MIN_PROTO_VERSION, 0, ptr::null_mut()) as c_int + } + + pub unsafe fn SSL_CTX_get_max_proto_version(ctx: *mut SSL_CTX) -> c_int { + SSL_CTX_ctrl(ctx, SSL_CTRL_GET_MAX_PROTO_VERSION, 0, ptr::null_mut()) as c_int + } + pub unsafe fn SSL_get_min_proto_version(s: *mut SSL) -> c_int { + SSL_ctrl(s, SSL_CTRL_GET_MIN_PROTO_VERSION, 0, ptr::null_mut()) as c_int + } + pub unsafe fn SSL_get_max_proto_version(s: *mut SSL) -> c_int { + SSL_ctrl(s, SSL_CTRL_GET_MAX_PROTO_VERSION, 0, ptr::null_mut()) as c_int + } + } +} +cfg_if! { + if #[cfg(ossl300)] { + pub unsafe fn SSL_get_peer_tmp_key(ssl: *mut SSL, key: *mut *mut EVP_PKEY) -> c_long { + SSL_ctrl(ssl, SSL_CTRL_GET_PEER_TMP_KEY, 0, key as *mut c_void) + } + + pub unsafe fn SSL_get_tmp_key(ssl: *mut SSL, key: *mut *mut EVP_PKEY) -> c_long { + SSL_ctrl(ssl, SSL_CTRL_GET_TMP_KEY, 0, key as *mut c_void) + } + } +} + +#[cfg(ossl111)] +pub const SSL_CLIENT_HELLO_SUCCESS: c_int = 1; +#[cfg(ossl111)] +pub const SSL_CLIENT_HELLO_ERROR: c_int = 0; +#[cfg(ossl111)] +pub const SSL_CLIENT_HELLO_RETRY: c_int = -1; + +#[cfg(any(ossl111, libressl340))] +pub const SSL_READ_EARLY_DATA_ERROR: c_int = 0; +#[cfg(any(ossl111, libressl340))] +pub const SSL_READ_EARLY_DATA_SUCCESS: c_int = 1; +#[cfg(any(ossl111, libressl340))] +pub const SSL_READ_EARLY_DATA_FINISH: c_int = 2; + +cfg_if! { + if #[cfg(ossl110)] { + pub unsafe fn SSL_get_ex_new_index( + l: c_long, + p: *mut c_void, + newf: Option, + dupf: Option, + freef: Option, + ) -> c_int { + CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_SSL, l, p, newf, dupf, freef) + } + } +} +cfg_if! { + if #[cfg(ossl110)] { + pub unsafe fn SSL_CTX_get_ex_new_index( + l: c_long, + p: *mut c_void, + newf: Option, + dupf: Option, + freef: Option, + ) -> c_int { + CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_SSL_CTX, l, p, newf, dupf, freef) + } + } +} + +pub unsafe fn SSL_CTX_sess_set_cache_size(ctx: *mut SSL_CTX, t: c_long) -> c_long { + SSL_CTX_ctrl(ctx, SSL_CTRL_SET_SESS_CACHE_SIZE, t, ptr::null_mut()) +} + +pub unsafe fn SSL_CTX_sess_get_cache_size(ctx: *mut SSL_CTX) -> c_long { + SSL_CTX_ctrl(ctx, SSL_CTRL_GET_SESS_CACHE_SIZE, 0, ptr::null_mut()) +} + +pub unsafe fn SSL_CTX_set_session_cache_mode(ctx: *mut SSL_CTX, m: c_long) -> c_long { + SSL_CTX_ctrl(ctx, SSL_CTRL_SET_SESS_CACHE_MODE, m, ptr::null_mut()) +} + +pub unsafe fn SSL_CTX_set_read_ahead(ctx: *mut SSL_CTX, m: c_long) -> c_long { + SSL_CTX_ctrl(ctx, SSL_CTRL_SET_READ_AHEAD, m, ptr::null_mut()) +} + +#[allow(clashing_extern_declarations)] +extern "C" { + #[deprecated(note = "use SSL_CTX_set_tmp_dh_callback__fixed_rust instead")] + pub fn SSL_CTX_set_tmp_dh_callback( + ctx: *mut SSL_CTX, + dh: unsafe extern "C" fn(ssl: *mut SSL, is_export: c_int, keylength: c_int) -> *mut DH, + ); + #[deprecated(note = "use SSL_set_tmp_dh_callback__fixed_rust instead")] + pub fn SSL_set_tmp_dh_callback( + ctx: *mut SSL, + dh: unsafe extern "C" fn(ssl: *mut SSL, is_export: c_int, keylength: c_int) -> *mut DH, + ); + #[deprecated(note = "use SSL_CTX_set_tmp_ecdh_callback__fixed_rust instead")] + #[cfg(not(ossl110))] + pub fn SSL_CTX_set_tmp_ecdh_callback( + ctx: *mut SSL_CTX, + ecdh: unsafe extern "C" fn( + ssl: *mut SSL, + is_export: c_int, + keylength: c_int, + ) -> *mut EC_KEY, + ); + #[deprecated(note = "use SSL_set_tmp_ecdh_callback__fixed_rust instead")] + #[cfg(not(ossl110))] + pub fn SSL_set_tmp_ecdh_callback( + ssl: *mut SSL, + ecdh: unsafe extern "C" fn( + ssl: *mut SSL, + is_export: c_int, + keylength: c_int, + ) -> *mut EC_KEY, + ); + + #[deprecated(note = "use SSL_CTX_callback_ctrl__fixed_rust instead")] + pub fn SSL_CTX_callback_ctrl( + ctx: *mut SSL_CTX, + cmd: c_int, + fp: Option, + ) -> c_long; + + #[deprecated(note = "use SSL_CTX_set_alpn_select_cb__fixed_rust instead")] + #[cfg(any(ossl102, libressl261))] + pub fn SSL_CTX_set_alpn_select_cb( + ssl: *mut SSL_CTX, + cb: extern "C" fn( + ssl: *mut SSL, + out: *mut *const c_uchar, + outlen: *mut c_uchar, + inbuf: *const c_uchar, + inlen: c_uint, + arg: *mut c_void, + ) -> c_int, + arg: *mut c_void, + ); +} + +#[cfg(not(ossl110))] +pub unsafe fn SSL_session_reused(ssl: *mut SSL) -> c_int { + SSL_ctrl(ssl, SSL_CTRL_GET_SESSION_REUSED, 0, ptr::null_mut()) as c_int +} + +#[cfg(ossl110)] +pub const OPENSSL_INIT_LOAD_SSL_STRINGS: u64 = 0x00200000; +#[cfg(ossl111b)] +pub const OPENSSL_INIT_NO_ATEXIT: u64 = 0x00080000; + +cfg_if! { + if #[cfg(ossl330)] { + pub const SSL_VALUE_CLASS_GENERIC: c_uint = 0; + pub const SSL_VALUE_CLASS_FEATURE_REQUEST: c_uint = 1; + pub const SSL_VALUE_CLASS_FEATURE_PEER_REQUEST: c_uint = 2; + pub const SSL_VALUE_CLASS_FEATURE_NEGOTIATED: c_uint = 3; + + pub const SSL_VALUE_NONE: c_uint = 0; + pub const SSL_VALUE_QUIC_STREAM_BIDI_LOCAL_AVAIL: c_uint = 1; + pub const SSL_VALUE_QUIC_STREAM_BIDI_REMOTE_AVAIL: c_uint = 2; + pub const SSL_VALUE_QUIC_STREAM_UNI_LOCAL_AVAIL: c_uint = 3; + pub const SSL_VALUE_QUIC_STREAM_UNI_REMOTE_AVAIL: c_uint = 4; + pub const SSL_VALUE_QUIC_IDLE_TIMEOUT: c_uint = 5; + pub const SSL_VALUE_EVENT_HANDLING_MODE: c_uint = 6; + pub const SSL_VALUE_STREAM_WRITE_BUF_SIZE: c_uint = 7; + pub const SSL_VALUE_STREAM_WRITE_BUF_USED: c_uint = 8; + pub const SSL_VALUE_STREAM_WRITE_BUF_AVAIL: c_uint = 9; + + pub const SSL_VALUE_EVENT_HANDLING_MODE_INHERIT: c_uint = 0; + pub const SSL_VALUE_EVENT_HANDLING_MODE_IMPLICIT: c_uint = 1; + pub const SSL_VALUE_EVENT_HANDLING_MODE_EXPLICIT: c_uint = 2; + + pub unsafe fn SSL_get_generic_value_uint(ssl: *mut SSL, id: u32, value: *mut u64) -> c_int { + SSL_get_value_uint(ssl, SSL_VALUE_CLASS_GENERIC, id, value) + } + pub unsafe fn SSL_set_generic_value_uint(ssl: *mut SSL, id: u32, value: u64) -> c_int { + SSL_set_value_uint(ssl, SSL_VALUE_CLASS_GENERIC, id, value) + } + pub unsafe fn SSL_get_feature_request_uint(ssl: *mut SSL, id: u32, value: *mut u64) -> c_int { + SSL_get_value_uint(ssl, SSL_VALUE_CLASS_FEATURE_REQUEST, id, value) + } + pub unsafe fn SSL_set_feature_request_uint(ssl: *mut SSL, id: u32, value: u64) -> c_int { + SSL_set_value_uint(ssl, SSL_VALUE_CLASS_FEATURE_REQUEST, id, value) + } + pub unsafe fn SSL_get_feature_peer_request_uint(ssl: *mut SSL, id: u32, value: *mut u64) -> c_int { + SSL_get_value_uint(ssl, SSL_VALUE_CLASS_FEATURE_PEER_REQUEST, id, value) + } + pub unsafe fn SSL_get_feature_negotiated_uint(ssl: *mut SSL, id: u32, value: *mut u64) -> c_int { + SSL_get_value_uint(ssl, SSL_VALUE_CLASS_FEATURE_NEGOTIATED, id, value) + } + pub unsafe fn SSL_get_quic_stream_bidi_local_avail(ssl: *mut SSL, value: *mut u64) -> c_int { + SSL_get_generic_value_uint(ssl, SSL_VALUE_QUIC_STREAM_BIDI_LOCAL_AVAIL, value) + } + pub unsafe fn SSL_get_quic_stream_bidi_remote_avail(ssl: *mut SSL, value: *mut u64) -> c_int { + SSL_get_generic_value_uint(ssl, SSL_VALUE_QUIC_STREAM_BIDI_REMOTE_AVAIL, value) + } + pub unsafe fn SSL_get_quic_stream_uni_local_avail(ssl: *mut SSL, value: *mut u64) -> c_int { + SSL_get_generic_value_uint(ssl, SSL_VALUE_QUIC_STREAM_UNI_LOCAL_AVAIL, value) + } + pub unsafe fn SSL_get_quic_stream_uni_remote_avail(ssl: *mut SSL, value: *mut u64) -> c_int { + SSL_get_generic_value_uint(ssl, SSL_VALUE_QUIC_STREAM_UNI_REMOTE_AVAIL, value) + } + pub unsafe fn SSL_get_event_handling_mode(ssl: *mut SSL, value: *mut u64) -> c_int { + SSL_get_generic_value_uint(ssl, SSL_VALUE_EVENT_HANDLING_MODE, value) + } + pub unsafe fn SSL_set_event_handling_mode(ssl: *mut SSL, value: u64) -> c_int { + SSL_set_generic_value_uint(ssl, SSL_VALUE_EVENT_HANDLING_MODE, value) + } + pub unsafe fn SSL_get_stream_write_buf_size(ssl: *mut SSL, value: *mut u64) -> c_int { + SSL_get_generic_value_uint(ssl, SSL_VALUE_STREAM_WRITE_BUF_SIZE, value) + } + pub unsafe fn SSL_get_stream_write_buf_avail(ssl: *mut SSL, value: *mut u64) -> c_int { + SSL_get_generic_value_uint(ssl, SSL_VALUE_STREAM_WRITE_BUF_AVAIL, value) + } + pub unsafe fn SSL_get_stream_write_buf_used(ssl: *mut SSL, value: *mut u64) -> c_int { + SSL_get_generic_value_uint(ssl, SSL_VALUE_STREAM_WRITE_BUF_USED, value) + } + } +} diff --git a/vendor/openssl-sys/src/ssl3.rs b/vendor/openssl-sys/src/ssl3.rs new file mode 100644 index 0000000..822613e --- /dev/null +++ b/vendor/openssl-sys/src/ssl3.rs @@ -0,0 +1,5 @@ +use libc::*; + +pub const SSL3_VERSION: c_int = 0x300; + +pub const SSL3_AD_ILLEGAL_PARAMETER: c_int = 47; diff --git a/vendor/openssl-sys/src/tls1.rs b/vendor/openssl-sys/src/tls1.rs new file mode 100644 index 0000000..7ff0b9d --- /dev/null +++ b/vendor/openssl-sys/src/tls1.rs @@ -0,0 +1,114 @@ +use libc::*; +use std::mem; +use std::ptr; + +use super::*; + +pub const TLS1_VERSION: c_int = 0x301; +pub const TLS1_1_VERSION: c_int = 0x302; +pub const TLS1_2_VERSION: c_int = 0x303; +#[cfg(any(ossl111, libressl340))] +pub const TLS1_3_VERSION: c_int = 0x304; + +pub const DTLS1_VERSION: c_int = 0xFEFF; +#[cfg(any(ossl102, libressl332))] +pub const DTLS1_2_VERSION: c_int = 0xFEFD; + +pub const TLS1_AD_DECODE_ERROR: c_int = 50; +pub const TLS1_AD_UNRECOGNIZED_NAME: c_int = 112; + +pub const TLSEXT_NAMETYPE_host_name: c_int = 0; +pub const TLSEXT_STATUSTYPE_ocsp: c_int = 1; + +pub unsafe fn SSL_set_tlsext_host_name(s: *mut SSL, name: *mut c_char) -> c_long { + SSL_ctrl( + s, + SSL_CTRL_SET_TLSEXT_HOSTNAME, + TLSEXT_NAMETYPE_host_name as c_long, + name as *mut c_void, + ) +} + +pub unsafe fn SSL_set_tlsext_status_type(s: *mut SSL, type_: c_int) -> c_long { + SSL_ctrl( + s, + SSL_CTRL_SET_TLSEXT_STATUS_REQ_TYPE, + type_ as c_long, + ptr::null_mut(), + ) +} + +pub unsafe fn SSL_get_tlsext_status_ocsp_resp(ssl: *mut SSL, resp: *mut *mut c_uchar) -> c_long { + SSL_ctrl( + ssl, + SSL_CTRL_GET_TLSEXT_STATUS_REQ_OCSP_RESP, + 0, + resp as *mut c_void, + ) +} + +pub unsafe fn SSL_set_tlsext_status_ocsp_resp( + ssl: *mut SSL, + resp: *mut c_uchar, + len: c_long, +) -> c_long { + SSL_ctrl( + ssl, + SSL_CTRL_SET_TLSEXT_STATUS_REQ_OCSP_RESP, + len, + resp as *mut c_void, + ) +} + +#[deprecated(note = "use SSL_CTX_set_tlsext_servername_callback__fixed_rust instead")] +#[allow(deprecated)] +pub unsafe fn SSL_CTX_set_tlsext_servername_callback( + ctx: *mut SSL_CTX, + // FIXME should have the right signature + cb: Option, +) -> c_long { + SSL_CTX_callback_ctrl(ctx, SSL_CTRL_SET_TLSEXT_SERVERNAME_CB, cb) +} + +pub unsafe fn SSL_CTX_set_tlsext_servername_callback__fixed_rust( + ctx: *mut SSL_CTX, + cb: Option c_int>, +) -> c_long { + SSL_CTX_callback_ctrl__fixed_rust( + ctx, + SSL_CTRL_SET_TLSEXT_SERVERNAME_CB, + mem::transmute::< + std::option::Option< + unsafe extern "C" fn(*mut SSL, *mut c_int, *mut libc::c_void) -> i32, + >, + std::option::Option, + >(cb), + ) +} + +pub const SSL_TLSEXT_ERR_OK: c_int = 0; +pub const SSL_TLSEXT_ERR_ALERT_WARNING: c_int = 1; +pub const SSL_TLSEXT_ERR_ALERT_FATAL: c_int = 2; +pub const SSL_TLSEXT_ERR_NOACK: c_int = 3; + +pub unsafe fn SSL_CTX_set_tlsext_servername_arg(ctx: *mut SSL_CTX, arg: *mut c_void) -> c_long { + SSL_CTX_ctrl(ctx, SSL_CTRL_SET_TLSEXT_SERVERNAME_ARG, 0, arg) +} + +pub unsafe fn SSL_CTX_set_tlsext_status_cb( + ctx: *mut SSL_CTX, + cb: Option c_int>, +) -> c_long { + SSL_CTX_callback_ctrl__fixed_rust( + ctx, + SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB, + mem::transmute::< + std::option::Option i32>, + std::option::Option, + >(cb), + ) +} + +pub unsafe fn SSL_CTX_set_tlsext_status_arg(ctx: *mut SSL_CTX, arg: *mut c_void) -> c_long { + SSL_CTX_ctrl(ctx, SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB_ARG, 0, arg) +} diff --git a/vendor/openssl-sys/src/types.rs b/vendor/openssl-sys/src/types.rs new file mode 100644 index 0000000..10c8f67 --- /dev/null +++ b/vendor/openssl-sys/src/types.rs @@ -0,0 +1,21 @@ +use libc::*; + +use super::*; + +cfg_if! { + if #[cfg(any(ossl110, libressl280))] { + pub enum EVP_PKEY {} + } else { + #[repr(C)] + pub struct EVP_PKEY { + pub type_: c_int, + pub save_type: c_int, + pub references: c_int, + pub ameth: *const EVP_PKEY_ASN1_METHOD, + pub engine: *mut ENGINE, + pub pkey: *mut c_void, + pub save_parameters: c_int, + pub attributes: *mut stack_st_X509_ATTRIBUTE, + } + } +} diff --git a/vendor/openssl-sys/src/x509.rs b/vendor/openssl-sys/src/x509.rs new file mode 100644 index 0000000..714b06c --- /dev/null +++ b/vendor/openssl-sys/src/x509.rs @@ -0,0 +1,15 @@ +use libc::*; + +pub const X509_FILETYPE_PEM: c_int = 1; +pub const X509_FILETYPE_ASN1: c_int = 2; +pub const X509_FILETYPE_DEFAULT: c_int = 3; + +pub const ASN1_R_HEADER_TOO_LONG: c_int = 123; + +cfg_if! { + if #[cfg(not(any(ossl110, libressl350)))] { + pub const X509_LU_FAIL: c_int = 0; + pub const X509_LU_X509: c_int = 1; + pub const X509_LU_CRL: c_int = 2; + } +} diff --git a/vendor/openssl-sys/src/x509_vfy.rs b/vendor/openssl-sys/src/x509_vfy.rs new file mode 100644 index 0000000..2fa176f --- /dev/null +++ b/vendor/openssl-sys/src/x509_vfy.rs @@ -0,0 +1,149 @@ +use libc::*; + +use super::*; + +pub const X509_V_OK: c_int = 0; +#[cfg(ossl102f)] +pub const X509_V_ERR_UNSPECIFIED: c_int = 1; +pub const X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT: c_int = 2; +pub const X509_V_ERR_UNABLE_TO_GET_CRL: c_int = 3; +pub const X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE: c_int = 4; +pub const X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE: c_int = 5; +pub const X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY: c_int = 6; +pub const X509_V_ERR_CERT_SIGNATURE_FAILURE: c_int = 7; +pub const X509_V_ERR_CRL_SIGNATURE_FAILURE: c_int = 8; +pub const X509_V_ERR_CERT_NOT_YET_VALID: c_int = 9; +pub const X509_V_ERR_CERT_HAS_EXPIRED: c_int = 10; +pub const X509_V_ERR_CRL_NOT_YET_VALID: c_int = 11; +pub const X509_V_ERR_CRL_HAS_EXPIRED: c_int = 12; +pub const X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD: c_int = 13; +pub const X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD: c_int = 14; +pub const X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD: c_int = 15; +pub const X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD: c_int = 16; +pub const X509_V_ERR_OUT_OF_MEM: c_int = 17; +pub const X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT: c_int = 18; +pub const X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN: c_int = 19; +pub const X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY: c_int = 20; +pub const X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE: c_int = 21; +pub const X509_V_ERR_CERT_CHAIN_TOO_LONG: c_int = 22; +pub const X509_V_ERR_CERT_REVOKED: c_int = 23; +cfg_if! { + if #[cfg(ossl300)] { + pub const X509_V_ERR_NO_ISSUER_PUBLIC_KEY: c_int = 24; + } else { + pub const X509_V_ERR_INVALID_CA: c_int = 24; + } +} +pub const X509_V_ERR_PATH_LENGTH_EXCEEDED: c_int = 25; +pub const X509_V_ERR_INVALID_PURPOSE: c_int = 26; +pub const X509_V_ERR_CERT_UNTRUSTED: c_int = 27; +pub const X509_V_ERR_CERT_REJECTED: c_int = 28; +pub const X509_V_ERR_SUBJECT_ISSUER_MISMATCH: c_int = 29; +pub const X509_V_ERR_AKID_SKID_MISMATCH: c_int = 30; +pub const X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH: c_int = 31; +pub const X509_V_ERR_KEYUSAGE_NO_CERTSIGN: c_int = 32; +pub const X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER: c_int = 33; +pub const X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION: c_int = 34; +pub const X509_V_ERR_KEYUSAGE_NO_CRL_SIGN: c_int = 35; +pub const X509_V_ERR_UNHANDLED_CRITICAL_CRL_EXTENSION: c_int = 36; +pub const X509_V_ERR_INVALID_NON_CA: c_int = 37; +pub const X509_V_ERR_PROXY_PATH_LENGTH_EXCEEDED: c_int = 38; +pub const X509_V_ERR_KEYUSAGE_NO_DIGITAL_SIGNATURE: c_int = 39; +pub const X509_V_ERR_PROXY_CERTIFICATES_NOT_ALLOWED: c_int = 40; +pub const X509_V_ERR_INVALID_EXTENSION: c_int = 41; +pub const X509_V_ERR_INVALID_POLICY_EXTENSION: c_int = 42; +pub const X509_V_ERR_NO_EXPLICIT_POLICY: c_int = 43; +pub const X509_V_ERR_DIFFERENT_CRL_SCOPE: c_int = 44; +pub const X509_V_ERR_UNSUPPORTED_EXTENSION_FEATURE: c_int = 45; +pub const X509_V_ERR_UNNESTED_RESOURCE: c_int = 46; +pub const X509_V_ERR_PERMITTED_VIOLATION: c_int = 47; +pub const X509_V_ERR_EXCLUDED_VIOLATION: c_int = 48; +pub const X509_V_ERR_SUBTREE_MINMAX: c_int = 49; +pub const X509_V_ERR_APPLICATION_VERIFICATION: c_int = 50; +pub const X509_V_ERR_UNSUPPORTED_CONSTRAINT_TYPE: c_int = 51; +pub const X509_V_ERR_UNSUPPORTED_CONSTRAINT_SYNTAX: c_int = 52; +pub const X509_V_ERR_UNSUPPORTED_NAME_SYNTAX: c_int = 53; +pub const X509_V_ERR_CRL_PATH_VALIDATION_ERROR: c_int = 54; +#[cfg(ossl102)] +pub const X509_V_ERR_SUITE_B_INVALID_VERSION: c_int = 56; +#[cfg(ossl102)] +pub const X509_V_ERR_SUITE_B_INVALID_ALGORITHM: c_int = 57; +#[cfg(ossl102)] +pub const X509_V_ERR_SUITE_B_INVALID_CURVE: c_int = 58; +#[cfg(ossl102)] +pub const X509_V_ERR_SUITE_B_INVALID_SIGNATURE_ALGORITHM: c_int = 59; +#[cfg(ossl102)] +pub const X509_V_ERR_SUITE_B_LOS_NOT_ALLOWED: c_int = 60; +#[cfg(ossl102)] +pub const X509_V_ERR_SUITE_B_CANNOT_SIGN_P_384_WITH_P_256: c_int = 61; +#[cfg(ossl102)] +pub const X509_V_ERR_HOSTNAME_MISMATCH: c_int = 62; +#[cfg(ossl102)] +pub const X509_V_ERR_EMAIL_MISMATCH: c_int = 63; +#[cfg(ossl102)] +pub const X509_V_ERR_IP_ADDRESS_MISMATCH: c_int = 64; +cfg_if! { + if #[cfg(ossl110)] { + pub const X509_V_ERR_DANE_NO_MATCH: c_int = 65; + pub const X509_V_ERR_EE_KEY_TOO_SMALL: c_int = 66; + pub const X509_V_ERR_CA_KEY_TOO_SMALL: c_int = 67; + pub const X509_V_ERR_CA_MD_TOO_WEAK: c_int = 68; + pub const X509_V_ERR_INVALID_CALL: c_int = 69; + pub const X509_V_ERR_STORE_LOOKUP: c_int = 70; + pub const X509_V_ERR_NO_VALID_SCTS: c_int = 71; + } else if #[cfg(ossl102h)] { + pub const X509_V_ERR_INVALID_CALL: c_int = 65; + pub const X509_V_ERR_STORE_LOOKUP: c_int = 66; + pub const X509_V_ERR_PROXY_SUBJECT_NAME_VIOLATION: c_int = 67; + } +} +#[cfg(ossl300)] +pub const X509_V_ERR_INVALID_CA: c_int = 79; + +#[cfg(not(any(ossl110, libressl370)))] +pub const X509_V_FLAG_CB_ISSUER_CHECK: c_ulong = 0x1; +#[cfg(any(ossl110, libressl370))] +pub const X509_V_FLAG_CB_ISSUER_CHECK: c_ulong = 0x0; +pub const X509_V_FLAG_USE_CHECK_TIME: c_ulong = 0x2; +pub const X509_V_FLAG_CRL_CHECK: c_ulong = 0x4; +pub const X509_V_FLAG_CRL_CHECK_ALL: c_ulong = 0x8; +pub const X509_V_FLAG_IGNORE_CRITICAL: c_ulong = 0x10; +pub const X509_V_FLAG_X509_STRICT: c_ulong = 0x20; +pub const X509_V_FLAG_ALLOW_PROXY_CERTS: c_ulong = 0x40; +pub const X509_V_FLAG_POLICY_CHECK: c_ulong = 0x80; +pub const X509_V_FLAG_EXPLICIT_POLICY: c_ulong = 0x100; +pub const X509_V_FLAG_INHIBIT_ANY: c_ulong = 0x200; +pub const X509_V_FLAG_INHIBIT_MAP: c_ulong = 0x400; +pub const X509_V_FLAG_NOTIFY_POLICY: c_ulong = 0x800; +pub const X509_V_FLAG_EXTENDED_CRL_SUPPORT: c_ulong = 0x1000; +pub const X509_V_FLAG_USE_DELTAS: c_ulong = 0x2000; +pub const X509_V_FLAG_CHECK_SS_SIGNATURE: c_ulong = 0x4000; +#[cfg(ossl102)] +pub const X509_V_FLAG_TRUSTED_FIRST: c_ulong = 0x8000; +#[cfg(ossl102)] +pub const X509_V_FLAG_SUITEB_128_LOS_ONLY: c_ulong = 0x10000; +#[cfg(ossl102)] +pub const X509_V_FLAG_SUITEB_192_LOS: c_ulong = 0x20000; +#[cfg(ossl102)] +pub const X509_V_FLAG_SUITEB_128_LOS: c_ulong = 0x30000; +#[cfg(ossl102)] +pub const X509_V_FLAG_PARTIAL_CHAIN: c_ulong = 0x80000; +#[cfg(ossl110)] +pub const X509_V_FLAG_NO_ALT_CHAINS: c_ulong = 0x100000; +#[cfg(ossl110)] +pub const X509_V_FLAG_NO_CHECK_TIME: c_ulong = 0x200000; + +pub unsafe fn X509_LOOKUP_add_dir( + ctx: *mut X509_LOOKUP, + name: *const c_char, + _type: c_int, +) -> c_int { + const X509_L_ADD_DIR: c_int = 2; + X509_LOOKUP_ctrl( + ctx, + X509_L_ADD_DIR, + name, + _type as c_long, + std::ptr::null_mut(), + ) +} diff --git a/vendor/openssl-sys/src/x509v3.rs b/vendor/openssl-sys/src/x509v3.rs new file mode 100644 index 0000000..230dea1 --- /dev/null +++ b/vendor/openssl-sys/src/x509v3.rs @@ -0,0 +1,112 @@ +use libc::*; + +use super::*; + +#[repr(C)] +pub struct GENERAL_NAME { + pub type_: c_int, + // FIXME should be a union + pub d: *mut c_void, +} + +stack!(stack_st_GENERAL_NAME); + +pub const GEN_OTHERNAME: c_int = 0; +pub const GEN_EMAIL: c_int = 1; +pub const GEN_DNS: c_int = 2; +pub const GEN_X400: c_int = 3; +pub const GEN_DIRNAME: c_int = 4; +pub const GEN_EDIPARTY: c_int = 5; +pub const GEN_URI: c_int = 6; +pub const GEN_IPADD: c_int = 7; +pub const GEN_RID: c_int = 8; + +#[cfg(any(ossl102, libressl261))] +pub const X509_CHECK_FLAG_ALWAYS_CHECK_SUBJECT: c_uint = 0x1; +#[cfg(any(ossl102, libressl261))] +pub const X509_CHECK_FLAG_NO_WILDCARDS: c_uint = 0x2; +#[cfg(any(ossl102, libressl261))] +pub const X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS: c_uint = 0x4; +#[cfg(any(ossl102, libressl261))] +pub const X509_CHECK_FLAG_MULTI_LABEL_WILDCARDS: c_uint = 0x8; +#[cfg(any(ossl102, libressl261))] +pub const X509_CHECK_FLAG_SINGLE_LABEL_SUBDOMAINS: c_uint = 0x10; +#[cfg(ossl110)] +pub const X509_CHECK_FLAG_NEVER_CHECK_SUBJECT: c_uint = 0x20; + +pub const X509V3_ADD_DEFAULT: c_ulong = 0; +pub const X509V3_ADD_APPEND: c_ulong = 1; +pub const X509V3_ADD_REPLACE: c_ulong = 2; +pub const X509V3_ADD_REPLACE_EXISTING: c_ulong = 3; +pub const X509V3_ADD_KEEP_EXISTING: c_ulong = 4; +pub const X509V3_ADD_DELETE: c_ulong = 5; +pub const X509V3_ADD_SILENT: c_ulong = 0x10; + +pub const EXFLAG_BCONS: u32 = 0x1; +pub const EXFLAG_KUSAGE: u32 = 0x2; +pub const EXFLAG_XKUSAGE: u32 = 0x4; +pub const EXFLAG_NSCERT: u32 = 0x8; +pub const EXFLAG_CA: u32 = 0x10; +pub const EXFLAG_SI: u32 = 0x20; +pub const EXFLAG_V1: u32 = 0x40; +pub const EXFLAG_INVALID: u32 = 0x80; +pub const EXFLAG_SET: u32 = 0x100; +pub const EXFLAG_CRITICAL: u32 = 0x200; +pub const EXFLAG_PROXY: u32 = 0x400; +pub const EXFLAG_INVALID_POLICY: u32 = 0x800; +pub const EXFLAG_FRESHEST: u32 = 0x1000; +#[cfg(any(ossl102, libressl261))] +pub const EXFLAG_SS: u32 = 0x2000; + +pub const X509v3_KU_DIGITAL_SIGNATURE: u32 = 0x0080; +pub const X509v3_KU_NON_REPUDIATION: u32 = 0x0040; +pub const X509v3_KU_KEY_ENCIPHERMENT: u32 = 0x0020; +pub const X509v3_KU_DATA_ENCIPHERMENT: u32 = 0x0010; +pub const X509v3_KU_KEY_AGREEMENT: u32 = 0x0008; +pub const X509v3_KU_KEY_CERT_SIGN: u32 = 0x0004; +pub const X509v3_KU_CRL_SIGN: u32 = 0x0002; +pub const X509v3_KU_ENCIPHER_ONLY: u32 = 0x0001; +pub const X509v3_KU_DECIPHER_ONLY: u32 = 0x8000; +pub const X509v3_KU_UNDEF: u32 = 0xffff; + +pub const XKU_SSL_SERVER: u32 = 0x1; +pub const XKU_SSL_CLIENT: u32 = 0x2; +pub const XKU_SMIME: u32 = 0x4; +pub const XKU_CODE_SIGN: u32 = 0x8; +pub const XKU_SGC: u32 = 0x10; +pub const XKU_OCSP_SIGN: u32 = 0x20; +pub const XKU_TIMESTAMP: u32 = 0x40; +pub const XKU_DVCS: u32 = 0x80; +#[cfg(ossl110)] +pub const XKU_ANYEKU: u32 = 0x100; + +pub const X509_PURPOSE_SSL_CLIENT: c_int = 1; +pub const X509_PURPOSE_SSL_SERVER: c_int = 2; +pub const X509_PURPOSE_NS_SSL_SERVER: c_int = 3; +pub const X509_PURPOSE_SMIME_SIGN: c_int = 4; +pub const X509_PURPOSE_SMIME_ENCRYPT: c_int = 5; +pub const X509_PURPOSE_CRL_SIGN: c_int = 6; +pub const X509_PURPOSE_ANY: c_int = 7; +pub const X509_PURPOSE_OCSP_HELPER: c_int = 8; +pub const X509_PURPOSE_TIMESTAMP_SIGN: c_int = 9; +#[cfg(ossl320)] +pub const X509_PURPOSE_CODE_SIGN: c_int = 10; +pub const X509_PURPOSE_MIN: c_int = 1; +cfg_if! { + if #[cfg(ossl320)] { + pub const X509_PURPOSE_MAX: c_int = 10; + } else { + pub const X509_PURPOSE_MAX: c_int = 9; + } +} + +pub const CRL_REASON_UNSPECIFIED: c_int = 0; +pub const CRL_REASON_KEY_COMPROMISE: c_int = 1; +pub const CRL_REASON_CA_COMPROMISE: c_int = 2; +pub const CRL_REASON_AFFILIATION_CHANGED: c_int = 3; +pub const CRL_REASON_SUPERSEDED: c_int = 4; +pub const CRL_REASON_CESSATION_OF_OPERATION: c_int = 5; +pub const CRL_REASON_CERTIFICATE_HOLD: c_int = 6; +pub const CRL_REASON_REMOVE_FROM_CRL: c_int = 8; +pub const CRL_REASON_PRIVILEGE_WITHDRAWN: c_int = 9; +pub const CRL_REASON_AA_COMPROMISE: c_int = 10; diff --git a/vendor/openssl/.cargo-checksum.json b/vendor/openssl/.cargo-checksum.json new file mode 100644 index 0000000..d1d7757 --- /dev/null +++ b/vendor/openssl/.cargo-checksum.json @@ -0,0 +1 @@ +{"files":{"CHANGELOG.md":"dc9ceddf128c267cab5a69dfb46e2c296afb335fa81ef45194e8ab38245fad44","Cargo.lock":"748c0d2f852b59ae148f4f62fbc8aa0bcd77e647116fb89c6e704d787e7e812c","Cargo.toml":"8f2810f34e367478a4a35e00a907f57290595b524bb47c8455fbb387e5e1860a","LICENSE":"f3d4287b4a21c5176fea2f9bd4ae800696004e2fb8e05cbc818be513f188a941","README.md":"c5ddde25c2756a1115daaa671fb4297cdc83bf23009c8356ba65b5311d0dd30d","build.rs":"03a49462e8e59eff6367bad6dfe2a7684203689e6fad5d2733ad9063284856ea","examples/mk_certs.rs":"012569fc734c314c5d3c1c9dc8ae64a32db4cfa917e8fbc363c1eef118600d0a","src/aes.rs":"c1ad71fc0a76dd7fbb07864583e47c7da8764f8e6029a4ff8c310bf2fde63e15","src/asn1.rs":"ebf14c9c07e9c3e05a2d04aaa4d24c96eb1730ce29ab3d8b7d485642e3d88752","src/base64.rs":"9087b546206c3a824aec3af6cf0e54d890515cc62d859951fd46ef72fbeba3aa","src/bio.rs":"df2f33abe39f822d73dd552820dfeaa1dbc6f752fbf50c3827a4bf45a1fd66b8","src/bn.rs":"fa7a2cb1d06dfcb6213f3507d938892cd82654c2caf765ccf17ada032adad901","src/cipher.rs":"3bf4595773be7c5f292b671c9272979d2b300b0e2961e14d3aa0d1c03a24b83d","src/cipher_ctx.rs":"302c71044eea2137bfbe46fcd13aa824823db552613966078a83857428936ec6","src/cms.rs":"0dfa2f1134b84de1c7c9a8ad78ad2b8cd773cea75c9b80cf57bcf181f7ed4573","src/conf.rs":"ba31a8ea546e3276db3a46f0e12767acc21e050f5bf7cf2bdd5bfdccb62d1bf7","src/derive.rs":"ccb6087ac9f51330a292d02d2c4ec80784bbb2fb9c4beb46f7d5484961303340","src/dh.rs":"e9fc6d5910241a6cba0b7c6ce4139ba8cbd04be7de5c92a479406ddc79a581cd","src/dsa.rs":"10b6aca140fe332cb35c78cb3b0e9f1aa7cf18971059ac93a9a458481de26f85","src/ec.rs":"43142ab898dd4dc25efd7cd5c081be4f1a65c39d48e715fa3a208c7a2c5cb534","src/ecdsa.rs":"895136cad2a938f6a274e56fe2218e0bf066d4df33f5ad77c98d50921a25f50a","src/encrypt.rs":"c29ef5ad919e7fdaf608ddeea7a89e58d091e6aef5a8dde62097dc6ecd6ff405","src/envelope.rs":"d842c52a3297620121446514b57b6441e88faf5c48d98ae723f4e05164ea0a2b","src/error.rs":"ede27beebf1594a9165f16aa8732816f28501a8454d3125b6eb5ce98756e0255","src/ex_data.rs":"0a58a3a274a4ef2251dadb64cbcd44b43710d252201b137ecfb91cf14373c04f","src/fips.rs":"761cd7cdfbc16af88fbfefd38e54cb77b4ba8e2f49221607e145bc541f089d7e","src/hash.rs":"3372f06080c31f92dbdb1d921dddf8ee34eff09ca5ef243f07b28e90a5c0c66d","src/kdf.rs":"52e2430f4351c7e507c68350fdc6f270ddd54731ddc5bbb61f0723417ff1215c","src/lib.rs":"c6834466448e5419200e049923eeb8541cf0ee24b4bdd5f07dc438193d945649","src/lib_ctx.rs":"ec6431adad53f3a9621b011506678104bd4f62bdea38ef9d1b731334507ab068","src/macros.rs":"fc83887358d36f7edd61f2718e0d7a83161b1c23eccbf782fd2918b34a8f5a12","src/md.rs":"fd241588f1c5860ee43b1abd74952a74e2c0432c045ded4b2950a419bb4597ee","src/md_ctx.rs":"e9ee7267b5511f8da9b8c9bfb76ef89f16c9ca7810d5ce2febe2a7b60aa9f717","src/memcmp.rs":"f48e0e29f372db2d0eb2239290abec8819300eb3e01e3bb1030783d6f6a8b2c9","src/nid.rs":"17d408c10e4ee5a3666db5c9a2a2a614c0cec19e4da4b2cd058dafde95903398","src/ocsp.rs":"d7dc1c37bdab7d1633958d310a792261ca03ca20068663f235208f513eb009bd","src/pkcs12.rs":"b4171fa4423eaf8e1b060cf68f9b85fe0bc84d6c5fe23dabf3ddb0fed9a8cb23","src/pkcs5.rs":"5afbbb784714cde2fb39b34c867db7a600c0cd0f1173d1971ec645f9c3376caf","src/pkcs7.rs":"24431303749047c08aad278f53ea47d6e47130318d368dd5213194e27bd58620","src/pkey.rs":"c500536756324354aa698509ca03f488cf180e3eba9c3b1ba198e68b991eb22f","src/pkey_ctx.rs":"0da4de8cc6cd814133a96a941ace5dbc76ea8b19f145ae71a150f32e2397aa8a","src/provider.rs":"5ab0b25e8866ecea327ad764d44594912f1dc09eb73c3ed5db134714e9f4b73e","src/rand.rs":"4007c6e88a8e875fb8eb475895ba5579e2e789634536303ea8e99ec1866b71a3","src/rsa.rs":"0aa58f0dc0bbae38c96c6a8e25650892a95296df8faeb4894d31e76b22261fb2","src/sha.rs":"c34f2f9df5fb52b578022568e195e011d0967f9f5ff57b559d7d2a235951a5b9","src/sign.rs":"de988ea05addee3b9252d06e9bb623c2d573deef787087ef4f8ceb99232a83fa","src/srtp.rs":"3defe1815cfc790e2407ff935f8ca7b0e8d504242886e8841715279e0d85f721","src/ssl/bio.rs":"2b4afa060cfe663cab49aa10249609ad9a56872b47418bfea79f64d1d5e98b5c","src/ssl/callbacks.rs":"2aa0b737816117979f6ffcfe9537f4bf0ef47012c23b9f2728224b1db3fd9447","src/ssl/connector.rs":"32afe0925584b349b3595aaabd0dadbf6ab383b5879c49c68ad2d0fddf0b0e4a","src/ssl/error.rs":"f39ac3e1037a35ae5cccbf5cf5976044614a6368c9ffe3f1b96bead63c0c4231","src/ssl/mod.rs":"c56c2dc6bbb1108ca8e14a6ab13892651f0f64c98aac78f34f84324c91e799e5","src/ssl/test/mod.rs":"9b3d722b9ce280d0786c81c23a46d35575eb25b8298e507c48c1d7af828a558a","src/ssl/test/server.rs":"4276ba970a0fac5c9cae21d7df7af36389c377472f3546ce597678ffc6ad5b38","src/stack.rs":"c901d803adab5633db011b25a996ba75018d88a311b55a4ab011d42f81738412","src/string.rs":"8276d719b35cd74ee0efbecce9e58e754d50d8cc96111f2febd3c0d8849847a8","src/symm.rs":"324b95644e89b03724ef502e4f7fbca924345a5f411943e208ec3ee29048c5c6","src/util.rs":"09701e853997f00c46336da9cff99142b22af5a20f6284ed6a8c597c238e8ad6","src/version.rs":"0b8e6e227ac4b9ae20ec9cd816c98d9fe1a5a0d1f81be87db64915bc13dec72d","src/x509/extension.rs":"26a265248eb0e54c3b106708f8fce7d5fb5b91b7195f17a97e1b8b1d3b6fa119","src/x509/mod.rs":"3c25807860d1e26e7feb1882df010d9cc4ca5a6a16d059ce5bdc2e1efdd583a0","src/x509/store.rs":"e42823f931ce2b6e4bac5f7314f3790c70dd12002398da03a2ebecd96f248c98","src/x509/tests.rs":"efd1573171de75b70416a8d2f708e457601fc64c472fdb5507e32f74f4968fd0","src/x509/verify.rs":"9db665ffccecfd8a29874f8f4b0b3c09d195899daaa927dffdf57d6e9d32403e","test/aia_test_cert.pem":"9eaf52b5d0023f3be7911938d937ed16fc75d43d14dbe41557a800b0a82f4b1b","test/alt_name_cert.pem":"f3cc0a1d21657164918dffab0dac8f1c499fc1cf5717805420a0134b3aee128c","test/authority_key_identifier.pem":"4644b83bbcd36a6e1917d1f7bd3b8ff913bf86cc74917c07dd78b6731b4d5bec","test/ca.crt":"70bcf52acc79191409801e72371db3a0cd8a27c0fc24eacb3fb8f8ab3e558f67","test/cert.pem":"53c8b338be254490c71a6b13da90dc5a59ba596587c548be5673657e04824afb","test/certs.pem":"106d5d22c86e26c3db619b9525567f22333d22de82e4d2850ed379150c638008","test/certv3.pem":"c230b76b6efb973816d0e3096ae95cdcf4941ec928c01c31b6537d01743fcd8a","test/certv3_extfile":"610fdc10edac2da398a582895e53d288d3e47a9d4f3868c2c7f7662c212b60bd","test/cms.p12":"d33fc5edd6b9caa672e7570b869135235bb2583580a273f6e88c6a6c68fd5a8a","test/cms_pubkey.der":"03682a732e1fd861f5fa687915a8e6f5c935d10273b0f6f73f3db52a8d71fc6d","test/corrupted-rsa.pem":"cff269f11b8db1222ae94a5bdfb16b5d4795c23cac7250ebe2c892a2428f5890","test/crl-ca.crt":"911360ccdf700fd7d6091bd78c4138da0e9f027ca211f7ed80b394e570eb897c","test/csr.pem":"24423008144c43cf33f56ebcc245931b2d61bcd4eee17b476d7adb6f7416e24d","test/dhparams.pem":"14d9461949d9ae8ca50a393b008ee2168254f14342b0e17b56c0a62d2905b963","test/dsa.pem":"826d513234205fd3dee0bbbf844f0b6fea501145bdf05ea3b14e14df98cbe090","test/dsa.pem.pub":"721677bebf9ab28b8650f98a0cd27658de0c1acd867a4b6e985fe1df95a8bd37","test/dsaparam.pem":"94a1284bdd7d7566151cfde0c7f245e84f7b99ba840f202e3f27ea0160f82988","test/entry_extensions.crl":"bee73d33a326bde92d3c38f275b3f94943e46cf778d7043e1176e84413dc22e9","test/identity.p12":"aceeb3e5516471bd5af9a44bbeffc9559c4f228f67c677d29f36a4b368e2779f","test/intermediate-ca.key":"a5f3d331af87c1305843e235841e494a0669a95d3824a6c766d09371f62c3bab","test/intermediate-ca.pem":"5ff8055325d0cbb60586f4e20bd2df7718e4d94f5261f2ee05ba52a8fb9223f0","test/key.der":"e8842cd6674b5c77a83e0283cd876a91de404561dfc86d79ce525f6e55b28197","test/key.der.pub":"e559d56bb6ec57ad743dbf972bbcaf263a9fa7d320433baa71b04f849d987060","test/key.pem":"12d9105a92bf39b615ccb4820c5c1e38c61905483cd30be13f9ab99b98af64ed","test/key.pem.pub":"f5d030df843ddbaba5bf316ae18f1434de5a63a955be66442429dd4f16f161ef","test/keystore-empty-chain.p12":"bbea280f6fe10556d7470df7072ef0e4ee3997e2c0b3666197f423430c0e6b61","test/leaf.pem":"4f2c3fd02f73b3f49a1e05cf0622669ed014ba019876d89d3f21c788457c1e01","test/nid_test_cert.pem":"7047e8d317e284c6b698eee4a0f1a629d50cd4615ad7da85fe90a2ffb6c21611","test/nid_uid_test_cert.pem":"a735211f3b40edbde7084337138fb0aea06aea6c78369c52015253e4b7a17d83","test/pkcs1.pem.pub":"4d446864b63c4178ec2c7dc8df9b7121d9271851c1f4701231fccb8b07c94918","test/pkcs8-nocrypt.der":"5590d03cc0d037c6c27d78fafc937f48defb226e9a52cde84d54df68086d0575","test/pkcs8.der":"8719fc002d59313fb97e46e068ae40db4d9acc0e2debd308ac9eb46329bea487","test/root-ca.key":"b37cf88614980c38e43c4329cdf7162bae48cc8af1fafd54db2fe0d17e458e1d","test/root-ca.pem":"59b9200c35e818bf21be4aaa97ba87bb6a18fd780527a9f9c51cc74212c631a0","test/rsa-encrypted.pem":"ea41b0f1816056672de6abbab43d0e8089da047c329ceed14aace5a5bde713f1","test/rsa.pem":"f866a5506ea9a37ed2f73f62f503e1aff32f7e4145be62b023535f4da1c24416","test/rsa.pem.pub":"2c5eeea39708e90396f9f09d920f2af8b7e9f84ace963c1319072224dd3d302b","test/subca.crt":"70bcf52acc79191409801e72371db3a0cd8a27c0fc24eacb3fb8f8ab3e558f67","test/test.crl":"ac8443257214f9e82543871c3df48694ea39f2b16bd6c4ef5998a161edbb8fba"},"package":"6174bc48f102d208783c2c84bf931bb75927a617866870de8a4ea85597f871f5"} \ No newline at end of file diff --git a/vendor/openssl/CHANGELOG.md b/vendor/openssl/CHANGELOG.md new file mode 100644 index 0000000..e939d47 --- /dev/null +++ b/vendor/openssl/CHANGELOG.md @@ -0,0 +1,1004 @@ +# Change Log + +## [Unreleased] + +## [v0.10.68] - 2024-10-16 + +### Fixed + +* Fixed building on Rust 1.63.0 (our MSRV) with OpenSSL 3.2 or newer. + +## [v0.10.67] - 2024-10-15 + +### Added + +* Added support for LibreSSL 4.0.x. +* Added `argon2id` + +### Fixed + +* Fixed a case where `MdCtxRef::digest_verify_final` could leave an error on the stack. +* Fixed a case where `RsaRef::check_key` could leave an errror on the stack. + +### Changed + +* `openssl` is now a 2021 edition crate +* Explicitly specify the MSRV in `Cargo.toml` + +## [v0.10.66] - 2024-07-21 + +### Fixed + +- Fixed undefined behavior in `MemBio::get_buf` when the resulting buffer had a length of 0. + +## [v0.10.65] - 2024-07-20 + +### Fixed + +* Ensure we are initialized in `MessageDigest::from_nid`, `Md::from_nid`, `Md::fetch` + +### Changed + +* Expose `SslContextBuilder::set_keylog_callback` on BoringSSL + +## [v0.10.64] - 2024-02-19 + +### Added + +* Added `PkeyCtxRef::{nonce_type, set_nonce_type}`. +* Added `X509Ref::alias`. + + +## [v0.10.63] - 2024-01-19 + +### Added + +* Added `Pkcs7Ref::{type_,signed}`. +* Added `Pkcs7SignedRef::certificates`. +* Added `Cipher::{aes_256_xts,des_ede3_ecb,des_ede3_cfb8,des_ede3_ofb,camellia128_ofb,camellia192_ofb,camellia256_ofb,cast5_ofb,idea_ofb}` +* Added `PKey::from_dhx` +* Added `PKey::{public_key_from_pem_passphrase,public_key_from_pem_callback}`. + +### Changed + +* `Cipher::aes_128_ofb` is now available on BoringSSL +* `Nid::{BRAINPOOL_P256R1,BRAINPOOL_P320R1,BRAINPOOL_P384R1,BRAINPOOL_P512R1}` are now available on LibreSSL. + +## [v0.10.62] - 2023-12-22 + +### Added + +* Added `Nid::BRAINPOOL_P320R1` +* Added `rand_priv_bytes` + +### Fixed + +* Fixed building on the latest version of BoringSSL + +## [v0.10.61] - 2023-12-04 + +### Changed + +* `SslStream` now uses `SSL_read_ex`, `SSL_write_ex`, and `SSL_peek_ex` when available + +### Added + +* Added `SslStream::{read_uninit, ssl_read_uninit}`. + +## [v0.10.60] - 2023-11-22 + +### Deprecated + +* Deprecated `X509StoreRef::objects`. It is unsound. All callers should migrate to using `X509StoreRef::all_certificates` instead. + +### Fixed + +* Fixed a memory leak when calling `SslContextBuilder::set_ex_data` and `SslRef::set_ex_data` multiple times with the same index. + +### Added + +* Added `X509StoreRef::all_certificates` +* Added `cipher::Cipher::{camellia128_cbc,camellia192_cbc,camellia256_cbc,cast5_cbc,idea_cbc}` +* Added `symm::Cipher::{des_ede3_ecb,des_ede3_cfb8,des_ede3_ofb,camellia_128_ecb,camellia_128_ofb,camellia_128_cfb128,camellia_192_ecb,camellia_192_ofb,camellia_192_cfb128,camellia_256_ecb,camellia_256_ofb,camellia_256_cfb128,cast5_ecb,cast5_ofb,cast5_cfb64,idea_ecb,idea_ofb,idea_cfb64}` +* Added `Crypter::update_unchecked` +* Added `SslRef::{peer_tmp_key,tmp_key}` + +### Changed + +* `cipher::Cipher::chacha20` is now available on LibreSSL +* `symm::Cipher::chacha20` is now available on LibreSSL + +## [v0.10.59] - 2023-11-03 + +### Added + +* Added `Nid::CHACHA20_POLY1305` + +### Changed + +* Fixed the availability of `Id::RSA_PSS` on OpenSSL + +## [v0.10.58] - 2023-11-01 + +### Added + +* Added `Id::{RSA_PSS,DHX}` constants +* Added `SslContextBuilder::set_security_level` +* Added `SslContextRef::security_level` +* Added `SslRef::set_security_level`, `SslRef::security_level` +* Added `Cipher::{camellia_128_cbc, camellia_192_cbc, camellia_256_cbc, cast5_cbc, idea_cbc}` +* Added `X509CrlRef::extension` +* Added `X509PurposeId::CODE_SIGN` + +### Changed + +* `Pkey` HKDF functionality now works on LibreSSL +* `BigNum::mod_sqrt` is now available on all OpenSSLs +* `MessageDigest::sha3*` are now available on LibreSSL + +## [v0.10.57] - 2023-08-27 + +### Added +* Added `X509VerifyParam::set_email` +* `Cipher::chacha20_poly1305` is now available on LibreSSL +* Added `CipherCtx::copy` + +### Changed +* Updated `bitflags` dependecy to the 2.x series + +## [v0.10.56] - 2023-08-06 + +## Added + +* Added `BigNumRef::mod_sqrt`. +* Added `PkeyCtxRef::set_signature_md` and `PkeyCtxRef::set_rsa_pss_saltlen`. +* Added `PkeyCtxRef::verify_recover_init` and `PkeyCtxRef::verify_recover`. +* Added `BigNumRef::is_even` and `BigNumRef::is_odd`. +* Added `EcPointRef::to_hex_str` and `EcPoint::from_hex_str`. +* Added support for AES key wrap and wrap pad. + +## [v0.10.55] - 2023-06-20 + +### Fixed + +* Fixed compilation with the latest version of BoringSSL. +* Fixed compilation when OpenSSL is compiled with `OPENSSL_NO_OCB`. +* Fixed a segfault in `X509VerifyParamRef::set_host` when called with an empty string. + +### Added + +* Added `Deriver::set_peer_ex`. +* Added `EcGroupRef::asn1_flag`. +* Exposed `EcPointRef::affine_coordinates` on BoringSSL and LibreSSL. +* Added `Nid::SM2` and `Id::SM2` + +## [v0.10.54] - 2023-05-31 + +### Fixed + +* `PKey::private_key_to_pkcs8_passphrase` no longer panics if a `passphrase` contains a NUL byte. + +## [v0.10.53] - 2023-05-30 + +### Added + +* Added `Dsa::from_pqg`, `Dsa::generate_key`, and `Dsa::generate_params`. +* Added `SslRef::bytes_to_cipher_list`. +* Added `SubjectAlternativeName::other_name2` + +## [v0.10.52] - 2023-04-24 + +### Added + +* Added `DhRef::check_key`. +* Added `Id::POLY1305`. +* Added `X509Ref::subject_key_id`, `X509Ref::authority_key_id`, `X509Ref::authority_issuer`, and `X509Ref::authority_serial`. + + +## [v0.10.51] - 2023-04-20 + +### Added + +* Added `X509RevokedRef::issuer_name` and `X509RevokedRef::reason_code`. +* Added `Dh::set_key` and `Dh::set_public_key` +* Added `Asn1OctetString` and `Asn1OctetStringRef1` +* Added `X509Extension::new_from_der` + +### Deprecated + +* Deprecated `X509Extension::new` and `X509Extension::new_nid` in favor of `X509Extension::new_from_der` and the `extensions` module. +* Deprecated `X509Extension::add_alias`, it is not required with `new_from_der` or the `extensions` module. + +## [v0.10.50] - 2023-04-09 + +### Added + +* Added `CipherCtxRef::cipher_update_inplace`. + +## [v0.10.49] - 2023-04-01 + +### Fixed + +* `SslConnector` no longer sets the SNI extension when connecting to an IP address. + +### Added + +* Implemented `Ord`, `PartialOrd`, `Eq`, and `PartialEq` for `Asn1Integer` and `Asn1IntegerRef`. +* Added `X509Ref::crl_distribution_points`, and `DistPoint`. + +## [v0.10.48] - 2023-03-23 + +### Fixed + +* Fixed injection vulnerabilities where OpenSSL's configuration mini-language could be used via `x509::extension::SubjectAlternativeName` and `x509::extension::ExtendedKeyUsage`. The mini-language can read arbitrary files amongst other things. + * As part of fixing this `SubjectAlternativeName::dir_name` and `SubjectAlternativeName::other_name` are deprecated and their implementations always `panic!`. If you have a use case for these, please file an issue. +* Fixed several NULL pointer dereferences in OpenSSL that could be triggered via `x509::X509Extension::new` and `x509::X509Extension::new_nid`. Note that these methods still accept OpenSSL's configuration mini-language, and therefore should not be used with untrusted data. +* Fixed a data-race with `x509::X509Name` that are created with `x509::X509NameBuilder` and then used concurrently. +* Fixed LibreSSL version checking. More functions should now be correctly available on LibreSSL. + +## [v0.10.47] - 2023-03-19 + +### Added + +* Added support for X25519 and Ed25519 on LibreSSL and BoringSSL. +* Added `Error::library_code` and `Error::reason_code`. + +## [v0.10.46] - 2023-03-14 + +### Fixed + +* Fixed a potential null-pointer deref when parsing a PKCS#12 archive with no identity. +* Fixed builds against OpenSSL built with `no-cast`. +* Fixed debug formatting of `GeneralName`. + +### Deprecated + +* Deprecated `PKcs12Ref::parse` in favor of `Pkcs12Ref::parse2`. +* Deprecated `ParsedPkcs12` in favor of `ParsedPkcs12_2`. +* Deprecated `Pkcs12Builder::build` in favor of `Pkcs12Builder::build2`. + +### Added + +* Added `X509VerifyParamRef::set_auth_level`, `X509VerifyParamRef::auth_level`, and `X509VerifyParamRef::set_purpose`. +* Added `X509PurposeId` and `X509Purpose`. +* Added `X509NameBuilder::append_entry`. +* Added `PKeyRef::private_key_to_pkcs8`. +* Added `X509LookupRef::load_crl_file`. +* Added `Pkcs12Builder::name`, `Pkcs12Builder::pkey`, and `Pkcs12Builder::cert`. +* Added `SslRef::set_method`, `SslRef::set_private_key_file`, `SslRef::set_private_key`, `SslRef::set_certificate`, `SslRef::set_certificate_chain_file`, `SslRef::add_client_ca`, `SslRef::set_client_ca_list`, `SslRef::set_min_proto_version`, `SslREf::set_max_proto_version`, `SslRef::set_ciphersuites`, `SslRef::set_cipher_list`, `SslRef::set_verify_cert_store`. +* Added `X509NameRef::to_owned`. +* Added `SslContextBuilder::set_num_tickets`, `SslContextRef::num_tickets`, `SslRef::set_num_tickets`, and `SslRef::num_tickets`. +* Added `CmsContentInfo::verify`. + +## [v0.10.45] - 2022-12-20 + +### Fixed + +* Removed the newly added `CipherCtxRef::minimal_output_size` method, which did not work properly. +* Added `NO_DEPRECATED_3_0` cfg checks for more APIs. + +### Added + +* Added `SslRef::add_chain_cert`. +* Added `PKeyRef::security_bits`. +* Added `Provider::set_default_search_path`. +* Added `CipherCtxRef::cipher_final_unchecked`. + +## [v0.10.44] - 2022-12-06 + +### Added + +* Added `CipherCtxRef::num`, `CipherCtxRef::minimal_output_size`, and `CipherCtxRef::cipher_update_unchecked`. +* Improved output buffer size checks in `CipherCtxRef::cipher_update`. +* Added `X509Lookup::file` and `X509LookupRef::load_cert_file`. + +## [v0.10.43] - 2022-11-23 + +### Added + +* Added `Nid::BRAINPOOL_P256R1`, `Nid::BRAINPOOL_P384R1`, `Nid::BRAINPOOL_P512R1`. +* Added `BigNumRef::copy_from_slice`. +* Added `Cipher` constructors for Camellia, CAST5, and IDEA ciphers. +* Added `DsaSig`. +* Added `X509StoreBuilderRef::set_param`. +* Added `X509VerifyParam::new`, `X509VerifyParamRef::set_time`, and `X509VerifyParamRef::set_depth`. + +## [v0.10.42] - 2022-09-26 + +### Added + +* Added `SslRef::psk_identity_hint` and `SslRef::psk_identity`. +* Added SHA-3 constants to `Nid`. +* Added `SslOptions::PRIORITIZE_CHACHA`. +* Added `X509ReqRef::to_text`. +* Added `MdCtxRef::size`. +* Added `X509NameRef::try_cmp`. +* Added `MdCtxRef::reset`. +* Added experimental, unstable support for BoringSSL. + +### Fixed + +* Fixed `MdCtxRef::digest_verify_init` to support `PKey`s with only public components. + +## [v0.10.41] - 2022-06-09 + +### Fixed + +* Fixed a use-after-free in `Error::function` and `Error::file` with OpenSSL 3.x. + +### Added + +* Added `MessageDigest::block_size` and `MdRef::block_size`. +* Implemented `Ord` and `Eq` for `X509` and `X509Ref`. +* Added `X509Extension::add_alias`. +* Added SM4 support. +* Added `EcGroup::from_components` `EcGropuRef::set_generator`, and `EcPointRef::set_affine_coordinates_gfp`. + +## [v0.10.40] - 2022-05-04 + +### Fixed + +* Fixed the openssl-sys dependency version. + +## [v0.10.39] - 2022-05-02 + +### Deprecated + +* Deprecated `SslContextBuilder::set_tmp_ecdh_callback` and `SslRef::set_tmp_ecdh_callback`. + +### Added + +* Added `SslRef::extms_support`. +* Added `Nid::create`. +* Added `CipherCtx`, which exposes a more direct interface to `EVP_CIPHER_CTX`. +* Added `PkeyCtx`, which exposes a more direct interface to `EVP_PKEY_CTX`. +* Added `MdCtx`, which exposes a more direct interface to `EVP_MD_CTX`. +* Added `Pkcs12Builder::mac_md`. +* Added `Provider`. +* Added `X509Ref::issuer_name_hash`. +* Added `Decrypter::set_rsa_oaep_label`. +* Added `X509Ref::to_text`. + +## [v0.10.38] - 2021-10-31 + +### Added + +* Added `Pkey::ec_gen`. + +## [v0.10.37] - 2021-10-27 + +### Fixed + +* Fixed linkage against OpenSSL distributions built with `no-chacha`. + +### Added + +* Added `BigNumRef::to_vec_padded`. +* Added `X509Name::from_der` and `X509NameRef::to_der`. +* Added `BigNum::new_secure`, `BigNumReef::set_const_time`, `BigNumref::is_const_time`, and `BigNumRef::is_secure`. + +## [v0.10.36] - 2021-08-17 + +### Added + +* Added `Asn1Object::as_slice`. +* Added `PKeyRef::{raw_public_key, raw_private_key, private_key_to_pkcs8_passphrase}` and + `PKey::{private_key_from_raw_bytes, public_key_from_raw_bytes}`. +* Added `Cipher::{seed_cbc, seed_cfb128, seed_ecb, seed_ofb}`. + +## [v0.10.35] - 2021-06-18 + +### Fixed + +* Fixed a memory leak in `Deriver`. + +### Added + +* Added support for OpenSSL 3.x.x. +* Added `SslStream::peek`. + +## [v0.10.34] - 2021-04-28 + +### Added + +* Added `Dh::set_private_key` and `DhRef::private_key`. +* Added `EcPointRef::affine_coordinates`. +* Added `TryFrom` implementations to convert between `PKey` and specific key types. +* Added `X509StoreBuilderRef::set_flags`. + +## [v0.10.33] - 2021-03-13 + +### Fixed + +* `Dh::generate_params` now uses `DH_generate_params_ex` rather than the deprecated `DH_generated_params` function. + +### Added + +* Added `Asn1Type`. +* Added `CmsContentInfoRef::decrypt_without_cert_check`. +* Added `EcPointRef::{is_infinity, is_on_curve}`. +* Added `Encrypter::set_rsa_oaep_label`. +* Added `MessageDigest::sm3`. +* Added `Pkcs7Ref::signers`. +* Added `Cipher::nid`. +* Added `X509Ref::authority_info` and `AccessDescription::{method, location}`. +* Added `X509NameBuilder::{append_entry_by_text_with_type, append_entry_by_nid_with_type}`. + +## [v0.10.32] - 2020-12-24 + +### Fixed + +* Fixed `Ssl::new` to take a `&SslContextRef` rather than `&SslContext`. + +### Added + +* Added the `encrypt` module to support asymmetric encryption and decryption with `PKey`s. +* Added `MessageDigest::from_name`. +* Added `ConnectConfiguration::into_ssl`. +* Added the ability to create unconnected `SslStream`s directly from an `Ssl` and transport stream + without performing any part of the handshake with `SslStream::new`. +* Added `SslStream::{read_early_data, write_early_data, connect, accept, do_handshake, stateless}`. +* Implemented `ToOwned` for `SslContextRef`. +* Added `SslRef::{set_connect_state, set_accept_state}`. + +### Deprecated + +* Deprecated `SslStream::from_raw_parts` in favor of `Ssl::from_ptr` and `SslStream::new`. +* Deprecated `SslStreamBuilder` in favor of methods on `Ssl` and `SslStream`. + +## [v0.10.31] - 2020-12-09 + +### Added + +* Added `Asn1Object::from_str`. +* Added `Dh::from_pgq`, `DhRef::prime_p`, `DhRef::prime_q`, `DhRef::generator`, `DhRef::generate_params`, + `DhRef::generate_key`, `DhRef::public_key`, and `DhRef::compute_key`. +* Added `Pkcs7::from_der` and `Pkcs7Ref::to_der`. +* Added `Id::X25519`, `Id::X448`, `PKey::generate_x25519`, and `PKey::generate_x448`. +* Added `SrtpProfileId::SRTP_AEAD_AES_128_GCM` and `SrtpProfileId::SRTP_AEAD_AES_256_GCM`. +* Added `SslContextBuilder::verify_param` and `SslContextBuilder::verify_param_mut`. +* Added `X509Ref::subject_name_hash` and `X509Ref::version`. +* Added `X509StoreBuilderRef::add_lookup`, and the `X509Lookup` type. +* Added `X509VerifyFlags`, `X509VerifyParamRef::set_flags`, `X509VerifyParamRef::clear_flags` + `X509VerifyParamRef::get_flags`. + +## [v0.10.30] - 2020-06-25 + +### Fixed + +* `DsaRef::private_key_to_pem` can no longer be called without a private key. + +### Changed + +* Improved the `Debug` implementations of many types. + +### Added + +* Added `is_empty` implementations for `Asn1StringRef` and `Asn1BitStringRef`. +* Added `EcPointRef::{to_pem, to_dir}` and `EcKeyRef::{public_key_from_pem, public_key_from_der}`. +* Added `Default` implementations for many types. +* Added `Debug` implementations for many types. +* Added `SslStream::from_raw_parts`. +* Added `SslRef::set_mtu`. +* Added `Cipher::{aes_128_ocb, aes_192_ocb, aes_256_ocb}`. + +### Deprecated + +* Deprecated `SslStreamBuilder::set_dtls_mtu_size` in favor of `SslRef::set_mtu`. + +## [v0.10.29] - 2020-04-07 + +### Fixed + +* Fixed a memory leak in `X509Builder::append_extension`. + +### Added + +* Added `SslConnector::into_context` and `SslConnector::context`. +* Added `SslAcceptor::into_context` and `SslAcceptor::context`. +* Added `SslMethod::tls_client` and `SslMethod::tls_server`. +* Added `SslContextBuilder::set_cert_store`. +* Added `SslContextRef::verify_mode` and `SslRef::verify_mode`. +* Added `SslRef::is_init_finished`. +* Added `X509Object`. +* Added `X509StoreRef::objects`. + +## [v0.10.28] - 2020-02-04 + +### Fixed + +* Fixed the mutability of `Signer::sign_oneshot` and `Verifier::verify_oneshot`. This is unfortunately a breaking + change, but a necessary soundness fix. + +## [v0.10.27] - 2020-01-29 + +### Added + +* Added `MessageDigest::null`. +* Added `PKey::private_key_from_pkcs8`. +* Added `SslOptions::NO_RENEGOTIATION`. +* Added `SslStreamBuilder::set_dtls_mtu_size`. + +## [v0.10.26] - 2019-11-22 + +### Fixed + +* Fixed improper handling of the IV buffer in `envelope::{Seal, Unseal}`. + +### Added + +* Added `Asn1TimeRef::{diff, compare}`. +* Added `Asn1Time::from_unix`. +* Added `PartialEq` and `PartialOrd` implementations for `Asn1Time` and `Asn1TimeRef`. +* Added `base64::{encode_block, decode_block}`. +* Added `EcGroupRef::order_bits`. +* Added `Clone` implementations for `Sha1`, `Sha224`, `Sha256`, `Sha384`, and `Sha512`. +* Added `SslContextBuilder::{set_sigalgs_list, set_groups_list}`. + +## [v0.10.25] - 2019-10-02 + +### Fixed + +* Fixed a memory leak in `EcdsaSig::from_private_components` when using OpenSSL 1.0.x. + +### Added + +* Added support for Ed25519 and Ed448 keys. +* Implemented `ToOwned` for `PKeyRef` and `Clone` for `PKey`. + +## [v0.10.24] - 2019-07-19 + +### Fixed + +* Worked around an OpenSSL 1.0.x bug triggered by code calling `SSL_set_app_data`. + +### Added + +* Added `aes::{wrap_key, unwrap_key}`. +* Added `CmsContentInfoRef::to_pem` and `CmsContentInfo::from_pem`. +* Added `DsaRef::private_key_to_pem`. +* Added `EcGroupRef::{cofactor, generator}`. +* Added `EcPointRef::to_owned`. +* Added a `Debug` implementation for `EcKey`. +* Added `SslAcceptor::{mozilla_intermediate_v5, mozilla_modern_v5}`. +* Added `Cipher::{aes_128_ofb, aes_192_ecb, aes_192_cbc, aes_192_ctr, aes_192_cfb1, aes_192_cfb128, aes_192_cfb8, + aes_192_gcm, aes_192_ccm, aes_192_ofb, aes_256_ofb}`. + +## [v0.10.23] - 2019-05-18 + +### Fixed + +* Fixed session callbacks when an `Ssl`'s context is replaced. + +### Added + +* Added `SslContextBuilder::add_client_ca`. + +## [v0.10.22] - 2019-05-08 + +### Added + +* Added support for the LibreSSL 2.9.x series. + +## [v0.10.21] - 2019-04-30 + +### Fixed + +* Fixed overly conservatifve buffer size checks in `Crypter` when using stream ciphers. + +### Added + +* Added bindings to envelope encryption APIs. +* Added `PkeyRef::size`. + +## [v0.10.20] - 2019-03-20 + +### Added + +* Added `CmsContentInfo::from_der` and `CmsContentInfo::encrypt`. +* Added `X509Ref::verify` and `X509ReqRef::verify`. +* Implemented `PartialEq` and `Eq` for `MessageDigest`. +* Added `MessageDigest::type_` and `EcGroupRef::curve_name`. + +## [v0.10.19] - 2019-03-01 + +### Added + +* The openssl-sys build script now logs the values of environment variables. +* Added `ERR_PACK` to openssl-sys. +* The `ERR_*` functions in openssl-sys are const functions when building against newer Rust versions. +* Implemented `Clone` for `Dsa`. +* Added `SslContextRef::add_session` and `SslContextRef::remove_session`. +* Added `SslSessionRef::time`, `SslSessionRef::timeout`, and `SslSessionRef::protocol_version`. +* Added `SslContextBuilder::set_session_cache_size` and `SslContextRef::session_cache_size`. + +## [v0.10.18] - 2019-02-22 + +### Fixed + +* Fixed the return type of `ssl::cipher_name`. + +## [v0.10.17] - 2019-02-22 + +### Added + +* Implemented `AsRef` and `AsRef<[u8]>` for `OpenSslString`. +* Added `Asn1Integer::from_bn`. +* Added `RsaRef::check_key`. +* Added `Asn1Time::from_str` and `Asn1Time::from_str_x509`. +* Added `Rsa::generate_with_e`. +* Added `Cipher::des_ede3_cfb64`. +* Added `SslCipherRef::standard_name` and `ssl::cipher_name`. + +## [v0.10.16] - 2018-12-16 + +### Added + +* Added SHA3 and SHAKE to `MessageDigest`. +* Added `rand::keep_random_devices_open`. +* Added support for LibreSSL 2.9.0. + +## [v0.10.15] - 2018-10-22 + +### Added + +* Implemented `DoubleEndedIterator` for stack iterators. + +## [v0.10.14] - 2018-10-18 + +### Fixed + +* Made some accidentally exposed internal functions private. + +### Added + +* Added support for LibreSSL 2.8. + +### Changed + +* The OpenSSL version used with the `vendored` feature has been upgraded from 1.1.0 to 1.1.1. + +## [v0.10.13] - 2018-10-14 + +### Fixed + +* Fixed a double-free in the `SslContextBuilder::set_get_session_callback` API. + +### Added + +* Added `SslContextBuilder::set_client_hello_callback`. +* Added support for LibreSSL 2.8.1. +* Added `EcdsaSig::from_der` and `EcdsaSig::to_der`. +* Added PKCS#7 support. + +## [v0.10.12] - 2018-09-13 + +### Fixed + +* Fixed handling of SNI callbacks during renegotiation. + +### Added + +* Added `SslRef::get_shutdown` and `SslRef::set_shutdown`. +* Added support for SRTP in DTLS sessions. +* Added support for LibreSSL 2.8.0. + +## [v0.10.11] - 2018-08-04 + +### Added + +* The new `vendored` cargo feature will cause openssl-sys to compile and statically link to a + vendored copy of OpenSSL. +* Added `SslContextBuilder::set_psk_server_callback`. +* Added `DsaRef::pub_key` and `DsaRef::priv_key`. +* Added `Dsa::from_private_components` and `Dsa::from_public_components`. +* Added `X509NameRef::entries`. + +### Deprecated + +* `SslContextBuilder::set_psk_callback` has been renamed to + `SslContextBuilder::set_psk_client_callback` and deprecated. + +## [v0.10.10] - 2018-06-06 + +### Added + +* Added `SslRef::set_alpn_protos`. +* Added `SslContextBuilder::set_ciphersuites`. + +## [v0.10.9] - 2018-06-01 + +### Fixed + +* Fixed a use-after-free in `CmsContentInfo::sign`. +* `SslRef::servername` now returns `None` rather than panicking on a non-UTF8 name. + +### Added + +* Added `MessageDigest::from_nid`. +* Added `Nid::signature_algorithms`, `Nid::long_name`, and `Nid::short_name`. +* Added early data and early keying material export support for TLS 1.3. +* Added `SslRef::verified_chain`. +* Added `SslRef::servername_raw` which returns a `&[u8]` rather than `&str`. +* Added `SslRef::finished` and `SslRef::peer_finished`. +* Added `X509Ref::digest` to replace `X509Ref::fingerprint`. +* `X509StoreBuilder` and `X509Store` now implement `Sync` and `Send`. + +### Deprecated + +* `X509Ref::fingerprint` has been deprecated in favor of `X509Ref::digest`. + +## [v0.10.8] - 2018-05-20 + +### Fixed + +* `openssl-sys` will now detect Homebrew-installed OpenSSL when installed to a non-default + directory. +* The `X509_V_ERR_INVALID_CALL`, `X509_V_ERR_STORE_LOOKUP`, and + `X509_V_ERR_PROXY_SUBJECT_NAME_VIOLATION` constants in `openssl-sys` are now only present when + building against 1.1.0g and up rather than 1.1.0. +* `SslContextBuilder::max_proto_version` and `SslContextBuilder::min_proto_version` are only present + when building against 1.1.0g and up rather than 1.1.0. + +### Added + +* Added `CmsContentInfo::sign`. +* Added `Clone` and `ToOwned` implementations to `Rsa` and `RsaRef` respectively. +* The `min_proto_version` and `max_proto_version` methods are available when linking against + LibreSSL 2.6.1 and up in addition to OpenSSL. +* `X509VerifyParam` is available when linking against LibreSSL 2.6.1 and up in addition to OpenSSL. +* ALPN support is available when linking against LibreSSL 2.6.1 and up in addition to OpenSSL. +* `Stack` and `StackRef` are now `Sync` and `Send`. + +## [v0.10.7] - 2018-04-30 + +### Added + +* Added `X509Req::public_key` and `X509Req::extensions`. +* Added `RsaPrivateKeyBuilder` to allow control over initialization of optional components of an RSA + private key. +* Added DER encode/decode support to `SslSession`. +* openssl-sys now provides the `DEP_OPENSSL_VERSION_NUMBER` and + `DEP_OPENSSL_LIBRESSL_VERSION_NUMBER` environment variables to downstream build scripts which + contains the hex-encoded version number of the OpenSSL or LibreSSL distribution being built + against. The other variables are deprecated. + +## [v0.10.6] - 2018-03-05 + +### Added + +* Added `SslOptions::ENABLE_MIDDLEBOX_COMPAT`. +* Added more `Sync` and `Send` implementations. +* Added `PKeyRef::id`. +* Added `Padding::PKCS1_PSS`. +* Added `Signer::set_rsa_pss_saltlen`, `Signer::set_rsa_mgf1_md`, `Signer::set_rsa_pss_saltlen`, and + `Signer::set_rsa_mgf1_md` +* Added `X509StoreContextRef::verify` to directly verify certificates. +* Added low level ECDSA support. +* Added support for TLSv1.3 custom extensions. (OpenSSL 1.1.1 only) +* Added AES-CCM support. +* Added `EcKey::from_private_components`. +* Added CMAC support. +* Added support for LibreSSL 2.7. +* Added `X509Ref::serial_number`. +* Added `Asn1IntegerRef::to_bn`. +* Added support for TLSv1.3 stateless handshakes. (OpenSSL 1.1.1 only) + +### Changed + +* The Cargo features previously used to gate access to version-specific OpenSSL APIs have been + removed. Those APIs will be available automatically when building against an appropriate OpenSSL + version. +* Fixed `PKey::private_key_from_der` to return a `PKey` rather than a `PKey`. This + is technically a breaking change but the function was pretty useless previously. + +### Deprecated + +* `X509CheckFlags::FLAG_NO_WILDCARDS` has been renamed to `X509CheckFlags::NO_WILDCARDS` and the old + name deprecated. + +## [v0.10.5] - 2018-02-28 + +### Fixed + +* `ErrorStack`'s `Display` implementation no longer writes an empty string if it contains no errors. + +### Added + +* Added `SslRef::version2`. +* Added `Cipher::des_ede3_cbc`. +* Added `SslRef::export_keying_material`. +* Added the ability to push an `Error` or `ErrorStack` back onto OpenSSL's error stack. Various + callback bindings use this to propagate errors properly. +* Added `SslContextBuilder::set_cookie_generate_cb` and `SslContextBuilder::set_cookie_verify_cb`. +* Added `SslContextBuilder::set_max_proto_version`, `SslContextBuilder::set_min_proto_version`, + `SslContextBuilder::max_proto_version`, and `SslContextBuilder::min_proto_version`. + +### Changed + +* Updated `SslConnector`'s default cipher list to match Python's. + +### Deprecated + +* `SslRef::version` has been deprecated. Use `SslRef::version_str` instead. + +## [v0.10.4] - 2018-02-18 + +### Added + +* Added OpenSSL 1.1.1 support. +* Added `Rsa::public_key_from_pem_pkcs1`. +* Added `SslOptions::NO_TLSV1_3`. (OpenSSL 1.1.1 only) +* Added `SslVersion`. +* Added `SslSessionCacheMode` and `SslContextBuilder::set_session_cache_mode`. +* Added `SslContextBuilder::set_new_session_callback`, + `SslContextBuilder::set_remove_session_callback`, and + `SslContextBuilder::set_get_session_callback`. +* Added `SslContextBuilder::set_keylog_callback`. (OpenSSL 1.1.1 only) +* Added `SslRef::client_random` and `SslRef::server_random`. (OpenSSL 1.1.0+ only) + +### Fixed + +* The `SslAcceptorBuilder::mozilla_modern` constructor now disables TLSv1.0 and TLSv1.1 in + accordance with Mozilla's recommendations. + +## [v0.10.3] - 2018-02-12 + +### Added + +* OpenSSL is now automatically detected on FreeBSD systems. +* Added `GeneralName` accessors for `rfc822Name` and `uri` variants. +* Added DES-EDE3 support. + +### Fixed + +* Fixed a memory leak in `X509StoreBuilder::add_cert`. + +## [v0.10.2] - 2018-01-11 + +### Added + +* Added `ConnectConfiguration::set_use_server_name_indication` and + `ConnectConfiguration::set_verify_hostname` for use in contexts where you don't have ownership + of the `ConnectConfiguration`. + +## [v0.10.1] - 2018-01-10 + +### Added + +* Added a `From for ssl::Error` implementation. + +## [v0.10.0] - 2018-01-10 + +### Compatibility + +* openssl 0.10 still uses openssl-sys 0.9, so openssl 0.9 and 0.10 can coexist without issue. + +### Added + +* The `ssl::select_next_proto` function can be used to easily implement the ALPN selection callback + in a "standard" way. +* FIPS mode support is available in the `fips` module. +* Accessors for the Issuer and Issuer Alternative Name fields of X509 certificates have been added. +* The `X509VerifyResult` can now be set in the certificate verification callback via + `X509StoreContextRef::set_error`. + +### Changed + +* All constants have been moved to associated constants of their type. For example, `bn::MSB_ONE` + is now `bn::MsbOption::ONE`. +* Asymmetric key types are now parameterized over what they contain. In OpenSSL, the same type is + used for key parameters, public keys, and private keys. Unfortunately, some APIs simply assume + that certain components are present and will segfault trying to use things that aren't there. + + The `pkey` module contains new tag types named `Params`, `Public`, and `Private`, and the + `Dh`, `Dsa`, `EcKey`, `Rsa`, and `PKey` have a type parameter set to one of those values. This + allows the `Signer` constructor to indicate that it requires a private key at compile time for + example. Previously, `Signer` would simply segfault if provided a key without private + components. +* ALPN support has been changed to more directly model OpenSSL's own APIs. Instead of a single + method used for both the server and client sides which performed everything automatically, the + `SslContextBuilder::set_alpn_protos` and `SslContextBuilder::set_alpn_select_callback` handle + the client and server sides respectively. +* `SslConnector::danger_connect_without_providing_domain_for_certificate_verification_and_server_name_indication` + has been removed in favor of new methods which provide more control. The + `ConnectConfiguration::use_server_name_indication` method controls the use of Server Name + Indication (SNI), and the `ConnectConfiguration::verify_hostname` method controls the use of + hostname verification. These can be controlled independently, and if both are disabled, the + domain argument to `ConnectConfiguration::connect` is ignored. +* Shared secret derivation is now handled by the new `derive::Deriver` type rather than + `pkey::PKeyContext`, which has been removed. +* `ssl::Error` is now no longer an enum, and provides more direct access to the relevant state. +* `SslConnectorBuilder::new` has been moved and renamed to `SslConnector::builder`. +* `SslAcceptorBuilder::mozilla_intermediate` and `SslAcceptorBuilder::mozilla_modern` have been + moved to `SslAcceptor` and no longer take the private key and certificate chain. Install those + manually after creating the builder. +* `X509VerifyError` is now `X509VerifyResult` and can now have the "ok" value in addition to error + values. +* `x509::X509FileType` is now `ssl::SslFiletype`. +* Asymmetric key serialization and deserialization methods now document the formats that they + correspond to, and some have been renamed to better indicate that. + +### Removed + +* All deprecated APIs have been removed. +* NPN support has been removed. It has been supersceded by ALPN, and is hopefully no longer being + used in practice. If you still depend on it, please file an issue! +* `SslRef::compression` has been removed. +* Some `ssl::SslOptions` flags have been removed as they no longer do anything. + +## Older + +Look at the [release tags] for information about older releases. + +[Unreleased]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.68...master +[v0.10.68]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.67...openssl-v0.10.68 +[v0.10.67]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.66...openssl-v0.10.67 +[v0.10.66]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.65...openssl-v0.10.66 +[v0.10.65]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.64...openssl-v0.10.65 +[v0.10.64]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.63...openssl-v0.10.64 +[v0.10.63]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.62...openssl-v0.10.63 +[v0.10.62]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.61...openssl-v0.10.62 +[v0.10.61]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.60...openssl-v0.10.61 +[v0.10.60]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.59...openssl-v0.10.60 +[v0.10.59]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.58...openssl-v0.10.59 +[v0.10.58]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.57...openssl-v0.10.58 +[v0.10.57]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.56...openssl-v0.10.57 +[v0.10.56]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.55...openssl-v0.10.56 +[v0.10.55]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.54...openssl-v0.10.55 +[v0.10.54]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.53...openssl-v0.10.54 +[v0.10.53]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.52...openssl-v0.10.53 +[v0.10.52]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.51...openssl-v0.10.52 +[v0.10.51]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.50...openssl-v0.10.51 +[v0.10.50]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.49...openssl-v0.10.50 +[v0.10.49]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.48...openssl-v0.10.49 +[v0.10.48]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.47...openssl-v0.10.48 +[v0.10.47]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.46...openssl-v0.10.47 +[v0.10.46]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.45...openssl-v0.10.46 +[v0.10.45]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.44...openssl-v0.10.45 +[v0.10.44]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.43...openssl-v0.10.44 +[v0.10.43]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.42...openssl-v0.10.43 +[v0.10.42]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.41...openssl-v0.10.42 +[v0.10.41]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.40...openssl-v0.10.41 +[v0.10.40]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.39...openssl-v0.10.40 +[v0.10.39]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.38...openssl-v0.10.39 +[v0.10.38]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.37...openssl-v0.10.38 +[v0.10.37]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.36...openssl-v0.10.37 +[v0.10.36]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.35...openssl-v0.10.36 +[v0.10.35]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.34...openssl-v0.10.35 +[v0.10.34]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.33...openssl-v0.10.34 +[v0.10.33]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.32...openssl-v0.10.33 +[v0.10.32]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.31...openssl-v0.10.32 +[v0.10.31]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.30...openssl-v0.10.31 +[v0.10.30]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.29...openssl-v0.10.30 +[v0.10.29]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.28...openssl-v0.10.29 +[v0.10.28]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.27...openssl-v0.10.28 +[v0.10.27]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.26...openssl-v0.10.27 +[v0.10.26]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.25...openssl-v0.10.26 +[v0.10.25]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.24...openssl-v0.10.25 +[v0.10.24]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.23...openssl-v0.10.24 +[v0.10.23]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.22...openssl-v0.10.23 +[v0.10.22]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.21...openssl-v0.10.22 +[v0.10.21]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.20...openssl-v0.10.21 +[v0.10.20]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.19...openssl-v0.10.20 +[v0.10.19]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.18...openssl-v0.10.19 +[v0.10.18]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.17...openssl-v0.10.18 +[v0.10.17]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.16...openssl-v0.10.17 +[v0.10.16]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.15...openssl-v0.10.16 +[v0.10.15]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.14...openssl-v0.10.15 +[v0.10.14]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.13...openssl-v0.10.14 +[v0.10.13]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.12...openssl-v0.10.13 +[v0.10.12]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.11...openssl-v0.10.12 +[v0.10.11]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.10...openssl-v0.10.11 +[v0.10.10]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.9...openssl-v0.10.10 +[v0.10.9]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.8...openssl-v0.10.9 +[v0.10.8]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.7...openssl-v0.10.8 +[v0.10.7]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.6...openssl-v0.10.7 +[v0.10.6]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.5...openssl-v0.10.6 +[v0.10.5]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.4...openssl-v0.10.5 +[v0.10.4]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.3...openssl-v0.10.4 +[v0.10.3]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.2...openssl-v0.10.3 +[v0.10.2]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.1...openssl-v0.10.2 +[v0.10.1]: https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.0...openssl-v0.10.1 +[v0.10.0]: https://github.com/sfackler/rust-openssl/compare/v0.9.23...openssl-v0.10.0 +[release tags]: https://github.com/sfackler/rust-openssl/releases diff --git a/vendor/openssl/Cargo.toml b/vendor/openssl/Cargo.toml new file mode 100644 index 0000000..56265c8 --- /dev/null +++ b/vendor/openssl/Cargo.toml @@ -0,0 +1,79 @@ +# 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] +edition = "2021" +rust-version = "1.63.0" +name = "openssl" +version = "0.10.68" +authors = ["Steven Fackler "] +build = "build.rs" +autobins = false +autoexamples = false +autotests = false +autobenches = false +description = "OpenSSL bindings" +readme = "README.md" +keywords = [ + "crypto", + "tls", + "ssl", + "dtls", +] +categories = [ + "cryptography", + "api-bindings", +] +license = "Apache-2.0" +repository = "https://github.com/sfackler/rust-openssl" + +[lib] +name = "openssl" +path = "src/lib.rs" + +[[example]] +name = "mk_certs" +path = "examples/mk_certs.rs" + +[dependencies.bitflags] +version = "2.2.1" + +[dependencies.cfg-if] +version = "1.0" + +[dependencies.ffi] +version = "0.9.104" +package = "openssl-sys" + +[dependencies.foreign-types] +version = "0.3.1" + +[dependencies.libc] +version = "0.2" + +[dependencies.once_cell] +version = "1.5.2" + +[dependencies.openssl-macros] +version = "0.1.0" + +[dev-dependencies.hex] +version = "0.4" + +[features] +bindgen = ["ffi/bindgen"] +default = [] +unstable_boringssl = ["ffi/unstable_boringssl"] +v101 = [] +v102 = [] +v110 = [] +v111 = [] +vendored = ["ffi/vendored"] diff --git a/vendor/openssl/LICENSE b/vendor/openssl/LICENSE new file mode 100644 index 0000000..f259067 --- /dev/null +++ b/vendor/openssl/LICENSE @@ -0,0 +1,15 @@ +Copyright 2011-2017 Google Inc. + 2013 Jack Lloyd + 2013-2014 Steven Fackler + +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/openssl/README.md b/vendor/openssl/README.md new file mode 100644 index 0000000..50c6d57 --- /dev/null +++ b/vendor/openssl/README.md @@ -0,0 +1,22 @@ +# rust-openssl + +[![crates.io](https://img.shields.io/crates/v/openssl.svg)](https://crates.io/crates/openssl) + +OpenSSL bindings for the Rust programming language. + +[Documentation](https://docs.rs/openssl). + +## Release Support + +The current supported release of `openssl` is 0.10 and `openssl-sys` is 0.9. + +New major versions will be published at most once per year. After a new +release, the previous major version will be partially supported with bug +fixes for 3 months, after which support will be dropped entirely. + +### Contribution + +Unless you explicitly state otherwise, any contribution intentionally +submitted for inclusion in the work by you, as defined in the Apache-2.0 +license, shall be dual licensed under the terms of both the Apache License, +Version 2.0 and the MIT license without any additional terms or conditions. diff --git a/vendor/openssl/build.rs b/vendor/openssl/build.rs new file mode 100644 index 0000000..33372ef --- /dev/null +++ b/vendor/openssl/build.rs @@ -0,0 +1,164 @@ +#![allow( + clippy::inconsistent_digit_grouping, + clippy::uninlined_format_args, + clippy::unusual_byte_groupings +)] + +use std::env; + +fn main() { + println!("cargo:rustc-check-cfg=cfg(osslconf, values(\"OPENSSL_NO_OCB\", \"OPENSSL_NO_SM4\", \"OPENSSL_NO_SEED\", \"OPENSSL_NO_CHACHA\", \"OPENSSL_NO_CAST\", \"OPENSSL_NO_IDEA\", \"OPENSSL_NO_CAMELLIA\", \"OPENSSL_NO_RC4\", \"OPENSSL_NO_BF\", \"OPENSSL_NO_PSK\", \"OPENSSL_NO_DEPRECATED_3_0\", \"OPENSSL_NO_SCRYPT\", \"OPENSSL_NO_SM3\", \"OPENSSL_NO_RMD160\", \"OPENSSL_NO_EC2M\", \"OPENSSL_NO_OCSP\", \"OPENSSL_NO_CMS\", \"OPENSSL_NO_EC\", \"OPENSSL_NO_ARGON2\"))"); + + println!("cargo:rustc-check-cfg=cfg(libressl)"); + println!("cargo:rustc-check-cfg=cfg(boringssl)"); + + println!("cargo:rustc-check-cfg=cfg(libressl250)"); + println!("cargo:rustc-check-cfg=cfg(libressl251)"); + println!("cargo:rustc-check-cfg=cfg(libressl261)"); + println!("cargo:rustc-check-cfg=cfg(libressl270)"); + println!("cargo:rustc-check-cfg=cfg(libressl271)"); + println!("cargo:rustc-check-cfg=cfg(libressl273)"); + println!("cargo:rustc-check-cfg=cfg(libressl280)"); + println!("cargo:rustc-check-cfg=cfg(libressl291)"); + println!("cargo:rustc-check-cfg=cfg(libressl310)"); + println!("cargo:rustc-check-cfg=cfg(libressl321)"); + println!("cargo:rustc-check-cfg=cfg(libressl332)"); + println!("cargo:rustc-check-cfg=cfg(libressl340)"); + println!("cargo:rustc-check-cfg=cfg(libressl350)"); + println!("cargo:rustc-check-cfg=cfg(libressl360)"); + println!("cargo:rustc-check-cfg=cfg(libressl361)"); + println!("cargo:rustc-check-cfg=cfg(libressl370)"); + println!("cargo:rustc-check-cfg=cfg(libressl380)"); + println!("cargo:rustc-check-cfg=cfg(libressl382)"); + println!("cargo:rustc-check-cfg=cfg(libressl390)"); + println!("cargo:rustc-check-cfg=cfg(libressl400)"); + + println!("cargo:rustc-check-cfg=cfg(ossl101)"); + println!("cargo:rustc-check-cfg=cfg(ossl102)"); + println!("cargo:rustc-check-cfg=cfg(ossl110)"); + println!("cargo:rustc-check-cfg=cfg(ossl110g)"); + println!("cargo:rustc-check-cfg=cfg(ossl110h)"); + println!("cargo:rustc-check-cfg=cfg(ossl111)"); + println!("cargo:rustc-check-cfg=cfg(ossl111d)"); + println!("cargo:rustc-check-cfg=cfg(ossl300)"); + println!("cargo:rustc-check-cfg=cfg(ossl310)"); + println!("cargo:rustc-check-cfg=cfg(ossl320)"); + println!("cargo:rustc-check-cfg=cfg(ossl330)"); + + if env::var("DEP_OPENSSL_LIBRESSL").is_ok() { + println!("cargo:rustc-cfg=libressl"); + } + + if env::var("DEP_OPENSSL_BORINGSSL").is_ok() { + println!("cargo:rustc-cfg=boringssl"); + } + + if let Ok(v) = env::var("DEP_OPENSSL_LIBRESSL_VERSION_NUMBER") { + let version = u64::from_str_radix(&v, 16).unwrap(); + + if version >= 0x2_05_00_00_0 { + println!("cargo:rustc-cfg=libressl250"); + } + if version >= 0x2_05_01_00_0 { + println!("cargo:rustc-cfg=libressl251"); + } + if version >= 0x2_06_01_00_0 { + println!("cargo:rustc-cfg=libressl261"); + } + if version >= 0x2_07_00_00_0 { + println!("cargo:rustc-cfg=libressl270"); + } + if version >= 0x2_07_01_00_0 { + println!("cargo:rustc-cfg=libressl271"); + } + if version >= 0x2_07_03_00_0 { + println!("cargo:rustc-cfg=libressl273"); + } + if version >= 0x2_08_00_00_0 { + println!("cargo:rustc-cfg=libressl280"); + } + if version >= 0x2_09_01_00_0 { + println!("cargo:rustc-cfg=libressl291"); + } + if version >= 0x3_01_00_00_0 { + println!("cargo:rustc-cfg=libressl310"); + } + if version >= 0x3_02_01_00_0 { + println!("cargo:rustc-cfg=libressl321"); + } + if version >= 0x3_03_02_00_0 { + println!("cargo:rustc-cfg=libressl332"); + } + if version >= 0x3_04_00_00_0 { + println!("cargo:rustc-cfg=libressl340"); + } + if version >= 0x3_05_00_00_0 { + println!("cargo:rustc-cfg=libressl350"); + } + if version >= 0x3_06_00_00_0 { + println!("cargo:rustc-cfg=libressl360"); + } + if version >= 0x3_06_01_00_0 { + println!("cargo:rustc-cfg=libressl361"); + } + if version >= 0x3_07_00_00_0 { + println!("cargo:rustc-cfg=libressl370"); + } + if version >= 0x3_08_00_00_0 { + println!("cargo:rustc-cfg=libressl380"); + } + if version >= 0x3_08_02_00_0 { + println!("cargo:rustc-cfg=libressl382"); + } + if version >= 0x3_09_00_00_0 { + println!("cargo:rustc-cfg=libressl390"); + } + if version >= 0x4_00_00_00_0 { + println!("cargo:rustc-cfg=libressl400"); + } + } + + if let Ok(vars) = env::var("DEP_OPENSSL_CONF") { + for var in vars.split(',') { + println!("cargo:rustc-cfg=osslconf=\"{}\"", var); + } + } + + if let Ok(version) = env::var("DEP_OPENSSL_VERSION_NUMBER") { + let version = u64::from_str_radix(&version, 16).unwrap(); + + if version >= 0x1_00_01_00_0 { + println!("cargo:rustc-cfg=ossl101"); + } + if version >= 0x1_00_02_00_0 { + println!("cargo:rustc-cfg=ossl102"); + } + if version >= 0x1_01_00_00_0 { + println!("cargo:rustc-cfg=ossl110"); + } + if version >= 0x1_01_00_07_0 { + println!("cargo:rustc-cfg=ossl110g"); + } + if version >= 0x1_01_00_08_0 { + println!("cargo:rustc-cfg=ossl110h"); + } + if version >= 0x1_01_01_00_0 { + println!("cargo:rustc-cfg=ossl111"); + } + if version >= 0x1_01_01_04_0 { + println!("cargo:rustc-cfg=ossl111d"); + } + if version >= 0x3_00_00_00_0 { + println!("cargo:rustc-cfg=ossl300"); + } + if version >= 0x3_01_00_00_0 { + println!("cargo:rustc-cfg=ossl310"); + } + if version >= 0x3_02_00_00_0 { + println!("cargo:rustc-cfg=ossl320"); + } + if version >= 0x3_03_00_00_0 { + println!("cargo:rustc-cfg=ossl330"); + } + } +} diff --git a/vendor/openssl/examples/mk_certs.rs b/vendor/openssl/examples/mk_certs.rs new file mode 100644 index 0000000..48538c7 --- /dev/null +++ b/vendor/openssl/examples/mk_certs.rs @@ -0,0 +1,160 @@ +#![allow(clippy::uninlined_format_args)] + +//! A program that generates ca certs, certs verified by the ca, and public +//! and private keys. + +use openssl::asn1::Asn1Time; +use openssl::bn::{BigNum, MsbOption}; +use openssl::error::ErrorStack; +use openssl::hash::MessageDigest; +use openssl::pkey::{PKey, PKeyRef, Private}; +use openssl::rsa::Rsa; +use openssl::x509::extension::{ + AuthorityKeyIdentifier, BasicConstraints, KeyUsage, SubjectAlternativeName, + SubjectKeyIdentifier, +}; +use openssl::x509::{X509NameBuilder, X509Ref, X509Req, X509ReqBuilder, X509VerifyResult, X509}; + +/// Make a CA certificate and private key +fn mk_ca_cert() -> Result<(X509, PKey), ErrorStack> { + let rsa = Rsa::generate(2048)?; + let key_pair = PKey::from_rsa(rsa)?; + + let mut x509_name = X509NameBuilder::new()?; + x509_name.append_entry_by_text("C", "US")?; + x509_name.append_entry_by_text("ST", "TX")?; + x509_name.append_entry_by_text("O", "Some CA organization")?; + x509_name.append_entry_by_text("CN", "ca test")?; + let x509_name = x509_name.build(); + + let mut cert_builder = X509::builder()?; + cert_builder.set_version(2)?; + let serial_number = { + let mut serial = BigNum::new()?; + serial.rand(159, MsbOption::MAYBE_ZERO, false)?; + serial.to_asn1_integer()? + }; + cert_builder.set_serial_number(&serial_number)?; + cert_builder.set_subject_name(&x509_name)?; + cert_builder.set_issuer_name(&x509_name)?; + cert_builder.set_pubkey(&key_pair)?; + let not_before = Asn1Time::days_from_now(0)?; + cert_builder.set_not_before(¬_before)?; + let not_after = Asn1Time::days_from_now(365)?; + cert_builder.set_not_after(¬_after)?; + + cert_builder.append_extension(BasicConstraints::new().critical().ca().build()?)?; + cert_builder.append_extension( + KeyUsage::new() + .critical() + .key_cert_sign() + .crl_sign() + .build()?, + )?; + + let subject_key_identifier = + SubjectKeyIdentifier::new().build(&cert_builder.x509v3_context(None, None))?; + cert_builder.append_extension(subject_key_identifier)?; + + cert_builder.sign(&key_pair, MessageDigest::sha256())?; + let cert = cert_builder.build(); + + Ok((cert, key_pair)) +} + +/// Make a X509 request with the given private key +fn mk_request(key_pair: &PKey) -> Result { + let mut req_builder = X509ReqBuilder::new()?; + req_builder.set_pubkey(key_pair)?; + + let mut x509_name = X509NameBuilder::new()?; + x509_name.append_entry_by_text("C", "US")?; + x509_name.append_entry_by_text("ST", "TX")?; + x509_name.append_entry_by_text("O", "Some organization")?; + x509_name.append_entry_by_text("CN", "www.example.com")?; + let x509_name = x509_name.build(); + req_builder.set_subject_name(&x509_name)?; + + req_builder.sign(key_pair, MessageDigest::sha256())?; + let req = req_builder.build(); + Ok(req) +} + +/// Make a certificate and private key signed by the given CA cert and private key +fn mk_ca_signed_cert( + ca_cert: &X509Ref, + ca_key_pair: &PKeyRef, +) -> Result<(X509, PKey), ErrorStack> { + let rsa = Rsa::generate(2048)?; + let key_pair = PKey::from_rsa(rsa)?; + + let req = mk_request(&key_pair)?; + + let mut cert_builder = X509::builder()?; + cert_builder.set_version(2)?; + let serial_number = { + let mut serial = BigNum::new()?; + serial.rand(159, MsbOption::MAYBE_ZERO, false)?; + serial.to_asn1_integer()? + }; + cert_builder.set_serial_number(&serial_number)?; + cert_builder.set_subject_name(req.subject_name())?; + cert_builder.set_issuer_name(ca_cert.subject_name())?; + cert_builder.set_pubkey(&key_pair)?; + let not_before = Asn1Time::days_from_now(0)?; + cert_builder.set_not_before(¬_before)?; + let not_after = Asn1Time::days_from_now(365)?; + cert_builder.set_not_after(¬_after)?; + + cert_builder.append_extension(BasicConstraints::new().build()?)?; + + cert_builder.append_extension( + KeyUsage::new() + .critical() + .non_repudiation() + .digital_signature() + .key_encipherment() + .build()?, + )?; + + let subject_key_identifier = + SubjectKeyIdentifier::new().build(&cert_builder.x509v3_context(Some(ca_cert), None))?; + cert_builder.append_extension(subject_key_identifier)?; + + let auth_key_identifier = AuthorityKeyIdentifier::new() + .keyid(false) + .issuer(false) + .build(&cert_builder.x509v3_context(Some(ca_cert), None))?; + cert_builder.append_extension(auth_key_identifier)?; + + let subject_alt_name = SubjectAlternativeName::new() + .dns("*.example.com") + .dns("hello.com") + .build(&cert_builder.x509v3_context(Some(ca_cert), None))?; + cert_builder.append_extension(subject_alt_name)?; + + cert_builder.sign(ca_key_pair, MessageDigest::sha256())?; + let cert = cert_builder.build(); + + Ok((cert, key_pair)) +} + +fn real_main() -> Result<(), ErrorStack> { + let (ca_cert, ca_key_pair) = mk_ca_cert()?; + let (cert, _key_pair) = mk_ca_signed_cert(&ca_cert, &ca_key_pair)?; + + // Verify that this cert was issued by this ca + match ca_cert.issued(&cert) { + X509VerifyResult::OK => println!("Certificate verified!"), + ver_err => println!("Failed to verify certificate: {}", ver_err), + }; + + Ok(()) +} + +fn main() { + match real_main() { + Ok(()) => println!("Finished."), + Err(e) => println!("Error: {}", e), + }; +} diff --git a/vendor/openssl/src/aes.rs b/vendor/openssl/src/aes.rs new file mode 100644 index 0000000..cd1f3ed --- /dev/null +++ b/vendor/openssl/src/aes.rs @@ -0,0 +1,319 @@ +//! Low level AES IGE and key wrapping functionality +//! +//! AES ECB, CBC, XTS, CTR, CFB, GCM and other conventional symmetric encryption +//! modes are found in [`symm`]. This is the implementation of AES IGE and key wrapping +//! +//! Advanced Encryption Standard (AES) provides symmetric key cipher that +//! the same key is used to encrypt and decrypt data. This implementation +//! uses 128, 192, or 256 bit keys. This module provides functions to +//! create a new key with [`new_encrypt`] and perform an encryption/decryption +//! using that key with [`aes_ige`]. +//! +//! [`new_encrypt`]: struct.AesKey.html#method.new_encrypt +//! [`aes_ige`]: fn.aes_ige.html +//! +//! The [`symm`] module should be used in preference to this module in most cases. +//! The IGE block cipher is a non-traditional cipher mode. More traditional AES +//! encryption methods are found in the [`Crypter`] and [`Cipher`] structs. +//! +//! [`symm`]: ../symm/index.html +//! [`Crypter`]: ../symm/struct.Crypter.html +//! [`Cipher`]: ../symm/struct.Cipher.html +//! +//! # Examples + +#![cfg_attr( + all(not(boringssl), not(osslconf = "OPENSSL_NO_DEPRECATED_3_0")), + doc = r#"\ +## AES IGE +```rust +use openssl::aes::{AesKey, aes_ige}; +use openssl::symm::Mode; + +let key = b"\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F"; +let plaintext = b"\x12\x34\x56\x78\x90\x12\x34\x56\x12\x34\x56\x78\x90\x12\x34\x56"; +let mut iv = *b"\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\ + \x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F"; + + let key = AesKey::new_encrypt(key).unwrap(); + let mut output = [0u8; 16]; + aes_ige(plaintext, &mut output, &key, &mut iv, Mode::Encrypt); + assert_eq!(output, *b"\xa6\xad\x97\x4d\x5c\xea\x1d\x36\xd2\xf3\x67\x98\x09\x07\xed\x32"); +```"# +)] + +//! +//! ## Key wrapping +//! ```rust +//! use openssl::aes::{AesKey, unwrap_key, wrap_key}; +//! +//! let kek = b"\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F"; +//! let key_to_wrap = b"\x00\x11\x22\x33\x44\x55\x66\x77\x88\x99\xAA\xBB\xCC\xDD\xEE\xFF"; +//! +//! let enc_key = AesKey::new_encrypt(kek).unwrap(); +//! let mut ciphertext = [0u8; 24]; +//! wrap_key(&enc_key, None, &mut ciphertext, &key_to_wrap[..]).unwrap(); +//! let dec_key = AesKey::new_decrypt(kek).unwrap(); +//! let mut orig_key = [0u8; 16]; +//! unwrap_key(&dec_key, None, &mut orig_key, &ciphertext[..]).unwrap(); +//! +//! assert_eq!(&orig_key[..], &key_to_wrap[..]); +//! ``` +//! +use cfg_if::cfg_if; +use libc::{c_int, c_uint}; +use std::mem::MaybeUninit; +use std::ptr; + +#[cfg(not(boringssl))] +use crate::symm::Mode; +use openssl_macros::corresponds; + +/// Provides Error handling for parsing keys. +#[derive(Debug)] +pub struct KeyError(()); + +/// The key used to encrypt or decrypt cipher blocks. +pub struct AesKey(ffi::AES_KEY); + +cfg_if! { + if #[cfg(boringssl)] { + type AesBitType = c_uint; + type AesSizeType = usize; + } else { + type AesBitType = c_int; + type AesSizeType = c_uint; + } +} + +impl AesKey { + /// Prepares a key for encryption. + /// + /// # Failure + /// + /// Returns an error if the key is not 128, 192, or 256 bits. + #[corresponds(AES_set_encrypt_key)] + pub fn new_encrypt(key: &[u8]) -> Result { + unsafe { + assert!(key.len() <= c_int::MAX as usize / 8); + + let mut aes_key = MaybeUninit::uninit(); + let r = ffi::AES_set_encrypt_key( + key.as_ptr() as *const _, + key.len() as AesBitType * 8, + aes_key.as_mut_ptr(), + ); + if r == 0 { + Ok(AesKey(aes_key.assume_init())) + } else { + Err(KeyError(())) + } + } + } + + /// Prepares a key for decryption. + /// + /// # Failure + /// + /// Returns an error if the key is not 128, 192, or 256 bits. + #[corresponds(AES_set_decrypt_key)] + pub fn new_decrypt(key: &[u8]) -> Result { + unsafe { + assert!(key.len() <= c_int::MAX as usize / 8); + + let mut aes_key = MaybeUninit::uninit(); + let r = ffi::AES_set_decrypt_key( + key.as_ptr() as *const _, + key.len() as AesBitType * 8, + aes_key.as_mut_ptr(), + ); + + if r == 0 { + Ok(AesKey(aes_key.assume_init())) + } else { + Err(KeyError(())) + } + } + } +} + +/// Performs AES IGE encryption or decryption +/// +/// AES IGE (Infinite Garble Extension) is a form of AES block cipher utilized in +/// OpenSSL. Infinite Garble refers to propagating forward errors. IGE, like other +/// block ciphers implemented for AES requires an initialization vector. The IGE mode +/// allows a stream of blocks to be encrypted or decrypted without having the entire +/// plaintext available. For more information, visit [AES IGE Encryption]. +/// +/// This block cipher uses 16 byte blocks. The rust implementation will panic +/// if the input or output does not meet this 16-byte boundary. Attention must +/// be made in this low level implementation to pad the value to the 128-bit boundary. +/// +/// [AES IGE Encryption]: http://www.links.org/files/openssl-ige.pdf +/// +/// # Panics +/// +/// Panics if `in_` is not the same length as `out`, if that length is not a multiple of 16, or if +/// `iv` is not at least 32 bytes. +#[cfg(not(boringssl))] +#[cfg(not(osslconf = "OPENSSL_NO_DEPRECATED_3_0"))] +#[corresponds(AES_ige_encrypt)] +pub fn aes_ige(in_: &[u8], out: &mut [u8], key: &AesKey, iv: &mut [u8], mode: Mode) { + unsafe { + assert!(in_.len() == out.len()); + assert!(in_.len() % ffi::AES_BLOCK_SIZE as usize == 0); + assert!(iv.len() >= ffi::AES_BLOCK_SIZE as usize * 2); + + let mode = match mode { + Mode::Encrypt => ffi::AES_ENCRYPT, + Mode::Decrypt => ffi::AES_DECRYPT, + }; + ffi::AES_ige_encrypt( + in_.as_ptr() as *const _, + out.as_mut_ptr() as *mut _, + in_.len(), + &key.0, + iv.as_mut_ptr() as *mut _, + mode, + ); + } +} + +/// Wrap a key, according to [RFC 3394](https://tools.ietf.org/html/rfc3394) +/// +/// * `key`: The key-encrypting-key to use. Must be a encrypting key +/// * `iv`: The IV to use. You must use the same IV for both wrapping and unwrapping +/// * `out`: The output buffer to store the ciphertext +/// * `in_`: The input buffer, storing the key to be wrapped +/// +/// Returns the number of bytes written into `out` +/// +/// # Panics +/// +/// Panics if either `out` or `in_` do not have sizes that are a multiple of 8, or if +/// `out` is not 8 bytes longer than `in_` +#[corresponds(AES_wrap_key)] +pub fn wrap_key( + key: &AesKey, + iv: Option<[u8; 8]>, + out: &mut [u8], + in_: &[u8], +) -> Result { + unsafe { + assert!(out.len() >= in_.len() + 8); // Ciphertext is 64 bits longer (see 2.2.1) + + let written = ffi::AES_wrap_key( + &key.0 as *const _ as *mut _, // this is safe, the implementation only uses the key as a const pointer. + iv.as_ref() + .map_or(ptr::null(), |iv| iv.as_ptr() as *const _), + out.as_ptr() as *mut _, + in_.as_ptr() as *const _, + in_.len() as AesSizeType, + ); + if written <= 0 { + Err(KeyError(())) + } else { + Ok(written as usize) + } + } +} + +/// Unwrap a key, according to [RFC 3394](https://tools.ietf.org/html/rfc3394) +/// +/// * `key`: The key-encrypting-key to decrypt the wrapped key. Must be a decrypting key +/// * `iv`: The same IV used for wrapping the key +/// * `out`: The buffer to write the unwrapped key to +/// * `in_`: The input ciphertext +/// +/// Returns the number of bytes written into `out` +/// +/// # Panics +/// +/// Panics if either `out` or `in_` do not have sizes that are a multiple of 8, or +/// if `in_` is not 8 bytes longer than `out` +#[corresponds(AES_unwrap_key)] +pub fn unwrap_key( + key: &AesKey, + iv: Option<[u8; 8]>, + out: &mut [u8], + in_: &[u8], +) -> Result { + unsafe { + assert!(out.len() + 8 <= in_.len()); + + let written = ffi::AES_unwrap_key( + &key.0 as *const _ as *mut _, // this is safe, the implementation only uses the key as a const pointer. + iv.as_ref() + .map_or(ptr::null(), |iv| iv.as_ptr() as *const _), + out.as_ptr() as *mut _, + in_.as_ptr() as *const _, + in_.len() as AesSizeType, + ); + + if written <= 0 { + Err(KeyError(())) + } else { + Ok(written as usize) + } + } +} + +#[cfg(test)] +mod test { + use hex::FromHex; + + use super::*; + #[cfg(not(boringssl))] + use crate::symm::Mode; + + // From https://www.mgp25.com/AESIGE/ + #[test] + #[cfg(not(boringssl))] + #[cfg(not(osslconf = "OPENSSL_NO_DEPRECATED_3_0"))] + fn ige_vector_1() { + let raw_key = "000102030405060708090A0B0C0D0E0F"; + let raw_iv = "000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F"; + let raw_pt = "0000000000000000000000000000000000000000000000000000000000000000"; + let raw_ct = "1A8519A6557BE652E9DA8E43DA4EF4453CF456B4CA488AA383C79C98B34797CB"; + + let key = AesKey::new_encrypt(&Vec::from_hex(raw_key).unwrap()).unwrap(); + let mut iv = Vec::from_hex(raw_iv).unwrap(); + let pt = Vec::from_hex(raw_pt).unwrap(); + let ct = Vec::from_hex(raw_ct).unwrap(); + + let mut ct_actual = vec![0; ct.len()]; + aes_ige(&pt, &mut ct_actual, &key, &mut iv, Mode::Encrypt); + assert_eq!(ct_actual, ct); + + let key = AesKey::new_decrypt(&Vec::from_hex(raw_key).unwrap()).unwrap(); + let mut iv = Vec::from_hex(raw_iv).unwrap(); + let mut pt_actual = vec![0; pt.len()]; + aes_ige(&ct, &mut pt_actual, &key, &mut iv, Mode::Decrypt); + assert_eq!(pt_actual, pt); + } + + // from the RFC https://tools.ietf.org/html/rfc3394#section-2.2.3 + #[test] + fn test_wrap_unwrap() { + let raw_key = Vec::from_hex("000102030405060708090A0B0C0D0E0F").unwrap(); + let key_data = Vec::from_hex("00112233445566778899AABBCCDDEEFF").unwrap(); + let expected_ciphertext = + Vec::from_hex("1FA68B0A8112B447AEF34BD8FB5A7B829D3E862371D2CFE5").unwrap(); + + let enc_key = AesKey::new_encrypt(&raw_key).unwrap(); + let mut wrapped = [0; 24]; + assert_eq!( + wrap_key(&enc_key, None, &mut wrapped, &key_data).unwrap(), + 24 + ); + assert_eq!(&wrapped[..], &expected_ciphertext[..]); + + let dec_key = AesKey::new_decrypt(&raw_key).unwrap(); + let mut unwrapped = [0; 16]; + assert_eq!( + unwrap_key(&dec_key, None, &mut unwrapped, &wrapped).unwrap(), + 16 + ); + assert_eq!(&unwrapped[..], &key_data[..]); + } +} diff --git a/vendor/openssl/src/asn1.rs b/vendor/openssl/src/asn1.rs new file mode 100644 index 0000000..19bd3b5 --- /dev/null +++ b/vendor/openssl/src/asn1.rs @@ -0,0 +1,910 @@ +#![deny(missing_docs)] + +//! Defines the format of certificates +//! +//! This module is used by [`x509`] and other certificate building functions +//! to describe time, strings, and objects. +//! +//! Abstract Syntax Notation One is an interface description language. +//! The specification comes from [X.208] by OSI, and rewritten in X.680. +//! ASN.1 describes properties of an object with a type set. Those types +//! can be atomic, structured, choice, and other (CHOICE and ANY). These +//! types are expressed as a number and the assignment operator ::= gives +//! the type a name. +//! +//! The implementation here provides a subset of the ASN.1 types that OpenSSL +//! uses, especially in the properties of a certificate used in HTTPS. +//! +//! [X.208]: https://www.itu.int/rec/T-REC-X.208-198811-W/en +//! [`x509`]: ../x509/struct.X509Builder.html +//! +//! ## Examples +//! +//! ``` +//! use openssl::asn1::Asn1Time; +//! let tomorrow = Asn1Time::days_from_now(1); +//! ``` +use cfg_if::cfg_if; +use foreign_types::{ForeignType, ForeignTypeRef}; +use libc::{c_char, c_int, c_long, time_t}; +use std::cmp::Ordering; +use std::convert::TryInto; +use std::ffi::CString; +use std::fmt; +use std::ptr; +use std::str; + +use crate::bio::MemBio; +use crate::bn::{BigNum, BigNumRef}; +use crate::error::ErrorStack; +use crate::nid::Nid; +use crate::stack::Stackable; +use crate::string::OpensslString; +use crate::{cvt, cvt_p, util}; +use openssl_macros::corresponds; + +foreign_type_and_impl_send_sync! { + type CType = ffi::ASN1_GENERALIZEDTIME; + fn drop = ffi::ASN1_GENERALIZEDTIME_free; + + /// Non-UTC representation of time + /// + /// If a time can be represented by UTCTime, UTCTime is used + /// otherwise, ASN1_GENERALIZEDTIME is used. This would be, for + /// example outside the year range of 1950-2049. + /// + /// [ASN1_GENERALIZEDTIME_set] documentation from OpenSSL provides + /// further details of implementation. Note: these docs are from the master + /// branch as documentation on the 1.1.0 branch did not include this page. + /// + /// [ASN1_GENERALIZEDTIME_set]: https://www.openssl.org/docs/manmaster/man3/ASN1_GENERALIZEDTIME_set.html + pub struct Asn1GeneralizedTime; + /// Reference to a [`Asn1GeneralizedTime`] + /// + /// [`Asn1GeneralizedTime`]: struct.Asn1GeneralizedTime.html + pub struct Asn1GeneralizedTimeRef; +} + +impl fmt::Display for Asn1GeneralizedTimeRef { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + unsafe { + let mem_bio = match MemBio::new() { + Err(_) => return f.write_str("error"), + Ok(m) => m, + }; + let print_result = cvt(ffi::ASN1_GENERALIZEDTIME_print( + mem_bio.as_ptr(), + self.as_ptr(), + )); + match print_result { + Err(_) => f.write_str("error"), + Ok(_) => f.write_str(str::from_utf8_unchecked(mem_bio.get_buf())), + } + } + } +} + +/// The type of an ASN.1 value. +#[derive(Debug, Copy, Clone, PartialEq, Eq)] +pub struct Asn1Type(c_int); + +#[allow(missing_docs)] // no need to document the constants +impl Asn1Type { + pub const EOC: Asn1Type = Asn1Type(ffi::V_ASN1_EOC); + + pub const BOOLEAN: Asn1Type = Asn1Type(ffi::V_ASN1_BOOLEAN); + + pub const INTEGER: Asn1Type = Asn1Type(ffi::V_ASN1_INTEGER); + + pub const BIT_STRING: Asn1Type = Asn1Type(ffi::V_ASN1_BIT_STRING); + + pub const OCTET_STRING: Asn1Type = Asn1Type(ffi::V_ASN1_OCTET_STRING); + + pub const NULL: Asn1Type = Asn1Type(ffi::V_ASN1_NULL); + + pub const OBJECT: Asn1Type = Asn1Type(ffi::V_ASN1_OBJECT); + + pub const OBJECT_DESCRIPTOR: Asn1Type = Asn1Type(ffi::V_ASN1_OBJECT_DESCRIPTOR); + + pub const EXTERNAL: Asn1Type = Asn1Type(ffi::V_ASN1_EXTERNAL); + + pub const REAL: Asn1Type = Asn1Type(ffi::V_ASN1_REAL); + + pub const ENUMERATED: Asn1Type = Asn1Type(ffi::V_ASN1_ENUMERATED); + + pub const UTF8STRING: Asn1Type = Asn1Type(ffi::V_ASN1_UTF8STRING); + + pub const SEQUENCE: Asn1Type = Asn1Type(ffi::V_ASN1_SEQUENCE); + + pub const SET: Asn1Type = Asn1Type(ffi::V_ASN1_SET); + + pub const NUMERICSTRING: Asn1Type = Asn1Type(ffi::V_ASN1_NUMERICSTRING); + + pub const PRINTABLESTRING: Asn1Type = Asn1Type(ffi::V_ASN1_PRINTABLESTRING); + + pub const T61STRING: Asn1Type = Asn1Type(ffi::V_ASN1_T61STRING); + + pub const TELETEXSTRING: Asn1Type = Asn1Type(ffi::V_ASN1_TELETEXSTRING); + + pub const VIDEOTEXSTRING: Asn1Type = Asn1Type(ffi::V_ASN1_VIDEOTEXSTRING); + + pub const IA5STRING: Asn1Type = Asn1Type(ffi::V_ASN1_IA5STRING); + + pub const UTCTIME: Asn1Type = Asn1Type(ffi::V_ASN1_UTCTIME); + + pub const GENERALIZEDTIME: Asn1Type = Asn1Type(ffi::V_ASN1_GENERALIZEDTIME); + + pub const GRAPHICSTRING: Asn1Type = Asn1Type(ffi::V_ASN1_GRAPHICSTRING); + + pub const ISO64STRING: Asn1Type = Asn1Type(ffi::V_ASN1_ISO64STRING); + + pub const VISIBLESTRING: Asn1Type = Asn1Type(ffi::V_ASN1_VISIBLESTRING); + + pub const GENERALSTRING: Asn1Type = Asn1Type(ffi::V_ASN1_GENERALSTRING); + + pub const UNIVERSALSTRING: Asn1Type = Asn1Type(ffi::V_ASN1_UNIVERSALSTRING); + + pub const BMPSTRING: Asn1Type = Asn1Type(ffi::V_ASN1_BMPSTRING); + + /// Constructs an `Asn1Type` from a raw OpenSSL value. + pub fn from_raw(value: c_int) -> Self { + Asn1Type(value) + } + + /// Returns the raw OpenSSL value represented by this type. + pub fn as_raw(&self) -> c_int { + self.0 + } +} + +/// Difference between two ASN1 times. +/// +/// This `struct` is created by the [`diff`] method on [`Asn1TimeRef`]. See its +/// documentation for more. +/// +/// [`diff`]: struct.Asn1TimeRef.html#method.diff +/// [`Asn1TimeRef`]: struct.Asn1TimeRef.html +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +#[cfg(any(ossl102, boringssl))] +pub struct TimeDiff { + /// Difference in days + pub days: c_int, + /// Difference in seconds. + /// + /// This is always less than the number of seconds in a day. + pub secs: c_int, +} + +foreign_type_and_impl_send_sync! { + type CType = ffi::ASN1_TIME; + fn drop = ffi::ASN1_TIME_free; + /// Time storage and comparison + /// + /// Asn1Time should be used to store and share time information + /// using certificates. If Asn1Time is set using a string, it must + /// be in either YYMMDDHHMMSSZ, YYYYMMDDHHMMSSZ, or another ASN.1 format. + /// + /// [ASN_TIME_set] documentation at OpenSSL explains the ASN.1 implementation + /// used by OpenSSL. + /// + /// [ASN_TIME_set]: https://www.openssl.org/docs/manmaster/crypto/ASN1_TIME_set.html + pub struct Asn1Time; + /// Reference to an [`Asn1Time`] + /// + /// [`Asn1Time`]: struct.Asn1Time.html + pub struct Asn1TimeRef; +} + +impl Asn1TimeRef { + /// Find difference between two times + #[corresponds(ASN1_TIME_diff)] + #[cfg(any(ossl102, boringssl))] + pub fn diff(&self, compare: &Self) -> Result { + let mut days = 0; + let mut secs = 0; + let other = compare.as_ptr(); + + let err = unsafe { ffi::ASN1_TIME_diff(&mut days, &mut secs, self.as_ptr(), other) }; + + match err { + 0 => Err(ErrorStack::get()), + _ => Ok(TimeDiff { days, secs }), + } + } + + /// Compare two times + #[corresponds(ASN1_TIME_compare)] + #[cfg(any(ossl102, boringssl))] + pub fn compare(&self, other: &Self) -> Result { + let d = self.diff(other)?; + if d.days > 0 || d.secs > 0 { + return Ok(Ordering::Less); + } + if d.days < 0 || d.secs < 0 { + return Ok(Ordering::Greater); + } + + Ok(Ordering::Equal) + } +} + +#[cfg(any(ossl102, boringssl))] +impl PartialEq for Asn1TimeRef { + fn eq(&self, other: &Asn1TimeRef) -> bool { + self.diff(other) + .map(|t| t.days == 0 && t.secs == 0) + .unwrap_or(false) + } +} + +#[cfg(any(ossl102, boringssl))] +impl PartialEq for Asn1TimeRef { + fn eq(&self, other: &Asn1Time) -> bool { + self.diff(other) + .map(|t| t.days == 0 && t.secs == 0) + .unwrap_or(false) + } +} + +#[cfg(any(ossl102, boringssl))] +impl PartialEq for &Asn1TimeRef { + fn eq(&self, other: &Asn1Time) -> bool { + self.diff(other) + .map(|t| t.days == 0 && t.secs == 0) + .unwrap_or(false) + } +} + +#[cfg(any(ossl102, boringssl))] +impl PartialOrd for Asn1TimeRef { + fn partial_cmp(&self, other: &Asn1TimeRef) -> Option { + self.compare(other).ok() + } +} + +#[cfg(any(ossl102, boringssl))] +impl PartialOrd for Asn1TimeRef { + fn partial_cmp(&self, other: &Asn1Time) -> Option { + self.compare(other).ok() + } +} + +#[cfg(any(ossl102, boringssl))] +impl PartialOrd for &Asn1TimeRef { + fn partial_cmp(&self, other: &Asn1Time) -> Option { + self.compare(other).ok() + } +} + +impl fmt::Display for Asn1TimeRef { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + unsafe { + let mem_bio = match MemBio::new() { + Err(_) => return f.write_str("error"), + Ok(m) => m, + }; + let print_result = cvt(ffi::ASN1_TIME_print(mem_bio.as_ptr(), self.as_ptr())); + match print_result { + Err(_) => f.write_str("error"), + Ok(_) => f.write_str(str::from_utf8_unchecked(mem_bio.get_buf())), + } + } + } +} + +impl fmt::Debug for Asn1TimeRef { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.write_str(&self.to_string()) + } +} + +impl Asn1Time { + #[corresponds(ASN1_TIME_new)] + fn new() -> Result { + ffi::init(); + + unsafe { + let handle = cvt_p(ffi::ASN1_TIME_new())?; + Ok(Asn1Time::from_ptr(handle)) + } + } + + #[corresponds(X509_gmtime_adj)] + fn from_period(period: c_long) -> Result { + ffi::init(); + + unsafe { + let handle = cvt_p(ffi::X509_gmtime_adj(ptr::null_mut(), period))?; + Ok(Asn1Time::from_ptr(handle)) + } + } + + /// Creates a new time on specified interval in days from now + pub fn days_from_now(days: u32) -> Result { + Asn1Time::from_period(days as c_long * 60 * 60 * 24) + } + + /// Creates a new time from the specified `time_t` value + #[corresponds(ASN1_TIME_set)] + pub fn from_unix(time: time_t) -> Result { + ffi::init(); + + unsafe { + let handle = cvt_p(ffi::ASN1_TIME_set(ptr::null_mut(), time))?; + Ok(Asn1Time::from_ptr(handle)) + } + } + + /// Creates a new time corresponding to the specified ASN1 time string. + #[corresponds(ASN1_TIME_set_string)] + #[allow(clippy::should_implement_trait)] + pub fn from_str(s: &str) -> Result { + unsafe { + let s = CString::new(s).unwrap(); + + let time = Asn1Time::new()?; + cvt(ffi::ASN1_TIME_set_string(time.as_ptr(), s.as_ptr()))?; + + Ok(time) + } + } + + /// Creates a new time corresponding to the specified X509 time string. + /// + /// Requires BoringSSL or OpenSSL 1.1.1 or newer. + #[corresponds(ASN1_TIME_set_string_X509)] + #[cfg(any(ossl111, boringssl))] + pub fn from_str_x509(s: &str) -> Result { + unsafe { + let s = CString::new(s).unwrap(); + + let time = Asn1Time::new()?; + cvt(ffi::ASN1_TIME_set_string_X509(time.as_ptr(), s.as_ptr()))?; + + Ok(time) + } + } +} + +#[cfg(any(ossl102, boringssl))] +impl PartialEq for Asn1Time { + fn eq(&self, other: &Asn1Time) -> bool { + self.diff(other) + .map(|t| t.days == 0 && t.secs == 0) + .unwrap_or(false) + } +} + +#[cfg(any(ossl102, boringssl))] +impl PartialEq for Asn1Time { + fn eq(&self, other: &Asn1TimeRef) -> bool { + self.diff(other) + .map(|t| t.days == 0 && t.secs == 0) + .unwrap_or(false) + } +} + +#[cfg(any(ossl102, boringssl))] +impl<'a> PartialEq<&'a Asn1TimeRef> for Asn1Time { + fn eq(&self, other: &&'a Asn1TimeRef) -> bool { + self.diff(other) + .map(|t| t.days == 0 && t.secs == 0) + .unwrap_or(false) + } +} + +#[cfg(any(ossl102, boringssl))] +impl PartialOrd for Asn1Time { + fn partial_cmp(&self, other: &Asn1Time) -> Option { + self.compare(other).ok() + } +} + +#[cfg(any(ossl102, boringssl))] +impl PartialOrd for Asn1Time { + fn partial_cmp(&self, other: &Asn1TimeRef) -> Option { + self.compare(other).ok() + } +} + +#[cfg(any(ossl102, boringssl))] +impl<'a> PartialOrd<&'a Asn1TimeRef> for Asn1Time { + fn partial_cmp(&self, other: &&'a Asn1TimeRef) -> Option { + self.compare(other).ok() + } +} + +foreign_type_and_impl_send_sync! { + type CType = ffi::ASN1_STRING; + fn drop = ffi::ASN1_STRING_free; + /// Primary ASN.1 type used by OpenSSL + /// + /// Almost all ASN.1 types in OpenSSL are represented by ASN1_STRING + /// structures. This implementation uses [ASN1_STRING-to_UTF8] to preserve + /// compatibility with Rust's String. + /// + /// [ASN1_STRING-to_UTF8]: https://www.openssl.org/docs/manmaster/crypto/ASN1_STRING_to_UTF8.html + pub struct Asn1String; + /// A reference to an [`Asn1String`]. + pub struct Asn1StringRef; +} + +impl Asn1StringRef { + /// Converts the ASN.1 underlying format to UTF8 + /// + /// ASN.1 strings may utilize UTF-16, ASCII, BMP, or UTF8. This is important to + /// consume the string in a meaningful way without knowing the underlying + /// format. + #[corresponds(ASN1_STRING_to_UTF8)] + pub fn as_utf8(&self) -> Result { + unsafe { + let mut ptr = ptr::null_mut(); + let len = ffi::ASN1_STRING_to_UTF8(&mut ptr, self.as_ptr()); + if len < 0 { + return Err(ErrorStack::get()); + } + + Ok(OpensslString::from_ptr(ptr as *mut c_char)) + } + } + + /// Return the string as an array of bytes. + /// + /// The bytes do not directly correspond to UTF-8 encoding. To interact with + /// strings in rust, it is preferable to use [`as_utf8`] + /// + /// [`as_utf8`]: struct.Asn1String.html#method.as_utf8 + #[corresponds(ASN1_STRING_get0_data)] + pub fn as_slice(&self) -> &[u8] { + unsafe { util::from_raw_parts(ASN1_STRING_get0_data(self.as_ptr()), self.len()) } + } + + /// Returns the number of bytes in the string. + #[corresponds(ASN1_STRING_length)] + pub fn len(&self) -> usize { + unsafe { ffi::ASN1_STRING_length(self.as_ptr()) as usize } + } + + /// Determines if the string is empty. + pub fn is_empty(&self) -> bool { + self.len() == 0 + } +} + +impl fmt::Debug for Asn1StringRef { + fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { + match self.as_utf8() { + Ok(openssl_string) => openssl_string.fmt(fmt), + Err(_) => fmt.write_str("error"), + } + } +} + +foreign_type_and_impl_send_sync! { + type CType = ffi::ASN1_INTEGER; + fn drop = ffi::ASN1_INTEGER_free; + + /// Numeric representation + /// + /// Integers in ASN.1 may include BigNum, int64 or uint64. BigNum implementation + /// can be found within [`bn`] module. + /// + /// OpenSSL documentation includes [`ASN1_INTEGER_set`]. + /// + /// [`bn`]: ../bn/index.html + /// [`ASN1_INTEGER_set`]: https://www.openssl.org/docs/manmaster/crypto/ASN1_INTEGER_set.html + pub struct Asn1Integer; + /// A reference to an [`Asn1Integer`]. + pub struct Asn1IntegerRef; +} + +impl Asn1Integer { + /// Converts a bignum to an `Asn1Integer`. + /// + /// Corresponds to [`BN_to_ASN1_INTEGER`]. Also see + /// [`BigNumRef::to_asn1_integer`]. + /// + /// [`BN_to_ASN1_INTEGER`]: https://www.openssl.org/docs/manmaster/crypto/BN_to_ASN1_INTEGER.html + /// [`BigNumRef::to_asn1_integer`]: ../bn/struct.BigNumRef.html#method.to_asn1_integer + pub fn from_bn(bn: &BigNumRef) -> Result { + bn.to_asn1_integer() + } +} + +impl Ord for Asn1Integer { + fn cmp(&self, other: &Self) -> Ordering { + Asn1IntegerRef::cmp(self, other) + } +} +impl PartialOrd for Asn1Integer { + fn partial_cmp(&self, other: &Asn1Integer) -> Option { + Some(self.cmp(other)) + } +} +impl Eq for Asn1Integer {} +impl PartialEq for Asn1Integer { + fn eq(&self, other: &Asn1Integer) -> bool { + Asn1IntegerRef::eq(self, other) + } +} + +impl Asn1IntegerRef { + #[allow(missing_docs, clippy::unnecessary_cast)] + #[deprecated(since = "0.10.6", note = "use to_bn instead")] + pub fn get(&self) -> i64 { + unsafe { ffi::ASN1_INTEGER_get(self.as_ptr()) as i64 } + } + + /// Converts the integer to a `BigNum`. + #[corresponds(ASN1_INTEGER_to_BN)] + pub fn to_bn(&self) -> Result { + unsafe { + cvt_p(ffi::ASN1_INTEGER_to_BN(self.as_ptr(), ptr::null_mut())) + .map(|p| BigNum::from_ptr(p)) + } + } + + /// Sets the ASN.1 value to the value of a signed 32-bit integer, for larger numbers + /// see [`bn`]. + /// + /// [`bn`]: ../bn/struct.BigNumRef.html#method.to_asn1_integer + #[corresponds(ASN1_INTEGER_set)] + pub fn set(&mut self, value: i32) -> Result<(), ErrorStack> { + unsafe { cvt(ffi::ASN1_INTEGER_set(self.as_ptr(), value as c_long)).map(|_| ()) } + } + + /// Creates a new Asn1Integer with the same value. + #[corresponds(ASN1_INTEGER_dup)] + pub fn to_owned(&self) -> Result { + unsafe { cvt_p(ffi::ASN1_INTEGER_dup(self.as_ptr())).map(|p| Asn1Integer::from_ptr(p)) } + } +} + +impl Ord for Asn1IntegerRef { + fn cmp(&self, other: &Self) -> Ordering { + let res = unsafe { ffi::ASN1_INTEGER_cmp(self.as_ptr(), other.as_ptr()) }; + res.cmp(&0) + } +} +impl PartialOrd for Asn1IntegerRef { + fn partial_cmp(&self, other: &Asn1IntegerRef) -> Option { + Some(self.cmp(other)) + } +} +impl Eq for Asn1IntegerRef {} +impl PartialEq for Asn1IntegerRef { + fn eq(&self, other: &Asn1IntegerRef) -> bool { + self.cmp(other) == Ordering::Equal + } +} + +foreign_type_and_impl_send_sync! { + type CType = ffi::ASN1_BIT_STRING; + fn drop = ffi::ASN1_BIT_STRING_free; + /// Sequence of bytes + /// + /// Asn1BitString is used in [`x509`] certificates for the signature. + /// The bit string acts as a collection of bytes. + /// + /// [`x509`]: ../x509/struct.X509.html#method.signature + pub struct Asn1BitString; + /// A reference to an [`Asn1BitString`]. + pub struct Asn1BitStringRef; +} + +impl Asn1BitStringRef { + /// Returns the Asn1BitString as a slice. + #[corresponds(ASN1_STRING_get0_data)] + pub fn as_slice(&self) -> &[u8] { + unsafe { util::from_raw_parts(ASN1_STRING_get0_data(self.as_ptr() as *mut _), self.len()) } + } + + /// Returns the number of bytes in the string. + #[corresponds(ASN1_STRING_length)] + pub fn len(&self) -> usize { + unsafe { ffi::ASN1_STRING_length(self.as_ptr() as *const _) as usize } + } + + /// Determines if the string is empty. + pub fn is_empty(&self) -> bool { + self.len() == 0 + } +} + +foreign_type_and_impl_send_sync! { + type CType = ffi::ASN1_OCTET_STRING; + fn drop = ffi::ASN1_OCTET_STRING_free; + /// ASN.1 OCTET STRING type + pub struct Asn1OctetString; + /// A reference to an [`Asn1OctetString`]. + pub struct Asn1OctetStringRef; +} + +impl Asn1OctetString { + /// Creates an Asn1OctetString from bytes + pub fn new_from_bytes(value: &[u8]) -> Result { + ffi::init(); + unsafe { + let s = cvt_p(ffi::ASN1_OCTET_STRING_new())?; + ffi::ASN1_OCTET_STRING_set(s, value.as_ptr(), value.len().try_into().unwrap()); + Ok(Self::from_ptr(s)) + } + } +} + +impl Asn1OctetStringRef { + /// Returns the octet string as an array of bytes. + #[corresponds(ASN1_STRING_get0_data)] + pub fn as_slice(&self) -> &[u8] { + unsafe { util::from_raw_parts(ASN1_STRING_get0_data(self.as_ptr().cast()), self.len()) } + } + + /// Returns the number of bytes in the octet string. + #[corresponds(ASN1_STRING_length)] + pub fn len(&self) -> usize { + unsafe { ffi::ASN1_STRING_length(self.as_ptr().cast()) as usize } + } + + /// Determines if the string is empty. + pub fn is_empty(&self) -> bool { + self.len() == 0 + } +} + +foreign_type_and_impl_send_sync! { + type CType = ffi::ASN1_OBJECT; + fn drop = ffi::ASN1_OBJECT_free; + fn clone = ffi::OBJ_dup; + + /// Object Identifier + /// + /// Represents an ASN.1 Object. Typically, NIDs, or numeric identifiers + /// are stored as a table within the [`Nid`] module. These constants are + /// used to determine attributes of a certificate, such as mapping the + /// attribute "CommonName" to "CN" which is represented as the OID of 13. + /// This attribute is a constant in the [`nid::COMMONNAME`]. + /// + /// OpenSSL documentation at [`OBJ_nid2obj`] + /// + /// [`Nid`]: ../nid/index.html + /// [`nid::COMMONNAME`]: ../nid/constant.COMMONNAME.html + /// [`OBJ_nid2obj`]: https://www.openssl.org/docs/manmaster/crypto/OBJ_obj2nid.html + pub struct Asn1Object; + /// A reference to an [`Asn1Object`]. + pub struct Asn1ObjectRef; +} + +impl Stackable for Asn1Object { + type StackType = ffi::stack_st_ASN1_OBJECT; +} + +impl Asn1Object { + /// Constructs an ASN.1 Object Identifier from a string representation of the OID. + #[corresponds(OBJ_txt2obj)] + #[allow(clippy::should_implement_trait)] + pub fn from_str(txt: &str) -> Result { + unsafe { + ffi::init(); + let txt = CString::new(txt).unwrap(); + let obj: *mut ffi::ASN1_OBJECT = cvt_p(ffi::OBJ_txt2obj(txt.as_ptr() as *const _, 0))?; + Ok(Asn1Object::from_ptr(obj)) + } + } + + /// Return the OID as an DER encoded array of bytes. This is the ASN.1 + /// value, not including tag or length. + /// + /// Requires OpenSSL 1.1.1 or newer. + #[corresponds(OBJ_get0_data)] + #[cfg(ossl111)] + pub fn as_slice(&self) -> &[u8] { + unsafe { + let len = ffi::OBJ_length(self.as_ptr()); + util::from_raw_parts(ffi::OBJ_get0_data(self.as_ptr()), len) + } + } +} + +impl Asn1ObjectRef { + /// Returns the NID associated with this OID. + pub fn nid(&self) -> Nid { + unsafe { Nid::from_raw(ffi::OBJ_obj2nid(self.as_ptr())) } + } +} + +impl fmt::Display for Asn1ObjectRef { + fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { + unsafe { + let mut buf = [0; 80]; + let len = ffi::OBJ_obj2txt( + buf.as_mut_ptr() as *mut _, + buf.len() as c_int, + self.as_ptr(), + 0, + ); + match str::from_utf8(&buf[..len as usize]) { + Err(_) => fmt.write_str("error"), + Ok(s) => fmt.write_str(s), + } + } + } +} + +impl fmt::Debug for Asn1ObjectRef { + fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { + fmt.write_str(self.to_string().as_str()) + } +} + +cfg_if! { + if #[cfg(any(ossl110, libressl273, boringssl))] { + use ffi::ASN1_STRING_get0_data; + } else { + #[allow(bad_style)] + unsafe fn ASN1_STRING_get0_data(s: *mut ffi::ASN1_STRING) -> *const ::libc::c_uchar { + ffi::ASN1_STRING_data(s) + } + } +} + +foreign_type_and_impl_send_sync! { + type CType = ffi::ASN1_ENUMERATED; + fn drop = ffi::ASN1_ENUMERATED_free; + + /// An ASN.1 enumerated. + pub struct Asn1Enumerated; + /// A reference to an [`Asn1Enumerated`]. + pub struct Asn1EnumeratedRef; +} + +impl Asn1EnumeratedRef { + /// Get the value, if it fits in the required bounds. + #[corresponds(ASN1_ENUMERATED_get_int64)] + #[cfg(ossl110)] + pub fn get_i64(&self) -> Result { + let mut crl_reason = 0; + unsafe { + cvt(ffi::ASN1_ENUMERATED_get_int64( + &mut crl_reason, + self.as_ptr(), + ))?; + } + Ok(crl_reason) + } +} + +#[cfg(test)] +mod tests { + use super::*; + + use crate::bn::BigNum; + use crate::nid::Nid; + + /// Tests conversion between BigNum and Asn1Integer. + #[test] + fn bn_cvt() { + fn roundtrip(bn: BigNum) { + let large = Asn1Integer::from_bn(&bn).unwrap(); + assert_eq!(large.to_bn().unwrap(), bn); + } + + roundtrip(BigNum::from_dec_str("1000000000000000000000000000000000").unwrap()); + roundtrip(-BigNum::from_dec_str("1000000000000000000000000000000000").unwrap()); + roundtrip(BigNum::from_u32(1234).unwrap()); + roundtrip(-BigNum::from_u32(1234).unwrap()); + } + + #[test] + fn time_from_str() { + Asn1Time::from_str("99991231235959Z").unwrap(); + #[cfg(ossl111)] + Asn1Time::from_str_x509("99991231235959Z").unwrap(); + } + + #[test] + fn time_from_unix() { + let t = Asn1Time::from_unix(0).unwrap(); + assert_eq!("Jan 1 00:00:00 1970 GMT", t.to_string()); + } + + #[test] + #[cfg(any(ossl102, boringssl))] + fn time_eq() { + let a = Asn1Time::from_str("99991231235959Z").unwrap(); + let b = Asn1Time::from_str("99991231235959Z").unwrap(); + let c = Asn1Time::from_str("99991231235958Z").unwrap(); + let a_ref = a.as_ref(); + let b_ref = b.as_ref(); + let c_ref = c.as_ref(); + assert!(a == b); + assert!(a != c); + assert!(a == b_ref); + assert!(a != c_ref); + assert!(b_ref == a); + assert!(c_ref != a); + assert!(a_ref == b_ref); + assert!(a_ref != c_ref); + } + + #[test] + #[cfg(any(ossl102, boringssl))] + fn time_ord() { + let a = Asn1Time::from_str("99991231235959Z").unwrap(); + let b = Asn1Time::from_str("99991231235959Z").unwrap(); + let c = Asn1Time::from_str("99991231235958Z").unwrap(); + let a_ref = a.as_ref(); + let b_ref = b.as_ref(); + let c_ref = c.as_ref(); + assert!(a >= b); + assert!(a > c); + assert!(b <= a); + assert!(c < a); + + assert!(a_ref >= b); + assert!(a_ref > c); + assert!(b_ref <= a); + assert!(c_ref < a); + + assert!(a >= b_ref); + assert!(a > c_ref); + assert!(b <= a_ref); + assert!(c < a_ref); + + assert!(a_ref >= b_ref); + assert!(a_ref > c_ref); + assert!(b_ref <= a_ref); + assert!(c_ref < a_ref); + } + + #[test] + fn integer_to_owned() { + let a = Asn1Integer::from_bn(&BigNum::from_dec_str("42").unwrap()).unwrap(); + let b = a.to_owned().unwrap(); + assert_eq!( + a.to_bn().unwrap().to_dec_str().unwrap().to_string(), + b.to_bn().unwrap().to_dec_str().unwrap().to_string(), + ); + assert_ne!(a.as_ptr(), b.as_ptr()); + } + + #[test] + fn integer_cmp() { + let a = Asn1Integer::from_bn(&BigNum::from_dec_str("42").unwrap()).unwrap(); + let b = Asn1Integer::from_bn(&BigNum::from_dec_str("42").unwrap()).unwrap(); + let c = Asn1Integer::from_bn(&BigNum::from_dec_str("43").unwrap()).unwrap(); + assert!(a == b); + assert!(a != c); + assert!(a < c); + assert!(c > b); + } + + #[test] + fn object_from_str() { + let object = Asn1Object::from_str("2.16.840.1.101.3.4.2.1").unwrap(); + assert_eq!(object.nid(), Nid::SHA256); + } + + #[test] + fn object_from_str_with_invalid_input() { + Asn1Object::from_str("NOT AN OID") + .map(|object| object.to_string()) + .expect_err("parsing invalid OID should fail"); + } + + #[test] + #[cfg(ossl111)] + fn object_to_slice() { + let object = Asn1Object::from_str("2.16.840.1.101.3.4.2.1").unwrap(); + assert_eq!( + object.as_slice(), + &[0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01], + ); + } + + #[test] + fn asn1_octet_string() { + let octet_string = Asn1OctetString::new_from_bytes(b"hello world").unwrap(); + assert_eq!(octet_string.as_slice(), b"hello world"); + assert_eq!(octet_string.len(), 11); + } +} diff --git a/vendor/openssl/src/base64.rs b/vendor/openssl/src/base64.rs new file mode 100644 index 0000000..5ac3547 --- /dev/null +++ b/vendor/openssl/src/base64.rs @@ -0,0 +1,128 @@ +//! Base64 encoding support. +use crate::error::ErrorStack; +use crate::{cvt_n, LenType}; +use libc::c_int; +use openssl_macros::corresponds; + +/// Encodes a slice of bytes to a base64 string. +/// +/// # Panics +/// +/// Panics if the input length or computed output length overflow a signed C integer. +#[corresponds(EVP_EncodeBlock)] +pub fn encode_block(src: &[u8]) -> String { + assert!(src.len() <= c_int::MAX as usize); + let src_len = src.len() as LenType; + + let len = encoded_len(src_len).unwrap(); + let mut out = Vec::with_capacity(len as usize); + + // SAFETY: `encoded_len` ensures space for 4 output characters + // for every 3 input bytes including padding and nul terminator. + // `EVP_EncodeBlock` will write only single byte ASCII characters. + // `EVP_EncodeBlock` will only write to not read from `out`. + unsafe { + let out_len = ffi::EVP_EncodeBlock(out.as_mut_ptr(), src.as_ptr(), src_len); + out.set_len(out_len as usize); + String::from_utf8_unchecked(out) + } +} + +/// Decodes a base64-encoded string to bytes. +/// +/// # Panics +/// +/// Panics if the input length or computed output length overflow a signed C integer. +#[corresponds(EVP_DecodeBlock)] +pub fn decode_block(src: &str) -> Result, ErrorStack> { + let src = src.trim(); + + // https://github.com/openssl/openssl/issues/12143 + if src.is_empty() { + return Ok(vec![]); + } + + assert!(src.len() <= c_int::MAX as usize); + let src_len = src.len() as LenType; + + let len = decoded_len(src_len).unwrap(); + let mut out = Vec::with_capacity(len as usize); + + // SAFETY: `decoded_len` ensures space for 3 output bytes + // for every 4 input characters including padding. + // `EVP_DecodeBlock` can write fewer bytes after stripping + // leading and trailing whitespace, but never more. + // `EVP_DecodeBlock` will only write to not read from `out`. + unsafe { + let out_len = cvt_n(ffi::EVP_DecodeBlock( + out.as_mut_ptr(), + src.as_ptr(), + src_len, + ))?; + out.set_len(out_len as usize); + } + + if src.ends_with('=') { + out.pop(); + if src.ends_with("==") { + out.pop(); + } + } + + Ok(out) +} + +fn encoded_len(src_len: LenType) -> Option { + let mut len = (src_len / 3).checked_mul(4)?; + + if src_len % 3 != 0 { + len = len.checked_add(4)?; + } + + len = len.checked_add(1)?; + + Some(len) +} + +fn decoded_len(src_len: LenType) -> Option { + let mut len = (src_len / 4).checked_mul(3)?; + + if src_len % 4 != 0 { + len = len.checked_add(3)?; + } + + Some(len) +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_encode_block() { + assert_eq!("".to_string(), encode_block(b"")); + assert_eq!("Zg==".to_string(), encode_block(b"f")); + assert_eq!("Zm8=".to_string(), encode_block(b"fo")); + assert_eq!("Zm9v".to_string(), encode_block(b"foo")); + assert_eq!("Zm9vYg==".to_string(), encode_block(b"foob")); + assert_eq!("Zm9vYmE=".to_string(), encode_block(b"fooba")); + assert_eq!("Zm9vYmFy".to_string(), encode_block(b"foobar")); + } + + #[test] + fn test_decode_block() { + assert_eq!(b"".to_vec(), decode_block("").unwrap()); + assert_eq!(b"f".to_vec(), decode_block("Zg==").unwrap()); + assert_eq!(b"fo".to_vec(), decode_block("Zm8=").unwrap()); + assert_eq!(b"foo".to_vec(), decode_block("Zm9v").unwrap()); + assert_eq!(b"foob".to_vec(), decode_block("Zm9vYg==").unwrap()); + assert_eq!(b"fooba".to_vec(), decode_block("Zm9vYmE=").unwrap()); + assert_eq!(b"foobar".to_vec(), decode_block("Zm9vYmFy").unwrap()); + } + + #[test] + fn test_strip_whitespace() { + assert_eq!(b"foobar".to_vec(), decode_block(" Zm9vYmFy\n").unwrap()); + assert_eq!(b"foob".to_vec(), decode_block(" Zm9vYg==\n").unwrap()); + } +} diff --git a/vendor/openssl/src/bio.rs b/vendor/openssl/src/bio.rs new file mode 100644 index 0000000..e97374b --- /dev/null +++ b/vendor/openssl/src/bio.rs @@ -0,0 +1,96 @@ +use cfg_if::cfg_if; +use libc::c_int; +use std::marker::PhantomData; +use std::ptr; + +use crate::cvt_p; +use crate::error::ErrorStack; +use crate::util; + +pub struct MemBioSlice<'a>(*mut ffi::BIO, PhantomData<&'a [u8]>); + +impl Drop for MemBioSlice<'_> { + fn drop(&mut self) { + unsafe { + ffi::BIO_free_all(self.0); + } + } +} + +impl<'a> MemBioSlice<'a> { + pub fn new(buf: &'a [u8]) -> Result, ErrorStack> { + ffi::init(); + + assert!(buf.len() <= c_int::MAX as usize); + let bio = unsafe { + cvt_p(BIO_new_mem_buf( + buf.as_ptr() as *const _, + buf.len() as crate::SLenType, + ))? + }; + + Ok(MemBioSlice(bio, PhantomData)) + } + + pub fn as_ptr(&self) -> *mut ffi::BIO { + self.0 + } +} + +pub struct MemBio(*mut ffi::BIO); + +impl Drop for MemBio { + fn drop(&mut self) { + unsafe { + ffi::BIO_free_all(self.0); + } + } +} + +impl MemBio { + pub fn new() -> Result { + ffi::init(); + + let bio = unsafe { cvt_p(ffi::BIO_new(ffi::BIO_s_mem()))? }; + Ok(MemBio(bio)) + } + + pub fn as_ptr(&self) -> *mut ffi::BIO { + self.0 + } + + pub fn get_buf(&self) -> &[u8] { + unsafe { + let mut ptr = ptr::null_mut(); + let len = ffi::BIO_get_mem_data(self.0, &mut ptr); + util::from_raw_parts(ptr as *const _ as *const _, len as usize) + } + } + + #[cfg(not(boringssl))] + pub unsafe fn from_ptr(bio: *mut ffi::BIO) -> MemBio { + MemBio(bio) + } +} + +cfg_if! { + if #[cfg(any(ossl102, boringssl))] { + use ffi::BIO_new_mem_buf; + } else { + #[allow(bad_style)] + unsafe fn BIO_new_mem_buf(buf: *const ::libc::c_void, len: ::libc::c_int) -> *mut ffi::BIO { + ffi::BIO_new_mem_buf(buf as *mut _, len) + } + } +} + +#[cfg(test)] +mod tests { + use super::MemBio; + + #[test] + fn test_mem_bio_get_buf_empty() { + let b = MemBio::new().unwrap(); + assert_eq!(b.get_buf(), &[]); + } +} diff --git a/vendor/openssl/src/bn.rs b/vendor/openssl/src/bn.rs new file mode 100644 index 0000000..99292fd --- /dev/null +++ b/vendor/openssl/src/bn.rs @@ -0,0 +1,1523 @@ +//! BigNum implementation +//! +//! Large numbers are important for a cryptographic library. OpenSSL implementation +//! of BigNum uses dynamically assigned memory to store an array of bit chunks. This +//! allows numbers of any size to be compared and mathematical functions performed. +//! +//! OpenSSL wiki describes the [`BIGNUM`] data structure. +//! +//! # Examples +//! +//! ``` +//! use openssl::bn::BigNum; +//! use openssl::error::ErrorStack; +//! +//! fn main() -> Result<(), ErrorStack> { +//! let a = BigNum::new()?; // a = 0 +//! let b = BigNum::from_dec_str("1234567890123456789012345")?; +//! let c = &a * &b; +//! assert_eq!(a, c); +//! Ok(()) +//! } +//! ``` +//! +//! [`BIGNUM`]: https://wiki.openssl.org/index.php/Manual:Bn_internal(3) +use cfg_if::cfg_if; +use foreign_types::{ForeignType, ForeignTypeRef}; +use libc::c_int; +use std::cmp::Ordering; +use std::ffi::CString; +use std::ops::{Add, Deref, Div, Mul, Neg, Rem, Shl, Shr, Sub}; +use std::{fmt, ptr}; + +use crate::asn1::Asn1Integer; +use crate::error::ErrorStack; +use crate::string::OpensslString; +use crate::{cvt, cvt_n, cvt_p, LenType}; +use openssl_macros::corresponds; + +cfg_if! { + if #[cfg(any(ossl110, libressl350))] { + use ffi::{ + BN_get_rfc2409_prime_1024, BN_get_rfc2409_prime_768, BN_get_rfc3526_prime_1536, + BN_get_rfc3526_prime_2048, BN_get_rfc3526_prime_3072, BN_get_rfc3526_prime_4096, + BN_get_rfc3526_prime_6144, BN_get_rfc3526_prime_8192, BN_is_negative, + }; + } else if #[cfg(boringssl)] { + use ffi::BN_is_negative; + } else { + use ffi::{ + get_rfc2409_prime_1024 as BN_get_rfc2409_prime_1024, + get_rfc2409_prime_768 as BN_get_rfc2409_prime_768, + get_rfc3526_prime_1536 as BN_get_rfc3526_prime_1536, + get_rfc3526_prime_2048 as BN_get_rfc3526_prime_2048, + get_rfc3526_prime_3072 as BN_get_rfc3526_prime_3072, + get_rfc3526_prime_4096 as BN_get_rfc3526_prime_4096, + get_rfc3526_prime_6144 as BN_get_rfc3526_prime_6144, + get_rfc3526_prime_8192 as BN_get_rfc3526_prime_8192, + }; + + #[allow(bad_style)] + unsafe fn BN_is_negative(bn: *const ffi::BIGNUM) -> c_int { + (*bn).neg + } + } +} + +/// Options for the most significant bits of a randomly generated `BigNum`. +pub struct MsbOption(c_int); + +impl MsbOption { + /// The most significant bit of the number may be 0. + pub const MAYBE_ZERO: MsbOption = MsbOption(-1); + + /// The most significant bit of the number must be 1. + pub const ONE: MsbOption = MsbOption(0); + + /// The most significant two bits of the number must be 1. + /// + /// The number of bits in the product of two such numbers will always be exactly twice the + /// number of bits in the original numbers. + pub const TWO_ONES: MsbOption = MsbOption(1); +} + +foreign_type_and_impl_send_sync! { + type CType = ffi::BN_CTX; + fn drop = ffi::BN_CTX_free; + + /// Temporary storage for BigNums on the secure heap + /// + /// BigNum values are stored dynamically and therefore can be expensive + /// to allocate. BigNumContext and the OpenSSL [`BN_CTX`] structure are used + /// internally when passing BigNum values between subroutines. + /// + /// [`BN_CTX`]: https://www.openssl.org/docs/manmaster/crypto/BN_CTX_new.html + pub struct BigNumContext; + /// Reference to [`BigNumContext`] + /// + /// [`BigNumContext`]: struct.BigNumContext.html + pub struct BigNumContextRef; +} + +impl BigNumContext { + /// Returns a new `BigNumContext`. + #[corresponds(BN_CTX_new)] + pub fn new() -> Result { + unsafe { + ffi::init(); + cvt_p(ffi::BN_CTX_new()).map(BigNumContext) + } + } + + /// Returns a new secure `BigNumContext`. + #[corresponds(BN_CTX_secure_new)] + #[cfg(ossl110)] + pub fn new_secure() -> Result { + unsafe { + ffi::init(); + cvt_p(ffi::BN_CTX_secure_new()).map(BigNumContext) + } + } +} + +foreign_type_and_impl_send_sync! { + type CType = ffi::BIGNUM; + fn drop = ffi::BN_free; + + /// Dynamically sized large number implementation + /// + /// Perform large number mathematics. Create a new BigNum + /// with [`new`]. Perform standard mathematics on large numbers using + /// methods from [`Dref`] + /// + /// OpenSSL documentation at [`BN_new`]. + /// + /// [`new`]: struct.BigNum.html#method.new + /// [`Dref`]: struct.BigNum.html#deref-methods + /// [`BN_new`]: https://www.openssl.org/docs/manmaster/crypto/BN_new.html + /// + /// # Examples + /// ``` + /// use openssl::bn::BigNum; + /// # use openssl::error::ErrorStack; + /// # fn bignums() -> Result< (), ErrorStack > { + /// let little_big = BigNum::from_u32(std::u32::MAX)?; + /// assert_eq!(*&little_big.num_bytes(), 4); + /// # Ok(()) + /// # } + /// # fn main () { bignums(); } + /// ``` + pub struct BigNum; + /// Reference to a [`BigNum`] + /// + /// [`BigNum`]: struct.BigNum.html + pub struct BigNumRef; +} + +impl BigNumRef { + /// Erases the memory used by this `BigNum`, resetting its value to 0. + /// + /// This can be used to destroy sensitive data such as keys when they are no longer needed. + #[corresponds(BN_clear)] + pub fn clear(&mut self) { + unsafe { ffi::BN_clear(self.as_ptr()) } + } + + /// Adds a `u32` to `self`. + #[corresponds(BN_add_word)] + pub fn add_word(&mut self, w: u32) -> Result<(), ErrorStack> { + unsafe { cvt(ffi::BN_add_word(self.as_ptr(), w as ffi::BN_ULONG)).map(|_| ()) } + } + + /// Subtracts a `u32` from `self`. + #[corresponds(BN_sub_word)] + pub fn sub_word(&mut self, w: u32) -> Result<(), ErrorStack> { + unsafe { cvt(ffi::BN_sub_word(self.as_ptr(), w as ffi::BN_ULONG)).map(|_| ()) } + } + + /// Multiplies a `u32` by `self`. + #[corresponds(BN_mul_word)] + pub fn mul_word(&mut self, w: u32) -> Result<(), ErrorStack> { + unsafe { cvt(ffi::BN_mul_word(self.as_ptr(), w as ffi::BN_ULONG)).map(|_| ()) } + } + + /// Divides `self` by a `u32`, returning the remainder. + #[corresponds(BN_div_word)] + #[allow(clippy::useless_conversion)] + pub fn div_word(&mut self, w: u32) -> Result { + unsafe { + let r = ffi::BN_div_word(self.as_ptr(), w.into()); + if r == ffi::BN_ULONG::MAX { + Err(ErrorStack::get()) + } else { + Ok(r.into()) + } + } + } + + /// Returns the result of `self` modulo `w`. + #[corresponds(BN_mod_word)] + #[allow(clippy::useless_conversion)] + pub fn mod_word(&self, w: u32) -> Result { + unsafe { + let r = ffi::BN_mod_word(self.as_ptr(), w.into()); + if r == ffi::BN_ULONG::MAX { + Err(ErrorStack::get()) + } else { + Ok(r.into()) + } + } + } + + /// Places a cryptographically-secure pseudo-random nonnegative + /// number less than `self` in `rnd`. + #[corresponds(BN_rand_range)] + pub fn rand_range(&self, rnd: &mut BigNumRef) -> Result<(), ErrorStack> { + unsafe { cvt(ffi::BN_rand_range(rnd.as_ptr(), self.as_ptr())).map(|_| ()) } + } + + /// The cryptographically weak counterpart to `rand_in_range`. + #[cfg(not(osslconf = "OPENSSL_NO_DEPRECATED_3_0"))] + #[corresponds(BN_pseudo_rand_range)] + pub fn pseudo_rand_range(&self, rnd: &mut BigNumRef) -> Result<(), ErrorStack> { + unsafe { cvt(ffi::BN_pseudo_rand_range(rnd.as_ptr(), self.as_ptr())).map(|_| ()) } + } + + /// Sets bit `n`. Equivalent to `self |= (1 << n)`. + /// + /// When setting a bit outside of `self`, it is expanded. + #[corresponds(BN_set_bit)] + #[allow(clippy::useless_conversion)] + pub fn set_bit(&mut self, n: i32) -> Result<(), ErrorStack> { + unsafe { cvt(ffi::BN_set_bit(self.as_ptr(), n.into())).map(|_| ()) } + } + + /// Clears bit `n`, setting it to 0. Equivalent to `self &= ~(1 << n)`. + /// + /// When clearing a bit outside of `self`, an error is returned. + #[corresponds(BN_clear_bit)] + #[allow(clippy::useless_conversion)] + pub fn clear_bit(&mut self, n: i32) -> Result<(), ErrorStack> { + unsafe { cvt(ffi::BN_clear_bit(self.as_ptr(), n.into())).map(|_| ()) } + } + + /// Returns `true` if the `n`th bit of `self` is set to 1, `false` otherwise. + #[corresponds(BN_is_bit_set)] + #[allow(clippy::useless_conversion)] + pub fn is_bit_set(&self, n: i32) -> bool { + unsafe { ffi::BN_is_bit_set(self.as_ptr(), n.into()) == 1 } + } + + /// Truncates `self` to the lowest `n` bits. + /// + /// An error occurs if `self` is already shorter than `n` bits. + #[corresponds(BN_mask_bits)] + #[allow(clippy::useless_conversion)] + pub fn mask_bits(&mut self, n: i32) -> Result<(), ErrorStack> { + unsafe { cvt(ffi::BN_mask_bits(self.as_ptr(), n.into())).map(|_| ()) } + } + + /// Places `a << 1` in `self`. Equivalent to `self * 2`. + #[corresponds(BN_lshift1)] + pub fn lshift1(&mut self, a: &BigNumRef) -> Result<(), ErrorStack> { + unsafe { cvt(ffi::BN_lshift1(self.as_ptr(), a.as_ptr())).map(|_| ()) } + } + + /// Places `a >> 1` in `self`. Equivalent to `self / 2`. + #[corresponds(BN_rshift1)] + pub fn rshift1(&mut self, a: &BigNumRef) -> Result<(), ErrorStack> { + unsafe { cvt(ffi::BN_rshift1(self.as_ptr(), a.as_ptr())).map(|_| ()) } + } + + /// Places `a + b` in `self`. [`core::ops::Add`] is also implemented for `BigNumRef`. + /// + /// [`core::ops::Add`]: struct.BigNumRef.html#method.add + #[corresponds(BN_add)] + pub fn checked_add(&mut self, a: &BigNumRef, b: &BigNumRef) -> Result<(), ErrorStack> { + unsafe { cvt(ffi::BN_add(self.as_ptr(), a.as_ptr(), b.as_ptr())).map(|_| ()) } + } + + /// Places `a - b` in `self`. [`core::ops::Sub`] is also implemented for `BigNumRef`. + /// + /// [`core::ops::Sub`]: struct.BigNumRef.html#method.sub + #[corresponds(BN_sub)] + pub fn checked_sub(&mut self, a: &BigNumRef, b: &BigNumRef) -> Result<(), ErrorStack> { + unsafe { cvt(ffi::BN_sub(self.as_ptr(), a.as_ptr(), b.as_ptr())).map(|_| ()) } + } + + /// Places `a << n` in `self`. Equivalent to `a * 2 ^ n`. + #[corresponds(BN_lshift)] + #[allow(clippy::useless_conversion)] + pub fn lshift(&mut self, a: &BigNumRef, n: i32) -> Result<(), ErrorStack> { + unsafe { cvt(ffi::BN_lshift(self.as_ptr(), a.as_ptr(), n.into())).map(|_| ()) } + } + + /// Places `a >> n` in `self`. Equivalent to `a / 2 ^ n`. + #[corresponds(BN_rshift)] + #[allow(clippy::useless_conversion)] + pub fn rshift(&mut self, a: &BigNumRef, n: i32) -> Result<(), ErrorStack> { + unsafe { cvt(ffi::BN_rshift(self.as_ptr(), a.as_ptr(), n.into())).map(|_| ()) } + } + + /// Creates a new BigNum with the same value. + #[corresponds(BN_dup)] + pub fn to_owned(&self) -> Result { + unsafe { cvt_p(ffi::BN_dup(self.as_ptr())).map(|b| BigNum::from_ptr(b)) } + } + + /// Sets the sign of `self`. Pass true to set `self` to a negative. False sets + /// `self` positive. + #[corresponds(BN_set_negative)] + pub fn set_negative(&mut self, negative: bool) { + unsafe { ffi::BN_set_negative(self.as_ptr(), negative as c_int) } + } + + /// Compare the absolute values of `self` and `oth`. + /// + /// # Examples + /// + /// ``` + /// # use openssl::bn::BigNum; + /// # use std::cmp::Ordering; + /// let s = -BigNum::from_u32(8).unwrap(); + /// let o = BigNum::from_u32(8).unwrap(); + /// + /// assert_eq!(s.ucmp(&o), Ordering::Equal); + /// ``` + #[corresponds(BN_ucmp)] + pub fn ucmp(&self, oth: &BigNumRef) -> Ordering { + unsafe { ffi::BN_ucmp(self.as_ptr(), oth.as_ptr()).cmp(&0) } + } + + /// Returns `true` if `self` is negative. + #[corresponds(BN_is_negative)] + pub fn is_negative(&self) -> bool { + unsafe { BN_is_negative(self.as_ptr()) == 1 } + } + + /// Returns `true` is `self` is even. + #[corresponds(BN_is_even)] + #[cfg(any(ossl110, boringssl, libressl350))] + pub fn is_even(&self) -> bool { + !self.is_odd() + } + + /// Returns `true` is `self` is odd. + #[corresponds(BN_is_odd)] + #[cfg(any(ossl110, boringssl, libressl350))] + pub fn is_odd(&self) -> bool { + unsafe { ffi::BN_is_odd(self.as_ptr()) == 1 } + } + + /// Returns the number of significant bits in `self`. + #[corresponds(BN_num_bits)] + #[allow(clippy::unnecessary_cast)] + pub fn num_bits(&self) -> i32 { + unsafe { ffi::BN_num_bits(self.as_ptr()) as i32 } + } + + /// Returns the size of `self` in bytes. Implemented natively. + pub fn num_bytes(&self) -> i32 { + (self.num_bits() + 7) / 8 + } + + /// Generates a cryptographically strong pseudo-random `BigNum`, placing it in `self`. + /// + /// # Parameters + /// + /// * `bits`: Length of the number in bits. + /// * `msb`: The desired properties of the most significant bit. See [`constants`]. + /// * `odd`: If `true`, the generated number will be odd. + /// + /// # Examples + /// + /// ``` + /// use openssl::bn::{BigNum, MsbOption}; + /// use openssl::error::ErrorStack; + /// + /// fn generate_random() -> Result< BigNum, ErrorStack > { + /// let mut big = BigNum::new()?; + /// + /// // Generates a 128-bit odd random number + /// big.rand(128, MsbOption::MAYBE_ZERO, true); + /// Ok((big)) + /// } + /// ``` + /// + /// [`constants`]: index.html#constants + #[corresponds(BN_rand)] + #[allow(clippy::useless_conversion)] + pub fn rand(&mut self, bits: i32, msb: MsbOption, odd: bool) -> Result<(), ErrorStack> { + unsafe { + cvt(ffi::BN_rand( + self.as_ptr(), + bits.into(), + msb.0, + odd as c_int, + )) + .map(|_| ()) + } + } + + /// The cryptographically weak counterpart to `rand`. Not suitable for key generation. + #[cfg(not(osslconf = "OPENSSL_NO_DEPRECATED_3_0"))] + #[corresponds(BN_pseudo_rand)] + #[allow(clippy::useless_conversion)] + pub fn pseudo_rand(&mut self, bits: i32, msb: MsbOption, odd: bool) -> Result<(), ErrorStack> { + unsafe { + cvt(ffi::BN_pseudo_rand( + self.as_ptr(), + bits.into(), + msb.0, + odd as c_int, + )) + .map(|_| ()) + } + } + + /// Generates a prime number, placing it in `self`. + /// + /// # Parameters + /// + /// * `bits`: The length of the prime in bits (lower bound). + /// * `safe`: If true, returns a "safe" prime `p` so that `(p-1)/2` is also prime. + /// * `add`/`rem`: If `add` is set to `Some(add)`, `p % add == rem` will hold, where `p` is the + /// generated prime and `rem` is `1` if not specified (`None`). + /// + /// # Examples + /// + /// ``` + /// use openssl::bn::BigNum; + /// use openssl::error::ErrorStack; + /// + /// fn generate_weak_prime() -> Result< BigNum, ErrorStack > { + /// let mut big = BigNum::new()?; + /// + /// // Generates a 128-bit simple prime number + /// big.generate_prime(128, false, None, None); + /// Ok((big)) + /// } + /// ``` + #[corresponds(BN_generate_prime_ex)] + pub fn generate_prime( + &mut self, + bits: i32, + safe: bool, + add: Option<&BigNumRef>, + rem: Option<&BigNumRef>, + ) -> Result<(), ErrorStack> { + unsafe { + cvt(ffi::BN_generate_prime_ex( + self.as_ptr(), + bits as c_int, + safe as c_int, + add.map(|n| n.as_ptr()).unwrap_or(ptr::null_mut()), + rem.map(|n| n.as_ptr()).unwrap_or(ptr::null_mut()), + ptr::null_mut(), + )) + .map(|_| ()) + } + } + + /// Places the result of `a * b` in `self`. + /// [`core::ops::Mul`] is also implemented for `BigNumRef`. + /// + /// [`core::ops::Mul`]: struct.BigNumRef.html#method.mul + #[corresponds(BN_mul)] + pub fn checked_mul( + &mut self, + a: &BigNumRef, + b: &BigNumRef, + ctx: &mut BigNumContextRef, + ) -> Result<(), ErrorStack> { + unsafe { + cvt(ffi::BN_mul( + self.as_ptr(), + a.as_ptr(), + b.as_ptr(), + ctx.as_ptr(), + )) + .map(|_| ()) + } + } + + /// Places the result of `a / b` in `self`. The remainder is discarded. + /// [`core::ops::Div`] is also implemented for `BigNumRef`. + /// + /// [`core::ops::Div`]: struct.BigNumRef.html#method.div + #[corresponds(BN_div)] + pub fn checked_div( + &mut self, + a: &BigNumRef, + b: &BigNumRef, + ctx: &mut BigNumContextRef, + ) -> Result<(), ErrorStack> { + unsafe { + cvt(ffi::BN_div( + self.as_ptr(), + ptr::null_mut(), + a.as_ptr(), + b.as_ptr(), + ctx.as_ptr(), + )) + .map(|_| ()) + } + } + + /// Places the result of `a % b` in `self`. + #[corresponds(BN_div)] + pub fn checked_rem( + &mut self, + a: &BigNumRef, + b: &BigNumRef, + ctx: &mut BigNumContextRef, + ) -> Result<(), ErrorStack> { + unsafe { + cvt(ffi::BN_div( + ptr::null_mut(), + self.as_ptr(), + a.as_ptr(), + b.as_ptr(), + ctx.as_ptr(), + )) + .map(|_| ()) + } + } + + /// Places the result of `a / b` in `self` and `a % b` in `rem`. + #[corresponds(BN_div)] + pub fn div_rem( + &mut self, + rem: &mut BigNumRef, + a: &BigNumRef, + b: &BigNumRef, + ctx: &mut BigNumContextRef, + ) -> Result<(), ErrorStack> { + unsafe { + cvt(ffi::BN_div( + self.as_ptr(), + rem.as_ptr(), + a.as_ptr(), + b.as_ptr(), + ctx.as_ptr(), + )) + .map(|_| ()) + } + } + + /// Places the result of `a²` in `self`. + #[corresponds(BN_sqr)] + pub fn sqr(&mut self, a: &BigNumRef, ctx: &mut BigNumContextRef) -> Result<(), ErrorStack> { + unsafe { cvt(ffi::BN_sqr(self.as_ptr(), a.as_ptr(), ctx.as_ptr())).map(|_| ()) } + } + + /// Places the result of `a mod m` in `self`. As opposed to `div_rem` + /// the result is non-negative. + #[corresponds(BN_nnmod)] + pub fn nnmod( + &mut self, + a: &BigNumRef, + m: &BigNumRef, + ctx: &mut BigNumContextRef, + ) -> Result<(), ErrorStack> { + unsafe { + cvt(ffi::BN_nnmod( + self.as_ptr(), + a.as_ptr(), + m.as_ptr(), + ctx.as_ptr(), + )) + .map(|_| ()) + } + } + + /// Places the result of `(a + b) mod m` in `self`. + #[corresponds(BN_mod_add)] + pub fn mod_add( + &mut self, + a: &BigNumRef, + b: &BigNumRef, + m: &BigNumRef, + ctx: &mut BigNumContextRef, + ) -> Result<(), ErrorStack> { + unsafe { + cvt(ffi::BN_mod_add( + self.as_ptr(), + a.as_ptr(), + b.as_ptr(), + m.as_ptr(), + ctx.as_ptr(), + )) + .map(|_| ()) + } + } + + /// Places the result of `(a - b) mod m` in `self`. + #[corresponds(BN_mod_sub)] + pub fn mod_sub( + &mut self, + a: &BigNumRef, + b: &BigNumRef, + m: &BigNumRef, + ctx: &mut BigNumContextRef, + ) -> Result<(), ErrorStack> { + unsafe { + cvt(ffi::BN_mod_sub( + self.as_ptr(), + a.as_ptr(), + b.as_ptr(), + m.as_ptr(), + ctx.as_ptr(), + )) + .map(|_| ()) + } + } + + /// Places the result of `(a * b) mod m` in `self`. + #[corresponds(BN_mod_mul)] + pub fn mod_mul( + &mut self, + a: &BigNumRef, + b: &BigNumRef, + m: &BigNumRef, + ctx: &mut BigNumContextRef, + ) -> Result<(), ErrorStack> { + unsafe { + cvt(ffi::BN_mod_mul( + self.as_ptr(), + a.as_ptr(), + b.as_ptr(), + m.as_ptr(), + ctx.as_ptr(), + )) + .map(|_| ()) + } + } + + /// Places the result of `a² mod m` in `self`. + #[corresponds(BN_mod_sqr)] + pub fn mod_sqr( + &mut self, + a: &BigNumRef, + m: &BigNumRef, + ctx: &mut BigNumContextRef, + ) -> Result<(), ErrorStack> { + unsafe { + cvt(ffi::BN_mod_sqr( + self.as_ptr(), + a.as_ptr(), + m.as_ptr(), + ctx.as_ptr(), + )) + .map(|_| ()) + } + } + + /// Places into `self` the modular square root of `a` such that `self^2 = a (mod p)` + #[corresponds(BN_mod_sqrt)] + pub fn mod_sqrt( + &mut self, + a: &BigNumRef, + p: &BigNumRef, + ctx: &mut BigNumContextRef, + ) -> Result<(), ErrorStack> { + unsafe { + cvt_p(ffi::BN_mod_sqrt( + self.as_ptr(), + a.as_ptr(), + p.as_ptr(), + ctx.as_ptr(), + )) + .map(|_| ()) + } + } + + /// Places the result of `a^p` in `self`. + #[corresponds(BN_exp)] + pub fn exp( + &mut self, + a: &BigNumRef, + p: &BigNumRef, + ctx: &mut BigNumContextRef, + ) -> Result<(), ErrorStack> { + unsafe { + cvt(ffi::BN_exp( + self.as_ptr(), + a.as_ptr(), + p.as_ptr(), + ctx.as_ptr(), + )) + .map(|_| ()) + } + } + + /// Places the result of `a^p mod m` in `self`. + #[corresponds(BN_mod_exp)] + pub fn mod_exp( + &mut self, + a: &BigNumRef, + p: &BigNumRef, + m: &BigNumRef, + ctx: &mut BigNumContextRef, + ) -> Result<(), ErrorStack> { + unsafe { + cvt(ffi::BN_mod_exp( + self.as_ptr(), + a.as_ptr(), + p.as_ptr(), + m.as_ptr(), + ctx.as_ptr(), + )) + .map(|_| ()) + } + } + + /// Places the inverse of `a` modulo `n` in `self`. + #[corresponds(BN_mod_inverse)] + pub fn mod_inverse( + &mut self, + a: &BigNumRef, + n: &BigNumRef, + ctx: &mut BigNumContextRef, + ) -> Result<(), ErrorStack> { + unsafe { + cvt_p(ffi::BN_mod_inverse( + self.as_ptr(), + a.as_ptr(), + n.as_ptr(), + ctx.as_ptr(), + )) + .map(|_| ()) + } + } + + /// Places the greatest common denominator of `a` and `b` in `self`. + #[corresponds(BN_gcd)] + pub fn gcd( + &mut self, + a: &BigNumRef, + b: &BigNumRef, + ctx: &mut BigNumContextRef, + ) -> Result<(), ErrorStack> { + unsafe { + cvt(ffi::BN_gcd( + self.as_ptr(), + a.as_ptr(), + b.as_ptr(), + ctx.as_ptr(), + )) + .map(|_| ()) + } + } + + /// Checks whether `self` is prime. + /// + /// Performs a Miller-Rabin probabilistic primality test with `checks` iterations. + /// + /// # Return Value + /// + /// Returns `true` if `self` is prime with an error probability of less than `0.25 ^ checks`. + #[cfg(not(osslconf = "OPENSSL_NO_DEPRECATED_3_0"))] + #[corresponds(BN_is_prime_ex)] + #[allow(clippy::useless_conversion)] + pub fn is_prime(&self, checks: i32, ctx: &mut BigNumContextRef) -> Result { + unsafe { + cvt_n(ffi::BN_is_prime_ex( + self.as_ptr(), + checks.into(), + ctx.as_ptr(), + ptr::null_mut(), + )) + .map(|r| r != 0) + } + } + + /// Checks whether `self` is prime with optional trial division. + /// + /// If `do_trial_division` is `true`, first performs trial division by a number of small primes. + /// Then, like `is_prime`, performs a Miller-Rabin probabilistic primality test with `checks` + /// iterations. + /// + /// # Return Value + /// + /// Returns `true` if `self` is prime with an error probability of less than `0.25 ^ checks`. + #[cfg(not(osslconf = "OPENSSL_NO_DEPRECATED_3_0"))] + #[corresponds(BN_is_prime_fasttest_ex)] + #[allow(clippy::useless_conversion)] + pub fn is_prime_fasttest( + &self, + checks: i32, + ctx: &mut BigNumContextRef, + do_trial_division: bool, + ) -> Result { + unsafe { + cvt_n(ffi::BN_is_prime_fasttest_ex( + self.as_ptr(), + checks.into(), + ctx.as_ptr(), + do_trial_division as c_int, + ptr::null_mut(), + )) + .map(|r| r != 0) + } + } + + /// Returns a big-endian byte vector representation of the absolute value of `self`. + /// + /// `self` can be recreated by using `from_slice`. + /// + /// ``` + /// # use openssl::bn::BigNum; + /// let s = -BigNum::from_u32(4543).unwrap(); + /// let r = BigNum::from_u32(4543).unwrap(); + /// + /// let s_vec = s.to_vec(); + /// assert_eq!(BigNum::from_slice(&s_vec).unwrap(), r); + /// ``` + #[corresponds(BN_bn2bin)] + pub fn to_vec(&self) -> Vec { + let size = self.num_bytes() as usize; + let mut v = Vec::with_capacity(size); + unsafe { + ffi::BN_bn2bin(self.as_ptr(), v.as_mut_ptr()); + v.set_len(size); + } + v + } + + /// Returns a big-endian byte vector representation of the absolute value of `self` padded + /// to `pad_to` bytes. + /// + /// If `pad_to` is less than `self.num_bytes()` then an error is returned. + /// + /// `self` can be recreated by using `from_slice`. + /// + /// ``` + /// # use openssl::bn::BigNum; + /// let bn = BigNum::from_u32(0x4543).unwrap(); + /// + /// let bn_vec = bn.to_vec_padded(4).unwrap(); + /// assert_eq!(&bn_vec, &[0, 0, 0x45, 0x43]); + /// + /// let r = bn.to_vec_padded(1); + /// assert!(r.is_err()); + /// + /// let bn = -BigNum::from_u32(0x4543).unwrap(); + /// let bn_vec = bn.to_vec_padded(4).unwrap(); + /// assert_eq!(&bn_vec, &[0, 0, 0x45, 0x43]); + /// ``` + #[corresponds(BN_bn2binpad)] + #[cfg(any(ossl110, libressl340, boringssl))] + pub fn to_vec_padded(&self, pad_to: i32) -> Result, ErrorStack> { + let mut v = Vec::with_capacity(pad_to as usize); + unsafe { + cvt(ffi::BN_bn2binpad(self.as_ptr(), v.as_mut_ptr(), pad_to))?; + v.set_len(pad_to as usize); + } + Ok(v) + } + + /// Returns a decimal string representation of `self`. + /// + /// ``` + /// # use openssl::bn::BigNum; + /// let s = -BigNum::from_u32(12345).unwrap(); + /// + /// assert_eq!(&**s.to_dec_str().unwrap(), "-12345"); + /// ``` + #[corresponds(BN_bn2dec)] + pub fn to_dec_str(&self) -> Result { + unsafe { + let buf = cvt_p(ffi::BN_bn2dec(self.as_ptr()))?; + Ok(OpensslString::from_ptr(buf)) + } + } + + /// Returns a hexadecimal string representation of `self`. + /// + /// ``` + /// # use openssl::bn::BigNum; + /// let s = -BigNum::from_u32(0x99ff).unwrap(); + /// + /// assert_eq!(s.to_hex_str().unwrap().to_uppercase(), "-99FF"); + /// ``` + #[corresponds(BN_bn2hex)] + pub fn to_hex_str(&self) -> Result { + unsafe { + let buf = cvt_p(ffi::BN_bn2hex(self.as_ptr()))?; + Ok(OpensslString::from_ptr(buf)) + } + } + + /// Returns an `Asn1Integer` containing the value of `self`. + #[corresponds(BN_to_ASN1_INTEGER)] + pub fn to_asn1_integer(&self) -> Result { + unsafe { + cvt_p(ffi::BN_to_ASN1_INTEGER(self.as_ptr(), ptr::null_mut())) + .map(|p| Asn1Integer::from_ptr(p)) + } + } + + /// Force constant time computation on this value. + #[corresponds(BN_set_flags)] + #[cfg(ossl110)] + pub fn set_const_time(&mut self) { + unsafe { ffi::BN_set_flags(self.as_ptr(), ffi::BN_FLG_CONSTTIME) } + } + + /// Returns true if `self` is in const time mode. + #[corresponds(BN_get_flags)] + #[cfg(ossl110)] + pub fn is_const_time(&self) -> bool { + unsafe { + let ret = ffi::BN_get_flags(self.as_ptr(), ffi::BN_FLG_CONSTTIME); + ret == ffi::BN_FLG_CONSTTIME + } + } + + /// Returns true if `self` was created with [`BigNum::new_secure`]. + #[corresponds(BN_get_flags)] + #[cfg(ossl110)] + pub fn is_secure(&self) -> bool { + unsafe { + let ret = ffi::BN_get_flags(self.as_ptr(), ffi::BN_FLG_SECURE); + ret == ffi::BN_FLG_SECURE + } + } +} + +impl BigNum { + /// Creates a new `BigNum` with the value 0. + #[corresponds(BN_new)] + pub fn new() -> Result { + unsafe { + ffi::init(); + let v = cvt_p(ffi::BN_new())?; + Ok(BigNum::from_ptr(v)) + } + } + + /// Returns a new secure `BigNum`. + #[corresponds(BN_secure_new)] + #[cfg(ossl110)] + pub fn new_secure() -> Result { + unsafe { + ffi::init(); + let v = cvt_p(ffi::BN_secure_new())?; + Ok(BigNum::from_ptr(v)) + } + } + + /// Creates a new `BigNum` with the given value. + #[corresponds(BN_set_word)] + pub fn from_u32(n: u32) -> Result { + BigNum::new().and_then(|v| unsafe { + cvt(ffi::BN_set_word(v.as_ptr(), n as ffi::BN_ULONG)).map(|_| v) + }) + } + + /// Creates a `BigNum` from a decimal string. + #[corresponds(BN_dec2bn)] + pub fn from_dec_str(s: &str) -> Result { + unsafe { + ffi::init(); + let c_str = CString::new(s.as_bytes()).unwrap(); + let mut bn = ptr::null_mut(); + cvt(ffi::BN_dec2bn(&mut bn, c_str.as_ptr() as *const _))?; + Ok(BigNum::from_ptr(bn)) + } + } + + /// Creates a `BigNum` from a hexadecimal string. + #[corresponds(BN_hex2bn)] + pub fn from_hex_str(s: &str) -> Result { + unsafe { + ffi::init(); + let c_str = CString::new(s.as_bytes()).unwrap(); + let mut bn = ptr::null_mut(); + cvt(ffi::BN_hex2bn(&mut bn, c_str.as_ptr() as *const _))?; + Ok(BigNum::from_ptr(bn)) + } + } + + /// Returns a constant used in IKE as defined in [`RFC 2409`]. This prime number is in + /// the order of magnitude of `2 ^ 768`. This number is used during calculated key + /// exchanges such as Diffie-Hellman. This number is labeled Oakley group id 1. + /// + /// [`RFC 2409`]: https://tools.ietf.org/html/rfc2409#page-21 + #[corresponds(BN_get_rfc2409_prime_768)] + #[cfg(not(boringssl))] + pub fn get_rfc2409_prime_768() -> Result { + unsafe { + ffi::init(); + cvt_p(BN_get_rfc2409_prime_768(ptr::null_mut())).map(BigNum) + } + } + + /// Returns a constant used in IKE as defined in [`RFC 2409`]. This prime number is in + /// the order of magnitude of `2 ^ 1024`. This number is used during calculated key + /// exchanges such as Diffie-Hellman. This number is labeled Oakly group 2. + /// + /// [`RFC 2409`]: https://tools.ietf.org/html/rfc2409#page-21 + #[corresponds(BN_get_rfc2409_prime_1024)] + #[cfg(not(boringssl))] + pub fn get_rfc2409_prime_1024() -> Result { + unsafe { + ffi::init(); + cvt_p(BN_get_rfc2409_prime_1024(ptr::null_mut())).map(BigNum) + } + } + + /// Returns a constant used in IKE as defined in [`RFC 3526`]. The prime is in the order + /// of magnitude of `2 ^ 1536`. This number is used during calculated key + /// exchanges such as Diffie-Hellman. This number is labeled MODP group 5. + /// + /// [`RFC 3526`]: https://tools.ietf.org/html/rfc3526#page-3 + #[corresponds(BN_get_rfc3526_prime_1536)] + #[cfg(not(boringssl))] + pub fn get_rfc3526_prime_1536() -> Result { + unsafe { + ffi::init(); + cvt_p(BN_get_rfc3526_prime_1536(ptr::null_mut())).map(BigNum) + } + } + + /// Returns a constant used in IKE as defined in [`RFC 3526`]. The prime is in the order + /// of magnitude of `2 ^ 2048`. This number is used during calculated key + /// exchanges such as Diffie-Hellman. This number is labeled MODP group 14. + /// + /// [`RFC 3526`]: https://tools.ietf.org/html/rfc3526#page-3 + #[corresponds(BN_get_rfc3526_prime_2048)] + #[cfg(not(boringssl))] + pub fn get_rfc3526_prime_2048() -> Result { + unsafe { + ffi::init(); + cvt_p(BN_get_rfc3526_prime_2048(ptr::null_mut())).map(BigNum) + } + } + + /// Returns a constant used in IKE as defined in [`RFC 3526`]. The prime is in the order + /// of magnitude of `2 ^ 3072`. This number is used during calculated key + /// exchanges such as Diffie-Hellman. This number is labeled MODP group 15. + /// + /// [`RFC 3526`]: https://tools.ietf.org/html/rfc3526#page-4 + #[corresponds(BN_get_rfc3526_prime_3072)] + #[cfg(not(boringssl))] + pub fn get_rfc3526_prime_3072() -> Result { + unsafe { + ffi::init(); + cvt_p(BN_get_rfc3526_prime_3072(ptr::null_mut())).map(BigNum) + } + } + + /// Returns a constant used in IKE as defined in [`RFC 3526`]. The prime is in the order + /// of magnitude of `2 ^ 4096`. This number is used during calculated key + /// exchanges such as Diffie-Hellman. This number is labeled MODP group 16. + /// + /// [`RFC 3526`]: https://tools.ietf.org/html/rfc3526#page-4 + #[corresponds(BN_get_rfc3526_prime_4096)] + #[cfg(not(boringssl))] + pub fn get_rfc3526_prime_4096() -> Result { + unsafe { + ffi::init(); + cvt_p(BN_get_rfc3526_prime_4096(ptr::null_mut())).map(BigNum) + } + } + + /// Returns a constant used in IKE as defined in [`RFC 3526`]. The prime is in the order + /// of magnitude of `2 ^ 6144`. This number is used during calculated key + /// exchanges such as Diffie-Hellman. This number is labeled MODP group 17. + /// + /// [`RFC 3526`]: https://tools.ietf.org/html/rfc3526#page-6 + #[corresponds(BN_get_rfc3526_prime_6114)] + #[cfg(not(boringssl))] + pub fn get_rfc3526_prime_6144() -> Result { + unsafe { + ffi::init(); + cvt_p(BN_get_rfc3526_prime_6144(ptr::null_mut())).map(BigNum) + } + } + + /// Returns a constant used in IKE as defined in [`RFC 3526`]. The prime is in the order + /// of magnitude of `2 ^ 8192`. This number is used during calculated key + /// exchanges such as Diffie-Hellman. This number is labeled MODP group 18. + /// + /// [`RFC 3526`]: https://tools.ietf.org/html/rfc3526#page-6 + #[corresponds(BN_get_rfc3526_prime_8192)] + #[cfg(not(boringssl))] + pub fn get_rfc3526_prime_8192() -> Result { + unsafe { + ffi::init(); + cvt_p(BN_get_rfc3526_prime_8192(ptr::null_mut())).map(BigNum) + } + } + + /// Creates a new `BigNum` from an unsigned, big-endian encoded number of arbitrary length. + /// + /// OpenSSL documentation at [`BN_bin2bn`] + /// + /// [`BN_bin2bn`]: https://www.openssl.org/docs/manmaster/crypto/BN_bin2bn.html + /// + /// ``` + /// # use openssl::bn::BigNum; + /// let bignum = BigNum::from_slice(&[0x12, 0x00, 0x34]).unwrap(); + /// + /// assert_eq!(bignum, BigNum::from_u32(0x120034).unwrap()); + /// ``` + #[corresponds(BN_bin2bn)] + pub fn from_slice(n: &[u8]) -> Result { + unsafe { + ffi::init(); + assert!(n.len() <= LenType::MAX as usize); + + cvt_p(ffi::BN_bin2bn( + n.as_ptr(), + n.len() as LenType, + ptr::null_mut(), + )) + .map(|p| BigNum::from_ptr(p)) + } + } + + /// Copies data from a slice overwriting what was in the BigNum. + /// + /// This function can be used to copy data from a slice to a + /// [secure BigNum][`BigNum::new_secure`]. + /// + /// # Examples + /// + /// ``` + /// # use openssl::bn::BigNum; + /// let mut bignum = BigNum::new().unwrap(); + /// bignum.copy_from_slice(&[0x12, 0x00, 0x34]).unwrap(); + /// + /// assert_eq!(bignum, BigNum::from_u32(0x120034).unwrap()); + /// ``` + #[corresponds(BN_bin2bn)] + pub fn copy_from_slice(&mut self, n: &[u8]) -> Result<(), ErrorStack> { + unsafe { + assert!(n.len() <= LenType::MAX as usize); + + cvt_p(ffi::BN_bin2bn(n.as_ptr(), n.len() as LenType, self.0))?; + Ok(()) + } + } +} + +impl fmt::Debug for BigNumRef { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self.to_dec_str() { + Ok(s) => f.write_str(&s), + Err(e) => Err(e.into()), + } + } +} + +impl fmt::Debug for BigNum { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self.to_dec_str() { + Ok(s) => f.write_str(&s), + Err(e) => Err(e.into()), + } + } +} + +impl fmt::Display for BigNumRef { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self.to_dec_str() { + Ok(s) => f.write_str(&s), + Err(e) => Err(e.into()), + } + } +} + +impl fmt::Display for BigNum { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self.to_dec_str() { + Ok(s) => f.write_str(&s), + Err(e) => Err(e.into()), + } + } +} + +impl PartialEq for BigNumRef { + fn eq(&self, oth: &BigNumRef) -> bool { + self.cmp(oth) == Ordering::Equal + } +} + +impl PartialEq for BigNumRef { + fn eq(&self, oth: &BigNum) -> bool { + self.eq(oth.deref()) + } +} + +impl Eq for BigNumRef {} + +impl PartialEq for BigNum { + fn eq(&self, oth: &BigNum) -> bool { + self.deref().eq(oth) + } +} + +impl PartialEq for BigNum { + fn eq(&self, oth: &BigNumRef) -> bool { + self.deref().eq(oth) + } +} + +impl Eq for BigNum {} + +impl PartialOrd for BigNumRef { + fn partial_cmp(&self, oth: &BigNumRef) -> Option { + Some(self.cmp(oth)) + } +} + +impl PartialOrd for BigNumRef { + fn partial_cmp(&self, oth: &BigNum) -> Option { + Some(self.cmp(oth.deref())) + } +} + +impl Ord for BigNumRef { + fn cmp(&self, oth: &BigNumRef) -> Ordering { + unsafe { ffi::BN_cmp(self.as_ptr(), oth.as_ptr()).cmp(&0) } + } +} + +impl PartialOrd for BigNum { + fn partial_cmp(&self, oth: &BigNum) -> Option { + Some(self.cmp(oth)) + } +} + +impl PartialOrd for BigNum { + fn partial_cmp(&self, oth: &BigNumRef) -> Option { + self.deref().partial_cmp(oth) + } +} + +impl Ord for BigNum { + fn cmp(&self, oth: &BigNum) -> Ordering { + self.deref().cmp(oth.deref()) + } +} + +macro_rules! delegate { + ($t:ident, $m:ident) => { + impl<'a, 'b> $t<&'b BigNum> for &'a BigNumRef { + type Output = BigNum; + + fn $m(self, oth: &BigNum) -> BigNum { + $t::$m(self, oth.deref()) + } + } + + impl<'a, 'b> $t<&'b BigNumRef> for &'a BigNum { + type Output = BigNum; + + fn $m(self, oth: &BigNumRef) -> BigNum { + $t::$m(self.deref(), oth) + } + } + + impl<'a, 'b> $t<&'b BigNum> for &'a BigNum { + type Output = BigNum; + + fn $m(self, oth: &BigNum) -> BigNum { + $t::$m(self.deref(), oth.deref()) + } + } + }; +} + +impl Add<&BigNumRef> for &BigNumRef { + type Output = BigNum; + + fn add(self, oth: &BigNumRef) -> BigNum { + let mut r = BigNum::new().unwrap(); + r.checked_add(self, oth).unwrap(); + r + } +} + +delegate!(Add, add); + +impl Sub<&BigNumRef> for &BigNumRef { + type Output = BigNum; + + fn sub(self, oth: &BigNumRef) -> BigNum { + let mut r = BigNum::new().unwrap(); + r.checked_sub(self, oth).unwrap(); + r + } +} + +delegate!(Sub, sub); + +impl Mul<&BigNumRef> for &BigNumRef { + type Output = BigNum; + + fn mul(self, oth: &BigNumRef) -> BigNum { + let mut ctx = BigNumContext::new().unwrap(); + let mut r = BigNum::new().unwrap(); + r.checked_mul(self, oth, &mut ctx).unwrap(); + r + } +} + +delegate!(Mul, mul); + +impl<'b> Div<&'b BigNumRef> for &BigNumRef { + type Output = BigNum; + + fn div(self, oth: &'b BigNumRef) -> BigNum { + let mut ctx = BigNumContext::new().unwrap(); + let mut r = BigNum::new().unwrap(); + r.checked_div(self, oth, &mut ctx).unwrap(); + r + } +} + +delegate!(Div, div); + +impl<'b> Rem<&'b BigNumRef> for &BigNumRef { + type Output = BigNum; + + fn rem(self, oth: &'b BigNumRef) -> BigNum { + let mut ctx = BigNumContext::new().unwrap(); + let mut r = BigNum::new().unwrap(); + r.checked_rem(self, oth, &mut ctx).unwrap(); + r + } +} + +delegate!(Rem, rem); + +impl Shl for &BigNumRef { + type Output = BigNum; + + fn shl(self, n: i32) -> BigNum { + let mut r = BigNum::new().unwrap(); + r.lshift(self, n).unwrap(); + r + } +} + +impl Shl for &BigNum { + type Output = BigNum; + + fn shl(self, n: i32) -> BigNum { + self.deref().shl(n) + } +} + +impl Shr for &BigNumRef { + type Output = BigNum; + + fn shr(self, n: i32) -> BigNum { + let mut r = BigNum::new().unwrap(); + r.rshift(self, n).unwrap(); + r + } +} + +impl Shr for &BigNum { + type Output = BigNum; + + fn shr(self, n: i32) -> BigNum { + self.deref().shr(n) + } +} + +impl Neg for &BigNumRef { + type Output = BigNum; + + fn neg(self) -> BigNum { + self.to_owned().unwrap().neg() + } +} + +impl Neg for &BigNum { + type Output = BigNum; + + fn neg(self) -> BigNum { + self.deref().neg() + } +} + +impl Neg for BigNum { + type Output = BigNum; + + fn neg(mut self) -> BigNum { + let negative = self.is_negative(); + self.set_negative(!negative); + self + } +} + +#[cfg(test)] +mod tests { + use crate::bn::{BigNum, BigNumContext}; + + #[test] + fn test_to_from_slice() { + let v0 = BigNum::from_u32(10_203_004).unwrap(); + let vec = v0.to_vec(); + let v1 = BigNum::from_slice(&vec).unwrap(); + + assert_eq!(v0, v1); + } + + #[test] + fn test_negation() { + let a = BigNum::from_u32(909_829_283).unwrap(); + + assert!(!a.is_negative()); + assert!((-a).is_negative()); + } + + #[test] + fn test_shift() { + let a = BigNum::from_u32(909_829_283).unwrap(); + + assert_eq!(a, &(&a << 1) >> 1); + } + + #[cfg(not(osslconf = "OPENSSL_NO_DEPRECATED_3_0"))] + #[test] + fn test_rand_range() { + let range = BigNum::from_u32(909_829_283).unwrap(); + let mut result = BigNum::from_dec_str(&range.to_dec_str().unwrap()).unwrap(); + range.rand_range(&mut result).unwrap(); + assert!(result >= BigNum::from_u32(0).unwrap() && result < range); + } + + #[cfg(not(osslconf = "OPENSSL_NO_DEPRECATED_3_0"))] + #[test] + fn test_pseudo_rand_range() { + let range = BigNum::from_u32(909_829_283).unwrap(); + let mut result = BigNum::from_dec_str(&range.to_dec_str().unwrap()).unwrap(); + range.pseudo_rand_range(&mut result).unwrap(); + assert!(result >= BigNum::from_u32(0).unwrap() && result < range); + } + + #[cfg(not(osslconf = "OPENSSL_NO_DEPRECATED_3_0"))] + #[test] + fn test_prime_numbers() { + let a = BigNum::from_u32(19_029_017).unwrap(); + let mut p = BigNum::new().unwrap(); + p.generate_prime(128, true, None, Some(&a)).unwrap(); + + let mut ctx = BigNumContext::new().unwrap(); + assert!(p.is_prime(100, &mut ctx).unwrap()); + assert!(p.is_prime_fasttest(100, &mut ctx, true).unwrap()); + } + + #[cfg(ossl110)] + #[test] + fn test_secure_bn_ctx() { + let mut cxt = BigNumContext::new_secure().unwrap(); + let a = BigNum::from_u32(8).unwrap(); + let b = BigNum::from_u32(3).unwrap(); + + let mut remainder = BigNum::new().unwrap(); + remainder.nnmod(&a, &b, &mut cxt).unwrap(); + + assert!(remainder.eq(&BigNum::from_u32(2).unwrap())); + } + + #[cfg(ossl110)] + #[test] + fn test_secure_bn() { + let a = BigNum::new().unwrap(); + assert!(!a.is_secure()); + + let b = BigNum::new_secure().unwrap(); + assert!(b.is_secure()) + } + + #[cfg(ossl110)] + #[test] + fn test_const_time_bn() { + let a = BigNum::new().unwrap(); + assert!(!a.is_const_time()); + + let mut b = BigNum::new().unwrap(); + b.set_const_time(); + assert!(b.is_const_time()) + } + + #[test] + fn test_mod_sqrt() { + let mut ctx = BigNumContext::new().unwrap(); + + let s = BigNum::from_hex_str("2").unwrap(); + let p = BigNum::from_hex_str("7DEB1").unwrap(); + let mut sqrt = BigNum::new().unwrap(); + let mut out = BigNum::new().unwrap(); + + // Square the root because OpenSSL randomly returns one of 2E42C or 4FA85 + sqrt.mod_sqrt(&s, &p, &mut ctx).unwrap(); + out.mod_sqr(&sqrt, &p, &mut ctx).unwrap(); + assert!(out == s); + + let s = BigNum::from_hex_str("3").unwrap(); + let p = BigNum::from_hex_str("5").unwrap(); + assert!(out.mod_sqrt(&s, &p, &mut ctx).is_err()); + } + + #[test] + #[cfg(any(ossl110, boringssl, libressl350))] + fn test_odd_even() { + let a = BigNum::from_u32(17).unwrap(); + let b = BigNum::from_u32(18).unwrap(); + + assert!(a.is_odd()); + assert!(!b.is_odd()); + + assert!(!a.is_even()); + assert!(b.is_even()); + } +} diff --git a/vendor/openssl/src/cipher.rs b/vendor/openssl/src/cipher.rs new file mode 100644 index 0000000..c4cb260 --- /dev/null +++ b/vendor/openssl/src/cipher.rs @@ -0,0 +1,597 @@ +//! Symmetric ciphers. + +#[cfg(ossl300)] +use crate::cvt_p; +#[cfg(ossl300)] +use crate::error::ErrorStack; +#[cfg(ossl300)] +use crate::lib_ctx::LibCtxRef; +use crate::nid::Nid; +use cfg_if::cfg_if; +use foreign_types::{ForeignTypeRef, Opaque}; +use openssl_macros::corresponds; +#[cfg(ossl300)] +use std::ffi::CString; +use std::ops::{Deref, DerefMut}; +#[cfg(ossl300)] +use std::ptr; + +cfg_if! { + if #[cfg(any(boringssl, ossl110, libressl273))] { + use ffi::{EVP_CIPHER_block_size, EVP_CIPHER_iv_length, EVP_CIPHER_key_length}; + } else { + use libc::c_int; + + #[allow(bad_style)] + pub unsafe fn EVP_CIPHER_iv_length(ptr: *const ffi::EVP_CIPHER) -> c_int { + (*ptr).iv_len + } + + #[allow(bad_style)] + pub unsafe fn EVP_CIPHER_block_size(ptr: *const ffi::EVP_CIPHER) -> c_int { + (*ptr).block_size + } + + #[allow(bad_style)] + pub unsafe fn EVP_CIPHER_key_length(ptr: *const ffi::EVP_CIPHER) -> c_int { + (*ptr).key_len + } + } +} + +cfg_if! { + if #[cfg(ossl300)] { + use foreign_types::ForeignType; + + type Inner = *mut ffi::EVP_CIPHER; + + impl Drop for Cipher { + #[inline] + fn drop(&mut self) { + unsafe { + ffi::EVP_CIPHER_free(self.as_ptr()); + } + } + } + + impl ForeignType for Cipher { + type CType = ffi::EVP_CIPHER; + type Ref = CipherRef; + + #[inline] + unsafe fn from_ptr(ptr: *mut Self::CType) -> Self { + Cipher(ptr) + } + + #[inline] + fn as_ptr(&self) -> *mut Self::CType { + self.0 + } + } + + impl Deref for Cipher { + type Target = CipherRef; + + #[inline] + fn deref(&self) -> &Self::Target { + unsafe { + CipherRef::from_ptr(self.as_ptr()) + } + } + } + + impl DerefMut for Cipher { + #[inline] + fn deref_mut(&mut self) -> &mut Self::Target { + unsafe { + CipherRef::from_ptr_mut(self.as_ptr()) + } + } + } + } else { + enum Inner {} + + impl Deref for Cipher { + type Target = CipherRef; + + #[inline] + fn deref(&self) -> &Self::Target { + match self.0 {} + } + } + + impl DerefMut for Cipher { + #[inline] + fn deref_mut(&mut self) -> &mut Self::Target { + match self.0 {} + } + } + } +} + +/// A symmetric cipher. +pub struct Cipher(Inner); + +unsafe impl Sync for Cipher {} +unsafe impl Send for Cipher {} + +impl Cipher { + /// Looks up the cipher for a certain nid. + #[corresponds(EVP_get_cipherbynid)] + pub fn from_nid(nid: Nid) -> Option<&'static CipherRef> { + unsafe { + let ptr = ffi::EVP_get_cipherbyname(ffi::OBJ_nid2sn(nid.as_raw())); + if ptr.is_null() { + None + } else { + Some(CipherRef::from_ptr(ptr as *mut _)) + } + } + } + + /// Fetches a cipher object corresponding to the specified algorithm name and properties. + /// + /// Requires OpenSSL 3.0.0 or newer. + #[corresponds(EVP_CIPHER_fetch)] + #[cfg(ossl300)] + pub fn fetch( + ctx: Option<&LibCtxRef>, + algorithm: &str, + properties: Option<&str>, + ) -> Result { + let algorithm = CString::new(algorithm).unwrap(); + let properties = properties.map(|s| CString::new(s).unwrap()); + + unsafe { + let ptr = cvt_p(ffi::EVP_CIPHER_fetch( + ctx.map_or(ptr::null_mut(), ForeignTypeRef::as_ptr), + algorithm.as_ptr(), + properties.map_or(ptr::null_mut(), |s| s.as_ptr()), + ))?; + + Ok(Cipher::from_ptr(ptr)) + } + } + + pub fn aes_128_ecb() -> &'static CipherRef { + unsafe { CipherRef::from_ptr(ffi::EVP_aes_128_ecb() as *mut _) } + } + + pub fn aes_128_cbc() -> &'static CipherRef { + unsafe { CipherRef::from_ptr(ffi::EVP_aes_128_cbc() as *mut _) } + } + + #[cfg(not(boringssl))] + pub fn aes_128_xts() -> &'static CipherRef { + unsafe { CipherRef::from_ptr(ffi::EVP_aes_128_xts() as *mut _) } + } + + #[cfg(not(boringssl))] + pub fn aes_256_xts() -> &'static CipherRef { + unsafe { CipherRef::from_ptr(ffi::EVP_aes_256_xts() as *mut _) } + } + + pub fn aes_128_ctr() -> &'static CipherRef { + unsafe { CipherRef::from_ptr(ffi::EVP_aes_128_ctr() as *mut _) } + } + + #[cfg(not(boringssl))] + pub fn aes_128_cfb1() -> &'static CipherRef { + unsafe { CipherRef::from_ptr(ffi::EVP_aes_128_cfb1() as *mut _) } + } + + #[cfg(not(boringssl))] + pub fn aes_128_cfb128() -> &'static CipherRef { + unsafe { CipherRef::from_ptr(ffi::EVP_aes_128_cfb128() as *mut _) } + } + + #[cfg(not(boringssl))] + pub fn aes_128_cfb8() -> &'static CipherRef { + unsafe { CipherRef::from_ptr(ffi::EVP_aes_128_cfb8() as *mut _) } + } + + pub fn aes_128_gcm() -> &'static CipherRef { + unsafe { CipherRef::from_ptr(ffi::EVP_aes_128_gcm() as *mut _) } + } + + #[cfg(not(boringssl))] + pub fn aes_128_ccm() -> &'static CipherRef { + unsafe { CipherRef::from_ptr(ffi::EVP_aes_128_ccm() as *mut _) } + } + + pub fn aes_128_ofb() -> &'static CipherRef { + unsafe { CipherRef::from_ptr(ffi::EVP_aes_128_ofb() as *mut _) } + } + + /// Requires OpenSSL 1.1.0 or newer. + #[cfg(all(ossl110, not(osslconf = "OPENSSL_NO_OCB")))] + pub fn aes_128_ocb() -> &'static CipherRef { + unsafe { CipherRef::from_ptr(ffi::EVP_aes_128_ocb() as *mut _) } + } + + /// Requires OpenSSL 1.0.2 or newer. + #[cfg(ossl102)] + pub fn aes_128_wrap() -> &'static CipherRef { + unsafe { CipherRef::from_ptr(ffi::EVP_aes_128_wrap() as *mut _) } + } + + /// Requires OpenSSL 1.1.0 or newer. + #[cfg(ossl110)] + pub fn aes_128_wrap_pad() -> &'static CipherRef { + unsafe { CipherRef::from_ptr(ffi::EVP_aes_128_wrap_pad() as *mut _) } + } + + pub fn aes_192_ecb() -> &'static CipherRef { + unsafe { CipherRef::from_ptr(ffi::EVP_aes_192_ecb() as *mut _) } + } + + pub fn aes_192_cbc() -> &'static CipherRef { + unsafe { CipherRef::from_ptr(ffi::EVP_aes_192_cbc() as *mut _) } + } + + pub fn aes_192_ctr() -> &'static CipherRef { + unsafe { CipherRef::from_ptr(ffi::EVP_aes_192_ctr() as *mut _) } + } + + #[cfg(not(boringssl))] + pub fn aes_192_cfb1() -> &'static CipherRef { + unsafe { CipherRef::from_ptr(ffi::EVP_aes_192_cfb1() as *mut _) } + } + + pub fn aes_192_cfb128() -> &'static CipherRef { + unsafe { CipherRef::from_ptr(ffi::EVP_aes_192_cfb128() as *mut _) } + } + + #[cfg(not(boringssl))] + pub fn aes_192_cfb8() -> &'static CipherRef { + unsafe { CipherRef::from_ptr(ffi::EVP_aes_192_cfb8() as *mut _) } + } + + pub fn aes_192_gcm() -> &'static CipherRef { + unsafe { CipherRef::from_ptr(ffi::EVP_aes_192_gcm() as *mut _) } + } + + #[cfg(not(boringssl))] + pub fn aes_192_ccm() -> &'static CipherRef { + unsafe { CipherRef::from_ptr(ffi::EVP_aes_192_ccm() as *mut _) } + } + + pub fn aes_192_ofb() -> &'static CipherRef { + unsafe { CipherRef::from_ptr(ffi::EVP_aes_192_ofb() as *mut _) } + } + + /// Requires OpenSSL 1.1.0 or newer. + #[cfg(all(ossl110, not(osslconf = "OPENSSL_NO_OCB")))] + pub fn aes_192_ocb() -> &'static CipherRef { + unsafe { CipherRef::from_ptr(ffi::EVP_aes_192_ocb() as *mut _) } + } + + /// Requires OpenSSL 1.0.2 or newer. + #[cfg(ossl102)] + pub fn aes_192_wrap() -> &'static CipherRef { + unsafe { CipherRef::from_ptr(ffi::EVP_aes_192_wrap() as *mut _) } + } + + /// Requires OpenSSL 1.1.0 or newer. + #[cfg(ossl110)] + pub fn aes_192_wrap_pad() -> &'static CipherRef { + unsafe { CipherRef::from_ptr(ffi::EVP_aes_192_wrap_pad() as *mut _) } + } + + pub fn aes_256_ecb() -> &'static CipherRef { + unsafe { CipherRef::from_ptr(ffi::EVP_aes_256_ecb() as *mut _) } + } + + pub fn aes_256_cbc() -> &'static CipherRef { + unsafe { CipherRef::from_ptr(ffi::EVP_aes_256_cbc() as *mut _) } + } + + pub fn aes_256_ctr() -> &'static CipherRef { + unsafe { CipherRef::from_ptr(ffi::EVP_aes_256_ctr() as *mut _) } + } + + #[cfg(not(boringssl))] + pub fn aes_256_cfb1() -> &'static CipherRef { + unsafe { CipherRef::from_ptr(ffi::EVP_aes_256_cfb1() as *mut _) } + } + + pub fn aes_256_cfb128() -> &'static CipherRef { + unsafe { CipherRef::from_ptr(ffi::EVP_aes_256_cfb128() as *mut _) } + } + + #[cfg(not(boringssl))] + pub fn aes_256_cfb8() -> &'static CipherRef { + unsafe { CipherRef::from_ptr(ffi::EVP_aes_256_cfb8() as *mut _) } + } + + pub fn aes_256_gcm() -> &'static CipherRef { + unsafe { CipherRef::from_ptr(ffi::EVP_aes_256_gcm() as *mut _) } + } + + #[cfg(not(boringssl))] + pub fn aes_256_ccm() -> &'static CipherRef { + unsafe { CipherRef::from_ptr(ffi::EVP_aes_256_ccm() as *mut _) } + } + + pub fn aes_256_ofb() -> &'static CipherRef { + unsafe { CipherRef::from_ptr(ffi::EVP_aes_256_ofb() as *mut _) } + } + + /// Requires OpenSSL 1.1.0 or newer. + #[cfg(all(ossl110, not(osslconf = "OPENSSL_NO_OCB")))] + pub fn aes_256_ocb() -> &'static CipherRef { + unsafe { CipherRef::from_ptr(ffi::EVP_aes_256_ocb() as *mut _) } + } + + /// Requires OpenSSL 1.0.2 or newer. + #[cfg(ossl102)] + pub fn aes_256_wrap() -> &'static CipherRef { + unsafe { CipherRef::from_ptr(ffi::EVP_aes_256_wrap() as *mut _) } + } + + /// Requires OpenSSL 1.1.0 or newer. + #[cfg(ossl110)] + pub fn aes_256_wrap_pad() -> &'static CipherRef { + unsafe { CipherRef::from_ptr(ffi::EVP_aes_256_wrap_pad() as *mut _) } + } + + #[cfg(not(osslconf = "OPENSSL_NO_BF"))] + pub fn bf_cbc() -> &'static CipherRef { + unsafe { CipherRef::from_ptr(ffi::EVP_bf_cbc() as *mut _) } + } + + #[cfg(not(osslconf = "OPENSSL_NO_BF"))] + pub fn bf_ecb() -> &'static CipherRef { + unsafe { CipherRef::from_ptr(ffi::EVP_bf_ecb() as *mut _) } + } + + #[cfg(not(osslconf = "OPENSSL_NO_BF"))] + pub fn bf_cfb64() -> &'static CipherRef { + unsafe { CipherRef::from_ptr(ffi::EVP_bf_cfb64() as *mut _) } + } + + #[cfg(not(osslconf = "OPENSSL_NO_BF"))] + pub fn bf_ofb() -> &'static CipherRef { + unsafe { CipherRef::from_ptr(ffi::EVP_bf_ofb() as *mut _) } + } + + pub fn des_cbc() -> &'static CipherRef { + unsafe { CipherRef::from_ptr(ffi::EVP_des_cbc() as *mut _) } + } + + pub fn des_ecb() -> &'static CipherRef { + unsafe { CipherRef::from_ptr(ffi::EVP_des_ecb() as *mut _) } + } + + pub fn des_ede3() -> &'static CipherRef { + unsafe { CipherRef::from_ptr(ffi::EVP_des_ede3() as *mut _) } + } + + pub fn des_ede3_ecb() -> &'static CipherRef { + unsafe { CipherRef::from_ptr(ffi::EVP_des_ede3_ecb() as *mut _) } + } + + pub fn des_ede3_cbc() -> &'static CipherRef { + unsafe { CipherRef::from_ptr(ffi::EVP_des_ede3_cbc() as *mut _) } + } + + #[cfg(not(boringssl))] + pub fn des_ede3_cfb8() -> &'static CipherRef { + unsafe { CipherRef::from_ptr(ffi::EVP_des_ede3_cfb8() as *mut _) } + } + + #[cfg(not(boringssl))] + pub fn des_ede3_cfb64() -> &'static CipherRef { + unsafe { CipherRef::from_ptr(ffi::EVP_des_ede3_cfb64() as *mut _) } + } + + #[cfg(not(boringssl))] + pub fn des_ede3_ofb() -> &'static CipherRef { + unsafe { CipherRef::from_ptr(ffi::EVP_des_ede3_ofb() as *mut _) } + } + + #[cfg(not(osslconf = "OPENSSL_NO_RC4"))] + pub fn rc4() -> &'static CipherRef { + unsafe { CipherRef::from_ptr(ffi::EVP_rc4() as *mut _) } + } + + #[cfg(not(osslconf = "OPENSSL_NO_CAMELLIA"))] + pub fn camellia128_cfb128() -> &'static CipherRef { + unsafe { CipherRef::from_ptr(ffi::EVP_camellia_128_cfb128() as *mut _) } + } + + #[cfg(not(osslconf = "OPENSSL_NO_CAMELLIA"))] + pub fn camellia128_ecb() -> &'static CipherRef { + unsafe { CipherRef::from_ptr(ffi::EVP_camellia_128_ecb() as *mut _) } + } + + #[cfg(not(osslconf = "OPENSSL_NO_CAMELLIA"))] + pub fn camellia128_cbc() -> &'static CipherRef { + unsafe { CipherRef::from_ptr(ffi::EVP_camellia_128_cbc() as *mut _) } + } + + #[cfg(not(osslconf = "OPENSSL_NO_CAMELLIA"))] + pub fn camellia128_ofb() -> &'static CipherRef { + unsafe { CipherRef::from_ptr(ffi::EVP_camellia_128_ofb() as *mut _) } + } + + #[cfg(not(osslconf = "OPENSSL_NO_CAMELLIA"))] + pub fn camellia192_cfb128() -> &'static CipherRef { + unsafe { CipherRef::from_ptr(ffi::EVP_camellia_192_cfb128() as *mut _) } + } + + #[cfg(not(osslconf = "OPENSSL_NO_CAMELLIA"))] + pub fn camellia192_ecb() -> &'static CipherRef { + unsafe { CipherRef::from_ptr(ffi::EVP_camellia_192_ecb() as *mut _) } + } + + #[cfg(not(osslconf = "OPENSSL_NO_CAMELLIA"))] + pub fn camellia192_cbc() -> &'static CipherRef { + unsafe { CipherRef::from_ptr(ffi::EVP_camellia_192_cbc() as *mut _) } + } + + #[cfg(not(osslconf = "OPENSSL_NO_CAMELLIA"))] + pub fn camellia192_ofb() -> &'static CipherRef { + unsafe { CipherRef::from_ptr(ffi::EVP_camellia_192_ofb() as *mut _) } + } + + #[cfg(not(osslconf = "OPENSSL_NO_CAMELLIA"))] + pub fn camellia256_cfb128() -> &'static CipherRef { + unsafe { CipherRef::from_ptr(ffi::EVP_camellia_256_cfb128() as *mut _) } + } + + #[cfg(not(osslconf = "OPENSSL_NO_CAMELLIA"))] + pub fn camellia256_ecb() -> &'static CipherRef { + unsafe { CipherRef::from_ptr(ffi::EVP_camellia_256_ecb() as *mut _) } + } + + #[cfg(not(osslconf = "OPENSSL_NO_CAMELLIA"))] + pub fn camellia256_cbc() -> &'static CipherRef { + unsafe { CipherRef::from_ptr(ffi::EVP_camellia_256_cbc() as *mut _) } + } + + #[cfg(not(osslconf = "OPENSSL_NO_CAMELLIA"))] + pub fn camellia256_ofb() -> &'static CipherRef { + unsafe { CipherRef::from_ptr(ffi::EVP_camellia_256_ofb() as *mut _) } + } + + #[cfg(not(osslconf = "OPENSSL_NO_CAST"))] + pub fn cast5_cfb64() -> &'static CipherRef { + unsafe { CipherRef::from_ptr(ffi::EVP_cast5_cfb64() as *mut _) } + } + + #[cfg(not(osslconf = "OPENSSL_NO_CAST"))] + pub fn cast5_ecb() -> &'static CipherRef { + unsafe { CipherRef::from_ptr(ffi::EVP_cast5_ecb() as *mut _) } + } + + #[cfg(not(osslconf = "OPENSSL_NO_CAST"))] + pub fn cast5_cbc() -> &'static CipherRef { + unsafe { CipherRef::from_ptr(ffi::EVP_cast5_cbc() as *mut _) } + } + + #[cfg(not(osslconf = "OPENSSL_NO_CAST"))] + pub fn cast5_ofb() -> &'static CipherRef { + unsafe { CipherRef::from_ptr(ffi::EVP_cast5_ofb() as *mut _) } + } + + #[cfg(not(osslconf = "OPENSSL_NO_IDEA"))] + pub fn idea_cfb64() -> &'static CipherRef { + unsafe { CipherRef::from_ptr(ffi::EVP_idea_cfb64() as *mut _) } + } + + #[cfg(not(osslconf = "OPENSSL_NO_IDEA"))] + pub fn idea_ecb() -> &'static CipherRef { + unsafe { CipherRef::from_ptr(ffi::EVP_idea_ecb() as *mut _) } + } + + #[cfg(not(osslconf = "OPENSSL_NO_IDEA"))] + pub fn idea_cbc() -> &'static CipherRef { + unsafe { CipherRef::from_ptr(ffi::EVP_idea_cbc() as *mut _) } + } + + #[cfg(not(osslconf = "OPENSSL_NO_IDEA"))] + pub fn idea_ofb() -> &'static CipherRef { + unsafe { CipherRef::from_ptr(ffi::EVP_idea_ofb() as *mut _) } + } + + #[cfg(all(any(ossl110, libressl310), not(osslconf = "OPENSSL_NO_CHACHA")))] + pub fn chacha20() -> &'static CipherRef { + unsafe { CipherRef::from_ptr(ffi::EVP_chacha20() as *mut _) } + } + + #[cfg(all(any(ossl110, libressl360), not(osslconf = "OPENSSL_NO_CHACHA")))] + pub fn chacha20_poly1305() -> &'static CipherRef { + unsafe { CipherRef::from_ptr(ffi::EVP_chacha20_poly1305() as *mut _) } + } + + #[cfg(not(osslconf = "OPENSSL_NO_SEED"))] + pub fn seed_cbc() -> &'static CipherRef { + unsafe { CipherRef::from_ptr(ffi::EVP_seed_cbc() as *mut _) } + } + + #[cfg(not(osslconf = "OPENSSL_NO_SEED"))] + pub fn seed_cfb128() -> &'static CipherRef { + unsafe { CipherRef::from_ptr(ffi::EVP_seed_cfb128() as *mut _) } + } + + #[cfg(not(osslconf = "OPENSSL_NO_SEED"))] + pub fn seed_ecb() -> &'static CipherRef { + unsafe { CipherRef::from_ptr(ffi::EVP_seed_ecb() as *mut _) } + } + + #[cfg(not(osslconf = "OPENSSL_NO_SEED"))] + pub fn seed_ofb() -> &'static CipherRef { + unsafe { CipherRef::from_ptr(ffi::EVP_seed_ofb() as *mut _) } + } + + #[cfg(all(any(ossl111, libressl291), not(osslconf = "OPENSSL_NO_SM4")))] + pub fn sm4_ecb() -> &'static CipherRef { + unsafe { CipherRef::from_ptr(ffi::EVP_sm4_ecb() as *mut _) } + } + + #[cfg(all(any(ossl111, libressl291), not(osslconf = "OPENSSL_NO_SM4")))] + pub fn sm4_cbc() -> &'static CipherRef { + unsafe { CipherRef::from_ptr(ffi::EVP_sm4_cbc() as *mut _) } + } + + #[cfg(all(any(ossl111, libressl291), not(osslconf = "OPENSSL_NO_SM4")))] + pub fn sm4_ctr() -> &'static CipherRef { + unsafe { CipherRef::from_ptr(ffi::EVP_sm4_ctr() as *mut _) } + } + + #[cfg(all(any(ossl111, libressl291), not(osslconf = "OPENSSL_NO_SM4")))] + pub fn sm4_cfb128() -> &'static CipherRef { + unsafe { CipherRef::from_ptr(ffi::EVP_sm4_cfb128() as *mut _) } + } + + #[cfg(all(any(ossl111, libressl291), not(osslconf = "OPENSSL_NO_SM4")))] + pub fn sm4_ofb() -> &'static CipherRef { + unsafe { CipherRef::from_ptr(ffi::EVP_sm4_ofb() as *mut _) } + } +} + +/// A reference to a [`Cipher`]. +pub struct CipherRef(Opaque); + +impl ForeignTypeRef for CipherRef { + type CType = ffi::EVP_CIPHER; +} + +unsafe impl Sync for CipherRef {} +unsafe impl Send for CipherRef {} + +impl CipherRef { + /// Returns the cipher's Nid. + #[corresponds(EVP_CIPHER_nid)] + pub fn nid(&self) -> Nid { + let nid = unsafe { ffi::EVP_CIPHER_nid(self.as_ptr()) }; + Nid::from_raw(nid) + } + + /// Returns the length of keys used with this cipher. + #[corresponds(EVP_CIPHER_key_length)] + pub fn key_length(&self) -> usize { + unsafe { EVP_CIPHER_key_length(self.as_ptr()) as usize } + } + + /// Returns the length of the IV used with this cipher. + /// + /// # Note + /// + /// Ciphers that do not use an IV have an IV length of 0. + #[corresponds(EVP_CIPHER_iv_length)] + pub fn iv_length(&self) -> usize { + unsafe { EVP_CIPHER_iv_length(self.as_ptr()) as usize } + } + + /// Returns the block size of the cipher. + /// + /// # Note + /// + /// Stream ciphers have a block size of 1. + #[corresponds(EVP_CIPHER_block_size)] + pub fn block_size(&self) -> usize { + unsafe { EVP_CIPHER_block_size(self.as_ptr()) as usize } + } +} diff --git a/vendor/openssl/src/cipher_ctx.rs b/vendor/openssl/src/cipher_ctx.rs new file mode 100644 index 0000000..d31830a --- /dev/null +++ b/vendor/openssl/src/cipher_ctx.rs @@ -0,0 +1,1106 @@ +//! The symmetric encryption context. +//! +//! # Examples +//! +//! Encrypt data with AES128 CBC +//! +//! ``` +//! use openssl::cipher::Cipher; +//! use openssl::cipher_ctx::CipherCtx; +//! +//! let cipher = Cipher::aes_128_cbc(); +//! let data = b"Some Crypto Text"; +//! let key = b"\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F"; +//! let iv = b"\x00\x01\x02\x03\x04\x05\x06\x07\x00\x01\x02\x03\x04\x05\x06\x07"; +//! +//! let mut ctx = CipherCtx::new().unwrap(); +//! ctx.encrypt_init(Some(cipher), Some(key), Some(iv)).unwrap(); +//! +//! let mut ciphertext = vec![]; +//! ctx.cipher_update_vec(data, &mut ciphertext).unwrap(); +//! ctx.cipher_final_vec(&mut ciphertext).unwrap(); +//! +//! assert_eq!( +//! b"\xB4\xB9\xE7\x30\xD6\xD6\xF7\xDE\x77\x3F\x1C\xFF\xB3\x3E\x44\x5A\x91\xD7\x27\x62\x87\x4D\ +//! \xFB\x3C\x5E\xC4\x59\x72\x4A\xF4\x7C\xA1", +//! &ciphertext[..], +//! ); +//! ``` +//! +//! Decrypt data with AES128 CBC +//! +//! ``` +//! use openssl::cipher::Cipher; +//! use openssl::cipher_ctx::CipherCtx; +//! +//! let cipher = Cipher::aes_128_cbc(); +//! let data = b"\xB4\xB9\xE7\x30\xD6\xD6\xF7\xDE\x77\x3F\x1C\xFF\xB3\x3E\x44\x5A\x91\xD7\x27\x62\ +//! \x87\x4D\xFB\x3C\x5E\xC4\x59\x72\x4A\xF4\x7C\xA1"; +//! let key = b"\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F"; +//! let iv = b"\x00\x01\x02\x03\x04\x05\x06\x07\x00\x01\x02\x03\x04\x05\x06\x07"; +//! +//! let mut ctx = CipherCtx::new().unwrap(); +//! ctx.decrypt_init(Some(cipher), Some(key), Some(iv)).unwrap(); +//! +//! let mut plaintext = vec![]; +//! ctx.cipher_update_vec(data, &mut plaintext).unwrap(); +//! ctx.cipher_final_vec(&mut plaintext).unwrap(); +//! +//! assert_eq!(b"Some Crypto Text", &plaintext[..]); +//! ``` +#![warn(missing_docs)] + +use crate::cipher::CipherRef; +use crate::error::ErrorStack; +#[cfg(not(boringssl))] +use crate::pkey::{HasPrivate, HasPublic, PKey, PKeyRef}; +use crate::{cvt, cvt_p}; +#[cfg(ossl102)] +use bitflags::bitflags; +use cfg_if::cfg_if; +use foreign_types::{ForeignType, ForeignTypeRef}; +use libc::{c_int, c_uchar}; +use openssl_macros::corresponds; +use std::convert::{TryFrom, TryInto}; +use std::ptr; + +cfg_if! { + if #[cfg(ossl300)] { + use ffi::EVP_CIPHER_CTX_get0_cipher; + } else { + use ffi::EVP_CIPHER_CTX_cipher as EVP_CIPHER_CTX_get0_cipher; + } +} + +foreign_type_and_impl_send_sync! { + type CType = ffi::EVP_CIPHER_CTX; + fn drop = ffi::EVP_CIPHER_CTX_free; + + /// A context object used to perform symmetric encryption operations. + pub struct CipherCtx; + /// A reference to a [`CipherCtx`]. + pub struct CipherCtxRef; +} + +#[cfg(ossl102)] +bitflags! { + /// Flags for `EVP_CIPHER_CTX`. + pub struct CipherCtxFlags : c_int { + /// The flag used to opt into AES key wrap ciphers. + const FLAG_WRAP_ALLOW = ffi::EVP_CIPHER_CTX_FLAG_WRAP_ALLOW; + } +} + +impl CipherCtx { + /// Creates a new context. + #[corresponds(EVP_CIPHER_CTX_new)] + pub fn new() -> Result { + ffi::init(); + + unsafe { + let ptr = cvt_p(ffi::EVP_CIPHER_CTX_new())?; + Ok(CipherCtx::from_ptr(ptr)) + } + } +} + +impl CipherCtxRef { + #[corresponds(EVP_CIPHER_CTX_copy)] + pub fn copy(&mut self, src: &CipherCtxRef) -> Result<(), ErrorStack> { + unsafe { + cvt(ffi::EVP_CIPHER_CTX_copy(self.as_ptr(), src.as_ptr()))?; + Ok(()) + } + } + + /// Initializes the context for encryption. + /// + /// Normally this is called once to set all of the cipher, key, and IV. However, this process can be split up + /// by first setting the cipher with no key or IV and then setting the key and IV with no cipher. This can be used + /// to, for example, use a nonstandard IV size. + /// + /// # Panics + /// + /// Panics if the key buffer is smaller than the key size of the cipher, the IV buffer is smaller than the IV size + /// of the cipher, or if a key or IV is provided before a cipher. + #[corresponds(EVP_EncryptInit_ex)] + pub fn encrypt_init( + &mut self, + type_: Option<&CipherRef>, + key: Option<&[u8]>, + iv: Option<&[u8]>, + ) -> Result<(), ErrorStack> { + self.cipher_init(type_, key, iv, ffi::EVP_EncryptInit_ex) + } + + /// Initializes the context for decryption. + /// + /// Normally this is called once to set all of the cipher, key, and IV. However, this process can be split up + /// by first setting the cipher with no key or IV and then setting the key and IV with no cipher. This can be used + /// to, for example, use a nonstandard IV size. + /// + /// # Panics + /// + /// Panics if the key buffer is smaller than the key size of the cipher, the IV buffer is smaller than the IV size + /// of the cipher, or if a key or IV is provided before a cipher. + #[corresponds(EVP_DecryptInit_ex)] + pub fn decrypt_init( + &mut self, + type_: Option<&CipherRef>, + key: Option<&[u8]>, + iv: Option<&[u8]>, + ) -> Result<(), ErrorStack> { + self.cipher_init(type_, key, iv, ffi::EVP_DecryptInit_ex) + } + + fn cipher_init( + &mut self, + type_: Option<&CipherRef>, + key: Option<&[u8]>, + iv: Option<&[u8]>, + f: unsafe extern "C" fn( + *mut ffi::EVP_CIPHER_CTX, + *const ffi::EVP_CIPHER, + *mut ffi::ENGINE, + *const c_uchar, + *const c_uchar, + ) -> c_int, + ) -> Result<(), ErrorStack> { + if let Some(key) = key { + let key_len = type_.map_or_else(|| self.key_length(), |c| c.key_length()); + assert!(key_len <= key.len()); + } + + if let Some(iv) = iv { + let iv_len = type_.map_or_else(|| self.iv_length(), |c| c.iv_length()); + assert!(iv_len <= iv.len()); + } + + unsafe { + cvt(f( + self.as_ptr(), + type_.map_or(ptr::null(), |p| p.as_ptr()), + ptr::null_mut(), + key.map_or(ptr::null(), |k| k.as_ptr()), + iv.map_or(ptr::null(), |iv| iv.as_ptr()), + ))?; + } + + Ok(()) + } + + /// Initializes the context to perform envelope encryption. + /// + /// Normally this is called once to set both the cipher and public keys. However, this process may be split up by + /// first providing the cipher with no public keys and then setting the public keys with no cipher. + /// + /// `encrypted_keys` will contain the generated symmetric key encrypted with each corresponding asymmetric private + /// key. The generated IV will be written to `iv`. + /// + /// # Panics + /// + /// Panics if `pub_keys` is not the same size as `encrypted_keys`, the IV buffer is smaller than the cipher's IV + /// size, or if an IV is provided before the cipher. + #[corresponds(EVP_SealInit)] + #[cfg(not(boringssl))] + pub fn seal_init( + &mut self, + type_: Option<&CipherRef>, + pub_keys: &[PKey], + encrypted_keys: &mut [Vec], + iv: Option<&mut [u8]>, + ) -> Result<(), ErrorStack> + where + T: HasPublic, + { + assert_eq!(pub_keys.len(), encrypted_keys.len()); + if !pub_keys.is_empty() { + let iv_len = type_.map_or_else(|| self.iv_length(), |c| c.iv_length()); + assert!(iv.as_ref().map_or(0, |b| b.len()) >= iv_len); + } + + for (pub_key, buf) in pub_keys.iter().zip(&mut *encrypted_keys) { + buf.resize(pub_key.size(), 0); + } + + let mut keys = encrypted_keys + .iter_mut() + .map(|b| b.as_mut_ptr()) + .collect::>(); + let mut key_lengths = vec![0; pub_keys.len()]; + let pub_keys_len = i32::try_from(pub_keys.len()).unwrap(); + + unsafe { + cvt(ffi::EVP_SealInit( + self.as_ptr(), + type_.map_or(ptr::null(), |p| p.as_ptr()), + keys.as_mut_ptr(), + key_lengths.as_mut_ptr(), + iv.map_or(ptr::null_mut(), |b| b.as_mut_ptr()), + pub_keys.as_ptr() as *mut _, + pub_keys_len, + ))?; + } + + for (buf, len) in encrypted_keys.iter_mut().zip(key_lengths) { + buf.truncate(len as usize); + } + + Ok(()) + } + + /// Initializes the context to perform envelope decryption. + /// + /// Normally this is called once with all of the arguments present. However, this process may be split up by first + /// providing the cipher alone and then after providing the rest of the arguments in a second call. + /// + /// # Panics + /// + /// Panics if the IV buffer is smaller than the cipher's required IV size or if the IV is provided before the + /// cipher. + #[corresponds(EVP_OpenInit)] + #[cfg(not(boringssl))] + pub fn open_init( + &mut self, + type_: Option<&CipherRef>, + encrypted_key: &[u8], + iv: Option<&[u8]>, + priv_key: Option<&PKeyRef>, + ) -> Result<(), ErrorStack> + where + T: HasPrivate, + { + if priv_key.is_some() { + let iv_len = type_.map_or_else(|| self.iv_length(), |c| c.iv_length()); + assert!(iv.map_or(0, |b| b.len()) >= iv_len); + } + + let len = c_int::try_from(encrypted_key.len()).unwrap(); + unsafe { + cvt(ffi::EVP_OpenInit( + self.as_ptr(), + type_.map_or(ptr::null(), |p| p.as_ptr()), + encrypted_key.as_ptr(), + len, + iv.map_or(ptr::null(), |b| b.as_ptr()), + priv_key.map_or(ptr::null_mut(), ForeignTypeRef::as_ptr), + ))?; + } + + Ok(()) + } + + fn assert_cipher(&self) { + unsafe { + assert!(!EVP_CIPHER_CTX_get0_cipher(self.as_ptr()).is_null()); + } + } + + /// Returns the block size of the context's cipher. + /// + /// Stream ciphers will report a block size of 1. + /// + /// # Panics + /// + /// Panics if the context has not been initialized with a cipher. + #[corresponds(EVP_CIPHER_CTX_block_size)] + pub fn block_size(&self) -> usize { + self.assert_cipher(); + + unsafe { ffi::EVP_CIPHER_CTX_block_size(self.as_ptr()) as usize } + } + + /// Returns the key length of the context's cipher. + /// + /// # Panics + /// + /// Panics if the context has not been initialized with a cipher. + #[corresponds(EVP_CIPHER_CTX_key_length)] + pub fn key_length(&self) -> usize { + self.assert_cipher(); + + unsafe { ffi::EVP_CIPHER_CTX_key_length(self.as_ptr()) as usize } + } + + /// Generates a random key based on the configured cipher. + /// + /// # Panics + /// + /// Panics if the context has not been initialized with a cipher or if the buffer is smaller than the cipher's key + /// length. + #[corresponds(EVP_CIPHER_CTX_rand_key)] + #[cfg(not(boringssl))] + pub fn rand_key(&self, buf: &mut [u8]) -> Result<(), ErrorStack> { + assert!(buf.len() >= self.key_length()); + + unsafe { + cvt(ffi::EVP_CIPHER_CTX_rand_key( + self.as_ptr(), + buf.as_mut_ptr(), + ))?; + } + + Ok(()) + } + + /// Sets the length of the key expected by the context. + /// + /// Only some ciphers support configurable key lengths. + /// + /// # Panics + /// + /// Panics if the context has not been initialized with a cipher. + #[corresponds(EVP_CIPHER_CTX_set_key_length)] + pub fn set_key_length(&mut self, len: usize) -> Result<(), ErrorStack> { + self.assert_cipher(); + + unsafe { + cvt(ffi::EVP_CIPHER_CTX_set_key_length( + self.as_ptr(), + len.try_into().unwrap(), + ))?; + } + + Ok(()) + } + + /// Returns the length of the IV expected by this context. + /// + /// Returns 0 if the cipher does not use an IV. + /// + /// # Panics + /// + /// Panics if the context has not been initialized with a cipher. + #[corresponds(EVP_CIPHER_CTX_iv_length)] + pub fn iv_length(&self) -> usize { + self.assert_cipher(); + + unsafe { ffi::EVP_CIPHER_CTX_iv_length(self.as_ptr()) as usize } + } + + /// Returns the `num` parameter of the cipher. + /// + /// Built-in ciphers typically use this to track how much of the + /// current underlying block has been "used" already. + /// + /// # Panics + /// + /// Panics if the context has not been initialized with a cipher. + #[corresponds(EVP_CIPHER_CTX_num)] + #[cfg(ossl110)] + pub fn num(&self) -> usize { + self.assert_cipher(); + + unsafe { ffi::EVP_CIPHER_CTX_num(self.as_ptr()) as usize } + } + + /// Sets the length of the IV expected by this context. + /// + /// Only some ciphers support configurable IV lengths. + /// + /// # Panics + /// + /// Panics if the context has not been initialized with a cipher. + #[corresponds(EVP_CIPHER_CTX_ctrl)] + pub fn set_iv_length(&mut self, len: usize) -> Result<(), ErrorStack> { + self.assert_cipher(); + + let len = c_int::try_from(len).unwrap(); + + unsafe { + cvt(ffi::EVP_CIPHER_CTX_ctrl( + self.as_ptr(), + ffi::EVP_CTRL_GCM_SET_IVLEN, + len, + ptr::null_mut(), + ))?; + } + + Ok(()) + } + + /// Returns the length of the authentication tag expected by this context. + /// + /// Returns 0 if the cipher is not authenticated. + /// + /// # Panics + /// + /// Panics if the context has not been initialized with a cipher. + /// + /// Requires OpenSSL 3.0.0 or newer. + #[corresponds(EVP_CIPHER_CTX_get_tag_length)] + #[cfg(ossl300)] + pub fn tag_length(&self) -> usize { + self.assert_cipher(); + + unsafe { ffi::EVP_CIPHER_CTX_get_tag_length(self.as_ptr()) as usize } + } + + /// Retrieves the calculated authentication tag from the context. + /// + /// This should be called after [`Self::cipher_final`], and is only supported by authenticated ciphers. + /// + /// The size of the buffer indicates the size of the tag. While some ciphers support a range of tag sizes, it is + /// recommended to pick the maximum size. + #[corresponds(EVP_CIPHER_CTX_ctrl)] + pub fn tag(&self, tag: &mut [u8]) -> Result<(), ErrorStack> { + let len = c_int::try_from(tag.len()).unwrap(); + + unsafe { + cvt(ffi::EVP_CIPHER_CTX_ctrl( + self.as_ptr(), + ffi::EVP_CTRL_GCM_GET_TAG, + len, + tag.as_mut_ptr() as *mut _, + ))?; + } + + Ok(()) + } + + /// Sets the length of the generated authentication tag. + /// + /// This must be called when encrypting with a cipher in CCM mode to use a tag size other than the default. + #[corresponds(EVP_CIPHER_CTX_ctrl)] + pub fn set_tag_length(&mut self, len: usize) -> Result<(), ErrorStack> { + let len = c_int::try_from(len).unwrap(); + + unsafe { + cvt(ffi::EVP_CIPHER_CTX_ctrl( + self.as_ptr(), + ffi::EVP_CTRL_GCM_SET_TAG, + len, + ptr::null_mut(), + ))?; + } + + Ok(()) + } + + /// Sets the authentication tag for verification during decryption. + #[corresponds(EVP_CIPHER_CTX_ctrl)] + pub fn set_tag(&mut self, tag: &[u8]) -> Result<(), ErrorStack> { + let len = c_int::try_from(tag.len()).unwrap(); + + unsafe { + cvt(ffi::EVP_CIPHER_CTX_ctrl( + self.as_ptr(), + ffi::EVP_CTRL_GCM_SET_TAG, + len, + tag.as_ptr() as *mut _, + ))?; + } + + Ok(()) + } + + /// Enables or disables padding. + /// + /// If padding is disabled, the plaintext must be an exact multiple of the cipher's block size. + #[corresponds(EVP_CIPHER_CTX_set_padding)] + pub fn set_padding(&mut self, padding: bool) { + unsafe { + ffi::EVP_CIPHER_CTX_set_padding(self.as_ptr(), padding as c_int); + } + } + + /// Sets the total length of plaintext data. + /// + /// This is required for ciphers operating in CCM mode. + #[corresponds(EVP_CipherUpdate)] + pub fn set_data_len(&mut self, len: usize) -> Result<(), ErrorStack> { + let len = c_int::try_from(len).unwrap(); + + unsafe { + cvt(ffi::EVP_CipherUpdate( + self.as_ptr(), + ptr::null_mut(), + &mut 0, + ptr::null(), + len, + ))?; + } + + Ok(()) + } + + /// Set ctx flags. + /// + /// This function is currently used to enable AES key wrap feature supported by OpenSSL 1.0.2 or newer. + #[corresponds(EVP_CIPHER_CTX_set_flags)] + #[cfg(ossl102)] + pub fn set_flags(&mut self, flags: CipherCtxFlags) { + unsafe { + ffi::EVP_CIPHER_CTX_set_flags(self.as_ptr(), flags.bits()); + } + } + + /// Writes data into the context. + /// + /// Providing no output buffer will cause the input to be considered additional authenticated data (AAD). + /// + /// Returns the number of bytes written to `output`. + /// + /// # Panics + /// + /// Panics if `output` doesn't contain enough space for data to be + /// written. + #[corresponds(EVP_CipherUpdate)] + pub fn cipher_update( + &mut self, + input: &[u8], + output: Option<&mut [u8]>, + ) -> Result { + if let Some(output) = &output { + let mut block_size = self.block_size(); + if block_size == 1 { + block_size = 0; + } + let min_output_size = input.len() + block_size; + assert!( + output.len() >= min_output_size, + "Output buffer size should be at least {} bytes.", + min_output_size + ); + } + + unsafe { self.cipher_update_unchecked(input, output) } + } + + /// Writes data into the context. + /// + /// Providing no output buffer will cause the input to be considered additional authenticated data (AAD). + /// + /// Returns the number of bytes written to `output`. + /// + /// This function is the same as [`Self::cipher_update`] but with the + /// output size check removed. It can be used when the exact + /// buffer size control is maintained by the caller. + /// + /// # Safety + /// + /// The caller is expected to provide `output` buffer + /// large enough to contain correct number of bytes. For streaming + /// ciphers the output buffer size should be at least as big as + /// the input buffer. For block ciphers the size of the output + /// buffer depends on the state of partially updated blocks. + #[corresponds(EVP_CipherUpdate)] + pub unsafe fn cipher_update_unchecked( + &mut self, + input: &[u8], + output: Option<&mut [u8]>, + ) -> Result { + let inlen = c_int::try_from(input.len()).unwrap(); + + let mut outlen = 0; + + cvt(ffi::EVP_CipherUpdate( + self.as_ptr(), + output.map_or(ptr::null_mut(), |b| b.as_mut_ptr()), + &mut outlen, + input.as_ptr(), + inlen, + ))?; + + Ok(outlen as usize) + } + + /// Like [`Self::cipher_update`] except that it appends output to a [`Vec`]. + pub fn cipher_update_vec( + &mut self, + input: &[u8], + output: &mut Vec, + ) -> Result { + let base = output.len(); + output.resize(base + input.len() + self.block_size(), 0); + let len = self.cipher_update(input, Some(&mut output[base..]))?; + output.truncate(base + len); + + Ok(len) + } + + /// Like [`Self::cipher_update`] except that it writes output into the + /// `data` buffer. The `inlen` parameter specifies the number of bytes in + /// `data` that are considered the input. For streaming ciphers, the size of + /// `data` must be at least the input size. Otherwise, it must be at least + /// an additional block size larger. + /// + /// Note: Use [`Self::cipher_update`] with no output argument to write AAD. + /// + /// # Panics + /// + /// This function panics if the input size cannot be represented as `int` or + /// exceeds the buffer size, or if the output buffer does not contain enough + /// additional space. + #[corresponds(EVP_CipherUpdate)] + pub fn cipher_update_inplace( + &mut self, + data: &mut [u8], + inlen: usize, + ) -> Result { + assert!(inlen <= data.len(), "Input size may not exceed buffer size"); + let block_size = self.block_size(); + if block_size != 1 { + assert!( + data.len() >= inlen + block_size, + "Output buffer size must be at least {} bytes.", + inlen + block_size + ); + } + + let inlen = c_int::try_from(inlen).unwrap(); + let mut outlen = 0; + unsafe { + cvt(ffi::EVP_CipherUpdate( + self.as_ptr(), + data.as_mut_ptr(), + &mut outlen, + data.as_ptr(), + inlen, + )) + }?; + + Ok(outlen as usize) + } + + /// Finalizes the encryption or decryption process. + /// + /// Any remaining data will be written to the output buffer. + /// + /// Returns the number of bytes written to `output`. + /// + /// # Panics + /// + /// Panics if `output` is smaller than the cipher's block size. + #[corresponds(EVP_CipherFinal)] + pub fn cipher_final(&mut self, output: &mut [u8]) -> Result { + let block_size = self.block_size(); + if block_size > 1 { + assert!(output.len() >= block_size); + } + + unsafe { self.cipher_final_unchecked(output) } + } + + /// Finalizes the encryption or decryption process. + /// + /// Any remaining data will be written to the output buffer. + /// + /// Returns the number of bytes written to `output`. + /// + /// This function is the same as [`Self::cipher_final`] but with + /// the output buffer size check removed. + /// + /// # Safety + /// + /// The caller is expected to provide `output` buffer + /// large enough to contain correct number of bytes. For streaming + /// ciphers the output buffer can be empty, for block ciphers the + /// output buffer should be at least as big as the block. + #[corresponds(EVP_CipherFinal)] + pub unsafe fn cipher_final_unchecked( + &mut self, + output: &mut [u8], + ) -> Result { + let mut outl = 0; + + cvt(ffi::EVP_CipherFinal( + self.as_ptr(), + output.as_mut_ptr(), + &mut outl, + ))?; + + Ok(outl as usize) + } + + /// Like [`Self::cipher_final`] except that it appends output to a [`Vec`]. + pub fn cipher_final_vec(&mut self, output: &mut Vec) -> Result { + let base = output.len(); + output.resize(base + self.block_size(), 0); + let len = self.cipher_final(&mut output[base..])?; + output.truncate(base + len); + + Ok(len) + } +} + +#[cfg(test)] +mod test { + use super::*; + use crate::{cipher::Cipher, rand::rand_bytes}; + #[cfg(not(boringssl))] + use std::slice; + + #[test] + #[cfg(not(boringssl))] + fn seal_open() { + let private_pem = include_bytes!("../test/rsa.pem"); + let public_pem = include_bytes!("../test/rsa.pem.pub"); + let private_key = PKey::private_key_from_pem(private_pem).unwrap(); + let public_key = PKey::public_key_from_pem(public_pem).unwrap(); + let cipher = Cipher::aes_256_cbc(); + let secret = b"My secret message"; + + let mut ctx = CipherCtx::new().unwrap(); + let mut encrypted_key = vec![]; + let mut iv = vec![0; cipher.iv_length()]; + let mut encrypted = vec![]; + ctx.seal_init( + Some(cipher), + &[public_key], + slice::from_mut(&mut encrypted_key), + Some(&mut iv), + ) + .unwrap(); + ctx.cipher_update_vec(secret, &mut encrypted).unwrap(); + ctx.cipher_final_vec(&mut encrypted).unwrap(); + + let mut decrypted = vec![]; + ctx.open_init(Some(cipher), &encrypted_key, Some(&iv), Some(&private_key)) + .unwrap(); + ctx.cipher_update_vec(&encrypted, &mut decrypted).unwrap(); + ctx.cipher_final_vec(&mut decrypted).unwrap(); + + assert_eq!(secret, &decrypted[..]); + } + + fn aes_128_cbc(cipher: &CipherRef) { + // from https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-38a.pdf + let key = hex::decode("2b7e151628aed2a6abf7158809cf4f3c").unwrap(); + let iv = hex::decode("000102030405060708090a0b0c0d0e0f").unwrap(); + let pt = hex::decode("6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e51") + .unwrap(); + let ct = hex::decode("7649abac8119b246cee98e9b12e9197d5086cb9b507219ee95db113a917678b2") + .unwrap(); + + let mut ctx = CipherCtx::new().unwrap(); + + ctx.encrypt_init(Some(cipher), Some(&key), Some(&iv)) + .unwrap(); + ctx.set_padding(false); + + let mut buf = vec![]; + ctx.cipher_update_vec(&pt, &mut buf).unwrap(); + ctx.cipher_final_vec(&mut buf).unwrap(); + + assert_eq!(buf, ct); + + ctx.decrypt_init(Some(cipher), Some(&key), Some(&iv)) + .unwrap(); + ctx.set_padding(false); + + let mut buf = vec![]; + ctx.cipher_update_vec(&ct, &mut buf).unwrap(); + ctx.cipher_final_vec(&mut buf).unwrap(); + + assert_eq!(buf, pt); + } + + #[test] + #[cfg(ossl300)] + fn fetched_aes_128_cbc() { + let cipher = Cipher::fetch(None, "AES-128-CBC", None).unwrap(); + aes_128_cbc(&cipher); + } + + #[test] + fn default_aes_128_cbc() { + let cipher = Cipher::aes_128_cbc(); + aes_128_cbc(cipher); + } + + #[test] + fn test_stream_ciphers() { + test_stream_cipher(Cipher::aes_192_ctr()); + test_stream_cipher(Cipher::aes_256_ctr()); + } + + fn test_stream_cipher(cipher: &'static CipherRef) { + let mut key = vec![0; cipher.key_length()]; + rand_bytes(&mut key).unwrap(); + let mut iv = vec![0; cipher.iv_length()]; + rand_bytes(&mut iv).unwrap(); + + let mut ctx = CipherCtx::new().unwrap(); + + ctx.encrypt_init(Some(cipher), Some(&key), Some(&iv)) + .unwrap(); + ctx.set_padding(false); + + assert_eq!( + 1, + cipher.block_size(), + "Need a stream cipher, not a block cipher" + ); + + // update cipher with non-full block + // this is a streaming cipher so the number of output bytes + // will be the same as the number of input bytes + let mut output = vec![0; 32]; + let outlen = ctx + .cipher_update(&[1; 15], Some(&mut output[0..15])) + .unwrap(); + assert_eq!(15, outlen); + + // update cipher with missing bytes from the previous block + // as previously it will output the same number of bytes as + // the input + let outlen = ctx + .cipher_update(&[1; 17], Some(&mut output[15..])) + .unwrap(); + assert_eq!(17, outlen); + + ctx.cipher_final_vec(&mut vec![0; 0]).unwrap(); + + // encrypt again, but use in-place encryption this time + // First reset the IV + ctx.encrypt_init(None, None, Some(&iv)).unwrap(); + ctx.set_padding(false); + let mut data_inplace: [u8; 32] = [1; 32]; + let outlen = ctx + .cipher_update_inplace(&mut data_inplace[0..15], 15) + .unwrap(); + assert_eq!(15, outlen); + + let outlen = ctx + .cipher_update_inplace(&mut data_inplace[15..32], 17) + .unwrap(); + assert_eq!(17, outlen); + + ctx.cipher_final(&mut [0u8; 0]).unwrap(); + + // Check that the resulting data is encrypted in the same manner + assert_eq!(data_inplace.as_slice(), output.as_slice()); + + // try to decrypt + ctx.decrypt_init(Some(cipher), Some(&key), Some(&iv)) + .unwrap(); + ctx.set_padding(false); + + // update cipher with non-full block + // expect that the output for stream cipher will contain + // the same number of bytes as the input + let mut output_decrypted = vec![0; 32]; + let outlen = ctx + .cipher_update(&output[0..15], Some(&mut output_decrypted[0..15])) + .unwrap(); + assert_eq!(15, outlen); + + let outlen = ctx + .cipher_update(&output[15..], Some(&mut output_decrypted[15..])) + .unwrap(); + assert_eq!(17, outlen); + + ctx.cipher_final_vec(&mut vec![0; 0]).unwrap(); + // check if the decrypted blocks are the same as input (all ones) + assert_eq!(output_decrypted, vec![1; 32]); + + // decrypt again, but now the output in-place + ctx.decrypt_init(None, None, Some(&iv)).unwrap(); + ctx.set_padding(false); + + let outlen = ctx.cipher_update_inplace(&mut output[0..15], 15).unwrap(); + assert_eq!(15, outlen); + + let outlen = ctx.cipher_update_inplace(&mut output[15..], 17).unwrap(); + assert_eq!(17, outlen); + + ctx.cipher_final_vec(&mut vec![0; 0]).unwrap(); + assert_eq!(output_decrypted, output); + } + + #[test] + #[should_panic(expected = "Output buffer size should be at least 33 bytes.")] + fn full_block_updates_aes_128() { + output_buffer_too_small(Cipher::aes_128_cbc()); + } + + #[test] + #[should_panic(expected = "Output buffer size should be at least 33 bytes.")] + fn full_block_updates_aes_256() { + output_buffer_too_small(Cipher::aes_256_cbc()); + } + + #[test] + #[should_panic(expected = "Output buffer size should be at least 17 bytes.")] + fn full_block_updates_3des() { + output_buffer_too_small(Cipher::des_ede3_cbc()); + } + + fn output_buffer_too_small(cipher: &'static CipherRef) { + let mut key = vec![0; cipher.key_length()]; + rand_bytes(&mut key).unwrap(); + let mut iv = vec![0; cipher.iv_length()]; + rand_bytes(&mut iv).unwrap(); + + let mut ctx = CipherCtx::new().unwrap(); + + ctx.encrypt_init(Some(cipher), Some(&key), Some(&iv)) + .unwrap(); + ctx.set_padding(false); + + let block_size = cipher.block_size(); + assert!(block_size > 1, "Need a block cipher, not a stream cipher"); + + ctx.cipher_update(&vec![0; block_size + 1], Some(&mut vec![0; block_size - 1])) + .unwrap(); + } + + #[cfg(ossl102)] + fn cipher_wrap_test(cipher: &CipherRef, pt: &str, ct: &str, key: &str, iv: Option<&str>) { + let pt = hex::decode(pt).unwrap(); + let key = hex::decode(key).unwrap(); + let expected = hex::decode(ct).unwrap(); + let iv = iv.map(|v| hex::decode(v).unwrap()); + let padding = 8 - pt.len() % 8; + let mut computed = vec![0; pt.len() + padding + cipher.block_size() * 2]; + let mut ctx = CipherCtx::new().unwrap(); + + ctx.set_flags(CipherCtxFlags::FLAG_WRAP_ALLOW); + ctx.encrypt_init(Some(cipher), Some(&key), iv.as_deref()) + .unwrap(); + + let count = ctx.cipher_update(&pt, Some(&mut computed)).unwrap(); + let rest = ctx.cipher_final(&mut computed[count..]).unwrap(); + computed.truncate(count + rest); + + if computed != expected { + println!("Computed: {}", hex::encode(&computed)); + println!("Expected: {}", hex::encode(&expected)); + if computed.len() != expected.len() { + println!( + "Lengths differ: {} in computed vs {} expected", + computed.len(), + expected.len() + ); + } + panic!("test failure"); + } + } + + #[test] + #[cfg(ossl102)] + fn test_aes128_wrap() { + let pt = "00112233445566778899aabbccddeeff"; + let ct = "7940ff694448b5bb5139c959a4896832e55d69aa04daa27e"; + let key = "2b7e151628aed2a6abf7158809cf4f3c"; + let iv = "0001020304050607"; + + cipher_wrap_test(Cipher::aes_128_wrap(), pt, ct, key, Some(iv)); + } + + #[test] + #[cfg(ossl102)] + fn test_aes128_wrap_default_iv() { + let pt = "00112233445566778899aabbccddeeff"; + let ct = "38f1215f0212526f8a70b51955b9fbdc9fe3041d9832306e"; + let key = "2b7e151628aed2a6abf7158809cf4f3c"; + + cipher_wrap_test(Cipher::aes_128_wrap(), pt, ct, key, None); + } + + #[test] + #[cfg(ossl110)] + fn test_aes128_wrap_pad() { + let pt = "00112233445566778899aabbccddee"; + let ct = "f13998f5ab32ef82a1bdbcbe585e1d837385b529572a1e1b"; + let key = "2b7e151628aed2a6abf7158809cf4f3c"; + let iv = "00010203"; + + cipher_wrap_test(Cipher::aes_128_wrap_pad(), pt, ct, key, Some(iv)); + } + + #[test] + #[cfg(ossl110)] + fn test_aes128_wrap_pad_default_iv() { + let pt = "00112233445566778899aabbccddee"; + let ct = "3a501085fb8cf66f4186b7df851914d471ed823411598add"; + let key = "2b7e151628aed2a6abf7158809cf4f3c"; + + cipher_wrap_test(Cipher::aes_128_wrap_pad(), pt, ct, key, None); + } + + #[test] + #[cfg(ossl102)] + fn test_aes192_wrap() { + let pt = "9f6dee187d35302116aecbfd059657efd9f7589c4b5e7f5b"; + let ct = "83b89142dfeeb4871e078bfb81134d33e23fedc19b03a1cf689973d3831b6813"; + let key = "8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b"; + let iv = "0001020304050607"; + + cipher_wrap_test(Cipher::aes_192_wrap(), pt, ct, key, Some(iv)); + } + + #[test] + #[cfg(ossl102)] + fn test_aes192_wrap_default_iv() { + let pt = "9f6dee187d35302116aecbfd059657efd9f7589c4b5e7f5b"; + let ct = "c02c2cf11505d3e4851030d5534cbf5a1d7eca7ba8839adbf239756daf1b43e6"; + let key = "8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b"; + + cipher_wrap_test(Cipher::aes_192_wrap(), pt, ct, key, None); + } + + #[test] + #[cfg(ossl110)] + fn test_aes192_wrap_pad() { + let pt = "00112233445566778899aabbccddee"; + let ct = "b4f6bb167ef7caf061a74da82b36ad038ca057ab51e98d3a"; + let key = "8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b"; + let iv = "00010203"; + + cipher_wrap_test(Cipher::aes_192_wrap_pad(), pt, ct, key, Some(iv)); + } + + #[test] + #[cfg(ossl110)] + fn test_aes192_wrap_pad_default_iv() { + let pt = "00112233445566778899aabbccddee"; + let ct = "b2c37a28cc602753a7c944a4c2555a2df9c98b2eded5312e"; + let key = "8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b"; + + cipher_wrap_test(Cipher::aes_192_wrap_pad(), pt, ct, key, None); + } + + #[test] + #[cfg(ossl102)] + fn test_aes256_wrap() { + let pt = "6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e51"; + let ct = "cc05da2a7f56f7dd0c144231f90bce58648fa20a8278f5a6b7d13bba6aa57a33229d4333866b7fd6"; + let key = "603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4"; + let iv = "0001020304050607"; + + cipher_wrap_test(Cipher::aes_256_wrap(), pt, ct, key, Some(iv)); + } + + #[test] + #[cfg(ossl102)] + fn test_aes256_wrap_default_iv() { + let pt = "6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e51"; + let ct = "0b24f068b50e52bc6987868411c36e1b03900866ed12af81eb87cef70a8d1911731c1d7abf789d88"; + let key = "603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4"; + + cipher_wrap_test(Cipher::aes_256_wrap(), pt, ct, key, None); + } + + #[test] + #[cfg(ossl110)] + fn test_aes256_wrap_pad() { + let pt = "00112233445566778899aabbccddee"; + let ct = "91594e044ccc06130d60e6c84a996aa4f96a9faff8c5f6e7"; + let key = "603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4"; + let iv = "00010203"; + + cipher_wrap_test(Cipher::aes_256_wrap_pad(), pt, ct, key, Some(iv)); + } + + #[test] + #[cfg(ossl110)] + fn test_aes256_wrap_pad_default_iv() { + let pt = "00112233445566778899aabbccddee"; + let ct = "dc3c166a854afd68aea624a4272693554bf2e4fcbae602cd"; + let key = "603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4"; + + cipher_wrap_test(Cipher::aes_256_wrap_pad(), pt, ct, key, None); + } +} diff --git a/vendor/openssl/src/cms.rs b/vendor/openssl/src/cms.rs new file mode 100644 index 0000000..a946230 --- /dev/null +++ b/vendor/openssl/src/cms.rs @@ -0,0 +1,484 @@ +//! SMIME implementation using CMS +//! +//! CMS (PKCS#7) is an encryption standard. It allows signing and encrypting data using +//! X.509 certificates. The OpenSSL implementation of CMS is used in email encryption +//! generated from a `Vec` of bytes. This `Vec` follows the smime protocol standards. +//! Data accepted by this module will be smime type `enveloped-data`. + +use bitflags::bitflags; +use foreign_types::{ForeignType, ForeignTypeRef}; +use libc::c_uint; +use std::ptr; + +use crate::bio::{MemBio, MemBioSlice}; +use crate::error::ErrorStack; +use crate::pkey::{HasPrivate, PKeyRef}; +use crate::stack::StackRef; +use crate::symm::Cipher; +use crate::x509::{store::X509StoreRef, X509Ref, X509}; +use crate::{cvt, cvt_p}; +use openssl_macros::corresponds; + +bitflags! { + #[derive(Copy, Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)] + #[repr(transparent)] + pub struct CMSOptions : c_uint { + const TEXT = ffi::CMS_TEXT; + const CMS_NOCERTS = ffi::CMS_NOCERTS; + const NO_CONTENT_VERIFY = ffi::CMS_NO_CONTENT_VERIFY; + const NO_ATTR_VERIFY = ffi::CMS_NO_ATTR_VERIFY; + const NOSIGS = ffi::CMS_NOSIGS; + const NOINTERN = ffi::CMS_NOINTERN; + const NO_SIGNER_CERT_VERIFY = ffi::CMS_NO_SIGNER_CERT_VERIFY; + const NOVERIFY = ffi::CMS_NOVERIFY; + const DETACHED = ffi::CMS_DETACHED; + const BINARY = ffi::CMS_BINARY; + const NOATTR = ffi::CMS_NOATTR; + const NOSMIMECAP = ffi::CMS_NOSMIMECAP; + const NOOLDMIMETYPE = ffi::CMS_NOOLDMIMETYPE; + const CRLFEOL = ffi::CMS_CRLFEOL; + const STREAM = ffi::CMS_STREAM; + const NOCRL = ffi::CMS_NOCRL; + const PARTIAL = ffi::CMS_PARTIAL; + const REUSE_DIGEST = ffi::CMS_REUSE_DIGEST; + const USE_KEYID = ffi::CMS_USE_KEYID; + const DEBUG_DECRYPT = ffi::CMS_DEBUG_DECRYPT; + #[cfg(all(not(libressl), not(ossl101)))] + const KEY_PARAM = ffi::CMS_KEY_PARAM; + #[cfg(all(not(libressl), not(ossl101), not(ossl102)))] + const ASCIICRLF = ffi::CMS_ASCIICRLF; + } +} + +foreign_type_and_impl_send_sync! { + type CType = ffi::CMS_ContentInfo; + fn drop = ffi::CMS_ContentInfo_free; + + /// High level CMS wrapper + /// + /// CMS supports nesting various types of data, including signatures, certificates, + /// encrypted data, smime messages (encrypted email), and data digest. The ContentInfo + /// content type is the encapsulation of all those content types. [`RFC 5652`] describes + /// CMS and OpenSSL follows this RFC's implementation. + /// + /// [`RFC 5652`]: https://tools.ietf.org/html/rfc5652#page-6 + pub struct CmsContentInfo; + /// Reference to [`CMSContentInfo`] + /// + /// [`CMSContentInfo`]:struct.CmsContentInfo.html + pub struct CmsContentInfoRef; +} + +impl CmsContentInfoRef { + /// Given the sender's private key, `pkey` and the recipient's certificate, `cert`, + /// decrypt the data in `self`. + #[corresponds(CMS_decrypt)] + pub fn decrypt(&self, pkey: &PKeyRef, cert: &X509) -> Result, ErrorStack> + where + T: HasPrivate, + { + unsafe { + let pkey = pkey.as_ptr(); + let cert = cert.as_ptr(); + let out = MemBio::new()?; + + cvt(ffi::CMS_decrypt( + self.as_ptr(), + pkey, + cert, + ptr::null_mut(), + out.as_ptr(), + 0, + ))?; + + Ok(out.get_buf().to_owned()) + } + } + + /// Given the sender's private key, `pkey`, + /// decrypt the data in `self` without validating the recipient certificate. + /// + /// *Warning*: Not checking the recipient certificate may leave you vulnerable to Bleichenbacher's attack on PKCS#1 v1.5 RSA padding. + #[corresponds(CMS_decrypt)] + // FIXME merge into decrypt + pub fn decrypt_without_cert_check(&self, pkey: &PKeyRef) -> Result, ErrorStack> + where + T: HasPrivate, + { + unsafe { + let pkey = pkey.as_ptr(); + let out = MemBio::new()?; + + cvt(ffi::CMS_decrypt( + self.as_ptr(), + pkey, + ptr::null_mut(), + ptr::null_mut(), + out.as_ptr(), + 0, + ))?; + + Ok(out.get_buf().to_owned()) + } + } + + to_der! { + /// Serializes this CmsContentInfo using DER. + #[corresponds(i2d_CMS_ContentInfo)] + to_der, + ffi::i2d_CMS_ContentInfo + } + + to_pem! { + /// Serializes this CmsContentInfo using DER. + #[corresponds(PEM_write_bio_CMS)] + to_pem, + ffi::PEM_write_bio_CMS + } +} + +impl CmsContentInfo { + /// Parses a smime formatted `vec` of bytes into a `CmsContentInfo`. + #[corresponds(SMIME_read_CMS)] + pub fn smime_read_cms(smime: &[u8]) -> Result { + unsafe { + let bio = MemBioSlice::new(smime)?; + + let cms = cvt_p(ffi::SMIME_read_CMS(bio.as_ptr(), ptr::null_mut()))?; + + Ok(CmsContentInfo::from_ptr(cms)) + } + } + + from_der! { + /// Deserializes a DER-encoded ContentInfo structure. + #[corresponds(d2i_CMS_ContentInfo)] + from_der, + CmsContentInfo, + ffi::d2i_CMS_ContentInfo + } + + from_pem! { + /// Deserializes a PEM-encoded ContentInfo structure. + #[corresponds(PEM_read_bio_CMS)] + from_pem, + CmsContentInfo, + ffi::PEM_read_bio_CMS + } + + /// Given a signing cert `signcert`, private key `pkey`, a certificate stack `certs`, + /// data `data` and flags `flags`, create a CmsContentInfo struct. + /// + /// All arguments are optional. + #[corresponds(CMS_sign)] + pub fn sign( + signcert: Option<&X509Ref>, + pkey: Option<&PKeyRef>, + certs: Option<&StackRef>, + data: Option<&[u8]>, + flags: CMSOptions, + ) -> Result + where + T: HasPrivate, + { + unsafe { + let signcert = signcert.map_or(ptr::null_mut(), |p| p.as_ptr()); + let pkey = pkey.map_or(ptr::null_mut(), |p| p.as_ptr()); + let data_bio = match data { + Some(data) => Some(MemBioSlice::new(data)?), + None => None, + }; + let data_bio_ptr = data_bio.as_ref().map_or(ptr::null_mut(), |p| p.as_ptr()); + let certs = certs.map_or(ptr::null_mut(), |p| p.as_ptr()); + + let cms = cvt_p(ffi::CMS_sign( + signcert, + pkey, + certs, + data_bio_ptr, + flags.bits(), + ))?; + + Ok(CmsContentInfo::from_ptr(cms)) + } + } + + /// Given a certificate stack `certs`, data `data`, cipher `cipher` and flags `flags`, + /// create a CmsContentInfo struct. + /// + /// OpenSSL documentation at [`CMS_encrypt`] + /// + /// [`CMS_encrypt`]: https://www.openssl.org/docs/manmaster/man3/CMS_encrypt.html + #[corresponds(CMS_encrypt)] + pub fn encrypt( + certs: &StackRef, + data: &[u8], + cipher: Cipher, + flags: CMSOptions, + ) -> Result { + unsafe { + let data_bio = MemBioSlice::new(data)?; + + let cms = cvt_p(ffi::CMS_encrypt( + certs.as_ptr(), + data_bio.as_ptr(), + cipher.as_ptr(), + flags.bits(), + ))?; + + Ok(CmsContentInfo::from_ptr(cms)) + } + } + + /// Verify this CmsContentInfo's signature, + /// This will search the 'certs' list for the signing certificate. + /// Additional certificates, needed for building the certificate chain, may be + /// given in 'store' as well as additional CRLs. + /// A detached signature may be passed in `detached_data`. The signed content + /// without signature, will be copied into output_data if it is present. + /// + #[corresponds(CMS_verify)] + pub fn verify( + &mut self, + certs: Option<&StackRef>, + store: Option<&X509StoreRef>, + detached_data: Option<&[u8]>, + output_data: Option<&mut Vec>, + flags: CMSOptions, + ) -> Result<(), ErrorStack> { + unsafe { + let certs_ptr = certs.map_or(ptr::null_mut(), |p| p.as_ptr()); + let store_ptr = store.map_or(ptr::null_mut(), |p| p.as_ptr()); + let detached_data_bio = match detached_data { + Some(data) => Some(MemBioSlice::new(data)?), + None => None, + }; + let detached_data_bio_ptr = detached_data_bio + .as_ref() + .map_or(ptr::null_mut(), |p| p.as_ptr()); + let out_bio = MemBio::new()?; + + cvt(ffi::CMS_verify( + self.as_ptr(), + certs_ptr, + store_ptr, + detached_data_bio_ptr, + out_bio.as_ptr(), + flags.bits(), + ))?; + + if let Some(data) = output_data { + data.clear(); + data.extend_from_slice(out_bio.get_buf()); + }; + + Ok(()) + } + } +} + +#[cfg(test)] +mod test { + use super::*; + + use crate::pkcs12::Pkcs12; + use crate::pkey::PKey; + use crate::stack::Stack; + use crate::x509::{ + store::{X509Store, X509StoreBuilder}, + X509, + }; + + #[test] + fn cms_encrypt_decrypt() { + #[cfg(ossl300)] + let _provider = crate::provider::Provider::try_load(None, "legacy", true).unwrap(); + + // load cert with public key only + let pub_cert_bytes = include_bytes!("../test/cms_pubkey.der"); + let pub_cert = X509::from_der(pub_cert_bytes).expect("failed to load pub cert"); + + // load cert with private key + let priv_cert_bytes = include_bytes!("../test/cms.p12"); + let priv_cert = Pkcs12::from_der(priv_cert_bytes).expect("failed to load priv cert"); + let priv_cert = priv_cert + .parse2("mypass") + .expect("failed to parse priv cert"); + + // encrypt cms message using public key cert + let input = String::from("My Message"); + let mut cert_stack = Stack::new().expect("failed to create stack"); + cert_stack + .push(pub_cert) + .expect("failed to add pub cert to stack"); + + let encrypt = CmsContentInfo::encrypt( + &cert_stack, + input.as_bytes(), + Cipher::des_ede3_cbc(), + CMSOptions::empty(), + ) + .expect("failed create encrypted cms"); + + // decrypt cms message using private key cert (DER) + { + let encrypted_der = encrypt.to_der().expect("failed to create der from cms"); + let decrypt = + CmsContentInfo::from_der(&encrypted_der).expect("failed read cms from der"); + + let decrypt_with_cert_check = decrypt + .decrypt( + priv_cert.pkey.as_ref().unwrap(), + priv_cert.cert.as_ref().unwrap(), + ) + .expect("failed to decrypt cms"); + let decrypt_with_cert_check = String::from_utf8(decrypt_with_cert_check) + .expect("failed to create string from cms content"); + + let decrypt_without_cert_check = decrypt + .decrypt_without_cert_check(priv_cert.pkey.as_ref().unwrap()) + .expect("failed to decrypt cms"); + let decrypt_without_cert_check = String::from_utf8(decrypt_without_cert_check) + .expect("failed to create string from cms content"); + + assert_eq!(input, decrypt_with_cert_check); + assert_eq!(input, decrypt_without_cert_check); + } + + // decrypt cms message using private key cert (PEM) + { + let encrypted_pem = encrypt.to_pem().expect("failed to create pem from cms"); + let decrypt = + CmsContentInfo::from_pem(&encrypted_pem).expect("failed read cms from pem"); + + let decrypt_with_cert_check = decrypt + .decrypt( + priv_cert.pkey.as_ref().unwrap(), + priv_cert.cert.as_ref().unwrap(), + ) + .expect("failed to decrypt cms"); + let decrypt_with_cert_check = String::from_utf8(decrypt_with_cert_check) + .expect("failed to create string from cms content"); + + let decrypt_without_cert_check = decrypt + .decrypt_without_cert_check(priv_cert.pkey.as_ref().unwrap()) + .expect("failed to decrypt cms"); + let decrypt_without_cert_check = String::from_utf8(decrypt_without_cert_check) + .expect("failed to create string from cms content"); + + assert_eq!(input, decrypt_with_cert_check); + assert_eq!(input, decrypt_without_cert_check); + } + } + + fn cms_sign_verify_generic_helper(is_detached: bool) { + // load cert with private key + let cert_bytes = include_bytes!("../test/cert.pem"); + let cert = X509::from_pem(cert_bytes).expect("failed to load cert.pem"); + + let key_bytes = include_bytes!("../test/key.pem"); + let key = PKey::private_key_from_pem(key_bytes).expect("failed to load key.pem"); + + let root_bytes = include_bytes!("../test/root-ca.pem"); + let root = X509::from_pem(root_bytes).expect("failed to load root-ca.pem"); + + // sign cms message using public key cert + let data = b"Hello world!"; + + let (opt, ext_data): (CMSOptions, Option<&[u8]>) = if is_detached { + (CMSOptions::DETACHED | CMSOptions::BINARY, Some(data)) + } else { + (CMSOptions::empty(), None) + }; + + let mut cms = CmsContentInfo::sign(Some(&cert), Some(&key), None, Some(data), opt) + .expect("failed to CMS sign a message"); + + // check CMS signature length + let pem_cms = cms + .to_pem() + .expect("failed to pack CmsContentInfo into PEM"); + assert!(!pem_cms.is_empty()); + + // verify CMS signature + let mut builder = X509StoreBuilder::new().expect("failed to create X509StoreBuilder"); + builder + .add_cert(root) + .expect("failed to add root-ca into X509StoreBuilder"); + let store: X509Store = builder.build(); + let mut out_data: Vec = Vec::new(); + let res = cms.verify( + None, + Some(&store), + ext_data, + Some(&mut out_data), + CMSOptions::empty(), + ); + + // check verification result - valid signature + res.unwrap(); + assert_eq!(data.to_vec(), out_data); + } + + #[test] + fn cms_sign_verify_ok() { + cms_sign_verify_generic_helper(false); + } + + #[test] + fn cms_sign_verify_detached_ok() { + cms_sign_verify_generic_helper(true); + } + + #[test] + fn cms_sign_verify_error() { + #[cfg(ossl300)] + let _provider = crate::provider::Provider::try_load(None, "legacy", true).unwrap(); + + // load cert with private key + let priv_cert_bytes = include_bytes!("../test/cms.p12"); + let priv_cert = Pkcs12::from_der(priv_cert_bytes).expect("failed to load priv cert"); + let priv_cert = priv_cert + .parse2("mypass") + .expect("failed to parse priv cert"); + + // sign cms message using public key cert + let data = b"Hello world!"; + let mut cms = CmsContentInfo::sign( + Some(&priv_cert.cert.unwrap()), + Some(&priv_cert.pkey.unwrap()), + None, + Some(data), + CMSOptions::empty(), + ) + .expect("failed to CMS sign a message"); + + // check CMS signature length + let pem_cms = cms + .to_pem() + .expect("failed to pack CmsContentInfo into PEM"); + assert!(!pem_cms.is_empty()); + + let empty_store = X509StoreBuilder::new() + .expect("failed to create X509StoreBuilder") + .build(); + + // verify CMS signature + let res = cms.verify( + None, + Some(&empty_store), + Some(data), + None, + CMSOptions::empty(), + ); + + // check verification result - this is an invalid signature + // defined in openssl crypto/cms/cms.h + const CMS_R_CERTIFICATE_VERIFY_ERROR: i32 = 100; + let es = res.unwrap_err(); + let error_array = es.errors(); + assert_eq!(1, error_array.len()); + let code = error_array[0].reason_code(); + assert_eq!(code, CMS_R_CERTIFICATE_VERIFY_ERROR); + } +} diff --git a/vendor/openssl/src/conf.rs b/vendor/openssl/src/conf.rs new file mode 100644 index 0000000..8874029 --- /dev/null +++ b/vendor/openssl/src/conf.rs @@ -0,0 +1,65 @@ +//! Interface for processing OpenSSL configuration files. + +foreign_type_and_impl_send_sync! { + type CType = ffi::CONF; + fn drop = ffi::NCONF_free; + + pub struct Conf; + pub struct ConfRef; +} + +#[cfg(not(any(boringssl, libressl400)))] +mod methods { + use super::Conf; + use crate::cvt_p; + use crate::error::ErrorStack; + use openssl_macros::corresponds; + + pub struct ConfMethod(*mut ffi::CONF_METHOD); + + impl ConfMethod { + /// Retrieve handle to the default OpenSSL configuration file processing function. + #[corresponds(NCONF_default)] + #[allow(clippy::should_implement_trait)] + pub fn default() -> ConfMethod { + unsafe { + ffi::init(); + // `NCONF` stands for "New Conf", as described in crypto/conf/conf_lib.c. This is + // a newer API than the "CONF classic" functions. + ConfMethod(ffi::NCONF_default()) + } + } + + /// Construct from raw pointer. + /// + /// # Safety + /// + /// The caller must ensure that the pointer is valid. + pub unsafe fn from_ptr(ptr: *mut ffi::CONF_METHOD) -> ConfMethod { + ConfMethod(ptr) + } + + /// Convert to raw pointer. + pub fn as_ptr(&self) -> *mut ffi::CONF_METHOD { + self.0 + } + } + + impl Conf { + /// Create a configuration parser. + /// + /// # Examples + /// + /// ``` + /// use openssl::conf::{Conf, ConfMethod}; + /// + /// let conf = Conf::new(ConfMethod::default()); + /// ``` + #[corresponds(NCONF_new)] + pub fn new(method: ConfMethod) -> Result { + unsafe { cvt_p(ffi::NCONF_new(method.as_ptr())).map(Conf) } + } + } +} +#[cfg(not(any(boringssl, libressl400)))] +pub use methods::*; diff --git a/vendor/openssl/src/derive.rs b/vendor/openssl/src/derive.rs new file mode 100644 index 0000000..90a5650 --- /dev/null +++ b/vendor/openssl/src/derive.rs @@ -0,0 +1,217 @@ +//! Shared secret derivation. +//! +//! # Example +//! +//! The following example implements [ECDH] using `NIST P-384` keys: +//! +//! ``` +//! # fn main() -> Result<(), Box> { +//! # use std::convert::TryInto; +//! use openssl::bn::BigNumContext; +//! use openssl::pkey::PKey; +//! use openssl::derive::Deriver; +//! use openssl::ec::{EcGroup, EcKey, EcPoint, PointConversionForm}; +//! use openssl::nid::Nid; +//! +//! let group = EcGroup::from_curve_name(Nid::SECP384R1)?; +//! +//! let first: PKey<_> = EcKey::generate(&group)?.try_into()?; +//! +//! // second party generates an ephemeral key and derives +//! // a shared secret using first party's public key +//! let shared_key = EcKey::generate(&group)?; +//! // shared_public is sent to first party +//! let mut ctx = BigNumContext::new()?; +//! let shared_public = shared_key.public_key().to_bytes( +//! &group, +//! PointConversionForm::COMPRESSED, +//! &mut ctx, +//! )?; +//! +//! let shared_key: PKey<_> = shared_key.try_into()?; +//! let mut deriver = Deriver::new(&shared_key)?; +//! deriver.set_peer(&first)?; +//! // secret can be used e.g. as a symmetric encryption key +//! let secret = deriver.derive_to_vec()?; +//! # drop(deriver); +//! +//! // first party derives the same shared secret using +//! // shared_public +//! let point = EcPoint::from_bytes(&group, &shared_public, &mut ctx)?; +//! let recipient_key: PKey<_> = EcKey::from_public_key(&group, &point)?.try_into()?; +//! let mut deriver = Deriver::new(&first)?; +//! deriver.set_peer(&recipient_key)?; +//! let first_secret = deriver.derive_to_vec()?; +//! +//! assert_eq!(secret, first_secret); +//! # Ok(()) } +//! ``` +//! +//! [ECDH]: https://wiki.openssl.org/index.php/Elliptic_Curve_Diffie_Hellman + +use foreign_types::ForeignTypeRef; +use std::marker::PhantomData; +use std::ptr; + +use crate::error::ErrorStack; +use crate::pkey::{HasPrivate, HasPublic, PKeyRef}; +use crate::{cvt, cvt_p}; +use openssl_macros::corresponds; + +/// A type used to derive a shared secret between two keys. +pub struct Deriver<'a>(*mut ffi::EVP_PKEY_CTX, PhantomData<&'a ()>); + +unsafe impl Sync for Deriver<'_> {} +unsafe impl Send for Deriver<'_> {} + +#[allow(clippy::len_without_is_empty)] +impl<'a> Deriver<'a> { + /// Creates a new `Deriver` using the provided private key. + /// + /// This corresponds to [`EVP_PKEY_derive_init`]. + /// + /// [`EVP_PKEY_derive_init`]: https://www.openssl.org/docs/manmaster/crypto/EVP_PKEY_derive_init.html + pub fn new(key: &'a PKeyRef) -> Result, ErrorStack> + where + T: HasPrivate, + { + unsafe { + cvt_p(ffi::EVP_PKEY_CTX_new(key.as_ptr(), ptr::null_mut())) + .map(|p| Deriver(p, PhantomData)) + .and_then(|ctx| cvt(ffi::EVP_PKEY_derive_init(ctx.0)).map(|_| ctx)) + } + } + + /// Sets the peer key used for secret derivation. + #[corresponds(EVP_PKEY_derive_set_peer)] + pub fn set_peer(&mut self, key: &'a PKeyRef) -> Result<(), ErrorStack> + where + T: HasPublic, + { + unsafe { cvt(ffi::EVP_PKEY_derive_set_peer(self.0, key.as_ptr())).map(|_| ()) } + } + + /// Sets the peer key used for secret derivation along with optionally validating the peer public key. + /// + /// Requires OpenSSL 3.0.0 or newer. + #[corresponds(EVP_PKEY_derive_set_peer_ex)] + #[cfg(ossl300)] + pub fn set_peer_ex( + &mut self, + key: &'a PKeyRef, + validate_peer: bool, + ) -> Result<(), ErrorStack> + where + T: HasPublic, + { + unsafe { + cvt(ffi::EVP_PKEY_derive_set_peer_ex( + self.0, + key.as_ptr(), + validate_peer as i32, + )) + .map(|_| ()) + } + } + + /// Returns the size of the shared secret. + /// + /// It can be used to size the buffer passed to [`Deriver::derive`]. + /// + /// This corresponds to [`EVP_PKEY_derive`]. + /// + /// [`Deriver::derive`]: #method.derive + /// [`EVP_PKEY_derive`]: https://www.openssl.org/docs/manmaster/crypto/EVP_PKEY_derive_init.html + pub fn len(&mut self) -> Result { + unsafe { + let mut len = 0; + cvt(ffi::EVP_PKEY_derive(self.0, ptr::null_mut(), &mut len)).map(|_| len) + } + } + + /// Derives a shared secret between the two keys, writing it into the buffer. + /// + /// Returns the number of bytes written. + /// + /// This corresponds to [`EVP_PKEY_derive`]. + /// + /// [`EVP_PKEY_derive`]: https://www.openssl.org/docs/manmaster/crypto/EVP_PKEY_derive_init.html + pub fn derive(&mut self, buf: &mut [u8]) -> Result { + let mut len = buf.len(); + unsafe { + cvt(ffi::EVP_PKEY_derive( + self.0, + buf.as_mut_ptr() as *mut _, + &mut len, + )) + .map(|_| len) + } + } + + /// A convenience function which derives a shared secret and returns it in a new buffer. + /// + /// This simply wraps [`Deriver::len`] and [`Deriver::derive`]. + /// + /// [`Deriver::len`]: #method.len + /// [`Deriver::derive`]: #method.derive + pub fn derive_to_vec(&mut self) -> Result, ErrorStack> { + let len = self.len()?; + let mut buf = vec![0; len]; + let len = self.derive(&mut buf)?; + buf.truncate(len); + Ok(buf) + } +} + +impl Drop for Deriver<'_> { + fn drop(&mut self) { + unsafe { + ffi::EVP_PKEY_CTX_free(self.0); + } + } +} + +#[cfg(test)] +mod test { + use super::*; + + use crate::ec::{EcGroup, EcKey}; + use crate::nid::Nid; + use crate::pkey::PKey; + + #[test] + fn derive_without_peer() { + let group = EcGroup::from_curve_name(Nid::X9_62_PRIME256V1).unwrap(); + let ec_key = EcKey::generate(&group).unwrap(); + let pkey = PKey::from_ec_key(ec_key).unwrap(); + let mut deriver = Deriver::new(&pkey).unwrap(); + deriver.derive_to_vec().unwrap_err(); + } + + #[test] + fn test_ec_key_derive() { + let group = EcGroup::from_curve_name(Nid::X9_62_PRIME256V1).unwrap(); + let ec_key = EcKey::generate(&group).unwrap(); + let ec_key2 = EcKey::generate(&group).unwrap(); + let pkey = PKey::from_ec_key(ec_key).unwrap(); + let pkey2 = PKey::from_ec_key(ec_key2).unwrap(); + let mut deriver = Deriver::new(&pkey).unwrap(); + deriver.set_peer(&pkey2).unwrap(); + let shared = deriver.derive_to_vec().unwrap(); + assert!(!shared.is_empty()); + } + + #[test] + #[cfg(ossl300)] + fn test_ec_key_derive_ex() { + let group = EcGroup::from_curve_name(Nid::X9_62_PRIME256V1).unwrap(); + let ec_key = EcKey::generate(&group).unwrap(); + let ec_key2 = EcKey::generate(&group).unwrap(); + let pkey = PKey::from_ec_key(ec_key).unwrap(); + let pkey2 = PKey::from_ec_key(ec_key2).unwrap(); + let mut deriver = Deriver::new(&pkey).unwrap(); + deriver.set_peer_ex(&pkey2, true).unwrap(); + let shared = deriver.derive_to_vec().unwrap(); + assert!(!shared.is_empty()); + } +} diff --git a/vendor/openssl/src/dh.rs b/vendor/openssl/src/dh.rs new file mode 100644 index 0000000..c8d135f --- /dev/null +++ b/vendor/openssl/src/dh.rs @@ -0,0 +1,499 @@ +//! Diffie-Hellman key agreement. + +use cfg_if::cfg_if; +use foreign_types::{ForeignType, ForeignTypeRef}; +use std::mem; +use std::ptr; + +use crate::bn::{BigNum, BigNumRef}; +use crate::error::ErrorStack; +use crate::pkey::{HasParams, HasPrivate, HasPublic, Params, Private, Public}; +use crate::{cvt, cvt_p}; +use openssl_macros::corresponds; + +generic_foreign_type_and_impl_send_sync! { + type CType = ffi::DH; + fn drop = ffi::DH_free; + + pub struct Dh; + + pub struct DhRef; +} + +impl DhRef +where + T: HasParams, +{ + to_pem! { + /// Serializes the parameters into a PEM-encoded PKCS#3 DHparameter structure. + /// + /// The output will have a header of `-----BEGIN DH PARAMETERS-----`. + #[corresponds(PEM_write_bio_DHparams)] + params_to_pem, + ffi::PEM_write_bio_DHparams + } + + to_der! { + /// Serializes the parameters into a DER-encoded PKCS#3 DHparameter structure. + #[corresponds(i2d_DHparams)] + params_to_der, + ffi::i2d_DHparams + } + + /// Validates DH parameters for correctness + #[corresponds(DH_check_key)] + pub fn check_key(&self) -> Result { + unsafe { + let mut codes = 0; + cvt(ffi::DH_check(self.as_ptr(), &mut codes))?; + Ok(codes == 0) + } + } +} + +impl Dh { + pub fn from_params(p: BigNum, g: BigNum, q: BigNum) -> Result, ErrorStack> { + Self::from_pqg(p, Some(q), g) + } + + /// Creates a DH instance based upon the given primes and generator params. + #[corresponds(DH_set0_pqg)] + pub fn from_pqg( + prime_p: BigNum, + prime_q: Option, + generator: BigNum, + ) -> Result, ErrorStack> { + unsafe { + let dh = Dh::from_ptr(cvt_p(ffi::DH_new())?); + cvt(DH_set0_pqg( + dh.0, + prime_p.as_ptr(), + prime_q.as_ref().map_or(ptr::null_mut(), |q| q.as_ptr()), + generator.as_ptr(), + ))?; + mem::forget((prime_p, prime_q, generator)); + Ok(dh) + } + } + + /// Sets the public key on the DH object. + pub fn set_public_key(self, pub_key: BigNum) -> Result, ErrorStack> { + unsafe { + let dh_ptr = self.0; + cvt(DH_set0_key(dh_ptr, pub_key.as_ptr(), ptr::null_mut()))?; + mem::forget((self, pub_key)); + Ok(Dh::from_ptr(dh_ptr)) + } + } + + /// Sets the private key on the DH object and recomputes the public key. + pub fn set_private_key(self, priv_key: BigNum) -> Result, ErrorStack> { + unsafe { + let dh_ptr = self.0; + cvt(DH_set0_key(dh_ptr, ptr::null_mut(), priv_key.as_ptr()))?; + mem::forget(priv_key); + + cvt(ffi::DH_generate_key(dh_ptr))?; + mem::forget(self); + Ok(Dh::from_ptr(dh_ptr)) + } + } + + /// Sets the public and private keys on the DH object. + pub fn set_key(self, pub_key: BigNum, priv_key: BigNum) -> Result, ErrorStack> { + unsafe { + let dh_ptr = self.0; + cvt(DH_set0_key(dh_ptr, pub_key.as_ptr(), priv_key.as_ptr()))?; + mem::forget((self, pub_key, priv_key)); + Ok(Dh::from_ptr(dh_ptr)) + } + } + + /// Generates DH params based on the given `prime_len` and a fixed `generator` value. + #[corresponds(DH_generate_parameters_ex)] + pub fn generate_params(prime_len: u32, generator: u32) -> Result, ErrorStack> { + unsafe { + let dh = Dh::from_ptr(cvt_p(ffi::DH_new())?); + cvt(ffi::DH_generate_parameters_ex( + dh.0, + prime_len as i32, + generator as i32, + ptr::null_mut(), + ))?; + Ok(dh) + } + } + + /// Generates a public and a private key based on the DH params. + #[corresponds(DH_generate_key)] + pub fn generate_key(self) -> Result, ErrorStack> { + unsafe { + let dh_ptr = self.0; + cvt(ffi::DH_generate_key(dh_ptr))?; + mem::forget(self); + Ok(Dh::from_ptr(dh_ptr)) + } + } + + from_pem! { + /// Deserializes a PEM-encoded PKCS#3 DHpararameters structure. + /// + /// The input should have a header of `-----BEGIN DH PARAMETERS-----`. + #[corresponds(PEM_read_bio_DHparams)] + params_from_pem, + Dh, + ffi::PEM_read_bio_DHparams + } + + from_der! { + /// Deserializes a DER-encoded PKCS#3 DHparameters structure. + #[corresponds(d2i_DHparams)] + params_from_der, + Dh, + ffi::d2i_DHparams + } + + /// Requires OpenSSL 1.0.2 or newer. + #[corresponds(DH_get_1024_160)] + #[cfg(any(ossl102, ossl110))] + pub fn get_1024_160() -> Result, ErrorStack> { + unsafe { + ffi::init(); + cvt_p(ffi::DH_get_1024_160()).map(|p| Dh::from_ptr(p)) + } + } + + /// Requires OpenSSL 1.0.2 or newer. + #[corresponds(DH_get_2048_224)] + #[cfg(any(ossl102, ossl110))] + pub fn get_2048_224() -> Result, ErrorStack> { + unsafe { + ffi::init(); + cvt_p(ffi::DH_get_2048_224()).map(|p| Dh::from_ptr(p)) + } + } + + /// Requires OpenSSL 1.0.2 or newer. + #[corresponds(DH_get_2048_256)] + #[cfg(any(ossl102, ossl110))] + pub fn get_2048_256() -> Result, ErrorStack> { + unsafe { + ffi::init(); + cvt_p(ffi::DH_get_2048_256()).map(|p| Dh::from_ptr(p)) + } + } +} + +impl Dh +where + T: HasParams, +{ + /// Returns the prime `p` from the DH instance. + #[corresponds(DH_get0_pqg)] + pub fn prime_p(&self) -> &BigNumRef { + let mut p = ptr::null(); + unsafe { + DH_get0_pqg(self.as_ptr(), &mut p, ptr::null_mut(), ptr::null_mut()); + BigNumRef::from_ptr(p as *mut _) + } + } + + /// Returns the prime `q` from the DH instance. + #[corresponds(DH_get0_pqg)] + pub fn prime_q(&self) -> Option<&BigNumRef> { + let mut q = ptr::null(); + unsafe { + DH_get0_pqg(self.as_ptr(), ptr::null_mut(), &mut q, ptr::null_mut()); + if q.is_null() { + None + } else { + Some(BigNumRef::from_ptr(q as *mut _)) + } + } + } + + /// Returns the generator from the DH instance. + #[corresponds(DH_get0_pqg)] + pub fn generator(&self) -> &BigNumRef { + let mut g = ptr::null(); + unsafe { + DH_get0_pqg(self.as_ptr(), ptr::null_mut(), ptr::null_mut(), &mut g); + BigNumRef::from_ptr(g as *mut _) + } + } +} + +impl DhRef +where + T: HasPublic, +{ + /// Returns the public key from the DH instance. + #[corresponds(DH_get0_key)] + pub fn public_key(&self) -> &BigNumRef { + let mut pub_key = ptr::null(); + unsafe { + DH_get0_key(self.as_ptr(), &mut pub_key, ptr::null_mut()); + BigNumRef::from_ptr(pub_key as *mut _) + } + } +} + +impl DhRef +where + T: HasPrivate, +{ + /// Computes a shared secret from the own private key and the given `public_key`. + #[corresponds(DH_compute_key)] + pub fn compute_key(&self, public_key: &BigNumRef) -> Result, ErrorStack> { + unsafe { + let key_len = ffi::DH_size(self.as_ptr()); + let mut key = vec![0u8; key_len as usize]; + cvt(ffi::DH_compute_key( + key.as_mut_ptr(), + public_key.as_ptr(), + self.as_ptr(), + ))?; + Ok(key) + } + } + + /// Returns the private key from the DH instance. + #[corresponds(DH_get0_key)] + pub fn private_key(&self) -> &BigNumRef { + let mut priv_key = ptr::null(); + unsafe { + DH_get0_key(self.as_ptr(), ptr::null_mut(), &mut priv_key); + BigNumRef::from_ptr(priv_key as *mut _) + } + } +} + +cfg_if! { + if #[cfg(any(ossl110, libressl270, boringssl))] { + use ffi::{DH_set0_pqg, DH_get0_pqg, DH_get0_key, DH_set0_key}; + } else { + #[allow(bad_style)] + unsafe fn DH_set0_pqg( + dh: *mut ffi::DH, + p: *mut ffi::BIGNUM, + q: *mut ffi::BIGNUM, + g: *mut ffi::BIGNUM, + ) -> ::libc::c_int { + (*dh).p = p; + (*dh).q = q; + (*dh).g = g; + 1 + } + + #[allow(bad_style)] + unsafe fn DH_get0_pqg( + dh: *mut ffi::DH, + p: *mut *const ffi::BIGNUM, + q: *mut *const ffi::BIGNUM, + g: *mut *const ffi::BIGNUM, + ) { + if !p.is_null() { + *p = (*dh).p; + } + if !q.is_null() { + *q = (*dh).q; + } + if !g.is_null() { + *g = (*dh).g; + } + } + + #[allow(bad_style)] + unsafe fn DH_set0_key( + dh: *mut ffi::DH, + pub_key: *mut ffi::BIGNUM, + priv_key: *mut ffi::BIGNUM, + ) -> ::libc::c_int { + (*dh).pub_key = pub_key; + (*dh).priv_key = priv_key; + 1 + } + + #[allow(bad_style)] + unsafe fn DH_get0_key( + dh: *mut ffi::DH, + pub_key: *mut *const ffi::BIGNUM, + priv_key: *mut *const ffi::BIGNUM, + ) { + if !pub_key.is_null() { + *pub_key = (*dh).pub_key; + } + if !priv_key.is_null() { + *priv_key = (*dh).priv_key; + } + } + } +} + +#[cfg(test)] +mod tests { + use crate::bn::BigNum; + use crate::dh::Dh; + #[cfg(all(not(boringssl), ossl110))] + use crate::pkey::PKey; + use crate::ssl::{SslContext, SslMethod}; + + #[test] + #[cfg(ossl102)] + fn test_dh_rfc5114() { + let mut ctx = SslContext::builder(SslMethod::tls()).unwrap(); + let dh2 = Dh::get_2048_224().unwrap(); + ctx.set_tmp_dh(&dh2).unwrap(); + let dh3 = Dh::get_2048_256().unwrap(); + ctx.set_tmp_dh(&dh3).unwrap(); + } + + #[test] + fn test_dh_params() { + let mut ctx = SslContext::builder(SslMethod::tls()).unwrap(); + let prime_p = BigNum::from_hex_str( + "87A8E61DB4B6663CFFBBD19C651959998CEEF608660DD0F25D2CEED4435E3B00E00DF8F1D61957D4FAF7DF\ + 4561B2AA3016C3D91134096FAA3BF4296D830E9A7C209E0C6497517ABD5A8A9D306BCF67ED91F9E6725B47\ + 58C022E0B1EF4275BF7B6C5BFC11D45F9088B941F54EB1E59BB8BC39A0BF12307F5C4FDB70C581B23F76B6\ + 3ACAE1CAA6B7902D52526735488A0EF13C6D9A51BFA4AB3AD8347796524D8EF6A167B5A41825D967E144E5\ + 140564251CCACB83E6B486F6B3CA3F7971506026C0B857F689962856DED4010ABD0BE621C3A3960A54E710\ + C375F26375D7014103A4B54330C198AF126116D2276E11715F693877FAD7EF09CADB094AE91E1A1597", + ).unwrap(); + let prime_q = BigNum::from_hex_str( + "3FB32C9B73134D0B2E77506660EDBD484CA7B18F21EF205407F4793A1A0BA12510DBC15077BE463FFF4FED\ + 4AAC0BB555BE3A6C1B0C6B47B1BC3773BF7E8C6F62901228F8C28CBB18A55AE31341000A650196F931C77A\ + 57F2DDF463E5E9EC144B777DE62AAAB8A8628AC376D282D6ED3864E67982428EBC831D14348F6F2F9193B5\ + 045AF2767164E1DFC967C1FB3F2E55A4BD1BFFE83B9C80D052B985D182EA0ADB2A3B7313D3FE14C8484B1E\ + 052588B9B7D2BBD2DF016199ECD06E1557CD0915B3353BBB64E0EC377FD028370DF92B52C7891428CDC67E\ + B6184B523D1DB246C32F63078490F00EF8D647D148D47954515E2327CFEF98C582664B4C0F6CC41659", + ).unwrap(); + let generator = BigNum::from_hex_str( + "8CF83642A709A097B447997640129DA299B1A47D1EB3750BA308B0FE64F5FBD3", + ) + .unwrap(); + let dh = Dh::from_params( + prime_p.to_owned().unwrap(), + generator.to_owned().unwrap(), + prime_q.to_owned().unwrap(), + ) + .unwrap(); + ctx.set_tmp_dh(&dh).unwrap(); + + assert_eq!(dh.prime_p(), &prime_p); + assert_eq!(dh.prime_q().unwrap(), &prime_q); + assert_eq!(dh.generator(), &generator); + } + + #[test] + #[cfg(all(not(boringssl), ossl110))] + fn test_from_dhx_serializes_q() { + let p = BigNum::from_hex_str("00ad107e1e9123a9d0d660faa79559c51fa20d64e5683b9fd1b54b1597b61d0a75e6fa141df95a56dbaf9a3c407ba1df15eb3d688a309c180e1de6b85a1274a0a66d3f8152ad6ac2129037c9edefda4df8d91e8fef55b7394b7ad5b7d0b6c12207c9f98d11ed34dbf6c6ba0b2c8bbc27be6a00e0a0b9c49708b3bf8a317091883681286130bc8985db1602e714415d9330278273c7de31efdc7310f7121fd5a07415987d9adc0a486dcdf93acc44328387315d75e198c641a480cd86a1b9e587e8be60e69cc928b2b9c52172e413042e9b23f10b0e16e79763c9b53dcf4ba80a29e3fb73c16b8e75b97ef363e2ffa31f71cf9de5384e71b81c0ac4dffe0c10e64f").unwrap(); + let g = BigNum::from_hex_str("00ac4032ef4f2d9ae39df30b5c8ffdac506cdebe7b89998caf74866a08cfe4ffe3a6824a4e10b9a6f0dd921f01a70c4afaab739d7700c29f52c57db17c620a8652be5e9001a8d66ad7c17669101999024af4d027275ac1348bb8a762d0521bc98ae247150422ea1ed409939d54da7460cdb5f6c6b250717cbef180eb34118e98d119529a45d6f834566e3025e316a330efbb77a86f0c1ab15b051ae3d428c8f8acb70a8137150b8eeb10e183edd19963ddd9e263e4770589ef6aa21e7f5f2ff381b539cce3409d13cd566afbb48d6c019181e1bcfe94b30269edfe72fe9b6aa4bd7b5a0f1c71cfff4c19c418e1f6ec017981bc087f2a7065b384b890d3191f2bfa").unwrap(); + let q = BigNum::from_hex_str("00801c0d34c58d93fe997177101f80535a4738cebcbf389a99b36371eb") + .unwrap(); + let y = BigNum::from_hex_str("0082c165bb576243ecf46d58c3d1501616955fca0320fa95ea11d2e6c1b9cf217676720dc1c08c85bf20c4d232b60a29a1e51c7b773bc645014587c525c86151b30d75486ec7b6c98efb5f74955b83116d01d0af1232af89213c2de574369d701aba9357300b920d3d8b98252d46c46952c16a5f33554b38317809c7b9add4701f5c158c1b7035e9fe39366ececb90d2896b78c523c4a577287ef5ba7a2663ed58aa20b5ec66e30f316610dfaa38583e495ab6af771c284387e660edbef4edb872e2e80e1d244ee95622e76d028e61c1e887c2aa792717362139f4dd26eafd49b2366eeb2350b01fe1b56022a2809e379559c37b375ba01c4eaacc14fd1b247837").unwrap(); + + let dh = Dh::from_params(p, g, q).unwrap(); + let dh = dh.set_public_key(y).unwrap(); + + // Verify that 'q' is serialized in the public key. + let pkey = PKey::from_dhx(dh).unwrap(); + assert_eq!(pkey.public_key_to_der().unwrap(), b"\x30\x82\x03\x44\x30\x82\x02\x36\x06\x07\x2a\x86\x48\xce\x3e\x02\x01\x30\x82\x02\x29\x02\x82\x01\x01\x00\xad\x10\x7e\x1e\x91\x23\xa9\xd0\xd6\x60\xfa\xa7\x95\x59\xc5\x1f\xa2\x0d\x64\xe5\x68\x3b\x9f\xd1\xb5\x4b\x15\x97\xb6\x1d\x0a\x75\xe6\xfa\x14\x1d\xf9\x5a\x56\xdb\xaf\x9a\x3c\x40\x7b\xa1\xdf\x15\xeb\x3d\x68\x8a\x30\x9c\x18\x0e\x1d\xe6\xb8\x5a\x12\x74\xa0\xa6\x6d\x3f\x81\x52\xad\x6a\xc2\x12\x90\x37\xc9\xed\xef\xda\x4d\xf8\xd9\x1e\x8f\xef\x55\xb7\x39\x4b\x7a\xd5\xb7\xd0\xb6\xc1\x22\x07\xc9\xf9\x8d\x11\xed\x34\xdb\xf6\xc6\xba\x0b\x2c\x8b\xbc\x27\xbe\x6a\x00\xe0\xa0\xb9\xc4\x97\x08\xb3\xbf\x8a\x31\x70\x91\x88\x36\x81\x28\x61\x30\xbc\x89\x85\xdb\x16\x02\xe7\x14\x41\x5d\x93\x30\x27\x82\x73\xc7\xde\x31\xef\xdc\x73\x10\xf7\x12\x1f\xd5\xa0\x74\x15\x98\x7d\x9a\xdc\x0a\x48\x6d\xcd\xf9\x3a\xcc\x44\x32\x83\x87\x31\x5d\x75\xe1\x98\xc6\x41\xa4\x80\xcd\x86\xa1\xb9\xe5\x87\xe8\xbe\x60\xe6\x9c\xc9\x28\xb2\xb9\xc5\x21\x72\xe4\x13\x04\x2e\x9b\x23\xf1\x0b\x0e\x16\xe7\x97\x63\xc9\xb5\x3d\xcf\x4b\xa8\x0a\x29\xe3\xfb\x73\xc1\x6b\x8e\x75\xb9\x7e\xf3\x63\xe2\xff\xa3\x1f\x71\xcf\x9d\xe5\x38\x4e\x71\xb8\x1c\x0a\xc4\xdf\xfe\x0c\x10\xe6\x4f\x02\x82\x01\x01\x00\xac\x40\x32\xef\x4f\x2d\x9a\xe3\x9d\xf3\x0b\x5c\x8f\xfd\xac\x50\x6c\xde\xbe\x7b\x89\x99\x8c\xaf\x74\x86\x6a\x08\xcf\xe4\xff\xe3\xa6\x82\x4a\x4e\x10\xb9\xa6\xf0\xdd\x92\x1f\x01\xa7\x0c\x4a\xfa\xab\x73\x9d\x77\x00\xc2\x9f\x52\xc5\x7d\xb1\x7c\x62\x0a\x86\x52\xbe\x5e\x90\x01\xa8\xd6\x6a\xd7\xc1\x76\x69\x10\x19\x99\x02\x4a\xf4\xd0\x27\x27\x5a\xc1\x34\x8b\xb8\xa7\x62\xd0\x52\x1b\xc9\x8a\xe2\x47\x15\x04\x22\xea\x1e\xd4\x09\x93\x9d\x54\xda\x74\x60\xcd\xb5\xf6\xc6\xb2\x50\x71\x7c\xbe\xf1\x80\xeb\x34\x11\x8e\x98\xd1\x19\x52\x9a\x45\xd6\xf8\x34\x56\x6e\x30\x25\xe3\x16\xa3\x30\xef\xbb\x77\xa8\x6f\x0c\x1a\xb1\x5b\x05\x1a\xe3\xd4\x28\xc8\xf8\xac\xb7\x0a\x81\x37\x15\x0b\x8e\xeb\x10\xe1\x83\xed\xd1\x99\x63\xdd\xd9\xe2\x63\xe4\x77\x05\x89\xef\x6a\xa2\x1e\x7f\x5f\x2f\xf3\x81\xb5\x39\xcc\xe3\x40\x9d\x13\xcd\x56\x6a\xfb\xb4\x8d\x6c\x01\x91\x81\xe1\xbc\xfe\x94\xb3\x02\x69\xed\xfe\x72\xfe\x9b\x6a\xa4\xbd\x7b\x5a\x0f\x1c\x71\xcf\xff\x4c\x19\xc4\x18\xe1\xf6\xec\x01\x79\x81\xbc\x08\x7f\x2a\x70\x65\xb3\x84\xb8\x90\xd3\x19\x1f\x2b\xfa\x02\x1d\x00\x80\x1c\x0d\x34\xc5\x8d\x93\xfe\x99\x71\x77\x10\x1f\x80\x53\x5a\x47\x38\xce\xbc\xbf\x38\x9a\x99\xb3\x63\x71\xeb\x03\x82\x01\x06\x00\x02\x82\x01\x01\x00\x82\xc1\x65\xbb\x57\x62\x43\xec\xf4\x6d\x58\xc3\xd1\x50\x16\x16\x95\x5f\xca\x03\x20\xfa\x95\xea\x11\xd2\xe6\xc1\xb9\xcf\x21\x76\x76\x72\x0d\xc1\xc0\x8c\x85\xbf\x20\xc4\xd2\x32\xb6\x0a\x29\xa1\xe5\x1c\x7b\x77\x3b\xc6\x45\x01\x45\x87\xc5\x25\xc8\x61\x51\xb3\x0d\x75\x48\x6e\xc7\xb6\xc9\x8e\xfb\x5f\x74\x95\x5b\x83\x11\x6d\x01\xd0\xaf\x12\x32\xaf\x89\x21\x3c\x2d\xe5\x74\x36\x9d\x70\x1a\xba\x93\x57\x30\x0b\x92\x0d\x3d\x8b\x98\x25\x2d\x46\xc4\x69\x52\xc1\x6a\x5f\x33\x55\x4b\x38\x31\x78\x09\xc7\xb9\xad\xd4\x70\x1f\x5c\x15\x8c\x1b\x70\x35\xe9\xfe\x39\x36\x6e\xce\xcb\x90\xd2\x89\x6b\x78\xc5\x23\xc4\xa5\x77\x28\x7e\xf5\xba\x7a\x26\x63\xed\x58\xaa\x20\xb5\xec\x66\xe3\x0f\x31\x66\x10\xdf\xaa\x38\x58\x3e\x49\x5a\xb6\xaf\x77\x1c\x28\x43\x87\xe6\x60\xed\xbe\xf4\xed\xb8\x72\xe2\xe8\x0e\x1d\x24\x4e\xe9\x56\x22\xe7\x6d\x02\x8e\x61\xc1\xe8\x87\xc2\xaa\x79\x27\x17\x36\x21\x39\xf4\xdd\x26\xea\xfd\x49\xb2\x36\x6e\xeb\x23\x50\xb0\x1f\xe1\xb5\x60\x22\xa2\x80\x9e\x37\x95\x59\xc3\x7b\x37\x5b\xa0\x1c\x4e\xaa\xcc\x14\xfd\x1b\x24\x78\x37"); + } + + #[test] + #[cfg(ossl102)] + fn test_dh_stored_restored() { + let dh1 = Dh::get_2048_256().unwrap(); + let key1 = dh1.generate_key().unwrap(); + + let dh2 = Dh::get_2048_256().unwrap(); + let key2 = dh2 + .set_private_key(key1.private_key().to_owned().unwrap()) + .unwrap(); + + assert_eq!(key1.public_key(), key2.public_key()); + assert_eq!(key1.private_key(), key2.private_key()); + } + + #[test] + #[cfg(ossl102)] + fn test_set_keys() { + let dh1 = Dh::get_2048_256().unwrap(); + let key1 = dh1.generate_key().unwrap(); + + let dh2 = Dh::get_2048_256().unwrap(); + let key2 = dh2 + .set_public_key(key1.public_key().to_owned().unwrap()) + .unwrap(); + + assert_eq!(key1.public_key(), key2.public_key()); + + let dh3 = Dh::get_2048_256().unwrap(); + let key3 = dh3 + .set_key( + key1.public_key().to_owned().unwrap(), + key1.private_key().to_owned().unwrap(), + ) + .unwrap(); + assert_eq!(key1.public_key(), key3.public_key()); + assert_eq!(key1.private_key(), key3.private_key()); + } + + #[test] + fn test_dh_from_pem() { + let mut ctx = SslContext::builder(SslMethod::tls()).unwrap(); + let params = include_bytes!("../test/dhparams.pem"); + let dh = Dh::params_from_pem(params).unwrap(); + ctx.set_tmp_dh(&dh).unwrap(); + } + + #[test] + fn test_dh_from_der() { + let params = include_bytes!("../test/dhparams.pem"); + let dh = Dh::params_from_pem(params).unwrap(); + let der = dh.params_to_der().unwrap(); + Dh::params_from_der(&der).unwrap(); + } + + #[test] + #[cfg(ossl102)] + fn test_dh_generate_key_compute_key() { + let dh1 = Dh::get_2048_224().unwrap().generate_key().unwrap(); + let dh2 = Dh::get_2048_224().unwrap().generate_key().unwrap(); + + let shared_a = dh1.compute_key(dh2.public_key()).unwrap(); + let shared_b = dh2.compute_key(dh1.public_key()).unwrap(); + + assert_eq!(shared_a, shared_b); + } + + #[test] + fn test_dh_generate_params_generate_key_compute_key() { + let dh_params1 = Dh::generate_params(512, 2).unwrap(); + let dh_params2 = Dh::from_pqg( + dh_params1.prime_p().to_owned().unwrap(), + None, + dh_params1.generator().to_owned().unwrap(), + ) + .unwrap(); + + let dh1 = dh_params1.generate_key().unwrap(); + let dh2 = dh_params2.generate_key().unwrap(); + + let shared_a = dh1.compute_key(dh2.public_key()).unwrap(); + let shared_b = dh2.compute_key(dh1.public_key()).unwrap(); + + assert_eq!(shared_a, shared_b); + } + + #[test] + fn test_dh_check_key() { + let dh1 = Dh::generate_params(512, 2).unwrap(); + let p = BigNum::from_hex_str("04").unwrap(); + let g = BigNum::from_hex_str("02").unwrap(); + let dh2 = Dh::from_pqg(p, None, g).unwrap(); + assert!(dh1.check_key().unwrap()); + assert!(matches!(dh2.check_key(), Ok(false) | Err(_))); + } +} diff --git a/vendor/openssl/src/dsa.rs b/vendor/openssl/src/dsa.rs new file mode 100644 index 0000000..1a63e8a --- /dev/null +++ b/vendor/openssl/src/dsa.rs @@ -0,0 +1,697 @@ +//! Digital Signatures +//! +//! DSA ensures a message originated from a known sender, and was not modified. +//! DSA uses asymmetrical keys and an algorithm to output a signature of the message +//! using the private key that can be validated with the public key but not be generated +//! without the private key. + +use cfg_if::cfg_if; +use foreign_types::{ForeignType, ForeignTypeRef}; +#[cfg(not(boringssl))] +use libc::c_int; +use std::fmt; +use std::mem; +use std::ptr; + +use crate::bn::{BigNum, BigNumRef}; +use crate::error::ErrorStack; +use crate::pkey::{HasParams, HasPrivate, HasPublic, Params, Private, Public}; +use crate::util::ForeignTypeRefExt; +use crate::{cvt, cvt_p}; +use openssl_macros::corresponds; + +generic_foreign_type_and_impl_send_sync! { + type CType = ffi::DSA; + fn drop = ffi::DSA_free; + + /// Object representing DSA keys. + /// + /// A DSA object contains the parameters p, q, and g. There is a private + /// and public key. The values p, g, and q are: + /// + /// * `p`: DSA prime parameter + /// * `q`: DSA sub-prime parameter + /// * `g`: DSA base parameter + /// + /// These values are used to calculate a pair of asymmetrical keys used for + /// signing. + /// + /// OpenSSL documentation at [`DSA_new`] + /// + /// [`DSA_new`]: https://www.openssl.org/docs/manmaster/crypto/DSA_new.html + /// + /// # Examples + /// + /// ``` + /// use openssl::dsa::Dsa; + /// use openssl::error::ErrorStack; + /// use openssl::pkey::Private; + /// + /// fn create_dsa() -> Result, ErrorStack> { + /// let sign = Dsa::generate(2048)?; + /// Ok(sign) + /// } + /// # fn main() { + /// # create_dsa(); + /// # } + /// ``` + pub struct Dsa; + /// Reference to [`Dsa`]. + /// + /// [`Dsa`]: struct.Dsa.html + pub struct DsaRef; +} + +impl Clone for Dsa { + fn clone(&self) -> Dsa { + (**self).to_owned() + } +} + +impl ToOwned for DsaRef { + type Owned = Dsa; + + fn to_owned(&self) -> Dsa { + unsafe { + ffi::DSA_up_ref(self.as_ptr()); + Dsa::from_ptr(self.as_ptr()) + } + } +} + +impl DsaRef +where + T: HasPublic, +{ + to_pem! { + /// Serializes the public key into a PEM-encoded SubjectPublicKeyInfo structure. + /// + /// The output will have a header of `-----BEGIN PUBLIC KEY-----`. + #[corresponds(PEM_write_bio_DSA_PUBKEY)] + public_key_to_pem, + ffi::PEM_write_bio_DSA_PUBKEY + } + + to_der! { + /// Serializes the public key into a DER-encoded SubjectPublicKeyInfo structure. + #[corresponds(i2d_DSA_PUBKEY)] + public_key_to_der, + ffi::i2d_DSA_PUBKEY + } + + /// Returns a reference to the public key component of `self`. + #[corresponds(DSA_get0_key)] + pub fn pub_key(&self) -> &BigNumRef { + unsafe { + let mut pub_key = ptr::null(); + DSA_get0_key(self.as_ptr(), &mut pub_key, ptr::null_mut()); + BigNumRef::from_const_ptr(pub_key) + } + } +} + +impl DsaRef +where + T: HasPrivate, +{ + private_key_to_pem! { + /// Serializes the private key to a PEM-encoded DSAPrivateKey structure. + /// + /// The output will have a header of `-----BEGIN DSA PRIVATE KEY-----`. + #[corresponds(PEM_write_bio_DSAPrivateKey)] + private_key_to_pem, + /// Serializes the private key to a PEM-encoded encrypted DSAPrivateKey structure. + /// + /// The output will have a header of `-----BEGIN DSA PRIVATE KEY-----`. + #[corresponds(PEM_write_bio_DSAPrivateKey)] + private_key_to_pem_passphrase, + ffi::PEM_write_bio_DSAPrivateKey + } + + to_der! { + /// Serializes the private_key to a DER-encoded `DSAPrivateKey` structure. + #[corresponds(i2d_DSAPrivateKey)] + private_key_to_der, + ffi::i2d_DSAPrivateKey + } + + /// Returns a reference to the private key component of `self`. + #[corresponds(DSA_get0_key)] + pub fn priv_key(&self) -> &BigNumRef { + unsafe { + let mut priv_key = ptr::null(); + DSA_get0_key(self.as_ptr(), ptr::null_mut(), &mut priv_key); + BigNumRef::from_const_ptr(priv_key) + } + } +} + +impl DsaRef +where + T: HasParams, +{ + /// Returns the maximum size of the signature output by `self` in bytes. + #[corresponds(DSA_size)] + pub fn size(&self) -> u32 { + unsafe { ffi::DSA_size(self.as_ptr()) as u32 } + } + + /// Returns the DSA prime parameter of `self`. + #[corresponds(DSA_get0_pqg)] + pub fn p(&self) -> &BigNumRef { + unsafe { + let mut p = ptr::null(); + DSA_get0_pqg(self.as_ptr(), &mut p, ptr::null_mut(), ptr::null_mut()); + BigNumRef::from_const_ptr(p) + } + } + + /// Returns the DSA sub-prime parameter of `self`. + #[corresponds(DSA_get0_pqg)] + pub fn q(&self) -> &BigNumRef { + unsafe { + let mut q = ptr::null(); + DSA_get0_pqg(self.as_ptr(), ptr::null_mut(), &mut q, ptr::null_mut()); + BigNumRef::from_const_ptr(q) + } + } + + /// Returns the DSA base parameter of `self`. + #[corresponds(DSA_get0_pqg)] + pub fn g(&self) -> &BigNumRef { + unsafe { + let mut g = ptr::null(); + DSA_get0_pqg(self.as_ptr(), ptr::null_mut(), ptr::null_mut(), &mut g); + BigNumRef::from_const_ptr(g) + } + } +} +#[cfg(boringssl)] +type BitType = libc::c_uint; +#[cfg(not(boringssl))] +type BitType = c_int; + +impl Dsa { + /// Creates a DSA params based upon the given parameters. + #[corresponds(DSA_set0_pqg)] + pub fn from_pqg(p: BigNum, q: BigNum, g: BigNum) -> Result, ErrorStack> { + unsafe { + let dsa = Dsa::from_ptr(cvt_p(ffi::DSA_new())?); + cvt(DSA_set0_pqg(dsa.0, p.as_ptr(), q.as_ptr(), g.as_ptr()))?; + mem::forget((p, q, g)); + Ok(dsa) + } + } + + /// Generates DSA params based on the given number of bits. + #[corresponds(DSA_generate_parameters_ex)] + pub fn generate_params(bits: u32) -> Result, ErrorStack> { + ffi::init(); + unsafe { + let dsa = Dsa::from_ptr(cvt_p(ffi::DSA_new())?); + cvt(ffi::DSA_generate_parameters_ex( + dsa.0, + bits as BitType, + ptr::null(), + 0, + ptr::null_mut(), + ptr::null_mut(), + ptr::null_mut(), + ))?; + Ok(dsa) + } + } + + /// Generates a private key based on the DSA params. + #[corresponds(DSA_generate_key)] + pub fn generate_key(self) -> Result, ErrorStack> { + unsafe { + let dsa_ptr = self.0; + cvt(ffi::DSA_generate_key(dsa_ptr))?; + mem::forget(self); + Ok(Dsa::from_ptr(dsa_ptr)) + } + } +} + +impl Dsa { + /// Generate a DSA key pair. + /// + /// The `bits` parameter corresponds to the length of the prime `p`. + pub fn generate(bits: u32) -> Result, ErrorStack> { + let params = Dsa::generate_params(bits)?; + params.generate_key() + } + + /// Create a DSA key pair with the given parameters + /// + /// `p`, `q` and `g` are the common parameters. + /// `priv_key` is the private component of the key pair. + /// `pub_key` is the public component of the key. Can be computed via `g^(priv_key) mod p` + pub fn from_private_components( + p: BigNum, + q: BigNum, + g: BigNum, + priv_key: BigNum, + pub_key: BigNum, + ) -> Result, ErrorStack> { + ffi::init(); + unsafe { + let dsa = Dsa::from_ptr(cvt_p(ffi::DSA_new())?); + cvt(DSA_set0_pqg(dsa.0, p.as_ptr(), q.as_ptr(), g.as_ptr()))?; + mem::forget((p, q, g)); + cvt(DSA_set0_key(dsa.0, pub_key.as_ptr(), priv_key.as_ptr()))?; + mem::forget((pub_key, priv_key)); + Ok(dsa) + } + } +} + +impl Dsa { + from_pem! { + /// Decodes a PEM-encoded SubjectPublicKeyInfo structure containing a DSA key. + /// + /// The input should have a header of `-----BEGIN PUBLIC KEY-----`. + #[corresponds(PEM_read_bio_DSA_PUBKEY)] + public_key_from_pem, + Dsa, + ffi::PEM_read_bio_DSA_PUBKEY + } + + from_der! { + /// Decodes a DER-encoded SubjectPublicKeyInfo structure containing a DSA key. + #[corresponds(d2i_DSA_PUBKEY)] + public_key_from_der, + Dsa, + ffi::d2i_DSA_PUBKEY + } + + /// Create a new DSA key with only public components. + /// + /// `p`, `q` and `g` are the common parameters. + /// `pub_key` is the public component of the key. + pub fn from_public_components( + p: BigNum, + q: BigNum, + g: BigNum, + pub_key: BigNum, + ) -> Result, ErrorStack> { + ffi::init(); + unsafe { + let dsa = Dsa::from_ptr(cvt_p(ffi::DSA_new())?); + cvt(DSA_set0_pqg(dsa.0, p.as_ptr(), q.as_ptr(), g.as_ptr()))?; + mem::forget((p, q, g)); + cvt(DSA_set0_key(dsa.0, pub_key.as_ptr(), ptr::null_mut()))?; + mem::forget(pub_key); + Ok(dsa) + } + } +} + +impl fmt::Debug for Dsa { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "DSA") + } +} + +cfg_if! { + if #[cfg(any(ossl110, libressl273, boringssl))] { + use ffi::{DSA_get0_key, DSA_get0_pqg, DSA_set0_key, DSA_set0_pqg}; + } else { + #[allow(bad_style)] + unsafe fn DSA_get0_pqg( + d: *mut ffi::DSA, + p: *mut *const ffi::BIGNUM, + q: *mut *const ffi::BIGNUM, + g: *mut *const ffi::BIGNUM) + { + if !p.is_null() { + *p = (*d).p; + } + if !q.is_null() { + *q = (*d).q; + } + if !g.is_null() { + *g = (*d).g; + } + } + + #[allow(bad_style)] + unsafe fn DSA_get0_key( + d: *mut ffi::DSA, + pub_key: *mut *const ffi::BIGNUM, + priv_key: *mut *const ffi::BIGNUM) + { + if !pub_key.is_null() { + *pub_key = (*d).pub_key; + } + if !priv_key.is_null() { + *priv_key = (*d).priv_key; + } + } + + #[allow(bad_style)] + unsafe fn DSA_set0_key( + d: *mut ffi::DSA, + pub_key: *mut ffi::BIGNUM, + priv_key: *mut ffi::BIGNUM) -> c_int + { + (*d).pub_key = pub_key; + (*d).priv_key = priv_key; + 1 + } + + #[allow(bad_style)] + unsafe fn DSA_set0_pqg( + d: *mut ffi::DSA, + p: *mut ffi::BIGNUM, + q: *mut ffi::BIGNUM, + g: *mut ffi::BIGNUM) -> c_int + { + (*d).p = p; + (*d).q = q; + (*d).g = g; + 1 + } + } +} + +foreign_type_and_impl_send_sync! { + type CType = ffi::DSA_SIG; + fn drop = ffi::DSA_SIG_free; + + /// Object representing DSA signature. + /// + /// DSA signatures consist of two components: `r` and `s`. + /// + /// # Examples + /// + /// ``` + /// use std::convert::TryInto; + /// + /// use openssl::bn::BigNum; + /// use openssl::dsa::{Dsa, DsaSig}; + /// use openssl::hash::MessageDigest; + /// use openssl::pkey::PKey; + /// use openssl::sign::{Signer, Verifier}; + /// + /// const TEST_DATA: &[u8] = &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]; + /// let dsa_ref = Dsa::generate(1024).unwrap(); + /// + /// let pub_key: PKey<_> = dsa_ref.clone().try_into().unwrap(); + /// let priv_key: PKey<_> = dsa_ref.try_into().unwrap(); + /// + /// let mut signer = if let Ok(signer) = Signer::new(MessageDigest::sha256(), &priv_key) { + /// signer + /// } else { + /// // DSA signing is not supported (eg. BoringSSL) + /// return; + /// }; + /// + /// signer.update(TEST_DATA).unwrap(); + /// + /// let signature = signer.sign_to_vec().unwrap(); + /// // Parse DER-encoded DSA signature + /// let signature = DsaSig::from_der(&signature).unwrap(); + /// + /// // Extract components `r` and `s` + /// let r = BigNum::from_slice(&signature.r().to_vec()).unwrap(); + /// let s = BigNum::from_slice(&signature.s().to_vec()).unwrap(); + /// + /// // Construct new DSA signature from components + /// let signature = DsaSig::from_private_components(r, s).unwrap(); + /// + /// // Serialize DSA signature to DER + /// let signature = signature.to_der().unwrap(); + /// + /// let mut verifier = Verifier::new(MessageDigest::sha256(), &pub_key).unwrap(); + /// verifier.update(TEST_DATA).unwrap(); + /// assert!(verifier.verify(&signature[..]).unwrap()); + /// ``` + pub struct DsaSig; + + /// Reference to a [`DsaSig`]. + pub struct DsaSigRef; +} + +impl DsaSig { + /// Returns a new `DsaSig` by setting the `r` and `s` values associated with an DSA signature. + #[corresponds(DSA_SIG_set0)] + pub fn from_private_components(r: BigNum, s: BigNum) -> Result { + unsafe { + let sig = cvt_p(ffi::DSA_SIG_new())?; + DSA_SIG_set0(sig, r.as_ptr(), s.as_ptr()); + mem::forget((r, s)); + Ok(DsaSig::from_ptr(sig)) + } + } + + from_der! { + /// Decodes a DER-encoded DSA signature. + #[corresponds(d2i_DSA_SIG)] + from_der, + DsaSig, + ffi::d2i_DSA_SIG + } +} + +impl fmt::Debug for DsaSig { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("DsaSig") + .field("r", self.r()) + .field("s", self.s()) + .finish() + } +} + +impl DsaSigRef { + to_der! { + /// Serializes the DSA signature into a DER-encoded `DSASignature` structure. + #[corresponds(i2d_DSA_SIG)] + to_der, + ffi::i2d_DSA_SIG + } + + /// Returns internal component `r` of an `DsaSig`. + #[corresponds(DSA_SIG_get0)] + pub fn r(&self) -> &BigNumRef { + unsafe { + let mut r = ptr::null(); + DSA_SIG_get0(self.as_ptr(), &mut r, ptr::null_mut()); + BigNumRef::from_const_ptr(r) + } + } + + /// Returns internal component `s` of an `DsaSig`. + #[corresponds(DSA_SIG_get0)] + pub fn s(&self) -> &BigNumRef { + unsafe { + let mut s = ptr::null(); + DSA_SIG_get0(self.as_ptr(), ptr::null_mut(), &mut s); + BigNumRef::from_const_ptr(s) + } + } +} + +cfg_if! { + if #[cfg(any(ossl110, libressl273, boringssl))] { + use ffi::{DSA_SIG_set0, DSA_SIG_get0}; + } else { + #[allow(bad_style)] + unsafe fn DSA_SIG_set0( + sig: *mut ffi::DSA_SIG, + r: *mut ffi::BIGNUM, + s: *mut ffi::BIGNUM, + ) -> c_int { + if r.is_null() || s.is_null() { + return 0; + } + ffi::BN_clear_free((*sig).r); + ffi::BN_clear_free((*sig).s); + (*sig).r = r; + (*sig).s = s; + 1 + } + + #[allow(bad_style)] + unsafe fn DSA_SIG_get0( + sig: *const ffi::DSA_SIG, + pr: *mut *const ffi::BIGNUM, + ps: *mut *const ffi::BIGNUM) + { + if !pr.is_null() { + (*pr) = (*sig).r; + } + if !ps.is_null() { + (*ps) = (*sig).s; + } + } + } +} + +#[cfg(test)] +mod test { + use super::*; + use crate::bn::BigNumContext; + #[cfg(not(boringssl))] + use crate::hash::MessageDigest; + #[cfg(not(boringssl))] + use crate::pkey::PKey; + #[cfg(not(boringssl))] + use crate::sign::{Signer, Verifier}; + + #[test] + pub fn test_generate() { + Dsa::generate(1024).unwrap(); + } + + #[test] + fn test_pubkey_generation() { + let dsa = Dsa::generate(1024).unwrap(); + let p = dsa.p(); + let g = dsa.g(); + let priv_key = dsa.priv_key(); + let pub_key = dsa.pub_key(); + let mut ctx = BigNumContext::new().unwrap(); + let mut calc = BigNum::new().unwrap(); + calc.mod_exp(g, priv_key, p, &mut ctx).unwrap(); + assert_eq!(&calc, pub_key) + } + + #[test] + fn test_priv_key_from_parts() { + let p = BigNum::from_u32(283).unwrap(); + let q = BigNum::from_u32(47).unwrap(); + let g = BigNum::from_u32(60).unwrap(); + let priv_key = BigNum::from_u32(15).unwrap(); + let pub_key = BigNum::from_u32(207).unwrap(); + + let dsa = Dsa::from_private_components(p, q, g, priv_key, pub_key).unwrap(); + assert_eq!(dsa.pub_key(), &BigNum::from_u32(207).unwrap()); + assert_eq!(dsa.priv_key(), &BigNum::from_u32(15).unwrap()); + assert_eq!(dsa.p(), &BigNum::from_u32(283).unwrap()); + assert_eq!(dsa.q(), &BigNum::from_u32(47).unwrap()); + assert_eq!(dsa.g(), &BigNum::from_u32(60).unwrap()); + } + + #[test] + fn test_pub_key_from_parts() { + let p = BigNum::from_u32(283).unwrap(); + let q = BigNum::from_u32(47).unwrap(); + let g = BigNum::from_u32(60).unwrap(); + let pub_key = BigNum::from_u32(207).unwrap(); + + let dsa = Dsa::from_public_components(p, q, g, pub_key).unwrap(); + assert_eq!(dsa.pub_key(), &BigNum::from_u32(207).unwrap()); + assert_eq!(dsa.p(), &BigNum::from_u32(283).unwrap()); + assert_eq!(dsa.q(), &BigNum::from_u32(47).unwrap()); + assert_eq!(dsa.g(), &BigNum::from_u32(60).unwrap()); + } + + #[test] + fn test_params() { + let params = Dsa::generate_params(1024).unwrap(); + let p = params.p().to_owned().unwrap(); + let q = params.q().to_owned().unwrap(); + let g = params.g().to_owned().unwrap(); + let key = params.generate_key().unwrap(); + let params2 = Dsa::from_pqg( + key.p().to_owned().unwrap(), + key.q().to_owned().unwrap(), + key.g().to_owned().unwrap(), + ) + .unwrap(); + assert_eq!(p, *params2.p()); + assert_eq!(q, *params2.q()); + assert_eq!(g, *params2.g()); + } + + #[test] + #[cfg(not(boringssl))] + fn test_signature() { + const TEST_DATA: &[u8] = &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]; + let dsa_ref = Dsa::generate(1024).unwrap(); + + let p = dsa_ref.p(); + let q = dsa_ref.q(); + let g = dsa_ref.g(); + + let pub_key = dsa_ref.pub_key(); + let priv_key = dsa_ref.priv_key(); + + let priv_key = Dsa::from_private_components( + BigNumRef::to_owned(p).unwrap(), + BigNumRef::to_owned(q).unwrap(), + BigNumRef::to_owned(g).unwrap(), + BigNumRef::to_owned(priv_key).unwrap(), + BigNumRef::to_owned(pub_key).unwrap(), + ) + .unwrap(); + let priv_key = PKey::from_dsa(priv_key).unwrap(); + + let pub_key = Dsa::from_public_components( + BigNumRef::to_owned(p).unwrap(), + BigNumRef::to_owned(q).unwrap(), + BigNumRef::to_owned(g).unwrap(), + BigNumRef::to_owned(pub_key).unwrap(), + ) + .unwrap(); + let pub_key = PKey::from_dsa(pub_key).unwrap(); + + let mut signer = Signer::new(MessageDigest::sha256(), &priv_key).unwrap(); + signer.update(TEST_DATA).unwrap(); + + let signature = signer.sign_to_vec().unwrap(); + let mut verifier = Verifier::new(MessageDigest::sha256(), &pub_key).unwrap(); + verifier.update(TEST_DATA).unwrap(); + assert!(verifier.verify(&signature[..]).unwrap()); + } + + #[test] + #[cfg(not(boringssl))] + fn test_signature_der() { + use std::convert::TryInto; + + const TEST_DATA: &[u8] = &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]; + let dsa_ref = Dsa::generate(1024).unwrap(); + + let pub_key: PKey<_> = dsa_ref.clone().try_into().unwrap(); + let priv_key: PKey<_> = dsa_ref.try_into().unwrap(); + + let mut signer = Signer::new(MessageDigest::sha256(), &priv_key).unwrap(); + signer.update(TEST_DATA).unwrap(); + + let signature = signer.sign_to_vec().unwrap(); + eprintln!("{:?}", signature); + let signature = DsaSig::from_der(&signature).unwrap(); + + let r = BigNum::from_slice(&signature.r().to_vec()).unwrap(); + let s = BigNum::from_slice(&signature.s().to_vec()).unwrap(); + + let signature = DsaSig::from_private_components(r, s).unwrap(); + let signature = signature.to_der().unwrap(); + + let mut verifier = Verifier::new(MessageDigest::sha256(), &pub_key).unwrap(); + verifier.update(TEST_DATA).unwrap(); + assert!(verifier.verify(&signature[..]).unwrap()); + } + + #[test] + #[allow(clippy::redundant_clone)] + fn clone() { + let key = Dsa::generate(2048).unwrap(); + drop(key.clone()); + } + + #[test] + fn dsa_sig_debug() { + let sig = DsaSig::from_der(&[ + 48, 46, 2, 21, 0, 135, 169, 24, 58, 153, 37, 175, 248, 200, 45, 251, 112, 238, 238, 89, + 172, 177, 182, 166, 237, 2, 21, 0, 159, 146, 151, 237, 187, 8, 82, 115, 14, 183, 103, + 12, 203, 46, 161, 208, 251, 167, 123, 131, + ]) + .unwrap(); + let s = format!("{:?}", sig); + assert_eq!(s, "DsaSig { r: 774484690634577222213819810519929266740561094381, s: 910998676210681457251421818099943952372231273347 }"); + } +} diff --git a/vendor/openssl/src/ec.rs b/vendor/openssl/src/ec.rs new file mode 100644 index 0000000..0dda1db --- /dev/null +++ b/vendor/openssl/src/ec.rs @@ -0,0 +1,1345 @@ +//! Elliptic Curve +//! +//! Cryptography relies on the difficulty of solving mathematical problems, such as the factor +//! of large integers composed of two large prime numbers and the discrete logarithm of a +//! random elliptic curve. This module provides low-level features of the latter. +//! Elliptic Curve protocols can provide the same security with smaller keys. +//! +//! There are 2 forms of elliptic curves, `Fp` and `F2^m`. These curves use irreducible +//! trinomial or pentanomial. Being a generic interface to a wide range of algorithms, +//! the curves are generally referenced by [`EcGroup`]. There are many built-in groups +//! found in [`Nid`]. +//! +//! OpenSSL Wiki explains the fields and curves in detail at [Elliptic Curve Cryptography]. +//! +//! [`EcGroup`]: struct.EcGroup.html +//! [`Nid`]: ../nid/struct.Nid.html +//! [Elliptic Curve Cryptography]: https://wiki.openssl.org/index.php/Elliptic_Curve_Cryptography +use cfg_if::cfg_if; +use foreign_types::{ForeignType, ForeignTypeRef}; +use libc::c_int; +use std::fmt; +use std::ptr; + +use crate::bn::{BigNum, BigNumContextRef, BigNumRef}; +use crate::error::ErrorStack; +use crate::nid::Nid; +use crate::pkey::{HasParams, HasPrivate, HasPublic, Params, Private, Public}; +use crate::util::ForeignTypeRefExt; +use crate::{cvt, cvt_n, cvt_p, init}; +use openssl_macros::corresponds; + +cfg_if! { + if #[cfg(not(boringssl))] { + use std::ffi::CString; + use crate::string::OpensslString; + } +} + +/// Compressed or Uncompressed conversion +/// +/// Conversion from the binary value of the point on the curve is performed in one of +/// compressed, uncompressed, or hybrid conversions. The default is compressed, except +/// for binary curves. +/// +/// Further documentation is available in the [X9.62] standard. +/// +/// [X9.62]: http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.202.2977&rep=rep1&type=pdf +#[derive(Copy, Clone)] +pub struct PointConversionForm(ffi::point_conversion_form_t); + +impl PointConversionForm { + /// Compressed conversion from point value. + pub const COMPRESSED: PointConversionForm = + PointConversionForm(ffi::point_conversion_form_t::POINT_CONVERSION_COMPRESSED); + + /// Uncompressed conversion from point value. + pub const UNCOMPRESSED: PointConversionForm = + PointConversionForm(ffi::point_conversion_form_t::POINT_CONVERSION_UNCOMPRESSED); + + /// Performs both compressed and uncompressed conversions. + pub const HYBRID: PointConversionForm = + PointConversionForm(ffi::point_conversion_form_t::POINT_CONVERSION_HYBRID); +} + +/// Named Curve or Explicit +/// +/// This type acts as a boolean as to whether the `EcGroup` is named or explicit. +#[derive(Copy, Clone, Debug, PartialEq)] +pub struct Asn1Flag(c_int); + +impl Asn1Flag { + /// Curve defined using polynomial parameters + /// + /// Most applications use a named EC_GROUP curve, however, support + /// is included to explicitly define the curve used to calculate keys + /// This information would need to be known by both endpoint to make communication + /// effective. + /// + /// OPENSSL_EC_EXPLICIT_CURVE, but that was only added in 1.1. + /// Man page documents that 0 can be used in older versions. + /// + /// OpenSSL documentation at [`EC_GROUP`] + /// + /// [`EC_GROUP`]: https://www.openssl.org/docs/manmaster/crypto/EC_GROUP_get_seed_len.html + pub const EXPLICIT_CURVE: Asn1Flag = Asn1Flag(0); + + /// Standard Curves + /// + /// Curves that make up the typical encryption use cases. The collection of curves + /// are well known but extensible. + /// + /// OpenSSL documentation at [`EC_GROUP`] + /// + /// [`EC_GROUP`]: https://www.openssl.org/docs/manmaster/man3/EC_GROUP_order_bits.html + pub const NAMED_CURVE: Asn1Flag = Asn1Flag(ffi::OPENSSL_EC_NAMED_CURVE); +} + +foreign_type_and_impl_send_sync! { + type CType = ffi::EC_GROUP; + fn drop = ffi::EC_GROUP_free; + + /// Describes the curve + /// + /// A curve can be of the named curve type. These curves can be discovered + /// using openssl binary `openssl ecparam -list_curves`. Other operations + /// are available in the [wiki]. These named curves are available in the + /// [`Nid`] module. + /// + /// Curves can also be generated using prime field parameters or a binary field. + /// + /// Prime fields use the formula `y^2 mod p = x^3 + ax + b mod p`. Binary + /// fields use the formula `y^2 + xy = x^3 + ax^2 + b`. Named curves have + /// assured security. To prevent accidental vulnerabilities, they should + /// be preferred. + /// + /// [wiki]: https://wiki.openssl.org/index.php/Command_Line_Elliptic_Curve_Operations + /// [`Nid`]: ../nid/index.html + pub struct EcGroup; + /// Reference to [`EcGroup`] + /// + /// [`EcGroup`]: struct.EcGroup.html + pub struct EcGroupRef; +} + +impl EcGroup { + /// Returns the group of a standard named curve. + /// + /// # Examples + /// + /// ``` + /// # fn main() -> Result<(), Box> { + /// use openssl::nid::Nid; + /// use openssl::ec::{EcGroup, EcKey}; + /// + /// let nid = Nid::X9_62_PRIME256V1; // NIST P-256 curve + /// let group = EcGroup::from_curve_name(nid)?; + /// let key = EcKey::generate(&group)?; + /// # Ok(()) } + /// ``` + #[corresponds(EC_GROUP_new_by_curve_name)] + pub fn from_curve_name(nid: Nid) -> Result { + unsafe { + init(); + cvt_p(ffi::EC_GROUP_new_by_curve_name(nid.as_raw())).map(EcGroup) + } + } + + /// Returns the group for given parameters + #[corresponds(EC_GROUP_new_curve_GFp)] + pub fn from_components( + p: BigNum, + a: BigNum, + b: BigNum, + ctx: &mut BigNumContextRef, + ) -> Result { + unsafe { + cvt_p(ffi::EC_GROUP_new_curve_GFp( + p.as_ptr(), + a.as_ptr(), + b.as_ptr(), + ctx.as_ptr(), + )) + .map(EcGroup) + } + } +} + +impl EcGroupRef { + /// Places the components of a curve over a prime field in the provided `BigNum`s. + /// The components make up the formula `y^2 mod p = x^3 + ax + b mod p`. + #[corresponds(EC_GROUP_get_curve_GFp)] + pub fn components_gfp( + &self, + p: &mut BigNumRef, + a: &mut BigNumRef, + b: &mut BigNumRef, + ctx: &mut BigNumContextRef, + ) -> Result<(), ErrorStack> { + unsafe { + cvt(ffi::EC_GROUP_get_curve_GFp( + self.as_ptr(), + p.as_ptr(), + a.as_ptr(), + b.as_ptr(), + ctx.as_ptr(), + )) + .map(|_| ()) + } + } + + /// Places the components of a curve over a binary field in the provided `BigNum`s. + /// The components make up the formula `y^2 + xy = x^3 + ax^2 + b`. + /// + /// In this form `p` relates to the irreducible polynomial. Each bit represents + /// a term in the polynomial. It will be set to 3 `1`s or 5 `1`s depending on + /// using a trinomial or pentanomial. + #[corresponds(EC_GROUP_get_curve_GF2m)] + #[cfg(not(osslconf = "OPENSSL_NO_EC2M"))] + pub fn components_gf2m( + &self, + p: &mut BigNumRef, + a: &mut BigNumRef, + b: &mut BigNumRef, + ctx: &mut BigNumContextRef, + ) -> Result<(), ErrorStack> { + unsafe { + cvt(ffi::EC_GROUP_get_curve_GF2m( + self.as_ptr(), + p.as_ptr(), + a.as_ptr(), + b.as_ptr(), + ctx.as_ptr(), + )) + .map(|_| ()) + } + } + + /// Places the cofactor of the group in the provided `BigNum`. + #[corresponds(EC_GROUP_get_cofactor)] + pub fn cofactor( + &self, + cofactor: &mut BigNumRef, + ctx: &mut BigNumContextRef, + ) -> Result<(), ErrorStack> { + unsafe { + cvt(ffi::EC_GROUP_get_cofactor( + self.as_ptr(), + cofactor.as_ptr(), + ctx.as_ptr(), + )) + .map(|_| ()) + } + } + + /// Returns the degree of the curve. + #[corresponds(EC_GROUP_get_degree)] + pub fn degree(&self) -> u32 { + unsafe { ffi::EC_GROUP_get_degree(self.as_ptr()) as u32 } + } + + /// Returns the number of bits in the group order. + #[corresponds(EC_GROUP_order_bits)] + #[cfg(ossl110)] + pub fn order_bits(&self) -> u32 { + unsafe { ffi::EC_GROUP_order_bits(self.as_ptr()) as u32 } + } + + /// Returns the generator for the given curve as an [`EcPoint`]. + #[corresponds(EC_GROUP_get0_generator)] + pub fn generator(&self) -> &EcPointRef { + unsafe { + let ptr = ffi::EC_GROUP_get0_generator(self.as_ptr()); + EcPointRef::from_const_ptr(ptr) + } + } + + /// Sets the generator point for the given curve + #[corresponds(EC_GROUP_set_generator)] + pub fn set_generator( + &mut self, + generator: EcPoint, + order: BigNum, + cofactor: BigNum, + ) -> Result<(), ErrorStack> { + unsafe { + cvt(ffi::EC_GROUP_set_generator( + self.as_ptr(), + generator.as_ptr(), + order.as_ptr(), + cofactor.as_ptr(), + )) + .map(|_| ()) + } + } + + /// Places the order of the curve in the provided `BigNum`. + #[corresponds(EC_GROUP_get_order)] + pub fn order( + &self, + order: &mut BigNumRef, + ctx: &mut BigNumContextRef, + ) -> Result<(), ErrorStack> { + unsafe { + cvt(ffi::EC_GROUP_get_order( + self.as_ptr(), + order.as_ptr(), + ctx.as_ptr(), + )) + .map(|_| ()) + } + } + + /// Sets the flag determining if the group corresponds to a named curve or must be explicitly + /// parameterized. + /// + /// This defaults to `EXPLICIT_CURVE` in OpenSSL 1.0.1 and 1.0.2, but `NAMED_CURVE` in OpenSSL + /// 1.1.0. + #[corresponds(EC_GROUP_set_asn1_flag)] + pub fn set_asn1_flag(&mut self, flag: Asn1Flag) { + unsafe { + ffi::EC_GROUP_set_asn1_flag(self.as_ptr(), flag.0); + } + } + + /// Gets the flag determining if the group corresponds to a named curve. + #[corresponds(EC_GROUP_get_asn1_flag)] + pub fn asn1_flag(&self) -> Asn1Flag { + unsafe { Asn1Flag(ffi::EC_GROUP_get_asn1_flag(self.as_ptr())) } + } + + /// Returns the name of the curve, if a name is associated. + #[corresponds(EC_GROUP_get_curve_name)] + pub fn curve_name(&self) -> Option { + let nid = unsafe { ffi::EC_GROUP_get_curve_name(self.as_ptr()) }; + if nid > 0 { + Some(Nid::from_raw(nid)) + } else { + None + } + } +} + +foreign_type_and_impl_send_sync! { + type CType = ffi::EC_POINT; + fn drop = ffi::EC_POINT_free; + + /// Represents a point on the curve + pub struct EcPoint; + /// A reference a borrowed [`EcPoint`]. + pub struct EcPointRef; +} + +impl EcPointRef { + /// Computes `a + b`, storing the result in `self`. + #[corresponds(EC_POINT_add)] + pub fn add( + &mut self, + group: &EcGroupRef, + a: &EcPointRef, + b: &EcPointRef, + ctx: &mut BigNumContextRef, + ) -> Result<(), ErrorStack> { + unsafe { + cvt(ffi::EC_POINT_add( + group.as_ptr(), + self.as_ptr(), + a.as_ptr(), + b.as_ptr(), + ctx.as_ptr(), + )) + .map(|_| ()) + } + } + + /// Computes `q * m`, storing the result in `self`. + #[corresponds(EC_POINT_mul)] + pub fn mul( + &mut self, + group: &EcGroupRef, + q: &EcPointRef, + m: &BigNumRef, + // FIXME should be &mut + ctx: &BigNumContextRef, + ) -> Result<(), ErrorStack> { + unsafe { + cvt(ffi::EC_POINT_mul( + group.as_ptr(), + self.as_ptr(), + ptr::null(), + q.as_ptr(), + m.as_ptr(), + ctx.as_ptr(), + )) + .map(|_| ()) + } + } + + /// Computes `generator * n`, storing the result in `self`. + #[corresponds(EC_POINT_mul)] + pub fn mul_generator( + &mut self, + group: &EcGroupRef, + n: &BigNumRef, + // FIXME should be &mut + ctx: &BigNumContextRef, + ) -> Result<(), ErrorStack> { + unsafe { + cvt(ffi::EC_POINT_mul( + group.as_ptr(), + self.as_ptr(), + n.as_ptr(), + ptr::null(), + ptr::null(), + ctx.as_ptr(), + )) + .map(|_| ()) + } + } + + /// Computes `generator * n + q * m`, storing the result in `self`. + #[corresponds(EC_POINT_mul)] + pub fn mul_full( + &mut self, + group: &EcGroupRef, + n: &BigNumRef, + q: &EcPointRef, + m: &BigNumRef, + ctx: &mut BigNumContextRef, + ) -> Result<(), ErrorStack> { + unsafe { + cvt(ffi::EC_POINT_mul( + group.as_ptr(), + self.as_ptr(), + n.as_ptr(), + q.as_ptr(), + m.as_ptr(), + ctx.as_ptr(), + )) + .map(|_| ()) + } + } + + /// Inverts `self`. + #[corresponds(EC_POINT_invert)] + // FIXME should be mutable + pub fn invert(&mut self, group: &EcGroupRef, ctx: &BigNumContextRef) -> Result<(), ErrorStack> { + unsafe { + cvt(ffi::EC_POINT_invert( + group.as_ptr(), + self.as_ptr(), + ctx.as_ptr(), + )) + .map(|_| ()) + } + } + + /// Serializes the point to a binary representation. + #[corresponds(EC_POINT_point2oct)] + pub fn to_bytes( + &self, + group: &EcGroupRef, + form: PointConversionForm, + ctx: &mut BigNumContextRef, + ) -> Result, ErrorStack> { + unsafe { + let len = ffi::EC_POINT_point2oct( + group.as_ptr(), + self.as_ptr(), + form.0, + ptr::null_mut(), + 0, + ctx.as_ptr(), + ); + if len == 0 { + return Err(ErrorStack::get()); + } + let mut buf = vec![0; len]; + let len = ffi::EC_POINT_point2oct( + group.as_ptr(), + self.as_ptr(), + form.0, + buf.as_mut_ptr(), + len, + ctx.as_ptr(), + ); + if len == 0 { + Err(ErrorStack::get()) + } else { + Ok(buf) + } + } + } + + /// Serializes the point to a hexadecimal string representation. + #[corresponds(EC_POINT_point2hex)] + #[cfg(not(boringssl))] + pub fn to_hex_str( + &self, + group: &EcGroupRef, + form: PointConversionForm, + ctx: &mut BigNumContextRef, + ) -> Result { + unsafe { + let buf = cvt_p(ffi::EC_POINT_point2hex( + group.as_ptr(), + self.as_ptr(), + form.0, + ctx.as_ptr(), + ))?; + Ok(OpensslString::from_ptr(buf)) + } + } + + /// Creates a new point on the specified curve with the same value. + #[corresponds(EC_POINT_dup)] + pub fn to_owned(&self, group: &EcGroupRef) -> Result { + unsafe { cvt_p(ffi::EC_POINT_dup(self.as_ptr(), group.as_ptr())).map(EcPoint) } + } + + /// Determines if this point is equal to another. + #[corresponds(EC_POINT_cmp)] + pub fn eq( + &self, + group: &EcGroupRef, + other: &EcPointRef, + ctx: &mut BigNumContextRef, + ) -> Result { + unsafe { + let res = cvt_n(ffi::EC_POINT_cmp( + group.as_ptr(), + self.as_ptr(), + other.as_ptr(), + ctx.as_ptr(), + ))?; + Ok(res == 0) + } + } + + /// Places affine coordinates of a curve over a prime field in the provided + /// `x` and `y` `BigNum`s. + #[corresponds(EC_POINT_get_affine_coordinates)] + #[cfg(any(ossl111, boringssl, libressl350))] + pub fn affine_coordinates( + &self, + group: &EcGroupRef, + x: &mut BigNumRef, + y: &mut BigNumRef, + ctx: &mut BigNumContextRef, + ) -> Result<(), ErrorStack> { + unsafe { + cvt(ffi::EC_POINT_get_affine_coordinates( + group.as_ptr(), + self.as_ptr(), + x.as_ptr(), + y.as_ptr(), + ctx.as_ptr(), + )) + .map(|_| ()) + } + } + + /// Places affine coordinates of a curve over a prime field in the provided + /// `x` and `y` `BigNum`s + #[corresponds(EC_POINT_get_affine_coordinates_GFp)] + pub fn affine_coordinates_gfp( + &self, + group: &EcGroupRef, + x: &mut BigNumRef, + y: &mut BigNumRef, + ctx: &mut BigNumContextRef, + ) -> Result<(), ErrorStack> { + unsafe { + cvt(ffi::EC_POINT_get_affine_coordinates_GFp( + group.as_ptr(), + self.as_ptr(), + x.as_ptr(), + y.as_ptr(), + ctx.as_ptr(), + )) + .map(|_| ()) + } + } + + /// Sets affine coordinates of a curve over a prime field using the provided + /// `x` and `y` `BigNum`s + #[corresponds(EC_POINT_set_affine_coordinates_GFp)] + pub fn set_affine_coordinates_gfp( + &mut self, + group: &EcGroupRef, + x: &BigNumRef, + y: &BigNumRef, + ctx: &mut BigNumContextRef, + ) -> Result<(), ErrorStack> { + unsafe { + cvt(ffi::EC_POINT_set_affine_coordinates_GFp( + group.as_ptr(), + self.as_ptr(), + x.as_ptr(), + y.as_ptr(), + ctx.as_ptr(), + )) + .map(|_| ()) + } + } + + /// Places affine coordinates of a curve over a binary field in the provided + /// `x` and `y` `BigNum`s + #[corresponds(EC_POINT_get_affine_coordinates_GF2m)] + #[cfg(not(osslconf = "OPENSSL_NO_EC2M"))] + pub fn affine_coordinates_gf2m( + &self, + group: &EcGroupRef, + x: &mut BigNumRef, + y: &mut BigNumRef, + ctx: &mut BigNumContextRef, + ) -> Result<(), ErrorStack> { + unsafe { + cvt(ffi::EC_POINT_get_affine_coordinates_GF2m( + group.as_ptr(), + self.as_ptr(), + x.as_ptr(), + y.as_ptr(), + ctx.as_ptr(), + )) + .map(|_| ()) + } + } + + /// Checks if point is infinity + #[corresponds(EC_POINT_is_at_infinity)] + pub fn is_infinity(&self, group: &EcGroupRef) -> bool { + unsafe { + let res = ffi::EC_POINT_is_at_infinity(group.as_ptr(), self.as_ptr()); + res == 1 + } + } + + /// Checks if point is on a given curve + #[corresponds(EC_POINT_is_on_curve)] + pub fn is_on_curve( + &self, + group: &EcGroupRef, + ctx: &mut BigNumContextRef, + ) -> Result { + unsafe { + let res = cvt_n(ffi::EC_POINT_is_on_curve( + group.as_ptr(), + self.as_ptr(), + ctx.as_ptr(), + ))?; + Ok(res == 1) + } + } +} + +impl EcPoint { + /// Creates a new point on the specified curve. + #[corresponds(EC_POINT_new)] + pub fn new(group: &EcGroupRef) -> Result { + unsafe { cvt_p(ffi::EC_POINT_new(group.as_ptr())).map(EcPoint) } + } + + /// Creates point from a binary representation + #[corresponds(EC_POINT_oct2point)] + pub fn from_bytes( + group: &EcGroupRef, + buf: &[u8], + ctx: &mut BigNumContextRef, + ) -> Result { + let point = EcPoint::new(group)?; + unsafe { + cvt(ffi::EC_POINT_oct2point( + group.as_ptr(), + point.as_ptr(), + buf.as_ptr(), + buf.len(), + ctx.as_ptr(), + ))?; + } + Ok(point) + } + + /// Creates point from a hexadecimal string representation + #[corresponds(EC_POINT_hex2point)] + #[cfg(not(boringssl))] + pub fn from_hex_str( + group: &EcGroupRef, + s: &str, + ctx: &mut BigNumContextRef, + ) -> Result { + let point = EcPoint::new(group)?; + unsafe { + let c_str = CString::new(s.as_bytes()).unwrap(); + cvt_p(ffi::EC_POINT_hex2point( + group.as_ptr(), + c_str.as_ptr() as *const _, + point.as_ptr(), + ctx.as_ptr(), + ))?; + } + Ok(point) + } +} + +generic_foreign_type_and_impl_send_sync! { + type CType = ffi::EC_KEY; + fn drop = ffi::EC_KEY_free; + + /// Public and optional private key on the given curve. + pub struct EcKey; + /// A reference to an [`EcKey`]. + pub struct EcKeyRef; +} + +impl EcKeyRef +where + T: HasPrivate, +{ + private_key_to_pem! { + /// Serializes the private key to a PEM-encoded ECPrivateKey structure. + /// + /// The output will have a header of `-----BEGIN EC PRIVATE KEY-----`. + #[corresponds(PEM_write_bio_ECPrivateKey)] + private_key_to_pem, + /// Serializes the private key to a PEM-encoded encrypted ECPrivateKey structure. + /// + /// The output will have a header of `-----BEGIN EC PRIVATE KEY-----`. + #[corresponds(PEM_write_bio_ECPrivateKey)] + private_key_to_pem_passphrase, + ffi::PEM_write_bio_ECPrivateKey + } + + to_der! { + /// Serializes the private key into a DER-encoded ECPrivateKey structure. + #[corresponds(i2d_ECPrivateKey)] + private_key_to_der, + ffi::i2d_ECPrivateKey + } + + /// Returns the private key value. + #[corresponds(EC_KEY_get0_private_key)] + pub fn private_key(&self) -> &BigNumRef { + unsafe { + let ptr = ffi::EC_KEY_get0_private_key(self.as_ptr()); + BigNumRef::from_const_ptr(ptr) + } + } +} + +impl EcKeyRef +where + T: HasPublic, +{ + /// Returns the public key. + #[corresponds(EC_KEY_get0_public_key)] + pub fn public_key(&self) -> &EcPointRef { + unsafe { + let ptr = ffi::EC_KEY_get0_public_key(self.as_ptr()); + EcPointRef::from_const_ptr(ptr) + } + } + + to_pem! { + /// Serializes the public key into a PEM-encoded SubjectPublicKeyInfo structure. + /// + /// The output will have a header of `-----BEGIN PUBLIC KEY-----`. + #[corresponds(PEM_write_bio_EC_PUBKEY)] + public_key_to_pem, + ffi::PEM_write_bio_EC_PUBKEY + } + + to_der! { + /// Serializes the public key into a DER-encoded SubjectPublicKeyInfo structure. + #[corresponds(i2d_EC_PUBKEY)] + public_key_to_der, + ffi::i2d_EC_PUBKEY + } +} + +impl EcKeyRef +where + T: HasParams, +{ + /// Returns the key's group. + #[corresponds(EC_KEY_get0_group)] + pub fn group(&self) -> &EcGroupRef { + unsafe { + let ptr = ffi::EC_KEY_get0_group(self.as_ptr()); + EcGroupRef::from_const_ptr(ptr) + } + } + + /// Checks the key for validity. + #[corresponds(EC_KEY_check_key)] + pub fn check_key(&self) -> Result<(), ErrorStack> { + unsafe { cvt(ffi::EC_KEY_check_key(self.as_ptr())).map(|_| ()) } + } +} + +impl ToOwned for EcKeyRef { + type Owned = EcKey; + + fn to_owned(&self) -> EcKey { + unsafe { + let r = ffi::EC_KEY_up_ref(self.as_ptr()); + assert!(r == 1); + EcKey::from_ptr(self.as_ptr()) + } + } +} + +impl EcKey { + /// Constructs an `EcKey` corresponding to a known curve. + /// + /// It will not have an associated public or private key. This kind of key is primarily useful + /// to be provided to the `set_tmp_ecdh` methods on `Ssl` and `SslContextBuilder`. + #[corresponds(EC_KEY_new_by_curve_name)] + pub fn from_curve_name(nid: Nid) -> Result, ErrorStack> { + unsafe { + init(); + cvt_p(ffi::EC_KEY_new_by_curve_name(nid.as_raw())).map(|p| EcKey::from_ptr(p)) + } + } + + /// Constructs an `EcKey` corresponding to a curve. + #[corresponds(EC_KEY_set_group)] + pub fn from_group(group: &EcGroupRef) -> Result, ErrorStack> { + unsafe { + cvt_p(ffi::EC_KEY_new()) + .map(|p| EcKey::from_ptr(p)) + .and_then(|key| { + cvt(ffi::EC_KEY_set_group(key.as_ptr(), group.as_ptr())).map(|_| key) + }) + } + } +} + +impl EcKey { + /// Constructs an `EcKey` from the specified group with the associated [`EcPoint`]: `public_key`. + /// + /// This will only have the associated `public_key`. + /// + /// # Example + /// + /// ``` + /// # fn main() -> Result<(), Box> { + /// use openssl::bn::BigNumContext; + /// use openssl::ec::*; + /// use openssl::nid::Nid; + /// use openssl::pkey::PKey; + /// + /// let group = EcGroup::from_curve_name(Nid::SECP384R1)?; + /// let mut ctx = BigNumContext::new()?; + /// + /// // get bytes from somewhere + /// let public_key = // ... + /// # EcKey::generate(&group)?.public_key().to_bytes(&group, + /// # PointConversionForm::COMPRESSED, &mut ctx)?; + /// + /// // create an EcKey from the binary form of a EcPoint + /// let point = EcPoint::from_bytes(&group, &public_key, &mut ctx)?; + /// let key = EcKey::from_public_key(&group, &point)?; + /// key.check_key()?; + /// # Ok(()) } + /// ``` + #[corresponds(EC_KEY_set_public_key)] + pub fn from_public_key( + group: &EcGroupRef, + public_key: &EcPointRef, + ) -> Result, ErrorStack> { + unsafe { + cvt_p(ffi::EC_KEY_new()) + .map(|p| EcKey::from_ptr(p)) + .and_then(|key| { + cvt(ffi::EC_KEY_set_group(key.as_ptr(), group.as_ptr())).map(|_| key) + }) + .and_then(|key| { + cvt(ffi::EC_KEY_set_public_key( + key.as_ptr(), + public_key.as_ptr(), + )) + .map(|_| key) + }) + } + } + + /// Constructs a public key from its affine coordinates. + #[corresponds(EC_KEY_set_public_key_affine_coordinates)] + pub fn from_public_key_affine_coordinates( + group: &EcGroupRef, + x: &BigNumRef, + y: &BigNumRef, + ) -> Result, ErrorStack> { + unsafe { + cvt_p(ffi::EC_KEY_new()) + .map(|p| EcKey::from_ptr(p)) + .and_then(|key| { + cvt(ffi::EC_KEY_set_group(key.as_ptr(), group.as_ptr())).map(|_| key) + }) + .and_then(|key| { + cvt(ffi::EC_KEY_set_public_key_affine_coordinates( + key.as_ptr(), + x.as_ptr(), + y.as_ptr(), + )) + .map(|_| key) + }) + } + } + + from_pem! { + /// Decodes a PEM-encoded SubjectPublicKeyInfo structure containing a EC key. + /// + /// The input should have a header of `-----BEGIN PUBLIC KEY-----`. + #[corresponds(PEM_read_bio_EC_PUBKEY)] + public_key_from_pem, + EcKey, + ffi::PEM_read_bio_EC_PUBKEY + } + + from_der! { + /// Decodes a DER-encoded SubjectPublicKeyInfo structure containing a EC key. + #[corresponds(d2i_EC_PUBKEY)] + public_key_from_der, + EcKey, + ffi::d2i_EC_PUBKEY + } +} + +impl EcKey { + /// Generates a new public/private key pair on the specified curve. + /// + /// # Examples + /// + /// ``` + /// # fn main() -> Result<(), Box> { + /// use openssl::bn::BigNumContext; + /// use openssl::nid::Nid; + /// use openssl::ec::{EcGroup, EcKey, PointConversionForm}; + /// + /// let nid = Nid::X9_62_PRIME256V1; // NIST P-256 curve + /// let group = EcGroup::from_curve_name(nid)?; + /// let key = EcKey::generate(&group)?; + /// + /// let mut ctx = BigNumContext::new()?; + /// + /// let public_key = &key.public_key().to_bytes( + /// &group, + /// PointConversionForm::COMPRESSED, + /// &mut ctx, + /// )?; + /// assert_eq!(public_key.len(), 33); + /// assert_ne!(public_key[0], 0x04); + /// + /// let private_key = key.private_key().to_vec(); + /// assert!(private_key.len() >= 31); + /// # Ok(()) } + /// ``` + #[corresponds(EC_KEY_generate_key)] + pub fn generate(group: &EcGroupRef) -> Result, ErrorStack> { + unsafe { + cvt_p(ffi::EC_KEY_new()) + .map(|p| EcKey::from_ptr(p)) + .and_then(|key| { + cvt(ffi::EC_KEY_set_group(key.as_ptr(), group.as_ptr())).map(|_| key) + }) + .and_then(|key| cvt(ffi::EC_KEY_generate_key(key.as_ptr())).map(|_| key)) + } + } + + /// Constructs an public/private key pair given a curve, a private key and a public key point. + #[corresponds(EC_KEY_set_private_key)] + pub fn from_private_components( + group: &EcGroupRef, + private_number: &BigNumRef, + public_key: &EcPointRef, + ) -> Result, ErrorStack> { + unsafe { + cvt_p(ffi::EC_KEY_new()) + .map(|p| EcKey::from_ptr(p)) + .and_then(|key| { + cvt(ffi::EC_KEY_set_group(key.as_ptr(), group.as_ptr())).map(|_| key) + }) + .and_then(|key| { + cvt(ffi::EC_KEY_set_private_key( + key.as_ptr(), + private_number.as_ptr(), + )) + .map(|_| key) + }) + .and_then(|key| { + cvt(ffi::EC_KEY_set_public_key( + key.as_ptr(), + public_key.as_ptr(), + )) + .map(|_| key) + }) + } + } + + private_key_from_pem! { + /// Deserializes a private key from a PEM-encoded ECPrivateKey structure. + /// + /// The input should have a header of `-----BEGIN EC PRIVATE KEY-----`. + #[corresponds(PEM_read_bio_ECPrivateKey)] + private_key_from_pem, + + /// Deserializes a private key from a PEM-encoded encrypted ECPrivateKey structure. + /// + /// The input should have a header of `-----BEGIN EC PRIVATE KEY-----`. + #[corresponds(PEM_read_bio_ECPrivateKey)] + private_key_from_pem_passphrase, + + /// Deserializes a private key from a PEM-encoded encrypted ECPrivateKey structure. + /// + /// The callback should fill the password into the provided buffer and return its length. + /// + /// The input should have a header of `-----BEGIN EC PRIVATE KEY-----`. + #[corresponds(PEM_read_bio_ECPrivateKey)] + private_key_from_pem_callback, + EcKey, + ffi::PEM_read_bio_ECPrivateKey + } + + from_der! { + /// Decodes a DER-encoded elliptic curve private key structure. + #[corresponds(d2i_ECPrivateKey)] + private_key_from_der, + EcKey, + ffi::d2i_ECPrivateKey + } +} + +impl Clone for EcKey { + fn clone(&self) -> EcKey { + (**self).to_owned() + } +} + +impl fmt::Debug for EcKey { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "EcKey") + } +} + +#[cfg(test)] +mod test { + use hex::FromHex; + + use super::*; + use crate::bn::{BigNum, BigNumContext}; + use crate::nid::Nid; + + #[test] + fn key_new_by_curve_name() { + EcKey::from_curve_name(Nid::X9_62_PRIME256V1).unwrap(); + } + + #[test] + fn generate() { + let group = EcGroup::from_curve_name(Nid::X9_62_PRIME256V1).unwrap(); + EcKey::generate(&group).unwrap(); + } + + #[test] + fn ec_group_from_components() { + // parameters are from secp256r1 + let p = BigNum::from_hex_str( + "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF", + ) + .unwrap(); + let a = BigNum::from_hex_str( + "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC", + ) + .unwrap(); + let b = BigNum::from_hex_str( + "5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B", + ) + .unwrap(); + let mut ctx = BigNumContext::new().unwrap(); + + let _curve = EcGroup::from_components(p, a, b, &mut ctx).unwrap(); + } + + #[test] + fn ec_point_set_affine() { + // parameters are from secp256r1 + let group = EcGroup::from_curve_name(Nid::X9_62_PRIME256V1).unwrap(); + let mut ctx = BigNumContext::new().unwrap(); + let mut gen_point = EcPoint::new(&group).unwrap(); + let gen_x = BigNum::from_hex_str( + "6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296", + ) + .unwrap(); + let gen_y = BigNum::from_hex_str( + "4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5", + ) + .unwrap(); + gen_point + .set_affine_coordinates_gfp(&group, &gen_x, &gen_y, &mut ctx) + .unwrap(); + assert!(gen_point.is_on_curve(&group, &mut ctx).unwrap()); + } + + #[test] + fn ec_group_set_generator() { + // parameters are from secp256r1 + let mut ctx = BigNumContext::new().unwrap(); + let p = BigNum::from_hex_str( + "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF", + ) + .unwrap(); + let a = BigNum::from_hex_str( + "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC", + ) + .unwrap(); + let b = BigNum::from_hex_str( + "5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B", + ) + .unwrap(); + + let mut group = EcGroup::from_components(p, a, b, &mut ctx).unwrap(); + + let mut gen_point = EcPoint::new(&group).unwrap(); + let gen_x = BigNum::from_hex_str( + "6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296", + ) + .unwrap(); + let gen_y = BigNum::from_hex_str( + "4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5", + ) + .unwrap(); + gen_point + .set_affine_coordinates_gfp(&group, &gen_x, &gen_y, &mut ctx) + .unwrap(); + + let order = BigNum::from_hex_str( + "FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551", + ) + .unwrap(); + let cofactor = BigNum::from_hex_str("01").unwrap(); + group.set_generator(gen_point, order, cofactor).unwrap(); + let mut constructed_order = BigNum::new().unwrap(); + group.order(&mut constructed_order, &mut ctx).unwrap(); + + let named_group = EcGroup::from_curve_name(Nid::X9_62_PRIME256V1).unwrap(); + let mut named_order = BigNum::new().unwrap(); + named_group.order(&mut named_order, &mut ctx).unwrap(); + + assert_eq!( + constructed_order.ucmp(&named_order), + std::cmp::Ordering::Equal + ); + } + + #[test] + fn cofactor() { + let group = EcGroup::from_curve_name(Nid::X9_62_PRIME256V1).unwrap(); + let mut ctx = BigNumContext::new().unwrap(); + let mut cofactor = BigNum::new().unwrap(); + group.cofactor(&mut cofactor, &mut ctx).unwrap(); + let one = BigNum::from_u32(1).unwrap(); + assert_eq!(cofactor, one); + } + + #[test] + #[allow(clippy::redundant_clone)] + fn dup() { + let group = EcGroup::from_curve_name(Nid::X9_62_PRIME256V1).unwrap(); + let key = EcKey::generate(&group).unwrap(); + drop(key.clone()); + } + + #[test] + fn point_new() { + let group = EcGroup::from_curve_name(Nid::X9_62_PRIME256V1).unwrap(); + EcPoint::new(&group).unwrap(); + } + + #[test] + fn point_bytes() { + let group = EcGroup::from_curve_name(Nid::X9_62_PRIME256V1).unwrap(); + let key = EcKey::generate(&group).unwrap(); + let point = key.public_key(); + let mut ctx = BigNumContext::new().unwrap(); + let bytes = point + .to_bytes(&group, PointConversionForm::COMPRESSED, &mut ctx) + .unwrap(); + let point2 = EcPoint::from_bytes(&group, &bytes, &mut ctx).unwrap(); + assert!(point.eq(&group, &point2, &mut ctx).unwrap()); + } + + #[test] + #[cfg(not(boringssl))] + fn point_hex_str() { + let group = EcGroup::from_curve_name(Nid::X9_62_PRIME256V1).unwrap(); + let key = EcKey::generate(&group).unwrap(); + let point = key.public_key(); + let mut ctx = BigNumContext::new().unwrap(); + let hex = point + .to_hex_str(&group, PointConversionForm::COMPRESSED, &mut ctx) + .unwrap(); + let point2 = EcPoint::from_hex_str(&group, &hex, &mut ctx).unwrap(); + assert!(point.eq(&group, &point2, &mut ctx).unwrap()); + } + + #[test] + fn point_owned() { + let group = EcGroup::from_curve_name(Nid::X9_62_PRIME256V1).unwrap(); + let key = EcKey::generate(&group).unwrap(); + let point = key.public_key(); + let owned = point.to_owned(&group).unwrap(); + let mut ctx = BigNumContext::new().unwrap(); + assert!(owned.eq(&group, point, &mut ctx).unwrap()); + } + + #[test] + fn mul_generator() { + let group = EcGroup::from_curve_name(Nid::X9_62_PRIME256V1).unwrap(); + let key = EcKey::generate(&group).unwrap(); + let mut ctx = BigNumContext::new().unwrap(); + let mut public_key = EcPoint::new(&group).unwrap(); + public_key + .mul_generator(&group, key.private_key(), &ctx) + .unwrap(); + assert!(public_key.eq(&group, key.public_key(), &mut ctx).unwrap()); + } + + #[test] + fn generator() { + let group = EcGroup::from_curve_name(Nid::X9_62_PRIME256V1).unwrap(); + let gen = group.generator(); + let one = BigNum::from_u32(1).unwrap(); + let mut ctx = BigNumContext::new().unwrap(); + let mut ecp = EcPoint::new(&group).unwrap(); + ecp.mul_generator(&group, &one, &ctx).unwrap(); + assert!(ecp.eq(&group, gen, &mut ctx).unwrap()); + } + + #[test] + fn key_from_public_key() { + let group = EcGroup::from_curve_name(Nid::X9_62_PRIME256V1).unwrap(); + let key = EcKey::generate(&group).unwrap(); + let mut ctx = BigNumContext::new().unwrap(); + let bytes = key + .public_key() + .to_bytes(&group, PointConversionForm::COMPRESSED, &mut ctx) + .unwrap(); + + drop(key); + let public_key = EcPoint::from_bytes(&group, &bytes, &mut ctx).unwrap(); + let ec_key = EcKey::from_public_key(&group, &public_key).unwrap(); + assert!(ec_key.check_key().is_ok()); + } + + #[test] + fn key_from_private_components() { + let group = EcGroup::from_curve_name(Nid::X9_62_PRIME256V1).unwrap(); + let key = EcKey::generate(&group).unwrap(); + + let dup_key = + EcKey::from_private_components(&group, key.private_key(), key.public_key()).unwrap(); + dup_key.check_key().unwrap(); + + assert!(key.private_key() == dup_key.private_key()); + } + + #[test] + fn key_from_affine_coordinates() { + let group = EcGroup::from_curve_name(Nid::X9_62_PRIME256V1).unwrap(); + let x = Vec::from_hex("30a0424cd21c2944838a2d75c92b37e76ea20d9f00893a3b4eee8a3c0aafec3e") + .unwrap(); + let y = Vec::from_hex("e04b65e92456d9888b52b379bdfbd51ee869ef1f0fc65b6659695b6cce081723") + .unwrap(); + + let xbn = BigNum::from_slice(&x).unwrap(); + let ybn = BigNum::from_slice(&y).unwrap(); + + let ec_key = EcKey::from_public_key_affine_coordinates(&group, &xbn, &ybn).unwrap(); + assert!(ec_key.check_key().is_ok()); + } + + #[cfg(any(ossl111, boringssl, libressl350))] + #[test] + fn get_affine_coordinates() { + let group = EcGroup::from_curve_name(Nid::X9_62_PRIME256V1).unwrap(); + let x = Vec::from_hex("30a0424cd21c2944838a2d75c92b37e76ea20d9f00893a3b4eee8a3c0aafec3e") + .unwrap(); + let y = Vec::from_hex("e04b65e92456d9888b52b379bdfbd51ee869ef1f0fc65b6659695b6cce081723") + .unwrap(); + + let xbn = BigNum::from_slice(&x).unwrap(); + let ybn = BigNum::from_slice(&y).unwrap(); + + let ec_key = EcKey::from_public_key_affine_coordinates(&group, &xbn, &ybn).unwrap(); + + let mut xbn2 = BigNum::new().unwrap(); + let mut ybn2 = BigNum::new().unwrap(); + let mut ctx = BigNumContext::new().unwrap(); + let ec_key_pk = ec_key.public_key(); + ec_key_pk + .affine_coordinates(&group, &mut xbn2, &mut ybn2, &mut ctx) + .unwrap(); + assert_eq!(xbn2, xbn); + assert_eq!(ybn2, ybn); + } + + #[test] + fn get_affine_coordinates_gfp() { + let group = EcGroup::from_curve_name(Nid::X9_62_PRIME256V1).unwrap(); + let x = Vec::from_hex("30a0424cd21c2944838a2d75c92b37e76ea20d9f00893a3b4eee8a3c0aafec3e") + .unwrap(); + let y = Vec::from_hex("e04b65e92456d9888b52b379bdfbd51ee869ef1f0fc65b6659695b6cce081723") + .unwrap(); + + let xbn = BigNum::from_slice(&x).unwrap(); + let ybn = BigNum::from_slice(&y).unwrap(); + + let ec_key = EcKey::from_public_key_affine_coordinates(&group, &xbn, &ybn).unwrap(); + + let mut xbn2 = BigNum::new().unwrap(); + let mut ybn2 = BigNum::new().unwrap(); + let mut ctx = BigNumContext::new().unwrap(); + let ec_key_pk = ec_key.public_key(); + ec_key_pk + .affine_coordinates_gfp(&group, &mut xbn2, &mut ybn2, &mut ctx) + .unwrap(); + assert_eq!(xbn2, xbn); + assert_eq!(ybn2, ybn); + } + + #[test] + fn is_infinity() { + let group = EcGroup::from_curve_name(Nid::X9_62_PRIME256V1).unwrap(); + let mut ctx = BigNumContext::new().unwrap(); + let g = group.generator(); + assert!(!g.is_infinity(&group)); + + let mut order = BigNum::new().unwrap(); + group.order(&mut order, &mut ctx).unwrap(); + let mut inf = EcPoint::new(&group).unwrap(); + inf.mul_generator(&group, &order, &ctx).unwrap(); + assert!(inf.is_infinity(&group)); + } + + #[test] + #[cfg(not(osslconf = "OPENSSL_NO_EC2M"))] + fn is_on_curve() { + let group = EcGroup::from_curve_name(Nid::X9_62_PRIME256V1).unwrap(); + let mut ctx = BigNumContext::new().unwrap(); + let g = group.generator(); + assert!(g.is_on_curve(&group, &mut ctx).unwrap()); + + let group2 = EcGroup::from_curve_name(Nid::X9_62_PRIME239V3).unwrap(); + assert!(!g.is_on_curve(&group2, &mut ctx).unwrap()); + } + + #[test] + #[cfg(any(boringssl, ossl111, libressl350))] + fn asn1_flag() { + let group = EcGroup::from_curve_name(Nid::X9_62_PRIME256V1).unwrap(); + let flag = group.asn1_flag(); + assert_eq!(flag, Asn1Flag::NAMED_CURVE); + } +} diff --git a/vendor/openssl/src/ecdsa.rs b/vendor/openssl/src/ecdsa.rs new file mode 100644 index 0000000..26c6ddd --- /dev/null +++ b/vendor/openssl/src/ecdsa.rs @@ -0,0 +1,224 @@ +//! Low level Elliptic Curve Digital Signature Algorithm (ECDSA) functions. + +use cfg_if::cfg_if; +use foreign_types::{ForeignType, ForeignTypeRef}; +use libc::c_int; +use std::mem; +use std::ptr; + +use crate::bn::{BigNum, BigNumRef}; +use crate::ec::EcKeyRef; +use crate::error::ErrorStack; +use crate::pkey::{HasPrivate, HasPublic}; +use crate::util::ForeignTypeRefExt; +use crate::{cvt_n, cvt_p, LenType}; +use openssl_macros::corresponds; + +foreign_type_and_impl_send_sync! { + type CType = ffi::ECDSA_SIG; + fn drop = ffi::ECDSA_SIG_free; + + /// A low level interface to ECDSA. + pub struct EcdsaSig; + /// A reference to an [`EcdsaSig`]. + pub struct EcdsaSigRef; +} + +impl EcdsaSig { + /// Computes a digital signature of the hash value `data` using the private EC key eckey. + #[corresponds(ECDSA_do_sign)] + pub fn sign(data: &[u8], eckey: &EcKeyRef) -> Result + where + T: HasPrivate, + { + unsafe { + assert!(data.len() <= c_int::MAX as usize); + let sig = cvt_p(ffi::ECDSA_do_sign( + data.as_ptr(), + data.len() as LenType, + eckey.as_ptr(), + ))?; + Ok(EcdsaSig::from_ptr(sig)) + } + } + + /// Returns a new `EcdsaSig` by setting the `r` and `s` values associated with an ECDSA signature. + #[corresponds(ECDSA_SIG_set0)] + pub fn from_private_components(r: BigNum, s: BigNum) -> Result { + unsafe { + let sig = cvt_p(ffi::ECDSA_SIG_new())?; + ECDSA_SIG_set0(sig, r.as_ptr(), s.as_ptr()); + mem::forget((r, s)); + Ok(EcdsaSig::from_ptr(sig)) + } + } + + from_der! { + /// Decodes a DER-encoded ECDSA signature. + #[corresponds(d2i_ECDSA_SIG)] + from_der, + EcdsaSig, + ffi::d2i_ECDSA_SIG + } +} + +impl EcdsaSigRef { + to_der! { + /// Serializes the ECDSA signature into a DER-encoded ECDSASignature structure. + #[corresponds(i2d_ECDSA_SIG)] + to_der, + ffi::i2d_ECDSA_SIG + } + + /// Verifies if the signature is a valid ECDSA signature using the given public key. + #[corresponds(ECDSA_do_verify)] + pub fn verify(&self, data: &[u8], eckey: &EcKeyRef) -> Result + where + T: HasPublic, + { + unsafe { + assert!(data.len() <= c_int::MAX as usize); + cvt_n(ffi::ECDSA_do_verify( + data.as_ptr(), + data.len() as LenType, + self.as_ptr(), + eckey.as_ptr(), + )) + .map(|x| x == 1) + } + } + + /// Returns internal component: `r` of an `EcdsaSig`. (See X9.62 or FIPS 186-2) + #[corresponds(ECDSA_SIG_get0)] + pub fn r(&self) -> &BigNumRef { + unsafe { + let mut r = ptr::null(); + ECDSA_SIG_get0(self.as_ptr(), &mut r, ptr::null_mut()); + BigNumRef::from_const_ptr(r) + } + } + + /// Returns internal components: `s` of an `EcdsaSig`. (See X9.62 or FIPS 186-2) + #[corresponds(ECDSA_SIG_get0)] + pub fn s(&self) -> &BigNumRef { + unsafe { + let mut s = ptr::null(); + ECDSA_SIG_get0(self.as_ptr(), ptr::null_mut(), &mut s); + BigNumRef::from_const_ptr(s) + } + } +} + +cfg_if! { + if #[cfg(any(ossl110, libressl273, boringssl))] { + use ffi::{ECDSA_SIG_set0, ECDSA_SIG_get0}; + } else { + #[allow(bad_style)] + unsafe fn ECDSA_SIG_set0( + sig: *mut ffi::ECDSA_SIG, + r: *mut ffi::BIGNUM, + s: *mut ffi::BIGNUM, + ) -> c_int { + if r.is_null() || s.is_null() { + return 0; + } + ffi::BN_clear_free((*sig).r); + ffi::BN_clear_free((*sig).s); + (*sig).r = r; + (*sig).s = s; + 1 + } + + #[allow(bad_style)] + unsafe fn ECDSA_SIG_get0( + sig: *const ffi::ECDSA_SIG, + pr: *mut *const ffi::BIGNUM, + ps: *mut *const ffi::BIGNUM) + { + if !pr.is_null() { + (*pr) = (*sig).r; + } + if !ps.is_null() { + (*ps) = (*sig).s; + } + } + } +} + +#[cfg(test)] +mod test { + use super::*; + use crate::ec::EcGroup; + use crate::ec::EcKey; + use crate::nid::Nid; + use crate::pkey::{Private, Public}; + + fn get_public_key(group: &EcGroup, x: &EcKey) -> Result, ErrorStack> { + EcKey::from_public_key(group, x.public_key()) + } + + #[test] + #[cfg_attr(osslconf = "OPENSSL_NO_EC", ignore)] + fn sign_and_verify() { + let group = EcGroup::from_curve_name(Nid::X9_62_PRIME256V1).unwrap(); + let private_key = EcKey::generate(&group).unwrap(); + let public_key = get_public_key(&group, &private_key).unwrap(); + + let private_key2 = EcKey::generate(&group).unwrap(); + let public_key2 = get_public_key(&group, &private_key2).unwrap(); + + let data = String::from("hello"); + let res = EcdsaSig::sign(data.as_bytes(), &private_key).unwrap(); + + // Signature can be verified using the correct data & correct public key + let verification = res.verify(data.as_bytes(), &public_key).unwrap(); + assert!(verification); + + // Signature will not be verified using the incorrect data but the correct public key + let verification2 = res + .verify(String::from("hello2").as_bytes(), &public_key) + .unwrap(); + assert!(!verification2); + + // Signature will not be verified using the correct data but the incorrect public key + let verification3 = res.verify(data.as_bytes(), &public_key2).unwrap(); + assert!(!verification3); + } + + #[test] + #[cfg_attr(osslconf = "OPENSSL_NO_EC", ignore)] + fn check_private_components() { + let group = EcGroup::from_curve_name(Nid::X9_62_PRIME256V1).unwrap(); + let private_key = EcKey::generate(&group).unwrap(); + let public_key = get_public_key(&group, &private_key).unwrap(); + let data = String::from("hello"); + let res = EcdsaSig::sign(data.as_bytes(), &private_key).unwrap(); + + let verification = res.verify(data.as_bytes(), &public_key).unwrap(); + assert!(verification); + + let r = res.r().to_owned().unwrap(); + let s = res.s().to_owned().unwrap(); + + let res2 = EcdsaSig::from_private_components(r, s).unwrap(); + let verification2 = res2.verify(data.as_bytes(), &public_key).unwrap(); + assert!(verification2); + } + + #[test] + #[cfg_attr(osslconf = "OPENSSL_NO_EC", ignore)] + fn serialize_deserialize() { + let group = EcGroup::from_curve_name(Nid::X9_62_PRIME256V1).unwrap(); + let private_key = EcKey::generate(&group).unwrap(); + let public_key = get_public_key(&group, &private_key).unwrap(); + + let data = String::from("hello"); + let res = EcdsaSig::sign(data.as_bytes(), &private_key).unwrap(); + + let der = res.to_der().unwrap(); + let sig = EcdsaSig::from_der(&der).unwrap(); + + let verification = sig.verify(data.as_bytes(), &public_key).unwrap(); + assert!(verification); + } +} diff --git a/vendor/openssl/src/encrypt.rs b/vendor/openssl/src/encrypt.rs new file mode 100644 index 0000000..c50be08 --- /dev/null +++ b/vendor/openssl/src/encrypt.rs @@ -0,0 +1,578 @@ +//! Message encryption. +//! +//! The [`Encrypter`] allows for encryption of data given a public key. The [`Decrypter`] can be +//! used with the corresponding private key to decrypt the data. +//! +//! # Examples +//! +//! Encrypt and decrypt data given an RSA keypair: +//! +//! ```rust +//! use openssl::encrypt::{Encrypter, Decrypter}; +//! use openssl::rsa::{Rsa, Padding}; +//! use openssl::pkey::PKey; +//! +//! // Generate a keypair +//! let keypair = Rsa::generate(2048).unwrap(); +//! let keypair = PKey::from_rsa(keypair).unwrap(); +//! +//! let data = b"hello, world!"; +//! +//! // Encrypt the data with RSA PKCS1 +//! let mut encrypter = Encrypter::new(&keypair).unwrap(); +//! encrypter.set_rsa_padding(Padding::PKCS1).unwrap(); +//! // Create an output buffer +//! let buffer_len = encrypter.encrypt_len(data).unwrap(); +//! let mut encrypted = vec![0; buffer_len]; +//! // Encrypt and truncate the buffer +//! let encrypted_len = encrypter.encrypt(data, &mut encrypted).unwrap(); +//! encrypted.truncate(encrypted_len); +//! +//! // Decrypt the data +//! let mut decrypter = Decrypter::new(&keypair).unwrap(); +//! decrypter.set_rsa_padding(Padding::PKCS1).unwrap(); +//! // Create an output buffer +//! let buffer_len = decrypter.decrypt_len(&encrypted).unwrap(); +//! let mut decrypted = vec![0; buffer_len]; +//! // Encrypt and truncate the buffer +//! let decrypted_len = decrypter.decrypt(&encrypted, &mut decrypted).unwrap(); +//! decrypted.truncate(decrypted_len); +//! assert_eq!(&*decrypted, data); +//! ``` +#[cfg(any(ossl102, libressl310))] +use libc::c_int; +use std::{marker::PhantomData, ptr}; + +use crate::error::ErrorStack; +use crate::hash::MessageDigest; +use crate::pkey::{HasPrivate, HasPublic, PKeyRef}; +use crate::rsa::Padding; +use crate::{cvt, cvt_p}; +use foreign_types::ForeignTypeRef; + +/// A type which encrypts data. +pub struct Encrypter<'a> { + pctx: *mut ffi::EVP_PKEY_CTX, + _p: PhantomData<&'a ()>, +} + +unsafe impl Sync for Encrypter<'_> {} +unsafe impl Send for Encrypter<'_> {} + +impl Drop for Encrypter<'_> { + fn drop(&mut self) { + unsafe { + ffi::EVP_PKEY_CTX_free(self.pctx); + } + } +} + +impl<'a> Encrypter<'a> { + /// Creates a new `Encrypter`. + /// + /// OpenSSL documentation at [`EVP_PKEY_encrypt_init`]. + /// + /// [`EVP_PKEY_encrypt_init`]: https://www.openssl.org/docs/manmaster/man3/EVP_PKEY_encrypt_init.html + pub fn new(pkey: &'a PKeyRef) -> Result, ErrorStack> + where + T: HasPublic, + { + unsafe { + ffi::init(); + + let pctx = cvt_p(ffi::EVP_PKEY_CTX_new(pkey.as_ptr(), ptr::null_mut()))?; + let r = ffi::EVP_PKEY_encrypt_init(pctx); + if r != 1 { + ffi::EVP_PKEY_CTX_free(pctx); + return Err(ErrorStack::get()); + } + + Ok(Encrypter { + pctx, + _p: PhantomData, + }) + } + } + + /// Returns the RSA padding mode in use. + /// + /// This is only useful for RSA keys. + /// + /// This corresponds to `EVP_PKEY_CTX_get_rsa_padding`. + pub fn rsa_padding(&self) -> Result { + unsafe { + let mut pad = 0; + cvt(ffi::EVP_PKEY_CTX_get_rsa_padding(self.pctx, &mut pad)) + .map(|_| Padding::from_raw(pad)) + } + } + + /// Sets the RSA padding mode. + /// + /// This is only useful for RSA keys. + /// + /// This corresponds to [`EVP_PKEY_CTX_set_rsa_padding`]. + /// + /// [`EVP_PKEY_CTX_set_rsa_padding`]: https://www.openssl.org/docs/manmaster/crypto/EVP_PKEY_CTX_set_rsa_padding.html + pub fn set_rsa_padding(&mut self, padding: Padding) -> Result<(), ErrorStack> { + unsafe { + cvt(ffi::EVP_PKEY_CTX_set_rsa_padding( + self.pctx, + padding.as_raw(), + )) + .map(|_| ()) + } + } + + /// Sets the RSA MGF1 algorithm. + /// + /// This is only useful for RSA keys. + /// + /// This corresponds to [`EVP_PKEY_CTX_set_rsa_mgf1_md`]. + /// + /// [`EVP_PKEY_CTX_set_rsa_mgf1_md`]: https://www.openssl.org/docs/manmaster/man7/RSA-PSS.html + pub fn set_rsa_mgf1_md(&mut self, md: MessageDigest) -> Result<(), ErrorStack> { + unsafe { + cvt(ffi::EVP_PKEY_CTX_set_rsa_mgf1_md( + self.pctx, + md.as_ptr() as *mut _, + )) + .map(|_| ()) + } + } + + /// Sets the RSA OAEP algorithm. + /// + /// This is only useful for RSA keys. + /// + /// This corresponds to [`EVP_PKEY_CTX_set_rsa_oaep_md`]. + /// + /// [`EVP_PKEY_CTX_set_rsa_oaep_md`]: https://www.openssl.org/docs/manmaster/man3/EVP_PKEY_CTX_set_rsa_oaep_md.html + #[cfg(any(ossl102, libressl310))] + pub fn set_rsa_oaep_md(&mut self, md: MessageDigest) -> Result<(), ErrorStack> { + unsafe { + cvt(ffi::EVP_PKEY_CTX_set_rsa_oaep_md( + self.pctx, + md.as_ptr() as *mut _, + )) + .map(|_| ()) + } + } + + /// Sets the RSA OAEP label. + /// + /// This is only useful for RSA keys. + /// + /// This corresponds to [`EVP_PKEY_CTX_set0_rsa_oaep_label`]. + /// + /// [`EVP_PKEY_CTX_set0_rsa_oaep_label`]: https://www.openssl.org/docs/manmaster/man3/EVP_PKEY_CTX_set0_rsa_oaep_label.html + #[cfg(any(ossl102, libressl310))] + pub fn set_rsa_oaep_label(&mut self, label: &[u8]) -> Result<(), ErrorStack> { + unsafe { + let p = cvt_p(ffi::OPENSSL_malloc(label.len() as _))?; + ptr::copy_nonoverlapping(label.as_ptr(), p as *mut u8, label.len()); + + cvt(ffi::EVP_PKEY_CTX_set0_rsa_oaep_label( + self.pctx, + p, + label.len() as c_int, + )) + .map(|_| ()) + .map_err(|e| { + ffi::OPENSSL_free(p); + e + }) + } + } + + /// Performs public key encryption. + /// + /// In order to know the size needed for the output buffer, use [`encrypt_len`](Encrypter::encrypt_len). + /// Note that the length of the output buffer can be greater of the length of the encoded data. + /// ``` + /// # use openssl::{ + /// # encrypt::Encrypter, + /// # pkey::PKey, + /// # rsa::{Rsa, Padding}, + /// # }; + /// # + /// # let key = include_bytes!("../test/rsa.pem"); + /// # let private_key = Rsa::private_key_from_pem(key).unwrap(); + /// # let pkey = PKey::from_rsa(private_key).unwrap(); + /// # let input = b"hello world".to_vec(); + /// # + /// let mut encrypter = Encrypter::new(&pkey).unwrap(); + /// encrypter.set_rsa_padding(Padding::PKCS1).unwrap(); + /// + /// // Get the length of the output buffer + /// let buffer_len = encrypter.encrypt_len(&input).unwrap(); + /// let mut encoded = vec![0u8; buffer_len]; + /// + /// // Encode the data and get its length + /// let encoded_len = encrypter.encrypt(&input, &mut encoded).unwrap(); + /// + /// // Use only the part of the buffer with the encoded data + /// let encoded = &encoded[..encoded_len]; + /// ``` + /// + /// This corresponds to [`EVP_PKEY_encrypt`]. + /// + /// [`EVP_PKEY_encrypt`]: https://www.openssl.org/docs/manmaster/man3/EVP_PKEY_encrypt.html + pub fn encrypt(&self, from: &[u8], to: &mut [u8]) -> Result { + let mut written = to.len(); + unsafe { + cvt(ffi::EVP_PKEY_encrypt( + self.pctx, + to.as_mut_ptr(), + &mut written, + from.as_ptr(), + from.len(), + ))?; + } + + Ok(written) + } + + /// Gets the size of the buffer needed to encrypt the input data. + /// + /// This corresponds to [`EVP_PKEY_encrypt`] called with a null pointer as output argument. + /// + /// [`EVP_PKEY_encrypt`]: https://www.openssl.org/docs/manmaster/man3/EVP_PKEY_encrypt.html + pub fn encrypt_len(&self, from: &[u8]) -> Result { + let mut written = 0; + unsafe { + cvt(ffi::EVP_PKEY_encrypt( + self.pctx, + ptr::null_mut(), + &mut written, + from.as_ptr(), + from.len(), + ))?; + } + + Ok(written) + } +} + +/// A type which decrypts data. +pub struct Decrypter<'a> { + pctx: *mut ffi::EVP_PKEY_CTX, + _p: PhantomData<&'a ()>, +} + +unsafe impl Sync for Decrypter<'_> {} +unsafe impl Send for Decrypter<'_> {} + +impl Drop for Decrypter<'_> { + fn drop(&mut self) { + unsafe { + ffi::EVP_PKEY_CTX_free(self.pctx); + } + } +} + +impl<'a> Decrypter<'a> { + /// Creates a new `Decrypter`. + /// + /// OpenSSL documentation at [`EVP_PKEY_decrypt_init`]. + /// + /// [`EVP_PKEY_decrypt_init`]: https://www.openssl.org/docs/manmaster/man3/EVP_PKEY_decrypt_init.html + pub fn new(pkey: &'a PKeyRef) -> Result, ErrorStack> + where + T: HasPrivate, + { + unsafe { + ffi::init(); + + let pctx = cvt_p(ffi::EVP_PKEY_CTX_new(pkey.as_ptr(), ptr::null_mut()))?; + let r = ffi::EVP_PKEY_decrypt_init(pctx); + if r != 1 { + ffi::EVP_PKEY_CTX_free(pctx); + return Err(ErrorStack::get()); + } + + Ok(Decrypter { + pctx, + _p: PhantomData, + }) + } + } + + /// Returns the RSA padding mode in use. + /// + /// This is only useful for RSA keys. + /// + /// This corresponds to `EVP_PKEY_CTX_get_rsa_padding`. + pub fn rsa_padding(&self) -> Result { + unsafe { + let mut pad = 0; + cvt(ffi::EVP_PKEY_CTX_get_rsa_padding(self.pctx, &mut pad)) + .map(|_| Padding::from_raw(pad)) + } + } + + /// Sets the RSA padding mode. + /// + /// This is only useful for RSA keys. + /// + /// This corresponds to [`EVP_PKEY_CTX_set_rsa_padding`]. + /// + /// [`EVP_PKEY_CTX_set_rsa_padding`]: https://www.openssl.org/docs/manmaster/crypto/EVP_PKEY_CTX_set_rsa_padding.html + pub fn set_rsa_padding(&mut self, padding: Padding) -> Result<(), ErrorStack> { + unsafe { + cvt(ffi::EVP_PKEY_CTX_set_rsa_padding( + self.pctx, + padding.as_raw(), + )) + .map(|_| ()) + } + } + + /// Sets the RSA MGF1 algorithm. + /// + /// This is only useful for RSA keys. + /// + /// This corresponds to [`EVP_PKEY_CTX_set_rsa_mgf1_md`]. + /// + /// [`EVP_PKEY_CTX_set_rsa_mgf1_md`]: https://www.openssl.org/docs/manmaster/man7/RSA-PSS.html + pub fn set_rsa_mgf1_md(&mut self, md: MessageDigest) -> Result<(), ErrorStack> { + unsafe { + cvt(ffi::EVP_PKEY_CTX_set_rsa_mgf1_md( + self.pctx, + md.as_ptr() as *mut _, + )) + .map(|_| ()) + } + } + + /// Sets the RSA OAEP algorithm. + /// + /// This is only useful for RSA keys. + /// + /// This corresponds to [`EVP_PKEY_CTX_set_rsa_oaep_md`]. + /// + /// [`EVP_PKEY_CTX_set_rsa_oaep_md`]: https://www.openssl.org/docs/manmaster/man3/EVP_PKEY_CTX_set_rsa_oaep_md.html + #[cfg(any(ossl102, libressl310))] + pub fn set_rsa_oaep_md(&mut self, md: MessageDigest) -> Result<(), ErrorStack> { + unsafe { + cvt(ffi::EVP_PKEY_CTX_set_rsa_oaep_md( + self.pctx, + md.as_ptr() as *mut _, + )) + .map(|_| ()) + } + } + + /// Sets the RSA OAEP label. + /// + /// This is only useful for RSA keys. + /// + /// This corresponds to [`EVP_PKEY_CTX_set0_rsa_oaep_label`]. + /// + /// [`EVP_PKEY_CTX_set0_rsa_oaep_label`]: https://www.openssl.org/docs/manmaster/man3/EVP_PKEY_CTX_set0_rsa_oaep_label.html + #[cfg(any(ossl102, libressl310))] + pub fn set_rsa_oaep_label(&mut self, label: &[u8]) -> Result<(), ErrorStack> { + unsafe { + let p = cvt_p(ffi::OPENSSL_malloc(label.len() as _))?; + ptr::copy_nonoverlapping(label.as_ptr(), p as *mut u8, label.len()); + + cvt(ffi::EVP_PKEY_CTX_set0_rsa_oaep_label( + self.pctx, + p, + label.len() as c_int, + )) + .map(|_| ()) + .map_err(|e| { + ffi::OPENSSL_free(p); + e + }) + } + } + + /// Performs public key decryption. + /// + /// In order to know the size needed for the output buffer, use [`decrypt_len`](Decrypter::decrypt_len). + /// Note that the length of the output buffer can be greater of the length of the decoded data. + /// ``` + /// # use openssl::{ + /// # encrypt::Decrypter, + /// # pkey::PKey, + /// # rsa::{Rsa, Padding}, + /// # }; + /// # + /// # const INPUT: &[u8] = b"\ + /// # \x26\xa1\xc1\x13\xc5\x7f\xb4\x9f\xa0\xb4\xde\x61\x5e\x2e\xc6\xfb\x76\x5c\xd1\x2b\x5f\ + /// # \x1d\x36\x60\xfa\xf8\xe8\xb3\x21\xf4\x9c\x70\xbc\x03\xea\xea\xac\xce\x4b\xb3\xf6\x45\ + /// # \xcc\xb3\x80\x9e\xa8\xf7\xc3\x5d\x06\x12\x7a\xa3\x0c\x30\x67\xf1\xe7\x94\x6c\xf6\x26\ + /// # \xac\x28\x17\x59\x69\xe1\xdc\xed\x7e\xc0\xe9\x62\x57\x49\xce\xdd\x13\x07\xde\x18\x03\ + /// # \x0f\x9d\x61\x65\xb9\x23\x8c\x78\x4b\xad\x23\x49\x75\x47\x64\xa0\xa0\xa2\x90\xc1\x49\ + /// # \x1b\x05\x24\xc2\xe9\x2c\x0d\x49\x78\x72\x61\x72\xed\x8b\x6f\x8a\xe8\xca\x05\x5c\x58\ + /// # \xd6\x95\xd6\x7b\xe3\x2d\x0d\xaa\x3e\x6d\x3c\x9a\x1c\x1d\xb4\x6c\x42\x9d\x9a\x82\x55\ + /// # \xd9\xde\xc8\x08\x7b\x17\xac\xd7\xaf\x86\x7b\x69\x9e\x3c\xf4\x5e\x1c\x39\x52\x6d\x62\ + /// # \x50\x51\xbd\xa6\xc8\x4e\xe9\x34\xf0\x37\x0d\xa9\xa9\x77\xe6\xf5\xc2\x47\x2d\xa8\xee\ + /// # \x3f\x69\x78\xff\xa9\xdc\x70\x22\x20\x9a\x5c\x9b\x70\x15\x90\xd3\xb4\x0e\x54\x9e\x48\ + /// # \xed\xb6\x2c\x88\xfc\xb4\xa9\x37\x10\xfa\x71\xb2\xec\x75\xe7\xe7\x0e\xf4\x60\x2c\x7b\ + /// # \x58\xaf\xa0\x53\xbd\x24\xf1\x12\xe3\x2e\x99\x25\x0a\x54\x54\x9d\xa1\xdb\xca\x41\x85\ + /// # \xf4\x62\x78\x64"; + /// # + /// # let key = include_bytes!("../test/rsa.pem"); + /// # let private_key = Rsa::private_key_from_pem(key).unwrap(); + /// # let pkey = PKey::from_rsa(private_key).unwrap(); + /// # let input = INPUT.to_vec(); + /// # + /// let mut decrypter = Decrypter::new(&pkey).unwrap(); + /// decrypter.set_rsa_padding(Padding::PKCS1).unwrap(); + /// + /// // Get the length of the output buffer + /// let buffer_len = decrypter.decrypt_len(&input).unwrap(); + /// let mut decoded = vec![0u8; buffer_len]; + /// + /// // Decrypt the data and get its length + /// let decoded_len = decrypter.decrypt(&input, &mut decoded).unwrap(); + /// + /// // Use only the part of the buffer with the decrypted data + /// let decoded = &decoded[..decoded_len]; + /// ``` + /// + /// This corresponds to [`EVP_PKEY_decrypt`]. + /// + /// [`EVP_PKEY_decrypt`]: https://www.openssl.org/docs/manmaster/man3/EVP_PKEY_decrypt.html + pub fn decrypt(&self, from: &[u8], to: &mut [u8]) -> Result { + let mut written = to.len(); + unsafe { + cvt(ffi::EVP_PKEY_decrypt( + self.pctx, + to.as_mut_ptr(), + &mut written, + from.as_ptr(), + from.len(), + ))?; + } + + Ok(written) + } + + /// Gets the size of the buffer needed to decrypt the input data. + /// + /// This corresponds to [`EVP_PKEY_decrypt`] called with a null pointer as output argument. + /// + /// [`EVP_PKEY_decrypt`]: https://www.openssl.org/docs/manmaster/man3/EVP_PKEY_decrypt.html + pub fn decrypt_len(&self, from: &[u8]) -> Result { + let mut written = 0; + unsafe { + cvt(ffi::EVP_PKEY_decrypt( + self.pctx, + ptr::null_mut(), + &mut written, + from.as_ptr(), + from.len(), + ))?; + } + + Ok(written) + } +} + +#[cfg(test)] +mod test { + use hex::FromHex; + + use crate::encrypt::{Decrypter, Encrypter}; + #[cfg(any(ossl102, libressl310))] + use crate::hash::MessageDigest; + use crate::pkey::PKey; + use crate::rsa::{Padding, Rsa}; + + const INPUT: &str = + "65794a68624763694f694a53557a49314e694a392e65794a7063334d694f694a71623255694c41304b49434a6c\ + 654841694f6a457a4d4441344d546b7a4f44417344516f67496d6830644841364c79396c654746746347786c4c\ + 6d4e76625339706331397962323930496a7030636e566c6651"; + + #[test] + fn rsa_encrypt_decrypt() { + let key = include_bytes!("../test/rsa.pem"); + let private_key = Rsa::private_key_from_pem(key).unwrap(); + let pkey = PKey::from_rsa(private_key).unwrap(); + + let mut encrypter = Encrypter::new(&pkey).unwrap(); + encrypter.set_rsa_padding(Padding::PKCS1).unwrap(); + let input = Vec::from_hex(INPUT).unwrap(); + let buffer_len = encrypter.encrypt_len(&input).unwrap(); + let mut encoded = vec![0u8; buffer_len]; + let encoded_len = encrypter.encrypt(&input, &mut encoded).unwrap(); + let encoded = &encoded[..encoded_len]; + + let mut decrypter = Decrypter::new(&pkey).unwrap(); + decrypter.set_rsa_padding(Padding::PKCS1).unwrap(); + let buffer_len = decrypter.decrypt_len(encoded).unwrap(); + let mut decoded = vec![0u8; buffer_len]; + let decoded_len = decrypter.decrypt(encoded, &mut decoded).unwrap(); + let decoded = &decoded[..decoded_len]; + + assert_eq!(decoded, &*input); + } + + #[test] + #[cfg(any(ossl102, libressl310))] + fn rsa_encrypt_decrypt_with_sha256() { + let key = include_bytes!("../test/rsa.pem"); + let private_key = Rsa::private_key_from_pem(key).unwrap(); + let pkey = PKey::from_rsa(private_key).unwrap(); + + let md = MessageDigest::sha256(); + + let mut encrypter = Encrypter::new(&pkey).unwrap(); + encrypter.set_rsa_padding(Padding::PKCS1_OAEP).unwrap(); + encrypter.set_rsa_oaep_md(md).unwrap(); + encrypter.set_rsa_mgf1_md(md).unwrap(); + let input = Vec::from_hex(INPUT).unwrap(); + let buffer_len = encrypter.encrypt_len(&input).unwrap(); + let mut encoded = vec![0u8; buffer_len]; + let encoded_len = encrypter.encrypt(&input, &mut encoded).unwrap(); + let encoded = &encoded[..encoded_len]; + + let mut decrypter = Decrypter::new(&pkey).unwrap(); + decrypter.set_rsa_padding(Padding::PKCS1_OAEP).unwrap(); + decrypter.set_rsa_oaep_md(md).unwrap(); + decrypter.set_rsa_mgf1_md(md).unwrap(); + let buffer_len = decrypter.decrypt_len(encoded).unwrap(); + let mut decoded = vec![0u8; buffer_len]; + let decoded_len = decrypter.decrypt(encoded, &mut decoded).unwrap(); + let decoded = &decoded[..decoded_len]; + + assert_eq!(decoded, &*input); + } + + #[test] + #[cfg(any(ossl102, libressl310))] + fn rsa_encrypt_decrypt_oaep_label() { + let key = include_bytes!("../test/rsa.pem"); + let private_key = Rsa::private_key_from_pem(key).unwrap(); + let pkey = PKey::from_rsa(private_key).unwrap(); + + let mut encrypter = Encrypter::new(&pkey).unwrap(); + encrypter.set_rsa_padding(Padding::PKCS1_OAEP).unwrap(); + encrypter.set_rsa_oaep_label(b"test_oaep_label").unwrap(); + let input = Vec::from_hex(INPUT).unwrap(); + let buffer_len = encrypter.encrypt_len(&input).unwrap(); + let mut encoded = vec![0u8; buffer_len]; + let encoded_len = encrypter.encrypt(&input, &mut encoded).unwrap(); + let encoded = &encoded[..encoded_len]; + + let mut decrypter = Decrypter::new(&pkey).unwrap(); + decrypter.set_rsa_padding(Padding::PKCS1_OAEP).unwrap(); + decrypter.set_rsa_oaep_label(b"test_oaep_label").unwrap(); + let buffer_len = decrypter.decrypt_len(encoded).unwrap(); + let mut decoded = vec![0u8; buffer_len]; + let decoded_len = decrypter.decrypt(encoded, &mut decoded).unwrap(); + let decoded = &decoded[..decoded_len]; + + assert_eq!(decoded, &*input); + + decrypter.set_rsa_oaep_label(b"wrong_oaep_label").unwrap(); + let buffer_len = decrypter.decrypt_len(encoded).unwrap(); + let mut decoded = vec![0u8; buffer_len]; + + assert!(decrypter.decrypt(encoded, &mut decoded).is_err()); + } +} diff --git a/vendor/openssl/src/envelope.rs b/vendor/openssl/src/envelope.rs new file mode 100644 index 0000000..f6ebc72 --- /dev/null +++ b/vendor/openssl/src/envelope.rs @@ -0,0 +1,181 @@ +//! Envelope encryption. +//! +//! # Example +//! +//! ```rust +//! use openssl::rsa::Rsa; +//! use openssl::envelope::Seal; +//! use openssl::pkey::PKey; +//! use openssl::symm::Cipher; +//! +//! let rsa = Rsa::generate(2048).unwrap(); +//! let key = PKey::from_rsa(rsa).unwrap(); +//! +//! let cipher = Cipher::aes_256_cbc(); +//! let mut seal = Seal::new(cipher, &[key]).unwrap(); +//! +//! let secret = b"My secret message"; +//! let mut encrypted = vec![0; secret.len() + cipher.block_size()]; +//! +//! let mut enc_len = seal.update(secret, &mut encrypted).unwrap(); +//! enc_len += seal.finalize(&mut encrypted[enc_len..]).unwrap(); +//! encrypted.truncate(enc_len); +//! ``` +use crate::cipher::CipherRef; +use crate::cipher_ctx::CipherCtx; +use crate::error::ErrorStack; +use crate::pkey::{HasPrivate, HasPublic, PKey, PKeyRef}; +use crate::symm::Cipher; +use foreign_types::ForeignTypeRef; + +/// Represents an EVP_Seal context. +pub struct Seal { + ctx: CipherCtx, + iv: Option>, + enc_keys: Vec>, +} + +impl Seal { + /// Creates a new `Seal`. + pub fn new(cipher: Cipher, pub_keys: &[PKey]) -> Result + where + T: HasPublic, + { + let mut iv = cipher.iv_len().map(|len| vec![0; len]); + let mut enc_keys = vec![vec![]; pub_keys.len()]; + + let mut ctx = CipherCtx::new()?; + ctx.seal_init( + Some(unsafe { CipherRef::from_ptr(cipher.as_ptr() as *mut _) }), + pub_keys, + &mut enc_keys, + iv.as_deref_mut(), + )?; + + Ok(Seal { ctx, iv, enc_keys }) + } + + /// Returns the initialization vector, if the cipher uses one. + #[allow(clippy::option_as_ref_deref)] + pub fn iv(&self) -> Option<&[u8]> { + self.iv.as_ref().map(|v| &**v) + } + + /// Returns the encrypted keys. + pub fn encrypted_keys(&self) -> &[Vec] { + &self.enc_keys + } + + /// Feeds data from `input` through the cipher, writing encrypted bytes into `output`. + /// + /// The number of bytes written to `output` is returned. Note that this may + /// not be equal to the length of `input`. + /// + /// # Panics + /// + /// Panics if `output.len() < input.len() + block_size` where `block_size` is + /// the block size of the cipher (see `Cipher::block_size`), or if + /// `output.len() > c_int::MAX`. + pub fn update(&mut self, input: &[u8], output: &mut [u8]) -> Result { + self.ctx.cipher_update(input, Some(output)) + } + + /// Finishes the encryption process, writing any remaining data to `output`. + /// + /// The number of bytes written to `output` is returned. + /// + /// `update` should not be called after this method. + /// + /// # Panics + /// + /// Panics if `output` is less than the cipher's block size. + pub fn finalize(&mut self, output: &mut [u8]) -> Result { + self.ctx.cipher_final(output) + } +} + +/// Represents an EVP_Open context. +pub struct Open { + ctx: CipherCtx, +} + +impl Open { + /// Creates a new `Open`. + pub fn new( + cipher: Cipher, + priv_key: &PKeyRef, + iv: Option<&[u8]>, + encrypted_key: &[u8], + ) -> Result + where + T: HasPrivate, + { + let mut ctx = CipherCtx::new()?; + ctx.open_init( + Some(unsafe { CipherRef::from_ptr(cipher.as_ptr() as *mut _) }), + encrypted_key, + iv, + Some(priv_key), + )?; + + Ok(Open { ctx }) + } + + /// Feeds data from `input` through the cipher, writing decrypted bytes into `output`. + /// + /// The number of bytes written to `output` is returned. Note that this may + /// not be equal to the length of `input`. + /// + /// # Panics + /// + /// Panics if `output.len() < input.len() + block_size` where + /// `block_size` is the block size of the cipher (see `Cipher::block_size`), + /// or if `output.len() > c_int::MAX`. + pub fn update(&mut self, input: &[u8], output: &mut [u8]) -> Result { + self.ctx.cipher_update(input, Some(output)) + } + + /// Finishes the decryption process, writing any remaining data to `output`. + /// + /// The number of bytes written to `output` is returned. + /// + /// `update` should not be called after this method. + /// + /// # Panics + /// + /// Panics if `output` is less than the cipher's block size. + pub fn finalize(&mut self, output: &mut [u8]) -> Result { + self.ctx.cipher_final(output) + } +} + +#[cfg(test)] +mod test { + use super::*; + use crate::pkey::PKey; + use crate::symm::Cipher; + + #[test] + fn public_encrypt_private_decrypt() { + let private_pem = include_bytes!("../test/rsa.pem"); + let public_pem = include_bytes!("../test/rsa.pem.pub"); + let private_key = PKey::private_key_from_pem(private_pem).unwrap(); + let public_key = PKey::public_key_from_pem(public_pem).unwrap(); + let cipher = Cipher::aes_256_cbc(); + let secret = b"My secret message"; + + let mut seal = Seal::new(cipher, &[public_key]).unwrap(); + let mut encrypted = vec![0; secret.len() + cipher.block_size()]; + let mut enc_len = seal.update(secret, &mut encrypted).unwrap(); + enc_len += seal.finalize(&mut encrypted[enc_len..]).unwrap(); + let iv = seal.iv(); + let encrypted_key = &seal.encrypted_keys()[0]; + + let mut open = Open::new(cipher, &private_key, iv, encrypted_key).unwrap(); + let mut decrypted = vec![0; enc_len + cipher.block_size()]; + let mut dec_len = open.update(&encrypted[..enc_len], &mut decrypted).unwrap(); + dec_len += open.finalize(&mut decrypted[dec_len..]).unwrap(); + + assert_eq!(&secret[..], &decrypted[..dec_len]); + } +} diff --git a/vendor/openssl/src/error.rs b/vendor/openssl/src/error.rs new file mode 100644 index 0000000..e097ce6 --- /dev/null +++ b/vendor/openssl/src/error.rs @@ -0,0 +1,418 @@ +//! Errors returned by OpenSSL library. +//! +//! OpenSSL errors are stored in an `ErrorStack`. Most methods in the crate +//! returns a `Result` type. +//! +//! # Examples +//! +//! ``` +//! use openssl::error::ErrorStack; +//! use openssl::bn::BigNum; +//! +//! let an_error = BigNum::from_dec_str("Cannot parse letters"); +//! match an_error { +//! Ok(_) => (), +//! Err(e) => println!("Parsing Error: {:?}", e), +//! } +//! ``` +use cfg_if::cfg_if; +use libc::{c_char, c_int}; +use std::borrow::Cow; +#[cfg(boringssl)] +use std::convert::TryInto; +use std::error; +use std::ffi::CStr; +use std::fmt; +use std::io; +use std::ptr; +use std::str; + +#[cfg(not(boringssl))] +type ErrType = libc::c_ulong; +#[cfg(boringssl)] +type ErrType = libc::c_uint; + +/// Collection of [`Error`]s from OpenSSL. +/// +/// [`Error`]: struct.Error.html +#[derive(Debug, Clone)] +pub struct ErrorStack(Vec); + +impl ErrorStack { + /// Returns the contents of the OpenSSL error stack. + pub fn get() -> ErrorStack { + let mut vec = vec![]; + while let Some(err) = Error::get() { + vec.push(err); + } + ErrorStack(vec) + } + + /// Pushes the errors back onto the OpenSSL error stack. + pub fn put(&self) { + for error in self.errors() { + error.put(); + } + } +} + +impl ErrorStack { + /// Returns the errors in the stack. + pub fn errors(&self) -> &[Error] { + &self.0 + } +} + +impl fmt::Display for ErrorStack { + fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { + if self.0.is_empty() { + return fmt.write_str("OpenSSL error"); + } + + let mut first = true; + for err in &self.0 { + if !first { + fmt.write_str(", ")?; + } + write!(fmt, "{}", err)?; + first = false; + } + Ok(()) + } +} + +impl error::Error for ErrorStack {} + +impl From for io::Error { + fn from(e: ErrorStack) -> io::Error { + io::Error::new(io::ErrorKind::Other, e) + } +} + +impl From for fmt::Error { + fn from(_: ErrorStack) -> fmt::Error { + fmt::Error + } +} + +/// An error reported from OpenSSL. +#[derive(Clone)] +pub struct Error { + code: ErrType, + file: ShimStr, + line: c_int, + func: Option, + data: Option>, +} + +unsafe impl Sync for Error {} +unsafe impl Send for Error {} + +impl Error { + /// Returns the first error on the OpenSSL error stack. + pub fn get() -> Option { + unsafe { + ffi::init(); + + let mut file = ptr::null(); + let mut line = 0; + let mut func = ptr::null(); + let mut data = ptr::null(); + let mut flags = 0; + match ERR_get_error_all(&mut file, &mut line, &mut func, &mut data, &mut flags) { + 0 => None, + code => { + // The memory referenced by data is only valid until that slot is overwritten + // in the error stack, so we'll need to copy it off if it's dynamic + let data = if flags & ffi::ERR_TXT_STRING != 0 { + let bytes = CStr::from_ptr(data as *const _).to_bytes(); + let data = str::from_utf8(bytes).unwrap(); + #[cfg(not(boringssl))] + let data = if flags & ffi::ERR_TXT_MALLOCED != 0 { + Cow::Owned(data.to_string()) + } else { + Cow::Borrowed(data) + }; + #[cfg(boringssl)] + let data = Cow::Borrowed(data); + Some(data) + } else { + None + }; + + let file = ShimStr::new(file); + + let func = if func.is_null() { + None + } else { + Some(ShimStr::new(func)) + }; + + Some(Error { + code, + file, + line, + func, + data, + }) + } + } + } + } + + /// Pushes the error back onto the OpenSSL error stack. + pub fn put(&self) { + self.put_error(); + + unsafe { + let data = match self.data { + Some(Cow::Borrowed(data)) => Some((data.as_ptr() as *mut c_char, 0)), + Some(Cow::Owned(ref data)) => { + let ptr = ffi::CRYPTO_malloc( + (data.len() + 1) as _, + concat!(file!(), "\0").as_ptr() as _, + line!() as _, + ) as *mut c_char; + if ptr.is_null() { + None + } else { + ptr::copy_nonoverlapping(data.as_ptr(), ptr as *mut u8, data.len()); + *ptr.add(data.len()) = 0; + Some((ptr, ffi::ERR_TXT_MALLOCED)) + } + } + None => None, + }; + if let Some((ptr, flags)) = data { + ffi::ERR_set_error_data(ptr, flags | ffi::ERR_TXT_STRING); + } + } + } + + #[cfg(ossl300)] + fn put_error(&self) { + unsafe { + ffi::ERR_new(); + ffi::ERR_set_debug( + self.file.as_ptr(), + self.line, + self.func.as_ref().map_or(ptr::null(), |s| s.as_ptr()), + ); + ffi::ERR_set_error(self.library_code(), self.reason_code(), ptr::null()); + } + } + + #[cfg(not(ossl300))] + fn put_error(&self) { + #[cfg(not(boringssl))] + let line = self.line; + #[cfg(boringssl)] + let line = self.line.try_into().unwrap(); + unsafe { + ffi::ERR_put_error( + self.library_code(), + ffi::ERR_GET_FUNC(self.code), + self.reason_code(), + self.file.as_ptr(), + line, + ); + } + } + + /// Returns the raw OpenSSL error code for this error. + pub fn code(&self) -> ErrType { + self.code + } + + /// Returns the name of the library reporting the error, if available. + pub fn library(&self) -> Option<&'static str> { + unsafe { + let cstr = ffi::ERR_lib_error_string(self.code); + if cstr.is_null() { + return None; + } + let bytes = CStr::from_ptr(cstr as *const _).to_bytes(); + Some(str::from_utf8(bytes).unwrap()) + } + } + + /// Returns the raw OpenSSL error constant for the library reporting the + /// error. + // On BoringSSL ERR_GET_{LIB,FUNC,REASON} are `unsafe`, but on + // OpenSSL/LibreSSL they're safe. + #[allow(unused_unsafe)] + pub fn library_code(&self) -> libc::c_int { + unsafe { ffi::ERR_GET_LIB(self.code) } + } + + /// Returns the name of the function reporting the error. + pub fn function(&self) -> Option> { + self.func.as_ref().map(|s| s.as_str()) + } + + /// Returns the reason for the error. + pub fn reason(&self) -> Option<&'static str> { + unsafe { + let cstr = ffi::ERR_reason_error_string(self.code); + if cstr.is_null() { + return None; + } + let bytes = CStr::from_ptr(cstr as *const _).to_bytes(); + Some(str::from_utf8(bytes).unwrap()) + } + } + + /// Returns the raw OpenSSL error constant for the reason for the error. + // On BoringSSL ERR_GET_{LIB,FUNC,REASON} are `unsafe`, but on + // OpenSSL/LibreSSL they're safe. + #[allow(unused_unsafe)] + pub fn reason_code(&self) -> libc::c_int { + unsafe { ffi::ERR_GET_REASON(self.code) } + } + + /// Returns the name of the source file which encountered the error. + pub fn file(&self) -> RetStr<'_> { + self.file.as_str() + } + + /// Returns the line in the source file which encountered the error. + pub fn line(&self) -> u32 { + self.line as u32 + } + + /// Returns additional data describing the error. + #[allow(clippy::option_as_ref_deref)] + pub fn data(&self) -> Option<&str> { + self.data.as_ref().map(|s| &**s) + } +} + +impl fmt::Debug for Error { + fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { + let mut builder = fmt.debug_struct("Error"); + builder.field("code", &self.code()); + if let Some(library) = self.library() { + builder.field("library", &library); + } + if let Some(function) = self.function() { + builder.field("function", &function); + } + if let Some(reason) = self.reason() { + builder.field("reason", &reason); + } + builder.field("file", &self.file()); + builder.field("line", &self.line()); + if let Some(data) = self.data() { + builder.field("data", &data); + } + builder.finish() + } +} + +impl fmt::Display for Error { + // On BoringSSL ERR_GET_{LIB,FUNC,REASON} are `unsafe`, but on + // OpenSSL/LibreSSL they're safe. + #[allow(unused_unsafe)] + fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(fmt, "error:{:08X}", self.code())?; + match self.library() { + Some(l) => write!(fmt, ":{}", l)?, + None => write!(fmt, ":lib({})", self.library_code())?, + } + match self.function() { + Some(f) => write!(fmt, ":{}", f)?, + None => write!(fmt, ":func({})", unsafe { ffi::ERR_GET_FUNC(self.code()) })?, + } + match self.reason() { + Some(r) => write!(fmt, ":{}", r)?, + None => write!(fmt, ":reason({})", self.reason_code())?, + } + write!( + fmt, + ":{}:{}:{}", + self.file(), + self.line(), + self.data().unwrap_or("") + ) + } +} + +impl error::Error for Error {} + +cfg_if! { + if #[cfg(ossl300)] { + use std::ffi::{CString}; + use ffi::ERR_get_error_all; + + type RetStr<'a> = &'a str; + + #[derive(Clone)] + struct ShimStr(CString); + + impl ShimStr { + unsafe fn new(s: *const c_char) -> Self { + ShimStr(CStr::from_ptr(s).to_owned()) + } + + fn as_ptr(&self) -> *const c_char { + self.0.as_ptr() + } + + fn as_str(&self) -> &str { + self.0.to_str().unwrap() + } + } + } else { + #[allow(bad_style)] + unsafe extern "C" fn ERR_get_error_all( + file: *mut *const c_char, + line: *mut c_int, + func: *mut *const c_char, + data: *mut *const c_char, + flags: *mut c_int, + ) -> ErrType { + let code = ffi::ERR_get_error_line_data(file, line, data, flags); + *func = ffi::ERR_func_error_string(code); + code + } + + type RetStr<'a> = &'static str; + + #[derive(Clone)] + struct ShimStr(*const c_char); + + impl ShimStr { + unsafe fn new(s: *const c_char) -> Self { + ShimStr(s) + } + + fn as_ptr(&self) -> *const c_char { + self.0 + } + + fn as_str(&self) -> &'static str { + unsafe { + CStr::from_ptr(self.0).to_str().unwrap() + } + } + } + } +} + +#[cfg(test)] +mod tests { + #[cfg(not(ossl310))] + use crate::nid::Nid; + + #[test] + // Due to a bug in OpenSSL 3.1.0, this test can hang there. Skip for now. + #[cfg(not(ossl310))] + fn test_error_library_code() { + let stack = Nid::create("not-an-oid", "invalid", "invalid").unwrap_err(); + let errors = stack.errors(); + #[cfg(not(boringssl))] + assert_eq!(errors[0].library_code(), ffi::ERR_LIB_ASN1); + #[cfg(boringssl)] + assert_eq!(errors[0].library_code(), ffi::ERR_LIB_OBJ as libc::c_int); + } +} diff --git a/vendor/openssl/src/ex_data.rs b/vendor/openssl/src/ex_data.rs new file mode 100644 index 0000000..d4f0021 --- /dev/null +++ b/vendor/openssl/src/ex_data.rs @@ -0,0 +1,32 @@ +use libc::c_int; +use std::marker::PhantomData; + +/// A slot in a type's "extra data" structure. +/// +/// It is parameterized over the type containing the extra data as well as the +/// type of the data in the slot. +pub struct Index(c_int, PhantomData<(T, U)>); + +impl Copy for Index {} + +impl Clone for Index { + fn clone(&self) -> Index { + *self + } +} + +impl Index { + /// Creates an `Index` from a raw integer index. + /// + /// # Safety + /// + /// The caller must ensure that the index correctly maps to a `U` value stored in a `T`. + pub unsafe fn from_raw(idx: c_int) -> Index { + Index(idx, PhantomData) + } + + #[allow(clippy::trivially_copy_pass_by_ref)] + pub fn as_raw(&self) -> c_int { + self.0 + } +} diff --git a/vendor/openssl/src/fips.rs b/vendor/openssl/src/fips.rs new file mode 100644 index 0000000..2a8a2fe --- /dev/null +++ b/vendor/openssl/src/fips.rs @@ -0,0 +1,21 @@ +//! FIPS 140-2 support. +//! +//! See [OpenSSL's documentation] for details. +//! +//! [OpenSSL's documentation]: https://www.openssl.org/docs/fips/UserGuide-2.0.pdf +use crate::cvt; +use crate::error::ErrorStack; +use openssl_macros::corresponds; + +/// Moves the library into or out of the FIPS 140-2 mode of operation. +#[corresponds(FIPS_mode_set)] +pub fn enable(enabled: bool) -> Result<(), ErrorStack> { + ffi::init(); + unsafe { cvt(ffi::FIPS_mode_set(enabled as _)).map(|_| ()) } +} + +/// Determines if the library is running in the FIPS 140-2 mode of operation. +#[corresponds(FIPS_mode)] +pub fn enabled() -> bool { + unsafe { ffi::FIPS_mode() != 0 } +} diff --git a/vendor/openssl/src/hash.rs b/vendor/openssl/src/hash.rs new file mode 100644 index 0000000..b25eded --- /dev/null +++ b/vendor/openssl/src/hash.rs @@ -0,0 +1,796 @@ +//! Message digest (hash) computation support. +//! +//! # Examples +//! +//! Calculate a hash in one go: +//! +//! ``` +//! # fn main() -> Result<(), Box> { +//! use openssl::hash::{hash, MessageDigest}; +//! +//! let data = b"\x42\xF4\x97\xE0"; +//! let spec = b"\x7c\x43\x0f\x17\x8a\xef\xdf\x14\x87\xfe\xe7\x14\x4e\x96\x41\xe2"; +//! let res = hash(MessageDigest::md5(), data)?; +//! assert_eq!(&*res, spec); +//! # Ok(()) } +//! ``` +//! +//! Supply the input in chunks: +//! +//! ``` +//! use openssl::hash::{Hasher, MessageDigest}; +//! +//! # fn main() -> Result<(), Box> { +//! let mut hasher = Hasher::new(MessageDigest::sha256())?; +//! hasher.update(b"test")?; +//! hasher.update(b"this")?; +//! let digest: &[u8] = &hasher.finish()?; +//! +//! let expected = hex::decode("9740e652ab5b4acd997a7cca13d6696702ccb2d441cca59fc6e285127f28cfe6")?; +//! assert_eq!(digest, expected); +//! # Ok(()) } +//! ``` +use cfg_if::cfg_if; +use std::ffi::CString; +use std::fmt; +use std::io; +use std::io::prelude::*; +use std::ops::{Deref, DerefMut}; +use std::ptr; + +use crate::error::ErrorStack; +use crate::nid::Nid; +use crate::{cvt, cvt_p}; +use openssl_macros::corresponds; + +cfg_if! { + if #[cfg(any(ossl110, boringssl, libressl382))] { + use ffi::{EVP_MD_CTX_free, EVP_MD_CTX_new}; + } else { + use ffi::{EVP_MD_CTX_create as EVP_MD_CTX_new, EVP_MD_CTX_destroy as EVP_MD_CTX_free}; + } +} + +/// A message digest algorithm. +#[derive(Copy, Clone, PartialEq, Eq)] +pub struct MessageDigest(*const ffi::EVP_MD); + +impl MessageDigest { + /// Creates a `MessageDigest` from a raw OpenSSL pointer. + /// + /// # Safety + /// + /// The caller must ensure the pointer is valid. + pub unsafe fn from_ptr(x: *const ffi::EVP_MD) -> Self { + MessageDigest(x) + } + + /// Returns the `MessageDigest` corresponding to an `Nid`. + #[corresponds(EVP_get_digestbynid)] + pub fn from_nid(type_: Nid) -> Option { + ffi::init(); + unsafe { + let ptr = ffi::EVP_get_digestbynid(type_.as_raw()); + if ptr.is_null() { + None + } else { + Some(MessageDigest(ptr)) + } + } + } + + /// Returns the `MessageDigest` corresponding to an algorithm name. + #[corresponds(EVP_get_digestbyname)] + pub fn from_name(name: &str) -> Option { + ffi::init(); + let name = CString::new(name).ok()?; + unsafe { + let ptr = ffi::EVP_get_digestbyname(name.as_ptr()); + if ptr.is_null() { + None + } else { + Some(MessageDigest(ptr)) + } + } + } + + #[cfg(not(boringssl))] + pub fn null() -> MessageDigest { + unsafe { MessageDigest(ffi::EVP_md_null()) } + } + + pub fn md5() -> MessageDigest { + unsafe { MessageDigest(ffi::EVP_md5()) } + } + + pub fn sha1() -> MessageDigest { + unsafe { MessageDigest(ffi::EVP_sha1()) } + } + + pub fn sha224() -> MessageDigest { + unsafe { MessageDigest(ffi::EVP_sha224()) } + } + + pub fn sha256() -> MessageDigest { + unsafe { MessageDigest(ffi::EVP_sha256()) } + } + + pub fn sha384() -> MessageDigest { + unsafe { MessageDigest(ffi::EVP_sha384()) } + } + + pub fn sha512() -> MessageDigest { + unsafe { MessageDigest(ffi::EVP_sha512()) } + } + + #[cfg(any(ossl111, libressl380))] + pub fn sha3_224() -> MessageDigest { + unsafe { MessageDigest(ffi::EVP_sha3_224()) } + } + + #[cfg(any(ossl111, libressl380))] + pub fn sha3_256() -> MessageDigest { + unsafe { MessageDigest(ffi::EVP_sha3_256()) } + } + + #[cfg(any(ossl111, libressl380))] + pub fn sha3_384() -> MessageDigest { + unsafe { MessageDigest(ffi::EVP_sha3_384()) } + } + + #[cfg(any(ossl111, libressl380))] + pub fn sha3_512() -> MessageDigest { + unsafe { MessageDigest(ffi::EVP_sha3_512()) } + } + + #[cfg(ossl111)] + pub fn shake_128() -> MessageDigest { + unsafe { MessageDigest(ffi::EVP_shake128()) } + } + + #[cfg(ossl111)] + pub fn shake_256() -> MessageDigest { + unsafe { MessageDigest(ffi::EVP_shake256()) } + } + + #[cfg(not(osslconf = "OPENSSL_NO_RMD160"))] + pub fn ripemd160() -> MessageDigest { + unsafe { MessageDigest(ffi::EVP_ripemd160()) } + } + + #[cfg(all(any(ossl111, libressl291), not(osslconf = "OPENSSL_NO_SM3")))] + pub fn sm3() -> MessageDigest { + unsafe { MessageDigest(ffi::EVP_sm3()) } + } + + #[allow(clippy::trivially_copy_pass_by_ref)] + pub fn as_ptr(&self) -> *const ffi::EVP_MD { + self.0 + } + + /// The block size of the digest in bytes. + #[allow(clippy::trivially_copy_pass_by_ref)] + pub fn block_size(&self) -> usize { + unsafe { ffi::EVP_MD_block_size(self.0) as usize } + } + + /// The size of the digest in bytes. + #[allow(clippy::trivially_copy_pass_by_ref)] + pub fn size(&self) -> usize { + unsafe { ffi::EVP_MD_size(self.0) as usize } + } + + /// The name of the digest. + #[allow(clippy::trivially_copy_pass_by_ref)] + pub fn type_(&self) -> Nid { + Nid::from_raw(unsafe { ffi::EVP_MD_type(self.0) }) + } +} + +unsafe impl Sync for MessageDigest {} +unsafe impl Send for MessageDigest {} + +#[derive(PartialEq, Copy, Clone)] +enum State { + Reset, + Updated, + Finalized, +} + +use self::State::*; + +/// Provides message digest (hash) computation. +/// +/// # Examples +/// +/// ``` +/// use openssl::hash::{Hasher, MessageDigest}; +/// +/// # fn main() -> Result<(), Box> { +/// let data = [b"\x42\xF4", b"\x97\xE0"]; +/// let spec = b"\x7c\x43\x0f\x17\x8a\xef\xdf\x14\x87\xfe\xe7\x14\x4e\x96\x41\xe2"; +/// let mut h = Hasher::new(MessageDigest::md5())?; +/// h.update(data[0])?; +/// h.update(data[1])?; +/// let res = h.finish()?; +/// assert_eq!(&*res, spec); +/// # Ok(()) } +/// ``` +/// +/// # Warning +/// +/// Don't actually use MD5 and SHA-1 hashes, they're not secure anymore. +/// +/// Don't ever hash passwords, use the functions in the `pkcs5` module or bcrypt/scrypt instead. +/// +/// For extendable output functions (XOFs, i.e. SHAKE128/SHAKE256), +/// you must use [`Hasher::finish_xof`] instead of [`Hasher::finish`] +/// and provide a `buf` to store the hash. The hash will be as long as +/// the `buf`. +pub struct Hasher { + ctx: *mut ffi::EVP_MD_CTX, + md: *const ffi::EVP_MD, + type_: MessageDigest, + state: State, +} + +unsafe impl Sync for Hasher {} +unsafe impl Send for Hasher {} + +impl Hasher { + /// Creates a new `Hasher` with the specified hash type. + pub fn new(ty: MessageDigest) -> Result { + ffi::init(); + + let ctx = unsafe { cvt_p(EVP_MD_CTX_new())? }; + + let mut h = Hasher { + ctx, + md: ty.as_ptr(), + type_: ty, + state: Finalized, + }; + h.init()?; + Ok(h) + } + + fn init(&mut self) -> Result<(), ErrorStack> { + match self.state { + Reset => return Ok(()), + Updated => { + self.finish()?; + } + Finalized => (), + } + unsafe { + cvt(ffi::EVP_DigestInit_ex(self.ctx, self.md, ptr::null_mut()))?; + } + self.state = Reset; + Ok(()) + } + + /// Feeds data into the hasher. + pub fn update(&mut self, data: &[u8]) -> Result<(), ErrorStack> { + if self.state == Finalized { + self.init()?; + } + unsafe { + cvt(ffi::EVP_DigestUpdate( + self.ctx, + data.as_ptr() as *mut _, + data.len(), + ))?; + } + self.state = Updated; + Ok(()) + } + + /// Returns the hash of the data written and resets the non-XOF hasher. + pub fn finish(&mut self) -> Result { + if self.state == Finalized { + self.init()?; + } + unsafe { + #[cfg(not(boringssl))] + let mut len = ffi::EVP_MAX_MD_SIZE; + #[cfg(boringssl)] + let mut len = ffi::EVP_MAX_MD_SIZE as u32; + let mut buf = [0; ffi::EVP_MAX_MD_SIZE as usize]; + cvt(ffi::EVP_DigestFinal_ex( + self.ctx, + buf.as_mut_ptr(), + &mut len, + ))?; + self.state = Finalized; + Ok(DigestBytes { + buf, + len: len as usize, + }) + } + } + + /// Writes the hash of the data into the supplied buf and resets the XOF hasher. + /// The hash will be as long as the buf. + #[cfg(ossl111)] + pub fn finish_xof(&mut self, buf: &mut [u8]) -> Result<(), ErrorStack> { + if self.state == Finalized { + self.init()?; + } + unsafe { + cvt(ffi::EVP_DigestFinalXOF( + self.ctx, + buf.as_mut_ptr(), + buf.len(), + ))?; + self.state = Finalized; + Ok(()) + } + } +} + +impl Write for Hasher { + #[inline] + fn write(&mut self, buf: &[u8]) -> io::Result { + self.update(buf)?; + Ok(buf.len()) + } + + fn flush(&mut self) -> io::Result<()> { + Ok(()) + } +} + +impl Clone for Hasher { + fn clone(&self) -> Hasher { + let ctx = unsafe { + let ctx = EVP_MD_CTX_new(); + assert!(!ctx.is_null()); + let r = ffi::EVP_MD_CTX_copy_ex(ctx, self.ctx); + assert_eq!(r, 1); + ctx + }; + Hasher { + ctx, + md: self.md, + type_: self.type_, + state: self.state, + } + } +} + +impl Drop for Hasher { + fn drop(&mut self) { + unsafe { + if self.state != Finalized { + drop(self.finish()); + } + EVP_MD_CTX_free(self.ctx); + } + } +} + +/// The resulting bytes of a digest. +/// +/// This type derefs to a byte slice - it exists to avoid allocating memory to +/// store the digest data. +#[derive(Copy)] +pub struct DigestBytes { + pub(crate) buf: [u8; ffi::EVP_MAX_MD_SIZE as usize], + pub(crate) len: usize, +} + +impl Clone for DigestBytes { + #[inline] + fn clone(&self) -> DigestBytes { + *self + } +} + +impl Deref for DigestBytes { + type Target = [u8]; + + #[inline] + fn deref(&self) -> &[u8] { + &self.buf[..self.len] + } +} + +impl DerefMut for DigestBytes { + #[inline] + fn deref_mut(&mut self) -> &mut [u8] { + &mut self.buf[..self.len] + } +} + +impl AsRef<[u8]> for DigestBytes { + #[inline] + fn as_ref(&self) -> &[u8] { + self.deref() + } +} + +impl fmt::Debug for DigestBytes { + fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { + fmt::Debug::fmt(&**self, fmt) + } +} + +/// Computes the hash of the `data` with the non-XOF hasher `t`. +/// +/// # Examples +/// +/// ``` +/// # fn main() -> Result<(), Box> { +/// use openssl::hash::{hash, MessageDigest}; +/// +/// let data = b"\x42\xF4\x97\xE0"; +/// let spec = b"\x7c\x43\x0f\x17\x8a\xef\xdf\x14\x87\xfe\xe7\x14\x4e\x96\x41\xe2"; +/// let res = hash(MessageDigest::md5(), data)?; +/// assert_eq!(&*res, spec); +/// # Ok(()) } +/// ``` +pub fn hash(t: MessageDigest, data: &[u8]) -> Result { + let mut h = Hasher::new(t)?; + h.update(data)?; + h.finish() +} + +/// Computes the hash of the `data` with the XOF hasher `t` and stores it in `buf`. +/// +/// # Examples +/// +/// ``` +/// use openssl::hash::{hash_xof, MessageDigest}; +/// +/// let data = b"\x41\x6c\x6c\x20\x79\x6f\x75\x72\x20\x62\x61\x73\x65\x20\x61\x72\x65\x20\x62\x65\x6c\x6f\x6e\x67\x20\x74\x6f\x20\x75\x73"; +/// let spec = b"\x49\xd0\x69\x7f\xf5\x08\x11\x1d\x8b\x84\xf1\x5e\x46\xda\xf1\x35"; +/// let mut buf = vec![0; 16]; +/// hash_xof(MessageDigest::shake_128(), data, buf.as_mut_slice()).unwrap(); +/// assert_eq!(buf, spec); +/// ``` +/// +#[cfg(ossl111)] +pub fn hash_xof(t: MessageDigest, data: &[u8], buf: &mut [u8]) -> Result<(), ErrorStack> { + let mut h = Hasher::new(t)?; + h.update(data)?; + h.finish_xof(buf) +} + +#[cfg(test)] +mod tests { + use hex::{self, FromHex}; + use std::io::prelude::*; + + use super::*; + + fn hash_test(hashtype: MessageDigest, hashtest: &(&str, &str)) { + let res = hash(hashtype, &Vec::from_hex(hashtest.0).unwrap()).unwrap(); + assert_eq!(hex::encode(res), hashtest.1); + } + + #[cfg(ossl111)] + fn hash_xof_test(hashtype: MessageDigest, hashtest: &(&str, &str)) { + let expected = Vec::from_hex(hashtest.1).unwrap(); + let mut buf = vec![0; expected.len()]; + hash_xof( + hashtype, + &Vec::from_hex(hashtest.0).unwrap(), + buf.as_mut_slice(), + ) + .unwrap(); + assert_eq!(buf, expected); + } + + fn hash_recycle_test(h: &mut Hasher, hashtest: &(&str, &str)) { + h.write_all(&Vec::from_hex(hashtest.0).unwrap()).unwrap(); + let res = h.finish().unwrap(); + assert_eq!(hex::encode(res), hashtest.1); + } + + // Test vectors from http://www.nsrl.nist.gov/testdata/ + const MD5_TESTS: [(&str, &str); 13] = [ + ("", "d41d8cd98f00b204e9800998ecf8427e"), + ("7F", "83acb6e67e50e31db6ed341dd2de1595"), + ("EC9C", "0b07f0d4ca797d8ac58874f887cb0b68"), + ("FEE57A", "e0d583171eb06d56198fc0ef22173907"), + ("42F497E0", "7c430f178aefdf1487fee7144e9641e2"), + ("C53B777F1C", "75ef141d64cb37ec423da2d9d440c925"), + ("89D5B576327B", "ebbaf15eb0ed784c6faa9dc32831bf33"), + ("5D4CCE781EB190", "ce175c4b08172019f05e6b5279889f2c"), + ("81901FE94932D7B9", "cd4d2f62b8cdb3a0cf968a735a239281"), + ("C9FFDEE7788EFB4EC9", "e0841a231ab698db30c6c0f3f246c014"), + ("66AC4B7EBA95E53DC10B", "a3b3cea71910d9af56742aa0bb2fe329"), + ("A510CD18F7A56852EB0319", "577e216843dd11573574d3fb209b97d8"), + ( + "AAED18DBE8938C19ED734A8D", + "6f80fb775f27e0a4ce5c2f42fc72c5f1", + ), + ]; + + #[test] + fn test_md5() { + for test in MD5_TESTS.iter() { + hash_test(MessageDigest::md5(), test); + } + + assert_eq!(MessageDigest::md5().block_size(), 64); + assert_eq!(MessageDigest::md5().size(), 16); + assert_eq!(MessageDigest::md5().type_().as_raw(), Nid::MD5.as_raw()); + } + + #[test] + fn test_md5_recycle() { + let mut h = Hasher::new(MessageDigest::md5()).unwrap(); + for test in MD5_TESTS.iter() { + hash_recycle_test(&mut h, test); + } + } + + #[test] + fn test_finish_twice() { + let mut h = Hasher::new(MessageDigest::md5()).unwrap(); + h.write_all(&Vec::from_hex(MD5_TESTS[6].0).unwrap()) + .unwrap(); + h.finish().unwrap(); + let res = h.finish().unwrap(); + let null = hash(MessageDigest::md5(), &[]).unwrap(); + assert_eq!(&*res, &*null); + } + + #[test] + #[allow(clippy::redundant_clone)] + fn test_clone() { + let i = 7; + let inp = Vec::from_hex(MD5_TESTS[i].0).unwrap(); + assert!(inp.len() > 2); + let p = inp.len() / 2; + let h0 = Hasher::new(MessageDigest::md5()).unwrap(); + + println!("Clone a new hasher"); + let mut h1 = h0.clone(); + h1.write_all(&inp[..p]).unwrap(); + { + println!("Clone an updated hasher"); + let mut h2 = h1.clone(); + h2.write_all(&inp[p..]).unwrap(); + let res = h2.finish().unwrap(); + assert_eq!(hex::encode(res), MD5_TESTS[i].1); + } + h1.write_all(&inp[p..]).unwrap(); + let res = h1.finish().unwrap(); + assert_eq!(hex::encode(res), MD5_TESTS[i].1); + + println!("Clone a finished hasher"); + let mut h3 = h1.clone(); + h3.write_all(&Vec::from_hex(MD5_TESTS[i + 1].0).unwrap()) + .unwrap(); + let res = h3.finish().unwrap(); + assert_eq!(hex::encode(res), MD5_TESTS[i + 1].1); + } + + #[test] + fn test_sha1() { + let tests = [("616263", "a9993e364706816aba3e25717850c26c9cd0d89d")]; + + for test in tests.iter() { + hash_test(MessageDigest::sha1(), test); + } + + assert_eq!(MessageDigest::sha1().block_size(), 64); + assert_eq!(MessageDigest::sha1().size(), 20); + assert_eq!(MessageDigest::sha1().type_().as_raw(), Nid::SHA1.as_raw()); + } + + #[test] + fn test_sha256() { + let tests = [( + "616263", + "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad", + )]; + + for test in tests.iter() { + hash_test(MessageDigest::sha256(), test); + } + + assert_eq!(MessageDigest::sha256().block_size(), 64); + assert_eq!(MessageDigest::sha256().size(), 32); + assert_eq!( + MessageDigest::sha256().type_().as_raw(), + Nid::SHA256.as_raw() + ); + } + + #[test] + fn test_sha512() { + let tests = [( + "737465766566696e647365766572797468696e67", + "ba61d1f1af0f2dd80729f6cc900f19c0966bd38ba5c75e4471ef11b771dfe7551afab7fcbd300fdc4418f2\ + b07a028fcd99e7b6446a566f2d9bcd7c604a1ea801", + )]; + + for test in tests.iter() { + hash_test(MessageDigest::sha512(), test); + } + + assert_eq!(MessageDigest::sha512().block_size(), 128); + assert_eq!(MessageDigest::sha512().size(), 64); + assert_eq!( + MessageDigest::sha512().type_().as_raw(), + Nid::SHA512.as_raw() + ); + } + + #[cfg(any(ossl111, libressl380))] + #[test] + fn test_sha3_224() { + let tests = [( + "416c6c20796f75722062617365206172652062656c6f6e6720746f207573", + "1de092dd9fbcbbf450f26264f4778abd48af851f2832924554c56913", + )]; + + for test in tests.iter() { + hash_test(MessageDigest::sha3_224(), test); + } + + assert_eq!(MessageDigest::sha3_224().block_size(), 144); + assert_eq!(MessageDigest::sha3_224().size(), 28); + assert_eq!( + MessageDigest::sha3_224().type_().as_raw(), + Nid::SHA3_224.as_raw() + ); + } + + #[cfg(any(ossl111, libressl380))] + #[test] + fn test_sha3_256() { + let tests = [( + "416c6c20796f75722062617365206172652062656c6f6e6720746f207573", + "b38e38f08bc1c0091ed4b5f060fe13e86aa4179578513ad11a6e3abba0062f61", + )]; + + for test in tests.iter() { + hash_test(MessageDigest::sha3_256(), test); + } + + assert_eq!(MessageDigest::sha3_256().block_size(), 136); + assert_eq!(MessageDigest::sha3_256().size(), 32); + assert_eq!( + MessageDigest::sha3_256().type_().as_raw(), + Nid::SHA3_256.as_raw() + ); + } + + #[cfg(any(ossl111, libressl380))] + #[test] + fn test_sha3_384() { + let tests = [("416c6c20796f75722062617365206172652062656c6f6e6720746f207573", + "966ee786ab3482dd811bf7c8fa8db79aa1f52f6c3c369942ef14240ebd857c6ff626ec35d9e131ff64d328\ + ef2008ff16" + )]; + + for test in tests.iter() { + hash_test(MessageDigest::sha3_384(), test); + } + + assert_eq!(MessageDigest::sha3_384().block_size(), 104); + assert_eq!(MessageDigest::sha3_384().size(), 48); + assert_eq!( + MessageDigest::sha3_384().type_().as_raw(), + Nid::SHA3_384.as_raw() + ); + } + + #[cfg(any(ossl111, libressl380))] + #[test] + fn test_sha3_512() { + let tests = [("416c6c20796f75722062617365206172652062656c6f6e6720746f207573", + "c072288ef728cd53a029c47687960b9225893532f42b923156e37020bdc1eda753aafbf30af859d4f4c3a1\ + 807caee3a79f8eb02dcd61589fbbdf5f40c8787a72" + )]; + + for test in tests.iter() { + hash_test(MessageDigest::sha3_512(), test); + } + + assert_eq!(MessageDigest::sha3_512().block_size(), 72); + assert_eq!(MessageDigest::sha3_512().size(), 64); + assert_eq!( + MessageDigest::sha3_512().type_().as_raw(), + Nid::SHA3_512.as_raw() + ); + } + + #[cfg(ossl111)] + #[test] + fn test_shake_128() { + let tests = [( + "416c6c20796f75722062617365206172652062656c6f6e6720746f207573", + "49d0697ff508111d8b84f15e46daf135", + )]; + + for test in tests.iter() { + hash_xof_test(MessageDigest::shake_128(), test); + } + + assert_eq!(MessageDigest::shake_128().block_size(), 168); + assert_eq!(MessageDigest::shake_128().size(), 16); + assert_eq!( + MessageDigest::shake_128().type_().as_raw(), + Nid::SHAKE128.as_raw() + ); + } + + #[cfg(ossl111)] + #[test] + fn test_shake_256() { + let tests = [( + "416c6c20796f75722062617365206172652062656c6f6e6720746f207573", + "4e2dfdaa75d1e049d0eaeffe28e76b17cea47b650fb8826fe48b94664326a697", + )]; + + for test in tests.iter() { + hash_xof_test(MessageDigest::shake_256(), test); + } + + assert_eq!(MessageDigest::shake_256().block_size(), 136); + assert_eq!(MessageDigest::shake_256().size(), 32); + assert_eq!( + MessageDigest::shake_256().type_().as_raw(), + Nid::SHAKE256.as_raw() + ); + } + + #[test] + #[cfg(not(osslconf = "OPENSSL_NO_RMD160"))] + #[cfg_attr(ossl300, ignore)] + fn test_ripemd160() { + #[cfg(ossl300)] + let _provider = crate::provider::Provider::try_load(None, "legacy", true).unwrap(); + + let tests = [("616263", "8eb208f7e05d987a9b044a8e98c6b087f15a0bfc")]; + + for test in tests.iter() { + hash_test(MessageDigest::ripemd160(), test); + } + + assert_eq!(MessageDigest::ripemd160().block_size(), 64); + assert_eq!(MessageDigest::ripemd160().size(), 20); + assert_eq!( + MessageDigest::ripemd160().type_().as_raw(), + Nid::RIPEMD160.as_raw() + ); + } + + #[cfg(all(any(ossl111, libressl291), not(osslconf = "OPENSSL_NO_SM3")))] + #[test] + fn test_sm3() { + let tests = [( + "616263", + "66c7f0f462eeedd9d1f2d46bdc10e4e24167c4875cf2f7a2297da02b8f4ba8e0", + )]; + + for test in tests.iter() { + hash_test(MessageDigest::sm3(), test); + } + + assert_eq!(MessageDigest::sm3().block_size(), 64); + assert_eq!(MessageDigest::sm3().size(), 32); + assert_eq!(MessageDigest::sm3().type_().as_raw(), Nid::SM3.as_raw()); + } + + #[test] + fn from_nid() { + assert_eq!( + MessageDigest::from_nid(Nid::SHA256).unwrap().as_ptr(), + MessageDigest::sha256().as_ptr() + ); + } + + #[test] + fn from_name() { + assert_eq!( + MessageDigest::from_name("SHA256").unwrap().as_ptr(), + MessageDigest::sha256().as_ptr() + ) + } +} diff --git a/vendor/openssl/src/kdf.rs b/vendor/openssl/src/kdf.rs new file mode 100644 index 0000000..a5da352 --- /dev/null +++ b/vendor/openssl/src/kdf.rs @@ -0,0 +1,176 @@ +#[cfg(ossl320)] +struct EvpKdf(*mut ffi::EVP_KDF); + +#[cfg(ossl320)] +impl Drop for EvpKdf { + fn drop(&mut self) { + unsafe { + ffi::EVP_KDF_free(self.0); + } + } +} + +#[cfg(ossl320)] +struct EvpKdfCtx(*mut ffi::EVP_KDF_CTX); + +#[cfg(ossl320)] +impl Drop for EvpKdfCtx { + fn drop(&mut self) { + unsafe { + ffi::EVP_KDF_CTX_free(self.0); + } + } +} + +cfg_if::cfg_if! { + if #[cfg(all(ossl320, not(osslconf = "OPENSSL_NO_ARGON2")))] { + use std::cmp; + use std::ffi::c_void; + use std::mem::MaybeUninit; + use std::ptr; + use foreign_types::ForeignTypeRef; + use libc::c_char; + use crate::{cvt, cvt_p}; + use crate::lib_ctx::LibCtxRef; + use crate::error::ErrorStack; + + /// Derives a key using the argon2id algorithm. + /// + /// To use multiple cores to process the lanes in parallel you must + /// set a global max thread count using `OSSL_set_max_threads`. On + /// builds with no threads all lanes will be processed sequentially. + /// + /// Requires OpenSSL 3.2.0 or newer. + #[allow(clippy::too_many_arguments)] + pub fn argon2id( + ctx: Option<&LibCtxRef>, + pass: &[u8], + salt: &[u8], + ad: Option<&[u8]>, + secret: Option<&[u8]>, + mut iter: u32, + mut lanes: u32, + mut memcost: u32, + out: &mut [u8], + ) -> Result<(), ErrorStack> { + unsafe { + ffi::init(); + let libctx = ctx.map_or(ptr::null_mut(), ForeignTypeRef::as_ptr); + + let max_threads = ffi::OSSL_get_max_threads(libctx); + let mut threads = 1; + // If max_threads is 0, then this isn't a threaded build. + // If max_threads is > u32::MAX we need to clamp since + // argon2id's threads parameter is a u32. + if max_threads > 0 { + threads = cmp::min(lanes, cmp::min(max_threads, u32::MAX as u64) as u32); + } + let mut params: [ffi::OSSL_PARAM; 10] = + core::array::from_fn(|_| MaybeUninit::::zeroed().assume_init()); + let mut idx = 0; + params[idx] = ffi::OSSL_PARAM_construct_octet_string( + b"pass\0".as_ptr() as *const c_char, + pass.as_ptr() as *mut c_void, + pass.len(), + ); + idx += 1; + params[idx] = ffi::OSSL_PARAM_construct_octet_string( + b"salt\0".as_ptr() as *const c_char, + salt.as_ptr() as *mut c_void, + salt.len(), + ); + idx += 1; + params[idx] = + ffi::OSSL_PARAM_construct_uint(b"threads\0".as_ptr() as *const c_char, &mut threads); + idx += 1; + params[idx] = + ffi::OSSL_PARAM_construct_uint(b"lanes\0".as_ptr() as *const c_char, &mut lanes); + idx += 1; + params[idx] = + ffi::OSSL_PARAM_construct_uint(b"memcost\0".as_ptr() as *const c_char, &mut memcost); + idx += 1; + params[idx] = + ffi::OSSL_PARAM_construct_uint(b"iter\0".as_ptr() as *const c_char, &mut iter); + idx += 1; + let mut size = out.len() as u32; + params[idx] = + ffi::OSSL_PARAM_construct_uint(b"size\0".as_ptr() as *const c_char, &mut size); + idx += 1; + if let Some(ad) = ad { + params[idx] = ffi::OSSL_PARAM_construct_octet_string( + b"ad\0".as_ptr() as *const c_char, + ad.as_ptr() as *mut c_void, + ad.len(), + ); + idx += 1; + } + if let Some(secret) = secret { + params[idx] = ffi::OSSL_PARAM_construct_octet_string( + b"secret\0".as_ptr() as *const c_char, + secret.as_ptr() as *mut c_void, + secret.len(), + ); + idx += 1; + } + params[idx] = ffi::OSSL_PARAM_construct_end(); + + let argon2 = EvpKdf(cvt_p(ffi::EVP_KDF_fetch( + libctx, + b"ARGON2ID\0".as_ptr() as *const c_char, + ptr::null(), + ))?); + let ctx = EvpKdfCtx(cvt_p(ffi::EVP_KDF_CTX_new(argon2.0))?); + cvt(ffi::EVP_KDF_derive( + ctx.0, + out.as_mut_ptr(), + out.len(), + params.as_ptr(), + )) + .map(|_| ()) + } + } + } +} + +#[cfg(test)] +mod tests { + #[test] + #[cfg(all(ossl320, not(osslconf = "OPENSSL_NO_ARGON2")))] + fn argon2id() { + // RFC 9106 test vector for argon2id + let pass = hex::decode("0101010101010101010101010101010101010101010101010101010101010101") + .unwrap(); + let salt = hex::decode("02020202020202020202020202020202").unwrap(); + let secret = hex::decode("0303030303030303").unwrap(); + let ad = hex::decode("040404040404040404040404").unwrap(); + let expected = "0d640df58d78766c08c037a34a8b53c9d01ef0452d75b65eb52520e96b01e659"; + + let mut actual = [0u8; 32]; + super::argon2id( + None, + &pass, + &salt, + Some(&ad), + Some(&secret), + 3, + 4, + 32, + &mut actual, + ) + .unwrap(); + assert_eq!(hex::encode(&actual[..]), expected); + } + + #[test] + #[cfg(all(ossl320, not(osslconf = "OPENSSL_NO_ARGON2")))] + fn argon2id_no_ad_secret() { + // Test vector from OpenSSL + let pass = b""; + let salt = hex::decode("02020202020202020202020202020202").unwrap(); + let expected = "0a34f1abde67086c82e785eaf17c68382259a264f4e61b91cd2763cb75ac189a"; + + let mut actual = [0u8; 32]; + super::argon2id(None, pass, &salt, None, None, 3, 4, 32, &mut actual).unwrap(); + assert_eq!(hex::encode(&actual[..]), expected); + } +} diff --git a/vendor/openssl/src/lib.rs b/vendor/openssl/src/lib.rs new file mode 100644 index 0000000..c58e5bf --- /dev/null +++ b/vendor/openssl/src/lib.rs @@ -0,0 +1,257 @@ +//! Bindings to OpenSSL +//! +//! This crate provides a safe interface to the popular OpenSSL cryptography library. OpenSSL versions 1.0.1 through +//! 3.x.x and LibreSSL versions 2.5 through 3.7.x are supported. +//! +//! # Building +//! +//! Both OpenSSL libraries and headers are required to build this crate. There are multiple options available to locate +//! OpenSSL. +//! +//! ## Vendored +//! +//! If the `vendored` Cargo feature is enabled, the `openssl-src` crate will be used to compile and statically link to +//! a copy of OpenSSL. The build process requires a C compiler, perl (and perl-core), and make. The OpenSSL version will generally track +//! the newest OpenSSL release, and changes to the version are *not* considered breaking changes. +//! +//! ```toml +//! [dependencies] +//! openssl = { version = "0.10", features = ["vendored"] } +//! ``` +//! +//! The vendored copy will be configured to automatically find a configuration and root certificates at `/usr/local/ssl`. +//! This path can be overridden with an environment variable (see the manual section below). +//! Alternatively, the `openssl-probe` crate can be used to find root certificates at runtime. +//! +//! ## Automatic +//! +//! The `openssl-sys` crate will automatically detect OpenSSL installations via Homebrew on macOS and vcpkg on Windows. +//! Additionally, it will use `pkg-config` on Unix-like systems to find the system installation. +//! +//! ```not_rust +//! # macOS (Homebrew) +//! $ brew install openssl@3 +//! +//! # macOS (MacPorts) +//! $ sudo port install openssl +//! +//! # macOS (pkgsrc) +//! $ sudo pkgin install openssl +//! +//! # Arch Linux +//! $ sudo pacman -S pkgconf openssl +//! +//! # Debian and Ubuntu +//! $ sudo apt-get install pkg-config libssl-dev +//! +//! # Fedora +//! $ sudo dnf install pkgconf perl-FindBin perl-IPC-Cmd openssl-devel +//! +//! # Alpine Linux +//! $ apk add pkgconf openssl-dev +//! +//! # openSUSE +//! $ sudo zypper in libopenssl-devel +//! ``` +//! +//! ## Manual +//! +//! A set of environment variables can be used to point `openssl-sys` towards an OpenSSL installation. They will +//! override the automatic detection logic. +//! +//! * `OPENSSL_DIR` - If specified, the directory of an OpenSSL installation. The directory should contain `lib` and +//! `include` subdirectories containing the libraries and headers respectively. +//! * `OPENSSL_LIB_DIR` and `OPENSSL_INCLUDE_DIR` - If specified, the directories containing the OpenSSL libraries and +//! headers respectively. This can be used if the OpenSSL installation is split in a nonstandard directory layout. +//! * `OPENSSL_STATIC` - If set, the crate will statically link to OpenSSL rather than dynamically link. +//! * `OPENSSL_LIBS` - If set, a `:`-separated list of library names to link to (e.g. `ssl:crypto`). This can be used +//! if nonstandard library names were used for whatever reason. +//! * `OPENSSL_NO_VENDOR` - If set, always find OpenSSL in the system, even if the `vendored` feature is enabled. +//! +//! If the `vendored` Cargo feature is enabled, the following environment variable can also be used to further configure +//! the OpenSSL build. +//! +//! * `OPENSSL_CONFIG_DIR` - If set, the copy of OpenSSL built by the `openssl-src` crate will be configured to look for +//! configuration files and root certificates in this directory. +//! +//! Additionally, these variables can be prefixed with the upper-cased target architecture (e.g. +//! `X86_64_UNKNOWN_LINUX_GNU_OPENSSL_DIR`), which can be useful when cross compiling. +//! +//! # Feature Detection +//! +//! APIs have been added to and removed from the various supported OpenSSL versions, and this library exposes the +//! functionality available in the version being linked against. This means that methods, constants, and even modules +//! will be present when building against one version of OpenSSL but not when building against another! APIs will +//! document any version-specific availability restrictions. +//! +//! A build script can be used to detect the OpenSSL or LibreSSL version at compile time if needed. The `openssl-sys` +//! crate propagates the version via the `DEP_OPENSSL_VERSION_NUMBER` and `DEP_OPENSSL_LIBRESSL_VERSION_NUMBER` +//! environment variables to build scripts. The version format is a hex-encoding of the OpenSSL release version: +//! `0xMNNFFPPS`. For example, version 1.0.2g's encoding is `0x1_00_02_07_0`. +//! +//! For example, let's say we want to adjust the TLSv1.3 cipher suites used by a client, but also want to compile +//! against OpenSSL versions that don't support TLSv1.3: +//! +//! Cargo.toml: +//! +//! ```toml +//! [dependencies] +//! openssl-sys = "0.9" +//! openssl = "0.10" +//! ``` +//! +//! build.rs: +//! +//! ``` +//! use std::env; +//! +//! fn main() { +//! if let Ok(v) = env::var("DEP_OPENSSL_VERSION_NUMBER") { +//! let version = u64::from_str_radix(&v, 16).unwrap(); +//! +//! if version >= 0x1_01_01_00_0 { +//! println!("cargo:rustc-cfg=openssl111"); +//! } +//! } +//! } +//! ``` +//! +//! lib.rs: +//! +//! ``` +//! use openssl::ssl::{SslConnector, SslMethod}; +//! +//! let mut ctx = SslConnector::builder(SslMethod::tls()).unwrap(); +//! +//! // set_ciphersuites was added in OpenSSL 1.1.1, so we can only call it when linking against that version +//! #[cfg(openssl111)] +//! ctx.set_ciphersuites("TLS_AES_256_GCM_SHA384:TLS_AES_128_GCM_SHA256").unwrap(); +//! ``` +#![doc(html_root_url = "https://docs.rs/openssl/0.10")] +#![warn(rust_2018_idioms)] +#![allow(clippy::uninlined_format_args, clippy::needless_doctest_main)] + +#[doc(inline)] +pub use ffi::init; + +use libc::c_int; +#[cfg(ossl300)] +use libc::c_long; + +use crate::error::ErrorStack; + +#[macro_use] +mod macros; + +mod bio; +#[macro_use] +mod util; +pub mod aes; +pub mod asn1; +pub mod base64; +pub mod bn; +pub mod cipher; +pub mod cipher_ctx; +#[cfg(all(not(libressl), not(osslconf = "OPENSSL_NO_CMS")))] +pub mod cms; +pub mod conf; +pub mod derive; +pub mod dh; +pub mod dsa; +pub mod ec; +pub mod ecdsa; +pub mod encrypt; +#[cfg(not(boringssl))] +pub mod envelope; +pub mod error; +pub mod ex_data; +#[cfg(not(any(libressl, ossl300)))] +pub mod fips; +pub mod hash; +pub mod kdf; +#[cfg(ossl300)] +pub mod lib_ctx; +pub mod md; +pub mod md_ctx; +pub mod memcmp; +pub mod nid; +#[cfg(not(osslconf = "OPENSSL_NO_OCSP"))] +pub mod ocsp; +pub mod pkcs12; +pub mod pkcs5; +#[cfg(not(boringssl))] +pub mod pkcs7; +pub mod pkey; +pub mod pkey_ctx; +#[cfg(ossl300)] +pub mod provider; +pub mod rand; +pub mod rsa; +pub mod sha; +pub mod sign; +pub mod srtp; +pub mod ssl; +pub mod stack; +pub mod string; +pub mod symm; +pub mod version; +pub mod x509; + +#[cfg(boringssl)] +type LenType = libc::size_t; +#[cfg(not(boringssl))] +type LenType = libc::c_int; + +#[cfg(boringssl)] +type SLenType = libc::ssize_t; +#[cfg(not(boringssl))] +type SLenType = libc::c_int; + +#[inline] +fn cvt_p(r: *mut T) -> Result<*mut T, ErrorStack> { + if r.is_null() { + Err(ErrorStack::get()) + } else { + Ok(r) + } +} + +#[inline] +fn cvt_p_const(r: *const T) -> Result<*const T, ErrorStack> { + if r.is_null() { + Err(ErrorStack::get()) + } else { + Ok(r) + } +} + +#[inline] +fn cvt(r: c_int) -> Result { + if r <= 0 { + Err(ErrorStack::get()) + } else { + Ok(r) + } +} + +// cvt_long is currently only used in functions that require openssl >= 3.0.0, +// so this cfg statement is used to avoid "unused function" errors when +// compiling with openssl < 3.0.0 +#[inline] +#[cfg(ossl300)] +fn cvt_long(r: c_long) -> Result { + if r <= 0 { + Err(ErrorStack::get()) + } else { + Ok(r) + } +} + +#[inline] +fn cvt_n(r: c_int) -> Result { + if r < 0 { + Err(ErrorStack::get()) + } else { + Ok(r) + } +} diff --git a/vendor/openssl/src/lib_ctx.rs b/vendor/openssl/src/lib_ctx.rs new file mode 100644 index 0000000..1fcdc65 --- /dev/null +++ b/vendor/openssl/src/lib_ctx.rs @@ -0,0 +1,22 @@ +use crate::cvt_p; +use crate::error::ErrorStack; +use foreign_types::ForeignType; +use openssl_macros::corresponds; + +foreign_type_and_impl_send_sync! { + type CType = ffi::OSSL_LIB_CTX; + fn drop = ffi::OSSL_LIB_CTX_free; + + pub struct LibCtx; + pub struct LibCtxRef; +} + +impl LibCtx { + #[corresponds(OSSL_LIB_CTX_new)] + pub fn new() -> Result { + unsafe { + let ptr = cvt_p(ffi::OSSL_LIB_CTX_new())?; + Ok(LibCtx::from_ptr(ptr)) + } + } +} diff --git a/vendor/openssl/src/macros.rs b/vendor/openssl/src/macros.rs new file mode 100644 index 0000000..69d1459 --- /dev/null +++ b/vendor/openssl/src/macros.rs @@ -0,0 +1,270 @@ +macro_rules! private_key_from_pem { + ($(#[$m:meta])* $n:ident, $(#[$m2:meta])* $n2:ident, $(#[$m3:meta])* $n3:ident, $t:ty, $f:path) => { + from_pem!($(#[$m])* $n, $t, $f); + + $(#[$m2])* + pub fn $n2(pem: &[u8], passphrase: &[u8]) -> Result<$t, crate::error::ErrorStack> { + unsafe { + ffi::init(); + let bio = crate::bio::MemBioSlice::new(pem)?; + let passphrase = ::std::ffi::CString::new(passphrase).unwrap(); + cvt_p($f(bio.as_ptr(), + ptr::null_mut(), + None, + passphrase.as_ptr() as *const _ as *mut _)) + .map(|p| ::foreign_types::ForeignType::from_ptr(p)) + } + } + + $(#[$m3])* + pub fn $n3(pem: &[u8], callback: F) -> Result<$t, crate::error::ErrorStack> + where F: FnOnce(&mut [u8]) -> Result + { + unsafe { + ffi::init(); + let mut cb = crate::util::CallbackState::new(callback); + let bio = crate::bio::MemBioSlice::new(pem)?; + cvt_p($f(bio.as_ptr(), + ptr::null_mut(), + Some(crate::util::invoke_passwd_cb::), + &mut cb as *mut _ as *mut _)) + .map(|p| ::foreign_types::ForeignType::from_ptr(p)) + } + } + } +} + +macro_rules! private_key_to_pem { + ($(#[$m:meta])* $n:ident, $(#[$m2:meta])* $n2:ident, $f:path) => { + $(#[$m])* + pub fn $n(&self) -> Result, crate::error::ErrorStack> { + unsafe { + let bio = crate::bio::MemBio::new()?; + cvt($f(bio.as_ptr(), + self.as_ptr(), + ptr::null(), + ptr::null_mut(), + -1, + None, + ptr::null_mut()))?; + Ok(bio.get_buf().to_owned()) + } + } + + $(#[$m2])* + pub fn $n2( + &self, + cipher: crate::symm::Cipher, + passphrase: &[u8] + ) -> Result, crate::error::ErrorStack> { + unsafe { + let bio = crate::bio::MemBio::new()?; + assert!(passphrase.len() <= ::libc::c_int::MAX as usize); + cvt($f(bio.as_ptr(), + self.as_ptr(), + cipher.as_ptr(), + passphrase.as_ptr() as *const _ as *mut _, + passphrase.len() as ::libc::c_int, + None, + ptr::null_mut()))?; + Ok(bio.get_buf().to_owned()) + } + } + } +} + +macro_rules! to_pem { + ($(#[$m:meta])* $n:ident, $f:path) => { + $(#[$m])* + pub fn $n(&self) -> Result, crate::error::ErrorStack> { + unsafe { + let bio = crate::bio::MemBio::new()?; + cvt($f(bio.as_ptr(), self.as_ptr()))?; + Ok(bio.get_buf().to_owned()) + } + } + } +} + +macro_rules! to_der { + ($(#[$m:meta])* $n:ident, $f:path) => { + $(#[$m])* + pub fn $n(&self) -> Result, crate::error::ErrorStack> { + unsafe { + let len = crate::cvt($f(::foreign_types::ForeignTypeRef::as_ptr(self), + ptr::null_mut()))?; + let mut buf = vec![0; len as usize]; + crate::cvt($f(::foreign_types::ForeignTypeRef::as_ptr(self), + &mut buf.as_mut_ptr()))?; + Ok(buf) + } + } + }; +} + +macro_rules! from_der { + ($(#[$m:meta])* $n:ident, $t:ty, $f:path) => { + $(#[$m])* + pub fn $n(der: &[u8]) -> Result<$t, crate::error::ErrorStack> { + use std::convert::TryInto; + unsafe { + ffi::init(); + let len = ::std::cmp::min(der.len(), ::libc::c_long::MAX as usize) as ::libc::c_long; + crate::cvt_p($f(::std::ptr::null_mut(), &mut der.as_ptr(), len.try_into().unwrap())) + .map(|p| ::foreign_types::ForeignType::from_ptr(p)) + } + } + } +} + +macro_rules! from_pem { + ($(#[$m:meta])* $n:ident, $t:ty, $f:path) => { + $(#[$m])* + pub fn $n(pem: &[u8]) -> Result<$t, crate::error::ErrorStack> { + unsafe { + crate::init(); + let bio = crate::bio::MemBioSlice::new(pem)?; + cvt_p($f(bio.as_ptr(), ::std::ptr::null_mut(), None, ::std::ptr::null_mut())) + .map(|p| ::foreign_types::ForeignType::from_ptr(p)) + } + } + } +} + +macro_rules! foreign_type_and_impl_send_sync { + ( + $(#[$impl_attr:meta])* + type CType = $ctype:ty; + fn drop = $drop:expr; + $(fn clone = $clone:expr;)* + + $(#[$owned_attr:meta])* + pub struct $owned:ident; + $(#[$borrowed_attr:meta])* + pub struct $borrowed:ident; + ) + => { + ::foreign_types::foreign_type! { + $(#[$impl_attr])* + type CType = $ctype; + fn drop = $drop; + $(fn clone = $clone;)* + $(#[$owned_attr])* + pub struct $owned; + $(#[$borrowed_attr])* + pub struct $borrowed; + } + + unsafe impl Send for $owned{} + unsafe impl Send for $borrowed{} + unsafe impl Sync for $owned{} + unsafe impl Sync for $borrowed{} + }; +} + +macro_rules! generic_foreign_type_and_impl_send_sync { + ( + $(#[$impl_attr:meta])* + type CType = $ctype:ty; + fn drop = $drop:expr; + $(fn clone = $clone:expr;)* + + $(#[$owned_attr:meta])* + pub struct $owned:ident; + $(#[$borrowed_attr:meta])* + pub struct $borrowed:ident; + ) => { + $(#[$owned_attr])* + pub struct $owned(*mut $ctype, ::std::marker::PhantomData); + + $(#[$impl_attr])* + impl ::foreign_types::ForeignType for $owned { + type CType = $ctype; + type Ref = $borrowed; + + #[inline] + unsafe fn from_ptr(ptr: *mut $ctype) -> $owned { + $owned(ptr, ::std::marker::PhantomData) + } + + #[inline] + fn as_ptr(&self) -> *mut $ctype { + self.0 + } + } + + impl Drop for $owned { + #[inline] + fn drop(&mut self) { + unsafe { $drop(self.0) } + } + } + + $( + impl Clone for $owned { + #[inline] + fn clone(&self) -> $owned { + unsafe { + let handle: *mut $ctype = $clone(self.0); + ::foreign_types::ForeignType::from_ptr(handle) + } + } + } + + impl ::std::borrow::ToOwned for $borrowed { + type Owned = $owned; + #[inline] + fn to_owned(&self) -> $owned { + unsafe { + let handle: *mut $ctype = + $clone(::foreign_types::ForeignTypeRef::as_ptr(self)); + $crate::ForeignType::from_ptr(handle) + } + } + } + )* + + impl ::std::ops::Deref for $owned { + type Target = $borrowed; + + #[inline] + fn deref(&self) -> &$borrowed { + unsafe { ::foreign_types::ForeignTypeRef::from_ptr(self.0) } + } + } + + impl ::std::ops::DerefMut for $owned { + #[inline] + fn deref_mut(&mut self) -> &mut $borrowed { + unsafe { ::foreign_types::ForeignTypeRef::from_ptr_mut(self.0) } + } + } + + impl ::std::borrow::Borrow<$borrowed> for $owned { + #[inline] + fn borrow(&self) -> &$borrowed { + &**self + } + } + + impl ::std::convert::AsRef<$borrowed> for $owned { + #[inline] + fn as_ref(&self) -> &$borrowed { + &**self + } + } + + $(#[$borrowed_attr])* + pub struct $borrowed(::foreign_types::Opaque, ::std::marker::PhantomData); + + $(#[$impl_attr])* + impl ::foreign_types::ForeignTypeRef for $borrowed { + type CType = $ctype; + } + + unsafe impl Send for $owned{} + unsafe impl Send for $borrowed{} + unsafe impl Sync for $owned{} + unsafe impl Sync for $borrowed{} + }; +} diff --git a/vendor/openssl/src/md.rs b/vendor/openssl/src/md.rs new file mode 100644 index 0000000..a9df311 --- /dev/null +++ b/vendor/openssl/src/md.rs @@ -0,0 +1,235 @@ +//! Message digest algorithms. + +#[cfg(ossl300)] +use crate::cvt_p; +#[cfg(ossl300)] +use crate::error::ErrorStack; +#[cfg(ossl300)] +use crate::lib_ctx::LibCtxRef; +use crate::nid::Nid; +use cfg_if::cfg_if; +use foreign_types::{ForeignTypeRef, Opaque}; +use openssl_macros::corresponds; +#[cfg(ossl300)] +use std::ffi::CString; +#[cfg(ossl300)] +use std::ptr; + +cfg_if! { + if #[cfg(ossl300)] { + use foreign_types::ForeignType; + use std::ops::{Deref, DerefMut}; + + type Inner = *mut ffi::EVP_MD; + + impl Drop for Md { + #[inline] + fn drop(&mut self) { + unsafe { + ffi::EVP_MD_free(self.as_ptr()); + } + } + } + + impl ForeignType for Md { + type CType = ffi::EVP_MD; + type Ref = MdRef; + + #[inline] + unsafe fn from_ptr(ptr: *mut Self::CType) -> Self { + Md(ptr) + } + + #[inline] + fn as_ptr(&self) -> *mut Self::CType { + self.0 + } + } + + impl Deref for Md { + type Target = MdRef; + + #[inline] + fn deref(&self) -> &Self::Target { + unsafe { + MdRef::from_ptr(self.as_ptr()) + } + } + } + + impl DerefMut for Md { + #[inline] + fn deref_mut(&mut self) -> &mut Self::Target { + unsafe { + MdRef::from_ptr_mut(self.as_ptr()) + } + } + } + } else { + enum Inner {} + } +} + +/// A message digest algorithm. +pub struct Md(Inner); + +unsafe impl Sync for Md {} +unsafe impl Send for Md {} + +impl Md { + /// Returns the `Md` corresponding to an [`Nid`]. + #[corresponds(EVP_get_digestbynid)] + pub fn from_nid(type_: Nid) -> Option<&'static MdRef> { + ffi::init(); + unsafe { + let ptr = ffi::EVP_get_digestbynid(type_.as_raw()); + if ptr.is_null() { + None + } else { + Some(MdRef::from_ptr(ptr as *mut _)) + } + } + } + + /// Fetches an `Md` object corresponding to the specified algorithm name and properties. + /// + /// Requires OpenSSL 3.0.0 or newer. + #[corresponds(EVP_MD_fetch)] + #[cfg(ossl300)] + pub fn fetch( + ctx: Option<&LibCtxRef>, + algorithm: &str, + properties: Option<&str>, + ) -> Result { + ffi::init(); + let algorithm = CString::new(algorithm).unwrap(); + let properties = properties.map(|s| CString::new(s).unwrap()); + + unsafe { + let ptr = cvt_p(ffi::EVP_MD_fetch( + ctx.map_or(ptr::null_mut(), ForeignTypeRef::as_ptr), + algorithm.as_ptr(), + properties.map_or(ptr::null_mut(), |s| s.as_ptr()), + ))?; + + Ok(Md::from_ptr(ptr)) + } + } + + #[inline] + #[cfg(not(boringssl))] + pub fn null() -> &'static MdRef { + unsafe { MdRef::from_ptr(ffi::EVP_md_null() as *mut _) } + } + + #[inline] + pub fn md5() -> &'static MdRef { + unsafe { MdRef::from_ptr(ffi::EVP_md5() as *mut _) } + } + + #[inline] + pub fn sha1() -> &'static MdRef { + unsafe { MdRef::from_ptr(ffi::EVP_sha1() as *mut _) } + } + + #[inline] + pub fn sha224() -> &'static MdRef { + unsafe { MdRef::from_ptr(ffi::EVP_sha224() as *mut _) } + } + + #[inline] + pub fn sha256() -> &'static MdRef { + unsafe { MdRef::from_ptr(ffi::EVP_sha256() as *mut _) } + } + + #[inline] + pub fn sha384() -> &'static MdRef { + unsafe { MdRef::from_ptr(ffi::EVP_sha384() as *mut _) } + } + + #[inline] + pub fn sha512() -> &'static MdRef { + unsafe { MdRef::from_ptr(ffi::EVP_sha512() as *mut _) } + } + + #[cfg(any(ossl111, libressl380))] + #[inline] + pub fn sha3_224() -> &'static MdRef { + unsafe { MdRef::from_ptr(ffi::EVP_sha3_224() as *mut _) } + } + + #[cfg(any(ossl111, libressl380))] + #[inline] + pub fn sha3_256() -> &'static MdRef { + unsafe { MdRef::from_ptr(ffi::EVP_sha3_256() as *mut _) } + } + + #[cfg(any(ossl111, libressl380))] + #[inline] + pub fn sha3_384() -> &'static MdRef { + unsafe { MdRef::from_ptr(ffi::EVP_sha3_384() as *mut _) } + } + + #[cfg(any(ossl111, libressl380))] + #[inline] + pub fn sha3_512() -> &'static MdRef { + unsafe { MdRef::from_ptr(ffi::EVP_sha3_512() as *mut _) } + } + + #[cfg(ossl111)] + #[inline] + pub fn shake128() -> &'static MdRef { + unsafe { MdRef::from_ptr(ffi::EVP_shake128() as *mut _) } + } + + #[cfg(ossl111)] + #[inline] + pub fn shake256() -> &'static MdRef { + unsafe { MdRef::from_ptr(ffi::EVP_shake256() as *mut _) } + } + + #[cfg(not(osslconf = "OPENSSL_NO_RMD160"))] + #[inline] + pub fn ripemd160() -> &'static MdRef { + unsafe { MdRef::from_ptr(ffi::EVP_ripemd160() as *mut _) } + } + + #[cfg(all(any(ossl111, libressl291), not(osslconf = "OPENSSL_NO_SM3")))] + #[inline] + pub fn sm3() -> &'static MdRef { + unsafe { MdRef::from_ptr(ffi::EVP_sm3() as *mut _) } + } +} + +/// A reference to an [`Md`]. +pub struct MdRef(Opaque); + +impl ForeignTypeRef for MdRef { + type CType = ffi::EVP_MD; +} + +unsafe impl Sync for MdRef {} +unsafe impl Send for MdRef {} + +impl MdRef { + /// Returns the block size of the digest in bytes. + #[corresponds(EVP_MD_block_size)] + #[inline] + pub fn block_size(&self) -> usize { + unsafe { ffi::EVP_MD_block_size(self.as_ptr()) as usize } + } + + /// Returns the size of the digest in bytes. + #[corresponds(EVP_MD_size)] + #[inline] + pub fn size(&self) -> usize { + unsafe { ffi::EVP_MD_size(self.as_ptr()) as usize } + } + + /// Returns the [`Nid`] of the digest. + #[corresponds(EVP_MD_type)] + #[inline] + pub fn type_(&self) -> Nid { + unsafe { Nid::from_raw(ffi::EVP_MD_type(self.as_ptr())) } + } +} diff --git a/vendor/openssl/src/md_ctx.rs b/vendor/openssl/src/md_ctx.rs new file mode 100644 index 0000000..36be3e9 --- /dev/null +++ b/vendor/openssl/src/md_ctx.rs @@ -0,0 +1,552 @@ +//! The message digest context. +//! +//! # Examples +//! +//! Compute the SHA256 checksum of data +//! +//! ``` +//! use openssl::md::Md; +//! use openssl::md_ctx::MdCtx; +//! +//! let mut ctx = MdCtx::new().unwrap(); +//! ctx.digest_init(Md::sha256()).unwrap(); +//! ctx.digest_update(b"Some Crypto Text").unwrap(); +//! let mut digest = [0; 32]; +//! ctx.digest_final(&mut digest).unwrap(); +//! +//! assert_eq!( +//! digest, +//! *b"\x60\x78\x56\x38\x8a\xca\x5c\x51\x83\xc4\xd1\x4d\xc8\xf9\xcc\xf2\ +//! \xa5\x21\xb3\x10\x93\x72\xfa\xd6\x7c\x55\xf5\xc9\xe3\xd1\x83\x19", +//! ); +//! ``` +//! +//! Sign and verify data with RSA and SHA256 +//! +//! ``` +//! use openssl::md::Md; +//! use openssl::md_ctx::MdCtx; +//! use openssl::pkey::PKey; +//! use openssl::rsa::Rsa; +//! +//! // Generate a random RSA key. +//! let key = Rsa::generate(4096).unwrap(); +//! let key = PKey::from_rsa(key).unwrap(); +//! +//! let text = b"Some Crypto Text"; +//! +//! // Create the signature. +//! let mut ctx = MdCtx::new().unwrap(); +//! ctx.digest_sign_init(Some(Md::sha256()), &key).unwrap(); +//! ctx.digest_sign_update(text).unwrap(); +//! let mut signature = vec![]; +//! ctx.digest_sign_final_to_vec(&mut signature).unwrap(); +//! +//! // Verify the signature. +//! let mut ctx = MdCtx::new().unwrap(); +//! ctx.digest_verify_init(Some(Md::sha256()), &key).unwrap(); +//! ctx.digest_verify_update(text).unwrap(); +//! let valid = ctx.digest_verify_final(&signature).unwrap(); +//! assert!(valid); +//! ``` +//! + +#![cfg_attr( + not(boringssl), + doc = r#"\ +Compute and verify an HMAC-SHA256 + +``` +use openssl::md::Md; +use openssl::md_ctx::MdCtx; +use openssl::memcmp; +use openssl::pkey::PKey; + +// Create a key with the HMAC secret. +let key = PKey::hmac(b"my secret").unwrap(); + +let text = b"Some Crypto Text"; + +// Compute the HMAC. +let mut ctx = MdCtx::new().unwrap(); +ctx.digest_sign_init(Some(Md::sha256()), &key).unwrap(); +ctx.digest_sign_update(text).unwrap(); +let mut hmac = vec![]; +ctx.digest_sign_final_to_vec(&mut hmac).unwrap(); + +// Verify the HMAC. You can't use MdCtx to do this; instead use a constant time equality check. +# let target = hmac.clone(); +let valid = memcmp::eq(&hmac, &target); +assert!(valid); +```"# +)] + +use crate::error::ErrorStack; +use crate::md::MdRef; +use crate::pkey::{HasPrivate, HasPublic, PKeyRef}; +use crate::pkey_ctx::PkeyCtxRef; +use crate::{cvt, cvt_p}; +use cfg_if::cfg_if; +use foreign_types::{ForeignType, ForeignTypeRef}; +use openssl_macros::corresponds; +use std::convert::TryFrom; +use std::ptr; + +cfg_if! { + if #[cfg(any(ossl110, boringssl, libressl382))] { + use ffi::{EVP_MD_CTX_free, EVP_MD_CTX_new}; + } else { + use ffi::{EVP_MD_CTX_create as EVP_MD_CTX_new, EVP_MD_CTX_destroy as EVP_MD_CTX_free}; + } +} + +foreign_type_and_impl_send_sync! { + type CType = ffi::EVP_MD_CTX; + fn drop = EVP_MD_CTX_free; + + pub struct MdCtx; + /// A reference to an [`MdCtx`]. + pub struct MdCtxRef; +} + +impl MdCtx { + /// Creates a new context. + #[corresponds(EVP_MD_CTX_new)] + #[inline] + pub fn new() -> Result { + ffi::init(); + + unsafe { + let ptr = cvt_p(EVP_MD_CTX_new())?; + Ok(MdCtx::from_ptr(ptr)) + } + } +} + +impl MdCtxRef { + /// Initializes the context to compute the digest of data. + #[corresponds(EVP_DigestInit_ex)] + #[inline] + pub fn digest_init(&mut self, digest: &MdRef) -> Result<(), ErrorStack> { + unsafe { + cvt(ffi::EVP_DigestInit_ex( + self.as_ptr(), + digest.as_ptr(), + ptr::null_mut(), + ))?; + } + + Ok(()) + } + + /// Initializes the context to compute the signature of data. + /// + /// A reference to the context's inner `PkeyCtx` is returned, allowing signature settings to be configured. + #[corresponds(EVP_DigestSignInit)] + #[inline] + pub fn digest_sign_init<'a, T>( + &'a mut self, + digest: Option<&MdRef>, + pkey: &PKeyRef, + ) -> Result<&'a mut PkeyCtxRef, ErrorStack> + where + T: HasPrivate, + { + unsafe { + let mut p = ptr::null_mut(); + cvt(ffi::EVP_DigestSignInit( + self.as_ptr(), + &mut p, + digest.map_or(ptr::null(), |p| p.as_ptr()), + ptr::null_mut(), + pkey.as_ptr(), + ))?; + Ok(PkeyCtxRef::from_ptr_mut(p)) + } + } + + /// Initializes the context to verify the signature of data. + /// + /// A reference to the context's inner `PkeyCtx` is returned, allowing signature settings to be configured. + #[corresponds(EVP_DigestVerifyInit)] + #[inline] + pub fn digest_verify_init<'a, T>( + &'a mut self, + digest: Option<&MdRef>, + pkey: &PKeyRef, + ) -> Result<&'a mut PkeyCtxRef, ErrorStack> + where + T: HasPublic, + { + unsafe { + let mut p = ptr::null_mut(); + cvt(ffi::EVP_DigestVerifyInit( + self.as_ptr(), + &mut p, + digest.map_or(ptr::null(), |p| p.as_ptr()), + ptr::null_mut(), + pkey.as_ptr(), + ))?; + Ok(PkeyCtxRef::from_ptr_mut(p)) + } + } + + /// Updates the context with more data. + #[corresponds(EVP_DigestUpdate)] + #[inline] + pub fn digest_update(&mut self, data: &[u8]) -> Result<(), ErrorStack> { + unsafe { + cvt(ffi::EVP_DigestUpdate( + self.as_ptr(), + data.as_ptr() as *const _, + data.len(), + ))?; + } + + Ok(()) + } + + /// Updates the context with more data. + #[corresponds(EVP_DigestSignUpdate)] + #[inline] + pub fn digest_sign_update(&mut self, data: &[u8]) -> Result<(), ErrorStack> { + unsafe { + cvt(ffi::EVP_DigestSignUpdate( + self.as_ptr(), + data.as_ptr() as *const _, + data.len(), + ))?; + } + + Ok(()) + } + + /// Updates the context with more data. + #[corresponds(EVP_DigestVerifyUpdate)] + #[inline] + pub fn digest_verify_update(&mut self, data: &[u8]) -> Result<(), ErrorStack> { + unsafe { + cvt(ffi::EVP_DigestVerifyUpdate( + self.as_ptr(), + data.as_ptr() as *const _, + data.len(), + ))?; + } + + Ok(()) + } + + /// Copies the computed digest into the buffer, returning the number of bytes written. + #[corresponds(EVP_DigestFinal)] + #[inline] + pub fn digest_final(&mut self, out: &mut [u8]) -> Result { + let mut len = u32::try_from(out.len()).unwrap_or(u32::MAX); + + unsafe { + cvt(ffi::EVP_DigestFinal( + self.as_ptr(), + out.as_mut_ptr(), + &mut len, + ))?; + } + + Ok(len as usize) + } + + /// Copies the computed digest into the buffer. + /// + /// Requires OpenSSL 1.1.1 or newer. + #[corresponds(EVP_DigestFinalXOF)] + #[inline] + #[cfg(ossl111)] + pub fn digest_final_xof(&mut self, out: &mut [u8]) -> Result<(), ErrorStack> { + unsafe { + cvt(ffi::EVP_DigestFinalXOF( + self.as_ptr(), + out.as_mut_ptr(), + out.len(), + ))?; + } + + Ok(()) + } + + /// Signs the computed digest. + /// + /// If `out` is set to `None`, an upper bound on the number of bytes required for the output buffer will be + /// returned. + #[corresponds(EVP_DigestSignFinal)] + #[inline] + pub fn digest_sign_final(&mut self, out: Option<&mut [u8]>) -> Result { + let mut len = out.as_ref().map_or(0, |b| b.len()); + + unsafe { + cvt(ffi::EVP_DigestSignFinal( + self.as_ptr(), + out.map_or(ptr::null_mut(), |b| b.as_mut_ptr()), + &mut len, + ))?; + } + + Ok(len) + } + + /// Like [`Self::digest_sign_final`] but appends the signature to a [`Vec`]. + pub fn digest_sign_final_to_vec(&mut self, out: &mut Vec) -> Result { + let base = out.len(); + let len = self.digest_sign_final(None)?; + out.resize(base + len, 0); + let len = self.digest_sign_final(Some(&mut out[base..]))?; + out.truncate(base + len); + Ok(len) + } + + /// Verifies the provided signature. + /// + /// Returns `Ok(true)` if the signature is valid, `Ok(false)` if the signature is invalid, and `Err` if an error + /// occurred. + #[corresponds(EVP_DigestVerifyFinal)] + #[inline] + pub fn digest_verify_final(&mut self, signature: &[u8]) -> Result { + unsafe { + let r = ffi::EVP_DigestVerifyFinal( + self.as_ptr(), + signature.as_ptr() as *mut _, + signature.len(), + ); + if r == 1 { + Ok(true) + } else { + let errors = ErrorStack::get(); + if errors.errors().is_empty() { + Ok(false) + } else { + Err(errors) + } + } + } + } + + /// Computes the signature of the data in `from`. + /// + /// If `to` is set to `None`, an upper bound on the number of bytes required for the output buffer will be + /// returned. + /// + /// Requires OpenSSL 1.1.1 or newer. + #[corresponds(EVP_DigestSign)] + #[cfg(ossl111)] + #[inline] + pub fn digest_sign(&mut self, from: &[u8], to: Option<&mut [u8]>) -> Result { + let mut len = to.as_ref().map_or(0, |b| b.len()); + + unsafe { + cvt(ffi::EVP_DigestSign( + self.as_ptr(), + to.map_or(ptr::null_mut(), |b| b.as_mut_ptr()), + &mut len, + from.as_ptr(), + from.len(), + ))?; + } + + Ok(len) + } + + /// Like [`Self::digest_sign`] but appends the signature to a [`Vec`]. + #[cfg(ossl111)] + pub fn digest_sign_to_vec( + &mut self, + from: &[u8], + to: &mut Vec, + ) -> Result { + let base = to.len(); + let len = self.digest_sign(from, None)?; + to.resize(base + len, 0); + let len = self.digest_sign(from, Some(&mut to[base..]))?; + to.truncate(base + len); + Ok(len) + } + + /// Verifies the signature of the data in `data`. + /// + /// Returns `Ok(true)` if the signature is valid, `Ok(false)` if the signature is invalid, and `Err` if an error + /// occurred. + /// + /// Requires OpenSSL 1.1.1 or newer. + #[corresponds(EVP_DigestVerify)] + #[cfg(ossl111)] + #[inline] + pub fn digest_verify(&mut self, data: &[u8], signature: &[u8]) -> Result { + unsafe { + let r = cvt(ffi::EVP_DigestVerify( + self.as_ptr(), + signature.as_ptr(), + signature.len(), + data.as_ptr(), + data.len(), + ))?; + Ok(r == 1) + } + } + + /// Returns the size of the message digest, i.e. the size of the hash + #[corresponds(EVP_MD_CTX_size)] + #[inline] + pub fn size(&self) -> usize { + unsafe { ffi::EVP_MD_CTX_size(self.as_ptr()) as usize } + } + + /// Resets the underlying EVP_MD_CTX instance + #[corresponds(EVP_MD_CTX_reset)] + #[cfg(ossl111)] + #[inline] + pub fn reset(&mut self) -> Result<(), ErrorStack> { + unsafe { + let _ = cvt(ffi::EVP_MD_CTX_reset(self.as_ptr()))?; + Ok(()) + } + } +} + +#[cfg(test)] +mod test { + use super::*; + use crate::md::Md; + use crate::pkey::PKey; + use crate::rsa::Rsa; + + #[test] + fn verify_fail() { + let key1 = Rsa::generate(4096).unwrap(); + let key1 = PKey::from_rsa(key1).unwrap(); + + let md = Md::sha256(); + let data = b"Some Crypto Text"; + + let mut ctx = MdCtx::new().unwrap(); + ctx.digest_sign_init(Some(md), &key1).unwrap(); + ctx.digest_sign_update(data).unwrap(); + let mut signature = vec![]; + ctx.digest_sign_final_to_vec(&mut signature).unwrap(); + + let bad_data = b"Some Crypto text"; + + ctx.digest_verify_init(Some(md), &key1).unwrap(); + ctx.digest_verify_update(bad_data).unwrap(); + assert!(matches!( + ctx.digest_verify_final(&signature), + Ok(false) | Err(_) + )); + assert!(ErrorStack::get().errors().is_empty()); + } + + #[test] + fn verify_success() { + let key1 = Rsa::generate(2048).unwrap(); + let key1 = PKey::from_rsa(key1).unwrap(); + + let md = Md::sha256(); + let data = b"Some Crypto Text"; + + let mut ctx = MdCtx::new().unwrap(); + ctx.digest_sign_init(Some(md), &key1).unwrap(); + ctx.digest_sign_update(data).unwrap(); + let mut signature = vec![]; + ctx.digest_sign_final_to_vec(&mut signature).unwrap(); + + let good_data = b"Some Crypto Text"; + + ctx.digest_verify_init(Some(md), &key1).unwrap(); + ctx.digest_verify_update(good_data).unwrap(); + let valid = ctx.digest_verify_final(&signature).unwrap(); + assert!(valid); + } + + #[test] + fn verify_with_public_success() { + let rsa = Rsa::generate(2048).unwrap(); + let key1 = PKey::from_rsa(rsa.clone()).unwrap(); + + let md = Md::sha256(); + let data = b"Some Crypto Text"; + + let mut ctx = MdCtx::new().unwrap(); + ctx.digest_sign_init(Some(md), &key1).unwrap(); + ctx.digest_sign_update(data).unwrap(); + let mut signature = vec![]; + ctx.digest_sign_final_to_vec(&mut signature).unwrap(); + + let good_data = b"Some Crypto Text"; + + // try to verify using only public components of the key + let n = rsa.n().to_owned().unwrap(); + let e = rsa.e().to_owned().unwrap(); + + let rsa = Rsa::from_public_components(n, e).unwrap(); + let key1 = PKey::from_rsa(rsa).unwrap(); + + ctx.digest_verify_init(Some(md), &key1).unwrap(); + ctx.digest_verify_update(good_data).unwrap(); + let valid = ctx.digest_verify_final(&signature).unwrap(); + assert!(valid); + } + + #[test] + fn verify_md_ctx_size() { + let mut ctx = MdCtx::new().unwrap(); + ctx.digest_init(Md::sha224()).unwrap(); + assert_eq!(Md::sha224().size(), ctx.size()); + assert_eq!(Md::sha224().size(), 28); + + let mut ctx = MdCtx::new().unwrap(); + ctx.digest_init(Md::sha256()).unwrap(); + assert_eq!(Md::sha256().size(), ctx.size()); + assert_eq!(Md::sha256().size(), 32); + + let mut ctx = MdCtx::new().unwrap(); + ctx.digest_init(Md::sha384()).unwrap(); + assert_eq!(Md::sha384().size(), ctx.size()); + assert_eq!(Md::sha384().size(), 48); + + let mut ctx = MdCtx::new().unwrap(); + ctx.digest_init(Md::sha512()).unwrap(); + assert_eq!(Md::sha512().size(), ctx.size()); + assert_eq!(Md::sha512().size(), 64); + } + + #[test] + #[cfg(ossl111)] + fn verify_md_ctx_reset() { + let hello_expected = + hex::decode("185f8db32271fe25f561a6fc938b2e264306ec304eda518007d1764826381969") + .unwrap(); + let world_expected = + hex::decode("78ae647dc5544d227130a0682a51e30bc7777fbb6d8a8f17007463a3ecd1d524") + .unwrap(); + // Calculate SHA-256 digest of "Hello" + let mut ctx = MdCtx::new().unwrap(); + ctx.digest_init(Md::sha256()).unwrap(); + ctx.digest_update(b"Hello").unwrap(); + let mut result = vec![0; 32]; + let result_len = ctx.digest_final(result.as_mut_slice()).unwrap(); + assert_eq!(result_len, result.len()); + // Validate result of "Hello" + assert_eq!(result, hello_expected); + + // Create new context + let mut ctx = MdCtx::new().unwrap(); + // Initialize and update to "Hello" + ctx.digest_init(Md::sha256()).unwrap(); + ctx.digest_update(b"Hello").unwrap(); + // Now reset, init to SHA-256 and use "World" + ctx.reset().unwrap(); + ctx.digest_init(Md::sha256()).unwrap(); + ctx.digest_update(b"World").unwrap(); + + let mut reset_result = vec![0; 32]; + let result_len = ctx.digest_final(reset_result.as_mut_slice()).unwrap(); + assert_eq!(result_len, reset_result.len()); + // Validate result of digest of "World" + assert_eq!(reset_result, world_expected); + } +} diff --git a/vendor/openssl/src/memcmp.rs b/vendor/openssl/src/memcmp.rs new file mode 100644 index 0000000..91281b9 --- /dev/null +++ b/vendor/openssl/src/memcmp.rs @@ -0,0 +1,93 @@ +//! Utilities to safely compare cryptographic values. +//! +//! Extra care must be taken when comparing values in +//! cryptographic code. If done incorrectly, it can lead +//! to a [timing attack](https://en.wikipedia.org/wiki/Timing_attack). +//! By analyzing the time taken to execute parts of a cryptographic +//! algorithm, and attacker can attempt to compromise the +//! cryptosystem. +//! +//! The utilities in this module are designed to be resistant +//! to this type of attack. +//! +//! # Examples +//! +//! To perform a constant-time comparison of two arrays of the same length but different +//! values: +//! +//! ``` +//! use openssl::memcmp::eq; +//! +//! // We want to compare `a` to `b` and `c`, without giving +//! // away through timing analysis that `c` is more similar to `a` +//! // than `b`. +//! let a = [0, 0, 0]; +//! let b = [1, 1, 1]; +//! let c = [0, 0, 1]; +//! +//! // These statements will execute in the same amount of time. +//! assert!(!eq(&a, &b)); +//! assert!(!eq(&a, &c)); +//! ``` +use libc::size_t; +use openssl_macros::corresponds; + +/// Returns `true` iff `a` and `b` contain the same bytes. +/// +/// This operation takes an amount of time dependent on the length of the two +/// arrays given, but is independent of the contents of a and b. +/// +/// # Panics +/// +/// This function will panic the current task if `a` and `b` do not have the same +/// length. +/// +/// # Examples +/// +/// To perform a constant-time comparison of two arrays of the same length but different +/// values: +/// +/// ``` +/// use openssl::memcmp::eq; +/// +/// // We want to compare `a` to `b` and `c`, without giving +/// // away through timing analysis that `c` is more similar to `a` +/// // than `b`. +/// let a = [0, 0, 0]; +/// let b = [1, 1, 1]; +/// let c = [0, 0, 1]; +/// +/// // These statements will execute in the same amount of time. +/// assert!(!eq(&a, &b)); +/// assert!(!eq(&a, &c)); +/// ``` +#[corresponds(CRYPTO_memcmp)] +pub fn eq(a: &[u8], b: &[u8]) -> bool { + assert!(a.len() == b.len()); + let ret = unsafe { + ffi::CRYPTO_memcmp( + a.as_ptr() as *const _, + b.as_ptr() as *const _, + a.len() as size_t, + ) + }; + ret == 0 +} + +#[cfg(test)] +mod tests { + use super::eq; + + #[test] + fn test_eq() { + assert!(eq(&[], &[])); + assert!(eq(&[1], &[1])); + assert!(!eq(&[1, 2, 3], &[1, 2, 4])); + } + + #[test] + #[should_panic] + fn test_diff_lens() { + eq(&[], &[1]); + } +} diff --git a/vendor/openssl/src/nid.rs b/vendor/openssl/src/nid.rs new file mode 100644 index 0000000..d093c67 --- /dev/null +++ b/vendor/openssl/src/nid.rs @@ -0,0 +1,1181 @@ +//! A collection of numerical identifiers for OpenSSL objects. +use libc::{c_char, c_int}; + +use std::ffi::CStr; +use std::ffi::CString; +use std::str; + +use crate::cvt_p; +use crate::error::ErrorStack; +use openssl_macros::corresponds; + +/// The digest and public-key algorithms associated with a signature. +pub struct SignatureAlgorithms { + /// The signature's digest. + /// + /// If the signature does not specify a digest, this will be `NID::UNDEF`. + pub digest: Nid, + + /// The signature's public-key. + pub pkey: Nid, +} + +/// A numerical identifier for an OpenSSL object. +/// +/// Objects in OpenSSL can have a short name, a long name, and +/// a numerical identifier (NID). For convenience, objects +/// are usually represented in source code using these numeric +/// identifiers. +/// +/// Users should generally not need to create new `Nid`s. +/// +/// # Examples +/// +/// To view the integer representation of a `Nid`: +/// +/// ``` +/// use openssl::nid::Nid; +/// +/// assert!(Nid::AES_256_GCM.as_raw() == 901); +/// ``` +/// +/// # External Documentation +/// +/// The following documentation provides context about `Nid`s and their usage +/// in OpenSSL. +/// +/// - [Obj_nid2obj](https://www.openssl.org/docs/manmaster/crypto/OBJ_create.html) +#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] +pub struct Nid(c_int); + +#[allow(non_snake_case)] +impl Nid { + /// Create a `Nid` from an integer representation. + pub const fn from_raw(raw: c_int) -> Nid { + Nid(raw) + } + + /// Return the integer representation of a `Nid`. + #[allow(clippy::trivially_copy_pass_by_ref)] + pub const fn as_raw(&self) -> c_int { + self.0 + } + + /// Creates a new `Nid` for the `oid` with short name `sn` and long name `ln`. + #[corresponds(OBJ_create)] + pub fn create(oid: &str, sn: &str, ln: &str) -> Result { + unsafe { + ffi::init(); + let oid = CString::new(oid).unwrap(); + let sn = CString::new(sn).unwrap(); + let ln = CString::new(ln).unwrap(); + let raw = ffi::OBJ_create(oid.as_ptr(), sn.as_ptr(), ln.as_ptr()); + if raw == ffi::NID_undef { + Err(ErrorStack::get()) + } else { + Ok(Nid(raw)) + } + } + } + + /// Returns the `Nid`s of the digest and public key algorithms associated with a signature ID. + #[corresponds(OBJ_find_sigid_algs)] + #[allow(clippy::trivially_copy_pass_by_ref)] + pub fn signature_algorithms(&self) -> Option { + unsafe { + let mut digest = 0; + let mut pkey = 0; + if ffi::OBJ_find_sigid_algs(self.0, &mut digest, &mut pkey) == 1 { + Some(SignatureAlgorithms { + digest: Nid(digest), + pkey: Nid(pkey), + }) + } else { + None + } + } + } + + /// Returns the string representation of a `Nid` (long). + #[corresponds(OBJ_nid2ln)] + #[allow(clippy::trivially_copy_pass_by_ref)] + pub fn long_name(&self) -> Result<&'static str, ErrorStack> { + unsafe { + cvt_p(ffi::OBJ_nid2ln(self.0) as *mut c_char) + .map(|nameptr| str::from_utf8(CStr::from_ptr(nameptr).to_bytes()).unwrap()) + } + } + + /// Returns the string representation of a `Nid` (short). + #[corresponds(OBJ_nid2sn)] + #[allow(clippy::trivially_copy_pass_by_ref)] + pub fn short_name(&self) -> Result<&'static str, ErrorStack> { + unsafe { + cvt_p(ffi::OBJ_nid2sn(self.0) as *mut c_char) + .map(|nameptr| str::from_utf8(CStr::from_ptr(nameptr).to_bytes()).unwrap()) + } + } + + pub const UNDEF: Nid = Nid(ffi::NID_undef); + pub const ITU_T: Nid = Nid(ffi::NID_itu_t); + #[cfg(not(boringssl))] + pub const CCITT: Nid = Nid(ffi::NID_ccitt); + pub const ISO: Nid = Nid(ffi::NID_iso); + pub const JOINT_ISO_ITU_T: Nid = Nid(ffi::NID_joint_iso_itu_t); + #[cfg(not(boringssl))] + pub const JOINT_ISO_CCITT: Nid = Nid(ffi::NID_joint_iso_ccitt); + pub const MEMBER_BODY: Nid = Nid(ffi::NID_member_body); + pub const IDENTIFIED_ORGANIZATION: Nid = Nid(ffi::NID_identified_organization); + pub const HMAC_MD5: Nid = Nid(ffi::NID_hmac_md5); + pub const HMAC_SHA1: Nid = Nid(ffi::NID_hmac_sha1); + pub const CERTICOM_ARC: Nid = Nid(ffi::NID_certicom_arc); + pub const INTERNATIONAL_ORGANIZATIONS: Nid = Nid(ffi::NID_international_organizations); + pub const WAP: Nid = Nid(ffi::NID_wap); + pub const WAP_WSG: Nid = Nid(ffi::NID_wap_wsg); + pub const SELECTED_ATTRIBUTE_TYPES: Nid = Nid(ffi::NID_selected_attribute_types); + pub const CLEARANCE: Nid = Nid(ffi::NID_clearance); + pub const ISO_US: Nid = Nid(ffi::NID_ISO_US); + pub const X9_57: Nid = Nid(ffi::NID_X9_57); + pub const X9CM: Nid = Nid(ffi::NID_X9cm); + pub const DSA: Nid = Nid(ffi::NID_dsa); + pub const DSAWITHSHA1: Nid = Nid(ffi::NID_dsaWithSHA1); + pub const ANSI_X9_62: Nid = Nid(ffi::NID_ansi_X9_62); + pub const X9_62_PRIME_FIELD: Nid = Nid(ffi::NID_X9_62_prime_field); + pub const X9_62_CHARACTERISTIC_TWO_FIELD: Nid = Nid(ffi::NID_X9_62_characteristic_two_field); + pub const X9_62_ID_CHARACTERISTIC_TWO_BASIS: Nid = + Nid(ffi::NID_X9_62_id_characteristic_two_basis); + pub const X9_62_ONBASIS: Nid = Nid(ffi::NID_X9_62_onBasis); + pub const X9_62_TPBASIS: Nid = Nid(ffi::NID_X9_62_tpBasis); + pub const X9_62_PPBASIS: Nid = Nid(ffi::NID_X9_62_ppBasis); + pub const X9_62_ID_ECPUBLICKEY: Nid = Nid(ffi::NID_X9_62_id_ecPublicKey); + pub const X9_62_C2PNB163V1: Nid = Nid(ffi::NID_X9_62_c2pnb163v1); + pub const X9_62_C2PNB163V2: Nid = Nid(ffi::NID_X9_62_c2pnb163v2); + pub const X9_62_C2PNB163V3: Nid = Nid(ffi::NID_X9_62_c2pnb163v3); + pub const X9_62_C2PNB176V1: Nid = Nid(ffi::NID_X9_62_c2pnb176v1); + pub const X9_62_C2TNB191V1: Nid = Nid(ffi::NID_X9_62_c2tnb191v1); + pub const X9_62_C2TNB191V2: Nid = Nid(ffi::NID_X9_62_c2tnb191v2); + pub const X9_62_C2TNB191V3: Nid = Nid(ffi::NID_X9_62_c2tnb191v3); + pub const X9_62_C2ONB191V4: Nid = Nid(ffi::NID_X9_62_c2onb191v4); + pub const X9_62_C2ONB191V5: Nid = Nid(ffi::NID_X9_62_c2onb191v5); + pub const X9_62_C2PNB208W1: Nid = Nid(ffi::NID_X9_62_c2pnb208w1); + pub const X9_62_C2TNB239V1: Nid = Nid(ffi::NID_X9_62_c2tnb239v1); + pub const X9_62_C2TNB239V2: Nid = Nid(ffi::NID_X9_62_c2tnb239v2); + pub const X9_62_C2TNB239V3: Nid = Nid(ffi::NID_X9_62_c2tnb239v3); + pub const X9_62_C2ONB239V4: Nid = Nid(ffi::NID_X9_62_c2onb239v4); + pub const X9_62_C2ONB239V5: Nid = Nid(ffi::NID_X9_62_c2onb239v5); + pub const X9_62_C2PNB272W1: Nid = Nid(ffi::NID_X9_62_c2pnb272w1); + pub const X9_62_C2PNB304W1: Nid = Nid(ffi::NID_X9_62_c2pnb304w1); + pub const X9_62_C2TNB359V1: Nid = Nid(ffi::NID_X9_62_c2tnb359v1); + pub const X9_62_C2PNB368W1: Nid = Nid(ffi::NID_X9_62_c2pnb368w1); + pub const X9_62_C2TNB431R1: Nid = Nid(ffi::NID_X9_62_c2tnb431r1); + pub const X9_62_PRIME192V1: Nid = Nid(ffi::NID_X9_62_prime192v1); + pub const X9_62_PRIME192V2: Nid = Nid(ffi::NID_X9_62_prime192v2); + pub const X9_62_PRIME192V3: Nid = Nid(ffi::NID_X9_62_prime192v3); + pub const X9_62_PRIME239V1: Nid = Nid(ffi::NID_X9_62_prime239v1); + pub const X9_62_PRIME239V2: Nid = Nid(ffi::NID_X9_62_prime239v2); + pub const X9_62_PRIME239V3: Nid = Nid(ffi::NID_X9_62_prime239v3); + pub const X9_62_PRIME256V1: Nid = Nid(ffi::NID_X9_62_prime256v1); + pub const ECDSA_WITH_SHA1: Nid = Nid(ffi::NID_ecdsa_with_SHA1); + pub const ECDSA_WITH_RECOMMENDED: Nid = Nid(ffi::NID_ecdsa_with_Recommended); + pub const ECDSA_WITH_SPECIFIED: Nid = Nid(ffi::NID_ecdsa_with_Specified); + pub const ECDSA_WITH_SHA224: Nid = Nid(ffi::NID_ecdsa_with_SHA224); + pub const ECDSA_WITH_SHA256: Nid = Nid(ffi::NID_ecdsa_with_SHA256); + pub const ECDSA_WITH_SHA384: Nid = Nid(ffi::NID_ecdsa_with_SHA384); + pub const ECDSA_WITH_SHA512: Nid = Nid(ffi::NID_ecdsa_with_SHA512); + pub const SECP112R1: Nid = Nid(ffi::NID_secp112r1); + pub const SECP112R2: Nid = Nid(ffi::NID_secp112r2); + pub const SECP128R1: Nid = Nid(ffi::NID_secp128r1); + pub const SECP128R2: Nid = Nid(ffi::NID_secp128r2); + pub const SECP160K1: Nid = Nid(ffi::NID_secp160k1); + pub const SECP160R1: Nid = Nid(ffi::NID_secp160r1); + pub const SECP160R2: Nid = Nid(ffi::NID_secp160r2); + pub const SECP192K1: Nid = Nid(ffi::NID_secp192k1); + pub const SECP224K1: Nid = Nid(ffi::NID_secp224k1); + pub const SECP224R1: Nid = Nid(ffi::NID_secp224r1); + pub const SECP256K1: Nid = Nid(ffi::NID_secp256k1); + pub const SECP384R1: Nid = Nid(ffi::NID_secp384r1); + pub const SECP521R1: Nid = Nid(ffi::NID_secp521r1); + pub const SECT113R1: Nid = Nid(ffi::NID_sect113r1); + pub const SECT113R2: Nid = Nid(ffi::NID_sect113r2); + pub const SECT131R1: Nid = Nid(ffi::NID_sect131r1); + pub const SECT131R2: Nid = Nid(ffi::NID_sect131r2); + pub const SECT163K1: Nid = Nid(ffi::NID_sect163k1); + pub const SECT163R1: Nid = Nid(ffi::NID_sect163r1); + pub const SECT163R2: Nid = Nid(ffi::NID_sect163r2); + pub const SECT193R1: Nid = Nid(ffi::NID_sect193r1); + pub const SECT193R2: Nid = Nid(ffi::NID_sect193r2); + pub const SECT233K1: Nid = Nid(ffi::NID_sect233k1); + pub const SECT233R1: Nid = Nid(ffi::NID_sect233r1); + pub const SECT239K1: Nid = Nid(ffi::NID_sect239k1); + pub const SECT283K1: Nid = Nid(ffi::NID_sect283k1); + pub const SECT283R1: Nid = Nid(ffi::NID_sect283r1); + pub const SECT409K1: Nid = Nid(ffi::NID_sect409k1); + pub const SECT409R1: Nid = Nid(ffi::NID_sect409r1); + pub const SECT571K1: Nid = Nid(ffi::NID_sect571k1); + pub const SECT571R1: Nid = Nid(ffi::NID_sect571r1); + #[cfg(any(ossl110, libressl))] + pub const BRAINPOOL_P256R1: Nid = Nid(ffi::NID_brainpoolP256r1); + #[cfg(any(ossl110, libressl))] + pub const BRAINPOOL_P320R1: Nid = Nid(ffi::NID_brainpoolP320r1); + #[cfg(any(ossl110, libressl))] + pub const BRAINPOOL_P384R1: Nid = Nid(ffi::NID_brainpoolP384r1); + #[cfg(any(ossl110, libressl))] + pub const BRAINPOOL_P512R1: Nid = Nid(ffi::NID_brainpoolP512r1); + pub const WAP_WSG_IDM_ECID_WTLS1: Nid = Nid(ffi::NID_wap_wsg_idm_ecid_wtls1); + pub const WAP_WSG_IDM_ECID_WTLS3: Nid = Nid(ffi::NID_wap_wsg_idm_ecid_wtls3); + pub const WAP_WSG_IDM_ECID_WTLS4: Nid = Nid(ffi::NID_wap_wsg_idm_ecid_wtls4); + pub const WAP_WSG_IDM_ECID_WTLS5: Nid = Nid(ffi::NID_wap_wsg_idm_ecid_wtls5); + pub const WAP_WSG_IDM_ECID_WTLS6: Nid = Nid(ffi::NID_wap_wsg_idm_ecid_wtls6); + pub const WAP_WSG_IDM_ECID_WTLS7: Nid = Nid(ffi::NID_wap_wsg_idm_ecid_wtls7); + pub const WAP_WSG_IDM_ECID_WTLS8: Nid = Nid(ffi::NID_wap_wsg_idm_ecid_wtls8); + pub const WAP_WSG_IDM_ECID_WTLS9: Nid = Nid(ffi::NID_wap_wsg_idm_ecid_wtls9); + pub const WAP_WSG_IDM_ECID_WTLS10: Nid = Nid(ffi::NID_wap_wsg_idm_ecid_wtls10); + pub const WAP_WSG_IDM_ECID_WTLS11: Nid = Nid(ffi::NID_wap_wsg_idm_ecid_wtls11); + pub const WAP_WSG_IDM_ECID_WTLS12: Nid = Nid(ffi::NID_wap_wsg_idm_ecid_wtls12); + pub const CAST5_CBC: Nid = Nid(ffi::NID_cast5_cbc); + pub const CAST5_ECB: Nid = Nid(ffi::NID_cast5_ecb); + pub const CAST5_CFB64: Nid = Nid(ffi::NID_cast5_cfb64); + pub const CAST5_OFB64: Nid = Nid(ffi::NID_cast5_ofb64); + pub const PBEWITHMD5ANDCAST5_CBC: Nid = Nid(ffi::NID_pbeWithMD5AndCast5_CBC); + pub const ID_PASSWORDBASEDMAC: Nid = Nid(ffi::NID_id_PasswordBasedMAC); + pub const ID_DHBASEDMAC: Nid = Nid(ffi::NID_id_DHBasedMac); + pub const RSADSI: Nid = Nid(ffi::NID_rsadsi); + pub const PKCS: Nid = Nid(ffi::NID_pkcs); + pub const PKCS1: Nid = Nid(ffi::NID_pkcs1); + pub const RSAENCRYPTION: Nid = Nid(ffi::NID_rsaEncryption); + pub const MD2WITHRSAENCRYPTION: Nid = Nid(ffi::NID_md2WithRSAEncryption); + pub const MD4WITHRSAENCRYPTION: Nid = Nid(ffi::NID_md4WithRSAEncryption); + pub const MD5WITHRSAENCRYPTION: Nid = Nid(ffi::NID_md5WithRSAEncryption); + pub const SHA1WITHRSAENCRYPTION: Nid = Nid(ffi::NID_sha1WithRSAEncryption); + pub const RSAESOAEP: Nid = Nid(ffi::NID_rsaesOaep); + pub const MGF1: Nid = Nid(ffi::NID_mgf1); + pub const RSASSAPSS: Nid = Nid(ffi::NID_rsassaPss); + pub const SHA256WITHRSAENCRYPTION: Nid = Nid(ffi::NID_sha256WithRSAEncryption); + pub const SHA384WITHRSAENCRYPTION: Nid = Nid(ffi::NID_sha384WithRSAEncryption); + pub const SHA512WITHRSAENCRYPTION: Nid = Nid(ffi::NID_sha512WithRSAEncryption); + pub const SHA224WITHRSAENCRYPTION: Nid = Nid(ffi::NID_sha224WithRSAEncryption); + pub const PKCS3: Nid = Nid(ffi::NID_pkcs3); + pub const DHKEYAGREEMENT: Nid = Nid(ffi::NID_dhKeyAgreement); + pub const PKCS5: Nid = Nid(ffi::NID_pkcs5); + pub const PBEWITHMD2ANDDES_CBC: Nid = Nid(ffi::NID_pbeWithMD2AndDES_CBC); + pub const PBEWITHMD5ANDDES_CBC: Nid = Nid(ffi::NID_pbeWithMD5AndDES_CBC); + pub const PBEWITHMD2ANDRC2_CBC: Nid = Nid(ffi::NID_pbeWithMD2AndRC2_CBC); + pub const PBEWITHMD5ANDRC2_CBC: Nid = Nid(ffi::NID_pbeWithMD5AndRC2_CBC); + pub const PBEWITHSHA1ANDDES_CBC: Nid = Nid(ffi::NID_pbeWithSHA1AndDES_CBC); + pub const PBEWITHSHA1ANDRC2_CBC: Nid = Nid(ffi::NID_pbeWithSHA1AndRC2_CBC); + pub const ID_PBKDF2: Nid = Nid(ffi::NID_id_pbkdf2); + pub const PBES2: Nid = Nid(ffi::NID_pbes2); + pub const PBMAC1: Nid = Nid(ffi::NID_pbmac1); + pub const PKCS7: Nid = Nid(ffi::NID_pkcs7); + pub const PKCS7_DATA: Nid = Nid(ffi::NID_pkcs7_data); + pub const PKCS7_SIGNED: Nid = Nid(ffi::NID_pkcs7_signed); + pub const PKCS7_ENVELOPED: Nid = Nid(ffi::NID_pkcs7_enveloped); + pub const PKCS7_SIGNEDANDENVELOPED: Nid = Nid(ffi::NID_pkcs7_signedAndEnveloped); + pub const PKCS7_DIGEST: Nid = Nid(ffi::NID_pkcs7_digest); + pub const PKCS7_ENCRYPTED: Nid = Nid(ffi::NID_pkcs7_encrypted); + pub const PKCS9: Nid = Nid(ffi::NID_pkcs9); + pub const PKCS9_EMAILADDRESS: Nid = Nid(ffi::NID_pkcs9_emailAddress); + pub const PKCS9_UNSTRUCTUREDNAME: Nid = Nid(ffi::NID_pkcs9_unstructuredName); + pub const PKCS9_CONTENTTYPE: Nid = Nid(ffi::NID_pkcs9_contentType); + pub const PKCS9_MESSAGEDIGEST: Nid = Nid(ffi::NID_pkcs9_messageDigest); + pub const PKCS9_SIGNINGTIME: Nid = Nid(ffi::NID_pkcs9_signingTime); + pub const PKCS9_COUNTERSIGNATURE: Nid = Nid(ffi::NID_pkcs9_countersignature); + pub const PKCS9_CHALLENGEPASSWORD: Nid = Nid(ffi::NID_pkcs9_challengePassword); + pub const PKCS9_UNSTRUCTUREDADDRESS: Nid = Nid(ffi::NID_pkcs9_unstructuredAddress); + pub const PKCS9_EXTCERTATTRIBUTES: Nid = Nid(ffi::NID_pkcs9_extCertAttributes); + pub const EXT_REQ: Nid = Nid(ffi::NID_ext_req); + pub const SMIMECAPABILITIES: Nid = Nid(ffi::NID_SMIMECapabilities); + pub const SMIME: Nid = Nid(ffi::NID_SMIME); + pub const ID_SMIME_MOD: Nid = Nid(ffi::NID_id_smime_mod); + pub const ID_SMIME_CT: Nid = Nid(ffi::NID_id_smime_ct); + pub const ID_SMIME_AA: Nid = Nid(ffi::NID_id_smime_aa); + pub const ID_SMIME_ALG: Nid = Nid(ffi::NID_id_smime_alg); + pub const ID_SMIME_CD: Nid = Nid(ffi::NID_id_smime_cd); + pub const ID_SMIME_SPQ: Nid = Nid(ffi::NID_id_smime_spq); + pub const ID_SMIME_CTI: Nid = Nid(ffi::NID_id_smime_cti); + pub const ID_SMIME_MOD_CMS: Nid = Nid(ffi::NID_id_smime_mod_cms); + pub const ID_SMIME_MOD_ESS: Nid = Nid(ffi::NID_id_smime_mod_ess); + pub const ID_SMIME_MOD_OID: Nid = Nid(ffi::NID_id_smime_mod_oid); + pub const ID_SMIME_MOD_MSG_V3: Nid = Nid(ffi::NID_id_smime_mod_msg_v3); + pub const ID_SMIME_MOD_ETS_ESIGNATURE_88: Nid = Nid(ffi::NID_id_smime_mod_ets_eSignature_88); + pub const ID_SMIME_MOD_ETS_ESIGNATURE_97: Nid = Nid(ffi::NID_id_smime_mod_ets_eSignature_97); + pub const ID_SMIME_MOD_ETS_ESIGPOLICY_88: Nid = Nid(ffi::NID_id_smime_mod_ets_eSigPolicy_88); + pub const ID_SMIME_MOD_ETS_ESIGPOLICY_97: Nid = Nid(ffi::NID_id_smime_mod_ets_eSigPolicy_97); + pub const ID_SMIME_CT_RECEIPT: Nid = Nid(ffi::NID_id_smime_ct_receipt); + pub const ID_SMIME_CT_AUTHDATA: Nid = Nid(ffi::NID_id_smime_ct_authData); + pub const ID_SMIME_CT_PUBLISHCERT: Nid = Nid(ffi::NID_id_smime_ct_publishCert); + pub const ID_SMIME_CT_TSTINFO: Nid = Nid(ffi::NID_id_smime_ct_TSTInfo); + pub const ID_SMIME_CT_TDTINFO: Nid = Nid(ffi::NID_id_smime_ct_TDTInfo); + pub const ID_SMIME_CT_CONTENTINFO: Nid = Nid(ffi::NID_id_smime_ct_contentInfo); + pub const ID_SMIME_CT_DVCSREQUESTDATA: Nid = Nid(ffi::NID_id_smime_ct_DVCSRequestData); + pub const ID_SMIME_CT_DVCSRESPONSEDATA: Nid = Nid(ffi::NID_id_smime_ct_DVCSResponseData); + pub const ID_SMIME_CT_COMPRESSEDDATA: Nid = Nid(ffi::NID_id_smime_ct_compressedData); + pub const ID_CT_ASCIITEXTWITHCRLF: Nid = Nid(ffi::NID_id_ct_asciiTextWithCRLF); + pub const ID_SMIME_AA_RECEIPTREQUEST: Nid = Nid(ffi::NID_id_smime_aa_receiptRequest); + pub const ID_SMIME_AA_SECURITYLABEL: Nid = Nid(ffi::NID_id_smime_aa_securityLabel); + pub const ID_SMIME_AA_MLEXPANDHISTORY: Nid = Nid(ffi::NID_id_smime_aa_mlExpandHistory); + pub const ID_SMIME_AA_CONTENTHINT: Nid = Nid(ffi::NID_id_smime_aa_contentHint); + pub const ID_SMIME_AA_MSGSIGDIGEST: Nid = Nid(ffi::NID_id_smime_aa_msgSigDigest); + pub const ID_SMIME_AA_ENCAPCONTENTTYPE: Nid = Nid(ffi::NID_id_smime_aa_encapContentType); + pub const ID_SMIME_AA_CONTENTIDENTIFIER: Nid = Nid(ffi::NID_id_smime_aa_contentIdentifier); + pub const ID_SMIME_AA_MACVALUE: Nid = Nid(ffi::NID_id_smime_aa_macValue); + pub const ID_SMIME_AA_EQUIVALENTLABELS: Nid = Nid(ffi::NID_id_smime_aa_equivalentLabels); + pub const ID_SMIME_AA_CONTENTREFERENCE: Nid = Nid(ffi::NID_id_smime_aa_contentReference); + pub const ID_SMIME_AA_ENCRYPKEYPREF: Nid = Nid(ffi::NID_id_smime_aa_encrypKeyPref); + pub const ID_SMIME_AA_SIGNINGCERTIFICATE: Nid = Nid(ffi::NID_id_smime_aa_signingCertificate); + pub const ID_SMIME_AA_SMIMEENCRYPTCERTS: Nid = Nid(ffi::NID_id_smime_aa_smimeEncryptCerts); + pub const ID_SMIME_AA_TIMESTAMPTOKEN: Nid = Nid(ffi::NID_id_smime_aa_timeStampToken); + pub const ID_SMIME_AA_ETS_SIGPOLICYID: Nid = Nid(ffi::NID_id_smime_aa_ets_sigPolicyId); + pub const ID_SMIME_AA_ETS_COMMITMENTTYPE: Nid = Nid(ffi::NID_id_smime_aa_ets_commitmentType); + pub const ID_SMIME_AA_ETS_SIGNERLOCATION: Nid = Nid(ffi::NID_id_smime_aa_ets_signerLocation); + pub const ID_SMIME_AA_ETS_SIGNERATTR: Nid = Nid(ffi::NID_id_smime_aa_ets_signerAttr); + pub const ID_SMIME_AA_ETS_OTHERSIGCERT: Nid = Nid(ffi::NID_id_smime_aa_ets_otherSigCert); + pub const ID_SMIME_AA_ETS_CONTENTTIMESTAMP: Nid = + Nid(ffi::NID_id_smime_aa_ets_contentTimestamp); + pub const ID_SMIME_AA_ETS_CERTIFICATEREFS: Nid = Nid(ffi::NID_id_smime_aa_ets_CertificateRefs); + pub const ID_SMIME_AA_ETS_REVOCATIONREFS: Nid = Nid(ffi::NID_id_smime_aa_ets_RevocationRefs); + pub const ID_SMIME_AA_ETS_CERTVALUES: Nid = Nid(ffi::NID_id_smime_aa_ets_certValues); + pub const ID_SMIME_AA_ETS_REVOCATIONVALUES: Nid = + Nid(ffi::NID_id_smime_aa_ets_revocationValues); + pub const ID_SMIME_AA_ETS_ESCTIMESTAMP: Nid = Nid(ffi::NID_id_smime_aa_ets_escTimeStamp); + pub const ID_SMIME_AA_ETS_CERTCRLTIMESTAMP: Nid = + Nid(ffi::NID_id_smime_aa_ets_certCRLTimestamp); + pub const ID_SMIME_AA_ETS_ARCHIVETIMESTAMP: Nid = + Nid(ffi::NID_id_smime_aa_ets_archiveTimeStamp); + pub const ID_SMIME_AA_SIGNATURETYPE: Nid = Nid(ffi::NID_id_smime_aa_signatureType); + pub const ID_SMIME_AA_DVCS_DVC: Nid = Nid(ffi::NID_id_smime_aa_dvcs_dvc); + pub const ID_SMIME_ALG_ESDHWITH3DES: Nid = Nid(ffi::NID_id_smime_alg_ESDHwith3DES); + pub const ID_SMIME_ALG_ESDHWITHRC2: Nid = Nid(ffi::NID_id_smime_alg_ESDHwithRC2); + pub const ID_SMIME_ALG_3DESWRAP: Nid = Nid(ffi::NID_id_smime_alg_3DESwrap); + pub const ID_SMIME_ALG_RC2WRAP: Nid = Nid(ffi::NID_id_smime_alg_RC2wrap); + pub const ID_SMIME_ALG_ESDH: Nid = Nid(ffi::NID_id_smime_alg_ESDH); + pub const ID_SMIME_ALG_CMS3DESWRAP: Nid = Nid(ffi::NID_id_smime_alg_CMS3DESwrap); + pub const ID_SMIME_ALG_CMSRC2WRAP: Nid = Nid(ffi::NID_id_smime_alg_CMSRC2wrap); + pub const ID_ALG_PWRI_KEK: Nid = Nid(ffi::NID_id_alg_PWRI_KEK); + pub const ID_SMIME_CD_LDAP: Nid = Nid(ffi::NID_id_smime_cd_ldap); + pub const ID_SMIME_SPQ_ETS_SQT_URI: Nid = Nid(ffi::NID_id_smime_spq_ets_sqt_uri); + pub const ID_SMIME_SPQ_ETS_SQT_UNOTICE: Nid = Nid(ffi::NID_id_smime_spq_ets_sqt_unotice); + pub const ID_SMIME_CTI_ETS_PROOFOFORIGIN: Nid = Nid(ffi::NID_id_smime_cti_ets_proofOfOrigin); + pub const ID_SMIME_CTI_ETS_PROOFOFRECEIPT: Nid = Nid(ffi::NID_id_smime_cti_ets_proofOfReceipt); + pub const ID_SMIME_CTI_ETS_PROOFOFDELIVERY: Nid = + Nid(ffi::NID_id_smime_cti_ets_proofOfDelivery); + pub const ID_SMIME_CTI_ETS_PROOFOFSENDER: Nid = Nid(ffi::NID_id_smime_cti_ets_proofOfSender); + pub const ID_SMIME_CTI_ETS_PROOFOFAPPROVAL: Nid = + Nid(ffi::NID_id_smime_cti_ets_proofOfApproval); + pub const ID_SMIME_CTI_ETS_PROOFOFCREATION: Nid = + Nid(ffi::NID_id_smime_cti_ets_proofOfCreation); + pub const FRIENDLYNAME: Nid = Nid(ffi::NID_friendlyName); + pub const LOCALKEYID: Nid = Nid(ffi::NID_localKeyID); + pub const MS_CSP_NAME: Nid = Nid(ffi::NID_ms_csp_name); + pub const LOCALKEYSET: Nid = Nid(ffi::NID_LocalKeySet); + pub const X509CERTIFICATE: Nid = Nid(ffi::NID_x509Certificate); + pub const SDSICERTIFICATE: Nid = Nid(ffi::NID_sdsiCertificate); + pub const X509CRL: Nid = Nid(ffi::NID_x509Crl); + pub const PBE_WITHSHA1AND128BITRC4: Nid = Nid(ffi::NID_pbe_WithSHA1And128BitRC4); + pub const PBE_WITHSHA1AND40BITRC4: Nid = Nid(ffi::NID_pbe_WithSHA1And40BitRC4); + pub const PBE_WITHSHA1AND3_KEY_TRIPLEDES_CBC: Nid = + Nid(ffi::NID_pbe_WithSHA1And3_Key_TripleDES_CBC); + pub const PBE_WITHSHA1AND2_KEY_TRIPLEDES_CBC: Nid = + Nid(ffi::NID_pbe_WithSHA1And2_Key_TripleDES_CBC); + pub const PBE_WITHSHA1AND128BITRC2_CBC: Nid = Nid(ffi::NID_pbe_WithSHA1And128BitRC2_CBC); + pub const PBE_WITHSHA1AND40BITRC2_CBC: Nid = Nid(ffi::NID_pbe_WithSHA1And40BitRC2_CBC); + pub const KEYBAG: Nid = Nid(ffi::NID_keyBag); + pub const PKCS8SHROUDEDKEYBAG: Nid = Nid(ffi::NID_pkcs8ShroudedKeyBag); + pub const CERTBAG: Nid = Nid(ffi::NID_certBag); + pub const CRLBAG: Nid = Nid(ffi::NID_crlBag); + pub const SECRETBAG: Nid = Nid(ffi::NID_secretBag); + pub const SAFECONTENTSBAG: Nid = Nid(ffi::NID_safeContentsBag); + pub const MD2: Nid = Nid(ffi::NID_md2); + pub const MD4: Nid = Nid(ffi::NID_md4); + pub const MD5: Nid = Nid(ffi::NID_md5); + pub const MD5_SHA1: Nid = Nid(ffi::NID_md5_sha1); + pub const HMACWITHMD5: Nid = Nid(ffi::NID_hmacWithMD5); + pub const HMACWITHSHA1: Nid = Nid(ffi::NID_hmacWithSHA1); + pub const HMACWITHSHA224: Nid = Nid(ffi::NID_hmacWithSHA224); + pub const HMACWITHSHA256: Nid = Nid(ffi::NID_hmacWithSHA256); + pub const HMACWITHSHA384: Nid = Nid(ffi::NID_hmacWithSHA384); + pub const HMACWITHSHA512: Nid = Nid(ffi::NID_hmacWithSHA512); + pub const RC2_CBC: Nid = Nid(ffi::NID_rc2_cbc); + pub const RC2_ECB: Nid = Nid(ffi::NID_rc2_ecb); + pub const RC2_CFB64: Nid = Nid(ffi::NID_rc2_cfb64); + pub const RC2_OFB64: Nid = Nid(ffi::NID_rc2_ofb64); + pub const RC2_40_CBC: Nid = Nid(ffi::NID_rc2_40_cbc); + pub const RC2_64_CBC: Nid = Nid(ffi::NID_rc2_64_cbc); + pub const RC4: Nid = Nid(ffi::NID_rc4); + pub const RC4_40: Nid = Nid(ffi::NID_rc4_40); + pub const DES_EDE3_CBC: Nid = Nid(ffi::NID_des_ede3_cbc); + pub const RC5_CBC: Nid = Nid(ffi::NID_rc5_cbc); + pub const RC5_ECB: Nid = Nid(ffi::NID_rc5_ecb); + pub const RC5_CFB64: Nid = Nid(ffi::NID_rc5_cfb64); + pub const RC5_OFB64: Nid = Nid(ffi::NID_rc5_ofb64); + pub const MS_EXT_REQ: Nid = Nid(ffi::NID_ms_ext_req); + pub const MS_CODE_IND: Nid = Nid(ffi::NID_ms_code_ind); + pub const MS_CODE_COM: Nid = Nid(ffi::NID_ms_code_com); + pub const MS_CTL_SIGN: Nid = Nid(ffi::NID_ms_ctl_sign); + pub const MS_SGC: Nid = Nid(ffi::NID_ms_sgc); + pub const MS_EFS: Nid = Nid(ffi::NID_ms_efs); + pub const MS_SMARTCARD_LOGIN: Nid = Nid(ffi::NID_ms_smartcard_login); + pub const MS_UPN: Nid = Nid(ffi::NID_ms_upn); + pub const IDEA_CBC: Nid = Nid(ffi::NID_idea_cbc); + pub const IDEA_ECB: Nid = Nid(ffi::NID_idea_ecb); + pub const IDEA_CFB64: Nid = Nid(ffi::NID_idea_cfb64); + pub const IDEA_OFB64: Nid = Nid(ffi::NID_idea_ofb64); + pub const BF_CBC: Nid = Nid(ffi::NID_bf_cbc); + pub const BF_ECB: Nid = Nid(ffi::NID_bf_ecb); + pub const BF_CFB64: Nid = Nid(ffi::NID_bf_cfb64); + pub const BF_OFB64: Nid = Nid(ffi::NID_bf_ofb64); + pub const ID_PKIX: Nid = Nid(ffi::NID_id_pkix); + pub const ID_PKIX_MOD: Nid = Nid(ffi::NID_id_pkix_mod); + pub const ID_PE: Nid = Nid(ffi::NID_id_pe); + pub const ID_QT: Nid = Nid(ffi::NID_id_qt); + pub const ID_KP: Nid = Nid(ffi::NID_id_kp); + pub const ID_IT: Nid = Nid(ffi::NID_id_it); + pub const ID_PKIP: Nid = Nid(ffi::NID_id_pkip); + pub const ID_ALG: Nid = Nid(ffi::NID_id_alg); + pub const ID_CMC: Nid = Nid(ffi::NID_id_cmc); + pub const ID_ON: Nid = Nid(ffi::NID_id_on); + pub const ID_PDA: Nid = Nid(ffi::NID_id_pda); + pub const ID_ACA: Nid = Nid(ffi::NID_id_aca); + pub const ID_QCS: Nid = Nid(ffi::NID_id_qcs); + pub const ID_CCT: Nid = Nid(ffi::NID_id_cct); + pub const ID_PPL: Nid = Nid(ffi::NID_id_ppl); + pub const ID_AD: Nid = Nid(ffi::NID_id_ad); + pub const ID_PKIX1_EXPLICIT_88: Nid = Nid(ffi::NID_id_pkix1_explicit_88); + pub const ID_PKIX1_IMPLICIT_88: Nid = Nid(ffi::NID_id_pkix1_implicit_88); + pub const ID_PKIX1_EXPLICIT_93: Nid = Nid(ffi::NID_id_pkix1_explicit_93); + pub const ID_PKIX1_IMPLICIT_93: Nid = Nid(ffi::NID_id_pkix1_implicit_93); + pub const ID_MOD_CRMF: Nid = Nid(ffi::NID_id_mod_crmf); + pub const ID_MOD_CMC: Nid = Nid(ffi::NID_id_mod_cmc); + pub const ID_MOD_KEA_PROFILE_88: Nid = Nid(ffi::NID_id_mod_kea_profile_88); + pub const ID_MOD_KEA_PROFILE_93: Nid = Nid(ffi::NID_id_mod_kea_profile_93); + pub const ID_MOD_CMP: Nid = Nid(ffi::NID_id_mod_cmp); + pub const ID_MOD_QUALIFIED_CERT_88: Nid = Nid(ffi::NID_id_mod_qualified_cert_88); + pub const ID_MOD_QUALIFIED_CERT_93: Nid = Nid(ffi::NID_id_mod_qualified_cert_93); + pub const ID_MOD_ATTRIBUTE_CERT: Nid = Nid(ffi::NID_id_mod_attribute_cert); + pub const ID_MOD_TIMESTAMP_PROTOCOL: Nid = Nid(ffi::NID_id_mod_timestamp_protocol); + pub const ID_MOD_OCSP: Nid = Nid(ffi::NID_id_mod_ocsp); + pub const ID_MOD_DVCS: Nid = Nid(ffi::NID_id_mod_dvcs); + pub const ID_MOD_CMP2000: Nid = Nid(ffi::NID_id_mod_cmp2000); + pub const INFO_ACCESS: Nid = Nid(ffi::NID_info_access); + pub const BIOMETRICINFO: Nid = Nid(ffi::NID_biometricInfo); + pub const QCSTATEMENTS: Nid = Nid(ffi::NID_qcStatements); + pub const AC_AUDITENTITY: Nid = Nid(ffi::NID_ac_auditEntity); + pub const AC_TARGETING: Nid = Nid(ffi::NID_ac_targeting); + pub const AACONTROLS: Nid = Nid(ffi::NID_aaControls); + pub const SBGP_IPADDRBLOCK: Nid = Nid(ffi::NID_sbgp_ipAddrBlock); + pub const SBGP_AUTONOMOUSSYSNUM: Nid = Nid(ffi::NID_sbgp_autonomousSysNum); + pub const SBGP_ROUTERIDENTIFIER: Nid = Nid(ffi::NID_sbgp_routerIdentifier); + pub const AC_PROXYING: Nid = Nid(ffi::NID_ac_proxying); + pub const SINFO_ACCESS: Nid = Nid(ffi::NID_sinfo_access); + pub const PROXYCERTINFO: Nid = Nid(ffi::NID_proxyCertInfo); + pub const ID_QT_CPS: Nid = Nid(ffi::NID_id_qt_cps); + pub const ID_QT_UNOTICE: Nid = Nid(ffi::NID_id_qt_unotice); + pub const TEXTNOTICE: Nid = Nid(ffi::NID_textNotice); + pub const SERVER_AUTH: Nid = Nid(ffi::NID_server_auth); + pub const CLIENT_AUTH: Nid = Nid(ffi::NID_client_auth); + pub const CODE_SIGN: Nid = Nid(ffi::NID_code_sign); + pub const EMAIL_PROTECT: Nid = Nid(ffi::NID_email_protect); + pub const IPSECENDSYSTEM: Nid = Nid(ffi::NID_ipsecEndSystem); + pub const IPSECTUNNEL: Nid = Nid(ffi::NID_ipsecTunnel); + pub const IPSECUSER: Nid = Nid(ffi::NID_ipsecUser); + pub const TIME_STAMP: Nid = Nid(ffi::NID_time_stamp); + pub const OCSP_SIGN: Nid = Nid(ffi::NID_OCSP_sign); + pub const DVCS: Nid = Nid(ffi::NID_dvcs); + pub const ID_IT_CAPROTENCCERT: Nid = Nid(ffi::NID_id_it_caProtEncCert); + pub const ID_IT_SIGNKEYPAIRTYPES: Nid = Nid(ffi::NID_id_it_signKeyPairTypes); + pub const ID_IT_ENCKEYPAIRTYPES: Nid = Nid(ffi::NID_id_it_encKeyPairTypes); + pub const ID_IT_PREFERREDSYMMALG: Nid = Nid(ffi::NID_id_it_preferredSymmAlg); + pub const ID_IT_CAKEYUPDATEINFO: Nid = Nid(ffi::NID_id_it_caKeyUpdateInfo); + pub const ID_IT_CURRENTCRL: Nid = Nid(ffi::NID_id_it_currentCRL); + pub const ID_IT_UNSUPPORTEDOIDS: Nid = Nid(ffi::NID_id_it_unsupportedOIDs); + pub const ID_IT_SUBSCRIPTIONREQUEST: Nid = Nid(ffi::NID_id_it_subscriptionRequest); + pub const ID_IT_SUBSCRIPTIONRESPONSE: Nid = Nid(ffi::NID_id_it_subscriptionResponse); + pub const ID_IT_KEYPAIRPARAMREQ: Nid = Nid(ffi::NID_id_it_keyPairParamReq); + pub const ID_IT_KEYPAIRPARAMREP: Nid = Nid(ffi::NID_id_it_keyPairParamRep); + pub const ID_IT_REVPASSPHRASE: Nid = Nid(ffi::NID_id_it_revPassphrase); + pub const ID_IT_IMPLICITCONFIRM: Nid = Nid(ffi::NID_id_it_implicitConfirm); + pub const ID_IT_CONFIRMWAITTIME: Nid = Nid(ffi::NID_id_it_confirmWaitTime); + pub const ID_IT_ORIGPKIMESSAGE: Nid = Nid(ffi::NID_id_it_origPKIMessage); + pub const ID_IT_SUPPLANGTAGS: Nid = Nid(ffi::NID_id_it_suppLangTags); + pub const ID_REGCTRL: Nid = Nid(ffi::NID_id_regCtrl); + pub const ID_REGINFO: Nid = Nid(ffi::NID_id_regInfo); + pub const ID_REGCTRL_REGTOKEN: Nid = Nid(ffi::NID_id_regCtrl_regToken); + pub const ID_REGCTRL_AUTHENTICATOR: Nid = Nid(ffi::NID_id_regCtrl_authenticator); + pub const ID_REGCTRL_PKIPUBLICATIONINFO: Nid = Nid(ffi::NID_id_regCtrl_pkiPublicationInfo); + pub const ID_REGCTRL_PKIARCHIVEOPTIONS: Nid = Nid(ffi::NID_id_regCtrl_pkiArchiveOptions); + pub const ID_REGCTRL_OLDCERTID: Nid = Nid(ffi::NID_id_regCtrl_oldCertID); + pub const ID_REGCTRL_PROTOCOLENCRKEY: Nid = Nid(ffi::NID_id_regCtrl_protocolEncrKey); + pub const ID_REGINFO_UTF8PAIRS: Nid = Nid(ffi::NID_id_regInfo_utf8Pairs); + pub const ID_REGINFO_CERTREQ: Nid = Nid(ffi::NID_id_regInfo_certReq); + pub const ID_ALG_DES40: Nid = Nid(ffi::NID_id_alg_des40); + pub const ID_ALG_NOSIGNATURE: Nid = Nid(ffi::NID_id_alg_noSignature); + pub const ID_ALG_DH_SIG_HMAC_SHA1: Nid = Nid(ffi::NID_id_alg_dh_sig_hmac_sha1); + pub const ID_ALG_DH_POP: Nid = Nid(ffi::NID_id_alg_dh_pop); + pub const ID_CMC_STATUSINFO: Nid = Nid(ffi::NID_id_cmc_statusInfo); + pub const ID_CMC_IDENTIFICATION: Nid = Nid(ffi::NID_id_cmc_identification); + pub const ID_CMC_IDENTITYPROOF: Nid = Nid(ffi::NID_id_cmc_identityProof); + pub const ID_CMC_DATARETURN: Nid = Nid(ffi::NID_id_cmc_dataReturn); + pub const ID_CMC_TRANSACTIONID: Nid = Nid(ffi::NID_id_cmc_transactionId); + pub const ID_CMC_SENDERNONCE: Nid = Nid(ffi::NID_id_cmc_senderNonce); + pub const ID_CMC_RECIPIENTNONCE: Nid = Nid(ffi::NID_id_cmc_recipientNonce); + pub const ID_CMC_ADDEXTENSIONS: Nid = Nid(ffi::NID_id_cmc_addExtensions); + pub const ID_CMC_ENCRYPTEDPOP: Nid = Nid(ffi::NID_id_cmc_encryptedPOP); + pub const ID_CMC_DECRYPTEDPOP: Nid = Nid(ffi::NID_id_cmc_decryptedPOP); + pub const ID_CMC_LRAPOPWITNESS: Nid = Nid(ffi::NID_id_cmc_lraPOPWitness); + pub const ID_CMC_GETCERT: Nid = Nid(ffi::NID_id_cmc_getCert); + pub const ID_CMC_GETCRL: Nid = Nid(ffi::NID_id_cmc_getCRL); + pub const ID_CMC_REVOKEREQUEST: Nid = Nid(ffi::NID_id_cmc_revokeRequest); + pub const ID_CMC_REGINFO: Nid = Nid(ffi::NID_id_cmc_regInfo); + pub const ID_CMC_RESPONSEINFO: Nid = Nid(ffi::NID_id_cmc_responseInfo); + pub const ID_CMC_QUERYPENDING: Nid = Nid(ffi::NID_id_cmc_queryPending); + pub const ID_CMC_POPLINKRANDOM: Nid = Nid(ffi::NID_id_cmc_popLinkRandom); + pub const ID_CMC_POPLINKWITNESS: Nid = Nid(ffi::NID_id_cmc_popLinkWitness); + pub const ID_CMC_CONFIRMCERTACCEPTANCE: Nid = Nid(ffi::NID_id_cmc_confirmCertAcceptance); + pub const ID_ON_PERSONALDATA: Nid = Nid(ffi::NID_id_on_personalData); + pub const ID_ON_PERMANENTIDENTIFIER: Nid = Nid(ffi::NID_id_on_permanentIdentifier); + pub const ID_PDA_DATEOFBIRTH: Nid = Nid(ffi::NID_id_pda_dateOfBirth); + pub const ID_PDA_PLACEOFBIRTH: Nid = Nid(ffi::NID_id_pda_placeOfBirth); + pub const ID_PDA_GENDER: Nid = Nid(ffi::NID_id_pda_gender); + pub const ID_PDA_COUNTRYOFCITIZENSHIP: Nid = Nid(ffi::NID_id_pda_countryOfCitizenship); + pub const ID_PDA_COUNTRYOFRESIDENCE: Nid = Nid(ffi::NID_id_pda_countryOfResidence); + pub const ID_ACA_AUTHENTICATIONINFO: Nid = Nid(ffi::NID_id_aca_authenticationInfo); + pub const ID_ACA_ACCESSIDENTITY: Nid = Nid(ffi::NID_id_aca_accessIdentity); + pub const ID_ACA_CHARGINGIDENTITY: Nid = Nid(ffi::NID_id_aca_chargingIdentity); + pub const ID_ACA_GROUP: Nid = Nid(ffi::NID_id_aca_group); + pub const ID_ACA_ROLE: Nid = Nid(ffi::NID_id_aca_role); + pub const ID_ACA_ENCATTRS: Nid = Nid(ffi::NID_id_aca_encAttrs); + pub const ID_QCS_PKIXQCSYNTAX_V1: Nid = Nid(ffi::NID_id_qcs_pkixQCSyntax_v1); + pub const ID_CCT_CRS: Nid = Nid(ffi::NID_id_cct_crs); + pub const ID_CCT_PKIDATA: Nid = Nid(ffi::NID_id_cct_PKIData); + pub const ID_CCT_PKIRESPONSE: Nid = Nid(ffi::NID_id_cct_PKIResponse); + pub const ID_PPL_ANYLANGUAGE: Nid = Nid(ffi::NID_id_ppl_anyLanguage); + pub const ID_PPL_INHERITALL: Nid = Nid(ffi::NID_id_ppl_inheritAll); + pub const INDEPENDENT: Nid = Nid(ffi::NID_Independent); + pub const AD_OCSP: Nid = Nid(ffi::NID_ad_OCSP); + pub const AD_CA_ISSUERS: Nid = Nid(ffi::NID_ad_ca_issuers); + pub const AD_TIMESTAMPING: Nid = Nid(ffi::NID_ad_timeStamping); + pub const AD_DVCS: Nid = Nid(ffi::NID_ad_dvcs); + pub const CAREPOSITORY: Nid = Nid(ffi::NID_caRepository); + pub const ID_PKIX_OCSP_BASIC: Nid = Nid(ffi::NID_id_pkix_OCSP_basic); + pub const ID_PKIX_OCSP_NONCE: Nid = Nid(ffi::NID_id_pkix_OCSP_Nonce); + pub const ID_PKIX_OCSP_CRLID: Nid = Nid(ffi::NID_id_pkix_OCSP_CrlID); + pub const ID_PKIX_OCSP_ACCEPTABLERESPONSES: Nid = + Nid(ffi::NID_id_pkix_OCSP_acceptableResponses); + pub const ID_PKIX_OCSP_NOCHECK: Nid = Nid(ffi::NID_id_pkix_OCSP_noCheck); + pub const ID_PKIX_OCSP_ARCHIVECUTOFF: Nid = Nid(ffi::NID_id_pkix_OCSP_archiveCutoff); + pub const ID_PKIX_OCSP_SERVICELOCATOR: Nid = Nid(ffi::NID_id_pkix_OCSP_serviceLocator); + pub const ID_PKIX_OCSP_EXTENDEDSTATUS: Nid = Nid(ffi::NID_id_pkix_OCSP_extendedStatus); + pub const ID_PKIX_OCSP_VALID: Nid = Nid(ffi::NID_id_pkix_OCSP_valid); + pub const ID_PKIX_OCSP_PATH: Nid = Nid(ffi::NID_id_pkix_OCSP_path); + pub const ID_PKIX_OCSP_TRUSTROOT: Nid = Nid(ffi::NID_id_pkix_OCSP_trustRoot); + pub const ALGORITHM: Nid = Nid(ffi::NID_algorithm); + pub const MD5WITHRSA: Nid = Nid(ffi::NID_md5WithRSA); + pub const DES_ECB: Nid = Nid(ffi::NID_des_ecb); + pub const DES_CBC: Nid = Nid(ffi::NID_des_cbc); + pub const DES_OFB64: Nid = Nid(ffi::NID_des_ofb64); + pub const DES_CFB64: Nid = Nid(ffi::NID_des_cfb64); + pub const RSASIGNATURE: Nid = Nid(ffi::NID_rsaSignature); + pub const DSA_2: Nid = Nid(ffi::NID_dsa_2); + pub const DSAWITHSHA: Nid = Nid(ffi::NID_dsaWithSHA); + pub const SHAWITHRSAENCRYPTION: Nid = Nid(ffi::NID_shaWithRSAEncryption); + pub const DES_EDE_ECB: Nid = Nid(ffi::NID_des_ede_ecb); + pub const DES_EDE3_ECB: Nid = Nid(ffi::NID_des_ede3_ecb); + pub const DES_EDE_CBC: Nid = Nid(ffi::NID_des_ede_cbc); + pub const DES_EDE_CFB64: Nid = Nid(ffi::NID_des_ede_cfb64); + pub const DES_EDE3_CFB64: Nid = Nid(ffi::NID_des_ede3_cfb64); + pub const DES_EDE_OFB64: Nid = Nid(ffi::NID_des_ede_ofb64); + pub const DES_EDE3_OFB64: Nid = Nid(ffi::NID_des_ede3_ofb64); + pub const DESX_CBC: Nid = Nid(ffi::NID_desx_cbc); + pub const SHA: Nid = Nid(ffi::NID_sha); + pub const SHA1: Nid = Nid(ffi::NID_sha1); + pub const DSAWITHSHA1_2: Nid = Nid(ffi::NID_dsaWithSHA1_2); + pub const SHA1WITHRSA: Nid = Nid(ffi::NID_sha1WithRSA); + pub const RIPEMD160: Nid = Nid(ffi::NID_ripemd160); + pub const RIPEMD160WITHRSA: Nid = Nid(ffi::NID_ripemd160WithRSA); + pub const SXNET: Nid = Nid(ffi::NID_sxnet); + pub const X500: Nid = Nid(ffi::NID_X500); + pub const X509: Nid = Nid(ffi::NID_X509); + pub const COMMONNAME: Nid = Nid(ffi::NID_commonName); + pub const SURNAME: Nid = Nid(ffi::NID_surname); + pub const SERIALNUMBER: Nid = Nid(ffi::NID_serialNumber); + pub const COUNTRYNAME: Nid = Nid(ffi::NID_countryName); + pub const LOCALITYNAME: Nid = Nid(ffi::NID_localityName); + pub const STATEORPROVINCENAME: Nid = Nid(ffi::NID_stateOrProvinceName); + pub const STREETADDRESS: Nid = Nid(ffi::NID_streetAddress); + pub const ORGANIZATIONNAME: Nid = Nid(ffi::NID_organizationName); + pub const ORGANIZATIONALUNITNAME: Nid = Nid(ffi::NID_organizationalUnitName); + pub const TITLE: Nid = Nid(ffi::NID_title); + pub const DESCRIPTION: Nid = Nid(ffi::NID_description); + pub const SEARCHGUIDE: Nid = Nid(ffi::NID_searchGuide); + pub const BUSINESSCATEGORY: Nid = Nid(ffi::NID_businessCategory); + pub const POSTALADDRESS: Nid = Nid(ffi::NID_postalAddress); + pub const POSTALCODE: Nid = Nid(ffi::NID_postalCode); + pub const POSTOFFICEBOX: Nid = Nid(ffi::NID_postOfficeBox); + pub const PHYSICALDELIVERYOFFICENAME: Nid = Nid(ffi::NID_physicalDeliveryOfficeName); + pub const TELEPHONENUMBER: Nid = Nid(ffi::NID_telephoneNumber); + pub const TELEXNUMBER: Nid = Nid(ffi::NID_telexNumber); + pub const TELETEXTERMINALIDENTIFIER: Nid = Nid(ffi::NID_teletexTerminalIdentifier); + pub const FACSIMILETELEPHONENUMBER: Nid = Nid(ffi::NID_facsimileTelephoneNumber); + pub const X121ADDRESS: Nid = Nid(ffi::NID_x121Address); + pub const INTERNATIONALISDNNUMBER: Nid = Nid(ffi::NID_internationaliSDNNumber); + pub const REGISTEREDADDRESS: Nid = Nid(ffi::NID_registeredAddress); + pub const DESTINATIONINDICATOR: Nid = Nid(ffi::NID_destinationIndicator); + pub const PREFERREDDELIVERYMETHOD: Nid = Nid(ffi::NID_preferredDeliveryMethod); + pub const PRESENTATIONADDRESS: Nid = Nid(ffi::NID_presentationAddress); + pub const SUPPORTEDAPPLICATIONCONTEXT: Nid = Nid(ffi::NID_supportedApplicationContext); + pub const MEMBER: Nid = Nid(ffi::NID_member); + pub const OWNER: Nid = Nid(ffi::NID_owner); + pub const ROLEOCCUPANT: Nid = Nid(ffi::NID_roleOccupant); + pub const SEEALSO: Nid = Nid(ffi::NID_seeAlso); + pub const USERPASSWORD: Nid = Nid(ffi::NID_userPassword); + pub const USERCERTIFICATE: Nid = Nid(ffi::NID_userCertificate); + pub const CACERTIFICATE: Nid = Nid(ffi::NID_cACertificate); + pub const AUTHORITYREVOCATIONLIST: Nid = Nid(ffi::NID_authorityRevocationList); + pub const CERTIFICATEREVOCATIONLIST: Nid = Nid(ffi::NID_certificateRevocationList); + pub const CROSSCERTIFICATEPAIR: Nid = Nid(ffi::NID_crossCertificatePair); + pub const NAME: Nid = Nid(ffi::NID_name); + pub const GIVENNAME: Nid = Nid(ffi::NID_givenName); + pub const INITIALS: Nid = Nid(ffi::NID_initials); + pub const GENERATIONQUALIFIER: Nid = Nid(ffi::NID_generationQualifier); + pub const X500UNIQUEIDENTIFIER: Nid = Nid(ffi::NID_x500UniqueIdentifier); + pub const DNQUALIFIER: Nid = Nid(ffi::NID_dnQualifier); + pub const ENHANCEDSEARCHGUIDE: Nid = Nid(ffi::NID_enhancedSearchGuide); + pub const PROTOCOLINFORMATION: Nid = Nid(ffi::NID_protocolInformation); + pub const DISTINGUISHEDNAME: Nid = Nid(ffi::NID_distinguishedName); + pub const UNIQUEMEMBER: Nid = Nid(ffi::NID_uniqueMember); + pub const HOUSEIDENTIFIER: Nid = Nid(ffi::NID_houseIdentifier); + pub const SUPPORTEDALGORITHMS: Nid = Nid(ffi::NID_supportedAlgorithms); + pub const DELTAREVOCATIONLIST: Nid = Nid(ffi::NID_deltaRevocationList); + pub const DMDNAME: Nid = Nid(ffi::NID_dmdName); + pub const PSEUDONYM: Nid = Nid(ffi::NID_pseudonym); + pub const ROLE: Nid = Nid(ffi::NID_role); + pub const X500ALGORITHMS: Nid = Nid(ffi::NID_X500algorithms); + pub const RSA: Nid = Nid(ffi::NID_rsa); + pub const MDC2WITHRSA: Nid = Nid(ffi::NID_mdc2WithRSA); + pub const MDC2: Nid = Nid(ffi::NID_mdc2); + pub const ID_CE: Nid = Nid(ffi::NID_id_ce); + pub const SUBJECT_DIRECTORY_ATTRIBUTES: Nid = Nid(ffi::NID_subject_directory_attributes); + pub const SUBJECT_KEY_IDENTIFIER: Nid = Nid(ffi::NID_subject_key_identifier); + pub const KEY_USAGE: Nid = Nid(ffi::NID_key_usage); + pub const PRIVATE_KEY_USAGE_PERIOD: Nid = Nid(ffi::NID_private_key_usage_period); + pub const SUBJECT_ALT_NAME: Nid = Nid(ffi::NID_subject_alt_name); + pub const ISSUER_ALT_NAME: Nid = Nid(ffi::NID_issuer_alt_name); + pub const BASIC_CONSTRAINTS: Nid = Nid(ffi::NID_basic_constraints); + pub const CRL_NUMBER: Nid = Nid(ffi::NID_crl_number); + pub const CRL_REASON: Nid = Nid(ffi::NID_crl_reason); + pub const INVALIDITY_DATE: Nid = Nid(ffi::NID_invalidity_date); + pub const DELTA_CRL: Nid = Nid(ffi::NID_delta_crl); + pub const ISSUING_DISTRIBUTION_POINT: Nid = Nid(ffi::NID_issuing_distribution_point); + pub const CERTIFICATE_ISSUER: Nid = Nid(ffi::NID_certificate_issuer); + pub const NAME_CONSTRAINTS: Nid = Nid(ffi::NID_name_constraints); + pub const CRL_DISTRIBUTION_POINTS: Nid = Nid(ffi::NID_crl_distribution_points); + pub const CERTIFICATE_POLICIES: Nid = Nid(ffi::NID_certificate_policies); + pub const ANY_POLICY: Nid = Nid(ffi::NID_any_policy); + pub const POLICY_MAPPINGS: Nid = Nid(ffi::NID_policy_mappings); + pub const AUTHORITY_KEY_IDENTIFIER: Nid = Nid(ffi::NID_authority_key_identifier); + pub const POLICY_CONSTRAINTS: Nid = Nid(ffi::NID_policy_constraints); + pub const EXT_KEY_USAGE: Nid = Nid(ffi::NID_ext_key_usage); + pub const FRESHEST_CRL: Nid = Nid(ffi::NID_freshest_crl); + pub const INHIBIT_ANY_POLICY: Nid = Nid(ffi::NID_inhibit_any_policy); + pub const TARGET_INFORMATION: Nid = Nid(ffi::NID_target_information); + pub const NO_REV_AVAIL: Nid = Nid(ffi::NID_no_rev_avail); + pub const ANYEXTENDEDKEYUSAGE: Nid = Nid(ffi::NID_anyExtendedKeyUsage); + pub const NETSCAPE: Nid = Nid(ffi::NID_netscape); + pub const NETSCAPE_CERT_EXTENSION: Nid = Nid(ffi::NID_netscape_cert_extension); + pub const NETSCAPE_DATA_TYPE: Nid = Nid(ffi::NID_netscape_data_type); + pub const NETSCAPE_CERT_TYPE: Nid = Nid(ffi::NID_netscape_cert_type); + pub const NETSCAPE_BASE_URL: Nid = Nid(ffi::NID_netscape_base_url); + pub const NETSCAPE_REVOCATION_URL: Nid = Nid(ffi::NID_netscape_revocation_url); + pub const NETSCAPE_CA_REVOCATION_URL: Nid = Nid(ffi::NID_netscape_ca_revocation_url); + pub const NETSCAPE_RENEWAL_URL: Nid = Nid(ffi::NID_netscape_renewal_url); + pub const NETSCAPE_CA_POLICY_URL: Nid = Nid(ffi::NID_netscape_ca_policy_url); + pub const NETSCAPE_SSL_SERVER_NAME: Nid = Nid(ffi::NID_netscape_ssl_server_name); + pub const NETSCAPE_COMMENT: Nid = Nid(ffi::NID_netscape_comment); + pub const NETSCAPE_CERT_SEQUENCE: Nid = Nid(ffi::NID_netscape_cert_sequence); + pub const NS_SGC: Nid = Nid(ffi::NID_ns_sgc); + pub const ORG: Nid = Nid(ffi::NID_org); + pub const DOD: Nid = Nid(ffi::NID_dod); + pub const IANA: Nid = Nid(ffi::NID_iana); + pub const DIRECTORY: Nid = Nid(ffi::NID_Directory); + pub const MANAGEMENT: Nid = Nid(ffi::NID_Management); + pub const EXPERIMENTAL: Nid = Nid(ffi::NID_Experimental); + pub const PRIVATE: Nid = Nid(ffi::NID_Private); + pub const SECURITY: Nid = Nid(ffi::NID_Security); + pub const SNMPV2: Nid = Nid(ffi::NID_SNMPv2); + pub const MAIL: Nid = Nid(ffi::NID_Mail); + pub const ENTERPRISES: Nid = Nid(ffi::NID_Enterprises); + pub const DCOBJECT: Nid = Nid(ffi::NID_dcObject); + pub const MIME_MHS: Nid = Nid(ffi::NID_mime_mhs); + pub const MIME_MHS_HEADINGS: Nid = Nid(ffi::NID_mime_mhs_headings); + pub const MIME_MHS_BODIES: Nid = Nid(ffi::NID_mime_mhs_bodies); + pub const ID_HEX_PARTIAL_MESSAGE: Nid = Nid(ffi::NID_id_hex_partial_message); + pub const ID_HEX_MULTIPART_MESSAGE: Nid = Nid(ffi::NID_id_hex_multipart_message); + pub const ZLIB_COMPRESSION: Nid = Nid(ffi::NID_zlib_compression); + pub const AES_128_ECB: Nid = Nid(ffi::NID_aes_128_ecb); + pub const AES_128_CBC: Nid = Nid(ffi::NID_aes_128_cbc); + pub const AES_128_OFB128: Nid = Nid(ffi::NID_aes_128_ofb128); + pub const AES_128_CFB128: Nid = Nid(ffi::NID_aes_128_cfb128); + pub const ID_AES128_WRAP: Nid = Nid(ffi::NID_id_aes128_wrap); + pub const AES_128_GCM: Nid = Nid(ffi::NID_aes_128_gcm); + pub const AES_128_CCM: Nid = Nid(ffi::NID_aes_128_ccm); + pub const ID_AES128_WRAP_PAD: Nid = Nid(ffi::NID_id_aes128_wrap_pad); + pub const AES_192_ECB: Nid = Nid(ffi::NID_aes_192_ecb); + pub const AES_192_CBC: Nid = Nid(ffi::NID_aes_192_cbc); + pub const AES_192_OFB128: Nid = Nid(ffi::NID_aes_192_ofb128); + pub const AES_192_CFB128: Nid = Nid(ffi::NID_aes_192_cfb128); + pub const ID_AES192_WRAP: Nid = Nid(ffi::NID_id_aes192_wrap); + pub const AES_192_GCM: Nid = Nid(ffi::NID_aes_192_gcm); + pub const AES_192_CCM: Nid = Nid(ffi::NID_aes_192_ccm); + pub const ID_AES192_WRAP_PAD: Nid = Nid(ffi::NID_id_aes192_wrap_pad); + pub const AES_256_ECB: Nid = Nid(ffi::NID_aes_256_ecb); + pub const AES_256_CBC: Nid = Nid(ffi::NID_aes_256_cbc); + pub const AES_256_OFB128: Nid = Nid(ffi::NID_aes_256_ofb128); + pub const AES_256_CFB128: Nid = Nid(ffi::NID_aes_256_cfb128); + pub const ID_AES256_WRAP: Nid = Nid(ffi::NID_id_aes256_wrap); + pub const AES_256_GCM: Nid = Nid(ffi::NID_aes_256_gcm); + pub const AES_256_CCM: Nid = Nid(ffi::NID_aes_256_ccm); + pub const ID_AES256_WRAP_PAD: Nid = Nid(ffi::NID_id_aes256_wrap_pad); + pub const AES_128_CFB1: Nid = Nid(ffi::NID_aes_128_cfb1); + pub const AES_192_CFB1: Nid = Nid(ffi::NID_aes_192_cfb1); + pub const AES_256_CFB1: Nid = Nid(ffi::NID_aes_256_cfb1); + pub const AES_128_CFB8: Nid = Nid(ffi::NID_aes_128_cfb8); + pub const AES_192_CFB8: Nid = Nid(ffi::NID_aes_192_cfb8); + pub const AES_256_CFB8: Nid = Nid(ffi::NID_aes_256_cfb8); + pub const AES_128_CTR: Nid = Nid(ffi::NID_aes_128_ctr); + pub const AES_192_CTR: Nid = Nid(ffi::NID_aes_192_ctr); + pub const AES_256_CTR: Nid = Nid(ffi::NID_aes_256_ctr); + pub const AES_128_XTS: Nid = Nid(ffi::NID_aes_128_xts); + pub const AES_256_XTS: Nid = Nid(ffi::NID_aes_256_xts); + pub const DES_CFB1: Nid = Nid(ffi::NID_des_cfb1); + pub const DES_CFB8: Nid = Nid(ffi::NID_des_cfb8); + pub const DES_EDE3_CFB1: Nid = Nid(ffi::NID_des_ede3_cfb1); + pub const DES_EDE3_CFB8: Nid = Nid(ffi::NID_des_ede3_cfb8); + pub const SHA256: Nid = Nid(ffi::NID_sha256); + pub const SHA384: Nid = Nid(ffi::NID_sha384); + pub const SHA512: Nid = Nid(ffi::NID_sha512); + pub const SHA224: Nid = Nid(ffi::NID_sha224); + pub const DSA_WITH_SHA224: Nid = Nid(ffi::NID_dsa_with_SHA224); + pub const DSA_WITH_SHA256: Nid = Nid(ffi::NID_dsa_with_SHA256); + pub const HOLD_INSTRUCTION_CODE: Nid = Nid(ffi::NID_hold_instruction_code); + pub const HOLD_INSTRUCTION_NONE: Nid = Nid(ffi::NID_hold_instruction_none); + pub const HOLD_INSTRUCTION_CALL_ISSUER: Nid = Nid(ffi::NID_hold_instruction_call_issuer); + pub const HOLD_INSTRUCTION_REJECT: Nid = Nid(ffi::NID_hold_instruction_reject); + pub const DATA: Nid = Nid(ffi::NID_data); + pub const PSS: Nid = Nid(ffi::NID_pss); + pub const UCL: Nid = Nid(ffi::NID_ucl); + pub const PILOT: Nid = Nid(ffi::NID_pilot); + pub const PILOTATTRIBUTETYPE: Nid = Nid(ffi::NID_pilotAttributeType); + pub const PILOTATTRIBUTESYNTAX: Nid = Nid(ffi::NID_pilotAttributeSyntax); + pub const PILOTOBJECTCLASS: Nid = Nid(ffi::NID_pilotObjectClass); + pub const PILOTGROUPS: Nid = Nid(ffi::NID_pilotGroups); + pub const IA5STRINGSYNTAX: Nid = Nid(ffi::NID_iA5StringSyntax); + pub const CASEIGNOREIA5STRINGSYNTAX: Nid = Nid(ffi::NID_caseIgnoreIA5StringSyntax); + pub const PILOTOBJECT: Nid = Nid(ffi::NID_pilotObject); + pub const PILOTPERSON: Nid = Nid(ffi::NID_pilotPerson); + pub const ACCOUNT: Nid = Nid(ffi::NID_account); + pub const DOCUMENT: Nid = Nid(ffi::NID_document); + pub const ROOM: Nid = Nid(ffi::NID_room); + pub const DOCUMENTSERIES: Nid = Nid(ffi::NID_documentSeries); + pub const DOMAIN: Nid = Nid(ffi::NID_Domain); + pub const RFC822LOCALPART: Nid = Nid(ffi::NID_rFC822localPart); + pub const DNSDOMAIN: Nid = Nid(ffi::NID_dNSDomain); + pub const DOMAINRELATEDOBJECT: Nid = Nid(ffi::NID_domainRelatedObject); + pub const FRIENDLYCOUNTRY: Nid = Nid(ffi::NID_friendlyCountry); + pub const SIMPLESECURITYOBJECT: Nid = Nid(ffi::NID_simpleSecurityObject); + pub const PILOTORGANIZATION: Nid = Nid(ffi::NID_pilotOrganization); + pub const PILOTDSA: Nid = Nid(ffi::NID_pilotDSA); + pub const QUALITYLABELLEDDATA: Nid = Nid(ffi::NID_qualityLabelledData); + pub const USERID: Nid = Nid(ffi::NID_userId); + pub const TEXTENCODEDORADDRESS: Nid = Nid(ffi::NID_textEncodedORAddress); + pub const RFC822MAILBOX: Nid = Nid(ffi::NID_rfc822Mailbox); + pub const INFO: Nid = Nid(ffi::NID_info); + pub const FAVOURITEDRINK: Nid = Nid(ffi::NID_favouriteDrink); + pub const ROOMNUMBER: Nid = Nid(ffi::NID_roomNumber); + pub const PHOTO: Nid = Nid(ffi::NID_photo); + pub const USERCLASS: Nid = Nid(ffi::NID_userClass); + pub const HOST: Nid = Nid(ffi::NID_host); + pub const MANAGER: Nid = Nid(ffi::NID_manager); + pub const DOCUMENTIDENTIFIER: Nid = Nid(ffi::NID_documentIdentifier); + pub const DOCUMENTTITLE: Nid = Nid(ffi::NID_documentTitle); + pub const DOCUMENTVERSION: Nid = Nid(ffi::NID_documentVersion); + pub const DOCUMENTAUTHOR: Nid = Nid(ffi::NID_documentAuthor); + pub const DOCUMENTLOCATION: Nid = Nid(ffi::NID_documentLocation); + pub const HOMETELEPHONENUMBER: Nid = Nid(ffi::NID_homeTelephoneNumber); + pub const SECRETARY: Nid = Nid(ffi::NID_secretary); + pub const OTHERMAILBOX: Nid = Nid(ffi::NID_otherMailbox); + pub const LASTMODIFIEDTIME: Nid = Nid(ffi::NID_lastModifiedTime); + pub const LASTMODIFIEDBY: Nid = Nid(ffi::NID_lastModifiedBy); + pub const DOMAINCOMPONENT: Nid = Nid(ffi::NID_domainComponent); + pub const ARECORD: Nid = Nid(ffi::NID_aRecord); + pub const PILOTATTRIBUTETYPE27: Nid = Nid(ffi::NID_pilotAttributeType27); + pub const MXRECORD: Nid = Nid(ffi::NID_mXRecord); + pub const NSRECORD: Nid = Nid(ffi::NID_nSRecord); + pub const SOARECORD: Nid = Nid(ffi::NID_sOARecord); + pub const CNAMERECORD: Nid = Nid(ffi::NID_cNAMERecord); + pub const ASSOCIATEDDOMAIN: Nid = Nid(ffi::NID_associatedDomain); + pub const ASSOCIATEDNAME: Nid = Nid(ffi::NID_associatedName); + pub const HOMEPOSTALADDRESS: Nid = Nid(ffi::NID_homePostalAddress); + pub const PERSONALTITLE: Nid = Nid(ffi::NID_personalTitle); + pub const MOBILETELEPHONENUMBER: Nid = Nid(ffi::NID_mobileTelephoneNumber); + pub const PAGERTELEPHONENUMBER: Nid = Nid(ffi::NID_pagerTelephoneNumber); + pub const FRIENDLYCOUNTRYNAME: Nid = Nid(ffi::NID_friendlyCountryName); + pub const ORGANIZATIONALSTATUS: Nid = Nid(ffi::NID_organizationalStatus); + pub const JANETMAILBOX: Nid = Nid(ffi::NID_janetMailbox); + pub const MAILPREFERENCEOPTION: Nid = Nid(ffi::NID_mailPreferenceOption); + pub const BUILDINGNAME: Nid = Nid(ffi::NID_buildingName); + pub const DSAQUALITY: Nid = Nid(ffi::NID_dSAQuality); + pub const SINGLELEVELQUALITY: Nid = Nid(ffi::NID_singleLevelQuality); + pub const SUBTREEMINIMUMQUALITY: Nid = Nid(ffi::NID_subtreeMinimumQuality); + pub const SUBTREEMAXIMUMQUALITY: Nid = Nid(ffi::NID_subtreeMaximumQuality); + pub const PERSONALSIGNATURE: Nid = Nid(ffi::NID_personalSignature); + pub const DITREDIRECT: Nid = Nid(ffi::NID_dITRedirect); + pub const AUDIO: Nid = Nid(ffi::NID_audio); + pub const DOCUMENTPUBLISHER: Nid = Nid(ffi::NID_documentPublisher); + pub const ID_SET: Nid = Nid(ffi::NID_id_set); + pub const SET_CTYPE: Nid = Nid(ffi::NID_set_ctype); + pub const SET_MSGEXT: Nid = Nid(ffi::NID_set_msgExt); + pub const SET_ATTR: Nid = Nid(ffi::NID_set_attr); + pub const SET_POLICY: Nid = Nid(ffi::NID_set_policy); + pub const SET_CERTEXT: Nid = Nid(ffi::NID_set_certExt); + pub const SET_BRAND: Nid = Nid(ffi::NID_set_brand); + pub const SETCT_PANDATA: Nid = Nid(ffi::NID_setct_PANData); + pub const SETCT_PANTOKEN: Nid = Nid(ffi::NID_setct_PANToken); + pub const SETCT_PANONLY: Nid = Nid(ffi::NID_setct_PANOnly); + pub const SETCT_OIDATA: Nid = Nid(ffi::NID_setct_OIData); + pub const SETCT_PI: Nid = Nid(ffi::NID_setct_PI); + pub const SETCT_PIDATA: Nid = Nid(ffi::NID_setct_PIData); + pub const SETCT_PIDATAUNSIGNED: Nid = Nid(ffi::NID_setct_PIDataUnsigned); + pub const SETCT_HODINPUT: Nid = Nid(ffi::NID_setct_HODInput); + pub const SETCT_AUTHRESBAGGAGE: Nid = Nid(ffi::NID_setct_AuthResBaggage); + pub const SETCT_AUTHREVREQBAGGAGE: Nid = Nid(ffi::NID_setct_AuthRevReqBaggage); + pub const SETCT_AUTHREVRESBAGGAGE: Nid = Nid(ffi::NID_setct_AuthRevResBaggage); + pub const SETCT_CAPTOKENSEQ: Nid = Nid(ffi::NID_setct_CapTokenSeq); + pub const SETCT_PINITRESDATA: Nid = Nid(ffi::NID_setct_PInitResData); + pub const SETCT_PI_TBS: Nid = Nid(ffi::NID_setct_PI_TBS); + pub const SETCT_PRESDATA: Nid = Nid(ffi::NID_setct_PResData); + pub const SETCT_AUTHREQTBS: Nid = Nid(ffi::NID_setct_AuthReqTBS); + pub const SETCT_AUTHRESTBS: Nid = Nid(ffi::NID_setct_AuthResTBS); + pub const SETCT_AUTHRESTBSX: Nid = Nid(ffi::NID_setct_AuthResTBSX); + pub const SETCT_AUTHTOKENTBS: Nid = Nid(ffi::NID_setct_AuthTokenTBS); + pub const SETCT_CAPTOKENDATA: Nid = Nid(ffi::NID_setct_CapTokenData); + pub const SETCT_CAPTOKENTBS: Nid = Nid(ffi::NID_setct_CapTokenTBS); + pub const SETCT_ACQCARDCODEMSG: Nid = Nid(ffi::NID_setct_AcqCardCodeMsg); + pub const SETCT_AUTHREVREQTBS: Nid = Nid(ffi::NID_setct_AuthRevReqTBS); + pub const SETCT_AUTHREVRESDATA: Nid = Nid(ffi::NID_setct_AuthRevResData); + pub const SETCT_AUTHREVRESTBS: Nid = Nid(ffi::NID_setct_AuthRevResTBS); + pub const SETCT_CAPREQTBS: Nid = Nid(ffi::NID_setct_CapReqTBS); + pub const SETCT_CAPREQTBSX: Nid = Nid(ffi::NID_setct_CapReqTBSX); + pub const SETCT_CAPRESDATA: Nid = Nid(ffi::NID_setct_CapResData); + pub const SETCT_CAPREVREQTBS: Nid = Nid(ffi::NID_setct_CapRevReqTBS); + pub const SETCT_CAPREVREQTBSX: Nid = Nid(ffi::NID_setct_CapRevReqTBSX); + pub const SETCT_CAPREVRESDATA: Nid = Nid(ffi::NID_setct_CapRevResData); + pub const SETCT_CREDREQTBS: Nid = Nid(ffi::NID_setct_CredReqTBS); + pub const SETCT_CREDREQTBSX: Nid = Nid(ffi::NID_setct_CredReqTBSX); + pub const SETCT_CREDRESDATA: Nid = Nid(ffi::NID_setct_CredResData); + pub const SETCT_CREDREVREQTBS: Nid = Nid(ffi::NID_setct_CredRevReqTBS); + pub const SETCT_CREDREVREQTBSX: Nid = Nid(ffi::NID_setct_CredRevReqTBSX); + pub const SETCT_CREDREVRESDATA: Nid = Nid(ffi::NID_setct_CredRevResData); + pub const SETCT_PCERTREQDATA: Nid = Nid(ffi::NID_setct_PCertReqData); + pub const SETCT_PCERTRESTBS: Nid = Nid(ffi::NID_setct_PCertResTBS); + pub const SETCT_BATCHADMINREQDATA: Nid = Nid(ffi::NID_setct_BatchAdminReqData); + pub const SETCT_BATCHADMINRESDATA: Nid = Nid(ffi::NID_setct_BatchAdminResData); + pub const SETCT_CARDCINITRESTBS: Nid = Nid(ffi::NID_setct_CardCInitResTBS); + pub const SETCT_MEAQCINITRESTBS: Nid = Nid(ffi::NID_setct_MeAqCInitResTBS); + pub const SETCT_REGFORMRESTBS: Nid = Nid(ffi::NID_setct_RegFormResTBS); + pub const SETCT_CERTREQDATA: Nid = Nid(ffi::NID_setct_CertReqData); + pub const SETCT_CERTREQTBS: Nid = Nid(ffi::NID_setct_CertReqTBS); + pub const SETCT_CERTRESDATA: Nid = Nid(ffi::NID_setct_CertResData); + pub const SETCT_CERTINQREQTBS: Nid = Nid(ffi::NID_setct_CertInqReqTBS); + pub const SETCT_ERRORTBS: Nid = Nid(ffi::NID_setct_ErrorTBS); + pub const SETCT_PIDUALSIGNEDTBE: Nid = Nid(ffi::NID_setct_PIDualSignedTBE); + pub const SETCT_PIUNSIGNEDTBE: Nid = Nid(ffi::NID_setct_PIUnsignedTBE); + pub const SETCT_AUTHREQTBE: Nid = Nid(ffi::NID_setct_AuthReqTBE); + pub const SETCT_AUTHRESTBE: Nid = Nid(ffi::NID_setct_AuthResTBE); + pub const SETCT_AUTHRESTBEX: Nid = Nid(ffi::NID_setct_AuthResTBEX); + pub const SETCT_AUTHTOKENTBE: Nid = Nid(ffi::NID_setct_AuthTokenTBE); + pub const SETCT_CAPTOKENTBE: Nid = Nid(ffi::NID_setct_CapTokenTBE); + pub const SETCT_CAPTOKENTBEX: Nid = Nid(ffi::NID_setct_CapTokenTBEX); + pub const SETCT_ACQCARDCODEMSGTBE: Nid = Nid(ffi::NID_setct_AcqCardCodeMsgTBE); + pub const SETCT_AUTHREVREQTBE: Nid = Nid(ffi::NID_setct_AuthRevReqTBE); + pub const SETCT_AUTHREVRESTBE: Nid = Nid(ffi::NID_setct_AuthRevResTBE); + pub const SETCT_AUTHREVRESTBEB: Nid = Nid(ffi::NID_setct_AuthRevResTBEB); + pub const SETCT_CAPREQTBE: Nid = Nid(ffi::NID_setct_CapReqTBE); + pub const SETCT_CAPREQTBEX: Nid = Nid(ffi::NID_setct_CapReqTBEX); + pub const SETCT_CAPRESTBE: Nid = Nid(ffi::NID_setct_CapResTBE); + pub const SETCT_CAPREVREQTBE: Nid = Nid(ffi::NID_setct_CapRevReqTBE); + pub const SETCT_CAPREVREQTBEX: Nid = Nid(ffi::NID_setct_CapRevReqTBEX); + pub const SETCT_CAPREVRESTBE: Nid = Nid(ffi::NID_setct_CapRevResTBE); + pub const SETCT_CREDREQTBE: Nid = Nid(ffi::NID_setct_CredReqTBE); + pub const SETCT_CREDREQTBEX: Nid = Nid(ffi::NID_setct_CredReqTBEX); + pub const SETCT_CREDRESTBE: Nid = Nid(ffi::NID_setct_CredResTBE); + pub const SETCT_CREDREVREQTBE: Nid = Nid(ffi::NID_setct_CredRevReqTBE); + pub const SETCT_CREDREVREQTBEX: Nid = Nid(ffi::NID_setct_CredRevReqTBEX); + pub const SETCT_CREDREVRESTBE: Nid = Nid(ffi::NID_setct_CredRevResTBE); + pub const SETCT_BATCHADMINREQTBE: Nid = Nid(ffi::NID_setct_BatchAdminReqTBE); + pub const SETCT_BATCHADMINRESTBE: Nid = Nid(ffi::NID_setct_BatchAdminResTBE); + pub const SETCT_REGFORMREQTBE: Nid = Nid(ffi::NID_setct_RegFormReqTBE); + pub const SETCT_CERTREQTBE: Nid = Nid(ffi::NID_setct_CertReqTBE); + pub const SETCT_CERTREQTBEX: Nid = Nid(ffi::NID_setct_CertReqTBEX); + pub const SETCT_CERTRESTBE: Nid = Nid(ffi::NID_setct_CertResTBE); + pub const SETCT_CRLNOTIFICATIONTBS: Nid = Nid(ffi::NID_setct_CRLNotificationTBS); + pub const SETCT_CRLNOTIFICATIONRESTBS: Nid = Nid(ffi::NID_setct_CRLNotificationResTBS); + pub const SETCT_BCIDISTRIBUTIONTBS: Nid = Nid(ffi::NID_setct_BCIDistributionTBS); + pub const SETEXT_GENCRYPT: Nid = Nid(ffi::NID_setext_genCrypt); + pub const SETEXT_MIAUTH: Nid = Nid(ffi::NID_setext_miAuth); + pub const SETEXT_PINSECURE: Nid = Nid(ffi::NID_setext_pinSecure); + pub const SETEXT_PINANY: Nid = Nid(ffi::NID_setext_pinAny); + pub const SETEXT_TRACK2: Nid = Nid(ffi::NID_setext_track2); + pub const SETEXT_CV: Nid = Nid(ffi::NID_setext_cv); + pub const SET_POLICY_ROOT: Nid = Nid(ffi::NID_set_policy_root); + pub const SETCEXT_HASHEDROOT: Nid = Nid(ffi::NID_setCext_hashedRoot); + pub const SETCEXT_CERTTYPE: Nid = Nid(ffi::NID_setCext_certType); + pub const SETCEXT_MERCHDATA: Nid = Nid(ffi::NID_setCext_merchData); + pub const SETCEXT_CCERTREQUIRED: Nid = Nid(ffi::NID_setCext_cCertRequired); + pub const SETCEXT_TUNNELING: Nid = Nid(ffi::NID_setCext_tunneling); + pub const SETCEXT_SETEXT: Nid = Nid(ffi::NID_setCext_setExt); + pub const SETCEXT_SETQUALF: Nid = Nid(ffi::NID_setCext_setQualf); + pub const SETCEXT_PGWYCAPABILITIES: Nid = Nid(ffi::NID_setCext_PGWYcapabilities); + pub const SETCEXT_TOKENIDENTIFIER: Nid = Nid(ffi::NID_setCext_TokenIdentifier); + pub const SETCEXT_TRACK2DATA: Nid = Nid(ffi::NID_setCext_Track2Data); + pub const SETCEXT_TOKENTYPE: Nid = Nid(ffi::NID_setCext_TokenType); + pub const SETCEXT_ISSUERCAPABILITIES: Nid = Nid(ffi::NID_setCext_IssuerCapabilities); + pub const SETATTR_CERT: Nid = Nid(ffi::NID_setAttr_Cert); + pub const SETATTR_PGWYCAP: Nid = Nid(ffi::NID_setAttr_PGWYcap); + pub const SETATTR_TOKENTYPE: Nid = Nid(ffi::NID_setAttr_TokenType); + pub const SETATTR_ISSCAP: Nid = Nid(ffi::NID_setAttr_IssCap); + pub const SET_ROOTKEYTHUMB: Nid = Nid(ffi::NID_set_rootKeyThumb); + pub const SET_ADDPOLICY: Nid = Nid(ffi::NID_set_addPolicy); + pub const SETATTR_TOKEN_EMV: Nid = Nid(ffi::NID_setAttr_Token_EMV); + pub const SETATTR_TOKEN_B0PRIME: Nid = Nid(ffi::NID_setAttr_Token_B0Prime); + pub const SETATTR_ISSCAP_CVM: Nid = Nid(ffi::NID_setAttr_IssCap_CVM); + pub const SETATTR_ISSCAP_T2: Nid = Nid(ffi::NID_setAttr_IssCap_T2); + pub const SETATTR_ISSCAP_SIG: Nid = Nid(ffi::NID_setAttr_IssCap_Sig); + pub const SETATTR_GENCRYPTGRM: Nid = Nid(ffi::NID_setAttr_GenCryptgrm); + pub const SETATTR_T2ENC: Nid = Nid(ffi::NID_setAttr_T2Enc); + pub const SETATTR_T2CLEARTXT: Nid = Nid(ffi::NID_setAttr_T2cleartxt); + pub const SETATTR_TOKICCSIG: Nid = Nid(ffi::NID_setAttr_TokICCsig); + pub const SETATTR_SECDEVSIG: Nid = Nid(ffi::NID_setAttr_SecDevSig); + pub const SET_BRAND_IATA_ATA: Nid = Nid(ffi::NID_set_brand_IATA_ATA); + pub const SET_BRAND_DINERS: Nid = Nid(ffi::NID_set_brand_Diners); + pub const SET_BRAND_AMERICANEXPRESS: Nid = Nid(ffi::NID_set_brand_AmericanExpress); + pub const SET_BRAND_JCB: Nid = Nid(ffi::NID_set_brand_JCB); + pub const SET_BRAND_VISA: Nid = Nid(ffi::NID_set_brand_Visa); + pub const SET_BRAND_MASTERCARD: Nid = Nid(ffi::NID_set_brand_MasterCard); + pub const SET_BRAND_NOVUS: Nid = Nid(ffi::NID_set_brand_Novus); + pub const DES_CDMF: Nid = Nid(ffi::NID_des_cdmf); + pub const RSAOAEPENCRYPTIONSET: Nid = Nid(ffi::NID_rsaOAEPEncryptionSET); + pub const IPSEC3: Nid = Nid(ffi::NID_ipsec3); + pub const IPSEC4: Nid = Nid(ffi::NID_ipsec4); + pub const WHIRLPOOL: Nid = Nid(ffi::NID_whirlpool); + pub const CRYPTOPRO: Nid = Nid(ffi::NID_cryptopro); + pub const CRYPTOCOM: Nid = Nid(ffi::NID_cryptocom); + pub const ID_GOSTR3411_94_WITH_GOSTR3410_2001: Nid = + Nid(ffi::NID_id_GostR3411_94_with_GostR3410_2001); + pub const ID_GOSTR3411_94_WITH_GOSTR3410_94: Nid = + Nid(ffi::NID_id_GostR3411_94_with_GostR3410_94); + pub const ID_GOSTR3411_94: Nid = Nid(ffi::NID_id_GostR3411_94); + pub const ID_HMACGOSTR3411_94: Nid = Nid(ffi::NID_id_HMACGostR3411_94); + pub const ID_GOSTR3410_2001: Nid = Nid(ffi::NID_id_GostR3410_2001); + pub const ID_GOSTR3410_94: Nid = Nid(ffi::NID_id_GostR3410_94); + pub const ID_GOST28147_89: Nid = Nid(ffi::NID_id_Gost28147_89); + pub const GOST89_CNT: Nid = Nid(ffi::NID_gost89_cnt); + pub const ID_GOST28147_89_MAC: Nid = Nid(ffi::NID_id_Gost28147_89_MAC); + pub const ID_GOSTR3411_94_PRF: Nid = Nid(ffi::NID_id_GostR3411_94_prf); + pub const ID_GOSTR3410_2001DH: Nid = Nid(ffi::NID_id_GostR3410_2001DH); + pub const ID_GOSTR3410_94DH: Nid = Nid(ffi::NID_id_GostR3410_94DH); + pub const ID_GOST28147_89_CRYPTOPRO_KEYMESHING: Nid = + Nid(ffi::NID_id_Gost28147_89_CryptoPro_KeyMeshing); + pub const ID_GOST28147_89_NONE_KEYMESHING: Nid = Nid(ffi::NID_id_Gost28147_89_None_KeyMeshing); + pub const ID_GOSTR3411_94_TESTPARAMSET: Nid = Nid(ffi::NID_id_GostR3411_94_TestParamSet); + pub const ID_GOSTR3411_94_CRYPTOPROPARAMSET: Nid = + Nid(ffi::NID_id_GostR3411_94_CryptoProParamSet); + pub const ID_GOST28147_89_TESTPARAMSET: Nid = Nid(ffi::NID_id_Gost28147_89_TestParamSet); + pub const ID_GOST28147_89_CRYPTOPRO_A_PARAMSET: Nid = + Nid(ffi::NID_id_Gost28147_89_CryptoPro_A_ParamSet); + pub const ID_GOST28147_89_CRYPTOPRO_B_PARAMSET: Nid = + Nid(ffi::NID_id_Gost28147_89_CryptoPro_B_ParamSet); + pub const ID_GOST28147_89_CRYPTOPRO_C_PARAMSET: Nid = + Nid(ffi::NID_id_Gost28147_89_CryptoPro_C_ParamSet); + pub const ID_GOST28147_89_CRYPTOPRO_D_PARAMSET: Nid = + Nid(ffi::NID_id_Gost28147_89_CryptoPro_D_ParamSet); + pub const ID_GOST28147_89_CRYPTOPRO_OSCAR_1_1_PARAMSET: Nid = + Nid(ffi::NID_id_Gost28147_89_CryptoPro_Oscar_1_1_ParamSet); + pub const ID_GOST28147_89_CRYPTOPRO_OSCAR_1_0_PARAMSET: Nid = + Nid(ffi::NID_id_Gost28147_89_CryptoPro_Oscar_1_0_ParamSet); + pub const ID_GOST28147_89_CRYPTOPRO_RIC_1_PARAMSET: Nid = + Nid(ffi::NID_id_Gost28147_89_CryptoPro_RIC_1_ParamSet); + pub const ID_GOSTR3410_94_TESTPARAMSET: Nid = Nid(ffi::NID_id_GostR3410_94_TestParamSet); + pub const ID_GOSTR3410_94_CRYPTOPRO_A_PARAMSET: Nid = + Nid(ffi::NID_id_GostR3410_94_CryptoPro_A_ParamSet); + pub const ID_GOSTR3410_94_CRYPTOPRO_B_PARAMSET: Nid = + Nid(ffi::NID_id_GostR3410_94_CryptoPro_B_ParamSet); + pub const ID_GOSTR3410_94_CRYPTOPRO_C_PARAMSET: Nid = + Nid(ffi::NID_id_GostR3410_94_CryptoPro_C_ParamSet); + pub const ID_GOSTR3410_94_CRYPTOPRO_D_PARAMSET: Nid = + Nid(ffi::NID_id_GostR3410_94_CryptoPro_D_ParamSet); + pub const ID_GOSTR3410_94_CRYPTOPRO_XCHA_PARAMSET: Nid = + Nid(ffi::NID_id_GostR3410_94_CryptoPro_XchA_ParamSet); + pub const ID_GOSTR3410_94_CRYPTOPRO_XCHB_PARAMSET: Nid = + Nid(ffi::NID_id_GostR3410_94_CryptoPro_XchB_ParamSet); + pub const ID_GOSTR3410_94_CRYPTOPRO_XCHC_PARAMSET: Nid = + Nid(ffi::NID_id_GostR3410_94_CryptoPro_XchC_ParamSet); + pub const ID_GOSTR3410_2001_TESTPARAMSET: Nid = Nid(ffi::NID_id_GostR3410_2001_TestParamSet); + pub const ID_GOSTR3410_2001_CRYPTOPRO_A_PARAMSET: Nid = + Nid(ffi::NID_id_GostR3410_2001_CryptoPro_A_ParamSet); + pub const ID_GOSTR3410_2001_CRYPTOPRO_B_PARAMSET: Nid = + Nid(ffi::NID_id_GostR3410_2001_CryptoPro_B_ParamSet); + pub const ID_GOSTR3410_2001_CRYPTOPRO_C_PARAMSET: Nid = + Nid(ffi::NID_id_GostR3410_2001_CryptoPro_C_ParamSet); + pub const ID_GOSTR3410_2001_CRYPTOPRO_XCHA_PARAMSET: Nid = + Nid(ffi::NID_id_GostR3410_2001_CryptoPro_XchA_ParamSet); + pub const ID_GOSTR3410_2001_CRYPTOPRO_XCHB_PARAMSET: Nid = + Nid(ffi::NID_id_GostR3410_2001_CryptoPro_XchB_ParamSet); + pub const ID_GOSTR3410_94_A: Nid = Nid(ffi::NID_id_GostR3410_94_a); + pub const ID_GOSTR3410_94_ABIS: Nid = Nid(ffi::NID_id_GostR3410_94_aBis); + pub const ID_GOSTR3410_94_B: Nid = Nid(ffi::NID_id_GostR3410_94_b); + pub const ID_GOSTR3410_94_BBIS: Nid = Nid(ffi::NID_id_GostR3410_94_bBis); + pub const ID_GOST28147_89_CC: Nid = Nid(ffi::NID_id_Gost28147_89_cc); + pub const ID_GOSTR3410_94_CC: Nid = Nid(ffi::NID_id_GostR3410_94_cc); + pub const ID_GOSTR3410_2001_CC: Nid = Nid(ffi::NID_id_GostR3410_2001_cc); + pub const ID_GOSTR3411_94_WITH_GOSTR3410_94_CC: Nid = + Nid(ffi::NID_id_GostR3411_94_with_GostR3410_94_cc); + pub const ID_GOSTR3411_94_WITH_GOSTR3410_2001_CC: Nid = + Nid(ffi::NID_id_GostR3411_94_with_GostR3410_2001_cc); + pub const ID_GOSTR3410_2001_PARAMSET_CC: Nid = Nid(ffi::NID_id_GostR3410_2001_ParamSet_cc); + pub const CAMELLIA_128_CBC: Nid = Nid(ffi::NID_camellia_128_cbc); + pub const CAMELLIA_192_CBC: Nid = Nid(ffi::NID_camellia_192_cbc); + pub const CAMELLIA_256_CBC: Nid = Nid(ffi::NID_camellia_256_cbc); + pub const ID_CAMELLIA128_WRAP: Nid = Nid(ffi::NID_id_camellia128_wrap); + pub const ID_CAMELLIA192_WRAP: Nid = Nid(ffi::NID_id_camellia192_wrap); + pub const ID_CAMELLIA256_WRAP: Nid = Nid(ffi::NID_id_camellia256_wrap); + pub const CAMELLIA_128_ECB: Nid = Nid(ffi::NID_camellia_128_ecb); + pub const CAMELLIA_128_OFB128: Nid = Nid(ffi::NID_camellia_128_ofb128); + pub const CAMELLIA_128_CFB128: Nid = Nid(ffi::NID_camellia_128_cfb128); + pub const CAMELLIA_192_ECB: Nid = Nid(ffi::NID_camellia_192_ecb); + pub const CAMELLIA_192_OFB128: Nid = Nid(ffi::NID_camellia_192_ofb128); + pub const CAMELLIA_192_CFB128: Nid = Nid(ffi::NID_camellia_192_cfb128); + pub const CAMELLIA_256_ECB: Nid = Nid(ffi::NID_camellia_256_ecb); + pub const CAMELLIA_256_OFB128: Nid = Nid(ffi::NID_camellia_256_ofb128); + pub const CAMELLIA_256_CFB128: Nid = Nid(ffi::NID_camellia_256_cfb128); + pub const CAMELLIA_128_CFB1: Nid = Nid(ffi::NID_camellia_128_cfb1); + pub const CAMELLIA_192_CFB1: Nid = Nid(ffi::NID_camellia_192_cfb1); + pub const CAMELLIA_256_CFB1: Nid = Nid(ffi::NID_camellia_256_cfb1); + pub const CAMELLIA_128_CFB8: Nid = Nid(ffi::NID_camellia_128_cfb8); + pub const CAMELLIA_192_CFB8: Nid = Nid(ffi::NID_camellia_192_cfb8); + pub const CAMELLIA_256_CFB8: Nid = Nid(ffi::NID_camellia_256_cfb8); + pub const KISA: Nid = Nid(ffi::NID_kisa); + pub const SEED_ECB: Nid = Nid(ffi::NID_seed_ecb); + pub const SEED_CBC: Nid = Nid(ffi::NID_seed_cbc); + pub const SEED_CFB128: Nid = Nid(ffi::NID_seed_cfb128); + pub const SEED_OFB128: Nid = Nid(ffi::NID_seed_ofb128); + pub const HMAC: Nid = Nid(ffi::NID_hmac); + pub const CMAC: Nid = Nid(ffi::NID_cmac); + pub const RC4_HMAC_MD5: Nid = Nid(ffi::NID_rc4_hmac_md5); + pub const AES_128_CBC_HMAC_SHA1: Nid = Nid(ffi::NID_aes_128_cbc_hmac_sha1); + pub const AES_192_CBC_HMAC_SHA1: Nid = Nid(ffi::NID_aes_192_cbc_hmac_sha1); + pub const AES_256_CBC_HMAC_SHA1: Nid = Nid(ffi::NID_aes_256_cbc_hmac_sha1); + #[cfg(ossl111)] + pub const SM2: Nid = Nid(ffi::NID_sm2); + #[cfg(any(ossl111, libressl291))] + pub const SM3: Nid = Nid(ffi::NID_sm3); + #[cfg(any(ossl111, libressl380))] + pub const SHA3_224: Nid = Nid(ffi::NID_sha3_224); + #[cfg(any(ossl111, libressl380))] + pub const SHA3_256: Nid = Nid(ffi::NID_sha3_256); + #[cfg(any(ossl111, libressl380))] + pub const SHA3_384: Nid = Nid(ffi::NID_sha3_384); + #[cfg(any(ossl111, libressl380))] + pub const SHA3_512: Nid = Nid(ffi::NID_sha3_512); + #[cfg(ossl111)] + pub const SHAKE128: Nid = Nid(ffi::NID_shake128); + #[cfg(ossl111)] + pub const SHAKE256: Nid = Nid(ffi::NID_shake256); + #[cfg(any(ossl110, libressl271))] + pub const CHACHA20_POLY1305: Nid = Nid(ffi::NID_chacha20_poly1305); +} + +#[cfg(test)] +mod test { + use super::Nid; + + #[test] + fn signature_digest() { + let algs = Nid::SHA256WITHRSAENCRYPTION.signature_algorithms().unwrap(); + assert_eq!(algs.digest, Nid::SHA256); + assert_eq!(algs.pkey, Nid::RSAENCRYPTION); + } + + #[test] + fn test_long_name_conversion() { + let common_name = Nid::COMMONNAME; + let organizational_unit_name = Nid::ORGANIZATIONALUNITNAME; + let aes256_cbc_hmac_sha1 = Nid::AES_256_CBC_HMAC_SHA1; + let id_cmc_lrapopwitness = Nid::ID_CMC_LRAPOPWITNESS; + let ms_ctl_sign = Nid::MS_CTL_SIGN; + let undefined_nid = Nid::from_raw(118); + + assert_eq!(common_name.long_name().unwrap(), "commonName"); + assert_eq!( + organizational_unit_name.long_name().unwrap(), + "organizationalUnitName" + ); + assert_eq!( + aes256_cbc_hmac_sha1.long_name().unwrap(), + "aes-256-cbc-hmac-sha1" + ); + assert_eq!( + id_cmc_lrapopwitness.long_name().unwrap(), + "id-cmc-lraPOPWitness" + ); + assert_eq!( + ms_ctl_sign.long_name().unwrap(), + "Microsoft Trust List Signing" + ); + assert!( + undefined_nid.long_name().is_err(), + "undefined_nid should not return a valid value" + ); + } + + #[test] + fn test_short_name_conversion() { + let common_name = Nid::COMMONNAME; + let organizational_unit_name = Nid::ORGANIZATIONALUNITNAME; + let aes256_cbc_hmac_sha1 = Nid::AES_256_CBC_HMAC_SHA1; + let id_cmc_lrapopwitness = Nid::ID_CMC_LRAPOPWITNESS; + let ms_ctl_sign = Nid::MS_CTL_SIGN; + let undefined_nid = Nid::from_raw(118); + + assert_eq!(common_name.short_name().unwrap(), "CN"); + assert_eq!(organizational_unit_name.short_name().unwrap(), "OU"); + assert_eq!( + aes256_cbc_hmac_sha1.short_name().unwrap(), + "AES-256-CBC-HMAC-SHA1" + ); + assert_eq!( + id_cmc_lrapopwitness.short_name().unwrap(), + "id-cmc-lraPOPWitness" + ); + assert_eq!(ms_ctl_sign.short_name().unwrap(), "msCTLSign"); + assert!( + undefined_nid.short_name().is_err(), + "undefined_nid should not return a valid value" + ); + } + + #[test] + fn test_create() { + let nid = Nid::create("1.2.3.4", "foo", "foobar").unwrap(); + assert_eq!(nid.short_name().unwrap(), "foo"); + assert_eq!(nid.long_name().unwrap(), "foobar"); + + // Due to a bug in OpenSSL 3.1.0, this test crashes on Windows + if !cfg!(ossl310) { + let invalid_oid = Nid::create("invalid_oid", "invalid", "invalid"); + assert!( + invalid_oid.is_err(), + "invalid_oid should not return a valid value" + ); + } + } +} diff --git a/vendor/openssl/src/ocsp.rs b/vendor/openssl/src/ocsp.rs new file mode 100644 index 0000000..570b8c2 --- /dev/null +++ b/vendor/openssl/src/ocsp.rs @@ -0,0 +1,352 @@ +use bitflags::bitflags; +use foreign_types::ForeignTypeRef; +use libc::{c_int, c_long, c_ulong}; +use std::mem; +use std::ptr; + +use crate::asn1::Asn1GeneralizedTimeRef; +use crate::error::ErrorStack; +use crate::hash::MessageDigest; +use crate::stack::StackRef; +use crate::util::ForeignTypeRefExt; +use crate::x509::store::X509StoreRef; +use crate::x509::{X509Ref, X509}; +use crate::{cvt, cvt_p}; +use openssl_macros::corresponds; + +bitflags! { + #[derive(Copy, Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)] + #[repr(transparent)] + pub struct OcspFlag: c_ulong { + const NO_CERTS = ffi::OCSP_NOCERTS; + const NO_INTERN = ffi::OCSP_NOINTERN; + const NO_CHAIN = ffi::OCSP_NOCHAIN; + const NO_VERIFY = ffi::OCSP_NOVERIFY; + const NO_EXPLICIT = ffi::OCSP_NOEXPLICIT; + const NO_CA_SIGN = ffi::OCSP_NOCASIGN; + const NO_DELEGATED = ffi::OCSP_NODELEGATED; + const NO_CHECKS = ffi::OCSP_NOCHECKS; + const TRUST_OTHER = ffi::OCSP_TRUSTOTHER; + const RESPID_KEY = ffi::OCSP_RESPID_KEY; + const NO_TIME = ffi::OCSP_NOTIME; + } +} + +#[derive(Copy, Clone, Debug, PartialEq, Eq)] +pub struct OcspResponseStatus(c_int); + +impl OcspResponseStatus { + pub const SUCCESSFUL: OcspResponseStatus = + OcspResponseStatus(ffi::OCSP_RESPONSE_STATUS_SUCCESSFUL); + pub const MALFORMED_REQUEST: OcspResponseStatus = + OcspResponseStatus(ffi::OCSP_RESPONSE_STATUS_MALFORMEDREQUEST); + pub const INTERNAL_ERROR: OcspResponseStatus = + OcspResponseStatus(ffi::OCSP_RESPONSE_STATUS_INTERNALERROR); + pub const TRY_LATER: OcspResponseStatus = + OcspResponseStatus(ffi::OCSP_RESPONSE_STATUS_TRYLATER); + pub const SIG_REQUIRED: OcspResponseStatus = + OcspResponseStatus(ffi::OCSP_RESPONSE_STATUS_SIGREQUIRED); + pub const UNAUTHORIZED: OcspResponseStatus = + OcspResponseStatus(ffi::OCSP_RESPONSE_STATUS_UNAUTHORIZED); + + pub fn from_raw(raw: c_int) -> OcspResponseStatus { + OcspResponseStatus(raw) + } + + #[allow(clippy::trivially_copy_pass_by_ref)] + pub fn as_raw(&self) -> c_int { + self.0 + } +} + +#[derive(Copy, Clone, Debug, PartialEq, Eq)] +pub struct OcspCertStatus(c_int); + +impl OcspCertStatus { + pub const GOOD: OcspCertStatus = OcspCertStatus(ffi::V_OCSP_CERTSTATUS_GOOD); + pub const REVOKED: OcspCertStatus = OcspCertStatus(ffi::V_OCSP_CERTSTATUS_REVOKED); + pub const UNKNOWN: OcspCertStatus = OcspCertStatus(ffi::V_OCSP_CERTSTATUS_UNKNOWN); + + pub fn from_raw(raw: c_int) -> OcspCertStatus { + OcspCertStatus(raw) + } + + #[allow(clippy::trivially_copy_pass_by_ref)] + pub fn as_raw(&self) -> c_int { + self.0 + } +} + +#[derive(Copy, Clone, Debug, PartialEq, Eq)] +pub struct OcspRevokedStatus(c_int); + +impl OcspRevokedStatus { + pub const NO_STATUS: OcspRevokedStatus = OcspRevokedStatus(ffi::OCSP_REVOKED_STATUS_NOSTATUS); + pub const UNSPECIFIED: OcspRevokedStatus = + OcspRevokedStatus(ffi::OCSP_REVOKED_STATUS_UNSPECIFIED); + pub const KEY_COMPROMISE: OcspRevokedStatus = + OcspRevokedStatus(ffi::OCSP_REVOKED_STATUS_KEYCOMPROMISE); + pub const CA_COMPROMISE: OcspRevokedStatus = + OcspRevokedStatus(ffi::OCSP_REVOKED_STATUS_CACOMPROMISE); + pub const AFFILIATION_CHANGED: OcspRevokedStatus = + OcspRevokedStatus(ffi::OCSP_REVOKED_STATUS_AFFILIATIONCHANGED); + pub const STATUS_SUPERSEDED: OcspRevokedStatus = + OcspRevokedStatus(ffi::OCSP_REVOKED_STATUS_SUPERSEDED); + pub const STATUS_CESSATION_OF_OPERATION: OcspRevokedStatus = + OcspRevokedStatus(ffi::OCSP_REVOKED_STATUS_CESSATIONOFOPERATION); + pub const STATUS_CERTIFICATE_HOLD: OcspRevokedStatus = + OcspRevokedStatus(ffi::OCSP_REVOKED_STATUS_CERTIFICATEHOLD); + pub const REMOVE_FROM_CRL: OcspRevokedStatus = + OcspRevokedStatus(ffi::OCSP_REVOKED_STATUS_REMOVEFROMCRL); + + pub fn from_raw(raw: c_int) -> OcspRevokedStatus { + OcspRevokedStatus(raw) + } + + #[allow(clippy::trivially_copy_pass_by_ref)] + pub fn as_raw(&self) -> c_int { + self.0 + } +} + +pub struct OcspStatus<'a> { + /// The overall status of the response. + pub status: OcspCertStatus, + /// If `status` is `CERT_STATUS_REVOKED`, the reason for the revocation. + pub reason: OcspRevokedStatus, + /// If `status` is `CERT_STATUS_REVOKED`, the time at which the certificate was revoked. + pub revocation_time: Option<&'a Asn1GeneralizedTimeRef>, + /// The time that this revocation check was performed. + pub this_update: &'a Asn1GeneralizedTimeRef, + /// The time at which this revocation check expires. + pub next_update: &'a Asn1GeneralizedTimeRef, +} + +impl OcspStatus<'_> { + /// Checks validity of the `this_update` and `next_update` fields. + /// + /// The `nsec` parameter specifies an amount of slack time that will be used when comparing + /// those times with the current time to account for delays and clock skew. + /// + /// The `maxsec` parameter limits the maximum age of the `this_update` parameter to prohibit + /// very old responses. + #[corresponds(OCSP_check_validity)] + pub fn check_validity(&self, nsec: u32, maxsec: Option) -> Result<(), ErrorStack> { + unsafe { + cvt(ffi::OCSP_check_validity( + self.this_update.as_ptr(), + self.next_update.as_ptr(), + nsec as c_long, + maxsec.map(|n| n as c_long).unwrap_or(-1), + )) + .map(|_| ()) + } + } +} + +foreign_type_and_impl_send_sync! { + type CType = ffi::OCSP_BASICRESP; + fn drop = ffi::OCSP_BASICRESP_free; + + pub struct OcspBasicResponse; + pub struct OcspBasicResponseRef; +} + +impl OcspBasicResponseRef { + /// Verifies the validity of the response. + /// + /// The `certs` parameter contains a set of certificates that will be searched when locating the + /// OCSP response signing certificate. Some responders do not include this in the response. + #[corresponds(OCSP_basic_verify)] + pub fn verify( + &self, + certs: &StackRef, + store: &X509StoreRef, + flags: OcspFlag, + ) -> Result<(), ErrorStack> { + unsafe { + cvt(ffi::OCSP_basic_verify( + self.as_ptr(), + certs.as_ptr(), + store.as_ptr(), + flags.bits(), + )) + .map(|_| ()) + } + } + + /// Looks up the status for the specified certificate ID. + #[corresponds(OCSP_resp_find_status)] + pub fn find_status<'a>(&'a self, id: &OcspCertIdRef) -> Option> { + unsafe { + let mut status = ffi::V_OCSP_CERTSTATUS_UNKNOWN; + let mut reason = ffi::OCSP_REVOKED_STATUS_NOSTATUS; + let mut revocation_time = ptr::null_mut(); + let mut this_update = ptr::null_mut(); + let mut next_update = ptr::null_mut(); + + let r = ffi::OCSP_resp_find_status( + self.as_ptr(), + id.as_ptr(), + &mut status, + &mut reason, + &mut revocation_time, + &mut this_update, + &mut next_update, + ); + if r == 1 { + let revocation_time = Asn1GeneralizedTimeRef::from_const_ptr_opt(revocation_time); + + Some(OcspStatus { + status: OcspCertStatus(status), + reason: OcspRevokedStatus(status), + revocation_time, + this_update: Asn1GeneralizedTimeRef::from_ptr(this_update), + next_update: Asn1GeneralizedTimeRef::from_ptr(next_update), + }) + } else { + None + } + } + } +} + +foreign_type_and_impl_send_sync! { + type CType = ffi::OCSP_CERTID; + fn drop = ffi::OCSP_CERTID_free; + + pub struct OcspCertId; + pub struct OcspCertIdRef; +} + +impl OcspCertId { + /// Constructs a certificate ID for certificate `subject`. + #[corresponds(OCSP_cert_to_id)] + pub fn from_cert( + digest: MessageDigest, + subject: &X509Ref, + issuer: &X509Ref, + ) -> Result { + unsafe { + cvt_p(ffi::OCSP_cert_to_id( + digest.as_ptr(), + subject.as_ptr(), + issuer.as_ptr(), + )) + .map(OcspCertId) + } + } +} + +foreign_type_and_impl_send_sync! { + type CType = ffi::OCSP_RESPONSE; + fn drop = ffi::OCSP_RESPONSE_free; + + pub struct OcspResponse; + pub struct OcspResponseRef; +} + +impl OcspResponse { + /// Creates an OCSP response from the status and optional body. + /// + /// A body should only be provided if `status` is `RESPONSE_STATUS_SUCCESSFUL`. + #[corresponds(OCSP_response_create)] + pub fn create( + status: OcspResponseStatus, + body: Option<&OcspBasicResponseRef>, + ) -> Result { + unsafe { + ffi::init(); + + cvt_p(ffi::OCSP_response_create( + status.as_raw(), + body.map(|r| r.as_ptr()).unwrap_or(ptr::null_mut()), + )) + .map(OcspResponse) + } + } + + from_der! { + /// Deserializes a DER-encoded OCSP response. + #[corresponds(d2i_OCSP_RESPONSE)] + from_der, + OcspResponse, + ffi::d2i_OCSP_RESPONSE + } +} + +impl OcspResponseRef { + to_der! { + /// Serializes the response to its standard DER encoding. + #[corresponds(i2d_OCSP_RESPONSE)] + to_der, + ffi::i2d_OCSP_RESPONSE + } + + /// Returns the status of the response. + #[corresponds(OCSP_response_status)] + pub fn status(&self) -> OcspResponseStatus { + unsafe { OcspResponseStatus(ffi::OCSP_response_status(self.as_ptr())) } + } + + /// Returns the basic response. + /// + /// This will only succeed if `status()` returns `RESPONSE_STATUS_SUCCESSFUL`. + #[corresponds(OCSP_response_get1_basic)] + pub fn basic(&self) -> Result { + unsafe { cvt_p(ffi::OCSP_response_get1_basic(self.as_ptr())).map(OcspBasicResponse) } + } +} + +foreign_type_and_impl_send_sync! { + type CType = ffi::OCSP_REQUEST; + fn drop = ffi::OCSP_REQUEST_free; + + pub struct OcspRequest; + pub struct OcspRequestRef; +} + +impl OcspRequest { + #[corresponds(OCSP_REQUEST_new)] + pub fn new() -> Result { + unsafe { + ffi::init(); + + cvt_p(ffi::OCSP_REQUEST_new()).map(OcspRequest) + } + } + + from_der! { + /// Deserializes a DER-encoded OCSP request. + #[corresponds(d2i_OCSP_REQUEST)] + from_der, + OcspRequest, + ffi::d2i_OCSP_REQUEST + } +} + +impl OcspRequestRef { + to_der! { + /// Serializes the request to its standard DER encoding. + #[corresponds(i2d_OCSP_REQUEST)] + to_der, + ffi::i2d_OCSP_REQUEST + } + + #[corresponds(OCSP_request_add0_id)] + pub fn add_id(&mut self, id: OcspCertId) -> Result<&mut OcspOneReqRef, ErrorStack> { + unsafe { + let ptr = cvt_p(ffi::OCSP_request_add0_id(self.as_ptr(), id.as_ptr()))?; + mem::forget(id); + Ok(OcspOneReqRef::from_ptr_mut(ptr)) + } + } +} + +foreign_type_and_impl_send_sync! { + type CType = ffi::OCSP_ONEREQ; + fn drop = ffi::OCSP_ONEREQ_free; + + pub struct OcspOneReq; + pub struct OcspOneReqRef; +} diff --git a/vendor/openssl/src/pkcs12.rs b/vendor/openssl/src/pkcs12.rs new file mode 100644 index 0000000..5f171da --- /dev/null +++ b/vendor/openssl/src/pkcs12.rs @@ -0,0 +1,403 @@ +//! PKCS #12 archives. + +use foreign_types::{ForeignType, ForeignTypeRef}; +use libc::c_int; +use std::ffi::CString; +use std::ptr; + +use crate::error::ErrorStack; +#[cfg(not(boringssl))] +use crate::hash::MessageDigest; +use crate::nid::Nid; +use crate::pkey::{HasPrivate, PKey, PKeyRef, Private}; +use crate::stack::Stack; +use crate::util::ForeignTypeExt; +use crate::x509::{X509Ref, X509}; +use crate::{cvt, cvt_p}; +use openssl_macros::corresponds; + +foreign_type_and_impl_send_sync! { + type CType = ffi::PKCS12; + fn drop = ffi::PKCS12_free; + + pub struct Pkcs12; + pub struct Pkcs12Ref; +} + +impl Pkcs12Ref { + to_der! { + /// Serializes the `Pkcs12` to its standard DER encoding. + #[corresponds(i2d_PKCS12)] + to_der, + ffi::i2d_PKCS12 + } + + /// Deprecated. + #[deprecated(note = "Use parse2 instead", since = "0.10.46")] + #[allow(deprecated)] + pub fn parse(&self, pass: &str) -> Result { + let parsed = self.parse2(pass)?; + + Ok(ParsedPkcs12 { + pkey: parsed.pkey.unwrap(), + cert: parsed.cert.unwrap(), + chain: parsed.ca, + }) + } + + /// Extracts the contents of the `Pkcs12`. + #[corresponds(PKCS12_parse)] + pub fn parse2(&self, pass: &str) -> Result { + unsafe { + let pass = CString::new(pass.as_bytes()).unwrap(); + + let mut pkey = ptr::null_mut(); + let mut cert = ptr::null_mut(); + let mut ca = ptr::null_mut(); + + cvt(ffi::PKCS12_parse( + self.as_ptr(), + pass.as_ptr(), + &mut pkey, + &mut cert, + &mut ca, + ))?; + + let pkey = PKey::from_ptr_opt(pkey); + let cert = X509::from_ptr_opt(cert); + let ca = Stack::from_ptr_opt(ca); + + Ok(ParsedPkcs12_2 { pkey, cert, ca }) + } + } +} + +impl Pkcs12 { + from_der! { + /// Deserializes a DER-encoded PKCS#12 archive. + #[corresponds(d2i_PKCS12)] + from_der, + Pkcs12, + ffi::d2i_PKCS12 + } + + /// Creates a new builder for a protected pkcs12 certificate. + /// + /// This uses the defaults from the OpenSSL library: + /// + /// * `nid_key` - `AES_256_CBC` (3.0.0+) or `PBE_WITHSHA1AND3_KEY_TRIPLEDES_CBC` + /// * `nid_cert` - `AES_256_CBC` (3.0.0+) or `PBE_WITHSHA1AND40BITRC2_CBC` + /// * `iter` - `2048` + /// * `mac_iter` - `2048` + /// * `mac_md` - `SHA-256` (3.0.0+) or `SHA-1` (`SHA-1` only for BoringSSL) + pub fn builder() -> Pkcs12Builder { + ffi::init(); + + Pkcs12Builder { + name: None, + pkey: None, + cert: None, + ca: None, + nid_key: Nid::UNDEF, + nid_cert: Nid::UNDEF, + iter: ffi::PKCS12_DEFAULT_ITER, + mac_iter: ffi::PKCS12_DEFAULT_ITER, + #[cfg(not(boringssl))] + mac_md: None, + } + } +} + +#[deprecated(note = "Use ParsedPkcs12_2 instead", since = "0.10.46")] +pub struct ParsedPkcs12 { + pub pkey: PKey, + pub cert: X509, + pub chain: Option>, +} + +pub struct ParsedPkcs12_2 { + pub pkey: Option>, + pub cert: Option, + pub ca: Option>, +} + +pub struct Pkcs12Builder { + // FIXME borrow + name: Option, + pkey: Option>, + cert: Option, + ca: Option>, + nid_key: Nid, + nid_cert: Nid, + iter: c_int, + mac_iter: c_int, + // FIXME remove + #[cfg(not(boringssl))] + mac_md: Option, +} + +impl Pkcs12Builder { + /// The `friendlyName` used for the certificate and private key. + pub fn name(&mut self, name: &str) -> &mut Self { + self.name = Some(CString::new(name).unwrap()); + self + } + + /// The private key. + pub fn pkey(&mut self, pkey: &PKeyRef) -> &mut Self + where + T: HasPrivate, + { + let new_pkey = unsafe { PKeyRef::from_ptr(pkey.as_ptr()) }; + self.pkey = Some(new_pkey.to_owned()); + self + } + + /// The certificate. + pub fn cert(&mut self, cert: &X509Ref) -> &mut Self { + self.cert = Some(cert.to_owned()); + self + } + + /// An additional set of certificates to include in the archive beyond the one provided to + /// `build`. + pub fn ca(&mut self, ca: Stack) -> &mut Self { + self.ca = Some(ca); + self + } + + /// The encryption algorithm that should be used for the key + pub fn key_algorithm(&mut self, nid: Nid) -> &mut Self { + self.nid_key = nid; + self + } + + /// The encryption algorithm that should be used for the cert + pub fn cert_algorithm(&mut self, nid: Nid) -> &mut Self { + self.nid_cert = nid; + self + } + + /// Key iteration count, default is 2048 as of this writing + pub fn key_iter(&mut self, iter: u32) -> &mut Self { + self.iter = iter as c_int; + self + } + + /// MAC iteration count, default is the same as key_iter. + /// + /// Old implementations don't understand MAC iterations greater than 1, (pre 1.0.1?), if such + /// compatibility is required this should be set to 1. + pub fn mac_iter(&mut self, mac_iter: u32) -> &mut Self { + self.mac_iter = mac_iter as c_int; + self + } + + /// MAC message digest type + #[cfg(not(boringssl))] + pub fn mac_md(&mut self, md: MessageDigest) -> &mut Self { + self.mac_md = Some(md); + self + } + + /// Deprecated. + #[deprecated( + note = "Use Self::{name, pkey, cert, build2} instead.", + since = "0.10.46" + )] + pub fn build( + mut self, + password: &str, + friendly_name: &str, + pkey: &PKeyRef, + cert: &X509Ref, + ) -> Result + where + T: HasPrivate, + { + self.name(friendly_name) + .pkey(pkey) + .cert(cert) + .build2(password) + } + + /// Builds the PKCS#12 object. + #[corresponds(PKCS12_create)] + pub fn build2(&self, password: &str) -> Result { + unsafe { + let pass = CString::new(password).unwrap(); + let pass = pass.as_ptr(); + let friendly_name = self.name.as_ref().map_or(ptr::null(), |p| p.as_ptr()); + let pkey = self.pkey.as_ref().map_or(ptr::null(), |p| p.as_ptr()); + let cert = self.cert.as_ref().map_or(ptr::null(), |p| p.as_ptr()); + let ca = self + .ca + .as_ref() + .map(|ca| ca.as_ptr()) + .unwrap_or(ptr::null_mut()); + let nid_key = self.nid_key.as_raw(); + let nid_cert = self.nid_cert.as_raw(); + + // According to the OpenSSL docs, keytype is a non-standard extension for MSIE, + // It's values are KEY_SIG or KEY_EX, see the OpenSSL docs for more information: + // https://www.openssl.org/docs/manmaster/crypto/PKCS12_create.html + let keytype = 0; + + let pkcs12 = cvt_p(ffi::PKCS12_create( + pass as *mut _, + friendly_name as *mut _, + pkey as *mut _, + cert as *mut _, + ca, + nid_key, + nid_cert, + self.iter, + self.mac_iter, + keytype, + )) + .map(Pkcs12)?; + + #[cfg(not(boringssl))] + // BoringSSL does not support overriding the MAC and will always + // use SHA-1 + { + let md_type = self + .mac_md + .map(|md_type| md_type.as_ptr()) + .unwrap_or(ptr::null()); + + cvt(ffi::PKCS12_set_mac( + pkcs12.as_ptr(), + pass, + -1, + ptr::null_mut(), + 0, + self.mac_iter, + md_type, + ))?; + } + + Ok(pkcs12) + } + } +} + +#[cfg(test)] +mod test { + use crate::asn1::Asn1Time; + use crate::hash::MessageDigest; + use crate::nid::Nid; + use crate::pkey::PKey; + use crate::rsa::Rsa; + use crate::x509::extension::KeyUsage; + use crate::x509::{X509Name, X509}; + + use super::*; + + #[test] + fn parse() { + #[cfg(ossl300)] + let _provider = crate::provider::Provider::try_load(None, "legacy", true).unwrap(); + + let der = include_bytes!("../test/identity.p12"); + let pkcs12 = Pkcs12::from_der(der).unwrap(); + let parsed = pkcs12.parse2("mypass").unwrap(); + + assert_eq!( + hex::encode( + parsed + .cert + .as_ref() + .unwrap() + .digest(MessageDigest::sha1()) + .unwrap() + ), + "59172d9313e84459bcff27f967e79e6e9217e584" + ); + assert_eq!( + parsed.cert.as_ref().unwrap().alias(), + Some(b"foobar.com" as &[u8]) + ); + + let chain = parsed.ca.unwrap(); + assert_eq!(chain.len(), 1); + assert_eq!( + hex::encode(chain[0].digest(MessageDigest::sha1()).unwrap()), + "c0cbdf7cdd03c9773e5468e1f6d2da7d5cbb1875" + ); + } + + #[test] + fn parse_empty_chain() { + #[cfg(ossl300)] + let _provider = crate::provider::Provider::try_load(None, "legacy", true).unwrap(); + + let der = include_bytes!("../test/keystore-empty-chain.p12"); + let pkcs12 = Pkcs12::from_der(der).unwrap(); + let parsed = pkcs12.parse2("cassandra").unwrap(); + if let Some(stack) = parsed.ca { + assert_eq!(stack.len(), 0); + } + } + + #[test] + fn create() { + let subject_name = "ns.example.com"; + let rsa = Rsa::generate(2048).unwrap(); + let pkey = PKey::from_rsa(rsa).unwrap(); + + let mut name = X509Name::builder().unwrap(); + name.append_entry_by_nid(Nid::COMMONNAME, subject_name) + .unwrap(); + let name = name.build(); + + let key_usage = KeyUsage::new().digital_signature().build().unwrap(); + + let mut builder = X509::builder().unwrap(); + builder.set_version(2).unwrap(); + builder + .set_not_before(&Asn1Time::days_from_now(0).unwrap()) + .unwrap(); + builder + .set_not_after(&Asn1Time::days_from_now(365).unwrap()) + .unwrap(); + builder.set_subject_name(&name).unwrap(); + builder.set_issuer_name(&name).unwrap(); + builder.append_extension(key_usage).unwrap(); + builder.set_pubkey(&pkey).unwrap(); + builder.sign(&pkey, MessageDigest::sha256()).unwrap(); + let cert = builder.build(); + + let pkcs12 = Pkcs12::builder() + .name(subject_name) + .pkey(&pkey) + .cert(&cert) + .build2("mypass") + .unwrap(); + let der = pkcs12.to_der().unwrap(); + + let pkcs12 = Pkcs12::from_der(&der).unwrap(); + let parsed = pkcs12.parse2("mypass").unwrap(); + + assert_eq!( + &*parsed.cert.unwrap().digest(MessageDigest::sha1()).unwrap(), + &*cert.digest(MessageDigest::sha1()).unwrap() + ); + assert!(parsed.pkey.unwrap().public_eq(&pkey)); + } + + #[test] + fn create_only_ca() { + let ca = include_bytes!("../test/root-ca.pem"); + let ca = X509::from_pem(ca).unwrap(); + let mut chain = Stack::new().unwrap(); + chain.push(ca).unwrap(); + + let pkcs12 = Pkcs12::builder().ca(chain).build2("hunter2").unwrap(); + let parsed = pkcs12.parse2("hunter2").unwrap(); + + assert!(parsed.cert.is_none()); + assert!(parsed.pkey.is_none()); + assert_eq!(parsed.ca.unwrap().len(), 1); + } +} diff --git a/vendor/openssl/src/pkcs5.rs b/vendor/openssl/src/pkcs5.rs new file mode 100644 index 0000000..594b5fc --- /dev/null +++ b/vendor/openssl/src/pkcs5.rs @@ -0,0 +1,310 @@ +#[cfg(not(boringssl))] +use libc::c_int; +use std::convert::TryInto; +#[cfg(not(boringssl))] +use std::ptr; + +use crate::cvt; +use crate::error::ErrorStack; +use crate::hash::MessageDigest; +#[cfg(not(boringssl))] +use crate::symm::Cipher; +use openssl_macros::corresponds; + +#[derive(Clone, Eq, PartialEq, Hash, Debug)] +pub struct KeyIvPair { + pub key: Vec, + pub iv: Option>, +} + +/// Derives a key and an IV from various parameters. +/// +/// If specified, `salt` must be 8 bytes in length. +/// +/// If the total key and IV length is less than 16 bytes and MD5 is used then +/// the algorithm is compatible with the key derivation algorithm from PKCS#5 +/// v1.5 or PBKDF1 from PKCS#5 v2.0. +/// +/// New applications should not use this and instead use +/// `pbkdf2_hmac` or another more modern key derivation algorithm. +#[corresponds(EVP_BytesToKey)] +#[allow(clippy::useless_conversion)] +#[cfg(not(boringssl))] +pub fn bytes_to_key( + cipher: Cipher, + digest: MessageDigest, + data: &[u8], + salt: Option<&[u8]>, + count: i32, +) -> Result { + unsafe { + assert!(data.len() <= c_int::MAX as usize); + let salt_ptr = match salt { + Some(salt) => { + assert_eq!(salt.len(), ffi::PKCS5_SALT_LEN as usize); + salt.as_ptr() + } + None => ptr::null(), + }; + + ffi::init(); + + let mut iv = cipher.iv_len().map(|l| vec![0; l]); + + let cipher = cipher.as_ptr(); + let digest = digest.as_ptr(); + + let len = cvt(ffi::EVP_BytesToKey( + cipher, + digest, + salt_ptr, + ptr::null(), + data.len() as c_int, + count.into(), + ptr::null_mut(), + ptr::null_mut(), + ))?; + + let mut key = vec![0; len as usize]; + let iv_ptr = iv + .as_mut() + .map(|v| v.as_mut_ptr()) + .unwrap_or(ptr::null_mut()); + + cvt(ffi::EVP_BytesToKey( + cipher, + digest, + salt_ptr, + data.as_ptr(), + data.len() as c_int, + count as c_int, + key.as_mut_ptr(), + iv_ptr, + ))?; + + Ok(KeyIvPair { key, iv }) + } +} + +/// Derives a key from a password and salt using the PBKDF2-HMAC algorithm with a digest function. +#[corresponds(PKCS5_PBKDF2_HMAC)] +pub fn pbkdf2_hmac( + pass: &[u8], + salt: &[u8], + iter: usize, + hash: MessageDigest, + key: &mut [u8], +) -> Result<(), ErrorStack> { + unsafe { + ffi::init(); + cvt(ffi::PKCS5_PBKDF2_HMAC( + pass.as_ptr() as *const _, + pass.len().try_into().unwrap(), + salt.as_ptr(), + salt.len().try_into().unwrap(), + iter.try_into().unwrap(), + hash.as_ptr(), + key.len().try_into().unwrap(), + key.as_mut_ptr(), + )) + .map(|_| ()) + } +} + +/// Derives a key from a password and salt using the scrypt algorithm. +/// +/// Requires OpenSSL 1.1.0 or newer. +#[corresponds(EVP_PBE_scrypt)] +#[cfg(all(any(ossl110, boringssl), not(osslconf = "OPENSSL_NO_SCRYPT")))] +#[allow(clippy::useless_conversion)] +pub fn scrypt( + pass: &[u8], + salt: &[u8], + n: u64, + r: u64, + p: u64, + maxmem: u64, + key: &mut [u8], +) -> Result<(), ErrorStack> { + unsafe { + ffi::init(); + cvt(ffi::EVP_PBE_scrypt( + pass.as_ptr() as *const _, + pass.len(), + salt.as_ptr() as *const _, + salt.len(), + n, + r, + p, + maxmem.try_into().unwrap(), + key.as_mut_ptr() as *mut _, + key.len(), + )) + .map(|_| ()) + } +} + +#[cfg(test)] +mod tests { + use crate::hash::MessageDigest; + #[cfg(not(boringssl))] + use crate::symm::Cipher; + + // Test vectors from + // https://git.lysator.liu.se/nettle/nettle/blob/nettle_3.1.1_release_20150424/testsuite/pbkdf2-test.c + #[test] + fn pbkdf2_hmac_sha256() { + let mut buf = [0; 16]; + + super::pbkdf2_hmac(b"passwd", b"salt", 1, MessageDigest::sha256(), &mut buf).unwrap(); + assert_eq!( + buf, + &[ + 0x55_u8, 0xac_u8, 0x04_u8, 0x6e_u8, 0x56_u8, 0xe3_u8, 0x08_u8, 0x9f_u8, 0xec_u8, + 0x16_u8, 0x91_u8, 0xc2_u8, 0x25_u8, 0x44_u8, 0xb6_u8, 0x05_u8, + ][..] + ); + + super::pbkdf2_hmac( + b"Password", + b"NaCl", + 80000, + MessageDigest::sha256(), + &mut buf, + ) + .unwrap(); + assert_eq!( + buf, + &[ + 0x4d_u8, 0xdc_u8, 0xd8_u8, 0xf6_u8, 0x0b_u8, 0x98_u8, 0xbe_u8, 0x21_u8, 0x83_u8, + 0x0c_u8, 0xee_u8, 0x5e_u8, 0xf2_u8, 0x27_u8, 0x01_u8, 0xf9_u8, + ][..] + ); + } + + // Test vectors from + // https://git.lysator.liu.se/nettle/nettle/blob/nettle_3.1.1_release_20150424/testsuite/pbkdf2-test.c + #[test] + fn pbkdf2_hmac_sha512() { + let mut buf = [0; 64]; + + super::pbkdf2_hmac(b"password", b"NaCL", 1, MessageDigest::sha512(), &mut buf).unwrap(); + assert_eq!( + &buf[..], + &[ + 0x73_u8, 0xde_u8, 0xcf_u8, 0xa5_u8, 0x8a_u8, 0xa2_u8, 0xe8_u8, 0x4f_u8, 0x94_u8, + 0x77_u8, 0x1a_u8, 0x75_u8, 0x73_u8, 0x6b_u8, 0xb8_u8, 0x8b_u8, 0xd3_u8, 0xc7_u8, + 0xb3_u8, 0x82_u8, 0x70_u8, 0xcf_u8, 0xb5_u8, 0x0c_u8, 0xb3_u8, 0x90_u8, 0xed_u8, + 0x78_u8, 0xb3_u8, 0x05_u8, 0x65_u8, 0x6a_u8, 0xf8_u8, 0x14_u8, 0x8e_u8, 0x52_u8, + 0x45_u8, 0x2b_u8, 0x22_u8, 0x16_u8, 0xb2_u8, 0xb8_u8, 0x09_u8, 0x8b_u8, 0x76_u8, + 0x1f_u8, 0xc6_u8, 0x33_u8, 0x60_u8, 0x60_u8, 0xa0_u8, 0x9f_u8, 0x76_u8, 0x41_u8, + 0x5e_u8, 0x9f_u8, 0x71_u8, 0xea_u8, 0x47_u8, 0xf9_u8, 0xe9_u8, 0x06_u8, 0x43_u8, + 0x06_u8, + ][..] + ); + + super::pbkdf2_hmac( + b"pass\0word", + b"sa\0lt", + 1, + MessageDigest::sha512(), + &mut buf, + ) + .unwrap(); + assert_eq!( + &buf[..], + &[ + 0x71_u8, 0xa0_u8, 0xec_u8, 0x84_u8, 0x2a_u8, 0xbd_u8, 0x5c_u8, 0x67_u8, 0x8b_u8, + 0xcf_u8, 0xd1_u8, 0x45_u8, 0xf0_u8, 0x9d_u8, 0x83_u8, 0x52_u8, 0x2f_u8, 0x93_u8, + 0x36_u8, 0x15_u8, 0x60_u8, 0x56_u8, 0x3c_u8, 0x4d_u8, 0x0d_u8, 0x63_u8, 0xb8_u8, + 0x83_u8, 0x29_u8, 0x87_u8, 0x10_u8, 0x90_u8, 0xe7_u8, 0x66_u8, 0x04_u8, 0xa4_u8, + 0x9a_u8, 0xf0_u8, 0x8f_u8, 0xe7_u8, 0xc9_u8, 0xf5_u8, 0x71_u8, 0x56_u8, 0xc8_u8, + 0x79_u8, 0x09_u8, 0x96_u8, 0xb2_u8, 0x0f_u8, 0x06_u8, 0xbc_u8, 0x53_u8, 0x5e_u8, + 0x5a_u8, 0xb5_u8, 0x44_u8, 0x0d_u8, 0xf7_u8, 0xe8_u8, 0x78_u8, 0x29_u8, 0x6f_u8, + 0xa7_u8, + ][..] + ); + + super::pbkdf2_hmac( + b"passwordPASSWORDpassword", + b"salt\0\0\0", + 50, + MessageDigest::sha512(), + &mut buf, + ) + .unwrap(); + assert_eq!( + &buf[..], + &[ + 0x01_u8, 0x68_u8, 0x71_u8, 0xa4_u8, 0xc4_u8, 0xb7_u8, 0x5f_u8, 0x96_u8, 0x85_u8, + 0x7f_u8, 0xd2_u8, 0xb9_u8, 0xf8_u8, 0xca_u8, 0x28_u8, 0x02_u8, 0x3b_u8, 0x30_u8, + 0xee_u8, 0x2a_u8, 0x39_u8, 0xf5_u8, 0xad_u8, 0xca_u8, 0xc8_u8, 0xc9_u8, 0x37_u8, + 0x5f_u8, 0x9b_u8, 0xda_u8, 0x1c_u8, 0xcd_u8, 0x1b_u8, 0x6f_u8, 0x0b_u8, 0x2f_u8, + 0xc3_u8, 0xad_u8, 0xda_u8, 0x50_u8, 0x54_u8, 0x12_u8, 0xe7_u8, 0x9d_u8, 0x89_u8, + 0x00_u8, 0x56_u8, 0xc6_u8, 0x2e_u8, 0x52_u8, 0x4c_u8, 0x7d_u8, 0x51_u8, 0x15_u8, + 0x4b_u8, 0x1a_u8, 0x85_u8, 0x34_u8, 0x57_u8, 0x5b_u8, 0xd0_u8, 0x2d_u8, 0xee_u8, + 0x39_u8, + ][..] + ); + } + + #[test] + #[cfg(not(boringssl))] + fn bytes_to_key() { + let salt = [16_u8, 34_u8, 19_u8, 23_u8, 141_u8, 4_u8, 207_u8, 221_u8]; + + let data = [ + 143_u8, 210_u8, 75_u8, 63_u8, 214_u8, 179_u8, 155_u8, 241_u8, 242_u8, 31_u8, 154_u8, + 56_u8, 198_u8, 145_u8, 192_u8, 64_u8, 2_u8, 245_u8, 167_u8, 220_u8, 55_u8, 119_u8, + 233_u8, 136_u8, 139_u8, 27_u8, 71_u8, 242_u8, 119_u8, 175_u8, 65_u8, 207_u8, + ]; + + let expected_key = vec![ + 249_u8, 115_u8, 114_u8, 97_u8, 32_u8, 213_u8, 165_u8, 146_u8, 58_u8, 87_u8, 234_u8, + 3_u8, 43_u8, 250_u8, 97_u8, 114_u8, 26_u8, 98_u8, 245_u8, 246_u8, 238_u8, 177_u8, + 229_u8, 161_u8, 183_u8, 224_u8, 174_u8, 3_u8, 6_u8, 244_u8, 236_u8, 255_u8, + ]; + let expected_iv = vec![ + 4_u8, 223_u8, 153_u8, 219_u8, 28_u8, 142_u8, 234_u8, 68_u8, 227_u8, 69_u8, 98_u8, + 107_u8, 208_u8, 14_u8, 236_u8, 60_u8, + ]; + + assert_eq!( + super::bytes_to_key( + Cipher::aes_256_cbc(), + MessageDigest::sha1(), + &data, + Some(&salt), + 1, + ) + .unwrap(), + super::KeyIvPair { + key: expected_key, + iv: Some(expected_iv), + } + ); + } + + #[test] + #[cfg(any(ossl110, boringssl))] + fn scrypt() { + let pass = "pleaseletmein"; + let salt = "SodiumChloride"; + let expected = + "7023bdcb3afd7348461c06cd81fd38ebfda8fbba904f8e3ea9b543f6545da1f2d5432955613\ + f0fcf62d49705242a9af9e61e85dc0d651e40dfcf017b45575887"; + + let mut actual = [0; 64]; + super::scrypt( + pass.as_bytes(), + salt.as_bytes(), + 16384, + 8, + 1, + 0, + &mut actual, + ) + .unwrap(); + assert_eq!(hex::encode(&actual[..]), expected); + } +} diff --git a/vendor/openssl/src/pkcs7.rs b/vendor/openssl/src/pkcs7.rs new file mode 100644 index 0000000..65a6e73 --- /dev/null +++ b/vendor/openssl/src/pkcs7.rs @@ -0,0 +1,573 @@ +use bitflags::bitflags; +use foreign_types::{ForeignType, ForeignTypeRef}; +use libc::c_int; +use std::mem; +use std::ptr; + +use crate::asn1::Asn1ObjectRef; +use crate::bio::{MemBio, MemBioSlice}; +use crate::error::ErrorStack; +use crate::nid::Nid; +use crate::pkey::{HasPrivate, PKeyRef}; +use crate::stack::{Stack, StackRef, Stackable}; +use crate::symm::Cipher; +use crate::util::ForeignTypeRefExt; +use crate::x509::store::X509StoreRef; +use crate::x509::{X509Ref, X509}; +use crate::{cvt, cvt_p}; +use openssl_macros::corresponds; + +foreign_type_and_impl_send_sync! { + type CType = ffi::PKCS7_SIGNER_INFO; + fn drop = ffi::PKCS7_SIGNER_INFO_free; + + pub struct Pkcs7SignerInfo; + pub struct Pkcs7SignerInfoRef; +} + +impl Stackable for Pkcs7SignerInfo { + type StackType = ffi::stack_st_PKCS7_SIGNER_INFO; +} + +foreign_type_and_impl_send_sync! { + type CType = ffi::PKCS7; + fn drop = ffi::PKCS7_free; + + /// A PKCS#7 structure. + /// + /// Contains signed and/or encrypted data. + pub struct Pkcs7; + + /// Reference to `Pkcs7` + pub struct Pkcs7Ref; +} + +foreign_type_and_impl_send_sync! { + type CType = ffi::PKCS7_SIGNED; + fn drop = ffi::PKCS7_SIGNED_free; + + /// A PKCS#7 signed data structure. + /// + /// Contains signed data. + pub struct Pkcs7Signed; + + /// Reference to `Pkcs7Signed` + pub struct Pkcs7SignedRef; +} + +bitflags! { + #[derive(Copy, Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)] + #[repr(transparent)] + pub struct Pkcs7Flags: c_int { + const TEXT = ffi::PKCS7_TEXT; + const NOCERTS = ffi::PKCS7_NOCERTS; + const NOSIGS = ffi::PKCS7_NOSIGS; + const NOCHAIN = ffi::PKCS7_NOCHAIN; + const NOINTERN = ffi::PKCS7_NOINTERN; + const NOVERIFY = ffi::PKCS7_NOVERIFY; + const DETACHED = ffi::PKCS7_DETACHED; + const BINARY = ffi::PKCS7_BINARY; + const NOATTR = ffi::PKCS7_NOATTR; + const NOSMIMECAP = ffi::PKCS7_NOSMIMECAP; + const NOOLDMIMETYPE = ffi::PKCS7_NOOLDMIMETYPE; + const CRLFEOL = ffi::PKCS7_CRLFEOL; + const STREAM = ffi::PKCS7_STREAM; + const NOCRL = ffi::PKCS7_NOCRL; + const PARTIAL = ffi::PKCS7_PARTIAL; + const REUSE_DIGEST = ffi::PKCS7_REUSE_DIGEST; + #[cfg(not(any(ossl101, ossl102, libressl)))] + const NO_DUAL_CONTENT = ffi::PKCS7_NO_DUAL_CONTENT; + } +} + +impl Pkcs7 { + from_pem! { + /// Deserializes a PEM-encoded PKCS#7 signature + /// + /// The input should have a header of `-----BEGIN PKCS7-----`. + #[corresponds(PEM_read_bio_PKCS7)] + from_pem, + Pkcs7, + ffi::PEM_read_bio_PKCS7 + } + + from_der! { + /// Deserializes a DER-encoded PKCS#7 signature + #[corresponds(d2i_PKCS7)] + from_der, + Pkcs7, + ffi::d2i_PKCS7 + } + + /// Parses a message in S/MIME format. + /// + /// Returns the loaded signature, along with the cleartext message (if + /// available). + #[corresponds(SMIME_read_PKCS7)] + pub fn from_smime(input: &[u8]) -> Result<(Pkcs7, Option>), ErrorStack> { + ffi::init(); + + let input_bio = MemBioSlice::new(input)?; + let mut bcont_bio = ptr::null_mut(); + unsafe { + let pkcs7 = + cvt_p(ffi::SMIME_read_PKCS7(input_bio.as_ptr(), &mut bcont_bio)).map(Pkcs7)?; + let out = if !bcont_bio.is_null() { + let bcont_bio = MemBio::from_ptr(bcont_bio); + Some(bcont_bio.get_buf().to_vec()) + } else { + None + }; + Ok((pkcs7, out)) + } + } + + /// Creates and returns a PKCS#7 `envelopedData` structure. + /// + /// `certs` is a list of recipient certificates. `input` is the content to be + /// encrypted. `cipher` is the symmetric cipher to use. `flags` is an optional + /// set of flags. + #[corresponds(PKCS7_encrypt)] + pub fn encrypt( + certs: &StackRef, + input: &[u8], + cipher: Cipher, + flags: Pkcs7Flags, + ) -> Result { + let input_bio = MemBioSlice::new(input)?; + + unsafe { + cvt_p(ffi::PKCS7_encrypt( + certs.as_ptr(), + input_bio.as_ptr(), + cipher.as_ptr(), + flags.bits(), + )) + .map(Pkcs7) + } + } + + /// Creates and returns a PKCS#7 `signedData` structure. + /// + /// `signcert` is the certificate to sign with, `pkey` is the corresponding + /// private key. `certs` is an optional additional set of certificates to + /// include in the PKCS#7 structure (for example any intermediate CAs in the + /// chain). + #[corresponds(PKCS7_sign)] + pub fn sign( + signcert: &X509Ref, + pkey: &PKeyRef, + certs: &StackRef, + input: &[u8], + flags: Pkcs7Flags, + ) -> Result + where + PT: HasPrivate, + { + let input_bio = MemBioSlice::new(input)?; + unsafe { + cvt_p(ffi::PKCS7_sign( + signcert.as_ptr(), + pkey.as_ptr(), + certs.as_ptr(), + input_bio.as_ptr(), + flags.bits(), + )) + .map(Pkcs7) + } + } +} + +impl Pkcs7Ref { + /// Converts PKCS#7 structure to S/MIME format + #[corresponds(SMIME_write_PKCS7)] + pub fn to_smime(&self, input: &[u8], flags: Pkcs7Flags) -> Result, ErrorStack> { + let input_bio = MemBioSlice::new(input)?; + let output = MemBio::new()?; + unsafe { + cvt(ffi::SMIME_write_PKCS7( + output.as_ptr(), + self.as_ptr(), + input_bio.as_ptr(), + flags.bits(), + )) + .map(|_| output.get_buf().to_owned()) + } + } + + to_pem! { + /// Serializes the data into a PEM-encoded PKCS#7 structure. + /// + /// The output will have a header of `-----BEGIN PKCS7-----`. + #[corresponds(PEM_write_bio_PKCS7)] + to_pem, + ffi::PEM_write_bio_PKCS7 + } + + to_der! { + /// Serializes the data into a DER-encoded PKCS#7 structure. + #[corresponds(i2d_PKCS7)] + to_der, + ffi::i2d_PKCS7 + } + + /// Decrypts data using the provided private key. + /// + /// `pkey` is the recipient's private key, and `cert` is the recipient's + /// certificate. + /// + /// Returns the decrypted message. + #[corresponds(PKCS7_decrypt)] + pub fn decrypt( + &self, + pkey: &PKeyRef, + cert: &X509Ref, + flags: Pkcs7Flags, + ) -> Result, ErrorStack> + where + PT: HasPrivate, + { + let output = MemBio::new()?; + + unsafe { + cvt(ffi::PKCS7_decrypt( + self.as_ptr(), + pkey.as_ptr(), + cert.as_ptr(), + output.as_ptr(), + flags.bits(), + )) + .map(|_| output.get_buf().to_owned()) + } + } + + /// Verifies the PKCS#7 `signedData` structure contained by `&self`. + /// + /// `certs` is a set of certificates in which to search for the signer's + /// certificate. `store` is a trusted certificate store (used for chain + /// verification). `indata` is the signed data if the content is not present + /// in `&self`. The content is written to `out` if it is not `None`. + #[corresponds(PKCS7_verify)] + pub fn verify( + &self, + certs: &StackRef, + store: &X509StoreRef, + indata: Option<&[u8]>, + out: Option<&mut Vec>, + flags: Pkcs7Flags, + ) -> Result<(), ErrorStack> { + let out_bio = MemBio::new()?; + + let indata_bio = match indata { + Some(data) => Some(MemBioSlice::new(data)?), + None => None, + }; + let indata_bio_ptr = indata_bio.as_ref().map_or(ptr::null_mut(), |p| p.as_ptr()); + + unsafe { + cvt(ffi::PKCS7_verify( + self.as_ptr(), + certs.as_ptr(), + store.as_ptr(), + indata_bio_ptr, + out_bio.as_ptr(), + flags.bits(), + )) + .map(|_| ())? + } + + if let Some(data) = out { + data.clear(); + data.extend_from_slice(out_bio.get_buf()); + } + + Ok(()) + } + + /// Retrieve the signer's certificates from the PKCS#7 structure without verifying them. + #[corresponds(PKCS7_get0_signers)] + pub fn signers( + &self, + certs: &StackRef, + flags: Pkcs7Flags, + ) -> Result, ErrorStack> { + unsafe { + let ptr = cvt_p(ffi::PKCS7_get0_signers( + self.as_ptr(), + certs.as_ptr(), + flags.bits(), + ))?; + + // The returned stack is owned by the caller, but the certs inside are not! Our stack interface can't deal + // with that, so instead we just manually bump the refcount of the certs so that the whole stack is properly + // owned. + let stack = Stack::::from_ptr(ptr); + for cert in &stack { + mem::forget(cert.to_owned()); + } + + Ok(stack) + } + } + + /// Return the type of a PKCS#7 structure as an Asn1Object + pub fn type_(&self) -> Option<&Asn1ObjectRef> { + unsafe { + let ptr = (*self.as_ptr()).type_; + Asn1ObjectRef::from_const_ptr_opt(ptr) + } + } + + /// Get the signed data of a PKCS#7 structure of type PKCS7_SIGNED + pub fn signed(&self) -> Option<&Pkcs7SignedRef> { + unsafe { + if self.type_().map(|x| x.nid()) != Some(Nid::PKCS7_SIGNED) { + return None; + } + let signed_data = (*self.as_ptr()).d.sign; + Pkcs7SignedRef::from_const_ptr_opt(signed_data) + } + } +} + +impl Pkcs7SignedRef { + /// Get the stack of certificates from the PKCS7_SIGNED object + pub fn certificates(&self) -> Option<&StackRef> { + unsafe { + self.as_ptr() + .as_ref() + .and_then(|x| x.cert.as_mut()) + .and_then(|x| StackRef::::from_const_ptr_opt(x)) + } + } +} + +#[cfg(test)] +mod tests { + use crate::hash::MessageDigest; + use crate::nid::Nid; + use crate::pkcs7::{Pkcs7, Pkcs7Flags}; + use crate::pkey::PKey; + use crate::stack::Stack; + use crate::symm::Cipher; + use crate::x509::store::X509StoreBuilder; + use crate::x509::X509; + + #[test] + fn encrypt_decrypt_test() { + let cert = include_bytes!("../test/certs.pem"); + let cert = X509::from_pem(cert).unwrap(); + let mut certs = Stack::new().unwrap(); + certs.push(cert.clone()).unwrap(); + let message: String = String::from("foo"); + let cipher = Cipher::des_ede3_cbc(); + let flags = Pkcs7Flags::STREAM; + let pkey = include_bytes!("../test/key.pem"); + let pkey = PKey::private_key_from_pem(pkey).unwrap(); + + let pkcs7 = + Pkcs7::encrypt(&certs, message.as_bytes(), cipher, flags).expect("should succeed"); + assert_eq!( + pkcs7.type_().expect("PKCS7 should have a type").nid(), + Nid::PKCS7_ENVELOPED + ); + + let encrypted = pkcs7 + .to_smime(message.as_bytes(), flags) + .expect("should succeed"); + + let (pkcs7_decoded, _) = Pkcs7::from_smime(encrypted.as_slice()).expect("should succeed"); + + let decoded = pkcs7_decoded + .decrypt(&pkey, &cert, Pkcs7Flags::empty()) + .expect("should succeed"); + + assert_eq!(decoded, message.into_bytes()); + } + + #[test] + fn sign_verify_test_detached() { + let cert = include_bytes!("../test/cert.pem"); + let cert = X509::from_pem(cert).unwrap(); + let certs = Stack::new().unwrap(); + let message = "foo"; + let flags = Pkcs7Flags::STREAM | Pkcs7Flags::DETACHED; + let pkey = include_bytes!("../test/key.pem"); + let pkey = PKey::private_key_from_pem(pkey).unwrap(); + let mut store_builder = X509StoreBuilder::new().expect("should succeed"); + + let root_ca = include_bytes!("../test/root-ca.pem"); + let root_ca = X509::from_pem(root_ca).unwrap(); + store_builder.add_cert(root_ca).expect("should succeed"); + + let store = store_builder.build(); + + let pkcs7 = + Pkcs7::sign(&cert, &pkey, &certs, message.as_bytes(), flags).expect("should succeed"); + assert_eq!( + pkcs7.type_().expect("PKCS7 should have a type").nid(), + Nid::PKCS7_SIGNED + ); + + let signed = pkcs7 + .to_smime(message.as_bytes(), flags) + .expect("should succeed"); + println!("{:?}", String::from_utf8(signed.clone()).unwrap()); + let (pkcs7_decoded, content) = + Pkcs7::from_smime(signed.as_slice()).expect("should succeed"); + + let mut output = Vec::new(); + pkcs7_decoded + .verify( + &certs, + &store, + Some(message.as_bytes()), + Some(&mut output), + flags, + ) + .expect("should succeed"); + + assert_eq!(output, message.as_bytes()); + assert_eq!(content.expect("should be non-empty"), message.as_bytes()); + } + + /// https://marc.info/?l=openbsd-cvs&m=166602943014106&w=2 + #[test] + #[cfg_attr(all(libressl360, not(libressl361)), ignore)] + fn sign_verify_test_normal() { + let cert = include_bytes!("../test/cert.pem"); + let cert = X509::from_pem(cert).unwrap(); + let certs = Stack::new().unwrap(); + let message = "foo"; + let flags = Pkcs7Flags::STREAM; + let pkey = include_bytes!("../test/key.pem"); + let pkey = PKey::private_key_from_pem(pkey).unwrap(); + let mut store_builder = X509StoreBuilder::new().expect("should succeed"); + + let root_ca = include_bytes!("../test/root-ca.pem"); + let root_ca = X509::from_pem(root_ca).unwrap(); + store_builder.add_cert(root_ca).expect("should succeed"); + + let store = store_builder.build(); + + let pkcs7 = + Pkcs7::sign(&cert, &pkey, &certs, message.as_bytes(), flags).expect("should succeed"); + assert_eq!( + pkcs7.type_().expect("PKCS7 should have a type").nid(), + Nid::PKCS7_SIGNED + ); + + let signed = pkcs7 + .to_smime(message.as_bytes(), flags) + .expect("should succeed"); + + let (pkcs7_decoded, content) = + Pkcs7::from_smime(signed.as_slice()).expect("should succeed"); + + let mut output = Vec::new(); + pkcs7_decoded + .verify(&certs, &store, None, Some(&mut output), flags) + .expect("should succeed"); + + assert_eq!(output, message.as_bytes()); + assert!(content.is_none()); + } + + /// https://marc.info/?l=openbsd-cvs&m=166602943014106&w=2 + #[test] + #[cfg_attr(all(libressl360, not(libressl361)), ignore)] + fn signers() { + let cert = include_bytes!("../test/cert.pem"); + let cert = X509::from_pem(cert).unwrap(); + let cert_digest = cert.digest(MessageDigest::sha256()).unwrap(); + let certs = Stack::new().unwrap(); + let message = "foo"; + let flags = Pkcs7Flags::STREAM; + let pkey = include_bytes!("../test/key.pem"); + let pkey = PKey::private_key_from_pem(pkey).unwrap(); + let mut store_builder = X509StoreBuilder::new().expect("should succeed"); + + let root_ca = include_bytes!("../test/root-ca.pem"); + let root_ca = X509::from_pem(root_ca).unwrap(); + store_builder.add_cert(root_ca).expect("should succeed"); + + let pkcs7 = + Pkcs7::sign(&cert, &pkey, &certs, message.as_bytes(), flags).expect("should succeed"); + assert_eq!( + pkcs7.type_().expect("PKCS7 should have a type").nid(), + Nid::PKCS7_SIGNED + ); + + let signed = pkcs7 + .to_smime(message.as_bytes(), flags) + .expect("should succeed"); + + let (pkcs7_decoded, _) = Pkcs7::from_smime(signed.as_slice()).expect("should succeed"); + + let empty_certs = Stack::new().unwrap(); + let signer_certs = pkcs7_decoded + .signers(&empty_certs, flags) + .expect("should succeed"); + assert_eq!(empty_certs.len(), 0); + assert_eq!(signer_certs.len(), 1); + let signer_digest = signer_certs[0].digest(MessageDigest::sha256()).unwrap(); + assert_eq!(*cert_digest, *signer_digest); + } + + #[test] + fn invalid_from_smime() { + let input = String::from("Invalid SMIME Message"); + let result = Pkcs7::from_smime(input.as_bytes()); + + assert!(result.is_err()); + } + + #[test] + fn signed_data_certificates() { + let cert = include_bytes!("../test/cert.pem"); + let cert = X509::from_pem(cert).unwrap(); + let mut extra_certs = Stack::::new().unwrap(); + for cert in + X509::stack_from_pem(include_bytes!("../test/certs.pem")).expect("should succeed") + { + extra_certs.push(cert).expect("should succeed"); + } + + let message = "foo"; + let flags = Pkcs7Flags::STREAM; + let pkey = include_bytes!("../test/key.pem"); + let pkey = PKey::private_key_from_pem(pkey).unwrap(); + + let pkcs7 = Pkcs7::sign(&cert, &pkey, &extra_certs, message.as_bytes(), flags) + .expect("should succeed"); + assert_eq!( + pkcs7.type_().expect("PKCS7 should have a type").nid(), + Nid::PKCS7_SIGNED + ); + let signed_data_certs = pkcs7.signed().and_then(|x| x.certificates()); + assert_eq!(signed_data_certs.expect("should succeed").len(), 3); + } + + #[test] + fn signed_data_certificates_no_signed_data() { + let cert = include_bytes!("../test/certs.pem"); + let cert = X509::from_pem(cert).unwrap(); + let mut certs = Stack::new().unwrap(); + certs.push(cert).unwrap(); + let message: String = String::from("foo"); + let cipher = Cipher::des_ede3_cbc(); + let flags = Pkcs7Flags::STREAM; + + // Use `Pkcs7::encrypt` since it populates the PKCS7_ENVELOPE struct rather than + // PKCS7_SIGNED + let pkcs7 = + Pkcs7::encrypt(&certs, message.as_bytes(), cipher, flags).expect("should succeed"); + assert_eq!( + pkcs7.type_().expect("PKCS7 should have a type").nid(), + Nid::PKCS7_ENVELOPED + ); + + let signed_data_certs = pkcs7.signed().and_then(|x| x.certificates()); + assert!(signed_data_certs.is_none()) + } +} diff --git a/vendor/openssl/src/pkey.rs b/vendor/openssl/src/pkey.rs new file mode 100644 index 0000000..f2cedd2 --- /dev/null +++ b/vendor/openssl/src/pkey.rs @@ -0,0 +1,1202 @@ +//! Public/private key processing. +//! +//! Asymmetric public key algorithms solve the problem of establishing and sharing +//! secret keys to securely send and receive messages. +//! This system uses a pair of keys: a public key, which can be freely +//! distributed, and a private key, which is kept to oneself. An entity may +//! encrypt information using a user's public key. The encrypted information can +//! only be deciphered using that user's private key. +//! +//! This module offers support for five popular algorithms: +//! +//! * RSA +//! +//! * DSA +//! +//! * Diffie-Hellman +//! +//! * Elliptic Curves +//! +//! * HMAC +//! +//! These algorithms rely on hard mathematical problems - namely integer factorization, +//! discrete logarithms, and elliptic curve relationships - that currently do not +//! yield efficient solutions. This property ensures the security of these +//! cryptographic algorithms. +//! +//! # Example +//! +//! Generate a 2048-bit RSA public/private key pair and print the public key. +//! +//! ```rust +//! use openssl::rsa::Rsa; +//! use openssl::pkey::PKey; +//! use std::str; +//! +//! let rsa = Rsa::generate(2048).unwrap(); +//! let pkey = PKey::from_rsa(rsa).unwrap(); +//! +//! let pub_key: Vec = pkey.public_key_to_pem().unwrap(); +//! println!("{:?}", str::from_utf8(pub_key.as_slice()).unwrap()); +//! ``` +#![allow(clippy::missing_safety_doc)] +use crate::bio::{MemBio, MemBioSlice}; +#[cfg(ossl110)] +use crate::cipher::CipherRef; +use crate::dh::Dh; +use crate::dsa::Dsa; +use crate::ec::EcKey; +use crate::error::ErrorStack; +#[cfg(any(ossl110, boringssl, libressl370))] +use crate::pkey_ctx::PkeyCtx; +use crate::rsa::Rsa; +use crate::symm::Cipher; +use crate::util::{invoke_passwd_cb, CallbackState}; +use crate::{cvt, cvt_p}; +use cfg_if::cfg_if; +use foreign_types::{ForeignType, ForeignTypeRef}; +use libc::{c_int, c_long}; +use openssl_macros::corresponds; +use std::convert::{TryFrom, TryInto}; +use std::ffi::CString; +use std::fmt; +#[cfg(all(not(boringssl), ossl110))] +use std::mem; +use std::ptr; + +/// A tag type indicating that a key only has parameters. +pub enum Params {} + +/// A tag type indicating that a key only has public components. +pub enum Public {} + +/// A tag type indicating that a key has private components. +pub enum Private {} + +/// An identifier of a kind of key. +#[derive(Debug, Copy, Clone, PartialEq, Eq)] +pub struct Id(c_int); + +impl Id { + pub const RSA: Id = Id(ffi::EVP_PKEY_RSA); + #[cfg(any(ossl111, libressl310, boringssl))] + pub const RSA_PSS: Id = Id(ffi::EVP_PKEY_RSA_PSS); + #[cfg(not(boringssl))] + pub const HMAC: Id = Id(ffi::EVP_PKEY_HMAC); + #[cfg(not(boringssl))] + pub const CMAC: Id = Id(ffi::EVP_PKEY_CMAC); + pub const DSA: Id = Id(ffi::EVP_PKEY_DSA); + pub const DH: Id = Id(ffi::EVP_PKEY_DH); + #[cfg(ossl110)] + pub const DHX: Id = Id(ffi::EVP_PKEY_DHX); + pub const EC: Id = Id(ffi::EVP_PKEY_EC); + #[cfg(ossl111)] + pub const SM2: Id = Id(ffi::EVP_PKEY_SM2); + + #[cfg(any(ossl110, boringssl, libressl360))] + pub const HKDF: Id = Id(ffi::EVP_PKEY_HKDF); + + #[cfg(any(ossl111, boringssl, libressl370))] + pub const ED25519: Id = Id(ffi::EVP_PKEY_ED25519); + #[cfg(ossl111)] + pub const ED448: Id = Id(ffi::EVP_PKEY_ED448); + #[cfg(any(ossl111, boringssl, libressl370))] + pub const X25519: Id = Id(ffi::EVP_PKEY_X25519); + #[cfg(ossl111)] + pub const X448: Id = Id(ffi::EVP_PKEY_X448); + #[cfg(ossl111)] + pub const POLY1305: Id = Id(ffi::EVP_PKEY_POLY1305); + + /// Creates a `Id` from an integer representation. + pub fn from_raw(value: c_int) -> Id { + Id(value) + } + + /// Returns the integer representation of the `Id`. + #[allow(clippy::trivially_copy_pass_by_ref)] + pub fn as_raw(&self) -> c_int { + self.0 + } +} + +/// A trait indicating that a key has parameters. +pub unsafe trait HasParams {} + +unsafe impl HasParams for Params {} + +unsafe impl HasParams for T where T: HasPublic {} + +/// A trait indicating that a key has public components. +pub unsafe trait HasPublic {} + +unsafe impl HasPublic for Public {} + +unsafe impl HasPublic for T where T: HasPrivate {} + +/// A trait indicating that a key has private components. +pub unsafe trait HasPrivate {} + +unsafe impl HasPrivate for Private {} + +generic_foreign_type_and_impl_send_sync! { + type CType = ffi::EVP_PKEY; + fn drop = ffi::EVP_PKEY_free; + + /// A public or private key. + pub struct PKey; + /// Reference to `PKey`. + pub struct PKeyRef; +} + +impl ToOwned for PKeyRef { + type Owned = PKey; + + fn to_owned(&self) -> PKey { + unsafe { + EVP_PKEY_up_ref(self.as_ptr()); + PKey::from_ptr(self.as_ptr()) + } + } +} + +impl PKeyRef { + /// Returns a copy of the internal RSA key. + #[corresponds(EVP_PKEY_get1_RSA)] + pub fn rsa(&self) -> Result, ErrorStack> { + unsafe { + let rsa = cvt_p(ffi::EVP_PKEY_get1_RSA(self.as_ptr()))?; + Ok(Rsa::from_ptr(rsa)) + } + } + + /// Returns a copy of the internal DSA key. + #[corresponds(EVP_PKEY_get1_DSA)] + pub fn dsa(&self) -> Result, ErrorStack> { + unsafe { + let dsa = cvt_p(ffi::EVP_PKEY_get1_DSA(self.as_ptr()))?; + Ok(Dsa::from_ptr(dsa)) + } + } + + /// Returns a copy of the internal DH key. + #[corresponds(EVP_PKEY_get1_DH)] + pub fn dh(&self) -> Result, ErrorStack> { + unsafe { + let dh = cvt_p(ffi::EVP_PKEY_get1_DH(self.as_ptr()))?; + Ok(Dh::from_ptr(dh)) + } + } + + /// Returns a copy of the internal elliptic curve key. + #[corresponds(EVP_PKEY_get1_EC_KEY)] + pub fn ec_key(&self) -> Result, ErrorStack> { + unsafe { + let ec_key = cvt_p(ffi::EVP_PKEY_get1_EC_KEY(self.as_ptr()))?; + Ok(EcKey::from_ptr(ec_key)) + } + } + + /// Returns the `Id` that represents the type of this key. + #[corresponds(EVP_PKEY_id)] + pub fn id(&self) -> Id { + unsafe { Id::from_raw(ffi::EVP_PKEY_id(self.as_ptr())) } + } + + /// Returns the maximum size of a signature in bytes. + #[corresponds(EVP_PKEY_size)] + pub fn size(&self) -> usize { + unsafe { ffi::EVP_PKEY_size(self.as_ptr()) as usize } + } +} + +impl PKeyRef +where + T: HasPublic, +{ + to_pem! { + /// Serializes the public key into a PEM-encoded SubjectPublicKeyInfo structure. + /// + /// The output will have a header of `-----BEGIN PUBLIC KEY-----`. + #[corresponds(PEM_write_bio_PUBKEY)] + public_key_to_pem, + ffi::PEM_write_bio_PUBKEY + } + + to_der! { + /// Serializes the public key into a DER-encoded SubjectPublicKeyInfo structure. + #[corresponds(i2d_PUBKEY)] + public_key_to_der, + ffi::i2d_PUBKEY + } + + /// Returns the size of the key. + /// + /// This corresponds to the bit length of the modulus of an RSA key, and the bit length of the + /// group order for an elliptic curve key, for example. + #[corresponds(EVP_PKEY_bits)] + pub fn bits(&self) -> u32 { + unsafe { ffi::EVP_PKEY_bits(self.as_ptr()) as u32 } + } + + ///Returns the number of security bits. + /// + ///Bits of security is defined in NIST SP800-57. + #[corresponds(EVP_PKEY_security_bits)] + #[cfg(any(ossl110, libressl360))] + pub fn security_bits(&self) -> u32 { + unsafe { ffi::EVP_PKEY_security_bits(self.as_ptr()) as u32 } + } + + /// Compares the public component of this key with another. + #[corresponds(EVP_PKEY_cmp)] + pub fn public_eq(&self, other: &PKeyRef) -> bool + where + U: HasPublic, + { + let res = unsafe { ffi::EVP_PKEY_cmp(self.as_ptr(), other.as_ptr()) == 1 }; + // Clear the stack. OpenSSL will put an error on the stack when the + // keys are different types in some situations. + let _ = ErrorStack::get(); + res + } + + /// Raw byte representation of a public key. + /// + /// This function only works for algorithms that support raw public keys. + /// Currently this is: [`Id::X25519`], [`Id::ED25519`], [`Id::X448`] or [`Id::ED448`]. + #[corresponds(EVP_PKEY_get_raw_public_key)] + #[cfg(any(ossl111, boringssl, libressl370))] + pub fn raw_public_key(&self) -> Result, ErrorStack> { + unsafe { + let mut len = 0; + cvt(ffi::EVP_PKEY_get_raw_public_key( + self.as_ptr(), + ptr::null_mut(), + &mut len, + ))?; + let mut buf = vec![0u8; len]; + cvt(ffi::EVP_PKEY_get_raw_public_key( + self.as_ptr(), + buf.as_mut_ptr(), + &mut len, + ))?; + buf.truncate(len); + Ok(buf) + } + } +} + +impl PKeyRef +where + T: HasPrivate, +{ + private_key_to_pem! { + /// Serializes the private key to a PEM-encoded PKCS#8 PrivateKeyInfo structure. + /// + /// The output will have a header of `-----BEGIN PRIVATE KEY-----`. + #[corresponds(PEM_write_bio_PKCS8PrivateKey)] + private_key_to_pem_pkcs8, + /// Serializes the private key to a PEM-encoded PKCS#8 EncryptedPrivateKeyInfo structure. + /// + /// The output will have a header of `-----BEGIN ENCRYPTED PRIVATE KEY-----`. + #[corresponds(PEM_write_bio_PKCS8PrivateKey)] + private_key_to_pem_pkcs8_passphrase, + ffi::PEM_write_bio_PKCS8PrivateKey + } + + to_der! { + /// Serializes the private key to a DER-encoded key type specific format. + #[corresponds(i2d_PrivateKey)] + private_key_to_der, + ffi::i2d_PrivateKey + } + + /// Raw byte representation of a private key. + /// + /// This function only works for algorithms that support raw private keys. + /// Currently this is: [`Id::HMAC`], [`Id::X25519`], [`Id::ED25519`], [`Id::X448`] or [`Id::ED448`]. + #[corresponds(EVP_PKEY_get_raw_private_key)] + #[cfg(any(ossl111, boringssl, libressl370))] + pub fn raw_private_key(&self) -> Result, ErrorStack> { + unsafe { + let mut len = 0; + cvt(ffi::EVP_PKEY_get_raw_private_key( + self.as_ptr(), + ptr::null_mut(), + &mut len, + ))?; + let mut buf = vec![0u8; len]; + cvt(ffi::EVP_PKEY_get_raw_private_key( + self.as_ptr(), + buf.as_mut_ptr(), + &mut len, + ))?; + buf.truncate(len); + Ok(buf) + } + } + + /// Serializes a private key into an unencrypted DER-formatted PKCS#8 + #[corresponds(i2d_PKCS8PrivateKey_bio)] + pub fn private_key_to_pkcs8(&self) -> Result, ErrorStack> { + unsafe { + let bio = MemBio::new()?; + cvt(ffi::i2d_PKCS8PrivateKey_bio( + bio.as_ptr(), + self.as_ptr(), + ptr::null(), + ptr::null_mut(), + 0, + None, + ptr::null_mut(), + ))?; + + Ok(bio.get_buf().to_owned()) + } + } + + /// Serializes a private key into a DER-formatted PKCS#8, using the supplied password to + /// encrypt the key. + #[corresponds(i2d_PKCS8PrivateKey_bio)] + pub fn private_key_to_pkcs8_passphrase( + &self, + cipher: Cipher, + passphrase: &[u8], + ) -> Result, ErrorStack> { + unsafe { + let bio = MemBio::new()?; + cvt(ffi::i2d_PKCS8PrivateKey_bio( + bio.as_ptr(), + self.as_ptr(), + cipher.as_ptr(), + passphrase.as_ptr() as *const _ as *mut _, + passphrase.len().try_into().unwrap(), + None, + ptr::null_mut(), + ))?; + + Ok(bio.get_buf().to_owned()) + } + } +} + +impl fmt::Debug for PKey { + fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { + let alg = match self.id() { + Id::RSA => "RSA", + #[cfg(not(boringssl))] + Id::HMAC => "HMAC", + Id::DSA => "DSA", + Id::DH => "DH", + Id::EC => "EC", + #[cfg(ossl111)] + Id::ED25519 => "Ed25519", + #[cfg(ossl111)] + Id::ED448 => "Ed448", + _ => "unknown", + }; + fmt.debug_struct("PKey").field("algorithm", &alg).finish() + // TODO: Print details for each specific type of key + } +} + +impl Clone for PKey { + fn clone(&self) -> PKey { + PKeyRef::to_owned(self) + } +} + +impl PKey { + /// Creates a new `PKey` containing an RSA key. + #[corresponds(EVP_PKEY_set1_RSA)] + pub fn from_rsa(rsa: Rsa) -> Result, ErrorStack> { + // TODO: Next time we make backwards incompatible changes, this could + // become an `&RsaRef`. Same for all the other `from_*` methods. + unsafe { + let evp = cvt_p(ffi::EVP_PKEY_new())?; + let pkey = PKey::from_ptr(evp); + cvt(ffi::EVP_PKEY_set1_RSA(pkey.0, rsa.as_ptr()))?; + Ok(pkey) + } + } + + /// Creates a new `PKey` containing a DSA key. + #[corresponds(EVP_PKEY_set1_DSA)] + pub fn from_dsa(dsa: Dsa) -> Result, ErrorStack> { + unsafe { + let evp = cvt_p(ffi::EVP_PKEY_new())?; + let pkey = PKey::from_ptr(evp); + cvt(ffi::EVP_PKEY_set1_DSA(pkey.0, dsa.as_ptr()))?; + Ok(pkey) + } + } + + /// Creates a new `PKey` containing a Diffie-Hellman key. + #[corresponds(EVP_PKEY_set1_DH)] + #[cfg(not(boringssl))] + pub fn from_dh(dh: Dh) -> Result, ErrorStack> { + unsafe { + let evp = cvt_p(ffi::EVP_PKEY_new())?; + let pkey = PKey::from_ptr(evp); + cvt(ffi::EVP_PKEY_set1_DH(pkey.0, dh.as_ptr()))?; + Ok(pkey) + } + } + + /// Creates a new `PKey` containing a Diffie-Hellman key with type DHX. + #[cfg(all(not(boringssl), ossl110))] + pub fn from_dhx(dh: Dh) -> Result, ErrorStack> { + unsafe { + let evp = cvt_p(ffi::EVP_PKEY_new())?; + let pkey = PKey::from_ptr(evp); + cvt(ffi::EVP_PKEY_assign( + pkey.0, + ffi::EVP_PKEY_DHX, + dh.as_ptr().cast(), + ))?; + mem::forget(dh); + Ok(pkey) + } + } + + /// Creates a new `PKey` containing an elliptic curve key. + #[corresponds(EVP_PKEY_set1_EC_KEY)] + pub fn from_ec_key(ec_key: EcKey) -> Result, ErrorStack> { + unsafe { + let evp = cvt_p(ffi::EVP_PKEY_new())?; + let pkey = PKey::from_ptr(evp); + cvt(ffi::EVP_PKEY_set1_EC_KEY(pkey.0, ec_key.as_ptr()))?; + Ok(pkey) + } + } +} + +impl PKey { + /// Creates a new `PKey` containing an HMAC key. + /// + /// # Note + /// + /// To compute HMAC values, use the `sign` module. + #[corresponds(EVP_PKEY_new_mac_key)] + #[cfg(not(boringssl))] + pub fn hmac(key: &[u8]) -> Result, ErrorStack> { + unsafe { + assert!(key.len() <= c_int::MAX as usize); + let key = cvt_p(ffi::EVP_PKEY_new_mac_key( + ffi::EVP_PKEY_HMAC, + ptr::null_mut(), + key.as_ptr() as *const _, + key.len() as c_int, + ))?; + Ok(PKey::from_ptr(key)) + } + } + + /// Creates a new `PKey` containing a CMAC key. + /// + /// Requires OpenSSL 1.1.0 or newer. + /// + /// # Note + /// + /// To compute CMAC values, use the `sign` module. + #[cfg(all(not(boringssl), ossl110))] + #[allow(clippy::trivially_copy_pass_by_ref)] + pub fn cmac(cipher: &Cipher, key: &[u8]) -> Result, ErrorStack> { + let mut ctx = PkeyCtx::new_id(Id::CMAC)?; + ctx.keygen_init()?; + ctx.set_keygen_cipher(unsafe { CipherRef::from_ptr(cipher.as_ptr() as *mut _) })?; + ctx.set_keygen_mac_key(key)?; + ctx.keygen() + } + + #[cfg(any(ossl111, boringssl, libressl370))] + fn generate_eddsa(id: Id) -> Result, ErrorStack> { + let mut ctx = PkeyCtx::new_id(id)?; + ctx.keygen_init()?; + ctx.keygen() + } + + /// Generates a new private X25519 key. + /// + /// To import a private key from raw bytes see [`PKey::private_key_from_raw_bytes`]. + /// + /// # Examples + /// + /// ``` + /// # fn main() -> Result<(), Box> { + /// use openssl::pkey::{PKey, Id}; + /// use openssl::derive::Deriver; + /// + /// let public = // ... + /// # &PKey::generate_x25519()?.raw_public_key()?; + /// let public_key = PKey::public_key_from_raw_bytes(public, Id::X25519)?; + /// + /// let key = PKey::generate_x25519()?; + /// let mut deriver = Deriver::new(&key)?; + /// deriver.set_peer(&public_key)?; + /// + /// let secret = deriver.derive_to_vec()?; + /// assert_eq!(secret.len(), 32); + /// # Ok(()) } + /// ``` + #[cfg(any(ossl111, boringssl, libressl370))] + pub fn generate_x25519() -> Result, ErrorStack> { + PKey::generate_eddsa(Id::X25519) + } + + /// Generates a new private X448 key. + /// + /// To import a private key from raw bytes see [`PKey::private_key_from_raw_bytes`]. + /// + /// # Examples + /// + /// ``` + /// # fn main() -> Result<(), Box> { + /// use openssl::pkey::{PKey, Id}; + /// use openssl::derive::Deriver; + /// + /// let public = // ... + /// # &PKey::generate_x448()?.raw_public_key()?; + /// let public_key = PKey::public_key_from_raw_bytes(public, Id::X448)?; + /// + /// let key = PKey::generate_x448()?; + /// let mut deriver = Deriver::new(&key)?; + /// deriver.set_peer(&public_key)?; + /// + /// let secret = deriver.derive_to_vec()?; + /// assert_eq!(secret.len(), 56); + /// # Ok(()) } + /// ``` + #[cfg(ossl111)] + pub fn generate_x448() -> Result, ErrorStack> { + PKey::generate_eddsa(Id::X448) + } + + /// Generates a new private Ed25519 key. + /// + /// To import a private key from raw bytes see [`PKey::private_key_from_raw_bytes`]. + /// + /// # Examples + /// + /// ``` + /// # fn main() -> Result<(), Box> { + /// use openssl::pkey::{PKey, Id}; + /// use openssl::sign::Signer; + /// + /// let key = PKey::generate_ed25519()?; + /// let public_key = key.raw_public_key()?; + /// + /// let mut signer = Signer::new_without_digest(&key)?; + /// let digest = // ... + /// # &vec![0; 32]; + /// let signature = signer.sign_oneshot_to_vec(digest)?; + /// assert_eq!(signature.len(), 64); + /// # Ok(()) } + /// ``` + #[cfg(any(ossl111, boringssl, libressl370))] + pub fn generate_ed25519() -> Result, ErrorStack> { + PKey::generate_eddsa(Id::ED25519) + } + + /// Generates a new private Ed448 key. + /// + /// To import a private key from raw bytes see [`PKey::private_key_from_raw_bytes`]. + /// + /// # Examples + /// + /// ``` + /// # fn main() -> Result<(), Box> { + /// use openssl::pkey::{PKey, Id}; + /// use openssl::sign::Signer; + /// + /// let key = PKey::generate_ed448()?; + /// let public_key = key.raw_public_key()?; + /// + /// let mut signer = Signer::new_without_digest(&key)?; + /// let digest = // ... + /// # &vec![0; 32]; + /// let signature = signer.sign_oneshot_to_vec(digest)?; + /// assert_eq!(signature.len(), 114); + /// # Ok(()) } + /// ``` + #[cfg(ossl111)] + pub fn generate_ed448() -> Result, ErrorStack> { + PKey::generate_eddsa(Id::ED448) + } + + /// Generates a new EC key using the provided curve. + /// + /// Requires OpenSSL 3.0.0 or newer. + #[corresponds(EVP_EC_gen)] + #[cfg(ossl300)] + pub fn ec_gen(curve: &str) -> Result, ErrorStack> { + ffi::init(); + + let curve = CString::new(curve).unwrap(); + unsafe { + let ptr = cvt_p(ffi::EVP_EC_gen(curve.as_ptr()))?; + Ok(PKey::from_ptr(ptr)) + } + } + + private_key_from_pem! { + /// Deserializes a private key from a PEM-encoded key type specific format. + #[corresponds(PEM_read_bio_PrivateKey)] + private_key_from_pem, + + /// Deserializes a private key from a PEM-encoded encrypted key type specific format. + #[corresponds(PEM_read_bio_PrivateKey)] + private_key_from_pem_passphrase, + + /// Deserializes a private key from a PEM-encoded encrypted key type specific format. + /// + /// The callback should fill the password into the provided buffer and return its length. + #[corresponds(PEM_read_bio_PrivateKey)] + private_key_from_pem_callback, + PKey, + ffi::PEM_read_bio_PrivateKey + } + + from_der! { + /// Decodes a DER-encoded private key. + /// + /// This function will attempt to automatically detect the underlying key format, and + /// supports the unencrypted PKCS#8 PrivateKeyInfo structures as well as key type specific + /// formats. + #[corresponds(d2i_AutoPrivateKey)] + private_key_from_der, + PKey, + ffi::d2i_AutoPrivateKey + } + + /// Deserializes a DER-formatted PKCS#8 unencrypted private key. + /// + /// This method is mainly for interoperability reasons. Encrypted keyfiles should be preferred. + pub fn private_key_from_pkcs8(der: &[u8]) -> Result, ErrorStack> { + unsafe { + ffi::init(); + let len = der.len().min(c_long::MAX as usize) as c_long; + let p8inf = cvt_p(ffi::d2i_PKCS8_PRIV_KEY_INFO( + ptr::null_mut(), + &mut der.as_ptr(), + len, + ))?; + let res = cvt_p(ffi::EVP_PKCS82PKEY(p8inf)).map(|p| PKey::from_ptr(p)); + ffi::PKCS8_PRIV_KEY_INFO_free(p8inf); + res + } + } + + /// Deserializes a DER-formatted PKCS#8 private key, using a callback to retrieve the password + /// if the key is encrypted. + /// + /// The callback should copy the password into the provided buffer and return the number of + /// bytes written. + #[corresponds(d2i_PKCS8PrivateKey_bio)] + pub fn private_key_from_pkcs8_callback( + der: &[u8], + callback: F, + ) -> Result, ErrorStack> + where + F: FnOnce(&mut [u8]) -> Result, + { + unsafe { + ffi::init(); + let mut cb = CallbackState::new(callback); + let bio = MemBioSlice::new(der)?; + cvt_p(ffi::d2i_PKCS8PrivateKey_bio( + bio.as_ptr(), + ptr::null_mut(), + Some(invoke_passwd_cb::), + &mut cb as *mut _ as *mut _, + )) + .map(|p| PKey::from_ptr(p)) + } + } + + /// Deserializes a DER-formatted PKCS#8 private key, using the supplied password if the key is + /// encrypted. + /// + /// # Panics + /// + /// Panics if `passphrase` contains an embedded null. + #[corresponds(d2i_PKCS8PrivateKey_bio)] + pub fn private_key_from_pkcs8_passphrase( + der: &[u8], + passphrase: &[u8], + ) -> Result, ErrorStack> { + unsafe { + ffi::init(); + let bio = MemBioSlice::new(der)?; + let passphrase = CString::new(passphrase).unwrap(); + cvt_p(ffi::d2i_PKCS8PrivateKey_bio( + bio.as_ptr(), + ptr::null_mut(), + None, + passphrase.as_ptr() as *const _ as *mut _, + )) + .map(|p| PKey::from_ptr(p)) + } + } + + /// Creates a private key from its raw byte representation + /// + /// Algorithm types that support raw private keys are HMAC, X25519, ED25519, X448 or ED448 + #[corresponds(EVP_PKEY_new_raw_private_key)] + #[cfg(any(ossl111, boringssl, libressl370))] + pub fn private_key_from_raw_bytes( + bytes: &[u8], + key_type: Id, + ) -> Result, ErrorStack> { + unsafe { + ffi::init(); + cvt_p(ffi::EVP_PKEY_new_raw_private_key( + key_type.as_raw(), + ptr::null_mut(), + bytes.as_ptr(), + bytes.len(), + )) + .map(|p| PKey::from_ptr(p)) + } + } +} + +impl PKey { + private_key_from_pem! { + /// Decodes a PEM-encoded SubjectPublicKeyInfo structure. + /// + /// The input should have a header of `-----BEGIN PUBLIC KEY-----`. + #[corresponds(PEM_read_bio_PUBKEY)] + public_key_from_pem, + + /// Decodes a PEM-encoded SubjectPublicKeyInfo structure. + #[corresponds(PEM_read_bio_PUBKEY)] + public_key_from_pem_passphrase, + + /// Decodes a PEM-encoded SubjectPublicKeyInfo structure. + /// + /// The callback should fill the password into the provided buffer and return its length. + #[corresponds(PEM_read_bio_PrivateKey)] + public_key_from_pem_callback, + PKey, + ffi::PEM_read_bio_PUBKEY + } + + from_der! { + /// Decodes a DER-encoded SubjectPublicKeyInfo structure. + #[corresponds(d2i_PUBKEY)] + public_key_from_der, + PKey, + ffi::d2i_PUBKEY + } + + /// Creates a public key from its raw byte representation + /// + /// Algorithm types that support raw public keys are X25519, ED25519, X448 or ED448 + #[corresponds(EVP_PKEY_new_raw_public_key)] + #[cfg(any(ossl111, boringssl, libressl370))] + pub fn public_key_from_raw_bytes( + bytes: &[u8], + key_type: Id, + ) -> Result, ErrorStack> { + unsafe { + ffi::init(); + cvt_p(ffi::EVP_PKEY_new_raw_public_key( + key_type.as_raw(), + ptr::null_mut(), + bytes.as_ptr(), + bytes.len(), + )) + .map(|p| PKey::from_ptr(p)) + } + } +} + +cfg_if! { + if #[cfg(any(boringssl, ossl110, libressl270))] { + use ffi::EVP_PKEY_up_ref; + } else { + #[allow(bad_style)] + unsafe extern "C" fn EVP_PKEY_up_ref(pkey: *mut ffi::EVP_PKEY) { + ffi::CRYPTO_add_lock( + &mut (*pkey).references, + 1, + ffi::CRYPTO_LOCK_EVP_PKEY, + "pkey.rs\0".as_ptr() as *const _, + line!() as c_int, + ); + } + } +} + +impl TryFrom> for PKey { + type Error = ErrorStack; + + fn try_from(ec_key: EcKey) -> Result, ErrorStack> { + PKey::from_ec_key(ec_key) + } +} + +impl TryFrom> for EcKey { + type Error = ErrorStack; + + fn try_from(pkey: PKey) -> Result, ErrorStack> { + pkey.ec_key() + } +} + +impl TryFrom> for PKey { + type Error = ErrorStack; + + fn try_from(rsa: Rsa) -> Result, ErrorStack> { + PKey::from_rsa(rsa) + } +} + +impl TryFrom> for Rsa { + type Error = ErrorStack; + + fn try_from(pkey: PKey) -> Result, ErrorStack> { + pkey.rsa() + } +} + +impl TryFrom> for PKey { + type Error = ErrorStack; + + fn try_from(dsa: Dsa) -> Result, ErrorStack> { + PKey::from_dsa(dsa) + } +} + +impl TryFrom> for Dsa { + type Error = ErrorStack; + + fn try_from(pkey: PKey) -> Result, ErrorStack> { + pkey.dsa() + } +} + +#[cfg(not(boringssl))] +impl TryFrom> for PKey { + type Error = ErrorStack; + + fn try_from(dh: Dh) -> Result, ErrorStack> { + PKey::from_dh(dh) + } +} + +impl TryFrom> for Dh { + type Error = ErrorStack; + + fn try_from(pkey: PKey) -> Result, ErrorStack> { + pkey.dh() + } +} + +#[cfg(test)] +mod tests { + use std::convert::TryInto; + + #[cfg(not(boringssl))] + use crate::dh::Dh; + use crate::dsa::Dsa; + use crate::ec::EcKey; + use crate::error::Error; + use crate::nid::Nid; + use crate::rsa::Rsa; + use crate::symm::Cipher; + + use super::*; + + #[cfg(ossl111)] + use crate::rand::rand_bytes; + + #[test] + fn test_to_password() { + let rsa = Rsa::generate(2048).unwrap(); + let pkey = PKey::from_rsa(rsa).unwrap(); + let pem = pkey + .private_key_to_pem_pkcs8_passphrase(Cipher::aes_128_cbc(), b"foobar") + .unwrap(); + PKey::private_key_from_pem_passphrase(&pem, b"foobar").unwrap(); + assert!(PKey::private_key_from_pem_passphrase(&pem, b"fizzbuzz").is_err()); + } + + #[test] + fn test_unencrypted_pkcs8() { + let key = include_bytes!("../test/pkcs8-nocrypt.der"); + let pkey = PKey::private_key_from_pkcs8(key).unwrap(); + let serialized = pkey.private_key_to_pkcs8().unwrap(); + let pkey2 = PKey::private_key_from_pkcs8(&serialized).unwrap(); + + assert_eq!( + pkey2.private_key_to_der().unwrap(), + pkey.private_key_to_der().unwrap() + ); + } + + #[test] + fn test_encrypted_pkcs8_passphrase() { + let key = include_bytes!("../test/pkcs8.der"); + PKey::private_key_from_pkcs8_passphrase(key, b"mypass").unwrap(); + + let rsa = Rsa::generate(2048).unwrap(); + let pkey = PKey::from_rsa(rsa).unwrap(); + let der = pkey + .private_key_to_pkcs8_passphrase(Cipher::aes_128_cbc(), b"mypass") + .unwrap(); + let pkey2 = PKey::private_key_from_pkcs8_passphrase(&der, b"mypass").unwrap(); + assert_eq!( + pkey.private_key_to_der().unwrap(), + pkey2.private_key_to_der().unwrap() + ); + } + + #[test] + fn test_encrypted_pkcs8_callback() { + let mut password_queried = false; + let key = include_bytes!("../test/pkcs8.der"); + PKey::private_key_from_pkcs8_callback(key, |password| { + password_queried = true; + password[..6].copy_from_slice(b"mypass"); + Ok(6) + }) + .unwrap(); + assert!(password_queried); + } + + #[test] + fn test_private_key_from_pem() { + let key = include_bytes!("../test/key.pem"); + PKey::private_key_from_pem(key).unwrap(); + } + + #[test] + fn test_public_key_from_pem() { + let key = include_bytes!("../test/key.pem.pub"); + PKey::public_key_from_pem(key).unwrap(); + } + + #[test] + fn test_public_key_from_der() { + let key = include_bytes!("../test/key.der.pub"); + PKey::public_key_from_der(key).unwrap(); + } + + #[test] + fn test_private_key_from_der() { + let key = include_bytes!("../test/key.der"); + PKey::private_key_from_der(key).unwrap(); + } + + #[test] + fn test_pem() { + let key = include_bytes!("../test/key.pem"); + let key = PKey::private_key_from_pem(key).unwrap(); + + let priv_key = key.private_key_to_pem_pkcs8().unwrap(); + let pub_key = key.public_key_to_pem().unwrap(); + + // As a super-simple verification, just check that the buffers contain + // the `PRIVATE KEY` or `PUBLIC KEY` strings. + assert!(priv_key.windows(11).any(|s| s == b"PRIVATE KEY")); + assert!(pub_key.windows(10).any(|s| s == b"PUBLIC KEY")); + } + + #[test] + fn test_rsa_accessor() { + let rsa = Rsa::generate(2048).unwrap(); + let pkey = PKey::from_rsa(rsa).unwrap(); + pkey.rsa().unwrap(); + assert_eq!(pkey.id(), Id::RSA); + assert!(pkey.dsa().is_err()); + } + + #[test] + fn test_dsa_accessor() { + let dsa = Dsa::generate(2048).unwrap(); + let pkey = PKey::from_dsa(dsa).unwrap(); + pkey.dsa().unwrap(); + assert_eq!(pkey.id(), Id::DSA); + assert!(pkey.rsa().is_err()); + } + + #[test] + #[cfg(not(boringssl))] + fn test_dh_accessor() { + let dh = include_bytes!("../test/dhparams.pem"); + let dh = Dh::params_from_pem(dh).unwrap(); + let pkey = PKey::from_dh(dh).unwrap(); + pkey.dh().unwrap(); + assert_eq!(pkey.id(), Id::DH); + assert!(pkey.rsa().is_err()); + } + + #[test] + fn test_ec_key_accessor() { + let ec_key = EcKey::from_curve_name(Nid::X9_62_PRIME256V1).unwrap(); + let pkey = PKey::from_ec_key(ec_key).unwrap(); + pkey.ec_key().unwrap(); + assert_eq!(pkey.id(), Id::EC); + assert!(pkey.rsa().is_err()); + } + + #[test] + fn test_rsa_conversion() { + let rsa = Rsa::generate(2048).unwrap(); + let pkey: PKey = rsa.clone().try_into().unwrap(); + let rsa_: Rsa = pkey.try_into().unwrap(); + // Eq is missing + assert_eq!(rsa.p(), rsa_.p()); + assert_eq!(rsa.q(), rsa_.q()); + } + + #[test] + fn test_dsa_conversion() { + let dsa = Dsa::generate(2048).unwrap(); + let pkey: PKey = dsa.clone().try_into().unwrap(); + let dsa_: Dsa = pkey.try_into().unwrap(); + // Eq is missing + assert_eq!(dsa.priv_key(), dsa_.priv_key()); + } + + #[test] + fn test_ec_key_conversion() { + let group = crate::ec::EcGroup::from_curve_name(crate::nid::Nid::X9_62_PRIME256V1).unwrap(); + let ec_key = EcKey::generate(&group).unwrap(); + let pkey: PKey = ec_key.clone().try_into().unwrap(); + let ec_key_: EcKey = pkey.try_into().unwrap(); + // Eq is missing + assert_eq!(ec_key.private_key(), ec_key_.private_key()); + } + + #[test] + #[cfg(any(ossl110, libressl360))] + fn test_security_bits() { + let group = crate::ec::EcGroup::from_curve_name(crate::nid::Nid::SECP521R1).unwrap(); + let ec_key = EcKey::generate(&group).unwrap(); + let pkey: PKey = ec_key.try_into().unwrap(); + + assert_eq!(pkey.security_bits(), 256); + } + + #[test] + #[cfg(not(boringssl))] + fn test_dh_conversion() { + let dh_params = include_bytes!("../test/dhparams.pem"); + let dh_params = Dh::params_from_pem(dh_params).unwrap(); + let dh = dh_params.generate_key().unwrap(); + + // Clone is missing for Dh, save the parameters + let p = dh.prime_p().to_owned().unwrap(); + let q = dh.prime_q().map(|q| q.to_owned().unwrap()); + let g = dh.generator().to_owned().unwrap(); + + let pkey: PKey = dh.try_into().unwrap(); + let dh_: Dh = pkey.try_into().unwrap(); + + // Eq is missing + assert_eq!(&p, dh_.prime_p()); + assert_eq!(q, dh_.prime_q().map(|q| q.to_owned().unwrap())); + assert_eq!(&g, dh_.generator()); + } + + #[cfg(any(ossl111, boringssl, libressl370))] + fn test_raw_public_key(gen: fn() -> Result, ErrorStack>, key_type: Id) { + // Generate a new key + let key = gen().unwrap(); + + // Get the raw bytes, and create a new key from the raw bytes + let raw = key.raw_public_key().unwrap(); + let from_raw = PKey::public_key_from_raw_bytes(&raw, key_type).unwrap(); + + // Compare the der encoding of the original and raw / restored public key + assert_eq!( + key.public_key_to_der().unwrap(), + from_raw.public_key_to_der().unwrap() + ); + } + + #[cfg(any(ossl111, boringssl, libressl370))] + fn test_raw_private_key(gen: fn() -> Result, ErrorStack>, key_type: Id) { + // Generate a new key + let key = gen().unwrap(); + + // Get the raw bytes, and create a new key from the raw bytes + let raw = key.raw_private_key().unwrap(); + let from_raw = PKey::private_key_from_raw_bytes(&raw, key_type).unwrap(); + + // Compare the der encoding of the original and raw / restored public key + assert_eq!( + key.private_key_to_pkcs8().unwrap(), + from_raw.private_key_to_pkcs8().unwrap() + ); + } + + #[cfg(any(ossl111, boringssl, libressl370))] + #[test] + fn test_raw_public_key_bytes() { + test_raw_public_key(PKey::generate_x25519, Id::X25519); + test_raw_public_key(PKey::generate_ed25519, Id::ED25519); + #[cfg(all(not(boringssl), not(libressl370)))] + test_raw_public_key(PKey::generate_x448, Id::X448); + #[cfg(all(not(boringssl), not(libressl370)))] + test_raw_public_key(PKey::generate_ed448, Id::ED448); + } + + #[cfg(any(ossl111, boringssl, libressl370))] + #[test] + fn test_raw_private_key_bytes() { + test_raw_private_key(PKey::generate_x25519, Id::X25519); + test_raw_private_key(PKey::generate_ed25519, Id::ED25519); + #[cfg(all(not(boringssl), not(libressl370)))] + test_raw_private_key(PKey::generate_x448, Id::X448); + #[cfg(all(not(boringssl), not(libressl370)))] + test_raw_private_key(PKey::generate_ed448, Id::ED448); + } + + #[cfg(ossl111)] + #[test] + fn test_raw_hmac() { + let mut test_bytes = vec![0u8; 32]; + rand_bytes(&mut test_bytes).unwrap(); + + let hmac_key = PKey::hmac(&test_bytes).unwrap(); + assert!(hmac_key.raw_public_key().is_err()); + + let key_bytes = hmac_key.raw_private_key().unwrap(); + assert_eq!(key_bytes, test_bytes); + } + + #[cfg(ossl111)] + #[test] + fn test_raw_key_fail() { + // Getting a raw byte representation will not work with Nist curves + let group = crate::ec::EcGroup::from_curve_name(Nid::SECP256K1).unwrap(); + let ec_key = EcKey::generate(&group).unwrap(); + let pkey = PKey::from_ec_key(ec_key).unwrap(); + assert!(pkey.raw_private_key().is_err()); + assert!(pkey.raw_public_key().is_err()); + } + + #[cfg(ossl300)] + #[test] + fn test_ec_gen() { + let key = PKey::ec_gen("prime256v1").unwrap(); + assert!(key.ec_key().is_ok()); + } + + #[test] + fn test_public_eq() { + let rsa = Rsa::generate(2048).unwrap(); + let pkey1 = PKey::from_rsa(rsa).unwrap(); + + let group = crate::ec::EcGroup::from_curve_name(Nid::X9_62_PRIME256V1).unwrap(); + let ec_key = EcKey::generate(&group).unwrap(); + let pkey2 = PKey::from_ec_key(ec_key).unwrap(); + + assert!(!pkey1.public_eq(&pkey2)); + assert!(Error::get().is_none()); + } +} diff --git a/vendor/openssl/src/pkey_ctx.rs b/vendor/openssl/src/pkey_ctx.rs new file mode 100644 index 0000000..add7830 --- /dev/null +++ b/vendor/openssl/src/pkey_ctx.rs @@ -0,0 +1,1110 @@ +//! The asymmetric encryption context. +//! +//! # Examples +//! +//! Encrypt data with RSA +//! +//! ``` +//! use openssl::rsa::Rsa; +//! use openssl::pkey::PKey; +//! use openssl::pkey_ctx::PkeyCtx; +//! +//! let key = Rsa::generate(4096).unwrap(); +//! let key = PKey::from_rsa(key).unwrap(); +//! +//! let mut ctx = PkeyCtx::new(&key).unwrap(); +//! ctx.encrypt_init().unwrap(); +//! +//! let data = b"Some Crypto Text"; +//! let mut ciphertext = vec![]; +//! ctx.encrypt_to_vec(data, &mut ciphertext).unwrap(); +//! ``` + +#![cfg_attr( + not(boringssl), + doc = r#"\ +Generate a CMAC key + +``` +use openssl::pkey_ctx::PkeyCtx; +use openssl::pkey::Id; +use openssl::cipher::Cipher; + +let mut ctx = PkeyCtx::new_id(Id::CMAC).unwrap(); +ctx.keygen_init().unwrap(); +ctx.set_keygen_cipher(Cipher::aes_128_cbc()).unwrap(); +ctx.set_keygen_mac_key(b"0123456789abcdef").unwrap(); +let cmac_key = ctx.keygen().unwrap(); +```"# +)] + +//! +//! Sign and verify data with RSA +//! +//! ``` +//! use openssl::pkey_ctx::PkeyCtx; +//! use openssl::pkey::PKey; +//! use openssl::rsa::Rsa; +//! +//! // Generate a random RSA key. +//! let key = Rsa::generate(4096).unwrap(); +//! let key = PKey::from_rsa(key).unwrap(); +//! +//! let text = b"Some Crypto Text"; +//! +//! // Create the signature. +//! let mut ctx = PkeyCtx::new(&key).unwrap(); +//! ctx.sign_init().unwrap(); +//! let mut signature = vec![]; +//! ctx.sign_to_vec(text, &mut signature).unwrap(); +//! +//! // Verify the signature. +//! let mut ctx = PkeyCtx::new(&key).unwrap(); +//! ctx.verify_init().unwrap(); +//! let valid = ctx.verify(text, &signature).unwrap(); +//! assert!(valid); +//! ``` +#[cfg(not(boringssl))] +use crate::cipher::CipherRef; +use crate::error::ErrorStack; +use crate::md::MdRef; +use crate::pkey::{HasPrivate, HasPublic, Id, PKey, PKeyRef, Private}; +use crate::rsa::Padding; +use crate::sign::RsaPssSaltlen; +use crate::{cvt, cvt_p}; +use foreign_types::{ForeignType, ForeignTypeRef}; +#[cfg(not(boringssl))] +use libc::c_int; +#[cfg(ossl320)] +use libc::c_uint; +use openssl_macros::corresponds; +use std::convert::TryFrom; +#[cfg(ossl320)] +use std::ffi::CStr; +use std::ptr; + +/// HKDF modes of operation. +#[cfg(any(ossl111, libressl360))] +pub struct HkdfMode(c_int); + +#[cfg(any(ossl111, libressl360))] +impl HkdfMode { + /// This is the default mode. Calling [`derive`][PkeyCtxRef::derive] on a [`PkeyCtxRef`] set up + /// for HKDF will perform an extract followed by an expand operation in one go. The derived key + /// returned will be the result after the expand operation. The intermediate fixed-length + /// pseudorandom key K is not returned. + pub const EXTRACT_THEN_EXPAND: Self = HkdfMode(ffi::EVP_PKEY_HKDEF_MODE_EXTRACT_AND_EXPAND); + + /// In this mode calling [`derive`][PkeyCtxRef::derive] will just perform the extract operation. + /// The value returned will be the intermediate fixed-length pseudorandom key K. + /// + /// The digest, key and salt values must be set before a key is derived or an error occurs. + pub const EXTRACT_ONLY: Self = HkdfMode(ffi::EVP_PKEY_HKDEF_MODE_EXTRACT_ONLY); + + /// In this mode calling [`derive`][PkeyCtxRef::derive] will just perform the expand operation. + /// The input key should be set to the intermediate fixed-length pseudorandom key K returned + /// from a previous extract operation. + /// + /// The digest, key and info values must be set before a key is derived or an error occurs. + pub const EXPAND_ONLY: Self = HkdfMode(ffi::EVP_PKEY_HKDEF_MODE_EXPAND_ONLY); +} + +/// Nonce type for ECDSA and DSA. +#[cfg(ossl320)] +#[derive(Debug, PartialEq)] +pub struct NonceType(c_uint); + +#[cfg(ossl320)] +impl NonceType { + /// This is the default mode. It uses a random value for the nonce k as defined in FIPS 186-4 Section 6.3 + /// “Secret Number Generation”. + pub const RANDOM_K: Self = NonceType(0); + + /// Uses a deterministic value for the nonce k as defined in RFC #6979 (See Section 3.2 “Generation of k”). + pub const DETERMINISTIC_K: Self = NonceType(1); +} + +generic_foreign_type_and_impl_send_sync! { + type CType = ffi::EVP_PKEY_CTX; + fn drop = ffi::EVP_PKEY_CTX_free; + + /// A context object which can perform asymmetric cryptography operations. + pub struct PkeyCtx; + /// A reference to a [`PkeyCtx`]. + pub struct PkeyCtxRef; +} + +impl PkeyCtx { + /// Creates a new pkey context using the provided key. + #[corresponds(EVP_PKEY_CTX_new)] + #[inline] + pub fn new(pkey: &PKeyRef) -> Result { + unsafe { + let ptr = cvt_p(ffi::EVP_PKEY_CTX_new(pkey.as_ptr(), ptr::null_mut()))?; + Ok(PkeyCtx::from_ptr(ptr)) + } + } +} + +impl PkeyCtx<()> { + /// Creates a new pkey context for the specified algorithm ID. + #[corresponds(EVP_PKEY_new_id)] + #[inline] + pub fn new_id(id: Id) -> Result { + unsafe { + let ptr = cvt_p(ffi::EVP_PKEY_CTX_new_id(id.as_raw(), ptr::null_mut()))?; + Ok(PkeyCtx::from_ptr(ptr)) + } + } +} + +impl PkeyCtxRef +where + T: HasPublic, +{ + /// Prepares the context for encryption using the public key. + #[corresponds(EVP_PKEY_encrypt_init)] + #[inline] + pub fn encrypt_init(&mut self) -> Result<(), ErrorStack> { + unsafe { + cvt(ffi::EVP_PKEY_encrypt_init(self.as_ptr()))?; + } + + Ok(()) + } + + /// Prepares the context for signature verification using the public key. + #[corresponds(EVP_PKEY_verify_init)] + #[inline] + pub fn verify_init(&mut self) -> Result<(), ErrorStack> { + unsafe { + cvt(ffi::EVP_PKEY_verify_init(self.as_ptr()))?; + } + + Ok(()) + } + + /// Prepares the context for signature recovery using the public key. + #[corresponds(EVP_PKEY_verify_recover_init)] + #[inline] + pub fn verify_recover_init(&mut self) -> Result<(), ErrorStack> { + unsafe { + cvt(ffi::EVP_PKEY_verify_recover_init(self.as_ptr()))?; + } + + Ok(()) + } + + /// Encrypts data using the public key. + /// + /// If `to` is set to `None`, an upper bound on the number of bytes required for the output buffer will be + /// returned. + #[corresponds(EVP_PKEY_encrypt)] + #[inline] + pub fn encrypt(&mut self, from: &[u8], to: Option<&mut [u8]>) -> Result { + let mut written = to.as_ref().map_or(0, |b| b.len()); + unsafe { + cvt(ffi::EVP_PKEY_encrypt( + self.as_ptr(), + to.map_or(ptr::null_mut(), |b| b.as_mut_ptr()), + &mut written, + from.as_ptr(), + from.len(), + ))?; + } + + Ok(written) + } + + /// Like [`Self::encrypt`] but appends ciphertext to a [`Vec`]. + pub fn encrypt_to_vec(&mut self, from: &[u8], out: &mut Vec) -> Result { + let base = out.len(); + let len = self.encrypt(from, None)?; + out.resize(base + len, 0); + let len = self.encrypt(from, Some(&mut out[base..]))?; + out.truncate(base + len); + Ok(len) + } + + /// Verifies the signature of data using the public key. + /// + /// Returns `Ok(true)` if the signature is valid, `Ok(false)` if the signature is invalid, and `Err` if an error + /// occurred. + /// + /// # Note + /// + /// This verifies the signature of the *raw* data. It is more common to compute and verify the signature of the + /// cryptographic hash of an arbitrary amount of data. The [`MdCtx`](crate::md_ctx::MdCtx) type can be used to do + /// that. + #[corresponds(EVP_PKEY_verify)] + #[inline] + pub fn verify(&mut self, data: &[u8], sig: &[u8]) -> Result { + unsafe { + let r = ffi::EVP_PKEY_verify( + self.as_ptr(), + sig.as_ptr(), + sig.len(), + data.as_ptr(), + data.len(), + ); + // `EVP_PKEY_verify` is not terribly consistent about how it, + // reports errors. It does not clearly distinguish between 0 and + // -1, and may put errors on the stack in both cases. If there's + // errors on the stack, we return `Err()`, else we return + // `Ok(false)`. + if r <= 0 { + let errors = ErrorStack::get(); + if !errors.errors().is_empty() { + return Err(errors); + } + } + + Ok(r == 1) + } + } + + /// Recovers the original data signed by the private key. You almost + /// always want `verify` instead. + /// + /// Returns the number of bytes written to `to`, or the number of bytes + /// that would be written, if `to` is `None. + #[corresponds(EVP_PKEY_verify_recover)] + #[inline] + pub fn verify_recover( + &mut self, + sig: &[u8], + to: Option<&mut [u8]>, + ) -> Result { + let mut written = to.as_ref().map_or(0, |b| b.len()); + unsafe { + cvt(ffi::EVP_PKEY_verify_recover( + self.as_ptr(), + to.map_or(ptr::null_mut(), |b| b.as_mut_ptr()), + &mut written, + sig.as_ptr(), + sig.len(), + ))?; + } + + Ok(written) + } +} + +impl PkeyCtxRef +where + T: HasPrivate, +{ + /// Prepares the context for decryption using the private key. + #[corresponds(EVP_PKEY_decrypt_init)] + #[inline] + pub fn decrypt_init(&mut self) -> Result<(), ErrorStack> { + unsafe { + cvt(ffi::EVP_PKEY_decrypt_init(self.as_ptr()))?; + } + + Ok(()) + } + + /// Prepares the context for signing using the private key. + #[corresponds(EVP_PKEY_sign_init)] + #[inline] + pub fn sign_init(&mut self) -> Result<(), ErrorStack> { + unsafe { + cvt(ffi::EVP_PKEY_sign_init(self.as_ptr()))?; + } + + Ok(()) + } + + /// Sets the peer key used for secret derivation. + #[corresponds(EVP_PKEY_derive_set_peer)] + pub fn derive_set_peer(&mut self, key: &PKeyRef) -> Result<(), ErrorStack> + where + U: HasPublic, + { + unsafe { + cvt(ffi::EVP_PKEY_derive_set_peer(self.as_ptr(), key.as_ptr()))?; + } + + Ok(()) + } + + /// Decrypts data using the private key. + /// + /// If `to` is set to `None`, an upper bound on the number of bytes required for the output buffer will be + /// returned. + #[corresponds(EVP_PKEY_decrypt)] + #[inline] + pub fn decrypt(&mut self, from: &[u8], to: Option<&mut [u8]>) -> Result { + let mut written = to.as_ref().map_or(0, |b| b.len()); + unsafe { + cvt(ffi::EVP_PKEY_decrypt( + self.as_ptr(), + to.map_or(ptr::null_mut(), |b| b.as_mut_ptr()), + &mut written, + from.as_ptr(), + from.len(), + ))?; + } + + Ok(written) + } + + /// Like [`Self::decrypt`] but appends plaintext to a [`Vec`]. + pub fn decrypt_to_vec(&mut self, from: &[u8], out: &mut Vec) -> Result { + let base = out.len(); + let len = self.decrypt(from, None)?; + out.resize(base + len, 0); + let len = self.decrypt(from, Some(&mut out[base..]))?; + out.truncate(base + len); + Ok(len) + } + + /// Signs the contents of `data`. + /// + /// If `sig` is set to `None`, an upper bound on the number of bytes required for the output buffer will be + /// returned. + /// + /// # Note + /// + /// This computes the signature of the *raw* bytes of `data`. It is more common to sign the cryptographic hash of + /// an arbitrary amount of data. The [`MdCtx`](crate::md_ctx::MdCtx) type can be used to do that. + #[corresponds(EVP_PKEY_sign)] + #[inline] + pub fn sign(&mut self, data: &[u8], sig: Option<&mut [u8]>) -> Result { + let mut written = sig.as_ref().map_or(0, |b| b.len()); + unsafe { + cvt(ffi::EVP_PKEY_sign( + self.as_ptr(), + sig.map_or(ptr::null_mut(), |b| b.as_mut_ptr()), + &mut written, + data.as_ptr(), + data.len(), + ))?; + } + + Ok(written) + } + + /// Like [`Self::sign`] but appends the signature to a [`Vec`]. + pub fn sign_to_vec(&mut self, data: &[u8], sig: &mut Vec) -> Result { + let base = sig.len(); + let len = self.sign(data, None)?; + sig.resize(base + len, 0); + let len = self.sign(data, Some(&mut sig[base..]))?; + sig.truncate(base + len); + Ok(len) + } +} + +impl PkeyCtxRef { + /// Prepares the context for shared secret derivation. + #[corresponds(EVP_PKEY_derive_init)] + #[inline] + pub fn derive_init(&mut self) -> Result<(), ErrorStack> { + unsafe { + cvt(ffi::EVP_PKEY_derive_init(self.as_ptr()))?; + } + + Ok(()) + } + + /// Prepares the context for key generation. + #[corresponds(EVP_PKEY_keygen_init)] + #[inline] + pub fn keygen_init(&mut self) -> Result<(), ErrorStack> { + unsafe { + cvt(ffi::EVP_PKEY_keygen_init(self.as_ptr()))?; + } + + Ok(()) + } + + /// Sets which algorithm was used to compute the digest used in a + /// signature. With RSA signatures this causes the signature to be wrapped + /// in a `DigestInfo` structure. This is almost always what you want with + /// RSA signatures. + #[corresponds(EVP_PKEY_CTX_set_signature_md)] + #[inline] + pub fn set_signature_md(&self, md: &MdRef) -> Result<(), ErrorStack> { + unsafe { + cvt(ffi::EVP_PKEY_CTX_set_signature_md( + self.as_ptr(), + md.as_ptr(), + ))?; + } + Ok(()) + } + + /// Returns the RSA padding mode in use. + /// + /// This is only useful for RSA keys. + #[corresponds(EVP_PKEY_CTX_get_rsa_padding)] + #[inline] + pub fn rsa_padding(&self) -> Result { + let mut pad = 0; + unsafe { + cvt(ffi::EVP_PKEY_CTX_get_rsa_padding(self.as_ptr(), &mut pad))?; + } + + Ok(Padding::from_raw(pad)) + } + + /// Sets the RSA padding mode. + /// + /// This is only useful for RSA keys. + #[corresponds(EVP_PKEY_CTX_set_rsa_padding)] + #[inline] + pub fn set_rsa_padding(&mut self, padding: Padding) -> Result<(), ErrorStack> { + unsafe { + cvt(ffi::EVP_PKEY_CTX_set_rsa_padding( + self.as_ptr(), + padding.as_raw(), + ))?; + } + + Ok(()) + } + + /// Sets the RSA PSS salt length. + /// + /// This is only useful for RSA keys. + #[corresponds(EVP_PKEY_CTX_set_rsa_pss_saltlen)] + #[inline] + pub fn set_rsa_pss_saltlen(&mut self, len: RsaPssSaltlen) -> Result<(), ErrorStack> { + unsafe { + cvt(ffi::EVP_PKEY_CTX_set_rsa_pss_saltlen( + self.as_ptr(), + len.as_raw(), + )) + .map(|_| ()) + } + } + + /// Sets the RSA MGF1 algorithm. + /// + /// This is only useful for RSA keys. + #[corresponds(EVP_PKEY_CTX_set_rsa_mgf1_md)] + #[inline] + pub fn set_rsa_mgf1_md(&mut self, md: &MdRef) -> Result<(), ErrorStack> { + unsafe { + cvt(ffi::EVP_PKEY_CTX_set_rsa_mgf1_md( + self.as_ptr(), + md.as_ptr(), + ))?; + } + + Ok(()) + } + + /// Sets the RSA OAEP algorithm. + /// + /// This is only useful for RSA keys. + #[corresponds(EVP_PKEY_CTX_set_rsa_oaep_md)] + #[cfg(any(ossl102, libressl310, boringssl))] + #[inline] + pub fn set_rsa_oaep_md(&mut self, md: &MdRef) -> Result<(), ErrorStack> { + unsafe { + cvt(ffi::EVP_PKEY_CTX_set_rsa_oaep_md( + self.as_ptr(), + md.as_ptr() as *mut _, + ))?; + } + + Ok(()) + } + + /// Sets the RSA OAEP label. + /// + /// This is only useful for RSA keys. + #[corresponds(EVP_PKEY_CTX_set0_rsa_oaep_label)] + #[cfg(any(ossl102, libressl310, boringssl))] + pub fn set_rsa_oaep_label(&mut self, label: &[u8]) -> Result<(), ErrorStack> { + use crate::LenType; + let len = LenType::try_from(label.len()).unwrap(); + + unsafe { + let p = ffi::OPENSSL_malloc(label.len() as _); + ptr::copy_nonoverlapping(label.as_ptr(), p as *mut _, label.len()); + + let r = cvt(ffi::EVP_PKEY_CTX_set0_rsa_oaep_label( + self.as_ptr(), + p as *mut _, + len, + )); + if r.is_err() { + ffi::OPENSSL_free(p); + } + r?; + } + + Ok(()) + } + + /// Sets the cipher used during key generation. + #[cfg(not(boringssl))] + #[corresponds(EVP_PKEY_CTX_ctrl)] + #[inline] + pub fn set_keygen_cipher(&mut self, cipher: &CipherRef) -> Result<(), ErrorStack> { + unsafe { + cvt(ffi::EVP_PKEY_CTX_ctrl( + self.as_ptr(), + -1, + ffi::EVP_PKEY_OP_KEYGEN, + ffi::EVP_PKEY_CTRL_CIPHER, + 0, + cipher.as_ptr() as *mut _, + ))?; + } + + Ok(()) + } + + /// Sets the key MAC key used during key generation. + #[cfg(not(boringssl))] + #[corresponds(EVP_PKEY_CTX_ctrl)] + #[inline] + pub fn set_keygen_mac_key(&mut self, key: &[u8]) -> Result<(), ErrorStack> { + let len = c_int::try_from(key.len()).unwrap(); + + unsafe { + cvt(ffi::EVP_PKEY_CTX_ctrl( + self.as_ptr(), + -1, + ffi::EVP_PKEY_OP_KEYGEN, + ffi::EVP_PKEY_CTRL_SET_MAC_KEY, + len, + key.as_ptr() as *mut _, + ))?; + } + + Ok(()) + } + + /// Sets the digest used for HKDF derivation. + /// + /// Requires OpenSSL 1.1.0 or newer. + #[corresponds(EVP_PKEY_CTX_set_hkdf_md)] + #[cfg(any(ossl110, boringssl, libressl360))] + #[inline] + pub fn set_hkdf_md(&mut self, digest: &MdRef) -> Result<(), ErrorStack> { + unsafe { + cvt(ffi::EVP_PKEY_CTX_set_hkdf_md( + self.as_ptr(), + digest.as_ptr(), + ))?; + } + + Ok(()) + } + + /// Sets the HKDF mode of operation. + /// + /// Defaults to [`HkdfMode::EXTRACT_THEN_EXPAND`]. + /// + /// WARNING: Although this API calls it a "mode", HKDF-Extract and HKDF-Expand are distinct + /// operations with distinct inputs and distinct kinds of keys. Callers should not pass input + /// secrets for one operation into the other. + /// + /// Requires OpenSSL 1.1.1 or newer. + #[corresponds(EVP_PKEY_CTX_set_hkdf_mode)] + #[cfg(any(ossl111, libressl360))] + #[inline] + pub fn set_hkdf_mode(&mut self, mode: HkdfMode) -> Result<(), ErrorStack> { + unsafe { + cvt(ffi::EVP_PKEY_CTX_set_hkdf_mode(self.as_ptr(), mode.0))?; + } + + Ok(()) + } + + /// Sets the input material for HKDF generation as the "key". + /// + /// Which input is the key depends on the "mode" (see [`set_hkdf_mode`][Self::set_hkdf_mode]). + /// If [`HkdfMode::EXTRACT_THEN_EXPAND`] or [`HkdfMode::EXTRACT_ONLY`], this function specifies + /// the input keying material (IKM) for HKDF-Extract. If [`HkdfMode::EXPAND_ONLY`], it instead + /// specifies the pseudorandom key (PRK) for HKDF-Expand. + /// + /// Requires OpenSSL 1.1.0 or newer. + #[corresponds(EVP_PKEY_CTX_set1_hkdf_key)] + #[cfg(any(ossl110, boringssl, libressl360))] + #[inline] + pub fn set_hkdf_key(&mut self, key: &[u8]) -> Result<(), ErrorStack> { + #[cfg(not(boringssl))] + let len = c_int::try_from(key.len()).unwrap(); + #[cfg(boringssl)] + let len = key.len(); + + unsafe { + cvt(ffi::EVP_PKEY_CTX_set1_hkdf_key( + self.as_ptr(), + key.as_ptr(), + len, + ))?; + } + + Ok(()) + } + + /// Sets the salt value for HKDF generation. + /// + /// If performing HKDF-Expand only, this parameter is ignored. + /// + /// Requires OpenSSL 1.1.0 or newer. + #[corresponds(EVP_PKEY_CTX_set1_hkdf_salt)] + #[cfg(any(ossl110, boringssl, libressl360))] + #[inline] + pub fn set_hkdf_salt(&mut self, salt: &[u8]) -> Result<(), ErrorStack> { + #[cfg(not(boringssl))] + let len = c_int::try_from(salt.len()).unwrap(); + #[cfg(boringssl)] + let len = salt.len(); + + unsafe { + cvt(ffi::EVP_PKEY_CTX_set1_hkdf_salt( + self.as_ptr(), + salt.as_ptr(), + len, + ))?; + } + + Ok(()) + } + + /// Appends info bytes for HKDF generation. + /// + /// If performing HKDF-Extract only, this parameter is ignored. + /// + /// Requires OpenSSL 1.1.0 or newer. + #[corresponds(EVP_PKEY_CTX_add1_hkdf_info)] + #[cfg(any(ossl110, boringssl, libressl360))] + #[inline] + pub fn add_hkdf_info(&mut self, info: &[u8]) -> Result<(), ErrorStack> { + #[cfg(not(boringssl))] + let len = c_int::try_from(info.len()).unwrap(); + #[cfg(boringssl)] + let len = info.len(); + + unsafe { + cvt(ffi::EVP_PKEY_CTX_add1_hkdf_info( + self.as_ptr(), + info.as_ptr(), + len, + ))?; + } + + Ok(()) + } + + /// Derives a shared secret between two keys. + /// + /// If `buf` is set to `None`, an upper bound on the number of bytes required for the buffer will be returned. + #[corresponds(EVP_PKEY_derive)] + pub fn derive(&mut self, buf: Option<&mut [u8]>) -> Result { + let mut len = buf.as_ref().map_or(0, |b| b.len()); + unsafe { + cvt(ffi::EVP_PKEY_derive( + self.as_ptr(), + buf.map_or(ptr::null_mut(), |b| b.as_mut_ptr()), + &mut len, + ))?; + } + + Ok(len) + } + + /// Like [`Self::derive`] but appends the secret to a [`Vec`]. + pub fn derive_to_vec(&mut self, buf: &mut Vec) -> Result { + let base = buf.len(); + let len = self.derive(None)?; + buf.resize(base + len, 0); + let len = self.derive(Some(&mut buf[base..]))?; + buf.truncate(base + len); + Ok(len) + } + + /// Generates a new public/private keypair. + #[corresponds(EVP_PKEY_keygen)] + #[inline] + pub fn keygen(&mut self) -> Result, ErrorStack> { + unsafe { + let mut key = ptr::null_mut(); + cvt(ffi::EVP_PKEY_keygen(self.as_ptr(), &mut key))?; + Ok(PKey::from_ptr(key)) + } + } + + /// Sets the nonce type for a private key context. + /// + /// The nonce for DSA and ECDSA can be either random (the default) or deterministic (as defined by RFC 6979). + /// + /// This is only useful for DSA and ECDSA. + /// Requires OpenSSL 3.2.0 or newer. + #[cfg(ossl320)] + #[corresponds(EVP_PKEY_CTX_set_params)] + pub fn set_nonce_type(&mut self, nonce_type: NonceType) -> Result<(), ErrorStack> { + let nonce_field_name = CStr::from_bytes_with_nul(b"nonce-type\0").unwrap(); + let mut nonce_type = nonce_type.0; + unsafe { + let param_nonce = + ffi::OSSL_PARAM_construct_uint(nonce_field_name.as_ptr(), &mut nonce_type); + let param_end = ffi::OSSL_PARAM_construct_end(); + + let params = [param_nonce, param_end]; + cvt(ffi::EVP_PKEY_CTX_set_params(self.as_ptr(), params.as_ptr()))?; + } + Ok(()) + } + + /// Gets the nonce type for a private key context. + /// + /// The nonce for DSA and ECDSA can be either random (the default) or deterministic (as defined by RFC 6979). + /// + /// This is only useful for DSA and ECDSA. + /// Requires OpenSSL 3.2.0 or newer. + #[cfg(ossl320)] + #[corresponds(EVP_PKEY_CTX_get_params)] + pub fn nonce_type(&mut self) -> Result { + let nonce_field_name = CStr::from_bytes_with_nul(b"nonce-type\0").unwrap(); + let mut nonce_type: c_uint = 0; + unsafe { + let param_nonce = + ffi::OSSL_PARAM_construct_uint(nonce_field_name.as_ptr(), &mut nonce_type); + let param_end = ffi::OSSL_PARAM_construct_end(); + + let mut params = [param_nonce, param_end]; + cvt(ffi::EVP_PKEY_CTX_get_params( + self.as_ptr(), + params.as_mut_ptr(), + ))?; + } + Ok(NonceType(nonce_type)) + } +} + +#[cfg(test)] +mod test { + use super::*; + #[cfg(not(boringssl))] + use crate::cipher::Cipher; + use crate::ec::{EcGroup, EcKey}; + use crate::hash::{hash, MessageDigest}; + use crate::md::Md; + use crate::nid::Nid; + use crate::pkey::PKey; + use crate::rsa::Rsa; + use crate::sign::Verifier; + + #[test] + fn rsa() { + let key = include_bytes!("../test/rsa.pem"); + let rsa = Rsa::private_key_from_pem(key).unwrap(); + let pkey = PKey::from_rsa(rsa).unwrap(); + + let mut ctx = PkeyCtx::new(&pkey).unwrap(); + ctx.encrypt_init().unwrap(); + ctx.set_rsa_padding(Padding::PKCS1).unwrap(); + + let pt = "hello world".as_bytes(); + let mut ct = vec![]; + ctx.encrypt_to_vec(pt, &mut ct).unwrap(); + + ctx.decrypt_init().unwrap(); + ctx.set_rsa_padding(Padding::PKCS1).unwrap(); + + let mut out = vec![]; + ctx.decrypt_to_vec(&ct, &mut out).unwrap(); + + assert_eq!(pt, out); + } + + #[test] + #[cfg(any(ossl102, libressl310, boringssl))] + fn rsa_oaep() { + let key = include_bytes!("../test/rsa.pem"); + let rsa = Rsa::private_key_from_pem(key).unwrap(); + let pkey = PKey::from_rsa(rsa).unwrap(); + + let mut ctx = PkeyCtx::new(&pkey).unwrap(); + ctx.encrypt_init().unwrap(); + ctx.set_rsa_padding(Padding::PKCS1_OAEP).unwrap(); + ctx.set_rsa_oaep_md(Md::sha256()).unwrap(); + ctx.set_rsa_mgf1_md(Md::sha256()).unwrap(); + + let pt = "hello world".as_bytes(); + let mut ct = vec![]; + ctx.encrypt_to_vec(pt, &mut ct).unwrap(); + + ctx.decrypt_init().unwrap(); + ctx.set_rsa_padding(Padding::PKCS1_OAEP).unwrap(); + ctx.set_rsa_oaep_md(Md::sha256()).unwrap(); + ctx.set_rsa_mgf1_md(Md::sha256()).unwrap(); + + let mut out = vec![]; + ctx.decrypt_to_vec(&ct, &mut out).unwrap(); + + assert_eq!(pt, out); + } + + #[test] + fn rsa_sign() { + let key = include_bytes!("../test/rsa.pem"); + let rsa = Rsa::private_key_from_pem(key).unwrap(); + let pkey = PKey::from_rsa(rsa).unwrap(); + + let mut ctx = PkeyCtx::new(&pkey).unwrap(); + ctx.sign_init().unwrap(); + ctx.set_rsa_padding(Padding::PKCS1).unwrap(); + ctx.set_signature_md(Md::sha384()).unwrap(); + + let msg = b"hello world"; + let digest = hash(MessageDigest::sha384(), msg).unwrap(); + let mut signature = vec![]; + ctx.sign_to_vec(&digest, &mut signature).unwrap(); + + let mut verifier = Verifier::new(MessageDigest::sha384(), &pkey).unwrap(); + verifier.update(msg).unwrap(); + assert!(matches!(verifier.verify(&signature), Ok(true))); + } + + #[test] + fn rsa_sign_pss() { + let key = include_bytes!("../test/rsa.pem"); + let rsa = Rsa::private_key_from_pem(key).unwrap(); + let pkey = PKey::from_rsa(rsa).unwrap(); + + let mut ctx = PkeyCtx::new(&pkey).unwrap(); + ctx.sign_init().unwrap(); + ctx.set_rsa_padding(Padding::PKCS1_PSS).unwrap(); + ctx.set_signature_md(Md::sha384()).unwrap(); + ctx.set_rsa_pss_saltlen(RsaPssSaltlen::custom(14)).unwrap(); + + let msg = b"hello world"; + let digest = hash(MessageDigest::sha384(), msg).unwrap(); + let mut signature = vec![]; + ctx.sign_to_vec(&digest, &mut signature).unwrap(); + + let mut verifier = Verifier::new(MessageDigest::sha384(), &pkey).unwrap(); + verifier.set_rsa_padding(Padding::PKCS1_PSS).unwrap(); + verifier + .set_rsa_pss_saltlen(RsaPssSaltlen::custom(14)) + .unwrap(); + verifier.update(msg).unwrap(); + assert!(matches!(verifier.verify(&signature), Ok(true))); + } + + #[test] + fn derive() { + let group = EcGroup::from_curve_name(Nid::X9_62_PRIME256V1).unwrap(); + let key1 = EcKey::generate(&group).unwrap(); + let key1 = PKey::from_ec_key(key1).unwrap(); + let key2 = EcKey::generate(&group).unwrap(); + let key2 = PKey::from_ec_key(key2).unwrap(); + + let mut ctx = PkeyCtx::new(&key1).unwrap(); + ctx.derive_init().unwrap(); + ctx.derive_set_peer(&key2).unwrap(); + + let mut buf = vec![]; + ctx.derive_to_vec(&mut buf).unwrap(); + } + + #[test] + #[cfg(not(boringssl))] + fn cmac_keygen() { + let mut ctx = PkeyCtx::new_id(Id::CMAC).unwrap(); + ctx.keygen_init().unwrap(); + ctx.set_keygen_cipher(Cipher::aes_128_cbc()).unwrap(); + ctx.set_keygen_mac_key(&hex::decode("9294727a3638bb1c13f48ef8158bfc9d").unwrap()) + .unwrap(); + ctx.keygen().unwrap(); + } + + #[test] + #[cfg(any(ossl110, boringssl, libressl360))] + fn hkdf() { + let mut ctx = PkeyCtx::new_id(Id::HKDF).unwrap(); + ctx.derive_init().unwrap(); + ctx.set_hkdf_md(Md::sha256()).unwrap(); + ctx.set_hkdf_key(&hex::decode("0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b").unwrap()) + .unwrap(); + ctx.set_hkdf_salt(&hex::decode("000102030405060708090a0b0c").unwrap()) + .unwrap(); + ctx.add_hkdf_info(&hex::decode("f0f1f2f3f4f5f6f7f8f9").unwrap()) + .unwrap(); + let mut out = [0; 42]; + ctx.derive(Some(&mut out)).unwrap(); + + assert_eq!( + &out[..], + hex::decode("3cb25f25faacd57a90434f64d0362f2a2d2d0a90cf1a5a4c5db02d56ecc4c5bf34007208d5b887185865") + .unwrap() + ); + } + + #[test] + #[cfg(any(ossl111, libressl360))] + fn hkdf_expand() { + let mut ctx = PkeyCtx::new_id(Id::HKDF).unwrap(); + ctx.derive_init().unwrap(); + ctx.set_hkdf_mode(HkdfMode::EXPAND_ONLY).unwrap(); + ctx.set_hkdf_md(Md::sha256()).unwrap(); + ctx.set_hkdf_key( + &hex::decode("077709362c2e32df0ddc3f0dc47bba6390b6c73bb50f9c3122ec844ad7c2b3e5") + .unwrap(), + ) + .unwrap(); + ctx.add_hkdf_info(&hex::decode("f0f1f2f3f4f5f6f7f8f9").unwrap()) + .unwrap(); + let mut out = [0; 42]; + ctx.derive(Some(&mut out)).unwrap(); + + assert_eq!( + &out[..], + hex::decode("3cb25f25faacd57a90434f64d0362f2a2d2d0a90cf1a5a4c5db02d56ecc4c5bf34007208d5b887185865") + .unwrap() + ); + } + + #[test] + #[cfg(any(ossl111, libressl360))] + fn hkdf_extract() { + let mut ctx = PkeyCtx::new_id(Id::HKDF).unwrap(); + ctx.derive_init().unwrap(); + ctx.set_hkdf_mode(HkdfMode::EXTRACT_ONLY).unwrap(); + ctx.set_hkdf_md(Md::sha256()).unwrap(); + ctx.set_hkdf_key(&hex::decode("0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b").unwrap()) + .unwrap(); + ctx.set_hkdf_salt(&hex::decode("000102030405060708090a0b0c").unwrap()) + .unwrap(); + let mut out = vec![]; + ctx.derive_to_vec(&mut out).unwrap(); + + assert_eq!( + &out[..], + hex::decode("077709362c2e32df0ddc3f0dc47bba6390b6c73bb50f9c3122ec844ad7c2b3e5") + .unwrap() + ); + } + + #[test] + fn verify_fail() { + let key1 = Rsa::generate(4096).unwrap(); + let key1 = PKey::from_rsa(key1).unwrap(); + + let data = b"Some Crypto Text"; + + let mut ctx = PkeyCtx::new(&key1).unwrap(); + ctx.sign_init().unwrap(); + let mut signature = vec![]; + ctx.sign_to_vec(data, &mut signature).unwrap(); + + let bad_data = b"Some Crypto text"; + + ctx.verify_init().unwrap(); + let valid = ctx.verify(bad_data, &signature); + assert!(matches!(valid, Ok(false) | Err(_))); + assert!(ErrorStack::get().errors().is_empty()); + } + + #[test] + fn verify_fail_ec() { + let key1 = + EcKey::generate(&EcGroup::from_curve_name(Nid::X9_62_PRIME256V1).unwrap()).unwrap(); + let key1 = PKey::from_ec_key(key1).unwrap(); + + let data = b"Some Crypto Text"; + let mut ctx = PkeyCtx::new(&key1).unwrap(); + ctx.verify_init().unwrap(); + assert!(matches!(ctx.verify(data, &[0; 64]), Ok(false) | Err(_))); + assert!(ErrorStack::get().errors().is_empty()); + } + + #[test] + fn test_verify_recover() { + let key = Rsa::generate(2048).unwrap(); + let key = PKey::from_rsa(key).unwrap(); + + let digest = [ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, + 24, 25, 26, 27, 28, 29, 30, 31, + ]; + + let mut ctx = PkeyCtx::new(&key).unwrap(); + ctx.sign_init().unwrap(); + ctx.set_rsa_padding(Padding::PKCS1).unwrap(); + ctx.set_signature_md(Md::sha256()).unwrap(); + let mut signature = vec![]; + ctx.sign_to_vec(&digest, &mut signature).unwrap(); + + // Attempt recovery of just the digest. + let mut ctx = PkeyCtx::new(&key).unwrap(); + ctx.verify_recover_init().unwrap(); + ctx.set_rsa_padding(Padding::PKCS1).unwrap(); + ctx.set_signature_md(Md::sha256()).unwrap(); + let length = ctx.verify_recover(&signature, None).unwrap(); + let mut result_buf = vec![0; length]; + let length = ctx + .verify_recover(&signature, Some(&mut result_buf)) + .unwrap(); + assert_eq!(length, digest.len()); + // result_buf contains the digest + assert_eq!(result_buf[..length], digest); + + // Attempt recovery of teh entire DigestInfo + let mut ctx = PkeyCtx::new(&key).unwrap(); + ctx.verify_recover_init().unwrap(); + ctx.set_rsa_padding(Padding::PKCS1).unwrap(); + let length = ctx.verify_recover(&signature, None).unwrap(); + let mut result_buf = vec![0; length]; + let length = ctx + .verify_recover(&signature, Some(&mut result_buf)) + .unwrap(); + // 32-bytes of SHA256 digest + the ASN.1 DigestInfo structure == 51 bytes + assert_eq!(length, 51); + // The digest is the end of the DigestInfo structure. + assert_eq!(result_buf[length - digest.len()..length], digest); + } + + #[test] + #[cfg(ossl320)] + fn set_nonce_type() { + let key1 = + EcKey::generate(&EcGroup::from_curve_name(Nid::X9_62_PRIME256V1).unwrap()).unwrap(); + let key1 = PKey::from_ec_key(key1).unwrap(); + + let mut ctx = PkeyCtx::new(&key1).unwrap(); + ctx.sign_init().unwrap(); + ctx.set_nonce_type(NonceType::DETERMINISTIC_K).unwrap(); + let nonce_type = ctx.nonce_type().unwrap(); + assert_eq!(nonce_type, NonceType::DETERMINISTIC_K); + assert!(ErrorStack::get().errors().is_empty()); + } + + // Test vector from + // https://github.com/openssl/openssl/blob/openssl-3.2.0/test/recipes/30-test_evp_data/evppkey_ecdsa_rfc6979.txt + #[test] + #[cfg(ossl320)] + fn ecdsa_deterministic_signature() { + let private_key_pem = "-----BEGIN PRIVATE KEY----- +MDkCAQAwEwYHKoZIzj0CAQYIKoZIzj0DAQEEHzAdAgEBBBhvqwNJNOTA/Jrmf1tWWanX0f79GH7g +n9Q= +-----END PRIVATE KEY-----"; + + let key1 = EcKey::private_key_from_pem(private_key_pem.as_bytes()).unwrap(); + let key1 = PKey::from_ec_key(key1).unwrap(); + let input = "sample"; + let expected_output = hex::decode("303502190098C6BD12B23EAF5E2A2045132086BE3EB8EBD62ABF6698FF021857A22B07DEA9530F8DE9471B1DC6624472E8E2844BC25B64").unwrap(); + + let hashed_input = hash(MessageDigest::sha1(), input.as_bytes()).unwrap(); + let mut ctx = PkeyCtx::new(&key1).unwrap(); + ctx.sign_init().unwrap(); + ctx.set_signature_md(Md::sha1()).unwrap(); + ctx.set_nonce_type(NonceType::DETERMINISTIC_K).unwrap(); + + let mut output = vec![]; + ctx.sign_to_vec(&hashed_input, &mut output).unwrap(); + assert_eq!(output, expected_output); + assert!(ErrorStack::get().errors().is_empty()); + } +} diff --git a/vendor/openssl/src/provider.rs b/vendor/openssl/src/provider.rs new file mode 100644 index 0000000..01b5820 --- /dev/null +++ b/vendor/openssl/src/provider.rs @@ -0,0 +1,81 @@ +use crate::error::ErrorStack; +use crate::lib_ctx::LibCtxRef; +use crate::{cvt, cvt_p}; +use foreign_types::{ForeignType, ForeignTypeRef}; +use openssl_macros::corresponds; +use std::ffi::CString; +use std::ptr; + +foreign_type_and_impl_send_sync! { + type CType = ffi::OSSL_PROVIDER; + fn drop = ossl_provider_free; + + pub struct Provider; + /// A reference to a [`Provider`]. + pub struct ProviderRef; +} + +#[inline] +unsafe fn ossl_provider_free(p: *mut ffi::OSSL_PROVIDER) { + ffi::OSSL_PROVIDER_unload(p); +} + +impl Provider { + /// Loads a new provider into the specified library context, disabling the fallback providers. + /// + /// If `ctx` is `None`, the provider will be loaded in to the default library context. + #[corresponds(OSSL_provider_load)] + pub fn load(ctx: Option<&LibCtxRef>, name: &str) -> Result { + let name = CString::new(name).unwrap(); + unsafe { + let p = cvt_p(ffi::OSSL_PROVIDER_load( + ctx.map_or(ptr::null_mut(), ForeignTypeRef::as_ptr), + name.as_ptr(), + ))?; + + Ok(Provider::from_ptr(p)) + } + } + + /// Loads a new provider into the specified library context, disabling the fallback providers if `retain_fallbacks` + /// is `false` and the load succeeds. + /// + /// If `ctx` is `None`, the provider will be loaded into the default library context. + #[corresponds(OSSL_provider_try_load)] + pub fn try_load( + ctx: Option<&LibCtxRef>, + name: &str, + retain_fallbacks: bool, + ) -> Result { + let name = CString::new(name).unwrap(); + unsafe { + let p = cvt_p(ffi::OSSL_PROVIDER_try_load( + ctx.map_or(ptr::null_mut(), ForeignTypeRef::as_ptr), + name.as_ptr(), + retain_fallbacks as _, + ))?; + + // OSSL_PROVIDER_try_load seems to leave errors on the stack, even + // when it succeeds. + let _ = ErrorStack::get(); + + Ok(Provider::from_ptr(p)) + } + } + + /// Specifies the default search path that is to be used for looking for providers in the specified library context. + /// If left unspecified, an environment variable and a fall back default value will be used instead + /// + /// If `ctx` is `None`, the provider will be loaded into the default library context. + #[corresponds(OSSL_PROVIDER_set_default_search_path)] + pub fn set_default_search_path(ctx: Option<&LibCtxRef>, path: &str) -> Result<(), ErrorStack> { + let path = CString::new(path).unwrap(); + unsafe { + cvt(ffi::OSSL_PROVIDER_set_default_search_path( + ctx.map_or(ptr::null_mut(), ForeignTypeRef::as_ptr), + path.as_ptr(), + )) + .map(|_| ()) + } + } +} diff --git a/vendor/openssl/src/rand.rs b/vendor/openssl/src/rand.rs new file mode 100644 index 0000000..fe8423b --- /dev/null +++ b/vendor/openssl/src/rand.rs @@ -0,0 +1,90 @@ +//! Utilities for secure random number generation. +//! +//! # Examples +//! +//! To generate a buffer with cryptographically strong bytes: +//! +//! ``` +//! use openssl::rand::rand_bytes; +//! +//! let mut buf = [0; 256]; +//! rand_bytes(&mut buf).unwrap(); +//! ``` +use libc::c_int; + +use crate::error::ErrorStack; +use crate::{cvt, LenType}; +use openssl_macros::corresponds; + +/// Fill buffer with cryptographically strong pseudo-random bytes. +/// +/// # Examples +/// +/// To generate a buffer with cryptographically strong random bytes: +/// +/// ``` +/// use openssl::rand::rand_bytes; +/// +/// let mut buf = [0; 256]; +/// rand_bytes(&mut buf).unwrap(); +/// ``` +#[corresponds(RAND_bytes)] +pub fn rand_bytes(buf: &mut [u8]) -> Result<(), ErrorStack> { + unsafe { + ffi::init(); + assert!(buf.len() <= c_int::MAX as usize); + cvt(ffi::RAND_bytes(buf.as_mut_ptr(), buf.len() as LenType)).map(|_| ()) + } +} + +/// Fill buffer with cryptographically strong pseudo-random bytes. It is +/// intended to be used for generating values that should remain private. +/// +/// # Examples +/// +/// To generate a buffer with cryptographically strong random bytes: +/// +/// ``` +/// use openssl::rand::rand_priv_bytes; +/// +/// let mut buf = [0; 256]; +/// rand_priv_bytes(&mut buf).unwrap(); +/// ``` +/// +/// Requires OpenSSL 1.1.1 or newer. +#[corresponds(RAND_priv_bytes)] +#[cfg(ossl111)] +pub fn rand_priv_bytes(buf: &mut [u8]) -> Result<(), ErrorStack> { + unsafe { + ffi::init(); + assert!(buf.len() <= c_int::MAX as usize); + cvt(ffi::RAND_priv_bytes(buf.as_mut_ptr(), buf.len() as LenType)).map(|_| ()) + } +} + +/// Controls random device file descriptor behavior. +/// +/// Requires OpenSSL 1.1.1 or newer. +#[corresponds(RAND_keep_random_devices_open)] +#[cfg(ossl111)] +pub fn keep_random_devices_open(keep: bool) { + unsafe { + ffi::RAND_keep_random_devices_open(keep as LenType); + } +} + +#[cfg(test)] +mod tests { + #[test] + fn test_rand_bytes() { + let mut buf = [0; 32]; + super::rand_bytes(&mut buf).unwrap(); + } + + #[test] + #[cfg(ossl111)] + fn test_rand_priv_bytes() { + let mut buf = [0; 32]; + super::rand_priv_bytes(&mut buf).unwrap(); + } +} diff --git a/vendor/openssl/src/rsa.rs b/vendor/openssl/src/rsa.rs new file mode 100644 index 0000000..2e6614a --- /dev/null +++ b/vendor/openssl/src/rsa.rs @@ -0,0 +1,873 @@ +//! Rivest–Shamir–Adleman cryptosystem +//! +//! RSA is one of the earliest asymmetric public key encryption schemes. +//! Like many other cryptosystems, RSA relies on the presumed difficulty of a hard +//! mathematical problem, namely factorization of the product of two large prime +//! numbers. At the moment there does not exist an algorithm that can factor such +//! large numbers in reasonable time. RSA is used in a wide variety of +//! applications including digital signatures and key exchanges such as +//! establishing a TLS/SSL connection. +//! +//! The RSA acronym is derived from the first letters of the surnames of the +//! algorithm's founding trio. +//! +//! # Example +//! +//! Generate a 2048-bit RSA key pair and use the public key to encrypt some data. +//! +//! ```rust +//! use openssl::rsa::{Rsa, Padding}; +//! +//! let rsa = Rsa::generate(2048).unwrap(); +//! let data = b"foobar"; +//! let mut buf = vec![0; rsa.size() as usize]; +//! let encrypted_len = rsa.public_encrypt(data, &mut buf, Padding::PKCS1).unwrap(); +//! ``` +use cfg_if::cfg_if; +use foreign_types::{ForeignType, ForeignTypeRef}; +use libc::c_int; +use std::fmt; +use std::mem; +use std::ptr; + +use crate::bn::{BigNum, BigNumRef}; +use crate::error::ErrorStack; +use crate::pkey::{HasPrivate, HasPublic, Private, Public}; +use crate::util::ForeignTypeRefExt; +use crate::{cvt, cvt_n, cvt_p, LenType}; +use openssl_macros::corresponds; + +/// Type of encryption padding to use. +/// +/// Random length padding is primarily used to prevent attackers from +/// predicting or knowing the exact length of a plaintext message that +/// can possibly lead to breaking encryption. +#[derive(Debug, Copy, Clone, PartialEq, Eq)] +pub struct Padding(c_int); + +impl Padding { + pub const NONE: Padding = Padding(ffi::RSA_NO_PADDING); + pub const PKCS1: Padding = Padding(ffi::RSA_PKCS1_PADDING); + pub const PKCS1_OAEP: Padding = Padding(ffi::RSA_PKCS1_OAEP_PADDING); + pub const PKCS1_PSS: Padding = Padding(ffi::RSA_PKCS1_PSS_PADDING); + + /// Creates a `Padding` from an integer representation. + pub fn from_raw(value: c_int) -> Padding { + Padding(value) + } + + /// Returns the integer representation of `Padding`. + #[allow(clippy::trivially_copy_pass_by_ref)] + pub fn as_raw(&self) -> c_int { + self.0 + } +} + +generic_foreign_type_and_impl_send_sync! { + type CType = ffi::RSA; + fn drop = ffi::RSA_free; + + /// An RSA key. + pub struct Rsa; + + /// Reference to `RSA` + pub struct RsaRef; +} + +impl Clone for Rsa { + fn clone(&self) -> Rsa { + (**self).to_owned() + } +} + +impl ToOwned for RsaRef { + type Owned = Rsa; + + fn to_owned(&self) -> Rsa { + unsafe { + ffi::RSA_up_ref(self.as_ptr()); + Rsa::from_ptr(self.as_ptr()) + } + } +} + +impl RsaRef +where + T: HasPrivate, +{ + private_key_to_pem! { + /// Serializes the private key to a PEM-encoded PKCS#1 RSAPrivateKey structure. + /// + /// The output will have a header of `-----BEGIN RSA PRIVATE KEY-----`. + #[corresponds(PEM_write_bio_RSAPrivateKey)] + private_key_to_pem, + /// Serializes the private key to a PEM-encoded encrypted PKCS#1 RSAPrivateKey structure. + /// + /// The output will have a header of `-----BEGIN RSA PRIVATE KEY-----`. + #[corresponds(PEM_write_bio_RSAPrivateKey)] + private_key_to_pem_passphrase, + ffi::PEM_write_bio_RSAPrivateKey + } + + to_der! { + /// Serializes the private key to a DER-encoded PKCS#1 RSAPrivateKey structure. + #[corresponds(i2d_RSAPrivateKey)] + private_key_to_der, + ffi::i2d_RSAPrivateKey + } + + /// Decrypts data using the private key, returning the number of decrypted bytes. + /// + /// # Panics + /// + /// Panics if `self` has no private components, or if `to` is smaller + /// than `self.size()`. + #[corresponds(RSA_private_decrypt)] + pub fn private_decrypt( + &self, + from: &[u8], + to: &mut [u8], + padding: Padding, + ) -> Result { + assert!(from.len() <= i32::MAX as usize); + assert!(to.len() >= self.size() as usize); + + unsafe { + let len = cvt_n(ffi::RSA_private_decrypt( + from.len() as LenType, + from.as_ptr(), + to.as_mut_ptr(), + self.as_ptr(), + padding.0, + ))?; + Ok(len as usize) + } + } + + /// Encrypts data using the private key, returning the number of encrypted bytes. + /// + /// # Panics + /// + /// Panics if `self` has no private components, or if `to` is smaller + /// than `self.size()`. + #[corresponds(RSA_private_encrypt)] + pub fn private_encrypt( + &self, + from: &[u8], + to: &mut [u8], + padding: Padding, + ) -> Result { + assert!(from.len() <= i32::MAX as usize); + assert!(to.len() >= self.size() as usize); + + unsafe { + let len = cvt_n(ffi::RSA_private_encrypt( + from.len() as LenType, + from.as_ptr(), + to.as_mut_ptr(), + self.as_ptr(), + padding.0, + ))?; + Ok(len as usize) + } + } + + /// Returns a reference to the private exponent of the key. + #[corresponds(RSA_get0_key)] + pub fn d(&self) -> &BigNumRef { + unsafe { + let mut d = ptr::null(); + RSA_get0_key(self.as_ptr(), ptr::null_mut(), ptr::null_mut(), &mut d); + BigNumRef::from_const_ptr(d) + } + } + + /// Returns a reference to the first factor of the exponent of the key. + #[corresponds(RSA_get0_factors)] + pub fn p(&self) -> Option<&BigNumRef> { + unsafe { + let mut p = ptr::null(); + RSA_get0_factors(self.as_ptr(), &mut p, ptr::null_mut()); + BigNumRef::from_const_ptr_opt(p) + } + } + + /// Returns a reference to the second factor of the exponent of the key. + #[corresponds(RSA_get0_factors)] + pub fn q(&self) -> Option<&BigNumRef> { + unsafe { + let mut q = ptr::null(); + RSA_get0_factors(self.as_ptr(), ptr::null_mut(), &mut q); + BigNumRef::from_const_ptr_opt(q) + } + } + + /// Returns a reference to the first exponent used for CRT calculations. + #[corresponds(RSA_get0_crt_params)] + pub fn dmp1(&self) -> Option<&BigNumRef> { + unsafe { + let mut dp = ptr::null(); + RSA_get0_crt_params(self.as_ptr(), &mut dp, ptr::null_mut(), ptr::null_mut()); + BigNumRef::from_const_ptr_opt(dp) + } + } + + /// Returns a reference to the second exponent used for CRT calculations. + #[corresponds(RSA_get0_crt_params)] + pub fn dmq1(&self) -> Option<&BigNumRef> { + unsafe { + let mut dq = ptr::null(); + RSA_get0_crt_params(self.as_ptr(), ptr::null_mut(), &mut dq, ptr::null_mut()); + BigNumRef::from_const_ptr_opt(dq) + } + } + + /// Returns a reference to the coefficient used for CRT calculations. + #[corresponds(RSA_get0_crt_params)] + pub fn iqmp(&self) -> Option<&BigNumRef> { + unsafe { + let mut qi = ptr::null(); + RSA_get0_crt_params(self.as_ptr(), ptr::null_mut(), ptr::null_mut(), &mut qi); + BigNumRef::from_const_ptr_opt(qi) + } + } + + /// Validates RSA parameters for correctness + #[corresponds(RSA_check_key)] + pub fn check_key(&self) -> Result { + unsafe { + let result = ffi::RSA_check_key(self.as_ptr()); + if result != 1 { + let errors = ErrorStack::get(); + if errors.errors().is_empty() { + Ok(false) + } else { + Err(errors) + } + } else { + Ok(true) + } + } + } +} + +impl RsaRef +where + T: HasPublic, +{ + to_pem! { + /// Serializes the public key into a PEM-encoded SubjectPublicKeyInfo structure. + /// + /// The output will have a header of `-----BEGIN PUBLIC KEY-----`. + #[corresponds(PEM_write_bio_RSA_PUBKEY)] + public_key_to_pem, + ffi::PEM_write_bio_RSA_PUBKEY + } + + to_der! { + /// Serializes the public key into a DER-encoded SubjectPublicKeyInfo structure. + #[corresponds(i2d_RSA_PUBKEY)] + public_key_to_der, + ffi::i2d_RSA_PUBKEY + } + + to_pem! { + /// Serializes the public key into a PEM-encoded PKCS#1 RSAPublicKey structure. + /// + /// The output will have a header of `-----BEGIN RSA PUBLIC KEY-----`. + #[corresponds(PEM_write_bio_RSAPublicKey)] + public_key_to_pem_pkcs1, + ffi::PEM_write_bio_RSAPublicKey + } + + to_der! { + /// Serializes the public key into a DER-encoded PKCS#1 RSAPublicKey structure. + #[corresponds(i2d_RSAPublicKey)] + public_key_to_der_pkcs1, + ffi::i2d_RSAPublicKey + } + + /// Returns the size of the modulus in bytes. + #[corresponds(RSA_size)] + pub fn size(&self) -> u32 { + unsafe { ffi::RSA_size(self.as_ptr()) as u32 } + } + + /// Decrypts data using the public key, returning the number of decrypted bytes. + /// + /// # Panics + /// + /// Panics if `to` is smaller than `self.size()`. + #[corresponds(RSA_public_decrypt)] + pub fn public_decrypt( + &self, + from: &[u8], + to: &mut [u8], + padding: Padding, + ) -> Result { + assert!(from.len() <= i32::MAX as usize); + assert!(to.len() >= self.size() as usize); + + unsafe { + let len = cvt_n(ffi::RSA_public_decrypt( + from.len() as LenType, + from.as_ptr(), + to.as_mut_ptr(), + self.as_ptr(), + padding.0, + ))?; + Ok(len as usize) + } + } + + /// Encrypts data using the public key, returning the number of encrypted bytes. + /// + /// # Panics + /// + /// Panics if `to` is smaller than `self.size()`. + #[corresponds(RSA_public_encrypt)] + pub fn public_encrypt( + &self, + from: &[u8], + to: &mut [u8], + padding: Padding, + ) -> Result { + assert!(from.len() <= i32::MAX as usize); + assert!(to.len() >= self.size() as usize); + + unsafe { + let len = cvt_n(ffi::RSA_public_encrypt( + from.len() as LenType, + from.as_ptr(), + to.as_mut_ptr(), + self.as_ptr(), + padding.0, + ))?; + Ok(len as usize) + } + } + + /// Returns a reference to the modulus of the key. + #[corresponds(RSA_get0_key)] + pub fn n(&self) -> &BigNumRef { + unsafe { + let mut n = ptr::null(); + RSA_get0_key(self.as_ptr(), &mut n, ptr::null_mut(), ptr::null_mut()); + BigNumRef::from_const_ptr(n) + } + } + + /// Returns a reference to the public exponent of the key. + #[corresponds(RSA_get0_key)] + pub fn e(&self) -> &BigNumRef { + unsafe { + let mut e = ptr::null(); + RSA_get0_key(self.as_ptr(), ptr::null_mut(), &mut e, ptr::null_mut()); + BigNumRef::from_const_ptr(e) + } + } +} + +impl Rsa { + /// Creates a new RSA key with only public components. + /// + /// `n` is the modulus common to both public and private key. + /// `e` is the public exponent. + /// + /// This corresponds to [`RSA_new`] and uses [`RSA_set0_key`]. + /// + /// [`RSA_new`]: https://www.openssl.org/docs/manmaster/crypto/RSA_new.html + /// [`RSA_set0_key`]: https://www.openssl.org/docs/manmaster/crypto/RSA_set0_key.html + pub fn from_public_components(n: BigNum, e: BigNum) -> Result, ErrorStack> { + unsafe { + let rsa = cvt_p(ffi::RSA_new())?; + RSA_set0_key(rsa, n.as_ptr(), e.as_ptr(), ptr::null_mut()); + mem::forget((n, e)); + Ok(Rsa::from_ptr(rsa)) + } + } + + from_pem! { + /// Decodes a PEM-encoded SubjectPublicKeyInfo structure containing an RSA key. + /// + /// The input should have a header of `-----BEGIN PUBLIC KEY-----`. + #[corresponds(PEM_read_bio_RSA_PUBKEY)] + public_key_from_pem, + Rsa, + ffi::PEM_read_bio_RSA_PUBKEY + } + + from_pem! { + /// Decodes a PEM-encoded PKCS#1 RSAPublicKey structure. + /// + /// The input should have a header of `-----BEGIN RSA PUBLIC KEY-----`. + #[corresponds(PEM_read_bio_RSAPublicKey)] + public_key_from_pem_pkcs1, + Rsa, + ffi::PEM_read_bio_RSAPublicKey + } + + from_der! { + /// Decodes a DER-encoded SubjectPublicKeyInfo structure containing an RSA key. + #[corresponds(d2i_RSA_PUBKEY)] + public_key_from_der, + Rsa, + ffi::d2i_RSA_PUBKEY + } + + from_der! { + /// Decodes a DER-encoded PKCS#1 RSAPublicKey structure. + #[corresponds(d2i_RSAPublicKey)] + public_key_from_der_pkcs1, + Rsa, + ffi::d2i_RSAPublicKey + } +} + +pub struct RsaPrivateKeyBuilder { + rsa: Rsa, +} + +impl RsaPrivateKeyBuilder { + /// Creates a new `RsaPrivateKeyBuilder`. + /// + /// `n` is the modulus common to both public and private key. + /// `e` is the public exponent and `d` is the private exponent. + /// + /// This corresponds to [`RSA_new`] and uses [`RSA_set0_key`]. + /// + /// [`RSA_new`]: https://www.openssl.org/docs/manmaster/crypto/RSA_new.html + /// [`RSA_set0_key`]: https://www.openssl.org/docs/manmaster/crypto/RSA_set0_key.html + pub fn new(n: BigNum, e: BigNum, d: BigNum) -> Result { + unsafe { + let rsa = cvt_p(ffi::RSA_new())?; + RSA_set0_key(rsa, n.as_ptr(), e.as_ptr(), d.as_ptr()); + mem::forget((n, e, d)); + Ok(RsaPrivateKeyBuilder { + rsa: Rsa::from_ptr(rsa), + }) + } + } + + /// Sets the factors of the Rsa key. + /// + /// `p` and `q` are the first and second factors of `n`. + #[corresponds(RSA_set0_factors)] + // FIXME should be infallible + pub fn set_factors(self, p: BigNum, q: BigNum) -> Result { + unsafe { + RSA_set0_factors(self.rsa.as_ptr(), p.as_ptr(), q.as_ptr()); + mem::forget((p, q)); + } + Ok(self) + } + + /// Sets the Chinese Remainder Theorem params of the Rsa key. + /// + /// `dmp1`, `dmq1`, and `iqmp` are the exponents and coefficient for + /// CRT calculations which is used to speed up RSA operations. + #[corresponds(RSA_set0_crt_params)] + // FIXME should be infallible + pub fn set_crt_params( + self, + dmp1: BigNum, + dmq1: BigNum, + iqmp: BigNum, + ) -> Result { + unsafe { + RSA_set0_crt_params( + self.rsa.as_ptr(), + dmp1.as_ptr(), + dmq1.as_ptr(), + iqmp.as_ptr(), + ); + mem::forget((dmp1, dmq1, iqmp)); + } + Ok(self) + } + + /// Returns the Rsa key. + pub fn build(self) -> Rsa { + self.rsa + } +} + +impl Rsa { + /// Creates a new RSA key with private components (public components are assumed). + /// + /// This a convenience method over: + /// ``` + /// # use openssl::rsa::RsaPrivateKeyBuilder; + /// # fn main() -> Result<(), Box> { + /// # let bn = || openssl::bn::BigNum::new().unwrap(); + /// # let (n, e, d, p, q, dmp1, dmq1, iqmp) = (bn(), bn(), bn(), bn(), bn(), bn(), bn(), bn()); + /// RsaPrivateKeyBuilder::new(n, e, d)? + /// .set_factors(p, q)? + /// .set_crt_params(dmp1, dmq1, iqmp)? + /// .build(); + /// # Ok(()) } + /// ``` + #[allow(clippy::too_many_arguments, clippy::many_single_char_names)] + pub fn from_private_components( + n: BigNum, + e: BigNum, + d: BigNum, + p: BigNum, + q: BigNum, + dmp1: BigNum, + dmq1: BigNum, + iqmp: BigNum, + ) -> Result, ErrorStack> { + Ok(RsaPrivateKeyBuilder::new(n, e, d)? + .set_factors(p, q)? + .set_crt_params(dmp1, dmq1, iqmp)? + .build()) + } + + /// Generates a public/private key pair with the specified size. + /// + /// The public exponent will be 65537. + #[corresponds(RSA_generate_key_ex)] + pub fn generate(bits: u32) -> Result, ErrorStack> { + let e = BigNum::from_u32(ffi::RSA_F4 as u32)?; + Rsa::generate_with_e(bits, &e) + } + + /// Generates a public/private key pair with the specified size and a custom exponent. + /// + /// Unless you have specific needs and know what you're doing, use `Rsa::generate` instead. + #[corresponds(RSA_generate_key_ex)] + pub fn generate_with_e(bits: u32, e: &BigNumRef) -> Result, ErrorStack> { + unsafe { + let rsa = Rsa::from_ptr(cvt_p(ffi::RSA_new())?); + cvt(ffi::RSA_generate_key_ex( + rsa.0, + bits as c_int, + e.as_ptr(), + ptr::null_mut(), + ))?; + Ok(rsa) + } + } + + // FIXME these need to identify input formats + private_key_from_pem! { + /// Deserializes a private key from a PEM-encoded PKCS#1 RSAPrivateKey structure. + #[corresponds(PEM_read_bio_RSAPrivateKey)] + private_key_from_pem, + + /// Deserializes a private key from a PEM-encoded encrypted PKCS#1 RSAPrivateKey structure. + #[corresponds(PEM_read_bio_RSAPrivateKey)] + private_key_from_pem_passphrase, + + /// Deserializes a private key from a PEM-encoded encrypted PKCS#1 RSAPrivateKey structure. + /// + /// The callback should fill the password into the provided buffer and return its length. + #[corresponds(PEM_read_bio_RSAPrivateKey)] + private_key_from_pem_callback, + Rsa, + ffi::PEM_read_bio_RSAPrivateKey + } + + from_der! { + /// Decodes a DER-encoded PKCS#1 RSAPrivateKey structure. + #[corresponds(d2i_RSAPrivateKey)] + private_key_from_der, + Rsa, + ffi::d2i_RSAPrivateKey + } +} + +impl fmt::Debug for Rsa { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "Rsa") + } +} + +cfg_if! { + if #[cfg(any(ossl110, libressl273, boringssl))] { + use ffi::{ + RSA_get0_key, RSA_get0_factors, RSA_get0_crt_params, RSA_set0_key, RSA_set0_factors, + RSA_set0_crt_params, + }; + } else { + #[allow(bad_style)] + unsafe fn RSA_get0_key( + r: *const ffi::RSA, + n: *mut *const ffi::BIGNUM, + e: *mut *const ffi::BIGNUM, + d: *mut *const ffi::BIGNUM, + ) { + if !n.is_null() { + *n = (*r).n; + } + if !e.is_null() { + *e = (*r).e; + } + if !d.is_null() { + *d = (*r).d; + } + } + + #[allow(bad_style)] + unsafe fn RSA_get0_factors( + r: *const ffi::RSA, + p: *mut *const ffi::BIGNUM, + q: *mut *const ffi::BIGNUM, + ) { + if !p.is_null() { + *p = (*r).p; + } + if !q.is_null() { + *q = (*r).q; + } + } + + #[allow(bad_style)] + unsafe fn RSA_get0_crt_params( + r: *const ffi::RSA, + dmp1: *mut *const ffi::BIGNUM, + dmq1: *mut *const ffi::BIGNUM, + iqmp: *mut *const ffi::BIGNUM, + ) { + if !dmp1.is_null() { + *dmp1 = (*r).dmp1; + } + if !dmq1.is_null() { + *dmq1 = (*r).dmq1; + } + if !iqmp.is_null() { + *iqmp = (*r).iqmp; + } + } + + #[allow(bad_style)] + unsafe fn RSA_set0_key( + r: *mut ffi::RSA, + n: *mut ffi::BIGNUM, + e: *mut ffi::BIGNUM, + d: *mut ffi::BIGNUM, + ) -> c_int { + (*r).n = n; + (*r).e = e; + (*r).d = d; + 1 + } + + #[allow(bad_style)] + unsafe fn RSA_set0_factors( + r: *mut ffi::RSA, + p: *mut ffi::BIGNUM, + q: *mut ffi::BIGNUM, + ) -> c_int { + (*r).p = p; + (*r).q = q; + 1 + } + + #[allow(bad_style)] + unsafe fn RSA_set0_crt_params( + r: *mut ffi::RSA, + dmp1: *mut ffi::BIGNUM, + dmq1: *mut ffi::BIGNUM, + iqmp: *mut ffi::BIGNUM, + ) -> c_int { + (*r).dmp1 = dmp1; + (*r).dmq1 = dmq1; + (*r).iqmp = iqmp; + 1 + } + } +} + +#[cfg(test)] +mod test { + use crate::symm::Cipher; + + use super::*; + + #[test] + fn test_from_password() { + let key = include_bytes!("../test/rsa-encrypted.pem"); + Rsa::private_key_from_pem_passphrase(key, b"mypass").unwrap(); + } + + #[test] + fn test_from_password_callback() { + let mut password_queried = false; + let key = include_bytes!("../test/rsa-encrypted.pem"); + Rsa::private_key_from_pem_callback(key, |password| { + password_queried = true; + password[..6].copy_from_slice(b"mypass"); + Ok(6) + }) + .unwrap(); + + assert!(password_queried); + } + + #[test] + fn test_to_password() { + let key = Rsa::generate(2048).unwrap(); + let pem = key + .private_key_to_pem_passphrase(Cipher::aes_128_cbc(), b"foobar") + .unwrap(); + Rsa::private_key_from_pem_passphrase(&pem, b"foobar").unwrap(); + assert!(Rsa::private_key_from_pem_passphrase(&pem, b"fizzbuzz").is_err()); + } + + #[test] + fn test_public_encrypt_private_decrypt_with_padding() { + let key = include_bytes!("../test/rsa.pem.pub"); + let public_key = Rsa::public_key_from_pem(key).unwrap(); + + let mut result = vec![0; public_key.size() as usize]; + let original_data = b"This is test"; + let len = public_key + .public_encrypt(original_data, &mut result, Padding::PKCS1) + .unwrap(); + assert_eq!(len, 256); + + let pkey = include_bytes!("../test/rsa.pem"); + let private_key = Rsa::private_key_from_pem(pkey).unwrap(); + let mut dec_result = vec![0; private_key.size() as usize]; + let len = private_key + .private_decrypt(&result, &mut dec_result, Padding::PKCS1) + .unwrap(); + + assert_eq!(&dec_result[..len], original_data); + } + + #[test] + fn test_private_encrypt() { + let k0 = super::Rsa::generate(512).unwrap(); + let k0pkey = k0.public_key_to_pem().unwrap(); + let k1 = super::Rsa::public_key_from_pem(&k0pkey).unwrap(); + + let msg = vec![0xdeu8, 0xadu8, 0xd0u8, 0x0du8]; + + let mut emesg = vec![0; k0.size() as usize]; + k0.private_encrypt(&msg, &mut emesg, Padding::PKCS1) + .unwrap(); + let mut dmesg = vec![0; k1.size() as usize]; + let len = k1 + .public_decrypt(&emesg, &mut dmesg, Padding::PKCS1) + .unwrap(); + assert_eq!(msg, &dmesg[..len]); + } + + #[test] + fn test_public_encrypt() { + let k0 = super::Rsa::generate(512).unwrap(); + let k0pkey = k0.private_key_to_pem().unwrap(); + let k1 = super::Rsa::private_key_from_pem(&k0pkey).unwrap(); + + let msg = vec![0xdeu8, 0xadu8, 0xd0u8, 0x0du8]; + + let mut emesg = vec![0; k0.size() as usize]; + k0.public_encrypt(&msg, &mut emesg, Padding::PKCS1).unwrap(); + let mut dmesg = vec![0; k1.size() as usize]; + let len = k1 + .private_decrypt(&emesg, &mut dmesg, Padding::PKCS1) + .unwrap(); + assert_eq!(msg, &dmesg[..len]); + } + + #[test] + fn test_public_key_from_pem_pkcs1() { + let key = include_bytes!("../test/pkcs1.pem.pub"); + Rsa::public_key_from_pem_pkcs1(key).unwrap(); + } + + #[test] + #[should_panic] + fn test_public_key_from_pem_pkcs1_file_panic() { + let key = include_bytes!("../test/key.pem.pub"); + Rsa::public_key_from_pem_pkcs1(key).unwrap(); + } + + #[test] + fn test_public_key_to_pem_pkcs1() { + let keypair = super::Rsa::generate(512).unwrap(); + let pubkey_pem = keypair.public_key_to_pem_pkcs1().unwrap(); + super::Rsa::public_key_from_pem_pkcs1(&pubkey_pem).unwrap(); + } + + #[test] + #[should_panic] + fn test_public_key_from_pem_pkcs1_generate_panic() { + let keypair = super::Rsa::generate(512).unwrap(); + let pubkey_pem = keypair.public_key_to_pem().unwrap(); + super::Rsa::public_key_from_pem_pkcs1(&pubkey_pem).unwrap(); + } + + #[test] + fn test_pem_pkcs1_encrypt() { + let keypair = super::Rsa::generate(2048).unwrap(); + let pubkey_pem = keypair.public_key_to_pem_pkcs1().unwrap(); + let pubkey = super::Rsa::public_key_from_pem_pkcs1(&pubkey_pem).unwrap(); + let msg = b"Hello, world!"; + + let mut encrypted = vec![0; pubkey.size() as usize]; + let len = pubkey + .public_encrypt(msg, &mut encrypted, Padding::PKCS1) + .unwrap(); + assert!(len > msg.len()); + let mut decrypted = vec![0; keypair.size() as usize]; + let len = keypair + .private_decrypt(&encrypted, &mut decrypted, Padding::PKCS1) + .unwrap(); + assert_eq!(len, msg.len()); + assert_eq!(&decrypted[..len], msg); + } + + #[test] + fn test_pem_pkcs1_padding() { + let keypair = super::Rsa::generate(2048).unwrap(); + let pubkey_pem = keypair.public_key_to_pem_pkcs1().unwrap(); + let pubkey = super::Rsa::public_key_from_pem_pkcs1(&pubkey_pem).unwrap(); + let msg = b"foo"; + + let mut encrypted1 = vec![0; pubkey.size() as usize]; + let mut encrypted2 = vec![0; pubkey.size() as usize]; + let len1 = pubkey + .public_encrypt(msg, &mut encrypted1, Padding::PKCS1) + .unwrap(); + let len2 = pubkey + .public_encrypt(msg, &mut encrypted2, Padding::PKCS1) + .unwrap(); + assert!(len1 > (msg.len() + 1)); + assert_eq!(len1, len2); + assert_ne!(encrypted1, encrypted2); + } + + #[test] + #[allow(clippy::redundant_clone)] + fn clone() { + let key = Rsa::generate(2048).unwrap(); + drop(key.clone()); + } + + #[test] + fn generate_with_e() { + let e = BigNum::from_u32(0x10001).unwrap(); + Rsa::generate_with_e(2048, &e).unwrap(); + } + + #[test] + fn test_check_key() { + let k = Rsa::private_key_from_pem_passphrase( + include_bytes!("../test/rsa-encrypted.pem"), + b"mypass", + ) + .unwrap(); + assert!(matches!(k.check_key(), Ok(true))); + assert!(ErrorStack::get().errors().is_empty()); + + // BoringSSL simply rejects this key, because its corrupted! + if let Ok(k) = Rsa::private_key_from_pem(include_bytes!("../test/corrupted-rsa.pem")) { + assert!(matches!(k.check_key(), Ok(false) | Err(_))); + assert!(ErrorStack::get().errors().is_empty()); + } + } +} diff --git a/vendor/openssl/src/sha.rs b/vendor/openssl/src/sha.rs new file mode 100644 index 0000000..2412890 --- /dev/null +++ b/vendor/openssl/src/sha.rs @@ -0,0 +1,463 @@ +//! The SHA family of hashes. +//! +//! SHA, or Secure Hash Algorithms, are a family of cryptographic hashing algorithms published by +//! the National Institute of Standards and Technology (NIST). Hash algorithms such as those in +//! the SHA family are used to map data of an arbitrary size to a fixed-size string of bytes. +//! As cryptographic hashing algorithms, these mappings have the property of being irreversible. +//! This property makes hash algorithms like these excellent for uses such as verifying the +//! contents of a file- if you know the hash you expect beforehand, then you can verify that the +//! data you have is correct if it hashes to the same value. +//! +//! # Examples +//! +//! When dealing with data that becomes available in chunks, such as while buffering data from IO, +//! you can create a hasher that you can repeatedly update to add bytes to. +//! +//! ```rust +//! use openssl::sha; +//! +//! let mut hasher = sha::Sha256::new(); +//! +//! hasher.update(b"Hello, "); +//! hasher.update(b"world"); +//! +//! let hash = hasher.finish(); +//! println!("Hashed \"Hello, world\" to {}", hex::encode(hash)); +//! ``` +//! +//! On the other hand, if you already have access to all of the data you would like to hash, you +//! may prefer to use the slightly simpler method of simply calling the hash function corresponding +//! to the algorithm you want to use. +//! +//! ```rust +//! use openssl::sha::sha256; +//! +//! let hash = sha256(b"your data or message"); +//! println!("Hash = {}", hex::encode(hash)); +//! ``` +use cfg_if::cfg_if; +use libc::c_void; +use openssl_macros::corresponds; +use std::mem::MaybeUninit; + +/// Computes the SHA1 hash of some data. +/// +/// # Warning +/// +/// SHA1 is known to be insecure - it should not be used unless required for +/// compatibility with existing systems. +#[corresponds(SHA1)] +#[inline] +pub fn sha1(data: &[u8]) -> [u8; 20] { + unsafe { + let mut hash = MaybeUninit::<[u8; 20]>::uninit(); + ffi::SHA1(data.as_ptr(), data.len(), hash.as_mut_ptr() as *mut _); + hash.assume_init() + } +} + +/// Computes the SHA224 hash of some data. +#[corresponds(SHA224)] +#[inline] +pub fn sha224(data: &[u8]) -> [u8; 28] { + unsafe { + let mut hash = MaybeUninit::<[u8; 28]>::uninit(); + ffi::SHA224(data.as_ptr(), data.len(), hash.as_mut_ptr() as *mut _); + hash.assume_init() + } +} + +/// Computes the SHA256 hash of some data. +#[corresponds(SHA256)] +#[inline] +pub fn sha256(data: &[u8]) -> [u8; 32] { + unsafe { + let mut hash = MaybeUninit::<[u8; 32]>::uninit(); + ffi::SHA256(data.as_ptr(), data.len(), hash.as_mut_ptr() as *mut _); + hash.assume_init() + } +} + +/// Computes the SHA384 hash of some data. +#[corresponds(SHA384)] +#[inline] +pub fn sha384(data: &[u8]) -> [u8; 48] { + unsafe { + let mut hash = MaybeUninit::<[u8; 48]>::uninit(); + ffi::SHA384(data.as_ptr(), data.len(), hash.as_mut_ptr() as *mut _); + hash.assume_init() + } +} + +/// Computes the SHA512 hash of some data. +#[corresponds(SHA512)] +#[inline] +pub fn sha512(data: &[u8]) -> [u8; 64] { + unsafe { + let mut hash = MaybeUninit::<[u8; 64]>::uninit(); + ffi::SHA512(data.as_ptr(), data.len(), hash.as_mut_ptr() as *mut _); + hash.assume_init() + } +} + +cfg_if! { + if #[cfg(not(osslconf = "OPENSSL_NO_DEPRECATED_3_0"))] { + /// An object which calculates a SHA1 hash of some data. + /// + /// # Warning + /// + /// SHA1 is known to be insecure - it should not be used unless required for + /// compatibility with existing systems. + #[derive(Clone)] + pub struct Sha1(ffi::SHA_CTX); + + impl Default for Sha1 { + #[inline] + fn default() -> Sha1 { + Sha1::new() + } + } + + impl Sha1 { + /// Creates a new hasher. + #[corresponds(SHA1_Init)] + #[inline] + pub fn new() -> Sha1 { + unsafe { + let mut ctx = MaybeUninit::uninit(); + ffi::SHA1_Init( ctx.as_mut_ptr()); + Sha1(ctx.assume_init()) + } + } + + /// Feeds some data into the hasher. + /// + /// This can be called multiple times. + #[corresponds(SHA1_Update)] + #[inline] + pub fn update(&mut self, buf: &[u8]) { + unsafe { + ffi::SHA1_Update(&mut self.0, buf.as_ptr() as *const c_void, buf.len()); + } + } + + /// Returns the hash of the data. + #[corresponds(SHA1_Final)] + #[inline] + pub fn finish(mut self) -> [u8; 20] { + unsafe { + let mut hash = MaybeUninit::<[u8; 20]>::uninit(); + ffi::SHA1_Final(hash.as_mut_ptr() as *mut _, &mut self.0); + hash.assume_init() + } + } + } + + /// An object which calculates a SHA224 hash of some data. + #[derive(Clone)] + pub struct Sha224(ffi::SHA256_CTX); + + impl Default for Sha224 { + #[inline] + fn default() -> Sha224 { + Sha224::new() + } + } + + impl Sha224 { + /// Creates a new hasher. + #[corresponds(SHA224_Init)] + #[inline] + pub fn new() -> Sha224 { + unsafe { + let mut ctx = MaybeUninit::uninit(); + ffi::SHA224_Init(ctx.as_mut_ptr()); + Sha224(ctx.assume_init()) + } + } + + /// Feeds some data into the hasher. + /// + /// This can be called multiple times. + #[corresponds(SHA224_Update)] + #[inline] + pub fn update(&mut self, buf: &[u8]) { + unsafe { + ffi::SHA224_Update(&mut self.0, buf.as_ptr() as *const c_void, buf.len()); + } + } + + /// Returns the hash of the data. + #[corresponds(SHA224_Final)] + #[inline] + pub fn finish(mut self) -> [u8; 28] { + unsafe { + let mut hash = MaybeUninit::<[u8; 28]>::uninit(); + ffi::SHA224_Final(hash.as_mut_ptr() as *mut _, &mut self.0); + hash.assume_init() + } + } + } + + /// An object which calculates a SHA256 hash of some data. + #[derive(Clone)] + pub struct Sha256(ffi::SHA256_CTX); + + impl Default for Sha256 { + #[inline] + fn default() -> Sha256 { + Sha256::new() + } + } + + impl Sha256 { + /// Creates a new hasher. + #[corresponds(SHA256_Init)] + #[inline] + pub fn new() -> Sha256 { + unsafe { + let mut ctx = MaybeUninit::uninit(); + ffi::SHA256_Init(ctx.as_mut_ptr()); + Sha256(ctx.assume_init()) + } + } + + /// Feeds some data into the hasher. + /// + /// This can be called multiple times. + #[corresponds(SHA256_Update)] + #[inline] + pub fn update(&mut self, buf: &[u8]) { + unsafe { + ffi::SHA256_Update(&mut self.0, buf.as_ptr() as *const c_void, buf.len()); + } + } + + /// Returns the hash of the data. + #[corresponds(SHA256_Final)] + #[inline] + pub fn finish(mut self) -> [u8; 32] { + unsafe { + let mut hash = MaybeUninit::<[u8; 32]>::uninit(); + ffi::SHA256_Final(hash.as_mut_ptr() as *mut _, &mut self.0); + hash.assume_init() + } + } + } + + /// An object which calculates a SHA384 hash of some data. + #[derive(Clone)] + pub struct Sha384(ffi::SHA512_CTX); + + impl Default for Sha384 { + #[inline] + fn default() -> Sha384 { + Sha384::new() + } + } + + impl Sha384 { + /// Creates a new hasher. + #[corresponds(SHA384_Init)] + #[inline] + pub fn new() -> Sha384 { + unsafe { + let mut ctx = MaybeUninit::uninit(); + ffi::SHA384_Init(ctx.as_mut_ptr()); + Sha384(ctx.assume_init()) + } + } + + /// Feeds some data into the hasher. + /// + /// This can be called multiple times. + #[corresponds(SHA384_Update)] + #[inline] + pub fn update(&mut self, buf: &[u8]) { + unsafe { + ffi::SHA384_Update(&mut self.0, buf.as_ptr() as *const c_void, buf.len()); + } + } + + /// Returns the hash of the data. + #[corresponds(SHA384_Final)] + #[inline] + pub fn finish(mut self) -> [u8; 48] { + unsafe { + let mut hash = MaybeUninit::<[u8; 48]>::uninit(); + ffi::SHA384_Final(hash.as_mut_ptr() as *mut _, &mut self.0); + hash.assume_init() + } + } + } + + /// An object which calculates a SHA512 hash of some data. + #[derive(Clone)] + pub struct Sha512(ffi::SHA512_CTX); + + impl Default for Sha512 { + #[inline] + fn default() -> Sha512 { + Sha512::new() + } + } + + impl Sha512 { + /// Creates a new hasher. + #[corresponds(SHA512_Init)] + #[inline] + pub fn new() -> Sha512 { + unsafe { + let mut ctx = MaybeUninit::uninit(); + ffi::SHA512_Init(ctx.as_mut_ptr()); + Sha512(ctx.assume_init()) + } + } + + /// Feeds some data into the hasher. + /// + /// This can be called multiple times. + #[corresponds(SHA512_Update)] + #[inline] + pub fn update(&mut self, buf: &[u8]) { + unsafe { + ffi::SHA512_Update(&mut self.0, buf.as_ptr() as *const c_void, buf.len()); + } + } + + /// Returns the hash of the data. + #[corresponds(SHA512_Final)] + #[inline] + pub fn finish(mut self) -> [u8; 64] { + unsafe { + let mut hash= MaybeUninit::<[u8; 64]>::uninit(); + ffi::SHA512_Final(hash.as_mut_ptr() as *mut _, &mut self.0); + hash.assume_init() + } + } + } + } +} + +#[cfg(test)] +mod test { + use super::*; + + #[test] + fn standalone_1() { + let data = b"abc"; + let expected = "a9993e364706816aba3e25717850c26c9cd0d89d"; + + assert_eq!(hex::encode(sha1(data)), expected); + } + + #[test] + #[cfg(not(osslconf = "OPENSSL_NO_DEPRECATED_3_0"))] + fn struct_1() { + let expected = "a9993e364706816aba3e25717850c26c9cd0d89d"; + + let mut hasher = Sha1::new(); + hasher.update(b"a"); + hasher.update(b"bc"); + assert_eq!(hex::encode(hasher.finish()), expected); + } + + #[test] + #[cfg(not(osslconf = "OPENSSL_NO_DEPRECATED_3_0"))] + fn cloning_allows_incremental_hashing() { + let expected = "a9993e364706816aba3e25717850c26c9cd0d89d"; + + let mut hasher = Sha1::new(); + hasher.update(b"a"); + + let mut incr_hasher = hasher.clone(); + incr_hasher.update(b"bc"); + + assert_eq!(hex::encode(incr_hasher.finish()), expected); + assert_ne!(hex::encode(hasher.finish()), expected); + } + + #[test] + fn standalone_224() { + let data = b"abc"; + let expected = "23097d223405d8228642a477bda255b32aadbce4bda0b3f7e36c9da7"; + + assert_eq!(hex::encode(sha224(data)), expected); + } + + #[test] + #[cfg(not(osslconf = "OPENSSL_NO_DEPRECATED_3_0"))] + fn struct_224() { + let expected = "23097d223405d8228642a477bda255b32aadbce4bda0b3f7e36c9da7"; + + let mut hasher = Sha224::new(); + hasher.update(b"a"); + hasher.update(b"bc"); + assert_eq!(hex::encode(hasher.finish()), expected); + } + + #[test] + fn standalone_256() { + let data = b"abc"; + let expected = "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad"; + + assert_eq!(hex::encode(sha256(data)), expected); + } + + #[test] + #[cfg(not(osslconf = "OPENSSL_NO_DEPRECATED_3_0"))] + fn struct_256() { + let expected = "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad"; + + let mut hasher = Sha256::new(); + hasher.update(b"a"); + hasher.update(b"bc"); + assert_eq!(hex::encode(hasher.finish()), expected); + } + + #[test] + fn standalone_384() { + let data = b"abc"; + let expected = + "cb00753f45a35e8bb5a03d699ac65007272c32ab0eded1631a8b605a43ff5bed8086072ba1e\ + 7cc2358baeca134c825a7"; + + assert_eq!(hex::encode(&sha384(data)[..]), expected); + } + + #[test] + #[cfg(not(osslconf = "OPENSSL_NO_DEPRECATED_3_0"))] + fn struct_384() { + let expected = + "cb00753f45a35e8bb5a03d699ac65007272c32ab0eded1631a8b605a43ff5bed8086072ba1e\ + 7cc2358baeca134c825a7"; + + let mut hasher = Sha384::new(); + hasher.update(b"a"); + hasher.update(b"bc"); + assert_eq!(hex::encode(&hasher.finish()[..]), expected); + } + + #[test] + fn standalone_512() { + let data = b"abc"; + let expected = + "ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a2192992a274\ + fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f"; + + assert_eq!(hex::encode(&sha512(data)[..]), expected); + } + + #[test] + #[cfg(not(osslconf = "OPENSSL_NO_DEPRECATED_3_0"))] + fn struct_512() { + let expected = + "ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a2192992a274\ + fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f"; + + let mut hasher = Sha512::new(); + hasher.update(b"a"); + hasher.update(b"bc"); + assert_eq!(hex::encode(&hasher.finish()[..]), expected); + } +} diff --git a/vendor/openssl/src/sign.rs b/vendor/openssl/src/sign.rs new file mode 100644 index 0000000..bea91a5 --- /dev/null +++ b/vendor/openssl/src/sign.rs @@ -0,0 +1,834 @@ +//! Message signatures. +//! +//! The `Signer` allows for the computation of cryptographic signatures of +//! data given a private key. The `Verifier` can then be used with the +//! corresponding public key to verify the integrity and authenticity of that +//! data given the signature. +//! +//! # Examples +//! +//! Sign and verify data given an RSA keypair: +//! +//! ```rust +//! use openssl::sign::{Signer, Verifier}; +//! use openssl::rsa::Rsa; +//! use openssl::pkey::PKey; +//! use openssl::hash::MessageDigest; +//! +//! // Generate a keypair +//! let keypair = Rsa::generate(2048).unwrap(); +//! let keypair = PKey::from_rsa(keypair).unwrap(); +//! +//! let data = b"hello, world!"; +//! let data2 = b"hola, mundo!"; +//! +//! // Sign the data +//! let mut signer = Signer::new(MessageDigest::sha256(), &keypair).unwrap(); +//! signer.update(data).unwrap(); +//! signer.update(data2).unwrap(); +//! let signature = signer.sign_to_vec().unwrap(); +//! +//! // Verify the data +//! let mut verifier = Verifier::new(MessageDigest::sha256(), &keypair).unwrap(); +//! verifier.update(data).unwrap(); +//! verifier.update(data2).unwrap(); +//! assert!(verifier.verify(&signature).unwrap()); +//! ``` + +#![cfg_attr( + not(boringssl), + doc = r#"\ + +Compute an HMAC: + +```rust +use openssl::hash::MessageDigest; +use openssl::memcmp; +use openssl::pkey::PKey; +use openssl::sign::Signer; + +// Create a PKey +let key = PKey::hmac(b"my secret").unwrap(); + +let data = b"hello, world!"; +let data2 = b"hola, mundo!"; + +// Compute the HMAC +let mut signer = Signer::new(MessageDigest::sha256(), &key).unwrap(); +signer.update(data).unwrap(); +signer.update(data2).unwrap(); +let hmac = signer.sign_to_vec().unwrap(); + +// `Verifier` cannot be used with HMACs; use the `memcmp::eq` function instead +// +// Do not simply check for equality with `==`! +# let target = hmac.clone(); +assert!(memcmp::eq(&hmac, &target)); +```"# +)] + +use cfg_if::cfg_if; +use foreign_types::ForeignTypeRef; +use libc::c_int; +use std::io::{self, Write}; +use std::marker::PhantomData; +use std::ptr; + +use crate::error::ErrorStack; +use crate::hash::MessageDigest; +use crate::pkey::{HasPrivate, HasPublic, PKeyRef}; +use crate::rsa::Padding; +use crate::{cvt, cvt_p}; +use openssl_macros::corresponds; + +cfg_if! { + if #[cfg(any(ossl110, libressl382))] { + use ffi::{EVP_MD_CTX_free, EVP_MD_CTX_new}; + } else { + use ffi::{EVP_MD_CTX_create as EVP_MD_CTX_new, EVP_MD_CTX_destroy as EVP_MD_CTX_free}; + } +} + +/// Salt lengths that must be used with `set_rsa_pss_saltlen`. +pub struct RsaPssSaltlen(c_int); + +impl RsaPssSaltlen { + /// Returns the integer representation of `RsaPssSaltlen`. + pub(crate) fn as_raw(&self) -> c_int { + self.0 + } + + /// Sets the salt length to the given value. + pub fn custom(val: c_int) -> RsaPssSaltlen { + RsaPssSaltlen(val) + } + + /// The salt length is set to the digest length. + /// Corresponds to the special value `-1`. + pub const DIGEST_LENGTH: RsaPssSaltlen = RsaPssSaltlen(-1); + /// The salt length is set to the maximum permissible value. + /// Corresponds to the special value `-2`. + pub const MAXIMUM_LENGTH: RsaPssSaltlen = RsaPssSaltlen(-2); +} + +/// A type which computes cryptographic signatures of data. +pub struct Signer<'a> { + md_ctx: *mut ffi::EVP_MD_CTX, + pctx: *mut ffi::EVP_PKEY_CTX, + _p: PhantomData<&'a ()>, +} + +unsafe impl Sync for Signer<'_> {} +unsafe impl Send for Signer<'_> {} + +impl Drop for Signer<'_> { + fn drop(&mut self) { + // pkey_ctx is owned by the md_ctx, so no need to explicitly free it. + unsafe { + EVP_MD_CTX_free(self.md_ctx); + } + } +} + +#[allow(clippy::len_without_is_empty)] +impl Signer<'_> { + /// Creates a new `Signer`. + /// + /// This cannot be used with Ed25519 or Ed448 keys. Please refer to + /// `new_without_digest`. + #[corresponds(EVP_DigestSignInit)] + pub fn new<'a, T>(type_: MessageDigest, pkey: &PKeyRef) -> Result, ErrorStack> + where + T: HasPrivate, + { + Self::new_intern(Some(type_), pkey) + } + + /// Creates a new `Signer` without a digest. + /// + /// This is the only way to create a `Verifier` for Ed25519 or Ed448 keys. + /// It can also be used to create a CMAC. + #[corresponds(EVP_DigestSignInit)] + pub fn new_without_digest<'a, T>(pkey: &PKeyRef) -> Result, ErrorStack> + where + T: HasPrivate, + { + Self::new_intern(None, pkey) + } + + fn new_intern<'a, T>( + type_: Option, + pkey: &PKeyRef, + ) -> Result, ErrorStack> + where + T: HasPrivate, + { + unsafe { + ffi::init(); + + let ctx = cvt_p(EVP_MD_CTX_new())?; + let mut pctx: *mut ffi::EVP_PKEY_CTX = ptr::null_mut(); + let r = ffi::EVP_DigestSignInit( + ctx, + &mut pctx, + type_.map(|t| t.as_ptr()).unwrap_or(ptr::null()), + ptr::null_mut(), + pkey.as_ptr(), + ); + if r != 1 { + EVP_MD_CTX_free(ctx); + return Err(ErrorStack::get()); + } + + assert!(!pctx.is_null()); + + Ok(Signer { + md_ctx: ctx, + pctx, + _p: PhantomData, + }) + } + } + + /// Returns the RSA padding mode in use. + /// + /// This is only useful for RSA keys. + #[corresponds(EVP_PKEY_CTX_get_rsa_padding)] + pub fn rsa_padding(&self) -> Result { + unsafe { + let mut pad = 0; + cvt(ffi::EVP_PKEY_CTX_get_rsa_padding(self.pctx, &mut pad)) + .map(|_| Padding::from_raw(pad)) + } + } + + /// Sets the RSA padding mode. + /// + /// This is only useful for RSA keys. + #[corresponds(EVP_PKEY_CTX_set_rsa_padding)] + pub fn set_rsa_padding(&mut self, padding: Padding) -> Result<(), ErrorStack> { + unsafe { + cvt(ffi::EVP_PKEY_CTX_set_rsa_padding( + self.pctx, + padding.as_raw(), + )) + .map(|_| ()) + } + } + + /// Sets the RSA PSS salt length. + /// + /// This is only useful for RSA keys. + #[corresponds(EVP_PKEY_CTX_set_rsa_pss_saltlen)] + pub fn set_rsa_pss_saltlen(&mut self, len: RsaPssSaltlen) -> Result<(), ErrorStack> { + unsafe { + cvt(ffi::EVP_PKEY_CTX_set_rsa_pss_saltlen( + self.pctx, + len.as_raw(), + )) + .map(|_| ()) + } + } + + /// Sets the RSA MGF1 algorithm. + /// + /// This is only useful for RSA keys. + #[corresponds(EVP_PKEY_CTX_set_rsa_mgf1_md)] + pub fn set_rsa_mgf1_md(&mut self, md: MessageDigest) -> Result<(), ErrorStack> { + unsafe { + cvt(ffi::EVP_PKEY_CTX_set_rsa_mgf1_md( + self.pctx, + md.as_ptr() as *mut _, + )) + .map(|_| ()) + } + } + + /// Feeds more data into the `Signer`. + /// + /// Please note that PureEdDSA (Ed25519 and Ed448 keys) do not support streaming. + /// Use `sign_oneshot` instead. + #[corresponds(EVP_DigestUpdate)] + pub fn update(&mut self, buf: &[u8]) -> Result<(), ErrorStack> { + unsafe { + cvt(ffi::EVP_DigestUpdate( + self.md_ctx, + buf.as_ptr() as *const _, + buf.len(), + )) + .map(|_| ()) + } + } + + /// Computes an upper bound on the signature length. + /// + /// The actual signature may be shorter than this value. Check the return value of + /// `sign` to get the exact length. + #[corresponds(EVP_DigestSignFinal)] + pub fn len(&self) -> Result { + self.len_intern() + } + + #[cfg(all(not(ossl111), not(boringssl), not(libressl370)))] + fn len_intern(&self) -> Result { + unsafe { + let mut len = 0; + cvt(ffi::EVP_DigestSignFinal( + self.md_ctx, + ptr::null_mut(), + &mut len, + ))?; + Ok(len) + } + } + + #[cfg(any(ossl111, boringssl, libressl370))] + fn len_intern(&self) -> Result { + unsafe { + let mut len = 0; + cvt(ffi::EVP_DigestSign( + self.md_ctx, + ptr::null_mut(), + &mut len, + ptr::null(), + 0, + ))?; + Ok(len) + } + } + + /// Writes the signature into the provided buffer, returning the number of bytes written. + /// + /// This method will fail if the buffer is not large enough for the signature. Use the `len` + /// method to get an upper bound on the required size. + #[corresponds(EVP_DigestSignFinal)] + pub fn sign(&self, buf: &mut [u8]) -> Result { + unsafe { + let mut len = buf.len(); + cvt(ffi::EVP_DigestSignFinal( + self.md_ctx, + buf.as_mut_ptr() as *mut _, + &mut len, + ))?; + Ok(len) + } + } + + /// Returns the signature. + /// + /// This is a simple convenience wrapper over `len` and `sign`. + pub fn sign_to_vec(&self) -> Result, ErrorStack> { + let mut buf = vec![0; self.len()?]; + let len = self.sign(&mut buf)?; + // The advertised length is not always equal to the real length for things like DSA + buf.truncate(len); + Ok(buf) + } + + /// Signs the data in `data_buf` and writes the signature into the buffer `sig_buf`, returning the + /// number of bytes written. + /// + /// For PureEdDSA (Ed25519 and Ed448 keys), this is the only way to sign data. + /// + /// This method will fail if the buffer is not large enough for the signature. Use the `len` + /// method to get an upper bound on the required size. + #[corresponds(EVP_DigestSign)] + #[cfg(any(ossl111, boringssl, libressl370))] + pub fn sign_oneshot( + &mut self, + sig_buf: &mut [u8], + data_buf: &[u8], + ) -> Result { + unsafe { + let mut sig_len = sig_buf.len(); + cvt(ffi::EVP_DigestSign( + self.md_ctx, + sig_buf.as_mut_ptr() as *mut _, + &mut sig_len, + data_buf.as_ptr() as *const _, + data_buf.len(), + ))?; + Ok(sig_len) + } + } + + /// Returns the signature. + /// + /// This is a simple convenience wrapper over `len` and `sign_oneshot`. + #[cfg(any(ossl111, boringssl, libressl370))] + pub fn sign_oneshot_to_vec(&mut self, data_buf: &[u8]) -> Result, ErrorStack> { + let mut sig_buf = vec![0; self.len()?]; + let len = self.sign_oneshot(&mut sig_buf, data_buf)?; + // The advertised length is not always equal to the real length for things like DSA + sig_buf.truncate(len); + Ok(sig_buf) + } +} + +impl Write for Signer<'_> { + fn write(&mut self, buf: &[u8]) -> io::Result { + self.update(buf)?; + Ok(buf.len()) + } + + fn flush(&mut self) -> io::Result<()> { + Ok(()) + } +} + +/// A type which can be used to verify the integrity and authenticity +/// of data given the signature. +pub struct Verifier<'a> { + md_ctx: *mut ffi::EVP_MD_CTX, + pctx: *mut ffi::EVP_PKEY_CTX, + pkey_pd: PhantomData<&'a ()>, +} + +unsafe impl Sync for Verifier<'_> {} +unsafe impl Send for Verifier<'_> {} + +impl Drop for Verifier<'_> { + fn drop(&mut self) { + // pkey_ctx is owned by the md_ctx, so no need to explicitly free it. + unsafe { + EVP_MD_CTX_free(self.md_ctx); + } + } +} + +/// A type which verifies cryptographic signatures of data. +impl<'a> Verifier<'a> { + /// Creates a new `Verifier`. + /// + /// This cannot be used with Ed25519 or Ed448 keys. Please refer to + /// [`Verifier::new_without_digest`]. + #[corresponds(EVP_DigestVerifyInit)] + pub fn new(type_: MessageDigest, pkey: &'a PKeyRef) -> Result, ErrorStack> + where + T: HasPublic, + { + Verifier::new_intern(Some(type_), pkey) + } + + /// Creates a new `Verifier` without a digest. + /// + /// This is the only way to create a `Verifier` for Ed25519 or Ed448 keys. + #[corresponds(EVP_DigestVerifyInit)] + pub fn new_without_digest(pkey: &'a PKeyRef) -> Result, ErrorStack> + where + T: HasPublic, + { + Verifier::new_intern(None, pkey) + } + + fn new_intern( + type_: Option, + pkey: &'a PKeyRef, + ) -> Result, ErrorStack> + where + T: HasPublic, + { + unsafe { + ffi::init(); + + let ctx = cvt_p(EVP_MD_CTX_new())?; + let mut pctx: *mut ffi::EVP_PKEY_CTX = ptr::null_mut(); + let r = ffi::EVP_DigestVerifyInit( + ctx, + &mut pctx, + type_.map(|t| t.as_ptr()).unwrap_or(ptr::null()), + ptr::null_mut(), + pkey.as_ptr(), + ); + if r != 1 { + EVP_MD_CTX_free(ctx); + return Err(ErrorStack::get()); + } + + assert!(!pctx.is_null()); + + Ok(Verifier { + md_ctx: ctx, + pctx, + pkey_pd: PhantomData, + }) + } + } + + /// Returns the RSA padding mode in use. + /// + /// This is only useful for RSA keys. + #[corresponds(EVP_PKEY_CTX_get_rsa_padding)] + pub fn rsa_padding(&self) -> Result { + unsafe { + let mut pad = 0; + cvt(ffi::EVP_PKEY_CTX_get_rsa_padding(self.pctx, &mut pad)) + .map(|_| Padding::from_raw(pad)) + } + } + + /// Sets the RSA padding mode. + /// + /// This is only useful for RSA keys. + #[corresponds(EVP_PKEY_CTX_set_rsa_padding)] + pub fn set_rsa_padding(&mut self, padding: Padding) -> Result<(), ErrorStack> { + unsafe { + cvt(ffi::EVP_PKEY_CTX_set_rsa_padding( + self.pctx, + padding.as_raw(), + )) + .map(|_| ()) + } + } + + /// Sets the RSA PSS salt length. + /// + /// This is only useful for RSA keys. + #[corresponds(EVP_PKEY_CTX_set_rsa_pss_saltlen)] + pub fn set_rsa_pss_saltlen(&mut self, len: RsaPssSaltlen) -> Result<(), ErrorStack> { + unsafe { + cvt(ffi::EVP_PKEY_CTX_set_rsa_pss_saltlen( + self.pctx, + len.as_raw(), + )) + .map(|_| ()) + } + } + + /// Sets the RSA MGF1 algorithm. + /// + /// This is only useful for RSA keys. + #[corresponds(EVP_PKEY_CTX_set_rsa_mgf1_md)] + pub fn set_rsa_mgf1_md(&mut self, md: MessageDigest) -> Result<(), ErrorStack> { + unsafe { + cvt(ffi::EVP_PKEY_CTX_set_rsa_mgf1_md( + self.pctx, + md.as_ptr() as *mut _, + )) + .map(|_| ()) + } + } + + /// Feeds more data into the `Verifier`. + /// + /// Please note that PureEdDSA (Ed25519 and Ed448 keys) do not support streaming. + /// Use [`Verifier::verify_oneshot`] instead. + #[corresponds(EVP_DigestUpdate)] + pub fn update(&mut self, buf: &[u8]) -> Result<(), ErrorStack> { + unsafe { + cvt(ffi::EVP_DigestUpdate( + self.md_ctx, + buf.as_ptr() as *const _, + buf.len(), + )) + .map(|_| ()) + } + } + + /// Determines if the data fed into the `Verifier` matches the provided signature. + #[corresponds(EVP_DigestVerifyFinal)] + pub fn verify(&self, signature: &[u8]) -> Result { + unsafe { + let r = + EVP_DigestVerifyFinal(self.md_ctx, signature.as_ptr() as *mut _, signature.len()); + match r { + 1 => Ok(true), + 0 => { + ErrorStack::get(); // discard error stack + Ok(false) + } + _ => Err(ErrorStack::get()), + } + } + } + + /// Determines if the data given in `buf` matches the provided signature. + #[corresponds(EVP_DigestVerify)] + #[cfg(any(ossl111, boringssl, libressl370))] + pub fn verify_oneshot(&mut self, signature: &[u8], buf: &[u8]) -> Result { + unsafe { + let r = ffi::EVP_DigestVerify( + self.md_ctx, + signature.as_ptr() as *const _, + signature.len(), + buf.as_ptr() as *const _, + buf.len(), + ); + match r { + 1 => Ok(true), + 0 => { + ErrorStack::get(); + Ok(false) + } + _ => Err(ErrorStack::get()), + } + } + } +} + +impl Write for Verifier<'_> { + fn write(&mut self, buf: &[u8]) -> io::Result { + self.update(buf)?; + Ok(buf.len()) + } + + fn flush(&mut self) -> io::Result<()> { + Ok(()) + } +} + +#[cfg(not(ossl101))] +use ffi::EVP_DigestVerifyFinal; + +#[cfg(ossl101)] +#[allow(bad_style)] +unsafe fn EVP_DigestVerifyFinal( + ctx: *mut ffi::EVP_MD_CTX, + sigret: *const ::libc::c_uchar, + siglen: ::libc::size_t, +) -> ::libc::c_int { + ffi::EVP_DigestVerifyFinal(ctx, sigret as *mut _, siglen) +} + +#[cfg(test)] +mod test { + use hex::{self, FromHex}; + #[cfg(not(boringssl))] + use std::iter; + + use crate::ec::{EcGroup, EcKey}; + use crate::hash::MessageDigest; + use crate::nid::Nid; + use crate::pkey::PKey; + use crate::rsa::{Padding, Rsa}; + #[cfg(ossl111)] + use crate::sign::RsaPssSaltlen; + use crate::sign::{Signer, Verifier}; + + const INPUT: &str = + "65794a68624763694f694a53557a49314e694a392e65794a7063334d694f694a71623255694c41304b49434a6c\ + 654841694f6a457a4d4441344d546b7a4f44417344516f67496d6830644841364c79396c654746746347786c4c\ + 6d4e76625339706331397962323930496a7030636e566c6651"; + + const SIGNATURE: &str = + "702e218943e88fd11eb5d82dbf7845f34106ae1b81fff7731116add1717d83656d420afd3c96eedd73a2663e51\ + 66687b000b87226e0187ed1073f945e582adfcef16d85a798ee8c66ddb3db8975b17d09402beedd5d9d9700710\ + 8db28160d5f8040ca7445762b81fbe7ff9d92e0ae76f24f25b33bbe6f44ae61eb1040acb20044d3ef9128ed401\ + 30795bd4bd3b41eecad066ab651981fde48df77f372dc38b9fafdd3befb18b5da3cc3c2eb02f9e3a41d612caad\ + 15911273a05f23b9e838faaf849d698429ef5a1e88798236c3d40e604522a544c8f27a7a2db80663d16cf7caea\ + 56de405cb2215a45b2c25566b55ac1a748a070dfc8a32a469543d019eefb47"; + + #[test] + fn rsa_sign() { + let key = include_bytes!("../test/rsa.pem"); + let private_key = Rsa::private_key_from_pem(key).unwrap(); + let pkey = PKey::from_rsa(private_key).unwrap(); + + let mut signer = Signer::new(MessageDigest::sha256(), &pkey).unwrap(); + assert_eq!(signer.rsa_padding().unwrap(), Padding::PKCS1); + signer.set_rsa_padding(Padding::PKCS1).unwrap(); + signer.update(&Vec::from_hex(INPUT).unwrap()).unwrap(); + let result = signer.sign_to_vec().unwrap(); + + assert_eq!(hex::encode(result), SIGNATURE); + } + + #[test] + fn rsa_verify_ok() { + let key = include_bytes!("../test/rsa.pem"); + let private_key = Rsa::private_key_from_pem(key).unwrap(); + let pkey = PKey::from_rsa(private_key).unwrap(); + + let mut verifier = Verifier::new(MessageDigest::sha256(), &pkey).unwrap(); + assert_eq!(verifier.rsa_padding().unwrap(), Padding::PKCS1); + verifier.update(&Vec::from_hex(INPUT).unwrap()).unwrap(); + assert!(verifier.verify(&Vec::from_hex(SIGNATURE).unwrap()).unwrap()); + } + + #[test] + fn rsa_verify_invalid() { + let key = include_bytes!("../test/rsa.pem"); + let private_key = Rsa::private_key_from_pem(key).unwrap(); + let pkey = PKey::from_rsa(private_key).unwrap(); + + let mut verifier = Verifier::new(MessageDigest::sha256(), &pkey).unwrap(); + verifier.update(&Vec::from_hex(INPUT).unwrap()).unwrap(); + verifier.update(b"foobar").unwrap(); + assert!(!verifier.verify(&Vec::from_hex(SIGNATURE).unwrap()).unwrap()); + } + + #[cfg(not(boringssl))] + fn test_hmac(ty: MessageDigest, tests: &[(Vec, Vec, Vec)]) { + for (key, data, res) in tests.iter() { + let pkey = PKey::hmac(key).unwrap(); + let mut signer = Signer::new(ty, &pkey).unwrap(); + signer.update(data).unwrap(); + assert_eq!(signer.sign_to_vec().unwrap(), *res); + } + } + + #[test] + #[cfg(not(boringssl))] + fn hmac_md5() { + // test vectors from RFC 2202 + let tests: [(Vec, Vec, Vec); 7] = [ + ( + iter::repeat(0x0b_u8).take(16).collect(), + b"Hi There".to_vec(), + Vec::from_hex("9294727a3638bb1c13f48ef8158bfc9d").unwrap(), + ), + ( + b"Jefe".to_vec(), + b"what do ya want for nothing?".to_vec(), + Vec::from_hex("750c783e6ab0b503eaa86e310a5db738").unwrap(), + ), + ( + iter::repeat(0xaa_u8).take(16).collect(), + iter::repeat(0xdd_u8).take(50).collect(), + Vec::from_hex("56be34521d144c88dbb8c733f0e8b3f6").unwrap(), + ), + ( + Vec::from_hex("0102030405060708090a0b0c0d0e0f10111213141516171819").unwrap(), + iter::repeat(0xcd_u8).take(50).collect(), + Vec::from_hex("697eaf0aca3a3aea3a75164746ffaa79").unwrap(), + ), + ( + iter::repeat(0x0c_u8).take(16).collect(), + b"Test With Truncation".to_vec(), + Vec::from_hex("56461ef2342edc00f9bab995690efd4c").unwrap(), + ), + ( + iter::repeat(0xaa_u8).take(80).collect(), + b"Test Using Larger Than Block-Size Key - Hash Key First".to_vec(), + Vec::from_hex("6b1ab7fe4bd7bf8f0b62e6ce61b9d0cd").unwrap(), + ), + ( + iter::repeat(0xaa_u8).take(80).collect(), + b"Test Using Larger Than Block-Size Key \ + and Larger Than One Block-Size Data" + .to_vec(), + Vec::from_hex("6f630fad67cda0ee1fb1f562db3aa53e").unwrap(), + ), + ]; + + test_hmac(MessageDigest::md5(), &tests); + } + + #[test] + #[cfg(not(boringssl))] + fn hmac_sha1() { + // test vectors from RFC 2202 + let tests: [(Vec, Vec, Vec); 7] = [ + ( + iter::repeat(0x0b_u8).take(20).collect(), + b"Hi There".to_vec(), + Vec::from_hex("b617318655057264e28bc0b6fb378c8ef146be00").unwrap(), + ), + ( + b"Jefe".to_vec(), + b"what do ya want for nothing?".to_vec(), + Vec::from_hex("effcdf6ae5eb2fa2d27416d5f184df9c259a7c79").unwrap(), + ), + ( + iter::repeat(0xaa_u8).take(20).collect(), + iter::repeat(0xdd_u8).take(50).collect(), + Vec::from_hex("125d7342b9ac11cd91a39af48aa17b4f63f175d3").unwrap(), + ), + ( + Vec::from_hex("0102030405060708090a0b0c0d0e0f10111213141516171819").unwrap(), + iter::repeat(0xcd_u8).take(50).collect(), + Vec::from_hex("4c9007f4026250c6bc8414f9bf50c86c2d7235da").unwrap(), + ), + ( + iter::repeat(0x0c_u8).take(20).collect(), + b"Test With Truncation".to_vec(), + Vec::from_hex("4c1a03424b55e07fe7f27be1d58bb9324a9a5a04").unwrap(), + ), + ( + iter::repeat(0xaa_u8).take(80).collect(), + b"Test Using Larger Than Block-Size Key - Hash Key First".to_vec(), + Vec::from_hex("aa4ae5e15272d00e95705637ce8a3b55ed402112").unwrap(), + ), + ( + iter::repeat(0xaa_u8).take(80).collect(), + b"Test Using Larger Than Block-Size Key \ + and Larger Than One Block-Size Data" + .to_vec(), + Vec::from_hex("e8e99d0f45237d786d6bbaa7965c7808bbff1a91").unwrap(), + ), + ]; + + test_hmac(MessageDigest::sha1(), &tests); + } + + #[test] + #[cfg(ossl110)] + fn test_cmac() { + let cipher = crate::symm::Cipher::aes_128_cbc(); + let key = Vec::from_hex("9294727a3638bb1c13f48ef8158bfc9d").unwrap(); + let pkey = PKey::cmac(&cipher, &key).unwrap(); + let mut signer = Signer::new_without_digest(&pkey).unwrap(); + + let data = b"Hi There"; + signer.update(data as &[u8]).unwrap(); + + let expected = vec![ + 136, 101, 61, 167, 61, 30, 248, 234, 124, 166, 196, 157, 203, 52, 171, 19, + ]; + assert_eq!(signer.sign_to_vec().unwrap(), expected); + } + + #[test] + fn ec() { + let group = EcGroup::from_curve_name(Nid::X9_62_PRIME256V1).unwrap(); + let key = EcKey::generate(&group).unwrap(); + let key = PKey::from_ec_key(key).unwrap(); + + let mut signer = Signer::new(MessageDigest::sha256(), &key).unwrap(); + signer.update(b"hello world").unwrap(); + let signature = signer.sign_to_vec().unwrap(); + + let mut verifier = Verifier::new(MessageDigest::sha256(), &key).unwrap(); + verifier.update(b"hello world").unwrap(); + assert!(verifier.verify(&signature).unwrap()); + } + + #[test] + #[cfg(any(ossl111, boringssl, libressl370))] + fn eddsa() { + let key = PKey::generate_ed25519().unwrap(); + + let mut signer = Signer::new_without_digest(&key).unwrap(); + let signature = signer.sign_oneshot_to_vec(b"hello world").unwrap(); + + let mut verifier = Verifier::new_without_digest(&key).unwrap(); + assert!(verifier.verify_oneshot(&signature, b"hello world").unwrap()); + } + + #[test] + #[cfg(ossl111)] + fn rsa_sign_verify() { + let key = include_bytes!("../test/rsa.pem"); + let private_key = Rsa::private_key_from_pem(key).unwrap(); + let pkey = PKey::from_rsa(private_key).unwrap(); + + let mut signer = Signer::new(MessageDigest::sha256(), &pkey).unwrap(); + signer.set_rsa_padding(Padding::PKCS1_PSS).unwrap(); + assert_eq!(signer.rsa_padding().unwrap(), Padding::PKCS1_PSS); + signer + .set_rsa_pss_saltlen(RsaPssSaltlen::DIGEST_LENGTH) + .unwrap(); + signer.set_rsa_mgf1_md(MessageDigest::sha256()).unwrap(); + signer.update(&Vec::from_hex(INPUT).unwrap()).unwrap(); + let signature = signer.sign_to_vec().unwrap(); + + let mut verifier = Verifier::new(MessageDigest::sha256(), &pkey).unwrap(); + verifier.set_rsa_padding(Padding::PKCS1_PSS).unwrap(); + verifier + .set_rsa_pss_saltlen(RsaPssSaltlen::DIGEST_LENGTH) + .unwrap(); + verifier.set_rsa_mgf1_md(MessageDigest::sha256()).unwrap(); + verifier.update(&Vec::from_hex(INPUT).unwrap()).unwrap(); + assert!(verifier.verify(&signature).unwrap()); + } +} diff --git a/vendor/openssl/src/srtp.rs b/vendor/openssl/src/srtp.rs new file mode 100644 index 0000000..595757d --- /dev/null +++ b/vendor/openssl/src/srtp.rs @@ -0,0 +1,66 @@ +use crate::stack::Stackable; +use foreign_types::ForeignTypeRef; +use libc::c_ulong; +use std::ffi::CStr; +use std::str; + +/// fake free method, since SRTP_PROTECTION_PROFILE is static +unsafe fn free(_profile: *mut ffi::SRTP_PROTECTION_PROFILE) {} + +foreign_type_and_impl_send_sync! { + type CType = ffi::SRTP_PROTECTION_PROFILE; + fn drop = free; + + pub struct SrtpProtectionProfile; + /// Reference to `SrtpProtectionProfile`. + pub struct SrtpProtectionProfileRef; +} + +impl Stackable for SrtpProtectionProfile { + type StackType = ffi::stack_st_SRTP_PROTECTION_PROFILE; +} + +impl SrtpProtectionProfileRef { + pub fn id(&self) -> SrtpProfileId { + SrtpProfileId::from_raw(unsafe { (*self.as_ptr()).id }) + } + pub fn name(&self) -> &'static str { + unsafe { CStr::from_ptr((*self.as_ptr()).name as *const _) } + .to_str() + .expect("should be UTF-8") + } +} + +/// An identifier of an SRTP protection profile. +#[derive(Debug, Copy, Clone, PartialEq, Eq)] +pub struct SrtpProfileId(c_ulong); + +impl SrtpProfileId { + pub const SRTP_AES128_CM_SHA1_80: SrtpProfileId = + SrtpProfileId(ffi::SRTP_AES128_CM_SHA1_80 as c_ulong); + pub const SRTP_AES128_CM_SHA1_32: SrtpProfileId = + SrtpProfileId(ffi::SRTP_AES128_CM_SHA1_32 as c_ulong); + pub const SRTP_AES128_F8_SHA1_80: SrtpProfileId = + SrtpProfileId(ffi::SRTP_AES128_F8_SHA1_80 as c_ulong); + pub const SRTP_AES128_F8_SHA1_32: SrtpProfileId = + SrtpProfileId(ffi::SRTP_AES128_F8_SHA1_32 as c_ulong); + pub const SRTP_NULL_SHA1_80: SrtpProfileId = SrtpProfileId(ffi::SRTP_NULL_SHA1_80 as c_ulong); + pub const SRTP_NULL_SHA1_32: SrtpProfileId = SrtpProfileId(ffi::SRTP_NULL_SHA1_32 as c_ulong); + #[cfg(any(boringssl, ossl110))] + pub const SRTP_AEAD_AES_128_GCM: SrtpProfileId = + SrtpProfileId(ffi::SRTP_AEAD_AES_128_GCM as c_ulong); + #[cfg(any(boringssl, ossl110))] + pub const SRTP_AEAD_AES_256_GCM: SrtpProfileId = + SrtpProfileId(ffi::SRTP_AEAD_AES_256_GCM as c_ulong); + + /// Creates a `SrtpProfileId` from an integer representation. + pub fn from_raw(value: c_ulong) -> SrtpProfileId { + SrtpProfileId(value) + } + + /// Returns the integer representation of `SrtpProfileId`. + #[allow(clippy::trivially_copy_pass_by_ref)] + pub fn as_raw(&self) -> c_ulong { + self.0 + } +} diff --git a/vendor/openssl/src/ssl/bio.rs b/vendor/openssl/src/ssl/bio.rs new file mode 100644 index 0000000..1648562 --- /dev/null +++ b/vendor/openssl/src/ssl/bio.rs @@ -0,0 +1,289 @@ +use cfg_if::cfg_if; +use ffi::{ + self, BIO_clear_retry_flags, BIO_new, BIO_set_retry_read, BIO_set_retry_write, BIO, + BIO_CTRL_DGRAM_QUERY_MTU, BIO_CTRL_FLUSH, +}; +use libc::{c_char, c_int, c_long, c_void, strlen}; +use std::any::Any; +use std::io; +use std::io::prelude::*; +use std::panic::{catch_unwind, AssertUnwindSafe}; +use std::ptr; + +use crate::error::ErrorStack; +use crate::{cvt_p, util}; + +pub struct StreamState { + pub stream: S, + pub error: Option, + pub panic: Option>, + pub dtls_mtu_size: c_long, +} + +/// Safe wrapper for `BIO_METHOD` +pub struct BioMethod(BIO_METHOD); + +impl BioMethod { + fn new() -> Result { + BIO_METHOD::new::().map(BioMethod) + } +} + +unsafe impl Sync for BioMethod {} +unsafe impl Send for BioMethod {} + +pub fn new(stream: S) -> Result<(*mut BIO, BioMethod), ErrorStack> { + let method = BioMethod::new::()?; + + let state = Box::new(StreamState { + stream, + error: None, + panic: None, + dtls_mtu_size: 0, + }); + + unsafe { + let bio = cvt_p(BIO_new(method.0.get()))?; + BIO_set_data(bio, Box::into_raw(state) as *mut _); + BIO_set_init(bio, 1); + + Ok((bio, method)) + } +} + +pub unsafe fn take_error(bio: *mut BIO) -> Option { + let state = state::(bio); + state.error.take() +} + +pub unsafe fn take_panic(bio: *mut BIO) -> Option> { + let state = state::(bio); + state.panic.take() +} + +pub unsafe fn get_ref<'a, S: 'a>(bio: *mut BIO) -> &'a S { + let state = &*(BIO_get_data(bio) as *const StreamState); + &state.stream +} + +pub unsafe fn get_mut<'a, S: 'a>(bio: *mut BIO) -> &'a mut S { + &mut state(bio).stream +} + +pub unsafe fn set_dtls_mtu_size(bio: *mut BIO, mtu_size: usize) { + if mtu_size as u64 > c_long::MAX as u64 { + panic!( + "Given MTU size {} can't be represented in a positive `c_long` range", + mtu_size + ) + } + state::(bio).dtls_mtu_size = mtu_size as c_long; +} + +unsafe fn state<'a, S: 'a>(bio: *mut BIO) -> &'a mut StreamState { + &mut *(BIO_get_data(bio) as *mut _) +} + +unsafe extern "C" fn bwrite(bio: *mut BIO, buf: *const c_char, len: c_int) -> c_int { + BIO_clear_retry_flags(bio); + + let state = state::(bio); + let buf = util::from_raw_parts(buf as *const _, len as usize); + + match catch_unwind(AssertUnwindSafe(|| state.stream.write(buf))) { + Ok(Ok(len)) => len as c_int, + Ok(Err(err)) => { + if retriable_error(&err) { + BIO_set_retry_write(bio); + } + state.error = Some(err); + -1 + } + Err(err) => { + state.panic = Some(err); + -1 + } + } +} + +unsafe extern "C" fn bread(bio: *mut BIO, buf: *mut c_char, len: c_int) -> c_int { + BIO_clear_retry_flags(bio); + + let state = state::(bio); + let buf = util::from_raw_parts_mut(buf as *mut _, len as usize); + + match catch_unwind(AssertUnwindSafe(|| state.stream.read(buf))) { + Ok(Ok(len)) => len as c_int, + Ok(Err(err)) => { + if retriable_error(&err) { + BIO_set_retry_read(bio); + } + state.error = Some(err); + -1 + } + Err(err) => { + state.panic = Some(err); + -1 + } + } +} + +#[allow(clippy::match_like_matches_macro)] // matches macro requires rust 1.42.0 +fn retriable_error(err: &io::Error) -> bool { + match err.kind() { + io::ErrorKind::WouldBlock | io::ErrorKind::NotConnected => true, + _ => false, + } +} + +unsafe extern "C" fn bputs(bio: *mut BIO, s: *const c_char) -> c_int { + bwrite::(bio, s, strlen(s) as c_int) +} + +unsafe extern "C" fn ctrl( + bio: *mut BIO, + cmd: c_int, + _num: c_long, + _ptr: *mut c_void, +) -> c_long { + let state = state::(bio); + + if cmd == BIO_CTRL_FLUSH { + match catch_unwind(AssertUnwindSafe(|| state.stream.flush())) { + Ok(Ok(())) => 1, + Ok(Err(err)) => { + state.error = Some(err); + 0 + } + Err(err) => { + state.panic = Some(err); + 0 + } + } + } else if cmd == BIO_CTRL_DGRAM_QUERY_MTU { + state.dtls_mtu_size + } else { + 0 + } +} + +unsafe extern "C" fn create(bio: *mut BIO) -> c_int { + BIO_set_init(bio, 0); + BIO_set_num(bio, 0); + BIO_set_data(bio, ptr::null_mut()); + BIO_set_flags(bio, 0); + 1 +} + +unsafe extern "C" fn destroy(bio: *mut BIO) -> c_int { + if bio.is_null() { + return 0; + } + + let data = BIO_get_data(bio); + assert!(!data.is_null()); + let _ = Box::>::from_raw(data as *mut _); + BIO_set_data(bio, ptr::null_mut()); + BIO_set_init(bio, 0); + 1 +} + +cfg_if! { + if #[cfg(any(ossl110, libressl273))] { + use ffi::{BIO_get_data, BIO_set_data, BIO_set_flags, BIO_set_init}; + use crate::cvt; + + #[allow(bad_style)] + unsafe fn BIO_set_num(_bio: *mut ffi::BIO, _num: c_int) {} + + #[allow(bad_style, clippy::upper_case_acronyms)] + struct BIO_METHOD(*mut ffi::BIO_METHOD); + + impl BIO_METHOD { + fn new() -> Result { + unsafe { + let ptr = cvt_p(ffi::BIO_meth_new(ffi::BIO_TYPE_NONE, b"rust\0".as_ptr() as *const _))?; + let method = BIO_METHOD(ptr); + cvt(ffi::BIO_meth_set_write__fixed_rust(method.0, Some(bwrite::)))?; + cvt(ffi::BIO_meth_set_read__fixed_rust(method.0, Some(bread::)))?; + cvt(ffi::BIO_meth_set_puts__fixed_rust(method.0, Some(bputs::)))?; + cvt(ffi::BIO_meth_set_ctrl__fixed_rust(method.0, Some(ctrl::)))?; + cvt(ffi::BIO_meth_set_create__fixed_rust(method.0, Some(create)))?; + cvt(ffi::BIO_meth_set_destroy__fixed_rust(method.0, Some(destroy::)))?; + Ok(method) + } + } + + fn get(&self) -> *mut ffi::BIO_METHOD { + self.0 + } + } + + impl Drop for BIO_METHOD { + fn drop(&mut self) { + unsafe { + ffi::BIO_meth_free(self.0); + } + } + } + } else { + #[allow(bad_style, clippy::upper_case_acronyms)] + struct BIO_METHOD(*mut ffi::BIO_METHOD); + + impl BIO_METHOD { + fn new() -> Result { + let ptr = Box::new(ffi::BIO_METHOD { + type_: ffi::BIO_TYPE_NONE, + name: b"rust\0".as_ptr() as *const _, + bwrite: Some(bwrite::), + bread: Some(bread::), + bputs: Some(bputs::), + bgets: None, + ctrl: Some(ctrl::), + create: Some(create), + destroy: Some(destroy::), + callback_ctrl: None, + }); + + Ok(BIO_METHOD(Box::into_raw(ptr))) + } + + fn get(&self) -> *mut ffi::BIO_METHOD { + self.0 + } + } + + impl Drop for BIO_METHOD { + fn drop(&mut self) { + unsafe { + let _ = Box::::from_raw(self.0); + } + } + } + + #[allow(bad_style)] + unsafe fn BIO_set_init(bio: *mut ffi::BIO, init: c_int) { + (*bio).init = init; + } + + #[allow(bad_style)] + unsafe fn BIO_set_flags(bio: *mut ffi::BIO, flags: c_int) { + (*bio).flags = flags; + } + + #[allow(bad_style)] + unsafe fn BIO_get_data(bio: *mut ffi::BIO) -> *mut c_void { + (*bio).ptr + } + + #[allow(bad_style)] + unsafe fn BIO_set_data(bio: *mut ffi::BIO, data: *mut c_void) { + (*bio).ptr = data; + } + + #[allow(bad_style)] + unsafe fn BIO_set_num(bio: *mut ffi::BIO, num: c_int) { + (*bio).num = num; + } + } +} diff --git a/vendor/openssl/src/ssl/callbacks.rs b/vendor/openssl/src/ssl/callbacks.rs new file mode 100644 index 0000000..ccf5308 --- /dev/null +++ b/vendor/openssl/src/ssl/callbacks.rs @@ -0,0 +1,707 @@ +use cfg_if::cfg_if; +use foreign_types::ForeignType; +use foreign_types::ForeignTypeRef; +#[cfg(any(ossl111, not(osslconf = "OPENSSL_NO_PSK")))] +use libc::c_char; +#[cfg(ossl111)] +use libc::size_t; +use libc::{c_int, c_uchar, c_uint, c_void}; +#[cfg(any(ossl111, not(osslconf = "OPENSSL_NO_PSK")))] +use std::ffi::CStr; +use std::mem; +use std::ptr; +#[cfg(any(ossl111, boringssl))] +use std::str; +use std::sync::Arc; + +use crate::dh::Dh; +#[cfg(all(ossl101, not(ossl110)))] +use crate::ec::EcKey; +use crate::error::ErrorStack; +use crate::pkey::Params; +#[cfg(any(ossl102, libressl261))] +use crate::ssl::AlpnError; +use crate::ssl::{ + try_get_session_ctx_index, SniError, Ssl, SslAlert, SslContext, SslContextRef, SslRef, + SslSession, SslSessionRef, +}; +#[cfg(ossl111)] +use crate::ssl::{ClientHelloResponse, ExtensionContext}; +use crate::util; +#[cfg(any(ossl111, boringssl))] +use crate::util::ForeignTypeRefExt; +#[cfg(ossl111)] +use crate::x509::X509Ref; +use crate::x509::{X509StoreContext, X509StoreContextRef}; + +pub extern "C" fn raw_verify(preverify_ok: c_int, x509_ctx: *mut ffi::X509_STORE_CTX) -> c_int +where + F: Fn(bool, &mut X509StoreContextRef) -> bool + 'static + Sync + Send, +{ + unsafe { + let ctx = X509StoreContextRef::from_ptr_mut(x509_ctx); + let ssl_idx = X509StoreContext::ssl_idx().expect("BUG: store context ssl index missing"); + let verify_idx = SslContext::cached_ex_index::(); + + // raw pointer shenanigans to break the borrow of ctx + // the callback can't mess with its own ex_data slot so this is safe + let verify = ctx + .ex_data(ssl_idx) + .expect("BUG: store context missing ssl") + .ssl_context() + .ex_data(verify_idx) + .expect("BUG: verify callback missing") as *const F; + + (*verify)(preverify_ok != 0, ctx) as c_int + } +} + +#[cfg(not(osslconf = "OPENSSL_NO_PSK"))] +pub extern "C" fn raw_client_psk( + ssl: *mut ffi::SSL, + hint: *const c_char, + identity: *mut c_char, + max_identity_len: c_uint, + psk: *mut c_uchar, + max_psk_len: c_uint, +) -> c_uint +where + F: Fn(&mut SslRef, Option<&[u8]>, &mut [u8], &mut [u8]) -> Result + + 'static + + Sync + + Send, +{ + unsafe { + let ssl = SslRef::from_ptr_mut(ssl); + let callback_idx = SslContext::cached_ex_index::(); + + let callback = ssl + .ssl_context() + .ex_data(callback_idx) + .expect("BUG: psk callback missing") as *const F; + let hint = if !hint.is_null() { + Some(CStr::from_ptr(hint).to_bytes()) + } else { + None + }; + // Give the callback mutable slices into which it can write the identity and psk. + let identity_sl = util::from_raw_parts_mut(identity as *mut u8, max_identity_len as usize); + #[allow(clippy::unnecessary_cast)] + let psk_sl = util::from_raw_parts_mut(psk as *mut u8, max_psk_len as usize); + match (*callback)(ssl, hint, identity_sl, psk_sl) { + Ok(psk_len) => psk_len as u32, + Err(e) => { + e.put(); + 0 + } + } + } +} + +#[cfg(not(osslconf = "OPENSSL_NO_PSK"))] +pub extern "C" fn raw_server_psk( + ssl: *mut ffi::SSL, + identity: *const c_char, + psk: *mut c_uchar, + max_psk_len: c_uint, +) -> c_uint +where + F: Fn(&mut SslRef, Option<&[u8]>, &mut [u8]) -> Result + + 'static + + Sync + + Send, +{ + unsafe { + let ssl = SslRef::from_ptr_mut(ssl); + let callback_idx = SslContext::cached_ex_index::(); + + let callback = ssl + .ssl_context() + .ex_data(callback_idx) + .expect("BUG: psk callback missing") as *const F; + let identity = if identity.is_null() { + None + } else { + Some(CStr::from_ptr(identity).to_bytes()) + }; + // Give the callback mutable slices into which it can write the psk. + #[allow(clippy::unnecessary_cast)] + let psk_sl = util::from_raw_parts_mut(psk as *mut u8, max_psk_len as usize); + match (*callback)(ssl, identity, psk_sl) { + Ok(psk_len) => psk_len as u32, + Err(e) => { + e.put(); + 0 + } + } + } +} + +pub extern "C" fn ssl_raw_verify( + preverify_ok: c_int, + x509_ctx: *mut ffi::X509_STORE_CTX, +) -> c_int +where + F: Fn(bool, &mut X509StoreContextRef) -> bool + 'static + Sync + Send, +{ + unsafe { + let ctx = X509StoreContextRef::from_ptr_mut(x509_ctx); + let ssl_idx = X509StoreContext::ssl_idx().expect("BUG: store context ssl index missing"); + let callback_idx = Ssl::cached_ex_index::>(); + + let callback = ctx + .ex_data(ssl_idx) + .expect("BUG: store context missing ssl") + .ex_data(callback_idx) + .expect("BUG: ssl verify callback missing") + .clone(); + + callback(preverify_ok != 0, ctx) as c_int + } +} + +pub extern "C" fn raw_sni(ssl: *mut ffi::SSL, al: *mut c_int, arg: *mut c_void) -> c_int +where + F: Fn(&mut SslRef, &mut SslAlert) -> Result<(), SniError> + 'static + Sync + Send, +{ + unsafe { + let ssl = SslRef::from_ptr_mut(ssl); + let callback = arg as *const F; + let mut alert = SslAlert(*al); + + let r = (*callback)(ssl, &mut alert); + *al = alert.0; + match r { + Ok(()) => ffi::SSL_TLSEXT_ERR_OK, + Err(e) => e.0, + } + } +} + +#[cfg(any(ossl102, libressl261))] +pub extern "C" fn raw_alpn_select( + ssl: *mut ffi::SSL, + out: *mut *const c_uchar, + outlen: *mut c_uchar, + inbuf: *const c_uchar, + inlen: c_uint, + _arg: *mut c_void, +) -> c_int +where + F: for<'a> Fn(&mut SslRef, &'a [u8]) -> Result<&'a [u8], AlpnError> + 'static + Sync + Send, +{ + unsafe { + let ssl = SslRef::from_ptr_mut(ssl); + let callback = ssl + .ssl_context() + .ex_data(SslContext::cached_ex_index::()) + .expect("BUG: alpn callback missing") as *const F; + #[allow(clippy::unnecessary_cast)] + let protos = util::from_raw_parts(inbuf as *const u8, inlen as usize); + + match (*callback)(ssl, protos) { + Ok(proto) => { + *out = proto.as_ptr() as *const c_uchar; + *outlen = proto.len() as c_uchar; + ffi::SSL_TLSEXT_ERR_OK + } + Err(e) => e.0, + } + } +} + +pub unsafe extern "C" fn raw_tmp_dh( + ssl: *mut ffi::SSL, + is_export: c_int, + keylength: c_int, +) -> *mut ffi::DH +where + F: Fn(&mut SslRef, bool, u32) -> Result, ErrorStack> + 'static + Sync + Send, +{ + let ssl = SslRef::from_ptr_mut(ssl); + let callback = ssl + .ssl_context() + .ex_data(SslContext::cached_ex_index::()) + .expect("BUG: tmp dh callback missing") as *const F; + + match (*callback)(ssl, is_export != 0, keylength as u32) { + Ok(dh) => { + let ptr = dh.as_ptr(); + mem::forget(dh); + ptr + } + Err(e) => { + e.put(); + ptr::null_mut() + } + } +} + +#[cfg(all(ossl101, not(ossl110)))] +pub unsafe extern "C" fn raw_tmp_ecdh( + ssl: *mut ffi::SSL, + is_export: c_int, + keylength: c_int, +) -> *mut ffi::EC_KEY +where + F: Fn(&mut SslRef, bool, u32) -> Result, ErrorStack> + 'static + Sync + Send, +{ + let ssl = SslRef::from_ptr_mut(ssl); + let callback = ssl + .ssl_context() + .ex_data(SslContext::cached_ex_index::()) + .expect("BUG: tmp ecdh callback missing") as *const F; + + match (*callback)(ssl, is_export != 0, keylength as u32) { + Ok(ec_key) => { + let ptr = ec_key.as_ptr(); + mem::forget(ec_key); + ptr + } + Err(e) => { + e.put(); + ptr::null_mut() + } + } +} + +pub unsafe extern "C" fn raw_tmp_dh_ssl( + ssl: *mut ffi::SSL, + is_export: c_int, + keylength: c_int, +) -> *mut ffi::DH +where + F: Fn(&mut SslRef, bool, u32) -> Result, ErrorStack> + 'static + Sync + Send, +{ + let ssl = SslRef::from_ptr_mut(ssl); + let callback = ssl + .ex_data(Ssl::cached_ex_index::>()) + .expect("BUG: ssl tmp dh callback missing") + .clone(); + + match callback(ssl, is_export != 0, keylength as u32) { + Ok(dh) => { + let ptr = dh.as_ptr(); + mem::forget(dh); + ptr + } + Err(e) => { + e.put(); + ptr::null_mut() + } + } +} + +#[cfg(all(ossl101, not(ossl110)))] +pub unsafe extern "C" fn raw_tmp_ecdh_ssl( + ssl: *mut ffi::SSL, + is_export: c_int, + keylength: c_int, +) -> *mut ffi::EC_KEY +where + F: Fn(&mut SslRef, bool, u32) -> Result, ErrorStack> + 'static + Sync + Send, +{ + let ssl = SslRef::from_ptr_mut(ssl); + let callback = ssl + .ex_data(Ssl::cached_ex_index::>()) + .expect("BUG: ssl tmp ecdh callback missing") + .clone(); + + match callback(ssl, is_export != 0, keylength as u32) { + Ok(ec_key) => { + let ptr = ec_key.as_ptr(); + mem::forget(ec_key); + ptr + } + Err(e) => { + e.put(); + ptr::null_mut() + } + } +} + +pub unsafe extern "C" fn raw_tlsext_status(ssl: *mut ffi::SSL, _: *mut c_void) -> c_int +where + F: Fn(&mut SslRef) -> Result + 'static + Sync + Send, +{ + let ssl = SslRef::from_ptr_mut(ssl); + let callback = ssl + .ssl_context() + .ex_data(SslContext::cached_ex_index::()) + .expect("BUG: ocsp callback missing") as *const F; + let ret = (*callback)(ssl); + + if ssl.is_server() { + match ret { + Ok(true) => ffi::SSL_TLSEXT_ERR_OK, + Ok(false) => ffi::SSL_TLSEXT_ERR_NOACK, + Err(e) => { + e.put(); + ffi::SSL_TLSEXT_ERR_ALERT_FATAL + } + } + } else { + match ret { + Ok(true) => 1, + Ok(false) => 0, + Err(e) => { + e.put(); + -1 + } + } + } +} + +pub unsafe extern "C" fn raw_new_session( + ssl: *mut ffi::SSL, + session: *mut ffi::SSL_SESSION, +) -> c_int +where + F: Fn(&mut SslRef, SslSession) + 'static + Sync + Send, +{ + let session_ctx_index = + try_get_session_ctx_index().expect("BUG: session context index initialization failed"); + let ssl = SslRef::from_ptr_mut(ssl); + let callback = ssl + .ex_data(*session_ctx_index) + .expect("BUG: session context missing") + .ex_data(SslContext::cached_ex_index::()) + .expect("BUG: new session callback missing") as *const F; + let session = SslSession::from_ptr(session); + + (*callback)(ssl, session); + + // the return code doesn't indicate error vs success, but whether or not we consumed the session + 1 +} + +pub unsafe extern "C" fn raw_remove_session( + ctx: *mut ffi::SSL_CTX, + session: *mut ffi::SSL_SESSION, +) where + F: Fn(&SslContextRef, &SslSessionRef) + 'static + Sync + Send, +{ + let ctx = SslContextRef::from_ptr(ctx); + let callback = ctx + .ex_data(SslContext::cached_ex_index::()) + .expect("BUG: remove session callback missing"); + let session = SslSessionRef::from_ptr(session); + + callback(ctx, session) +} + +cfg_if! { + if #[cfg(any(ossl110, libressl280, boringssl))] { + type DataPtr = *const c_uchar; + } else { + type DataPtr = *mut c_uchar; + } +} + +pub unsafe extern "C" fn raw_get_session( + ssl: *mut ffi::SSL, + data: DataPtr, + len: c_int, + copy: *mut c_int, +) -> *mut ffi::SSL_SESSION +where + F: Fn(&mut SslRef, &[u8]) -> Option + 'static + Sync + Send, +{ + let session_ctx_index = + try_get_session_ctx_index().expect("BUG: session context index initialization failed"); + let ssl = SslRef::from_ptr_mut(ssl); + let callback = ssl + .ex_data(*session_ctx_index) + .expect("BUG: session context missing") + .ex_data(SslContext::cached_ex_index::()) + .expect("BUG: get session callback missing") as *const F; + #[allow(clippy::unnecessary_cast)] + let data = util::from_raw_parts(data as *const u8, len as usize); + + match (*callback)(ssl, data) { + Some(session) => { + let p = session.as_ptr(); + mem::forget(session); + *copy = 0; + p + } + None => ptr::null_mut(), + } +} + +#[cfg(any(ossl111, boringssl))] +pub unsafe extern "C" fn raw_keylog(ssl: *const ffi::SSL, line: *const c_char) +where + F: Fn(&SslRef, &str) + 'static + Sync + Send, +{ + let ssl = SslRef::from_const_ptr(ssl); + let callback = ssl + .ssl_context() + .ex_data(SslContext::cached_ex_index::()) + .expect("BUG: get session callback missing"); + let line = CStr::from_ptr(line).to_bytes(); + let line = str::from_utf8_unchecked(line); + + callback(ssl, line); +} + +#[cfg(ossl111)] +pub unsafe extern "C" fn raw_stateless_cookie_generate( + ssl: *mut ffi::SSL, + cookie: *mut c_uchar, + cookie_len: *mut size_t, +) -> c_int +where + F: Fn(&mut SslRef, &mut [u8]) -> Result + 'static + Sync + Send, +{ + let ssl = SslRef::from_ptr_mut(ssl); + let callback = ssl + .ssl_context() + .ex_data(SslContext::cached_ex_index::()) + .expect("BUG: stateless cookie generate callback missing") as *const F; + #[allow(clippy::unnecessary_cast)] + let slice = util::from_raw_parts_mut(cookie as *mut u8, ffi::SSL_COOKIE_LENGTH as usize); + match (*callback)(ssl, slice) { + Ok(len) => { + *cookie_len = len as size_t; + 1 + } + Err(e) => { + e.put(); + 0 + } + } +} + +#[cfg(ossl111)] +pub unsafe extern "C" fn raw_stateless_cookie_verify( + ssl: *mut ffi::SSL, + cookie: *const c_uchar, + cookie_len: size_t, +) -> c_int +where + F: Fn(&mut SslRef, &[u8]) -> bool + 'static + Sync + Send, +{ + let ssl = SslRef::from_ptr_mut(ssl); + let callback = ssl + .ssl_context() + .ex_data(SslContext::cached_ex_index::()) + .expect("BUG: stateless cookie verify callback missing") as *const F; + #[allow(clippy::unnecessary_cast)] + let slice = util::from_raw_parts(cookie as *const c_uchar as *const u8, cookie_len); + (*callback)(ssl, slice) as c_int +} + +#[cfg(not(boringssl))] +pub extern "C" fn raw_cookie_generate( + ssl: *mut ffi::SSL, + cookie: *mut c_uchar, + cookie_len: *mut c_uint, +) -> c_int +where + F: Fn(&mut SslRef, &mut [u8]) -> Result + 'static + Sync + Send, +{ + unsafe { + let ssl = SslRef::from_ptr_mut(ssl); + let callback = ssl + .ssl_context() + .ex_data(SslContext::cached_ex_index::()) + .expect("BUG: cookie generate callback missing") as *const F; + // We subtract 1 from DTLS1_COOKIE_LENGTH as the ostensible value, 256, is erroneous but retained for + // compatibility. See comments in dtls1.h. + #[allow(clippy::unnecessary_cast)] + let slice = + util::from_raw_parts_mut(cookie as *mut u8, ffi::DTLS1_COOKIE_LENGTH as usize - 1); + match (*callback)(ssl, slice) { + Ok(len) => { + *cookie_len = len as c_uint; + 1 + } + Err(e) => { + e.put(); + 0 + } + } + } +} + +#[cfg(not(boringssl))] +cfg_if! { + if #[cfg(any(ossl110, libressl280))] { + type CookiePtr = *const c_uchar; + } else { + type CookiePtr = *mut c_uchar; + } +} + +#[cfg(not(boringssl))] +pub extern "C" fn raw_cookie_verify( + ssl: *mut ffi::SSL, + cookie: CookiePtr, + cookie_len: c_uint, +) -> c_int +where + F: Fn(&mut SslRef, &[u8]) -> bool + 'static + Sync + Send, +{ + unsafe { + let ssl = SslRef::from_ptr_mut(ssl); + let callback = ssl + .ssl_context() + .ex_data(SslContext::cached_ex_index::()) + .expect("BUG: cookie verify callback missing") as *const F; + #[allow(clippy::unnecessary_cast)] + let slice = + util::from_raw_parts(cookie as *const c_uchar as *const u8, cookie_len as usize); + (*callback)(ssl, slice) as c_int + } +} + +#[cfg(ossl111)] +pub struct CustomExtAddState(Option); + +#[cfg(ossl111)] +pub extern "C" fn raw_custom_ext_add( + ssl: *mut ffi::SSL, + _: c_uint, + context: c_uint, + out: *mut *const c_uchar, + outlen: *mut size_t, + x: *mut ffi::X509, + chainidx: size_t, + al: *mut c_int, + _: *mut c_void, +) -> c_int +where + F: Fn(&mut SslRef, ExtensionContext, Option<(usize, &X509Ref)>) -> Result, SslAlert> + + 'static + + Sync + + Send, + T: AsRef<[u8]> + 'static + Sync + Send, +{ + unsafe { + let ssl = SslRef::from_ptr_mut(ssl); + let callback = ssl + .ssl_context() + .ex_data(SslContext::cached_ex_index::()) + .expect("BUG: custom ext add callback missing") as *const F; + let ectx = ExtensionContext::from_bits_truncate(context); + let cert = if ectx.contains(ExtensionContext::TLS1_3_CERTIFICATE) { + Some((chainidx, X509Ref::from_ptr(x))) + } else { + None + }; + match (*callback)(ssl, ectx, cert) { + Ok(None) => 0, + Ok(Some(buf)) => { + *outlen = buf.as_ref().len(); + *out = buf.as_ref().as_ptr(); + + let idx = Ssl::cached_ex_index::>(); + let mut buf = Some(buf); + let new = match ssl.ex_data_mut(idx) { + Some(state) => { + state.0 = buf.take(); + false + } + None => true, + }; + if new { + ssl.set_ex_data(idx, CustomExtAddState(buf)); + } + 1 + } + Err(alert) => { + *al = alert.0; + -1 + } + } + } +} + +#[cfg(ossl111)] +pub extern "C" fn raw_custom_ext_free( + ssl: *mut ffi::SSL, + _: c_uint, + _: c_uint, + _: *const c_uchar, + _: *mut c_void, +) where + T: 'static + Sync + Send, +{ + unsafe { + let ssl = SslRef::from_ptr_mut(ssl); + let idx = Ssl::cached_ex_index::>(); + if let Some(state) = ssl.ex_data_mut(idx) { + state.0 = None; + } + } +} + +#[cfg(ossl111)] +pub extern "C" fn raw_custom_ext_parse( + ssl: *mut ffi::SSL, + _: c_uint, + context: c_uint, + input: *const c_uchar, + inlen: size_t, + x: *mut ffi::X509, + chainidx: size_t, + al: *mut c_int, + _: *mut c_void, +) -> c_int +where + F: Fn(&mut SslRef, ExtensionContext, &[u8], Option<(usize, &X509Ref)>) -> Result<(), SslAlert> + + 'static + + Sync + + Send, +{ + unsafe { + let ssl = SslRef::from_ptr_mut(ssl); + let callback = ssl + .ssl_context() + .ex_data(SslContext::cached_ex_index::()) + .expect("BUG: custom ext parse callback missing") as *const F; + let ectx = ExtensionContext::from_bits_truncate(context); + #[allow(clippy::unnecessary_cast)] + let slice = util::from_raw_parts(input as *const u8, inlen); + let cert = if ectx.contains(ExtensionContext::TLS1_3_CERTIFICATE) { + Some((chainidx, X509Ref::from_ptr(x))) + } else { + None + }; + match (*callback)(ssl, ectx, slice, cert) { + Ok(()) => 1, + Err(alert) => { + *al = alert.0; + 0 + } + } + } +} + +#[cfg(ossl111)] +pub unsafe extern "C" fn raw_client_hello( + ssl: *mut ffi::SSL, + al: *mut c_int, + arg: *mut c_void, +) -> c_int +where + F: Fn(&mut SslRef, &mut SslAlert) -> Result + + 'static + + Sync + + Send, +{ + let ssl = SslRef::from_ptr_mut(ssl); + let callback = arg as *const F; + let mut alert = SslAlert(*al); + + let r = (*callback)(ssl, &mut alert); + *al = alert.0; + match r { + Ok(c) => c.0, + Err(e) => { + e.put(); + ffi::SSL_CLIENT_HELLO_ERROR + } + } +} diff --git a/vendor/openssl/src/ssl/connector.rs b/vendor/openssl/src/ssl/connector.rs new file mode 100644 index 0000000..66d1bd8 --- /dev/null +++ b/vendor/openssl/src/ssl/connector.rs @@ -0,0 +1,605 @@ +use cfg_if::cfg_if; +use std::io::{Read, Write}; +use std::ops::{Deref, DerefMut}; + +use crate::dh::Dh; +use crate::error::ErrorStack; +#[cfg(any(ossl111, libressl340))] +use crate::ssl::SslVersion; +use crate::ssl::{ + HandshakeError, Ssl, SslContext, SslContextBuilder, SslContextRef, SslMethod, SslMode, + SslOptions, SslRef, SslStream, SslVerifyMode, +}; +use crate::version; +use std::net::IpAddr; + +const FFDHE_2048: &str = " +-----BEGIN DH PARAMETERS----- +MIIBCAKCAQEA//////////+t+FRYortKmq/cViAnPTzx2LnFg84tNpWp4TZBFGQz ++8yTnc4kmz75fS/jY2MMddj2gbICrsRhetPfHtXV/WVhJDP1H18GbtCFY2VVPe0a +87VXE15/V8k1mE8McODmi3fipona8+/och3xWKE2rec1MKzKT0g6eXq8CrGCsyT7 +YdEIqUuyyOP7uWrat2DX9GgdT0Kj3jlN9K5W7edjcrsZCwenyO4KbXCeAvzhzffi +7MA0BM0oNC9hkXL+nOmFg/+OTxIy7vKBg8P+OxtMb61zO7X8vC7CIAXFjvGDfRaD +ssbzSibBsu/6iGtCOGEoXJf//////////wIBAg== +-----END DH PARAMETERS----- +"; + +#[allow(clippy::inconsistent_digit_grouping, clippy::unusual_byte_groupings)] +fn ctx(method: SslMethod) -> Result { + let mut ctx = SslContextBuilder::new(method)?; + + cfg_if! { + if #[cfg(not(boringssl))] { + let mut opts = SslOptions::ALL + | SslOptions::NO_COMPRESSION + | SslOptions::NO_SSLV2 + | SslOptions::NO_SSLV3 + | SslOptions::SINGLE_DH_USE + | SslOptions::SINGLE_ECDH_USE; + opts &= !SslOptions::DONT_INSERT_EMPTY_FRAGMENTS; + + ctx.set_options(opts); + } + } + + let mut mode = + SslMode::AUTO_RETRY | SslMode::ACCEPT_MOVING_WRITE_BUFFER | SslMode::ENABLE_PARTIAL_WRITE; + + // This is quite a useful optimization for saving memory, but historically + // caused CVEs in OpenSSL pre-1.0.1h, according to + // https://bugs.python.org/issue25672 + if version::number() >= 0x1_00_01_08_0 { + mode |= SslMode::RELEASE_BUFFERS; + } + + ctx.set_mode(mode); + + Ok(ctx) +} + +/// A type which wraps client-side streams in a TLS session. +/// +/// OpenSSL's default configuration is highly insecure. This connector manages the OpenSSL +/// structures, configuring cipher suites, session options, hostname verification, and more. +/// +/// OpenSSL's built-in hostname verification is used when linking against OpenSSL 1.0.2 or 1.1.0, +/// and a custom implementation is used when linking against OpenSSL 1.0.1. +#[derive(Clone, Debug)] +pub struct SslConnector(SslContext); + +impl SslConnector { + /// Creates a new builder for TLS connections. + /// + /// The default configuration is subject to change, and is currently derived from Python. + pub fn builder(method: SslMethod) -> Result { + let mut ctx = ctx(method)?; + ctx.set_default_verify_paths()?; + ctx.set_cipher_list( + "DEFAULT:!aNULL:!eNULL:!MD5:!3DES:!DES:!RC4:!IDEA:!SEED:!aDSS:!SRP:!PSK", + )?; + setup_verify(&mut ctx); + + Ok(SslConnectorBuilder(ctx)) + } + + /// Initiates a client-side TLS session on a stream. + /// + /// The domain is used for SNI and hostname verification. + pub fn connect(&self, domain: &str, stream: S) -> Result, HandshakeError> + where + S: Read + Write, + { + self.configure()?.connect(domain, stream) + } + + /// Returns a structure allowing for configuration of a single TLS session before connection. + pub fn configure(&self) -> Result { + Ssl::new(&self.0).map(|ssl| ConnectConfiguration { + ssl, + sni: true, + verify_hostname: true, + }) + } + + /// Consumes the `SslConnector`, returning the inner raw `SslContext`. + pub fn into_context(self) -> SslContext { + self.0 + } + + /// Returns a shared reference to the inner raw `SslContext`. + pub fn context(&self) -> &SslContextRef { + &self.0 + } +} + +/// A builder for `SslConnector`s. +pub struct SslConnectorBuilder(SslContextBuilder); + +impl SslConnectorBuilder { + /// Consumes the builder, returning an `SslConnector`. + pub fn build(self) -> SslConnector { + SslConnector(self.0.build()) + } +} + +impl Deref for SslConnectorBuilder { + type Target = SslContextBuilder; + + fn deref(&self) -> &SslContextBuilder { + &self.0 + } +} + +impl DerefMut for SslConnectorBuilder { + fn deref_mut(&mut self) -> &mut SslContextBuilder { + &mut self.0 + } +} + +/// A type which allows for configuration of a client-side TLS session before connection. +pub struct ConnectConfiguration { + ssl: Ssl, + sni: bool, + verify_hostname: bool, +} + +impl ConnectConfiguration { + /// A builder-style version of `set_use_server_name_indication`. + pub fn use_server_name_indication(mut self, use_sni: bool) -> ConnectConfiguration { + self.set_use_server_name_indication(use_sni); + self + } + + /// Configures the use of Server Name Indication (SNI) when connecting. + /// + /// Defaults to `true`. + pub fn set_use_server_name_indication(&mut self, use_sni: bool) { + self.sni = use_sni; + } + + /// A builder-style version of `set_verify_hostname`. + pub fn verify_hostname(mut self, verify_hostname: bool) -> ConnectConfiguration { + self.set_verify_hostname(verify_hostname); + self + } + + /// Configures the use of hostname verification when connecting. + /// + /// Defaults to `true`. + /// + /// # Warning + /// + /// You should think very carefully before you use this method. If hostname verification is not + /// used, *any* valid certificate for *any* site will be trusted for use from any other. This + /// introduces a significant vulnerability to man-in-the-middle attacks. + pub fn set_verify_hostname(&mut self, verify_hostname: bool) { + self.verify_hostname = verify_hostname; + } + + /// Returns an `Ssl` configured to connect to the provided domain. + /// + /// The domain is used for SNI (if it is not an IP address) and hostname verification if enabled. + pub fn into_ssl(mut self, domain: &str) -> Result { + if self.sni && domain.parse::().is_err() { + self.ssl.set_hostname(domain)?; + } + + if self.verify_hostname { + setup_verify_hostname(&mut self.ssl, domain)?; + } + + Ok(self.ssl) + } + + /// Initiates a client-side TLS session on a stream. + /// + /// The domain is used for SNI and hostname verification if enabled. + pub fn connect(self, domain: &str, stream: S) -> Result, HandshakeError> + where + S: Read + Write, + { + self.into_ssl(domain)?.connect(stream) + } +} + +impl Deref for ConnectConfiguration { + type Target = SslRef; + + fn deref(&self) -> &SslRef { + &self.ssl + } +} + +impl DerefMut for ConnectConfiguration { + fn deref_mut(&mut self) -> &mut SslRef { + &mut self.ssl + } +} + +/// A type which wraps server-side streams in a TLS session. +/// +/// OpenSSL's default configuration is highly insecure. This connector manages the OpenSSL +/// structures, configuring cipher suites, session options, and more. +#[derive(Clone)] +pub struct SslAcceptor(SslContext); + +impl SslAcceptor { + /// Creates a new builder configured to connect to non-legacy clients. This should generally be + /// considered a reasonable default choice. + /// + /// This corresponds to the intermediate configuration of version 5 of Mozilla's server side TLS + /// recommendations. See its [documentation][docs] for more details on specifics. + /// + /// [docs]: https://wiki.mozilla.org/Security/Server_Side_TLS + pub fn mozilla_intermediate_v5(method: SslMethod) -> Result { + let mut ctx = ctx(method)?; + ctx.set_options(SslOptions::NO_TLSV1 | SslOptions::NO_TLSV1_1); + let dh = Dh::params_from_pem(FFDHE_2048.as_bytes())?; + ctx.set_tmp_dh(&dh)?; + setup_curves(&mut ctx)?; + ctx.set_cipher_list( + "ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:\ + ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:\ + DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384" + )?; + #[cfg(any(ossl111, libressl340))] + ctx.set_ciphersuites( + "TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256", + )?; + Ok(SslAcceptorBuilder(ctx)) + } + + /// Creates a new builder configured to connect to modern clients. + /// + /// This corresponds to the modern configuration of version 5 of Mozilla's server side TLS recommendations. + /// See its [documentation][docs] for more details on specifics. + /// + /// Requires OpenSSL 1.1.1 or LibreSSL 3.4.0 or newer. + /// + /// [docs]: https://wiki.mozilla.org/Security/Server_Side_TLS + #[cfg(any(ossl111, libressl340))] + pub fn mozilla_modern_v5(method: SslMethod) -> Result { + let mut ctx = ctx(method)?; + ctx.set_min_proto_version(Some(SslVersion::TLS1_3))?; + ctx.set_ciphersuites( + "TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256", + )?; + Ok(SslAcceptorBuilder(ctx)) + } + + /// Creates a new builder configured to connect to non-legacy clients. This should generally be + /// considered a reasonable default choice. + /// + /// This corresponds to the intermediate configuration of version 4 of Mozilla's server side TLS + /// recommendations. See its [documentation][docs] for more details on specifics. + /// + /// [docs]: https://wiki.mozilla.org/Security/Server_Side_TLS + // FIXME remove in next major version + pub fn mozilla_intermediate(method: SslMethod) -> Result { + let mut ctx = ctx(method)?; + ctx.set_options(SslOptions::CIPHER_SERVER_PREFERENCE); + #[cfg(any(ossl111, libressl340))] + ctx.set_options(SslOptions::NO_TLSV1_3); + let dh = Dh::params_from_pem(FFDHE_2048.as_bytes())?; + ctx.set_tmp_dh(&dh)?; + setup_curves(&mut ctx)?; + ctx.set_cipher_list( + "ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:\ + ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:\ + DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:\ + ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:\ + ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:\ + DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:ECDHE-ECDSA-DES-CBC3-SHA:ECDHE-RSA-DES-CBC3-SHA:\ + EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:\ + AES256-SHA:DES-CBC3-SHA:!DSS", + )?; + Ok(SslAcceptorBuilder(ctx)) + } + + /// Creates a new builder configured to connect to modern clients. + /// + /// This corresponds to the modern configuration of version 4 of Mozilla's server side TLS recommendations. + /// See its [documentation][docs] for more details on specifics. + /// + /// [docs]: https://wiki.mozilla.org/Security/Server_Side_TLS + // FIXME remove in next major version + pub fn mozilla_modern(method: SslMethod) -> Result { + let mut ctx = ctx(method)?; + ctx.set_options( + SslOptions::CIPHER_SERVER_PREFERENCE | SslOptions::NO_TLSV1 | SslOptions::NO_TLSV1_1, + ); + #[cfg(any(ossl111, libressl340))] + ctx.set_options(SslOptions::NO_TLSV1_3); + setup_curves(&mut ctx)?; + ctx.set_cipher_list( + "ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:\ + ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:\ + ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256", + )?; + Ok(SslAcceptorBuilder(ctx)) + } + + /// Initiates a server-side TLS session on a stream. + pub fn accept(&self, stream: S) -> Result, HandshakeError> + where + S: Read + Write, + { + let ssl = Ssl::new(&self.0)?; + ssl.accept(stream) + } + + /// Consumes the `SslAcceptor`, returning the inner raw `SslContext`. + pub fn into_context(self) -> SslContext { + self.0 + } + + /// Returns a shared reference to the inner raw `SslContext`. + pub fn context(&self) -> &SslContextRef { + &self.0 + } +} + +/// A builder for `SslAcceptor`s. +pub struct SslAcceptorBuilder(SslContextBuilder); + +impl SslAcceptorBuilder { + /// Consumes the builder, returning a `SslAcceptor`. + pub fn build(self) -> SslAcceptor { + SslAcceptor(self.0.build()) + } +} + +impl Deref for SslAcceptorBuilder { + type Target = SslContextBuilder; + + fn deref(&self) -> &SslContextBuilder { + &self.0 + } +} + +impl DerefMut for SslAcceptorBuilder { + fn deref_mut(&mut self) -> &mut SslContextBuilder { + &mut self.0 + } +} + +cfg_if! { + if #[cfg(ossl110)] { + #[allow(clippy::unnecessary_wraps)] + fn setup_curves(_: &mut SslContextBuilder) -> Result<(), ErrorStack> { + Ok(()) + } + } else if #[cfg(any(ossl102, libressl))] { + fn setup_curves(ctx: &mut SslContextBuilder) -> Result<(), ErrorStack> { + ctx.set_ecdh_auto(true) + } + } else { + fn setup_curves(ctx: &mut SslContextBuilder) -> Result<(), ErrorStack> { + use crate::ec::EcKey; + use crate::nid::Nid; + + let curve = EcKey::from_curve_name(Nid::X9_62_PRIME256V1)?; + ctx.set_tmp_ecdh(&curve) + } + } +} + +cfg_if! { + if #[cfg(any(ossl102, libressl261))] { + fn setup_verify(ctx: &mut SslContextBuilder) { + ctx.set_verify(SslVerifyMode::PEER); + } + + fn setup_verify_hostname(ssl: &mut SslRef, domain: &str) -> Result<(), ErrorStack> { + use crate::x509::verify::X509CheckFlags; + + let param = ssl.param_mut(); + param.set_hostflags(X509CheckFlags::NO_PARTIAL_WILDCARDS); + match domain.parse() { + Ok(ip) => param.set_ip(ip), + Err(_) => param.set_host(domain), + } + } + } else { + fn setup_verify(ctx: &mut SslContextBuilder) { + ctx.set_verify_callback(SslVerifyMode::PEER, verify::verify_callback); + } + + fn setup_verify_hostname(ssl: &mut Ssl, domain: &str) -> Result<(), ErrorStack> { + let domain = domain.to_string(); + let hostname_idx = verify::try_get_hostname_idx()?; + ssl.set_ex_data(*hostname_idx, domain); + Ok(()) + } + + mod verify { + use std::net::IpAddr; + use std::str; + use once_cell::sync::OnceCell; + + use crate::error::ErrorStack; + use crate::ex_data::Index; + use crate::nid::Nid; + use crate::ssl::Ssl; + use crate::stack::Stack; + use crate::x509::{ + GeneralName, X509NameRef, X509Ref, X509StoreContext, X509StoreContextRef, + X509VerifyResult, + }; + + static HOSTNAME_IDX: OnceCell> = OnceCell::new(); + + pub fn try_get_hostname_idx() -> Result<&'static Index, ErrorStack> { + HOSTNAME_IDX.get_or_try_init(Ssl::new_ex_index) + } + + pub fn verify_callback(preverify_ok: bool, x509_ctx: &mut X509StoreContextRef) -> bool { + if !preverify_ok || x509_ctx.error_depth() != 0 { + return preverify_ok; + } + + let hostname_idx = + try_get_hostname_idx().expect("failed to initialize hostname index"); + let ok = match ( + x509_ctx.current_cert(), + X509StoreContext::ssl_idx() + .ok() + .and_then(|idx| x509_ctx.ex_data(idx)) + .and_then(|ssl| ssl.ex_data(*hostname_idx)), + ) { + (Some(x509), Some(domain)) => verify_hostname(domain, &x509), + _ => true, + }; + + if !ok { + x509_ctx.set_error(X509VerifyResult::APPLICATION_VERIFICATION); + } + + ok + } + + fn verify_hostname(domain: &str, cert: &X509Ref) -> bool { + match cert.subject_alt_names() { + Some(names) => verify_subject_alt_names(domain, names), + None => verify_subject_name(domain, &cert.subject_name()), + } + } + + fn verify_subject_alt_names(domain: &str, names: Stack) -> bool { + let ip = domain.parse(); + + for name in &names { + match ip { + Ok(ip) => { + if let Some(actual) = name.ipaddress() { + if matches_ip(&ip, actual) { + return true; + } + } + } + Err(_) => { + if let Some(pattern) = name.dnsname() { + if matches_dns(pattern, domain) { + return true; + } + } + } + } + } + + false + } + + fn verify_subject_name(domain: &str, subject_name: &X509NameRef) -> bool { + match subject_name.entries_by_nid(Nid::COMMONNAME).next() { + Some(pattern) => { + let pattern = match str::from_utf8(pattern.data().as_slice()) { + Ok(pattern) => pattern, + Err(_) => return false, + }; + + // Unlike SANs, IP addresses in the subject name don't have a + // different encoding. + match domain.parse::() { + Ok(ip) => pattern + .parse::() + .ok() + .map_or(false, |pattern| pattern == ip), + Err(_) => matches_dns(pattern, domain), + } + } + None => false, + } + } + + fn matches_dns(mut pattern: &str, mut hostname: &str) -> bool { + // first strip trailing . off of pattern and hostname to normalize + if pattern.ends_with('.') { + pattern = &pattern[..pattern.len() - 1]; + } + if hostname.ends_with('.') { + hostname = &hostname[..hostname.len() - 1]; + } + + matches_wildcard(pattern, hostname).unwrap_or_else(|| pattern.eq_ignore_ascii_case(hostname)) + } + + fn matches_wildcard(pattern: &str, hostname: &str) -> Option { + let wildcard_location = match pattern.find('*') { + Some(l) => l, + None => return None, + }; + + let mut dot_idxs = pattern.match_indices('.').map(|(l, _)| l); + let wildcard_end = match dot_idxs.next() { + Some(l) => l, + None => return None, + }; + + // Never match wildcards if the pattern has less than 2 '.'s (no *.com) + // + // This is a bit dubious, as it doesn't disallow other TLDs like *.co.uk. + // Chrome has a black- and white-list for this, but Firefox (via NSS) does + // the same thing we do here. + // + // The Public Suffix (https://www.publicsuffix.org/) list could + // potentially be used here, but it's both huge and updated frequently + // enough that management would be a PITA. + if dot_idxs.next().is_none() { + return None; + } + + // Wildcards can only be in the first component, and must be the entire first label + if wildcard_location != 0 || wildcard_end != wildcard_location + 1 { + return None; + } + + let hostname_label_end = match hostname.find('.') { + Some(l) => l, + None => return None, + }; + + let pattern_after_wildcard = &pattern[wildcard_end..]; + let hostname_after_wildcard = &hostname[hostname_label_end..]; + + Some(pattern_after_wildcard.eq_ignore_ascii_case(hostname_after_wildcard)) + } + + fn matches_ip(expected: &IpAddr, actual: &[u8]) -> bool { + match *expected { + IpAddr::V4(ref addr) => actual == addr.octets(), + IpAddr::V6(ref addr) => actual == addr.octets(), + } + } + + #[test] + fn test_dns_match() { + use crate::ssl::connector::verify::matches_dns; + assert!(matches_dns("website.tld", "website.tld")); // A name should match itself. + assert!(matches_dns("website.tld", "wEbSiTe.tLd")); // DNS name matching ignores case of hostname. + assert!(matches_dns("wEbSiTe.TlD", "website.tld")); // DNS name matching ignores case of subject. + + assert!(matches_dns("xn--bcher-kva.tld", "xn--bcher-kva.tld")); // Likewise, nothing special to punycode names. + assert!(matches_dns("xn--bcher-kva.tld", "xn--BcHer-Kva.tLd")); // And punycode must be compared similarly case-insensitively. + + assert!(matches_dns("*.example.com", "subdomain.example.com")); // Wildcard matching works. + assert!(matches_dns("*.eXaMpLe.cOm", "subdomain.example.com")); // Wildcard matching ignores case of subject. + assert!(matches_dns("*.example.com", "sUbDoMaIn.eXaMpLe.cOm")); // Wildcard matching ignores case of hostname. + + assert!(!matches_dns("prefix*.example.com", "p.example.com")); // Prefix longer than the label works and does not match. + assert!(!matches_dns("*suffix.example.com", "s.example.com")); // Suffix longer than the label works and does not match. + + assert!(!matches_dns("prefix*.example.com", "prefix.example.com")); // Partial wildcards do not work. + assert!(!matches_dns("*suffix.example.com", "suffix.example.com")); // Partial wildcards do not work. + + assert!(!matches_dns("prefix*.example.com", "prefixdomain.example.com")); // Partial wildcards do not work. + assert!(!matches_dns("*suffix.example.com", "domainsuffix.example.com")); // Partial wildcards do not work. + + assert!(!matches_dns("xn--*.example.com", "subdomain.example.com")); // Punycode domains with wildcard parts do not match. + assert!(!matches_dns("xN--*.example.com", "subdomain.example.com")); // And we can't bypass a punycode test with weird casing. + assert!(!matches_dns("Xn--*.example.com", "subdomain.example.com")); // And we can't bypass a punycode test with weird casing. + assert!(!matches_dns("XN--*.example.com", "subdomain.example.com")); // And we can't bypass a punycode test with weird casing. + } + } + } +} diff --git a/vendor/openssl/src/ssl/error.rs b/vendor/openssl/src/ssl/error.rs new file mode 100644 index 0000000..5565833 --- /dev/null +++ b/vendor/openssl/src/ssl/error.rs @@ -0,0 +1,185 @@ +use libc::c_int; +use std::error; +use std::error::Error as StdError; +use std::fmt; +use std::io; + +use crate::error::ErrorStack; +use crate::ssl::MidHandshakeSslStream; +use crate::x509::X509VerifyResult; + +/// An error code returned from SSL functions. +#[derive(Debug, Copy, Clone, PartialEq, Eq)] +pub struct ErrorCode(c_int); + +impl ErrorCode { + /// The SSL session has been closed. + pub const ZERO_RETURN: ErrorCode = ErrorCode(ffi::SSL_ERROR_ZERO_RETURN); + + /// An attempt to read data from the underlying socket returned `WouldBlock`. + /// + /// Wait for read readiness and retry the operation. + pub const WANT_READ: ErrorCode = ErrorCode(ffi::SSL_ERROR_WANT_READ); + + /// An attempt to write data to the underlying socket returned `WouldBlock`. + /// + /// Wait for write readiness and retry the operation. + pub const WANT_WRITE: ErrorCode = ErrorCode(ffi::SSL_ERROR_WANT_WRITE); + + /// A non-recoverable IO error occurred. + pub const SYSCALL: ErrorCode = ErrorCode(ffi::SSL_ERROR_SYSCALL); + + /// An error occurred in the SSL library. + pub const SSL: ErrorCode = ErrorCode(ffi::SSL_ERROR_SSL); + + /// The client hello callback indicated that it needed to be retried. + /// + /// Requires OpenSSL 1.1.1 or newer. + #[cfg(ossl111)] + pub const WANT_CLIENT_HELLO_CB: ErrorCode = ErrorCode(ffi::SSL_ERROR_WANT_CLIENT_HELLO_CB); + + pub fn from_raw(raw: c_int) -> ErrorCode { + ErrorCode(raw) + } + + #[allow(clippy::trivially_copy_pass_by_ref)] + pub fn as_raw(&self) -> c_int { + self.0 + } +} + +#[derive(Debug)] +pub(crate) enum InnerError { + Io(io::Error), + Ssl(ErrorStack), +} + +/// An SSL error. +#[derive(Debug)] +pub struct Error { + pub(crate) code: ErrorCode, + pub(crate) cause: Option, +} + +impl Error { + pub fn code(&self) -> ErrorCode { + self.code + } + + pub fn io_error(&self) -> Option<&io::Error> { + match self.cause { + Some(InnerError::Io(ref e)) => Some(e), + _ => None, + } + } + + pub fn into_io_error(self) -> Result { + match self.cause { + Some(InnerError::Io(e)) => Ok(e), + _ => Err(self), + } + } + + pub fn ssl_error(&self) -> Option<&ErrorStack> { + match self.cause { + Some(InnerError::Ssl(ref e)) => Some(e), + _ => None, + } + } +} + +impl From for Error { + fn from(e: ErrorStack) -> Error { + Error { + code: ErrorCode::SSL, + cause: Some(InnerError::Ssl(e)), + } + } +} + +impl fmt::Display for Error { + fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { + match self.code { + ErrorCode::ZERO_RETURN => fmt.write_str("the SSL session has been shut down"), + ErrorCode::WANT_READ => match self.io_error() { + Some(_) => fmt.write_str("a nonblocking read call would have blocked"), + None => fmt.write_str("the operation should be retried"), + }, + ErrorCode::WANT_WRITE => match self.io_error() { + Some(_) => fmt.write_str("a nonblocking write call would have blocked"), + None => fmt.write_str("the operation should be retried"), + }, + ErrorCode::SYSCALL => match self.io_error() { + Some(err) => write!(fmt, "{}", err), + None => fmt.write_str("unexpected EOF"), + }, + ErrorCode::SSL => match self.ssl_error() { + Some(e) => write!(fmt, "{}", e), + None => fmt.write_str("OpenSSL error"), + }, + ErrorCode(code) => write!(fmt, "unknown error code {}", code), + } + } +} + +impl error::Error for Error { + fn source(&self) -> Option<&(dyn error::Error + 'static)> { + match self.cause { + Some(InnerError::Io(ref e)) => Some(e), + Some(InnerError::Ssl(ref e)) => Some(e), + None => None, + } + } +} + +/// An error or intermediate state after a TLS handshake attempt. +// FIXME overhaul +#[derive(Debug)] +pub enum HandshakeError { + /// Setup failed. + SetupFailure(ErrorStack), + /// The handshake failed. + Failure(MidHandshakeSslStream), + /// The handshake encountered a `WouldBlock` error midway through. + /// + /// This error will never be returned for blocking streams. + WouldBlock(MidHandshakeSslStream), +} + +impl StdError for HandshakeError { + fn source(&self) -> Option<&(dyn StdError + 'static)> { + match *self { + HandshakeError::SetupFailure(ref e) => Some(e), + HandshakeError::Failure(ref s) | HandshakeError::WouldBlock(ref s) => Some(s.error()), + } + } +} + +impl fmt::Display for HandshakeError { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match *self { + HandshakeError::SetupFailure(ref e) => write!(f, "stream setup failed: {}", e)?, + HandshakeError::Failure(ref s) => { + write!(f, "the handshake failed: {}", s.error())?; + let verify = s.ssl().verify_result(); + if verify != X509VerifyResult::OK { + write!(f, ": {}", verify)?; + } + } + HandshakeError::WouldBlock(ref s) => { + write!(f, "the handshake was interrupted: {}", s.error())?; + let verify = s.ssl().verify_result(); + if verify != X509VerifyResult::OK { + write!(f, ": {}", verify)?; + } + } + } + Ok(()) + } +} + +impl From for HandshakeError { + fn from(e: ErrorStack) -> HandshakeError { + HandshakeError::SetupFailure(e) + } +} diff --git a/vendor/openssl/src/ssl/mod.rs b/vendor/openssl/src/ssl/mod.rs new file mode 100644 index 0000000..d9b2a72 --- /dev/null +++ b/vendor/openssl/src/ssl/mod.rs @@ -0,0 +1,4345 @@ +//! SSL/TLS support. +//! +//! `SslConnector` and `SslAcceptor` should be used in most cases - they handle +//! configuration of the OpenSSL primitives for you. +//! +//! # Examples +//! +//! To connect as a client to a remote server: +//! +//! ```no_run +//! use openssl::ssl::{SslMethod, SslConnector}; +//! use std::io::{Read, Write}; +//! use std::net::TcpStream; +//! +//! let connector = SslConnector::builder(SslMethod::tls()).unwrap().build(); +//! +//! let stream = TcpStream::connect("google.com:443").unwrap(); +//! let mut stream = connector.connect("google.com", stream).unwrap(); +//! +//! stream.write_all(b"GET / HTTP/1.0\r\n\r\n").unwrap(); +//! let mut res = vec![]; +//! stream.read_to_end(&mut res).unwrap(); +//! println!("{}", String::from_utf8_lossy(&res)); +//! ``` +//! +//! To accept connections as a server from remote clients: +//! +//! ```no_run +//! use openssl::ssl::{SslMethod, SslAcceptor, SslStream, SslFiletype}; +//! use std::net::{TcpListener, TcpStream}; +//! use std::sync::Arc; +//! use std::thread; +//! +//! +//! let mut acceptor = SslAcceptor::mozilla_intermediate(SslMethod::tls()).unwrap(); +//! acceptor.set_private_key_file("key.pem", SslFiletype::PEM).unwrap(); +//! acceptor.set_certificate_chain_file("certs.pem").unwrap(); +//! acceptor.check_private_key().unwrap(); +//! let acceptor = Arc::new(acceptor.build()); +//! +//! let listener = TcpListener::bind("0.0.0.0:8443").unwrap(); +//! +//! fn handle_client(stream: SslStream) { +//! // ... +//! } +//! +//! for stream in listener.incoming() { +//! match stream { +//! Ok(stream) => { +//! let acceptor = acceptor.clone(); +//! thread::spawn(move || { +//! let stream = acceptor.accept(stream).unwrap(); +//! handle_client(stream); +//! }); +//! } +//! Err(e) => { /* connection failed */ } +//! } +//! } +//! ``` +#[cfg(ossl300)] +use crate::cvt_long; +use crate::dh::{Dh, DhRef}; +#[cfg(all(ossl101, not(ossl110)))] +use crate::ec::EcKey; +use crate::ec::EcKeyRef; +use crate::error::ErrorStack; +use crate::ex_data::Index; +#[cfg(ossl111)] +use crate::hash::MessageDigest; +#[cfg(any(ossl110, libressl270))] +use crate::nid::Nid; +use crate::pkey::{HasPrivate, PKeyRef, Params, Private}; +#[cfg(ossl300)] +use crate::pkey::{PKey, Public}; +use crate::srtp::{SrtpProtectionProfile, SrtpProtectionProfileRef}; +use crate::ssl::bio::BioMethod; +use crate::ssl::callbacks::*; +use crate::ssl::error::InnerError; +use crate::stack::{Stack, StackRef, Stackable}; +use crate::util; +use crate::util::{ForeignTypeExt, ForeignTypeRefExt}; +use crate::x509::store::{X509Store, X509StoreBuilderRef, X509StoreRef}; +#[cfg(any(ossl102, boringssl, libressl261))] +use crate::x509::verify::X509VerifyParamRef; +use crate::x509::{X509Name, X509Ref, X509StoreContextRef, X509VerifyResult, X509}; +use crate::{cvt, cvt_n, cvt_p, init}; +use bitflags::bitflags; +use cfg_if::cfg_if; +use foreign_types::{ForeignType, ForeignTypeRef, Opaque}; +use libc::{c_char, c_int, c_long, c_uchar, c_uint, c_void}; +use once_cell::sync::{Lazy, OnceCell}; +use openssl_macros::corresponds; +use std::any::TypeId; +use std::collections::HashMap; +use std::ffi::{CStr, CString}; +use std::fmt; +use std::io; +use std::io::prelude::*; +use std::marker::PhantomData; +use std::mem::{self, ManuallyDrop, MaybeUninit}; +use std::ops::{Deref, DerefMut}; +use std::panic::resume_unwind; +use std::path::Path; +use std::ptr; +use std::str; +use std::sync::{Arc, Mutex}; + +pub use crate::ssl::connector::{ + ConnectConfiguration, SslAcceptor, SslAcceptorBuilder, SslConnector, SslConnectorBuilder, +}; +pub use crate::ssl::error::{Error, ErrorCode, HandshakeError}; + +mod bio; +mod callbacks; +mod connector; +mod error; +#[cfg(test)] +mod test; + +/// Returns the OpenSSL name of a cipher corresponding to an RFC-standard cipher name. +/// +/// If the cipher has no corresponding OpenSSL name, the string `(NONE)` is returned. +/// +/// Requires OpenSSL 1.1.1 or newer. +#[corresponds(OPENSSL_cipher_name)] +#[cfg(ossl111)] +pub fn cipher_name(std_name: &str) -> &'static str { + unsafe { + ffi::init(); + + let s = CString::new(std_name).unwrap(); + let ptr = ffi::OPENSSL_cipher_name(s.as_ptr()); + CStr::from_ptr(ptr).to_str().unwrap() + } +} + +cfg_if! { + if #[cfg(ossl300)] { + type SslOptionsRepr = u64; + } else if #[cfg(boringssl)] { + type SslOptionsRepr = u32; + } else { + type SslOptionsRepr = libc::c_ulong; + } +} + +bitflags! { + /// Options controlling the behavior of an `SslContext`. + #[derive(Copy, Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)] + #[repr(transparent)] + pub struct SslOptions: SslOptionsRepr { + /// Disables a countermeasure against an SSLv3/TLSv1.0 vulnerability affecting CBC ciphers. + const DONT_INSERT_EMPTY_FRAGMENTS = ffi::SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS as SslOptionsRepr; + + /// A "reasonable default" set of options which enables compatibility flags. + #[cfg(not(boringssl))] + const ALL = ffi::SSL_OP_ALL as SslOptionsRepr; + + /// Do not query the MTU. + /// + /// Only affects DTLS connections. + const NO_QUERY_MTU = ffi::SSL_OP_NO_QUERY_MTU as SslOptionsRepr; + + /// Enables Cookie Exchange as described in [RFC 4347 Section 4.2.1]. + /// + /// Only affects DTLS connections. + /// + /// [RFC 4347 Section 4.2.1]: https://tools.ietf.org/html/rfc4347#section-4.2.1 + #[cfg(not(boringssl))] + const COOKIE_EXCHANGE = ffi::SSL_OP_COOKIE_EXCHANGE as SslOptionsRepr; + + /// Disables the use of session tickets for session resumption. + const NO_TICKET = ffi::SSL_OP_NO_TICKET as SslOptionsRepr; + + /// Always start a new session when performing a renegotiation on the server side. + #[cfg(not(boringssl))] + const NO_SESSION_RESUMPTION_ON_RENEGOTIATION = + ffi::SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION as SslOptionsRepr; + + /// Disables the use of TLS compression. + #[cfg(not(boringssl))] + const NO_COMPRESSION = ffi::SSL_OP_NO_COMPRESSION as SslOptionsRepr; + + /// Allow legacy insecure renegotiation with servers or clients that do not support secure + /// renegotiation. + const ALLOW_UNSAFE_LEGACY_RENEGOTIATION = + ffi::SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION as SslOptionsRepr; + + /// Creates a new key for each session when using ECDHE. + /// + /// This is always enabled in OpenSSL 1.1.0. + const SINGLE_ECDH_USE = ffi::SSL_OP_SINGLE_ECDH_USE as SslOptionsRepr; + + /// Creates a new key for each session when using DHE. + /// + /// This is always enabled in OpenSSL 1.1.0. + const SINGLE_DH_USE = ffi::SSL_OP_SINGLE_DH_USE as SslOptionsRepr; + + /// Use the server's preferences rather than the client's when selecting a cipher. + /// + /// This has no effect on the client side. + const CIPHER_SERVER_PREFERENCE = ffi::SSL_OP_CIPHER_SERVER_PREFERENCE as SslOptionsRepr; + + /// Disables version rollback attach detection. + const TLS_ROLLBACK_BUG = ffi::SSL_OP_TLS_ROLLBACK_BUG as SslOptionsRepr; + + /// Disables the use of SSLv2. + const NO_SSLV2 = ffi::SSL_OP_NO_SSLv2 as SslOptionsRepr; + + /// Disables the use of SSLv3. + const NO_SSLV3 = ffi::SSL_OP_NO_SSLv3 as SslOptionsRepr; + + /// Disables the use of TLSv1.0. + const NO_TLSV1 = ffi::SSL_OP_NO_TLSv1 as SslOptionsRepr; + + /// Disables the use of TLSv1.1. + const NO_TLSV1_1 = ffi::SSL_OP_NO_TLSv1_1 as SslOptionsRepr; + + /// Disables the use of TLSv1.2. + const NO_TLSV1_2 = ffi::SSL_OP_NO_TLSv1_2 as SslOptionsRepr; + + /// Disables the use of TLSv1.3. + /// + /// Requires OpenSSL 1.1.1 or LibreSSL 3.4.0 or newer. + #[cfg(any(boringssl, ossl111, libressl340))] + const NO_TLSV1_3 = ffi::SSL_OP_NO_TLSv1_3 as SslOptionsRepr; + + /// Disables the use of DTLSv1.0 + /// + /// Requires OpenSSL 1.0.2 or LibreSSL 3.3.2 or newer. + #[cfg(any(boringssl, ossl102, ossl110, libressl332))] + const NO_DTLSV1 = ffi::SSL_OP_NO_DTLSv1 as SslOptionsRepr; + + /// Disables the use of DTLSv1.2. + /// + /// Requires OpenSSL 1.0.2 or LibreSSL 3.3.2 or newer. + #[cfg(any(boringssl, ossl102, ossl110, libressl332))] + const NO_DTLSV1_2 = ffi::SSL_OP_NO_DTLSv1_2 as SslOptionsRepr; + + /// Disables the use of all (D)TLS protocol versions. + /// + /// This can be used as a mask when whitelisting protocol versions. + /// + /// Requires OpenSSL 1.0.2 or newer. + /// + /// # Examples + /// + /// Only support TLSv1.2: + /// + /// ```rust + /// use openssl::ssl::SslOptions; + /// + /// let options = SslOptions::NO_SSL_MASK & !SslOptions::NO_TLSV1_2; + /// ``` + #[cfg(any(ossl102, ossl110))] + const NO_SSL_MASK = ffi::SSL_OP_NO_SSL_MASK as SslOptionsRepr; + + /// Disallow all renegotiation in TLSv1.2 and earlier. + /// + /// Requires OpenSSL 1.1.0h or newer. + #[cfg(any(boringssl, ossl110h))] + const NO_RENEGOTIATION = ffi::SSL_OP_NO_RENEGOTIATION as SslOptionsRepr; + + /// Enable TLSv1.3 Compatibility mode. + /// + /// Requires OpenSSL 1.1.1 or newer. This is on by default in 1.1.1, but a future version + /// may have this disabled by default. + #[cfg(ossl111)] + const ENABLE_MIDDLEBOX_COMPAT = ffi::SSL_OP_ENABLE_MIDDLEBOX_COMPAT as SslOptionsRepr; + + /// Prioritize ChaCha ciphers when preferred by clients. + /// + /// Temporarily reprioritize ChaCha20-Poly1305 ciphers to the top of the server cipher list + /// if a ChaCha20-Poly1305 cipher is at the top of the client cipher list. This helps those + /// clients (e.g. mobile) use ChaCha20-Poly1305 if that cipher is anywhere in the server + /// cipher list; but still allows other clients to use AES and other ciphers. + /// + /// Requires enable [`SslOptions::CIPHER_SERVER_PREFERENCE`]. + /// Requires OpenSSL 1.1.1 or newer. + /// + /// [`SslOptions::CIPHER_SERVER_PREFERENCE`]: struct.SslOptions.html#associatedconstant.CIPHER_SERVER_PREFERENCE + #[cfg(ossl111)] + const PRIORITIZE_CHACHA = ffi::SSL_OP_PRIORITIZE_CHACHA as SslOptionsRepr; + } +} + +bitflags! { + /// Options controlling the behavior of an `SslContext`. + #[derive(Copy, Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)] + #[repr(transparent)] + pub struct SslMode: SslBitType { + /// Enables "short writes". + /// + /// Normally, a write in OpenSSL will always write out all of the requested data, even if it + /// requires more than one TLS record or write to the underlying stream. This option will + /// cause a write to return after writing a single TLS record instead. + const ENABLE_PARTIAL_WRITE = ffi::SSL_MODE_ENABLE_PARTIAL_WRITE; + + /// Disables a check that the data buffer has not moved between calls when operating in a + /// non-blocking context. + const ACCEPT_MOVING_WRITE_BUFFER = ffi::SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER; + + /// Enables automatic retries after TLS session events such as renegotiations or heartbeats. + /// + /// By default, OpenSSL will return a `WantRead` error after a renegotiation or heartbeat. + /// This option will cause OpenSSL to automatically continue processing the requested + /// operation instead. + /// + /// Note that `SslStream::read` and `SslStream::write` will automatically retry regardless + /// of the state of this option. It only affects `SslStream::ssl_read` and + /// `SslStream::ssl_write`. + const AUTO_RETRY = ffi::SSL_MODE_AUTO_RETRY; + + /// Disables automatic chain building when verifying a peer's certificate. + /// + /// TLS peers are responsible for sending the entire certificate chain from the leaf to a + /// trusted root, but some will incorrectly not do so. OpenSSL will try to build the chain + /// out of certificates it knows of, and this option will disable that behavior. + const NO_AUTO_CHAIN = ffi::SSL_MODE_NO_AUTO_CHAIN; + + /// Release memory buffers when the session does not need them. + /// + /// This saves ~34 KiB of memory for idle streams. + const RELEASE_BUFFERS = ffi::SSL_MODE_RELEASE_BUFFERS; + + /// Sends the fake `TLS_FALLBACK_SCSV` cipher suite in the ClientHello message of a + /// handshake. + /// + /// This should only be enabled if a client has failed to connect to a server which + /// attempted to downgrade the protocol version of the session. + /// + /// Do not use this unless you know what you're doing! + #[cfg(not(libressl))] + const SEND_FALLBACK_SCSV = ffi::SSL_MODE_SEND_FALLBACK_SCSV; + } +} + +/// A type specifying the kind of protocol an `SslContext` will speak. +#[derive(Copy, Clone)] +pub struct SslMethod(*const ffi::SSL_METHOD); + +impl SslMethod { + /// Support all versions of the TLS protocol. + #[corresponds(TLS_method)] + pub fn tls() -> SslMethod { + unsafe { SslMethod(TLS_method()) } + } + + /// Support all versions of the DTLS protocol. + #[corresponds(DTLS_method)] + pub fn dtls() -> SslMethod { + unsafe { SslMethod(DTLS_method()) } + } + + /// Support all versions of the TLS protocol, explicitly as a client. + #[corresponds(TLS_client_method)] + pub fn tls_client() -> SslMethod { + unsafe { SslMethod(TLS_client_method()) } + } + + /// Support all versions of the TLS protocol, explicitly as a server. + #[corresponds(TLS_server_method)] + pub fn tls_server() -> SslMethod { + unsafe { SslMethod(TLS_server_method()) } + } + + /// Constructs an `SslMethod` from a pointer to the underlying OpenSSL value. + /// + /// # Safety + /// + /// The caller must ensure the pointer is valid. + pub unsafe fn from_ptr(ptr: *const ffi::SSL_METHOD) -> SslMethod { + SslMethod(ptr) + } + + /// Returns a pointer to the underlying OpenSSL value. + #[allow(clippy::trivially_copy_pass_by_ref)] + pub fn as_ptr(&self) -> *const ffi::SSL_METHOD { + self.0 + } +} + +unsafe impl Sync for SslMethod {} +unsafe impl Send for SslMethod {} + +bitflags! { + /// Options controlling the behavior of certificate verification. + #[derive(Copy, Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)] + #[repr(transparent)] + pub struct SslVerifyMode: i32 { + /// Verifies that the peer's certificate is trusted. + /// + /// On the server side, this will cause OpenSSL to request a certificate from the client. + const PEER = ffi::SSL_VERIFY_PEER; + + /// Disables verification of the peer's certificate. + /// + /// On the server side, this will cause OpenSSL to not request a certificate from the + /// client. On the client side, the certificate will be checked for validity, but the + /// negotiation will continue regardless of the result of that check. + const NONE = ffi::SSL_VERIFY_NONE; + + /// On the server side, abort the handshake if the client did not send a certificate. + /// + /// This should be paired with `SSL_VERIFY_PEER`. It has no effect on the client side. + const FAIL_IF_NO_PEER_CERT = ffi::SSL_VERIFY_FAIL_IF_NO_PEER_CERT; + } +} + +#[cfg(boringssl)] +type SslBitType = c_int; +#[cfg(not(boringssl))] +type SslBitType = c_long; + +#[cfg(boringssl)] +type SslTimeTy = u64; +#[cfg(not(boringssl))] +type SslTimeTy = c_long; + +bitflags! { + /// Options controlling the behavior of session caching. + #[derive(Copy, Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)] + #[repr(transparent)] + pub struct SslSessionCacheMode: SslBitType { + /// No session caching for the client or server takes place. + const OFF = ffi::SSL_SESS_CACHE_OFF; + + /// Enable session caching on the client side. + /// + /// OpenSSL has no way of identifying the proper session to reuse automatically, so the + /// application is responsible for setting it explicitly via [`SslRef::set_session`]. + /// + /// [`SslRef::set_session`]: struct.SslRef.html#method.set_session + const CLIENT = ffi::SSL_SESS_CACHE_CLIENT; + + /// Enable session caching on the server side. + /// + /// This is the default mode. + const SERVER = ffi::SSL_SESS_CACHE_SERVER; + + /// Enable session caching on both the client and server side. + const BOTH = ffi::SSL_SESS_CACHE_BOTH; + + /// Disable automatic removal of expired sessions from the session cache. + const NO_AUTO_CLEAR = ffi::SSL_SESS_CACHE_NO_AUTO_CLEAR; + + /// Disable use of the internal session cache for session lookups. + const NO_INTERNAL_LOOKUP = ffi::SSL_SESS_CACHE_NO_INTERNAL_LOOKUP; + + /// Disable use of the internal session cache for session storage. + const NO_INTERNAL_STORE = ffi::SSL_SESS_CACHE_NO_INTERNAL_STORE; + + /// Disable use of the internal session cache for storage and lookup. + const NO_INTERNAL = ffi::SSL_SESS_CACHE_NO_INTERNAL; + } +} + +#[cfg(ossl111)] +bitflags! { + /// Which messages and under which conditions an extension should be added or expected. + #[derive(Copy, Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)] + #[repr(transparent)] + pub struct ExtensionContext: c_uint { + /// This extension is only allowed in TLS + const TLS_ONLY = ffi::SSL_EXT_TLS_ONLY; + /// This extension is only allowed in DTLS + const DTLS_ONLY = ffi::SSL_EXT_DTLS_ONLY; + /// Some extensions may be allowed in DTLS but we don't implement them for it + const TLS_IMPLEMENTATION_ONLY = ffi::SSL_EXT_TLS_IMPLEMENTATION_ONLY; + /// Most extensions are not defined for SSLv3 but EXT_TYPE_renegotiate is + const SSL3_ALLOWED = ffi::SSL_EXT_SSL3_ALLOWED; + /// Extension is only defined for TLS1.2 and below + const TLS1_2_AND_BELOW_ONLY = ffi::SSL_EXT_TLS1_2_AND_BELOW_ONLY; + /// Extension is only defined for TLS1.3 and above + const TLS1_3_ONLY = ffi::SSL_EXT_TLS1_3_ONLY; + /// Ignore this extension during parsing if we are resuming + const IGNORE_ON_RESUMPTION = ffi::SSL_EXT_IGNORE_ON_RESUMPTION; + const CLIENT_HELLO = ffi::SSL_EXT_CLIENT_HELLO; + /// Really means TLS1.2 or below + const TLS1_2_SERVER_HELLO = ffi::SSL_EXT_TLS1_2_SERVER_HELLO; + const TLS1_3_SERVER_HELLO = ffi::SSL_EXT_TLS1_3_SERVER_HELLO; + const TLS1_3_ENCRYPTED_EXTENSIONS = ffi::SSL_EXT_TLS1_3_ENCRYPTED_EXTENSIONS; + const TLS1_3_HELLO_RETRY_REQUEST = ffi::SSL_EXT_TLS1_3_HELLO_RETRY_REQUEST; + const TLS1_3_CERTIFICATE = ffi::SSL_EXT_TLS1_3_CERTIFICATE; + const TLS1_3_NEW_SESSION_TICKET = ffi::SSL_EXT_TLS1_3_NEW_SESSION_TICKET; + const TLS1_3_CERTIFICATE_REQUEST = ffi::SSL_EXT_TLS1_3_CERTIFICATE_REQUEST; + } +} + +/// An identifier of the format of a certificate or key file. +#[derive(Copy, Clone)] +pub struct SslFiletype(c_int); + +impl SslFiletype { + /// The PEM format. + /// + /// This corresponds to `SSL_FILETYPE_PEM`. + pub const PEM: SslFiletype = SslFiletype(ffi::SSL_FILETYPE_PEM); + + /// The ASN1 format. + /// + /// This corresponds to `SSL_FILETYPE_ASN1`. + pub const ASN1: SslFiletype = SslFiletype(ffi::SSL_FILETYPE_ASN1); + + /// Constructs an `SslFiletype` from a raw OpenSSL value. + pub fn from_raw(raw: c_int) -> SslFiletype { + SslFiletype(raw) + } + + /// Returns the raw OpenSSL value represented by this type. + #[allow(clippy::trivially_copy_pass_by_ref)] + pub fn as_raw(&self) -> c_int { + self.0 + } +} + +/// An identifier of a certificate status type. +#[derive(Copy, Clone)] +pub struct StatusType(c_int); + +impl StatusType { + /// An OSCP status. + pub const OCSP: StatusType = StatusType(ffi::TLSEXT_STATUSTYPE_ocsp); + + /// Constructs a `StatusType` from a raw OpenSSL value. + pub fn from_raw(raw: c_int) -> StatusType { + StatusType(raw) + } + + /// Returns the raw OpenSSL value represented by this type. + #[allow(clippy::trivially_copy_pass_by_ref)] + pub fn as_raw(&self) -> c_int { + self.0 + } +} + +/// An identifier of a session name type. +#[derive(Copy, Clone)] +pub struct NameType(c_int); + +impl NameType { + /// A host name. + pub const HOST_NAME: NameType = NameType(ffi::TLSEXT_NAMETYPE_host_name); + + /// Constructs a `StatusType` from a raw OpenSSL value. + pub fn from_raw(raw: c_int) -> StatusType { + StatusType(raw) + } + + /// Returns the raw OpenSSL value represented by this type. + #[allow(clippy::trivially_copy_pass_by_ref)] + pub fn as_raw(&self) -> c_int { + self.0 + } +} + +static INDEXES: Lazy>> = Lazy::new(|| Mutex::new(HashMap::new())); +static SSL_INDEXES: Lazy>> = Lazy::new(|| Mutex::new(HashMap::new())); +static SESSION_CTX_INDEX: OnceCell> = OnceCell::new(); + +fn try_get_session_ctx_index() -> Result<&'static Index, ErrorStack> { + SESSION_CTX_INDEX.get_or_try_init(Ssl::new_ex_index) +} + +unsafe extern "C" fn free_data_box( + _parent: *mut c_void, + ptr: *mut c_void, + _ad: *mut ffi::CRYPTO_EX_DATA, + _idx: c_int, + _argl: c_long, + _argp: *mut c_void, +) { + if !ptr.is_null() { + let _ = Box::::from_raw(ptr as *mut T); + } +} + +/// An error returned from the SNI callback. +#[derive(Debug, Copy, Clone, PartialEq, Eq)] +pub struct SniError(c_int); + +impl SniError { + /// Abort the handshake with a fatal alert. + pub const ALERT_FATAL: SniError = SniError(ffi::SSL_TLSEXT_ERR_ALERT_FATAL); + + /// Send a warning alert to the client and continue the handshake. + pub const ALERT_WARNING: SniError = SniError(ffi::SSL_TLSEXT_ERR_ALERT_WARNING); + + pub const NOACK: SniError = SniError(ffi::SSL_TLSEXT_ERR_NOACK); +} + +/// An SSL/TLS alert. +#[derive(Debug, Copy, Clone, PartialEq, Eq)] +pub struct SslAlert(c_int); + +impl SslAlert { + /// Alert 112 - `unrecognized_name`. + pub const UNRECOGNIZED_NAME: SslAlert = SslAlert(ffi::SSL_AD_UNRECOGNIZED_NAME); + pub const ILLEGAL_PARAMETER: SslAlert = SslAlert(ffi::SSL_AD_ILLEGAL_PARAMETER); + pub const DECODE_ERROR: SslAlert = SslAlert(ffi::SSL_AD_DECODE_ERROR); +} + +/// An error returned from an ALPN selection callback. +/// +/// Requires OpenSSL 1.0.2 or LibreSSL 2.6.1 or newer. +#[cfg(any(ossl102, libressl261))] +#[derive(Debug, Copy, Clone, PartialEq, Eq)] +pub struct AlpnError(c_int); + +#[cfg(any(ossl102, libressl261))] +impl AlpnError { + /// Terminate the handshake with a fatal alert. + /// + /// Requires OpenSSL 1.1.0 or newer. + #[cfg(ossl110)] + pub const ALERT_FATAL: AlpnError = AlpnError(ffi::SSL_TLSEXT_ERR_ALERT_FATAL); + + /// Do not select a protocol, but continue the handshake. + pub const NOACK: AlpnError = AlpnError(ffi::SSL_TLSEXT_ERR_NOACK); +} + +/// The result of a client hello callback. +/// +/// Requires OpenSSL 1.1.1 or newer. +#[cfg(ossl111)] +#[derive(Debug, Copy, Clone, PartialEq, Eq)] +pub struct ClientHelloResponse(c_int); + +#[cfg(ossl111)] +impl ClientHelloResponse { + /// Continue the handshake. + pub const SUCCESS: ClientHelloResponse = ClientHelloResponse(ffi::SSL_CLIENT_HELLO_SUCCESS); + + /// Return from the handshake with an `ErrorCode::WANT_CLIENT_HELLO_CB` error. + pub const RETRY: ClientHelloResponse = ClientHelloResponse(ffi::SSL_CLIENT_HELLO_RETRY); +} + +/// An SSL/TLS protocol version. +#[derive(Debug, Copy, Clone, PartialEq, Eq)] +pub struct SslVersion(c_int); + +impl SslVersion { + /// SSLv3 + pub const SSL3: SslVersion = SslVersion(ffi::SSL3_VERSION); + + /// TLSv1.0 + pub const TLS1: SslVersion = SslVersion(ffi::TLS1_VERSION); + + /// TLSv1.1 + pub const TLS1_1: SslVersion = SslVersion(ffi::TLS1_1_VERSION); + + /// TLSv1.2 + pub const TLS1_2: SslVersion = SslVersion(ffi::TLS1_2_VERSION); + + /// TLSv1.3 + /// + /// Requires BoringSSL or OpenSSL 1.1.1 or LibreSSL 3.4.0 or newer. + #[cfg(any(ossl111, libressl340, boringssl))] + pub const TLS1_3: SslVersion = SslVersion(ffi::TLS1_3_VERSION); + + /// DTLSv1.0 + /// + /// DTLS 1.0 corresponds to TLS 1.1. + pub const DTLS1: SslVersion = SslVersion(ffi::DTLS1_VERSION); + + /// DTLSv1.2 + /// + /// DTLS 1.2 corresponds to TLS 1.2 to harmonize versions. There was never a DTLS 1.1. + #[cfg(any(ossl102, libressl332, boringssl))] + pub const DTLS1_2: SslVersion = SslVersion(ffi::DTLS1_2_VERSION); +} + +cfg_if! { + if #[cfg(boringssl)] { + type SslCacheTy = i64; + type SslCacheSize = libc::c_ulong; + type MtuTy = u32; + type SizeTy = usize; + } else { + type SslCacheTy = i64; + type SslCacheSize = c_long; + type MtuTy = c_long; + type SizeTy = u32; + } +} + +/// A standard implementation of protocol selection for Application Layer Protocol Negotiation +/// (ALPN). +/// +/// `server` should contain the server's list of supported protocols and `client` the client's. They +/// must both be in the ALPN wire format. See the documentation for +/// [`SslContextBuilder::set_alpn_protos`] for details. +/// +/// It will select the first protocol supported by the server which is also supported by the client. +/// +/// [`SslContextBuilder::set_alpn_protos`]: struct.SslContextBuilder.html#method.set_alpn_protos +#[corresponds(SSL_select_next_proto)] +pub fn select_next_proto<'a>(server: &[u8], client: &'a [u8]) -> Option<&'a [u8]> { + unsafe { + let mut out = ptr::null_mut(); + let mut outlen = 0; + let r = ffi::SSL_select_next_proto( + &mut out, + &mut outlen, + server.as_ptr(), + server.len() as c_uint, + client.as_ptr(), + client.len() as c_uint, + ); + if r == ffi::OPENSSL_NPN_NEGOTIATED { + Some(util::from_raw_parts(out as *const u8, outlen as usize)) + } else { + None + } + } +} + +/// A builder for `SslContext`s. +pub struct SslContextBuilder(SslContext); + +impl SslContextBuilder { + /// Creates a new `SslContextBuilder`. + #[corresponds(SSL_CTX_new)] + pub fn new(method: SslMethod) -> Result { + unsafe { + init(); + let ctx = cvt_p(ffi::SSL_CTX_new(method.as_ptr()))?; + + Ok(SslContextBuilder::from_ptr(ctx)) + } + } + + /// Creates an `SslContextBuilder` from a pointer to a raw OpenSSL value. + /// + /// # Safety + /// + /// The caller must ensure that the pointer is valid and uniquely owned by the builder. + pub unsafe fn from_ptr(ctx: *mut ffi::SSL_CTX) -> SslContextBuilder { + SslContextBuilder(SslContext::from_ptr(ctx)) + } + + /// Returns a pointer to the raw OpenSSL value. + pub fn as_ptr(&self) -> *mut ffi::SSL_CTX { + self.0.as_ptr() + } + + /// Configures the certificate verification method for new connections. + #[corresponds(SSL_CTX_set_verify)] + pub fn set_verify(&mut self, mode: SslVerifyMode) { + unsafe { + ffi::SSL_CTX_set_verify(self.as_ptr(), mode.bits() as c_int, None); + } + } + + /// Configures the certificate verification method for new connections and + /// registers a verification callback. + /// + /// The callback is passed a boolean indicating if OpenSSL's internal verification succeeded as + /// well as a reference to the `X509StoreContext` which can be used to examine the certificate + /// chain. It should return a boolean indicating if verification succeeded. + #[corresponds(SSL_CTX_set_verify)] + pub fn set_verify_callback(&mut self, mode: SslVerifyMode, verify: F) + where + F: Fn(bool, &mut X509StoreContextRef) -> bool + 'static + Sync + Send, + { + unsafe { + self.set_ex_data(SslContext::cached_ex_index::(), verify); + ffi::SSL_CTX_set_verify(self.as_ptr(), mode.bits() as c_int, Some(raw_verify::)); + } + } + + /// Configures the server name indication (SNI) callback for new connections. + /// + /// SNI is used to allow a single server to handle requests for multiple domains, each of which + /// has its own certificate chain and configuration. + /// + /// Obtain the server name with the `servername` method and then set the corresponding context + /// with `set_ssl_context` + #[corresponds(SSL_CTX_set_tlsext_servername_callback)] + // FIXME tlsext prefix? + pub fn set_servername_callback(&mut self, callback: F) + where + F: Fn(&mut SslRef, &mut SslAlert) -> Result<(), SniError> + 'static + Sync + Send, + { + unsafe { + // The SNI callback is somewhat unique in that the callback associated with the original + // context associated with an SSL can be used even if the SSL's context has been swapped + // out. When that happens, we wouldn't be able to look up the callback's state in the + // context's ex data. Instead, pass the pointer directly as the servername arg. It's + // still stored in ex data to manage the lifetime. + let arg = self.set_ex_data_inner(SslContext::cached_ex_index::(), callback); + ffi::SSL_CTX_set_tlsext_servername_arg(self.as_ptr(), arg); + #[cfg(boringssl)] + ffi::SSL_CTX_set_tlsext_servername_callback(self.as_ptr(), Some(raw_sni::)); + #[cfg(not(boringssl))] + ffi::SSL_CTX_set_tlsext_servername_callback__fixed_rust( + self.as_ptr(), + Some(raw_sni::), + ); + } + } + + /// Sets the certificate verification depth. + /// + /// If the peer's certificate chain is longer than this value, verification will fail. + #[corresponds(SSL_CTX_set_verify_depth)] + pub fn set_verify_depth(&mut self, depth: u32) { + unsafe { + ffi::SSL_CTX_set_verify_depth(self.as_ptr(), depth as c_int); + } + } + + /// Sets a custom certificate store for verifying peer certificates. + /// + /// Requires OpenSSL 1.0.2 or newer. + #[corresponds(SSL_CTX_set0_verify_cert_store)] + #[cfg(ossl102)] + pub fn set_verify_cert_store(&mut self, cert_store: X509Store) -> Result<(), ErrorStack> { + unsafe { + let ptr = cert_store.as_ptr(); + cvt(ffi::SSL_CTX_set0_verify_cert_store(self.as_ptr(), ptr) as c_int)?; + mem::forget(cert_store); + + Ok(()) + } + } + + /// Replaces the context's certificate store. + #[corresponds(SSL_CTX_set_cert_store)] + pub fn set_cert_store(&mut self, cert_store: X509Store) { + unsafe { + ffi::SSL_CTX_set_cert_store(self.as_ptr(), cert_store.as_ptr()); + mem::forget(cert_store); + } + } + + /// Controls read ahead behavior. + /// + /// If enabled, OpenSSL will read as much data as is available from the underlying stream, + /// instead of a single record at a time. + /// + /// It has no effect when used with DTLS. + #[corresponds(SSL_CTX_set_read_ahead)] + pub fn set_read_ahead(&mut self, read_ahead: bool) { + unsafe { + ffi::SSL_CTX_set_read_ahead(self.as_ptr(), read_ahead as SslBitType); + } + } + + /// Sets the mode used by the context, returning the previous mode. + #[corresponds(SSL_CTX_set_mode)] + pub fn set_mode(&mut self, mode: SslMode) -> SslMode { + unsafe { + let bits = ffi::SSL_CTX_set_mode(self.as_ptr(), mode.bits() as MtuTy) as SslBitType; + SslMode::from_bits_retain(bits) + } + } + + /// Sets the parameters to be used during ephemeral Diffie-Hellman key exchange. + #[corresponds(SSL_CTX_set_tmp_dh)] + pub fn set_tmp_dh(&mut self, dh: &DhRef) -> Result<(), ErrorStack> { + unsafe { cvt(ffi::SSL_CTX_set_tmp_dh(self.as_ptr(), dh.as_ptr()) as c_int).map(|_| ()) } + } + + /// Sets the callback which will generate parameters to be used during ephemeral Diffie-Hellman + /// key exchange. + /// + /// The callback is provided with a reference to the `Ssl` for the session, as well as a boolean + /// indicating if the selected cipher is export-grade, and the key length. The export and key + /// length options are archaic and should be ignored in almost all cases. + #[corresponds(SSL_CTX_set_tmp_dh_callback)] + pub fn set_tmp_dh_callback(&mut self, callback: F) + where + F: Fn(&mut SslRef, bool, u32) -> Result, ErrorStack> + 'static + Sync + Send, + { + unsafe { + self.set_ex_data(SslContext::cached_ex_index::(), callback); + + #[cfg(not(boringssl))] + ffi::SSL_CTX_set_tmp_dh_callback__fixed_rust(self.as_ptr(), Some(raw_tmp_dh::)); + #[cfg(boringssl)] + ffi::SSL_CTX_set_tmp_dh_callback(self.as_ptr(), Some(raw_tmp_dh::)); + } + } + + /// Sets the parameters to be used during ephemeral elliptic curve Diffie-Hellman key exchange. + #[corresponds(SSL_CTX_set_tmp_ecdh)] + pub fn set_tmp_ecdh(&mut self, key: &EcKeyRef) -> Result<(), ErrorStack> { + unsafe { cvt(ffi::SSL_CTX_set_tmp_ecdh(self.as_ptr(), key.as_ptr()) as c_int).map(|_| ()) } + } + + /// Sets the callback which will generate parameters to be used during ephemeral elliptic curve + /// Diffie-Hellman key exchange. + /// + /// The callback is provided with a reference to the `Ssl` for the session, as well as a boolean + /// indicating if the selected cipher is export-grade, and the key length. The export and key + /// length options are archaic and should be ignored in almost all cases. + /// + /// Requires OpenSSL 1.0.1 or 1.0.2. + #[corresponds(SSL_CTX_set_tmp_ecdh_callback)] + #[cfg(all(ossl101, not(ossl110)))] + #[deprecated(note = "this function leaks memory and does not exist on newer OpenSSL versions")] + pub fn set_tmp_ecdh_callback(&mut self, callback: F) + where + F: Fn(&mut SslRef, bool, u32) -> Result, ErrorStack> + 'static + Sync + Send, + { + unsafe { + self.set_ex_data(SslContext::cached_ex_index::(), callback); + ffi::SSL_CTX_set_tmp_ecdh_callback__fixed_rust(self.as_ptr(), Some(raw_tmp_ecdh::)); + } + } + + /// Use the default locations of trusted certificates for verification. + /// + /// These locations are read from the `SSL_CERT_FILE` and `SSL_CERT_DIR` environment variables + /// if present, or defaults specified at OpenSSL build time otherwise. + #[corresponds(SSL_CTX_set_default_verify_paths)] + pub fn set_default_verify_paths(&mut self) -> Result<(), ErrorStack> { + unsafe { cvt(ffi::SSL_CTX_set_default_verify_paths(self.as_ptr())).map(|_| ()) } + } + + /// Loads trusted root certificates from a file. + /// + /// The file should contain a sequence of PEM-formatted CA certificates. + #[corresponds(SSL_CTX_load_verify_locations)] + pub fn set_ca_file>(&mut self, file: P) -> Result<(), ErrorStack> { + let file = CString::new(file.as_ref().as_os_str().to_str().unwrap()).unwrap(); + unsafe { + cvt(ffi::SSL_CTX_load_verify_locations( + self.as_ptr(), + file.as_ptr() as *const _, + ptr::null(), + )) + .map(|_| ()) + } + } + + /// Sets the list of CA names sent to the client. + /// + /// The CA certificates must still be added to the trust root - they are not automatically set + /// as trusted by this method. + #[corresponds(SSL_CTX_set_client_CA_list)] + pub fn set_client_ca_list(&mut self, list: Stack) { + unsafe { + ffi::SSL_CTX_set_client_CA_list(self.as_ptr(), list.as_ptr()); + mem::forget(list); + } + } + + /// Add the provided CA certificate to the list sent by the server to the client when + /// requesting client-side TLS authentication. + #[corresponds(SSL_CTX_add_client_CA)] + pub fn add_client_ca(&mut self, cacert: &X509Ref) -> Result<(), ErrorStack> { + unsafe { cvt(ffi::SSL_CTX_add_client_CA(self.as_ptr(), cacert.as_ptr())).map(|_| ()) } + } + + /// Set the context identifier for sessions. + /// + /// This value identifies the server's session cache to clients, telling them when they're + /// able to reuse sessions. It should be set to a unique value per server, unless multiple + /// servers share a session cache. + /// + /// This value should be set when using client certificates, or each request will fail its + /// handshake and need to be restarted. + #[corresponds(SSL_CTX_set_session_id_context)] + pub fn set_session_id_context(&mut self, sid_ctx: &[u8]) -> Result<(), ErrorStack> { + unsafe { + assert!(sid_ctx.len() <= c_uint::MAX as usize); + cvt(ffi::SSL_CTX_set_session_id_context( + self.as_ptr(), + sid_ctx.as_ptr(), + sid_ctx.len() as SizeTy, + )) + .map(|_| ()) + } + } + + /// Loads a leaf certificate from a file. + /// + /// Only a single certificate will be loaded - use `add_extra_chain_cert` to add the remainder + /// of the certificate chain, or `set_certificate_chain_file` to load the entire chain from a + /// single file. + #[corresponds(SSL_CTX_use_certificate_file)] + pub fn set_certificate_file>( + &mut self, + file: P, + file_type: SslFiletype, + ) -> Result<(), ErrorStack> { + let file = CString::new(file.as_ref().as_os_str().to_str().unwrap()).unwrap(); + unsafe { + cvt(ffi::SSL_CTX_use_certificate_file( + self.as_ptr(), + file.as_ptr() as *const _, + file_type.as_raw(), + )) + .map(|_| ()) + } + } + + /// Loads a certificate chain from a file. + /// + /// The file should contain a sequence of PEM-formatted certificates, the first being the leaf + /// certificate, and the remainder forming the chain of certificates up to and including the + /// trusted root certificate. + #[corresponds(SSL_CTX_use_certificate_chain_file)] + pub fn set_certificate_chain_file>( + &mut self, + file: P, + ) -> Result<(), ErrorStack> { + let file = CString::new(file.as_ref().as_os_str().to_str().unwrap()).unwrap(); + unsafe { + cvt(ffi::SSL_CTX_use_certificate_chain_file( + self.as_ptr(), + file.as_ptr() as *const _, + )) + .map(|_| ()) + } + } + + /// Sets the leaf certificate. + /// + /// Use `add_extra_chain_cert` to add the remainder of the certificate chain. + #[corresponds(SSL_CTX_use_certificate)] + pub fn set_certificate(&mut self, cert: &X509Ref) -> Result<(), ErrorStack> { + unsafe { cvt(ffi::SSL_CTX_use_certificate(self.as_ptr(), cert.as_ptr())).map(|_| ()) } + } + + /// Appends a certificate to the certificate chain. + /// + /// This chain should contain all certificates necessary to go from the certificate specified by + /// `set_certificate` to a trusted root. + #[corresponds(SSL_CTX_add_extra_chain_cert)] + pub fn add_extra_chain_cert(&mut self, cert: X509) -> Result<(), ErrorStack> { + unsafe { + cvt(ffi::SSL_CTX_add_extra_chain_cert(self.as_ptr(), cert.as_ptr()) as c_int)?; + mem::forget(cert); + Ok(()) + } + } + + /// Loads the private key from a file. + #[corresponds(SSL_CTX_use_PrivateKey_file)] + pub fn set_private_key_file>( + &mut self, + file: P, + file_type: SslFiletype, + ) -> Result<(), ErrorStack> { + let file = CString::new(file.as_ref().as_os_str().to_str().unwrap()).unwrap(); + unsafe { + cvt(ffi::SSL_CTX_use_PrivateKey_file( + self.as_ptr(), + file.as_ptr() as *const _, + file_type.as_raw(), + )) + .map(|_| ()) + } + } + + /// Sets the private key. + #[corresponds(SSL_CTX_use_PrivateKey)] + pub fn set_private_key(&mut self, key: &PKeyRef) -> Result<(), ErrorStack> + where + T: HasPrivate, + { + unsafe { cvt(ffi::SSL_CTX_use_PrivateKey(self.as_ptr(), key.as_ptr())).map(|_| ()) } + } + + /// Sets the list of supported ciphers for protocols before TLSv1.3. + /// + /// The `set_ciphersuites` method controls the cipher suites for TLSv1.3. + /// + /// See [`ciphers`] for details on the format. + /// + /// [`ciphers`]: https://www.openssl.org/docs/manmaster/apps/ciphers.html + #[corresponds(SSL_CTX_set_cipher_list)] + pub fn set_cipher_list(&mut self, cipher_list: &str) -> Result<(), ErrorStack> { + let cipher_list = CString::new(cipher_list).unwrap(); + unsafe { + cvt(ffi::SSL_CTX_set_cipher_list( + self.as_ptr(), + cipher_list.as_ptr() as *const _, + )) + .map(|_| ()) + } + } + + /// Sets the list of supported ciphers for the TLSv1.3 protocol. + /// + /// The `set_cipher_list` method controls the cipher suites for protocols before TLSv1.3. + /// + /// The format consists of TLSv1.3 cipher suite names separated by `:` characters in order of + /// preference. + /// + /// Requires OpenSSL 1.1.1 or LibreSSL 3.4.0 or newer. + #[corresponds(SSL_CTX_set_ciphersuites)] + #[cfg(any(ossl111, libressl340))] + pub fn set_ciphersuites(&mut self, cipher_list: &str) -> Result<(), ErrorStack> { + let cipher_list = CString::new(cipher_list).unwrap(); + unsafe { + cvt(ffi::SSL_CTX_set_ciphersuites( + self.as_ptr(), + cipher_list.as_ptr() as *const _, + )) + .map(|_| ()) + } + } + + /// Enables ECDHE key exchange with an automatically chosen curve list. + /// + /// Requires OpenSSL 1.0.2. + #[corresponds(SSL_CTX_set_ecdh_auto)] + #[cfg(any(libressl, all(ossl102, not(ossl110))))] + pub fn set_ecdh_auto(&mut self, onoff: bool) -> Result<(), ErrorStack> { + unsafe { cvt(ffi::SSL_CTX_set_ecdh_auto(self.as_ptr(), onoff as c_int)).map(|_| ()) } + } + + /// Sets the options used by the context, returning the old set. + /// + /// # Note + /// + /// This *enables* the specified options, but does not disable unspecified options. Use + /// `clear_options` for that. + #[corresponds(SSL_CTX_set_options)] + pub fn set_options(&mut self, option: SslOptions) -> SslOptions { + let bits = + unsafe { ffi::SSL_CTX_set_options(self.as_ptr(), option.bits()) } as SslOptionsRepr; + SslOptions::from_bits_retain(bits) + } + + /// Returns the options used by the context. + #[corresponds(SSL_CTX_get_options)] + pub fn options(&self) -> SslOptions { + let bits = unsafe { ffi::SSL_CTX_get_options(self.as_ptr()) } as SslOptionsRepr; + SslOptions::from_bits_retain(bits) + } + + /// Clears the options used by the context, returning the old set. + #[corresponds(SSL_CTX_clear_options)] + pub fn clear_options(&mut self, option: SslOptions) -> SslOptions { + let bits = + unsafe { ffi::SSL_CTX_clear_options(self.as_ptr(), option.bits()) } as SslOptionsRepr; + SslOptions::from_bits_retain(bits) + } + + /// Sets the minimum supported protocol version. + /// + /// A value of `None` will enable protocol versions down to the lowest version supported by + /// OpenSSL. + /// + /// Requires BoringSSL or OpenSSL 1.1.0 or LibreSSL 2.6.1 or newer. + #[corresponds(SSL_CTX_set_min_proto_version)] + #[cfg(any(ossl110, libressl261, boringssl))] + pub fn set_min_proto_version(&mut self, version: Option) -> Result<(), ErrorStack> { + unsafe { + cvt(ffi::SSL_CTX_set_min_proto_version( + self.as_ptr(), + version.map_or(0, |v| v.0 as _), + )) + .map(|_| ()) + } + } + + /// Sets the maximum supported protocol version. + /// + /// A value of `None` will enable protocol versions up to the highest version supported by + /// OpenSSL. + /// + /// Requires BoringSSL or OpenSSL 1.1.0 or or LibreSSL 2.6.1 or newer. + #[corresponds(SSL_CTX_set_max_proto_version)] + #[cfg(any(ossl110, libressl261, boringssl))] + pub fn set_max_proto_version(&mut self, version: Option) -> Result<(), ErrorStack> { + unsafe { + cvt(ffi::SSL_CTX_set_max_proto_version( + self.as_ptr(), + version.map_or(0, |v| v.0 as _), + )) + .map(|_| ()) + } + } + + /// Gets the minimum supported protocol version. + /// + /// A value of `None` indicates that all versions down to the lowest version supported by + /// OpenSSL are enabled. + /// + /// Requires OpenSSL 1.1.0g or LibreSSL 2.7.0 or newer. + #[corresponds(SSL_CTX_get_min_proto_version)] + #[cfg(any(ossl110g, libressl270))] + pub fn min_proto_version(&mut self) -> Option { + unsafe { + let r = ffi::SSL_CTX_get_min_proto_version(self.as_ptr()); + if r == 0 { + None + } else { + Some(SslVersion(r)) + } + } + } + + /// Gets the maximum supported protocol version. + /// + /// A value of `None` indicates that all versions up to the highest version supported by + /// OpenSSL are enabled. + /// + /// Requires OpenSSL 1.1.0g or LibreSSL 2.7.0 or newer. + #[corresponds(SSL_CTX_get_max_proto_version)] + #[cfg(any(ossl110g, libressl270))] + pub fn max_proto_version(&mut self) -> Option { + unsafe { + let r = ffi::SSL_CTX_get_max_proto_version(self.as_ptr()); + if r == 0 { + None + } else { + Some(SslVersion(r)) + } + } + } + + /// Sets the protocols to sent to the server for Application Layer Protocol Negotiation (ALPN). + /// + /// The input must be in ALPN "wire format". It consists of a sequence of supported protocol + /// names prefixed by their byte length. For example, the protocol list consisting of `spdy/1` + /// and `http/1.1` is encoded as `b"\x06spdy/1\x08http/1.1"`. The protocols are ordered by + /// preference. + /// + /// Requires BoringSSL or OpenSSL 1.0.2 or LibreSSL 2.6.1 or newer. + #[corresponds(SSL_CTX_set_alpn_protos)] + #[cfg(any(ossl102, libressl261, boringssl))] + pub fn set_alpn_protos(&mut self, protocols: &[u8]) -> Result<(), ErrorStack> { + unsafe { + assert!(protocols.len() <= c_uint::MAX as usize); + let r = ffi::SSL_CTX_set_alpn_protos( + self.as_ptr(), + protocols.as_ptr(), + protocols.len() as _, + ); + // fun fact, SSL_CTX_set_alpn_protos has a reversed return code D: + if r == 0 { + Ok(()) + } else { + Err(ErrorStack::get()) + } + } + } + + /// Enables the DTLS extension "use_srtp" as defined in RFC5764. + #[corresponds(SSL_CTX_set_tlsext_use_srtp)] + pub fn set_tlsext_use_srtp(&mut self, protocols: &str) -> Result<(), ErrorStack> { + unsafe { + let cstr = CString::new(protocols).unwrap(); + + let r = ffi::SSL_CTX_set_tlsext_use_srtp(self.as_ptr(), cstr.as_ptr()); + // fun fact, set_tlsext_use_srtp has a reversed return code D: + if r == 0 { + Ok(()) + } else { + Err(ErrorStack::get()) + } + } + } + + /// Sets the callback used by a server to select a protocol for Application Layer Protocol + /// Negotiation (ALPN). + /// + /// The callback is provided with the client's protocol list in ALPN wire format. See the + /// documentation for [`SslContextBuilder::set_alpn_protos`] for details. It should return one + /// of those protocols on success. The [`select_next_proto`] function implements the standard + /// protocol selection algorithm. + /// + /// Requires OpenSSL 1.0.2 or LibreSSL 2.6.1 or newer. + /// + /// [`SslContextBuilder::set_alpn_protos`]: struct.SslContextBuilder.html#method.set_alpn_protos + /// [`select_next_proto`]: fn.select_next_proto.html + #[corresponds(SSL_CTX_set_alpn_select_cb)] + #[cfg(any(ossl102, libressl261))] + pub fn set_alpn_select_callback(&mut self, callback: F) + where + F: for<'a> Fn(&mut SslRef, &'a [u8]) -> Result<&'a [u8], AlpnError> + 'static + Sync + Send, + { + unsafe { + self.set_ex_data(SslContext::cached_ex_index::(), callback); + ffi::SSL_CTX_set_alpn_select_cb__fixed_rust( + self.as_ptr(), + Some(callbacks::raw_alpn_select::), + ptr::null_mut(), + ); + } + } + + /// Checks for consistency between the private key and certificate. + #[corresponds(SSL_CTX_check_private_key)] + pub fn check_private_key(&self) -> Result<(), ErrorStack> { + unsafe { cvt(ffi::SSL_CTX_check_private_key(self.as_ptr())).map(|_| ()) } + } + + /// Returns a shared reference to the context's certificate store. + #[corresponds(SSL_CTX_get_cert_store)] + pub fn cert_store(&self) -> &X509StoreBuilderRef { + unsafe { X509StoreBuilderRef::from_ptr(ffi::SSL_CTX_get_cert_store(self.as_ptr())) } + } + + /// Returns a mutable reference to the context's certificate store. + #[corresponds(SSL_CTX_get_cert_store)] + pub fn cert_store_mut(&mut self) -> &mut X509StoreBuilderRef { + unsafe { X509StoreBuilderRef::from_ptr_mut(ffi::SSL_CTX_get_cert_store(self.as_ptr())) } + } + + /// Returns a reference to the X509 verification configuration. + /// + /// Requires BoringSSL or OpenSSL 1.0.2 or newer. + #[corresponds(SSL_CTX_get0_param)] + #[cfg(any(ossl102, boringssl, libressl261))] + pub fn verify_param(&self) -> &X509VerifyParamRef { + unsafe { X509VerifyParamRef::from_ptr(ffi::SSL_CTX_get0_param(self.as_ptr())) } + } + + /// Returns a mutable reference to the X509 verification configuration. + /// + /// Requires BoringSSL or OpenSSL 1.0.2 or newer. + #[corresponds(SSL_CTX_get0_param)] + #[cfg(any(ossl102, boringssl, libressl261))] + pub fn verify_param_mut(&mut self) -> &mut X509VerifyParamRef { + unsafe { X509VerifyParamRef::from_ptr_mut(ffi::SSL_CTX_get0_param(self.as_ptr())) } + } + + /// Sets the callback dealing with OCSP stapling. + /// + /// On the client side, this callback is responsible for validating the OCSP status response + /// returned by the server. The status may be retrieved with the `SslRef::ocsp_status` method. + /// A response of `Ok(true)` indicates that the OCSP status is valid, and a response of + /// `Ok(false)` indicates that the OCSP status is invalid and the handshake should be + /// terminated. + /// + /// On the server side, this callback is responsible for setting the OCSP status response to be + /// returned to clients. The status may be set with the `SslRef::set_ocsp_status` method. A + /// response of `Ok(true)` indicates that the OCSP status should be returned to the client, and + /// `Ok(false)` indicates that the status should not be returned to the client. + #[corresponds(SSL_CTX_set_tlsext_status_cb)] + pub fn set_status_callback(&mut self, callback: F) -> Result<(), ErrorStack> + where + F: Fn(&mut SslRef) -> Result + 'static + Sync + Send, + { + unsafe { + self.set_ex_data(SslContext::cached_ex_index::(), callback); + cvt( + ffi::SSL_CTX_set_tlsext_status_cb(self.as_ptr(), Some(raw_tlsext_status::)) + as c_int, + ) + .map(|_| ()) + } + } + + /// Sets the callback for providing an identity and pre-shared key for a TLS-PSK client. + /// + /// The callback will be called with the SSL context, an identity hint if one was provided + /// by the server, a mutable slice for each of the identity and pre-shared key bytes. The + /// identity must be written as a null-terminated C string. + #[corresponds(SSL_CTX_set_psk_client_callback)] + #[cfg(not(osslconf = "OPENSSL_NO_PSK"))] + pub fn set_psk_client_callback(&mut self, callback: F) + where + F: Fn(&mut SslRef, Option<&[u8]>, &mut [u8], &mut [u8]) -> Result + + 'static + + Sync + + Send, + { + unsafe { + self.set_ex_data(SslContext::cached_ex_index::(), callback); + ffi::SSL_CTX_set_psk_client_callback(self.as_ptr(), Some(raw_client_psk::)); + } + } + + #[deprecated(since = "0.10.10", note = "renamed to `set_psk_client_callback`")] + #[cfg(not(osslconf = "OPENSSL_NO_PSK"))] + pub fn set_psk_callback(&mut self, callback: F) + where + F: Fn(&mut SslRef, Option<&[u8]>, &mut [u8], &mut [u8]) -> Result + + 'static + + Sync + + Send, + { + self.set_psk_client_callback(callback) + } + + /// Sets the callback for providing an identity and pre-shared key for a TLS-PSK server. + /// + /// The callback will be called with the SSL context, an identity provided by the client, + /// and, a mutable slice for the pre-shared key bytes. The callback returns the number of + /// bytes in the pre-shared key. + #[corresponds(SSL_CTX_set_psk_server_callback)] + #[cfg(not(osslconf = "OPENSSL_NO_PSK"))] + pub fn set_psk_server_callback(&mut self, callback: F) + where + F: Fn(&mut SslRef, Option<&[u8]>, &mut [u8]) -> Result + + 'static + + Sync + + Send, + { + unsafe { + self.set_ex_data(SslContext::cached_ex_index::(), callback); + ffi::SSL_CTX_set_psk_server_callback(self.as_ptr(), Some(raw_server_psk::)); + } + } + + /// Sets the callback which is called when new sessions are negotiated. + /// + /// This can be used by clients to implement session caching. While in TLSv1.2 the session is + /// available to access via [`SslRef::session`] immediately after the handshake completes, this + /// is not the case for TLSv1.3. There, a session is not generally available immediately, and + /// the server may provide multiple session tokens to the client over a single session. The new + /// session callback is a portable way to deal with both cases. + /// + /// Note that session caching must be enabled for the callback to be invoked, and it defaults + /// off for clients. [`set_session_cache_mode`] controls that behavior. + /// + /// [`SslRef::session`]: struct.SslRef.html#method.session + /// [`set_session_cache_mode`]: #method.set_session_cache_mode + #[corresponds(SSL_CTX_sess_set_new_cb)] + pub fn set_new_session_callback(&mut self, callback: F) + where + F: Fn(&mut SslRef, SslSession) + 'static + Sync + Send, + { + unsafe { + self.set_ex_data(SslContext::cached_ex_index::(), callback); + ffi::SSL_CTX_sess_set_new_cb(self.as_ptr(), Some(callbacks::raw_new_session::)); + } + } + + /// Sets the callback which is called when sessions are removed from the context. + /// + /// Sessions can be removed because they have timed out or because they are considered faulty. + #[corresponds(SSL_CTX_sess_set_remove_cb)] + pub fn set_remove_session_callback(&mut self, callback: F) + where + F: Fn(&SslContextRef, &SslSessionRef) + 'static + Sync + Send, + { + unsafe { + self.set_ex_data(SslContext::cached_ex_index::(), callback); + ffi::SSL_CTX_sess_set_remove_cb( + self.as_ptr(), + Some(callbacks::raw_remove_session::), + ); + } + } + + /// Sets the callback which is called when a client proposed to resume a session but it was not + /// found in the internal cache. + /// + /// The callback is passed a reference to the session ID provided by the client. It should + /// return the session corresponding to that ID if available. This is only used for servers, not + /// clients. + /// + /// # Safety + /// + /// The returned `SslSession` must not be associated with a different `SslContext`. + #[corresponds(SSL_CTX_sess_set_get_cb)] + pub unsafe fn set_get_session_callback(&mut self, callback: F) + where + F: Fn(&mut SslRef, &[u8]) -> Option + 'static + Sync + Send, + { + self.set_ex_data(SslContext::cached_ex_index::(), callback); + ffi::SSL_CTX_sess_set_get_cb(self.as_ptr(), Some(callbacks::raw_get_session::)); + } + + /// Sets the TLS key logging callback. + /// + /// The callback is invoked whenever TLS key material is generated, and is passed a line of NSS + /// SSLKEYLOGFILE-formatted text. This can be used by tools like Wireshark to decrypt message + /// traffic. The line does not contain a trailing newline. + /// + /// Requires OpenSSL 1.1.1 or newer. + #[corresponds(SSL_CTX_set_keylog_callback)] + #[cfg(any(ossl111, boringssl))] + pub fn set_keylog_callback(&mut self, callback: F) + where + F: Fn(&SslRef, &str) + 'static + Sync + Send, + { + unsafe { + self.set_ex_data(SslContext::cached_ex_index::(), callback); + ffi::SSL_CTX_set_keylog_callback(self.as_ptr(), Some(callbacks::raw_keylog::)); + } + } + + /// Sets the session caching mode use for connections made with the context. + /// + /// Returns the previous session caching mode. + #[corresponds(SSL_CTX_set_session_cache_mode)] + pub fn set_session_cache_mode(&mut self, mode: SslSessionCacheMode) -> SslSessionCacheMode { + unsafe { + let bits = ffi::SSL_CTX_set_session_cache_mode(self.as_ptr(), mode.bits()); + SslSessionCacheMode::from_bits_retain(bits) + } + } + + /// Sets the callback for generating an application cookie for TLS1.3 + /// stateless handshakes. + /// + /// The callback will be called with the SSL context and a slice into which the cookie + /// should be written. The callback should return the number of bytes written. + #[corresponds(SSL_CTX_set_stateless_cookie_generate_cb)] + #[cfg(ossl111)] + pub fn set_stateless_cookie_generate_cb(&mut self, callback: F) + where + F: Fn(&mut SslRef, &mut [u8]) -> Result + 'static + Sync + Send, + { + unsafe { + self.set_ex_data(SslContext::cached_ex_index::(), callback); + ffi::SSL_CTX_set_stateless_cookie_generate_cb( + self.as_ptr(), + Some(raw_stateless_cookie_generate::), + ); + } + } + + /// Sets the callback for verifying an application cookie for TLS1.3 + /// stateless handshakes. + /// + /// The callback will be called with the SSL context and the cookie supplied by the + /// client. It should return true if and only if the cookie is valid. + /// + /// Note that the OpenSSL implementation independently verifies the integrity of + /// application cookies using an HMAC before invoking the supplied callback. + #[corresponds(SSL_CTX_set_stateless_cookie_verify_cb)] + #[cfg(ossl111)] + pub fn set_stateless_cookie_verify_cb(&mut self, callback: F) + where + F: Fn(&mut SslRef, &[u8]) -> bool + 'static + Sync + Send, + { + unsafe { + self.set_ex_data(SslContext::cached_ex_index::(), callback); + ffi::SSL_CTX_set_stateless_cookie_verify_cb( + self.as_ptr(), + Some(raw_stateless_cookie_verify::), + ) + } + } + + /// Sets the callback for generating a DTLSv1 cookie + /// + /// The callback will be called with the SSL context and a slice into which the cookie + /// should be written. The callback should return the number of bytes written. + #[corresponds(SSL_CTX_set_cookie_generate_cb)] + #[cfg(not(boringssl))] + pub fn set_cookie_generate_cb(&mut self, callback: F) + where + F: Fn(&mut SslRef, &mut [u8]) -> Result + 'static + Sync + Send, + { + unsafe { + self.set_ex_data(SslContext::cached_ex_index::(), callback); + ffi::SSL_CTX_set_cookie_generate_cb(self.as_ptr(), Some(raw_cookie_generate::)); + } + } + + /// Sets the callback for verifying a DTLSv1 cookie + /// + /// The callback will be called with the SSL context and the cookie supplied by the + /// client. It should return true if and only if the cookie is valid. + #[corresponds(SSL_CTX_set_cookie_verify_cb)] + #[cfg(not(boringssl))] + pub fn set_cookie_verify_cb(&mut self, callback: F) + where + F: Fn(&mut SslRef, &[u8]) -> bool + 'static + Sync + Send, + { + unsafe { + self.set_ex_data(SslContext::cached_ex_index::(), callback); + ffi::SSL_CTX_set_cookie_verify_cb(self.as_ptr(), Some(raw_cookie_verify::)); + } + } + + /// Sets the extra data at the specified index. + /// + /// This can be used to provide data to callbacks registered with the context. Use the + /// `SslContext::new_ex_index` method to create an `Index`. + // FIXME should return a result + #[corresponds(SSL_CTX_set_ex_data)] + pub fn set_ex_data(&mut self, index: Index, data: T) { + self.set_ex_data_inner(index, data); + } + + fn set_ex_data_inner(&mut self, index: Index, data: T) -> *mut c_void { + match self.ex_data_mut(index) { + Some(v) => { + *v = data; + (v as *mut T).cast() + } + _ => unsafe { + let data = Box::into_raw(Box::new(data)) as *mut c_void; + ffi::SSL_CTX_set_ex_data(self.as_ptr(), index.as_raw(), data); + data + }, + } + } + + fn ex_data_mut(&mut self, index: Index) -> Option<&mut T> { + unsafe { + let data = ffi::SSL_CTX_get_ex_data(self.as_ptr(), index.as_raw()); + if data.is_null() { + None + } else { + Some(&mut *data.cast()) + } + } + } + + /// Adds a custom extension for a TLS/DTLS client or server for all supported protocol versions. + /// + /// Requires OpenSSL 1.1.1 or newer. + #[corresponds(SSL_CTX_add_custom_ext)] + #[cfg(ossl111)] + pub fn add_custom_ext( + &mut self, + ext_type: u16, + context: ExtensionContext, + add_cb: AddFn, + parse_cb: ParseFn, + ) -> Result<(), ErrorStack> + where + AddFn: Fn( + &mut SslRef, + ExtensionContext, + Option<(usize, &X509Ref)>, + ) -> Result, SslAlert> + + 'static + + Sync + + Send, + T: AsRef<[u8]> + 'static + Sync + Send, + ParseFn: Fn( + &mut SslRef, + ExtensionContext, + &[u8], + Option<(usize, &X509Ref)>, + ) -> Result<(), SslAlert> + + 'static + + Sync + + Send, + { + let ret = unsafe { + self.set_ex_data(SslContext::cached_ex_index::(), add_cb); + self.set_ex_data(SslContext::cached_ex_index::(), parse_cb); + + ffi::SSL_CTX_add_custom_ext( + self.as_ptr(), + ext_type as c_uint, + context.bits(), + Some(raw_custom_ext_add::), + Some(raw_custom_ext_free::), + ptr::null_mut(), + Some(raw_custom_ext_parse::), + ptr::null_mut(), + ) + }; + if ret == 1 { + Ok(()) + } else { + Err(ErrorStack::get()) + } + } + + /// Sets the maximum amount of early data that will be accepted on incoming connections. + /// + /// Defaults to 0. + /// + /// Requires OpenSSL 1.1.1 or LibreSSL 3.4.0 or newer. + #[corresponds(SSL_CTX_set_max_early_data)] + #[cfg(any(ossl111, libressl340))] + pub fn set_max_early_data(&mut self, bytes: u32) -> Result<(), ErrorStack> { + if unsafe { ffi::SSL_CTX_set_max_early_data(self.as_ptr(), bytes) } == 1 { + Ok(()) + } else { + Err(ErrorStack::get()) + } + } + + /// Sets a callback which will be invoked just after the client's hello message is received. + /// + /// Requires OpenSSL 1.1.1 or newer. + #[corresponds(SSL_CTX_set_client_hello_cb)] + #[cfg(ossl111)] + pub fn set_client_hello_callback(&mut self, callback: F) + where + F: Fn(&mut SslRef, &mut SslAlert) -> Result + + 'static + + Sync + + Send, + { + unsafe { + let ptr = self.set_ex_data_inner(SslContext::cached_ex_index::(), callback); + ffi::SSL_CTX_set_client_hello_cb( + self.as_ptr(), + Some(callbacks::raw_client_hello::), + ptr, + ); + } + } + + /// Sets the context's session cache size limit, returning the previous limit. + /// + /// A value of 0 means that the cache size is unbounded. + #[corresponds(SSL_CTX_sess_set_cache_size)] + #[allow(clippy::useless_conversion)] + pub fn set_session_cache_size(&mut self, size: i32) -> i64 { + unsafe { + ffi::SSL_CTX_sess_set_cache_size(self.as_ptr(), size as SslCacheSize) as SslCacheTy + } + } + + /// Sets the context's supported signature algorithms. + /// + /// Requires OpenSSL 1.0.2 or newer. + #[corresponds(SSL_CTX_set1_sigalgs_list)] + #[cfg(ossl102)] + pub fn set_sigalgs_list(&mut self, sigalgs: &str) -> Result<(), ErrorStack> { + let sigalgs = CString::new(sigalgs).unwrap(); + unsafe { + cvt(ffi::SSL_CTX_set1_sigalgs_list(self.as_ptr(), sigalgs.as_ptr()) as c_int) + .map(|_| ()) + } + } + + /// Sets the context's supported elliptic curve groups. + /// + /// Requires BoringSSL or OpenSSL 1.1.1 or LibreSSL 2.5.1 or newer. + #[corresponds(SSL_CTX_set1_groups_list)] + #[cfg(any(ossl111, boringssl, libressl251))] + pub fn set_groups_list(&mut self, groups: &str) -> Result<(), ErrorStack> { + let groups = CString::new(groups).unwrap(); + unsafe { + cvt(ffi::SSL_CTX_set1_groups_list(self.as_ptr(), groups.as_ptr()) as c_int).map(|_| ()) + } + } + + /// Sets the number of TLS 1.3 session tickets that will be sent to a client after a full + /// handshake. + /// + /// Requires OpenSSL 1.1.1 or newer. + #[corresponds(SSL_CTX_set_num_tickets)] + #[cfg(ossl111)] + pub fn set_num_tickets(&mut self, num_tickets: usize) -> Result<(), ErrorStack> { + unsafe { cvt(ffi::SSL_CTX_set_num_tickets(self.as_ptr(), num_tickets)).map(|_| ()) } + } + + /// Set the context's security level to a value between 0 and 5, inclusive. + /// A security value of 0 allows allows all parameters and algorithms. + /// + /// Requires OpenSSL 1.1.0 or newer. + #[corresponds(SSL_CTX_set_security_level)] + #[cfg(any(ossl110, libressl360))] + pub fn set_security_level(&mut self, level: u32) { + unsafe { ffi::SSL_CTX_set_security_level(self.as_ptr(), level as c_int) } + } + + /// Consumes the builder, returning a new `SslContext`. + pub fn build(self) -> SslContext { + self.0 + } +} + +foreign_type_and_impl_send_sync! { + type CType = ffi::SSL_CTX; + fn drop = ffi::SSL_CTX_free; + + /// A context object for TLS streams. + /// + /// Applications commonly configure a single `SslContext` that is shared by all of its + /// `SslStreams`. + pub struct SslContext; + + /// Reference to [`SslContext`] + /// + /// [`SslContext`]: struct.SslContext.html + pub struct SslContextRef; +} + +impl Clone for SslContext { + fn clone(&self) -> Self { + (**self).to_owned() + } +} + +impl ToOwned for SslContextRef { + type Owned = SslContext; + + fn to_owned(&self) -> Self::Owned { + unsafe { + SSL_CTX_up_ref(self.as_ptr()); + SslContext::from_ptr(self.as_ptr()) + } + } +} + +// TODO: add useful info here +impl fmt::Debug for SslContext { + fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(fmt, "SslContext") + } +} + +impl SslContext { + /// Creates a new builder object for an `SslContext`. + pub fn builder(method: SslMethod) -> Result { + SslContextBuilder::new(method) + } + + /// Returns a new extra data index. + /// + /// Each invocation of this function is guaranteed to return a distinct index. These can be used + /// to store data in the context that can be retrieved later by callbacks, for example. + #[corresponds(SSL_CTX_get_ex_new_index)] + pub fn new_ex_index() -> Result, ErrorStack> + where + T: 'static + Sync + Send, + { + unsafe { + ffi::init(); + #[cfg(boringssl)] + let idx = cvt_n(get_new_idx(Some(free_data_box::)))?; + #[cfg(not(boringssl))] + let idx = cvt_n(get_new_idx(free_data_box::))?; + Ok(Index::from_raw(idx)) + } + } + + // FIXME should return a result? + fn cached_ex_index() -> Index + where + T: 'static + Sync + Send, + { + unsafe { + let idx = *INDEXES + .lock() + .unwrap_or_else(|e| e.into_inner()) + .entry(TypeId::of::()) + .or_insert_with(|| SslContext::new_ex_index::().unwrap().as_raw()); + Index::from_raw(idx) + } + } +} + +impl SslContextRef { + /// Returns the certificate associated with this `SslContext`, if present. + /// + /// Requires OpenSSL 1.0.2 or LibreSSL 2.7.0 or newer. + #[corresponds(SSL_CTX_get0_certificate)] + #[cfg(any(ossl102, libressl270))] + pub fn certificate(&self) -> Option<&X509Ref> { + unsafe { + let ptr = ffi::SSL_CTX_get0_certificate(self.as_ptr()); + X509Ref::from_const_ptr_opt(ptr) + } + } + + /// Returns the private key associated with this `SslContext`, if present. + /// + /// Requires OpenSSL 1.0.2 or LibreSSL 3.4.0 or newer. + #[corresponds(SSL_CTX_get0_privatekey)] + #[cfg(any(ossl102, libressl340))] + pub fn private_key(&self) -> Option<&PKeyRef> { + unsafe { + let ptr = ffi::SSL_CTX_get0_privatekey(self.as_ptr()); + PKeyRef::from_const_ptr_opt(ptr) + } + } + + /// Returns a shared reference to the certificate store used for verification. + #[corresponds(SSL_CTX_get_cert_store)] + pub fn cert_store(&self) -> &X509StoreRef { + unsafe { X509StoreRef::from_ptr(ffi::SSL_CTX_get_cert_store(self.as_ptr())) } + } + + /// Returns a shared reference to the stack of certificates making up the chain from the leaf. + #[corresponds(SSL_CTX_get_extra_chain_certs)] + pub fn extra_chain_certs(&self) -> &StackRef { + unsafe { + let mut chain = ptr::null_mut(); + ffi::SSL_CTX_get_extra_chain_certs(self.as_ptr(), &mut chain); + StackRef::from_const_ptr_opt(chain).expect("extra chain certs must not be null") + } + } + + /// Returns a reference to the extra data at the specified index. + #[corresponds(SSL_CTX_get_ex_data)] + pub fn ex_data(&self, index: Index) -> Option<&T> { + unsafe { + let data = ffi::SSL_CTX_get_ex_data(self.as_ptr(), index.as_raw()); + if data.is_null() { + None + } else { + Some(&*(data as *const T)) + } + } + } + + /// Gets the maximum amount of early data that will be accepted on incoming connections. + /// + /// Requires OpenSSL 1.1.1 or LibreSSL 3.4.0 or newer. + #[corresponds(SSL_CTX_get_max_early_data)] + #[cfg(any(ossl111, libressl340))] + pub fn max_early_data(&self) -> u32 { + unsafe { ffi::SSL_CTX_get_max_early_data(self.as_ptr()) } + } + + /// Adds a session to the context's cache. + /// + /// Returns `true` if the session was successfully added to the cache, and `false` if it was already present. + /// + /// # Safety + /// + /// The caller of this method is responsible for ensuring that the session has never been used with another + /// `SslContext` than this one. + #[corresponds(SSL_CTX_add_session)] + pub unsafe fn add_session(&self, session: &SslSessionRef) -> bool { + ffi::SSL_CTX_add_session(self.as_ptr(), session.as_ptr()) != 0 + } + + /// Removes a session from the context's cache and marks it as non-resumable. + /// + /// Returns `true` if the session was successfully found and removed, and `false` otherwise. + /// + /// # Safety + /// + /// The caller of this method is responsible for ensuring that the session has never been used with another + /// `SslContext` than this one. + #[corresponds(SSL_CTX_remove_session)] + pub unsafe fn remove_session(&self, session: &SslSessionRef) -> bool { + ffi::SSL_CTX_remove_session(self.as_ptr(), session.as_ptr()) != 0 + } + + /// Returns the context's session cache size limit. + /// + /// A value of 0 means that the cache size is unbounded. + #[corresponds(SSL_CTX_sess_get_cache_size)] + #[allow(clippy::unnecessary_cast)] + pub fn session_cache_size(&self) -> i64 { + unsafe { ffi::SSL_CTX_sess_get_cache_size(self.as_ptr()) as i64 } + } + + /// Returns the verify mode that was set on this context from [`SslContextBuilder::set_verify`]. + /// + /// [`SslContextBuilder::set_verify`]: struct.SslContextBuilder.html#method.set_verify + #[corresponds(SSL_CTX_get_verify_mode)] + pub fn verify_mode(&self) -> SslVerifyMode { + let mode = unsafe { ffi::SSL_CTX_get_verify_mode(self.as_ptr()) }; + SslVerifyMode::from_bits(mode).expect("SSL_CTX_get_verify_mode returned invalid mode") + } + + /// Gets the number of TLS 1.3 session tickets that will be sent to a client after a full + /// handshake. + /// + /// Requires OpenSSL 1.1.1 or newer. + #[corresponds(SSL_CTX_get_num_tickets)] + #[cfg(ossl111)] + pub fn num_tickets(&self) -> usize { + unsafe { ffi::SSL_CTX_get_num_tickets(self.as_ptr()) } + } + + /// Get the context's security level, which controls the allowed parameters + /// and algorithms. + /// + /// Requires OpenSSL 1.1.0 or newer. + #[corresponds(SSL_CTX_get_security_level)] + #[cfg(any(ossl110, libressl360))] + pub fn security_level(&self) -> u32 { + unsafe { ffi::SSL_CTX_get_security_level(self.as_ptr()) as u32 } + } +} + +/// Information about the state of a cipher. +pub struct CipherBits { + /// The number of secret bits used for the cipher. + pub secret: i32, + + /// The number of bits processed by the chosen algorithm. + pub algorithm: i32, +} + +/// Information about a cipher. +pub struct SslCipher(*mut ffi::SSL_CIPHER); + +impl ForeignType for SslCipher { + type CType = ffi::SSL_CIPHER; + type Ref = SslCipherRef; + + #[inline] + unsafe fn from_ptr(ptr: *mut ffi::SSL_CIPHER) -> SslCipher { + SslCipher(ptr) + } + + #[inline] + fn as_ptr(&self) -> *mut ffi::SSL_CIPHER { + self.0 + } +} + +impl Stackable for SslCipher { + type StackType = ffi::stack_st_SSL_CIPHER; +} + +impl Deref for SslCipher { + type Target = SslCipherRef; + + fn deref(&self) -> &SslCipherRef { + unsafe { SslCipherRef::from_ptr(self.0) } + } +} + +impl DerefMut for SslCipher { + fn deref_mut(&mut self) -> &mut SslCipherRef { + unsafe { SslCipherRef::from_ptr_mut(self.0) } + } +} + +/// Reference to an [`SslCipher`]. +/// +/// [`SslCipher`]: struct.SslCipher.html +pub struct SslCipherRef(Opaque); + +impl ForeignTypeRef for SslCipherRef { + type CType = ffi::SSL_CIPHER; +} + +impl SslCipherRef { + /// Returns the name of the cipher. + #[corresponds(SSL_CIPHER_get_name)] + pub fn name(&self) -> &'static str { + unsafe { + let ptr = ffi::SSL_CIPHER_get_name(self.as_ptr()); + CStr::from_ptr(ptr).to_str().unwrap() + } + } + + /// Returns the RFC-standard name of the cipher, if one exists. + /// + /// Requires OpenSSL 1.1.1 or newer. + #[corresponds(SSL_CIPHER_standard_name)] + #[cfg(ossl111)] + pub fn standard_name(&self) -> Option<&'static str> { + unsafe { + let ptr = ffi::SSL_CIPHER_standard_name(self.as_ptr()); + if ptr.is_null() { + None + } else { + Some(CStr::from_ptr(ptr).to_str().unwrap()) + } + } + } + + /// Returns the SSL/TLS protocol version that first defined the cipher. + #[corresponds(SSL_CIPHER_get_version)] + pub fn version(&self) -> &'static str { + let version = unsafe { + let ptr = ffi::SSL_CIPHER_get_version(self.as_ptr()); + CStr::from_ptr(ptr as *const _) + }; + + str::from_utf8(version.to_bytes()).unwrap() + } + + /// Returns the number of bits used for the cipher. + #[corresponds(SSL_CIPHER_get_bits)] + #[allow(clippy::useless_conversion)] + pub fn bits(&self) -> CipherBits { + unsafe { + let mut algo_bits = 0; + let secret_bits = ffi::SSL_CIPHER_get_bits(self.as_ptr(), &mut algo_bits); + CipherBits { + secret: secret_bits.into(), + algorithm: algo_bits.into(), + } + } + } + + /// Returns a textual description of the cipher. + #[corresponds(SSL_CIPHER_description)] + pub fn description(&self) -> String { + unsafe { + // SSL_CIPHER_description requires a buffer of at least 128 bytes. + let mut buf = [0; 128]; + let ptr = ffi::SSL_CIPHER_description(self.as_ptr(), buf.as_mut_ptr(), 128); + String::from_utf8(CStr::from_ptr(ptr as *const _).to_bytes().to_vec()).unwrap() + } + } + + /// Returns the handshake digest of the cipher. + /// + /// Requires OpenSSL 1.1.1 or newer. + #[corresponds(SSL_CIPHER_get_handshake_digest)] + #[cfg(ossl111)] + pub fn handshake_digest(&self) -> Option { + unsafe { + let ptr = ffi::SSL_CIPHER_get_handshake_digest(self.as_ptr()); + if ptr.is_null() { + None + } else { + Some(MessageDigest::from_ptr(ptr)) + } + } + } + + /// Returns the NID corresponding to the cipher. + /// + /// Requires OpenSSL 1.1.0 or LibreSSL 2.7.0 or newer. + #[corresponds(SSL_CIPHER_get_cipher_nid)] + #[cfg(any(ossl110, libressl270))] + pub fn cipher_nid(&self) -> Option { + let n = unsafe { ffi::SSL_CIPHER_get_cipher_nid(self.as_ptr()) }; + if n == 0 { + None + } else { + Some(Nid::from_raw(n)) + } + } +} + +impl fmt::Debug for SslCipherRef { + fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(fmt, "{}", self.name()) + } +} + +/// A stack of selected ciphers, and a stack of selected signalling cipher suites +#[derive(Debug)] +pub struct CipherLists { + pub suites: Stack, + pub signalling_suites: Stack, +} + +foreign_type_and_impl_send_sync! { + type CType = ffi::SSL_SESSION; + fn drop = ffi::SSL_SESSION_free; + + /// An encoded SSL session. + /// + /// These can be cached to share sessions across connections. + pub struct SslSession; + + /// Reference to [`SslSession`]. + /// + /// [`SslSession`]: struct.SslSession.html + pub struct SslSessionRef; +} + +impl Clone for SslSession { + fn clone(&self) -> SslSession { + SslSessionRef::to_owned(self) + } +} + +impl SslSession { + from_der! { + /// Deserializes a DER-encoded session structure. + #[corresponds(d2i_SSL_SESSION)] + from_der, + SslSession, + ffi::d2i_SSL_SESSION + } +} + +impl ToOwned for SslSessionRef { + type Owned = SslSession; + + fn to_owned(&self) -> SslSession { + unsafe { + SSL_SESSION_up_ref(self.as_ptr()); + SslSession(self.as_ptr()) + } + } +} + +impl SslSessionRef { + /// Returns the SSL session ID. + #[corresponds(SSL_SESSION_get_id)] + pub fn id(&self) -> &[u8] { + unsafe { + let mut len = 0; + let p = ffi::SSL_SESSION_get_id(self.as_ptr(), &mut len); + #[allow(clippy::unnecessary_cast)] + util::from_raw_parts(p as *const u8, len as usize) + } + } + + /// Returns the length of the master key. + #[corresponds(SSL_SESSION_get_master_key)] + pub fn master_key_len(&self) -> usize { + unsafe { SSL_SESSION_get_master_key(self.as_ptr(), ptr::null_mut(), 0) } + } + + /// Copies the master key into the provided buffer. + /// + /// Returns the number of bytes written, or the size of the master key if the buffer is empty. + #[corresponds(SSL_SESSION_get_master_key)] + pub fn master_key(&self, buf: &mut [u8]) -> usize { + unsafe { SSL_SESSION_get_master_key(self.as_ptr(), buf.as_mut_ptr(), buf.len()) } + } + + /// Gets the maximum amount of early data that can be sent on this session. + /// + /// Requires OpenSSL 1.1.1 or LibreSSL 3.4.0 or newer. + #[corresponds(SSL_SESSION_get_max_early_data)] + #[cfg(any(ossl111, libressl340))] + pub fn max_early_data(&self) -> u32 { + unsafe { ffi::SSL_SESSION_get_max_early_data(self.as_ptr()) } + } + + /// Returns the time at which the session was established, in seconds since the Unix epoch. + #[corresponds(SSL_SESSION_get_time)] + #[allow(clippy::useless_conversion)] + pub fn time(&self) -> SslTimeTy { + unsafe { ffi::SSL_SESSION_get_time(self.as_ptr()) } + } + + /// Returns the sessions timeout, in seconds. + /// + /// A session older than this time should not be used for session resumption. + #[corresponds(SSL_SESSION_get_timeout)] + #[allow(clippy::useless_conversion)] + pub fn timeout(&self) -> i64 { + unsafe { ffi::SSL_SESSION_get_timeout(self.as_ptr()).into() } + } + + /// Returns the session's TLS protocol version. + /// + /// Requires OpenSSL 1.1.0 or LibreSSL 2.7.0 or newer. + #[corresponds(SSL_SESSION_get_protocol_version)] + #[cfg(any(ossl110, libressl270))] + pub fn protocol_version(&self) -> SslVersion { + unsafe { + let version = ffi::SSL_SESSION_get_protocol_version(self.as_ptr()); + SslVersion(version) + } + } + + to_der! { + /// Serializes the session into a DER-encoded structure. + #[corresponds(i2d_SSL_SESSION)] + to_der, + ffi::i2d_SSL_SESSION + } +} + +foreign_type_and_impl_send_sync! { + type CType = ffi::SSL; + fn drop = ffi::SSL_free; + + /// The state of an SSL/TLS session. + /// + /// `Ssl` objects are created from an [`SslContext`], which provides configuration defaults. + /// These defaults can be overridden on a per-`Ssl` basis, however. + /// + /// [`SslContext`]: struct.SslContext.html + pub struct Ssl; + + /// Reference to an [`Ssl`]. + /// + /// [`Ssl`]: struct.Ssl.html + pub struct SslRef; +} + +impl fmt::Debug for Ssl { + fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { + fmt::Debug::fmt(&**self, fmt) + } +} + +impl Ssl { + /// Returns a new extra data index. + /// + /// Each invocation of this function is guaranteed to return a distinct index. These can be used + /// to store data in the context that can be retrieved later by callbacks, for example. + #[corresponds(SSL_get_ex_new_index)] + pub fn new_ex_index() -> Result, ErrorStack> + where + T: 'static + Sync + Send, + { + unsafe { + ffi::init(); + #[cfg(boringssl)] + let idx = cvt_n(get_new_ssl_idx(Some(free_data_box::)))?; + #[cfg(not(boringssl))] + let idx = cvt_n(get_new_ssl_idx(free_data_box::))?; + Ok(Index::from_raw(idx)) + } + } + + // FIXME should return a result? + fn cached_ex_index() -> Index + where + T: 'static + Sync + Send, + { + unsafe { + let idx = *SSL_INDEXES + .lock() + .unwrap_or_else(|e| e.into_inner()) + .entry(TypeId::of::()) + .or_insert_with(|| Ssl::new_ex_index::().unwrap().as_raw()); + Index::from_raw(idx) + } + } + + /// Creates a new `Ssl`. + #[corresponds(SSL_new)] + pub fn new(ctx: &SslContextRef) -> Result { + let session_ctx_index = try_get_session_ctx_index()?; + unsafe { + let ptr = cvt_p(ffi::SSL_new(ctx.as_ptr()))?; + let mut ssl = Ssl::from_ptr(ptr); + ssl.set_ex_data(*session_ctx_index, ctx.to_owned()); + + Ok(ssl) + } + } + + /// Initiates a client-side TLS handshake. + /// # Warning + /// + /// OpenSSL's default configuration is insecure. It is highly recommended to use + /// `SslConnector` rather than `Ssl` directly, as it manages that configuration. + #[corresponds(SSL_connect)] + #[allow(deprecated)] + pub fn connect(self, stream: S) -> Result, HandshakeError> + where + S: Read + Write, + { + SslStreamBuilder::new(self, stream).connect() + } + + /// Initiates a server-side TLS handshake. + /// + /// # Warning + /// + /// OpenSSL's default configuration is insecure. It is highly recommended to use + /// `SslAcceptor` rather than `Ssl` directly, as it manages that configuration. + #[corresponds(SSL_accept)] + #[allow(deprecated)] + pub fn accept(self, stream: S) -> Result, HandshakeError> + where + S: Read + Write, + { + SslStreamBuilder::new(self, stream).accept() + } +} + +impl fmt::Debug for SslRef { + fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { + fmt.debug_struct("Ssl") + .field("state", &self.state_string_long()) + .field("verify_result", &self.verify_result()) + .finish() + } +} + +impl SslRef { + fn get_raw_rbio(&self) -> *mut ffi::BIO { + unsafe { ffi::SSL_get_rbio(self.as_ptr()) } + } + + fn get_error(&self, ret: c_int) -> ErrorCode { + unsafe { ErrorCode::from_raw(ffi::SSL_get_error(self.as_ptr(), ret)) } + } + + /// Configure as an outgoing stream from a client. + #[corresponds(SSL_set_connect_state)] + pub fn set_connect_state(&mut self) { + unsafe { ffi::SSL_set_connect_state(self.as_ptr()) } + } + + /// Configure as an incoming stream to a server. + #[corresponds(SSL_set_accept_state)] + pub fn set_accept_state(&mut self) { + unsafe { ffi::SSL_set_accept_state(self.as_ptr()) } + } + + /// Like [`SslContextBuilder::set_verify`]. + /// + /// [`SslContextBuilder::set_verify`]: struct.SslContextBuilder.html#method.set_verify + #[corresponds(SSL_set_verify)] + pub fn set_verify(&mut self, mode: SslVerifyMode) { + unsafe { ffi::SSL_set_verify(self.as_ptr(), mode.bits() as c_int, None) } + } + + /// Returns the verify mode that was set using `set_verify`. + #[corresponds(SSL_set_verify_mode)] + pub fn verify_mode(&self) -> SslVerifyMode { + let mode = unsafe { ffi::SSL_get_verify_mode(self.as_ptr()) }; + SslVerifyMode::from_bits(mode).expect("SSL_get_verify_mode returned invalid mode") + } + + /// Like [`SslContextBuilder::set_verify_callback`]. + /// + /// [`SslContextBuilder::set_verify_callback`]: struct.SslContextBuilder.html#method.set_verify_callback + #[corresponds(SSL_set_verify)] + pub fn set_verify_callback(&mut self, mode: SslVerifyMode, verify: F) + where + F: Fn(bool, &mut X509StoreContextRef) -> bool + 'static + Sync + Send, + { + unsafe { + // this needs to be in an Arc since the callback can register a new callback! + self.set_ex_data(Ssl::cached_ex_index(), Arc::new(verify)); + ffi::SSL_set_verify( + self.as_ptr(), + mode.bits() as c_int, + Some(ssl_raw_verify::), + ); + } + } + + /// Like [`SslContextBuilder::set_tmp_dh`]. + /// + /// [`SslContextBuilder::set_tmp_dh`]: struct.SslContextBuilder.html#method.set_tmp_dh + #[corresponds(SSL_set_tmp_dh)] + pub fn set_tmp_dh(&mut self, dh: &DhRef) -> Result<(), ErrorStack> { + unsafe { cvt(ffi::SSL_set_tmp_dh(self.as_ptr(), dh.as_ptr()) as c_int).map(|_| ()) } + } + + /// Like [`SslContextBuilder::set_tmp_dh_callback`]. + /// + /// [`SslContextBuilder::set_tmp_dh_callback`]: struct.SslContextBuilder.html#method.set_tmp_dh_callback + #[corresponds(SSL_set_tmp_dh_callback)] + pub fn set_tmp_dh_callback(&mut self, callback: F) + where + F: Fn(&mut SslRef, bool, u32) -> Result, ErrorStack> + 'static + Sync + Send, + { + unsafe { + // this needs to be in an Arc since the callback can register a new callback! + self.set_ex_data(Ssl::cached_ex_index(), Arc::new(callback)); + #[cfg(boringssl)] + ffi::SSL_set_tmp_dh_callback(self.as_ptr(), Some(raw_tmp_dh_ssl::)); + #[cfg(not(boringssl))] + ffi::SSL_set_tmp_dh_callback__fixed_rust(self.as_ptr(), Some(raw_tmp_dh_ssl::)); + } + } + + /// Like [`SslContextBuilder::set_tmp_ecdh`]. + /// + /// [`SslContextBuilder::set_tmp_ecdh`]: struct.SslContextBuilder.html#method.set_tmp_ecdh + #[corresponds(SSL_set_tmp_ecdh)] + pub fn set_tmp_ecdh(&mut self, key: &EcKeyRef) -> Result<(), ErrorStack> { + unsafe { cvt(ffi::SSL_set_tmp_ecdh(self.as_ptr(), key.as_ptr()) as c_int).map(|_| ()) } + } + + /// Like [`SslContextBuilder::set_tmp_ecdh_callback`]. + /// + /// Requires OpenSSL 1.0.1 or 1.0.2. + #[corresponds(SSL_set_tmp_ecdh_callback)] + #[cfg(all(ossl101, not(ossl110)))] + #[deprecated(note = "this function leaks memory and does not exist on newer OpenSSL versions")] + pub fn set_tmp_ecdh_callback(&mut self, callback: F) + where + F: Fn(&mut SslRef, bool, u32) -> Result, ErrorStack> + 'static + Sync + Send, + { + unsafe { + // this needs to be in an Arc since the callback can register a new callback! + self.set_ex_data(Ssl::cached_ex_index(), Arc::new(callback)); + ffi::SSL_set_tmp_ecdh_callback__fixed_rust(self.as_ptr(), Some(raw_tmp_ecdh_ssl::)); + } + } + + /// Like [`SslContextBuilder::set_ecdh_auto`]. + /// + /// Requires OpenSSL 1.0.2 or LibreSSL. + /// + /// [`SslContextBuilder::set_tmp_ecdh`]: struct.SslContextBuilder.html#method.set_tmp_ecdh + #[corresponds(SSL_set_ecdh_auto)] + #[cfg(any(all(ossl102, not(ossl110)), libressl))] + pub fn set_ecdh_auto(&mut self, onoff: bool) -> Result<(), ErrorStack> { + unsafe { cvt(ffi::SSL_set_ecdh_auto(self.as_ptr(), onoff as c_int)).map(|_| ()) } + } + + /// Like [`SslContextBuilder::set_alpn_protos`]. + /// + /// Requires BoringSSL or OpenSSL 1.0.2 or LibreSSL 2.6.1 or newer. + /// + /// [`SslContextBuilder::set_alpn_protos`]: struct.SslContextBuilder.html#method.set_alpn_protos + #[corresponds(SSL_set_alpn_protos)] + #[cfg(any(ossl102, libressl261, boringssl))] + pub fn set_alpn_protos(&mut self, protocols: &[u8]) -> Result<(), ErrorStack> { + unsafe { + assert!(protocols.len() <= c_uint::MAX as usize); + let r = + ffi::SSL_set_alpn_protos(self.as_ptr(), protocols.as_ptr(), protocols.len() as _); + // fun fact, SSL_set_alpn_protos has a reversed return code D: + if r == 0 { + Ok(()) + } else { + Err(ErrorStack::get()) + } + } + } + + /// Returns the current cipher if the session is active. + #[corresponds(SSL_get_current_cipher)] + pub fn current_cipher(&self) -> Option<&SslCipherRef> { + unsafe { + let ptr = ffi::SSL_get_current_cipher(self.as_ptr()); + + SslCipherRef::from_const_ptr_opt(ptr) + } + } + + /// Returns a short string describing the state of the session. + #[corresponds(SSL_state_string)] + pub fn state_string(&self) -> &'static str { + let state = unsafe { + let ptr = ffi::SSL_state_string(self.as_ptr()); + CStr::from_ptr(ptr as *const _) + }; + + str::from_utf8(state.to_bytes()).unwrap() + } + + /// Returns a longer string describing the state of the session. + #[corresponds(SSL_state_string_long)] + pub fn state_string_long(&self) -> &'static str { + let state = unsafe { + let ptr = ffi::SSL_state_string_long(self.as_ptr()); + CStr::from_ptr(ptr as *const _) + }; + + str::from_utf8(state.to_bytes()).unwrap() + } + + /// Sets the host name to be sent to the server for Server Name Indication (SNI). + /// + /// It has no effect for a server-side connection. + #[corresponds(SSL_set_tlsext_host_name)] + pub fn set_hostname(&mut self, hostname: &str) -> Result<(), ErrorStack> { + let cstr = CString::new(hostname).unwrap(); + unsafe { + cvt(ffi::SSL_set_tlsext_host_name(self.as_ptr(), cstr.as_ptr() as *mut _) as c_int) + .map(|_| ()) + } + } + + /// Returns the peer's certificate, if present. + #[corresponds(SSL_get_peer_certificate)] + pub fn peer_certificate(&self) -> Option { + unsafe { + let ptr = SSL_get1_peer_certificate(self.as_ptr()); + X509::from_ptr_opt(ptr) + } + } + + /// Returns the certificate chain of the peer, if present. + /// + /// On the client side, the chain includes the leaf certificate, but on the server side it does + /// not. Fun! + #[corresponds(SSL_get_peer_cert_chain)] + pub fn peer_cert_chain(&self) -> Option<&StackRef> { + unsafe { + let ptr = ffi::SSL_get_peer_cert_chain(self.as_ptr()); + StackRef::from_const_ptr_opt(ptr) + } + } + + /// Returns the verified certificate chain of the peer, including the leaf certificate. + /// + /// If verification was not successful (i.e. [`verify_result`] does not return + /// [`X509VerifyResult::OK`]), this chain may be incomplete or invalid. + /// + /// Requires OpenSSL 1.1.0 or newer. + /// + /// [`verify_result`]: #method.verify_result + /// [`X509VerifyResult::OK`]: ../x509/struct.X509VerifyResult.html#associatedconstant.OK + #[corresponds(SSL_get0_verified_chain)] + #[cfg(ossl110)] + pub fn verified_chain(&self) -> Option<&StackRef> { + unsafe { + let ptr = ffi::SSL_get0_verified_chain(self.as_ptr()); + StackRef::from_const_ptr_opt(ptr) + } + } + + /// Like [`SslContext::certificate`]. + #[corresponds(SSL_get_certificate)] + pub fn certificate(&self) -> Option<&X509Ref> { + unsafe { + let ptr = ffi::SSL_get_certificate(self.as_ptr()); + X509Ref::from_const_ptr_opt(ptr) + } + } + + /// Like [`SslContext::private_key`]. + /// + /// [`SslContext::private_key`]: struct.SslContext.html#method.private_key + #[corresponds(SSL_get_privatekey)] + pub fn private_key(&self) -> Option<&PKeyRef> { + unsafe { + let ptr = ffi::SSL_get_privatekey(self.as_ptr()); + PKeyRef::from_const_ptr_opt(ptr) + } + } + + #[deprecated(since = "0.10.5", note = "renamed to `version_str`")] + pub fn version(&self) -> &str { + self.version_str() + } + + /// Returns the protocol version of the session. + #[corresponds(SSL_version)] + pub fn version2(&self) -> Option { + unsafe { + let r = ffi::SSL_version(self.as_ptr()); + if r == 0 { + None + } else { + Some(SslVersion(r)) + } + } + } + + /// Returns a string describing the protocol version of the session. + #[corresponds(SSL_get_version)] + pub fn version_str(&self) -> &'static str { + let version = unsafe { + let ptr = ffi::SSL_get_version(self.as_ptr()); + CStr::from_ptr(ptr as *const _) + }; + + str::from_utf8(version.to_bytes()).unwrap() + } + + /// Returns the protocol selected via Application Layer Protocol Negotiation (ALPN). + /// + /// The protocol's name is returned is an opaque sequence of bytes. It is up to the client + /// to interpret it. + /// + /// Requires BoringSSL or OpenSSL 1.0.2 or LibreSSL 2.6.1 or newer. + #[corresponds(SSL_get0_alpn_selected)] + #[cfg(any(ossl102, libressl261, boringssl))] + pub fn selected_alpn_protocol(&self) -> Option<&[u8]> { + unsafe { + let mut data: *const c_uchar = ptr::null(); + let mut len: c_uint = 0; + // Get the negotiated protocol from the SSL instance. + // `data` will point at a `c_uchar` array; `len` will contain the length of this array. + ffi::SSL_get0_alpn_selected(self.as_ptr(), &mut data, &mut len); + + if data.is_null() { + None + } else { + Some(util::from_raw_parts(data, len as usize)) + } + } + } + + /// Enables the DTLS extension "use_srtp" as defined in RFC5764. + #[corresponds(SSL_set_tlsext_use_srtp)] + pub fn set_tlsext_use_srtp(&mut self, protocols: &str) -> Result<(), ErrorStack> { + unsafe { + let cstr = CString::new(protocols).unwrap(); + + let r = ffi::SSL_set_tlsext_use_srtp(self.as_ptr(), cstr.as_ptr()); + // fun fact, set_tlsext_use_srtp has a reversed return code D: + if r == 0 { + Ok(()) + } else { + Err(ErrorStack::get()) + } + } + } + + /// Gets all SRTP profiles that are enabled for handshake via set_tlsext_use_srtp + /// + /// DTLS extension "use_srtp" as defined in RFC5764 has to be enabled. + #[corresponds(SSL_get_srtp_profiles)] + pub fn srtp_profiles(&self) -> Option<&StackRef> { + unsafe { + let chain = ffi::SSL_get_srtp_profiles(self.as_ptr()); + + StackRef::from_const_ptr_opt(chain) + } + } + + /// Gets the SRTP profile selected by handshake. + /// + /// DTLS extension "use_srtp" as defined in RFC5764 has to be enabled. + #[corresponds(SSL_get_selected_srtp_profile)] + pub fn selected_srtp_profile(&self) -> Option<&SrtpProtectionProfileRef> { + unsafe { + let profile = ffi::SSL_get_selected_srtp_profile(self.as_ptr()); + + SrtpProtectionProfileRef::from_const_ptr_opt(profile) + } + } + + /// Returns the number of bytes remaining in the currently processed TLS record. + /// + /// If this is greater than 0, the next call to `read` will not call down to the underlying + /// stream. + #[corresponds(SSL_pending)] + pub fn pending(&self) -> usize { + unsafe { ffi::SSL_pending(self.as_ptr()) as usize } + } + + /// Returns the servername sent by the client via Server Name Indication (SNI). + /// + /// It is only useful on the server side. + /// + /// # Note + /// + /// While the SNI specification requires that servernames be valid domain names (and therefore + /// ASCII), OpenSSL does not enforce this restriction. If the servername provided by the client + /// is not valid UTF-8, this function will return `None`. The `servername_raw` method returns + /// the raw bytes and does not have this restriction. + /// + /// [`SSL_get_servername`]: https://www.openssl.org/docs/manmaster/man3/SSL_get_servername.html + #[corresponds(SSL_get_servername)] + // FIXME maybe rethink in 0.11? + pub fn servername(&self, type_: NameType) -> Option<&str> { + self.servername_raw(type_) + .and_then(|b| str::from_utf8(b).ok()) + } + + /// Returns the servername sent by the client via Server Name Indication (SNI). + /// + /// It is only useful on the server side. + /// + /// # Note + /// + /// Unlike `servername`, this method does not require the name be valid UTF-8. + #[corresponds(SSL_get_servername)] + pub fn servername_raw(&self, type_: NameType) -> Option<&[u8]> { + unsafe { + let name = ffi::SSL_get_servername(self.as_ptr(), type_.0); + if name.is_null() { + None + } else { + Some(CStr::from_ptr(name as *const _).to_bytes()) + } + } + } + + /// Changes the context corresponding to the current connection. + /// + /// It is most commonly used in the Server Name Indication (SNI) callback. + #[corresponds(SSL_set_SSL_CTX)] + pub fn set_ssl_context(&mut self, ctx: &SslContextRef) -> Result<(), ErrorStack> { + unsafe { cvt_p(ffi::SSL_set_SSL_CTX(self.as_ptr(), ctx.as_ptr())).map(|_| ()) } + } + + /// Returns the context corresponding to the current connection. + #[corresponds(SSL_get_SSL_CTX)] + pub fn ssl_context(&self) -> &SslContextRef { + unsafe { + let ssl_ctx = ffi::SSL_get_SSL_CTX(self.as_ptr()); + SslContextRef::from_ptr(ssl_ctx) + } + } + + /// Returns a mutable reference to the X509 verification configuration. + /// + /// Requires BoringSSL or OpenSSL 1.0.2 or newer. + #[corresponds(SSL_get0_param)] + #[cfg(any(ossl102, boringssl, libressl261))] + pub fn param_mut(&mut self) -> &mut X509VerifyParamRef { + unsafe { X509VerifyParamRef::from_ptr_mut(ffi::SSL_get0_param(self.as_ptr())) } + } + + /// Returns the certificate verification result. + #[corresponds(SSL_get_verify_result)] + pub fn verify_result(&self) -> X509VerifyResult { + unsafe { X509VerifyResult::from_raw(ffi::SSL_get_verify_result(self.as_ptr()) as c_int) } + } + + /// Returns a shared reference to the SSL session. + #[corresponds(SSL_get_session)] + pub fn session(&self) -> Option<&SslSessionRef> { + unsafe { + let p = ffi::SSL_get_session(self.as_ptr()); + SslSessionRef::from_const_ptr_opt(p) + } + } + + /// Copies the `client_random` value sent by the client in the TLS handshake into a buffer. + /// + /// Returns the number of bytes copied, or if the buffer is empty, the size of the `client_random` + /// value. + /// + /// Requires OpenSSL 1.1.0 or LibreSSL 2.7.0 or newer. + #[corresponds(SSL_get_client_random)] + #[cfg(any(ossl110, libressl270))] + pub fn client_random(&self, buf: &mut [u8]) -> usize { + unsafe { + ffi::SSL_get_client_random(self.as_ptr(), buf.as_mut_ptr() as *mut c_uchar, buf.len()) + } + } + + /// Copies the `server_random` value sent by the server in the TLS handshake into a buffer. + /// + /// Returns the number of bytes copied, or if the buffer is empty, the size of the `server_random` + /// value. + /// + /// Requires OpenSSL 1.1.0 or LibreSSL 2.7.0 or newer. + #[corresponds(SSL_get_server_random)] + #[cfg(any(ossl110, libressl270))] + pub fn server_random(&self, buf: &mut [u8]) -> usize { + unsafe { + ffi::SSL_get_server_random(self.as_ptr(), buf.as_mut_ptr() as *mut c_uchar, buf.len()) + } + } + + /// Derives keying material for application use in accordance to RFC 5705. + #[corresponds(SSL_export_keying_material)] + pub fn export_keying_material( + &self, + out: &mut [u8], + label: &str, + context: Option<&[u8]>, + ) -> Result<(), ErrorStack> { + unsafe { + let (context, contextlen, use_context) = match context { + Some(context) => (context.as_ptr() as *const c_uchar, context.len(), 1), + None => (ptr::null(), 0, 0), + }; + cvt(ffi::SSL_export_keying_material( + self.as_ptr(), + out.as_mut_ptr() as *mut c_uchar, + out.len(), + label.as_ptr() as *const c_char, + label.len(), + context, + contextlen, + use_context, + )) + .map(|_| ()) + } + } + + /// Derives keying material for application use in accordance to RFC 5705. + /// + /// This function is only usable with TLSv1.3, wherein there is no distinction between an empty context and no + /// context. Therefore, unlike `export_keying_material`, `context` must always be supplied. + /// + /// Requires OpenSSL 1.1.1 or newer. + #[corresponds(SSL_export_keying_material_early)] + #[cfg(ossl111)] + pub fn export_keying_material_early( + &self, + out: &mut [u8], + label: &str, + context: &[u8], + ) -> Result<(), ErrorStack> { + unsafe { + cvt(ffi::SSL_export_keying_material_early( + self.as_ptr(), + out.as_mut_ptr() as *mut c_uchar, + out.len(), + label.as_ptr() as *const c_char, + label.len(), + context.as_ptr() as *const c_uchar, + context.len(), + )) + .map(|_| ()) + } + } + + /// Sets the session to be used. + /// + /// This should be called before the handshake to attempt to reuse a previously established + /// session. If the server is not willing to reuse the session, a new one will be transparently + /// negotiated. + /// + /// # Safety + /// + /// The caller of this method is responsible for ensuring that the session is associated + /// with the same `SslContext` as this `Ssl`. + #[corresponds(SSL_set_session)] + pub unsafe fn set_session(&mut self, session: &SslSessionRef) -> Result<(), ErrorStack> { + cvt(ffi::SSL_set_session(self.as_ptr(), session.as_ptr())).map(|_| ()) + } + + /// Determines if the session provided to `set_session` was successfully reused. + #[corresponds(SSL_session_reused)] + pub fn session_reused(&self) -> bool { + unsafe { ffi::SSL_session_reused(self.as_ptr()) != 0 } + } + + /// Sets the status response a client wishes the server to reply with. + #[corresponds(SSL_set_tlsext_status_type)] + pub fn set_status_type(&mut self, type_: StatusType) -> Result<(), ErrorStack> { + unsafe { + cvt(ffi::SSL_set_tlsext_status_type(self.as_ptr(), type_.as_raw()) as c_int).map(|_| ()) + } + } + + /// Determines if current session used Extended Master Secret + /// + /// Returns `None` if the handshake is still in-progress. + #[corresponds(SSL_get_extms_support)] + #[cfg(ossl110)] + pub fn extms_support(&self) -> Option { + unsafe { + match ffi::SSL_get_extms_support(self.as_ptr()) { + -1 => None, + ret => Some(ret != 0), + } + } + } + + /// Returns the server's OCSP response, if present. + #[corresponds(SSL_get_tlsext_status_ocsp_resp)] + #[cfg(not(boringssl))] + pub fn ocsp_status(&self) -> Option<&[u8]> { + unsafe { + let mut p = ptr::null_mut(); + let len = ffi::SSL_get_tlsext_status_ocsp_resp(self.as_ptr(), &mut p); + + if len < 0 { + None + } else { + Some(util::from_raw_parts(p as *const u8, len as usize)) + } + } + } + + /// Sets the OCSP response to be returned to the client. + #[corresponds(SSL_set_tlsext_status_oscp_resp)] + #[cfg(not(boringssl))] + pub fn set_ocsp_status(&mut self, response: &[u8]) -> Result<(), ErrorStack> { + unsafe { + assert!(response.len() <= c_int::MAX as usize); + let p = cvt_p(ffi::OPENSSL_malloc(response.len() as _))?; + ptr::copy_nonoverlapping(response.as_ptr(), p as *mut u8, response.len()); + cvt(ffi::SSL_set_tlsext_status_ocsp_resp( + self.as_ptr(), + p as *mut c_uchar, + response.len() as c_long, + ) as c_int) + .map(|_| ()) + .map_err(|e| { + ffi::OPENSSL_free(p); + e + }) + } + } + + /// Determines if this `Ssl` is configured for server-side or client-side use. + #[corresponds(SSL_is_server)] + pub fn is_server(&self) -> bool { + unsafe { SSL_is_server(self.as_ptr()) != 0 } + } + + /// Sets the extra data at the specified index. + /// + /// This can be used to provide data to callbacks registered with the context. Use the + /// `Ssl::new_ex_index` method to create an `Index`. + // FIXME should return a result + #[corresponds(SSL_set_ex_data)] + pub fn set_ex_data(&mut self, index: Index, data: T) { + match self.ex_data_mut(index) { + Some(v) => *v = data, + None => unsafe { + let data = Box::new(data); + ffi::SSL_set_ex_data( + self.as_ptr(), + index.as_raw(), + Box::into_raw(data) as *mut c_void, + ); + }, + } + } + + /// Returns a reference to the extra data at the specified index. + #[corresponds(SSL_get_ex_data)] + pub fn ex_data(&self, index: Index) -> Option<&T> { + unsafe { + let data = ffi::SSL_get_ex_data(self.as_ptr(), index.as_raw()); + if data.is_null() { + None + } else { + Some(&*(data as *const T)) + } + } + } + + /// Returns a mutable reference to the extra data at the specified index. + #[corresponds(SSL_get_ex_data)] + pub fn ex_data_mut(&mut self, index: Index) -> Option<&mut T> { + unsafe { + let data = ffi::SSL_get_ex_data(self.as_ptr(), index.as_raw()); + if data.is_null() { + None + } else { + Some(&mut *(data as *mut T)) + } + } + } + + /// Sets the maximum amount of early data that will be accepted on this connection. + /// + /// Requires OpenSSL 1.1.1 or LibreSSL 3.4.0 or newer. + #[corresponds(SSL_set_max_early_data)] + #[cfg(any(ossl111, libressl340))] + pub fn set_max_early_data(&mut self, bytes: u32) -> Result<(), ErrorStack> { + if unsafe { ffi::SSL_set_max_early_data(self.as_ptr(), bytes) } == 1 { + Ok(()) + } else { + Err(ErrorStack::get()) + } + } + + /// Gets the maximum amount of early data that can be sent on this connection. + /// + /// Requires OpenSSL 1.1.1 or LibreSSL 3.4.0 or newer. + #[corresponds(SSL_get_max_early_data)] + #[cfg(any(ossl111, libressl340))] + pub fn max_early_data(&self) -> u32 { + unsafe { ffi::SSL_get_max_early_data(self.as_ptr()) } + } + + /// Copies the contents of the last Finished message sent to the peer into the provided buffer. + /// + /// The total size of the message is returned, so this can be used to determine the size of the + /// buffer required. + #[corresponds(SSL_get_finished)] + pub fn finished(&self, buf: &mut [u8]) -> usize { + unsafe { ffi::SSL_get_finished(self.as_ptr(), buf.as_mut_ptr() as *mut c_void, buf.len()) } + } + + /// Copies the contents of the last Finished message received from the peer into the provided + /// buffer. + /// + /// The total size of the message is returned, so this can be used to determine the size of the + /// buffer required. + #[corresponds(SSL_get_peer_finished)] + pub fn peer_finished(&self, buf: &mut [u8]) -> usize { + unsafe { + ffi::SSL_get_peer_finished(self.as_ptr(), buf.as_mut_ptr() as *mut c_void, buf.len()) + } + } + + /// Determines if the initial handshake has been completed. + #[corresponds(SSL_is_init_finished)] + #[cfg(ossl110)] + pub fn is_init_finished(&self) -> bool { + unsafe { ffi::SSL_is_init_finished(self.as_ptr()) != 0 } + } + + /// Determines if the client's hello message is in the SSLv2 format. + /// + /// This can only be used inside of the client hello callback. Otherwise, `false` is returned. + /// + /// Requires OpenSSL 1.1.1 or newer. + #[corresponds(SSL_client_hello_isv2)] + #[cfg(ossl111)] + pub fn client_hello_isv2(&self) -> bool { + unsafe { ffi::SSL_client_hello_isv2(self.as_ptr()) != 0 } + } + + /// Returns the legacy version field of the client's hello message. + /// + /// This can only be used inside of the client hello callback. Otherwise, `None` is returned. + /// + /// Requires OpenSSL 1.1.1 or newer. + #[corresponds(SSL_client_hello_get0_legacy_version)] + #[cfg(ossl111)] + pub fn client_hello_legacy_version(&self) -> Option { + unsafe { + let version = ffi::SSL_client_hello_get0_legacy_version(self.as_ptr()); + if version == 0 { + None + } else { + Some(SslVersion(version as c_int)) + } + } + } + + /// Returns the random field of the client's hello message. + /// + /// This can only be used inside of the client hello callback. Otherwise, `None` is returned. + /// + /// Requires OpenSSL 1.1.1 or newer. + #[corresponds(SSL_client_hello_get0_random)] + #[cfg(ossl111)] + pub fn client_hello_random(&self) -> Option<&[u8]> { + unsafe { + let mut ptr = ptr::null(); + let len = ffi::SSL_client_hello_get0_random(self.as_ptr(), &mut ptr); + if len == 0 { + None + } else { + Some(util::from_raw_parts(ptr, len)) + } + } + } + + /// Returns the session ID field of the client's hello message. + /// + /// This can only be used inside of the client hello callback. Otherwise, `None` is returned. + /// + /// Requires OpenSSL 1.1.1 or newer. + #[corresponds(SSL_client_hello_get0_session_id)] + #[cfg(ossl111)] + pub fn client_hello_session_id(&self) -> Option<&[u8]> { + unsafe { + let mut ptr = ptr::null(); + let len = ffi::SSL_client_hello_get0_session_id(self.as_ptr(), &mut ptr); + if len == 0 { + None + } else { + Some(util::from_raw_parts(ptr, len)) + } + } + } + + /// Returns the ciphers field of the client's hello message. + /// + /// This can only be used inside of the client hello callback. Otherwise, `None` is returned. + /// + /// Requires OpenSSL 1.1.1 or newer. + #[corresponds(SSL_client_hello_get0_ciphers)] + #[cfg(ossl111)] + pub fn client_hello_ciphers(&self) -> Option<&[u8]> { + unsafe { + let mut ptr = ptr::null(); + let len = ffi::SSL_client_hello_get0_ciphers(self.as_ptr(), &mut ptr); + if len == 0 { + None + } else { + Some(util::from_raw_parts(ptr, len)) + } + } + } + + /// Decodes a slice of wire-format cipher suite specification bytes. Unsupported cipher suites + /// are ignored. + /// + /// Requires OpenSSL 1.1.1 or newer. + #[corresponds(SSL_bytes_to_cipher_list)] + #[cfg(ossl111)] + pub fn bytes_to_cipher_list( + &self, + bytes: &[u8], + isv2format: bool, + ) -> Result { + unsafe { + let ptr = bytes.as_ptr(); + let len = bytes.len(); + let mut sk = ptr::null_mut(); + let mut scsvs = ptr::null_mut(); + let res = ffi::SSL_bytes_to_cipher_list( + self.as_ptr(), + ptr, + len, + isv2format as c_int, + &mut sk, + &mut scsvs, + ); + if res == 1 { + Ok(CipherLists { + suites: Stack::from_ptr(sk), + signalling_suites: Stack::from_ptr(scsvs), + }) + } else { + Err(ErrorStack::get()) + } + } + } + + /// Returns the compression methods field of the client's hello message. + /// + /// This can only be used inside of the client hello callback. Otherwise, `None` is returned. + /// + /// Requires OpenSSL 1.1.1 or newer. + #[corresponds(SSL_client_hello_get0_compression_methods)] + #[cfg(ossl111)] + pub fn client_hello_compression_methods(&self) -> Option<&[u8]> { + unsafe { + let mut ptr = ptr::null(); + let len = ffi::SSL_client_hello_get0_compression_methods(self.as_ptr(), &mut ptr); + if len == 0 { + None + } else { + Some(util::from_raw_parts(ptr, len)) + } + } + } + + /// Sets the MTU used for DTLS connections. + #[corresponds(SSL_set_mtu)] + pub fn set_mtu(&mut self, mtu: u32) -> Result<(), ErrorStack> { + unsafe { cvt(ffi::SSL_set_mtu(self.as_ptr(), mtu as MtuTy) as c_int).map(|_| ()) } + } + + /// Returns the PSK identity hint used during connection setup. + /// + /// May return `None` if no PSK identity hint was used during the connection setup. + #[corresponds(SSL_get_psk_identity_hint)] + #[cfg(not(osslconf = "OPENSSL_NO_PSK"))] + pub fn psk_identity_hint(&self) -> Option<&[u8]> { + unsafe { + let ptr = ffi::SSL_get_psk_identity_hint(self.as_ptr()); + if ptr.is_null() { + None + } else { + Some(CStr::from_ptr(ptr).to_bytes()) + } + } + } + + /// Returns the PSK identity used during connection setup. + #[corresponds(SSL_get_psk_identity)] + #[cfg(not(osslconf = "OPENSSL_NO_PSK"))] + pub fn psk_identity(&self) -> Option<&[u8]> { + unsafe { + let ptr = ffi::SSL_get_psk_identity(self.as_ptr()); + if ptr.is_null() { + None + } else { + Some(CStr::from_ptr(ptr).to_bytes()) + } + } + } + + #[corresponds(SSL_add0_chain_cert)] + #[cfg(ossl102)] + pub fn add_chain_cert(&mut self, chain: X509) -> Result<(), ErrorStack> { + unsafe { + cvt(ffi::SSL_add0_chain_cert(self.as_ptr(), chain.as_ptr()) as c_int).map(|_| ())?; + mem::forget(chain); + } + Ok(()) + } + + /// Sets a new default TLS/SSL method for SSL objects + #[cfg(not(boringssl))] + pub fn set_method(&mut self, method: SslMethod) -> Result<(), ErrorStack> { + unsafe { + cvt(ffi::SSL_set_ssl_method(self.as_ptr(), method.as_ptr()))?; + }; + Ok(()) + } + + /// Loads the private key from a file. + #[corresponds(SSL_use_Private_Key_file)] + pub fn set_private_key_file>( + &mut self, + path: P, + ssl_file_type: SslFiletype, + ) -> Result<(), ErrorStack> { + let p = path.as_ref().as_os_str().to_str().unwrap(); + let key_file = CString::new(p).unwrap(); + unsafe { + cvt(ffi::SSL_use_PrivateKey_file( + self.as_ptr(), + key_file.as_ptr(), + ssl_file_type.as_raw(), + ))?; + }; + Ok(()) + } + + /// Sets the private key. + #[corresponds(SSL_use_PrivateKey)] + pub fn set_private_key(&mut self, pkey: &PKeyRef) -> Result<(), ErrorStack> { + unsafe { + cvt(ffi::SSL_use_PrivateKey(self.as_ptr(), pkey.as_ptr()))?; + }; + Ok(()) + } + + /// Sets the certificate + #[corresponds(SSL_use_certificate)] + pub fn set_certificate(&mut self, cert: &X509Ref) -> Result<(), ErrorStack> { + unsafe { + cvt(ffi::SSL_use_certificate(self.as_ptr(), cert.as_ptr()))?; + }; + Ok(()) + } + + /// Loads a certificate chain from a file. + /// + /// The file should contain a sequence of PEM-formatted certificates, the first being the leaf + /// certificate, and the remainder forming the chain of certificates up to and including the + /// trusted root certificate. + #[corresponds(SSL_use_certificate_chain_file)] + #[cfg(any(ossl110, libressl332))] + pub fn set_certificate_chain_file>( + &mut self, + path: P, + ) -> Result<(), ErrorStack> { + let p = path.as_ref().as_os_str().to_str().unwrap(); + let cert_file = CString::new(p).unwrap(); + unsafe { + cvt(ffi::SSL_use_certificate_chain_file( + self.as_ptr(), + cert_file.as_ptr(), + ))?; + }; + Ok(()) + } + + /// Sets ca certificate that client trusted + #[corresponds(SSL_add_client_CA)] + pub fn add_client_ca(&mut self, cacert: &X509Ref) -> Result<(), ErrorStack> { + unsafe { + cvt(ffi::SSL_add_client_CA(self.as_ptr(), cacert.as_ptr()))?; + }; + Ok(()) + } + + // Sets the list of CAs sent to the client when requesting a client certificate for the chosen ssl + #[corresponds(SSL_set_client_CA_list)] + pub fn set_client_ca_list(&mut self, list: Stack) { + unsafe { ffi::SSL_set_client_CA_list(self.as_ptr(), list.as_ptr()) } + mem::forget(list); + } + + /// Sets the minimum supported protocol version. + /// + /// A value of `None` will enable protocol versions down to the lowest version supported by + /// OpenSSL. + /// + /// Requires BoringSSL or OpenSSL 1.1.0 or LibreSSL 2.6.1 or newer. + #[corresponds(SSL_set_min_proto_version)] + #[cfg(any(ossl110, libressl261, boringssl))] + pub fn set_min_proto_version(&mut self, version: Option) -> Result<(), ErrorStack> { + unsafe { + cvt(ffi::SSL_set_min_proto_version( + self.as_ptr(), + version.map_or(0, |v| v.0 as _), + )) + .map(|_| ()) + } + } + + /// Sets the maximum supported protocol version. + /// + /// A value of `None` will enable protocol versions up to the highest version supported by + /// OpenSSL. + /// + /// Requires BoringSSL or OpenSSL 1.1.0 or or LibreSSL 2.6.1 or newer. + #[corresponds(SSL_set_max_proto_version)] + #[cfg(any(ossl110, libressl261, boringssl))] + pub fn set_max_proto_version(&mut self, version: Option) -> Result<(), ErrorStack> { + unsafe { + cvt(ffi::SSL_set_max_proto_version( + self.as_ptr(), + version.map_or(0, |v| v.0 as _), + )) + .map(|_| ()) + } + } + + /// Sets the list of supported ciphers for the TLSv1.3 protocol. + /// + /// The `set_cipher_list` method controls the cipher suites for protocols before TLSv1.3. + /// + /// The format consists of TLSv1.3 cipher suite names separated by `:` characters in order of + /// preference. + /// + /// Requires OpenSSL 1.1.1 or LibreSSL 3.4.0 or newer. + #[corresponds(SSL_set_ciphersuites)] + #[cfg(any(ossl111, libressl340))] + pub fn set_ciphersuites(&mut self, cipher_list: &str) -> Result<(), ErrorStack> { + let cipher_list = CString::new(cipher_list).unwrap(); + unsafe { + cvt(ffi::SSL_set_ciphersuites( + self.as_ptr(), + cipher_list.as_ptr() as *const _, + )) + .map(|_| ()) + } + } + + /// Sets the list of supported ciphers for protocols before TLSv1.3. + /// + /// The `set_ciphersuites` method controls the cipher suites for TLSv1.3. + /// + /// See [`ciphers`] for details on the format. + /// + /// [`ciphers`]: https://www.openssl.org/docs/manmaster/apps/ciphers.html + #[corresponds(SSL_set_cipher_list)] + pub fn set_cipher_list(&mut self, cipher_list: &str) -> Result<(), ErrorStack> { + let cipher_list = CString::new(cipher_list).unwrap(); + unsafe { + cvt(ffi::SSL_set_cipher_list( + self.as_ptr(), + cipher_list.as_ptr() as *const _, + )) + .map(|_| ()) + } + } + + /// Set the certificate store used for certificate verification + #[corresponds(SSL_set_cert_store)] + #[cfg(ossl102)] + pub fn set_verify_cert_store(&mut self, cert_store: X509Store) -> Result<(), ErrorStack> { + unsafe { + cvt(ffi::SSL_set0_verify_cert_store(self.as_ptr(), cert_store.as_ptr()) as c_int)?; + mem::forget(cert_store); + Ok(()) + } + } + + /// Sets the number of TLS 1.3 session tickets that will be sent to a client after a full + /// handshake. + /// + /// Requires OpenSSL 1.1.1 or newer. + #[corresponds(SSL_set_num_tickets)] + #[cfg(ossl111)] + pub fn set_num_tickets(&mut self, num_tickets: usize) -> Result<(), ErrorStack> { + unsafe { cvt(ffi::SSL_set_num_tickets(self.as_ptr(), num_tickets)).map(|_| ()) } + } + + /// Gets the number of TLS 1.3 session tickets that will be sent to a client after a full + /// handshake. + /// + /// Requires OpenSSL 1.1.1 or newer. + #[corresponds(SSL_get_num_tickets)] + #[cfg(ossl111)] + pub fn num_tickets(&self) -> usize { + unsafe { ffi::SSL_get_num_tickets(self.as_ptr()) } + } + + /// Set the context's security level to a value between 0 and 5, inclusive. + /// A security value of 0 allows allows all parameters and algorithms. + /// + /// Requires OpenSSL 1.1.0 or newer. + #[corresponds(SSL_set_security_level)] + #[cfg(any(ossl110, libressl360))] + pub fn set_security_level(&mut self, level: u32) { + unsafe { ffi::SSL_set_security_level(self.as_ptr(), level as c_int) } + } + + /// Get the connection's security level, which controls the allowed parameters + /// and algorithms. + /// + /// Requires OpenSSL 1.1.0 or newer. + #[corresponds(SSL_get_security_level)] + #[cfg(any(ossl110, libressl360))] + pub fn security_level(&self) -> u32 { + unsafe { ffi::SSL_get_security_level(self.as_ptr()) as u32 } + } + + /// Get the temporary key provided by the peer that is used during key + /// exchange. + // We use an owned value because EVP_KEY free need to be called when it is + // dropped + #[corresponds(SSL_get_peer_tmp_key)] + #[cfg(ossl300)] + pub fn peer_tmp_key(&self) -> Result, ErrorStack> { + unsafe { + let mut key = ptr::null_mut(); + match cvt_long(ffi::SSL_get_peer_tmp_key(self.as_ptr(), &mut key)) { + Ok(_) => Ok(PKey::::from_ptr(key)), + Err(e) => Err(e), + } + } + } + + /// Returns the temporary key from the local end of the connection that is + /// used during key exchange. + // We use an owned value because EVP_KEY free need to be called when it is + // dropped + #[corresponds(SSL_get_tmp_key)] + #[cfg(ossl300)] + pub fn tmp_key(&self) -> Result, ErrorStack> { + unsafe { + let mut key = ptr::null_mut(); + match cvt_long(ffi::SSL_get_tmp_key(self.as_ptr(), &mut key)) { + Ok(_) => Ok(PKey::::from_ptr(key)), + Err(e) => Err(e), + } + } + } +} + +/// An SSL stream midway through the handshake process. +#[derive(Debug)] +pub struct MidHandshakeSslStream { + stream: SslStream, + error: Error, +} + +impl MidHandshakeSslStream { + /// Returns a shared reference to the inner stream. + pub fn get_ref(&self) -> &S { + self.stream.get_ref() + } + + /// Returns a mutable reference to the inner stream. + pub fn get_mut(&mut self) -> &mut S { + self.stream.get_mut() + } + + /// Returns a shared reference to the `Ssl` of the stream. + pub fn ssl(&self) -> &SslRef { + self.stream.ssl() + } + + /// Returns the underlying error which interrupted this handshake. + pub fn error(&self) -> &Error { + &self.error + } + + /// Consumes `self`, returning its error. + pub fn into_error(self) -> Error { + self.error + } +} + +impl MidHandshakeSslStream +where + S: Read + Write, +{ + /// Restarts the handshake process. + /// + #[corresponds(SSL_do_handshake)] + pub fn handshake(mut self) -> Result, HandshakeError> { + match self.stream.do_handshake() { + Ok(()) => Ok(self.stream), + Err(error) => { + self.error = error; + match self.error.code() { + ErrorCode::WANT_READ | ErrorCode::WANT_WRITE => { + Err(HandshakeError::WouldBlock(self)) + } + _ => Err(HandshakeError::Failure(self)), + } + } + } + } +} + +/// A TLS session over a stream. +pub struct SslStream { + ssl: ManuallyDrop, + method: ManuallyDrop, + _p: PhantomData, +} + +impl Drop for SslStream { + fn drop(&mut self) { + // ssl holds a reference to method internally so it has to drop first + unsafe { + ManuallyDrop::drop(&mut self.ssl); + ManuallyDrop::drop(&mut self.method); + } + } +} + +impl fmt::Debug for SslStream +where + S: fmt::Debug, +{ + fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { + fmt.debug_struct("SslStream") + .field("stream", &self.get_ref()) + .field("ssl", &self.ssl()) + .finish() + } +} + +impl SslStream { + /// Creates a new `SslStream`. + /// + /// This function performs no IO; the stream will not have performed any part of the handshake + /// with the peer. If the `Ssl` was configured with [`SslRef::set_connect_state`] or + /// [`SslRef::set_accept_state`], the handshake can be performed automatically during the first + /// call to read or write. Otherwise the `connect` and `accept` methods can be used to + /// explicitly perform the handshake. + #[corresponds(SSL_set_bio)] + pub fn new(ssl: Ssl, stream: S) -> Result { + let (bio, method) = bio::new(stream)?; + unsafe { + ffi::SSL_set_bio(ssl.as_ptr(), bio, bio); + } + + Ok(SslStream { + ssl: ManuallyDrop::new(ssl), + method: ManuallyDrop::new(method), + _p: PhantomData, + }) + } + + /// Constructs an `SslStream` from a pointer to the underlying OpenSSL `SSL` struct. + /// + /// This is useful if the handshake has already been completed elsewhere. + /// + /// # Safety + /// + /// The caller must ensure the pointer is valid. + #[deprecated( + since = "0.10.32", + note = "use Ssl::from_ptr and SslStream::new instead" + )] + pub unsafe fn from_raw_parts(ssl: *mut ffi::SSL, stream: S) -> Self { + let ssl = Ssl::from_ptr(ssl); + Self::new(ssl, stream).unwrap() + } + + /// Read application data transmitted by a client before handshake completion. + /// + /// Useful for reducing latency, but vulnerable to replay attacks. Call + /// [`SslRef::set_accept_state`] first. + /// + /// Returns `Ok(0)` if all early data has been read. + /// + /// Requires OpenSSL 1.1.1 or LibreSSL 3.4.0 or newer. + #[corresponds(SSL_read_early_data)] + #[cfg(any(ossl111, libressl340))] + pub fn read_early_data(&mut self, buf: &mut [u8]) -> Result { + let mut read = 0; + let ret = unsafe { + ffi::SSL_read_early_data( + self.ssl.as_ptr(), + buf.as_ptr() as *mut c_void, + buf.len(), + &mut read, + ) + }; + match ret { + ffi::SSL_READ_EARLY_DATA_ERROR => Err(self.make_error(ret)), + ffi::SSL_READ_EARLY_DATA_SUCCESS => Ok(read), + ffi::SSL_READ_EARLY_DATA_FINISH => Ok(0), + _ => unreachable!(), + } + } + + /// Send data to the server without blocking on handshake completion. + /// + /// Useful for reducing latency, but vulnerable to replay attacks. Call + /// [`SslRef::set_connect_state`] first. + /// + /// Requires OpenSSL 1.1.1 or LibreSSL 3.4.0 or newer. + #[corresponds(SSL_write_early_data)] + #[cfg(any(ossl111, libressl340))] + pub fn write_early_data(&mut self, buf: &[u8]) -> Result { + let mut written = 0; + let ret = unsafe { + ffi::SSL_write_early_data( + self.ssl.as_ptr(), + buf.as_ptr() as *const c_void, + buf.len(), + &mut written, + ) + }; + if ret > 0 { + Ok(written) + } else { + Err(self.make_error(ret)) + } + } + + /// Initiates a client-side TLS handshake. + /// + /// # Warning + /// + /// OpenSSL's default configuration is insecure. It is highly recommended to use + /// `SslConnector` rather than `Ssl` directly, as it manages that configuration. + #[corresponds(SSL_connect)] + pub fn connect(&mut self) -> Result<(), Error> { + let ret = unsafe { ffi::SSL_connect(self.ssl.as_ptr()) }; + if ret > 0 { + Ok(()) + } else { + Err(self.make_error(ret)) + } + } + + /// Initiates a server-side TLS handshake. + /// + /// # Warning + /// + /// OpenSSL's default configuration is insecure. It is highly recommended to use + /// `SslAcceptor` rather than `Ssl` directly, as it manages that configuration. + #[corresponds(SSL_accept)] + pub fn accept(&mut self) -> Result<(), Error> { + let ret = unsafe { ffi::SSL_accept(self.ssl.as_ptr()) }; + if ret > 0 { + Ok(()) + } else { + Err(self.make_error(ret)) + } + } + + /// Initiates the handshake. + /// + /// This will fail if `set_accept_state` or `set_connect_state` was not called first. + #[corresponds(SSL_do_handshake)] + pub fn do_handshake(&mut self) -> Result<(), Error> { + let ret = unsafe { ffi::SSL_do_handshake(self.ssl.as_ptr()) }; + if ret > 0 { + Ok(()) + } else { + Err(self.make_error(ret)) + } + } + + /// Perform a stateless server-side handshake. + /// + /// Requires that cookie generation and verification callbacks were + /// set on the SSL context. + /// + /// Returns `Ok(true)` if a complete ClientHello containing a valid cookie + /// was read, in which case the handshake should be continued via + /// `accept`. If a HelloRetryRequest containing a fresh cookie was + /// transmitted, `Ok(false)` is returned instead. If the handshake cannot + /// proceed at all, `Err` is returned. + #[corresponds(SSL_stateless)] + #[cfg(ossl111)] + pub fn stateless(&mut self) -> Result { + match unsafe { ffi::SSL_stateless(self.ssl.as_ptr()) } { + 1 => Ok(true), + 0 => Ok(false), + -1 => Err(ErrorStack::get()), + _ => unreachable!(), + } + } + + /// Like `read`, but takes a possibly-uninitialized slice. + /// + /// # Safety + /// + /// No portion of `buf` will be de-initialized by this method. If the method returns `Ok(n)`, + /// then the first `n` bytes of `buf` are guaranteed to be initialized. + #[corresponds(SSL_read_ex)] + pub fn read_uninit(&mut self, buf: &mut [MaybeUninit]) -> io::Result { + loop { + match self.ssl_read_uninit(buf) { + Ok(n) => return Ok(n), + Err(ref e) if e.code() == ErrorCode::ZERO_RETURN => return Ok(0), + Err(ref e) if e.code() == ErrorCode::SYSCALL && e.io_error().is_none() => { + return Ok(0); + } + Err(ref e) if e.code() == ErrorCode::WANT_READ && e.io_error().is_none() => {} + Err(e) => { + return Err(e + .into_io_error() + .unwrap_or_else(|e| io::Error::new(io::ErrorKind::Other, e))); + } + } + } + } + + /// Like `read`, but returns an `ssl::Error` rather than an `io::Error`. + /// + /// It is particularly useful with a non-blocking socket, where the error value will identify if + /// OpenSSL is waiting on read or write readiness. + #[corresponds(SSL_read_ex)] + pub fn ssl_read(&mut self, buf: &mut [u8]) -> Result { + // SAFETY: `ssl_read_uninit` does not de-initialize the buffer. + unsafe { + self.ssl_read_uninit(util::from_raw_parts_mut( + buf.as_mut_ptr().cast::>(), + buf.len(), + )) + } + } + + /// Like `read_ssl`, but takes a possibly-uninitialized slice. + /// + /// # Safety + /// + /// No portion of `buf` will be de-initialized by this method. If the method returns `Ok(n)`, + /// then the first `n` bytes of `buf` are guaranteed to be initialized. + #[corresponds(SSL_read_ex)] + pub fn ssl_read_uninit(&mut self, buf: &mut [MaybeUninit]) -> Result { + cfg_if! { + if #[cfg(any(ossl111, libressl350))] { + let mut readbytes = 0; + let ret = unsafe { + ffi::SSL_read_ex( + self.ssl().as_ptr(), + buf.as_mut_ptr().cast(), + buf.len(), + &mut readbytes, + ) + }; + + if ret > 0 { + Ok(readbytes) + } else { + Err(self.make_error(ret)) + } + } else { + if buf.is_empty() { + return Ok(0); + } + + let len = usize::min(c_int::MAX as usize, buf.len()) as c_int; + let ret = unsafe { + ffi::SSL_read(self.ssl().as_ptr(), buf.as_mut_ptr().cast(), len) + }; + if ret > 0 { + Ok(ret as usize) + } else { + Err(self.make_error(ret)) + } + } + } + } + + /// Like `write`, but returns an `ssl::Error` rather than an `io::Error`. + /// + /// It is particularly useful with a non-blocking socket, where the error value will identify if + /// OpenSSL is waiting on read or write readiness. + #[corresponds(SSL_write_ex)] + pub fn ssl_write(&mut self, buf: &[u8]) -> Result { + cfg_if! { + if #[cfg(any(ossl111, libressl350))] { + let mut written = 0; + let ret = unsafe { + ffi::SSL_write_ex( + self.ssl().as_ptr(), + buf.as_ptr().cast(), + buf.len(), + &mut written, + ) + }; + + if ret > 0 { + Ok(written) + } else { + Err(self.make_error(ret)) + } + } else { + if buf.is_empty() { + return Ok(0); + } + + let len = usize::min(c_int::MAX as usize, buf.len()) as c_int; + let ret = unsafe { + ffi::SSL_write(self.ssl().as_ptr(), buf.as_ptr().cast(), len) + }; + if ret > 0 { + Ok(ret as usize) + } else { + Err(self.make_error(ret)) + } + } + } + } + + /// Reads data from the stream, without removing it from the queue. + #[corresponds(SSL_peek_ex)] + pub fn ssl_peek(&mut self, buf: &mut [u8]) -> Result { + cfg_if! { + if #[cfg(any(ossl111, libressl350))] { + let mut readbytes = 0; + let ret = unsafe { + ffi::SSL_peek_ex( + self.ssl().as_ptr(), + buf.as_mut_ptr().cast(), + buf.len(), + &mut readbytes, + ) + }; + + if ret > 0 { + Ok(readbytes) + } else { + Err(self.make_error(ret)) + } + } else { + if buf.is_empty() { + return Ok(0); + } + + let len = usize::min(c_int::MAX as usize, buf.len()) as c_int; + let ret = unsafe { + ffi::SSL_peek(self.ssl().as_ptr(), buf.as_mut_ptr().cast(), len) + }; + if ret > 0 { + Ok(ret as usize) + } else { + Err(self.make_error(ret)) + } + } + } + } + + /// Shuts down the session. + /// + /// The shutdown process consists of two steps. The first step sends a close notify message to + /// the peer, after which `ShutdownResult::Sent` is returned. The second step awaits the receipt + /// of a close notify message from the peer, after which `ShutdownResult::Received` is returned. + /// + /// While the connection may be closed after the first step, it is recommended to fully shut the + /// session down. In particular, it must be fully shut down if the connection is to be used for + /// further communication in the future. + #[corresponds(SSL_shutdown)] + pub fn shutdown(&mut self) -> Result { + match unsafe { ffi::SSL_shutdown(self.ssl.as_ptr()) } { + 0 => Ok(ShutdownResult::Sent), + 1 => Ok(ShutdownResult::Received), + n => Err(self.make_error(n)), + } + } + + /// Returns the session's shutdown state. + #[corresponds(SSL_get_shutdown)] + pub fn get_shutdown(&mut self) -> ShutdownState { + unsafe { + let bits = ffi::SSL_get_shutdown(self.ssl.as_ptr()); + ShutdownState::from_bits_retain(bits) + } + } + + /// Sets the session's shutdown state. + /// + /// This can be used to tell OpenSSL that the session should be cached even if a full two-way + /// shutdown was not completed. + #[corresponds(SSL_set_shutdown)] + pub fn set_shutdown(&mut self, state: ShutdownState) { + unsafe { ffi::SSL_set_shutdown(self.ssl.as_ptr(), state.bits()) } + } +} + +impl SslStream { + fn make_error(&mut self, ret: c_int) -> Error { + self.check_panic(); + + let code = self.ssl.get_error(ret); + + let cause = match code { + ErrorCode::SSL => Some(InnerError::Ssl(ErrorStack::get())), + ErrorCode::SYSCALL => { + let errs = ErrorStack::get(); + if errs.errors().is_empty() { + self.get_bio_error().map(InnerError::Io) + } else { + Some(InnerError::Ssl(errs)) + } + } + ErrorCode::ZERO_RETURN => None, + ErrorCode::WANT_READ | ErrorCode::WANT_WRITE => { + self.get_bio_error().map(InnerError::Io) + } + _ => None, + }; + + Error { code, cause } + } + + fn check_panic(&mut self) { + if let Some(err) = unsafe { bio::take_panic::(self.ssl.get_raw_rbio()) } { + resume_unwind(err) + } + } + + fn get_bio_error(&mut self) -> Option { + unsafe { bio::take_error::(self.ssl.get_raw_rbio()) } + } + + /// Returns a shared reference to the underlying stream. + pub fn get_ref(&self) -> &S { + unsafe { + let bio = self.ssl.get_raw_rbio(); + bio::get_ref(bio) + } + } + + /// Returns a mutable reference to the underlying stream. + /// + /// # Warning + /// + /// It is inadvisable to read from or write to the underlying stream as it + /// will most likely corrupt the SSL session. + pub fn get_mut(&mut self) -> &mut S { + unsafe { + let bio = self.ssl.get_raw_rbio(); + bio::get_mut(bio) + } + } + + /// Returns a shared reference to the `Ssl` object associated with this stream. + pub fn ssl(&self) -> &SslRef { + &self.ssl + } +} + +impl Read for SslStream { + fn read(&mut self, buf: &mut [u8]) -> io::Result { + // SAFETY: `read_uninit` does not de-initialize the buffer + unsafe { + self.read_uninit(util::from_raw_parts_mut( + buf.as_mut_ptr().cast::>(), + buf.len(), + )) + } + } +} + +impl Write for SslStream { + fn write(&mut self, buf: &[u8]) -> io::Result { + loop { + match self.ssl_write(buf) { + Ok(n) => return Ok(n), + Err(ref e) if e.code() == ErrorCode::WANT_READ && e.io_error().is_none() => {} + Err(e) => { + return Err(e + .into_io_error() + .unwrap_or_else(|e| io::Error::new(io::ErrorKind::Other, e))); + } + } + } + } + + fn flush(&mut self) -> io::Result<()> { + self.get_mut().flush() + } +} + +/// A partially constructed `SslStream`, useful for unusual handshakes. +#[deprecated( + since = "0.10.32", + note = "use the methods directly on Ssl/SslStream instead" +)] +pub struct SslStreamBuilder { + inner: SslStream, +} + +#[allow(deprecated)] +impl SslStreamBuilder +where + S: Read + Write, +{ + /// Begin creating an `SslStream` atop `stream` + pub fn new(ssl: Ssl, stream: S) -> Self { + Self { + inner: SslStream::new(ssl, stream).unwrap(), + } + } + + /// Perform a stateless server-side handshake + /// + /// Requires that cookie generation and verification callbacks were + /// set on the SSL context. + /// + /// Returns `Ok(true)` if a complete ClientHello containing a valid cookie + /// was read, in which case the handshake should be continued via + /// `accept`. If a HelloRetryRequest containing a fresh cookie was + /// transmitted, `Ok(false)` is returned instead. If the handshake cannot + /// proceed at all, `Err` is returned. + #[corresponds(SSL_stateless)] + #[cfg(ossl111)] + pub fn stateless(&mut self) -> Result { + match unsafe { ffi::SSL_stateless(self.inner.ssl.as_ptr()) } { + 1 => Ok(true), + 0 => Ok(false), + -1 => Err(ErrorStack::get()), + _ => unreachable!(), + } + } + + /// Configure as an outgoing stream from a client. + #[corresponds(SSL_set_connect_state)] + pub fn set_connect_state(&mut self) { + unsafe { ffi::SSL_set_connect_state(self.inner.ssl.as_ptr()) } + } + + /// Configure as an incoming stream to a server. + #[corresponds(SSL_set_accept_state)] + pub fn set_accept_state(&mut self) { + unsafe { ffi::SSL_set_accept_state(self.inner.ssl.as_ptr()) } + } + + /// See `Ssl::connect` + pub fn connect(mut self) -> Result, HandshakeError> { + match self.inner.connect() { + Ok(()) => Ok(self.inner), + Err(error) => match error.code() { + ErrorCode::WANT_READ | ErrorCode::WANT_WRITE => { + Err(HandshakeError::WouldBlock(MidHandshakeSslStream { + stream: self.inner, + error, + })) + } + _ => Err(HandshakeError::Failure(MidHandshakeSslStream { + stream: self.inner, + error, + })), + }, + } + } + + /// See `Ssl::accept` + pub fn accept(mut self) -> Result, HandshakeError> { + match self.inner.accept() { + Ok(()) => Ok(self.inner), + Err(error) => match error.code() { + ErrorCode::WANT_READ | ErrorCode::WANT_WRITE => { + Err(HandshakeError::WouldBlock(MidHandshakeSslStream { + stream: self.inner, + error, + })) + } + _ => Err(HandshakeError::Failure(MidHandshakeSslStream { + stream: self.inner, + error, + })), + }, + } + } + + /// Initiates the handshake. + /// + /// This will fail if `set_accept_state` or `set_connect_state` was not called first. + #[corresponds(SSL_do_handshake)] + pub fn handshake(mut self) -> Result, HandshakeError> { + match self.inner.do_handshake() { + Ok(()) => Ok(self.inner), + Err(error) => match error.code() { + ErrorCode::WANT_READ | ErrorCode::WANT_WRITE => { + Err(HandshakeError::WouldBlock(MidHandshakeSslStream { + stream: self.inner, + error, + })) + } + _ => Err(HandshakeError::Failure(MidHandshakeSslStream { + stream: self.inner, + error, + })), + }, + } + } + + /// Read application data transmitted by a client before handshake + /// completion. + /// + /// Useful for reducing latency, but vulnerable to replay attacks. Call + /// `set_accept_state` first. + /// + /// Returns `Ok(0)` if all early data has been read. + /// + /// Requires OpenSSL 1.1.1 or LibreSSL 3.4.0 or newer. + #[corresponds(SSL_read_early_data)] + #[cfg(any(ossl111, libressl340))] + pub fn read_early_data(&mut self, buf: &mut [u8]) -> Result { + self.inner.read_early_data(buf) + } + + /// Send data to the server without blocking on handshake completion. + /// + /// Useful for reducing latency, but vulnerable to replay attacks. Call + /// `set_connect_state` first. + /// + /// Requires OpenSSL 1.1.1 or LibreSSL 3.4.0 or newer. + #[corresponds(SSL_write_early_data)] + #[cfg(any(ossl111, libressl340))] + pub fn write_early_data(&mut self, buf: &[u8]) -> Result { + self.inner.write_early_data(buf) + } +} + +#[allow(deprecated)] +impl SslStreamBuilder { + /// Returns a shared reference to the underlying stream. + pub fn get_ref(&self) -> &S { + unsafe { + let bio = self.inner.ssl.get_raw_rbio(); + bio::get_ref(bio) + } + } + + /// Returns a mutable reference to the underlying stream. + /// + /// # Warning + /// + /// It is inadvisable to read from or write to the underlying stream as it + /// will most likely corrupt the SSL session. + pub fn get_mut(&mut self) -> &mut S { + unsafe { + let bio = self.inner.ssl.get_raw_rbio(); + bio::get_mut(bio) + } + } + + /// Returns a shared reference to the `Ssl` object associated with this builder. + pub fn ssl(&self) -> &SslRef { + &self.inner.ssl + } + + /// Set the DTLS MTU size. + /// + /// It will be ignored if the value is smaller than the minimum packet size + /// the DTLS protocol requires. + /// + /// # Panics + /// This function panics if the given mtu size can't be represented in a positive `c_long` range + #[deprecated(note = "Use SslRef::set_mtu instead", since = "0.10.30")] + pub fn set_dtls_mtu_size(&mut self, mtu_size: usize) { + unsafe { + let bio = self.inner.ssl.get_raw_rbio(); + bio::set_dtls_mtu_size::(bio, mtu_size); + } + } +} + +/// The result of a shutdown request. +#[derive(Copy, Clone, Debug, PartialEq, Eq)] +pub enum ShutdownResult { + /// A close notify message has been sent to the peer. + Sent, + + /// A close notify response message has been received from the peer. + Received, +} + +bitflags! { + /// The shutdown state of a session. + #[derive(Copy, Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)] + #[repr(transparent)] + pub struct ShutdownState: c_int { + /// A close notify message has been sent to the peer. + const SENT = ffi::SSL_SENT_SHUTDOWN; + /// A close notify message has been received from the peer. + const RECEIVED = ffi::SSL_RECEIVED_SHUTDOWN; + } +} + +cfg_if! { + if #[cfg(any(boringssl, ossl110, libressl273))] { + use ffi::{SSL_CTX_up_ref, SSL_SESSION_get_master_key, SSL_SESSION_up_ref, SSL_is_server}; + } else { + #[allow(bad_style)] + pub unsafe fn SSL_CTX_up_ref(ssl: *mut ffi::SSL_CTX) -> c_int { + ffi::CRYPTO_add_lock( + &mut (*ssl).references, + 1, + ffi::CRYPTO_LOCK_SSL_CTX, + "mod.rs\0".as_ptr() as *const _, + line!() as c_int, + ); + 0 + } + + #[allow(bad_style)] + pub unsafe fn SSL_SESSION_get_master_key( + session: *const ffi::SSL_SESSION, + out: *mut c_uchar, + mut outlen: usize, + ) -> usize { + if outlen == 0 { + return (*session).master_key_length as usize; + } + if outlen > (*session).master_key_length as usize { + outlen = (*session).master_key_length as usize; + } + ptr::copy_nonoverlapping((*session).master_key.as_ptr(), out, outlen); + outlen + } + + #[allow(bad_style)] + pub unsafe fn SSL_is_server(s: *mut ffi::SSL) -> c_int { + (*s).server + } + + #[allow(bad_style)] + pub unsafe fn SSL_SESSION_up_ref(ses: *mut ffi::SSL_SESSION) -> c_int { + ffi::CRYPTO_add_lock( + &mut (*ses).references, + 1, + ffi::CRYPTO_LOCK_SSL_CTX, + "mod.rs\0".as_ptr() as *const _, + line!() as c_int, + ); + 0 + } + } +} + +cfg_if! { + if #[cfg(ossl300)] { + use ffi::SSL_get1_peer_certificate; + } else { + use ffi::SSL_get_peer_certificate as SSL_get1_peer_certificate; + } +} +cfg_if! { + if #[cfg(any(boringssl, ossl110, libressl291))] { + use ffi::{TLS_method, DTLS_method, TLS_client_method, TLS_server_method}; + } else { + use ffi::{ + SSLv23_method as TLS_method, DTLSv1_method as DTLS_method, SSLv23_client_method as TLS_client_method, + SSLv23_server_method as TLS_server_method, + }; + } +} +cfg_if! { + if #[cfg(ossl110)] { + unsafe fn get_new_idx(f: ffi::CRYPTO_EX_free) -> c_int { + ffi::CRYPTO_get_ex_new_index( + ffi::CRYPTO_EX_INDEX_SSL_CTX, + 0, + ptr::null_mut(), + None, + None, + Some(f), + ) + } + + unsafe fn get_new_ssl_idx(f: ffi::CRYPTO_EX_free) -> c_int { + ffi::CRYPTO_get_ex_new_index( + ffi::CRYPTO_EX_INDEX_SSL, + 0, + ptr::null_mut(), + None, + None, + Some(f), + ) + } + } else { + use std::sync::Once; + + unsafe fn get_new_idx(f: ffi::CRYPTO_EX_free) -> c_int { + // hack around https://rt.openssl.org/Ticket/Display.html?id=3710&user=guest&pass=guest + static ONCE: Once = Once::new(); + ONCE.call_once(|| { + cfg_if! { + if #[cfg(not(boringssl))] { + ffi::SSL_CTX_get_ex_new_index(0, ptr::null_mut(), None, None, None); + } else { + ffi::SSL_CTX_get_ex_new_index(0, ptr::null_mut(), ptr::null_mut(), None, None); + } + } + }); + + cfg_if! { + if #[cfg(not(boringssl))] { + ffi::SSL_CTX_get_ex_new_index(0, ptr::null_mut(), None, None, Some(f)) + } else { + ffi::SSL_CTX_get_ex_new_index(0, ptr::null_mut(), ptr::null_mut(), None, f) + } + } + } + + unsafe fn get_new_ssl_idx(f: ffi::CRYPTO_EX_free) -> c_int { + // hack around https://rt.openssl.org/Ticket/Display.html?id=3710&user=guest&pass=guest + static ONCE: Once = Once::new(); + ONCE.call_once(|| { + #[cfg(not(boringssl))] + ffi::SSL_get_ex_new_index(0, ptr::null_mut(), None, None, None); + #[cfg(boringssl)] + ffi::SSL_get_ex_new_index(0, ptr::null_mut(), ptr::null_mut(), None, None); + }); + + #[cfg(not(boringssl))] + return ffi::SSL_get_ex_new_index(0, ptr::null_mut(), None, None, Some(f)); + #[cfg(boringssl)] + return ffi::SSL_get_ex_new_index(0, ptr::null_mut(), ptr::null_mut(), None, f); + } + } +} diff --git a/vendor/openssl/src/ssl/test/mod.rs b/vendor/openssl/src/ssl/test/mod.rs new file mode 100644 index 0000000..2c5fd00 --- /dev/null +++ b/vendor/openssl/src/ssl/test/mod.rs @@ -0,0 +1,1687 @@ +#![allow(unused_imports)] + +use std::env; +use std::fs::File; +use std::io::prelude::*; +use std::io::{self, BufReader}; +use std::iter; +use std::mem; +use std::net::UdpSocket; +use std::net::{SocketAddr, TcpListener, TcpStream}; +use std::path::Path; +use std::process::{Child, ChildStdin, Command, Stdio}; +use std::sync::atomic::{AtomicBool, AtomicUsize, Ordering}; +use std::thread; +use std::time::Duration; + +use crate::dh::Dh; +use crate::error::ErrorStack; +use crate::hash::MessageDigest; +#[cfg(not(boringssl))] +use crate::ocsp::{OcspResponse, OcspResponseStatus}; +use crate::pkey::{Id, PKey}; +use crate::srtp::SrtpProfileId; +use crate::ssl::test::server::Server; +#[cfg(any(ossl110, ossl111, libressl261))] +use crate::ssl::SslVersion; +use crate::ssl::{self, NameType, SslConnectorBuilder}; +#[cfg(ossl111)] +use crate::ssl::{ClientHelloResponse, ExtensionContext}; +use crate::ssl::{ + Error, HandshakeError, MidHandshakeSslStream, ShutdownResult, ShutdownState, Ssl, SslAcceptor, + SslAcceptorBuilder, SslConnector, SslContext, SslContextBuilder, SslFiletype, SslMethod, + SslOptions, SslSessionCacheMode, SslStream, SslVerifyMode, StatusType, +}; +#[cfg(ossl102)] +use crate::x509::store::X509StoreBuilder; +#[cfg(ossl102)] +use crate::x509::verify::X509CheckFlags; +use crate::x509::{X509Name, X509StoreContext, X509VerifyResult, X509}; + +mod server; + +static ROOT_CERT: &[u8] = include_bytes!("../../../test/root-ca.pem"); +static CERT: &[u8] = include_bytes!("../../../test/cert.pem"); +static KEY: &[u8] = include_bytes!("../../../test/key.pem"); + +#[test] +fn verify_untrusted() { + let mut server = Server::builder(); + server.should_error(); + let server = server.build(); + + let mut client = server.client(); + client.ctx().set_verify(SslVerifyMode::PEER); + + client.connect_err(); +} + +#[test] +fn verify_trusted() { + let server = Server::builder().build(); + + let mut client = server.client(); + client.ctx().set_ca_file("test/root-ca.pem").unwrap(); + + client.connect(); +} + +#[test] +#[cfg(ossl102)] +fn verify_trusted_with_set_cert() { + let server = Server::builder().build(); + + let mut store = X509StoreBuilder::new().unwrap(); + let x509 = X509::from_pem(ROOT_CERT).unwrap(); + store.add_cert(x509).unwrap(); + + let mut client = server.client(); + client.ctx().set_verify(SslVerifyMode::PEER); + client.ctx().set_verify_cert_store(store.build()).unwrap(); + + client.connect(); +} + +#[test] +fn verify_untrusted_callback_override_ok() { + static CALLED_BACK: AtomicBool = AtomicBool::new(false); + + let server = Server::builder().build(); + + let mut client = server.client(); + client + .ctx() + .set_verify_callback(SslVerifyMode::PEER, |_, x509| { + CALLED_BACK.store(true, Ordering::SeqCst); + assert!(x509.current_cert().is_some()); + true + }); + + client.connect(); + assert!(CALLED_BACK.load(Ordering::SeqCst)); +} + +#[test] +fn verify_untrusted_callback_override_bad() { + let mut server = Server::builder(); + server.should_error(); + let server = server.build(); + + let mut client = server.client(); + client + .ctx() + .set_verify_callback(SslVerifyMode::PEER, |_, _| false); + + client.connect_err(); +} + +#[test] +fn verify_trusted_callback_override_ok() { + static CALLED_BACK: AtomicBool = AtomicBool::new(false); + + let server = Server::builder().build(); + + let mut client = server.client(); + client.ctx().set_ca_file("test/root-ca.pem").unwrap(); + client + .ctx() + .set_verify_callback(SslVerifyMode::PEER, |_, x509| { + CALLED_BACK.store(true, Ordering::SeqCst); + assert!(x509.current_cert().is_some()); + true + }); + + client.connect(); + assert!(CALLED_BACK.load(Ordering::SeqCst)); +} + +#[test] +fn verify_trusted_callback_override_bad() { + let mut server = Server::builder(); + server.should_error(); + let server = server.build(); + + let mut client = server.client(); + client.ctx().set_ca_file("test/root-ca.pem").unwrap(); + client + .ctx() + .set_verify_callback(SslVerifyMode::PEER, |_, _| false); + + client.connect_err(); +} + +#[test] +fn verify_callback_load_certs() { + static CALLED_BACK: AtomicBool = AtomicBool::new(false); + + let server = Server::builder().build(); + + let mut client = server.client(); + client + .ctx() + .set_verify_callback(SslVerifyMode::PEER, |_, x509| { + CALLED_BACK.store(true, Ordering::SeqCst); + assert!(x509.current_cert().is_some()); + true + }); + + client.connect(); + assert!(CALLED_BACK.load(Ordering::SeqCst)); +} + +#[test] +fn verify_trusted_get_error_ok() { + static CALLED_BACK: AtomicBool = AtomicBool::new(false); + + let server = Server::builder().build(); + + let mut client = server.client(); + client.ctx().set_ca_file("test/root-ca.pem").unwrap(); + client + .ctx() + .set_verify_callback(SslVerifyMode::PEER, |_, x509| { + CALLED_BACK.store(true, Ordering::SeqCst); + assert_eq!(x509.error(), X509VerifyResult::OK); + true + }); + + client.connect(); + assert!(CALLED_BACK.load(Ordering::SeqCst)); +} + +#[test] +fn verify_trusted_get_error_err() { + let mut server = Server::builder(); + server.should_error(); + let server = server.build(); + + let mut client = server.client(); + client + .ctx() + .set_verify_callback(SslVerifyMode::PEER, |_, x509| { + assert_ne!(x509.error(), X509VerifyResult::OK); + false + }); + + client.connect_err(); +} + +#[test] +fn verify_callback() { + static CALLED_BACK: AtomicBool = AtomicBool::new(false); + + let server = Server::builder().build(); + + let mut client = server.client(); + let expected = "59172d9313e84459bcff27f967e79e6e9217e584"; + client + .ctx() + .set_verify_callback(SslVerifyMode::PEER, move |_, x509| { + CALLED_BACK.store(true, Ordering::SeqCst); + let cert = x509.current_cert().unwrap(); + let digest = cert.digest(MessageDigest::sha1()).unwrap(); + assert_eq!(hex::encode(digest), expected); + true + }); + + client.connect(); + assert!(CALLED_BACK.load(Ordering::SeqCst)); +} + +#[test] +fn ssl_verify_callback() { + static CALLED_BACK: AtomicBool = AtomicBool::new(false); + + let server = Server::builder().build(); + + let mut client = server.client().build().builder(); + let expected = "59172d9313e84459bcff27f967e79e6e9217e584"; + client + .ssl() + .set_verify_callback(SslVerifyMode::PEER, move |_, x509| { + CALLED_BACK.store(true, Ordering::SeqCst); + let cert = x509.current_cert().unwrap(); + let digest = cert.digest(MessageDigest::sha1()).unwrap(); + assert_eq!(hex::encode(digest), expected); + true + }); + + client.connect(); + assert!(CALLED_BACK.load(Ordering::SeqCst)); +} + +#[test] +fn get_ctx_options() { + let ctx = SslContext::builder(SslMethod::tls()).unwrap(); + ctx.options(); +} + +#[test] +fn set_ctx_options() { + let mut ctx = SslContext::builder(SslMethod::tls()).unwrap(); + let opts = ctx.set_options(SslOptions::NO_TICKET); + assert!(opts.contains(SslOptions::NO_TICKET)); +} + +#[test] +#[cfg(not(boringssl))] +fn clear_ctx_options() { + let mut ctx = SslContext::builder(SslMethod::tls()).unwrap(); + ctx.set_options(SslOptions::ALL); + let opts = ctx.clear_options(SslOptions::ALL); + assert!(!opts.contains(SslOptions::ALL)); +} + +#[test] +fn zero_length_buffers() { + let server = Server::builder().build(); + + let mut s = server.client().connect(); + assert_eq!(s.write(&[]).unwrap(), 0); + assert_eq!(s.read(&mut []).unwrap(), 0); +} + +#[test] +fn peer_certificate() { + let server = Server::builder().build(); + + let s = server.client().connect(); + let cert = s.ssl().peer_certificate().unwrap(); + let fingerprint = cert.digest(MessageDigest::sha1()).unwrap(); + assert_eq!( + hex::encode(fingerprint), + "59172d9313e84459bcff27f967e79e6e9217e584" + ); +} + +#[test] +fn pending() { + let mut server = Server::builder(); + server.io_cb(|mut s| s.write_all(&[0; 10]).unwrap()); + let server = server.build(); + + let mut s = server.client().connect(); + s.read_exact(&mut [0]).unwrap(); + + assert_eq!(s.ssl().pending(), 9); + assert_eq!(s.read(&mut [0; 10]).unwrap(), 9); +} + +#[test] +fn state() { + let server = Server::builder().build(); + + let s = server.client().connect(); + #[cfg(not(boringssl))] + assert_eq!(s.ssl().state_string().trim(), "SSLOK"); + #[cfg(boringssl)] + assert_eq!(s.ssl().state_string(), "!!!!!!"); + assert_eq!( + s.ssl().state_string_long(), + "SSL negotiation finished successfully" + ); +} + +// when a connection uses ECDHE P-384 key exchange, then the temp key APIs +// return P-384 keys, and the peer and local keys are different. +#[test] +#[cfg(ossl300)] +fn peer_tmp_key_p384() { + let mut server = Server::builder(); + server.ctx().set_groups_list("P-384").unwrap(); + let server = server.build(); + let s = server.client().connect(); + let peer_temp = s.ssl().peer_tmp_key().unwrap(); + assert_eq!(peer_temp.id(), Id::EC); + assert_eq!(peer_temp.bits(), 384); + + let local_temp = s.ssl().tmp_key().unwrap(); + assert_eq!(local_temp.id(), Id::EC); + assert_eq!(local_temp.bits(), 384); + + assert_ne!( + peer_temp.ec_key().unwrap().public_key_to_der().unwrap(), + local_temp.ec_key().unwrap().public_key_to_der().unwrap(), + ); +} + +// when a connection uses RSA key exchange, then the peer (server) temp key is +// an Error because there is no temp key, and the local (client) temp key is the +// temp key sent in the initial key share. +#[test] +#[cfg(ossl300)] +fn peer_tmp_key_rsa() { + let mut server = Server::builder(); + server.ctx().set_cipher_list("RSA").unwrap(); + // RSA key exchange is not allowed in TLS 1.3, so force the connection + // to negotiate TLS 1.2 + server + .ctx() + .set_max_proto_version(Some(SslVersion::TLS1_2)) + .unwrap(); + let server = server.build(); + let mut client = server.client(); + client.ctx().set_groups_list("P-521").unwrap(); + let s = client.connect(); + let peer_temp = s.ssl().peer_tmp_key(); + assert!(peer_temp.is_err()); + + // this is the temp key that the client sent in the initial key share + let local_temp = s.ssl().tmp_key().unwrap(); + assert_eq!(local_temp.id(), Id::EC); + assert_eq!(local_temp.bits(), 521); +} + +/// Tests that when both the client as well as the server use SRTP and their +/// lists of supported protocols have an overlap -- with only ONE protocol +/// being valid for both. +#[test] +fn test_connect_with_srtp_ctx() { + let listener = TcpListener::bind("127.0.0.1:0").unwrap(); + let addr = listener.local_addr().unwrap(); + + let guard = thread::spawn(move || { + let stream = listener.accept().unwrap().0; + let mut ctx = SslContext::builder(SslMethod::dtls()).unwrap(); + ctx.set_tlsext_use_srtp("SRTP_AES128_CM_SHA1_80:SRTP_AES128_CM_SHA1_32") + .unwrap(); + ctx.set_certificate_file(Path::new("test/cert.pem"), SslFiletype::PEM) + .unwrap(); + ctx.set_private_key_file(Path::new("test/key.pem"), SslFiletype::PEM) + .unwrap(); + let mut ssl = Ssl::new(&ctx.build()).unwrap(); + ssl.set_mtu(1500).unwrap(); + let mut stream = ssl.accept(stream).unwrap(); + + let mut buf = [0; 60]; + stream + .ssl() + .export_keying_material(&mut buf, "EXTRACTOR-dtls_srtp", None) + .unwrap(); + + stream.write_all(&[0]).unwrap(); + + buf + }); + + let stream = TcpStream::connect(addr).unwrap(); + let mut ctx = SslContext::builder(SslMethod::dtls()).unwrap(); + ctx.set_tlsext_use_srtp("SRTP_AES128_CM_SHA1_80:SRTP_AES128_CM_SHA1_32") + .unwrap(); + let mut ssl = Ssl::new(&ctx.build()).unwrap(); + ssl.set_mtu(1500).unwrap(); + let mut stream = ssl.connect(stream).unwrap(); + + let mut buf = [1; 60]; + { + let srtp_profile = stream.ssl().selected_srtp_profile().unwrap(); + assert_eq!("SRTP_AES128_CM_SHA1_80", srtp_profile.name()); + assert_eq!(SrtpProfileId::SRTP_AES128_CM_SHA1_80, srtp_profile.id()); + } + stream + .ssl() + .export_keying_material(&mut buf, "EXTRACTOR-dtls_srtp", None) + .expect("extract"); + + stream.read_exact(&mut [0]).unwrap(); + + let buf2 = guard.join().unwrap(); + + assert_eq!(buf[..], buf2[..]); +} + +/// Tests that when both the client as well as the server use SRTP and their +/// lists of supported protocols have an overlap -- with only ONE protocol +/// being valid for both. +#[test] +fn test_connect_with_srtp_ssl() { + let listener = TcpListener::bind("127.0.0.1:0").unwrap(); + let addr = listener.local_addr().unwrap(); + + let guard = thread::spawn(move || { + let stream = listener.accept().unwrap().0; + let mut ctx = SslContext::builder(SslMethod::dtls()).unwrap(); + ctx.set_certificate_file(Path::new("test/cert.pem"), SslFiletype::PEM) + .unwrap(); + ctx.set_private_key_file(Path::new("test/key.pem"), SslFiletype::PEM) + .unwrap(); + let mut ssl = Ssl::new(&ctx.build()).unwrap(); + ssl.set_tlsext_use_srtp("SRTP_AES128_CM_SHA1_80:SRTP_AES128_CM_SHA1_32") + .unwrap(); + let mut profilenames = String::new(); + for profile in ssl.srtp_profiles().unwrap() { + if !profilenames.is_empty() { + profilenames.push(':'); + } + profilenames += profile.name(); + } + assert_eq!( + "SRTP_AES128_CM_SHA1_80:SRTP_AES128_CM_SHA1_32", + profilenames + ); + ssl.set_mtu(1500).unwrap(); + let mut stream = ssl.accept(stream).unwrap(); + + let mut buf = [0; 60]; + stream + .ssl() + .export_keying_material(&mut buf, "EXTRACTOR-dtls_srtp", None) + .unwrap(); + + stream.write_all(&[0]).unwrap(); + + buf + }); + + let stream = TcpStream::connect(addr).unwrap(); + let ctx = SslContext::builder(SslMethod::dtls()).unwrap(); + let mut ssl = Ssl::new(&ctx.build()).unwrap(); + ssl.set_tlsext_use_srtp("SRTP_AES128_CM_SHA1_80:SRTP_AES128_CM_SHA1_32") + .unwrap(); + ssl.set_mtu(1500).unwrap(); + let mut stream = ssl.connect(stream).unwrap(); + + let mut buf = [1; 60]; + { + let srtp_profile = stream.ssl().selected_srtp_profile().unwrap(); + assert_eq!("SRTP_AES128_CM_SHA1_80", srtp_profile.name()); + assert_eq!(SrtpProfileId::SRTP_AES128_CM_SHA1_80, srtp_profile.id()); + } + stream + .ssl() + .export_keying_material(&mut buf, "EXTRACTOR-dtls_srtp", None) + .expect("extract"); + + stream.read_exact(&mut [0]).unwrap(); + + let buf2 = guard.join().unwrap(); + + assert_eq!(buf[..], buf2[..]); +} + +/// Tests that when the `SslStream` is created as a server stream, the protocols +/// are correctly advertised to the client. +#[test] +#[cfg(any(ossl102, libressl261))] +fn test_alpn_server_advertise_multiple() { + let mut server = Server::builder(); + server.ctx().set_alpn_select_callback(|_, client| { + ssl::select_next_proto(b"\x08http/1.1\x08spdy/3.1", client).ok_or(ssl::AlpnError::NOACK) + }); + let server = server.build(); + + let mut client = server.client(); + client.ctx().set_alpn_protos(b"\x08spdy/3.1").unwrap(); + let s = client.connect(); + assert_eq!(s.ssl().selected_alpn_protocol(), Some(&b"spdy/3.1"[..])); +} + +#[test] +#[cfg(ossl110)] +fn test_alpn_server_select_none_fatal() { + let mut server = Server::builder(); + server.ctx().set_alpn_select_callback(|_, client| { + ssl::select_next_proto(b"\x08http/1.1\x08spdy/3.1", client) + .ok_or(ssl::AlpnError::ALERT_FATAL) + }); + server.should_error(); + let server = server.build(); + + let mut client = server.client(); + client.ctx().set_alpn_protos(b"\x06http/2").unwrap(); + client.connect_err(); +} + +#[test] +#[cfg(any(ossl102, libressl261))] +fn test_alpn_server_select_none() { + static CALLED_BACK: AtomicBool = AtomicBool::new(false); + + let mut server = Server::builder(); + server.ctx().set_alpn_select_callback(|_, client| { + CALLED_BACK.store(true, Ordering::SeqCst); + ssl::select_next_proto(b"\x08http/1.1\x08spdy/3.1", client).ok_or(ssl::AlpnError::NOACK) + }); + let server = server.build(); + + let mut client = server.client(); + client.ctx().set_alpn_protos(b"\x06http/2").unwrap(); + let s = client.connect(); + assert_eq!(None, s.ssl().selected_alpn_protocol()); + assert!(CALLED_BACK.load(Ordering::SeqCst)); +} + +#[test] +#[cfg(any(boringssl, ossl102, libressl261))] +fn test_alpn_server_unilateral() { + let server = Server::builder().build(); + + let mut client = server.client(); + client.ctx().set_alpn_protos(b"\x06http/2").unwrap(); + let s = client.connect(); + assert_eq!(None, s.ssl().selected_alpn_protocol()); +} + +#[test] +#[should_panic(expected = "blammo")] +fn write_panic() { + struct ExplodingStream(TcpStream); + + impl Read for ExplodingStream { + fn read(&mut self, buf: &mut [u8]) -> io::Result { + self.0.read(buf) + } + } + + impl Write for ExplodingStream { + fn write(&mut self, _: &[u8]) -> io::Result { + panic!("blammo"); + } + + fn flush(&mut self) -> io::Result<()> { + self.0.flush() + } + } + + let mut server = Server::builder(); + server.should_error(); + let server = server.build(); + + let stream = ExplodingStream(server.connect_tcp()); + + let ctx = SslContext::builder(SslMethod::tls()).unwrap(); + let _ = Ssl::new(&ctx.build()).unwrap().connect(stream); +} + +#[test] +#[should_panic(expected = "blammo")] +fn read_panic() { + struct ExplodingStream(TcpStream); + + impl Read for ExplodingStream { + fn read(&mut self, _: &mut [u8]) -> io::Result { + panic!("blammo"); + } + } + + impl Write for ExplodingStream { + fn write(&mut self, buf: &[u8]) -> io::Result { + self.0.write(buf) + } + + fn flush(&mut self) -> io::Result<()> { + self.0.flush() + } + } + + let mut server = Server::builder(); + server.should_error(); + let server = server.build(); + + let stream = ExplodingStream(server.connect_tcp()); + + let ctx = SslContext::builder(SslMethod::tls()).unwrap(); + let _ = Ssl::new(&ctx.build()).unwrap().connect(stream); +} + +#[test] +#[cfg_attr(all(libressl321, not(libressl340)), ignore)] +#[should_panic(expected = "blammo")] +fn flush_panic() { + struct ExplodingStream(TcpStream); + + impl Read for ExplodingStream { + fn read(&mut self, buf: &mut [u8]) -> io::Result { + self.0.read(buf) + } + } + + impl Write for ExplodingStream { + fn write(&mut self, buf: &[u8]) -> io::Result { + self.0.write(buf) + } + + fn flush(&mut self) -> io::Result<()> { + panic!("blammo"); + } + } + + let mut server = Server::builder(); + server.should_error(); + let server = server.build(); + + let stream = ExplodingStream(server.connect_tcp()); + + let ctx = SslContext::builder(SslMethod::tls()).unwrap(); + let _ = Ssl::new(&ctx.build()).unwrap().connect(stream); +} + +#[test] +fn refcount_ssl_context() { + let mut ssl = { + let ctx = SslContext::builder(SslMethod::tls()).unwrap(); + ssl::Ssl::new(&ctx.build()).unwrap() + }; + + { + let new_ctx_a = SslContext::builder(SslMethod::tls()).unwrap().build(); + ssl.set_ssl_context(&new_ctx_a).unwrap(); + } +} + +#[test] +#[cfg_attr(libressl250, ignore)] +#[cfg_attr(target_os = "windows", ignore)] +#[cfg_attr(all(target_os = "macos", feature = "vendored"), ignore)] +fn default_verify_paths() { + let mut ctx = SslContext::builder(SslMethod::tls()).unwrap(); + ctx.set_default_verify_paths().unwrap(); + ctx.set_verify(SslVerifyMode::PEER); + let ctx = ctx.build(); + let s = match TcpStream::connect("google.com:443") { + Ok(s) => s, + Err(_) => return, + }; + let mut ssl = Ssl::new(&ctx).unwrap(); + ssl.set_hostname("google.com").unwrap(); + let mut socket = ssl.connect(s).unwrap(); + + socket.write_all(b"GET / HTTP/1.0\r\n\r\n").unwrap(); + let mut result = vec![]; + socket.read_to_end(&mut result).unwrap(); + + println!("{}", String::from_utf8_lossy(&result)); + assert!(result.starts_with(b"HTTP/1.0")); + assert!(result.ends_with(b"\r\n") || result.ends_with(b"")); +} + +#[test] +fn add_extra_chain_cert() { + let cert = X509::from_pem(CERT).unwrap(); + let mut ctx = SslContext::builder(SslMethod::tls()).unwrap(); + ctx.add_extra_chain_cert(cert).unwrap(); +} + +#[test] +#[cfg(ossl102)] +fn verify_valid_hostname() { + let server = Server::builder().build(); + + let mut client = server.client(); + client.ctx().set_ca_file("test/root-ca.pem").unwrap(); + client.ctx().set_verify(SslVerifyMode::PEER); + + let mut client = client.build().builder(); + client + .ssl() + .param_mut() + .set_hostflags(X509CheckFlags::NO_PARTIAL_WILDCARDS); + client.ssl().param_mut().set_host("foobar.com").unwrap(); + client.connect(); +} + +#[test] +#[cfg(ossl102)] +fn verify_invalid_hostname() { + let mut server = Server::builder(); + server.should_error(); + let server = server.build(); + + let mut client = server.client(); + client.ctx().set_ca_file("test/root-ca.pem").unwrap(); + client.ctx().set_verify(SslVerifyMode::PEER); + + let mut client = client.build().builder(); + client + .ssl() + .param_mut() + .set_hostflags(X509CheckFlags::NO_PARTIAL_WILDCARDS); + client.ssl().param_mut().set_host("bogus.com").unwrap(); + client.connect_err(); +} + +#[test] +fn connector_valid_hostname() { + let server = Server::builder().build(); + + let mut connector = SslConnector::builder(SslMethod::tls()).unwrap(); + connector.set_ca_file("test/root-ca.pem").unwrap(); + + let s = server.connect_tcp(); + let mut s = connector.build().connect("foobar.com", s).unwrap(); + s.read_exact(&mut [0]).unwrap(); +} + +#[test] +fn connector_invalid_hostname() { + let mut server = Server::builder(); + server.should_error(); + let server = server.build(); + + let mut connector = SslConnector::builder(SslMethod::tls()).unwrap(); + connector.set_ca_file("test/root-ca.pem").unwrap(); + + let s = server.connect_tcp(); + connector.build().connect("bogus.com", s).unwrap_err(); +} + +#[test] +fn connector_invalid_no_hostname_verification() { + let server = Server::builder().build(); + + let mut connector = SslConnector::builder(SslMethod::tls()).unwrap(); + connector.set_ca_file("test/root-ca.pem").unwrap(); + + let s = server.connect_tcp(); + let mut s = connector + .build() + .configure() + .unwrap() + .verify_hostname(false) + .connect("bogus.com", s) + .unwrap(); + s.read_exact(&mut [0]).unwrap(); +} + +#[test] +fn connector_no_hostname_still_verifies() { + let mut server = Server::builder(); + server.should_error(); + let server = server.build(); + + let connector = SslConnector::builder(SslMethod::tls()).unwrap().build(); + + let s = server.connect_tcp(); + assert!(connector + .configure() + .unwrap() + .verify_hostname(false) + .connect("fizzbuzz.com", s) + .is_err()); +} + +#[test] +fn connector_can_disable_verify() { + let server = Server::builder().build(); + + let mut connector = SslConnector::builder(SslMethod::tls()).unwrap(); + connector.set_verify(SslVerifyMode::NONE); + let connector = connector.build(); + + let s = server.connect_tcp(); + let mut s = connector + .configure() + .unwrap() + .connect("fizzbuzz.com", s) + .unwrap(); + s.read_exact(&mut [0]).unwrap(); +} + +#[test] +fn connector_does_use_sni_with_dnsnames() { + static CALLED_BACK: AtomicBool = AtomicBool::new(false); + + let mut builder = Server::builder(); + builder.ctx().set_servername_callback(|ssl, _| { + assert_eq!(ssl.servername(NameType::HOST_NAME), Some("foobar.com")); + CALLED_BACK.store(true, Ordering::SeqCst); + Ok(()) + }); + let server = builder.build(); + + let mut connector = SslConnector::builder(SslMethod::tls()).unwrap(); + connector.set_ca_file("test/root-ca.pem").unwrap(); + + let s = server.connect_tcp(); + let mut s = connector + .build() + .configure() + .unwrap() + .connect("foobar.com", s) + .unwrap(); + s.read_exact(&mut [0]).unwrap(); + + assert!(CALLED_BACK.load(Ordering::SeqCst)); +} + +#[test] +fn connector_doesnt_use_sni_with_ips() { + static CALLED_BACK: AtomicBool = AtomicBool::new(false); + + let mut builder = Server::builder(); + builder.ctx().set_servername_callback(|ssl, _| { + assert_eq!(ssl.servername(NameType::HOST_NAME), None); + CALLED_BACK.store(true, Ordering::SeqCst); + Ok(()) + }); + let server = builder.build(); + + let mut connector = SslConnector::builder(SslMethod::tls()).unwrap(); + // The server's cert isn't issued for 127.0.0.1 but we don't care for this test. + connector.set_verify(SslVerifyMode::NONE); + + let s = server.connect_tcp(); + let mut s = connector + .build() + .configure() + .unwrap() + .connect("127.0.0.1", s) + .unwrap(); + s.read_exact(&mut [0]).unwrap(); + + assert!(CALLED_BACK.load(Ordering::SeqCst)); +} + +fn test_mozilla_server(new: fn(SslMethod) -> Result) { + let listener = TcpListener::bind("127.0.0.1:0").unwrap(); + let port = listener.local_addr().unwrap().port(); + + let t = thread::spawn(move || { + let key = PKey::private_key_from_pem(KEY).unwrap(); + let cert = X509::from_pem(CERT).unwrap(); + let mut acceptor = new(SslMethod::tls()).unwrap(); + acceptor.set_private_key(&key).unwrap(); + acceptor.set_certificate(&cert).unwrap(); + let acceptor = acceptor.build(); + let stream = listener.accept().unwrap().0; + let mut stream = acceptor.accept(stream).unwrap(); + + stream.write_all(b"hello").unwrap(); + }); + + let mut connector = SslConnector::builder(SslMethod::tls()).unwrap(); + connector.set_ca_file("test/root-ca.pem").unwrap(); + let connector = connector.build(); + + let stream = TcpStream::connect(("127.0.0.1", port)).unwrap(); + let mut stream = connector.connect("foobar.com", stream).unwrap(); + + let mut buf = [0; 5]; + stream.read_exact(&mut buf).unwrap(); + assert_eq!(b"hello", &buf); + + t.join().unwrap(); +} + +#[test] +fn connector_client_server_mozilla_intermediate() { + test_mozilla_server(SslAcceptor::mozilla_intermediate); +} + +#[test] +fn connector_client_server_mozilla_modern() { + test_mozilla_server(SslAcceptor::mozilla_modern); +} + +#[test] +fn connector_client_server_mozilla_intermediate_v5() { + test_mozilla_server(SslAcceptor::mozilla_intermediate_v5); +} + +#[test] +#[cfg(any(ossl111, libressl340))] +fn connector_client_server_mozilla_modern_v5() { + test_mozilla_server(SslAcceptor::mozilla_modern_v5); +} + +#[test] +fn shutdown() { + let mut server = Server::builder(); + server.io_cb(|mut s| { + assert_eq!(s.read(&mut [0]).unwrap(), 0); + assert_eq!(s.shutdown().unwrap(), ShutdownResult::Received); + }); + let server = server.build(); + + let mut s = server.client().connect(); + + assert_eq!(s.get_shutdown(), ShutdownState::empty()); + assert_eq!(s.shutdown().unwrap(), ShutdownResult::Sent); + assert_eq!(s.get_shutdown(), ShutdownState::SENT); + assert_eq!(s.shutdown().unwrap(), ShutdownResult::Received); + assert_eq!( + s.get_shutdown(), + ShutdownState::SENT | ShutdownState::RECEIVED + ); +} + +#[test] +fn client_ca_list() { + let names = X509Name::load_client_ca_file("test/root-ca.pem").unwrap(); + assert_eq!(names.len(), 1); + + let mut ctx = SslContext::builder(SslMethod::tls()).unwrap(); + ctx.set_client_ca_list(names); +} + +#[test] +fn cert_store() { + let server = Server::builder().build(); + + let mut client = server.client(); + let cert = X509::from_pem(ROOT_CERT).unwrap(); + client.ctx().cert_store_mut().add_cert(cert).unwrap(); + client.ctx().set_verify(SslVerifyMode::PEER); + + client.connect(); +} + +#[test] +#[cfg_attr(any(all(libressl321, not(libressl340)), boringssl), ignore)] +fn tmp_dh_callback() { + static CALLED_BACK: AtomicBool = AtomicBool::new(false); + + let mut server = Server::builder(); + server.ctx().set_tmp_dh_callback(|_, _, _| { + CALLED_BACK.store(true, Ordering::SeqCst); + let dh = include_bytes!("../../../test/dhparams.pem"); + Dh::params_from_pem(dh) + }); + + let server = server.build(); + + let mut client = server.client(); + // TLS 1.3 has no DH suites, so make sure we don't pick that version + #[cfg(any(ossl111, libressl340))] + client.ctx().set_options(super::SslOptions::NO_TLSV1_3); + client.ctx().set_cipher_list("EDH").unwrap(); + client.connect(); + + assert!(CALLED_BACK.load(Ordering::SeqCst)); +} + +#[test] +#[cfg(all(ossl101, not(ossl110)))] +#[allow(deprecated)] +fn tmp_ecdh_callback() { + use crate::ec::EcKey; + use crate::nid::Nid; + + static CALLED_BACK: AtomicBool = AtomicBool::new(false); + + let mut server = Server::builder(); + server.ctx().set_tmp_ecdh_callback(|_, _, _| { + CALLED_BACK.store(true, Ordering::SeqCst); + EcKey::from_curve_name(Nid::X9_62_PRIME256V1) + }); + + let server = server.build(); + + let mut client = server.client(); + client.ctx().set_cipher_list("ECDH").unwrap(); + client.connect(); + + assert!(CALLED_BACK.load(Ordering::SeqCst)); +} + +#[test] +#[cfg_attr(any(all(libressl321, not(libressl340)), boringssl), ignore)] +fn tmp_dh_callback_ssl() { + static CALLED_BACK: AtomicBool = AtomicBool::new(false); + + let mut server = Server::builder(); + server.ssl_cb(|ssl| { + ssl.set_tmp_dh_callback(|_, _, _| { + CALLED_BACK.store(true, Ordering::SeqCst); + let dh = include_bytes!("../../../test/dhparams.pem"); + Dh::params_from_pem(dh) + }); + }); + + let server = server.build(); + + let mut client = server.client(); + // TLS 1.3 has no DH suites, so make sure we don't pick that version + #[cfg(any(ossl111, libressl340))] + client.ctx().set_options(super::SslOptions::NO_TLSV1_3); + client.ctx().set_cipher_list("EDH").unwrap(); + client.connect(); + + assert!(CALLED_BACK.load(Ordering::SeqCst)); +} + +#[test] +#[cfg(all(ossl101, not(ossl110)))] +#[allow(deprecated)] +fn tmp_ecdh_callback_ssl() { + use crate::ec::EcKey; + use crate::nid::Nid; + + static CALLED_BACK: AtomicBool = AtomicBool::new(false); + + let mut server = Server::builder(); + server.ssl_cb(|ssl| { + ssl.set_tmp_ecdh_callback(|_, _, _| { + CALLED_BACK.store(true, Ordering::SeqCst); + EcKey::from_curve_name(Nid::X9_62_PRIME256V1) + }); + }); + + let server = server.build(); + + let mut client = server.client(); + client.ctx().set_cipher_list("ECDH").unwrap(); + client.connect(); + + assert!(CALLED_BACK.load(Ordering::SeqCst)); +} + +#[test] +fn idle_session() { + let ctx = SslContext::builder(SslMethod::tls()).unwrap().build(); + let ssl = Ssl::new(&ctx).unwrap(); + assert!(ssl.session().is_none()); +} + +/// LibreSSL 3.2.1 enabled TLSv1.3 by default for clients and sessions do +/// not work due to lack of PSK support. The test passes with NO_TLSV1_3, +/// but let's ignore it until LibreSSL supports it out of the box. +#[test] +#[cfg_attr(libressl321, ignore)] +fn active_session() { + let server = Server::builder().build(); + + let s = server.client().connect(); + + let session = s.ssl().session().unwrap(); + let len = session.master_key_len(); + let mut buf = vec![0; len - 1]; + let copied = session.master_key(&mut buf); + assert_eq!(copied, buf.len()); + let mut buf = vec![0; len + 1]; + let copied = session.master_key(&mut buf); + assert_eq!(copied, len); +} + +#[test] +#[cfg(not(boringssl))] +fn status_callbacks() { + static CALLED_BACK_SERVER: AtomicBool = AtomicBool::new(false); + static CALLED_BACK_CLIENT: AtomicBool = AtomicBool::new(false); + + let mut server = Server::builder(); + server + .ctx() + .set_status_callback(|ssl| { + CALLED_BACK_SERVER.store(true, Ordering::SeqCst); + let response = OcspResponse::create(OcspResponseStatus::UNAUTHORIZED, None).unwrap(); + let response = response.to_der().unwrap(); + ssl.set_ocsp_status(&response).unwrap(); + Ok(true) + }) + .unwrap(); + + let server = server.build(); + + let mut client = server.client(); + client + .ctx() + .set_status_callback(|ssl| { + CALLED_BACK_CLIENT.store(true, Ordering::SeqCst); + let response = OcspResponse::from_der(ssl.ocsp_status().unwrap()).unwrap(); + assert_eq!(response.status(), OcspResponseStatus::UNAUTHORIZED); + Ok(true) + }) + .unwrap(); + + let mut client = client.build().builder(); + client.ssl().set_status_type(StatusType::OCSP).unwrap(); + + client.connect(); + + assert!(CALLED_BACK_SERVER.load(Ordering::SeqCst)); + assert!(CALLED_BACK_CLIENT.load(Ordering::SeqCst)); +} + +/// LibreSSL 3.2.1 enabled TLSv1.3 by default for clients and sessions do +/// not work due to lack of PSK support. The test passes with NO_TLSV1_3, +/// but let's ignore it until LibreSSL supports it out of the box. +#[test] +#[cfg_attr(libressl321, ignore)] +fn new_session_callback() { + static CALLED_BACK: AtomicBool = AtomicBool::new(false); + + let mut server = Server::builder(); + server.ctx().set_session_id_context(b"foo").unwrap(); + + let server = server.build(); + + let mut client = server.client(); + + client + .ctx() + .set_session_cache_mode(SslSessionCacheMode::CLIENT | SslSessionCacheMode::NO_INTERNAL); + client + .ctx() + .set_new_session_callback(|_, _| CALLED_BACK.store(true, Ordering::SeqCst)); + + client.connect(); + + assert!(CALLED_BACK.load(Ordering::SeqCst)); +} + +/// LibreSSL 3.2.1 enabled TLSv1.3 by default for clients and sessions do +/// not work due to lack of PSK support. The test passes with NO_TLSV1_3, +/// but let's ignore it until LibreSSL supports it out of the box. +#[test] +#[cfg_attr(libressl321, ignore)] +fn new_session_callback_swapped_ctx() { + static CALLED_BACK: AtomicBool = AtomicBool::new(false); + + let mut server = Server::builder(); + server.ctx().set_session_id_context(b"foo").unwrap(); + + let server = server.build(); + + let mut client = server.client(); + + client + .ctx() + .set_session_cache_mode(SslSessionCacheMode::CLIENT | SslSessionCacheMode::NO_INTERNAL); + client + .ctx() + .set_new_session_callback(|_, _| CALLED_BACK.store(true, Ordering::SeqCst)); + + let mut client = client.build().builder(); + + let ctx = SslContextBuilder::new(SslMethod::tls()).unwrap().build(); + client.ssl().set_ssl_context(&ctx).unwrap(); + + client.connect(); + + assert!(CALLED_BACK.load(Ordering::SeqCst)); +} + +#[test] +fn keying_export() { + let listener = TcpListener::bind("127.0.0.1:0").unwrap(); + let addr = listener.local_addr().unwrap(); + + let label = "EXPERIMENTAL test"; + let context = b"my context"; + + let guard = thread::spawn(move || { + let stream = listener.accept().unwrap().0; + let mut ctx = SslContext::builder(SslMethod::tls()).unwrap(); + ctx.set_certificate_file(Path::new("test/cert.pem"), SslFiletype::PEM) + .unwrap(); + ctx.set_private_key_file(Path::new("test/key.pem"), SslFiletype::PEM) + .unwrap(); + let ssl = Ssl::new(&ctx.build()).unwrap(); + let mut stream = ssl.accept(stream).unwrap(); + + let mut buf = [0; 32]; + stream + .ssl() + .export_keying_material(&mut buf, label, Some(context)) + .unwrap(); + + stream.write_all(&[0]).unwrap(); + + buf + }); + + let stream = TcpStream::connect(addr).unwrap(); + let ctx = SslContext::builder(SslMethod::tls()).unwrap(); + let ssl = Ssl::new(&ctx.build()).unwrap(); + let mut stream = ssl.connect(stream).unwrap(); + + let mut buf = [1; 32]; + stream + .ssl() + .export_keying_material(&mut buf, label, Some(context)) + .unwrap(); + + stream.read_exact(&mut [0]).unwrap(); + + let buf2 = guard.join().unwrap(); + + assert_eq!(buf, buf2); +} + +#[test] +#[cfg(any(ossl110, libressl261))] +fn no_version_overlap() { + let mut server = Server::builder(); + server.ctx().set_min_proto_version(None).unwrap(); + server + .ctx() + .set_max_proto_version(Some(SslVersion::TLS1_1)) + .unwrap(); + #[cfg(any(ossl110g, libressl270))] + assert_eq!(server.ctx().max_proto_version(), Some(SslVersion::TLS1_1)); + server.should_error(); + let server = server.build(); + + let mut client = server.client(); + client + .ctx() + .set_min_proto_version(Some(SslVersion::TLS1_2)) + .unwrap(); + #[cfg(ossl110g)] + assert_eq!(client.ctx().min_proto_version(), Some(SslVersion::TLS1_2)); + client.ctx().set_max_proto_version(None).unwrap(); + + client.connect_err(); +} + +#[test] +#[cfg(ossl111)] +fn custom_extensions() { + static FOUND_EXTENSION: AtomicBool = AtomicBool::new(false); + + let mut server = Server::builder(); + server + .ctx() + .add_custom_ext( + 12345, + ExtensionContext::CLIENT_HELLO, + |_, _, _| -> Result, _> { unreachable!() }, + |_, _, data, _| { + FOUND_EXTENSION.store(data == b"hello", Ordering::SeqCst); + Ok(()) + }, + ) + .unwrap(); + + let server = server.build(); + + let mut client = server.client(); + client + .ctx() + .add_custom_ext( + 12345, + ssl::ExtensionContext::CLIENT_HELLO, + |_, _, _| Ok(Some(b"hello")), + |_, _, _, _| unreachable!(), + ) + .unwrap(); + + client.connect(); + + assert!(FOUND_EXTENSION.load(Ordering::SeqCst)); +} + +fn _check_kinds() { + fn is_send() {} + fn is_sync() {} + + is_send::>(); + is_sync::>(); +} + +#[test] +#[cfg(ossl111)] +fn stateless() { + use super::SslOptions; + + #[derive(Debug)] + struct MemoryStream { + incoming: io::Cursor>, + outgoing: Vec, + } + + impl MemoryStream { + pub fn new() -> Self { + Self { + incoming: io::Cursor::new(Vec::new()), + outgoing: Vec::new(), + } + } + + pub fn extend_incoming(&mut self, data: &[u8]) { + self.incoming.get_mut().extend_from_slice(data); + } + + pub fn take_outgoing(&mut self) -> Outgoing<'_> { + Outgoing(&mut self.outgoing) + } + } + + impl Read for MemoryStream { + fn read(&mut self, buf: &mut [u8]) -> io::Result { + let n = self.incoming.read(buf)?; + if self.incoming.position() == self.incoming.get_ref().len() as u64 { + self.incoming.set_position(0); + self.incoming.get_mut().clear(); + } + if n == 0 { + return Err(io::Error::new( + io::ErrorKind::WouldBlock, + "no data available", + )); + } + Ok(n) + } + } + + impl Write for MemoryStream { + fn write(&mut self, buf: &[u8]) -> io::Result { + self.outgoing.write(buf) + } + + fn flush(&mut self) -> io::Result<()> { + Ok(()) + } + } + + pub struct Outgoing<'a>(&'a mut Vec); + + impl Drop for Outgoing<'_> { + fn drop(&mut self) { + self.0.clear(); + } + } + + impl ::std::ops::Deref for Outgoing<'_> { + type Target = [u8]; + fn deref(&self) -> &[u8] { + self.0 + } + } + + impl AsRef<[u8]> for Outgoing<'_> { + fn as_ref(&self) -> &[u8] { + self.0 + } + } + + fn send(from: &mut MemoryStream, to: &mut MemoryStream) { + to.extend_incoming(&from.take_outgoing()); + } + + // + // Setup + // + + let mut client_ctx = SslContext::builder(SslMethod::tls()).unwrap(); + client_ctx.clear_options(SslOptions::ENABLE_MIDDLEBOX_COMPAT); + let mut client_stream = + SslStream::new(Ssl::new(&client_ctx.build()).unwrap(), MemoryStream::new()).unwrap(); + + let mut server_ctx = SslContext::builder(SslMethod::tls()).unwrap(); + server_ctx + .set_certificate_file(Path::new("test/cert.pem"), SslFiletype::PEM) + .unwrap(); + server_ctx + .set_private_key_file(Path::new("test/key.pem"), SslFiletype::PEM) + .unwrap(); + const COOKIE: &[u8] = b"chocolate chip"; + server_ctx.set_stateless_cookie_generate_cb(|_tls, buf| { + buf[0..COOKIE.len()].copy_from_slice(COOKIE); + Ok(COOKIE.len()) + }); + server_ctx.set_stateless_cookie_verify_cb(|_tls, buf| buf == COOKIE); + let mut server_stream = + SslStream::new(Ssl::new(&server_ctx.build()).unwrap(), MemoryStream::new()).unwrap(); + + // + // Handshake + // + + // Initial ClientHello + client_stream.connect().unwrap_err(); + send(client_stream.get_mut(), server_stream.get_mut()); + // HelloRetryRequest + assert!(!server_stream.stateless().unwrap()); + send(server_stream.get_mut(), client_stream.get_mut()); + // Second ClientHello + client_stream.do_handshake().unwrap_err(); + send(client_stream.get_mut(), server_stream.get_mut()); + // OldServerHello + assert!(server_stream.stateless().unwrap()); + server_stream.accept().unwrap_err(); + send(server_stream.get_mut(), client_stream.get_mut()); + // Finished + client_stream.do_handshake().unwrap(); + send(client_stream.get_mut(), server_stream.get_mut()); + server_stream.do_handshake().unwrap(); +} + +#[cfg(not(osslconf = "OPENSSL_NO_PSK"))] +#[test] +fn psk_ciphers() { + const CIPHER: &str = "PSK-AES256-CBC-SHA"; + const PSK: &[u8] = b"thisisaverysecurekey"; + const CLIENT_IDENT: &[u8] = b"thisisaclient"; + static CLIENT_CALLED: AtomicBool = AtomicBool::new(false); + static SERVER_CALLED: AtomicBool = AtomicBool::new(false); + + let mut server = Server::builder(); + server.ctx().set_cipher_list(CIPHER).unwrap(); + server.ctx().set_psk_server_callback(|_, identity, psk| { + assert!(identity.unwrap_or(&[]) == CLIENT_IDENT); + psk[..PSK.len()].copy_from_slice(PSK); + SERVER_CALLED.store(true, Ordering::SeqCst); + Ok(PSK.len()) + }); + + let server = server.build(); + + let mut client = server.client(); + // This test relies on TLS 1.2 suites + #[cfg(any(boringssl, ossl111))] + client.ctx().set_options(super::SslOptions::NO_TLSV1_3); + client.ctx().set_cipher_list(CIPHER).unwrap(); + client + .ctx() + .set_psk_client_callback(move |_, _, identity, psk| { + identity[..CLIENT_IDENT.len()].copy_from_slice(CLIENT_IDENT); + identity[CLIENT_IDENT.len()] = 0; + psk[..PSK.len()].copy_from_slice(PSK); + CLIENT_CALLED.store(true, Ordering::SeqCst); + Ok(PSK.len()) + }); + + client.connect(); + + assert!(SERVER_CALLED.load(Ordering::SeqCst)); + assert!(CLIENT_CALLED.load(Ordering::SeqCst)); +} + +#[test] +fn sni_callback_swapped_ctx() { + static CALLED_BACK: AtomicBool = AtomicBool::new(false); + + let mut server = Server::builder(); + + let mut ctx = SslContext::builder(SslMethod::tls()).unwrap(); + ctx.set_servername_callback(|_, _| { + CALLED_BACK.store(true, Ordering::SeqCst); + Ok(()) + }); + + let keyed_ctx = mem::replace(server.ctx(), ctx).build(); + server.ssl_cb(move |ssl| ssl.set_ssl_context(&keyed_ctx).unwrap()); + + let server = server.build(); + + server.client().connect(); + + assert!(CALLED_BACK.load(Ordering::SeqCst)); +} + +#[test] +#[cfg(ossl111)] +fn client_hello() { + static CALLED_BACK: AtomicBool = AtomicBool::new(false); + + let mut server = Server::builder(); + server.ctx().set_client_hello_callback(|ssl, _| { + assert!(!ssl.client_hello_isv2()); + assert_eq!(ssl.client_hello_legacy_version(), Some(SslVersion::TLS1_2)); + assert!(ssl.client_hello_random().is_some()); + assert!(ssl.client_hello_session_id().is_some()); + assert!(ssl.client_hello_ciphers().is_some()); + assert!(ssl.client_hello_compression_methods().is_some()); + assert!(ssl + .bytes_to_cipher_list(ssl.client_hello_ciphers().unwrap(), ssl.client_hello_isv2()) + .is_ok()); + + CALLED_BACK.store(true, Ordering::SeqCst); + Ok(ClientHelloResponse::SUCCESS) + }); + + let server = server.build(); + server.client().connect(); + + assert!(CALLED_BACK.load(Ordering::SeqCst)); +} + +#[test] +#[cfg(ossl111)] +fn openssl_cipher_name() { + assert_eq!( + super::cipher_name("TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384"), + "ECDHE-RSA-AES256-SHA384", + ); + + assert_eq!(super::cipher_name("asdf"), "(NONE)"); +} + +#[test] +fn session_cache_size() { + let mut ctx = SslContext::builder(SslMethod::tls()).unwrap(); + ctx.set_session_cache_size(1234); + let ctx = ctx.build(); + assert_eq!(ctx.session_cache_size(), 1234); +} + +#[test] +#[cfg(ossl102)] +fn add_chain_cert() { + let ctx = SslContext::builder(SslMethod::tls()).unwrap().build(); + let cert = X509::from_pem(CERT).unwrap(); + let mut ssl = Ssl::new(&ctx).unwrap(); + assert!(ssl.add_chain_cert(cert).is_ok()); +} +#[test] +#[cfg(ossl111)] +fn set_ssl_certificate_key_related_api() { + let cert_str: &str = include_str!("../../../test/cert.pem"); + let key_str: &str = include_str!("../../../test/key.pem"); + let ctx = SslContext::builder(SslMethod::tls()).unwrap().build(); + let cert_x509 = X509::from_pem(CERT).unwrap(); + let mut ssl = Ssl::new(&ctx).unwrap(); + assert!(ssl.set_method(SslMethod::tls()).is_ok()); + ssl.set_private_key_file("test/key.pem", SslFiletype::PEM) + .unwrap(); + { + let pkey = String::from_utf8( + ssl.private_key() + .unwrap() + .private_key_to_pem_pkcs8() + .unwrap(), + ) + .unwrap(); + assert!(pkey.lines().eq(key_str.lines())); + } + let pkey = PKey::private_key_from_pem(KEY).unwrap(); + ssl.set_private_key(pkey.as_ref()).unwrap(); + { + let pkey = String::from_utf8( + ssl.private_key() + .unwrap() + .private_key_to_pem_pkcs8() + .unwrap(), + ) + .unwrap(); + assert!(pkey.lines().eq(key_str.lines())); + } + ssl.set_certificate(cert_x509.as_ref()).unwrap(); + let cert = String::from_utf8(ssl.certificate().unwrap().to_pem().unwrap()).unwrap(); + assert!(cert.lines().eq(cert_str.lines())); + ssl.add_client_ca(cert_x509.as_ref()).unwrap(); + ssl.set_min_proto_version(Some(SslVersion::TLS1_2)).unwrap(); + ssl.set_max_proto_version(Some(SslVersion::TLS1_3)).unwrap(); + ssl.set_cipher_list("HIGH:!aNULL:!MD5").unwrap(); + ssl.set_ciphersuites("TLS_AES_128_GCM_SHA256").unwrap(); + let x509 = X509::from_pem(ROOT_CERT).unwrap(); + let mut builder = X509StoreBuilder::new().unwrap(); + builder.add_cert(x509).unwrap(); + let store = builder.build(); + ssl.set_verify_cert_store(store).unwrap(); +} + +#[test] +#[cfg(ossl110)] +fn test_ssl_set_cert_chain_file() { + let ctx = SslContext::builder(SslMethod::tls()).unwrap().build(); + let mut ssl = Ssl::new(&ctx).unwrap(); + ssl.set_certificate_chain_file("test/cert.pem").unwrap(); +} + +#[test] +#[cfg(ossl111)] +fn set_num_tickets() { + let mut ctx = SslContext::builder(SslMethod::tls_server()).unwrap(); + ctx.set_num_tickets(3).unwrap(); + let ctx = ctx.build(); + assert_eq!(3, ctx.num_tickets()); + + let mut ssl = Ssl::new(&ctx).unwrap(); + ssl.set_num_tickets(5).unwrap(); + let ssl = ssl; + assert_eq!(5, ssl.num_tickets()); +} + +#[test] +#[cfg(ossl110)] +fn set_security_level() { + let mut ctx = SslContext::builder(SslMethod::tls_server()).unwrap(); + ctx.set_security_level(3); + let ctx = ctx.build(); + assert_eq!(3, ctx.security_level()); + + let mut ssl = Ssl::new(&ctx).unwrap(); + ssl.set_security_level(4); + let ssl = ssl; + assert_eq!(4, ssl.security_level()); +} + +#[test] +fn ssl_ctx_ex_data_leak() { + static DROPS: AtomicUsize = AtomicUsize::new(0); + + struct DropTest; + + impl Drop for DropTest { + fn drop(&mut self) { + DROPS.fetch_add(1, Ordering::Relaxed); + } + } + + let idx = SslContext::new_ex_index().unwrap(); + + let mut ctx = SslContext::builder(SslMethod::tls()).unwrap(); + ctx.set_ex_data(idx, DropTest); + ctx.set_ex_data(idx, DropTest); + assert_eq!(DROPS.load(Ordering::Relaxed), 1); + + drop(ctx); + assert_eq!(DROPS.load(Ordering::Relaxed), 2); +} + +#[test] +fn ssl_ex_data_leak() { + static DROPS: AtomicUsize = AtomicUsize::new(0); + + struct DropTest; + + impl Drop for DropTest { + fn drop(&mut self) { + DROPS.fetch_add(1, Ordering::Relaxed); + } + } + + let idx = Ssl::new_ex_index().unwrap(); + + let ctx = SslContext::builder(SslMethod::tls()).unwrap().build(); + let mut ssl = Ssl::new(&ctx).unwrap(); + ssl.set_ex_data(idx, DropTest); + ssl.set_ex_data(idx, DropTest); + assert_eq!(DROPS.load(Ordering::Relaxed), 1); + + drop(ssl); + assert_eq!(DROPS.load(Ordering::Relaxed), 2); +} diff --git a/vendor/openssl/src/ssl/test/server.rs b/vendor/openssl/src/ssl/test/server.rs new file mode 100644 index 0000000..41677e5 --- /dev/null +++ b/vendor/openssl/src/ssl/test/server.rs @@ -0,0 +1,167 @@ +use std::io::{Read, Write}; +use std::net::{SocketAddr, TcpListener, TcpStream}; +use std::thread::{self, JoinHandle}; + +use crate::ssl::{Ssl, SslContext, SslContextBuilder, SslFiletype, SslMethod, SslRef, SslStream}; + +pub struct Server { + handle: Option>, + addr: SocketAddr, +} + +impl Drop for Server { + fn drop(&mut self) { + if !thread::panicking() { + self.handle.take().unwrap().join().unwrap(); + } + } +} + +impl Server { + pub fn builder() -> Builder { + let mut ctx = SslContext::builder(SslMethod::tls()).unwrap(); + ctx.set_certificate_chain_file("test/cert.pem").unwrap(); + ctx.set_private_key_file("test/key.pem", SslFiletype::PEM) + .unwrap(); + + Builder { + ctx, + ssl_cb: Box::new(|_| {}), + io_cb: Box::new(|_| {}), + should_error: false, + } + } + + pub fn client(&self) -> ClientBuilder { + ClientBuilder { + ctx: SslContext::builder(SslMethod::tls()).unwrap(), + addr: self.addr, + } + } + + pub fn connect_tcp(&self) -> TcpStream { + TcpStream::connect(self.addr).unwrap() + } +} + +pub struct Builder { + ctx: SslContextBuilder, + ssl_cb: Box, + io_cb: Box) + Send>, + should_error: bool, +} + +impl Builder { + pub fn ctx(&mut self) -> &mut SslContextBuilder { + &mut self.ctx + } + + pub fn ssl_cb(&mut self, cb: F) + where + F: 'static + FnMut(&mut SslRef) + Send, + { + self.ssl_cb = Box::new(cb); + } + + pub fn io_cb(&mut self, cb: F) + where + F: 'static + FnMut(SslStream) + Send, + { + self.io_cb = Box::new(cb); + } + + pub fn should_error(&mut self) { + self.should_error = true; + } + + pub fn build(self) -> Server { + let ctx = self.ctx.build(); + let socket = TcpListener::bind("127.0.0.1:0").unwrap(); + let addr = socket.local_addr().unwrap(); + let mut ssl_cb = self.ssl_cb; + let mut io_cb = self.io_cb; + let should_error = self.should_error; + + let handle = thread::spawn(move || { + let socket = socket.accept().unwrap().0; + let mut ssl = Ssl::new(&ctx).unwrap(); + ssl_cb(&mut ssl); + let r = ssl.accept(socket); + if should_error { + r.unwrap_err(); + } else { + let mut socket = r.unwrap(); + socket.write_all(&[0]).unwrap(); + io_cb(socket); + } + }); + + Server { + handle: Some(handle), + addr, + } + } +} + +pub struct ClientBuilder { + ctx: SslContextBuilder, + addr: SocketAddr, +} + +impl ClientBuilder { + pub fn ctx(&mut self) -> &mut SslContextBuilder { + &mut self.ctx + } + + pub fn build(self) -> Client { + Client { + ctx: self.ctx.build(), + addr: self.addr, + } + } + + pub fn connect(self) -> SslStream { + self.build().builder().connect() + } + + pub fn connect_err(self) { + self.build().builder().connect_err(); + } +} + +pub struct Client { + ctx: SslContext, + addr: SocketAddr, +} + +impl Client { + pub fn builder(&self) -> ClientSslBuilder { + ClientSslBuilder { + ssl: Ssl::new(&self.ctx).unwrap(), + addr: self.addr, + } + } +} + +pub struct ClientSslBuilder { + ssl: Ssl, + addr: SocketAddr, +} + +impl ClientSslBuilder { + pub fn ssl(&mut self) -> &mut SslRef { + &mut self.ssl + } + + pub fn connect(self) -> SslStream { + let socket = TcpStream::connect(self.addr).unwrap(); + let mut s = self.ssl.connect(socket).unwrap(); + s.read_exact(&mut [0]).unwrap(); + s + } + + pub fn connect_err(self) { + let socket = TcpStream::connect(self.addr).unwrap(); + self.ssl.connect(socket).unwrap_err(); + } +} diff --git a/vendor/openssl/src/stack.rs b/vendor/openssl/src/stack.rs new file mode 100644 index 0000000..112aa7f --- /dev/null +++ b/vendor/openssl/src/stack.rs @@ -0,0 +1,380 @@ +use cfg_if::cfg_if; +use foreign_types::{ForeignType, ForeignTypeRef, Opaque}; +use libc::c_int; +use std::borrow::Borrow; +use std::convert::AsRef; +use std::fmt; +use std::iter; +use std::marker::PhantomData; +use std::mem; +use std::ops::{Deref, DerefMut, Index, IndexMut, Range}; + +use crate::error::ErrorStack; +use crate::util::ForeignTypeExt; +use crate::{cvt, cvt_p, LenType}; + +cfg_if! { + if #[cfg(any(ossl110, boringssl))] { + use ffi::{ + OPENSSL_sk_pop, OPENSSL_sk_free, OPENSSL_sk_num, OPENSSL_sk_value, OPENSSL_STACK, + OPENSSL_sk_new_null, OPENSSL_sk_push, + }; + } else { + use ffi::{ + sk_pop as OPENSSL_sk_pop, sk_free as OPENSSL_sk_free, sk_num as OPENSSL_sk_num, + sk_value as OPENSSL_sk_value, _STACK as OPENSSL_STACK, + sk_new_null as OPENSSL_sk_new_null, sk_push as OPENSSL_sk_push, + }; + } +} + +/// Trait implemented by types which can be placed in a stack. +/// +/// It should not be implemented for any type outside of this crate. +pub trait Stackable: ForeignType { + /// The C stack type for this element. + /// + /// Generally called `stack_st_{ELEMENT_TYPE}`, normally hidden by the + /// `STACK_OF(ELEMENT_TYPE)` macro in the OpenSSL API. + type StackType; +} + +/// An owned stack of `T`. +pub struct Stack(*mut T::StackType); + +unsafe impl Send for Stack {} +unsafe impl Sync for Stack {} + +impl fmt::Debug for Stack +where + T: Stackable, + T::Ref: fmt::Debug, +{ + fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { + fmt.debug_list().entries(self).finish() + } +} +impl Drop for Stack { + fn drop(&mut self) { + unsafe { + while self.pop().is_some() {} + OPENSSL_sk_free(self.0 as *mut _); + } + } +} + +impl Stack { + pub fn new() -> Result, ErrorStack> { + unsafe { + ffi::init(); + let ptr = cvt_p(OPENSSL_sk_new_null())?; + Ok(Stack(ptr as *mut _)) + } + } +} + +impl iter::IntoIterator for Stack { + type IntoIter = IntoIter; + type Item = T; + + fn into_iter(self) -> IntoIter { + let it = IntoIter { + stack: self.0, + idxs: 0..self.len() as LenType, + }; + mem::forget(self); + it + } +} + +impl AsRef> for Stack { + fn as_ref(&self) -> &StackRef { + self + } +} + +impl Borrow> for Stack { + fn borrow(&self) -> &StackRef { + self + } +} + +impl ForeignType for Stack { + type CType = T::StackType; + type Ref = StackRef; + + #[inline] + unsafe fn from_ptr(ptr: *mut T::StackType) -> Stack { + assert!( + !ptr.is_null(), + "Must not instantiate a Stack from a null-ptr - use Stack::new() in \ + that case" + ); + Stack(ptr) + } + + #[inline] + fn as_ptr(&self) -> *mut T::StackType { + self.0 + } +} + +impl Deref for Stack { + type Target = StackRef; + + fn deref(&self) -> &StackRef { + unsafe { StackRef::from_ptr(self.0) } + } +} + +impl DerefMut for Stack { + fn deref_mut(&mut self) -> &mut StackRef { + unsafe { StackRef::from_ptr_mut(self.0) } + } +} + +pub struct IntoIter { + stack: *mut T::StackType, + idxs: Range, +} + +impl Drop for IntoIter { + fn drop(&mut self) { + unsafe { + // https://github.com/rust-lang/rust-clippy/issues/7510 + #[allow(clippy::while_let_on_iterator)] + while let Some(_) = self.next() {} + OPENSSL_sk_free(self.stack as *mut _); + } + } +} + +impl Iterator for IntoIter { + type Item = T; + + fn next(&mut self) -> Option { + unsafe { + self.idxs + .next() + .map(|i| T::from_ptr(OPENSSL_sk_value(self.stack as *mut _, i) as *mut _)) + } + } + + fn size_hint(&self) -> (usize, Option) { + self.idxs.size_hint() + } +} + +impl DoubleEndedIterator for IntoIter { + fn next_back(&mut self) -> Option { + unsafe { + self.idxs + .next_back() + .map(|i| T::from_ptr(OPENSSL_sk_value(self.stack as *mut _, i) as *mut _)) + } + } +} + +impl ExactSizeIterator for IntoIter {} + +pub struct StackRef(Opaque, PhantomData); + +unsafe impl Send for StackRef {} +unsafe impl Sync for StackRef {} + +impl ForeignTypeRef for StackRef { + type CType = T::StackType; +} + +impl StackRef { + fn as_stack(&self) -> *mut OPENSSL_STACK { + self.as_ptr() as *mut _ + } + + /// Returns the number of items in the stack. + pub fn len(&self) -> usize { + unsafe { OPENSSL_sk_num(self.as_stack()) as usize } + } + + /// Determines if the stack is empty. + pub fn is_empty(&self) -> bool { + self.len() == 0 + } + + pub fn iter(&self) -> Iter<'_, T> { + Iter { + stack: self, + idxs: 0..self.len() as LenType, + } + } + + pub fn iter_mut(&mut self) -> IterMut<'_, T> { + IterMut { + idxs: 0..self.len() as LenType, + stack: self, + } + } + + /// Returns a reference to the element at the given index in the + /// stack or `None` if the index is out of bounds + pub fn get(&self, idx: usize) -> Option<&T::Ref> { + unsafe { + if idx >= self.len() { + return None; + } + + Some(T::Ref::from_ptr(self._get(idx))) + } + } + + /// Returns a mutable reference to the element at the given index in the + /// stack or `None` if the index is out of bounds + pub fn get_mut(&mut self, idx: usize) -> Option<&mut T::Ref> { + unsafe { + if idx >= self.len() { + return None; + } + + Some(T::Ref::from_ptr_mut(self._get(idx))) + } + } + + /// Pushes a value onto the top of the stack. + pub fn push(&mut self, data: T) -> Result<(), ErrorStack> { + unsafe { + cvt(OPENSSL_sk_push(self.as_stack(), data.as_ptr() as *mut _) as c_int)?; + mem::forget(data); + Ok(()) + } + } + + /// Removes the last element from the stack and returns it. + pub fn pop(&mut self) -> Option { + unsafe { + let ptr = OPENSSL_sk_pop(self.as_stack()); + T::from_ptr_opt(ptr as *mut _) + } + } + + unsafe fn _get(&self, idx: usize) -> *mut T::CType { + OPENSSL_sk_value(self.as_stack(), idx as LenType) as *mut _ + } +} + +impl Index for StackRef { + type Output = T::Ref; + + fn index(&self, index: usize) -> &T::Ref { + self.get(index).unwrap() + } +} + +impl IndexMut for StackRef { + fn index_mut(&mut self, index: usize) -> &mut T::Ref { + self.get_mut(index).unwrap() + } +} + +impl<'a, T: Stackable> iter::IntoIterator for &'a StackRef { + type Item = &'a T::Ref; + type IntoIter = Iter<'a, T>; + + fn into_iter(self) -> Iter<'a, T> { + self.iter() + } +} + +impl<'a, T: Stackable> iter::IntoIterator for &'a mut StackRef { + type Item = &'a mut T::Ref; + type IntoIter = IterMut<'a, T>; + + fn into_iter(self) -> IterMut<'a, T> { + self.iter_mut() + } +} + +impl<'a, T: Stackable> iter::IntoIterator for &'a Stack { + type Item = &'a T::Ref; + type IntoIter = Iter<'a, T>; + + fn into_iter(self) -> Iter<'a, T> { + self.iter() + } +} + +impl<'a, T: Stackable> iter::IntoIterator for &'a mut Stack { + type Item = &'a mut T::Ref; + type IntoIter = IterMut<'a, T>; + + fn into_iter(self) -> IterMut<'a, T> { + self.iter_mut() + } +} + +/// An iterator over the stack's contents. +pub struct Iter<'a, T: Stackable> { + stack: &'a StackRef, + idxs: Range, +} + +impl<'a, T: Stackable> Iterator for Iter<'a, T> { + type Item = &'a T::Ref; + + fn next(&mut self) -> Option<&'a T::Ref> { + unsafe { + self.idxs + .next() + .map(|i| T::Ref::from_ptr(OPENSSL_sk_value(self.stack.as_stack(), i) as *mut _)) + } + } + + fn size_hint(&self) -> (usize, Option) { + self.idxs.size_hint() + } +} + +impl<'a, T: Stackable> DoubleEndedIterator for Iter<'a, T> { + fn next_back(&mut self) -> Option<&'a T::Ref> { + unsafe { + self.idxs + .next_back() + .map(|i| T::Ref::from_ptr(OPENSSL_sk_value(self.stack.as_stack(), i) as *mut _)) + } + } +} + +impl ExactSizeIterator for Iter<'_, T> {} + +/// A mutable iterator over the stack's contents. +pub struct IterMut<'a, T: Stackable> { + stack: &'a mut StackRef, + idxs: Range, +} + +impl<'a, T: Stackable> Iterator for IterMut<'a, T> { + type Item = &'a mut T::Ref; + + fn next(&mut self) -> Option<&'a mut T::Ref> { + unsafe { + self.idxs + .next() + .map(|i| T::Ref::from_ptr_mut(OPENSSL_sk_value(self.stack.as_stack(), i) as *mut _)) + } + } + + fn size_hint(&self) -> (usize, Option) { + self.idxs.size_hint() + } +} + +impl<'a, T: Stackable> DoubleEndedIterator for IterMut<'a, T> { + fn next_back(&mut self) -> Option<&'a mut T::Ref> { + unsafe { + self.idxs + .next_back() + .map(|i| T::Ref::from_ptr_mut(OPENSSL_sk_value(self.stack.as_stack(), i) as *mut _)) + } + } +} + +impl ExactSizeIterator for IterMut<'_, T> {} diff --git a/vendor/openssl/src/string.rs b/vendor/openssl/src/string.rs new file mode 100644 index 0000000..95494b5 --- /dev/null +++ b/vendor/openssl/src/string.rs @@ -0,0 +1,96 @@ +use foreign_types::ForeignTypeRef; +use libc::{c_char, c_void}; +use std::convert::AsRef; +use std::ffi::CStr; +use std::fmt; +use std::ops::Deref; +use std::str; + +use crate::stack::Stackable; + +foreign_type_and_impl_send_sync! { + type CType = c_char; + fn drop = free; + + pub struct OpensslString; + pub struct OpensslStringRef; +} + +impl fmt::Display for OpensslString { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + fmt::Display::fmt(&**self, f) + } +} + +impl fmt::Debug for OpensslString { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + fmt::Debug::fmt(&**self, f) + } +} + +impl Stackable for OpensslString { + type StackType = ffi::stack_st_OPENSSL_STRING; +} + +impl AsRef for OpensslString { + fn as_ref(&self) -> &str { + self + } +} + +impl AsRef<[u8]> for OpensslString { + fn as_ref(&self) -> &[u8] { + self.as_bytes() + } +} + +impl Deref for OpensslStringRef { + type Target = str; + + fn deref(&self) -> &str { + unsafe { + let slice = CStr::from_ptr(self.as_ptr()).to_bytes(); + str::from_utf8_unchecked(slice) + } + } +} + +impl AsRef for OpensslStringRef { + fn as_ref(&self) -> &str { + self + } +} + +impl AsRef<[u8]> for OpensslStringRef { + fn as_ref(&self) -> &[u8] { + self.as_bytes() + } +} + +impl fmt::Display for OpensslStringRef { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + fmt::Display::fmt(&**self, f) + } +} + +impl fmt::Debug for OpensslStringRef { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + fmt::Debug::fmt(&**self, f) + } +} + +#[inline] +#[cfg(not(boringssl))] +unsafe fn free(buf: *mut c_char) { + ffi::OPENSSL_free(buf as *mut c_void); +} + +#[inline] +#[cfg(boringssl)] +unsafe fn free(buf: *mut c_char) { + ffi::CRYPTO_free( + buf as *mut c_void, + concat!(file!(), "\0").as_ptr() as *const c_char, + line!() as ::libc::c_int, + ); +} diff --git a/vendor/openssl/src/symm.rs b/vendor/openssl/src/symm.rs new file mode 100644 index 0000000..3929c59 --- /dev/null +++ b/vendor/openssl/src/symm.rs @@ -0,0 +1,1763 @@ +//! High level interface to certain symmetric ciphers. +//! +//! # Examples +//! +//! Encrypt data in AES128 CBC mode +//! +//! ``` +//! use openssl::symm::{encrypt, Cipher}; +//! +//! let cipher = Cipher::aes_128_cbc(); +//! let data = b"Some Crypto Text"; +//! let key = b"\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F"; +//! let iv = b"\x00\x01\x02\x03\x04\x05\x06\x07\x00\x01\x02\x03\x04\x05\x06\x07"; +//! let ciphertext = encrypt( +//! cipher, +//! key, +//! Some(iv), +//! data).unwrap(); +//! +//! assert_eq!( +//! b"\xB4\xB9\xE7\x30\xD6\xD6\xF7\xDE\x77\x3F\x1C\xFF\xB3\x3E\x44\x5A\x91\xD7\x27\x62\x87\x4D\ +//! \xFB\x3C\x5E\xC4\x59\x72\x4A\xF4\x7C\xA1", +//! &ciphertext[..]); +//! ``` +//! +//! Encrypting an asymmetric key with a symmetric cipher +//! +//! ``` +//! use openssl::rsa::{Padding, Rsa}; +//! use openssl::symm::Cipher; +//! +//! // Generate keypair and encrypt private key: +//! let keypair = Rsa::generate(2048).unwrap(); +//! let cipher = Cipher::aes_256_cbc(); +//! let pubkey_pem = keypair.public_key_to_pem_pkcs1().unwrap(); +//! let privkey_pem = keypair.private_key_to_pem_passphrase(cipher, b"Rust").unwrap(); +//! // pubkey_pem and privkey_pem could be written to file here. +//! +//! // Load private and public key from string: +//! let pubkey = Rsa::public_key_from_pem_pkcs1(&pubkey_pem).unwrap(); +//! let privkey = Rsa::private_key_from_pem_passphrase(&privkey_pem, b"Rust").unwrap(); +//! +//! // Use the asymmetric keys to encrypt and decrypt a short message: +//! let msg = b"Foo bar"; +//! let mut encrypted = vec![0; pubkey.size() as usize]; +//! let mut decrypted = vec![0; privkey.size() as usize]; +//! let len = pubkey.public_encrypt(msg, &mut encrypted, Padding::PKCS1).unwrap(); +//! assert!(len > msg.len()); +//! let len = privkey.private_decrypt(&encrypted, &mut decrypted, Padding::PKCS1).unwrap(); +//! let output_string = String::from_utf8(decrypted[..len].to_vec()).unwrap(); +//! assert_eq!("Foo bar", output_string); +//! println!("Decrypted: '{}'", output_string); +//! ``` +use crate::cipher::CipherRef; +use crate::cipher_ctx::{CipherCtx, CipherCtxRef}; +use crate::error::ErrorStack; +use crate::nid::Nid; +use cfg_if::cfg_if; +use foreign_types::ForeignTypeRef; +use openssl_macros::corresponds; + +#[derive(Copy, Clone)] +pub enum Mode { + Encrypt, + Decrypt, +} + +/// Represents a particular cipher algorithm. +/// +/// See OpenSSL doc at [`EVP_EncryptInit`] for more information on each algorithms. +/// +/// [`EVP_EncryptInit`]: https://www.openssl.org/docs/manmaster/crypto/EVP_EncryptInit.html +#[derive(Copy, Clone, PartialEq, Eq)] +pub struct Cipher(*const ffi::EVP_CIPHER); + +impl Cipher { + /// Looks up the cipher for a certain nid. + #[corresponds(EVP_get_cipherbynid)] + pub fn from_nid(nid: Nid) -> Option { + let ptr = unsafe { ffi::EVP_get_cipherbyname(ffi::OBJ_nid2sn(nid.as_raw())) }; + if ptr.is_null() { + None + } else { + Some(Cipher(ptr)) + } + } + + /// Returns the cipher's Nid. + #[corresponds(EVP_CIPHER_nid)] + pub fn nid(&self) -> Nid { + let nid = unsafe { ffi::EVP_CIPHER_nid(self.0) }; + Nid::from_raw(nid) + } + + pub fn aes_128_ecb() -> Cipher { + unsafe { Cipher(ffi::EVP_aes_128_ecb()) } + } + + pub fn aes_128_cbc() -> Cipher { + unsafe { Cipher(ffi::EVP_aes_128_cbc()) } + } + + #[cfg(not(boringssl))] + pub fn aes_128_xts() -> Cipher { + unsafe { Cipher(ffi::EVP_aes_128_xts()) } + } + + pub fn aes_128_ctr() -> Cipher { + unsafe { Cipher(ffi::EVP_aes_128_ctr()) } + } + + #[cfg(not(boringssl))] + pub fn aes_128_cfb1() -> Cipher { + unsafe { Cipher(ffi::EVP_aes_128_cfb1()) } + } + + pub fn aes_128_cfb128() -> Cipher { + unsafe { Cipher(ffi::EVP_aes_128_cfb128()) } + } + + #[cfg(not(boringssl))] + pub fn aes_128_cfb8() -> Cipher { + unsafe { Cipher(ffi::EVP_aes_128_cfb8()) } + } + + pub fn aes_128_gcm() -> Cipher { + unsafe { Cipher(ffi::EVP_aes_128_gcm()) } + } + + #[cfg(not(boringssl))] + pub fn aes_128_ccm() -> Cipher { + unsafe { Cipher(ffi::EVP_aes_128_ccm()) } + } + + pub fn aes_128_ofb() -> Cipher { + unsafe { Cipher(ffi::EVP_aes_128_ofb()) } + } + + /// Requires OpenSSL 1.1.0 or newer. + #[cfg(all(ossl110, not(osslconf = "OPENSSL_NO_OCB")))] + pub fn aes_128_ocb() -> Cipher { + unsafe { Cipher(ffi::EVP_aes_128_ocb()) } + } + + pub fn aes_192_ecb() -> Cipher { + unsafe { Cipher(ffi::EVP_aes_192_ecb()) } + } + + pub fn aes_192_cbc() -> Cipher { + unsafe { Cipher(ffi::EVP_aes_192_cbc()) } + } + + pub fn aes_192_ctr() -> Cipher { + unsafe { Cipher(ffi::EVP_aes_192_ctr()) } + } + + #[cfg(not(boringssl))] + pub fn aes_192_cfb1() -> Cipher { + unsafe { Cipher(ffi::EVP_aes_192_cfb1()) } + } + + pub fn aes_192_cfb128() -> Cipher { + unsafe { Cipher(ffi::EVP_aes_192_cfb128()) } + } + + #[cfg(not(boringssl))] + pub fn aes_192_cfb8() -> Cipher { + unsafe { Cipher(ffi::EVP_aes_192_cfb8()) } + } + + pub fn aes_192_gcm() -> Cipher { + unsafe { Cipher(ffi::EVP_aes_192_gcm()) } + } + + #[cfg(not(boringssl))] + pub fn aes_192_ccm() -> Cipher { + unsafe { Cipher(ffi::EVP_aes_192_ccm()) } + } + + pub fn aes_192_ofb() -> Cipher { + unsafe { Cipher(ffi::EVP_aes_192_ofb()) } + } + + /// Requires OpenSSL 1.1.0 or newer. + #[cfg(all(ossl110, not(osslconf = "OPENSSL_NO_OCB")))] + pub fn aes_192_ocb() -> Cipher { + unsafe { Cipher(ffi::EVP_aes_192_ocb()) } + } + + pub fn aes_256_ecb() -> Cipher { + unsafe { Cipher(ffi::EVP_aes_256_ecb()) } + } + + pub fn aes_256_cbc() -> Cipher { + unsafe { Cipher(ffi::EVP_aes_256_cbc()) } + } + + #[cfg(not(boringssl))] + pub fn aes_256_xts() -> Cipher { + unsafe { Cipher(ffi::EVP_aes_256_xts()) } + } + + pub fn aes_256_ctr() -> Cipher { + unsafe { Cipher(ffi::EVP_aes_256_ctr()) } + } + + #[cfg(not(boringssl))] + pub fn aes_256_cfb1() -> Cipher { + unsafe { Cipher(ffi::EVP_aes_256_cfb1()) } + } + + pub fn aes_256_cfb128() -> Cipher { + unsafe { Cipher(ffi::EVP_aes_256_cfb128()) } + } + + #[cfg(not(boringssl))] + pub fn aes_256_cfb8() -> Cipher { + unsafe { Cipher(ffi::EVP_aes_256_cfb8()) } + } + + pub fn aes_256_gcm() -> Cipher { + unsafe { Cipher(ffi::EVP_aes_256_gcm()) } + } + + #[cfg(not(boringssl))] + pub fn aes_256_ccm() -> Cipher { + unsafe { Cipher(ffi::EVP_aes_256_ccm()) } + } + + pub fn aes_256_ofb() -> Cipher { + unsafe { Cipher(ffi::EVP_aes_256_ofb()) } + } + + /// Requires OpenSSL 1.1.0 or newer. + #[cfg(all(ossl110, not(osslconf = "OPENSSL_NO_OCB")))] + pub fn aes_256_ocb() -> Cipher { + unsafe { Cipher(ffi::EVP_aes_256_ocb()) } + } + + #[cfg(not(osslconf = "OPENSSL_NO_BF"))] + pub fn bf_cbc() -> Cipher { + unsafe { Cipher(ffi::EVP_bf_cbc()) } + } + + #[cfg(not(osslconf = "OPENSSL_NO_BF"))] + pub fn bf_ecb() -> Cipher { + unsafe { Cipher(ffi::EVP_bf_ecb()) } + } + + #[cfg(not(osslconf = "OPENSSL_NO_BF"))] + pub fn bf_cfb64() -> Cipher { + unsafe { Cipher(ffi::EVP_bf_cfb64()) } + } + + #[cfg(not(osslconf = "OPENSSL_NO_BF"))] + pub fn bf_ofb() -> Cipher { + unsafe { Cipher(ffi::EVP_bf_ofb()) } + } + + pub fn des_cbc() -> Cipher { + unsafe { Cipher(ffi::EVP_des_cbc()) } + } + + pub fn des_ecb() -> Cipher { + unsafe { Cipher(ffi::EVP_des_ecb()) } + } + + pub fn des_ede3() -> Cipher { + unsafe { Cipher(ffi::EVP_des_ede3()) } + } + + pub fn des_ede3_cbc() -> Cipher { + unsafe { Cipher(ffi::EVP_des_ede3_cbc()) } + } + + pub fn des_ede3_ecb() -> Cipher { + unsafe { Cipher(ffi::EVP_des_ede3_ecb()) } + } + + #[cfg(not(boringssl))] + pub fn des_ede3_cfb64() -> Cipher { + unsafe { Cipher(ffi::EVP_des_ede3_cfb64()) } + } + + #[cfg(not(boringssl))] + pub fn des_ede3_cfb8() -> Cipher { + unsafe { Cipher(ffi::EVP_des_ede3_cfb8()) } + } + + #[cfg(not(boringssl))] + pub fn des_ede3_ofb() -> Cipher { + unsafe { Cipher(ffi::EVP_des_ede3_ofb()) } + } + + #[cfg(not(osslconf = "OPENSSL_NO_RC4"))] + pub fn rc4() -> Cipher { + unsafe { Cipher(ffi::EVP_rc4()) } + } + + #[cfg(not(osslconf = "OPENSSL_NO_CAMELLIA"))] + pub fn camellia_128_cbc() -> Cipher { + unsafe { Cipher(ffi::EVP_camellia_128_cbc()) } + } + + #[cfg(not(osslconf = "OPENSSL_NO_CAMELLIA"))] + pub fn camellia_128_ecb() -> Cipher { + unsafe { Cipher(ffi::EVP_camellia_128_ecb()) } + } + + #[cfg(not(osslconf = "OPENSSL_NO_CAMELLIA"))] + pub fn camellia_128_ofb() -> Cipher { + unsafe { Cipher(ffi::EVP_camellia_128_ofb()) } + } + + #[cfg(not(osslconf = "OPENSSL_NO_CAMELLIA"))] + pub fn camellia_128_cfb128() -> Cipher { + unsafe { Cipher(ffi::EVP_camellia_128_cfb128()) } + } + + #[cfg(not(osslconf = "OPENSSL_NO_CAMELLIA"))] + pub fn camellia_192_cbc() -> Cipher { + unsafe { Cipher(ffi::EVP_camellia_192_cbc()) } + } + + #[cfg(not(osslconf = "OPENSSL_NO_CAMELLIA"))] + pub fn camellia_192_ecb() -> Cipher { + unsafe { Cipher(ffi::EVP_camellia_192_ecb()) } + } + + #[cfg(not(osslconf = "OPENSSL_NO_CAMELLIA"))] + pub fn camellia_192_ofb() -> Cipher { + unsafe { Cipher(ffi::EVP_camellia_192_ofb()) } + } + + #[cfg(not(osslconf = "OPENSSL_NO_CAMELLIA"))] + pub fn camellia_192_cfb128() -> Cipher { + unsafe { Cipher(ffi::EVP_camellia_192_cfb128()) } + } + + #[cfg(not(osslconf = "OPENSSL_NO_CAMELLIA"))] + pub fn camellia_256_cbc() -> Cipher { + unsafe { Cipher(ffi::EVP_camellia_256_cbc()) } + } + + #[cfg(not(osslconf = "OPENSSL_NO_CAMELLIA"))] + pub fn camellia_256_ecb() -> Cipher { + unsafe { Cipher(ffi::EVP_camellia_256_ecb()) } + } + + #[cfg(not(osslconf = "OPENSSL_NO_CAMELLIA"))] + pub fn camellia_256_ofb() -> Cipher { + unsafe { Cipher(ffi::EVP_camellia_256_ofb()) } + } + + #[cfg(not(osslconf = "OPENSSL_NO_CAMELLIA"))] + pub fn camellia_256_cfb128() -> Cipher { + unsafe { Cipher(ffi::EVP_camellia_256_cfb128()) } + } + + #[cfg(not(osslconf = "OPENSSL_NO_CAST"))] + pub fn cast5_cbc() -> Cipher { + unsafe { Cipher(ffi::EVP_cast5_cbc()) } + } + + #[cfg(not(osslconf = "OPENSSL_NO_CAST"))] + pub fn cast5_ecb() -> Cipher { + unsafe { Cipher(ffi::EVP_cast5_ecb()) } + } + + #[cfg(not(osslconf = "OPENSSL_NO_CAST"))] + pub fn cast5_ofb() -> Cipher { + unsafe { Cipher(ffi::EVP_cast5_ofb()) } + } + + #[cfg(not(osslconf = "OPENSSL_NO_CAST"))] + pub fn cast5_cfb64() -> Cipher { + unsafe { Cipher(ffi::EVP_cast5_cfb64()) } + } + + /// Requires OpenSSL 1.1.0 or newer. + #[cfg(all(any(ossl110, libressl310), not(osslconf = "OPENSSL_NO_CHACHA")))] + pub fn chacha20() -> Cipher { + unsafe { Cipher(ffi::EVP_chacha20()) } + } + + /// Requires OpenSSL 1.1.0 or newer. + #[cfg(all(any(ossl110, libressl360), not(osslconf = "OPENSSL_NO_CHACHA")))] + pub fn chacha20_poly1305() -> Cipher { + unsafe { Cipher(ffi::EVP_chacha20_poly1305()) } + } + + #[cfg(not(osslconf = "OPENSSL_NO_IDEA"))] + pub fn idea_cbc() -> Cipher { + unsafe { Cipher(ffi::EVP_idea_cbc()) } + } + + #[cfg(not(osslconf = "OPENSSL_NO_IDEA"))] + pub fn idea_ecb() -> Cipher { + unsafe { Cipher(ffi::EVP_idea_ecb()) } + } + + #[cfg(not(osslconf = "OPENSSL_NO_IDEA"))] + pub fn idea_ofb() -> Cipher { + unsafe { Cipher(ffi::EVP_idea_ofb()) } + } + + #[cfg(not(osslconf = "OPENSSL_NO_IDEA"))] + pub fn idea_cfb64() -> Cipher { + unsafe { Cipher(ffi::EVP_idea_cfb64()) } + } + + #[cfg(not(osslconf = "OPENSSL_NO_SEED"))] + pub fn seed_cbc() -> Cipher { + unsafe { Cipher(ffi::EVP_seed_cbc()) } + } + + #[cfg(not(osslconf = "OPENSSL_NO_SEED"))] + pub fn seed_cfb128() -> Cipher { + unsafe { Cipher(ffi::EVP_seed_cfb128()) } + } + + #[cfg(not(osslconf = "OPENSSL_NO_SEED"))] + pub fn seed_ecb() -> Cipher { + unsafe { Cipher(ffi::EVP_seed_ecb()) } + } + + #[cfg(not(osslconf = "OPENSSL_NO_SEED"))] + pub fn seed_ofb() -> Cipher { + unsafe { Cipher(ffi::EVP_seed_ofb()) } + } + + #[cfg(all(any(ossl111, libressl291), not(osslconf = "OPENSSL_NO_SM4")))] + pub fn sm4_ecb() -> Cipher { + unsafe { Cipher(ffi::EVP_sm4_ecb()) } + } + + #[cfg(all(any(ossl111, libressl291), not(osslconf = "OPENSSL_NO_SM4")))] + pub fn sm4_cbc() -> Cipher { + unsafe { Cipher(ffi::EVP_sm4_cbc()) } + } + + #[cfg(all(any(ossl111, libressl291), not(osslconf = "OPENSSL_NO_SM4")))] + pub fn sm4_ctr() -> Cipher { + unsafe { Cipher(ffi::EVP_sm4_ctr()) } + } + + #[cfg(all(any(ossl111, libressl291), not(osslconf = "OPENSSL_NO_SM4")))] + pub fn sm4_cfb128() -> Cipher { + unsafe { Cipher(ffi::EVP_sm4_cfb128()) } + } + + #[cfg(all(any(ossl111, libressl291), not(osslconf = "OPENSSL_NO_SM4")))] + pub fn sm4_ofb() -> Cipher { + unsafe { Cipher(ffi::EVP_sm4_ofb()) } + } + + /// Creates a `Cipher` from a raw pointer to its OpenSSL type. + /// + /// # Safety + /// + /// The caller must ensure the pointer is valid for the `'static` lifetime. + pub unsafe fn from_ptr(ptr: *const ffi::EVP_CIPHER) -> Cipher { + Cipher(ptr) + } + + #[allow(clippy::trivially_copy_pass_by_ref)] + pub fn as_ptr(&self) -> *const ffi::EVP_CIPHER { + self.0 + } + + /// Returns the length of keys used with this cipher. + #[allow(clippy::trivially_copy_pass_by_ref)] + pub fn key_len(&self) -> usize { + unsafe { EVP_CIPHER_key_length(self.0) as usize } + } + + /// Returns the length of the IV used with this cipher, or `None` if the + /// cipher does not use an IV. + #[allow(clippy::trivially_copy_pass_by_ref)] + pub fn iv_len(&self) -> Option { + unsafe { + let len = EVP_CIPHER_iv_length(self.0) as usize; + if len == 0 { + None + } else { + Some(len) + } + } + } + + /// Returns the block size of the cipher. + /// + /// # Note + /// + /// Stream ciphers such as RC4 have a block size of 1. + #[allow(clippy::trivially_copy_pass_by_ref)] + pub fn block_size(&self) -> usize { + unsafe { EVP_CIPHER_block_size(self.0) as usize } + } + + /// Determines whether the cipher is using CCM mode + #[cfg(not(boringssl))] + fn is_ccm(self) -> bool { + // NOTE: OpenSSL returns pointers to static structs, which makes this work as expected + self == Cipher::aes_128_ccm() || self == Cipher::aes_256_ccm() + } + + #[cfg(boringssl)] + fn is_ccm(self) -> bool { + false + } + + /// Determines whether the cipher is using OCB mode + #[cfg(all(ossl110, not(osslconf = "OPENSSL_NO_OCB")))] + fn is_ocb(self) -> bool { + self == Cipher::aes_128_ocb() + || self == Cipher::aes_192_ocb() + || self == Cipher::aes_256_ocb() + } + + #[cfg(any(not(ossl110), osslconf = "OPENSSL_NO_OCB"))] + const fn is_ocb(self) -> bool { + false + } +} + +unsafe impl Sync for Cipher {} +unsafe impl Send for Cipher {} + +/// Represents a symmetric cipher context. +/// +/// Padding is enabled by default. +/// +/// # Examples +/// +/// Encrypt some plaintext in chunks, then decrypt the ciphertext back into plaintext, in AES 128 +/// CBC mode. +/// +/// ``` +/// use openssl::symm::{Cipher, Mode, Crypter}; +/// +/// let plaintexts: [&[u8]; 2] = [b"Some Stream of", b" Crypto Text"]; +/// let key = b"\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F"; +/// let iv = b"\x00\x01\x02\x03\x04\x05\x06\x07\x00\x01\x02\x03\x04\x05\x06\x07"; +/// let data_len = plaintexts.iter().fold(0, |sum, x| sum + x.len()); +/// +/// // Create a cipher context for encryption. +/// let mut encrypter = Crypter::new( +/// Cipher::aes_128_cbc(), +/// Mode::Encrypt, +/// key, +/// Some(iv)).unwrap(); +/// +/// let block_size = Cipher::aes_128_cbc().block_size(); +/// let mut ciphertext = vec![0; data_len + block_size]; +/// +/// // Encrypt 2 chunks of plaintexts successively. +/// let mut count = encrypter.update(plaintexts[0], &mut ciphertext).unwrap(); +/// count += encrypter.update(plaintexts[1], &mut ciphertext[count..]).unwrap(); +/// count += encrypter.finalize(&mut ciphertext[count..]).unwrap(); +/// ciphertext.truncate(count); +/// +/// assert_eq!( +/// b"\x0F\x21\x83\x7E\xB2\x88\x04\xAF\xD9\xCC\xE2\x03\x49\xB4\x88\xF6\xC4\x61\x0E\x32\x1C\xF9\ +/// \x0D\x66\xB1\xE6\x2C\x77\x76\x18\x8D\x99", +/// &ciphertext[..] +/// ); +/// +/// +/// // Let's pretend we don't know the plaintext, and now decrypt the ciphertext. +/// let data_len = ciphertext.len(); +/// let ciphertexts = [&ciphertext[..9], &ciphertext[9..]]; +/// +/// // Create a cipher context for decryption. +/// let mut decrypter = Crypter::new( +/// Cipher::aes_128_cbc(), +/// Mode::Decrypt, +/// key, +/// Some(iv)).unwrap(); +/// let mut plaintext = vec![0; data_len + block_size]; +/// +/// // Decrypt 2 chunks of ciphertexts successively. +/// let mut count = decrypter.update(ciphertexts[0], &mut plaintext).unwrap(); +/// count += decrypter.update(ciphertexts[1], &mut plaintext[count..]).unwrap(); +/// count += decrypter.finalize(&mut plaintext[count..]).unwrap(); +/// plaintext.truncate(count); +/// +/// assert_eq!(b"Some Stream of Crypto Text", &plaintext[..]); +/// ``` +pub struct Crypter { + ctx: CipherCtx, +} + +impl Crypter { + /// Creates a new `Crypter`. The initialisation vector, `iv`, is not necessary for certain + /// types of `Cipher`. + /// + /// # Panics + /// + /// Panics if an IV is required by the cipher but not provided. Also make sure that the key + /// and IV size are appropriate for your cipher. + pub fn new( + t: Cipher, + mode: Mode, + key: &[u8], + iv: Option<&[u8]>, + ) -> Result { + let mut ctx = CipherCtx::new()?; + + let f = match mode { + Mode::Encrypt => CipherCtxRef::encrypt_init, + Mode::Decrypt => CipherCtxRef::decrypt_init, + }; + + f( + &mut ctx, + Some(unsafe { CipherRef::from_ptr(t.as_ptr() as *mut _) }), + None, + None, + )?; + + ctx.set_key_length(key.len())?; + + if let (Some(iv), Some(iv_len)) = (iv, t.iv_len()) { + if iv.len() != iv_len { + ctx.set_iv_length(iv.len())?; + } + } + + f(&mut ctx, None, Some(key), iv)?; + + Ok(Crypter { ctx }) + } + + /// Enables or disables padding. + /// + /// If padding is disabled, total amount of data encrypted/decrypted must + /// be a multiple of the cipher's block size. + pub fn pad(&mut self, padding: bool) { + self.ctx.set_padding(padding) + } + + /// Sets the tag used to authenticate ciphertext in AEAD ciphers such as AES GCM. + /// + /// When decrypting cipher text using an AEAD cipher, this must be called before `finalize`. + pub fn set_tag(&mut self, tag: &[u8]) -> Result<(), ErrorStack> { + self.ctx.set_tag(tag) + } + + /// Sets the length of the authentication tag to generate in AES CCM. + /// + /// When encrypting with AES CCM, the tag length needs to be explicitly set in order + /// to use a value different than the default 12 bytes. + pub fn set_tag_len(&mut self, tag_len: usize) -> Result<(), ErrorStack> { + self.ctx.set_tag_length(tag_len) + } + + /// Feeds total plaintext length to the cipher. + /// + /// The total plaintext or ciphertext length MUST be passed to the cipher when it operates in + /// CCM mode. + pub fn set_data_len(&mut self, data_len: usize) -> Result<(), ErrorStack> { + self.ctx.set_data_len(data_len) + } + + /// Feeds Additional Authenticated Data (AAD) through the cipher. + /// + /// This can only be used with AEAD ciphers such as AES GCM. Data fed in is not encrypted, but + /// is factored into the authentication tag. It must be called before the first call to + /// `update`. + pub fn aad_update(&mut self, input: &[u8]) -> Result<(), ErrorStack> { + self.ctx.cipher_update(input, None)?; + Ok(()) + } + + /// Feeds data from `input` through the cipher, writing encrypted/decrypted + /// bytes into `output`. + /// + /// The number of bytes written to `output` is returned. Note that this may + /// not be equal to the length of `input`. + /// + /// # Panics + /// + /// Panics for stream ciphers if `output.len() < input.len()`. + /// + /// Panics for block ciphers if `output.len() < input.len() + block_size`, + /// where `block_size` is the block size of the cipher (see `Cipher::block_size`). + /// + /// Panics if `output.len() > c_int::MAX`. + pub fn update(&mut self, input: &[u8], output: &mut [u8]) -> Result { + self.ctx.cipher_update(input, Some(output)) + } + + /// Feeds data from `input` through the cipher, writing encrypted/decrypted + /// bytes into `output`. + /// + /// The number of bytes written to `output` is returned. Note that this may + /// not be equal to the length of `input`. + /// + /// # Safety + /// + /// The caller must provide an `output` buffer large enough to contain + /// correct number of bytes. For streaming ciphers the output buffer size + /// should be at least as big as the input buffer. For block ciphers the + /// size of the output buffer depends on the state of partially updated + /// blocks. + pub unsafe fn update_unchecked( + &mut self, + input: &[u8], + output: &mut [u8], + ) -> Result { + self.ctx.cipher_update_unchecked(input, Some(output)) + } + + /// Finishes the encryption/decryption process, writing any remaining data + /// to `output`. + /// + /// The number of bytes written to `output` is returned. + /// + /// `update` should not be called after this method. + /// + /// # Panics + /// + /// Panics for block ciphers if `output.len() < block_size`, + /// where `block_size` is the block size of the cipher (see `Cipher::block_size`). + pub fn finalize(&mut self, output: &mut [u8]) -> Result { + self.ctx.cipher_final(output) + } + + /// Retrieves the authentication tag used to authenticate ciphertext in AEAD ciphers such + /// as AES GCM. + /// + /// When encrypting data with an AEAD cipher, this must be called after `finalize`. + /// + /// The size of the buffer indicates the required size of the tag. While some ciphers support a + /// range of tag sizes, it is recommended to pick the maximum size. For AES GCM, this is 16 + /// bytes, for example. + pub fn get_tag(&self, tag: &mut [u8]) -> Result<(), ErrorStack> { + self.ctx.tag(tag) + } +} + +/// Encrypts data in one go, and returns the encrypted data. +/// +/// Data is encrypted using the specified cipher type `t` in encrypt mode with the specified `key` +/// and initialization vector `iv`. Padding is enabled. +/// +/// This is a convenient interface to `Crypter` to encrypt all data in one go. To encrypt a stream +/// of data incrementally , use `Crypter` instead. +/// +/// # Examples +/// +/// Encrypt data in AES128 CBC mode +/// +/// ``` +/// use openssl::symm::{encrypt, Cipher}; +/// +/// let cipher = Cipher::aes_128_cbc(); +/// let data = b"Some Crypto Text"; +/// let key = b"\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F"; +/// let iv = b"\x00\x01\x02\x03\x04\x05\x06\x07\x00\x01\x02\x03\x04\x05\x06\x07"; +/// let ciphertext = encrypt( +/// cipher, +/// key, +/// Some(iv), +/// data).unwrap(); +/// +/// assert_eq!( +/// b"\xB4\xB9\xE7\x30\xD6\xD6\xF7\xDE\x77\x3F\x1C\xFF\xB3\x3E\x44\x5A\x91\xD7\x27\x62\x87\x4D\ +/// \xFB\x3C\x5E\xC4\x59\x72\x4A\xF4\x7C\xA1", +/// &ciphertext[..]); +/// ``` +pub fn encrypt( + t: Cipher, + key: &[u8], + iv: Option<&[u8]>, + data: &[u8], +) -> Result, ErrorStack> { + cipher(t, Mode::Encrypt, key, iv, data) +} + +/// Decrypts data in one go, and returns the decrypted data. +/// +/// Data is decrypted using the specified cipher type `t` in decrypt mode with the specified `key` +/// and initialization vector `iv`. Padding is enabled. +/// +/// This is a convenient interface to `Crypter` to decrypt all data in one go. To decrypt a stream +/// of data incrementally , use `Crypter` instead. +/// +/// # Examples +/// +/// Decrypt data in AES128 CBC mode +/// +/// ``` +/// use openssl::symm::{decrypt, Cipher}; +/// +/// let cipher = Cipher::aes_128_cbc(); +/// let data = b"\xB4\xB9\xE7\x30\xD6\xD6\xF7\xDE\x77\x3F\x1C\xFF\xB3\x3E\x44\x5A\x91\xD7\x27\x62\ +/// \x87\x4D\xFB\x3C\x5E\xC4\x59\x72\x4A\xF4\x7C\xA1"; +/// let key = b"\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F"; +/// let iv = b"\x00\x01\x02\x03\x04\x05\x06\x07\x00\x01\x02\x03\x04\x05\x06\x07"; +/// let ciphertext = decrypt( +/// cipher, +/// key, +/// Some(iv), +/// data).unwrap(); +/// +/// assert_eq!( +/// b"Some Crypto Text", +/// &ciphertext[..]); +/// ``` +pub fn decrypt( + t: Cipher, + key: &[u8], + iv: Option<&[u8]>, + data: &[u8], +) -> Result, ErrorStack> { + cipher(t, Mode::Decrypt, key, iv, data) +} + +fn cipher( + t: Cipher, + mode: Mode, + key: &[u8], + iv: Option<&[u8]>, + data: &[u8], +) -> Result, ErrorStack> { + let mut c = Crypter::new(t, mode, key, iv)?; + let mut out = vec![0; data.len() + t.block_size()]; + let count = c.update(data, &mut out)?; + let rest = c.finalize(&mut out[count..])?; + out.truncate(count + rest); + Ok(out) +} + +/// Like `encrypt`, but for AEAD ciphers such as AES GCM. +/// +/// Additional Authenticated Data can be provided in the `aad` field, and the authentication tag +/// will be copied into the `tag` field. +/// +/// The size of the `tag` buffer indicates the required size of the tag. While some ciphers support +/// a range of tag sizes, it is recommended to pick the maximum size. For AES GCM, this is 16 bytes, +/// for example. +pub fn encrypt_aead( + t: Cipher, + key: &[u8], + iv: Option<&[u8]>, + aad: &[u8], + data: &[u8], + tag: &mut [u8], +) -> Result, ErrorStack> { + let mut c = Crypter::new(t, Mode::Encrypt, key, iv)?; + let mut out = vec![0; data.len() + t.block_size()]; + + let is_ccm = t.is_ccm(); + if is_ccm || t.is_ocb() { + c.set_tag_len(tag.len())?; + if is_ccm { + c.set_data_len(data.len())?; + } + } + + c.aad_update(aad)?; + let count = c.update(data, &mut out)?; + let rest = c.finalize(&mut out[count..])?; + c.get_tag(tag)?; + out.truncate(count + rest); + Ok(out) +} + +/// Like `decrypt`, but for AEAD ciphers such as AES GCM. +/// +/// Additional Authenticated Data can be provided in the `aad` field, and the authentication tag +/// should be provided in the `tag` field. +pub fn decrypt_aead( + t: Cipher, + key: &[u8], + iv: Option<&[u8]>, + aad: &[u8], + data: &[u8], + tag: &[u8], +) -> Result, ErrorStack> { + let mut c = Crypter::new(t, Mode::Decrypt, key, iv)?; + let mut out = vec![0; data.len() + t.block_size()]; + + let is_ccm = t.is_ccm(); + if is_ccm || t.is_ocb() { + c.set_tag(tag)?; + if is_ccm { + c.set_data_len(data.len())?; + } + } + + c.aad_update(aad)?; + let count = c.update(data, &mut out)?; + + let rest = if t.is_ccm() { + 0 + } else { + c.set_tag(tag)?; + c.finalize(&mut out[count..])? + }; + + out.truncate(count + rest); + Ok(out) +} + +cfg_if! { + if #[cfg(any(boringssl, ossl110, libressl273))] { + use ffi::{EVP_CIPHER_block_size, EVP_CIPHER_iv_length, EVP_CIPHER_key_length}; + } else { + use crate::LenType; + + #[allow(bad_style)] + pub unsafe fn EVP_CIPHER_iv_length(ptr: *const ffi::EVP_CIPHER) -> LenType { + (*ptr).iv_len + } + + #[allow(bad_style)] + pub unsafe fn EVP_CIPHER_block_size(ptr: *const ffi::EVP_CIPHER) -> LenType { + (*ptr).block_size + } + + #[allow(bad_style)] + pub unsafe fn EVP_CIPHER_key_length(ptr: *const ffi::EVP_CIPHER) -> LenType { + (*ptr).key_len + } + } +} + +#[cfg(test)] +mod tests { + use super::*; + use hex::{self, FromHex}; + + #[test] + fn test_stream_cipher_output() { + let key = [0u8; 16]; + let iv = [0u8; 16]; + let mut c = super::Crypter::new( + super::Cipher::aes_128_ctr(), + super::Mode::Encrypt, + &key, + Some(&iv), + ) + .unwrap(); + + assert_eq!(c.update(&[0u8; 15], &mut [0u8; 15]).unwrap(), 15); + assert_eq!(c.update(&[0u8; 1], &mut [0u8; 1]).unwrap(), 1); + assert_eq!(c.finalize(&mut [0u8; 0]).unwrap(), 0); + } + + // Test vectors from FIPS-197: + // http://csrc.nist.gov/publications/fips/fips197/fips-197.pdf + #[test] + fn test_aes_256_ecb() { + let k0 = [ + 0x00u8, 0x01u8, 0x02u8, 0x03u8, 0x04u8, 0x05u8, 0x06u8, 0x07u8, 0x08u8, 0x09u8, 0x0au8, + 0x0bu8, 0x0cu8, 0x0du8, 0x0eu8, 0x0fu8, 0x10u8, 0x11u8, 0x12u8, 0x13u8, 0x14u8, 0x15u8, + 0x16u8, 0x17u8, 0x18u8, 0x19u8, 0x1au8, 0x1bu8, 0x1cu8, 0x1du8, 0x1eu8, 0x1fu8, + ]; + let p0 = [ + 0x00u8, 0x11u8, 0x22u8, 0x33u8, 0x44u8, 0x55u8, 0x66u8, 0x77u8, 0x88u8, 0x99u8, 0xaau8, + 0xbbu8, 0xccu8, 0xddu8, 0xeeu8, 0xffu8, + ]; + let c0 = [ + 0x8eu8, 0xa2u8, 0xb7u8, 0xcau8, 0x51u8, 0x67u8, 0x45u8, 0xbfu8, 0xeau8, 0xfcu8, 0x49u8, + 0x90u8, 0x4bu8, 0x49u8, 0x60u8, 0x89u8, + ]; + let mut c = super::Crypter::new( + super::Cipher::aes_256_ecb(), + super::Mode::Encrypt, + &k0, + None, + ) + .unwrap(); + c.pad(false); + let mut r0 = vec![0; c0.len() + super::Cipher::aes_256_ecb().block_size()]; + let count = c.update(&p0, &mut r0).unwrap(); + let rest = c.finalize(&mut r0[count..]).unwrap(); + r0.truncate(count + rest); + assert_eq!(hex::encode(&r0), hex::encode(c0)); + + let mut c = super::Crypter::new( + super::Cipher::aes_256_ecb(), + super::Mode::Decrypt, + &k0, + None, + ) + .unwrap(); + c.pad(false); + let mut p1 = vec![0; r0.len() + super::Cipher::aes_256_ecb().block_size()]; + let count = c.update(&r0, &mut p1).unwrap(); + let rest = c.finalize(&mut p1[count..]).unwrap(); + p1.truncate(count + rest); + assert_eq!(hex::encode(p1), hex::encode(p0)); + } + + #[test] + fn test_aes_256_cbc_decrypt() { + let iv = [ + 4_u8, 223_u8, 153_u8, 219_u8, 28_u8, 142_u8, 234_u8, 68_u8, 227_u8, 69_u8, 98_u8, + 107_u8, 208_u8, 14_u8, 236_u8, 60_u8, + ]; + let data = [ + 143_u8, 210_u8, 75_u8, 63_u8, 214_u8, 179_u8, 155_u8, 241_u8, 242_u8, 31_u8, 154_u8, + 56_u8, 198_u8, 145_u8, 192_u8, 64_u8, 2_u8, 245_u8, 167_u8, 220_u8, 55_u8, 119_u8, + 233_u8, 136_u8, 139_u8, 27_u8, 71_u8, 242_u8, 119_u8, 175_u8, 65_u8, 207_u8, + ]; + let ciphered_data = [ + 0x4a_u8, 0x2e_u8, 0xe5_u8, 0x6_u8, 0xbf_u8, 0xcf_u8, 0xf2_u8, 0xd7_u8, 0xea_u8, + 0x2d_u8, 0xb1_u8, 0x85_u8, 0x6c_u8, 0x93_u8, 0x65_u8, 0x6f_u8, + ]; + let mut cr = super::Crypter::new( + super::Cipher::aes_256_cbc(), + super::Mode::Decrypt, + &data, + Some(&iv), + ) + .unwrap(); + cr.pad(false); + let mut unciphered_data = vec![0; data.len() + super::Cipher::aes_256_cbc().block_size()]; + let count = cr.update(&ciphered_data, &mut unciphered_data).unwrap(); + let rest = cr.finalize(&mut unciphered_data[count..]).unwrap(); + unciphered_data.truncate(count + rest); + + let expected_unciphered_data = b"I love turtles.\x01"; + + assert_eq!(&unciphered_data, expected_unciphered_data); + } + + fn cipher_test(ciphertype: super::Cipher, pt: &str, ct: &str, key: &str, iv: &str) { + let pt = Vec::from_hex(pt).unwrap(); + let ct = Vec::from_hex(ct).unwrap(); + let key = Vec::from_hex(key).unwrap(); + let iv = Vec::from_hex(iv).unwrap(); + + let computed = super::decrypt(ciphertype, &key, Some(&iv), &ct).unwrap(); + let expected = pt; + + if computed != expected { + println!("Computed: {}", hex::encode(&computed)); + println!("Expected: {}", hex::encode(&expected)); + if computed.len() != expected.len() { + println!( + "Lengths differ: {} in computed vs {} expected", + computed.len(), + expected.len() + ); + } + panic!("test failure"); + } + } + + #[cfg(not(boringssl))] + fn cipher_test_nopad(ciphertype: super::Cipher, pt: &str, ct: &str, key: &str, iv: &str) { + let pt = Vec::from_hex(pt).unwrap(); + let ct = Vec::from_hex(ct).unwrap(); + let key = Vec::from_hex(key).unwrap(); + let iv = Vec::from_hex(iv).unwrap(); + + let computed = { + let mut c = Crypter::new(ciphertype, Mode::Decrypt, &key, Some(&iv)).unwrap(); + c.pad(false); + let mut out = vec![0; ct.len() + ciphertype.block_size()]; + let count = c.update(&ct, &mut out).unwrap(); + let rest = c.finalize(&mut out[count..]).unwrap(); + out.truncate(count + rest); + out + }; + let expected = pt; + + if computed != expected { + println!("Computed: {}", hex::encode(&computed)); + println!("Expected: {}", hex::encode(&expected)); + if computed.len() != expected.len() { + println!( + "Lengths differ: {} in computed vs {} expected", + computed.len(), + expected.len() + ); + } + panic!("test failure"); + } + } + + #[test] + fn test_rc4() { + #[cfg(ossl300)] + let _provider = crate::provider::Provider::try_load(None, "legacy", true).unwrap(); + + let pt = "0000000000000000000000000000000000000000000000000000000000000000000000000000"; + let ct = "A68686B04D686AA107BD8D4CAB191A3EEC0A6294BC78B60F65C25CB47BD7BB3A48EFC4D26BE4"; + let key = "97CD440324DA5FD1F7955C1C13B6B466"; + let iv = ""; + + cipher_test(super::Cipher::rc4(), pt, ct, key, iv); + } + + #[test] + #[cfg(not(boringssl))] + fn test_aes256_xts() { + // Test case 174 from + // http://csrc.nist.gov/groups/STM/cavp/documents/aes/XTSTestVectors.zip + let pt = "77f4ef63d734ebd028508da66c22cdebdd52ecd6ee2ab0a50bc8ad0cfd692ca5fcd4e6dedc45df7f\ + 6503f462611dc542"; + let ct = "ce7d905a7776ac72f240d22aafed5e4eb7566cdc7211220e970da634ce015f131a5ecb8d400bc9e8\ + 4f0b81d8725dbbc7"; + let key = "b6bfef891f83b5ff073f2231267be51eb084b791fa19a154399c0684c8b2dfcb37de77d28bbda3b\ + 4180026ad640b74243b3133e7b9fae629403f6733423dae28"; + let iv = "db200efb7eaaa737dbdf40babb68953f"; + + cipher_test(super::Cipher::aes_256_xts(), pt, ct, key, iv); + } + + #[test] + fn test_aes128_ctr() { + let pt = "6BC1BEE22E409F96E93D7E117393172AAE2D8A571E03AC9C9EB76FAC45AF8E5130C81C46A35CE411\ + E5FBC1191A0A52EFF69F2445DF4F9B17AD2B417BE66C3710"; + let ct = "874D6191B620E3261BEF6864990DB6CE9806F66B7970FDFF8617187BB9FFFDFF5AE4DF3EDBD5D35E\ + 5B4F09020DB03EAB1E031DDA2FBE03D1792170A0F3009CEE"; + let key = "2B7E151628AED2A6ABF7158809CF4F3C"; + let iv = "F0F1F2F3F4F5F6F7F8F9FAFBFCFDFEFF"; + + cipher_test(super::Cipher::aes_128_ctr(), pt, ct, key, iv); + } + + #[test] + #[cfg(not(boringssl))] + fn test_aes128_cfb1() { + // Lifted from http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf + + let pt = "6bc1"; + let ct = "68b3"; + let key = "2b7e151628aed2a6abf7158809cf4f3c"; + let iv = "000102030405060708090a0b0c0d0e0f"; + + cipher_test(super::Cipher::aes_128_cfb1(), pt, ct, key, iv); + } + + #[test] + #[cfg(not(boringssl))] + fn test_aes128_cfb128() { + let pt = "6bc1bee22e409f96e93d7e117393172a"; + let ct = "3b3fd92eb72dad20333449f8e83cfb4a"; + let key = "2b7e151628aed2a6abf7158809cf4f3c"; + let iv = "000102030405060708090a0b0c0d0e0f"; + + cipher_test(super::Cipher::aes_128_cfb128(), pt, ct, key, iv); + } + + #[test] + #[cfg(not(boringssl))] + fn test_aes128_cfb8() { + let pt = "6bc1bee22e409f96e93d7e117393172aae2d"; + let ct = "3b79424c9c0dd436bace9e0ed4586a4f32b9"; + let key = "2b7e151628aed2a6abf7158809cf4f3c"; + let iv = "000102030405060708090a0b0c0d0e0f"; + + cipher_test(super::Cipher::aes_128_cfb8(), pt, ct, key, iv); + } + + #[test] + fn test_aes128_ofb() { + // Lifted from http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf + + let pt = "6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411e5fbc1191a0a52eff69f2445df4f9b17ad2b417be66c3710"; + let ct = "3b3fd92eb72dad20333449f8e83cfb4a7789508d16918f03f53c52dac54ed8259740051e9c5fecf64344f7a82260edcc304c6528f659c77866a510d9c1d6ae5e"; + let key = "2b7e151628aed2a6abf7158809cf4f3c"; + let iv = "000102030405060708090a0b0c0d0e0f"; + + cipher_test(super::Cipher::aes_128_ofb(), pt, ct, key, iv); + } + + #[test] + fn test_aes192_ctr() { + // Lifted from http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf + + let pt = "6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411e5fbc1191a0a52eff69f2445df4f9b17ad2b417be66c3710"; + let ct = "1abc932417521ca24f2b0459fe7e6e0b090339ec0aa6faefd5ccc2c6f4ce8e941e36b26bd1ebc670d1bd1d665620abf74f78a7f6d29809585a97daec58c6b050"; + let key = "8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b"; + let iv = "f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff"; + + cipher_test(super::Cipher::aes_192_ctr(), pt, ct, key, iv); + } + + #[test] + #[cfg(not(boringssl))] + fn test_aes192_cfb1() { + // Lifted from http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf + + let pt = "6bc1"; + let ct = "9359"; + let key = "8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b"; + let iv = "000102030405060708090a0b0c0d0e0f"; + + cipher_test(super::Cipher::aes_192_cfb1(), pt, ct, key, iv); + } + + #[test] + #[cfg(not(boringssl))] + fn test_aes192_cfb128() { + // Lifted from http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf + + let pt = "6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411e5fbc1191a0a52eff69f2445df4f9b17ad2b417be66c3710"; + let ct = "cdc80d6fddf18cab34c25909c99a417467ce7f7f81173621961a2b70171d3d7a2e1e8a1dd59b88b1c8e60fed1efac4c9c05f9f9ca9834fa042ae8fba584b09ff"; + let key = "8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b"; + let iv = "000102030405060708090a0b0c0d0e0f"; + + cipher_test(super::Cipher::aes_192_cfb128(), pt, ct, key, iv); + } + + #[test] + #[cfg(not(boringssl))] + fn test_aes192_cfb8() { + // Lifted from http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf + + let pt = "6bc1bee22e409f96e93d7e117393172aae2d"; + let ct = "cda2521ef0a905ca44cd057cbf0d47a0678a"; + let key = "8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b"; + let iv = "000102030405060708090a0b0c0d0e0f"; + + cipher_test(super::Cipher::aes_192_cfb8(), pt, ct, key, iv); + } + + #[test] + fn test_aes192_ofb() { + // Lifted from http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf + + let pt = "6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411e5fbc1191a0a52eff69f2445df4f9b17ad2b417be66c3710"; + let ct = "cdc80d6fddf18cab34c25909c99a4174fcc28b8d4c63837c09e81700c11004018d9a9aeac0f6596f559c6d4daf59a5f26d9f200857ca6c3e9cac524bd9acc92a"; + let key = "8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b"; + let iv = "000102030405060708090a0b0c0d0e0f"; + + cipher_test(super::Cipher::aes_192_ofb(), pt, ct, key, iv); + } + + #[test] + #[cfg(not(boringssl))] + fn test_aes256_cfb1() { + let pt = "6bc1"; + let ct = "9029"; + let key = "603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4"; + let iv = "000102030405060708090a0b0c0d0e0f"; + + cipher_test(super::Cipher::aes_256_cfb1(), pt, ct, key, iv); + } + + #[test] + #[cfg(not(boringssl))] + fn test_aes256_cfb128() { + let pt = "6bc1bee22e409f96e93d7e117393172a"; + let ct = "dc7e84bfda79164b7ecd8486985d3860"; + let key = "603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4"; + let iv = "000102030405060708090a0b0c0d0e0f"; + + cipher_test(super::Cipher::aes_256_cfb128(), pt, ct, key, iv); + } + + #[test] + #[cfg(not(boringssl))] + fn test_aes256_cfb8() { + let pt = "6bc1bee22e409f96e93d7e117393172aae2d"; + let ct = "dc1f1a8520a64db55fcc8ac554844e889700"; + let key = "603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4"; + let iv = "000102030405060708090a0b0c0d0e0f"; + + cipher_test(super::Cipher::aes_256_cfb8(), pt, ct, key, iv); + } + + #[test] + fn test_aes256_ofb() { + // Lifted from http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf + + let pt = "6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411e5fbc1191a0a52eff69f2445df4f9b17ad2b417be66c3710"; + let ct = "dc7e84bfda79164b7ecd8486985d38604febdc6740d20b3ac88f6ad82a4fb08d71ab47a086e86eedf39d1c5bba97c4080126141d67f37be8538f5a8be740e484"; + let key = "603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4"; + let iv = "000102030405060708090a0b0c0d0e0f"; + + cipher_test(super::Cipher::aes_256_ofb(), pt, ct, key, iv); + } + + #[test] + #[cfg_attr(ossl300, ignore)] + #[cfg(not(boringssl))] + fn test_bf_cbc() { + #[cfg(ossl300)] + let _provider = crate::provider::Provider::try_load(None, "legacy", true).unwrap(); + + // https://www.schneier.com/code/vectors.txt + + let pt = "37363534333231204E6F77206973207468652074696D6520666F722000000000"; + let ct = "6B77B4D63006DEE605B156E27403979358DEB9E7154616D959F1652BD5FF92CC"; + let key = "0123456789ABCDEFF0E1D2C3B4A59687"; + let iv = "FEDCBA9876543210"; + + cipher_test_nopad(super::Cipher::bf_cbc(), pt, ct, key, iv); + } + + #[test] + #[cfg_attr(ossl300, ignore)] + #[cfg(not(boringssl))] + fn test_bf_ecb() { + #[cfg(ossl300)] + let _provider = crate::provider::Provider::try_load(None, "legacy", true).unwrap(); + + let pt = "5CD54CA83DEF57DA"; + let ct = "B1B8CC0B250F09A0"; + let key = "0131D9619DC1376E"; + let iv = "0000000000000000"; + + cipher_test_nopad(super::Cipher::bf_ecb(), pt, ct, key, iv); + } + + #[test] + #[cfg_attr(ossl300, ignore)] + #[cfg(not(boringssl))] + fn test_bf_cfb64() { + #[cfg(ossl300)] + let _provider = crate::provider::Provider::try_load(None, "legacy", true).unwrap(); + + let pt = "37363534333231204E6F77206973207468652074696D6520666F722000"; + let ct = "E73214A2822139CAF26ECF6D2EB9E76E3DA3DE04D1517200519D57A6C3"; + let key = "0123456789ABCDEFF0E1D2C3B4A59687"; + let iv = "FEDCBA9876543210"; + + cipher_test_nopad(super::Cipher::bf_cfb64(), pt, ct, key, iv); + } + + #[test] + #[cfg_attr(ossl300, ignore)] + #[cfg(not(boringssl))] + fn test_bf_ofb() { + #[cfg(ossl300)] + let _provider = crate::provider::Provider::try_load(None, "legacy", true).unwrap(); + + let pt = "37363534333231204E6F77206973207468652074696D6520666F722000"; + let ct = "E73214A2822139CA62B343CC5B65587310DD908D0C241B2263C2CF80DA"; + let key = "0123456789ABCDEFF0E1D2C3B4A59687"; + let iv = "FEDCBA9876543210"; + + cipher_test_nopad(super::Cipher::bf_ofb(), pt, ct, key, iv); + } + + #[test] + fn test_des_cbc() { + #[cfg(ossl300)] + let _provider = crate::provider::Provider::try_load(None, "legacy", true).unwrap(); + + let pt = "54686973206973206120746573742e"; + let ct = "6f2867cfefda048a4046ef7e556c7132"; + let key = "7cb66337f3d3c0fe"; + let iv = "0001020304050607"; + + cipher_test(super::Cipher::des_cbc(), pt, ct, key, iv); + } + + #[test] + fn test_des_ecb() { + #[cfg(ossl300)] + let _provider = crate::provider::Provider::try_load(None, "legacy", true).unwrap(); + + let pt = "54686973206973206120746573742e"; + let ct = "0050ab8aecec758843fe157b4dde938c"; + let key = "7cb66337f3d3c0fe"; + let iv = "0001020304050607"; + + cipher_test(super::Cipher::des_ecb(), pt, ct, key, iv); + } + + #[test] + fn test_des_ede3() { + let pt = "9994f4c69d40ae4f34ff403b5cf39d4c8207ea5d3e19a5fd"; + let ct = "9e5c4297d60582f81071ac8ab7d0698d4c79de8b94c519858207ea5d3e19a5fd"; + let key = "010203040506070801020304050607080102030405060708"; + let iv = "5cc118306dc702e4"; + + cipher_test(super::Cipher::des_ede3(), pt, ct, key, iv); + } + + #[test] + fn test_des_ede3_cbc() { + let pt = "54686973206973206120746573742e"; + let ct = "6f2867cfefda048a4046ef7e556c7132"; + let key = "7cb66337f3d3c0fe7cb66337f3d3c0fe7cb66337f3d3c0fe"; + let iv = "0001020304050607"; + + cipher_test(super::Cipher::des_ede3_cbc(), pt, ct, key, iv); + } + + #[test] + #[cfg(not(boringssl))] + fn test_des_ede3_cfb64() { + let pt = "2b1773784b5889dc788477367daa98ad"; + let ct = "6f2867cfefda048a4046ef7e556c7132"; + let key = "7cb66337f3d3c0fe7cb66337f3d3c0fe7cb66337f3d3c0fe"; + let iv = "0001020304050607"; + + cipher_test(super::Cipher::des_ede3_cfb64(), pt, ct, key, iv); + } + + #[test] + fn test_aes128_gcm() { + let key = "23dc8d23d95b6fd1251741a64f7d4f41"; + let iv = "f416f48ad44d9efa1179e167"; + let pt = "6cb9b71dd0ccd42cdf87e8e396fc581fd8e0d700e360f590593b748e105390de"; + let aad = "45074844c97d515c65bbe37c210a5a4b08c21c588efe5c5f73c4d9c17d34dacddc0bb6a8a53f7bf477b9780c1c2a928660df87016b2873fe876b2b887fb5886bfd63216b7eaecc046372a82c047eb043f0b063226ee52a12c69b"; + let ct = "8ad20486778e87387efb3f2574e509951c0626816722018129e578b2787969d3"; + let tag = "91e1bc09"; + + // this tag is smaller than you'd normally want, but I pulled this test from the part of + // the NIST test vectors that cover 4 byte tags. + let mut actual_tag = [0; 4]; + let out = encrypt_aead( + Cipher::aes_128_gcm(), + &Vec::from_hex(key).unwrap(), + Some(&Vec::from_hex(iv).unwrap()), + &Vec::from_hex(aad).unwrap(), + &Vec::from_hex(pt).unwrap(), + &mut actual_tag, + ) + .unwrap(); + assert_eq!(ct, hex::encode(out)); + assert_eq!(tag, hex::encode(actual_tag)); + + let out = decrypt_aead( + Cipher::aes_128_gcm(), + &Vec::from_hex(key).unwrap(), + Some(&Vec::from_hex(iv).unwrap()), + &Vec::from_hex(aad).unwrap(), + &Vec::from_hex(ct).unwrap(), + &Vec::from_hex(tag).unwrap(), + ) + .unwrap(); + assert_eq!(pt, hex::encode(out)); + } + + #[test] + #[cfg(not(boringssl))] + fn test_aes128_ccm() { + let key = "3ee186594f110fb788a8bf8aa8be5d4a"; + let nonce = "44f705d52acf27b7f17196aa9b"; + let aad = "2c16724296ff85e079627be3053ea95adf35722c21886baba343bd6c79b5cb57"; + + let pt = "d71864877f2578db092daba2d6a1f9f4698a9c356c7830a1"; + let ct = "b4dd74e7a0cc51aea45dfb401a41d5822c96901a83247ea0"; + let tag = "d6965f5aa6e31302a9cc2b36"; + + let mut actual_tag = [0; 12]; + let out = encrypt_aead( + Cipher::aes_128_ccm(), + &Vec::from_hex(key).unwrap(), + Some(&Vec::from_hex(nonce).unwrap()), + &Vec::from_hex(aad).unwrap(), + &Vec::from_hex(pt).unwrap(), + &mut actual_tag, + ) + .unwrap(); + + assert_eq!(ct, hex::encode(out)); + assert_eq!(tag, hex::encode(actual_tag)); + + let out = decrypt_aead( + Cipher::aes_128_ccm(), + &Vec::from_hex(key).unwrap(), + Some(&Vec::from_hex(nonce).unwrap()), + &Vec::from_hex(aad).unwrap(), + &Vec::from_hex(ct).unwrap(), + &Vec::from_hex(tag).unwrap(), + ) + .unwrap(); + assert_eq!(pt, hex::encode(out)); + } + + #[test] + #[cfg(not(boringssl))] + fn test_aes128_ccm_verify_fail() { + let key = "3ee186594f110fb788a8bf8aa8be5d4a"; + let nonce = "44f705d52acf27b7f17196aa9b"; + let aad = "2c16724296ff85e079627be3053ea95adf35722c21886baba343bd6c79b5cb57"; + + let ct = "b4dd74e7a0cc51aea45dfb401a41d5822c96901a83247ea0"; + let tag = "00005f5aa6e31302a9cc2b36"; + + let out = decrypt_aead( + Cipher::aes_128_ccm(), + &Vec::from_hex(key).unwrap(), + Some(&Vec::from_hex(nonce).unwrap()), + &Vec::from_hex(aad).unwrap(), + &Vec::from_hex(ct).unwrap(), + &Vec::from_hex(tag).unwrap(), + ); + assert!(out.is_err()); + } + + #[test] + #[cfg(not(boringssl))] + fn test_aes256_ccm() { + let key = "7f4af6765cad1d511db07e33aaafd57646ec279db629048aa6770af24849aa0d"; + let nonce = "dde2a362ce81b2b6913abc3095"; + let aad = "404f5df97ece7431987bc098cce994fc3c063b519ffa47b0365226a0015ef695"; + + let pt = "7ebef26bf4ecf6f0ebb2eb860edbf900f27b75b4a6340fdb"; + let ct = "353022db9c568bd7183a13c40b1ba30fcc768c54264aa2cd"; + let tag = "2927a053c9244d3217a7ad05"; + + let mut actual_tag = [0; 12]; + let out = encrypt_aead( + Cipher::aes_256_ccm(), + &Vec::from_hex(key).unwrap(), + Some(&Vec::from_hex(nonce).unwrap()), + &Vec::from_hex(aad).unwrap(), + &Vec::from_hex(pt).unwrap(), + &mut actual_tag, + ) + .unwrap(); + + assert_eq!(ct, hex::encode(out)); + assert_eq!(tag, hex::encode(actual_tag)); + + let out = decrypt_aead( + Cipher::aes_256_ccm(), + &Vec::from_hex(key).unwrap(), + Some(&Vec::from_hex(nonce).unwrap()), + &Vec::from_hex(aad).unwrap(), + &Vec::from_hex(ct).unwrap(), + &Vec::from_hex(tag).unwrap(), + ) + .unwrap(); + assert_eq!(pt, hex::encode(out)); + } + + #[test] + #[cfg(not(boringssl))] + fn test_aes256_ccm_verify_fail() { + let key = "7f4af6765cad1d511db07e33aaafd57646ec279db629048aa6770af24849aa0d"; + let nonce = "dde2a362ce81b2b6913abc3095"; + let aad = "404f5df97ece7431987bc098cce994fc3c063b519ffa47b0365226a0015ef695"; + + let ct = "353022db9c568bd7183a13c40b1ba30fcc768c54264aa2cd"; + let tag = "0000a053c9244d3217a7ad05"; + + let out = decrypt_aead( + Cipher::aes_256_ccm(), + &Vec::from_hex(key).unwrap(), + Some(&Vec::from_hex(nonce).unwrap()), + &Vec::from_hex(aad).unwrap(), + &Vec::from_hex(ct).unwrap(), + &Vec::from_hex(tag).unwrap(), + ); + assert!(out.is_err()); + } + + #[test] + #[cfg(all(ossl110, not(osslconf = "OPENSSL_NO_OCB")))] + fn test_aes_128_ocb() { + let key = "000102030405060708090a0b0c0d0e0f"; + let aad = "0001020304050607"; + let tag = "16dc76a46d47e1ead537209e8a96d14e"; + let iv = "000102030405060708090a0b"; + let pt = "0001020304050607"; + let ct = "92b657130a74b85a"; + + let mut actual_tag = [0; 16]; + let out = encrypt_aead( + Cipher::aes_128_ocb(), + &Vec::from_hex(key).unwrap(), + Some(&Vec::from_hex(iv).unwrap()), + &Vec::from_hex(aad).unwrap(), + &Vec::from_hex(pt).unwrap(), + &mut actual_tag, + ) + .unwrap(); + + assert_eq!(ct, hex::encode(out)); + assert_eq!(tag, hex::encode(actual_tag)); + + let out = decrypt_aead( + Cipher::aes_128_ocb(), + &Vec::from_hex(key).unwrap(), + Some(&Vec::from_hex(iv).unwrap()), + &Vec::from_hex(aad).unwrap(), + &Vec::from_hex(ct).unwrap(), + &Vec::from_hex(tag).unwrap(), + ) + .unwrap(); + assert_eq!(pt, hex::encode(out)); + } + + #[test] + #[cfg(all(ossl110, not(osslconf = "OPENSSL_NO_OCB")))] + fn test_aes_128_ocb_fail() { + let key = "000102030405060708090a0b0c0d0e0f"; + let aad = "0001020304050607"; + let tag = "16dc76a46d47e1ead537209e8a96d14e"; + let iv = "000000000405060708090a0b"; + let ct = "92b657130a74b85a"; + + let out = decrypt_aead( + Cipher::aes_128_ocb(), + &Vec::from_hex(key).unwrap(), + Some(&Vec::from_hex(iv).unwrap()), + &Vec::from_hex(aad).unwrap(), + &Vec::from_hex(ct).unwrap(), + &Vec::from_hex(tag).unwrap(), + ); + assert!(out.is_err()); + } + + #[test] + #[cfg(any(ossl110, libressl310))] + fn test_chacha20() { + let key = "0000000000000000000000000000000000000000000000000000000000000000"; + let iv = "00000000000000000000000000000000"; + let pt = + "000000000000000000000000000000000000000000000000000000000000000000000000000000000\ + 00000000000000000000000000000000000000000000000"; + let ct = + "76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7da41597c5157488d7\ + 724e03fb8d84a376a43b8f41518a11cc387b669b2ee6586"; + + cipher_test(Cipher::chacha20(), pt, ct, key, iv); + } + + #[test] + #[cfg(any(ossl110, libressl360))] + fn test_chacha20_poly1305() { + let key = "808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f"; + let iv = "070000004041424344454647"; + let aad = "50515253c0c1c2c3c4c5c6c7"; + let pt = + "4c616469657320616e642047656e746c656d656e206f662074686520636c617373206f66202739393\ + a204966204920636f756c64206f6666657220796f75206f6e6c79206f6e652074697020666f722074\ + 6865206675747572652c2073756e73637265656e20776f756c642062652069742e"; + let ct = + "d31a8d34648e60db7b86afbc53ef7ec2a4aded51296e08fea9e2b5a736ee62d63dbea45e8ca967128\ + 2fafb69da92728b1a71de0a9e060b2905d6a5b67ecd3b3692ddbd7f2d778b8c9803aee328091b58fa\ + b324e4fad675945585808b4831d7bc3ff4def08e4b7a9de576d26586cec64b6116"; + let tag = "1ae10b594f09e26a7e902ecbd0600691"; + + let mut actual_tag = [0; 16]; + let out = encrypt_aead( + Cipher::chacha20_poly1305(), + &Vec::from_hex(key).unwrap(), + Some(&Vec::from_hex(iv).unwrap()), + &Vec::from_hex(aad).unwrap(), + &Vec::from_hex(pt).unwrap(), + &mut actual_tag, + ) + .unwrap(); + assert_eq!(ct, hex::encode(out)); + assert_eq!(tag, hex::encode(actual_tag)); + + let out = decrypt_aead( + Cipher::chacha20_poly1305(), + &Vec::from_hex(key).unwrap(), + Some(&Vec::from_hex(iv).unwrap()), + &Vec::from_hex(aad).unwrap(), + &Vec::from_hex(ct).unwrap(), + &Vec::from_hex(tag).unwrap(), + ) + .unwrap(); + assert_eq!(pt, hex::encode(out)); + } + + #[test] + #[cfg(not(any(osslconf = "OPENSSL_NO_SEED", ossl300)))] + fn test_seed_cbc() { + #[cfg(ossl300)] + let _provider = crate::provider::Provider::try_load(None, "legacy", true).unwrap(); + + let pt = "5363686f6b6f6c6164656e6b756368656e0a"; + let ct = "c2edf0fb2eb11bf7b2f39417a8528896d34b24b6fd79e5923b116dfcd2aba5a4"; + let key = "41414141414141414141414141414141"; + let iv = "41414141414141414141414141414141"; + + cipher_test(super::Cipher::seed_cbc(), pt, ct, key, iv); + } + + #[test] + #[cfg(not(any(osslconf = "OPENSSL_NO_SEED", ossl300)))] + fn test_seed_cfb128() { + #[cfg(ossl300)] + let _provider = crate::provider::Provider::try_load(None, "legacy", true).unwrap(); + + let pt = "5363686f6b6f6c6164656e6b756368656e0a"; + let ct = "71d4d25fc1750cb7789259e7f34061939a41"; + let key = "41414141414141414141414141414141"; + let iv = "41414141414141414141414141414141"; + + cipher_test(super::Cipher::seed_cfb128(), pt, ct, key, iv); + } + + #[test] + #[cfg(not(any(osslconf = "OPENSSL_NO_SEED", ossl300)))] + fn test_seed_ecb() { + #[cfg(ossl300)] + let _provider = crate::provider::Provider::try_load(None, "legacy", true).unwrap(); + + let pt = "5363686f6b6f6c6164656e6b756368656e0a"; + let ct = "0263a9cd498cf0edb0ef72a3231761d00ce601f7d08ad19ad74f0815f2c77f7e"; + let key = "41414141414141414141414141414141"; + let iv = "41414141414141414141414141414141"; + + cipher_test(super::Cipher::seed_ecb(), pt, ct, key, iv); + } + + #[test] + #[cfg(not(any(osslconf = "OPENSSL_NO_SEED", ossl300)))] + fn test_seed_ofb() { + #[cfg(ossl300)] + let _provider = crate::provider::Provider::try_load(None, "legacy", true).unwrap(); + + let pt = "5363686f6b6f6c6164656e6b756368656e0a"; + let ct = "71d4d25fc1750cb7789259e7f34061930afd"; + let key = "41414141414141414141414141414141"; + let iv = "41414141414141414141414141414141"; + + cipher_test(super::Cipher::seed_ofb(), pt, ct, key, iv); + } + + // GB/T 32907-2016 + // http://openstd.samr.gov.cn/bzgk/gb/newGbInfo?hcno=7803DE42D3BC5E80B0C3E5D8E873D56A + #[test] + #[cfg(all(any(ossl111, libressl291), not(osslconf = "OPENSSL_NO_SM4")))] + fn test_sm4_ecb() { + use std::mem; + + let key = vec![ + 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, + 0x32, 0x10, + ]; + let pt = vec![ + 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, + 0x32, 0x10, + ]; + let ct = vec![ + 0x68, 0x1e, 0xdf, 0x34, 0xd2, 0x06, 0x96, 0x5e, 0x86, 0xb3, 0xe9, 0x4f, 0x53, 0x6e, + 0x42, 0x46, + ]; + let ct1 = vec![ + 0x59, 0x52, 0x98, 0xc7, 0xc6, 0xfd, 0x27, 0x1f, 0x04, 0x02, 0xf8, 0x04, 0xc3, 0x3d, + 0x3f, 0x66, + ]; + + let block_size = Cipher::sm4_ecb().block_size(); + let mut c = Crypter::new(Cipher::sm4_ecb(), Mode::Encrypt, &key, None).unwrap(); + c.pad(false); + + // 1 round + let mut r = vec![0; pt.len() + Cipher::sm4_ecb().block_size()]; + let count = c.update(&pt, &mut r).unwrap(); + assert_eq!(ct, &r[..count]); + + // 1000000 rounds + let mut r1 = vec![0; pt.len() + Cipher::sm4_ecb().block_size()]; + for _ in 0..999999 { + c.update(&r[..block_size], &mut r1).unwrap(); + mem::swap(&mut r, &mut r1); + } + assert_eq!(ct1, &r[..count]); + } +} diff --git a/vendor/openssl/src/util.rs b/vendor/openssl/src/util.rs new file mode 100644 index 0000000..c903a32 --- /dev/null +++ b/vendor/openssl/src/util.rs @@ -0,0 +1,118 @@ +use crate::error::ErrorStack; +use crate::util; +use foreign_types::{ForeignType, ForeignTypeRef}; +use libc::{c_char, c_int, c_void}; +use std::any::Any; +use std::panic::{self, AssertUnwindSafe}; +use std::slice; + +/// Wraps a user-supplied callback and a slot for panics thrown inside the callback (while FFI +/// frames are on the stack). +/// +/// When dropped, checks if the callback has panicked, and resumes unwinding if so. +pub struct CallbackState { + /// The user callback. Taken out of the `Option` when called. + cb: Option, + /// If the callback panics, we place the panic object here, to be re-thrown once OpenSSL + /// returns. + panic: Option>, +} + +impl CallbackState { + pub fn new(callback: F) -> Self { + CallbackState { + cb: Some(callback), + panic: None, + } + } +} + +impl Drop for CallbackState { + fn drop(&mut self) { + if let Some(panic) = self.panic.take() { + panic::resume_unwind(panic); + } + } +} + +/// Password callback function, passed to private key loading functions. +/// +/// `cb_state` is expected to be a pointer to a `CallbackState`. +pub unsafe extern "C" fn invoke_passwd_cb( + buf: *mut c_char, + size: c_int, + _rwflag: c_int, + cb_state: *mut c_void, +) -> c_int +where + F: FnOnce(&mut [u8]) -> Result, +{ + let callback = &mut *(cb_state as *mut CallbackState); + + let result = panic::catch_unwind(AssertUnwindSafe(|| { + let pass_slice = util::from_raw_parts_mut(buf as *mut u8, size as usize); + callback.cb.take().unwrap()(pass_slice) + })); + + match result { + Ok(Ok(len)) => len as c_int, + Ok(Err(_)) => { + // FIXME restore error stack + 0 + } + Err(err) => { + callback.panic = Some(err); + 0 + } + } +} + +pub trait ForeignTypeExt: ForeignType { + unsafe fn from_ptr_opt(ptr: *mut Self::CType) -> Option { + if ptr.is_null() { + None + } else { + Some(Self::from_ptr(ptr)) + } + } +} +impl ForeignTypeExt for FT {} + +pub trait ForeignTypeRefExt: ForeignTypeRef { + unsafe fn from_const_ptr<'a>(ptr: *const Self::CType) -> &'a Self { + Self::from_ptr(ptr as *mut Self::CType) + } + + unsafe fn from_const_ptr_opt<'a>(ptr: *const Self::CType) -> Option<&'a Self> { + if ptr.is_null() { + None + } else { + Some(Self::from_const_ptr(ptr as *mut Self::CType)) + } + } +} +impl ForeignTypeRefExt for FT {} + +/// The same as `slice::from_raw_parts`, except that `data` may be `NULL` if +/// `len` is 0. +pub unsafe fn from_raw_parts<'a, T>(data: *const T, len: usize) -> &'a [T] { + if len == 0 { + &[] + } else { + // Using this to implement the preferred API + #[allow(clippy::disallowed_methods)] + slice::from_raw_parts(data, len) + } +} + +/// The same as `slice::from_raw_parts_mut`, except that `data` may be `NULL` +/// if `len` is 0. +pub unsafe fn from_raw_parts_mut<'a, T>(data: *mut T, len: usize) -> &'a mut [T] { + if len == 0 { + &mut [] + } else { + // Using this to implement the preferred API + #[allow(clippy::disallowed_methods)] + slice::from_raw_parts_mut(data, len) + } +} diff --git a/vendor/openssl/src/version.rs b/vendor/openssl/src/version.rs new file mode 100644 index 0000000..12ab3d8 --- /dev/null +++ b/vendor/openssl/src/version.rs @@ -0,0 +1,134 @@ +// 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. +// + +//! Build and version information. + +use cfg_if::cfg_if; +use openssl_macros::corresponds; +use std::ffi::CStr; + +cfg_if! { + if #[cfg(any(ossl110, libressl271))] { + use ffi::{ + OPENSSL_VERSION, OPENSSL_CFLAGS, OPENSSL_BUILT_ON, OPENSSL_PLATFORM, OPENSSL_DIR, + OpenSSL_version_num, OpenSSL_version, + }; + } else { + use ffi::{ + SSLEAY_VERSION as OPENSSL_VERSION, SSLEAY_CFLAGS as OPENSSL_CFLAGS, + SSLEAY_BUILT_ON as OPENSSL_BUILT_ON, SSLEAY_PLATFORM as OPENSSL_PLATFORM, + SSLEAY_DIR as OPENSSL_DIR, SSLeay as OpenSSL_version_num, + SSLeay_version as OpenSSL_version, + }; + } +} + +/// OPENSSL_VERSION_NUMBER is a numeric release version identifier: +/// +/// `MNNFFPPS: major minor fix patch status` +/// +/// The status nibble has one of the values 0 for development, 1 to e for betas 1 to 14, and f for release. +/// +/// for example +/// +/// `0x000906000 == 0.9.6 dev` +/// `0x000906023 == 0.9.6b beta 3` +/// `0x00090605f == 0.9.6e release` +#[corresponds(OpenSSL_version_num)] +pub fn number() -> i64 { + unsafe { OpenSSL_version_num() as i64 } +} + +/// The text variant of the version number and the release date. For example, "OpenSSL 0.9.5a 1 Apr 2000". +#[corresponds(OpenSSL_version)] +pub fn version() -> &'static str { + unsafe { + CStr::from_ptr(OpenSSL_version(OPENSSL_VERSION)) + .to_str() + .unwrap() + } +} + +/// The compiler flags set for the compilation process in the form "compiler: ..." if available or +/// "compiler: information not available" otherwise. +#[corresponds(OpenSSL_version)] +pub fn c_flags() -> &'static str { + unsafe { + CStr::from_ptr(OpenSSL_version(OPENSSL_CFLAGS)) + .to_str() + .unwrap() + } +} + +/// The date of the build process in the form "built on: ..." if available or "built on: date not available" otherwise. +#[corresponds(OpenSSL_version)] +pub fn built_on() -> &'static str { + unsafe { + CStr::from_ptr(OpenSSL_version(OPENSSL_BUILT_ON)) + .to_str() + .unwrap() + } +} + +/// The "Configure" target of the library build in the form "platform: ..." if available or "platform: information not available" otherwise. +#[corresponds(OpenSSL_version)] +pub fn platform() -> &'static str { + unsafe { + CStr::from_ptr(OpenSSL_version(OPENSSL_PLATFORM)) + .to_str() + .unwrap() + } +} + +/// The "OPENSSLDIR" setting of the library build in the form "OPENSSLDIR: "..."" if available or "OPENSSLDIR: N/A" otherwise. +#[corresponds(OpenSSL_version)] +pub fn dir() -> &'static str { + unsafe { + CStr::from_ptr(OpenSSL_version(OPENSSL_DIR)) + .to_str() + .unwrap() + } +} + +/// This test ensures that we do not segfault when calling the functions of this module +/// and that the strings respect a reasonable format. +#[test] +fn test_versions() { + println!("Number: '{}'", number()); + println!("Version: '{}'", version()); + println!("C flags: '{}'", c_flags()); + println!("Built on: '{}'", built_on()); + println!("Platform: '{}'", platform()); + println!("Dir: '{}'", dir()); + + #[cfg(not(any(libressl, boringssl)))] + fn expected_name() -> &'static str { + "OpenSSL" + } + #[cfg(libressl)] + fn expected_name() -> &'static str { + "LibreSSL" + } + #[cfg(boringssl)] + fn expected_name() -> &'static str { + "BoringSSL" + } + + assert!(number() > 0); + assert!(version().starts_with(expected_name())); + assert!(c_flags().starts_with("compiler:")); + // some distributions patch out dates out of openssl so that the builds are reproducible + if !built_on().is_empty() { + assert!(built_on().starts_with("built on:")); + } +} diff --git a/vendor/openssl/src/x509/extension.rs b/vendor/openssl/src/x509/extension.rs new file mode 100644 index 0000000..11e0151 --- /dev/null +++ b/vendor/openssl/src/x509/extension.rs @@ -0,0 +1,562 @@ +//! Add extensions to an `X509` certificate or certificate request. +//! +//! The extensions defined for X.509 v3 certificates provide methods for +//! associating additional attributes with users or public keys and for +//! managing relationships between CAs. The extensions created using this +//! module can be used with `X509v3Context` objects. +//! +//! # Example +//! +//! ```rust +//! use openssl::x509::extension::BasicConstraints; +//! use openssl::x509::X509Extension; +//! +//! let mut bc = BasicConstraints::new(); +//! let bc = bc.critical().ca().pathlen(1); +//! +//! let extension: X509Extension = bc.build().unwrap(); +//! ``` +use std::fmt::Write; + +use crate::asn1::Asn1Object; +use crate::error::ErrorStack; +use crate::nid::Nid; +use crate::x509::{GeneralName, Stack, X509Extension, X509v3Context}; +use foreign_types::ForeignType; + +/// An extension which indicates whether a certificate is a CA certificate. +pub struct BasicConstraints { + critical: bool, + ca: bool, + pathlen: Option, +} + +impl Default for BasicConstraints { + fn default() -> BasicConstraints { + BasicConstraints::new() + } +} + +impl BasicConstraints { + /// Construct a new `BasicConstraints` extension. + pub fn new() -> BasicConstraints { + BasicConstraints { + critical: false, + ca: false, + pathlen: None, + } + } + + /// Sets the `critical` flag to `true`. The extension will be critical. + pub fn critical(&mut self) -> &mut BasicConstraints { + self.critical = true; + self + } + + /// Sets the `ca` flag to `true`. + pub fn ca(&mut self) -> &mut BasicConstraints { + self.ca = true; + self + } + + /// Sets the `pathlen` to an optional non-negative value. The `pathlen` is the + /// maximum number of CAs that can appear below this one in a chain. + pub fn pathlen(&mut self, pathlen: u32) -> &mut BasicConstraints { + self.pathlen = Some(pathlen); + self + } + + /// Return the `BasicConstraints` extension as an `X509Extension`. + // Temporarily silence the deprecation warning - this should be ported to + // `X509Extension::new_internal`. + #[allow(deprecated)] + pub fn build(&self) -> Result { + let mut value = String::new(); + if self.critical { + value.push_str("critical,"); + } + value.push_str("CA:"); + if self.ca { + value.push_str("TRUE"); + } else { + value.push_str("FALSE"); + } + if let Some(pathlen) = self.pathlen { + write!(value, ",pathlen:{}", pathlen).unwrap(); + } + X509Extension::new_nid(None, None, Nid::BASIC_CONSTRAINTS, &value) + } +} + +/// An extension consisting of a list of names of the permitted key usages. +pub struct KeyUsage { + critical: bool, + digital_signature: bool, + non_repudiation: bool, + key_encipherment: bool, + data_encipherment: bool, + key_agreement: bool, + key_cert_sign: bool, + crl_sign: bool, + encipher_only: bool, + decipher_only: bool, +} + +impl Default for KeyUsage { + fn default() -> KeyUsage { + KeyUsage::new() + } +} + +impl KeyUsage { + /// Construct a new `KeyUsage` extension. + pub fn new() -> KeyUsage { + KeyUsage { + critical: false, + digital_signature: false, + non_repudiation: false, + key_encipherment: false, + data_encipherment: false, + key_agreement: false, + key_cert_sign: false, + crl_sign: false, + encipher_only: false, + decipher_only: false, + } + } + + /// Sets the `critical` flag to `true`. The extension will be critical. + pub fn critical(&mut self) -> &mut KeyUsage { + self.critical = true; + self + } + + /// Sets the `digitalSignature` flag to `true`. + pub fn digital_signature(&mut self) -> &mut KeyUsage { + self.digital_signature = true; + self + } + + /// Sets the `nonRepudiation` flag to `true`. + pub fn non_repudiation(&mut self) -> &mut KeyUsage { + self.non_repudiation = true; + self + } + + /// Sets the `keyEncipherment` flag to `true`. + pub fn key_encipherment(&mut self) -> &mut KeyUsage { + self.key_encipherment = true; + self + } + + /// Sets the `dataEncipherment` flag to `true`. + pub fn data_encipherment(&mut self) -> &mut KeyUsage { + self.data_encipherment = true; + self + } + + /// Sets the `keyAgreement` flag to `true`. + pub fn key_agreement(&mut self) -> &mut KeyUsage { + self.key_agreement = true; + self + } + + /// Sets the `keyCertSign` flag to `true`. + pub fn key_cert_sign(&mut self) -> &mut KeyUsage { + self.key_cert_sign = true; + self + } + + /// Sets the `cRLSign` flag to `true`. + pub fn crl_sign(&mut self) -> &mut KeyUsage { + self.crl_sign = true; + self + } + + /// Sets the `encipherOnly` flag to `true`. + pub fn encipher_only(&mut self) -> &mut KeyUsage { + self.encipher_only = true; + self + } + + /// Sets the `decipherOnly` flag to `true`. + pub fn decipher_only(&mut self) -> &mut KeyUsage { + self.decipher_only = true; + self + } + + /// Return the `KeyUsage` extension as an `X509Extension`. + // Temporarily silence the deprecation warning - this should be ported to + // `X509Extension::new_internal`. + #[allow(deprecated)] + pub fn build(&self) -> Result { + let mut value = String::new(); + let mut first = true; + append(&mut value, &mut first, self.critical, "critical"); + append( + &mut value, + &mut first, + self.digital_signature, + "digitalSignature", + ); + append( + &mut value, + &mut first, + self.non_repudiation, + "nonRepudiation", + ); + append( + &mut value, + &mut first, + self.key_encipherment, + "keyEncipherment", + ); + append( + &mut value, + &mut first, + self.data_encipherment, + "dataEncipherment", + ); + append(&mut value, &mut first, self.key_agreement, "keyAgreement"); + append(&mut value, &mut first, self.key_cert_sign, "keyCertSign"); + append(&mut value, &mut first, self.crl_sign, "cRLSign"); + append(&mut value, &mut first, self.encipher_only, "encipherOnly"); + append(&mut value, &mut first, self.decipher_only, "decipherOnly"); + X509Extension::new_nid(None, None, Nid::KEY_USAGE, &value) + } +} + +/// An extension consisting of a list of usages indicating purposes +/// for which the certificate public key can be used for. +pub struct ExtendedKeyUsage { + critical: bool, + items: Vec, +} + +impl Default for ExtendedKeyUsage { + fn default() -> ExtendedKeyUsage { + ExtendedKeyUsage::new() + } +} + +impl ExtendedKeyUsage { + /// Construct a new `ExtendedKeyUsage` extension. + pub fn new() -> ExtendedKeyUsage { + ExtendedKeyUsage { + critical: false, + items: vec![], + } + } + + /// Sets the `critical` flag to `true`. The extension will be critical. + pub fn critical(&mut self) -> &mut ExtendedKeyUsage { + self.critical = true; + self + } + + /// Sets the `serverAuth` flag to `true`. + pub fn server_auth(&mut self) -> &mut ExtendedKeyUsage { + self.other("serverAuth") + } + + /// Sets the `clientAuth` flag to `true`. + pub fn client_auth(&mut self) -> &mut ExtendedKeyUsage { + self.other("clientAuth") + } + + /// Sets the `codeSigning` flag to `true`. + pub fn code_signing(&mut self) -> &mut ExtendedKeyUsage { + self.other("codeSigning") + } + + /// Sets the `emailProtection` flag to `true`. + pub fn email_protection(&mut self) -> &mut ExtendedKeyUsage { + self.other("emailProtection") + } + + /// Sets the `timeStamping` flag to `true`. + pub fn time_stamping(&mut self) -> &mut ExtendedKeyUsage { + self.other("timeStamping") + } + + /// Sets the `msCodeInd` flag to `true`. + pub fn ms_code_ind(&mut self) -> &mut ExtendedKeyUsage { + self.other("msCodeInd") + } + + /// Sets the `msCodeCom` flag to `true`. + pub fn ms_code_com(&mut self) -> &mut ExtendedKeyUsage { + self.other("msCodeCom") + } + + /// Sets the `msCTLSign` flag to `true`. + pub fn ms_ctl_sign(&mut self) -> &mut ExtendedKeyUsage { + self.other("msCTLSign") + } + + /// Sets the `msSGC` flag to `true`. + pub fn ms_sgc(&mut self) -> &mut ExtendedKeyUsage { + self.other("msSGC") + } + + /// Sets the `msEFS` flag to `true`. + pub fn ms_efs(&mut self) -> &mut ExtendedKeyUsage { + self.other("msEFS") + } + + /// Sets the `nsSGC` flag to `true`. + pub fn ns_sgc(&mut self) -> &mut ExtendedKeyUsage { + self.other("nsSGC") + } + + /// Sets a flag not already defined. + pub fn other(&mut self, other: &str) -> &mut ExtendedKeyUsage { + self.items.push(other.to_string()); + self + } + + /// Return the `ExtendedKeyUsage` extension as an `X509Extension`. + pub fn build(&self) -> Result { + let mut stack = Stack::new()?; + for item in &self.items { + stack.push(Asn1Object::from_str(item)?)?; + } + unsafe { + X509Extension::new_internal(Nid::EXT_KEY_USAGE, self.critical, stack.as_ptr().cast()) + } + } +} + +/// An extension that provides a means of identifying certificates that contain a +/// particular public key. +pub struct SubjectKeyIdentifier { + critical: bool, +} + +impl Default for SubjectKeyIdentifier { + fn default() -> SubjectKeyIdentifier { + SubjectKeyIdentifier::new() + } +} + +impl SubjectKeyIdentifier { + /// Construct a new `SubjectKeyIdentifier` extension. + pub fn new() -> SubjectKeyIdentifier { + SubjectKeyIdentifier { critical: false } + } + + /// Sets the `critical` flag to `true`. The extension will be critical. + pub fn critical(&mut self) -> &mut SubjectKeyIdentifier { + self.critical = true; + self + } + + /// Return a `SubjectKeyIdentifier` extension as an `X509Extension`. + // Temporarily silence the deprecation warning - this should be ported to + // `X509Extension::new_internal`. + #[allow(deprecated)] + pub fn build(&self, ctx: &X509v3Context<'_>) -> Result { + let mut value = String::new(); + let mut first = true; + append(&mut value, &mut first, self.critical, "critical"); + append(&mut value, &mut first, true, "hash"); + X509Extension::new_nid(None, Some(ctx), Nid::SUBJECT_KEY_IDENTIFIER, &value) + } +} + +/// An extension that provides a means of identifying the public key corresponding +/// to the private key used to sign a CRL. +pub struct AuthorityKeyIdentifier { + critical: bool, + keyid: Option, + issuer: Option, +} + +impl Default for AuthorityKeyIdentifier { + fn default() -> AuthorityKeyIdentifier { + AuthorityKeyIdentifier::new() + } +} + +impl AuthorityKeyIdentifier { + /// Construct a new `AuthorityKeyIdentifier` extension. + pub fn new() -> AuthorityKeyIdentifier { + AuthorityKeyIdentifier { + critical: false, + keyid: None, + issuer: None, + } + } + + /// Sets the `critical` flag to `true`. The extension will be critical. + pub fn critical(&mut self) -> &mut AuthorityKeyIdentifier { + self.critical = true; + self + } + + /// Sets the `keyid` flag. + pub fn keyid(&mut self, always: bool) -> &mut AuthorityKeyIdentifier { + self.keyid = Some(always); + self + } + + /// Sets the `issuer` flag. + pub fn issuer(&mut self, always: bool) -> &mut AuthorityKeyIdentifier { + self.issuer = Some(always); + self + } + + /// Return a `AuthorityKeyIdentifier` extension as an `X509Extension`. + // Temporarily silence the deprecation warning - this should be ported to + // `X509Extension::new_internal`. + #[allow(deprecated)] + pub fn build(&self, ctx: &X509v3Context<'_>) -> Result { + let mut value = String::new(); + let mut first = true; + append(&mut value, &mut first, self.critical, "critical"); + match self.keyid { + Some(true) => append(&mut value, &mut first, true, "keyid:always"), + Some(false) => append(&mut value, &mut first, true, "keyid"), + None => {} + } + match self.issuer { + Some(true) => append(&mut value, &mut first, true, "issuer:always"), + Some(false) => append(&mut value, &mut first, true, "issuer"), + None => {} + } + X509Extension::new_nid(None, Some(ctx), Nid::AUTHORITY_KEY_IDENTIFIER, &value) + } +} + +enum RustGeneralName { + Dns(String), + Email(String), + Uri(String), + Ip(String), + Rid(String), + OtherName(Asn1Object, Vec), +} + +/// An extension that allows additional identities to be bound to the subject +/// of the certificate. +pub struct SubjectAlternativeName { + critical: bool, + items: Vec, +} + +impl Default for SubjectAlternativeName { + fn default() -> SubjectAlternativeName { + SubjectAlternativeName::new() + } +} + +impl SubjectAlternativeName { + /// Construct a new `SubjectAlternativeName` extension. + pub fn new() -> SubjectAlternativeName { + SubjectAlternativeName { + critical: false, + items: vec![], + } + } + + /// Sets the `critical` flag to `true`. The extension will be critical. + pub fn critical(&mut self) -> &mut SubjectAlternativeName { + self.critical = true; + self + } + + /// Sets the `email` flag. + pub fn email(&mut self, email: &str) -> &mut SubjectAlternativeName { + self.items.push(RustGeneralName::Email(email.to_string())); + self + } + + /// Sets the `uri` flag. + pub fn uri(&mut self, uri: &str) -> &mut SubjectAlternativeName { + self.items.push(RustGeneralName::Uri(uri.to_string())); + self + } + + /// Sets the `dns` flag. + pub fn dns(&mut self, dns: &str) -> &mut SubjectAlternativeName { + self.items.push(RustGeneralName::Dns(dns.to_string())); + self + } + + /// Sets the `rid` flag. + pub fn rid(&mut self, rid: &str) -> &mut SubjectAlternativeName { + self.items.push(RustGeneralName::Rid(rid.to_string())); + self + } + + /// Sets the `ip` flag. + pub fn ip(&mut self, ip: &str) -> &mut SubjectAlternativeName { + self.items.push(RustGeneralName::Ip(ip.to_string())); + self + } + + /// Sets the `dirName` flag. + /// + /// Not currently actually supported, always panics. + #[deprecated = "dir_name is deprecated and always panics. Please file a bug if you have a use case for this."] + pub fn dir_name(&mut self, _dir_name: &str) -> &mut SubjectAlternativeName { + unimplemented!( + "This has not yet been adapted for the new internals. File a bug if you need this." + ); + } + + /// Sets the `otherName` flag. + /// + /// Not currently actually supported, always panics. Please use other_name2 + #[deprecated = "other_name is deprecated and always panics. Please use other_name2."] + pub fn other_name(&mut self, _other_name: &str) -> &mut SubjectAlternativeName { + unimplemented!("This has not yet been adapted for the new internals. Use other_name2."); + } + + /// Sets the `otherName` flag. + /// + /// `content` must be a valid der encoded ASN1_TYPE + /// + /// If you want to add just a ia5string use `other_name_ia5string` + pub fn other_name2(&mut self, oid: Asn1Object, content: &[u8]) -> &mut SubjectAlternativeName { + self.items + .push(RustGeneralName::OtherName(oid, content.into())); + self + } + + /// Return a `SubjectAlternativeName` extension as an `X509Extension`. + pub fn build(&self, _ctx: &X509v3Context<'_>) -> Result { + let mut stack = Stack::new()?; + for item in &self.items { + let gn = match item { + RustGeneralName::Dns(s) => GeneralName::new_dns(s.as_bytes())?, + RustGeneralName::Email(s) => GeneralName::new_email(s.as_bytes())?, + RustGeneralName::Uri(s) => GeneralName::new_uri(s.as_bytes())?, + RustGeneralName::Ip(s) => { + GeneralName::new_ip(s.parse().map_err(|_| ErrorStack::get())?)? + } + RustGeneralName::Rid(s) => GeneralName::new_rid(Asn1Object::from_str(s)?)?, + RustGeneralName::OtherName(oid, content) => { + GeneralName::new_other_name(oid.clone(), content)? + } + }; + stack.push(gn)?; + } + + unsafe { + X509Extension::new_internal(Nid::SUBJECT_ALT_NAME, self.critical, stack.as_ptr().cast()) + } + } +} + +fn append(value: &mut String, first: &mut bool, should: bool, element: &str) { + if !should { + return; + } + + if !*first { + value.push(','); + } + *first = false; + value.push_str(element); +} diff --git a/vendor/openssl/src/x509/mod.rs b/vendor/openssl/src/x509/mod.rs new file mode 100644 index 0000000..67c86ee --- /dev/null +++ b/vendor/openssl/src/x509/mod.rs @@ -0,0 +1,2546 @@ +//! The standard defining the format of public key certificates. +//! +//! An `X509` certificate binds an identity to a public key, and is either +//! signed by a certificate authority (CA) or self-signed. An entity that gets +//! a hold of a certificate can both verify your identity (via a CA) and encrypt +//! data with the included public key. `X509` certificates are used in many +//! Internet protocols, including SSL/TLS, which is the basis for HTTPS, +//! the secure protocol for browsing the web. + +use cfg_if::cfg_if; +use foreign_types::{ForeignType, ForeignTypeRef, Opaque}; +use libc::{c_int, c_long, c_uint, c_void}; +use std::cmp::{self, Ordering}; +use std::convert::{TryFrom, TryInto}; +use std::error::Error; +use std::ffi::{CStr, CString}; +use std::fmt; +use std::marker::PhantomData; +use std::mem; +use std::net::IpAddr; +use std::path::Path; +use std::ptr; +use std::str; + +use crate::asn1::{ + Asn1BitStringRef, Asn1Enumerated, Asn1IntegerRef, Asn1Object, Asn1ObjectRef, + Asn1OctetStringRef, Asn1StringRef, Asn1TimeRef, Asn1Type, +}; +use crate::bio::MemBioSlice; +use crate::conf::ConfRef; +use crate::error::ErrorStack; +use crate::ex_data::Index; +use crate::hash::{DigestBytes, MessageDigest}; +use crate::nid::Nid; +use crate::pkey::{HasPrivate, HasPublic, PKey, PKeyRef, Public}; +use crate::ssl::SslRef; +use crate::stack::{Stack, StackRef, Stackable}; +use crate::string::OpensslString; +use crate::util::{self, ForeignTypeExt, ForeignTypeRefExt}; +use crate::{cvt, cvt_n, cvt_p, cvt_p_const}; +use openssl_macros::corresponds; + +#[cfg(any(ossl102, boringssl, libressl261))] +pub mod verify; + +pub mod extension; +pub mod store; + +#[cfg(test)] +mod tests; + +/// A type of X509 extension. +/// +/// # Safety +/// The value of NID and Output must match those in OpenSSL so that +/// `Output::from_ptr_opt(*_get_ext_d2i(*, NID, ...))` is valid. +pub unsafe trait ExtensionType { + const NID: Nid; + type Output: ForeignType; +} + +foreign_type_and_impl_send_sync! { + type CType = ffi::X509_STORE_CTX; + fn drop = ffi::X509_STORE_CTX_free; + + /// An `X509` certificate store context. + pub struct X509StoreContext; + + /// A reference to an [`X509StoreContext`]. + pub struct X509StoreContextRef; +} + +impl X509StoreContext { + /// Returns the index which can be used to obtain a reference to the `Ssl` associated with a + /// context. + #[corresponds(SSL_get_ex_data_X509_STORE_CTX_idx)] + pub fn ssl_idx() -> Result, ErrorStack> { + unsafe { cvt_n(ffi::SSL_get_ex_data_X509_STORE_CTX_idx()).map(|idx| Index::from_raw(idx)) } + } + + /// Creates a new `X509StoreContext` instance. + #[corresponds(X509_STORE_CTX_new)] + pub fn new() -> Result { + unsafe { + ffi::init(); + cvt_p(ffi::X509_STORE_CTX_new()).map(X509StoreContext) + } + } +} + +impl X509StoreContextRef { + /// Returns application data pertaining to an `X509` store context. + #[corresponds(X509_STORE_CTX_get_ex_data)] + pub fn ex_data(&self, index: Index) -> Option<&T> { + unsafe { + let data = ffi::X509_STORE_CTX_get_ex_data(self.as_ptr(), index.as_raw()); + if data.is_null() { + None + } else { + Some(&*(data as *const T)) + } + } + } + + /// Returns the error code of the context. + #[corresponds(X509_STORE_CTX_get_error)] + pub fn error(&self) -> X509VerifyResult { + unsafe { X509VerifyResult::from_raw(ffi::X509_STORE_CTX_get_error(self.as_ptr())) } + } + + /// Initializes this context with the given certificate, certificates chain and certificate + /// store. After initializing the context, the `with_context` closure is called with the prepared + /// context. As long as the closure is running, the context stays initialized and can be used + /// to e.g. verify a certificate. The context will be cleaned up, after the closure finished. + /// + /// * `trust` - The certificate store with the trusted certificates. + /// * `cert` - The certificate that should be verified. + /// * `cert_chain` - The certificates chain. + /// * `with_context` - The closure that is called with the initialized context. + /// + /// This corresponds to [`X509_STORE_CTX_init`] before calling `with_context` and to + /// [`X509_STORE_CTX_cleanup`] after calling `with_context`. + /// + /// [`X509_STORE_CTX_init`]: https://www.openssl.org/docs/manmaster/crypto/X509_STORE_CTX_init.html + /// [`X509_STORE_CTX_cleanup`]: https://www.openssl.org/docs/manmaster/crypto/X509_STORE_CTX_cleanup.html + pub fn init( + &mut self, + trust: &store::X509StoreRef, + cert: &X509Ref, + cert_chain: &StackRef, + with_context: F, + ) -> Result + where + F: FnOnce(&mut X509StoreContextRef) -> Result, + { + struct Cleanup<'a>(&'a mut X509StoreContextRef); + + impl Drop for Cleanup<'_> { + fn drop(&mut self) { + unsafe { + ffi::X509_STORE_CTX_cleanup(self.0.as_ptr()); + } + } + } + + unsafe { + cvt(ffi::X509_STORE_CTX_init( + self.as_ptr(), + trust.as_ptr(), + cert.as_ptr(), + cert_chain.as_ptr(), + ))?; + + let cleanup = Cleanup(self); + with_context(cleanup.0) + } + } + + /// Verifies the stored certificate. + /// + /// Returns `true` if verification succeeds. The `error` method will return the specific + /// validation error if the certificate was not valid. + /// + /// This will only work inside of a call to `init`. + #[corresponds(X509_verify_cert)] + pub fn verify_cert(&mut self) -> Result { + unsafe { cvt_n(ffi::X509_verify_cert(self.as_ptr())).map(|n| n != 0) } + } + + /// Set the error code of the context. + #[corresponds(X509_STORE_CTX_set_error)] + pub fn set_error(&mut self, result: X509VerifyResult) { + unsafe { + ffi::X509_STORE_CTX_set_error(self.as_ptr(), result.as_raw()); + } + } + + /// Returns a reference to the certificate which caused the error or None if + /// no certificate is relevant to the error. + #[corresponds(X509_STORE_CTX_get_current_cert)] + pub fn current_cert(&self) -> Option<&X509Ref> { + unsafe { + let ptr = ffi::X509_STORE_CTX_get_current_cert(self.as_ptr()); + X509Ref::from_const_ptr_opt(ptr) + } + } + + /// Returns a non-negative integer representing the depth in the certificate + /// chain where the error occurred. If it is zero it occurred in the end + /// entity certificate, one if it is the certificate which signed the end + /// entity certificate and so on. + #[corresponds(X509_STORE_CTX_get_error_depth)] + pub fn error_depth(&self) -> u32 { + unsafe { ffi::X509_STORE_CTX_get_error_depth(self.as_ptr()) as u32 } + } + + /// Returns a reference to a complete valid `X509` certificate chain. + #[corresponds(X509_STORE_CTX_get0_chain)] + pub fn chain(&self) -> Option<&StackRef> { + unsafe { + let chain = X509_STORE_CTX_get0_chain(self.as_ptr()); + + if chain.is_null() { + None + } else { + Some(StackRef::from_ptr(chain)) + } + } + } +} + +/// A builder used to construct an `X509`. +pub struct X509Builder(X509); + +impl X509Builder { + /// Creates a new builder. + #[corresponds(X509_new)] + pub fn new() -> Result { + unsafe { + ffi::init(); + cvt_p(ffi::X509_new()).map(|p| X509Builder(X509(p))) + } + } + + /// Sets the notAfter constraint on the certificate. + #[corresponds(X509_set1_notAfter)] + pub fn set_not_after(&mut self, not_after: &Asn1TimeRef) -> Result<(), ErrorStack> { + unsafe { cvt(X509_set1_notAfter(self.0.as_ptr(), not_after.as_ptr())).map(|_| ()) } + } + + /// Sets the notBefore constraint on the certificate. + #[corresponds(X509_set1_notBefore)] + pub fn set_not_before(&mut self, not_before: &Asn1TimeRef) -> Result<(), ErrorStack> { + unsafe { cvt(X509_set1_notBefore(self.0.as_ptr(), not_before.as_ptr())).map(|_| ()) } + } + + /// Sets the version of the certificate. + /// + /// Note that the version is zero-indexed; that is, a certificate corresponding to version 3 of + /// the X.509 standard should pass `2` to this method. + #[corresponds(X509_set_version)] + #[allow(clippy::useless_conversion)] + pub fn set_version(&mut self, version: i32) -> Result<(), ErrorStack> { + unsafe { cvt(ffi::X509_set_version(self.0.as_ptr(), version as c_long)).map(|_| ()) } + } + + /// Sets the serial number of the certificate. + #[corresponds(X509_set_serialNumber)] + pub fn set_serial_number(&mut self, serial_number: &Asn1IntegerRef) -> Result<(), ErrorStack> { + unsafe { + cvt(ffi::X509_set_serialNumber( + self.0.as_ptr(), + serial_number.as_ptr(), + )) + .map(|_| ()) + } + } + + /// Sets the issuer name of the certificate. + #[corresponds(X509_set_issuer_name)] + pub fn set_issuer_name(&mut self, issuer_name: &X509NameRef) -> Result<(), ErrorStack> { + unsafe { + cvt(ffi::X509_set_issuer_name( + self.0.as_ptr(), + issuer_name.as_ptr(), + )) + .map(|_| ()) + } + } + + /// Sets the subject name of the certificate. + /// + /// When building certificates, the `C`, `ST`, and `O` options are common when using the openssl command line tools. + /// The `CN` field is used for the common name, such as a DNS name. + /// + /// ``` + /// use openssl::x509::{X509, X509NameBuilder}; + /// + /// let mut x509_name = openssl::x509::X509NameBuilder::new().unwrap(); + /// x509_name.append_entry_by_text("C", "US").unwrap(); + /// x509_name.append_entry_by_text("ST", "CA").unwrap(); + /// x509_name.append_entry_by_text("O", "Some organization").unwrap(); + /// x509_name.append_entry_by_text("CN", "www.example.com").unwrap(); + /// let x509_name = x509_name.build(); + /// + /// let mut x509 = openssl::x509::X509::builder().unwrap(); + /// x509.set_subject_name(&x509_name).unwrap(); + /// ``` + #[corresponds(X509_set_subject_name)] + pub fn set_subject_name(&mut self, subject_name: &X509NameRef) -> Result<(), ErrorStack> { + unsafe { + cvt(ffi::X509_set_subject_name( + self.0.as_ptr(), + subject_name.as_ptr(), + )) + .map(|_| ()) + } + } + + /// Sets the public key associated with the certificate. + #[corresponds(X509_set_pubkey)] + pub fn set_pubkey(&mut self, key: &PKeyRef) -> Result<(), ErrorStack> + where + T: HasPublic, + { + unsafe { cvt(ffi::X509_set_pubkey(self.0.as_ptr(), key.as_ptr())).map(|_| ()) } + } + + /// Returns a context object which is needed to create certain X509 extension values. + /// + /// Set `issuer` to `None` if the certificate will be self-signed. + #[corresponds(X509V3_set_ctx)] + pub fn x509v3_context<'a>( + &'a self, + issuer: Option<&'a X509Ref>, + conf: Option<&'a ConfRef>, + ) -> X509v3Context<'a> { + unsafe { + let mut ctx = mem::zeroed(); + + let issuer = match issuer { + Some(issuer) => issuer.as_ptr(), + None => self.0.as_ptr(), + }; + let subject = self.0.as_ptr(); + ffi::X509V3_set_ctx( + &mut ctx, + issuer, + subject, + ptr::null_mut(), + ptr::null_mut(), + 0, + ); + + // nodb case taken care of since we zeroed ctx above + if let Some(conf) = conf { + ffi::X509V3_set_nconf(&mut ctx, conf.as_ptr()); + } + + X509v3Context(ctx, PhantomData) + } + } + + /// Adds an X509 extension value to the certificate. + /// + /// This works just as `append_extension` except it takes ownership of the `X509Extension`. + pub fn append_extension(&mut self, extension: X509Extension) -> Result<(), ErrorStack> { + self.append_extension2(&extension) + } + + /// Adds an X509 extension value to the certificate. + #[corresponds(X509_add_ext)] + pub fn append_extension2(&mut self, extension: &X509ExtensionRef) -> Result<(), ErrorStack> { + unsafe { + cvt(ffi::X509_add_ext(self.0.as_ptr(), extension.as_ptr(), -1))?; + Ok(()) + } + } + + /// Signs the certificate with a private key. + #[corresponds(X509_sign)] + pub fn sign(&mut self, key: &PKeyRef, hash: MessageDigest) -> Result<(), ErrorStack> + where + T: HasPrivate, + { + unsafe { cvt(ffi::X509_sign(self.0.as_ptr(), key.as_ptr(), hash.as_ptr())).map(|_| ()) } + } + + /// Consumes the builder, returning the certificate. + pub fn build(self) -> X509 { + self.0 + } +} + +foreign_type_and_impl_send_sync! { + type CType = ffi::X509; + fn drop = ffi::X509_free; + + /// An `X509` public key certificate. + pub struct X509; + /// Reference to `X509`. + pub struct X509Ref; +} + +impl X509Ref { + /// Returns this certificate's subject name. + #[corresponds(X509_get_subject_name)] + pub fn subject_name(&self) -> &X509NameRef { + unsafe { + let name = ffi::X509_get_subject_name(self.as_ptr()); + X509NameRef::from_const_ptr_opt(name).expect("subject name must not be null") + } + } + + /// Returns the hash of the certificates subject + #[corresponds(X509_subject_name_hash)] + pub fn subject_name_hash(&self) -> u32 { + #[allow(clippy::unnecessary_cast)] + unsafe { + ffi::X509_subject_name_hash(self.as_ptr()) as u32 + } + } + + /// Returns this certificate's issuer name. + #[corresponds(X509_get_issuer_name)] + pub fn issuer_name(&self) -> &X509NameRef { + unsafe { + let name = ffi::X509_get_issuer_name(self.as_ptr()); + X509NameRef::from_const_ptr_opt(name).expect("issuer name must not be null") + } + } + + /// Returns the hash of the certificates issuer + #[corresponds(X509_issuer_name_hash)] + pub fn issuer_name_hash(&self) -> u32 { + #[allow(clippy::unnecessary_cast)] + unsafe { + ffi::X509_issuer_name_hash(self.as_ptr()) as u32 + } + } + + /// Returns this certificate's subject alternative name entries, if they exist. + #[corresponds(X509_get_ext_d2i)] + pub fn subject_alt_names(&self) -> Option> { + unsafe { + let stack = ffi::X509_get_ext_d2i( + self.as_ptr(), + ffi::NID_subject_alt_name, + ptr::null_mut(), + ptr::null_mut(), + ); + Stack::from_ptr_opt(stack as *mut _) + } + } + + /// Returns this certificate's CRL distribution points, if they exist. + #[corresponds(X509_get_ext_d2i)] + pub fn crl_distribution_points(&self) -> Option> { + unsafe { + let stack = ffi::X509_get_ext_d2i( + self.as_ptr(), + ffi::NID_crl_distribution_points, + ptr::null_mut(), + ptr::null_mut(), + ); + Stack::from_ptr_opt(stack as *mut _) + } + } + + /// Returns this certificate's issuer alternative name entries, if they exist. + #[corresponds(X509_get_ext_d2i)] + pub fn issuer_alt_names(&self) -> Option> { + unsafe { + let stack = ffi::X509_get_ext_d2i( + self.as_ptr(), + ffi::NID_issuer_alt_name, + ptr::null_mut(), + ptr::null_mut(), + ); + Stack::from_ptr_opt(stack as *mut _) + } + } + + /// Returns this certificate's [`authority information access`] entries, if they exist. + /// + /// [`authority information access`]: https://tools.ietf.org/html/rfc5280#section-4.2.2.1 + #[corresponds(X509_get_ext_d2i)] + pub fn authority_info(&self) -> Option> { + unsafe { + let stack = ffi::X509_get_ext_d2i( + self.as_ptr(), + ffi::NID_info_access, + ptr::null_mut(), + ptr::null_mut(), + ); + Stack::from_ptr_opt(stack as *mut _) + } + } + + /// Retrieves the path length extension from a certificate, if it exists. + #[corresponds(X509_get_pathlen)] + #[cfg(any(ossl110, boringssl))] + pub fn pathlen(&self) -> Option { + let v = unsafe { ffi::X509_get_pathlen(self.as_ptr()) }; + u32::try_from(v).ok() + } + + /// Returns this certificate's subject key id, if it exists. + #[corresponds(X509_get0_subject_key_id)] + #[cfg(any(ossl110, boringssl))] + pub fn subject_key_id(&self) -> Option<&Asn1OctetStringRef> { + unsafe { + let data = ffi::X509_get0_subject_key_id(self.as_ptr()); + Asn1OctetStringRef::from_const_ptr_opt(data) + } + } + + /// Returns this certificate's authority key id, if it exists. + #[corresponds(X509_get0_authority_key_id)] + #[cfg(any(ossl110, boringssl))] + pub fn authority_key_id(&self) -> Option<&Asn1OctetStringRef> { + unsafe { + let data = ffi::X509_get0_authority_key_id(self.as_ptr()); + Asn1OctetStringRef::from_const_ptr_opt(data) + } + } + + /// Returns this certificate's authority issuer name entries, if they exist. + #[corresponds(X509_get0_authority_issuer)] + #[cfg(ossl111d)] + pub fn authority_issuer(&self) -> Option<&StackRef> { + unsafe { + let stack = ffi::X509_get0_authority_issuer(self.as_ptr()); + StackRef::from_const_ptr_opt(stack) + } + } + + /// Returns this certificate's authority serial number, if it exists. + #[corresponds(X509_get0_authority_serial)] + #[cfg(ossl111d)] + pub fn authority_serial(&self) -> Option<&Asn1IntegerRef> { + unsafe { + let r = ffi::X509_get0_authority_serial(self.as_ptr()); + Asn1IntegerRef::from_const_ptr_opt(r) + } + } + + #[corresponds(X509_get_pubkey)] + pub fn public_key(&self) -> Result, ErrorStack> { + unsafe { + let pkey = cvt_p(ffi::X509_get_pubkey(self.as_ptr()))?; + Ok(PKey::from_ptr(pkey)) + } + } + + /// Returns a digest of the DER representation of the certificate. + #[corresponds(X509_digest)] + pub fn digest(&self, hash_type: MessageDigest) -> Result { + unsafe { + let mut digest = DigestBytes { + buf: [0; ffi::EVP_MAX_MD_SIZE as usize], + len: ffi::EVP_MAX_MD_SIZE as usize, + }; + let mut len = ffi::EVP_MAX_MD_SIZE as c_uint; + cvt(ffi::X509_digest( + self.as_ptr(), + hash_type.as_ptr(), + digest.buf.as_mut_ptr() as *mut _, + &mut len, + ))?; + digest.len = len as usize; + + Ok(digest) + } + } + + #[deprecated(since = "0.10.9", note = "renamed to digest")] + pub fn fingerprint(&self, hash_type: MessageDigest) -> Result, ErrorStack> { + self.digest(hash_type).map(|b| b.to_vec()) + } + + /// Returns the certificate's Not After validity period. + #[corresponds(X509_getm_notAfter)] + pub fn not_after(&self) -> &Asn1TimeRef { + unsafe { + let date = X509_getm_notAfter(self.as_ptr()); + Asn1TimeRef::from_const_ptr_opt(date).expect("not_after must not be null") + } + } + + /// Returns the certificate's Not Before validity period. + #[corresponds(X509_getm_notBefore)] + pub fn not_before(&self) -> &Asn1TimeRef { + unsafe { + let date = X509_getm_notBefore(self.as_ptr()); + Asn1TimeRef::from_const_ptr_opt(date).expect("not_before must not be null") + } + } + + /// Returns the certificate's signature + #[corresponds(X509_get0_signature)] + pub fn signature(&self) -> &Asn1BitStringRef { + unsafe { + let mut signature = ptr::null(); + X509_get0_signature(&mut signature, ptr::null_mut(), self.as_ptr()); + Asn1BitStringRef::from_const_ptr_opt(signature).expect("signature must not be null") + } + } + + /// Returns the certificate's signature algorithm. + #[corresponds(X509_get0_signature)] + pub fn signature_algorithm(&self) -> &X509AlgorithmRef { + unsafe { + let mut algor = ptr::null(); + X509_get0_signature(ptr::null_mut(), &mut algor, self.as_ptr()); + X509AlgorithmRef::from_const_ptr_opt(algor) + .expect("signature algorithm must not be null") + } + } + + /// Returns the list of OCSP responder URLs specified in the certificate's Authority Information + /// Access field. + #[corresponds(X509_get1_ocsp)] + pub fn ocsp_responders(&self) -> Result, ErrorStack> { + unsafe { cvt_p(ffi::X509_get1_ocsp(self.as_ptr())).map(|p| Stack::from_ptr(p)) } + } + + /// Checks that this certificate issued `subject`. + #[corresponds(X509_check_issued)] + pub fn issued(&self, subject: &X509Ref) -> X509VerifyResult { + unsafe { + let r = ffi::X509_check_issued(self.as_ptr(), subject.as_ptr()); + X509VerifyResult::from_raw(r) + } + } + + /// Returns certificate version. If this certificate has no explicit version set, it defaults to + /// version 1. + /// + /// Note that `0` return value stands for version 1, `1` for version 2 and so on. + #[corresponds(X509_get_version)] + #[cfg(ossl110)] + #[allow(clippy::unnecessary_cast)] + pub fn version(&self) -> i32 { + unsafe { ffi::X509_get_version(self.as_ptr()) as i32 } + } + + /// Check if the certificate is signed using the given public key. + /// + /// Only the signature is checked: no other checks (such as certificate chain validity) + /// are performed. + /// + /// Returns `true` if verification succeeds. + #[corresponds(X509_verify)] + pub fn verify(&self, key: &PKeyRef) -> Result + where + T: HasPublic, + { + unsafe { cvt_n(ffi::X509_verify(self.as_ptr(), key.as_ptr())).map(|n| n != 0) } + } + + /// Returns this certificate's serial number. + #[corresponds(X509_get_serialNumber)] + pub fn serial_number(&self) -> &Asn1IntegerRef { + unsafe { + let r = ffi::X509_get_serialNumber(self.as_ptr()); + Asn1IntegerRef::from_const_ptr_opt(r).expect("serial number must not be null") + } + } + + /// Returns this certificate's "alias". This field is populated by + /// OpenSSL in some situations -- specifically OpenSSL will store a + /// PKCS#12 `friendlyName` in this field. This is not a part of the X.509 + /// certificate itself, OpenSSL merely attaches it to this structure in + /// memory. + #[corresponds(X509_alias_get0)] + pub fn alias(&self) -> Option<&[u8]> { + unsafe { + let mut len = 0; + let ptr = ffi::X509_alias_get0(self.as_ptr(), &mut len); + if ptr.is_null() { + None + } else { + Some(util::from_raw_parts(ptr, len as usize)) + } + } + } + + to_pem! { + /// Serializes the certificate into a PEM-encoded X509 structure. + /// + /// The output will have a header of `-----BEGIN CERTIFICATE-----`. + #[corresponds(PEM_write_bio_X509)] + to_pem, + ffi::PEM_write_bio_X509 + } + + to_der! { + /// Serializes the certificate into a DER-encoded X509 structure. + #[corresponds(i2d_X509)] + to_der, + ffi::i2d_X509 + } + + to_pem! { + /// Converts the certificate to human readable text. + #[corresponds(X509_print)] + to_text, + ffi::X509_print + } +} + +impl ToOwned for X509Ref { + type Owned = X509; + + fn to_owned(&self) -> X509 { + unsafe { + X509_up_ref(self.as_ptr()); + X509::from_ptr(self.as_ptr()) + } + } +} + +impl Ord for X509Ref { + fn cmp(&self, other: &Self) -> cmp::Ordering { + // X509_cmp returns a number <0 for less than, 0 for equal and >0 for greater than. + // It can't fail if both pointers are valid, which we know is true. + let cmp = unsafe { ffi::X509_cmp(self.as_ptr(), other.as_ptr()) }; + cmp.cmp(&0) + } +} + +impl PartialOrd for X509Ref { + fn partial_cmp(&self, other: &Self) -> Option { + Some(self.cmp(other)) + } +} + +impl PartialOrd for X509Ref { + fn partial_cmp(&self, other: &X509) -> Option { + >::partial_cmp(self, other) + } +} + +impl PartialEq for X509Ref { + fn eq(&self, other: &Self) -> bool { + self.cmp(other) == cmp::Ordering::Equal + } +} + +impl PartialEq for X509Ref { + fn eq(&self, other: &X509) -> bool { + >::eq(self, other) + } +} + +impl Eq for X509Ref {} + +impl X509 { + /// Returns a new builder. + pub fn builder() -> Result { + X509Builder::new() + } + + from_pem! { + /// Deserializes a PEM-encoded X509 structure. + /// + /// The input should have a header of `-----BEGIN CERTIFICATE-----`. + #[corresponds(PEM_read_bio_X509)] + from_pem, + X509, + ffi::PEM_read_bio_X509 + } + + from_der! { + /// Deserializes a DER-encoded X509 structure. + #[corresponds(d2i_X509)] + from_der, + X509, + ffi::d2i_X509 + } + + /// Deserializes a list of PEM-formatted certificates. + #[corresponds(PEM_read_bio_X509)] + pub fn stack_from_pem(pem: &[u8]) -> Result, ErrorStack> { + unsafe { + ffi::init(); + let bio = MemBioSlice::new(pem)?; + + let mut certs = vec![]; + loop { + let r = + ffi::PEM_read_bio_X509(bio.as_ptr(), ptr::null_mut(), None, ptr::null_mut()); + if r.is_null() { + let e = ErrorStack::get(); + + if let Some(err) = e.errors().last() { + if err.library_code() == ffi::ERR_LIB_PEM as libc::c_int + && err.reason_code() == ffi::PEM_R_NO_START_LINE as libc::c_int + { + break; + } + } + + return Err(e); + } else { + certs.push(X509(r)); + } + } + + Ok(certs) + } + } +} + +impl Clone for X509 { + fn clone(&self) -> X509 { + X509Ref::to_owned(self) + } +} + +impl fmt::Debug for X509 { + fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { + let serial = match &self.serial_number().to_bn() { + Ok(bn) => match bn.to_hex_str() { + Ok(hex) => hex.to_string(), + Err(_) => "".to_string(), + }, + Err(_) => "".to_string(), + }; + let mut debug_struct = formatter.debug_struct("X509"); + debug_struct.field("serial_number", &serial); + debug_struct.field("signature_algorithm", &self.signature_algorithm().object()); + debug_struct.field("issuer", &self.issuer_name()); + debug_struct.field("subject", &self.subject_name()); + if let Some(subject_alt_names) = &self.subject_alt_names() { + debug_struct.field("subject_alt_names", subject_alt_names); + } + debug_struct.field("not_before", &self.not_before()); + debug_struct.field("not_after", &self.not_after()); + + if let Ok(public_key) = &self.public_key() { + debug_struct.field("public_key", public_key); + }; + // TODO: Print extensions once they are supported on the X509 struct. + + debug_struct.finish() + } +} + +impl AsRef for X509Ref { + fn as_ref(&self) -> &X509Ref { + self + } +} + +impl Stackable for X509 { + type StackType = ffi::stack_st_X509; +} + +impl Ord for X509 { + fn cmp(&self, other: &Self) -> cmp::Ordering { + X509Ref::cmp(self, other) + } +} + +impl PartialOrd for X509 { + fn partial_cmp(&self, other: &Self) -> Option { + Some(self.cmp(other)) + } +} + +impl PartialOrd for X509 { + fn partial_cmp(&self, other: &X509Ref) -> Option { + X509Ref::partial_cmp(self, other) + } +} + +impl PartialEq for X509 { + fn eq(&self, other: &Self) -> bool { + X509Ref::eq(self, other) + } +} + +impl PartialEq for X509 { + fn eq(&self, other: &X509Ref) -> bool { + X509Ref::eq(self, other) + } +} + +impl Eq for X509 {} + +/// A context object required to construct certain `X509` extension values. +pub struct X509v3Context<'a>(ffi::X509V3_CTX, PhantomData<(&'a X509Ref, &'a ConfRef)>); + +impl X509v3Context<'_> { + pub fn as_ptr(&self) -> *mut ffi::X509V3_CTX { + &self.0 as *const _ as *mut _ + } +} + +foreign_type_and_impl_send_sync! { + type CType = ffi::X509_EXTENSION; + fn drop = ffi::X509_EXTENSION_free; + + /// Permit additional fields to be added to an `X509` v3 certificate. + pub struct X509Extension; + /// Reference to `X509Extension`. + pub struct X509ExtensionRef; +} + +impl Stackable for X509Extension { + type StackType = ffi::stack_st_X509_EXTENSION; +} + +impl X509Extension { + /// Constructs an X509 extension value. See `man x509v3_config` for information on supported + /// names and their value formats. + /// + /// Some extension types, such as `subjectAlternativeName`, require an `X509v3Context` to be + /// provided. + /// + /// DO NOT CALL THIS WITH UNTRUSTED `value`: `value` is an OpenSSL + /// mini-language that can read arbitrary files. + /// + /// See the extension module for builder types which will construct certain common extensions. + /// + /// This function is deprecated, `X509Extension::new_from_der` or the + /// types in `x509::extension` should be used in its place. + #[deprecated( + note = "Use x509::extension types or new_from_der instead", + since = "0.10.51" + )] + pub fn new( + conf: Option<&ConfRef>, + context: Option<&X509v3Context<'_>>, + name: &str, + value: &str, + ) -> Result { + let name = CString::new(name).unwrap(); + let value = CString::new(value).unwrap(); + let mut ctx; + unsafe { + ffi::init(); + let conf = conf.map_or(ptr::null_mut(), ConfRef::as_ptr); + let context_ptr = match context { + Some(c) => c.as_ptr(), + None => { + ctx = mem::zeroed(); + + ffi::X509V3_set_ctx( + &mut ctx, + ptr::null_mut(), + ptr::null_mut(), + ptr::null_mut(), + ptr::null_mut(), + 0, + ); + &mut ctx + } + }; + let name = name.as_ptr() as *mut _; + let value = value.as_ptr() as *mut _; + + cvt_p(ffi::X509V3_EXT_nconf(conf, context_ptr, name, value)).map(X509Extension) + } + } + + /// Constructs an X509 extension value. See `man x509v3_config` for information on supported + /// extensions and their value formats. + /// + /// Some extension types, such as `nid::SUBJECT_ALTERNATIVE_NAME`, require an `X509v3Context` to + /// be provided. + /// + /// DO NOT CALL THIS WITH UNTRUSTED `value`: `value` is an OpenSSL + /// mini-language that can read arbitrary files. + /// + /// See the extension module for builder types which will construct certain common extensions. + /// + /// This function is deprecated, `X509Extension::new_from_der` or the + /// types in `x509::extension` should be used in its place. + #[deprecated( + note = "Use x509::extension types or new_from_der instead", + since = "0.10.51" + )] + pub fn new_nid( + conf: Option<&ConfRef>, + context: Option<&X509v3Context<'_>>, + name: Nid, + value: &str, + ) -> Result { + let value = CString::new(value).unwrap(); + let mut ctx; + unsafe { + ffi::init(); + let conf = conf.map_or(ptr::null_mut(), ConfRef::as_ptr); + let context_ptr = match context { + Some(c) => c.as_ptr(), + None => { + ctx = mem::zeroed(); + + ffi::X509V3_set_ctx( + &mut ctx, + ptr::null_mut(), + ptr::null_mut(), + ptr::null_mut(), + ptr::null_mut(), + 0, + ); + &mut ctx + } + }; + let name = name.as_raw(); + let value = value.as_ptr() as *mut _; + + cvt_p(ffi::X509V3_EXT_nconf_nid(conf, context_ptr, name, value)).map(X509Extension) + } + } + + /// Constructs a new X509 extension value from its OID, whether it's + /// critical, and its DER contents. + /// + /// The extent structure of the DER value will vary based on the + /// extension type, and can generally be found in the RFC defining the + /// extension. + /// + /// For common extension types, there are Rust APIs provided in + /// `openssl::x509::extensions` which are more ergonomic. + pub fn new_from_der( + oid: &Asn1ObjectRef, + critical: bool, + der_contents: &Asn1OctetStringRef, + ) -> Result { + unsafe { + cvt_p(ffi::X509_EXTENSION_create_by_OBJ( + ptr::null_mut(), + oid.as_ptr(), + critical as _, + der_contents.as_ptr(), + )) + .map(X509Extension) + } + } + + pub(crate) unsafe fn new_internal( + nid: Nid, + critical: bool, + value: *mut c_void, + ) -> Result { + ffi::init(); + cvt_p(ffi::X509V3_EXT_i2d(nid.as_raw(), critical as _, value)).map(X509Extension) + } + + /// Adds an alias for an extension + /// + /// # Safety + /// + /// This method modifies global state without locking and therefore is not thread safe + #[cfg(not(libressl390))] + #[corresponds(X509V3_EXT_add_alias)] + #[deprecated( + note = "Use x509::extension types or new_from_der and then this is not necessary", + since = "0.10.51" + )] + pub unsafe fn add_alias(to: Nid, from: Nid) -> Result<(), ErrorStack> { + ffi::init(); + cvt(ffi::X509V3_EXT_add_alias(to.as_raw(), from.as_raw())).map(|_| ()) + } +} + +impl X509ExtensionRef { + to_der! { + /// Serializes the Extension to its standard DER encoding. + #[corresponds(i2d_X509_EXTENSION)] + to_der, + ffi::i2d_X509_EXTENSION + } +} + +/// A builder used to construct an `X509Name`. +pub struct X509NameBuilder(X509Name); + +impl X509NameBuilder { + /// Creates a new builder. + pub fn new() -> Result { + unsafe { + ffi::init(); + cvt_p(ffi::X509_NAME_new()).map(|p| X509NameBuilder(X509Name(p))) + } + } + + /// Add a name entry + #[corresponds(X509_NAME_add_entry)] + #[cfg(any(ossl101, libressl350))] + pub fn append_entry(&mut self, ne: &X509NameEntryRef) -> std::result::Result<(), ErrorStack> { + unsafe { + cvt(ffi::X509_NAME_add_entry( + self.0.as_ptr(), + ne.as_ptr(), + -1, + 0, + )) + .map(|_| ()) + } + } + + /// Add a field entry by str. + #[corresponds(X509_NAME_add_entry_by_txt)] + pub fn append_entry_by_text(&mut self, field: &str, value: &str) -> Result<(), ErrorStack> { + unsafe { + let field = CString::new(field).unwrap(); + assert!(value.len() <= crate::SLenType::MAX as usize); + cvt(ffi::X509_NAME_add_entry_by_txt( + self.0.as_ptr(), + field.as_ptr() as *mut _, + ffi::MBSTRING_UTF8, + value.as_ptr(), + value.len() as crate::SLenType, + -1, + 0, + )) + .map(|_| ()) + } + } + + /// Add a field entry by str with a specific type. + #[corresponds(X509_NAME_add_entry_by_txt)] + pub fn append_entry_by_text_with_type( + &mut self, + field: &str, + value: &str, + ty: Asn1Type, + ) -> Result<(), ErrorStack> { + unsafe { + let field = CString::new(field).unwrap(); + assert!(value.len() <= crate::SLenType::MAX as usize); + cvt(ffi::X509_NAME_add_entry_by_txt( + self.0.as_ptr(), + field.as_ptr() as *mut _, + ty.as_raw(), + value.as_ptr(), + value.len() as crate::SLenType, + -1, + 0, + )) + .map(|_| ()) + } + } + + /// Add a field entry by NID. + #[corresponds(X509_NAME_add_entry_by_NID)] + pub fn append_entry_by_nid(&mut self, field: Nid, value: &str) -> Result<(), ErrorStack> { + unsafe { + assert!(value.len() <= crate::SLenType::MAX as usize); + cvt(ffi::X509_NAME_add_entry_by_NID( + self.0.as_ptr(), + field.as_raw(), + ffi::MBSTRING_UTF8, + value.as_ptr() as *mut _, + value.len() as crate::SLenType, + -1, + 0, + )) + .map(|_| ()) + } + } + + /// Add a field entry by NID with a specific type. + #[corresponds(X509_NAME_add_entry_by_NID)] + pub fn append_entry_by_nid_with_type( + &mut self, + field: Nid, + value: &str, + ty: Asn1Type, + ) -> Result<(), ErrorStack> { + unsafe { + assert!(value.len() <= crate::SLenType::MAX as usize); + cvt(ffi::X509_NAME_add_entry_by_NID( + self.0.as_ptr(), + field.as_raw(), + ty.as_raw(), + value.as_ptr() as *mut _, + value.len() as crate::SLenType, + -1, + 0, + )) + .map(|_| ()) + } + } + + /// Return an `X509Name`. + pub fn build(self) -> X509Name { + // Round-trip through bytes because OpenSSL is not const correct and + // names in a "modified" state compute various things lazily. This can + // lead to data-races because OpenSSL doesn't have locks or anything. + X509Name::from_der(&self.0.to_der().unwrap()).unwrap() + } +} + +foreign_type_and_impl_send_sync! { + type CType = ffi::X509_NAME; + fn drop = ffi::X509_NAME_free; + + /// The names of an `X509` certificate. + pub struct X509Name; + /// Reference to `X509Name`. + pub struct X509NameRef; +} + +impl X509Name { + /// Returns a new builder. + pub fn builder() -> Result { + X509NameBuilder::new() + } + + /// Loads subject names from a file containing PEM-formatted certificates. + /// + /// This is commonly used in conjunction with `SslContextBuilder::set_client_ca_list`. + pub fn load_client_ca_file>(file: P) -> Result, ErrorStack> { + let file = CString::new(file.as_ref().as_os_str().to_str().unwrap()).unwrap(); + unsafe { cvt_p(ffi::SSL_load_client_CA_file(file.as_ptr())).map(|p| Stack::from_ptr(p)) } + } + + from_der! { + /// Deserializes a DER-encoded X509 name structure. + /// + /// This corresponds to [`d2i_X509_NAME`]. + /// + /// [`d2i_X509_NAME`]: https://www.openssl.org/docs/manmaster/man3/d2i_X509_NAME.html + from_der, + X509Name, + ffi::d2i_X509_NAME + } +} + +impl Stackable for X509Name { + type StackType = ffi::stack_st_X509_NAME; +} + +impl X509NameRef { + /// Returns the name entries by the nid. + pub fn entries_by_nid(&self, nid: Nid) -> X509NameEntries<'_> { + X509NameEntries { + name: self, + nid: Some(nid), + loc: -1, + } + } + + /// Returns an iterator over all `X509NameEntry` values + pub fn entries(&self) -> X509NameEntries<'_> { + X509NameEntries { + name: self, + nid: None, + loc: -1, + } + } + + /// Compare two names, like [`Ord`] but it may fail. + /// + /// With OpenSSL versions from 3.0.0 this may return an error if the underlying `X509_NAME_cmp` + /// call fails. + /// For OpenSSL versions before 3.0.0 it will never return an error, but due to a bug it may + /// spuriously return `Ordering::Less` if the `X509_NAME_cmp` call fails. + #[corresponds(X509_NAME_cmp)] + pub fn try_cmp(&self, other: &X509NameRef) -> Result { + let cmp = unsafe { ffi::X509_NAME_cmp(self.as_ptr(), other.as_ptr()) }; + if cfg!(ossl300) && cmp == -2 { + return Err(ErrorStack::get()); + } + Ok(cmp.cmp(&0)) + } + + /// Copies the name to a new `X509Name`. + #[corresponds(X509_NAME_dup)] + #[cfg(any(boringssl, ossl110, libressl270))] + pub fn to_owned(&self) -> Result { + unsafe { cvt_p(ffi::X509_NAME_dup(self.as_ptr())).map(|n| X509Name::from_ptr(n)) } + } + + to_der! { + /// Serializes the certificate into a DER-encoded X509 name structure. + /// + /// This corresponds to [`i2d_X509_NAME`]. + /// + /// [`i2d_X509_NAME`]: https://www.openssl.org/docs/manmaster/crypto/i2d_X509_NAME.html + to_der, + ffi::i2d_X509_NAME + } +} + +impl fmt::Debug for X509NameRef { + fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { + formatter.debug_list().entries(self.entries()).finish() + } +} + +/// A type to destructure and examine an `X509Name`. +pub struct X509NameEntries<'a> { + name: &'a X509NameRef, + nid: Option, + loc: c_int, +} + +impl<'a> Iterator for X509NameEntries<'a> { + type Item = &'a X509NameEntryRef; + + fn next(&mut self) -> Option<&'a X509NameEntryRef> { + unsafe { + match self.nid { + Some(nid) => { + // There is a `Nid` specified to search for + self.loc = + ffi::X509_NAME_get_index_by_NID(self.name.as_ptr(), nid.as_raw(), self.loc); + if self.loc == -1 { + return None; + } + } + None => { + // Iterate over all `Nid`s + self.loc += 1; + if self.loc >= ffi::X509_NAME_entry_count(self.name.as_ptr()) { + return None; + } + } + } + + let entry = ffi::X509_NAME_get_entry(self.name.as_ptr(), self.loc); + + Some(X509NameEntryRef::from_const_ptr_opt(entry).expect("entry must not be null")) + } + } +} + +foreign_type_and_impl_send_sync! { + type CType = ffi::X509_NAME_ENTRY; + fn drop = ffi::X509_NAME_ENTRY_free; + + /// A name entry associated with a `X509Name`. + pub struct X509NameEntry; + /// Reference to `X509NameEntry`. + pub struct X509NameEntryRef; +} + +impl X509NameEntryRef { + /// Returns the field value of an `X509NameEntry`. + #[corresponds(X509_NAME_ENTRY_get_data)] + pub fn data(&self) -> &Asn1StringRef { + unsafe { + let data = ffi::X509_NAME_ENTRY_get_data(self.as_ptr()); + Asn1StringRef::from_ptr(data) + } + } + + /// Returns the `Asn1Object` value of an `X509NameEntry`. + /// This is useful for finding out about the actual `Nid` when iterating over all `X509NameEntries`. + #[corresponds(X509_NAME_ENTRY_get_object)] + pub fn object(&self) -> &Asn1ObjectRef { + unsafe { + let object = ffi::X509_NAME_ENTRY_get_object(self.as_ptr()); + Asn1ObjectRef::from_ptr(object) + } + } +} + +impl fmt::Debug for X509NameEntryRef { + fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { + formatter.write_fmt(format_args!("{:?} = {:?}", self.object(), self.data())) + } +} + +/// A builder used to construct an `X509Req`. +pub struct X509ReqBuilder(X509Req); + +impl X509ReqBuilder { + /// Returns a builder for a certificate request. + #[corresponds(X509_REQ_new)] + pub fn new() -> Result { + unsafe { + ffi::init(); + cvt_p(ffi::X509_REQ_new()).map(|p| X509ReqBuilder(X509Req(p))) + } + } + + /// Set the numerical value of the version field. + #[corresponds(X509_REQ_set_version)] + #[allow(clippy::useless_conversion)] + pub fn set_version(&mut self, version: i32) -> Result<(), ErrorStack> { + unsafe { + cvt(ffi::X509_REQ_set_version( + self.0.as_ptr(), + version as c_long, + )) + .map(|_| ()) + } + } + + /// Set the issuer name. + #[corresponds(X509_REQ_set_subject_name)] + pub fn set_subject_name(&mut self, subject_name: &X509NameRef) -> Result<(), ErrorStack> { + unsafe { + cvt(ffi::X509_REQ_set_subject_name( + self.0.as_ptr(), + subject_name.as_ptr(), + )) + .map(|_| ()) + } + } + + /// Set the public key. + #[corresponds(X509_REQ_set_pubkey)] + pub fn set_pubkey(&mut self, key: &PKeyRef) -> Result<(), ErrorStack> + where + T: HasPublic, + { + unsafe { cvt(ffi::X509_REQ_set_pubkey(self.0.as_ptr(), key.as_ptr())).map(|_| ()) } + } + + /// Return an `X509v3Context`. This context object can be used to construct + /// certain `X509` extensions. + pub fn x509v3_context<'a>(&'a self, conf: Option<&'a ConfRef>) -> X509v3Context<'a> { + unsafe { + let mut ctx = mem::zeroed(); + + ffi::X509V3_set_ctx( + &mut ctx, + ptr::null_mut(), + ptr::null_mut(), + self.0.as_ptr(), + ptr::null_mut(), + 0, + ); + + // nodb case taken care of since we zeroed ctx above + if let Some(conf) = conf { + ffi::X509V3_set_nconf(&mut ctx, conf.as_ptr()); + } + + X509v3Context(ctx, PhantomData) + } + } + + /// Permits any number of extension fields to be added to the certificate. + pub fn add_extensions( + &mut self, + extensions: &StackRef, + ) -> Result<(), ErrorStack> { + unsafe { + cvt(ffi::X509_REQ_add_extensions( + self.0.as_ptr(), + extensions.as_ptr(), + )) + .map(|_| ()) + } + } + + /// Sign the request using a private key. + #[corresponds(X509_REQ_sign)] + pub fn sign(&mut self, key: &PKeyRef, hash: MessageDigest) -> Result<(), ErrorStack> + where + T: HasPrivate, + { + unsafe { + cvt(ffi::X509_REQ_sign( + self.0.as_ptr(), + key.as_ptr(), + hash.as_ptr(), + )) + .map(|_| ()) + } + } + + /// Returns the `X509Req`. + pub fn build(self) -> X509Req { + self.0 + } +} + +foreign_type_and_impl_send_sync! { + type CType = ffi::X509_REQ; + fn drop = ffi::X509_REQ_free; + + /// An `X509` certificate request. + pub struct X509Req; + /// Reference to `X509Req`. + pub struct X509ReqRef; +} + +impl X509Req { + /// A builder for `X509Req`. + pub fn builder() -> Result { + X509ReqBuilder::new() + } + + from_pem! { + /// Deserializes a PEM-encoded PKCS#10 certificate request structure. + /// + /// The input should have a header of `-----BEGIN CERTIFICATE REQUEST-----`. + /// + /// This corresponds to [`PEM_read_bio_X509_REQ`]. + /// + /// [`PEM_read_bio_X509_REQ`]: https://www.openssl.org/docs/manmaster/crypto/PEM_read_bio_X509_REQ.html + from_pem, + X509Req, + ffi::PEM_read_bio_X509_REQ + } + + from_der! { + /// Deserializes a DER-encoded PKCS#10 certificate request structure. + /// + /// This corresponds to [`d2i_X509_REQ`]. + /// + /// [`d2i_X509_REQ`]: https://www.openssl.org/docs/manmaster/crypto/d2i_X509_REQ.html + from_der, + X509Req, + ffi::d2i_X509_REQ + } +} + +impl X509ReqRef { + to_pem! { + /// Serializes the certificate request to a PEM-encoded PKCS#10 structure. + /// + /// The output will have a header of `-----BEGIN CERTIFICATE REQUEST-----`. + /// + /// This corresponds to [`PEM_write_bio_X509_REQ`]. + /// + /// [`PEM_write_bio_X509_REQ`]: https://www.openssl.org/docs/manmaster/crypto/PEM_write_bio_X509_REQ.html + to_pem, + ffi::PEM_write_bio_X509_REQ + } + + to_der! { + /// Serializes the certificate request to a DER-encoded PKCS#10 structure. + /// + /// This corresponds to [`i2d_X509_REQ`]. + /// + /// [`i2d_X509_REQ`]: https://www.openssl.org/docs/manmaster/crypto/i2d_X509_REQ.html + to_der, + ffi::i2d_X509_REQ + } + + to_pem! { + /// Converts the request to human readable text. + #[corresponds(X509_Req_print)] + to_text, + ffi::X509_REQ_print + } + + /// Returns the numerical value of the version field of the certificate request. + #[corresponds(X509_REQ_get_version)] + #[allow(clippy::unnecessary_cast)] + pub fn version(&self) -> i32 { + unsafe { X509_REQ_get_version(self.as_ptr()) as i32 } + } + + /// Returns the subject name of the certificate request. + #[corresponds(X509_REQ_get_subject_name)] + pub fn subject_name(&self) -> &X509NameRef { + unsafe { + let name = X509_REQ_get_subject_name(self.as_ptr()); + X509NameRef::from_const_ptr_opt(name).expect("subject name must not be null") + } + } + + /// Returns the public key of the certificate request. + #[corresponds(X509_REQ_get_pubkey)] + pub fn public_key(&self) -> Result, ErrorStack> { + unsafe { + let key = cvt_p(ffi::X509_REQ_get_pubkey(self.as_ptr()))?; + Ok(PKey::from_ptr(key)) + } + } + + /// Check if the certificate request is signed using the given public key. + /// + /// Returns `true` if verification succeeds. + #[corresponds(X509_REQ_verify)] + pub fn verify(&self, key: &PKeyRef) -> Result + where + T: HasPublic, + { + unsafe { cvt_n(ffi::X509_REQ_verify(self.as_ptr(), key.as_ptr())).map(|n| n != 0) } + } + + /// Returns the extensions of the certificate request. + #[corresponds(X509_REQ_get_extensions)] + pub fn extensions(&self) -> Result, ErrorStack> { + unsafe { + let extensions = cvt_p(ffi::X509_REQ_get_extensions(self.as_ptr()))?; + Ok(Stack::from_ptr(extensions)) + } + } +} + +/// The reason that a certificate was revoked. +#[derive(Debug, Copy, Clone, PartialEq, Eq)] +pub struct CrlReason(c_int); + +#[allow(missing_docs)] // no need to document the constants +impl CrlReason { + pub const UNSPECIFIED: CrlReason = CrlReason(ffi::CRL_REASON_UNSPECIFIED); + pub const KEY_COMPROMISE: CrlReason = CrlReason(ffi::CRL_REASON_KEY_COMPROMISE); + pub const CA_COMPROMISE: CrlReason = CrlReason(ffi::CRL_REASON_CA_COMPROMISE); + pub const AFFILIATION_CHANGED: CrlReason = CrlReason(ffi::CRL_REASON_AFFILIATION_CHANGED); + pub const SUPERSEDED: CrlReason = CrlReason(ffi::CRL_REASON_SUPERSEDED); + pub const CESSATION_OF_OPERATION: CrlReason = CrlReason(ffi::CRL_REASON_CESSATION_OF_OPERATION); + pub const CERTIFICATE_HOLD: CrlReason = CrlReason(ffi::CRL_REASON_CERTIFICATE_HOLD); + pub const REMOVE_FROM_CRL: CrlReason = CrlReason(ffi::CRL_REASON_REMOVE_FROM_CRL); + pub const PRIVILEGE_WITHDRAWN: CrlReason = CrlReason(ffi::CRL_REASON_PRIVILEGE_WITHDRAWN); + pub const AA_COMPROMISE: CrlReason = CrlReason(ffi::CRL_REASON_AA_COMPROMISE); + + /// Constructs an `CrlReason` from a raw OpenSSL value. + pub const fn from_raw(value: c_int) -> Self { + CrlReason(value) + } + + /// Returns the raw OpenSSL value represented by this type. + pub const fn as_raw(&self) -> c_int { + self.0 + } +} + +foreign_type_and_impl_send_sync! { + type CType = ffi::X509_REVOKED; + fn drop = ffi::X509_REVOKED_free; + + /// An `X509` certificate revocation status. + pub struct X509Revoked; + /// Reference to `X509Revoked`. + pub struct X509RevokedRef; +} + +impl Stackable for X509Revoked { + type StackType = ffi::stack_st_X509_REVOKED; +} + +impl X509Revoked { + from_der! { + /// Deserializes a DER-encoded certificate revocation status + #[corresponds(d2i_X509_REVOKED)] + from_der, + X509Revoked, + ffi::d2i_X509_REVOKED + } +} + +impl X509RevokedRef { + to_der! { + /// Serializes the certificate request to a DER-encoded certificate revocation status + #[corresponds(d2i_X509_REVOKED)] + to_der, + ffi::i2d_X509_REVOKED + } + + /// Copies the entry to a new `X509Revoked`. + #[corresponds(X509_NAME_dup)] + #[cfg(any(boringssl, ossl110, libressl270))] + pub fn to_owned(&self) -> Result { + unsafe { cvt_p(ffi::X509_REVOKED_dup(self.as_ptr())).map(|n| X509Revoked::from_ptr(n)) } + } + + /// Get the date that the certificate was revoked + #[corresponds(X509_REVOKED_get0_revocationDate)] + pub fn revocation_date(&self) -> &Asn1TimeRef { + unsafe { + let r = X509_REVOKED_get0_revocationDate(self.as_ptr() as *const _); + assert!(!r.is_null()); + Asn1TimeRef::from_ptr(r as *mut _) + } + } + + /// Get the serial number of the revoked certificate + #[corresponds(X509_REVOKED_get0_serialNumber)] + pub fn serial_number(&self) -> &Asn1IntegerRef { + unsafe { + let r = X509_REVOKED_get0_serialNumber(self.as_ptr() as *const _); + assert!(!r.is_null()); + Asn1IntegerRef::from_ptr(r as *mut _) + } + } + + /// Get the criticality and value of an extension. + /// + /// This returns None if the extension is not present or occurs multiple times. + #[corresponds(X509_REVOKED_get_ext_d2i)] + pub fn extension(&self) -> Result, ErrorStack> { + let mut critical = -1; + let out = unsafe { + // SAFETY: self.as_ptr() is a valid pointer to an X509_REVOKED. + let ext = ffi::X509_REVOKED_get_ext_d2i( + self.as_ptr(), + T::NID.as_raw(), + &mut critical as *mut _, + ptr::null_mut(), + ); + // SAFETY: Extensions's contract promises that the type returned by + // OpenSSL here is T::Output. + T::Output::from_ptr_opt(ext as *mut _) + }; + match (critical, out) { + (0, Some(out)) => Ok(Some((false, out))), + (1, Some(out)) => Ok(Some((true, out))), + // -1 means the extension wasn't found, -2 means multiple were found. + (-1 | -2, _) => Ok(None), + // A critical value of 0 or 1 suggests success, but a null pointer + // was returned so something went wrong. + (0 | 1, None) => Err(ErrorStack::get()), + (c_int::MIN..=-2 | 2.., _) => panic!("OpenSSL should only return -2, -1, 0, or 1 for an extension's criticality but it returned {}", critical), + } + } +} + +/// The CRL entry extension identifying the reason for revocation see [`CrlReason`], +/// this is as defined in RFC 5280 Section 5.3.1. +pub enum ReasonCode {} + +// SAFETY: CertificateIssuer is defined to be a stack of GeneralName in the RFC +// and in OpenSSL. +unsafe impl ExtensionType for ReasonCode { + const NID: Nid = Nid::from_raw(ffi::NID_crl_reason); + + type Output = Asn1Enumerated; +} + +/// The CRL entry extension identifying the issuer of a certificate used in +/// indirect CRLs, as defined in RFC 5280 Section 5.3.3. +pub enum CertificateIssuer {} + +// SAFETY: CertificateIssuer is defined to be a stack of GeneralName in the RFC +// and in OpenSSL. +unsafe impl ExtensionType for CertificateIssuer { + const NID: Nid = Nid::from_raw(ffi::NID_certificate_issuer); + + type Output = Stack; +} + +/// The CRL extension identifying how to access information and services for the issuer of the CRL +pub enum AuthorityInformationAccess {} + +// SAFETY: AuthorityInformationAccess is defined to be a stack of AccessDescription in the RFC +// and in OpenSSL. +unsafe impl ExtensionType for AuthorityInformationAccess { + const NID: Nid = Nid::from_raw(ffi::NID_info_access); + + type Output = Stack; +} + +foreign_type_and_impl_send_sync! { + type CType = ffi::X509_CRL; + fn drop = ffi::X509_CRL_free; + + /// An `X509` certificate revocation list. + pub struct X509Crl; + /// Reference to `X509Crl`. + pub struct X509CrlRef; +} + +/// The status of a certificate in a revoction list +/// +/// Corresponds to the return value from the [`X509_CRL_get0_by_*`] methods. +/// +/// [`X509_CRL_get0_by_*`]: https://www.openssl.org/docs/man1.1.0/man3/X509_CRL_get0_by_serial.html +pub enum CrlStatus<'a> { + /// The certificate is not present in the list + NotRevoked, + /// The certificate is in the list and is revoked + Revoked(&'a X509RevokedRef), + /// The certificate is in the list, but has the "removeFromCrl" status. + /// + /// This can occur if the certificate was revoked with the "CertificateHold" + /// reason, and has since been unrevoked. + RemoveFromCrl(&'a X509RevokedRef), +} + +impl<'a> CrlStatus<'a> { + // Helper used by the X509_CRL_get0_by_* methods to convert their return + // value to the status enum. + // Safety note: the returned CrlStatus must not outlive the owner of the + // revoked_entry pointer. + unsafe fn from_ffi_status( + status: c_int, + revoked_entry: *mut ffi::X509_REVOKED, + ) -> CrlStatus<'a> { + match status { + 0 => CrlStatus::NotRevoked, + 1 => { + assert!(!revoked_entry.is_null()); + CrlStatus::Revoked(X509RevokedRef::from_ptr(revoked_entry)) + } + 2 => { + assert!(!revoked_entry.is_null()); + CrlStatus::RemoveFromCrl(X509RevokedRef::from_ptr(revoked_entry)) + } + _ => unreachable!( + "{}", + "X509_CRL_get0_by_{{serial,cert}} should only return 0, 1, or 2." + ), + } + } +} + +impl X509Crl { + from_pem! { + /// Deserializes a PEM-encoded Certificate Revocation List + /// + /// The input should have a header of `-----BEGIN X509 CRL-----`. + #[corresponds(PEM_read_bio_X509_CRL)] + from_pem, + X509Crl, + ffi::PEM_read_bio_X509_CRL + } + + from_der! { + /// Deserializes a DER-encoded Certificate Revocation List + #[corresponds(d2i_X509_CRL)] + from_der, + X509Crl, + ffi::d2i_X509_CRL + } +} + +impl X509CrlRef { + to_pem! { + /// Serializes the certificate request to a PEM-encoded Certificate Revocation List. + /// + /// The output will have a header of `-----BEGIN X509 CRL-----`. + #[corresponds(PEM_write_bio_X509_CRL)] + to_pem, + ffi::PEM_write_bio_X509_CRL + } + + to_der! { + /// Serializes the certificate request to a DER-encoded Certificate Revocation List. + #[corresponds(i2d_X509_CRL)] + to_der, + ffi::i2d_X509_CRL + } + + /// Get the stack of revocation entries + pub fn get_revoked(&self) -> Option<&StackRef> { + unsafe { + let revoked = X509_CRL_get_REVOKED(self.as_ptr()); + if revoked.is_null() { + None + } else { + Some(StackRef::from_ptr(revoked)) + } + } + } + + /// Returns the CRL's `lastUpdate` time. + #[corresponds(X509_CRL_get0_lastUpdate)] + pub fn last_update(&self) -> &Asn1TimeRef { + unsafe { + let date = X509_CRL_get0_lastUpdate(self.as_ptr()); + assert!(!date.is_null()); + Asn1TimeRef::from_ptr(date as *mut _) + } + } + + /// Returns the CRL's `nextUpdate` time. + /// + /// If the `nextUpdate` field is missing, returns `None`. + #[corresponds(X509_CRL_get0_nextUpdate)] + pub fn next_update(&self) -> Option<&Asn1TimeRef> { + unsafe { + let date = X509_CRL_get0_nextUpdate(self.as_ptr()); + Asn1TimeRef::from_const_ptr_opt(date) + } + } + + /// Get the revocation status of a certificate by its serial number + #[corresponds(X509_CRL_get0_by_serial)] + pub fn get_by_serial<'a>(&'a self, serial: &Asn1IntegerRef) -> CrlStatus<'a> { + unsafe { + let mut ret = ptr::null_mut::(); + let status = + ffi::X509_CRL_get0_by_serial(self.as_ptr(), &mut ret as *mut _, serial.as_ptr()); + CrlStatus::from_ffi_status(status, ret) + } + } + + /// Get the revocation status of a certificate + #[corresponds(X509_CRL_get0_by_cert)] + pub fn get_by_cert<'a>(&'a self, cert: &X509) -> CrlStatus<'a> { + unsafe { + let mut ret = ptr::null_mut::(); + let status = + ffi::X509_CRL_get0_by_cert(self.as_ptr(), &mut ret as *mut _, cert.as_ptr()); + CrlStatus::from_ffi_status(status, ret) + } + } + + /// Get the issuer name from the revocation list. + #[corresponds(X509_CRL_get_issuer)] + pub fn issuer_name(&self) -> &X509NameRef { + unsafe { + let name = X509_CRL_get_issuer(self.as_ptr()); + assert!(!name.is_null()); + X509NameRef::from_ptr(name) + } + } + + /// Check if the CRL is signed using the given public key. + /// + /// Only the signature is checked: no other checks (such as certificate chain validity) + /// are performed. + /// + /// Returns `true` if verification succeeds. + #[corresponds(X509_CRL_verify)] + pub fn verify(&self, key: &PKeyRef) -> Result + where + T: HasPublic, + { + unsafe { cvt_n(ffi::X509_CRL_verify(self.as_ptr(), key.as_ptr())).map(|n| n != 0) } + } + + /// Get the criticality and value of an extension. + /// + /// This returns None if the extension is not present or occurs multiple times. + #[corresponds(X509_CRL_get_ext_d2i)] + pub fn extension(&self) -> Result, ErrorStack> { + let mut critical = -1; + let out = unsafe { + // SAFETY: self.as_ptr() is a valid pointer to an X509_CRL. + let ext = ffi::X509_CRL_get_ext_d2i( + self.as_ptr(), + T::NID.as_raw(), + &mut critical as *mut _, + ptr::null_mut(), + ); + // SAFETY: Extensions's contract promises that the type returned by + // OpenSSL here is T::Output. + T::Output::from_ptr_opt(ext as *mut _) + }; + match (critical, out) { + (0, Some(out)) => Ok(Some((false, out))), + (1, Some(out)) => Ok(Some((true, out))), + // -1 means the extension wasn't found, -2 means multiple were found. + (-1 | -2, _) => Ok(None), + // A critical value of 0 or 1 suggests success, but a null pointer + // was returned so something went wrong. + (0 | 1, None) => Err(ErrorStack::get()), + (c_int::MIN..=-2 | 2.., _) => panic!("OpenSSL should only return -2, -1, 0, or 1 for an extension's criticality but it returned {}", critical), + } + } +} + +/// The result of peer certificate verification. +#[derive(Copy, Clone, PartialEq, Eq)] +pub struct X509VerifyResult(c_int); + +impl fmt::Debug for X509VerifyResult { + fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { + fmt.debug_struct("X509VerifyResult") + .field("code", &self.0) + .field("error", &self.error_string()) + .finish() + } +} + +impl fmt::Display for X509VerifyResult { + fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { + fmt.write_str(self.error_string()) + } +} + +impl Error for X509VerifyResult {} + +impl X509VerifyResult { + /// Creates an `X509VerifyResult` from a raw error number. + /// + /// # Safety + /// + /// Some methods on `X509VerifyResult` are not thread safe if the error + /// number is invalid. + pub unsafe fn from_raw(err: c_int) -> X509VerifyResult { + X509VerifyResult(err) + } + + /// Return the integer representation of an `X509VerifyResult`. + #[allow(clippy::trivially_copy_pass_by_ref)] + pub fn as_raw(&self) -> c_int { + self.0 + } + + /// Return a human readable error string from the verification error. + #[corresponds(X509_verify_cert_error_string)] + #[allow(clippy::trivially_copy_pass_by_ref)] + pub fn error_string(&self) -> &'static str { + ffi::init(); + + unsafe { + let s = ffi::X509_verify_cert_error_string(self.0 as c_long); + str::from_utf8(CStr::from_ptr(s).to_bytes()).unwrap() + } + } + + /// Successful peer certificate verification. + pub const OK: X509VerifyResult = X509VerifyResult(ffi::X509_V_OK); + /// Application verification failure. + pub const APPLICATION_VERIFICATION: X509VerifyResult = + X509VerifyResult(ffi::X509_V_ERR_APPLICATION_VERIFICATION); +} + +foreign_type_and_impl_send_sync! { + type CType = ffi::GENERAL_NAME; + fn drop = ffi::GENERAL_NAME_free; + + /// An `X509` certificate alternative names. + pub struct GeneralName; + /// Reference to `GeneralName`. + pub struct GeneralNameRef; +} + +impl GeneralName { + unsafe fn new( + type_: c_int, + asn1_type: Asn1Type, + value: &[u8], + ) -> Result { + ffi::init(); + let gn = GeneralName::from_ptr(cvt_p(ffi::GENERAL_NAME_new())?); + (*gn.as_ptr()).type_ = type_; + let s = cvt_p(ffi::ASN1_STRING_type_new(asn1_type.as_raw()))?; + ffi::ASN1_STRING_set(s, value.as_ptr().cast(), value.len().try_into().unwrap()); + + #[cfg(boringssl)] + { + (*gn.as_ptr()).d.ptr = s.cast(); + } + #[cfg(not(boringssl))] + { + (*gn.as_ptr()).d = s.cast(); + } + + Ok(gn) + } + + pub(crate) fn new_email(email: &[u8]) -> Result { + unsafe { GeneralName::new(ffi::GEN_EMAIL, Asn1Type::IA5STRING, email) } + } + + pub(crate) fn new_dns(dns: &[u8]) -> Result { + unsafe { GeneralName::new(ffi::GEN_DNS, Asn1Type::IA5STRING, dns) } + } + + pub(crate) fn new_uri(uri: &[u8]) -> Result { + unsafe { GeneralName::new(ffi::GEN_URI, Asn1Type::IA5STRING, uri) } + } + + pub(crate) fn new_ip(ip: IpAddr) -> Result { + match ip { + IpAddr::V4(addr) => unsafe { + GeneralName::new(ffi::GEN_IPADD, Asn1Type::OCTET_STRING, &addr.octets()) + }, + IpAddr::V6(addr) => unsafe { + GeneralName::new(ffi::GEN_IPADD, Asn1Type::OCTET_STRING, &addr.octets()) + }, + } + } + + pub(crate) fn new_rid(oid: Asn1Object) -> Result { + unsafe { + ffi::init(); + let gn = cvt_p(ffi::GENERAL_NAME_new())?; + (*gn).type_ = ffi::GEN_RID; + + #[cfg(boringssl)] + { + (*gn).d.registeredID = oid.as_ptr(); + } + #[cfg(not(boringssl))] + { + (*gn).d = oid.as_ptr().cast(); + } + + mem::forget(oid); + + Ok(GeneralName::from_ptr(gn)) + } + } + + pub(crate) fn new_other_name(oid: Asn1Object, value: &[u8]) -> Result { + unsafe { + ffi::init(); + + let typ = cvt_p(ffi::d2i_ASN1_TYPE( + ptr::null_mut(), + &mut value.as_ptr().cast(), + value.len().try_into().unwrap(), + ))?; + + let gn = cvt_p(ffi::GENERAL_NAME_new())?; + (*gn).type_ = ffi::GEN_OTHERNAME; + + if let Err(e) = cvt(ffi::GENERAL_NAME_set0_othername( + gn, + oid.as_ptr().cast(), + typ, + )) { + ffi::GENERAL_NAME_free(gn); + return Err(e); + } + + mem::forget(oid); + + Ok(GeneralName::from_ptr(gn)) + } + } +} + +impl GeneralNameRef { + fn ia5_string(&self, ffi_type: c_int) -> Option<&str> { + unsafe { + if (*self.as_ptr()).type_ != ffi_type { + return None; + } + + #[cfg(boringssl)] + let d = (*self.as_ptr()).d.ptr; + #[cfg(not(boringssl))] + let d = (*self.as_ptr()).d; + + let ptr = ASN1_STRING_get0_data(d as *mut _); + let len = ffi::ASN1_STRING_length(d as *mut _); + + #[allow(clippy::unnecessary_cast)] + let slice = util::from_raw_parts(ptr as *const u8, len as usize); + // IA5Strings are stated to be ASCII (specifically IA5). Hopefully + // OpenSSL checks that when loading a certificate but if not we'll + // use this instead of from_utf8_unchecked just in case. + str::from_utf8(slice).ok() + } + } + + /// Returns the contents of this `GeneralName` if it is an `rfc822Name`. + pub fn email(&self) -> Option<&str> { + self.ia5_string(ffi::GEN_EMAIL) + } + + /// Returns the contents of this `GeneralName` if it is a `directoryName`. + pub fn directory_name(&self) -> Option<&X509NameRef> { + unsafe { + if (*self.as_ptr()).type_ != ffi::GEN_DIRNAME { + return None; + } + + #[cfg(boringssl)] + let d = (*self.as_ptr()).d.ptr; + #[cfg(not(boringssl))] + let d = (*self.as_ptr()).d; + + Some(X509NameRef::from_const_ptr(d as *const _)) + } + } + + /// Returns the contents of this `GeneralName` if it is a `dNSName`. + pub fn dnsname(&self) -> Option<&str> { + self.ia5_string(ffi::GEN_DNS) + } + + /// Returns the contents of this `GeneralName` if it is an `uniformResourceIdentifier`. + pub fn uri(&self) -> Option<&str> { + self.ia5_string(ffi::GEN_URI) + } + + /// Returns the contents of this `GeneralName` if it is an `iPAddress`. + pub fn ipaddress(&self) -> Option<&[u8]> { + unsafe { + if (*self.as_ptr()).type_ != ffi::GEN_IPADD { + return None; + } + #[cfg(boringssl)] + let d: *const ffi::ASN1_STRING = std::mem::transmute((*self.as_ptr()).d); + #[cfg(not(boringssl))] + let d = (*self.as_ptr()).d; + + let ptr = ASN1_STRING_get0_data(d as *mut _); + let len = ffi::ASN1_STRING_length(d as *mut _); + + #[allow(clippy::unnecessary_cast)] + Some(util::from_raw_parts(ptr as *const u8, len as usize)) + } + } +} + +impl fmt::Debug for GeneralNameRef { + fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { + if let Some(email) = self.email() { + formatter.write_str(email) + } else if let Some(dnsname) = self.dnsname() { + formatter.write_str(dnsname) + } else if let Some(uri) = self.uri() { + formatter.write_str(uri) + } else if let Some(ipaddress) = self.ipaddress() { + let address = <[u8; 16]>::try_from(ipaddress) + .map(IpAddr::from) + .or_else(|_| <[u8; 4]>::try_from(ipaddress).map(IpAddr::from)); + match address { + Ok(a) => fmt::Debug::fmt(&a, formatter), + Err(_) => fmt::Debug::fmt(ipaddress, formatter), + } + } else { + formatter.write_str("(empty)") + } + } +} + +impl Stackable for GeneralName { + type StackType = ffi::stack_st_GENERAL_NAME; +} + +foreign_type_and_impl_send_sync! { + type CType = ffi::DIST_POINT; + fn drop = ffi::DIST_POINT_free; + + /// A `X509` distribution point. + pub struct DistPoint; + /// Reference to `DistPoint`. + pub struct DistPointRef; +} + +impl DistPointRef { + /// Returns the name of this distribution point if it exists + pub fn distpoint(&self) -> Option<&DistPointNameRef> { + unsafe { DistPointNameRef::from_const_ptr_opt((*self.as_ptr()).distpoint) } + } +} + +foreign_type_and_impl_send_sync! { + type CType = ffi::DIST_POINT_NAME; + fn drop = ffi::DIST_POINT_NAME_free; + + /// A `X509` distribution point. + pub struct DistPointName; + /// Reference to `DistPointName`. + pub struct DistPointNameRef; +} + +impl DistPointNameRef { + /// Returns the contents of this DistPointName if it is a fullname. + pub fn fullname(&self) -> Option<&StackRef> { + unsafe { + if (*self.as_ptr()).type_ != 0 { + return None; + } + StackRef::from_const_ptr_opt((*self.as_ptr()).name.fullname) + } + } +} + +impl Stackable for DistPoint { + type StackType = ffi::stack_st_DIST_POINT; +} + +foreign_type_and_impl_send_sync! { + type CType = ffi::ACCESS_DESCRIPTION; + fn drop = ffi::ACCESS_DESCRIPTION_free; + + /// `AccessDescription` of certificate authority information. + pub struct AccessDescription; + /// Reference to `AccessDescription`. + pub struct AccessDescriptionRef; +} + +impl AccessDescriptionRef { + /// Returns the access method OID. + pub fn method(&self) -> &Asn1ObjectRef { + unsafe { Asn1ObjectRef::from_ptr((*self.as_ptr()).method) } + } + + // Returns the access location. + pub fn location(&self) -> &GeneralNameRef { + unsafe { GeneralNameRef::from_ptr((*self.as_ptr()).location) } + } +} + +impl Stackable for AccessDescription { + type StackType = ffi::stack_st_ACCESS_DESCRIPTION; +} + +foreign_type_and_impl_send_sync! { + type CType = ffi::X509_ALGOR; + fn drop = ffi::X509_ALGOR_free; + + /// An `X509` certificate signature algorithm. + pub struct X509Algorithm; + /// Reference to `X509Algorithm`. + pub struct X509AlgorithmRef; +} + +impl X509AlgorithmRef { + /// Returns the ASN.1 OID of this algorithm. + pub fn object(&self) -> &Asn1ObjectRef { + unsafe { + let mut oid = ptr::null(); + X509_ALGOR_get0(&mut oid, ptr::null_mut(), ptr::null_mut(), self.as_ptr()); + Asn1ObjectRef::from_const_ptr_opt(oid).expect("algorithm oid must not be null") + } + } +} + +foreign_type_and_impl_send_sync! { + type CType = ffi::X509_OBJECT; + fn drop = X509_OBJECT_free; + + /// An `X509` or an X509 certificate revocation list. + pub struct X509Object; + /// Reference to `X509Object` + pub struct X509ObjectRef; +} + +impl X509ObjectRef { + pub fn x509(&self) -> Option<&X509Ref> { + unsafe { + let ptr = X509_OBJECT_get0_X509(self.as_ptr()); + X509Ref::from_const_ptr_opt(ptr) + } + } +} + +impl Stackable for X509Object { + type StackType = ffi::stack_st_X509_OBJECT; +} + +cfg_if! { + if #[cfg(any(boringssl, ossl110, libressl273))] { + use ffi::{X509_getm_notAfter, X509_getm_notBefore, X509_up_ref, X509_get0_signature}; + } else { + #[allow(bad_style)] + unsafe fn X509_getm_notAfter(x: *mut ffi::X509) -> *mut ffi::ASN1_TIME { + (*(*(*x).cert_info).validity).notAfter + } + + #[allow(bad_style)] + unsafe fn X509_getm_notBefore(x: *mut ffi::X509) -> *mut ffi::ASN1_TIME { + (*(*(*x).cert_info).validity).notBefore + } + + #[allow(bad_style)] + unsafe fn X509_up_ref(x: *mut ffi::X509) { + ffi::CRYPTO_add_lock( + &mut (*x).references, + 1, + ffi::CRYPTO_LOCK_X509, + "mod.rs\0".as_ptr() as *const _, + line!() as c_int, + ); + } + + #[allow(bad_style)] + unsafe fn X509_get0_signature( + psig: *mut *const ffi::ASN1_BIT_STRING, + palg: *mut *const ffi::X509_ALGOR, + x: *const ffi::X509, + ) { + if !psig.is_null() { + *psig = (*x).signature; + } + if !palg.is_null() { + *palg = (*x).sig_alg; + } + } + } +} + +cfg_if! { + if #[cfg(any(boringssl, ossl110, libressl350))] { + use ffi::{ + X509_ALGOR_get0, ASN1_STRING_get0_data, X509_STORE_CTX_get0_chain, X509_set1_notAfter, + X509_set1_notBefore, X509_REQ_get_version, X509_REQ_get_subject_name, + }; + } else { + use ffi::{ + ASN1_STRING_data as ASN1_STRING_get0_data, + X509_STORE_CTX_get_chain as X509_STORE_CTX_get0_chain, + X509_set_notAfter as X509_set1_notAfter, + X509_set_notBefore as X509_set1_notBefore, + }; + + #[allow(bad_style)] + unsafe fn X509_REQ_get_version(x: *mut ffi::X509_REQ) -> ::libc::c_long { + ffi::ASN1_INTEGER_get((*(*x).req_info).version) + } + + #[allow(bad_style)] + unsafe fn X509_REQ_get_subject_name(x: *mut ffi::X509_REQ) -> *mut ::ffi::X509_NAME { + (*(*x).req_info).subject + } + + #[allow(bad_style)] + unsafe fn X509_ALGOR_get0( + paobj: *mut *const ffi::ASN1_OBJECT, + pptype: *mut c_int, + pval: *mut *mut ::libc::c_void, + alg: *const ffi::X509_ALGOR, + ) { + if !paobj.is_null() { + *paobj = (*alg).algorithm; + } + assert!(pptype.is_null()); + assert!(pval.is_null()); + } + } +} + +cfg_if! { + if #[cfg(any(ossl110, boringssl, libressl270))] { + use ffi::X509_OBJECT_get0_X509; + } else { + #[allow(bad_style)] + unsafe fn X509_OBJECT_get0_X509(x: *mut ffi::X509_OBJECT) -> *mut ffi::X509 { + if (*x).type_ == ffi::X509_LU_X509 { + (*x).data.x509 + } else { + ptr::null_mut() + } + } + } +} + +cfg_if! { + if #[cfg(any(ossl110, libressl350, boringssl))] { + use ffi::X509_OBJECT_free; + } else { + #[allow(bad_style)] + unsafe fn X509_OBJECT_free(x: *mut ffi::X509_OBJECT) { + ffi::X509_OBJECT_free_contents(x); + ffi::CRYPTO_free(x as *mut libc::c_void); + } + } +} + +cfg_if! { + if #[cfg(any(ossl110, libressl350, boringssl))] { + use ffi::{ + X509_CRL_get_issuer, X509_CRL_get0_nextUpdate, X509_CRL_get0_lastUpdate, + X509_CRL_get_REVOKED, + X509_REVOKED_get0_revocationDate, X509_REVOKED_get0_serialNumber, + }; + } else { + #[allow(bad_style)] + unsafe fn X509_CRL_get0_lastUpdate(x: *const ffi::X509_CRL) -> *mut ffi::ASN1_TIME { + (*(*x).crl).lastUpdate + } + #[allow(bad_style)] + unsafe fn X509_CRL_get0_nextUpdate(x: *const ffi::X509_CRL) -> *mut ffi::ASN1_TIME { + (*(*x).crl).nextUpdate + } + #[allow(bad_style)] + unsafe fn X509_CRL_get_issuer(x: *const ffi::X509_CRL) -> *mut ffi::X509_NAME { + (*(*x).crl).issuer + } + #[allow(bad_style)] + unsafe fn X509_CRL_get_REVOKED(x: *const ffi::X509_CRL) -> *mut ffi::stack_st_X509_REVOKED { + (*(*x).crl).revoked + } + #[allow(bad_style)] + unsafe fn X509_REVOKED_get0_serialNumber(x: *const ffi::X509_REVOKED) -> *mut ffi::ASN1_INTEGER { + (*x).serialNumber + } + #[allow(bad_style)] + unsafe fn X509_REVOKED_get0_revocationDate(x: *const ffi::X509_REVOKED) -> *mut ffi::ASN1_TIME { + (*x).revocationDate + } + } +} + +#[derive(Copy, Clone, PartialEq, Eq)] +pub struct X509PurposeId(c_int); + +impl X509PurposeId { + pub const SSL_CLIENT: X509PurposeId = X509PurposeId(ffi::X509_PURPOSE_SSL_CLIENT); + pub const SSL_SERVER: X509PurposeId = X509PurposeId(ffi::X509_PURPOSE_SSL_SERVER); + pub const NS_SSL_SERVER: X509PurposeId = X509PurposeId(ffi::X509_PURPOSE_NS_SSL_SERVER); + pub const SMIME_SIGN: X509PurposeId = X509PurposeId(ffi::X509_PURPOSE_SMIME_SIGN); + pub const SMIME_ENCRYPT: X509PurposeId = X509PurposeId(ffi::X509_PURPOSE_SMIME_ENCRYPT); + pub const CRL_SIGN: X509PurposeId = X509PurposeId(ffi::X509_PURPOSE_CRL_SIGN); + pub const ANY: X509PurposeId = X509PurposeId(ffi::X509_PURPOSE_ANY); + pub const OCSP_HELPER: X509PurposeId = X509PurposeId(ffi::X509_PURPOSE_OCSP_HELPER); + pub const TIMESTAMP_SIGN: X509PurposeId = X509PurposeId(ffi::X509_PURPOSE_TIMESTAMP_SIGN); + #[cfg(ossl320)] + pub const CODE_SIGN: X509PurposeId = X509PurposeId(ffi::X509_PURPOSE_CODE_SIGN); + + /// Constructs an `X509PurposeId` from a raw OpenSSL value. + pub fn from_raw(id: c_int) -> Self { + X509PurposeId(id) + } + + /// Returns the raw OpenSSL value represented by this type. + pub fn as_raw(&self) -> c_int { + self.0 + } +} + +/// A reference to an [`X509_PURPOSE`]. +pub struct X509PurposeRef(Opaque); + +/// Implements a wrapper type for the static `X509_PURPOSE` table in OpenSSL. +impl ForeignTypeRef for X509PurposeRef { + type CType = ffi::X509_PURPOSE; +} + +impl X509PurposeRef { + /// Get the internal table index of an X509_PURPOSE for a given short name. Valid short + /// names include + /// - "sslclient", + /// - "sslserver", + /// - "nssslserver", + /// - "smimesign", + /// - "smimeencrypt", + /// - "crlsign", + /// - "any", + /// - "ocsphelper", + /// - "timestampsign" + /// + /// The index can be used with `X509PurposeRef::from_idx()` to get the purpose. + #[allow(clippy::unnecessary_cast)] + pub fn get_by_sname(sname: &str) -> Result { + unsafe { + let sname = CString::new(sname).unwrap(); + cfg_if! { + if #[cfg(any(ossl110, libressl280, boringssl))] { + let purpose = cvt_n(ffi::X509_PURPOSE_get_by_sname(sname.as_ptr() as *const _))?; + } else { + let purpose = cvt_n(ffi::X509_PURPOSE_get_by_sname(sname.as_ptr() as *mut _))?; + } + } + Ok(purpose) + } + } + /// Get an `X509PurposeRef` for a given index value. The index can be obtained from e.g. + /// `X509PurposeRef::get_by_sname()`. + #[corresponds(X509_PURPOSE_get0)] + pub fn from_idx(idx: c_int) -> Result<&'static X509PurposeRef, ErrorStack> { + unsafe { + let ptr = cvt_p_const(ffi::X509_PURPOSE_get0(idx))?; + Ok(X509PurposeRef::from_const_ptr(ptr)) + } + } + + /// Get the purpose value from an X509Purpose structure. This value is one of + /// - `X509_PURPOSE_SSL_CLIENT` + /// - `X509_PURPOSE_SSL_SERVER` + /// - `X509_PURPOSE_NS_SSL_SERVER` + /// - `X509_PURPOSE_SMIME_SIGN` + /// - `X509_PURPOSE_SMIME_ENCRYPT` + /// - `X509_PURPOSE_CRL_SIGN` + /// - `X509_PURPOSE_ANY` + /// - `X509_PURPOSE_OCSP_HELPER` + /// - `X509_PURPOSE_TIMESTAMP_SIGN` + pub fn purpose(&self) -> X509PurposeId { + unsafe { + cfg_if! { + if #[cfg(any(ossl110, libressl280, boringssl))] { + let x509_purpose = self.as_ptr() as *const ffi::X509_PURPOSE; + } else { + let x509_purpose = self.as_ptr() as *mut ffi::X509_PURPOSE; + } + } + X509PurposeId::from_raw(ffi::X509_PURPOSE_get_id(x509_purpose)) + } + } +} diff --git a/vendor/openssl/src/x509/store.rs b/vendor/openssl/src/x509/store.rs new file mode 100644 index 0000000..3a173be --- /dev/null +++ b/vendor/openssl/src/x509/store.rs @@ -0,0 +1,304 @@ +//! Describe a context in which to verify an `X509` certificate. +//! +//! The `X509` certificate store holds trusted CA certificates used to verify +//! peer certificates. +//! +//! # Example +//! +//! ```rust +//! use openssl::x509::store::{X509StoreBuilder, X509Store}; +//! use openssl::x509::{X509, X509Name}; +//! use openssl::asn1::Asn1Time; +//! use openssl::pkey::PKey; +//! use openssl::hash::MessageDigest; +//! use openssl::rsa::Rsa; +//! use openssl::nid::Nid; +//! +//! let rsa = Rsa::generate(2048).unwrap(); +//! let pkey = PKey::from_rsa(rsa).unwrap(); +//! +//! let mut name = X509Name::builder().unwrap(); +//! name.append_entry_by_nid(Nid::COMMONNAME, "foobar.com").unwrap(); +//! let name = name.build(); +//! +//! // Sep 27th, 2016 +//! let sample_time = Asn1Time::from_unix(1474934400).unwrap(); +//! +//! let mut builder = X509::builder().unwrap(); +//! builder.set_version(2).unwrap(); +//! builder.set_subject_name(&name).unwrap(); +//! builder.set_issuer_name(&name).unwrap(); +//! builder.set_pubkey(&pkey).unwrap(); +//! builder.set_not_before(&sample_time); +//! builder.set_not_after(&sample_time); +//! builder.sign(&pkey, MessageDigest::sha256()).unwrap(); +//! +//! let certificate: X509 = builder.build(); +//! +//! let mut builder = X509StoreBuilder::new().unwrap(); +//! let _ = builder.add_cert(certificate); +//! +//! let store: X509Store = builder.build(); +//! ``` + +use cfg_if::cfg_if; +use foreign_types::{ForeignType, ForeignTypeRef}; +use std::mem; + +use crate::error::ErrorStack; +#[cfg(not(boringssl))] +use crate::ssl::SslFiletype; +#[cfg(ossl300)] +use crate::stack::Stack; +use crate::stack::StackRef; +use crate::util::ForeignTypeRefExt; +#[cfg(any(ossl102, boringssl, libressl261))] +use crate::x509::verify::{X509VerifyFlags, X509VerifyParamRef}; +use crate::x509::{X509Object, X509PurposeId, X509}; +use crate::{cvt, cvt_p}; +use openssl_macros::corresponds; +#[cfg(not(boringssl))] +use std::ffi::CString; +#[cfg(not(boringssl))] +use std::path::Path; + +foreign_type_and_impl_send_sync! { + type CType = ffi::X509_STORE; + fn drop = ffi::X509_STORE_free; + + /// A builder type used to construct an `X509Store`. + pub struct X509StoreBuilder; + /// A reference to an [`X509StoreBuilder`]. + pub struct X509StoreBuilderRef; +} + +impl X509StoreBuilder { + /// Returns a builder for a certificate store. + /// + /// The store is initially empty. + #[corresponds(X509_STORE_new)] + pub fn new() -> Result { + unsafe { + ffi::init(); + + cvt_p(ffi::X509_STORE_new()).map(X509StoreBuilder) + } + } + + /// Constructs the `X509Store`. + pub fn build(self) -> X509Store { + let store = X509Store(self.0); + mem::forget(self); + store + } +} + +impl X509StoreBuilderRef { + /// Adds a certificate to the certificate store. + // FIXME should take an &X509Ref + #[corresponds(X509_STORE_add_cert)] + pub fn add_cert(&mut self, cert: X509) -> Result<(), ErrorStack> { + unsafe { cvt(ffi::X509_STORE_add_cert(self.as_ptr(), cert.as_ptr())).map(|_| ()) } + } + + /// Load certificates from their default locations. + /// + /// These locations are read from the `SSL_CERT_FILE` and `SSL_CERT_DIR` + /// environment variables if present, or defaults specified at OpenSSL + /// build time otherwise. + #[corresponds(X509_STORE_set_default_paths)] + pub fn set_default_paths(&mut self) -> Result<(), ErrorStack> { + unsafe { cvt(ffi::X509_STORE_set_default_paths(self.as_ptr())).map(|_| ()) } + } + + /// Adds a lookup method to the store. + #[corresponds(X509_STORE_add_lookup)] + pub fn add_lookup( + &mut self, + method: &'static X509LookupMethodRef, + ) -> Result<&mut X509LookupRef, ErrorStack> { + let lookup = unsafe { ffi::X509_STORE_add_lookup(self.as_ptr(), method.as_ptr()) }; + cvt_p(lookup).map(|ptr| unsafe { X509LookupRef::from_ptr_mut(ptr) }) + } + + /// Sets certificate chain validation related flags. + #[corresponds(X509_STORE_set_flags)] + #[cfg(any(ossl102, boringssl, libressl261))] + pub fn set_flags(&mut self, flags: X509VerifyFlags) -> Result<(), ErrorStack> { + unsafe { cvt(ffi::X509_STORE_set_flags(self.as_ptr(), flags.bits())).map(|_| ()) } + } + + /// Sets the certificate purpose. + /// The purpose value can be obtained by `X509PurposeRef::get_by_sname()` + #[corresponds(X509_STORE_set_purpose)] + pub fn set_purpose(&mut self, purpose: X509PurposeId) -> Result<(), ErrorStack> { + unsafe { cvt(ffi::X509_STORE_set_purpose(self.as_ptr(), purpose.as_raw())).map(|_| ()) } + } + + /// Sets certificate chain validation related parameters. + #[corresponds[X509_STORE_set1_param]] + #[cfg(any(ossl102, boringssl, libressl261))] + pub fn set_param(&mut self, param: &X509VerifyParamRef) -> Result<(), ErrorStack> { + unsafe { cvt(ffi::X509_STORE_set1_param(self.as_ptr(), param.as_ptr())).map(|_| ()) } + } +} + +generic_foreign_type_and_impl_send_sync! { + type CType = ffi::X509_LOOKUP; + fn drop = ffi::X509_LOOKUP_free; + + /// Information used by an `X509Store` to look up certificates and CRLs. + pub struct X509Lookup; + /// A reference to an [`X509Lookup`]. + pub struct X509LookupRef; +} + +/// Marker type corresponding to the [`X509_LOOKUP_hash_dir`] lookup method. +/// +/// [`X509_LOOKUP_hash_dir`]: https://www.openssl.org/docs/manmaster/crypto/X509_LOOKUP_hash_dir.html +// FIXME should be an enum +pub struct HashDir; + +impl X509Lookup { + /// Lookup method that loads certificates and CRLs on demand and caches + /// them in memory once they are loaded. It also checks for newer CRLs upon + /// each lookup, so that newer CRLs are used as soon as they appear in the + /// directory. + #[corresponds(X509_LOOKUP_hash_dir)] + pub fn hash_dir() -> &'static X509LookupMethodRef { + unsafe { X509LookupMethodRef::from_const_ptr(ffi::X509_LOOKUP_hash_dir()) } + } +} + +#[cfg(not(boringssl))] +impl X509LookupRef { + /// Specifies a directory from which certificates and CRLs will be loaded + /// on-demand. Must be used with `X509Lookup::hash_dir`. + #[corresponds(X509_LOOKUP_add_dir)] + pub fn add_dir(&mut self, name: &str, file_type: SslFiletype) -> Result<(), ErrorStack> { + let name = CString::new(name).unwrap(); + unsafe { + cvt(ffi::X509_LOOKUP_add_dir( + self.as_ptr(), + name.as_ptr(), + file_type.as_raw(), + )) + .map(|_| ()) + } + } +} + +/// Marker type corresponding to the [`X509_LOOKUP_file`] lookup method. +/// +/// [`X509_LOOKUP_file`]: https://www.openssl.org/docs/man1.1.1/man3/X509_LOOKUP_file.html +pub struct File; + +impl X509Lookup { + /// Lookup method loads all the certificates or CRLs present in a file + /// into memory at the time the file is added as a lookup source. + #[corresponds(X509_LOOKUP_file)] + pub fn file() -> &'static X509LookupMethodRef { + unsafe { X509LookupMethodRef::from_const_ptr(ffi::X509_LOOKUP_file()) } + } +} + +#[cfg(not(boringssl))] +impl X509LookupRef { + /// Specifies a file from which certificates will be loaded + #[corresponds(X509_load_cert_file)] + // FIXME should return 'Result>( + &mut self, + file: P, + file_type: SslFiletype, + ) -> Result<(), ErrorStack> { + let file = CString::new(file.as_ref().as_os_str().to_str().unwrap()).unwrap(); + unsafe { + cvt(ffi::X509_load_cert_file( + self.as_ptr(), + file.as_ptr(), + file_type.as_raw(), + )) + .map(|_| ()) + } + } + + /// Specifies a file from which certificate revocation lists will be loaded + #[corresponds(X509_load_crl_file)] + pub fn load_crl_file>( + &mut self, + file: P, + file_type: SslFiletype, + ) -> Result { + let file = CString::new(file.as_ref().as_os_str().to_str().unwrap()).unwrap(); + unsafe { + cvt(ffi::X509_load_crl_file( + self.as_ptr(), + file.as_ptr(), + file_type.as_raw(), + )) + } + } +} + +generic_foreign_type_and_impl_send_sync! { + type CType = ffi::X509_LOOKUP_METHOD; + fn drop = X509_LOOKUP_meth_free; + + /// Method used to look up certificates and CRLs. + pub struct X509LookupMethod; + /// A reference to an [`X509LookupMethod`]. + pub struct X509LookupMethodRef; +} + +foreign_type_and_impl_send_sync! { + type CType = ffi::X509_STORE; + fn drop = ffi::X509_STORE_free; + + /// A certificate store to hold trusted `X509` certificates. + pub struct X509Store; + /// Reference to an `X509Store`. + pub struct X509StoreRef; +} + +impl X509StoreRef { + /// Get a reference to the cache of certificates in this store. + /// + /// This method is deprecated. It is **unsound** and will be removed in a + /// future version of rust-openssl. `X509StoreRef::all_certificates` + /// should be used instead. + #[deprecated( + note = "This method is unsound, and will be removed in a future version of rust-openssl. X509StoreRef::all_certificates should be used instead." + )] + #[corresponds(X509_STORE_get0_objects)] + pub fn objects(&self) -> &StackRef { + unsafe { StackRef::from_ptr(X509_STORE_get0_objects(self.as_ptr())) } + } + + /// Returns a stack of all the certificates in this store. + #[corresponds(X509_STORE_get1_all_certs)] + #[cfg(ossl300)] + pub fn all_certificates(&self) -> Stack { + unsafe { Stack::from_ptr(ffi::X509_STORE_get1_all_certs(self.as_ptr())) } + } +} + +cfg_if! { + if #[cfg(any(boringssl, ossl110, libressl270))] { + use ffi::X509_STORE_get0_objects; + } else { + #[allow(bad_style)] + unsafe fn X509_STORE_get0_objects(x: *mut ffi::X509_STORE) -> *mut ffi::stack_st_X509_OBJECT { + (*x).objs + } + } +} + +cfg_if! { + if #[cfg(ossl110)] { + use ffi::X509_LOOKUP_meth_free; + } else { + #[allow(bad_style)] + unsafe fn X509_LOOKUP_meth_free(_x: *mut ffi::X509_LOOKUP_METHOD) {} + } +} diff --git a/vendor/openssl/src/x509/tests.rs b/vendor/openssl/src/x509/tests.rs new file mode 100644 index 0000000..25c2da0 --- /dev/null +++ b/vendor/openssl/src/x509/tests.rs @@ -0,0 +1,1194 @@ +use std::cmp::Ordering; + +use crate::asn1::{Asn1Object, Asn1OctetString, Asn1Time}; +use crate::bn::{BigNum, MsbOption}; +use crate::hash::MessageDigest; +use crate::nid::Nid; +use crate::pkey::{PKey, Private}; +use crate::rsa::Rsa; +#[cfg(not(boringssl))] +use crate::ssl::SslFiletype; +use crate::stack::Stack; +use crate::x509::extension::{ + AuthorityKeyIdentifier, BasicConstraints, ExtendedKeyUsage, KeyUsage, SubjectAlternativeName, + SubjectKeyIdentifier, +}; +#[cfg(not(boringssl))] +use crate::x509::store::X509Lookup; +use crate::x509::store::X509StoreBuilder; +#[cfg(any(ossl102, boringssl, libressl261))] +use crate::x509::verify::{X509VerifyFlags, X509VerifyParam}; +#[cfg(any(ossl102, boringssl))] +use crate::x509::X509PurposeId; +#[cfg(any(ossl102, boringssl, libressl261))] +use crate::x509::X509PurposeRef; +#[cfg(ossl110)] +use crate::x509::{CrlReason, X509Builder}; +use crate::x509::{ + CrlStatus, X509Crl, X509Extension, X509Name, X509Req, X509StoreContext, X509VerifyResult, X509, +}; + +#[cfg(ossl110)] +use foreign_types::ForeignType; +use hex::{self, FromHex}; +#[cfg(any(ossl102, boringssl, libressl261))] +use libc::time_t; + +use super::{AuthorityInformationAccess, CertificateIssuer, ReasonCode}; + +fn pkey() -> PKey { + let rsa = Rsa::generate(2048).unwrap(); + PKey::from_rsa(rsa).unwrap() +} + +#[test] +fn test_cert_loading() { + let cert = include_bytes!("../../test/cert.pem"); + let cert = X509::from_pem(cert).unwrap(); + let fingerprint = cert.digest(MessageDigest::sha1()).unwrap(); + + let hash_str = "59172d9313e84459bcff27f967e79e6e9217e584"; + let hash_vec = Vec::from_hex(hash_str).unwrap(); + + assert_eq!(hash_vec, &*fingerprint); +} + +#[test] +fn test_debug() { + let cert = include_bytes!("../../test/cert.pem"); + let cert = X509::from_pem(cert).unwrap(); + let debugged = format!("{:#?}", cert); + #[cfg(boringssl)] + assert!(debugged.contains(r#"serial_number: "8771f7bdee982fa5""#)); + #[cfg(not(boringssl))] + assert!(debugged.contains(r#"serial_number: "8771F7BDEE982FA5""#)); + assert!(debugged.contains(r#"signature_algorithm: sha256WithRSAEncryption"#)); + assert!(debugged.contains(r#"countryName = "AU""#)); + assert!(debugged.contains(r#"stateOrProvinceName = "Some-State""#)); + assert!(debugged.contains(r#"not_before: Aug 14 17:00:03 2016 GMT"#)); + assert!(debugged.contains(r#"not_after: Aug 12 17:00:03 2026 GMT"#)); +} + +#[test] +fn test_cert_issue_validity() { + let cert = include_bytes!("../../test/cert.pem"); + let cert = X509::from_pem(cert).unwrap(); + let not_before = cert.not_before().to_string(); + let not_after = cert.not_after().to_string(); + + assert_eq!(not_before, "Aug 14 17:00:03 2016 GMT"); + assert_eq!(not_after, "Aug 12 17:00:03 2026 GMT"); +} + +#[test] +fn test_save_der() { + let cert = include_bytes!("../../test/cert.pem"); + let cert = X509::from_pem(cert).unwrap(); + + let der = cert.to_der().unwrap(); + assert!(!der.is_empty()); +} + +#[test] +fn test_subject_read_cn() { + let cert = include_bytes!("../../test/cert.pem"); + let cert = X509::from_pem(cert).unwrap(); + let subject = cert.subject_name(); + let cn = subject.entries_by_nid(Nid::COMMONNAME).next().unwrap(); + assert_eq!(cn.data().as_slice(), b"foobar.com") +} + +#[test] +fn test_nid_values() { + let cert = include_bytes!("../../test/nid_test_cert.pem"); + let cert = X509::from_pem(cert).unwrap(); + let subject = cert.subject_name(); + + let cn = subject.entries_by_nid(Nid::COMMONNAME).next().unwrap(); + assert_eq!(cn.data().as_slice(), b"example.com"); + + let email = subject + .entries_by_nid(Nid::PKCS9_EMAILADDRESS) + .next() + .unwrap(); + assert_eq!(email.data().as_slice(), b"test@example.com"); + + let friendly = subject.entries_by_nid(Nid::FRIENDLYNAME).next().unwrap(); + assert_eq!(&**friendly.data().as_utf8().unwrap(), "Example"); +} + +#[test] +fn test_nameref_iterator() { + let cert = include_bytes!("../../test/nid_test_cert.pem"); + let cert = X509::from_pem(cert).unwrap(); + let subject = cert.subject_name(); + let mut all_entries = subject.entries(); + + let email = all_entries.next().unwrap(); + assert_eq!( + email.object().nid().as_raw(), + Nid::PKCS9_EMAILADDRESS.as_raw() + ); + assert_eq!(email.data().as_slice(), b"test@example.com"); + + let cn = all_entries.next().unwrap(); + assert_eq!(cn.object().nid().as_raw(), Nid::COMMONNAME.as_raw()); + assert_eq!(cn.data().as_slice(), b"example.com"); + + let friendly = all_entries.next().unwrap(); + assert_eq!(friendly.object().nid().as_raw(), Nid::FRIENDLYNAME.as_raw()); + assert_eq!(&**friendly.data().as_utf8().unwrap(), "Example"); + + if all_entries.next().is_some() { + panic!(); + } +} + +#[test] +fn test_nid_uid_value() { + let cert = include_bytes!("../../test/nid_uid_test_cert.pem"); + let cert = X509::from_pem(cert).unwrap(); + let subject = cert.subject_name(); + + let cn = subject.entries_by_nid(Nid::USERID).next().unwrap(); + assert_eq!(cn.data().as_slice(), b"this is the userId"); +} + +#[test] +fn test_subject_alt_name() { + let cert = include_bytes!("../../test/alt_name_cert.pem"); + let cert = X509::from_pem(cert).unwrap(); + + let subject_alt_names = cert.subject_alt_names().unwrap(); + assert_eq!(5, subject_alt_names.len()); + assert_eq!(Some("example.com"), subject_alt_names[0].dnsname()); + assert_eq!(subject_alt_names[1].ipaddress(), Some(&[127, 0, 0, 1][..])); + assert_eq!( + subject_alt_names[2].ipaddress(), + Some(&b"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x01"[..]) + ); + assert_eq!(Some("test@example.com"), subject_alt_names[3].email()); + assert_eq!(Some("http://www.example.com"), subject_alt_names[4].uri()); +} + +#[test] +#[cfg(any(ossl110, boringssl))] +fn test_retrieve_pathlen() { + let cert = include_bytes!("../../test/root-ca.pem"); + let cert = X509::from_pem(cert).unwrap(); + assert_eq!(cert.pathlen(), None); + + let cert = include_bytes!("../../test/intermediate-ca.pem"); + let cert = X509::from_pem(cert).unwrap(); + assert_eq!(cert.pathlen(), Some(0)); + + let cert = include_bytes!("../../test/alt_name_cert.pem"); + let cert = X509::from_pem(cert).unwrap(); + assert_eq!(cert.pathlen(), None); +} + +#[test] +#[cfg(any(ossl110, boringssl))] +fn test_subject_key_id() { + let cert = include_bytes!("../../test/certv3.pem"); + let cert = X509::from_pem(cert).unwrap(); + + let subject_key_id = cert.subject_key_id().unwrap(); + assert_eq!( + subject_key_id.as_slice(), + &b"\xB6\x73\x2F\x61\xA5\x4B\xA1\xEF\x48\x2C\x15\xB1\x9F\xF3\xDC\x34\x2F\xBC\xAC\x30"[..] + ); +} + +#[test] +#[cfg(any(ossl110, boringssl))] +fn test_authority_key_id() { + let cert = include_bytes!("../../test/certv3.pem"); + let cert = X509::from_pem(cert).unwrap(); + + let authority_key_id = cert.authority_key_id().unwrap(); + assert_eq!( + authority_key_id.as_slice(), + &b"\x6C\xD3\xA5\x03\xAB\x0D\x5F\x2C\xC9\x8D\x8A\x9C\x88\xA7\x88\x77\xB8\x37\xFD\x9A"[..] + ); +} + +#[test] +#[cfg(ossl111d)] +fn test_authority_issuer_and_serial() { + let cert = include_bytes!("../../test/authority_key_identifier.pem"); + let cert = X509::from_pem(cert).unwrap(); + + let authority_issuer = cert.authority_issuer().unwrap(); + assert_eq!(1, authority_issuer.len()); + let dn = authority_issuer[0].directory_name().unwrap(); + let mut o = dn.entries_by_nid(Nid::ORGANIZATIONNAME); + let o = o.next().unwrap().data().as_utf8().unwrap(); + assert_eq!(o.as_bytes(), b"PyCA"); + let mut cn = dn.entries_by_nid(Nid::COMMONNAME); + let cn = cn.next().unwrap().data().as_utf8().unwrap(); + assert_eq!(cn.as_bytes(), b"cryptography.io"); + + let authority_serial = cert.authority_serial().unwrap(); + let serial = authority_serial.to_bn().unwrap(); + let expected = BigNum::from_u32(3).unwrap(); + assert_eq!(serial, expected); +} + +#[test] +fn test_subject_alt_name_iter() { + let cert = include_bytes!("../../test/alt_name_cert.pem"); + let cert = X509::from_pem(cert).unwrap(); + + let subject_alt_names = cert.subject_alt_names().unwrap(); + let mut subject_alt_names_iter = subject_alt_names.iter(); + assert_eq!( + subject_alt_names_iter.next().unwrap().dnsname(), + Some("example.com") + ); + assert_eq!( + subject_alt_names_iter.next().unwrap().ipaddress(), + Some(&[127, 0, 0, 1][..]) + ); + assert_eq!( + subject_alt_names_iter.next().unwrap().ipaddress(), + Some(&b"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x01"[..]) + ); + assert_eq!( + subject_alt_names_iter.next().unwrap().email(), + Some("test@example.com") + ); + assert_eq!( + subject_alt_names_iter.next().unwrap().uri(), + Some("http://www.example.com") + ); + assert!(subject_alt_names_iter.next().is_none()); +} + +#[test] +fn test_aia_ca_issuer() { + // With AIA + let cert = include_bytes!("../../test/aia_test_cert.pem"); + let cert = X509::from_pem(cert).unwrap(); + let authority_info = cert.authority_info().unwrap(); + assert_eq!(authority_info.len(), 1); + assert_eq!(authority_info[0].method().to_string(), "CA Issuers"); + assert_eq!( + authority_info[0].location().uri(), + Some("http://www.example.com/cert.pem") + ); + // Without AIA + let cert = include_bytes!("../../test/cert.pem"); + let cert = X509::from_pem(cert).unwrap(); + assert!(cert.authority_info().is_none()); +} + +#[test] +fn x509_builder() { + let pkey = pkey(); + + let mut name = X509Name::builder().unwrap(); + name.append_entry_by_nid(Nid::COMMONNAME, "foobar.com") + .unwrap(); + let name = name.build(); + + let mut builder = X509::builder().unwrap(); + builder.set_version(2).unwrap(); + builder.set_subject_name(&name).unwrap(); + builder.set_issuer_name(&name).unwrap(); + builder + .set_not_before(&Asn1Time::days_from_now(0).unwrap()) + .unwrap(); + builder + .set_not_after(&Asn1Time::days_from_now(365).unwrap()) + .unwrap(); + builder.set_pubkey(&pkey).unwrap(); + + let mut serial = BigNum::new().unwrap(); + serial.rand(128, MsbOption::MAYBE_ZERO, false).unwrap(); + builder + .set_serial_number(&serial.to_asn1_integer().unwrap()) + .unwrap(); + + let basic_constraints = BasicConstraints::new().critical().ca().build().unwrap(); + builder.append_extension(basic_constraints).unwrap(); + let key_usage = KeyUsage::new() + .digital_signature() + .key_encipherment() + .build() + .unwrap(); + builder.append_extension(key_usage).unwrap(); + let ext_key_usage = ExtendedKeyUsage::new() + .client_auth() + .server_auth() + .other("2.999.1") + .build() + .unwrap(); + builder.append_extension(ext_key_usage).unwrap(); + let subject_key_identifier = SubjectKeyIdentifier::new() + .build(&builder.x509v3_context(None, None)) + .unwrap(); + builder.append_extension(subject_key_identifier).unwrap(); + let authority_key_identifier = AuthorityKeyIdentifier::new() + .keyid(true) + .build(&builder.x509v3_context(None, None)) + .unwrap(); + builder.append_extension(authority_key_identifier).unwrap(); + let subject_alternative_name = SubjectAlternativeName::new() + .dns("example.com") + .build(&builder.x509v3_context(None, None)) + .unwrap(); + builder.append_extension(subject_alternative_name).unwrap(); + + builder.sign(&pkey, MessageDigest::sha256()).unwrap(); + + let x509 = builder.build(); + + assert!(pkey.public_eq(&x509.public_key().unwrap())); + assert!(x509.verify(&pkey).unwrap()); + + let cn = x509 + .subject_name() + .entries_by_nid(Nid::COMMONNAME) + .next() + .unwrap(); + assert_eq!(cn.data().as_slice(), b"foobar.com"); + assert_eq!(serial, x509.serial_number().to_bn().unwrap()); +} + +#[test] +// This tests `X509Extension::new`, even though its deprecated. +#[allow(deprecated)] +fn x509_extension_new() { + assert!(X509Extension::new(None, None, "crlDistributionPoints", "section").is_err()); + assert!(X509Extension::new(None, None, "proxyCertInfo", "").is_err()); + assert!(X509Extension::new(None, None, "certificatePolicies", "").is_err()); + assert!(X509Extension::new(None, None, "subjectAltName", "dirName:section").is_err()); +} + +#[test] +fn x509_extension_new_from_der() { + let ext = X509Extension::new_from_der( + &Asn1Object::from_str("2.5.29.19").unwrap(), + true, + &Asn1OctetString::new_from_bytes(b"\x30\x03\x01\x01\xff").unwrap(), + ) + .unwrap(); + assert_eq!( + ext.to_der().unwrap(), + b"0\x0f\x06\x03U\x1d\x13\x01\x01\xff\x04\x050\x03\x01\x01\xff" + ); +} + +#[test] +fn x509_extension_to_der() { + let builder = X509::builder().unwrap(); + + for (ext, expected) in [ + ( + BasicConstraints::new().critical().ca().build().unwrap(), + b"0\x0f\x06\x03U\x1d\x13\x01\x01\xff\x04\x050\x03\x01\x01\xff" as &[u8], + ), + ( + SubjectAlternativeName::new() + .dns("example.com,DNS:example2.com") + .build(&builder.x509v3_context(None, None)) + .unwrap(), + b"0'\x06\x03U\x1d\x11\x04 0\x1e\x82\x1cexample.com,DNS:example2.com", + ), + ( + SubjectAlternativeName::new() + .rid("1.2.3.4") + .uri("https://example.com") + .build(&builder.x509v3_context(None, None)) + .unwrap(), + b"0#\x06\x03U\x1d\x11\x04\x1c0\x1a\x88\x03*\x03\x04\x86\x13https://example.com", + ), + ( + ExtendedKeyUsage::new() + .server_auth() + .other("2.999.1") + .other("clientAuth") + .build() + .unwrap(), + b"0\x22\x06\x03U\x1d%\x04\x1b0\x19\x06\x08+\x06\x01\x05\x05\x07\x03\x01\x06\x03\x887\x01\x06\x08+\x06\x01\x05\x05\x07\x03\x02", + ), + ] { + assert_eq!(&ext.to_der().unwrap(), expected); + } +} + +#[test] +fn eku_invalid_other() { + assert!(ExtendedKeyUsage::new() + .other("1.1.1.1.1,2.2.2.2.2") + .build() + .is_err()); +} + +#[test] +fn x509_req_builder() { + let pkey = pkey(); + + let mut name = X509Name::builder().unwrap(); + name.append_entry_by_nid(Nid::COMMONNAME, "foobar.com") + .unwrap(); + let name = name.build(); + + let mut builder = X509Req::builder().unwrap(); + builder.set_version(0).unwrap(); + builder.set_subject_name(&name).unwrap(); + builder.set_pubkey(&pkey).unwrap(); + + let mut extensions = Stack::new().unwrap(); + let key_usage = KeyUsage::new() + .digital_signature() + .key_encipherment() + .build() + .unwrap(); + extensions.push(key_usage).unwrap(); + let subject_alternative_name = SubjectAlternativeName::new() + .dns("example.com") + .build(&builder.x509v3_context(None)) + .unwrap(); + extensions.push(subject_alternative_name).unwrap(); + builder.add_extensions(&extensions).unwrap(); + + builder.sign(&pkey, MessageDigest::sha256()).unwrap(); + + let req = builder.build(); + assert!(req.public_key().unwrap().public_eq(&pkey)); + assert_eq!(req.extensions().unwrap().len(), extensions.len()); + assert!(req.verify(&pkey).unwrap()); +} + +#[test] +fn test_stack_from_pem() { + let certs = include_bytes!("../../test/certs.pem"); + let certs = X509::stack_from_pem(certs).unwrap(); + + assert_eq!(certs.len(), 2); + assert_eq!( + hex::encode(certs[0].digest(MessageDigest::sha1()).unwrap()), + "59172d9313e84459bcff27f967e79e6e9217e584" + ); + assert_eq!( + hex::encode(certs[1].digest(MessageDigest::sha1()).unwrap()), + "c0cbdf7cdd03c9773e5468e1f6d2da7d5cbb1875" + ); +} + +#[test] +fn issued() { + let cert = include_bytes!("../../test/cert.pem"); + let cert = X509::from_pem(cert).unwrap(); + let ca = include_bytes!("../../test/root-ca.pem"); + let ca = X509::from_pem(ca).unwrap(); + + assert_eq!(ca.issued(&cert), X509VerifyResult::OK); + assert_ne!(cert.issued(&cert), X509VerifyResult::OK); +} + +#[test] +fn signature() { + let cert = include_bytes!("../../test/cert.pem"); + let cert = X509::from_pem(cert).unwrap(); + let signature = cert.signature(); + assert_eq!( + hex::encode(signature.as_slice()), + "4af607b889790b43470442cfa551cdb8b6d0b0340d2958f76b9e3ef6ad4992230cead6842587f0ecad5\ + 78e6e11a221521e940187e3d6652de14e84e82f6671f097cc47932e022add3c0cb54a26bf27fa84c107\ + 4971caa6bee2e42d34a5b066c427f2d452038082b8073993399548088429de034fdd589dcfb0dd33be7\ + ebdfdf698a28d628a89568881d658151276bde333600969502c4e62e1d3470a683364dfb241f78d310a\ + 89c119297df093eb36b7fd7540224f488806780305d1e79ffc938fe2275441726522ab36d88348e6c51\ + f13dcc46b5e1cdac23c974fd5ef86aa41e91c9311655090a52333bc79687c748d833595d4c5f987508f\ + e121997410d37c" + ); + let algorithm = cert.signature_algorithm(); + assert_eq!(algorithm.object().nid(), Nid::SHA256WITHRSAENCRYPTION); + assert_eq!(algorithm.object().to_string(), "sha256WithRSAEncryption"); +} + +#[test] +#[allow(clippy::redundant_clone)] +fn clone_x509() { + let cert = include_bytes!("../../test/cert.pem"); + let cert = X509::from_pem(cert).unwrap(); + drop(cert.clone()); +} + +#[test] +fn test_verify_cert() { + let cert = include_bytes!("../../test/cert.pem"); + let cert = X509::from_pem(cert).unwrap(); + let ca = include_bytes!("../../test/root-ca.pem"); + let ca = X509::from_pem(ca).unwrap(); + let chain = Stack::new().unwrap(); + + let mut store_bldr = X509StoreBuilder::new().unwrap(); + store_bldr.add_cert(ca).unwrap(); + let store = store_bldr.build(); + + let mut context = X509StoreContext::new().unwrap(); + assert!(context + .init(&store, &cert, &chain, |c| c.verify_cert()) + .unwrap()); + assert!(context + .init(&store, &cert, &chain, |c| c.verify_cert()) + .unwrap()); +} + +#[test] +fn test_verify_fails() { + let cert = include_bytes!("../../test/cert.pem"); + let cert = X509::from_pem(cert).unwrap(); + let ca = include_bytes!("../../test/alt_name_cert.pem"); + let ca = X509::from_pem(ca).unwrap(); + let chain = Stack::new().unwrap(); + + let mut store_bldr = X509StoreBuilder::new().unwrap(); + store_bldr.add_cert(ca).unwrap(); + let store = store_bldr.build(); + + let mut context = X509StoreContext::new().unwrap(); + assert!(!context + .init(&store, &cert, &chain, |c| c.verify_cert()) + .unwrap()); +} + +#[test] +#[cfg(any(ossl102, boringssl, libressl261))] +fn test_verify_fails_with_crl_flag_set_and_no_crl() { + let cert = include_bytes!("../../test/cert.pem"); + let cert = X509::from_pem(cert).unwrap(); + let ca = include_bytes!("../../test/root-ca.pem"); + let ca = X509::from_pem(ca).unwrap(); + let chain = Stack::new().unwrap(); + + let mut store_bldr = X509StoreBuilder::new().unwrap(); + store_bldr.add_cert(ca).unwrap(); + store_bldr.set_flags(X509VerifyFlags::CRL_CHECK).unwrap(); + let store = store_bldr.build(); + + let mut context = X509StoreContext::new().unwrap(); + assert_eq!( + context + .init(&store, &cert, &chain, |c| { + c.verify_cert()?; + Ok(c.error()) + }) + .unwrap() + .error_string(), + "unable to get certificate CRL" + ) +} + +#[test] +#[cfg(any(ossl102, boringssl, libressl261))] +fn test_verify_cert_with_purpose() { + let cert = include_bytes!("../../test/cert.pem"); + let cert = X509::from_pem(cert).unwrap(); + let ca = include_bytes!("../../test/root-ca.pem"); + let ca = X509::from_pem(ca).unwrap(); + let chain = Stack::new().unwrap(); + + let mut store_bldr = X509StoreBuilder::new().unwrap(); + let purpose_idx = X509PurposeRef::get_by_sname("sslserver") + .expect("Getting certificate purpose 'sslserver' failed"); + let x509_purposeref = + X509PurposeRef::from_idx(purpose_idx).expect("Getting certificate purpose failed"); + store_bldr + .set_purpose(x509_purposeref.purpose()) + .expect("Setting certificate purpose failed"); + store_bldr.add_cert(ca).unwrap(); + + let store = store_bldr.build(); + + let mut context = X509StoreContext::new().unwrap(); + assert!(context + .init(&store, &cert, &chain, |c| c.verify_cert()) + .unwrap()); +} + +#[test] +#[cfg(any(ossl102, boringssl, libressl261))] +fn test_verify_cert_with_wrong_purpose_fails() { + let cert = include_bytes!("../../test/cert.pem"); + let cert = X509::from_pem(cert).unwrap(); + let ca = include_bytes!("../../test/root-ca.pem"); + let ca = X509::from_pem(ca).unwrap(); + let chain = Stack::new().unwrap(); + + let mut store_bldr = X509StoreBuilder::new().unwrap(); + let purpose_idx = X509PurposeRef::get_by_sname("timestampsign") + .expect("Getting certificate purpose 'timestampsign' failed"); + let x509_purpose = + X509PurposeRef::from_idx(purpose_idx).expect("Getting certificate purpose failed"); + store_bldr + .set_purpose(x509_purpose.purpose()) + .expect("Setting certificate purpose failed"); + store_bldr.add_cert(ca).unwrap(); + + let store = store_bldr.build(); + + let expected_error = ffi::X509_V_ERR_INVALID_PURPOSE; + let mut context = X509StoreContext::new().unwrap(); + assert_eq!( + context + .init(&store, &cert, &chain, |c| { + c.verify_cert()?; + Ok(c.error()) + }) + .unwrap() + .as_raw(), + expected_error + ) +} + +#[cfg(ossl110)] +#[test] +fn x509_ref_version() { + let mut builder = X509Builder::new().unwrap(); + let expected_version = 2; + builder + .set_version(expected_version) + .expect("Failed to set certificate version"); + let cert = builder.build(); + let actual_version = cert.version(); + assert_eq!( + expected_version, actual_version, + "Obtained certificate version is incorrect", + ); +} + +#[cfg(ossl110)] +#[test] +fn x509_ref_version_no_version_set() { + let cert = X509Builder::new().unwrap().build(); + let actual_version = cert.version(); + assert_eq!( + 0, actual_version, + "Default certificate version is incorrect", + ); +} + +#[test] +fn test_load_crl() { + let ca = include_bytes!("../../test/crl-ca.crt"); + let ca = X509::from_pem(ca).unwrap(); + + let crl = include_bytes!("../../test/test.crl"); + let crl = X509Crl::from_der(crl).unwrap(); + assert!(crl.verify(&ca.public_key().unwrap()).unwrap()); + + let cert = include_bytes!("../../test/subca.crt"); + let cert = X509::from_pem(cert).unwrap(); + + let revoked = match crl.get_by_cert(&cert) { + CrlStatus::Revoked(revoked) => revoked, + _ => panic!("cert should be revoked"), + }; + + assert_eq!( + revoked.serial_number().to_bn().unwrap(), + cert.serial_number().to_bn().unwrap(), + "revoked and cert serial numbers should match" + ); +} + +#[test] +fn test_crl_entry_extensions() { + let crl = include_bytes!("../../test/entry_extensions.crl"); + let crl = X509Crl::from_pem(crl).unwrap(); + + let (critical, access_info) = crl + .extension::() + .unwrap() + .expect("Authority Information Access extension should be present"); + assert!( + !critical, + "Authority Information Access extension is not critical" + ); + assert_eq!( + access_info.len(), + 1, + "Authority Information Access should have one entry" + ); + assert_eq!(access_info[0].method().to_string(), "CA Issuers"); + assert_eq!( + access_info[0].location().uri(), + Some("http://www.example.com/ca.crt") + ); + let revoked_certs = crl.get_revoked().unwrap(); + let entry = &revoked_certs[0]; + + let (critical, issuer) = entry + .extension::() + .unwrap() + .expect("Certificate issuer extension should be present"); + assert!(critical, "Certificate issuer extension is critical"); + assert_eq!(issuer.len(), 1, "Certificate issuer should have one entry"); + let issuer = issuer[0] + .directory_name() + .expect("Issuer should be a directory name"); + assert_eq!( + format!("{:?}", issuer), + r#"[countryName = "GB", commonName = "Test CA"]"# + ); + + // reason_code can't be inspected without ossl110 + #[allow(unused_variables)] + let (critical, reason_code) = entry + .extension::() + .unwrap() + .expect("Reason code extension should be present"); + assert!(!critical, "Reason code extension is not critical"); + #[cfg(ossl110)] + assert_eq!( + CrlReason::KEY_COMPROMISE, + CrlReason::from_raw(reason_code.get_i64().unwrap() as ffi::c_int) + ); +} + +#[test] +fn test_save_subject_der() { + let cert = include_bytes!("../../test/cert.pem"); + let cert = X509::from_pem(cert).unwrap(); + + let der = cert.subject_name().to_der().unwrap(); + println!("der: {:?}", der); + assert!(!der.is_empty()); +} + +#[test] +fn test_load_subject_der() { + // The subject from ../../test/cert.pem + const SUBJECT_DER: &[u8] = &[ + 48, 90, 49, 11, 48, 9, 6, 3, 85, 4, 6, 19, 2, 65, 85, 49, 19, 48, 17, 6, 3, 85, 4, 8, 12, + 10, 83, 111, 109, 101, 45, 83, 116, 97, 116, 101, 49, 33, 48, 31, 6, 3, 85, 4, 10, 12, 24, + 73, 110, 116, 101, 114, 110, 101, 116, 32, 87, 105, 100, 103, 105, 116, 115, 32, 80, 116, + 121, 32, 76, 116, 100, 49, 19, 48, 17, 6, 3, 85, 4, 3, 12, 10, 102, 111, 111, 98, 97, 114, + 46, 99, 111, 109, + ]; + X509Name::from_der(SUBJECT_DER).unwrap(); +} + +#[test] +fn test_convert_to_text() { + let cert = include_bytes!("../../test/cert.pem"); + let cert = X509::from_pem(cert).unwrap(); + + const SUBSTRINGS: &[&str] = &[ + "Certificate:\n", + "Serial Number:", + "Signature Algorithm:", + "Issuer: C=AU, ST=Some-State, O=Internet Widgits Pty Ltd\n", + "Subject: C=AU, ST=Some-State, O=Internet Widgits Pty Ltd, CN=foobar.com\n", + "Subject Public Key Info:", + ]; + + let text = String::from_utf8(cert.to_text().unwrap()).unwrap(); + + for substring in SUBSTRINGS { + assert!( + text.contains(substring), + "{:?} not found inside {}", + substring, + text + ); + } +} + +#[test] +fn test_convert_req_to_text() { + let csr = include_bytes!("../../test/csr.pem"); + let csr = X509Req::from_pem(csr).unwrap(); + + const SUBSTRINGS: &[&str] = &[ + "Certificate Request:\n", + "Version:", + "Subject: C=AU, ST=Some-State, O=Internet Widgits Pty Ltd, CN=foobar.com\n", + "Subject Public Key Info:", + "Signature Algorithm:", + ]; + + let text = String::from_utf8(csr.to_text().unwrap()).unwrap(); + + for substring in SUBSTRINGS { + assert!( + text.contains(substring), + "{:?} not found inside {}", + substring, + text + ); + } +} + +#[test] +fn test_name_cmp() { + let cert = include_bytes!("../../test/cert.pem"); + let cert = X509::from_pem(cert).unwrap(); + + let subject = cert.subject_name(); + let issuer = cert.issuer_name(); + assert_eq!(Ordering::Equal, subject.try_cmp(subject).unwrap()); + assert_eq!(Ordering::Greater, subject.try_cmp(issuer).unwrap()); +} + +#[test] +#[cfg(any(boringssl, ossl110, libressl270))] +fn test_name_to_owned() { + let cert = include_bytes!("../../test/cert.pem"); + let cert = X509::from_pem(cert).unwrap(); + let name = cert.subject_name(); + let copied_name = name.to_owned().unwrap(); + assert_eq!(Ordering::Equal, name.try_cmp(&copied_name).unwrap()); +} + +#[test] +#[cfg(any(ossl102, boringssl, libressl261))] +fn test_verify_param_set_time_fails_verification() { + const TEST_T_2030: time_t = 1893456000; + + let cert = include_bytes!("../../test/cert.pem"); + let cert = X509::from_pem(cert).unwrap(); + let ca = include_bytes!("../../test/root-ca.pem"); + let ca = X509::from_pem(ca).unwrap(); + let chain = Stack::new().unwrap(); + + let mut store_bldr = X509StoreBuilder::new().unwrap(); + store_bldr.add_cert(ca).unwrap(); + let mut verify_params = X509VerifyParam::new().unwrap(); + verify_params.set_time(TEST_T_2030); + store_bldr.set_param(&verify_params).unwrap(); + let store = store_bldr.build(); + + let mut context = X509StoreContext::new().unwrap(); + assert_eq!( + context + .init(&store, &cert, &chain, |c| { + c.verify_cert()?; + Ok(c.error()) + }) + .unwrap() + .error_string(), + "certificate has expired" + ) +} + +#[test] +#[cfg(any(ossl102, boringssl, libressl261))] +fn test_verify_param_set_time() { + const TEST_T_2020: time_t = 1577836800; + + let cert = include_bytes!("../../test/cert.pem"); + let cert = X509::from_pem(cert).unwrap(); + let ca = include_bytes!("../../test/root-ca.pem"); + let ca = X509::from_pem(ca).unwrap(); + let chain = Stack::new().unwrap(); + + let mut store_bldr = X509StoreBuilder::new().unwrap(); + store_bldr.add_cert(ca).unwrap(); + let mut verify_params = X509VerifyParam::new().unwrap(); + verify_params.set_time(TEST_T_2020); + store_bldr.set_param(&verify_params).unwrap(); + let store = store_bldr.build(); + + let mut context = X509StoreContext::new().unwrap(); + assert!(context + .init(&store, &cert, &chain, |c| c.verify_cert()) + .unwrap()); +} + +#[test] +#[cfg(any(ossl102, boringssl, libressl261))] +fn test_verify_param_set_depth() { + let cert = include_bytes!("../../test/leaf.pem"); + let cert = X509::from_pem(cert).unwrap(); + let intermediate_ca = include_bytes!("../../test/intermediate-ca.pem"); + let intermediate_ca = X509::from_pem(intermediate_ca).unwrap(); + let ca = include_bytes!("../../test/root-ca.pem"); + let ca = X509::from_pem(ca).unwrap(); + let mut chain = Stack::new().unwrap(); + chain.push(intermediate_ca).unwrap(); + + let mut store_bldr = X509StoreBuilder::new().unwrap(); + store_bldr.add_cert(ca).unwrap(); + let mut verify_params = X509VerifyParam::new().unwrap(); + // OpenSSL 1.1.0+ considers the root certificate to not be part of the chain, while 1.0.2 and LibreSSL do + let expected_depth = if cfg!(any(ossl110)) { 1 } else { 2 }; + verify_params.set_depth(expected_depth); + store_bldr.set_param(&verify_params).unwrap(); + let store = store_bldr.build(); + + let mut context = X509StoreContext::new().unwrap(); + assert!(context + .init(&store, &cert, &chain, |c| c.verify_cert()) + .unwrap()); +} + +#[test] +#[cfg(any(ossl102, boringssl, libressl261))] +#[allow(clippy::bool_to_int_with_if)] +fn test_verify_param_set_depth_fails_verification() { + let cert = include_bytes!("../../test/leaf.pem"); + let cert = X509::from_pem(cert).unwrap(); + let intermediate_ca = include_bytes!("../../test/intermediate-ca.pem"); + let intermediate_ca = X509::from_pem(intermediate_ca).unwrap(); + let ca = include_bytes!("../../test/root-ca.pem"); + let ca = X509::from_pem(ca).unwrap(); + let mut chain = Stack::new().unwrap(); + chain.push(intermediate_ca).unwrap(); + + let mut store_bldr = X509StoreBuilder::new().unwrap(); + store_bldr.add_cert(ca).unwrap(); + let mut verify_params = X509VerifyParam::new().unwrap(); + // OpenSSL 1.1.0+ considers the root certificate to not be part of the chain, while 1.0.2 and LibreSSL do + let expected_depth = if cfg!(any(ossl110, boringssl)) { 0 } else { 1 }; + verify_params.set_depth(expected_depth); + store_bldr.set_param(&verify_params).unwrap(); + let store = store_bldr.build(); + + // OpenSSL 1.1.0+ added support for X509_V_ERR_CERT_CHAIN_TOO_LONG, while 1.0.2 simply ignores the intermediate + let expected_error = if cfg!(any(ossl110, libressl261)) { + "certificate chain too long" + } else { + "unable to get local issuer certificate" + }; + + let mut context = X509StoreContext::new().unwrap(); + assert_eq!( + context + .init(&store, &cert, &chain, |c| { + c.verify_cert()?; + Ok(c.error()) + }) + .unwrap() + .error_string(), + expected_error + ) +} + +#[test] +#[cfg(not(boringssl))] +fn test_load_cert_file() { + let cert = include_bytes!("../../test/cert.pem"); + let cert = X509::from_pem(cert).unwrap(); + let chain = Stack::new().unwrap(); + + let mut store_bldr = X509StoreBuilder::new().unwrap(); + let lookup = store_bldr.add_lookup(X509Lookup::file()).unwrap(); + lookup + .load_cert_file("test/root-ca.pem", SslFiletype::PEM) + .unwrap(); + let store = store_bldr.build(); + + let mut context = X509StoreContext::new().unwrap(); + assert!(context + .init(&store, &cert, &chain, |c| c.verify_cert()) + .unwrap()); +} + +#[test] +#[cfg(ossl110)] +fn test_verify_param_auth_level() { + let mut param = X509VerifyParam::new().unwrap(); + let auth_lvl = 2; + let auth_lvl_default = -1; + + assert_eq!(param.auth_level(), auth_lvl_default); + + param.set_auth_level(auth_lvl); + assert_eq!(param.auth_level(), auth_lvl); +} + +#[test] +#[cfg(any(ossl102, boringssl))] +fn test_set_purpose() { + let cert = include_bytes!("../../test/leaf.pem"); + let cert = X509::from_pem(cert).unwrap(); + let intermediate_ca = include_bytes!("../../test/intermediate-ca.pem"); + let intermediate_ca = X509::from_pem(intermediate_ca).unwrap(); + let ca = include_bytes!("../../test/root-ca.pem"); + let ca = X509::from_pem(ca).unwrap(); + let mut chain = Stack::new().unwrap(); + chain.push(intermediate_ca).unwrap(); + + let mut store_bldr = X509StoreBuilder::new().unwrap(); + store_bldr.add_cert(ca).unwrap(); + let mut verify_params = X509VerifyParam::new().unwrap(); + verify_params.set_purpose(X509PurposeId::ANY).unwrap(); + store_bldr.set_param(&verify_params).unwrap(); + let store = store_bldr.build(); + let mut context = X509StoreContext::new().unwrap(); + + assert!(context + .init(&store, &cert, &chain, |c| c.verify_cert()) + .unwrap()); +} + +#[test] +#[cfg(any(ossl102, boringssl))] +fn test_set_purpose_fails_verification() { + let cert = include_bytes!("../../test/leaf.pem"); + let cert = X509::from_pem(cert).unwrap(); + let intermediate_ca = include_bytes!("../../test/intermediate-ca.pem"); + let intermediate_ca = X509::from_pem(intermediate_ca).unwrap(); + let ca = include_bytes!("../../test/root-ca.pem"); + let ca = X509::from_pem(ca).unwrap(); + let mut chain = Stack::new().unwrap(); + chain.push(intermediate_ca).unwrap(); + + let mut store_bldr = X509StoreBuilder::new().unwrap(); + store_bldr.add_cert(ca).unwrap(); + let mut verify_params = X509VerifyParam::new().unwrap(); + verify_params + .set_purpose(X509PurposeId::TIMESTAMP_SIGN) + .unwrap(); + store_bldr.set_param(&verify_params).unwrap(); + let store = store_bldr.build(); + + let expected_error = ffi::X509_V_ERR_INVALID_PURPOSE; + let mut context = X509StoreContext::new().unwrap(); + assert_eq!( + context + .init(&store, &cert, &chain, |c| { + c.verify_cert()?; + Ok(c.error()) + }) + .unwrap() + .as_raw(), + expected_error + ) +} + +#[test] +#[cfg(any(ossl101, libressl350))] +fn test_add_name_entry() { + let cert = include_bytes!("../../test/cert.pem"); + let cert = X509::from_pem(cert).unwrap(); + let inp_name = cert.subject_name().entries().next().unwrap(); + + let mut names = X509Name::builder().unwrap(); + names.append_entry(inp_name).unwrap(); + let names = names.build(); + + let mut entries = names.entries(); + let outp_name = entries.next().unwrap(); + assert_eq!(outp_name.object().nid(), inp_name.object().nid()); + assert_eq!(outp_name.data().as_slice(), inp_name.data().as_slice()); + assert!(entries.next().is_none()); +} + +#[test] +#[cfg(not(boringssl))] +fn test_load_crl_file_fail() { + let mut store_bldr = X509StoreBuilder::new().unwrap(); + let lookup = store_bldr.add_lookup(X509Lookup::file()).unwrap(); + let res = lookup.load_crl_file("test/root-ca.pem", SslFiletype::PEM); + assert!(res.is_err()); +} + +#[cfg(ossl110)] +fn ipaddress_as_subject_alternative_name_is_formatted_in_debug(expected_ip: T) +where + T: Into, +{ + let expected_ip = format!("{:?}", expected_ip.into()); + let mut builder = X509Builder::new().unwrap(); + let san = SubjectAlternativeName::new() + .ip(&expected_ip) + .build(&builder.x509v3_context(None, None)) + .unwrap(); + builder.append_extension(san).unwrap(); + let cert = builder.build(); + let actual_ip = cert + .subject_alt_names() + .into_iter() + .flatten() + .map(|n| format!("{:?}", *n)) + .next() + .unwrap(); + assert_eq!(actual_ip, expected_ip); +} + +#[cfg(ossl110)] +#[test] +fn ipv4_as_subject_alternative_name_is_formatted_in_debug() { + ipaddress_as_subject_alternative_name_is_formatted_in_debug([8u8, 8, 8, 128]); +} + +#[cfg(ossl110)] +#[test] +fn ipv6_as_subject_alternative_name_is_formatted_in_debug() { + ipaddress_as_subject_alternative_name_is_formatted_in_debug([ + 8u8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 128, + ]); +} + +#[cfg(ossl110)] +#[test] +fn other_name_as_subject_alternative_name() { + let oid = Asn1Object::from_str("1.3.6.1.5.5.7.8.11").unwrap(); + // this is the hex representation of "test" encoded as a ia5string + let content = [0x16, 0x04, 0x74, 0x65, 0x73, 0x74]; + + let mut builder = X509Builder::new().unwrap(); + let san = SubjectAlternativeName::new() + .other_name2(oid, &content) + .build(&builder.x509v3_context(None, None)) + .unwrap(); + builder.append_extension(san).unwrap(); + let cert = builder.build(); + let general_name = cert + .subject_alt_names() + .into_iter() + .flatten() + .next() + .unwrap(); + unsafe { + assert_eq!((*general_name.as_ptr()).type_, 0); + } +} + +#[test] +fn test_dist_point() { + let cert = include_bytes!("../../test/certv3.pem"); + let cert = X509::from_pem(cert).unwrap(); + + let dps = cert.crl_distribution_points().unwrap(); + let dp = dps.get(0).unwrap(); + let dp_nm = dp.distpoint().unwrap(); + let dp_gns = dp_nm.fullname().unwrap(); + let dp_gn = dp_gns.get(0).unwrap(); + assert_eq!(dp_gn.uri().unwrap(), "http://example.com/crl.pem"); + + let dp = dps.get(1).unwrap(); + let dp_nm = dp.distpoint().unwrap(); + let dp_gns = dp_nm.fullname().unwrap(); + let dp_gn = dp_gns.get(0).unwrap(); + assert_eq!(dp_gn.uri().unwrap(), "http://example.com/crl2.pem"); + assert!(dps.get(2).is_none()) +} + +#[test] +fn test_dist_point_null() { + let cert = include_bytes!("../../test/cert.pem"); + let cert = X509::from_pem(cert).unwrap(); + assert!(cert.crl_distribution_points().is_none()); +} + +#[test] +#[cfg(ossl300)] +fn test_store_all_certificates() { + let cert = include_bytes!("../../test/cert.pem"); + let cert = X509::from_pem(cert).unwrap(); + + let store = { + let mut b = X509StoreBuilder::new().unwrap(); + b.add_cert(cert).unwrap(); + b.build() + }; + + assert_eq!(store.all_certificates().len(), 1); +} diff --git a/vendor/openssl/src/x509/verify.rs b/vendor/openssl/src/x509/verify.rs new file mode 100644 index 0000000..2cde93f --- /dev/null +++ b/vendor/openssl/src/x509/verify.rs @@ -0,0 +1,215 @@ +use bitflags::bitflags; +use foreign_types::ForeignTypeRef; +use libc::{c_int, c_uint, c_ulong, time_t}; +use std::net::IpAddr; + +use crate::error::ErrorStack; +#[cfg(any(ossl102, boringssl))] +use crate::x509::X509PurposeId; +use crate::{cvt, cvt_p}; +use openssl_macros::corresponds; + +bitflags! { + /// Flags used to check an `X509` certificate. + #[derive(Copy, Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)] + #[repr(transparent)] + pub struct X509CheckFlags: c_uint { + const ALWAYS_CHECK_SUBJECT = ffi::X509_CHECK_FLAG_ALWAYS_CHECK_SUBJECT as _; + const NO_WILDCARDS = ffi::X509_CHECK_FLAG_NO_WILDCARDS as _; + const NO_PARTIAL_WILDCARDS = ffi::X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS as _; + const MULTI_LABEL_WILDCARDS = ffi::X509_CHECK_FLAG_MULTI_LABEL_WILDCARDS as _; + const SINGLE_LABEL_SUBDOMAINS = ffi::X509_CHECK_FLAG_SINGLE_LABEL_SUBDOMAINS as _; + /// Requires OpenSSL 1.1.0 or newer. + #[cfg(any(ossl110))] + const NEVER_CHECK_SUBJECT = ffi::X509_CHECK_FLAG_NEVER_CHECK_SUBJECT; + + #[deprecated(since = "0.10.6", note = "renamed to NO_WILDCARDS")] + const FLAG_NO_WILDCARDS = ffi::X509_CHECK_FLAG_NO_WILDCARDS as _; + } +} + +bitflags! { + /// Flags used to verify an `X509` certificate chain. + #[derive(Copy, Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)] + #[repr(transparent)] + pub struct X509VerifyFlags: c_ulong { + const CB_ISSUER_CHECK = ffi::X509_V_FLAG_CB_ISSUER_CHECK as _; + const USE_CHECK_TIME = ffi::X509_V_FLAG_USE_CHECK_TIME as _; + const CRL_CHECK = ffi::X509_V_FLAG_CRL_CHECK as _; + const CRL_CHECK_ALL = ffi::X509_V_FLAG_CRL_CHECK_ALL as _; + const IGNORE_CRITICAL = ffi::X509_V_FLAG_IGNORE_CRITICAL as _; + const X509_STRICT = ffi::X509_V_FLAG_X509_STRICT as _; + const ALLOW_PROXY_CERTS = ffi::X509_V_FLAG_ALLOW_PROXY_CERTS as _; + const POLICY_CHECK = ffi::X509_V_FLAG_POLICY_CHECK as _; + const EXPLICIT_POLICY = ffi::X509_V_FLAG_EXPLICIT_POLICY as _; + const INHIBIT_ANY = ffi::X509_V_FLAG_INHIBIT_ANY as _; + const INHIBIT_MAP = ffi::X509_V_FLAG_INHIBIT_MAP as _; + const NOTIFY_POLICY = ffi::X509_V_FLAG_NOTIFY_POLICY as _; + const EXTENDED_CRL_SUPPORT = ffi::X509_V_FLAG_EXTENDED_CRL_SUPPORT as _; + const USE_DELTAS = ffi::X509_V_FLAG_USE_DELTAS as _; + const CHECK_SS_SIGNATURE = ffi::X509_V_FLAG_CHECK_SS_SIGNATURE as _; + #[cfg(any(ossl102, boringssl))] + const TRUSTED_FIRST = ffi::X509_V_FLAG_TRUSTED_FIRST as _; + #[cfg(ossl102)] + const SUITEB_128_LOS_ONLY = ffi::X509_V_FLAG_SUITEB_128_LOS_ONLY; + #[cfg(ossl102)] + const SUITEB_192_LOS = ffi::X509_V_FLAG_SUITEB_128_LOS; + #[cfg(ossl102)] + const SUITEB_128_LOS = ffi::X509_V_FLAG_SUITEB_192_LOS; + #[cfg(any(ossl102, boringssl))] + const PARTIAL_CHAIN = ffi::X509_V_FLAG_PARTIAL_CHAIN as _; + #[cfg(any(ossl110, boringssl))] + const NO_ALT_CHAINS = ffi::X509_V_FLAG_NO_ALT_CHAINS as _; + #[cfg(any(ossl110, boringssl))] + const NO_CHECK_TIME = ffi::X509_V_FLAG_NO_CHECK_TIME as _; + } +} + +foreign_type_and_impl_send_sync! { + type CType = ffi::X509_VERIFY_PARAM; + fn drop = ffi::X509_VERIFY_PARAM_free; + + /// Adjust parameters associated with certificate verification. + pub struct X509VerifyParam; + /// Reference to `X509VerifyParam`. + pub struct X509VerifyParamRef; +} + +impl X509VerifyParam { + /// Create an X509VerifyParam + #[corresponds(X509_VERIFY_PARAM_new)] + pub fn new() -> Result { + unsafe { + ffi::init(); + cvt_p(ffi::X509_VERIFY_PARAM_new()).map(X509VerifyParam) + } + } +} + +impl X509VerifyParamRef { + /// Set the host flags. + #[corresponds(X509_VERIFY_PARAM_set_hostflags)] + pub fn set_hostflags(&mut self, hostflags: X509CheckFlags) { + unsafe { + ffi::X509_VERIFY_PARAM_set_hostflags(self.as_ptr(), hostflags.bits()); + } + } + + /// Set verification flags. + #[corresponds(X509_VERIFY_PARAM_set_flags)] + pub fn set_flags(&mut self, flags: X509VerifyFlags) -> Result<(), ErrorStack> { + unsafe { + cvt(ffi::X509_VERIFY_PARAM_set_flags( + self.as_ptr(), + flags.bits(), + )) + .map(|_| ()) + } + } + + /// Clear verification flags. + #[corresponds(X509_VERIFY_PARAM_clear_flags)] + pub fn clear_flags(&mut self, flags: X509VerifyFlags) -> Result<(), ErrorStack> { + unsafe { + cvt(ffi::X509_VERIFY_PARAM_clear_flags( + self.as_ptr(), + flags.bits(), + )) + .map(|_| ()) + } + } + + /// Gets verification flags. + #[corresponds(X509_VERIFY_PARAM_get_flags)] + pub fn flags(&mut self) -> X509VerifyFlags { + let bits = unsafe { ffi::X509_VERIFY_PARAM_get_flags(self.as_ptr()) }; + X509VerifyFlags::from_bits_retain(bits) + } + + /// Set the expected DNS hostname. + #[corresponds(X509_VERIFY_PARAM_set1_host)] + pub fn set_host(&mut self, host: &str) -> Result<(), ErrorStack> { + unsafe { + // len == 0 means "run strlen" :( + let raw_host = if host.is_empty() { "\0" } else { host }; + cvt(ffi::X509_VERIFY_PARAM_set1_host( + self.as_ptr(), + raw_host.as_ptr() as *const _, + host.len(), + )) + .map(|_| ()) + } + } + + /// Set the expected email address. + #[corresponds(X509_VERIFY_PARAM_set1_email)] + pub fn set_email(&mut self, email: &str) -> Result<(), ErrorStack> { + unsafe { + // len == 0 means "run strlen" :( + let raw_email = if email.is_empty() { "\0" } else { email }; + cvt(ffi::X509_VERIFY_PARAM_set1_email( + self.as_ptr(), + raw_email.as_ptr() as *const _, + email.len(), + )) + .map(|_| ()) + } + } + + /// Set the expected IPv4 or IPv6 address. + #[corresponds(X509_VERIFY_PARAM_set1_ip)] + pub fn set_ip(&mut self, ip: IpAddr) -> Result<(), ErrorStack> { + unsafe { + let mut buf = [0; 16]; + let len = match ip { + IpAddr::V4(addr) => { + buf[..4].copy_from_slice(&addr.octets()); + 4 + } + IpAddr::V6(addr) => { + buf.copy_from_slice(&addr.octets()); + 16 + } + }; + cvt(ffi::X509_VERIFY_PARAM_set1_ip( + self.as_ptr(), + buf.as_ptr() as *const _, + len, + )) + .map(|_| ()) + } + } + + /// Set the verification time, where time is of type time_t, traditionaly defined as seconds since the epoch + #[corresponds(X509_VERIFY_PARAM_set_time)] + pub fn set_time(&mut self, time: time_t) { + unsafe { ffi::X509_VERIFY_PARAM_set_time(self.as_ptr(), time) } + } + + /// Set the verification depth + #[corresponds(X509_VERIFY_PARAM_set_depth)] + pub fn set_depth(&mut self, depth: c_int) { + unsafe { ffi::X509_VERIFY_PARAM_set_depth(self.as_ptr(), depth) } + } + + /// Sets the authentication security level to auth_level + #[corresponds(X509_VERIFY_PARAM_set_auth_level)] + #[cfg(ossl110)] + pub fn set_auth_level(&mut self, lvl: c_int) { + unsafe { ffi::X509_VERIFY_PARAM_set_auth_level(self.as_ptr(), lvl) } + } + + /// Gets the current authentication security level + #[corresponds(X509_VERIFY_PARAM_get_auth_level)] + #[cfg(ossl110)] + pub fn auth_level(&self) -> i32 { + unsafe { ffi::X509_VERIFY_PARAM_get_auth_level(self.as_ptr()) } + } + + /// Sets the verification purpose + #[corresponds(X509_VERIFY_PARAM_set_purpose)] + #[cfg(any(ossl102, boringssl))] + pub fn set_purpose(&mut self, purpose: X509PurposeId) -> Result<(), ErrorStack> { + unsafe { cvt(ffi::X509_VERIFY_PARAM_set_purpose(self.as_ptr(), purpose.0)).map(|_| ()) } + } +} diff --git a/vendor/openssl/test/aia_test_cert.pem b/vendor/openssl/test/aia_test_cert.pem new file mode 100644 index 0000000..6cc522e --- /dev/null +++ b/vendor/openssl/test/aia_test_cert.pem @@ -0,0 +1,22 @@ +-----BEGIN CERTIFICATE----- +MIIDozCCAougAwIBAgIJAJayG40CARAjMA0GCSqGSIb3DQEBCwUAMA8xDTALBgNV +BAMMBHRlc3QwHhcNMjEwMzAyMDA1NzQ3WhcNNDgwNzE4MDA1NzQ3WjBzMQswCQYD +VQQGEwJYWDELMAkGA1UECAwCWFgxEDAOBgNVBAcMB25vd2hlcmUxEDAOBgNVBAoM +B3Rlc3RvcmcxEjAQBgNVBAsMCXRlc3Rncm91cDEfMB0GA1UEAwwWbWFjaGluZS0w +Lm15aG9zdC5teW5ldDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANKA +3zhwC70hbxFVdC0dYk9BHaNntZ4LPUVwFSG2HBn34oO8zCp4wkH+VIi9vOhWiySK +Gs3gW4qpjMbF82Gqc3dG2KfqUrOtWY+u54zAzqpgiJf08wmREHPoZmjqfCfgM3FO +VMEA8g1BQxXEd+y7UEDoXhPIoeFnqzMu9sg4npnL9U5BLaQJiWnXHClnBrvAAKXW +E8KDNmcavtFvo2xQVC09C6dJG5CrigWcZe4CaUl44rHiPaQd+jOp0HAccl/XLA0/ +QyHvW6ksjco/mb7ia1U9ohaC/3NHmzUA1S3kdq/qgnkPsjmy5v8k5vizowNc5rFO +XsV86BIv44rh1Jut52ECAwEAAaOBnTCBmjAMBgNVHRMEBTADAQH/MAsGA1UdDwQE +AwIF4DAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwIQYDVR0RBBowGIIW +bWFjaGluZS0wLm15aG9zdC5teW5ldDA7BggrBgEFBQcBAQQvMC0wKwYIKwYBBQUH +MAKGH2h0dHA6Ly93d3cuZXhhbXBsZS5jb20vY2VydC5wZW0wDQYJKoZIhvcNAQEL +BQADggEBAH+ayx8qGvxzrG57jgXJudq+z783O6E2xGBJn1cT9Jhrg1VnlU+tHcNd +fFcsp0gdQZCmm3pu3E0m/FsgTpfHUgdCOmZQp45QrxCz2oRdWQM71SSA/x1VfQ9w +670iZOEY15/ss2nRl0woaYO7tBVadpZfymW5+OhsTKn5gL0pVmW3RciHuAmbIvQO +bouUwzuZIJMfca7T1MqZYdrKoJrOBj0LaPTutjfQB7O/02vUCPjTTIH20aqsMe5K +KXCrjiZO2jkxQ49Hz5uwfPx12dSVHNLpsnfOAH+MUToeW+SPx2OPvl/uAHcph2lj +MLA6Wi64rSUxzkcFLFsGpKcK6QKcHUw= +-----END CERTIFICATE----- diff --git a/vendor/openssl/test/alt_name_cert.pem b/vendor/openssl/test/alt_name_cert.pem new file mode 100644 index 0000000..d9e9f90 --- /dev/null +++ b/vendor/openssl/test/alt_name_cert.pem @@ -0,0 +1,22 @@ +-----BEGIN CERTIFICATE----- +MIIDsDCCApigAwIBAgIBATANBgkqhkiG9w0BAQsFADBFMQswCQYDVQQGEwJBVTET +MBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0cyBQ +dHkgTHRkMB4XDTE4MDExNTExMDcwM1oXDTI4MDExMzExMDcwM1owfDELMAkGA1UE +BhMCVVMxCzAJBgNVBAgMAk5ZMREwDwYDVQQHDAhOZXcgWW9yazEVMBMGA1UECgwM +RXhhbXBsZSwgTExDMTYwNAYDVQQDDC1FeGFtcGxlIENvbXBhbnkvZW1haWxBZGRy +ZXNzPXRlc3RAZXhhbXBsZS5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK +AoIBAQCo9CWMRLMXo1CF/iORh9B4NhtJF/8tR9PlG95sNvyWuQQ/8jfev+8zErpl +xfLkt0pJqcoiZG8g9NU0kU6o5T+/1QgZclCAoZaS0Jqxmoo2Yk/1Qsj16pnMBc10 +uSDk6V9aJSX1vKwONVNSwiHA1MhX+i7Wf7/K0niq+k7hOkhleFkWgZtUq41gXh1V +fOugka7UktYnk9mrBbAMjmaloZNn2pMMAQxVg4ThiLm3zvuWqvXASWzUZc7IAd1G +bN4AtDuhs252eqE9E4iTHk7F14wAS1JWqv666hReGHrmZJGx0xQTM9vPD1HN5t2U +3KTfhO/mTlAUWVyg9tCtOzboKgs1AgMBAAGjdDByMAkGA1UdEwQCMAAwCwYDVR0P +BAQDAgWgMFgGA1UdEQRRME+CC2V4YW1wbGUuY29thwR/AAABhxAAAAAAAAAAAAAA +AAAAAAABgRB0ZXN0QGV4YW1wbGUuY29thhZodHRwOi8vd3d3LmV4YW1wbGUuY29t +MA0GCSqGSIb3DQEBCwUAA4IBAQAx14G99z/MnSbs8h5jSos+dgLvhc2IQB/3CChE +hPyELc7iyw1iteRs7bS1m2NZx6gv6TZ6VydDrK1dnWSatQ7sskXTO+zfC6qjMwXl +IV+u7T8EREwciniIA82d8GWs60BGyBL3zp2iUOr5ULG4+c/S6OLdlyJv+fDKv+Xo +fKv1UGDi5rcvUBikeNkpEPTN9UsE9/A8XJfDyq+4RKuDW19EtzOOeVx4xpHOMnAy +VVAQVMKJzhoXtLF4k2j409na+f6FIcZSBet+plmzfB+WZNIgUUi/7MQIXOFQRkj4 +zH3SnsPm/IYpJzlH2vHhlqIBdaSoTWpGVWPq7D+H8OS3mmXF +-----END CERTIFICATE----- diff --git a/vendor/openssl/test/authority_key_identifier.pem b/vendor/openssl/test/authority_key_identifier.pem new file mode 100644 index 0000000..cbe9169 --- /dev/null +++ b/vendor/openssl/test/authority_key_identifier.pem @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIDIjCCAgqgAwIBAgIBAzANBgkqhkiG9w0BAQUFADApMQ0wCwYDVQQKDARQeUNB +MRgwFgYDVQQDDA9jcnlwdG9ncmFwaHkuaW8wHhcNMTUwNTAzMDk0OTU2WhcNMTYw +NTAyMDk0OTU2WjApMQ0wCwYDVQQKDARQeUNBMRgwFgYDVQQDDA9jcnlwdG9ncmFw +aHkuaW8wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDCadi1UZioxdnP +ajqlRZHeKsSxvXXhgrWvlt91P3gV0dBThRFhJsLOhjNLz6PO6KeRbjz9GhTA2hdk +xtIpXrjvTv9dEJ1/k0xebsHWgFC43aTlgekw0U4cMwMe5NGeeg1tfzbJwldIN+cK +vabc08ADlkmM6DMnUArkzA2yii0DErRFMSIGrkDr6E9puord3h6Mh8Jfnc3TDAq8 +Qo1DI2XM7oFSWNfecQ9KbIC5wzzT+7Shoyz7QmCk/XhRzt8Xcfc3yAXIwazvLf8b +YP1auaSG11a5E+w6onj91h8UHKKOXu+rdq5YYPZ+qUYpxA7ZJ/VAGadMulYbXaO8 +Syi39HTpAgMBAAGjVTBTMFEGA1UdIwRKMEiAFDlFPso9Yh3qhkn2WqtAt6RwmPHs +oS2kKzApMQ0wCwYDVQQKDARQeUNBMRgwFgYDVQQDDA9jcnlwdG9ncmFwaHkuaW+C +AQMwDQYJKoZIhvcNAQEFBQADggEBAFbZYy6aZJUK/f7nJx2Rs/ht6hMbM32/RoXZ +JGbYapNVqVu/vymcfc/se3FHS5OVmPsnRlo/FIKDn/r5DGl73Sn/FvDJiLJZFucT +msyYuHZ+ZRYWzWmN2fcB3cfxj0s3qps6f5OoCOqoINOSe4HRGlw4X9keZSD+3xAt +vHNwQdlPC7zWbPdrzLT+FqR0e/O81vFJJS6drHJWqPcR3NQVtZw+UF7A/HKwbfeL +Nu2zj6165hzOi9HUxa2/mPr/eLUUV1sTzXp2+TFjt3rVCjW1XnpMLdwNBHzjpyAB +dTOX3iw0+BPy3s2jtnCW1PLpc74kvSTaBwhg74sq39EXfIKax00= +-----END CERTIFICATE----- diff --git a/vendor/openssl/test/ca.crt b/vendor/openssl/test/ca.crt new file mode 100644 index 0000000..a0a8ab2 --- /dev/null +++ b/vendor/openssl/test/ca.crt @@ -0,0 +1,88 @@ +Certificate: + Data: + Version: 3 (0x2) + Serial Number: + 13:ae:da:d8:f4:18:d7:73:b8:bd:35:c9:ce:8e:b3:fc + Signature Algorithm: sha256WithRSAEncryption + Issuer: CN=TestCA + Validity + Not Before: Jun 6 19:11:19 2019 GMT + Not After : May 21 19:11:19 2022 GMT + Subject: CN=SubCA + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + RSA Public-Key: (2048 bit) + Modulus: + 00:b0:09:fc:54:e7:6a:9f:0c:bd:ad:5a:8d:ef:94: + 4e:11:a6:87:19:4f:bf:a6:e1:62:a5:2d:b7:17:df: + 67:53:70:da:fe:7d:99:17:ee:13:47:0b:40:0b:a2: + 34:32:a9:d3:bf:20:fc:13:77:a1:d5:26:60:1f:f0: + d4:be:dc:76:7c:1e:6c:b4:4c:01:7c:56:cd:5c:53: + ec:81:b3:81:2a:b2:35:26:06:5a:79:e0:b3:9e:e4: + 57:e1:09:de:ad:7f:c8:cd:87:ee:49:93:30:52:58: + b2:bc:0f:c1:b6:10:44:f8:85:d5:5b:0a:9b:28:fe: + f4:f4:4a:16:a6:f7:25:e9:96:47:69:73:5b:33:77: + 92:7d:61:8d:2a:3d:d5:04:89:40:bf:6b:d2:fd:5d: + e2:1a:80:a9:8e:c8:92:f6:e5:4c:00:84:f9:6e:2a: + 93:a3:23:ee:28:23:81:f4:54:f0:18:2c:ee:32:8e: + 38:9c:a0:c8:33:04:b0:fc:4c:43:1a:5c:04:84:9f: + 73:c6:08:c7:1d:64:39:fe:72:19:3b:cc:a5:fd:0b: + 43:25:0d:2b:a9:88:77:9e:62:e6:ac:c2:9a:60:42: + 4f:4a:54:47:bc:a0:29:72:7c:38:52:c9:ea:27:c5: + 3d:d0:81:4a:3e:b8:78:79:4b:89:b8:4e:6d:1b:24: + 15:bd + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 CRL Distribution Points: + + Full Name: + URI:http://127.0.0.1:8081/pki/test.crl + + X509v3 Basic Constraints: + CA:TRUE + X509v3 Subject Key Identifier: + FD:82:45:39:A1:91:41:F2:66:CC:0D:75:D5:0D:40:D5:81:A7:A1:43 + X509v3 Authority Key Identifier: + keyid:C5:CC:F5:A1:8C:D9:E4:A7:BA:EC:21:F5:D1:84:23:EA:0D:C2:C7:30 + DirName:/CN=TestCA + serial:33:E7:04:87:09:32:87:21:D9:CD:7C:AA:4C:5A:BB:2C:6C:7B:54:28 + + X509v3 Key Usage: + Certificate Sign, CRL Sign + Signature Algorithm: sha256WithRSAEncryption + 96:a0:ff:8a:4b:bd:45:96:c9:72:3c:63:e3:48:c4:ab:ef:7e: + db:76:3f:d9:02:9e:69:c8:d9:36:55:e1:f5:9b:c9:69:d8:69: + 02:ac:50:8c:60:94:2c:2e:b9:a8:65:ac:f5:00:b0:8b:96:25: + 0b:8a:ef:94:21:57:e2:04:c2:c3:86:bf:06:4e:91:5c:e6:bc: + 1b:03:31:8b:64:ea:c5:79:c3:5c:94:e5:aa:67:7e:74:12:07: + 14:fd:cd:32:02:26:26:c9:0a:ed:d4:da:ee:2a:84:e3:f1:60: + b3:09:77:27:a1:3c:ac:ec:61:18:30:b5:6d:1f:16:0a:24:1a: + cf:1c:1b:60:a5:60:e5:2c:8b:cf:37:83:0c:15:e7:79:30:3f: + ee:50:45:7c:4b:c6:2c:cd:2c:81:0a:98:f1:65:44:7a:ca:2a: + 20:1a:de:19:d9:4b:ca:a1:e2:a4:b5:14:47:bf:b4:68:15:03: + c0:55:e5:f4:47:0e:55:9f:fe:85:d8:2c:7d:d0:1a:96:11:b9: + 68:b7:74:1e:61:94:c1:ae:87:52:2d:c6:26:ba:51:ed:f1:91: + c0:e6:4c:f8:ad:02:23:75:51:fc:f8:69:05:ec:cf:31:50:5a: + 41:78:eb:3d:27:4d:9b:68:ef:ba:0e:ba:3a:7d:60:00:9d:53: + a5:08:3d:c6 +-----BEGIN CERTIFICATE----- +MIIDbDCCAlSgAwIBAgIQE67a2PQY13O4vTXJzo6z/DANBgkqhkiG9w0BAQsFADAR +MQ8wDQYDVQQDDAZUZXN0Q0EwHhcNMTkwNjA2MTkxMTE5WhcNMjIwNTIxMTkxMTE5 +WjAQMQ4wDAYDVQQDDAVTdWJDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC +ggEBALAJ/FTnap8Mva1aje+UThGmhxlPv6bhYqUttxffZ1Nw2v59mRfuE0cLQAui +NDKp078g/BN3odUmYB/w1L7cdnwebLRMAXxWzVxT7IGzgSqyNSYGWnngs57kV+EJ +3q1/yM2H7kmTMFJYsrwPwbYQRPiF1VsKmyj+9PRKFqb3JemWR2lzWzN3kn1hjSo9 +1QSJQL9r0v1d4hqAqY7IkvblTACE+W4qk6Mj7igjgfRU8Bgs7jKOOJygyDMEsPxM +QxpcBISfc8YIxx1kOf5yGTvMpf0LQyUNK6mId55i5qzCmmBCT0pUR7ygKXJ8OFLJ +6ifFPdCBSj64eHlLibhObRskFb0CAwEAAaOBwDCBvTAzBgNVHR8ELDAqMCigJqAk +hiJodHRwOi8vMTI3LjAuMC4xOjgwODEvcGtpL3Rlc3QuY3JsMAwGA1UdEwQFMAMB +Af8wHQYDVR0OBBYEFP2CRTmhkUHyZswNddUNQNWBp6FDMEwGA1UdIwRFMEOAFMXM +9aGM2eSnuuwh9dGEI+oNwscwoRWkEzARMQ8wDQYDVQQDDAZUZXN0Q0GCFDPnBIcJ +Moch2c18qkxauyxse1QoMAsGA1UdDwQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAQEA +lqD/iku9RZbJcjxj40jEq+9+23Y/2QKeacjZNlXh9ZvJadhpAqxQjGCULC65qGWs +9QCwi5YlC4rvlCFX4gTCw4a/Bk6RXOa8GwMxi2TqxXnDXJTlqmd+dBIHFP3NMgIm +JskK7dTa7iqE4/Fgswl3J6E8rOxhGDC1bR8WCiQazxwbYKVg5SyLzzeDDBXneTA/ +7lBFfEvGLM0sgQqY8WVEesoqIBreGdlLyqHipLUUR7+0aBUDwFXl9EcOVZ/+hdgs +fdAalhG5aLd0HmGUwa6HUi3GJrpR7fGRwOZM+K0CI3VR/PhpBezPMVBaQXjrPSdN +m2jvug66On1gAJ1TpQg9xg== +-----END CERTIFICATE----- diff --git a/vendor/openssl/test/cert.pem b/vendor/openssl/test/cert.pem new file mode 100644 index 0000000..032fe60 --- /dev/null +++ b/vendor/openssl/test/cert.pem @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIDGzCCAgMCCQCHcfe97pgvpTANBgkqhkiG9w0BAQsFADBFMQswCQYDVQQGEwJB +VTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0 +cyBQdHkgTHRkMB4XDTE2MDgxNDE3MDAwM1oXDTI2MDgxMjE3MDAwM1owWjELMAkG +A1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0 +IFdpZGdpdHMgUHR5IEx0ZDETMBEGA1UEAwwKZm9vYmFyLmNvbTCCASIwDQYJKoZI +hvcNAQEBBQADggEPADCCAQoCggEBAKj0JYxEsxejUIX+I5GH0Hg2G0kX/y1H0+Ub +3mw2/Ja5BD/yN96/7zMSumXF8uS3SkmpyiJkbyD01TSRTqjlP7/VCBlyUIChlpLQ +mrGaijZiT/VCyPXqmcwFzXS5IOTpX1olJfW8rA41U1LCIcDUyFf6LtZ/v8rSeKr6 +TuE6SGV4WRaBm1SrjWBeHVV866CRrtSS1ieT2asFsAyOZqWhk2fakwwBDFWDhOGI +ubfO+5aq9cBJbNRlzsgB3UZs3gC0O6GzbnZ6oT0TiJMeTsXXjABLUlaq/rrqFF4Y +euZkkbHTFBMz288PUc3m3ZTcpN+E7+ZOUBRZXKD20K07NugqCzUCAwEAATANBgkq +hkiG9w0BAQsFAAOCAQEASvYHuIl5C0NHBELPpVHNuLbQsDQNKVj3a54+9q1JkiMM +6taEJYfw7K1Xjm4RoiFSHpQBh+PWZS3hToToL2Zx8JfMR5MuAirdPAy1Sia/J/qE +wQdJccqmvuLkLTSlsGbEJ/LUUgOAgrgHOZM5lUgIhCneA0/dWJ3PsN0zvn69/faY +oo1iiolWiIHWWBUSdr3jM2AJaVAsTmLh00cKaDNk37JB940xConBGSl98JPrNrf9 +dUAiT0iIBngDBdHnn/yTj+InVEFyZSKrNtiDSObFHxPcxGteHNrCPJdP1e+GqkHp +HJMRZVCQpSMzvHlofHSNgzWV1MX5h1CP4SGZdBDTfA== +-----END CERTIFICATE----- diff --git a/vendor/openssl/test/certs.pem b/vendor/openssl/test/certs.pem new file mode 100644 index 0000000..9d35166 --- /dev/null +++ b/vendor/openssl/test/certs.pem @@ -0,0 +1,40 @@ +-----BEGIN CERTIFICATE----- +MIIDGzCCAgMCCQCHcfe97pgvpTANBgkqhkiG9w0BAQsFADBFMQswCQYDVQQGEwJB +VTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0 +cyBQdHkgTHRkMB4XDTE2MDgxNDE3MDAwM1oXDTI2MDgxMjE3MDAwM1owWjELMAkG +A1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0 +IFdpZGdpdHMgUHR5IEx0ZDETMBEGA1UEAwwKZm9vYmFyLmNvbTCCASIwDQYJKoZI +hvcNAQEBBQADggEPADCCAQoCggEBAKj0JYxEsxejUIX+I5GH0Hg2G0kX/y1H0+Ub +3mw2/Ja5BD/yN96/7zMSumXF8uS3SkmpyiJkbyD01TSRTqjlP7/VCBlyUIChlpLQ +mrGaijZiT/VCyPXqmcwFzXS5IOTpX1olJfW8rA41U1LCIcDUyFf6LtZ/v8rSeKr6 +TuE6SGV4WRaBm1SrjWBeHVV866CRrtSS1ieT2asFsAyOZqWhk2fakwwBDFWDhOGI +ubfO+5aq9cBJbNRlzsgB3UZs3gC0O6GzbnZ6oT0TiJMeTsXXjABLUlaq/rrqFF4Y +euZkkbHTFBMz288PUc3m3ZTcpN+E7+ZOUBRZXKD20K07NugqCzUCAwEAATANBgkq +hkiG9w0BAQsFAAOCAQEASvYHuIl5C0NHBELPpVHNuLbQsDQNKVj3a54+9q1JkiMM +6taEJYfw7K1Xjm4RoiFSHpQBh+PWZS3hToToL2Zx8JfMR5MuAirdPAy1Sia/J/qE +wQdJccqmvuLkLTSlsGbEJ/LUUgOAgrgHOZM5lUgIhCneA0/dWJ3PsN0zvn69/faY +oo1iiolWiIHWWBUSdr3jM2AJaVAsTmLh00cKaDNk37JB940xConBGSl98JPrNrf9 +dUAiT0iIBngDBdHnn/yTj+InVEFyZSKrNtiDSObFHxPcxGteHNrCPJdP1e+GqkHp +HJMRZVCQpSMzvHlofHSNgzWV1MX5h1CP4SGZdBDTfA== +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIDXTCCAkWgAwIBAgIJAOIvDiVb18eVMA0GCSqGSIb3DQEBCwUAMEUxCzAJBgNV +BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX +aWRnaXRzIFB0eSBMdGQwHhcNMTYwODE0MTY1NjExWhcNMjYwODEyMTY1NjExWjBF +MQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50 +ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB +CgKCAQEArVHWFn52Lbl1l59exduZntVSZyDYpzDND+S2LUcO6fRBWhV/1Kzox+2G +ZptbuMGmfI3iAnb0CFT4uC3kBkQQlXonGATSVyaFTFR+jq/lc0SP+9Bd7SBXieIV +eIXlY1TvlwIvj3Ntw9zX+scTA4SXxH6M0rKv9gTOub2vCMSHeF16X8DQr4XsZuQr +7Cp7j1I4aqOJyap5JTl5ijmG8cnu0n+8UcRlBzy99dLWJG0AfI3VRJdWpGTNVZ92 +aFff3RpK3F/WI2gp3qV1ynRAKuvmncGC3LDvYfcc2dgsc1N6Ffq8GIrkgRob6eBc +klDHp1d023Lwre+VaVDSo1//Y72UFwIDAQABo1AwTjAdBgNVHQ4EFgQUbNOlA6sN +XyzJjYqciKeId7g3/ZowHwYDVR0jBBgwFoAUbNOlA6sNXyzJjYqciKeId7g3/Zow +DAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAVVaR5QWLZIRR4Dw6TSBn +BQiLpBSXN6oAxdDw6n4PtwW6CzydaA+creiK6LfwEsiifUfQe9f+T+TBSpdIYtMv +Z2H2tjlFX8VrjUFvPrvn5c28CuLI0foBgY8XGSkR2YMYzWw2jPEq3Th/KM5Catn3 +AFm3bGKWMtGPR4v+90chEN0jzaAmJYRrVUh9vea27bOCn31Nse6XXQPmSI6Gyncy +OAPUsvPClF3IjeL1tmBotWqSGn1cYxLo+Lwjk22A9h6vjcNQRyZF2VLVvtwYrNU3 +mwJ6GCLsLHpwW/yjyvn8iEltnJvByM/eeRnfXV6WDObyiZsE/n6DxIRJodQzFqy9 +GA== +-----END CERTIFICATE----- diff --git a/vendor/openssl/test/certv3.pem b/vendor/openssl/test/certv3.pem new file mode 100644 index 0000000..8194091 --- /dev/null +++ b/vendor/openssl/test/certv3.pem @@ -0,0 +1,23 @@ +-----BEGIN CERTIFICATE----- +MIIDwTCCAqmgAwIBAgIUDeCGNunyJfBd3U/qUtmCcvbMyZwwDQYJKoZIhvcNAQEL +BQAwRTELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoM +GEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDAeFw0yMzAxMjMxMzMzNTJaFw0zMzAx +MjAxMzMzNTJaMFoxCzAJBgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEw +HwYDVQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQxEzARBgNVBAMMCmZvb2Jh +ci5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCo9CWMRLMXo1CF +/iORh9B4NhtJF/8tR9PlG95sNvyWuQQ/8jfev+8zErplxfLkt0pJqcoiZG8g9NU0 +kU6o5T+/1QgZclCAoZaS0Jqxmoo2Yk/1Qsj16pnMBc10uSDk6V9aJSX1vKwONVNS +wiHA1MhX+i7Wf7/K0niq+k7hOkhleFkWgZtUq41gXh1VfOugka7UktYnk9mrBbAM +jmaloZNn2pMMAQxVg4ThiLm3zvuWqvXASWzUZc7IAd1GbN4AtDuhs252eqE9E4iT +Hk7F14wAS1JWqv666hReGHrmZJGx0xQTM9vPD1HN5t2U3KTfhO/mTlAUWVyg9tCt +OzboKgs1AgMBAAGjgZMwgZAwTgYDVR0fBEcwRTAgoB6gHIYaaHR0cDovL2V4YW1w +bGUuY29tL2NybC5wZW0wIaAfoB2GG2h0dHA6Ly9leGFtcGxlLmNvbS9jcmwyLnBl +bTAdBgNVHQ4EFgQUtnMvYaVLoe9ILBWxn/PcNC+8rDAwHwYDVR0jBBgwFoAUbNOl +A6sNXyzJjYqciKeId7g3/ZowDQYJKoZIhvcNAQELBQADggEBAJZyk6Eo4p3JIyOt +7t6ET3K18BKvlRilze+zrGkaQYvKRsP6YzbZWgcIq59hy5VeFCX5O2WP91CPG3MU +I9eRiih66/ry3G4I8QEdpRKnn0N5unbGjb5qPT5wXrhU4IO+vn3sGZGM4uIM1/3K +N/bOh9CTsu9YqrdHSGeDyNzCy/XZ/j5bP4aNm31ZDNCZDFsbjr3/yTLcpHPL0UP3 +mCX8D16BDu1Nep+wK9VRuOEw6Z9tlT/VjTImzoOUoJO/o2UHfSHahX+n2aC5OpI6 +BdhaFBuJ1vn+yTWf3zIjhWUdp9TlzgRyFiyetP2FcKwremVVGdDq/Y6dfXaq8CA1 +6Fr9KTY= +-----END CERTIFICATE----- diff --git a/vendor/openssl/test/certv3_extfile b/vendor/openssl/test/certv3_extfile new file mode 100644 index 0000000..1b3df49 --- /dev/null +++ b/vendor/openssl/test/certv3_extfile @@ -0,0 +1 @@ +crlDistributionPoints=URI:http://example.com/crl.pem,URI:http://example.com/crl2.pem diff --git a/vendor/openssl/test/cms.p12 b/vendor/openssl/test/cms.p12 new file mode 100644 index 0000000..c4f96b6 Binary files /dev/null and b/vendor/openssl/test/cms.p12 differ diff --git a/vendor/openssl/test/cms_pubkey.der b/vendor/openssl/test/cms_pubkey.der new file mode 100644 index 0000000..7efd440 Binary files /dev/null and b/vendor/openssl/test/cms_pubkey.der differ diff --git a/vendor/openssl/test/corrupted-rsa.pem b/vendor/openssl/test/corrupted-rsa.pem new file mode 100644 index 0000000..fa2cc3b --- /dev/null +++ b/vendor/openssl/test/corrupted-rsa.pem @@ -0,0 +1,28 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCyiHMQLLOSG6T6 +AYpMTJj9f4WzXQF0+T0Ri/Mk6vcJMQdnLMrlEMIJA/4iCn32zvpQ0raYcuZZoyso +/Svqg7tAeC3aQ/iFopYWfaR+SDMEnpKMl26qwiIxlPcj9J8hAQw/9WA7YneBXq+T +ypONX4EeDn+bsp/mSNSZKYJBmwXevQ9xbnOOxmBrVd5OS07ZwYuQXy8uVsYe4IXX +7/F+BIyULnIlUxRcVRjKp9++PeS53KLJX04H6HeqUiWC8Ntd+DuD3df0a067L38o +sc+CVzwKXqvh75RwlXCR4/B3D9qEqSYmY7lxp9vA3hirWcSJn0xUIbHb7q1hzE0H +rL65mLwnAgMBAAECggEADePYJpKBGBAm35KTcB3ngJWAJp/I92ZVbieNb7peJOzC +btsJIBWT2xVgm2+7NCK5+Tl486xrfTQuLUlhNiTbQof3HUumKr4nCjHqmdlD1YtW +yzG+7kceAkMyOoMThwL+Bn3bPP42CQPVCjJmahyGPvs8H2DK2E+jRr/4KTgxQTki +s/MXmJa4+xhvfF4CmFVj8imkKCyUTFoaqvYevHDMrJ3cohXFONBPv0MT8X/Y0sgw +UVaZ1aw3dbLC2PBpZFotILGxch2rODXgOcer/GBC41aGQTBB8mLPwKb6KMh0xdPd +1E5NwyODA3YJ6W3fGe8WE0MIHoYlOkX+ukf4W4+U0wKBgQDhueBkZwrd1HdhqwhG +QKt1/itCx24Go75G/+5vJUCB4bcdaJP49aH0/H4BiSsKI8r+GVsVJcrKP8h3tgjw +hhuLLPSaWi9TiUsWeDTw0JrAJc7w6hwL1EYbnwcto5mRQdbfugitlkhh17yUmgdj +gczAKLfV3igxslnR67iNOEYrlwKBgQDKejyWNnxhBJoXerpR/hijoXhMaHqV6Z7T +gUy6F0BiJ5CqN+TOTaC17CEnsMmI28o1rWJ6bIKwOUPFXOE9Z5gyxuIJhY9M8n30 +iwm/Ug2oBTFAdZQyyCuCmPiNURnGo+Hhu1EtVwMWLt3Z0L+/DdI6pgPX8mG0NNZm ++pS96Lg9owKBgHOzCslr5638kZSGTh90Vm6McTAxeLv+gjFyTYy6022/fFSenfom +LXWdVhkDbgQshIfqBz23uVIhj2eM7tgaZVPZHydewpNW9B34T2qAAlIrDv99gBKw +I59UzCEgkj5aOQFEId6YAVHlesvQh6kBhymXtWLyFDgk6tUmtdns1krRAoGBAJj0 +pnhDSMpxk4ZRLBdsgGh8PkhaVOCSz2yvrKqXjgeYI+yytKI0ekdzzcgSAOzmPGc4 +R8B74G4HlG6vr2eXrp4NKAxRXOOf/A6UShTBg5d99KrhJ8cE9/l8XadDsNkiTC0e +OECsDqTfWrCExZUqd7neV+D2NWDQ2XaJrXuZJjVJAoGAIGA5ktXIxWIDeXkxo06b +nHeTEmOAgER/5UIikHnoSAnXo5JNZyFxqoylthWuA1fMPQw/UphAeawDwEXVKp1J +NEhLUfVAO/p1RBUsQi8LQVoO9Nql5u5dFjqoCnlRv5tbeAAzZH5magZk7/1rOS5T +Cj7WW2zW+iL20suUmXfCQGU= +-----END RSA PRIVATE KEY----- diff --git a/vendor/openssl/test/crl-ca.crt b/vendor/openssl/test/crl-ca.crt new file mode 100644 index 0000000..a4a9075 --- /dev/null +++ b/vendor/openssl/test/crl-ca.crt @@ -0,0 +1,20 @@ +-----BEGIN CERTIFICATE----- +MIIDPDCCAiSgAwIBAgIUM+cEhwkyhyHZzXyqTFq7LGx7VCgwDQYJKoZIhvcNAQEL +BQAwETEPMA0GA1UEAwwGVGVzdENBMB4XDTE5MDYwNjE5MTA1NVoXDTI5MDYwMzE5 +MTA1NVowETEPMA0GA1UEAwwGVGVzdENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A +MIIBCgKCAQEAtNcFPtD1MHcolhgTHIAx/b9OyawCbVzvgasv8R9+94ZMhoGc/tNc +dVg271pCSmj+zYAFYsIwjxW+iq2e5A/fiBc6uqtNfEbU7+77QzxFG5wIbXtmmqEb +dVbqBT28NeKTR6X+EHlNgbw90CHy7byA7LMewxbTt2q1eY1RnB0ji8zdGZmIUPeC +WxzkxXEd0fg+KwBFN3YHV9CJX2KJ10qv7DvbKHeIVBU7osm6tzvNglNnnT90GFSY +zc59b+zS00axcY3Kn08Vt+1qWB9Sl8tixCTGqR538y/ambDr3NCWsiQYWys9KE1L +g0nEaIjb84R7b+qNmPtOezd9tanx7j9UzQIDAQABo4GLMIGIMB0GA1UdDgQWBBTF +zPWhjNnkp7rsIfXRhCPqDcLHMDBMBgNVHSMERTBDgBTFzPWhjNnkp7rsIfXRhCPq +DcLHMKEVpBMwETEPMA0GA1UEAwwGVGVzdENBghQz5wSHCTKHIdnNfKpMWrssbHtU +KDAMBgNVHRMEBTADAQH/MAsGA1UdDwQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAQEA +gdyQq6F8DO5rn7rZSLehTFx6tbtfncC/BOXZEGLZO0ciTrQ9Q8xHwRhz0W09QE1A +/GsBzb++PuvAl9i82WvunyPB5KZh+GPiaaqf466MdQrXj+IyqxeC9Lg9wEUjwRgp +ANVd3moKap5IZ9WDvhyEng2Oy8/btP2iqVEmd58rGAodd671eOPD8QkIxSquiIwy +Cu5s3IBZ0BOuSG9fWoyPTGMKAhzQPFiXGvWOabCkMz3TsPYVY5ENpq2K8cWn2D/r +TD1yPPdINg6HrALGD3S0sD+k588oS7U5oj1L8V4KJQTLSbh6/XcBpasa5Jdv7ZZe +lVgt69Gsn5Cf2BkbwhbF2Q== +-----END CERTIFICATE----- diff --git a/vendor/openssl/test/csr.pem b/vendor/openssl/test/csr.pem new file mode 100644 index 0000000..cf9dde2 --- /dev/null +++ b/vendor/openssl/test/csr.pem @@ -0,0 +1,62 @@ +Certificate Request: + Data: + Version: 1 (0x0) + Subject: C = AU, ST = Some-State, O = Internet Widgits Pty Ltd, CN = foobar.com + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + RSA Public-Key: (2048 bit) + Modulus: + 00:a8:f4:25:8c:44:b3:17:a3:50:85:fe:23:91:87: + d0:78:36:1b:49:17:ff:2d:47:d3:e5:1b:de:6c:36: + fc:96:b9:04:3f:f2:37:de:bf:ef:33:12:ba:65:c5: + f2:e4:b7:4a:49:a9:ca:22:64:6f:20:f4:d5:34:91: + 4e:a8:e5:3f:bf:d5:08:19:72:50:80:a1:96:92:d0: + 9a:b1:9a:8a:36:62:4f:f5:42:c8:f5:ea:99:cc:05: + cd:74:b9:20:e4:e9:5f:5a:25:25:f5:bc:ac:0e:35: + 53:52:c2:21:c0:d4:c8:57:fa:2e:d6:7f:bf:ca:d2: + 78:aa:fa:4e:e1:3a:48:65:78:59:16:81:9b:54:ab: + 8d:60:5e:1d:55:7c:eb:a0:91:ae:d4:92:d6:27:93: + d9:ab:05:b0:0c:8e:66:a5:a1:93:67:da:93:0c:01: + 0c:55:83:84:e1:88:b9:b7:ce:fb:96:aa:f5:c0:49: + 6c:d4:65:ce:c8:01:dd:46:6c:de:00:b4:3b:a1:b3: + 6e:76:7a:a1:3d:13:88:93:1e:4e:c5:d7:8c:00:4b: + 52:56:aa:fe:ba:ea:14:5e:18:7a:e6:64:91:b1:d3: + 14:13:33:db:cf:0f:51:cd:e6:dd:94:dc:a4:df:84: + ef:e6:4e:50:14:59:5c:a0:f6:d0:ad:3b:36:e8:2a: + 0b:35 + Exponent: 65537 (0x10001) + Attributes: + a0:00 + Signature Algorithm: sha256WithRSAEncryption + 95:26:e1:84:56:e7:80:da:2c:a4:c0:b5:85:43:61:85:34:84: + 37:83:c0:bc:cf:70:20:89:46:ce:3d:7e:23:8a:40:a4:a5:fa: + c5:e3:3d:ee:e5:05:16:58:93:f9:6c:f3:86:ee:99:cc:e1:04: + 5c:68:99:da:66:72:a1:95:31:cd:13:6f:a5:6f:fc:a9:ec:75: + 6a:f7:e5:cf:0e:7b:5f:2f:db:8d:45:e6:66:52:12:1d:c9:ac: + 3a:86:35:bd:1f:7b:6e:b5:e1:f3:4f:80:6a:06:73:1c:a0:0d: + a3:63:b6:40:76:25:b0:e9:96:33:7a:9d:18:7e:5e:93:c0:47: + d7:0b:da:b3:03:17:94:d0:0c:78:18:f3:0e:cd:3c:f7:e8:25: + 08:c2:13:0a:af:1e:5c:48:5f:17:41:b2:2d:d2:0f:37:2e:b3: + 10:fd:2b:c0:77:e1:17:8a:57:0c:95:5e:c8:03:eb:63:14:2e: + 46:fd:1e:14:13:9f:38:c1:2f:e9:9b:47:c3:60:a9:d7:6e:a3: + d0:af:0b:6f:df:6e:37:f6:d9:a0:1b:dd:1f:a5:a5:33:89:1f: + a5:a3:44:14:91:83:c3:c8:b2:6e:fb:3f:f1:6d:d2:51:21:f7: + 98:20:0a:40:75:a5:60:c3:59:53:08:62:3d:39:e8:83:55:90: + 1a:bf:51:57 +-----BEGIN CERTIFICATE REQUEST----- +MIICnzCCAYcCAQAwWjELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUx +ITAfBgNVBAoMGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDETMBEGA1UEAwwKZm9v +YmFyLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKj0JYxEsxej +UIX+I5GH0Hg2G0kX/y1H0+Ub3mw2/Ja5BD/yN96/7zMSumXF8uS3SkmpyiJkbyD0 +1TSRTqjlP7/VCBlyUIChlpLQmrGaijZiT/VCyPXqmcwFzXS5IOTpX1olJfW8rA41 +U1LCIcDUyFf6LtZ/v8rSeKr6TuE6SGV4WRaBm1SrjWBeHVV866CRrtSS1ieT2asF +sAyOZqWhk2fakwwBDFWDhOGIubfO+5aq9cBJbNRlzsgB3UZs3gC0O6GzbnZ6oT0T +iJMeTsXXjABLUlaq/rrqFF4YeuZkkbHTFBMz288PUc3m3ZTcpN+E7+ZOUBRZXKD2 +0K07NugqCzUCAwEAAaAAMA0GCSqGSIb3DQEBCwUAA4IBAQCVJuGEVueA2iykwLWF +Q2GFNIQ3g8C8z3AgiUbOPX4jikCkpfrF4z3u5QUWWJP5bPOG7pnM4QRcaJnaZnKh +lTHNE2+lb/yp7HVq9+XPDntfL9uNReZmUhIdyaw6hjW9H3tuteHzT4BqBnMcoA2j +Y7ZAdiWw6ZYzep0Yfl6TwEfXC9qzAxeU0Ax4GPMOzTz36CUIwhMKrx5cSF8XQbIt +0g83LrMQ/SvAd+EXilcMlV7IA+tjFC5G/R4UE584wS/pm0fDYKnXbqPQrwtv3243 +9tmgG90fpaUziR+lo0QUkYPDyLJu+z/xbdJRIfeYIApAdaVgw1lTCGI9OeiDVZAa +v1FX +-----END CERTIFICATE REQUEST----- diff --git a/vendor/openssl/test/dhparams.pem b/vendor/openssl/test/dhparams.pem new file mode 100644 index 0000000..6e4d4c6 --- /dev/null +++ b/vendor/openssl/test/dhparams.pem @@ -0,0 +1,8 @@ +-----BEGIN DH PARAMETERS----- +MIIBCAKCAQEAh3Betv+hf5jNsOmGXU8oxuABD2B8r0yU8FVgjnCZBSVo61qJ0A2d +J6r8rYKbjtolnrZN/V4IPSzYvxurHbu8nbiFVyhOySPchI2Fu+YT/HsSe/0MH9bW +gJTNzmutWoy9VxtWLCmXnOSZHep3MZ1ZNimno6Kh2qQ7VJr0+KF8GbxUKOPv4SqK +NBwouIQXFc0pE9kGhcGKbr7TnHhyJFCRLNP1OVDQZbcoKjk1Vh+5sy7vM2VUTQmM +yOToT2LEZVAUJXNumcYMki9MIwfYCwYZbNt0ZEolyHzUEesuyHfU1eJd6+sKEjUz +5GteQIR7AehxZIS+cytu7BXO7B0owLJ2awIBAg== +-----END DH PARAMETERS----- diff --git a/vendor/openssl/test/dsa.pem b/vendor/openssl/test/dsa.pem new file mode 100644 index 0000000..9b55018 --- /dev/null +++ b/vendor/openssl/test/dsa.pem @@ -0,0 +1,12 @@ +-----BEGIN DSA PRIVATE KEY----- +MIIBuwIBAAKBgQCkKe/jtYKJNQafaE7kg2aaJOEPUV0Doi451jkXHp5UfLh6+t42 +eabSGkE9WBAlILgaB8yHckLe9+zozN39+SUDp94kb2r38/8w/9Ffhbsep9uiyOj2 +ZRQur6SkpKQDKcnAd6IMZXZcvdSgPC90A6qraYUZKq7Csjn63gbC+IvXHwIVAIgS +PE43lXD8/rGYxos4cxCgGGAxAoGASMV56WhLvVQtWMVI36WSIxbZnC2EsnNIKeVW +yXnP/OmPJ2mdezG7i1alcwsO2TnSLbvjvGPlyzIqZzHvWC8EmDqsfbU+n8we/Eal +sm5nloC8m9ECWpbTzbNdvrAAj9UPVWjcDwg7grAGGysh6lGbBv5P+4zL/niq1UiE +LnKcifgCgYEAo6mAasO0+MVcu8shxxUXXNeTLsZ8NB/BIx9EZ/dzE23ivNW8dq1A +eecAAYhssI2m/CspQvyKw+seCvg4FccxJgB3+mGOe+blFHwO3eAwoyRn/t3DZDHh +FjxKKRsQdy4BkZv+vhTyIYYCw0iPZ5Wfln+pyGGTveIDED1MPG+J6c8CFCJAUlEl +4nHvbC15xLXXpd46zycY +-----END DSA PRIVATE KEY----- diff --git a/vendor/openssl/test/dsa.pem.pub b/vendor/openssl/test/dsa.pem.pub new file mode 100644 index 0000000..ae298d0 --- /dev/null +++ b/vendor/openssl/test/dsa.pem.pub @@ -0,0 +1,12 @@ +-----BEGIN PUBLIC KEY----- +MIIBtzCCASsGByqGSM44BAEwggEeAoGBAKQp7+O1gok1Bp9oTuSDZpok4Q9RXQOi +LjnWORcenlR8uHr63jZ5ptIaQT1YECUguBoHzIdyQt737OjM3f35JQOn3iRvavfz +/zD/0V+Fux6n26LI6PZlFC6vpKSkpAMpycB3ogxldly91KA8L3QDqqtphRkqrsKy +OfreBsL4i9cfAhUAiBI8TjeVcPz+sZjGizhzEKAYYDECgYBIxXnpaEu9VC1YxUjf +pZIjFtmcLYSyc0gp5VbJec/86Y8naZ17MbuLVqVzCw7ZOdItu+O8Y+XLMipnMe9Y +LwSYOqx9tT6fzB78RqWybmeWgLyb0QJaltPNs12+sACP1Q9VaNwPCDuCsAYbKyHq +UZsG/k/7jMv+eKrVSIQucpyJ+AOBhQACgYEAo6mAasO0+MVcu8shxxUXXNeTLsZ8 +NB/BIx9EZ/dzE23ivNW8dq1AeecAAYhssI2m/CspQvyKw+seCvg4FccxJgB3+mGO +e+blFHwO3eAwoyRn/t3DZDHhFjxKKRsQdy4BkZv+vhTyIYYCw0iPZ5Wfln+pyGGT +veIDED1MPG+J6c8= +-----END PUBLIC KEY----- diff --git a/vendor/openssl/test/dsaparam.pem b/vendor/openssl/test/dsaparam.pem new file mode 100644 index 0000000..53bda54 --- /dev/null +++ b/vendor/openssl/test/dsaparam.pem @@ -0,0 +1,9 @@ +-----BEGIN DSA PARAMETERS----- +MIIBHgKBgQCkKe/jtYKJNQafaE7kg2aaJOEPUV0Doi451jkXHp5UfLh6+t42eabS +GkE9WBAlILgaB8yHckLe9+zozN39+SUDp94kb2r38/8w/9Ffhbsep9uiyOj2ZRQu +r6SkpKQDKcnAd6IMZXZcvdSgPC90A6qraYUZKq7Csjn63gbC+IvXHwIVAIgSPE43 +lXD8/rGYxos4cxCgGGAxAoGASMV56WhLvVQtWMVI36WSIxbZnC2EsnNIKeVWyXnP +/OmPJ2mdezG7i1alcwsO2TnSLbvjvGPlyzIqZzHvWC8EmDqsfbU+n8we/Ealsm5n +loC8m9ECWpbTzbNdvrAAj9UPVWjcDwg7grAGGysh6lGbBv5P+4zL/niq1UiELnKc +ifg= +-----END DSA PARAMETERS----- diff --git a/vendor/openssl/test/entry_extensions.crl b/vendor/openssl/test/entry_extensions.crl new file mode 100644 index 0000000..5b0ee29 --- /dev/null +++ b/vendor/openssl/test/entry_extensions.crl @@ -0,0 +1,11 @@ +-----BEGIN X509 CRL----- +MIIBojCCAUkCAQEwCgYIKoZIzj0EAwIwHTEbMBkGA1UEAwwSY3J5cHRvZ3JhcGh5 +LmlvIENBFw0yMzA3MjUxNDA1MzlaFw0yMzA4MDExNDA1MzlaMIGAMH4CFE+Y95/1 +pOqa6c9fUEJ8c04kxu2PFw0yMzA3MjUxNDA1MzlaMFcwLwYDVR0dAQH/BCUwI6Qh +MB8xCzAJBgNVBAYTAkdCMRAwDgYDVQQDDAdUZXN0IENBMAoGA1UdFQQDCgEBMBgG +A1UdGAQRGA8yMDIzMDcyNTE0MDUzOVqgeDB2MB8GA1UdIwQYMBaAFK6qKNgsGefh +XexO9WsIwiQ/73R8MAoGA1UdFAQDAgEUMAwGA1UdHAQFMAOEAf8wOQYIKwYBBQUH +AQEELTArMCkGCCsGAQUFBzAChh1odHRwOi8vd3d3LmV4YW1wbGUuY29tL2NhLmNy +dDAKBggqhkjOPQQDAgNHADBEAiB22SXxFnQUB41uxfyCvg2dAs2nFiR0r8jft/cd +G8zcKAIgeYkNOzRn4lyopK6J94rhm8jIIuJRj3Ns9XcH+91N370= +-----END X509 CRL----- diff --git a/vendor/openssl/test/identity.p12 b/vendor/openssl/test/identity.p12 new file mode 100644 index 0000000..d16abb8 Binary files /dev/null and b/vendor/openssl/test/identity.p12 differ diff --git a/vendor/openssl/test/intermediate-ca.key b/vendor/openssl/test/intermediate-ca.key new file mode 100644 index 0000000..48f4495 --- /dev/null +++ b/vendor/openssl/test/intermediate-ca.key @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEpAIBAAKCAQEA1HsHFTpgKeWL/y6oKtARZm0Dy6J/08E0CujmdpVp0xnkXi/A +RARnbMEbOPfmBUMOkVtQT3+l5aCgIAX+Kg6K7sQvio8nQUgOxuO1YpGlYu9EMtc7 +5fNxA1T0CuXXx8ClfEqW1ZV7ziQV0J4gzvuI26A7XyUhdk1oP/Al3F/94TmH6dtP +SQ2K901O2zknU+bpPheQy08SE20k/nUOJAsiwtsxqY8hHOL1sXZ4K+I311hl0QpD +OYf7eBcBdo2Mc5Nzjd9LPGLk1lE3itAXpayFMmfuuA0IdH1gNfy18axFEEVnj6CS +2epGpmAckUEWUOse1WBhDEt6ddowT1iw7X4mWwIDAQABAoIBAGMGXzuudAiymTc5 +OFiTlbhlkAJEXkyC201GU7nqUmJ2y651lKZeYxEVQimfpszG/rARnXEfbWKCJH4o +LNbO5kL2na12n/XVrkVU9EDW3fwoxGDpXFoDxaSm4AGAMrs+diFh5b/upb9ho+UQ +/PtZ0OOCXokuFdU7qB08P3jgJ8LhooqWnZ4AC0rhN85CMNIKs/nrUrnmS3FZLVd/ +NWI9Vfjsndd41Gkho0A7tgOSnwRupk/Bv1b0px31h8ucp9/nLuR8vbGSdS/R9Sta +pB9KNYYQ3LrhQGjddnEU0gj8qsuWgnoPf7eaWsLVunPLHQzL2hNNKL1eBADm7Lhh +avIlnrkCgYEA8Q8UhOeIO0sMU8sB4NPTUf2UT9xjURoowGsGgbDEk21eABH6VC33 +VYt5r5xwbZFQvVaTbe+EI1YDpjH1cvpmorEWI47Nm4Vbf9JujW/hoQwuwpzOpdUT +2G4tfMQrmTw/9HJ0l9+1Ib+A93dB8GvR0NE1uueaWanWvXARInwGiscCgYEA4aZ9 +mbhuwx88sSRMXwxSZw+R5BRrjdC0CeoimGg4/P84bKgc0YsjAha5jWaC/h8xN2Pb +w45b3hQ0/FP8xohP0bp/5eeiDbqb6JuO5bI3CnfBrVpu1CAuIrf7lhkar3a0wluB +k03fVHuVLtydACDJBKrZm1F39lpiZiEqlBIp080CgYEAwRwYjwPAEefkHzhQ7+Ah +uNwQtQ1TjsQLA2J5mumWAJirphjA1jDgo+oQ+Iq1UkEIUjWJ85bd30TntXruK0bH +c+uzVZbvxXfGvhZAtBN9x/svdn4R2a1hsY9J51prpt0qStRp7MSsoTV9xkEGVOi6 +87K1fV5OOyggvC+Lunlq8D8CgYAVSCOObPOdWYPa3SaKzFm1OKW00iw2qtlgGgH7 +R9EgI14J+W0GYk4B82y6plFycDSvGa7vaazGbDd3GOC9RLvqduF7KHaDPvdXX9yB +U2aXiSXuGJpdTU+snJeQ13tJ0zNHJWQ6JV0L1cADNHFmQrFSzF5LpMpgpLOlGDmw +z2m8fQKBgQDclFeonyn0zcXqznun9kAKkMij4s6lSdRgi/5Zh1WbJwOso9oWfwz9 +SSTP2KBO8B+/yFvuo5SWrbNaTz9/KuzMTv4HXz5ukLbyN9Jjtk73fdBBRSjL+zF5 +jU56oXHrwBhEqWQ77Ps60r+FmDjUgUhyJl14ZfkzICUK7NLFxKrvMQ== +-----END RSA PRIVATE KEY----- diff --git a/vendor/openssl/test/intermediate-ca.pem b/vendor/openssl/test/intermediate-ca.pem new file mode 100644 index 0000000..266ef59 --- /dev/null +++ b/vendor/openssl/test/intermediate-ca.pem @@ -0,0 +1,22 @@ +-----BEGIN CERTIFICATE----- +MIIDszCCApugAwIBAgIEFSQSITANBgkqhkiG9w0BAQsFADBFMQswCQYDVQQGEwJB +VTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0 +cyBQdHkgTHRkMB4XDTIyMTEwMzA3MDc0OVoXDTI2MDgxMTA3MDc0OVowgYkxCzAJ +BgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5l +dCBXaWRnaXRzIFB0eSBMdGQxIDAeBgNVBAsMF0ludGVybWVkaWF0ZSBEZXBhcnRt +ZW50MSAwHgYDVQQDDBdpbnRlcm1lZGlhdGUuZm9vYmFyLmNvbTCCASIwDQYJKoZI +hvcNAQEBBQADggEPADCCAQoCggEBANR7BxU6YCnli/8uqCrQEWZtA8uif9PBNAro +5naVadMZ5F4vwEQEZ2zBGzj35gVDDpFbUE9/peWgoCAF/ioOiu7EL4qPJ0FIDsbj +tWKRpWLvRDLXO+XzcQNU9Arl18fApXxKltWVe84kFdCeIM77iNugO18lIXZNaD/w +Jdxf/eE5h+nbT0kNivdNTts5J1Pm6T4XkMtPEhNtJP51DiQLIsLbMamPIRzi9bF2 +eCviN9dYZdEKQzmH+3gXAXaNjHOTc43fSzxi5NZRN4rQF6WshTJn7rgNCHR9YDX8 +tfGsRRBFZ4+gktnqRqZgHJFBFlDrHtVgYQxLenXaME9YsO1+JlsCAwEAAaNmMGQw +HQYDVR0OBBYEFAXJImmmxYXx6L1SRRhgP3Tyq2J6MB8GA1UdIwQYMBaAFGzTpQOr +DV8syY2KnIiniHe4N/2aMBIGA1UdEwEB/wQIMAYBAf8CAQAwDgYDVR0PAQH/BAQD +AgGGMA0GCSqGSIb3DQEBCwUAA4IBAQCnUh7iNbnFBjVa4sFx02r65syxUhcvM/ya +DcSe1esGUwjZLyKVl9BTfQ6kfNa/6Z/t5cprp0R3etalN31dxka7xSDwzFNdBczB +zYDIVOVlcGLL1Xjozacm6YHo773dqxZS36rVMk3NqNUY6GJJ+CGso2xZShcBg2KG +fPlNPiRz3847E3dwouDYcP1MXf2ql/Y7dRbE+8kb3bWkSusJVb/4EHjpR7yZjKmh +eXHVVx1dKnCGRldn3+dSNhN6mxNaSeBE2hb158+diQvL5u3f//va7SOpCi0f4d8E +UCnLhieyrDlr42XXfz42BqRpqBO1SDjQwzIIc9Fbevwb916OSExp +-----END CERTIFICATE----- diff --git a/vendor/openssl/test/key.der b/vendor/openssl/test/key.der new file mode 100644 index 0000000..6b6209f Binary files /dev/null and b/vendor/openssl/test/key.der differ diff --git a/vendor/openssl/test/key.der.pub b/vendor/openssl/test/key.der.pub new file mode 100644 index 0000000..395b04a Binary files /dev/null and b/vendor/openssl/test/key.der.pub differ diff --git a/vendor/openssl/test/key.pem b/vendor/openssl/test/key.pem new file mode 100644 index 0000000..d381795 --- /dev/null +++ b/vendor/openssl/test/key.pem @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQCo9CWMRLMXo1CF +/iORh9B4NhtJF/8tR9PlG95sNvyWuQQ/8jfev+8zErplxfLkt0pJqcoiZG8g9NU0 +kU6o5T+/1QgZclCAoZaS0Jqxmoo2Yk/1Qsj16pnMBc10uSDk6V9aJSX1vKwONVNS +wiHA1MhX+i7Wf7/K0niq+k7hOkhleFkWgZtUq41gXh1VfOugka7UktYnk9mrBbAM +jmaloZNn2pMMAQxVg4ThiLm3zvuWqvXASWzUZc7IAd1GbN4AtDuhs252eqE9E4iT +Hk7F14wAS1JWqv666hReGHrmZJGx0xQTM9vPD1HN5t2U3KTfhO/mTlAUWVyg9tCt +OzboKgs1AgMBAAECggEBAKLj6IOJBKXolczpzb8UkyAjAkGBektcseV07gelJ/fk +3z0LuWPv5p12E/HlXB24vU2x/ikUbbP3eMsawRzDEahQqmNmPEkYAYUAy/Qpi9GN +DYvn3LqDec4jVgeQKS+p9H2DzUpTogp8zR2//yzbuWBg2+F//xh7vU0S0RQCziPM +x7RSBgbhxSfChfEJbS2sDnzfh0jRQmoY95iFv7puet1FJtzdZ4fgCd1RqmC2lFM5 +H0eZtN/Cz19lieVs0b996DErdEBqClVZO00eYbRozCDaBzRU3ybB/dMrGJxhkkXm +wb3kWMtziH9qOYsostuHIFu8eKFLloKxFnq2R4DGxOECgYEA2KUIZISOeGJSBcLJ +JAUK2gvgXPNo4HHWIwOA9xeN3ZJlsnPlffXQNnm6t1st1V2gfMm9I2n0m/F0y2B/ +n/XGSa8bghfPA9l0c2h58lkL3JQJR/paa8ycTz+YZPrznEyN7Qa0RrJXUvZv9lQL +Hc3+FHcSHgMqDV2f2bHAEu9YGi0CgYEAx6VEIPNvrHFgjo/jk1RTuk+m0xEWQsZL +Cs+izQMr2TaeJn8LG+93AvFuYn0J0nT3WuStLPrUg8i4IhSS6lf1tId5ivIZPm4r +YwMyblBJXhnHbk7Uqodjfw/3s6V2HAu++B7hTdyVr9DFuST9uv4m8bkPV8rfX1jE +I2rAPVWvgikCgYB+wNAQP547wQrMZBLbCDg5KwmyWJfb+b6X7czexOEz6humNTjo +YZHYzY/5B1fhpk3ntQD8X1nGg5caBvOk21+QbOtjShrM3cXMYCw5JvBRtitX+Zo9 +yBEMLOE0877ki8XeEDYZxu5gk98d+D4oygUGZEQtWxyXhVepPt5qNa8OYQKBgQDH +RVgZI6KFlqzv3wMh3PutbS9wYQ+9GrtwUQuIYe/0YSW9+vSVr5E0qNKrD28sV39F +hBauXLady0yvB6YUrjMbPFW+sCMuQzyfGWPO4+g3OrfqjFiM1ZIkE0YEU9Tt7XNx +qTDtTI1D7bhNMnTnniI1B6ge0und+3XafAThs5L48QKBgQCTTpfqMt8kU3tcI9sf +0MK03y7kA76d5uw0pZbWFy7KI4qnzWutCzb+FMPWWsoFtLJLPZy//u/ZCUVFVa4d +0Y/ASNQIESVPXFLAltlLo4MSmsg1vCBsbviEEaPeEjvMrgki93pYtd/aOSgkYC1T +mEq154s5rmqh+h+XRIf7Au0SLw== +-----END PRIVATE KEY----- diff --git a/vendor/openssl/test/key.pem.pub b/vendor/openssl/test/key.pem.pub new file mode 100644 index 0000000..2a82256 --- /dev/null +++ b/vendor/openssl/test/key.pem.pub @@ -0,0 +1,9 @@ +-----BEGIN PUBLIC KEY----- +MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAr1bXMptaIgOL9PVL8a7W +KG/C8+IbxP018eMBQZT0SnPQmXp0Q8Aai/F+AEDE7b5sO5U7WdxU4GRYw0wqkQNF +si78KNfoj2ZMlx6NRfl4UKuzrpGTPgQxuKDYedngPpWcbmW4P3zEL2Y7b18n9NJr +atRUzH1Zh/ReRO525Xadu58aviPw1Mzgse7cKyzb03Gll9noLnYNIIpO8jL+QyrD +8qNmfacmR20U0a6XDTtmsmk7AitGETICbTT0KRf+oAP0yIHoonllPpNLUEPZQjrp +ClS/S/wKdj7gaq9TaMbHULhFMjbCV8cuPu//rUAuWp3riaznZGOVQyn3Dp2CB3ad +yQIDAQAB +-----END PUBLIC KEY----- diff --git a/vendor/openssl/test/keystore-empty-chain.p12 b/vendor/openssl/test/keystore-empty-chain.p12 new file mode 100644 index 0000000..c39930a Binary files /dev/null and b/vendor/openssl/test/keystore-empty-chain.p12 differ diff --git a/vendor/openssl/test/leaf.pem b/vendor/openssl/test/leaf.pem new file mode 100644 index 0000000..0f7aa80 --- /dev/null +++ b/vendor/openssl/test/leaf.pem @@ -0,0 +1,21 @@ +-----BEGIN CERTIFICATE----- +MIIDejCCAmICBBUkEiQwDQYJKoZIhvcNAQELBQAwgYkxCzAJBgNVBAYTAkFVMRMw +EQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0 +eSBMdGQxIDAeBgNVBAsMF0ludGVybWVkaWF0ZSBEZXBhcnRtZW50MSAwHgYDVQQD +DBdpbnRlcm1lZGlhdGUuZm9vYmFyLmNvbTAeFw0yMjExMDMwNzE3NTJaFw0yNjA4 +MTEwNzE3NTJaMHkxCzAJBgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEw +HwYDVQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQxGDAWBgNVBAsMD0xlYWYg +RGVwYXJ0bWVudDEYMBYGA1UEAwwPbGVhZi5mb29iYXIuY29tMIIBIjANBgkqhkiG +9w0BAQEFAAOCAQ8AMIIBCgKCAQEAs9STUHGIcSOtioK6+02k9Jx4JuYVJ0SB7Ebd +FAhGiOxBSoOljRVmmALti89QMmRiRqlyJnGJch7AloCCRsLJA0MfUYvauqmKHZFk +iqtZ1HocHQ/LGNKfkILcclb4xp2nGYntKAyEqer3Qc6aPWAnQAV/+BshU1vlMfwU +T6vOJRG69mft6dkHEWSzZd7++7HmFQGnDmIs5jBJVCOgKVttkN8Bk2EsTvJi9zl2 +SXLTcVrTAxEvuawv2ZXvdI/Cpt1WW0litXlFLcYBGwt/N93TX/L3Iyw5HcNd/xf9 +QwOr6RR66krQJzKxwcIY934uq6cyTQhexgnffb65qXL4bbV5fwIDAQABMA0GCSqG +SIb3DQEBCwUAA4IBAQAZf0/r04AeKN2QhQ7Z0o2Iu/Yj3OD2tnbxVoltYk8CRfp3 +7VGl/5PUbmXXBSwMc4Udj88JlreU7iNEPAKtBqFczw0pwNfvxKG4Eh3vsfKrP+5g +gtVwDG0mWeKJ7udrmFt8N0uwxVYDKp/gv5+Bw2eMew9Eoyenj6k2yg0nbFKzA3EH +DqngETzX0dhdiYwVcoJFUK5ni3tVl9qi6FpmaTE6C5nTQLyH4CI+vo2x/QHINGaJ +OzY/rx35iyVqXVqxN/gO/hp6g0nT5zLuMg2rfvcAhdDsD7htYcHiNkofrC8s0oQE +W+r01EhxdEVvY1nYWanBCF6tktc5v5qf2WMS4ye5 +-----END CERTIFICATE----- diff --git a/vendor/openssl/test/nid_test_cert.pem b/vendor/openssl/test/nid_test_cert.pem new file mode 100644 index 0000000..6f17e73 --- /dev/null +++ b/vendor/openssl/test/nid_test_cert.pem @@ -0,0 +1,12 @@ +-----BEGIN CERTIFICATE----- +MIIB1DCCAX6gAwIBAgIJAMzXWZGWHleWMA0GCSqGSIb3DQEBCwUAMFYxHzAdBgkq +hkiG9w0BCQEWEHRlc3RAZXhhbXBsZS5jb20xFDASBgNVBAMMC2V4YW1wbGUuY29t +MR0wGwYJKoZIhvcNAQkUHg4ARQB4AGEAbQBwAGwAZTAeFw0xNTA3MDEwNjQ3NDRa +Fw0xNTA3MzEwNjQ3NDRaMFYxHzAdBgkqhkiG9w0BCQEWEHRlc3RAZXhhbXBsZS5j +b20xFDASBgNVBAMMC2V4YW1wbGUuY29tMR0wGwYJKoZIhvcNAQkUHg4ARQB4AGEA +bQBwAGwAZTBcMA0GCSqGSIb3DQEBAQUAA0sAMEgCQQCmejzp4+o35FD0hAnx2trL +08h07X5jZca9DgZH35hWXPh7fMucLt/IPXIRnz2zKEa/Mo6D2V/fx03Mqo0epid7 +AgMBAAGjLzAtMB0GA1UdDgQWBBRQa57tXz3rZNRz+fTbo3w3jQJMBTAMBgNVHRME +BTADAQH/MA0GCSqGSIb3DQEBCwUAA0EAm0iY9cr+gvC+vcQIebdofpQ4GcDW8U6W +Bxs8ZXinLl69P0jYLum3+XITNFRiyQqcivaxdxthxDNOX7P+aKwkJA== +-----END CERTIFICATE----- diff --git a/vendor/openssl/test/nid_uid_test_cert.pem b/vendor/openssl/test/nid_uid_test_cert.pem new file mode 100644 index 0000000..de6722a --- /dev/null +++ b/vendor/openssl/test/nid_uid_test_cert.pem @@ -0,0 +1,24 @@ +-----BEGIN CERTIFICATE----- +MIIEGTCCAwGgAwIBAgIJAItKTzcGfL1lMA0GCSqGSIb3DQEBCwUAMIGiMSIwIAYK +CZImiZPyLGQBAQwSdGhpcyBpcyB0aGUgdXNlcklkMQswCQYDVQQGEwJVUzETMBEG +A1UECAwKQ2FsaWZvcm5pYTESMBAGA1UEBwwJU3Vubnl2YWxlMRUwEwYDVQQKDAxS +dXN0IE9wZW5TU0wxDDAKBgNVBAsMA09TUzEhMB8GA1UEAwwYcnVzdC1vcGVuc3Ns +LmV4YW1wbGUuY29tMB4XDTE2MDIwMjE3MjIwMVoXDTE2MDMwMzE3MjIwMVowgaIx +IjAgBgoJkiaJk/IsZAEBDBJ0aGlzIGlzIHRoZSB1c2VySWQxCzAJBgNVBAYTAlVT +MRMwEQYDVQQIDApDYWxpZm9ybmlhMRIwEAYDVQQHDAlTdW5ueXZhbGUxFTATBgNV +BAoMDFJ1c3QgT3BlblNTTDEMMAoGA1UECwwDT1NTMSEwHwYDVQQDDBhydXN0LW9w +ZW5zc2wuZXhhbXBsZS5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB +AQDa3Gc+IE5DOhTv1m5DZW8qKiyNLd7v4DaAYLXSsDuLs+9wJ+Bs+wlBfrg+PT0t +EJlPaLL9IfD5eR3WpFu62TUexYhnJh+3vhCGsFHOXcTjtM+wy/dzZtOVh2wTzvqE +/FHBGw1eG3Ww+RkSFbwYmtm8JhIN8ffYxGn2O0yQpxypf5hNPYrC81zX+52X2w1h +jDYLpYt55w+e6q+iRRFk0tKiWHEqqh/r6UQQRpj2EeS+xTloZlO6h0nl2NPkVF3r +CXBoT8Ittxr7sqcYqf8TAA0I4qZRYXKYehFmv/VkSt85CcURJ/zXeoJ1TpxSvQie +2R9cRDkYROrIOAFbB/0mmHLBAgMBAAGjUDBOMB0GA1UdDgQWBBRKfPqtgrbdbTmH +XR6RC/p8t/65GjAfBgNVHSMEGDAWgBRKfPqtgrbdbTmHXR6RC/p8t/65GjAMBgNV +HRMEBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQCKfeGRduGsIwKNiGcDUNkNrc7Z +f8SWAmb/R6xiDfgjbhrtfBDowIZ5natEkTgf6kQPMJKyjg2NEM2uJWBc55rLOHIv +es1wQOlYjfEUmFD3lTIt2TM/IUgXn2j+zV1CRkJthQLVFChXsidd0Bqq2fBjd3ad +Yjzrxf3uOTBAs27koh2INNHfcUZCRsx8hP739zz2kw/r5NB/9iyENEyJKQvxo0jb +oN0JK2joGZrWetDukQrqf032TsdkboW5JresYybbAD3326Ljp+hlT/3WINc+3nZJ +Dn+pPMdpuZ5BUZ+u+XyNEPum3k3P3K19AF+zWYGooX0J1cmuCBrrqce20Lwy +-----END CERTIFICATE----- diff --git a/vendor/openssl/test/pkcs1.pem.pub b/vendor/openssl/test/pkcs1.pem.pub new file mode 100644 index 0000000..4d55704 --- /dev/null +++ b/vendor/openssl/test/pkcs1.pem.pub @@ -0,0 +1,8 @@ +-----BEGIN RSA PUBLIC KEY----- +MIIBCgKCAQEAyrcf7lv42BCoiDd3LYmF8eaGO4rhmGzGgi+NSZowkEuLhibHGQle +FkZC7h1VKsxKFgy7Fx+GYHkv9OLm9H5fdp3HhYlo19bZVGvSJ66OJe/Bc4S02bBb +Y8vwpc/N5O77m5J/nHLuL7XJtpfSKkX+3NPiX1X2L99iipt7F0a7hNws3G3Lxg6t +P3Yc55TPjXzXvDIgjt/fag6iF8L/bR3augJJdDhLzNucR8A5HcvPtIVo51R631Zq +MCh+dZvgz9zGCXwsvSky/iOJTHN3wnpsWuCAzS1iJMfjR783Tfv6sWFs19FH7pHP +xBA3b2enPM9KBzINGOly0eM4h0fh+VBltQIDAQAB +-----END RSA PUBLIC KEY----- diff --git a/vendor/openssl/test/pkcs8-nocrypt.der b/vendor/openssl/test/pkcs8-nocrypt.der new file mode 100644 index 0000000..04fbdc2 Binary files /dev/null and b/vendor/openssl/test/pkcs8-nocrypt.der differ diff --git a/vendor/openssl/test/pkcs8.der b/vendor/openssl/test/pkcs8.der new file mode 100644 index 0000000..47a2db8 Binary files /dev/null and b/vendor/openssl/test/pkcs8.der differ diff --git a/vendor/openssl/test/root-ca.key b/vendor/openssl/test/root-ca.key new file mode 100644 index 0000000..746ae2a --- /dev/null +++ b/vendor/openssl/test/root-ca.key @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEpQIBAAKCAQEArVHWFn52Lbl1l59exduZntVSZyDYpzDND+S2LUcO6fRBWhV/ +1Kzox+2GZptbuMGmfI3iAnb0CFT4uC3kBkQQlXonGATSVyaFTFR+jq/lc0SP+9Bd +7SBXieIVeIXlY1TvlwIvj3Ntw9zX+scTA4SXxH6M0rKv9gTOub2vCMSHeF16X8DQ +r4XsZuQr7Cp7j1I4aqOJyap5JTl5ijmG8cnu0n+8UcRlBzy99dLWJG0AfI3VRJdW +pGTNVZ92aFff3RpK3F/WI2gp3qV1ynRAKuvmncGC3LDvYfcc2dgsc1N6Ffq8GIrk +gRob6eBcklDHp1d023Lwre+VaVDSo1//Y72UFwIDAQABAoIBAGZrnd/dC2kp11uq +Sg8SHk3GMdPPjTf/lq51sVJAU4fdV2Eso0XCiCzdKDcqR6F+jiu8jHp4YO0riW8N +b1pkjohGjyOaddIaaVsZ80/OkgDz20Ird9XQ7uoEODvopA12+755BDH5PDwqHVeM +nKfPiwAK6Jz6CxGO9bq9ZNoBiSyO1uofaB4Cpp8t74XVeAuPiI/Bb6WJ8TW5K5dt +x0Jihdo46QgZR+z4PnyWIoACkhSoQmtTb9NUrpKceBcxdCrZ/kEmYpnPq/PuSw6g +6HthjYP/H9Xulz69UR5Ez6z+1pU1rKFmQ46qK7X3zVHg233MlGekMzxdmShEjzCP +BMGYpQECgYEA5tqTZsUJwx3HDhkaZ/XOtaQqwOnZm9wPwTjGbV1t4+NUJzsl5gjP +ho+I8ZSGZ6MnNSh+ClpYhUHYBq0rTuAAYL2arcMOuOs1GrMmiZJbXm8zq8M7gYr5 +V99H/7akSx66WV/agPkLIvh/BWxlWgQcoVAIzZibbLUxr7Ye50pCLfECgYEAwDLn +mFz0mFMvGtaSp8RnTDTFCz9czCeDt0GujCxG1epdvtuxlg/S1QH+mGzA/AHkiu7z +uzCwGKWozNTdRkqVwYoJTB+AYHseSkuGP+a1zr39w+xBW/vESb2oP95GIwprXcG2 +b/qdeQVzuLQhYoqWI2u8CBwlHFfpQO4Bp2ea+ocCgYEAurIgLSfCqlpFpiAlG9hN +8NYwgU1d4E+LKj+JMd8yRO+PGh8amjub4X3pST5NqDjpN3Nk42iHWFWUqGmZsbM0 +ewg7tLUgDeqiStKBoxaK8AdMqWc9k5lZ53e6mZISsnHKUQdVBaLjH8gJqdAs8yyK +HudEB0mYwMSUxz6pJXIHrXECgYEAhJkaCpXm8chB8UQj/baUhZDKeI4IWZjRWHbq +Ey7g1+hPMMOk6yCTlf1ARqyRH8u2ftuIL5bRhs+Te21IE5yVYOb4rxn0mZuXNC6S +ujdTKwUMtESkeu9hZnaAQz/4J2ii1hY05WCDj+DhC4bKmY9/MYS8PuQb/kfwVqld +Xr8tvrUCgYEAmslHocXBUFXyRDkEOx/aKo+t9fPBr95PBZzFUt9ejrTP4PXsLa46 +3/PNOCGdrQxh5qHHcvLwR4bPL++Dj+qMUTJXANrArKPDpE2WqH6pqWIC6yaZvzUk +17QbpXR6bHcdJV045pWpw40UCStTocVynY1lBfOw8VqxBIBlpVBBzew= +-----END RSA PRIVATE KEY----- diff --git a/vendor/openssl/test/root-ca.pem b/vendor/openssl/test/root-ca.pem new file mode 100644 index 0000000..4ec2f53 --- /dev/null +++ b/vendor/openssl/test/root-ca.pem @@ -0,0 +1,21 @@ +-----BEGIN CERTIFICATE----- +MIIDXTCCAkWgAwIBAgIJAOIvDiVb18eVMA0GCSqGSIb3DQEBCwUAMEUxCzAJBgNV +BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX +aWRnaXRzIFB0eSBMdGQwHhcNMTYwODE0MTY1NjExWhcNMjYwODEyMTY1NjExWjBF +MQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50 +ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB +CgKCAQEArVHWFn52Lbl1l59exduZntVSZyDYpzDND+S2LUcO6fRBWhV/1Kzox+2G +ZptbuMGmfI3iAnb0CFT4uC3kBkQQlXonGATSVyaFTFR+jq/lc0SP+9Bd7SBXieIV +eIXlY1TvlwIvj3Ntw9zX+scTA4SXxH6M0rKv9gTOub2vCMSHeF16X8DQr4XsZuQr +7Cp7j1I4aqOJyap5JTl5ijmG8cnu0n+8UcRlBzy99dLWJG0AfI3VRJdWpGTNVZ92 +aFff3RpK3F/WI2gp3qV1ynRAKuvmncGC3LDvYfcc2dgsc1N6Ffq8GIrkgRob6eBc +klDHp1d023Lwre+VaVDSo1//Y72UFwIDAQABo1AwTjAdBgNVHQ4EFgQUbNOlA6sN +XyzJjYqciKeId7g3/ZowHwYDVR0jBBgwFoAUbNOlA6sNXyzJjYqciKeId7g3/Zow +DAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAVVaR5QWLZIRR4Dw6TSBn +BQiLpBSXN6oAxdDw6n4PtwW6CzydaA+creiK6LfwEsiifUfQe9f+T+TBSpdIYtMv +Z2H2tjlFX8VrjUFvPrvn5c28CuLI0foBgY8XGSkR2YMYzWw2jPEq3Th/KM5Catn3 +AFm3bGKWMtGPR4v+90chEN0jzaAmJYRrVUh9vea27bOCn31Nse6XXQPmSI6Gyncy +OAPUsvPClF3IjeL1tmBotWqSGn1cYxLo+Lwjk22A9h6vjcNQRyZF2VLVvtwYrNU3 +mwJ6GCLsLHpwW/yjyvn8iEltnJvByM/eeRnfXV6WDObyiZsE/n6DxIRJodQzFqy9 +GA== +-----END CERTIFICATE----- diff --git a/vendor/openssl/test/rsa-encrypted.pem b/vendor/openssl/test/rsa-encrypted.pem new file mode 100644 index 0000000..a624999 --- /dev/null +++ b/vendor/openssl/test/rsa-encrypted.pem @@ -0,0 +1,30 @@ +-----BEGIN RSA PRIVATE KEY----- +Proc-Type: 4,ENCRYPTED +DEK-Info: AES-128-CBC,E2F16153E2BA3D617285A68C896BA6AF + +vO9SnhtGjGe8pG1pN//vsONnvJr+DjU+lFCiSqGMPT7tezDnbehLfS+9kus2HV7r +HmI14JvVG9O7NpF7zMyBRlHYdWcCCWED9Yar0NsWN9419e5pMe/bqIXAzAiJbtT4 +OB9U5XF3m+349zjN1dVXPPLGRmMC1pcHAlofeb5nIUFTvUi5xcsbe1itGjgkkvHb +Bt8NioHTBun8kKrlsFQOuB55ylBU/eWG8DQBtvFOmQ7iWp0RnGQfh8k5e5rcZNpQ +fD9ygc7UVISl0xTrIG4IH15g34H+nrBauKtIPOpNPuXQPOMHCZv3XH8wnhrWHHwT +ZFnQBdXbSpQtMsRh0phG2G+VIlyCgSn4+CxjCJ+TgFtsoK/tU0unmRYc59QnTxxb +qkHYsPs3E0NApQAgH1ENEGl1M+FGLYQH7gftjc3ophBTeRA17sRmD7Y4QBInggsq +Gv6tImPVBdekAjz/Ls/EyMwjAvvrL5eAokqrIsAarGo+zmbJKHzknw2KUz2En0+k +YYaxB4oy9u7bzuQlvio6xYHJEb4K197bby4Dldmqv7YCCJBJwhOBAInMD687viKv +vcUwL8YuS6cW5E8MbvEENlY4+lvKKj3M8Bnyb79cYIPQe92EuCwXU9DZXPRMLwwM +oFEJpF5E/PmNJzu+B52ahHtDrh83WSx71fWqjdTqwkPZhAYo3ztsfFkb/UqUcq8u +rBSebeUjZh0XZ9B04eshZQ5vJUcXGtYIe/77beV3Pv89/fw+zTZjpiP9Q3sZALzf +Qt0YGp0/6qBuqR1tcqdu65AS2hun7yFw7uRavqYKvww4axRiz2do+xWmZFuoCAwD +EWktaUujltpvAc1lo7lg4C6nByefJB9Xqk22N/vpqOsWr1NbAntT42Qj/HF9BVWR +osvN3yMnKYWYe6oSTVnNBDM5obWAIHd3I9gcxTOTb1KsEwt2RrDs5EpB5ptS3Fjo +JfBRhNZQ3cXttrIIhsHgDn9BDNg865/xpIgktKj0gEd60Abx0PqkAIm6IZTh4Efg +7uZwfzxB+saOcddbrW2gNdzVZMC0s2Ye3sqHhtLbAJ3BlXYTxE4CAvTg54Ny+5hF +IjvjlOKgXceSG1cSfk21/wyp9RY3Ft0AEYvvp0kZScWZaoA2aSFDUrchXVhgrEbn +lJ7UptjefwRFIreAlwbKSbIDDNWnyzvIWyHfQ2aYqgnb7W7XqNPSgH9cALCfzirI +dlRHjha0bMUtrjPCC/YfMXzJBVniy0gG6Pd5uC7vz/Awn6/6HRQVNaTQASphPBQ7 +bJuz+JTfzI9OUVCMRMdnb6b35U4P9tibFmnPvzTIPe+3WUmf8aRsLS3NN3G1Webd +PMYVZpMycPaAI0Ht87axhsOzlxCWHYWjdHa+WoNNc1J90TxLCmAHquh5BDaWvjMK +0DySftJZjV7Tf1p2KosmU83LRl39B5NHMbZb1xOEZl9IWwhT/PVKTVZ25xdxWLfb +hF4l8rfvKehIp5r4t8zW1bvI2Hl6vrUvmcUVWt3BfKjxlgwRVD0vvwonMt1INesF +204vUBeXbDsUUicLwOyUgaFvJ3XU3dOyvL9MhOgM5OgoFRRhG+4AS8a5JCD8iLtq +-----END RSA PRIVATE KEY----- diff --git a/vendor/openssl/test/rsa.pem b/vendor/openssl/test/rsa.pem new file mode 100644 index 0000000..d8185fe --- /dev/null +++ b/vendor/openssl/test/rsa.pem @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEowIBAAKCAQEAofgWCuLjybRlzo0tZWJjNiuSfb4p4fAkd/wWJcyQoTbji9k0 +l8W26mPddxHmfHQp+Vaw+4qPCJrcS2mJPMEzP1Pt0Bm4d4QlL+yRT+SFd2lZS+pC +gNMsD1W/YpRPEwOWvG6b32690r2jZ47soMZo9wGzjb/7OMg0LOL+bSf63kpaSHSX +ndS5z5rexMdbBYUsLA9e+KXBdQOS+UTo7WTBEMa2R2CapHg665xsmtdVMTBQY4uD +Zlxvb3qCo5ZwKh9kG4LT6/I5IhlJH7aGhyxXFvUK+DWNmoudF8NAco9/h9iaGNj8 +q2ethFkMLs91kzk2PAcDTW9gb54h4FRWyuXpoQIDAQABAoIBABKucaRpzQorw35S +bEUAVx8dYXUdZOlJcHtiWQ+dC6V8ljxAHj/PLyzTveyI5QO/xkObCyjIL303l2cf +UhPu2MFaJdjVzqACXuOrLot/eSFvxjvqVidTtAZExqFRJ9mylUVAoLvhowVWmC1O +n95fZCXxTUtxNEG1Xcc7m0rtzJKs45J+N/V9DP1edYH6USyPSWGp6wuA+KgHRnKK +Vf9GRx80JQY7nVNkL17eHoTWEwga+lwi0FEoW9Y7lDtWXYmKBWhUE+U8PGxlJf8f +40493HDw1WRQ/aSLoS4QTp3rn7gYgeHEvfJdkkf0UMhlknlo53M09EFPdadQ4TlU +bjqKc50CgYEA4BzEEOtIpmVdVEZNCqS7baC4crd0pqnRH/5IB3jw3bcxGn6QLvnE +tfdUdiYrqBdss1l58BQ3KhooKeQTa9AB0Hw/Py5PJdTJNPY8cQn7ouZ2KKDcmnPG +BY5t7yLc1QlQ5xHdwW1VhvKn+nXqhJTBgIPgtldC+KDV5z+y2XDwGUcCgYEAuQPE +fgmVtjL0Uyyx88GZFF1fOunH3+7cepKmtH4pxhtCoHqpWmT8YAmZxaewHgHAjLYs +p1ZSe7zFYHj7C6ul7TjeLQeZD/YwD66t62wDmpe/HlB+TnBA+njbglfIsRLtXlnD +zQkv5dTltRJ11BKBBypeeF6689rjcJIDEz9RWdcCgYAHAp9XcCSrn8wVkMVkKdb7 +DOX4IKjzdahm+ctDAJN4O/y7OW5FKebvUjdAIt2GuoTZ71iTG+7F0F+lP88jtjP4 +U4qe7VHoewl4MKOfXZKTe+YCS1XbNvfgwJ3Ltyl1OH9hWvu2yza7q+d5PCsDzqtm +27kxuvULVeya+TEdAB1ijQKBgQCH/3r6YrVH/uCWGy6bzV1nGNOdjKc9tmkfOJmN +54dxdixdpozCQ6U4OxZrsj3FcOhHBsqAHvX2uuYjagqvo3cOj1TRqNocX40omfCC +Mx3bD1yPPf/6TI2XECva/ggqEY2mYzmIiA5LVVmc5nrybr+lssFKneeyxN2Wq93S +0iJMdQKBgCGHewxzoa1r8ZMD0LETNrToK423K377UCYqXfg5XMclbrjPbEC3YI1Z +NqMtuhdBJqUnBi6tjKMF+34Xf0CUN8ncuXGO2CAYvO8PdyCixHX52ybaDjy1FtCE +6yUXjoKNXKvUm7MWGsAYH6f4IegOetN5NvmUMFStCSkh7ixZLkN1 +-----END RSA PRIVATE KEY----- diff --git a/vendor/openssl/test/rsa.pem.pub b/vendor/openssl/test/rsa.pem.pub new file mode 100644 index 0000000..093f2ba --- /dev/null +++ b/vendor/openssl/test/rsa.pem.pub @@ -0,0 +1,9 @@ +-----BEGIN PUBLIC KEY----- +MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAofgWCuLjybRlzo0tZWJj +NiuSfb4p4fAkd/wWJcyQoTbji9k0l8W26mPddxHmfHQp+Vaw+4qPCJrcS2mJPMEz +P1Pt0Bm4d4QlL+yRT+SFd2lZS+pCgNMsD1W/YpRPEwOWvG6b32690r2jZ47soMZo +9wGzjb/7OMg0LOL+bSf63kpaSHSXndS5z5rexMdbBYUsLA9e+KXBdQOS+UTo7WTB +EMa2R2CapHg665xsmtdVMTBQY4uDZlxvb3qCo5ZwKh9kG4LT6/I5IhlJH7aGhyxX +FvUK+DWNmoudF8NAco9/h9iaGNj8q2ethFkMLs91kzk2PAcDTW9gb54h4FRWyuXp +oQIDAQAB +-----END PUBLIC KEY----- diff --git a/vendor/openssl/test/subca.crt b/vendor/openssl/test/subca.crt new file mode 100644 index 0000000..a0a8ab2 --- /dev/null +++ b/vendor/openssl/test/subca.crt @@ -0,0 +1,88 @@ +Certificate: + Data: + Version: 3 (0x2) + Serial Number: + 13:ae:da:d8:f4:18:d7:73:b8:bd:35:c9:ce:8e:b3:fc + Signature Algorithm: sha256WithRSAEncryption + Issuer: CN=TestCA + Validity + Not Before: Jun 6 19:11:19 2019 GMT + Not After : May 21 19:11:19 2022 GMT + Subject: CN=SubCA + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + RSA Public-Key: (2048 bit) + Modulus: + 00:b0:09:fc:54:e7:6a:9f:0c:bd:ad:5a:8d:ef:94: + 4e:11:a6:87:19:4f:bf:a6:e1:62:a5:2d:b7:17:df: + 67:53:70:da:fe:7d:99:17:ee:13:47:0b:40:0b:a2: + 34:32:a9:d3:bf:20:fc:13:77:a1:d5:26:60:1f:f0: + d4:be:dc:76:7c:1e:6c:b4:4c:01:7c:56:cd:5c:53: + ec:81:b3:81:2a:b2:35:26:06:5a:79:e0:b3:9e:e4: + 57:e1:09:de:ad:7f:c8:cd:87:ee:49:93:30:52:58: + b2:bc:0f:c1:b6:10:44:f8:85:d5:5b:0a:9b:28:fe: + f4:f4:4a:16:a6:f7:25:e9:96:47:69:73:5b:33:77: + 92:7d:61:8d:2a:3d:d5:04:89:40:bf:6b:d2:fd:5d: + e2:1a:80:a9:8e:c8:92:f6:e5:4c:00:84:f9:6e:2a: + 93:a3:23:ee:28:23:81:f4:54:f0:18:2c:ee:32:8e: + 38:9c:a0:c8:33:04:b0:fc:4c:43:1a:5c:04:84:9f: + 73:c6:08:c7:1d:64:39:fe:72:19:3b:cc:a5:fd:0b: + 43:25:0d:2b:a9:88:77:9e:62:e6:ac:c2:9a:60:42: + 4f:4a:54:47:bc:a0:29:72:7c:38:52:c9:ea:27:c5: + 3d:d0:81:4a:3e:b8:78:79:4b:89:b8:4e:6d:1b:24: + 15:bd + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 CRL Distribution Points: + + Full Name: + URI:http://127.0.0.1:8081/pki/test.crl + + X509v3 Basic Constraints: + CA:TRUE + X509v3 Subject Key Identifier: + FD:82:45:39:A1:91:41:F2:66:CC:0D:75:D5:0D:40:D5:81:A7:A1:43 + X509v3 Authority Key Identifier: + keyid:C5:CC:F5:A1:8C:D9:E4:A7:BA:EC:21:F5:D1:84:23:EA:0D:C2:C7:30 + DirName:/CN=TestCA + serial:33:E7:04:87:09:32:87:21:D9:CD:7C:AA:4C:5A:BB:2C:6C:7B:54:28 + + X509v3 Key Usage: + Certificate Sign, CRL Sign + Signature Algorithm: sha256WithRSAEncryption + 96:a0:ff:8a:4b:bd:45:96:c9:72:3c:63:e3:48:c4:ab:ef:7e: + db:76:3f:d9:02:9e:69:c8:d9:36:55:e1:f5:9b:c9:69:d8:69: + 02:ac:50:8c:60:94:2c:2e:b9:a8:65:ac:f5:00:b0:8b:96:25: + 0b:8a:ef:94:21:57:e2:04:c2:c3:86:bf:06:4e:91:5c:e6:bc: + 1b:03:31:8b:64:ea:c5:79:c3:5c:94:e5:aa:67:7e:74:12:07: + 14:fd:cd:32:02:26:26:c9:0a:ed:d4:da:ee:2a:84:e3:f1:60: + b3:09:77:27:a1:3c:ac:ec:61:18:30:b5:6d:1f:16:0a:24:1a: + cf:1c:1b:60:a5:60:e5:2c:8b:cf:37:83:0c:15:e7:79:30:3f: + ee:50:45:7c:4b:c6:2c:cd:2c:81:0a:98:f1:65:44:7a:ca:2a: + 20:1a:de:19:d9:4b:ca:a1:e2:a4:b5:14:47:bf:b4:68:15:03: + c0:55:e5:f4:47:0e:55:9f:fe:85:d8:2c:7d:d0:1a:96:11:b9: + 68:b7:74:1e:61:94:c1:ae:87:52:2d:c6:26:ba:51:ed:f1:91: + c0:e6:4c:f8:ad:02:23:75:51:fc:f8:69:05:ec:cf:31:50:5a: + 41:78:eb:3d:27:4d:9b:68:ef:ba:0e:ba:3a:7d:60:00:9d:53: + a5:08:3d:c6 +-----BEGIN CERTIFICATE----- +MIIDbDCCAlSgAwIBAgIQE67a2PQY13O4vTXJzo6z/DANBgkqhkiG9w0BAQsFADAR +MQ8wDQYDVQQDDAZUZXN0Q0EwHhcNMTkwNjA2MTkxMTE5WhcNMjIwNTIxMTkxMTE5 +WjAQMQ4wDAYDVQQDDAVTdWJDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC +ggEBALAJ/FTnap8Mva1aje+UThGmhxlPv6bhYqUttxffZ1Nw2v59mRfuE0cLQAui +NDKp078g/BN3odUmYB/w1L7cdnwebLRMAXxWzVxT7IGzgSqyNSYGWnngs57kV+EJ +3q1/yM2H7kmTMFJYsrwPwbYQRPiF1VsKmyj+9PRKFqb3JemWR2lzWzN3kn1hjSo9 +1QSJQL9r0v1d4hqAqY7IkvblTACE+W4qk6Mj7igjgfRU8Bgs7jKOOJygyDMEsPxM +QxpcBISfc8YIxx1kOf5yGTvMpf0LQyUNK6mId55i5qzCmmBCT0pUR7ygKXJ8OFLJ +6ifFPdCBSj64eHlLibhObRskFb0CAwEAAaOBwDCBvTAzBgNVHR8ELDAqMCigJqAk +hiJodHRwOi8vMTI3LjAuMC4xOjgwODEvcGtpL3Rlc3QuY3JsMAwGA1UdEwQFMAMB +Af8wHQYDVR0OBBYEFP2CRTmhkUHyZswNddUNQNWBp6FDMEwGA1UdIwRFMEOAFMXM +9aGM2eSnuuwh9dGEI+oNwscwoRWkEzARMQ8wDQYDVQQDDAZUZXN0Q0GCFDPnBIcJ +Moch2c18qkxauyxse1QoMAsGA1UdDwQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAQEA +lqD/iku9RZbJcjxj40jEq+9+23Y/2QKeacjZNlXh9ZvJadhpAqxQjGCULC65qGWs +9QCwi5YlC4rvlCFX4gTCw4a/Bk6RXOa8GwMxi2TqxXnDXJTlqmd+dBIHFP3NMgIm +JskK7dTa7iqE4/Fgswl3J6E8rOxhGDC1bR8WCiQazxwbYKVg5SyLzzeDDBXneTA/ +7lBFfEvGLM0sgQqY8WVEesoqIBreGdlLyqHipLUUR7+0aBUDwFXl9EcOVZ/+hdgs +fdAalhG5aLd0HmGUwa6HUi3GJrpR7fGRwOZM+K0CI3VR/PhpBezPMVBaQXjrPSdN +m2jvug66On1gAJ1TpQg9xg== +-----END CERTIFICATE----- diff --git a/vendor/openssl/test/test.crl b/vendor/openssl/test/test.crl new file mode 100644 index 0000000..aead062 Binary files /dev/null and b/vendor/openssl/test/test.crl differ diff --git a/vendor/pkg-config/.cargo-checksum.json b/vendor/pkg-config/.cargo-checksum.json new file mode 100644 index 0000000..57ada08 --- /dev/null +++ b/vendor/pkg-config/.cargo-checksum.json @@ -0,0 +1 @@ +{"files":{"CHANGELOG.md":"f3344c5bbe8a592cde86896c8071205e83565968c1b8a5fa69aab1e53003e21d","Cargo.lock.msrv":"3ac3ecadfe2f607a2c740663a65b107f931087432efc1b2075a12d0dcfc23271","Cargo.toml":"9fc36d6be10b8a7aa70ddfcd404a1cacd757674084e4e12465713618ee420095","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"378f5840b258e2779c39418f3f2d7b2ba96f1c7917dd6be0713f88305dbda397","README.md":"184dd47cdbb3168bdddccaa594f1e56604cb07034b06c1129ac91d41800902da","src/lib.rs":"49057b8265de63686b06302dc6fd3e2c69c63f5f01adcd2ccea609cab18a5068","tests/escape.pc":"00caa4136799dbe5bd504239ba90d1156c12def365c8d761da319fe8a83b398e","tests/foo.pc":"4a1c442c5d1c10761ea1644f8fd58f93cc5a706391bc67b04c243bbd35d70d79","tests/framework.pc":"304fdb6cea92973650e410ab1f70ce1ebeb7718af3f139e806efbf182acd565c","tests/rpath.pc":"424a844e844edfef02692492def9864833391f581338962946646989a69c1180","tests/test.rs":"aa60972a93f57fbc17620739996a94877de523a57e1de7541ee3541539ae2bb9"},"package":"953ec861398dccce10c670dfeaf3ec4911ca479e9c02154b3a215178c5f566f2"} \ No newline at end of file diff --git a/vendor/pkg-config/CHANGELOG.md b/vendor/pkg-config/CHANGELOG.md new file mode 100644 index 0000000..27727c5 --- /dev/null +++ b/vendor/pkg-config/CHANGELOG.md @@ -0,0 +1,209 @@ +# Changelog + +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## [0.3.31] - 2024-09-23 + +### Fixed + +- Remove double `cargo:` prefix from linker line (#168). + +## [0.3.30] - 2024-02-14 + +### Changed + +- Update documentation for cross-compilation (#161). + +- Update GitHub Action CI (#160). + +## [0.3.29] - 2024-01-17 + +### Fixed + +- Detection and usage of Windows static libraries (#154). + +- Passing `-Wl,-u` to the linker if specified in the pkg-config file (#154). + +## [0.3.28] - 2023-12-20 + +### Fixed + +- Pass -l:libfoo.a to linker directly (#149). + +### Changed + +- Improve error message when library not found (#158). + +## [0.3.27] - 2023-05-03 + +### Added + +- Support falling back to `pkgconf` if `pkg-config` is not available (#145). + +### Changed + +- Simplify running `pkg-config` (#144). + +- Document MSRV in `Cargo.toml` via `rust-version`. + +- Fix a couple of minor clippy warnings (#147). + +## [0.3.26] - 2022-10-26 + +### Added + +- Support for handling full paths to libraries in addition to normal `-l` + linker flags (#134). + +## [0.3.25] - 2022-03-31 + +### Added + +- Support for parsing `-Wl` linker arguments from the `Libs` lines and + passing them to the linker as well as making them available via + `Library::ld_args` (#131). + +### Changed + +- Use SPDX license format and remove obsolete badge info (#129). + +## [0.3.24] - 2021-12-11 + +### Fixed + +- Re-add `target_supported()`, which was accidentally removed in 0.3.15 (#128). + +## [0.3.23] - 2021-12-06 + +### Changed + +- Improve error messages when a `pkg-config` package can't be found (#127). + +## [0.3.22] - 2021-10-24 + +### Fixed + +- `pkg-config` compiles again with Rust 1.30 or newer. 0.3.21 accidentally + made use of API only available since 1.40 (#124, #125). + +### Changed + +- Switched from Travis to GitHub Actions for the CI. Travis is dysfunctional + since quite some time (#126). + +## [0.3.21] - 2021-10-22 + +### Fixed + +- Tests succeed again on macOS (#122). + +### Changed + +- Improve error message in case of missing pkg-config and provide instructions + how it can be installed (#121). + +## [0.3.20] - 2021-09-25 + +### Fixed + +- Use target-specific pkg-config consistently everywhere (#121, #118). + +## [0.3.19] - 2020-10-13 + +### Added + +- Add `README.md` to be displayed on crates.io (#111). + +- Support for `-isystem`, `-iquote` and `-idirafter` include flags (#115). + +### Changed + +- Improve documentation for cross-compilation (#113). + +- Allow overriding system root via the `PKG_CONFIG_SYSROOT_DIR` or `SYSROOT` + environment variable (#82). + +## [0.3.18] - 2020-07-11 + +### Fixed + +- Use `env::var_os()` almost everywhere to handle non-UTF8 paths in + environment variables, and also improve error handling around environment + variable handling (#106). + +### Changed + +- Default the `env_metadata` build parameter to `true` instead of `false`. + Whenever a pkg-config related environment variable changes it would make + sense to rebuild crates that use pkg-config, or otherwise changes might not + be picked up. As such the previous default didn't make much sense (#105). + +## [0.3.17] - 2019-11-02 + +### Fixed + +- Fix support for multiple version number constraints (#95) + +## [0.3.16] - 2019-09-09 + +### Changed +- Stop using deprecated functions and require Rust 1.30 (#84) + +### Fixed +- Fix repository URL in README.md +- Fix various clippy warnings + +### Added +- Run `cargo fmt` as part of the CI (#89) +- Derive `Clone` for `Library` and `Debug` for `Config (#91) +- Add support for `PKG_CONFIG_ALLOW_SYSTEM_CFLAGS` and enable by default (#93) + +## [0.3.15] - 2019-07-25 + +### Changed +- Changes minimum documented rust version to 1.28 (#76) + +### Fixed +- Fix Travis CI badge url (#78) +- Fix project name in README.md (#81) + +### Added +- Support specifying range of versions (#75) +- Allow cross-compilation if pkg-config is customized (#44, #86) + +## [0.3.14] - 2018-08-28 + +### Fixed +- Don't append .lib suffix on MSVC builds (#72) + +## [0.3.13] - 2018-08-06 + +### Fixed +- Fix MSVC support to actually work and consider library paths too (#71) + +## [0.3.12] - 2018-06-18 + +### Added +- Support for MSVC (#70) +- Document and test Rust 1.13 as minimally supported version (#66) + +## [0.3.11] - 2018-04-24 + +### Fixed +- Re-added AsciiExt import (#65) + +## [0.3.10] - 2018-04-23 + +### Added +- Allow static linking of /usr/ on macOS (#42) +- Add support for parsing `-Wl,` style framework flags (#48) +- Parse defines in `pkg-config` output (#49) +- Rerun on `PKG_CONFIG_PATH` changes (#50) +- Introduce target-scoped variables (#58) +- Respect pkg-config escaping rules used with --cflags and --libs (#61) + +### Changed +- Use `?` instead of `try!()` in the codebase (#63) diff --git a/vendor/pkg-config/Cargo.lock.msrv b/vendor/pkg-config/Cargo.lock.msrv new file mode 100644 index 0000000..c5dd9c2 --- /dev/null +++ b/vendor/pkg-config/Cargo.lock.msrv @@ -0,0 +1,14 @@ +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "pkg-config" +version = "0.3.30" +dependencies = [ + "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[metadata] +"checksum lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" diff --git a/vendor/pkg-config/Cargo.toml b/vendor/pkg-config/Cargo.toml new file mode 100644 index 0000000..8f0b782 --- /dev/null +++ b/vendor/pkg-config/Cargo.toml @@ -0,0 +1,42 @@ +# 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] +edition = "2018" +rust-version = "1.31" +name = "pkg-config" +version = "0.3.31" +authors = ["Alex Crichton "] +build = false +autobins = false +autoexamples = false +autotests = false +autobenches = false +description = """ +A library to run the pkg-config system tool at build time in order to be used in +Cargo build scripts. +""" +documentation = "https://docs.rs/pkg-config" +readme = "README.md" +keywords = ["build-dependencies"] +license = "MIT OR Apache-2.0" +repository = "https://github.com/rust-lang/pkg-config-rs" + +[lib] +name = "pkg_config" +path = "src/lib.rs" + +[[test]] +name = "test" +path = "tests/test.rs" + +[dev-dependencies.lazy_static] +version = "1" diff --git a/vendor/pkg-config/LICENSE-APACHE b/vendor/pkg-config/LICENSE-APACHE new file mode 100644 index 0000000..16fe87b --- /dev/null +++ b/vendor/pkg-config/LICENSE-APACHE @@ -0,0 +1,201 @@ + 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/pkg-config/LICENSE-MIT b/vendor/pkg-config/LICENSE-MIT new file mode 100644 index 0000000..39e0ed6 --- /dev/null +++ b/vendor/pkg-config/LICENSE-MIT @@ -0,0 +1,25 @@ +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/pkg-config/README.md b/vendor/pkg-config/README.md new file mode 100644 index 0000000..fea8213 --- /dev/null +++ b/vendor/pkg-config/README.md @@ -0,0 +1,79 @@ +# pkg-config-rs + +[![Build Status](https://github.com/rust-lang/pkg-config-rs/actions/workflows/ci.yml/badge.svg)](https://github.com/rust-lang/pkg-config-rs/actions) +[![Rust](https://img.shields.io/badge/rust-1.31%2B-blue.svg?maxAge=3600)](https://github.com/rust-lang/pkg-config-rs/) + +[Documentation](https://docs.rs/pkg-config) + +A simple library meant to be used as a build dependency with Cargo packages in +order to use the system `pkg-config` tool (if available) to determine where a +library is located. + +You can use this crate directly to probe for specific libraries, or use +[system-deps](https://github.com/gdesmott/system-deps) to declare all your +`pkg-config` dependencies in `Cargo.toml`. + +This library requires Rust 1.31+. + +# Example + +Find the system library named `foo`, with minimum version 1.2.3: + +```rust +extern crate pkg_config; + +fn main() { + pkg_config::Config::new().atleast_version("1.2.3").probe("foo").unwrap(); +} +``` + +Find the system library named `foo`, with no version requirement (not +recommended): + +```rust +extern crate pkg_config; + +fn main() { + pkg_config::probe_library("foo").unwrap(); +} +``` + +# External configuration via target-scoped environment variables + +In cross-compilation context, it is useful to manage separately `PKG_CONFIG_PATH` +and a few other variables for the `host` and the `target` platform. + +The supported variables are: `PKG_CONFIG_PATH`, `PKG_CONFIG_LIBDIR`, and +`PKG_CONFIG_SYSROOT_DIR`. + +Each of these variables can also be supplied with certain prefixes and suffixes, in the following prioritized order: + +1. `_` - for example, `PKG_CONFIG_PATH_x86_64-unknown-linux-gnu` +2. `_` - for example, `PKG_CONFIG_PATH_x86_64_unknown_linux_gnu` +3. `_` - for example, `HOST_PKG_CONFIG_PATH` or `TARGET_PKG_CONFIG_PATH` +4. `` - a plain `PKG_CONFIG_PATH` + +This crate will allow `pkg-config` to be used in cross-compilation +if `PKG_CONFIG_SYSROOT_DIR` or `PKG_CONFIG` is set. You can set `PKG_CONFIG_ALLOW_CROSS=1` +to bypass the compatibility check, but please note that enabling use of `pkg-config` in +cross-compilation without appropriate sysroot and search paths set is likely to break builds. + +Some Rust sys crates support building vendored libraries from source, which may be a work +around for lack of cross-compilation support in `pkg-config`. + +# 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 pkg-config-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/pkg-config/src/lib.rs b/vendor/pkg-config/src/lib.rs new file mode 100644 index 0000000..db693fa --- /dev/null +++ b/vendor/pkg-config/src/lib.rs @@ -0,0 +1,1188 @@ +//! A build dependency for Cargo libraries to find system artifacts through the +//! `pkg-config` utility. +//! +//! This library will shell out to `pkg-config` as part of build scripts and +//! probe the system to determine how to link to a specified library. The +//! `Config` structure serves as a method of configuring how `pkg-config` is +//! invoked in a builder style. +//! +//! After running `pkg-config` all appropriate Cargo metadata will be printed on +//! stdout if the search was successful. +//! +//! # Environment variables +//! +//! A number of environment variables are available to globally configure how +//! this crate will invoke `pkg-config`: +//! +//! * `FOO_NO_PKG_CONFIG` - if set, this will disable running `pkg-config` when +//! probing for the library named `foo`. +//! +//! ### Linking +//! +//! There are also a number of environment variables which can configure how a +//! library is linked to (dynamically vs statically). These variables control +//! whether the `--static` flag is passed. Note that this behavior can be +//! overridden by configuring explicitly on `Config`. The variables are checked +//! in the following order: +//! +//! * `FOO_STATIC` - pass `--static` for the library `foo` +//! * `FOO_DYNAMIC` - do not pass `--static` for the library `foo` +//! * `PKG_CONFIG_ALL_STATIC` - pass `--static` for all libraries +//! * `PKG_CONFIG_ALL_DYNAMIC` - do not pass `--static` for all libraries +//! +//! ### Cross-compilation +//! +//! In cross-compilation context, it is useful to manage separately +//! `PKG_CONFIG_PATH` and a few other variables for the `host` and the `target` +//! platform. +//! +//! The supported variables are: `PKG_CONFIG_PATH`, `PKG_CONFIG_LIBDIR`, and +//! `PKG_CONFIG_SYSROOT_DIR`. +//! +//! Each of these variables can also be supplied with certain prefixes and +//! suffixes, in the following prioritized order: +//! +//! 1. `_` - for example, `PKG_CONFIG_PATH_x86_64-unknown-linux-gnu` +//! 2. `_` - for example, +//! `PKG_CONFIG_PATH_x86_64_unknown_linux_gnu` +//! 3. `_` - for example, `HOST_PKG_CONFIG_PATH` or +//! `TARGET_PKG_CONFIG_PATH` +//! 4. `` - a plain `PKG_CONFIG_PATH` +//! +//! This crate will allow `pkg-config` to be used in cross-compilation +//! if `PKG_CONFIG_SYSROOT_DIR` or `PKG_CONFIG` is set. You can set +//! `PKG_CONFIG_ALLOW_CROSS=1` to bypass the compatibility check, but please +//! note that enabling use of `pkg-config` in cross-compilation without +//! appropriate sysroot and search paths set is likely to break builds. +//! +//! # Example +//! +//! Find the system library named `foo`, with minimum version 1.2.3: +//! +//! ```no_run +//! fn main() { +//! pkg_config::Config::new().atleast_version("1.2.3").probe("foo").unwrap(); +//! } +//! ``` +//! +//! Find the system library named `foo`, with no version requirement (not +//! recommended): +//! +//! ```no_run +//! fn main() { +//! pkg_config::probe_library("foo").unwrap(); +//! } +//! ``` +//! +//! Configure how library `foo` is linked to. +//! +//! ```no_run +//! fn main() { +//! pkg_config::Config::new().atleast_version("1.2.3").statik(true).probe("foo").unwrap(); +//! } +//! ``` + +#![doc(html_root_url = "https://docs.rs/pkg-config/0.3")] + +use std::collections::HashMap; +use std::env; +use std::error; +use std::ffi::{OsStr, OsString}; +use std::fmt; +use std::fmt::Display; +use std::io; +use std::ops::{Bound, RangeBounds}; +use std::path::PathBuf; +use std::process::{Command, Output}; +use std::str; + +/// Wrapper struct to polyfill methods introduced in 1.57 (`get_envs`, `get_args` etc). +/// This is needed to reconstruct the pkg-config command for output in a copy- +/// paste friendly format via `Display`. +struct WrappedCommand { + inner: Command, + program: OsString, + env_vars: Vec<(OsString, OsString)>, + args: Vec, +} + +#[derive(Clone, Debug)] +pub struct Config { + statik: Option, + min_version: Bound, + max_version: Bound, + extra_args: Vec, + cargo_metadata: bool, + env_metadata: bool, + print_system_libs: bool, + print_system_cflags: bool, +} + +#[derive(Clone, Debug)] +pub struct Library { + /// Libraries specified by -l + pub libs: Vec, + /// Library search paths specified by -L + pub link_paths: Vec, + /// Library file paths specified without -l + pub link_files: Vec, + /// Darwin frameworks specified by -framework + pub frameworks: Vec, + /// Darwin framework search paths specified by -F + pub framework_paths: Vec, + /// C/C++ header include paths specified by -I + pub include_paths: Vec, + /// Linker options specified by -Wl + pub ld_args: Vec>, + /// C/C++ definitions specified by -D + pub defines: HashMap>, + /// Version specified by .pc file's Version field + pub version: String, + /// Ensure that this struct can only be created via its private `[Library::new]` constructor. + /// Users of this crate can only access the struct via `[Config::probe]`. + _priv: (), +} + +/// Represents all reasons `pkg-config` might not succeed or be run at all. +pub enum Error { + /// Aborted because of `*_NO_PKG_CONFIG` environment variable. + /// + /// Contains the name of the responsible environment variable. + EnvNoPkgConfig(String), + + /// Detected cross compilation without a custom sysroot. + /// + /// Ignore the error with `PKG_CONFIG_ALLOW_CROSS=1`, + /// which may let `pkg-config` select libraries + /// for the host's architecture instead of the target's. + CrossCompilation, + + /// Failed to run `pkg-config`. + /// + /// Contains the command and the cause. + Command { command: String, cause: io::Error }, + + /// `pkg-config` did not exit successfully after probing a library. + /// + /// Contains the command and output. + Failure { command: String, output: Output }, + + /// `pkg-config` did not exit successfully on the first attempt to probe a library. + /// + /// Contains the command and output. + ProbeFailure { + name: String, + command: String, + output: Output, + }, + + #[doc(hidden)] + // please don't match on this, we're likely to add more variants over time + __Nonexhaustive, +} + +impl WrappedCommand { + fn new>(program: S) -> Self { + Self { + inner: Command::new(program.as_ref()), + program: program.as_ref().to_os_string(), + env_vars: Vec::new(), + args: Vec::new(), + } + } + + fn args(&mut self, args: I) -> &mut Self + where + I: IntoIterator + Clone, + S: AsRef, + { + self.inner.args(args.clone()); + self.args + .extend(args.into_iter().map(|arg| arg.as_ref().to_os_string())); + + self + } + + fn arg>(&mut self, arg: S) -> &mut Self { + self.inner.arg(arg.as_ref()); + self.args.push(arg.as_ref().to_os_string()); + + self + } + + fn env(&mut self, key: K, value: V) -> &mut Self + where + K: AsRef, + V: AsRef, + { + self.inner.env(key.as_ref(), value.as_ref()); + self.env_vars + .push((key.as_ref().to_os_string(), value.as_ref().to_os_string())); + + self + } + + fn output(&mut self) -> io::Result { + self.inner.output() + } +} + +/// Output a command invocation that can be copy-pasted into the terminal. +/// `Command`'s existing debug implementation is not used for that reason, +/// as it can sometimes lead to output such as: +/// `PKG_CONFIG_ALLOW_SYSTEM_CFLAGS="1" PKG_CONFIG_ALLOW_SYSTEM_LIBS="1" "pkg-config" "--libs" "--cflags" "mylibrary"` +/// Which cannot be copy-pasted into terminals such as nushell, and is a bit noisy. +/// This will look something like: +/// `PKG_CONFIG_ALLOW_SYSTEM_CFLAGS=1 PKG_CONFIG_ALLOW_SYSTEM_LIBS=1 pkg-config --libs --cflags mylibrary` +impl Display for WrappedCommand { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + // Format all explicitly defined environment variables + let envs = self + .env_vars + .iter() + .map(|(env, arg)| format!("{}={}", env.to_string_lossy(), arg.to_string_lossy())) + .collect::>() + .join(" "); + + // Format all pkg-config arguments + let args = self + .args + .iter() + .map(|arg| arg.to_string_lossy().to_string()) + .collect::>() + .join(" "); + + write!(f, "{} {} {}", envs, self.program.to_string_lossy(), args) + } +} + +impl error::Error for Error {} + +impl fmt::Debug for Error { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { + // Failed `unwrap()` prints Debug representation, but the default debug format lacks helpful instructions for the end users + ::fmt(self, f) + } +} + +impl fmt::Display for Error { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { + match *self { + Error::EnvNoPkgConfig(ref name) => write!(f, "Aborted because {} is set", name), + Error::CrossCompilation => f.write_str( + "pkg-config has not been configured to support cross-compilation.\n\ + \n\ + Install a sysroot for the target platform and configure it via\n\ + PKG_CONFIG_SYSROOT_DIR and PKG_CONFIG_PATH, or install a\n\ + cross-compiling wrapper for pkg-config and set it via\n\ + PKG_CONFIG environment variable.", + ), + Error::Command { + ref command, + ref cause, + } => { + match cause.kind() { + io::ErrorKind::NotFound => { + let crate_name = + std::env::var("CARGO_PKG_NAME").unwrap_or_else(|_| "sys".to_owned()); + let instructions = if cfg!(target_os = "macos") || cfg!(target_os = "ios") { + "Try `brew install pkg-config` if you have Homebrew.\n" + } else if cfg!(unix) { + "Try `apt install pkg-config`, or `yum install pkg-config`,\n\ + or `pkg install pkg-config`, or `apk add pkgconfig` \ + depending on your distribution.\n" + } else { + "" // There's no easy fix for Windows users + }; + write!(f, "Could not run `{command}`\n\ + The pkg-config command could not be found.\n\ + \n\ + Most likely, you need to install a pkg-config package for your OS.\n\ + {instructions}\ + \n\ + If you've already installed it, ensure the pkg-config command is one of the\n\ + directories in the PATH environment variable.\n\ + \n\ + If you did not expect this build to link to a pre-installed system library,\n\ + then check documentation of the {crate_name} crate for an option to\n\ + build the library from source, or disable features or dependencies\n\ + that require pkg-config.", command = command, instructions = instructions, crate_name = crate_name) + } + _ => write!(f, "Failed to run command `{}`, because: {}", command, cause), + } + } + Error::ProbeFailure { + ref name, + ref command, + ref output, + } => { + let crate_name = + env::var("CARGO_PKG_NAME").unwrap_or(String::from("")); + + writeln!(f, "")?; + + // Give a short explanation of what the error is + writeln!( + f, + "pkg-config {}", + match output.status.code() { + Some(code) => format!("exited with status code {}", code), + None => "was terminated by signal".to_string(), + } + )?; + + // Give the command run so users can reproduce the error + writeln!(f, "> {}\n", command)?; + + // Explain how it was caused + writeln!( + f, + "The system library `{}` required by crate `{}` was not found.", + name, crate_name + )?; + writeln!( + f, + "The file `{}.pc` needs to be installed and the PKG_CONFIG_PATH environment variable must contain its parent directory.", + name + )?; + + // There will be no status code if terminated by signal + if let Some(_code) = output.status.code() { + // Nix uses a wrapper script for pkg-config that sets the custom + // environment variable PKG_CONFIG_PATH_FOR_TARGET + let search_locations = ["PKG_CONFIG_PATH_FOR_TARGET", "PKG_CONFIG_PATH"]; + + // Find a search path to use + let mut search_data = None; + for location in search_locations.iter() { + if let Ok(search_path) = env::var(location) { + search_data = Some((location, search_path)); + break; + } + } + + // Guess the most reasonable course of action + let hint = if let Some((search_location, search_path)) = search_data { + writeln!( + f, + "{} contains the following:\n{}", + search_location, + search_path + .split(':') + .map(|path| format!(" - {}", path)) + .collect::>() + .join("\n"), + )?; + + format!("you may need to install a package such as {name}, {name}-dev or {name}-devel.", name=name) + } else { + // Even on Nix, setting PKG_CONFIG_PATH seems to be a viable option + writeln!(f, "The PKG_CONFIG_PATH environment variable is not set.")?; + + format!( + "if you have installed the library, try setting PKG_CONFIG_PATH to the directory containing `{}.pc`.", + name + ) + }; + + // Try and nudge the user in the right direction so they don't get stuck + writeln!(f, "\nHINT: {}", hint)?; + } + + Ok(()) + } + Error::Failure { + ref command, + ref output, + } => { + write!( + f, + "`{}` did not exit successfully: {}", + command, output.status + )?; + format_output(output, f) + } + Error::__Nonexhaustive => panic!(), + } + } +} + +fn format_output(output: &Output, f: &mut fmt::Formatter<'_>) -> fmt::Result { + let stdout = String::from_utf8_lossy(&output.stdout); + if !stdout.is_empty() { + write!(f, "\n--- stdout\n{}", stdout)?; + } + let stderr = String::from_utf8_lossy(&output.stderr); + if !stderr.is_empty() { + write!(f, "\n--- stderr\n{}", stderr)?; + } + Ok(()) +} + +/// Deprecated in favor of the probe_library function +#[doc(hidden)] +pub fn find_library(name: &str) -> Result { + probe_library(name).map_err(|e| e.to_string()) +} + +/// Simple shortcut for using all default options for finding a library. +pub fn probe_library(name: &str) -> Result { + Config::new().probe(name) +} + +#[doc(hidden)] +#[deprecated(note = "use config.target_supported() instance method instead")] +pub fn target_supported() -> bool { + Config::new().target_supported() +} + +/// Run `pkg-config` to get the value of a variable from a package using +/// `--variable`. +/// +/// The content of `PKG_CONFIG_SYSROOT_DIR` is not injected in paths that are +/// returned by `pkg-config --variable`, which makes them unsuitable to use +/// during cross-compilation unless specifically designed to be used +/// at that time. +pub fn get_variable(package: &str, variable: &str) -> Result { + let arg = format!("--variable={}", variable); + let cfg = Config::new(); + let out = cfg.run(package, &[&arg])?; + Ok(str::from_utf8(&out).unwrap().trim_end().to_owned()) +} + +impl Config { + /// Creates a new set of configuration options which are all initially set + /// to "blank". + pub fn new() -> Config { + Config { + statik: None, + min_version: Bound::Unbounded, + max_version: Bound::Unbounded, + extra_args: vec![], + print_system_cflags: true, + print_system_libs: true, + cargo_metadata: true, + env_metadata: true, + } + } + + /// Indicate whether the `--static` flag should be passed. + /// + /// This will override the inference from environment variables described in + /// the crate documentation. + pub fn statik(&mut self, statik: bool) -> &mut Config { + self.statik = Some(statik); + self + } + + /// Indicate that the library must be at least version `vers`. + pub fn atleast_version(&mut self, vers: &str) -> &mut Config { + self.min_version = Bound::Included(vers.to_string()); + self.max_version = Bound::Unbounded; + self + } + + /// Indicate that the library must be equal to version `vers`. + pub fn exactly_version(&mut self, vers: &str) -> &mut Config { + self.min_version = Bound::Included(vers.to_string()); + self.max_version = Bound::Included(vers.to_string()); + self + } + + /// Indicate that the library's version must be in `range`. + pub fn range_version<'a, R>(&mut self, range: R) -> &mut Config + where + R: RangeBounds<&'a str>, + { + self.min_version = match range.start_bound() { + Bound::Included(vers) => Bound::Included(vers.to_string()), + Bound::Excluded(vers) => Bound::Excluded(vers.to_string()), + Bound::Unbounded => Bound::Unbounded, + }; + self.max_version = match range.end_bound() { + Bound::Included(vers) => Bound::Included(vers.to_string()), + Bound::Excluded(vers) => Bound::Excluded(vers.to_string()), + Bound::Unbounded => Bound::Unbounded, + }; + self + } + + /// Add an argument to pass to pkg-config. + /// + /// It's placed after all of the arguments generated by this library. + pub fn arg>(&mut self, arg: S) -> &mut Config { + self.extra_args.push(arg.as_ref().to_os_string()); + self + } + + /// Define whether metadata should be emitted for cargo allowing it to + /// automatically link the binary. Defaults to `true`. + pub fn cargo_metadata(&mut self, cargo_metadata: bool) -> &mut Config { + self.cargo_metadata = cargo_metadata; + self + } + + /// Define whether metadata should be emitted for cargo allowing to + /// automatically rebuild when environment variables change. Defaults to + /// `true`. + pub fn env_metadata(&mut self, env_metadata: bool) -> &mut Config { + self.env_metadata = env_metadata; + self + } + + /// Enable or disable the `PKG_CONFIG_ALLOW_SYSTEM_LIBS` environment + /// variable. + /// + /// This env var is enabled by default. + pub fn print_system_libs(&mut self, print: bool) -> &mut Config { + self.print_system_libs = print; + self + } + + /// Enable or disable the `PKG_CONFIG_ALLOW_SYSTEM_CFLAGS` environment + /// variable. + /// + /// This env var is enabled by default. + pub fn print_system_cflags(&mut self, print: bool) -> &mut Config { + self.print_system_cflags = print; + self + } + + /// Deprecated in favor fo the `probe` function + #[doc(hidden)] + pub fn find(&self, name: &str) -> Result { + self.probe(name).map_err(|e| e.to_string()) + } + + /// Run `pkg-config` to find the library `name`. + /// + /// This will use all configuration previously set to specify how + /// `pkg-config` is run. + pub fn probe(&self, name: &str) -> Result { + let abort_var_name = format!("{}_NO_PKG_CONFIG", envify(name)); + if self.env_var_os(&abort_var_name).is_some() { + return Err(Error::EnvNoPkgConfig(abort_var_name)); + } else if !self.target_supported() { + return Err(Error::CrossCompilation); + } + + let mut library = Library::new(); + + let output = self + .run(name, &["--libs", "--cflags"]) + .map_err(|e| match e { + Error::Failure { command, output } => Error::ProbeFailure { + name: name.to_owned(), + command, + output, + }, + other => other, + })?; + library.parse_libs_cflags(name, &output, self); + + let output = self.run(name, &["--modversion"])?; + library.parse_modversion(str::from_utf8(&output).unwrap()); + + Ok(library) + } + + /// True if pkg-config is used for the host system, or configured for cross-compilation + pub fn target_supported(&self) -> bool { + let target = env::var_os("TARGET").unwrap_or_default(); + let host = env::var_os("HOST").unwrap_or_default(); + + // Only use pkg-config in host == target situations by default (allowing an + // override). + if host == target { + return true; + } + + // pkg-config may not be aware of cross-compilation, and require + // a wrapper script that sets up platform-specific prefixes. + match self.targeted_env_var("PKG_CONFIG_ALLOW_CROSS") { + // don't use pkg-config if explicitly disabled + Some(ref val) if val == "0" => false, + Some(_) => true, + None => { + // if not disabled, and pkg-config is customized, + // then assume it's prepared for cross-compilation + self.targeted_env_var("PKG_CONFIG").is_some() + || self.targeted_env_var("PKG_CONFIG_SYSROOT_DIR").is_some() + } + } + } + + /// Deprecated in favor of the top level `get_variable` function + #[doc(hidden)] + pub fn get_variable(package: &str, variable: &str) -> Result { + get_variable(package, variable).map_err(|e| e.to_string()) + } + + fn targeted_env_var(&self, var_base: &str) -> Option { + match (env::var("TARGET"), env::var("HOST")) { + (Ok(target), Ok(host)) => { + let kind = if host == target { "HOST" } else { "TARGET" }; + let target_u = target.replace('-', "_"); + + self.env_var_os(&format!("{}_{}", var_base, target)) + .or_else(|| self.env_var_os(&format!("{}_{}", var_base, target_u))) + .or_else(|| self.env_var_os(&format!("{}_{}", kind, var_base))) + .or_else(|| self.env_var_os(var_base)) + } + (Err(env::VarError::NotPresent), _) | (_, Err(env::VarError::NotPresent)) => { + self.env_var_os(var_base) + } + (Err(env::VarError::NotUnicode(s)), _) | (_, Err(env::VarError::NotUnicode(s))) => { + panic!( + "HOST or TARGET environment variable is not valid unicode: {:?}", + s + ) + } + } + } + + fn env_var_os(&self, name: &str) -> Option { + if self.env_metadata { + println!("cargo:rerun-if-env-changed={}", name); + } + env::var_os(name) + } + + fn is_static(&self, name: &str) -> bool { + self.statik.unwrap_or_else(|| self.infer_static(name)) + } + + fn run(&self, name: &str, args: &[&str]) -> Result, Error> { + let pkg_config_exe = self.targeted_env_var("PKG_CONFIG"); + let fallback_exe = if pkg_config_exe.is_none() { + Some(OsString::from("pkgconf")) + } else { + None + }; + let exe = pkg_config_exe.unwrap_or_else(|| OsString::from("pkg-config")); + + let mut cmd = self.command(exe, name, args); + + match cmd.output().or_else(|e| { + if let Some(exe) = fallback_exe { + self.command(exe, name, args).output() + } else { + Err(e) + } + }) { + Ok(output) => { + if output.status.success() { + Ok(output.stdout) + } else { + Err(Error::Failure { + command: format!("{}", cmd), + output, + }) + } + } + Err(cause) => Err(Error::Command { + command: format!("{}", cmd), + cause, + }), + } + } + + fn command(&self, exe: OsString, name: &str, args: &[&str]) -> WrappedCommand { + let mut cmd = WrappedCommand::new(exe); + if self.is_static(name) { + cmd.arg("--static"); + } + cmd.args(args).args(&self.extra_args); + + if let Some(value) = self.targeted_env_var("PKG_CONFIG_PATH") { + cmd.env("PKG_CONFIG_PATH", value); + } + if let Some(value) = self.targeted_env_var("PKG_CONFIG_LIBDIR") { + cmd.env("PKG_CONFIG_LIBDIR", value); + } + if let Some(value) = self.targeted_env_var("PKG_CONFIG_SYSROOT_DIR") { + cmd.env("PKG_CONFIG_SYSROOT_DIR", value); + } + if self.print_system_libs { + cmd.env("PKG_CONFIG_ALLOW_SYSTEM_LIBS", "1"); + } + if self.print_system_cflags { + cmd.env("PKG_CONFIG_ALLOW_SYSTEM_CFLAGS", "1"); + } + cmd.arg(name); + match self.min_version { + Bound::Included(ref version) => { + cmd.arg(&format!("{} >= {}", name, version)); + } + Bound::Excluded(ref version) => { + cmd.arg(&format!("{} > {}", name, version)); + } + _ => (), + } + match self.max_version { + Bound::Included(ref version) => { + cmd.arg(&format!("{} <= {}", name, version)); + } + Bound::Excluded(ref version) => { + cmd.arg(&format!("{} < {}", name, version)); + } + _ => (), + } + cmd + } + + fn print_metadata(&self, s: &str) { + if self.cargo_metadata { + println!("cargo:{}", s); + } + } + + fn infer_static(&self, name: &str) -> bool { + let name = envify(name); + if self.env_var_os(&format!("{}_STATIC", name)).is_some() { + true + } else if self.env_var_os(&format!("{}_DYNAMIC", name)).is_some() { + false + } else if self.env_var_os("PKG_CONFIG_ALL_STATIC").is_some() { + true + } else if self.env_var_os("PKG_CONFIG_ALL_DYNAMIC").is_some() { + false + } else { + false + } + } +} + +// Implement Default manually since Bound does not implement Default. +impl Default for Config { + fn default() -> Config { + Config { + statik: None, + min_version: Bound::Unbounded, + max_version: Bound::Unbounded, + extra_args: vec![], + print_system_cflags: false, + print_system_libs: false, + cargo_metadata: false, + env_metadata: false, + } + } +} + +impl Library { + fn new() -> Library { + Library { + libs: Vec::new(), + link_paths: Vec::new(), + link_files: Vec::new(), + include_paths: Vec::new(), + ld_args: Vec::new(), + frameworks: Vec::new(), + framework_paths: Vec::new(), + defines: HashMap::new(), + version: String::new(), + _priv: (), + } + } + + /// Extract the &str to pass to cargo:rustc-link-lib from a filename (just the file name, not including directories) + /// using target-specific logic. + fn extract_lib_from_filename<'a>(target: &str, filename: &'a str) -> Option<&'a str> { + fn test_suffixes<'b>(filename: &'b str, suffixes: &[&str]) -> Option<&'b str> { + for suffix in suffixes { + if filename.ends_with(suffix) { + return Some(&filename[..filename.len() - suffix.len()]); + } + } + None + } + + let prefix = "lib"; + if target.contains("windows") { + if target.contains("gnu") && filename.starts_with(prefix) { + // GNU targets for Windows, including gnullvm, use `LinkerFlavor::Gcc` internally in rustc, + // which tells rustc to use the GNU linker. rustc does not prepend/append to the string it + // receives via the -l command line argument before passing it to the linker: + // https://github.com/rust-lang/rust/blob/657f246812ab2684e3c3954b1c77f98fd59e0b21/compiler/rustc_codegen_ssa/src/back/linker.rs#L446 + // https://github.com/rust-lang/rust/blob/657f246812ab2684e3c3954b1c77f98fd59e0b21/compiler/rustc_codegen_ssa/src/back/linker.rs#L457 + // GNU ld can work with more types of files than just the .lib files that MSVC's link.exe needs. + // GNU ld will prepend the `lib` prefix to the filename if necessary, so it is okay to remove + // the `lib` prefix from the filename. The `.a` suffix *requires* the `lib` prefix. + // https://sourceware.org/binutils/docs-2.39/ld.html#index-direct-linking-to-a-dll + let filename = &filename[prefix.len()..]; + return test_suffixes(filename, &[".dll.a", ".dll", ".lib", ".a"]); + } else { + // According to link.exe documentation: + // https://learn.microsoft.com/en-us/cpp/build/reference/link-input-files?view=msvc-170 + // + // LINK doesn't use file extensions to make assumptions about the contents of a file. + // Instead, LINK examines each input file to determine what kind of file it is. + // + // However, rustc appends `.lib` to the string it receives from the -l command line argument, + // which it receives from Cargo via cargo:rustc-link-lib: + // https://github.com/rust-lang/rust/blob/657f246812ab2684e3c3954b1c77f98fd59e0b21/compiler/rustc_codegen_ssa/src/back/linker.rs#L828 + // https://github.com/rust-lang/rust/blob/657f246812ab2684e3c3954b1c77f98fd59e0b21/compiler/rustc_codegen_ssa/src/back/linker.rs#L843 + // So the only file extension that works for MSVC targets is `.lib` + // However, for externally created libraries, there's no + // guarantee that the extension is ".lib" so we need to + // consider all options. + // See: + // https://github.com/mesonbuild/meson/issues/8153 + // https://github.com/rust-lang/rust/issues/114013 + return test_suffixes(filename, &[".dll.a", ".dll", ".lib", ".a"]); + } + } else if target.contains("apple") { + if filename.starts_with(prefix) { + let filename = &filename[prefix.len()..]; + return test_suffixes(filename, &[".a", ".so", ".dylib"]); + } + return None; + } else { + if filename.starts_with(prefix) { + let filename = &filename[prefix.len()..]; + return test_suffixes(filename, &[".a", ".so"]); + } + return None; + } + } + + fn parse_libs_cflags(&mut self, name: &str, output: &[u8], config: &Config) { + let target = env::var("TARGET"); + let is_msvc = target + .as_ref() + .map(|target| target.contains("msvc")) + .unwrap_or(false); + + let system_roots = if cfg!(target_os = "macos") { + vec![PathBuf::from("/Library"), PathBuf::from("/System")] + } else { + let sysroot = config + .env_var_os("PKG_CONFIG_SYSROOT_DIR") + .or_else(|| config.env_var_os("SYSROOT")) + .map(PathBuf::from); + + if cfg!(target_os = "windows") { + if let Some(sysroot) = sysroot { + vec![sysroot] + } else { + vec![] + } + } else { + vec![sysroot.unwrap_or_else(|| PathBuf::from("/usr"))] + } + }; + + let mut dirs = Vec::new(); + let statik = config.is_static(name); + + let words = split_flags(output); + + // Handle single-character arguments like `-I/usr/include` + let parts = words + .iter() + .filter(|l| l.len() > 2) + .map(|arg| (&arg[0..2], &arg[2..])); + for (flag, val) in parts { + match flag { + "-L" => { + let meta = format!("rustc-link-search=native={}", val); + config.print_metadata(&meta); + dirs.push(PathBuf::from(val)); + self.link_paths.push(PathBuf::from(val)); + } + "-F" => { + let meta = format!("rustc-link-search=framework={}", val); + config.print_metadata(&meta); + self.framework_paths.push(PathBuf::from(val)); + } + "-I" => { + self.include_paths.push(PathBuf::from(val)); + } + "-l" => { + // These are provided by the CRT with MSVC + if is_msvc && ["m", "c", "pthread"].contains(&val) { + continue; + } + + if val.starts_with(':') { + // Pass this flag to linker directly. + let meta = format!("rustc-link-arg={}{}", flag, val); + config.print_metadata(&meta); + } else if statik && is_static_available(val, &system_roots, &dirs) { + let meta = format!("rustc-link-lib=static={}", val); + config.print_metadata(&meta); + } else { + let meta = format!("rustc-link-lib={}", val); + config.print_metadata(&meta); + } + + self.libs.push(val.to_string()); + } + "-D" => { + let mut iter = val.split('='); + self.defines.insert( + iter.next().unwrap().to_owned(), + iter.next().map(|s| s.to_owned()), + ); + } + "-u" => { + let meta = format!("rustc-link-arg=-Wl,-u,{}", val); + config.print_metadata(&meta); + } + _ => {} + } + } + + // Handle multi-character arguments with space-separated value like `-framework foo` + let mut iter = words.iter().flat_map(|arg| { + if arg.starts_with("-Wl,") { + arg[4..].split(',').collect() + } else { + vec![arg.as_ref()] + } + }); + while let Some(part) = iter.next() { + match part { + "-framework" => { + if let Some(lib) = iter.next() { + let meta = format!("rustc-link-lib=framework={}", lib); + config.print_metadata(&meta); + self.frameworks.push(lib.to_string()); + } + } + "-isystem" | "-iquote" | "-idirafter" => { + if let Some(inc) = iter.next() { + self.include_paths.push(PathBuf::from(inc)); + } + } + "-undefined" | "--undefined" => { + if let Some(symbol) = iter.next() { + let meta = format!("rustc-link-arg=-Wl,{},{}", part, symbol); + config.print_metadata(&meta); + } + } + _ => { + let path = std::path::Path::new(part); + if path.is_file() { + // Cargo doesn't have a means to directly specify a file path to link, + // so split up the path into the parent directory and library name. + // TODO: pass file path directly when link-arg library type is stabilized + // https://github.com/rust-lang/rust/issues/99427 + if let (Some(dir), Some(file_name), Ok(target)) = + (path.parent(), path.file_name(), &target) + { + match Self::extract_lib_from_filename( + target, + &file_name.to_string_lossy(), + ) { + Some(lib_basename) => { + let link_search = + format!("rustc-link-search={}", dir.display()); + config.print_metadata(&link_search); + + let link_lib = format!("rustc-link-lib={}", lib_basename); + config.print_metadata(&link_lib); + self.link_files.push(PathBuf::from(path)); + } + None => { + println!("cargo:warning=File path {} found in pkg-config file for {}, but could not extract library base name to pass to linker command line", path.display(), name); + } + } + } + } + } + } + } + + let linker_options = words.iter().filter(|arg| arg.starts_with("-Wl,")); + for option in linker_options { + let mut pop = false; + let mut ld_option = vec![]; + for subopt in option[4..].split(',') { + if pop { + pop = false; + continue; + } + + if subopt == "-framework" { + pop = true; + continue; + } + + ld_option.push(subopt); + } + + let meta = format!("rustc-link-arg=-Wl,{}", ld_option.join(",")); + config.print_metadata(&meta); + + self.ld_args + .push(ld_option.into_iter().map(String::from).collect()); + } + } + + fn parse_modversion(&mut self, output: &str) { + self.version.push_str(output.lines().next().unwrap().trim()); + } +} + +fn envify(name: &str) -> String { + name.chars() + .map(|c| c.to_ascii_uppercase()) + .map(|c| if c == '-' { '_' } else { c }) + .collect() +} + +/// System libraries should only be linked dynamically +fn is_static_available(name: &str, system_roots: &[PathBuf], dirs: &[PathBuf]) -> bool { + let libnames = { + let mut names = vec![format!("lib{}.a", name)]; + + if cfg!(target_os = "windows") { + names.push(format!("{}.lib", name)); + } + + names + }; + + dirs.iter().any(|dir| { + let library_exists = libnames.iter().any(|libname| dir.join(&libname).exists()); + library_exists && !system_roots.iter().any(|sys| dir.starts_with(sys)) + }) +} + +/// Split output produced by pkg-config --cflags and / or --libs into separate flags. +/// +/// Backslash in output is used to preserve literal meaning of following byte. Different words are +/// separated by unescaped space. Other whitespace characters generally should not occur unescaped +/// at all, apart from the newline at the end of output. For compatibility with what others +/// consumers of pkg-config output would do in this scenario, they are used here for splitting as +/// well. +fn split_flags(output: &[u8]) -> Vec { + let mut word = Vec::new(); + let mut words = Vec::new(); + let mut escaped = false; + + for &b in output { + match b { + _ if escaped => { + escaped = false; + word.push(b); + } + b'\\' => escaped = true, + b'\t' | b'\n' | b'\r' | b' ' => { + if !word.is_empty() { + words.push(String::from_utf8(word).unwrap()); + word = Vec::new(); + } + } + _ => word.push(b), + } + } + + if !word.is_empty() { + words.push(String::from_utf8(word).unwrap()); + } + + words +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + #[cfg(target_os = "macos")] + fn system_library_mac_test() { + use std::path::Path; + + let system_roots = vec![PathBuf::from("/Library"), PathBuf::from("/System")]; + + assert!(!is_static_available( + "PluginManager", + &system_roots, + &[PathBuf::from("/Library/Frameworks")] + )); + assert!(!is_static_available( + "python2.7", + &system_roots, + &[PathBuf::from( + "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/config" + )] + )); + assert!(!is_static_available( + "ffi_convenience", + &system_roots, + &[PathBuf::from( + "/Library/Ruby/Gems/2.0.0/gems/ffi-1.9.10/ext/ffi_c/libffi-x86_64/.libs" + )] + )); + + // Homebrew is in /usr/local, and it's not a part of the OS + if Path::new("/usr/local/lib/libpng16.a").exists() { + assert!(is_static_available( + "png16", + &system_roots, + &[PathBuf::from("/usr/local/lib")] + )); + + let libpng = Config::new() + .range_version("1".."99") + .probe("libpng16") + .unwrap(); + assert!(libpng.version.find('\n').is_none()); + } + } + + #[test] + #[cfg(target_os = "linux")] + fn system_library_linux_test() { + assert!(!is_static_available( + "util", + &[PathBuf::from("/usr")], + &[PathBuf::from("/usr/lib/x86_64-linux-gnu")] + )); + assert!(!is_static_available( + "dialog", + &[PathBuf::from("/usr")], + &[PathBuf::from("/usr/lib")] + )); + } + + fn test_library_filename(target: &str, filename: &str) { + assert_eq!( + Library::extract_lib_from_filename(target, filename), + Some("foo") + ); + } + + #[test] + fn link_filename_linux() { + let target = "x86_64-unknown-linux-gnu"; + test_library_filename(target, "libfoo.a"); + test_library_filename(target, "libfoo.so"); + } + + #[test] + fn link_filename_apple() { + let target = "x86_64-apple-darwin"; + test_library_filename(target, "libfoo.a"); + test_library_filename(target, "libfoo.so"); + test_library_filename(target, "libfoo.dylib"); + } + + #[test] + fn link_filename_msvc() { + let target = "x86_64-pc-windows-msvc"; + // static and dynamic libraries have the same .lib suffix + test_library_filename(target, "foo.lib"); + } + + #[test] + fn link_filename_mingw() { + let target = "x86_64-pc-windows-gnu"; + test_library_filename(target, "foo.lib"); + test_library_filename(target, "libfoo.a"); + test_library_filename(target, "foo.dll"); + test_library_filename(target, "foo.dll.a"); + } +} diff --git a/vendor/pkg-config/tests/escape.pc b/vendor/pkg-config/tests/escape.pc new file mode 100644 index 0000000..701c4bf --- /dev/null +++ b/vendor/pkg-config/tests/escape.pc @@ -0,0 +1,5 @@ +Name: Escape +Version: 4.2.0 +Description: Escape utility library +Libs: -Llink\ path\ with\ spaces +Cflags: -Iinclude\ path\ with\ spaces -DA=\"escaped\ string\'\ literal\" -DB=ESCAPED\ IDENTIFIER -DFOX=🦊 diff --git a/vendor/pkg-config/tests/foo.pc b/vendor/pkg-config/tests/foo.pc new file mode 100644 index 0000000..ce63ceb --- /dev/null +++ b/vendor/pkg-config/tests/foo.pc @@ -0,0 +1,16 @@ +prefix=/usr +exec_prefix=${prefix} +libdir=${exec_prefix}/lib +includedir=${prefix}/include/valgrind +arch=amd64 +os=linux +platform=amd64-linux +valt_load_address=0x38000000 + +Name: Valgrind +Description: A dynamic binary instrumentation framework +Version: 3.10.0.SVN +Requires: +Libs: -L${libdir}/valgrind -lcoregrind-amd64-linux -lvex-amd64-linux -lgcc +Cflags: -I${includedir} -isystem /usr/foo + diff --git a/vendor/pkg-config/tests/framework.pc b/vendor/pkg-config/tests/framework.pc new file mode 100644 index 0000000..fec17f4 --- /dev/null +++ b/vendor/pkg-config/tests/framework.pc @@ -0,0 +1,16 @@ +prefix=/usr +exec_prefix=${prefix} +libdir=${exec_prefix}/lib +includedir=${prefix}/include/valgrind +arch=amd64 +os=linux +platform=amd64-linux +valt_load_address=0x38000000 + +Name: Valgrind +Description: A dynamic binary instrumentation framework +Version: 3.10.0.SVN +Requires: +Libs: -F${libdir} -framework foo -Wl,-framework,bar -Wl,-framework -Wl,baz -Wl,-framework,foobar,-framework,foobaz +Cflags: -I${includedir} + diff --git a/vendor/pkg-config/tests/rpath.pc b/vendor/pkg-config/tests/rpath.pc new file mode 100644 index 0000000..7c36c5c --- /dev/null +++ b/vendor/pkg-config/tests/rpath.pc @@ -0,0 +1,7 @@ +prefix=/usr/local + +Name: rpath +Version: 4.2.0 +Description: RPath example library +Libs: -L${prefix}/lib -Wl,-rpath,${prefix}/lib -lrpath +Cflags: -I${prefix}/include diff --git a/vendor/pkg-config/tests/test.rs b/vendor/pkg-config/tests/test.rs new file mode 100644 index 0000000..ef80fc7 --- /dev/null +++ b/vendor/pkg-config/tests/test.rs @@ -0,0 +1,317 @@ +use lazy_static::lazy_static; +use pkg_config::Error; +use std::env; +use std::path::PathBuf; +use std::sync::Mutex; + +lazy_static! { + static ref LOCK: Mutex<()> = Mutex::new(()); +} + +fn reset() { + for (k, _) in env::vars() { + if k.contains("DYNAMIC") + || k.contains("STATIC") + || k.contains("PKG_CONFIG_ALLOW_CROSS") + || k.contains("PKG_CONFIG_SYSROOT_DIR") + || k.contains("FOO_NO_PKG_CONFIG") + { + env::remove_var(&k); + } + } + env::remove_var("TARGET"); + env::remove_var("HOST"); + env::set_var("PKG_CONFIG_PATH", env::current_dir().unwrap().join("tests")); +} + +fn find(name: &str) -> Result { + pkg_config::probe_library(name) +} + +#[test] +fn cross_disabled() { + let _g = LOCK.lock(); + reset(); + env::set_var("TARGET", "foo"); + env::set_var("HOST", "bar"); + match find("foo") { + Err(Error::CrossCompilation) => {} + x => panic!("Error::CrossCompilation expected, found `{:?}`", x), + } +} + +#[test] +fn cross_enabled() { + let _g = LOCK.lock(); + reset(); + env::set_var("TARGET", "foo"); + env::set_var("HOST", "bar"); + env::set_var("PKG_CONFIG_ALLOW_CROSS", "1"); + find("foo").unwrap(); +} + +#[test] +fn cross_enabled_if_customized() { + let _g = LOCK.lock(); + reset(); + env::set_var("TARGET", "foo"); + env::set_var("HOST", "bar"); + env::set_var("PKG_CONFIG_SYSROOT_DIR", "/tmp/cross-test"); + find("foo").unwrap(); +} + +#[test] +fn cross_disabled_if_customized() { + let _g = LOCK.lock(); + reset(); + env::set_var("TARGET", "foo"); + env::set_var("HOST", "bar"); + env::set_var("PKG_CONFIG_ALLOW_CROSS", "0"); + env::set_var("PKG_CONFIG_SYSROOT_DIR", "/tmp/cross-test"); + match find("foo") { + Err(Error::CrossCompilation) => {} + _ => panic!("expected CrossCompilation failure"), + } +} + +#[test] +fn package_disabled() { + let _g = LOCK.lock(); + reset(); + env::set_var("FOO_NO_PKG_CONFIG", "1"); + match find("foo") { + Err(Error::EnvNoPkgConfig(name)) => assert_eq!(name, "FOO_NO_PKG_CONFIG"), + x => panic!("Error::EnvNoPkgConfig expected, found `{:?}`", x), + } +} + +#[test] +fn output_ok() { + let _g = LOCK.lock(); + reset(); + let lib = find("foo").unwrap(); + assert!(lib.libs.contains(&"gcc".to_string())); + assert!(lib.libs.contains(&"coregrind-amd64-linux".to_string())); + assert!(lib.link_paths.contains(&PathBuf::from("/usr/lib/valgrind"))); + assert!(lib + .include_paths + .contains(&PathBuf::from("/usr/include/valgrind"))); + assert!(lib.include_paths.contains(&PathBuf::from("/usr/foo"))); +} + +#[test] +fn escapes() { + let _g = LOCK.lock(); + reset(); + let lib = find("escape").unwrap(); + assert!(lib + .include_paths + .contains(&PathBuf::from("include path with spaces"))); + assert!(lib + .link_paths + .contains(&PathBuf::from("link path with spaces"))); + assert_eq!( + lib.defines.get("A"), + Some(&Some("\"escaped string' literal\"".to_owned())) + ); + assert_eq!( + lib.defines.get("B"), + Some(&Some("ESCAPED IDENTIFIER".to_owned())) + ); + assert_eq!(lib.defines.get("FOX"), Some(&Some("🦊".to_owned()))); +} + +#[test] +fn framework() { + let _g = LOCK.lock(); + reset(); + let lib = find("framework").unwrap(); + assert!(lib.frameworks.contains(&"foo".to_string())); + assert!(lib.frameworks.contains(&"bar".to_string())); + assert!(lib.frameworks.contains(&"baz".to_string())); + assert!(lib.frameworks.contains(&"foobar".to_string())); + assert!(lib.frameworks.contains(&"foobaz".to_string())); + assert!(lib.framework_paths.contains(&PathBuf::from("/usr/lib"))); +} + +#[test] +fn get_variable() { + let _g = LOCK.lock(); + reset(); + let prefix = pkg_config::get_variable("foo", "prefix").unwrap(); + assert_eq!(prefix, "/usr"); +} + +#[test] +fn version() { + let _g = LOCK.lock(); + reset(); + assert_eq!(&find("foo").unwrap().version[..], "3.10.0.SVN"); +} + +#[test] +fn atleast_version_ok() { + let _g = LOCK.lock(); + reset(); + pkg_config::Config::new() + .atleast_version("3.10") + .probe("foo") + .unwrap(); +} + +#[test] +#[should_panic] +fn atleast_version_ng() { + let _g = LOCK.lock(); + reset(); + pkg_config::Config::new() + .atleast_version("3.11") + .probe("foo") + .unwrap(); +} + +#[test] +fn exactly_version_ok() { + let _g = LOCK.lock(); + reset(); + pkg_config::Config::new() + .exactly_version("3.10.0.SVN") + .probe("foo") + .unwrap(); +} + +#[test] +#[should_panic] +fn exactly_version_ng() { + let _g = LOCK.lock(); + reset(); + pkg_config::Config::new() + .exactly_version("3.10.0") + .probe("foo") + .unwrap(); +} + +#[test] +fn range_version_range_ok() { + let _g = LOCK.lock(); + reset(); + pkg_config::Config::new() + .range_version("4.2.0".."4.4.0") + .probe("escape") + .unwrap(); +} + +#[test] +#[should_panic] +fn range_version_range_ng() { + let _g = LOCK.lock(); + reset(); + pkg_config::Config::new() + .range_version("4.0.0".."4.2.0") + .probe("escape") + .unwrap(); +} + +#[test] +fn range_version_range_inclusive_ok() { + let _g = LOCK.lock(); + reset(); + pkg_config::Config::new() + .range_version("4.0.0"..="4.2.0") + .probe("escape") + .unwrap(); +} + +#[test] +#[should_panic] +fn range_version_range_inclusive_ng() { + let _g = LOCK.lock(); + reset(); + pkg_config::Config::new() + .range_version("3.8.0"..="4.0.0") + .probe("escape") + .unwrap(); +} + +#[test] +fn range_version_range_from_ok() { + let _g = LOCK.lock(); + reset(); + pkg_config::Config::new() + .range_version("4.0.0"..) + .probe("escape") + .unwrap(); +} + +#[test] +#[should_panic] +fn range_version_range_from_ng() { + let _g = LOCK.lock(); + reset(); + pkg_config::Config::new() + .range_version("4.4.0"..) + .probe("escape") + .unwrap(); +} + +#[test] +fn range_version_range_to_ok() { + let _g = LOCK.lock(); + reset(); + pkg_config::Config::new() + .range_version(.."4.4.0") + .probe("escape") + .unwrap(); +} + +#[test] +#[should_panic] +fn range_version_range_to_ng() { + let _g = LOCK.lock(); + reset(); + pkg_config::Config::new() + .range_version(.."4.2.0") + .probe("escape") + .unwrap(); +} + +#[test] +fn range_version_range_to_inclusive_ok() { + let _g = LOCK.lock(); + reset(); + pkg_config::Config::new() + .range_version(..="4.2.0") + .probe("escape") + .unwrap(); +} + +#[test] +#[should_panic] +fn range_version_range_to_inclusive_ng() { + let _g = LOCK.lock(); + reset(); + pkg_config::Config::new() + .range_version(..="4.0.0") + .probe("escape") + .unwrap(); +} + +#[test] +fn range_version_full() { + let _g = LOCK.lock(); + reset(); + pkg_config::Config::new() + .range_version(..) + .probe("escape") + .unwrap(); +} + +#[test] +fn rpath() { + let _g = LOCK.lock(); + reset(); + let lib = find("rpath").unwrap(); + assert!(lib + .ld_args + .contains(&vec!["-rpath".to_string(), "/usr/local/lib".to_string(),])); +} diff --git a/vendor/proc-macro2/.cargo-checksum.json b/vendor/proc-macro2/.cargo-checksum.json new file mode 100644 index 0000000..6cd8bd0 --- /dev/null +++ b/vendor/proc-macro2/.cargo-checksum.json @@ -0,0 +1 @@ +{"files":{"Cargo.toml":"634793a6fc0a4fb424d2b8c5f4d84c814494380ad9f5c81ad0730dd1c9a20db1","LICENSE-APACHE":"62c7a1e35f56406896d7aa7ca52d0cc0d272ac022b5d2796e7d6905db8a3636a","LICENSE-MIT":"23f18e03dc49df91622fe2a76176497404e46ced8a715d9d2b67a7446571cca3","README.md":"c609b6865476d6c35879784e9155367a97a0da496aa5c3c61488440a20f59883","build.rs":"cf78c0005f11d54ca42dbaee77cb76a440e6fa2e0b64798d3f74c04770a0ad2b","build/probe.rs":"df0d73191f20c207bb1051a4944fb6962e1f632d1e0535aba4b995aa7feba8d1","rust-toolchain.toml":"6bbb61302978c736b2da03e4fb40e3beab908f85d533ab46fd541e637b5f3e0f","src/detection.rs":"ed9a5f9a979ab01247d7a68eeb1afa3c13209334c5bfff0f9289cb07e5bb4e8b","src/extra.rs":"29f094473279a29b71c3cc9f5fa27c2e2c30c670390cf7e4b7cf451486cc857e","src/fallback.rs":"be1ce5e32c88c29d41d2ab663375951817d52decce3dc9e335ec22378be8fa65","src/lib.rs":"b073933783beae6a8f43635eace6250dbfa2bdf4ebed0049f112d034af7c2183","src/location.rs":"9225c5a55f03b56cce42bc55ceb509e8216a5e0b24c94aa1cd071b04e3d6c15f","src/marker.rs":"c11c5a1be8bdf18be3fcd224393f350a9aae7ce282e19ce583c84910c6903a8f","src/parse.rs":"4b77cddbc2752bc4d38a65acd8b96b6786c5220d19b1e1b37810257b5d24132d","src/rcvec.rs":"1c3c48c4f819927cc445ae15ca3bb06775feff2fd1cb21901ae4c40c7e6b4e82","src/wrapper.rs":"d4afc41f00ca40088b50e35c0b622fb8b72ca7c091385c528d0290e44dfd07a5","tests/comments.rs":"31115b3a56c83d93eef2fb4c9566bf4543e302560732986161b98aef504785ed","tests/features.rs":"a86deb8644992a4eb64d9fd493eff16f9cf9c5cb6ade3a634ce0c990cf87d559","tests/marker.rs":"473e962ee1aa0633dd5cf9a973b3bbd0ef43b740d4b7f6d008ff455a6b89d386","tests/test.rs":"2e7106f582367d168638be7364d4e9aadbe0affca8b51dd80f0b3977cc2fcf83","tests/test_fmt.rs":"b7743b612af65f2c88cbe109d50a093db7aa7e87f9e37bf45b7bbaeb240aa020","tests/test_size.rs":"62d8373ea46b669b87bc90a9c49b6d02f90ff4c21f9a25acebf60c9926e01fb7"},"package":"7c3a7fc5db1e57d5a779a352c8cdb57b29aa4c40cc69c3a68a7fedc815fbf2f9"} \ No newline at end of file diff --git a/vendor/proc-macro2/Cargo.toml b/vendor/proc-macro2/Cargo.toml new file mode 100644 index 0000000..e24d832 --- /dev/null +++ b/vendor/proc-macro2/Cargo.toml @@ -0,0 +1,105 @@ +# 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] +edition = "2021" +rust-version = "1.56" +name = "proc-macro2" +version = "1.0.88" +authors = [ + "David Tolnay ", + "Alex Crichton ", +] +build = "build.rs" +autolib = false +autobins = false +autoexamples = false +autotests = false +autobenches = false +description = "A substitute implementation of the compiler's `proc_macro` API to decouple token-based libraries from the procedural macro use case." +documentation = "https://docs.rs/proc-macro2" +readme = "README.md" +keywords = [ + "macros", + "syn", +] +categories = ["development-tools::procedural-macro-helpers"] +license = "MIT OR Apache-2.0" +repository = "https://github.com/dtolnay/proc-macro2" + +[package.metadata.docs.rs] +rustc-args = [ + "--cfg", + "procmacro2_semver_exempt", +] +rustdoc-args = [ + "--cfg", + "procmacro2_semver_exempt", + "--generate-link-to-definition", +] +targets = ["x86_64-unknown-linux-gnu"] + +[package.metadata.playground] +features = ["span-locations"] + +[lib] +name = "proc_macro2" +path = "src/lib.rs" +doc-scrape-examples = false + +[[test]] +name = "comments" +path = "tests/comments.rs" + +[[test]] +name = "features" +path = "tests/features.rs" + +[[test]] +name = "marker" +path = "tests/marker.rs" + +[[test]] +name = "test" +path = "tests/test.rs" + +[[test]] +name = "test_fmt" +path = "tests/test_fmt.rs" + +[[test]] +name = "test_size" +path = "tests/test_size.rs" + +[dependencies.unicode-ident] +version = "1.0" + +[dev-dependencies.flate2] +version = "1.0" + +[dev-dependencies.quote] +version = "1.0" +default-features = false + +[dev-dependencies.rayon] +version = "1.0" + +[dev-dependencies.rustversion] +version = "1" + +[dev-dependencies.tar] +version = "0.4" + +[features] +default = ["proc-macro"] +nightly = [] +proc-macro = [] +span-locations = [] diff --git a/vendor/proc-macro2/LICENSE-APACHE b/vendor/proc-macro2/LICENSE-APACHE new file mode 100644 index 0000000..1b5ec8b --- /dev/null +++ b/vendor/proc-macro2/LICENSE-APACHE @@ -0,0 +1,176 @@ + 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 diff --git a/vendor/proc-macro2/LICENSE-MIT b/vendor/proc-macro2/LICENSE-MIT new file mode 100644 index 0000000..31aa793 --- /dev/null +++ b/vendor/proc-macro2/LICENSE-MIT @@ -0,0 +1,23 @@ +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/proc-macro2/README.md b/vendor/proc-macro2/README.md new file mode 100644 index 0000000..3a29ce8 --- /dev/null +++ b/vendor/proc-macro2/README.md @@ -0,0 +1,94 @@ +# proc-macro2 + +[github](https://github.com/dtolnay/proc-macro2) +[crates.io](https://crates.io/crates/proc-macro2) +[docs.rs](https://docs.rs/proc-macro2) +[build status](https://github.com/dtolnay/proc-macro2/actions?query=branch%3Amaster) + +A wrapper around the procedural macro API of the compiler's `proc_macro` crate. +This library serves two purposes: + +- **Bring proc-macro-like functionality to other contexts like build.rs and + main.rs.** Types from `proc_macro` are entirely specific to procedural macros + and cannot ever exist in code outside of a procedural macro. Meanwhile + `proc_macro2` types may exist anywhere including non-macro code. By developing + foundational libraries like [syn] and [quote] against `proc_macro2` rather + than `proc_macro`, the procedural macro ecosystem becomes easily applicable to + many other use cases and we avoid reimplementing non-macro equivalents of + those libraries. + +- **Make procedural macros unit testable.** As a consequence of being specific + to procedural macros, nothing that uses `proc_macro` can be executed from a + unit test. In order for helper libraries or components of a macro to be + testable in isolation, they must be implemented using `proc_macro2`. + +[syn]: https://github.com/dtolnay/syn +[quote]: https://github.com/dtolnay/quote + +## Usage + +```toml +[dependencies] +proc-macro2 = "1.0" +``` + +The skeleton of a typical procedural macro typically looks like this: + +```rust +extern crate proc_macro; + +#[proc_macro_derive(MyDerive)] +pub fn my_derive(input: proc_macro::TokenStream) -> proc_macro::TokenStream { + let input = proc_macro2::TokenStream::from(input); + + let output: proc_macro2::TokenStream = { + /* transform input */ + }; + + proc_macro::TokenStream::from(output) +} +``` + +If parsing with [Syn], you'll use [`parse_macro_input!`] instead to propagate +parse errors correctly back to the compiler when parsing fails. + +[`parse_macro_input!`]: https://docs.rs/syn/2.0/syn/macro.parse_macro_input.html + +## Unstable features + +The default feature set of proc-macro2 tracks the most recent stable compiler +API. Functionality in `proc_macro` that is not yet stable is not exposed by +proc-macro2 by default. + +To opt into the additional APIs available in the most recent nightly compiler, +the `procmacro2_semver_exempt` config flag must be passed to rustc. We will +polyfill those nightly-only APIs back to Rust 1.56.0. As these are unstable APIs +that track the nightly compiler, minor versions of proc-macro2 may make breaking +changes to them at any time. + +``` +RUSTFLAGS='--cfg procmacro2_semver_exempt' cargo build +``` + +Note that this must not only be done for your crate, but for any crate that +depends on your crate. This infectious nature is intentional, as it serves as a +reminder that you are outside of the normal semver guarantees. + +Semver exempt methods are marked as such in the proc-macro2 documentation. + +
+ +#### License + + +Licensed under either of Apache License, Version +2.0 or MIT license at your option. + + +
+ + +Unless you explicitly state otherwise, any contribution intentionally submitted +for inclusion in this crate 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/proc-macro2/build.rs b/vendor/proc-macro2/build.rs new file mode 100644 index 0000000..1d3ae17 --- /dev/null +++ b/vendor/proc-macro2/build.rs @@ -0,0 +1,213 @@ +#![allow(unknown_lints)] +#![allow(unexpected_cfgs)] + +use std::env; +use std::ffi::OsString; +use std::iter; +use std::path::Path; +use std::process::{self, Command, Stdio}; +use std::str; + +fn main() { + let rustc = rustc_minor_version().unwrap_or(u32::MAX); + + if rustc >= 80 { + println!("cargo:rustc-check-cfg=cfg(fuzzing)"); + println!("cargo:rustc-check-cfg=cfg(no_is_available)"); + println!("cargo:rustc-check-cfg=cfg(no_literal_byte_character)"); + println!("cargo:rustc-check-cfg=cfg(no_literal_c_string)"); + println!("cargo:rustc-check-cfg=cfg(no_source_text)"); + println!("cargo:rustc-check-cfg=cfg(proc_macro_span)"); + println!("cargo:rustc-check-cfg=cfg(procmacro2_backtrace)"); + println!("cargo:rustc-check-cfg=cfg(procmacro2_nightly_testing)"); + println!("cargo:rustc-check-cfg=cfg(procmacro2_semver_exempt)"); + println!("cargo:rustc-check-cfg=cfg(randomize_layout)"); + println!("cargo:rustc-check-cfg=cfg(span_locations)"); + println!("cargo:rustc-check-cfg=cfg(super_unstable)"); + println!("cargo:rustc-check-cfg=cfg(wrap_proc_macro)"); + } + + let docs_rs = env::var_os("DOCS_RS").is_some(); + let semver_exempt = cfg!(procmacro2_semver_exempt) || docs_rs; + if semver_exempt { + // https://github.com/dtolnay/proc-macro2/issues/147 + println!("cargo:rustc-cfg=procmacro2_semver_exempt"); + } + + if semver_exempt || cfg!(feature = "span-locations") { + // Provide methods Span::start and Span::end which give the line/column + // location of a token. This is behind a cfg because tracking location + // inside spans is a performance hit. + println!("cargo:rustc-cfg=span_locations"); + } + + if rustc < 57 { + // Do not use proc_macro::is_available() to detect whether the proc + // macro API is available vs needs to be polyfilled. Instead, use the + // proc macro API unconditionally and catch the panic that occurs if it + // isn't available. + println!("cargo:rustc-cfg=no_is_available"); + } + + if rustc < 66 { + // Do not call libproc_macro's Span::source_text. Always return None. + println!("cargo:rustc-cfg=no_source_text"); + } + + if rustc < 79 { + // Do not call Literal::byte_character nor Literal::c_string. They can + // be emulated by way of Literal::from_str. + println!("cargo:rustc-cfg=no_literal_byte_character"); + println!("cargo:rustc-cfg=no_literal_c_string"); + } + + if !cfg!(feature = "proc-macro") { + println!("cargo:rerun-if-changed=build.rs"); + return; + } + + println!("cargo:rerun-if-changed=build/probe.rs"); + + let proc_macro_span; + let consider_rustc_bootstrap; + if compile_probe(false) { + // This is a nightly or dev compiler, so it supports unstable features + // regardless of RUSTC_BOOTSTRAP. No need to rerun build script if + // RUSTC_BOOTSTRAP is changed. + proc_macro_span = true; + consider_rustc_bootstrap = false; + } else if let Some(rustc_bootstrap) = env::var_os("RUSTC_BOOTSTRAP") { + if compile_probe(true) { + // This is a stable or beta compiler for which the user has set + // RUSTC_BOOTSTRAP to turn on unstable features. Rerun build script + // if they change it. + proc_macro_span = true; + consider_rustc_bootstrap = true; + } else if rustc_bootstrap == "1" { + // This compiler does not support the proc macro Span API in the + // form that proc-macro2 expects. No need to pay attention to + // RUSTC_BOOTSTRAP. + proc_macro_span = false; + consider_rustc_bootstrap = false; + } else { + // This is a stable or beta compiler for which RUSTC_BOOTSTRAP is + // set to restrict the use of unstable features by this crate. + proc_macro_span = false; + consider_rustc_bootstrap = true; + } + } else { + // Without RUSTC_BOOTSTRAP, this compiler does not support the proc + // macro Span API in the form that proc-macro2 expects, but try again if + // the user turns on unstable features. + proc_macro_span = false; + consider_rustc_bootstrap = true; + } + + if proc_macro_span || !semver_exempt { + // Wrap types from libproc_macro rather than polyfilling the whole API. + // Enabled as long as procmacro2_semver_exempt is not set, because we + // can't emulate the unstable API without emulating everything else. + // Also enabled unconditionally on nightly, in which case the + // procmacro2_semver_exempt surface area is implemented by using the + // nightly-only proc_macro API. + println!("cargo:rustc-cfg=wrap_proc_macro"); + } + + if proc_macro_span { + // Enable non-dummy behavior of Span::start and Span::end methods which + // requires an unstable compiler feature. Enabled when building with + // nightly, unless `-Z allow-feature` in RUSTFLAGS disallows unstable + // features. + println!("cargo:rustc-cfg=proc_macro_span"); + } + + if semver_exempt && proc_macro_span { + // Implement the semver exempt API in terms of the nightly-only + // proc_macro API. + println!("cargo:rustc-cfg=super_unstable"); + } + + if consider_rustc_bootstrap { + println!("cargo:rerun-if-env-changed=RUSTC_BOOTSTRAP"); + } +} + +fn compile_probe(rustc_bootstrap: bool) -> bool { + if env::var_os("RUSTC_STAGE").is_some() { + // We are running inside rustc bootstrap. This is a highly non-standard + // environment with issues such as: + // + // https://github.com/rust-lang/cargo/issues/11138 + // https://github.com/rust-lang/rust/issues/114839 + // + // Let's just not use nightly features here. + return false; + } + + let rustc = cargo_env_var("RUSTC"); + let out_dir = cargo_env_var("OUT_DIR"); + let probefile = Path::new("build").join("probe.rs"); + + let rustc_wrapper = env::var_os("RUSTC_WRAPPER").filter(|wrapper| !wrapper.is_empty()); + let rustc_workspace_wrapper = + env::var_os("RUSTC_WORKSPACE_WRAPPER").filter(|wrapper| !wrapper.is_empty()); + let mut rustc = rustc_wrapper + .into_iter() + .chain(rustc_workspace_wrapper) + .chain(iter::once(rustc)); + let mut cmd = Command::new(rustc.next().unwrap()); + cmd.args(rustc); + + if !rustc_bootstrap { + cmd.env_remove("RUSTC_BOOTSTRAP"); + } + + cmd.stderr(Stdio::null()) + .arg("--edition=2021") + .arg("--crate-name=proc_macro2") + .arg("--crate-type=lib") + .arg("--cap-lints=allow") + .arg("--emit=dep-info,metadata") + .arg("--out-dir") + .arg(out_dir) + .arg(probefile); + + if let Some(target) = env::var_os("TARGET") { + cmd.arg("--target").arg(target); + } + + // If Cargo wants to set RUSTFLAGS, use that. + if let Ok(rustflags) = env::var("CARGO_ENCODED_RUSTFLAGS") { + if !rustflags.is_empty() { + for arg in rustflags.split('\x1f') { + cmd.arg(arg); + } + } + } + + match cmd.status() { + Ok(status) => status.success(), + Err(_) => false, + } +} + +fn rustc_minor_version() -> Option { + let rustc = cargo_env_var("RUSTC"); + let output = Command::new(rustc).arg("--version").output().ok()?; + let version = str::from_utf8(&output.stdout).ok()?; + let mut pieces = version.split('.'); + if pieces.next() != Some("rustc 1") { + return None; + } + pieces.next()?.parse().ok() +} + +fn cargo_env_var(key: &str) -> OsString { + env::var_os(key).unwrap_or_else(|| { + eprintln!( + "Environment variable ${} is not set during execution of build script", + key, + ); + process::exit(1); + }) +} diff --git a/vendor/proc-macro2/build/probe.rs b/vendor/proc-macro2/build/probe.rs new file mode 100644 index 0000000..79c8ae2 --- /dev/null +++ b/vendor/proc-macro2/build/probe.rs @@ -0,0 +1,41 @@ +// This code exercises the surface area that we expect of Span's unstable API. +// If the current toolchain is able to compile it, then proc-macro2 is able to +// offer these APIs too. + +#![feature(proc_macro_span)] + +extern crate proc_macro; + +use core::ops::{Range, RangeBounds}; +use proc_macro::{Literal, Span}; + +pub fn byte_range(this: &Span) -> Range { + this.byte_range() +} + +pub fn start(this: &Span) -> Span { + this.start() +} + +pub fn end(this: &Span) -> Span { + this.end() +} + +pub fn line(this: &Span) -> usize { + this.line() +} + +pub fn column(this: &Span) -> usize { + this.column() +} + +pub fn join(this: &Span, other: Span) -> Option { + this.join(other) +} + +pub fn subspan>(this: &Literal, range: R) -> Option { + this.subspan(range) +} + +// Include in sccache cache key. +const _: Option<&str> = option_env!("RUSTC_BOOTSTRAP"); diff --git a/vendor/proc-macro2/rust-toolchain.toml b/vendor/proc-macro2/rust-toolchain.toml new file mode 100644 index 0000000..20fe888 --- /dev/null +++ b/vendor/proc-macro2/rust-toolchain.toml @@ -0,0 +1,2 @@ +[toolchain] +components = ["rust-src"] diff --git a/vendor/proc-macro2/src/detection.rs b/vendor/proc-macro2/src/detection.rs new file mode 100644 index 0000000..beba7b2 --- /dev/null +++ b/vendor/proc-macro2/src/detection.rs @@ -0,0 +1,75 @@ +use core::sync::atomic::{AtomicUsize, Ordering}; +use std::sync::Once; + +static WORKS: AtomicUsize = AtomicUsize::new(0); +static INIT: Once = Once::new(); + +pub(crate) fn inside_proc_macro() -> bool { + match WORKS.load(Ordering::Relaxed) { + 1 => return false, + 2 => return true, + _ => {} + } + + INIT.call_once(initialize); + inside_proc_macro() +} + +pub(crate) fn force_fallback() { + WORKS.store(1, Ordering::Relaxed); +} + +pub(crate) fn unforce_fallback() { + initialize(); +} + +#[cfg(not(no_is_available))] +fn initialize() { + let available = proc_macro::is_available(); + WORKS.store(available as usize + 1, Ordering::Relaxed); +} + +// Swap in a null panic hook to avoid printing "thread panicked" to stderr, +// then use catch_unwind to determine whether the compiler's proc_macro is +// working. When proc-macro2 is used from outside of a procedural macro all +// of the proc_macro crate's APIs currently panic. +// +// The Once is to prevent the possibility of this ordering: +// +// thread 1 calls take_hook, gets the user's original hook +// thread 1 calls set_hook with the null hook +// thread 2 calls take_hook, thinks null hook is the original hook +// thread 2 calls set_hook with the null hook +// thread 1 calls set_hook with the actual original hook +// thread 2 calls set_hook with what it thinks is the original hook +// +// in which the user's hook has been lost. +// +// There is still a race condition where a panic in a different thread can +// happen during the interval that the user's original panic hook is +// unregistered such that their hook is incorrectly not called. This is +// sufficiently unlikely and less bad than printing panic messages to stderr +// on correct use of this crate. Maybe there is a libstd feature request +// here. For now, if a user needs to guarantee that this failure mode does +// not occur, they need to call e.g. `proc_macro2::Span::call_site()` from +// the main thread before launching any other threads. +#[cfg(no_is_available)] +fn initialize() { + use std::panic::{self, PanicInfo}; + + type PanicHook = dyn Fn(&PanicInfo) + Sync + Send + 'static; + + let null_hook: Box = Box::new(|_panic_info| { /* ignore */ }); + let sanity_check = &*null_hook as *const PanicHook; + let original_hook = panic::take_hook(); + panic::set_hook(null_hook); + + let works = panic::catch_unwind(proc_macro::Span::call_site).is_ok(); + WORKS.store(works as usize + 1, Ordering::Relaxed); + + let hopefully_null_hook = panic::take_hook(); + panic::set_hook(original_hook); + if sanity_check != &*hopefully_null_hook { + panic!("observed race condition in proc_macro2::inside_proc_macro"); + } +} diff --git a/vendor/proc-macro2/src/extra.rs b/vendor/proc-macro2/src/extra.rs new file mode 100644 index 0000000..522a90e --- /dev/null +++ b/vendor/proc-macro2/src/extra.rs @@ -0,0 +1,151 @@ +//! Items which do not have a correspondence to any API in the proc_macro crate, +//! but are necessary to include in proc-macro2. + +use crate::fallback; +use crate::imp; +use crate::marker::{ProcMacroAutoTraits, MARKER}; +use crate::Span; +use core::fmt::{self, Debug}; + +/// Invalidate any `proc_macro2::Span` that exist on the current thread. +/// +/// The implementation of `Span` uses thread-local data structures and this +/// function clears them. Calling any method on a `Span` on the current thread +/// created prior to the invalidation will return incorrect values or crash. +/// +/// This function is useful for programs that process more than 232 +/// bytes of Rust source code on the same thread. Just like rustc, proc-macro2 +/// uses 32-bit source locations, and these wrap around when the total source +/// code processed by the same thread exceeds 232 bytes (4 +/// gigabytes). After a wraparound, `Span` methods such as `source_text()` can +/// return wrong data. +/// +/// # Example +/// +/// As of late 2023, there is 200 GB of Rust code published on crates.io. +/// Looking at just the newest version of every crate, it is 16 GB of code. So a +/// workload that involves parsing it all would overflow a 32-bit source +/// location unless spans are being invalidated. +/// +/// ``` +/// use flate2::read::GzDecoder; +/// use std::ffi::OsStr; +/// use std::io::{BufReader, Read}; +/// use std::str::FromStr; +/// use tar::Archive; +/// +/// rayon::scope(|s| { +/// for krate in every_version_of_every_crate() { +/// s.spawn(move |_| { +/// proc_macro2::extra::invalidate_current_thread_spans(); +/// +/// let reader = BufReader::new(krate); +/// let tar = GzDecoder::new(reader); +/// let mut archive = Archive::new(tar); +/// for entry in archive.entries().unwrap() { +/// let mut entry = entry.unwrap(); +/// let path = entry.path().unwrap(); +/// if path.extension() != Some(OsStr::new("rs")) { +/// continue; +/// } +/// let mut content = String::new(); +/// entry.read_to_string(&mut content).unwrap(); +/// match proc_macro2::TokenStream::from_str(&content) { +/// Ok(tokens) => {/* ... */}, +/// Err(_) => continue, +/// } +/// } +/// }); +/// } +/// }); +/// # +/// # fn every_version_of_every_crate() -> Vec { +/// # Vec::new() +/// # } +/// ``` +/// +/// # Panics +/// +/// This function is not applicable to and will panic if called from a +/// procedural macro. +#[cfg(span_locations)] +#[cfg_attr(docsrs, doc(cfg(feature = "span-locations")))] +pub fn invalidate_current_thread_spans() { + crate::imp::invalidate_current_thread_spans(); +} + +/// An object that holds a [`Group`]'s `span_open()` and `span_close()` together +/// in a more compact representation than holding those 2 spans individually. +/// +/// [`Group`]: crate::Group +#[derive(Copy, Clone)] +pub struct DelimSpan { + inner: DelimSpanEnum, + _marker: ProcMacroAutoTraits, +} + +#[derive(Copy, Clone)] +enum DelimSpanEnum { + #[cfg(wrap_proc_macro)] + Compiler { + join: proc_macro::Span, + open: proc_macro::Span, + close: proc_macro::Span, + }, + Fallback(fallback::Span), +} + +impl DelimSpan { + pub(crate) fn new(group: &imp::Group) -> Self { + #[cfg(wrap_proc_macro)] + let inner = match group { + imp::Group::Compiler(group) => DelimSpanEnum::Compiler { + join: group.span(), + open: group.span_open(), + close: group.span_close(), + }, + imp::Group::Fallback(group) => DelimSpanEnum::Fallback(group.span()), + }; + + #[cfg(not(wrap_proc_macro))] + let inner = DelimSpanEnum::Fallback(group.span()); + + DelimSpan { + inner, + _marker: MARKER, + } + } + + /// Returns a span covering the entire delimited group. + pub fn join(&self) -> Span { + match &self.inner { + #[cfg(wrap_proc_macro)] + DelimSpanEnum::Compiler { join, .. } => Span::_new(imp::Span::Compiler(*join)), + DelimSpanEnum::Fallback(span) => Span::_new_fallback(*span), + } + } + + /// Returns a span for the opening punctuation of the group only. + pub fn open(&self) -> Span { + match &self.inner { + #[cfg(wrap_proc_macro)] + DelimSpanEnum::Compiler { open, .. } => Span::_new(imp::Span::Compiler(*open)), + DelimSpanEnum::Fallback(span) => Span::_new_fallback(span.first_byte()), + } + } + + /// Returns a span for the closing punctuation of the group only. + pub fn close(&self) -> Span { + match &self.inner { + #[cfg(wrap_proc_macro)] + DelimSpanEnum::Compiler { close, .. } => Span::_new(imp::Span::Compiler(*close)), + DelimSpanEnum::Fallback(span) => Span::_new_fallback(span.last_byte()), + } + } +} + +impl Debug for DelimSpan { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + Debug::fmt(&self.join(), f) + } +} diff --git a/vendor/proc-macro2/src/fallback.rs b/vendor/proc-macro2/src/fallback.rs new file mode 100644 index 0000000..2d1c991 --- /dev/null +++ b/vendor/proc-macro2/src/fallback.rs @@ -0,0 +1,1226 @@ +#[cfg(span_locations)] +use crate::location::LineColumn; +use crate::parse::{self, Cursor}; +use crate::rcvec::{RcVec, RcVecBuilder, RcVecIntoIter, RcVecMut}; +use crate::{Delimiter, Spacing, TokenTree}; +#[cfg(all(span_locations, not(fuzzing)))] +use alloc::collections::BTreeMap; +#[cfg(all(span_locations, not(fuzzing)))] +use core::cell::RefCell; +#[cfg(span_locations)] +use core::cmp; +use core::fmt::{self, Debug, Display, Write}; +use core::mem::ManuallyDrop; +#[cfg(span_locations)] +use core::ops::Range; +use core::ops::RangeBounds; +use core::ptr; +use core::str::{self, FromStr}; +use std::ffi::CStr; +#[cfg(procmacro2_semver_exempt)] +use std::path::PathBuf; + +/// Force use of proc-macro2's fallback implementation of the API for now, even +/// if the compiler's implementation is available. +pub fn force() { + #[cfg(wrap_proc_macro)] + crate::detection::force_fallback(); +} + +/// Resume using the compiler's implementation of the proc macro API if it is +/// available. +pub fn unforce() { + #[cfg(wrap_proc_macro)] + crate::detection::unforce_fallback(); +} + +#[derive(Clone)] +pub(crate) struct TokenStream { + inner: RcVec, +} + +#[derive(Debug)] +pub(crate) struct LexError { + pub(crate) span: Span, +} + +impl LexError { + pub(crate) fn span(&self) -> Span { + self.span + } + + pub(crate) fn call_site() -> Self { + LexError { + span: Span::call_site(), + } + } +} + +impl TokenStream { + pub fn new() -> Self { + TokenStream { + inner: RcVecBuilder::new().build(), + } + } + + pub fn is_empty(&self) -> bool { + self.inner.len() == 0 + } + + fn take_inner(self) -> RcVecBuilder { + let nodrop = ManuallyDrop::new(self); + unsafe { ptr::read(&nodrop.inner) }.make_owned() + } +} + +fn push_token_from_proc_macro(mut vec: RcVecMut, token: TokenTree) { + // https://github.com/dtolnay/proc-macro2/issues/235 + match token { + TokenTree::Literal(crate::Literal { + #[cfg(wrap_proc_macro)] + inner: crate::imp::Literal::Fallback(literal), + #[cfg(not(wrap_proc_macro))] + inner: literal, + .. + }) if literal.repr.starts_with('-') => { + push_negative_literal(vec, literal); + } + _ => vec.push(token), + } + + #[cold] + fn push_negative_literal(mut vec: RcVecMut, mut literal: Literal) { + literal.repr.remove(0); + let mut punct = crate::Punct::new('-', Spacing::Alone); + punct.set_span(crate::Span::_new_fallback(literal.span)); + vec.push(TokenTree::Punct(punct)); + vec.push(TokenTree::Literal(crate::Literal::_new_fallback(literal))); + } +} + +// Nonrecursive to prevent stack overflow. +impl Drop for TokenStream { + fn drop(&mut self) { + let mut inner = match self.inner.get_mut() { + Some(inner) => inner, + None => return, + }; + while let Some(token) = inner.pop() { + let group = match token { + TokenTree::Group(group) => group.inner, + _ => continue, + }; + #[cfg(wrap_proc_macro)] + let group = match group { + crate::imp::Group::Fallback(group) => group, + crate::imp::Group::Compiler(_) => continue, + }; + inner.extend(group.stream.take_inner()); + } + } +} + +pub(crate) struct TokenStreamBuilder { + inner: RcVecBuilder, +} + +impl TokenStreamBuilder { + pub fn new() -> Self { + TokenStreamBuilder { + inner: RcVecBuilder::new(), + } + } + + pub fn with_capacity(cap: usize) -> Self { + TokenStreamBuilder { + inner: RcVecBuilder::with_capacity(cap), + } + } + + pub fn push_token_from_parser(&mut self, tt: TokenTree) { + self.inner.push(tt); + } + + pub fn build(self) -> TokenStream { + TokenStream { + inner: self.inner.build(), + } + } +} + +#[cfg(span_locations)] +fn get_cursor(src: &str) -> Cursor { + #[cfg(fuzzing)] + return Cursor { rest: src, off: 1 }; + + // Create a dummy file & add it to the source map + #[cfg(not(fuzzing))] + SOURCE_MAP.with(|sm| { + let mut sm = sm.borrow_mut(); + let span = sm.add_file(src); + Cursor { + rest: src, + off: span.lo, + } + }) +} + +#[cfg(not(span_locations))] +fn get_cursor(src: &str) -> Cursor { + Cursor { rest: src } +} + +impl FromStr for TokenStream { + type Err = LexError; + + fn from_str(src: &str) -> Result { + // Create a dummy file & add it to the source map + let mut cursor = get_cursor(src); + + // Strip a byte order mark if present + const BYTE_ORDER_MARK: &str = "\u{feff}"; + if cursor.starts_with(BYTE_ORDER_MARK) { + cursor = cursor.advance(BYTE_ORDER_MARK.len()); + } + + parse::token_stream(cursor) + } +} + +impl Display for LexError { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.write_str("cannot parse string into token stream") + } +} + +impl Display for TokenStream { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + let mut joint = false; + for (i, tt) in self.inner.iter().enumerate() { + if i != 0 && !joint { + write!(f, " ")?; + } + joint = false; + match tt { + TokenTree::Group(tt) => Display::fmt(tt, f), + TokenTree::Ident(tt) => Display::fmt(tt, f), + TokenTree::Punct(tt) => { + joint = tt.spacing() == Spacing::Joint; + Display::fmt(tt, f) + } + TokenTree::Literal(tt) => Display::fmt(tt, f), + }?; + } + + Ok(()) + } +} + +impl Debug for TokenStream { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.write_str("TokenStream ")?; + f.debug_list().entries(self.clone()).finish() + } +} + +#[cfg(feature = "proc-macro")] +impl From for TokenStream { + fn from(inner: proc_macro::TokenStream) -> Self { + inner + .to_string() + .parse() + .expect("compiler token stream parse failed") + } +} + +#[cfg(feature = "proc-macro")] +impl From for proc_macro::TokenStream { + fn from(inner: TokenStream) -> Self { + inner + .to_string() + .parse() + .expect("failed to parse to compiler tokens") + } +} + +impl From for TokenStream { + fn from(tree: TokenTree) -> Self { + let mut stream = RcVecBuilder::new(); + push_token_from_proc_macro(stream.as_mut(), tree); + TokenStream { + inner: stream.build(), + } + } +} + +impl FromIterator for TokenStream { + fn from_iter>(tokens: I) -> Self { + let mut stream = TokenStream::new(); + stream.extend(tokens); + stream + } +} + +impl FromIterator for TokenStream { + fn from_iter>(streams: I) -> Self { + let mut v = RcVecBuilder::new(); + + for stream in streams { + v.extend(stream.take_inner()); + } + + TokenStream { inner: v.build() } + } +} + +impl Extend for TokenStream { + fn extend>(&mut self, tokens: I) { + let mut vec = self.inner.make_mut(); + tokens + .into_iter() + .for_each(|token| push_token_from_proc_macro(vec.as_mut(), token)); + } +} + +impl Extend for TokenStream { + fn extend>(&mut self, streams: I) { + self.inner.make_mut().extend(streams.into_iter().flatten()); + } +} + +pub(crate) type TokenTreeIter = RcVecIntoIter; + +impl IntoIterator for TokenStream { + type Item = TokenTree; + type IntoIter = TokenTreeIter; + + fn into_iter(self) -> TokenTreeIter { + self.take_inner().into_iter() + } +} + +#[cfg(procmacro2_semver_exempt)] +#[derive(Clone, PartialEq, Eq)] +pub(crate) struct SourceFile { + path: PathBuf, +} + +#[cfg(procmacro2_semver_exempt)] +impl SourceFile { + /// Get the path to this source file as a string. + pub fn path(&self) -> PathBuf { + self.path.clone() + } + + pub fn is_real(&self) -> bool { + false + } +} + +#[cfg(procmacro2_semver_exempt)] +impl Debug for SourceFile { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.debug_struct("SourceFile") + .field("path", &self.path()) + .field("is_real", &self.is_real()) + .finish() + } +} + +#[cfg(all(span_locations, not(fuzzing)))] +thread_local! { + static SOURCE_MAP: RefCell = RefCell::new(SourceMap { + // Start with a single dummy file which all call_site() and def_site() + // spans reference. + files: vec![FileInfo { + source_text: String::new(), + span: Span { lo: 0, hi: 0 }, + lines: vec![0], + char_index_to_byte_offset: BTreeMap::new(), + }], + }); +} + +#[cfg(span_locations)] +pub(crate) fn invalidate_current_thread_spans() { + #[cfg(not(fuzzing))] + SOURCE_MAP.with(|sm| sm.borrow_mut().files.truncate(1)); +} + +#[cfg(all(span_locations, not(fuzzing)))] +struct FileInfo { + source_text: String, + span: Span, + lines: Vec, + char_index_to_byte_offset: BTreeMap, +} + +#[cfg(all(span_locations, not(fuzzing)))] +impl FileInfo { + fn offset_line_column(&self, offset: usize) -> LineColumn { + assert!(self.span_within(Span { + lo: offset as u32, + hi: offset as u32, + })); + let offset = offset - self.span.lo as usize; + match self.lines.binary_search(&offset) { + Ok(found) => LineColumn { + line: found + 1, + column: 0, + }, + Err(idx) => LineColumn { + line: idx, + column: offset - self.lines[idx - 1], + }, + } + } + + fn span_within(&self, span: Span) -> bool { + span.lo >= self.span.lo && span.hi <= self.span.hi + } + + fn byte_range(&mut self, span: Span) -> Range { + let lo_char = (span.lo - self.span.lo) as usize; + + // Look up offset of the largest already-computed char index that is + // less than or equal to the current requested one. We resume counting + // chars from that point. + let (&last_char_index, &last_byte_offset) = self + .char_index_to_byte_offset + .range(..=lo_char) + .next_back() + .unwrap_or((&0, &0)); + + let lo_byte = if last_char_index == lo_char { + last_byte_offset + } else { + let total_byte_offset = match self.source_text[last_byte_offset..] + .char_indices() + .nth(lo_char - last_char_index) + { + Some((additional_offset, _ch)) => last_byte_offset + additional_offset, + None => self.source_text.len(), + }; + self.char_index_to_byte_offset + .insert(lo_char, total_byte_offset); + total_byte_offset + }; + + let trunc_lo = &self.source_text[lo_byte..]; + let char_len = (span.hi - span.lo) as usize; + lo_byte..match trunc_lo.char_indices().nth(char_len) { + Some((offset, _ch)) => lo_byte + offset, + None => self.source_text.len(), + } + } + + fn source_text(&mut self, span: Span) -> String { + let byte_range = self.byte_range(span); + self.source_text[byte_range].to_owned() + } +} + +/// Computes the offsets of each line in the given source string +/// and the total number of characters +#[cfg(all(span_locations, not(fuzzing)))] +fn lines_offsets(s: &str) -> (usize, Vec) { + let mut lines = vec![0]; + let mut total = 0; + + for ch in s.chars() { + total += 1; + if ch == '\n' { + lines.push(total); + } + } + + (total, lines) +} + +#[cfg(all(span_locations, not(fuzzing)))] +struct SourceMap { + files: Vec, +} + +#[cfg(all(span_locations, not(fuzzing)))] +impl SourceMap { + fn next_start_pos(&self) -> u32 { + // Add 1 so there's always space between files. + // + // We'll always have at least 1 file, as we initialize our files list + // with a dummy file. + self.files.last().unwrap().span.hi + 1 + } + + fn add_file(&mut self, src: &str) -> Span { + let (len, lines) = lines_offsets(src); + let lo = self.next_start_pos(); + let span = Span { + lo, + hi: lo + (len as u32), + }; + + self.files.push(FileInfo { + source_text: src.to_owned(), + span, + lines, + // Populated lazily by source_text(). + char_index_to_byte_offset: BTreeMap::new(), + }); + + span + } + + #[cfg(procmacro2_semver_exempt)] + fn filepath(&self, span: Span) -> PathBuf { + for (i, file) in self.files.iter().enumerate() { + if file.span_within(span) { + return PathBuf::from(if i == 0 { + "".to_owned() + } else { + format!("", i) + }); + } + } + unreachable!("Invalid span with no related FileInfo!"); + } + + fn fileinfo(&self, span: Span) -> &FileInfo { + for file in &self.files { + if file.span_within(span) { + return file; + } + } + unreachable!("Invalid span with no related FileInfo!"); + } + + fn fileinfo_mut(&mut self, span: Span) -> &mut FileInfo { + for file in &mut self.files { + if file.span_within(span) { + return file; + } + } + unreachable!("Invalid span with no related FileInfo!"); + } +} + +#[derive(Clone, Copy, PartialEq, Eq)] +pub(crate) struct Span { + #[cfg(span_locations)] + pub(crate) lo: u32, + #[cfg(span_locations)] + pub(crate) hi: u32, +} + +impl Span { + #[cfg(not(span_locations))] + pub fn call_site() -> Self { + Span {} + } + + #[cfg(span_locations)] + pub fn call_site() -> Self { + Span { lo: 0, hi: 0 } + } + + pub fn mixed_site() -> Self { + Span::call_site() + } + + #[cfg(procmacro2_semver_exempt)] + pub fn def_site() -> Self { + Span::call_site() + } + + pub fn resolved_at(&self, _other: Span) -> Span { + // Stable spans consist only of line/column information, so + // `resolved_at` and `located_at` only select which span the + // caller wants line/column information from. + *self + } + + pub fn located_at(&self, other: Span) -> Span { + other + } + + #[cfg(procmacro2_semver_exempt)] + pub fn source_file(&self) -> SourceFile { + #[cfg(fuzzing)] + return SourceFile { + path: PathBuf::from(""), + }; + + #[cfg(not(fuzzing))] + SOURCE_MAP.with(|sm| { + let sm = sm.borrow(); + let path = sm.filepath(*self); + SourceFile { path } + }) + } + + #[cfg(span_locations)] + pub fn byte_range(&self) -> Range { + #[cfg(fuzzing)] + return 0..0; + + #[cfg(not(fuzzing))] + { + if self.is_call_site() { + 0..0 + } else { + SOURCE_MAP.with(|sm| sm.borrow_mut().fileinfo_mut(*self).byte_range(*self)) + } + } + } + + #[cfg(span_locations)] + pub fn start(&self) -> LineColumn { + #[cfg(fuzzing)] + return LineColumn { line: 0, column: 0 }; + + #[cfg(not(fuzzing))] + SOURCE_MAP.with(|sm| { + let sm = sm.borrow(); + let fi = sm.fileinfo(*self); + fi.offset_line_column(self.lo as usize) + }) + } + + #[cfg(span_locations)] + pub fn end(&self) -> LineColumn { + #[cfg(fuzzing)] + return LineColumn { line: 0, column: 0 }; + + #[cfg(not(fuzzing))] + SOURCE_MAP.with(|sm| { + let sm = sm.borrow(); + let fi = sm.fileinfo(*self); + fi.offset_line_column(self.hi as usize) + }) + } + + #[cfg(not(span_locations))] + pub fn join(&self, _other: Span) -> Option { + Some(Span {}) + } + + #[cfg(span_locations)] + pub fn join(&self, other: Span) -> Option { + #[cfg(fuzzing)] + return { + let _ = other; + None + }; + + #[cfg(not(fuzzing))] + SOURCE_MAP.with(|sm| { + let sm = sm.borrow(); + // If `other` is not within the same FileInfo as us, return None. + if !sm.fileinfo(*self).span_within(other) { + return None; + } + Some(Span { + lo: cmp::min(self.lo, other.lo), + hi: cmp::max(self.hi, other.hi), + }) + }) + } + + #[cfg(not(span_locations))] + pub fn source_text(&self) -> Option { + None + } + + #[cfg(span_locations)] + pub fn source_text(&self) -> Option { + #[cfg(fuzzing)] + return None; + + #[cfg(not(fuzzing))] + { + if self.is_call_site() { + None + } else { + Some(SOURCE_MAP.with(|sm| sm.borrow_mut().fileinfo_mut(*self).source_text(*self))) + } + } + } + + #[cfg(not(span_locations))] + pub(crate) fn first_byte(self) -> Self { + self + } + + #[cfg(span_locations)] + pub(crate) fn first_byte(self) -> Self { + Span { + lo: self.lo, + hi: cmp::min(self.lo.saturating_add(1), self.hi), + } + } + + #[cfg(not(span_locations))] + pub(crate) fn last_byte(self) -> Self { + self + } + + #[cfg(span_locations)] + pub(crate) fn last_byte(self) -> Self { + Span { + lo: cmp::max(self.hi.saturating_sub(1), self.lo), + hi: self.hi, + } + } + + #[cfg(span_locations)] + fn is_call_site(&self) -> bool { + self.lo == 0 && self.hi == 0 + } +} + +impl Debug for Span { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + #[cfg(span_locations)] + return write!(f, "bytes({}..{})", self.lo, self.hi); + + #[cfg(not(span_locations))] + write!(f, "Span") + } +} + +pub(crate) fn debug_span_field_if_nontrivial(debug: &mut fmt::DebugStruct, span: Span) { + #[cfg(span_locations)] + { + if span.is_call_site() { + return; + } + } + + if cfg!(span_locations) { + debug.field("span", &span); + } +} + +#[derive(Clone)] +pub(crate) struct Group { + delimiter: Delimiter, + stream: TokenStream, + span: Span, +} + +impl Group { + pub fn new(delimiter: Delimiter, stream: TokenStream) -> Self { + Group { + delimiter, + stream, + span: Span::call_site(), + } + } + + pub fn delimiter(&self) -> Delimiter { + self.delimiter + } + + pub fn stream(&self) -> TokenStream { + self.stream.clone() + } + + pub fn span(&self) -> Span { + self.span + } + + pub fn span_open(&self) -> Span { + self.span.first_byte() + } + + pub fn span_close(&self) -> Span { + self.span.last_byte() + } + + pub fn set_span(&mut self, span: Span) { + self.span = span; + } +} + +impl Display for Group { + // We attempt to match libproc_macro's formatting. + // Empty parens: () + // Nonempty parens: (...) + // Empty brackets: [] + // Nonempty brackets: [...] + // Empty braces: { } + // Nonempty braces: { ... } + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + let (open, close) = match self.delimiter { + Delimiter::Parenthesis => ("(", ")"), + Delimiter::Brace => ("{ ", "}"), + Delimiter::Bracket => ("[", "]"), + Delimiter::None => ("", ""), + }; + + f.write_str(open)?; + Display::fmt(&self.stream, f)?; + if self.delimiter == Delimiter::Brace && !self.stream.inner.is_empty() { + f.write_str(" ")?; + } + f.write_str(close)?; + + Ok(()) + } +} + +impl Debug for Group { + fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { + let mut debug = fmt.debug_struct("Group"); + debug.field("delimiter", &self.delimiter); + debug.field("stream", &self.stream); + debug_span_field_if_nontrivial(&mut debug, self.span); + debug.finish() + } +} + +#[derive(Clone)] +pub(crate) struct Ident { + sym: Box, + span: Span, + raw: bool, +} + +impl Ident { + #[track_caller] + pub fn new_checked(string: &str, span: Span) -> Self { + validate_ident(string); + Ident::new_unchecked(string, span) + } + + pub fn new_unchecked(string: &str, span: Span) -> Self { + Ident { + sym: Box::from(string), + span, + raw: false, + } + } + + #[track_caller] + pub fn new_raw_checked(string: &str, span: Span) -> Self { + validate_ident_raw(string); + Ident::new_raw_unchecked(string, span) + } + + pub fn new_raw_unchecked(string: &str, span: Span) -> Self { + Ident { + sym: Box::from(string), + span, + raw: true, + } + } + + pub fn span(&self) -> Span { + self.span + } + + pub fn set_span(&mut self, span: Span) { + self.span = span; + } +} + +pub(crate) fn is_ident_start(c: char) -> bool { + c == '_' || unicode_ident::is_xid_start(c) +} + +pub(crate) fn is_ident_continue(c: char) -> bool { + unicode_ident::is_xid_continue(c) +} + +#[track_caller] +fn validate_ident(string: &str) { + if string.is_empty() { + panic!("Ident is not allowed to be empty; use Option"); + } + + if string.bytes().all(|digit| b'0' <= digit && digit <= b'9') { + panic!("Ident cannot be a number; use Literal instead"); + } + + fn ident_ok(string: &str) -> bool { + let mut chars = string.chars(); + let first = chars.next().unwrap(); + if !is_ident_start(first) { + return false; + } + for ch in chars { + if !is_ident_continue(ch) { + return false; + } + } + true + } + + if !ident_ok(string) { + panic!("{:?} is not a valid Ident", string); + } +} + +#[track_caller] +fn validate_ident_raw(string: &str) { + validate_ident(string); + + match string { + "_" | "super" | "self" | "Self" | "crate" => { + panic!("`r#{}` cannot be a raw identifier", string); + } + _ => {} + } +} + +impl PartialEq for Ident { + fn eq(&self, other: &Ident) -> bool { + self.sym == other.sym && self.raw == other.raw + } +} + +impl PartialEq for Ident +where + T: ?Sized + AsRef, +{ + fn eq(&self, other: &T) -> bool { + let other = other.as_ref(); + if self.raw { + other.starts_with("r#") && *self.sym == other[2..] + } else { + *self.sym == *other + } + } +} + +impl Display for Ident { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + if self.raw { + f.write_str("r#")?; + } + Display::fmt(&self.sym, f) + } +} + +#[allow(clippy::missing_fields_in_debug)] +impl Debug for Ident { + // Ident(proc_macro), Ident(r#union) + #[cfg(not(span_locations))] + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + let mut debug = f.debug_tuple("Ident"); + debug.field(&format_args!("{}", self)); + debug.finish() + } + + // Ident { + // sym: proc_macro, + // span: bytes(128..138) + // } + #[cfg(span_locations)] + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + let mut debug = f.debug_struct("Ident"); + debug.field("sym", &format_args!("{}", self)); + debug_span_field_if_nontrivial(&mut debug, self.span); + debug.finish() + } +} + +#[derive(Clone)] +pub(crate) struct Literal { + pub(crate) repr: String, + span: Span, +} + +macro_rules! suffixed_numbers { + ($($name:ident => $kind:ident,)*) => ($( + pub fn $name(n: $kind) -> Literal { + Literal::_new(format!(concat!("{}", stringify!($kind)), n)) + } + )*) +} + +macro_rules! unsuffixed_numbers { + ($($name:ident => $kind:ident,)*) => ($( + pub fn $name(n: $kind) -> Literal { + Literal::_new(n.to_string()) + } + )*) +} + +impl Literal { + pub(crate) fn _new(repr: String) -> Self { + Literal { + repr, + span: Span::call_site(), + } + } + + pub(crate) unsafe fn from_str_unchecked(repr: &str) -> Self { + Literal::_new(repr.to_owned()) + } + + suffixed_numbers! { + u8_suffixed => u8, + u16_suffixed => u16, + u32_suffixed => u32, + u64_suffixed => u64, + u128_suffixed => u128, + usize_suffixed => usize, + i8_suffixed => i8, + i16_suffixed => i16, + i32_suffixed => i32, + i64_suffixed => i64, + i128_suffixed => i128, + isize_suffixed => isize, + + f32_suffixed => f32, + f64_suffixed => f64, + } + + unsuffixed_numbers! { + u8_unsuffixed => u8, + u16_unsuffixed => u16, + u32_unsuffixed => u32, + u64_unsuffixed => u64, + u128_unsuffixed => u128, + usize_unsuffixed => usize, + i8_unsuffixed => i8, + i16_unsuffixed => i16, + i32_unsuffixed => i32, + i64_unsuffixed => i64, + i128_unsuffixed => i128, + isize_unsuffixed => isize, + } + + pub fn f32_unsuffixed(f: f32) -> Literal { + let mut s = f.to_string(); + if !s.contains('.') { + s.push_str(".0"); + } + Literal::_new(s) + } + + pub fn f64_unsuffixed(f: f64) -> Literal { + let mut s = f.to_string(); + if !s.contains('.') { + s.push_str(".0"); + } + Literal::_new(s) + } + + pub fn string(string: &str) -> Literal { + let mut repr = String::with_capacity(string.len() + 2); + repr.push('"'); + escape_utf8(string, &mut repr); + repr.push('"'); + Literal::_new(repr) + } + + pub fn character(ch: char) -> Literal { + let mut repr = String::new(); + repr.push('\''); + if ch == '"' { + // escape_debug turns this into '\"' which is unnecessary. + repr.push(ch); + } else { + repr.extend(ch.escape_debug()); + } + repr.push('\''); + Literal::_new(repr) + } + + pub fn byte_character(byte: u8) -> Literal { + let mut repr = "b'".to_string(); + #[allow(clippy::match_overlapping_arm)] + match byte { + b'\0' => repr.push_str(r"\0"), + b'\t' => repr.push_str(r"\t"), + b'\n' => repr.push_str(r"\n"), + b'\r' => repr.push_str(r"\r"), + b'\'' => repr.push_str(r"\'"), + b'\\' => repr.push_str(r"\\"), + b'\x20'..=b'\x7E' => repr.push(byte as char), + _ => { + let _ = write!(repr, r"\x{:02X}", byte); + } + } + repr.push('\''); + Literal::_new(repr) + } + + pub fn byte_string(bytes: &[u8]) -> Literal { + let mut repr = "b\"".to_string(); + let mut bytes = bytes.iter(); + while let Some(&b) = bytes.next() { + #[allow(clippy::match_overlapping_arm)] + match b { + b'\0' => repr.push_str(match bytes.as_slice().first() { + // circumvent clippy::octal_escapes lint + Some(b'0'..=b'7') => r"\x00", + _ => r"\0", + }), + b'\t' => repr.push_str(r"\t"), + b'\n' => repr.push_str(r"\n"), + b'\r' => repr.push_str(r"\r"), + b'"' => repr.push_str("\\\""), + b'\\' => repr.push_str(r"\\"), + b'\x20'..=b'\x7E' => repr.push(b as char), + _ => { + let _ = write!(repr, r"\x{:02X}", b); + } + } + } + repr.push('"'); + Literal::_new(repr) + } + + pub fn c_string(string: &CStr) -> Literal { + let mut repr = "c\"".to_string(); + let mut bytes = string.to_bytes(); + while !bytes.is_empty() { + let (valid, invalid) = match str::from_utf8(bytes) { + Ok(all_valid) => { + bytes = b""; + (all_valid, bytes) + } + Err(utf8_error) => { + let (valid, rest) = bytes.split_at(utf8_error.valid_up_to()); + let valid = str::from_utf8(valid).unwrap(); + let invalid = utf8_error + .error_len() + .map_or(rest, |error_len| &rest[..error_len]); + bytes = &bytes[valid.len() + invalid.len()..]; + (valid, invalid) + } + }; + escape_utf8(valid, &mut repr); + for &byte in invalid { + let _ = write!(repr, r"\x{:02X}", byte); + } + } + repr.push('"'); + Literal::_new(repr) + } + + pub fn span(&self) -> Span { + self.span + } + + pub fn set_span(&mut self, span: Span) { + self.span = span; + } + + pub fn subspan>(&self, range: R) -> Option { + #[cfg(not(span_locations))] + { + let _ = range; + None + } + + #[cfg(span_locations)] + { + use core::ops::Bound; + + let lo = match range.start_bound() { + Bound::Included(start) => { + let start = u32::try_from(*start).ok()?; + self.span.lo.checked_add(start)? + } + Bound::Excluded(start) => { + let start = u32::try_from(*start).ok()?; + self.span.lo.checked_add(start)?.checked_add(1)? + } + Bound::Unbounded => self.span.lo, + }; + let hi = match range.end_bound() { + Bound::Included(end) => { + let end = u32::try_from(*end).ok()?; + self.span.lo.checked_add(end)?.checked_add(1)? + } + Bound::Excluded(end) => { + let end = u32::try_from(*end).ok()?; + self.span.lo.checked_add(end)? + } + Bound::Unbounded => self.span.hi, + }; + if lo <= hi && hi <= self.span.hi { + Some(Span { lo, hi }) + } else { + None + } + } + } +} + +impl FromStr for Literal { + type Err = LexError; + + fn from_str(repr: &str) -> Result { + let mut cursor = get_cursor(repr); + #[cfg(span_locations)] + let lo = cursor.off; + + let negative = cursor.starts_with_char('-'); + if negative { + cursor = cursor.advance(1); + if !cursor.starts_with_fn(|ch| ch.is_ascii_digit()) { + return Err(LexError::call_site()); + } + } + + if let Ok((rest, mut literal)) = parse::literal(cursor) { + if rest.is_empty() { + if negative { + literal.repr.insert(0, '-'); + } + literal.span = Span { + #[cfg(span_locations)] + lo, + #[cfg(span_locations)] + hi: rest.off, + }; + return Ok(literal); + } + } + Err(LexError::call_site()) + } +} + +impl Display for Literal { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + Display::fmt(&self.repr, f) + } +} + +impl Debug for Literal { + fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { + let mut debug = fmt.debug_struct("Literal"); + debug.field("lit", &format_args!("{}", self.repr)); + debug_span_field_if_nontrivial(&mut debug, self.span); + debug.finish() + } +} + +fn escape_utf8(string: &str, repr: &mut String) { + let mut chars = string.chars(); + while let Some(ch) = chars.next() { + if ch == '\0' { + repr.push_str( + if chars + .as_str() + .starts_with(|next| '0' <= next && next <= '7') + { + // circumvent clippy::octal_escapes lint + r"\x00" + } else { + r"\0" + }, + ); + } else if ch == '\'' { + // escape_debug turns this into "\'" which is unnecessary. + repr.push(ch); + } else { + repr.extend(ch.escape_debug()); + } + } +} diff --git a/vendor/proc-macro2/src/lib.rs b/vendor/proc-macro2/src/lib.rs new file mode 100644 index 0000000..43bac76 --- /dev/null +++ b/vendor/proc-macro2/src/lib.rs @@ -0,0 +1,1377 @@ +//! [![github]](https://github.com/dtolnay/proc-macro2) [![crates-io]](https://crates.io/crates/proc-macro2) [![docs-rs]](crate) +//! +//! [github]: https://img.shields.io/badge/github-8da0cb?style=for-the-badge&labelColor=555555&logo=github +//! [crates-io]: https://img.shields.io/badge/crates.io-fc8d62?style=for-the-badge&labelColor=555555&logo=rust +//! [docs-rs]: https://img.shields.io/badge/docs.rs-66c2a5?style=for-the-badge&labelColor=555555&logo=docs.rs +//! +//!
+//! +//! A wrapper around the procedural macro API of the compiler's [`proc_macro`] +//! crate. This library serves two purposes: +//! +//! [`proc_macro`]: https://doc.rust-lang.org/proc_macro/ +//! +//! - **Bring proc-macro-like functionality to other contexts like build.rs and +//! main.rs.** Types from `proc_macro` are entirely specific to procedural +//! macros and cannot ever exist in code outside of a procedural macro. +//! Meanwhile `proc_macro2` types may exist anywhere including non-macro code. +//! By developing foundational libraries like [syn] and [quote] against +//! `proc_macro2` rather than `proc_macro`, the procedural macro ecosystem +//! becomes easily applicable to many other use cases and we avoid +//! reimplementing non-macro equivalents of those libraries. +//! +//! - **Make procedural macros unit testable.** As a consequence of being +//! specific to procedural macros, nothing that uses `proc_macro` can be +//! executed from a unit test. In order for helper libraries or components of +//! a macro to be testable in isolation, they must be implemented using +//! `proc_macro2`. +//! +//! [syn]: https://github.com/dtolnay/syn +//! [quote]: https://github.com/dtolnay/quote +//! +//! # Usage +//! +//! The skeleton of a typical procedural macro typically looks like this: +//! +//! ``` +//! extern crate proc_macro; +//! +//! # const IGNORE: &str = stringify! { +//! #[proc_macro_derive(MyDerive)] +//! # }; +//! # #[cfg(wrap_proc_macro)] +//! pub fn my_derive(input: proc_macro::TokenStream) -> proc_macro::TokenStream { +//! let input = proc_macro2::TokenStream::from(input); +//! +//! let output: proc_macro2::TokenStream = { +//! /* transform input */ +//! # input +//! }; +//! +//! proc_macro::TokenStream::from(output) +//! } +//! ``` +//! +//! If parsing with [Syn], you'll use [`parse_macro_input!`] instead to +//! propagate parse errors correctly back to the compiler when parsing fails. +//! +//! [`parse_macro_input!`]: https://docs.rs/syn/2.0/syn/macro.parse_macro_input.html +//! +//! # Unstable features +//! +//! The default feature set of proc-macro2 tracks the most recent stable +//! compiler API. Functionality in `proc_macro` that is not yet stable is not +//! exposed by proc-macro2 by default. +//! +//! To opt into the additional APIs available in the most recent nightly +//! compiler, the `procmacro2_semver_exempt` config flag must be passed to +//! rustc. We will polyfill those nightly-only APIs back to Rust 1.56.0. As +//! these are unstable APIs that track the nightly compiler, minor versions of +//! proc-macro2 may make breaking changes to them at any time. +//! +//! ```sh +//! RUSTFLAGS='--cfg procmacro2_semver_exempt' cargo build +//! ``` +//! +//! Note that this must not only be done for your crate, but for any crate that +//! depends on your crate. This infectious nature is intentional, as it serves +//! as a reminder that you are outside of the normal semver guarantees. +//! +//! Semver exempt methods are marked as such in the proc-macro2 documentation. +//! +//! # Thread-Safety +//! +//! Most types in this crate are `!Sync` because the underlying compiler +//! types make use of thread-local memory, meaning they cannot be accessed from +//! a different thread. + +// Proc-macro2 types in rustdoc of other crates get linked to here. +#![doc(html_root_url = "https://docs.rs/proc-macro2/1.0.88")] +#![cfg_attr(any(proc_macro_span, super_unstable), feature(proc_macro_span))] +#![cfg_attr(super_unstable, feature(proc_macro_def_site))] +#![cfg_attr(docsrs, feature(doc_cfg))] +#![deny(unsafe_op_in_unsafe_fn)] +#![allow( + clippy::cast_lossless, + clippy::cast_possible_truncation, + clippy::checked_conversions, + clippy::doc_markdown, + clippy::incompatible_msrv, + clippy::items_after_statements, + clippy::iter_without_into_iter, + clippy::let_underscore_untyped, + clippy::manual_assert, + clippy::manual_range_contains, + clippy::missing_panics_doc, + clippy::missing_safety_doc, + clippy::must_use_candidate, + clippy::needless_doctest_main, + clippy::needless_lifetimes, + clippy::new_without_default, + clippy::return_self_not_must_use, + clippy::shadow_unrelated, + clippy::trivially_copy_pass_by_ref, + clippy::unnecessary_wraps, + clippy::unused_self, + clippy::used_underscore_binding, + clippy::vec_init_then_push +)] + +#[cfg(all(procmacro2_semver_exempt, wrap_proc_macro, not(super_unstable)))] +compile_error! {"\ + Something is not right. If you've tried to turn on \ + procmacro2_semver_exempt, you need to ensure that it \ + is turned on for the compilation of the proc-macro2 \ + build script as well. +"} + +#[cfg(all( + procmacro2_nightly_testing, + feature = "proc-macro", + not(proc_macro_span) +))] +compile_error! {"\ + Build script probe failed to compile. +"} + +extern crate alloc; + +#[cfg(feature = "proc-macro")] +extern crate proc_macro; + +mod marker; +mod parse; +mod rcvec; + +#[cfg(wrap_proc_macro)] +mod detection; + +// Public for proc_macro2::fallback::force() and unforce(), but those are quite +// a niche use case so we omit it from rustdoc. +#[doc(hidden)] +pub mod fallback; + +pub mod extra; + +#[cfg(not(wrap_proc_macro))] +use crate::fallback as imp; +#[path = "wrapper.rs"] +#[cfg(wrap_proc_macro)] +mod imp; + +#[cfg(span_locations)] +mod location; + +use crate::extra::DelimSpan; +use crate::marker::{ProcMacroAutoTraits, MARKER}; +use core::cmp::Ordering; +use core::fmt::{self, Debug, Display}; +use core::hash::{Hash, Hasher}; +#[cfg(span_locations)] +use core::ops::Range; +use core::ops::RangeBounds; +use core::str::FromStr; +use std::error::Error; +use std::ffi::CStr; +#[cfg(procmacro2_semver_exempt)] +use std::path::PathBuf; + +#[cfg(span_locations)] +#[cfg_attr(docsrs, doc(cfg(feature = "span-locations")))] +pub use crate::location::LineColumn; + +/// An abstract stream of tokens, or more concretely a sequence of token trees. +/// +/// This type provides interfaces for iterating over token trees and for +/// collecting token trees into one stream. +/// +/// Token stream is both the input and output of `#[proc_macro]`, +/// `#[proc_macro_attribute]` and `#[proc_macro_derive]` definitions. +#[derive(Clone)] +pub struct TokenStream { + inner: imp::TokenStream, + _marker: ProcMacroAutoTraits, +} + +/// Error returned from `TokenStream::from_str`. +pub struct LexError { + inner: imp::LexError, + _marker: ProcMacroAutoTraits, +} + +impl TokenStream { + fn _new(inner: imp::TokenStream) -> Self { + TokenStream { + inner, + _marker: MARKER, + } + } + + fn _new_fallback(inner: fallback::TokenStream) -> Self { + TokenStream { + inner: inner.into(), + _marker: MARKER, + } + } + + /// Returns an empty `TokenStream` containing no token trees. + pub fn new() -> Self { + TokenStream::_new(imp::TokenStream::new()) + } + + /// Checks if this `TokenStream` is empty. + pub fn is_empty(&self) -> bool { + self.inner.is_empty() + } +} + +/// `TokenStream::default()` returns an empty stream, +/// i.e. this is equivalent with `TokenStream::new()`. +impl Default for TokenStream { + fn default() -> Self { + TokenStream::new() + } +} + +/// Attempts to break the string into tokens and parse those tokens into a token +/// stream. +/// +/// May fail for a number of reasons, for example, if the string contains +/// unbalanced delimiters or characters not existing in the language. +/// +/// NOTE: Some errors may cause panics instead of returning `LexError`. We +/// reserve the right to change these errors into `LexError`s later. +impl FromStr for TokenStream { + type Err = LexError; + + fn from_str(src: &str) -> Result { + let e = src.parse().map_err(|e| LexError { + inner: e, + _marker: MARKER, + })?; + Ok(TokenStream::_new(e)) + } +} + +#[cfg(feature = "proc-macro")] +#[cfg_attr(docsrs, doc(cfg(feature = "proc-macro")))] +impl From for TokenStream { + fn from(inner: proc_macro::TokenStream) -> Self { + TokenStream::_new(inner.into()) + } +} + +#[cfg(feature = "proc-macro")] +#[cfg_attr(docsrs, doc(cfg(feature = "proc-macro")))] +impl From for proc_macro::TokenStream { + fn from(inner: TokenStream) -> Self { + inner.inner.into() + } +} + +impl From for TokenStream { + fn from(token: TokenTree) -> Self { + TokenStream::_new(imp::TokenStream::from(token)) + } +} + +impl Extend for TokenStream { + fn extend>(&mut self, streams: I) { + self.inner.extend(streams); + } +} + +impl Extend for TokenStream { + fn extend>(&mut self, streams: I) { + self.inner + .extend(streams.into_iter().map(|stream| stream.inner)); + } +} + +/// Collects a number of token trees into a single stream. +impl FromIterator for TokenStream { + fn from_iter>(streams: I) -> Self { + TokenStream::_new(streams.into_iter().collect()) + } +} +impl FromIterator for TokenStream { + fn from_iter>(streams: I) -> Self { + TokenStream::_new(streams.into_iter().map(|i| i.inner).collect()) + } +} + +/// Prints the token stream as a string that is supposed to be losslessly +/// convertible back into the same token stream (modulo spans), except for +/// possibly `TokenTree::Group`s with `Delimiter::None` delimiters and negative +/// numeric literals. +impl Display for TokenStream { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + Display::fmt(&self.inner, f) + } +} + +/// Prints token in a form convenient for debugging. +impl Debug for TokenStream { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + Debug::fmt(&self.inner, f) + } +} + +impl LexError { + pub fn span(&self) -> Span { + Span::_new(self.inner.span()) + } +} + +impl Debug for LexError { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + Debug::fmt(&self.inner, f) + } +} + +impl Display for LexError { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + Display::fmt(&self.inner, f) + } +} + +impl Error for LexError {} + +/// The source file of a given `Span`. +/// +/// This type is semver exempt and not exposed by default. +#[cfg(all(procmacro2_semver_exempt, any(not(wrap_proc_macro), super_unstable)))] +#[cfg_attr(docsrs, doc(cfg(procmacro2_semver_exempt)))] +#[derive(Clone, PartialEq, Eq)] +pub struct SourceFile { + inner: imp::SourceFile, + _marker: ProcMacroAutoTraits, +} + +#[cfg(all(procmacro2_semver_exempt, any(not(wrap_proc_macro), super_unstable)))] +impl SourceFile { + fn _new(inner: imp::SourceFile) -> Self { + SourceFile { + inner, + _marker: MARKER, + } + } + + /// Get the path to this source file. + /// + /// ### Note + /// + /// If the code span associated with this `SourceFile` was generated by an + /// external macro, this may not be an actual path on the filesystem. Use + /// [`is_real`] to check. + /// + /// Also note that even if `is_real` returns `true`, if + /// `--remap-path-prefix` was passed on the command line, the path as given + /// may not actually be valid. + /// + /// [`is_real`]: #method.is_real + pub fn path(&self) -> PathBuf { + self.inner.path() + } + + /// Returns `true` if this source file is a real source file, and not + /// generated by an external macro's expansion. + pub fn is_real(&self) -> bool { + self.inner.is_real() + } +} + +#[cfg(all(procmacro2_semver_exempt, any(not(wrap_proc_macro), super_unstable)))] +impl Debug for SourceFile { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + Debug::fmt(&self.inner, f) + } +} + +/// A region of source code, along with macro expansion information. +#[derive(Copy, Clone)] +pub struct Span { + inner: imp::Span, + _marker: ProcMacroAutoTraits, +} + +impl Span { + fn _new(inner: imp::Span) -> Self { + Span { + inner, + _marker: MARKER, + } + } + + fn _new_fallback(inner: fallback::Span) -> Self { + Span { + inner: inner.into(), + _marker: MARKER, + } + } + + /// The span of the invocation of the current procedural macro. + /// + /// Identifiers created with this span will be resolved as if they were + /// written directly at the macro call location (call-site hygiene) and + /// other code at the macro call site will be able to refer to them as well. + pub fn call_site() -> Self { + Span::_new(imp::Span::call_site()) + } + + /// The span located at the invocation of the procedural macro, but with + /// local variables, labels, and `$crate` resolved at the definition site + /// of the macro. This is the same hygiene behavior as `macro_rules`. + pub fn mixed_site() -> Self { + Span::_new(imp::Span::mixed_site()) + } + + /// A span that resolves at the macro definition site. + /// + /// This method is semver exempt and not exposed by default. + #[cfg(procmacro2_semver_exempt)] + #[cfg_attr(docsrs, doc(cfg(procmacro2_semver_exempt)))] + pub fn def_site() -> Self { + Span::_new(imp::Span::def_site()) + } + + /// Creates a new span with the same line/column information as `self` but + /// that resolves symbols as though it were at `other`. + pub fn resolved_at(&self, other: Span) -> Span { + Span::_new(self.inner.resolved_at(other.inner)) + } + + /// Creates a new span with the same name resolution behavior as `self` but + /// with the line/column information of `other`. + pub fn located_at(&self, other: Span) -> Span { + Span::_new(self.inner.located_at(other.inner)) + } + + /// Convert `proc_macro2::Span` to `proc_macro::Span`. + /// + /// This method is available when building with a nightly compiler, or when + /// building with rustc 1.29+ *without* semver exempt features. + /// + /// # Panics + /// + /// Panics if called from outside of a procedural macro. Unlike + /// `proc_macro2::Span`, the `proc_macro::Span` type can only exist within + /// the context of a procedural macro invocation. + #[cfg(wrap_proc_macro)] + pub fn unwrap(self) -> proc_macro::Span { + self.inner.unwrap() + } + + // Soft deprecated. Please use Span::unwrap. + #[cfg(wrap_proc_macro)] + #[doc(hidden)] + pub fn unstable(self) -> proc_macro::Span { + self.unwrap() + } + + /// The original source file into which this span points. + /// + /// This method is semver exempt and not exposed by default. + #[cfg(all(procmacro2_semver_exempt, any(not(wrap_proc_macro), super_unstable)))] + #[cfg_attr(docsrs, doc(cfg(procmacro2_semver_exempt)))] + pub fn source_file(&self) -> SourceFile { + SourceFile::_new(self.inner.source_file()) + } + + /// Returns the span's byte position range in the source file. + /// + /// This method requires the `"span-locations"` feature to be enabled. + /// + /// When executing in a procedural macro context, the returned range is only + /// accurate if compiled with a nightly toolchain. The stable toolchain does + /// not have this information available. When executing outside of a + /// procedural macro, such as main.rs or build.rs, the byte range is always + /// accurate regardless of toolchain. + #[cfg(span_locations)] + #[cfg_attr(docsrs, doc(cfg(feature = "span-locations")))] + pub fn byte_range(&self) -> Range { + self.inner.byte_range() + } + + /// Get the starting line/column in the source file for this span. + /// + /// This method requires the `"span-locations"` feature to be enabled. + /// + /// When executing in a procedural macro context, the returned line/column + /// are only meaningful if compiled with a nightly toolchain. The stable + /// toolchain does not have this information available. When executing + /// outside of a procedural macro, such as main.rs or build.rs, the + /// line/column are always meaningful regardless of toolchain. + #[cfg(span_locations)] + #[cfg_attr(docsrs, doc(cfg(feature = "span-locations")))] + pub fn start(&self) -> LineColumn { + self.inner.start() + } + + /// Get the ending line/column in the source file for this span. + /// + /// This method requires the `"span-locations"` feature to be enabled. + /// + /// When executing in a procedural macro context, the returned line/column + /// are only meaningful if compiled with a nightly toolchain. The stable + /// toolchain does not have this information available. When executing + /// outside of a procedural macro, such as main.rs or build.rs, the + /// line/column are always meaningful regardless of toolchain. + #[cfg(span_locations)] + #[cfg_attr(docsrs, doc(cfg(feature = "span-locations")))] + pub fn end(&self) -> LineColumn { + self.inner.end() + } + + /// Create a new span encompassing `self` and `other`. + /// + /// Returns `None` if `self` and `other` are from different files. + /// + /// Warning: the underlying [`proc_macro::Span::join`] method is + /// nightly-only. When called from within a procedural macro not using a + /// nightly compiler, this method will always return `None`. + /// + /// [`proc_macro::Span::join`]: https://doc.rust-lang.org/proc_macro/struct.Span.html#method.join + pub fn join(&self, other: Span) -> Option { + self.inner.join(other.inner).map(Span::_new) + } + + /// Compares two spans to see if they're equal. + /// + /// This method is semver exempt and not exposed by default. + #[cfg(procmacro2_semver_exempt)] + #[cfg_attr(docsrs, doc(cfg(procmacro2_semver_exempt)))] + pub fn eq(&self, other: &Span) -> bool { + self.inner.eq(&other.inner) + } + + /// Returns the source text behind a span. This preserves the original + /// source code, including spaces and comments. It only returns a result if + /// the span corresponds to real source code. + /// + /// Note: The observable result of a macro should only rely on the tokens + /// and not on this source text. The result of this function is a best + /// effort to be used for diagnostics only. + pub fn source_text(&self) -> Option { + self.inner.source_text() + } +} + +/// Prints a span in a form convenient for debugging. +impl Debug for Span { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + Debug::fmt(&self.inner, f) + } +} + +/// A single token or a delimited sequence of token trees (e.g. `[1, (), ..]`). +#[derive(Clone)] +pub enum TokenTree { + /// A token stream surrounded by bracket delimiters. + Group(Group), + /// An identifier. + Ident(Ident), + /// A single punctuation character (`+`, `,`, `$`, etc.). + Punct(Punct), + /// A literal character (`'a'`), string (`"hello"`), number (`2.3`), etc. + Literal(Literal), +} + +impl TokenTree { + /// Returns the span of this tree, delegating to the `span` method of + /// the contained token or a delimited stream. + pub fn span(&self) -> Span { + match self { + TokenTree::Group(t) => t.span(), + TokenTree::Ident(t) => t.span(), + TokenTree::Punct(t) => t.span(), + TokenTree::Literal(t) => t.span(), + } + } + + /// Configures the span for *only this token*. + /// + /// Note that if this token is a `Group` then this method will not configure + /// the span of each of the internal tokens, this will simply delegate to + /// the `set_span` method of each variant. + pub fn set_span(&mut self, span: Span) { + match self { + TokenTree::Group(t) => t.set_span(span), + TokenTree::Ident(t) => t.set_span(span), + TokenTree::Punct(t) => t.set_span(span), + TokenTree::Literal(t) => t.set_span(span), + } + } +} + +impl From for TokenTree { + fn from(g: Group) -> Self { + TokenTree::Group(g) + } +} + +impl From for TokenTree { + fn from(g: Ident) -> Self { + TokenTree::Ident(g) + } +} + +impl From for TokenTree { + fn from(g: Punct) -> Self { + TokenTree::Punct(g) + } +} + +impl From for TokenTree { + fn from(g: Literal) -> Self { + TokenTree::Literal(g) + } +} + +/// Prints the token tree as a string that is supposed to be losslessly +/// convertible back into the same token tree (modulo spans), except for +/// possibly `TokenTree::Group`s with `Delimiter::None` delimiters and negative +/// numeric literals. +impl Display for TokenTree { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match self { + TokenTree::Group(t) => Display::fmt(t, f), + TokenTree::Ident(t) => Display::fmt(t, f), + TokenTree::Punct(t) => Display::fmt(t, f), + TokenTree::Literal(t) => Display::fmt(t, f), + } + } +} + +/// Prints token tree in a form convenient for debugging. +impl Debug for TokenTree { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + // Each of these has the name in the struct type in the derived debug, + // so don't bother with an extra layer of indirection + match self { + TokenTree::Group(t) => Debug::fmt(t, f), + TokenTree::Ident(t) => { + let mut debug = f.debug_struct("Ident"); + debug.field("sym", &format_args!("{}", t)); + imp::debug_span_field_if_nontrivial(&mut debug, t.span().inner); + debug.finish() + } + TokenTree::Punct(t) => Debug::fmt(t, f), + TokenTree::Literal(t) => Debug::fmt(t, f), + } + } +} + +/// A delimited token stream. +/// +/// A `Group` internally contains a `TokenStream` which is surrounded by +/// `Delimiter`s. +#[derive(Clone)] +pub struct Group { + inner: imp::Group, +} + +/// Describes how a sequence of token trees is delimited. +#[derive(Copy, Clone, Debug, Eq, PartialEq)] +pub enum Delimiter { + /// `( ... )` + Parenthesis, + /// `{ ... }` + Brace, + /// `[ ... ]` + Bracket, + /// `∅ ... ∅` + /// + /// An invisible delimiter, that may, for example, appear around tokens + /// coming from a "macro variable" `$var`. It is important to preserve + /// operator priorities in cases like `$var * 3` where `$var` is `1 + 2`. + /// Invisible delimiters may not survive roundtrip of a token stream through + /// a string. + /// + ///
+ /// + /// Note: rustc currently can ignore the grouping of tokens delimited by `None` in the output + /// of a proc_macro. Only `None`-delimited groups created by a macro_rules macro in the input + /// of a proc_macro macro are preserved, and only in very specific circumstances. + /// Any `None`-delimited groups (re)created by a proc_macro will therefore not preserve + /// operator priorities as indicated above. The other `Delimiter` variants should be used + /// instead in this context. This is a rustc bug. For details, see + /// [rust-lang/rust#67062](https://github.com/rust-lang/rust/issues/67062). + /// + ///
+ None, +} + +impl Group { + fn _new(inner: imp::Group) -> Self { + Group { inner } + } + + fn _new_fallback(inner: fallback::Group) -> Self { + Group { + inner: inner.into(), + } + } + + /// Creates a new `Group` with the given delimiter and token stream. + /// + /// This constructor will set the span for this group to + /// `Span::call_site()`. To change the span you can use the `set_span` + /// method below. + pub fn new(delimiter: Delimiter, stream: TokenStream) -> Self { + Group { + inner: imp::Group::new(delimiter, stream.inner), + } + } + + /// Returns the punctuation used as the delimiter for this group: a set of + /// parentheses, square brackets, or curly braces. + pub fn delimiter(&self) -> Delimiter { + self.inner.delimiter() + } + + /// Returns the `TokenStream` of tokens that are delimited in this `Group`. + /// + /// Note that the returned token stream does not include the delimiter + /// returned above. + pub fn stream(&self) -> TokenStream { + TokenStream::_new(self.inner.stream()) + } + + /// Returns the span for the delimiters of this token stream, spanning the + /// entire `Group`. + /// + /// ```text + /// pub fn span(&self) -> Span { + /// ^^^^^^^ + /// ``` + pub fn span(&self) -> Span { + Span::_new(self.inner.span()) + } + + /// Returns the span pointing to the opening delimiter of this group. + /// + /// ```text + /// pub fn span_open(&self) -> Span { + /// ^ + /// ``` + pub fn span_open(&self) -> Span { + Span::_new(self.inner.span_open()) + } + + /// Returns the span pointing to the closing delimiter of this group. + /// + /// ```text + /// pub fn span_close(&self) -> Span { + /// ^ + /// ``` + pub fn span_close(&self) -> Span { + Span::_new(self.inner.span_close()) + } + + /// Returns an object that holds this group's `span_open()` and + /// `span_close()` together (in a more compact representation than holding + /// those 2 spans individually). + pub fn delim_span(&self) -> DelimSpan { + DelimSpan::new(&self.inner) + } + + /// Configures the span for this `Group`'s delimiters, but not its internal + /// tokens. + /// + /// This method will **not** set the span of all the internal tokens spanned + /// by this group, but rather it will only set the span of the delimiter + /// tokens at the level of the `Group`. + pub fn set_span(&mut self, span: Span) { + self.inner.set_span(span.inner); + } +} + +/// Prints the group as a string that should be losslessly convertible back +/// into the same group (modulo spans), except for possibly `TokenTree::Group`s +/// with `Delimiter::None` delimiters. +impl Display for Group { + fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + Display::fmt(&self.inner, formatter) + } +} + +impl Debug for Group { + fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + Debug::fmt(&self.inner, formatter) + } +} + +/// A `Punct` is a single punctuation character like `+`, `-` or `#`. +/// +/// Multicharacter operators like `+=` are represented as two instances of +/// `Punct` with different forms of `Spacing` returned. +#[derive(Clone)] +pub struct Punct { + ch: char, + spacing: Spacing, + span: Span, +} + +/// Whether a `Punct` is followed immediately by another `Punct` or followed by +/// another token or whitespace. +#[derive(Copy, Clone, Debug, Eq, PartialEq)] +pub enum Spacing { + /// E.g. `+` is `Alone` in `+ =`, `+ident` or `+()`. + Alone, + /// E.g. `+` is `Joint` in `+=` or `'` is `Joint` in `'#`. + /// + /// Additionally, single quote `'` can join with identifiers to form + /// lifetimes `'ident`. + Joint, +} + +impl Punct { + /// Creates a new `Punct` from the given character and spacing. + /// + /// The `ch` argument must be a valid punctuation character permitted by the + /// language, otherwise the function will panic. + /// + /// The returned `Punct` will have the default span of `Span::call_site()` + /// which can be further configured with the `set_span` method below. + pub fn new(ch: char, spacing: Spacing) -> Self { + if let '!' | '#' | '$' | '%' | '&' | '\'' | '*' | '+' | ',' | '-' | '.' | '/' | ':' | ';' + | '<' | '=' | '>' | '?' | '@' | '^' | '|' | '~' = ch + { + Punct { + ch, + spacing, + span: Span::call_site(), + } + } else { + panic!("unsupported proc macro punctuation character {:?}", ch); + } + } + + /// Returns the value of this punctuation character as `char`. + pub fn as_char(&self) -> char { + self.ch + } + + /// Returns the spacing of this punctuation character, indicating whether + /// it's immediately followed by another `Punct` in the token stream, so + /// they can potentially be combined into a multicharacter operator + /// (`Joint`), or it's followed by some other token or whitespace (`Alone`) + /// so the operator has certainly ended. + pub fn spacing(&self) -> Spacing { + self.spacing + } + + /// Returns the span for this punctuation character. + pub fn span(&self) -> Span { + self.span + } + + /// Configure the span for this punctuation character. + pub fn set_span(&mut self, span: Span) { + self.span = span; + } +} + +/// Prints the punctuation character as a string that should be losslessly +/// convertible back into the same character. +impl Display for Punct { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + Display::fmt(&self.ch, f) + } +} + +impl Debug for Punct { + fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { + let mut debug = fmt.debug_struct("Punct"); + debug.field("char", &self.ch); + debug.field("spacing", &self.spacing); + imp::debug_span_field_if_nontrivial(&mut debug, self.span.inner); + debug.finish() + } +} + +/// A word of Rust code, which may be a keyword or legal variable name. +/// +/// An identifier consists of at least one Unicode code point, the first of +/// which has the XID_Start property and the rest of which have the XID_Continue +/// property. +/// +/// - The empty string is not an identifier. Use `Option`. +/// - A lifetime is not an identifier. Use `syn::Lifetime` instead. +/// +/// An identifier constructed with `Ident::new` is permitted to be a Rust +/// keyword, though parsing one through its [`Parse`] implementation rejects +/// Rust keywords. Use `input.call(Ident::parse_any)` when parsing to match the +/// behaviour of `Ident::new`. +/// +/// [`Parse`]: https://docs.rs/syn/2.0/syn/parse/trait.Parse.html +/// +/// # Examples +/// +/// A new ident can be created from a string using the `Ident::new` function. +/// A span must be provided explicitly which governs the name resolution +/// behavior of the resulting identifier. +/// +/// ``` +/// use proc_macro2::{Ident, Span}; +/// +/// fn main() { +/// let call_ident = Ident::new("calligraphy", Span::call_site()); +/// +/// println!("{}", call_ident); +/// } +/// ``` +/// +/// An ident can be interpolated into a token stream using the `quote!` macro. +/// +/// ``` +/// use proc_macro2::{Ident, Span}; +/// use quote::quote; +/// +/// fn main() { +/// let ident = Ident::new("demo", Span::call_site()); +/// +/// // Create a variable binding whose name is this ident. +/// let expanded = quote! { let #ident = 10; }; +/// +/// // Create a variable binding with a slightly different name. +/// let temp_ident = Ident::new(&format!("new_{}", ident), Span::call_site()); +/// let expanded = quote! { let #temp_ident = 10; }; +/// } +/// ``` +/// +/// A string representation of the ident is available through the `to_string()` +/// method. +/// +/// ``` +/// # use proc_macro2::{Ident, Span}; +/// # +/// # let ident = Ident::new("another_identifier", Span::call_site()); +/// # +/// // Examine the ident as a string. +/// let ident_string = ident.to_string(); +/// if ident_string.len() > 60 { +/// println!("Very long identifier: {}", ident_string) +/// } +/// ``` +#[derive(Clone)] +pub struct Ident { + inner: imp::Ident, + _marker: ProcMacroAutoTraits, +} + +impl Ident { + fn _new(inner: imp::Ident) -> Self { + Ident { + inner, + _marker: MARKER, + } + } + + /// Creates a new `Ident` with the given `string` as well as the specified + /// `span`. + /// + /// The `string` argument must be a valid identifier permitted by the + /// language, otherwise the function will panic. + /// + /// Note that `span`, currently in rustc, configures the hygiene information + /// for this identifier. + /// + /// As of this time `Span::call_site()` explicitly opts-in to "call-site" + /// hygiene meaning that identifiers created with this span will be resolved + /// as if they were written directly at the location of the macro call, and + /// other code at the macro call site will be able to refer to them as well. + /// + /// Later spans like `Span::def_site()` will allow to opt-in to + /// "definition-site" hygiene meaning that identifiers created with this + /// span will be resolved at the location of the macro definition and other + /// code at the macro call site will not be able to refer to them. + /// + /// Due to the current importance of hygiene this constructor, unlike other + /// tokens, requires a `Span` to be specified at construction. + /// + /// # Panics + /// + /// Panics if the input string is neither a keyword nor a legal variable + /// name. If you are not sure whether the string contains an identifier and + /// need to handle an error case, use + /// syn::parse_str::<Ident> + /// rather than `Ident::new`. + #[track_caller] + pub fn new(string: &str, span: Span) -> Self { + Ident::_new(imp::Ident::new_checked(string, span.inner)) + } + + /// Same as `Ident::new`, but creates a raw identifier (`r#ident`). The + /// `string` argument must be a valid identifier permitted by the language + /// (including keywords, e.g. `fn`). Keywords which are usable in path + /// segments (e.g. `self`, `super`) are not supported, and will cause a + /// panic. + #[track_caller] + pub fn new_raw(string: &str, span: Span) -> Self { + Ident::_new(imp::Ident::new_raw_checked(string, span.inner)) + } + + /// Returns the span of this `Ident`. + pub fn span(&self) -> Span { + Span::_new(self.inner.span()) + } + + /// Configures the span of this `Ident`, possibly changing its hygiene + /// context. + pub fn set_span(&mut self, span: Span) { + self.inner.set_span(span.inner); + } +} + +impl PartialEq for Ident { + fn eq(&self, other: &Ident) -> bool { + self.inner == other.inner + } +} + +impl PartialEq for Ident +where + T: ?Sized + AsRef, +{ + fn eq(&self, other: &T) -> bool { + self.inner == other + } +} + +impl Eq for Ident {} + +impl PartialOrd for Ident { + fn partial_cmp(&self, other: &Ident) -> Option { + Some(self.cmp(other)) + } +} + +impl Ord for Ident { + fn cmp(&self, other: &Ident) -> Ordering { + self.to_string().cmp(&other.to_string()) + } +} + +impl Hash for Ident { + fn hash(&self, hasher: &mut H) { + self.to_string().hash(hasher); + } +} + +/// Prints the identifier as a string that should be losslessly convertible back +/// into the same identifier. +impl Display for Ident { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + Display::fmt(&self.inner, f) + } +} + +impl Debug for Ident { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + Debug::fmt(&self.inner, f) + } +} + +/// A literal string (`"hello"`), byte string (`b"hello"`), character (`'a'`), +/// byte character (`b'a'`), an integer or floating point number with or without +/// a suffix (`1`, `1u8`, `2.3`, `2.3f32`). +/// +/// Boolean literals like `true` and `false` do not belong here, they are +/// `Ident`s. +#[derive(Clone)] +pub struct Literal { + inner: imp::Literal, + _marker: ProcMacroAutoTraits, +} + +macro_rules! suffixed_int_literals { + ($($name:ident => $kind:ident,)*) => ($( + /// Creates a new suffixed integer literal with the specified value. + /// + /// This function will create an integer like `1u32` where the integer + /// value specified is the first part of the token and the integral is + /// also suffixed at the end. Literals created from negative numbers may + /// not survive roundtrips through `TokenStream` or strings and may be + /// broken into two tokens (`-` and positive literal). + /// + /// Literals created through this method have the `Span::call_site()` + /// span by default, which can be configured with the `set_span` method + /// below. + pub fn $name(n: $kind) -> Literal { + Literal::_new(imp::Literal::$name(n)) + } + )*) +} + +macro_rules! unsuffixed_int_literals { + ($($name:ident => $kind:ident,)*) => ($( + /// Creates a new unsuffixed integer literal with the specified value. + /// + /// This function will create an integer like `1` where the integer + /// value specified is the first part of the token. No suffix is + /// specified on this token, meaning that invocations like + /// `Literal::i8_unsuffixed(1)` are equivalent to + /// `Literal::u32_unsuffixed(1)`. Literals created from negative numbers + /// may not survive roundtrips through `TokenStream` or strings and may + /// be broken into two tokens (`-` and positive literal). + /// + /// Literals created through this method have the `Span::call_site()` + /// span by default, which can be configured with the `set_span` method + /// below. + pub fn $name(n: $kind) -> Literal { + Literal::_new(imp::Literal::$name(n)) + } + )*) +} + +impl Literal { + fn _new(inner: imp::Literal) -> Self { + Literal { + inner, + _marker: MARKER, + } + } + + fn _new_fallback(inner: fallback::Literal) -> Self { + Literal { + inner: inner.into(), + _marker: MARKER, + } + } + + suffixed_int_literals! { + u8_suffixed => u8, + u16_suffixed => u16, + u32_suffixed => u32, + u64_suffixed => u64, + u128_suffixed => u128, + usize_suffixed => usize, + i8_suffixed => i8, + i16_suffixed => i16, + i32_suffixed => i32, + i64_suffixed => i64, + i128_suffixed => i128, + isize_suffixed => isize, + } + + unsuffixed_int_literals! { + u8_unsuffixed => u8, + u16_unsuffixed => u16, + u32_unsuffixed => u32, + u64_unsuffixed => u64, + u128_unsuffixed => u128, + usize_unsuffixed => usize, + i8_unsuffixed => i8, + i16_unsuffixed => i16, + i32_unsuffixed => i32, + i64_unsuffixed => i64, + i128_unsuffixed => i128, + isize_unsuffixed => isize, + } + + /// Creates a new unsuffixed floating-point literal. + /// + /// This constructor is similar to those like `Literal::i8_unsuffixed` where + /// the float's value is emitted directly into the token but no suffix is + /// used, so it may be inferred to be a `f64` later in the compiler. + /// Literals created from negative numbers may not survive round-trips + /// through `TokenStream` or strings and may be broken into two tokens (`-` + /// and positive literal). + /// + /// # Panics + /// + /// This function requires that the specified float is finite, for example + /// if it is infinity or NaN this function will panic. + pub fn f64_unsuffixed(f: f64) -> Literal { + assert!(f.is_finite()); + Literal::_new(imp::Literal::f64_unsuffixed(f)) + } + + /// Creates a new suffixed floating-point literal. + /// + /// This constructor will create a literal like `1.0f64` where the value + /// specified is the preceding part of the token and `f64` is the suffix of + /// the token. This token will always be inferred to be an `f64` in the + /// compiler. Literals created from negative numbers may not survive + /// round-trips through `TokenStream` or strings and may be broken into two + /// tokens (`-` and positive literal). + /// + /// # Panics + /// + /// This function requires that the specified float is finite, for example + /// if it is infinity or NaN this function will panic. + pub fn f64_suffixed(f: f64) -> Literal { + assert!(f.is_finite()); + Literal::_new(imp::Literal::f64_suffixed(f)) + } + + /// Creates a new unsuffixed floating-point literal. + /// + /// This constructor is similar to those like `Literal::i8_unsuffixed` where + /// the float's value is emitted directly into the token but no suffix is + /// used, so it may be inferred to be a `f64` later in the compiler. + /// Literals created from negative numbers may not survive round-trips + /// through `TokenStream` or strings and may be broken into two tokens (`-` + /// and positive literal). + /// + /// # Panics + /// + /// This function requires that the specified float is finite, for example + /// if it is infinity or NaN this function will panic. + pub fn f32_unsuffixed(f: f32) -> Literal { + assert!(f.is_finite()); + Literal::_new(imp::Literal::f32_unsuffixed(f)) + } + + /// Creates a new suffixed floating-point literal. + /// + /// This constructor will create a literal like `1.0f32` where the value + /// specified is the preceding part of the token and `f32` is the suffix of + /// the token. This token will always be inferred to be an `f32` in the + /// compiler. Literals created from negative numbers may not survive + /// round-trips through `TokenStream` or strings and may be broken into two + /// tokens (`-` and positive literal). + /// + /// # Panics + /// + /// This function requires that the specified float is finite, for example + /// if it is infinity or NaN this function will panic. + pub fn f32_suffixed(f: f32) -> Literal { + assert!(f.is_finite()); + Literal::_new(imp::Literal::f32_suffixed(f)) + } + + /// String literal. + pub fn string(string: &str) -> Literal { + Literal::_new(imp::Literal::string(string)) + } + + /// Character literal. + pub fn character(ch: char) -> Literal { + Literal::_new(imp::Literal::character(ch)) + } + + /// Byte character literal. + pub fn byte_character(byte: u8) -> Literal { + Literal::_new(imp::Literal::byte_character(byte)) + } + + /// Byte string literal. + pub fn byte_string(bytes: &[u8]) -> Literal { + Literal::_new(imp::Literal::byte_string(bytes)) + } + + /// C string literal. + pub fn c_string(string: &CStr) -> Literal { + Literal::_new(imp::Literal::c_string(string)) + } + + /// Returns the span encompassing this literal. + pub fn span(&self) -> Span { + Span::_new(self.inner.span()) + } + + /// Configures the span associated for this literal. + pub fn set_span(&mut self, span: Span) { + self.inner.set_span(span.inner); + } + + /// Returns a `Span` that is a subset of `self.span()` containing only + /// the source bytes in range `range`. Returns `None` if the would-be + /// trimmed span is outside the bounds of `self`. + /// + /// Warning: the underlying [`proc_macro::Literal::subspan`] method is + /// nightly-only. When called from within a procedural macro not using a + /// nightly compiler, this method will always return `None`. + /// + /// [`proc_macro::Literal::subspan`]: https://doc.rust-lang.org/proc_macro/struct.Literal.html#method.subspan + pub fn subspan>(&self, range: R) -> Option { + self.inner.subspan(range).map(Span::_new) + } + + // Intended for the `quote!` macro to use when constructing a proc-macro2 + // token out of a macro_rules $:literal token, which is already known to be + // a valid literal. This avoids reparsing/validating the literal's string + // representation. This is not public API other than for quote. + #[doc(hidden)] + pub unsafe fn from_str_unchecked(repr: &str) -> Self { + Literal::_new(unsafe { imp::Literal::from_str_unchecked(repr) }) + } +} + +impl FromStr for Literal { + type Err = LexError; + + fn from_str(repr: &str) -> Result { + repr.parse().map(Literal::_new).map_err(|inner| LexError { + inner, + _marker: MARKER, + }) + } +} + +impl Debug for Literal { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + Debug::fmt(&self.inner, f) + } +} + +impl Display for Literal { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + Display::fmt(&self.inner, f) + } +} + +/// Public implementation details for the `TokenStream` type, such as iterators. +pub mod token_stream { + use crate::marker::{ProcMacroAutoTraits, MARKER}; + use crate::{imp, TokenTree}; + use core::fmt::{self, Debug}; + + pub use crate::TokenStream; + + /// An iterator over `TokenStream`'s `TokenTree`s. + /// + /// The iteration is "shallow", e.g. the iterator doesn't recurse into + /// delimited groups, and returns whole groups as token trees. + #[derive(Clone)] + pub struct IntoIter { + inner: imp::TokenTreeIter, + _marker: ProcMacroAutoTraits, + } + + impl Iterator for IntoIter { + type Item = TokenTree; + + fn next(&mut self) -> Option { + self.inner.next() + } + + fn size_hint(&self) -> (usize, Option) { + self.inner.size_hint() + } + } + + impl Debug for IntoIter { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.write_str("TokenStream ")?; + f.debug_list().entries(self.clone()).finish() + } + } + + impl IntoIterator for TokenStream { + type Item = TokenTree; + type IntoIter = IntoIter; + + fn into_iter(self) -> IntoIter { + IntoIter { + inner: self.inner.into_iter(), + _marker: MARKER, + } + } + } +} diff --git a/vendor/proc-macro2/src/location.rs b/vendor/proc-macro2/src/location.rs new file mode 100644 index 0000000..7190e2d --- /dev/null +++ b/vendor/proc-macro2/src/location.rs @@ -0,0 +1,29 @@ +use core::cmp::Ordering; + +/// A line-column pair representing the start or end of a `Span`. +/// +/// This type is semver exempt and not exposed by default. +#[cfg_attr(docsrs, doc(cfg(feature = "span-locations")))] +#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] +pub struct LineColumn { + /// The 1-indexed line in the source file on which the span starts or ends + /// (inclusive). + pub line: usize, + /// The 0-indexed column (in UTF-8 characters) in the source file on which + /// the span starts or ends (inclusive). + pub column: usize, +} + +impl Ord for LineColumn { + fn cmp(&self, other: &Self) -> Ordering { + self.line + .cmp(&other.line) + .then(self.column.cmp(&other.column)) + } +} + +impl PartialOrd for LineColumn { + fn partial_cmp(&self, other: &Self) -> Option { + Some(self.cmp(other)) + } +} diff --git a/vendor/proc-macro2/src/marker.rs b/vendor/proc-macro2/src/marker.rs new file mode 100644 index 0000000..23b94ce --- /dev/null +++ b/vendor/proc-macro2/src/marker.rs @@ -0,0 +1,17 @@ +use alloc::rc::Rc; +use core::marker::PhantomData; +use core::panic::{RefUnwindSafe, UnwindSafe}; + +// Zero sized marker with the correct set of autotrait impls we want all proc +// macro types to have. +#[derive(Copy, Clone)] +#[cfg_attr( + all(procmacro2_semver_exempt, any(not(wrap_proc_macro), super_unstable)), + derive(PartialEq, Eq) +)] +pub(crate) struct ProcMacroAutoTraits(PhantomData>); + +pub(crate) const MARKER: ProcMacroAutoTraits = ProcMacroAutoTraits(PhantomData); + +impl UnwindSafe for ProcMacroAutoTraits {} +impl RefUnwindSafe for ProcMacroAutoTraits {} diff --git a/vendor/proc-macro2/src/parse.rs b/vendor/proc-macro2/src/parse.rs new file mode 100644 index 0000000..07239bc --- /dev/null +++ b/vendor/proc-macro2/src/parse.rs @@ -0,0 +1,996 @@ +use crate::fallback::{ + self, is_ident_continue, is_ident_start, Group, LexError, Literal, Span, TokenStream, + TokenStreamBuilder, +}; +use crate::{Delimiter, Punct, Spacing, TokenTree}; +use core::char; +use core::str::{Bytes, CharIndices, Chars}; + +#[derive(Copy, Clone, Eq, PartialEq)] +pub(crate) struct Cursor<'a> { + pub rest: &'a str, + #[cfg(span_locations)] + pub off: u32, +} + +impl<'a> Cursor<'a> { + pub fn advance(&self, bytes: usize) -> Cursor<'a> { + let (_front, rest) = self.rest.split_at(bytes); + Cursor { + rest, + #[cfg(span_locations)] + off: self.off + _front.chars().count() as u32, + } + } + + pub fn starts_with(&self, s: &str) -> bool { + self.rest.starts_with(s) + } + + pub fn starts_with_char(&self, ch: char) -> bool { + self.rest.starts_with(ch) + } + + pub fn starts_with_fn(&self, f: Pattern) -> bool + where + Pattern: FnMut(char) -> bool, + { + self.rest.starts_with(f) + } + + pub fn is_empty(&self) -> bool { + self.rest.is_empty() + } + + fn len(&self) -> usize { + self.rest.len() + } + + fn as_bytes(&self) -> &'a [u8] { + self.rest.as_bytes() + } + + fn bytes(&self) -> Bytes<'a> { + self.rest.bytes() + } + + fn chars(&self) -> Chars<'a> { + self.rest.chars() + } + + fn char_indices(&self) -> CharIndices<'a> { + self.rest.char_indices() + } + + fn parse(&self, tag: &str) -> Result, Reject> { + if self.starts_with(tag) { + Ok(self.advance(tag.len())) + } else { + Err(Reject) + } + } +} + +pub(crate) struct Reject; +type PResult<'a, O> = Result<(Cursor<'a>, O), Reject>; + +fn skip_whitespace(input: Cursor) -> Cursor { + let mut s = input; + + while !s.is_empty() { + let byte = s.as_bytes()[0]; + if byte == b'/' { + if s.starts_with("//") + && (!s.starts_with("///") || s.starts_with("////")) + && !s.starts_with("//!") + { + let (cursor, _) = take_until_newline_or_eof(s); + s = cursor; + continue; + } else if s.starts_with("/**/") { + s = s.advance(4); + continue; + } else if s.starts_with("/*") + && (!s.starts_with("/**") || s.starts_with("/***")) + && !s.starts_with("/*!") + { + match block_comment(s) { + Ok((rest, _)) => { + s = rest; + continue; + } + Err(Reject) => return s, + } + } + } + match byte { + b' ' | 0x09..=0x0d => { + s = s.advance(1); + continue; + } + b if b.is_ascii() => {} + _ => { + let ch = s.chars().next().unwrap(); + if is_whitespace(ch) { + s = s.advance(ch.len_utf8()); + continue; + } + } + } + return s; + } + s +} + +fn block_comment(input: Cursor) -> PResult<&str> { + if !input.starts_with("/*") { + return Err(Reject); + } + + let mut depth = 0usize; + let bytes = input.as_bytes(); + let mut i = 0usize; + let upper = bytes.len() - 1; + + while i < upper { + if bytes[i] == b'/' && bytes[i + 1] == b'*' { + depth += 1; + i += 1; // eat '*' + } else if bytes[i] == b'*' && bytes[i + 1] == b'/' { + depth -= 1; + if depth == 0 { + return Ok((input.advance(i + 2), &input.rest[..i + 2])); + } + i += 1; // eat '/' + } + i += 1; + } + + Err(Reject) +} + +fn is_whitespace(ch: char) -> bool { + // Rust treats left-to-right mark and right-to-left mark as whitespace + ch.is_whitespace() || ch == '\u{200e}' || ch == '\u{200f}' +} + +fn word_break(input: Cursor) -> Result { + match input.chars().next() { + Some(ch) if is_ident_continue(ch) => Err(Reject), + Some(_) | None => Ok(input), + } +} + +// Rustc's representation of a macro expansion error in expression position or +// type position. +const ERROR: &str = "(/*ERROR*/)"; + +pub(crate) fn token_stream(mut input: Cursor) -> Result { + let mut trees = TokenStreamBuilder::new(); + let mut stack = Vec::new(); + + loop { + input = skip_whitespace(input); + + if let Ok((rest, ())) = doc_comment(input, &mut trees) { + input = rest; + continue; + } + + #[cfg(span_locations)] + let lo = input.off; + + let first = match input.bytes().next() { + Some(first) => first, + None => match stack.last() { + None => return Ok(trees.build()), + #[cfg(span_locations)] + Some((lo, _frame)) => { + return Err(LexError { + span: Span { lo: *lo, hi: *lo }, + }) + } + #[cfg(not(span_locations))] + Some(_frame) => return Err(LexError { span: Span {} }), + }, + }; + + if let Some(open_delimiter) = match first { + b'(' if !input.starts_with(ERROR) => Some(Delimiter::Parenthesis), + b'[' => Some(Delimiter::Bracket), + b'{' => Some(Delimiter::Brace), + _ => None, + } { + input = input.advance(1); + let frame = (open_delimiter, trees); + #[cfg(span_locations)] + let frame = (lo, frame); + stack.push(frame); + trees = TokenStreamBuilder::new(); + } else if let Some(close_delimiter) = match first { + b')' => Some(Delimiter::Parenthesis), + b']' => Some(Delimiter::Bracket), + b'}' => Some(Delimiter::Brace), + _ => None, + } { + let frame = match stack.pop() { + Some(frame) => frame, + None => return Err(lex_error(input)), + }; + #[cfg(span_locations)] + let (lo, frame) = frame; + let (open_delimiter, outer) = frame; + if open_delimiter != close_delimiter { + return Err(lex_error(input)); + } + input = input.advance(1); + let mut g = Group::new(open_delimiter, trees.build()); + g.set_span(Span { + #[cfg(span_locations)] + lo, + #[cfg(span_locations)] + hi: input.off, + }); + trees = outer; + trees.push_token_from_parser(TokenTree::Group(crate::Group::_new_fallback(g))); + } else { + let (rest, mut tt) = match leaf_token(input) { + Ok((rest, tt)) => (rest, tt), + Err(Reject) => return Err(lex_error(input)), + }; + tt.set_span(crate::Span::_new_fallback(Span { + #[cfg(span_locations)] + lo, + #[cfg(span_locations)] + hi: rest.off, + })); + trees.push_token_from_parser(tt); + input = rest; + } + } +} + +fn lex_error(cursor: Cursor) -> LexError { + #[cfg(not(span_locations))] + let _ = cursor; + LexError { + span: Span { + #[cfg(span_locations)] + lo: cursor.off, + #[cfg(span_locations)] + hi: cursor.off, + }, + } +} + +fn leaf_token(input: Cursor) -> PResult { + if let Ok((input, l)) = literal(input) { + // must be parsed before ident + Ok((input, TokenTree::Literal(crate::Literal::_new_fallback(l)))) + } else if let Ok((input, p)) = punct(input) { + Ok((input, TokenTree::Punct(p))) + } else if let Ok((input, i)) = ident(input) { + Ok((input, TokenTree::Ident(i))) + } else if input.starts_with(ERROR) { + let rest = input.advance(ERROR.len()); + let repr = crate::Literal::_new_fallback(Literal::_new(ERROR.to_owned())); + Ok((rest, TokenTree::Literal(repr))) + } else { + Err(Reject) + } +} + +fn ident(input: Cursor) -> PResult { + if [ + "r\"", "r#\"", "r##", "b\"", "b\'", "br\"", "br#", "c\"", "cr\"", "cr#", + ] + .iter() + .any(|prefix| input.starts_with(prefix)) + { + Err(Reject) + } else { + ident_any(input) + } +} + +fn ident_any(input: Cursor) -> PResult { + let raw = input.starts_with("r#"); + let rest = input.advance((raw as usize) << 1); + + let (rest, sym) = ident_not_raw(rest)?; + + if !raw { + let ident = crate::Ident::_new(crate::imp::Ident::new_unchecked( + sym, + fallback::Span::call_site(), + )); + return Ok((rest, ident)); + } + + match sym { + "_" | "super" | "self" | "Self" | "crate" => return Err(Reject), + _ => {} + } + + let ident = crate::Ident::_new(crate::imp::Ident::new_raw_unchecked( + sym, + fallback::Span::call_site(), + )); + Ok((rest, ident)) +} + +fn ident_not_raw(input: Cursor) -> PResult<&str> { + let mut chars = input.char_indices(); + + match chars.next() { + Some((_, ch)) if is_ident_start(ch) => {} + _ => return Err(Reject), + } + + let mut end = input.len(); + for (i, ch) in chars { + if !is_ident_continue(ch) { + end = i; + break; + } + } + + Ok((input.advance(end), &input.rest[..end])) +} + +pub(crate) fn literal(input: Cursor) -> PResult { + let rest = literal_nocapture(input)?; + let end = input.len() - rest.len(); + Ok((rest, Literal::_new(input.rest[..end].to_string()))) +} + +fn literal_nocapture(input: Cursor) -> Result { + if let Ok(ok) = string(input) { + Ok(ok) + } else if let Ok(ok) = byte_string(input) { + Ok(ok) + } else if let Ok(ok) = c_string(input) { + Ok(ok) + } else if let Ok(ok) = byte(input) { + Ok(ok) + } else if let Ok(ok) = character(input) { + Ok(ok) + } else if let Ok(ok) = float(input) { + Ok(ok) + } else if let Ok(ok) = int(input) { + Ok(ok) + } else { + Err(Reject) + } +} + +fn literal_suffix(input: Cursor) -> Cursor { + match ident_not_raw(input) { + Ok((input, _)) => input, + Err(Reject) => input, + } +} + +fn string(input: Cursor) -> Result { + if let Ok(input) = input.parse("\"") { + cooked_string(input) + } else if let Ok(input) = input.parse("r") { + raw_string(input) + } else { + Err(Reject) + } +} + +fn cooked_string(mut input: Cursor) -> Result { + let mut chars = input.char_indices(); + + while let Some((i, ch)) = chars.next() { + match ch { + '"' => { + let input = input.advance(i + 1); + return Ok(literal_suffix(input)); + } + '\r' => match chars.next() { + Some((_, '\n')) => {} + _ => break, + }, + '\\' => match chars.next() { + Some((_, 'x')) => { + backslash_x_char(&mut chars)?; + } + Some((_, 'n' | 'r' | 't' | '\\' | '\'' | '"' | '0')) => {} + Some((_, 'u')) => { + backslash_u(&mut chars)?; + } + Some((newline, ch @ ('\n' | '\r'))) => { + input = input.advance(newline + 1); + trailing_backslash(&mut input, ch as u8)?; + chars = input.char_indices(); + } + _ => break, + }, + _ch => {} + } + } + Err(Reject) +} + +fn raw_string(input: Cursor) -> Result { + let (input, delimiter) = delimiter_of_raw_string(input)?; + let mut bytes = input.bytes().enumerate(); + while let Some((i, byte)) = bytes.next() { + match byte { + b'"' if input.rest[i + 1..].starts_with(delimiter) => { + let rest = input.advance(i + 1 + delimiter.len()); + return Ok(literal_suffix(rest)); + } + b'\r' => match bytes.next() { + Some((_, b'\n')) => {} + _ => break, + }, + _ => {} + } + } + Err(Reject) +} + +fn byte_string(input: Cursor) -> Result { + if let Ok(input) = input.parse("b\"") { + cooked_byte_string(input) + } else if let Ok(input) = input.parse("br") { + raw_byte_string(input) + } else { + Err(Reject) + } +} + +fn cooked_byte_string(mut input: Cursor) -> Result { + let mut bytes = input.bytes().enumerate(); + while let Some((offset, b)) = bytes.next() { + match b { + b'"' => { + let input = input.advance(offset + 1); + return Ok(literal_suffix(input)); + } + b'\r' => match bytes.next() { + Some((_, b'\n')) => {} + _ => break, + }, + b'\\' => match bytes.next() { + Some((_, b'x')) => { + backslash_x_byte(&mut bytes)?; + } + Some((_, b'n' | b'r' | b't' | b'\\' | b'0' | b'\'' | b'"')) => {} + Some((newline, b @ (b'\n' | b'\r'))) => { + input = input.advance(newline + 1); + trailing_backslash(&mut input, b)?; + bytes = input.bytes().enumerate(); + } + _ => break, + }, + b if b.is_ascii() => {} + _ => break, + } + } + Err(Reject) +} + +fn delimiter_of_raw_string(input: Cursor) -> PResult<&str> { + for (i, byte) in input.bytes().enumerate() { + match byte { + b'"' => { + if i > 255 { + // https://github.com/rust-lang/rust/pull/95251 + return Err(Reject); + } + return Ok((input.advance(i + 1), &input.rest[..i])); + } + b'#' => {} + _ => break, + } + } + Err(Reject) +} + +fn raw_byte_string(input: Cursor) -> Result { + let (input, delimiter) = delimiter_of_raw_string(input)?; + let mut bytes = input.bytes().enumerate(); + while let Some((i, byte)) = bytes.next() { + match byte { + b'"' if input.rest[i + 1..].starts_with(delimiter) => { + let rest = input.advance(i + 1 + delimiter.len()); + return Ok(literal_suffix(rest)); + } + b'\r' => match bytes.next() { + Some((_, b'\n')) => {} + _ => break, + }, + other => { + if !other.is_ascii() { + break; + } + } + } + } + Err(Reject) +} + +fn c_string(input: Cursor) -> Result { + if let Ok(input) = input.parse("c\"") { + cooked_c_string(input) + } else if let Ok(input) = input.parse("cr") { + raw_c_string(input) + } else { + Err(Reject) + } +} + +fn raw_c_string(input: Cursor) -> Result { + let (input, delimiter) = delimiter_of_raw_string(input)?; + let mut bytes = input.bytes().enumerate(); + while let Some((i, byte)) = bytes.next() { + match byte { + b'"' if input.rest[i + 1..].starts_with(delimiter) => { + let rest = input.advance(i + 1 + delimiter.len()); + return Ok(literal_suffix(rest)); + } + b'\r' => match bytes.next() { + Some((_, b'\n')) => {} + _ => break, + }, + b'\0' => break, + _ => {} + } + } + Err(Reject) +} + +fn cooked_c_string(mut input: Cursor) -> Result { + let mut chars = input.char_indices(); + + while let Some((i, ch)) = chars.next() { + match ch { + '"' => { + let input = input.advance(i + 1); + return Ok(literal_suffix(input)); + } + '\r' => match chars.next() { + Some((_, '\n')) => {} + _ => break, + }, + '\\' => match chars.next() { + Some((_, 'x')) => { + backslash_x_nonzero(&mut chars)?; + } + Some((_, 'n' | 'r' | 't' | '\\' | '\'' | '"')) => {} + Some((_, 'u')) => { + if backslash_u(&mut chars)? == '\0' { + break; + } + } + Some((newline, ch @ ('\n' | '\r'))) => { + input = input.advance(newline + 1); + trailing_backslash(&mut input, ch as u8)?; + chars = input.char_indices(); + } + _ => break, + }, + '\0' => break, + _ch => {} + } + } + Err(Reject) +} + +fn byte(input: Cursor) -> Result { + let input = input.parse("b'")?; + let mut bytes = input.bytes().enumerate(); + let ok = match bytes.next().map(|(_, b)| b) { + Some(b'\\') => match bytes.next().map(|(_, b)| b) { + Some(b'x') => backslash_x_byte(&mut bytes).is_ok(), + Some(b'n' | b'r' | b't' | b'\\' | b'0' | b'\'' | b'"') => true, + _ => false, + }, + b => b.is_some(), + }; + if !ok { + return Err(Reject); + } + let (offset, _) = bytes.next().ok_or(Reject)?; + if !input.chars().as_str().is_char_boundary(offset) { + return Err(Reject); + } + let input = input.advance(offset).parse("'")?; + Ok(literal_suffix(input)) +} + +fn character(input: Cursor) -> Result { + let input = input.parse("'")?; + let mut chars = input.char_indices(); + let ok = match chars.next().map(|(_, ch)| ch) { + Some('\\') => match chars.next().map(|(_, ch)| ch) { + Some('x') => backslash_x_char(&mut chars).is_ok(), + Some('u') => backslash_u(&mut chars).is_ok(), + Some('n' | 'r' | 't' | '\\' | '0' | '\'' | '"') => true, + _ => false, + }, + ch => ch.is_some(), + }; + if !ok { + return Err(Reject); + } + let (idx, _) = chars.next().ok_or(Reject)?; + let input = input.advance(idx).parse("'")?; + Ok(literal_suffix(input)) +} + +macro_rules! next_ch { + ($chars:ident @ $pat:pat) => { + match $chars.next() { + Some((_, ch)) => match ch { + $pat => ch, + _ => return Err(Reject), + }, + None => return Err(Reject), + } + }; +} + +fn backslash_x_char(chars: &mut I) -> Result<(), Reject> +where + I: Iterator, +{ + next_ch!(chars @ '0'..='7'); + next_ch!(chars @ '0'..='9' | 'a'..='f' | 'A'..='F'); + Ok(()) +} + +fn backslash_x_byte(chars: &mut I) -> Result<(), Reject> +where + I: Iterator, +{ + next_ch!(chars @ b'0'..=b'9' | b'a'..=b'f' | b'A'..=b'F'); + next_ch!(chars @ b'0'..=b'9' | b'a'..=b'f' | b'A'..=b'F'); + Ok(()) +} + +fn backslash_x_nonzero(chars: &mut I) -> Result<(), Reject> +where + I: Iterator, +{ + let first = next_ch!(chars @ '0'..='9' | 'a'..='f' | 'A'..='F'); + let second = next_ch!(chars @ '0'..='9' | 'a'..='f' | 'A'..='F'); + if first == '0' && second == '0' { + Err(Reject) + } else { + Ok(()) + } +} + +fn backslash_u(chars: &mut I) -> Result +where + I: Iterator, +{ + next_ch!(chars @ '{'); + let mut value = 0; + let mut len = 0; + for (_, ch) in chars { + let digit = match ch { + '0'..='9' => ch as u8 - b'0', + 'a'..='f' => 10 + ch as u8 - b'a', + 'A'..='F' => 10 + ch as u8 - b'A', + '_' if len > 0 => continue, + '}' if len > 0 => return char::from_u32(value).ok_or(Reject), + _ => break, + }; + if len == 6 { + break; + } + value *= 0x10; + value += u32::from(digit); + len += 1; + } + Err(Reject) +} + +fn trailing_backslash(input: &mut Cursor, mut last: u8) -> Result<(), Reject> { + let mut whitespace = input.bytes().enumerate(); + loop { + if last == b'\r' && whitespace.next().map_or(true, |(_, b)| b != b'\n') { + return Err(Reject); + } + match whitespace.next() { + Some((_, b @ (b' ' | b'\t' | b'\n' | b'\r'))) => { + last = b; + } + Some((offset, _)) => { + *input = input.advance(offset); + return Ok(()); + } + None => return Err(Reject), + } + } +} + +fn float(input: Cursor) -> Result { + let mut rest = float_digits(input)?; + if let Some(ch) = rest.chars().next() { + if is_ident_start(ch) { + rest = ident_not_raw(rest)?.0; + } + } + word_break(rest) +} + +fn float_digits(input: Cursor) -> Result { + let mut chars = input.chars().peekable(); + match chars.next() { + Some(ch) if '0' <= ch && ch <= '9' => {} + _ => return Err(Reject), + } + + let mut len = 1; + let mut has_dot = false; + let mut has_exp = false; + while let Some(&ch) = chars.peek() { + match ch { + '0'..='9' | '_' => { + chars.next(); + len += 1; + } + '.' => { + if has_dot { + break; + } + chars.next(); + if chars + .peek() + .map_or(false, |&ch| ch == '.' || is_ident_start(ch)) + { + return Err(Reject); + } + len += 1; + has_dot = true; + } + 'e' | 'E' => { + chars.next(); + len += 1; + has_exp = true; + break; + } + _ => break, + } + } + + if !(has_dot || has_exp) { + return Err(Reject); + } + + if has_exp { + let token_before_exp = if has_dot { + Ok(input.advance(len - 1)) + } else { + Err(Reject) + }; + let mut has_sign = false; + let mut has_exp_value = false; + while let Some(&ch) = chars.peek() { + match ch { + '+' | '-' => { + if has_exp_value { + break; + } + if has_sign { + return token_before_exp; + } + chars.next(); + len += 1; + has_sign = true; + } + '0'..='9' => { + chars.next(); + len += 1; + has_exp_value = true; + } + '_' => { + chars.next(); + len += 1; + } + _ => break, + } + } + if !has_exp_value { + return token_before_exp; + } + } + + Ok(input.advance(len)) +} + +fn int(input: Cursor) -> Result { + let mut rest = digits(input)?; + if let Some(ch) = rest.chars().next() { + if is_ident_start(ch) { + rest = ident_not_raw(rest)?.0; + } + } + word_break(rest) +} + +fn digits(mut input: Cursor) -> Result { + let base = if input.starts_with("0x") { + input = input.advance(2); + 16 + } else if input.starts_with("0o") { + input = input.advance(2); + 8 + } else if input.starts_with("0b") { + input = input.advance(2); + 2 + } else { + 10 + }; + + let mut len = 0; + let mut empty = true; + for b in input.bytes() { + match b { + b'0'..=b'9' => { + let digit = (b - b'0') as u64; + if digit >= base { + return Err(Reject); + } + } + b'a'..=b'f' => { + let digit = 10 + (b - b'a') as u64; + if digit >= base { + break; + } + } + b'A'..=b'F' => { + let digit = 10 + (b - b'A') as u64; + if digit >= base { + break; + } + } + b'_' => { + if empty && base == 10 { + return Err(Reject); + } + len += 1; + continue; + } + _ => break, + }; + len += 1; + empty = false; + } + if empty { + Err(Reject) + } else { + Ok(input.advance(len)) + } +} + +fn punct(input: Cursor) -> PResult { + let (rest, ch) = punct_char(input)?; + if ch == '\'' { + if ident_any(rest)?.0.starts_with_char('\'') { + Err(Reject) + } else { + Ok((rest, Punct::new('\'', Spacing::Joint))) + } + } else { + let kind = match punct_char(rest) { + Ok(_) => Spacing::Joint, + Err(Reject) => Spacing::Alone, + }; + Ok((rest, Punct::new(ch, kind))) + } +} + +fn punct_char(input: Cursor) -> PResult { + if input.starts_with("//") || input.starts_with("/*") { + // Do not accept `/` of a comment as a punct. + return Err(Reject); + } + + let mut chars = input.chars(); + let first = match chars.next() { + Some(ch) => ch, + None => { + return Err(Reject); + } + }; + let recognized = "~!@#$%^&*-=+|;:,<.>/?'"; + if recognized.contains(first) { + Ok((input.advance(first.len_utf8()), first)) + } else { + Err(Reject) + } +} + +fn doc_comment<'a>(input: Cursor<'a>, trees: &mut TokenStreamBuilder) -> PResult<'a, ()> { + #[cfg(span_locations)] + let lo = input.off; + let (rest, (comment, inner)) = doc_comment_contents(input)?; + let fallback_span = Span { + #[cfg(span_locations)] + lo, + #[cfg(span_locations)] + hi: rest.off, + }; + let span = crate::Span::_new_fallback(fallback_span); + + let mut scan_for_bare_cr = comment; + while let Some(cr) = scan_for_bare_cr.find('\r') { + let rest = &scan_for_bare_cr[cr + 1..]; + if !rest.starts_with('\n') { + return Err(Reject); + } + scan_for_bare_cr = rest; + } + + let mut pound = Punct::new('#', Spacing::Alone); + pound.set_span(span); + trees.push_token_from_parser(TokenTree::Punct(pound)); + + if inner { + let mut bang = Punct::new('!', Spacing::Alone); + bang.set_span(span); + trees.push_token_from_parser(TokenTree::Punct(bang)); + } + + let doc_ident = crate::Ident::_new(crate::imp::Ident::new_unchecked("doc", fallback_span)); + let mut equal = Punct::new('=', Spacing::Alone); + equal.set_span(span); + let mut literal = crate::Literal::string(comment); + literal.set_span(span); + let mut bracketed = TokenStreamBuilder::with_capacity(3); + bracketed.push_token_from_parser(TokenTree::Ident(doc_ident)); + bracketed.push_token_from_parser(TokenTree::Punct(equal)); + bracketed.push_token_from_parser(TokenTree::Literal(literal)); + let group = Group::new(Delimiter::Bracket, bracketed.build()); + let mut group = crate::Group::_new_fallback(group); + group.set_span(span); + trees.push_token_from_parser(TokenTree::Group(group)); + + Ok((rest, ())) +} + +fn doc_comment_contents(input: Cursor) -> PResult<(&str, bool)> { + if input.starts_with("//!") { + let input = input.advance(3); + let (input, s) = take_until_newline_or_eof(input); + Ok((input, (s, true))) + } else if input.starts_with("/*!") { + let (input, s) = block_comment(input)?; + Ok((input, (&s[3..s.len() - 2], true))) + } else if input.starts_with("///") { + let input = input.advance(3); + if input.starts_with_char('/') { + return Err(Reject); + } + let (input, s) = take_until_newline_or_eof(input); + Ok((input, (s, false))) + } else if input.starts_with("/**") && !input.rest[3..].starts_with('*') { + let (input, s) = block_comment(input)?; + Ok((input, (&s[3..s.len() - 2], false))) + } else { + Err(Reject) + } +} + +fn take_until_newline_or_eof(input: Cursor) -> (Cursor, &str) { + let chars = input.char_indices(); + + for (i, ch) in chars { + if ch == '\n' { + return (input.advance(i), &input.rest[..i]); + } else if ch == '\r' && input.rest[i + 1..].starts_with('\n') { + return (input.advance(i + 1), &input.rest[..i]); + } + } + + (input.advance(input.len()), input.rest) +} diff --git a/vendor/proc-macro2/src/rcvec.rs b/vendor/proc-macro2/src/rcvec.rs new file mode 100644 index 0000000..37955af --- /dev/null +++ b/vendor/proc-macro2/src/rcvec.rs @@ -0,0 +1,145 @@ +use alloc::rc::Rc; +use alloc::vec; +use core::mem; +use core::panic::RefUnwindSafe; +use core::slice; + +pub(crate) struct RcVec { + inner: Rc>, +} + +pub(crate) struct RcVecBuilder { + inner: Vec, +} + +pub(crate) struct RcVecMut<'a, T> { + inner: &'a mut Vec, +} + +#[derive(Clone)] +pub(crate) struct RcVecIntoIter { + inner: vec::IntoIter, +} + +impl RcVec { + pub fn is_empty(&self) -> bool { + self.inner.is_empty() + } + + pub fn len(&self) -> usize { + self.inner.len() + } + + pub fn iter(&self) -> slice::Iter { + self.inner.iter() + } + + pub fn make_mut(&mut self) -> RcVecMut + where + T: Clone, + { + RcVecMut { + inner: Rc::make_mut(&mut self.inner), + } + } + + pub fn get_mut(&mut self) -> Option> { + let inner = Rc::get_mut(&mut self.inner)?; + Some(RcVecMut { inner }) + } + + pub fn make_owned(mut self) -> RcVecBuilder + where + T: Clone, + { + let vec = if let Some(owned) = Rc::get_mut(&mut self.inner) { + mem::take(owned) + } else { + Vec::clone(&self.inner) + }; + RcVecBuilder { inner: vec } + } +} + +impl RcVecBuilder { + pub fn new() -> Self { + RcVecBuilder { inner: Vec::new() } + } + + pub fn with_capacity(cap: usize) -> Self { + RcVecBuilder { + inner: Vec::with_capacity(cap), + } + } + + pub fn push(&mut self, element: T) { + self.inner.push(element); + } + + pub fn extend(&mut self, iter: impl IntoIterator) { + self.inner.extend(iter); + } + + pub fn as_mut(&mut self) -> RcVecMut { + RcVecMut { + inner: &mut self.inner, + } + } + + pub fn build(self) -> RcVec { + RcVec { + inner: Rc::new(self.inner), + } + } +} + +impl<'a, T> RcVecMut<'a, T> { + pub fn push(&mut self, element: T) { + self.inner.push(element); + } + + pub fn extend(&mut self, iter: impl IntoIterator) { + self.inner.extend(iter); + } + + pub fn pop(&mut self) -> Option { + self.inner.pop() + } + + pub fn as_mut(&mut self) -> RcVecMut { + RcVecMut { inner: self.inner } + } +} + +impl Clone for RcVec { + fn clone(&self) -> Self { + RcVec { + inner: Rc::clone(&self.inner), + } + } +} + +impl IntoIterator for RcVecBuilder { + type Item = T; + type IntoIter = RcVecIntoIter; + + fn into_iter(self) -> Self::IntoIter { + RcVecIntoIter { + inner: self.inner.into_iter(), + } + } +} + +impl Iterator for RcVecIntoIter { + type Item = T; + + fn next(&mut self) -> Option { + self.inner.next() + } + + fn size_hint(&self) -> (usize, Option) { + self.inner.size_hint() + } +} + +impl RefUnwindSafe for RcVec where T: RefUnwindSafe {} diff --git a/vendor/proc-macro2/src/wrapper.rs b/vendor/proc-macro2/src/wrapper.rs new file mode 100644 index 0000000..29481c1 --- /dev/null +++ b/vendor/proc-macro2/src/wrapper.rs @@ -0,0 +1,1008 @@ +use crate::detection::inside_proc_macro; +#[cfg(span_locations)] +use crate::location::LineColumn; +use crate::{fallback, Delimiter, Punct, Spacing, TokenTree}; +use core::fmt::{self, Debug, Display}; +#[cfg(span_locations)] +use core::ops::Range; +use core::ops::RangeBounds; +use core::str::FromStr; +use std::ffi::CStr; +use std::panic; +#[cfg(super_unstable)] +use std::path::PathBuf; + +#[derive(Clone)] +pub(crate) enum TokenStream { + Compiler(DeferredTokenStream), + Fallback(fallback::TokenStream), +} + +// Work around https://github.com/rust-lang/rust/issues/65080. +// In `impl Extend for TokenStream` which is used heavily by quote, +// we hold on to the appended tokens and do proc_macro::TokenStream::extend as +// late as possible to batch together consecutive uses of the Extend impl. +#[derive(Clone)] +pub(crate) struct DeferredTokenStream { + stream: proc_macro::TokenStream, + extra: Vec, +} + +pub(crate) enum LexError { + Compiler(proc_macro::LexError), + Fallback(fallback::LexError), + + // Rustc was supposed to return a LexError, but it panicked instead. + // https://github.com/rust-lang/rust/issues/58736 + CompilerPanic, +} + +#[cold] +fn mismatch(line: u32) -> ! { + #[cfg(procmacro2_backtrace)] + { + let backtrace = std::backtrace::Backtrace::force_capture(); + panic!("compiler/fallback mismatch #{}\n\n{}", line, backtrace) + } + #[cfg(not(procmacro2_backtrace))] + { + panic!("compiler/fallback mismatch #{}", line) + } +} + +impl DeferredTokenStream { + fn new(stream: proc_macro::TokenStream) -> Self { + DeferredTokenStream { + stream, + extra: Vec::new(), + } + } + + fn is_empty(&self) -> bool { + self.stream.is_empty() && self.extra.is_empty() + } + + fn evaluate_now(&mut self) { + // If-check provides a fast short circuit for the common case of `extra` + // being empty, which saves a round trip over the proc macro bridge. + // Improves macro expansion time in winrt by 6% in debug mode. + if !self.extra.is_empty() { + self.stream.extend(self.extra.drain(..)); + } + } + + fn into_token_stream(mut self) -> proc_macro::TokenStream { + self.evaluate_now(); + self.stream + } +} + +impl TokenStream { + pub fn new() -> Self { + if inside_proc_macro() { + TokenStream::Compiler(DeferredTokenStream::new(proc_macro::TokenStream::new())) + } else { + TokenStream::Fallback(fallback::TokenStream::new()) + } + } + + pub fn is_empty(&self) -> bool { + match self { + TokenStream::Compiler(tts) => tts.is_empty(), + TokenStream::Fallback(tts) => tts.is_empty(), + } + } + + fn unwrap_nightly(self) -> proc_macro::TokenStream { + match self { + TokenStream::Compiler(s) => s.into_token_stream(), + TokenStream::Fallback(_) => mismatch(line!()), + } + } + + fn unwrap_stable(self) -> fallback::TokenStream { + match self { + TokenStream::Compiler(_) => mismatch(line!()), + TokenStream::Fallback(s) => s, + } + } +} + +impl FromStr for TokenStream { + type Err = LexError; + + fn from_str(src: &str) -> Result { + if inside_proc_macro() { + Ok(TokenStream::Compiler(DeferredTokenStream::new( + proc_macro_parse(src)?, + ))) + } else { + Ok(TokenStream::Fallback(src.parse()?)) + } + } +} + +// Work around https://github.com/rust-lang/rust/issues/58736. +fn proc_macro_parse(src: &str) -> Result { + let result = panic::catch_unwind(|| src.parse().map_err(LexError::Compiler)); + result.unwrap_or_else(|_| Err(LexError::CompilerPanic)) +} + +impl Display for TokenStream { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match self { + TokenStream::Compiler(tts) => Display::fmt(&tts.clone().into_token_stream(), f), + TokenStream::Fallback(tts) => Display::fmt(tts, f), + } + } +} + +impl From for TokenStream { + fn from(inner: proc_macro::TokenStream) -> Self { + TokenStream::Compiler(DeferredTokenStream::new(inner)) + } +} + +impl From for proc_macro::TokenStream { + fn from(inner: TokenStream) -> Self { + match inner { + TokenStream::Compiler(inner) => inner.into_token_stream(), + TokenStream::Fallback(inner) => inner.to_string().parse().unwrap(), + } + } +} + +impl From for TokenStream { + fn from(inner: fallback::TokenStream) -> Self { + TokenStream::Fallback(inner) + } +} + +// Assumes inside_proc_macro(). +fn into_compiler_token(token: TokenTree) -> proc_macro::TokenTree { + match token { + TokenTree::Group(tt) => tt.inner.unwrap_nightly().into(), + TokenTree::Punct(tt) => { + let spacing = match tt.spacing() { + Spacing::Joint => proc_macro::Spacing::Joint, + Spacing::Alone => proc_macro::Spacing::Alone, + }; + let mut punct = proc_macro::Punct::new(tt.as_char(), spacing); + punct.set_span(tt.span().inner.unwrap_nightly()); + punct.into() + } + TokenTree::Ident(tt) => tt.inner.unwrap_nightly().into(), + TokenTree::Literal(tt) => tt.inner.unwrap_nightly().into(), + } +} + +impl From for TokenStream { + fn from(token: TokenTree) -> Self { + if inside_proc_macro() { + TokenStream::Compiler(DeferredTokenStream::new(into_compiler_token(token).into())) + } else { + TokenStream::Fallback(token.into()) + } + } +} + +impl FromIterator for TokenStream { + fn from_iter>(trees: I) -> Self { + if inside_proc_macro() { + TokenStream::Compiler(DeferredTokenStream::new( + trees.into_iter().map(into_compiler_token).collect(), + )) + } else { + TokenStream::Fallback(trees.into_iter().collect()) + } + } +} + +impl FromIterator for TokenStream { + fn from_iter>(streams: I) -> Self { + let mut streams = streams.into_iter(); + match streams.next() { + Some(TokenStream::Compiler(mut first)) => { + first.evaluate_now(); + first.stream.extend(streams.map(|s| match s { + TokenStream::Compiler(s) => s.into_token_stream(), + TokenStream::Fallback(_) => mismatch(line!()), + })); + TokenStream::Compiler(first) + } + Some(TokenStream::Fallback(mut first)) => { + first.extend(streams.map(|s| match s { + TokenStream::Fallback(s) => s, + TokenStream::Compiler(_) => mismatch(line!()), + })); + TokenStream::Fallback(first) + } + None => TokenStream::new(), + } + } +} + +impl Extend for TokenStream { + fn extend>(&mut self, stream: I) { + match self { + TokenStream::Compiler(tts) => { + // Here is the reason for DeferredTokenStream. + for token in stream { + tts.extra.push(into_compiler_token(token)); + } + } + TokenStream::Fallback(tts) => tts.extend(stream), + } + } +} + +impl Extend for TokenStream { + fn extend>(&mut self, streams: I) { + match self { + TokenStream::Compiler(tts) => { + tts.evaluate_now(); + tts.stream + .extend(streams.into_iter().map(TokenStream::unwrap_nightly)); + } + TokenStream::Fallback(tts) => { + tts.extend(streams.into_iter().map(TokenStream::unwrap_stable)); + } + } + } +} + +impl Debug for TokenStream { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match self { + TokenStream::Compiler(tts) => Debug::fmt(&tts.clone().into_token_stream(), f), + TokenStream::Fallback(tts) => Debug::fmt(tts, f), + } + } +} + +impl LexError { + pub(crate) fn span(&self) -> Span { + match self { + LexError::Compiler(_) | LexError::CompilerPanic => Span::call_site(), + LexError::Fallback(e) => Span::Fallback(e.span()), + } + } +} + +impl From for LexError { + fn from(e: proc_macro::LexError) -> Self { + LexError::Compiler(e) + } +} + +impl From for LexError { + fn from(e: fallback::LexError) -> Self { + LexError::Fallback(e) + } +} + +impl Debug for LexError { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match self { + LexError::Compiler(e) => Debug::fmt(e, f), + LexError::Fallback(e) => Debug::fmt(e, f), + LexError::CompilerPanic => { + let fallback = fallback::LexError::call_site(); + Debug::fmt(&fallback, f) + } + } + } +} + +impl Display for LexError { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match self { + LexError::Compiler(e) => Display::fmt(e, f), + LexError::Fallback(e) => Display::fmt(e, f), + LexError::CompilerPanic => { + let fallback = fallback::LexError::call_site(); + Display::fmt(&fallback, f) + } + } + } +} + +#[derive(Clone)] +pub(crate) enum TokenTreeIter { + Compiler(proc_macro::token_stream::IntoIter), + Fallback(fallback::TokenTreeIter), +} + +impl IntoIterator for TokenStream { + type Item = TokenTree; + type IntoIter = TokenTreeIter; + + fn into_iter(self) -> TokenTreeIter { + match self { + TokenStream::Compiler(tts) => { + TokenTreeIter::Compiler(tts.into_token_stream().into_iter()) + } + TokenStream::Fallback(tts) => TokenTreeIter::Fallback(tts.into_iter()), + } + } +} + +impl Iterator for TokenTreeIter { + type Item = TokenTree; + + fn next(&mut self) -> Option { + let token = match self { + TokenTreeIter::Compiler(iter) => iter.next()?, + TokenTreeIter::Fallback(iter) => return iter.next(), + }; + Some(match token { + proc_macro::TokenTree::Group(tt) => crate::Group::_new(Group::Compiler(tt)).into(), + proc_macro::TokenTree::Punct(tt) => { + let spacing = match tt.spacing() { + proc_macro::Spacing::Joint => Spacing::Joint, + proc_macro::Spacing::Alone => Spacing::Alone, + }; + let mut o = Punct::new(tt.as_char(), spacing); + o.set_span(crate::Span::_new(Span::Compiler(tt.span()))); + o.into() + } + proc_macro::TokenTree::Ident(s) => crate::Ident::_new(Ident::Compiler(s)).into(), + proc_macro::TokenTree::Literal(l) => crate::Literal::_new(Literal::Compiler(l)).into(), + }) + } + + fn size_hint(&self) -> (usize, Option) { + match self { + TokenTreeIter::Compiler(tts) => tts.size_hint(), + TokenTreeIter::Fallback(tts) => tts.size_hint(), + } + } +} + +#[derive(Clone, PartialEq, Eq)] +#[cfg(super_unstable)] +pub(crate) enum SourceFile { + Compiler(proc_macro::SourceFile), + Fallback(fallback::SourceFile), +} + +#[cfg(super_unstable)] +impl SourceFile { + fn nightly(sf: proc_macro::SourceFile) -> Self { + SourceFile::Compiler(sf) + } + + /// Get the path to this source file as a string. + pub fn path(&self) -> PathBuf { + match self { + SourceFile::Compiler(a) => a.path(), + SourceFile::Fallback(a) => a.path(), + } + } + + pub fn is_real(&self) -> bool { + match self { + SourceFile::Compiler(a) => a.is_real(), + SourceFile::Fallback(a) => a.is_real(), + } + } +} + +#[cfg(super_unstable)] +impl Debug for SourceFile { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match self { + SourceFile::Compiler(a) => Debug::fmt(a, f), + SourceFile::Fallback(a) => Debug::fmt(a, f), + } + } +} + +#[derive(Copy, Clone)] +pub(crate) enum Span { + Compiler(proc_macro::Span), + Fallback(fallback::Span), +} + +impl Span { + pub fn call_site() -> Self { + if inside_proc_macro() { + Span::Compiler(proc_macro::Span::call_site()) + } else { + Span::Fallback(fallback::Span::call_site()) + } + } + + pub fn mixed_site() -> Self { + if inside_proc_macro() { + Span::Compiler(proc_macro::Span::mixed_site()) + } else { + Span::Fallback(fallback::Span::mixed_site()) + } + } + + #[cfg(super_unstable)] + pub fn def_site() -> Self { + if inside_proc_macro() { + Span::Compiler(proc_macro::Span::def_site()) + } else { + Span::Fallback(fallback::Span::def_site()) + } + } + + pub fn resolved_at(&self, other: Span) -> Span { + match (self, other) { + (Span::Compiler(a), Span::Compiler(b)) => Span::Compiler(a.resolved_at(b)), + (Span::Fallback(a), Span::Fallback(b)) => Span::Fallback(a.resolved_at(b)), + (Span::Compiler(_), Span::Fallback(_)) => mismatch(line!()), + (Span::Fallback(_), Span::Compiler(_)) => mismatch(line!()), + } + } + + pub fn located_at(&self, other: Span) -> Span { + match (self, other) { + (Span::Compiler(a), Span::Compiler(b)) => Span::Compiler(a.located_at(b)), + (Span::Fallback(a), Span::Fallback(b)) => Span::Fallback(a.located_at(b)), + (Span::Compiler(_), Span::Fallback(_)) => mismatch(line!()), + (Span::Fallback(_), Span::Compiler(_)) => mismatch(line!()), + } + } + + pub fn unwrap(self) -> proc_macro::Span { + match self { + Span::Compiler(s) => s, + Span::Fallback(_) => panic!("proc_macro::Span is only available in procedural macros"), + } + } + + #[cfg(super_unstable)] + pub fn source_file(&self) -> SourceFile { + match self { + Span::Compiler(s) => SourceFile::nightly(s.source_file()), + Span::Fallback(s) => SourceFile::Fallback(s.source_file()), + } + } + + #[cfg(span_locations)] + pub fn byte_range(&self) -> Range { + match self { + #[cfg(proc_macro_span)] + Span::Compiler(s) => s.byte_range(), + #[cfg(not(proc_macro_span))] + Span::Compiler(_) => 0..0, + Span::Fallback(s) => s.byte_range(), + } + } + + #[cfg(span_locations)] + pub fn start(&self) -> LineColumn { + match self { + #[cfg(proc_macro_span)] + Span::Compiler(s) => LineColumn { + line: s.line(), + column: s.column().saturating_sub(1), + }, + #[cfg(not(proc_macro_span))] + Span::Compiler(_) => LineColumn { line: 0, column: 0 }, + Span::Fallback(s) => s.start(), + } + } + + #[cfg(span_locations)] + pub fn end(&self) -> LineColumn { + match self { + #[cfg(proc_macro_span)] + Span::Compiler(s) => { + let end = s.end(); + LineColumn { + line: end.line(), + column: end.column().saturating_sub(1), + } + } + #[cfg(not(proc_macro_span))] + Span::Compiler(_) => LineColumn { line: 0, column: 0 }, + Span::Fallback(s) => s.end(), + } + } + + pub fn join(&self, other: Span) -> Option { + let ret = match (self, other) { + #[cfg(proc_macro_span)] + (Span::Compiler(a), Span::Compiler(b)) => Span::Compiler(a.join(b)?), + (Span::Fallback(a), Span::Fallback(b)) => Span::Fallback(a.join(b)?), + _ => return None, + }; + Some(ret) + } + + #[cfg(super_unstable)] + pub fn eq(&self, other: &Span) -> bool { + match (self, other) { + (Span::Compiler(a), Span::Compiler(b)) => a.eq(b), + (Span::Fallback(a), Span::Fallback(b)) => a.eq(b), + _ => false, + } + } + + pub fn source_text(&self) -> Option { + match self { + #[cfg(not(no_source_text))] + Span::Compiler(s) => s.source_text(), + #[cfg(no_source_text)] + Span::Compiler(_) => None, + Span::Fallback(s) => s.source_text(), + } + } + + fn unwrap_nightly(self) -> proc_macro::Span { + match self { + Span::Compiler(s) => s, + Span::Fallback(_) => mismatch(line!()), + } + } +} + +impl From for crate::Span { + fn from(proc_span: proc_macro::Span) -> Self { + crate::Span::_new(Span::Compiler(proc_span)) + } +} + +impl From for Span { + fn from(inner: fallback::Span) -> Self { + Span::Fallback(inner) + } +} + +impl Debug for Span { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match self { + Span::Compiler(s) => Debug::fmt(s, f), + Span::Fallback(s) => Debug::fmt(s, f), + } + } +} + +pub(crate) fn debug_span_field_if_nontrivial(debug: &mut fmt::DebugStruct, span: Span) { + match span { + Span::Compiler(s) => { + debug.field("span", &s); + } + Span::Fallback(s) => fallback::debug_span_field_if_nontrivial(debug, s), + } +} + +#[derive(Clone)] +pub(crate) enum Group { + Compiler(proc_macro::Group), + Fallback(fallback::Group), +} + +impl Group { + pub fn new(delimiter: Delimiter, stream: TokenStream) -> Self { + match stream { + TokenStream::Compiler(tts) => { + let delimiter = match delimiter { + Delimiter::Parenthesis => proc_macro::Delimiter::Parenthesis, + Delimiter::Bracket => proc_macro::Delimiter::Bracket, + Delimiter::Brace => proc_macro::Delimiter::Brace, + Delimiter::None => proc_macro::Delimiter::None, + }; + Group::Compiler(proc_macro::Group::new(delimiter, tts.into_token_stream())) + } + TokenStream::Fallback(stream) => { + Group::Fallback(fallback::Group::new(delimiter, stream)) + } + } + } + + pub fn delimiter(&self) -> Delimiter { + match self { + Group::Compiler(g) => match g.delimiter() { + proc_macro::Delimiter::Parenthesis => Delimiter::Parenthesis, + proc_macro::Delimiter::Bracket => Delimiter::Bracket, + proc_macro::Delimiter::Brace => Delimiter::Brace, + proc_macro::Delimiter::None => Delimiter::None, + }, + Group::Fallback(g) => g.delimiter(), + } + } + + pub fn stream(&self) -> TokenStream { + match self { + Group::Compiler(g) => TokenStream::Compiler(DeferredTokenStream::new(g.stream())), + Group::Fallback(g) => TokenStream::Fallback(g.stream()), + } + } + + pub fn span(&self) -> Span { + match self { + Group::Compiler(g) => Span::Compiler(g.span()), + Group::Fallback(g) => Span::Fallback(g.span()), + } + } + + pub fn span_open(&self) -> Span { + match self { + Group::Compiler(g) => Span::Compiler(g.span_open()), + Group::Fallback(g) => Span::Fallback(g.span_open()), + } + } + + pub fn span_close(&self) -> Span { + match self { + Group::Compiler(g) => Span::Compiler(g.span_close()), + Group::Fallback(g) => Span::Fallback(g.span_close()), + } + } + + pub fn set_span(&mut self, span: Span) { + match (self, span) { + (Group::Compiler(g), Span::Compiler(s)) => g.set_span(s), + (Group::Fallback(g), Span::Fallback(s)) => g.set_span(s), + (Group::Compiler(_), Span::Fallback(_)) => mismatch(line!()), + (Group::Fallback(_), Span::Compiler(_)) => mismatch(line!()), + } + } + + fn unwrap_nightly(self) -> proc_macro::Group { + match self { + Group::Compiler(g) => g, + Group::Fallback(_) => mismatch(line!()), + } + } +} + +impl From for Group { + fn from(g: fallback::Group) -> Self { + Group::Fallback(g) + } +} + +impl Display for Group { + fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + match self { + Group::Compiler(group) => Display::fmt(group, formatter), + Group::Fallback(group) => Display::fmt(group, formatter), + } + } +} + +impl Debug for Group { + fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + match self { + Group::Compiler(group) => Debug::fmt(group, formatter), + Group::Fallback(group) => Debug::fmt(group, formatter), + } + } +} + +#[derive(Clone)] +pub(crate) enum Ident { + Compiler(proc_macro::Ident), + Fallback(fallback::Ident), +} + +impl Ident { + #[track_caller] + pub fn new_checked(string: &str, span: Span) -> Self { + match span { + Span::Compiler(s) => Ident::Compiler(proc_macro::Ident::new(string, s)), + Span::Fallback(s) => Ident::Fallback(fallback::Ident::new_checked(string, s)), + } + } + + pub fn new_unchecked(string: &str, span: fallback::Span) -> Self { + Ident::Fallback(fallback::Ident::new_unchecked(string, span)) + } + + #[track_caller] + pub fn new_raw_checked(string: &str, span: Span) -> Self { + match span { + Span::Compiler(s) => Ident::Compiler(proc_macro::Ident::new_raw(string, s)), + Span::Fallback(s) => Ident::Fallback(fallback::Ident::new_raw_checked(string, s)), + } + } + + pub fn new_raw_unchecked(string: &str, span: fallback::Span) -> Self { + Ident::Fallback(fallback::Ident::new_raw_unchecked(string, span)) + } + + pub fn span(&self) -> Span { + match self { + Ident::Compiler(t) => Span::Compiler(t.span()), + Ident::Fallback(t) => Span::Fallback(t.span()), + } + } + + pub fn set_span(&mut self, span: Span) { + match (self, span) { + (Ident::Compiler(t), Span::Compiler(s)) => t.set_span(s), + (Ident::Fallback(t), Span::Fallback(s)) => t.set_span(s), + (Ident::Compiler(_), Span::Fallback(_)) => mismatch(line!()), + (Ident::Fallback(_), Span::Compiler(_)) => mismatch(line!()), + } + } + + fn unwrap_nightly(self) -> proc_macro::Ident { + match self { + Ident::Compiler(s) => s, + Ident::Fallback(_) => mismatch(line!()), + } + } +} + +impl PartialEq for Ident { + fn eq(&self, other: &Ident) -> bool { + match (self, other) { + (Ident::Compiler(t), Ident::Compiler(o)) => t.to_string() == o.to_string(), + (Ident::Fallback(t), Ident::Fallback(o)) => t == o, + (Ident::Compiler(_), Ident::Fallback(_)) => mismatch(line!()), + (Ident::Fallback(_), Ident::Compiler(_)) => mismatch(line!()), + } + } +} + +impl PartialEq for Ident +where + T: ?Sized + AsRef, +{ + fn eq(&self, other: &T) -> bool { + let other = other.as_ref(); + match self { + Ident::Compiler(t) => t.to_string() == other, + Ident::Fallback(t) => t == other, + } + } +} + +impl Display for Ident { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match self { + Ident::Compiler(t) => Display::fmt(t, f), + Ident::Fallback(t) => Display::fmt(t, f), + } + } +} + +impl Debug for Ident { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match self { + Ident::Compiler(t) => Debug::fmt(t, f), + Ident::Fallback(t) => Debug::fmt(t, f), + } + } +} + +#[derive(Clone)] +pub(crate) enum Literal { + Compiler(proc_macro::Literal), + Fallback(fallback::Literal), +} + +macro_rules! suffixed_numbers { + ($($name:ident => $kind:ident,)*) => ($( + pub fn $name(n: $kind) -> Literal { + if inside_proc_macro() { + Literal::Compiler(proc_macro::Literal::$name(n)) + } else { + Literal::Fallback(fallback::Literal::$name(n)) + } + } + )*) +} + +macro_rules! unsuffixed_integers { + ($($name:ident => $kind:ident,)*) => ($( + pub fn $name(n: $kind) -> Literal { + if inside_proc_macro() { + Literal::Compiler(proc_macro::Literal::$name(n)) + } else { + Literal::Fallback(fallback::Literal::$name(n)) + } + } + )*) +} + +impl Literal { + pub unsafe fn from_str_unchecked(repr: &str) -> Self { + if inside_proc_macro() { + Literal::Compiler(proc_macro::Literal::from_str(repr).expect("invalid literal")) + } else { + Literal::Fallback(unsafe { fallback::Literal::from_str_unchecked(repr) }) + } + } + + suffixed_numbers! { + u8_suffixed => u8, + u16_suffixed => u16, + u32_suffixed => u32, + u64_suffixed => u64, + u128_suffixed => u128, + usize_suffixed => usize, + i8_suffixed => i8, + i16_suffixed => i16, + i32_suffixed => i32, + i64_suffixed => i64, + i128_suffixed => i128, + isize_suffixed => isize, + + f32_suffixed => f32, + f64_suffixed => f64, + } + + unsuffixed_integers! { + u8_unsuffixed => u8, + u16_unsuffixed => u16, + u32_unsuffixed => u32, + u64_unsuffixed => u64, + u128_unsuffixed => u128, + usize_unsuffixed => usize, + i8_unsuffixed => i8, + i16_unsuffixed => i16, + i32_unsuffixed => i32, + i64_unsuffixed => i64, + i128_unsuffixed => i128, + isize_unsuffixed => isize, + } + + pub fn f32_unsuffixed(f: f32) -> Literal { + if inside_proc_macro() { + Literal::Compiler(proc_macro::Literal::f32_unsuffixed(f)) + } else { + Literal::Fallback(fallback::Literal::f32_unsuffixed(f)) + } + } + + pub fn f64_unsuffixed(f: f64) -> Literal { + if inside_proc_macro() { + Literal::Compiler(proc_macro::Literal::f64_unsuffixed(f)) + } else { + Literal::Fallback(fallback::Literal::f64_unsuffixed(f)) + } + } + + pub fn string(string: &str) -> Literal { + if inside_proc_macro() { + Literal::Compiler(proc_macro::Literal::string(string)) + } else { + Literal::Fallback(fallback::Literal::string(string)) + } + } + + pub fn character(ch: char) -> Literal { + if inside_proc_macro() { + Literal::Compiler(proc_macro::Literal::character(ch)) + } else { + Literal::Fallback(fallback::Literal::character(ch)) + } + } + + pub fn byte_character(byte: u8) -> Literal { + if inside_proc_macro() { + Literal::Compiler({ + #[cfg(not(no_literal_byte_character))] + { + proc_macro::Literal::byte_character(byte) + } + + #[cfg(no_literal_byte_character)] + { + let fallback = fallback::Literal::byte_character(byte); + fallback.repr.parse::().unwrap() + } + }) + } else { + Literal::Fallback(fallback::Literal::byte_character(byte)) + } + } + + pub fn byte_string(bytes: &[u8]) -> Literal { + if inside_proc_macro() { + Literal::Compiler(proc_macro::Literal::byte_string(bytes)) + } else { + Literal::Fallback(fallback::Literal::byte_string(bytes)) + } + } + + pub fn c_string(string: &CStr) -> Literal { + if inside_proc_macro() { + Literal::Compiler({ + #[cfg(not(no_literal_c_string))] + { + proc_macro::Literal::c_string(string) + } + + #[cfg(no_literal_c_string)] + { + let fallback = fallback::Literal::c_string(string); + fallback.repr.parse::().unwrap() + } + }) + } else { + Literal::Fallback(fallback::Literal::c_string(string)) + } + } + + pub fn span(&self) -> Span { + match self { + Literal::Compiler(lit) => Span::Compiler(lit.span()), + Literal::Fallback(lit) => Span::Fallback(lit.span()), + } + } + + pub fn set_span(&mut self, span: Span) { + match (self, span) { + (Literal::Compiler(lit), Span::Compiler(s)) => lit.set_span(s), + (Literal::Fallback(lit), Span::Fallback(s)) => lit.set_span(s), + (Literal::Compiler(_), Span::Fallback(_)) => mismatch(line!()), + (Literal::Fallback(_), Span::Compiler(_)) => mismatch(line!()), + } + } + + pub fn subspan>(&self, range: R) -> Option { + match self { + #[cfg(proc_macro_span)] + Literal::Compiler(lit) => lit.subspan(range).map(Span::Compiler), + #[cfg(not(proc_macro_span))] + Literal::Compiler(_lit) => None, + Literal::Fallback(lit) => lit.subspan(range).map(Span::Fallback), + } + } + + fn unwrap_nightly(self) -> proc_macro::Literal { + match self { + Literal::Compiler(s) => s, + Literal::Fallback(_) => mismatch(line!()), + } + } +} + +impl From for Literal { + fn from(s: fallback::Literal) -> Self { + Literal::Fallback(s) + } +} + +impl FromStr for Literal { + type Err = LexError; + + fn from_str(repr: &str) -> Result { + if inside_proc_macro() { + let literal = proc_macro::Literal::from_str(repr)?; + Ok(Literal::Compiler(literal)) + } else { + let literal = fallback::Literal::from_str(repr)?; + Ok(Literal::Fallback(literal)) + } + } +} + +impl Display for Literal { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match self { + Literal::Compiler(t) => Display::fmt(t, f), + Literal::Fallback(t) => Display::fmt(t, f), + } + } +} + +impl Debug for Literal { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match self { + Literal::Compiler(t) => Debug::fmt(t, f), + Literal::Fallback(t) => Debug::fmt(t, f), + } + } +} + +#[cfg(span_locations)] +pub(crate) fn invalidate_current_thread_spans() { + if inside_proc_macro() { + panic!( + "proc_macro2::extra::invalidate_current_thread_spans is not available in procedural macros" + ); + } else { + crate::fallback::invalidate_current_thread_spans(); + } +} diff --git a/vendor/proc-macro2/tests/comments.rs b/vendor/proc-macro2/tests/comments.rs new file mode 100644 index 0000000..4f7236d --- /dev/null +++ b/vendor/proc-macro2/tests/comments.rs @@ -0,0 +1,105 @@ +#![allow(clippy::assertions_on_result_states)] + +use proc_macro2::{Delimiter, Literal, Spacing, TokenStream, TokenTree}; + +// #[doc = "..."] -> "..." +fn lit_of_outer_doc_comment(tokens: &TokenStream) -> Literal { + lit_of_doc_comment(tokens, false) +} + +// #![doc = "..."] -> "..." +fn lit_of_inner_doc_comment(tokens: &TokenStream) -> Literal { + lit_of_doc_comment(tokens, true) +} + +fn lit_of_doc_comment(tokens: &TokenStream, inner: bool) -> Literal { + let mut iter = tokens.clone().into_iter(); + match iter.next().unwrap() { + TokenTree::Punct(punct) => { + assert_eq!(punct.as_char(), '#'); + assert_eq!(punct.spacing(), Spacing::Alone); + } + _ => panic!("wrong token {:?}", tokens), + } + if inner { + match iter.next().unwrap() { + TokenTree::Punct(punct) => { + assert_eq!(punct.as_char(), '!'); + assert_eq!(punct.spacing(), Spacing::Alone); + } + _ => panic!("wrong token {:?}", tokens), + } + } + iter = match iter.next().unwrap() { + TokenTree::Group(group) => { + assert_eq!(group.delimiter(), Delimiter::Bracket); + assert!(iter.next().is_none(), "unexpected token {:?}", tokens); + group.stream().into_iter() + } + _ => panic!("wrong token {:?}", tokens), + }; + match iter.next().unwrap() { + TokenTree::Ident(ident) => assert_eq!(ident.to_string(), "doc"), + _ => panic!("wrong token {:?}", tokens), + } + match iter.next().unwrap() { + TokenTree::Punct(punct) => { + assert_eq!(punct.as_char(), '='); + assert_eq!(punct.spacing(), Spacing::Alone); + } + _ => panic!("wrong token {:?}", tokens), + } + match iter.next().unwrap() { + TokenTree::Literal(literal) => { + assert!(iter.next().is_none(), "unexpected token {:?}", tokens); + literal + } + _ => panic!("wrong token {:?}", tokens), + } +} + +#[test] +fn closed_immediately() { + let stream = "/**/".parse::().unwrap(); + let tokens = stream.into_iter().collect::>(); + assert!(tokens.is_empty(), "not empty -- {:?}", tokens); +} + +#[test] +fn incomplete() { + assert!("/*/".parse::().is_err()); +} + +#[test] +fn lit() { + let stream = "/// doc".parse::().unwrap(); + let lit = lit_of_outer_doc_comment(&stream); + assert_eq!(lit.to_string(), "\" doc\""); + + let stream = "//! doc".parse::().unwrap(); + let lit = lit_of_inner_doc_comment(&stream); + assert_eq!(lit.to_string(), "\" doc\""); + + let stream = "/** doc */".parse::().unwrap(); + let lit = lit_of_outer_doc_comment(&stream); + assert_eq!(lit.to_string(), "\" doc \""); + + let stream = "/*! doc */".parse::().unwrap(); + let lit = lit_of_inner_doc_comment(&stream); + assert_eq!(lit.to_string(), "\" doc \""); +} + +#[test] +fn carriage_return() { + let stream = "///\r\n".parse::().unwrap(); + let lit = lit_of_outer_doc_comment(&stream); + assert_eq!(lit.to_string(), "\"\""); + + let stream = "/**\r\n*/".parse::().unwrap(); + let lit = lit_of_outer_doc_comment(&stream); + assert_eq!(lit.to_string(), "\"\\r\\n\""); + + "///\r".parse::().unwrap_err(); + "///\r \n".parse::().unwrap_err(); + "/**\r \n*/".parse::().unwrap_err(); +} diff --git a/vendor/proc-macro2/tests/features.rs b/vendor/proc-macro2/tests/features.rs new file mode 100644 index 0000000..073f6e6 --- /dev/null +++ b/vendor/proc-macro2/tests/features.rs @@ -0,0 +1,8 @@ +#[test] +#[ignore] +fn make_sure_no_proc_macro() { + assert!( + !cfg!(feature = "proc-macro"), + "still compiled with proc_macro?" + ); +} diff --git a/vendor/proc-macro2/tests/marker.rs b/vendor/proc-macro2/tests/marker.rs new file mode 100644 index 0000000..99f64c0 --- /dev/null +++ b/vendor/proc-macro2/tests/marker.rs @@ -0,0 +1,100 @@ +#![allow(clippy::extra_unused_type_parameters)] + +use proc_macro2::{ + Delimiter, Group, Ident, LexError, Literal, Punct, Spacing, Span, TokenStream, TokenTree, +}; + +macro_rules! assert_impl { + ($ty:ident is $($marker:ident) and +) => { + #[test] + #[allow(non_snake_case)] + fn $ty() { + fn assert_implemented() {} + assert_implemented::<$ty>(); + } + }; + + ($ty:ident is not $($marker:ident) or +) => { + #[test] + #[allow(non_snake_case)] + fn $ty() { + $( + { + // Implemented for types that implement $marker. + #[allow(dead_code)] + trait IsNotImplemented { + fn assert_not_implemented() {} + } + impl IsNotImplemented for T {} + + // Implemented for the type being tested. + trait IsImplemented { + fn assert_not_implemented() {} + } + impl IsImplemented for $ty {} + + // If $ty does not implement $marker, there is no ambiguity + // in the following trait method call. + <$ty>::assert_not_implemented(); + } + )+ + } + }; +} + +assert_impl!(Delimiter is Send and Sync); +assert_impl!(Spacing is Send and Sync); + +assert_impl!(Group is not Send or Sync); +assert_impl!(Ident is not Send or Sync); +assert_impl!(LexError is not Send or Sync); +assert_impl!(Literal is not Send or Sync); +assert_impl!(Punct is not Send or Sync); +assert_impl!(Span is not Send or Sync); +assert_impl!(TokenStream is not Send or Sync); +assert_impl!(TokenTree is not Send or Sync); + +#[cfg(procmacro2_semver_exempt)] +mod semver_exempt { + use proc_macro2::{LineColumn, SourceFile}; + + assert_impl!(LineColumn is Send and Sync); + + assert_impl!(SourceFile is not Send or Sync); +} + +mod unwind_safe { + use proc_macro2::{ + Delimiter, Group, Ident, LexError, Literal, Punct, Spacing, Span, TokenStream, TokenTree, + }; + #[cfg(procmacro2_semver_exempt)] + use proc_macro2::{LineColumn, SourceFile}; + use std::panic::{RefUnwindSafe, UnwindSafe}; + + macro_rules! assert_unwind_safe { + ($($types:ident)*) => { + $( + assert_impl!($types is UnwindSafe and RefUnwindSafe); + )* + }; + } + + assert_unwind_safe! { + Delimiter + Group + Ident + LexError + Literal + Punct + Spacing + Span + TokenStream + TokenTree + } + + #[cfg(procmacro2_semver_exempt)] + assert_unwind_safe! { + LineColumn + SourceFile + } +} diff --git a/vendor/proc-macro2/tests/test.rs b/vendor/proc-macro2/tests/test.rs new file mode 100644 index 0000000..0d7c88d --- /dev/null +++ b/vendor/proc-macro2/tests/test.rs @@ -0,0 +1,905 @@ +#![allow( + clippy::assertions_on_result_states, + clippy::items_after_statements, + clippy::needless_pass_by_value, + clippy::needless_raw_string_hashes, + clippy::non_ascii_literal, + clippy::octal_escapes +)] + +use proc_macro2::{Ident, Literal, Punct, Spacing, Span, TokenStream, TokenTree}; +use std::ffi::CStr; +use std::iter; +use std::str::{self, FromStr}; + +#[test] +fn idents() { + assert_eq!( + Ident::new("String", Span::call_site()).to_string(), + "String" + ); + assert_eq!(Ident::new("fn", Span::call_site()).to_string(), "fn"); + assert_eq!(Ident::new("_", Span::call_site()).to_string(), "_"); +} + +#[test] +fn raw_idents() { + assert_eq!( + Ident::new_raw("String", Span::call_site()).to_string(), + "r#String" + ); + assert_eq!(Ident::new_raw("fn", Span::call_site()).to_string(), "r#fn"); +} + +#[test] +#[should_panic(expected = "`r#_` cannot be a raw identifier")] +fn ident_raw_underscore() { + Ident::new_raw("_", Span::call_site()); +} + +#[test] +#[should_panic(expected = "`r#super` cannot be a raw identifier")] +fn ident_raw_reserved() { + Ident::new_raw("super", Span::call_site()); +} + +#[test] +#[should_panic(expected = "Ident is not allowed to be empty; use Option")] +fn ident_empty() { + Ident::new("", Span::call_site()); +} + +#[test] +#[should_panic(expected = "Ident cannot be a number; use Literal instead")] +fn ident_number() { + Ident::new("255", Span::call_site()); +} + +#[test] +#[should_panic(expected = "\"a#\" is not a valid Ident")] +fn ident_invalid() { + Ident::new("a#", Span::call_site()); +} + +#[test] +#[should_panic(expected = "not a valid Ident")] +fn raw_ident_empty() { + Ident::new("r#", Span::call_site()); +} + +#[test] +#[should_panic(expected = "not a valid Ident")] +fn raw_ident_number() { + Ident::new("r#255", Span::call_site()); +} + +#[test] +#[should_panic(expected = "\"r#a#\" is not a valid Ident")] +fn raw_ident_invalid() { + Ident::new("r#a#", Span::call_site()); +} + +#[test] +#[should_panic(expected = "not a valid Ident")] +fn lifetime_empty() { + Ident::new("'", Span::call_site()); +} + +#[test] +#[should_panic(expected = "not a valid Ident")] +fn lifetime_number() { + Ident::new("'255", Span::call_site()); +} + +#[test] +#[should_panic(expected = r#""'a#" is not a valid Ident"#)] +fn lifetime_invalid() { + Ident::new("'a#", Span::call_site()); +} + +#[test] +fn literal_string() { + #[track_caller] + fn assert(literal: Literal, expected: &str) { + assert_eq!(literal.to_string(), expected.trim()); + } + + assert(Literal::string(""), r#" "" "#); + assert(Literal::string("aA"), r#" "aA" "#); + assert(Literal::string("\t"), r#" "\t" "#); + assert(Literal::string("❤"), r#" "❤" "#); + assert(Literal::string("'"), r#" "'" "#); + assert(Literal::string("\""), r#" "\"" "#); + assert(Literal::string("\0"), r#" "\0" "#); + assert(Literal::string("\u{1}"), r#" "\u{1}" "#); + assert( + Literal::string("a\00b\07c\08d\0e\0"), + r#" "a\x000b\x007c\08d\0e\0" "#, + ); + + "\"\\\r\n x\"".parse::().unwrap(); + "\"\\\r\n \rx\"".parse::().unwrap_err(); +} + +#[test] +fn literal_raw_string() { + "r\"\r\n\"".parse::().unwrap(); + + fn raw_string_literal_with_hashes(n: usize) -> String { + let mut literal = String::new(); + literal.push('r'); + literal.extend(iter::repeat('#').take(n)); + literal.push('"'); + literal.push('"'); + literal.extend(iter::repeat('#').take(n)); + literal + } + + raw_string_literal_with_hashes(255) + .parse::() + .unwrap(); + + // https://github.com/rust-lang/rust/pull/95251 + raw_string_literal_with_hashes(256) + .parse::() + .unwrap_err(); +} + +#[test] +fn literal_byte_character() { + #[track_caller] + fn assert(literal: Literal, expected: &str) { + assert_eq!(literal.to_string(), expected.trim()); + } + + assert(Literal::byte_character(b'a'), r#" b'a' "#); + assert(Literal::byte_character(b'\0'), r#" b'\0' "#); + assert(Literal::byte_character(b'\t'), r#" b'\t' "#); + assert(Literal::byte_character(b'\n'), r#" b'\n' "#); + assert(Literal::byte_character(b'\r'), r#" b'\r' "#); + assert(Literal::byte_character(b'\''), r#" b'\'' "#); + assert(Literal::byte_character(b'\\'), r#" b'\\' "#); + assert(Literal::byte_character(b'\x1f'), r#" b'\x1F' "#); + assert(Literal::byte_character(b'"'), r#" b'"' "#); +} + +#[test] +fn literal_byte_string() { + #[track_caller] + fn assert(literal: Literal, expected: &str) { + assert_eq!(literal.to_string(), expected.trim()); + } + + assert(Literal::byte_string(b""), r#" b"" "#); + assert(Literal::byte_string(b"\0"), r#" b"\0" "#); + assert(Literal::byte_string(b"\t"), r#" b"\t" "#); + assert(Literal::byte_string(b"\n"), r#" b"\n" "#); + assert(Literal::byte_string(b"\r"), r#" b"\r" "#); + assert(Literal::byte_string(b"\""), r#" b"\"" "#); + assert(Literal::byte_string(b"\\"), r#" b"\\" "#); + assert(Literal::byte_string(b"\x1f"), r#" b"\x1F" "#); + assert(Literal::byte_string(b"'"), r#" b"'" "#); + assert( + Literal::byte_string(b"a\00b\07c\08d\0e\0"), + r#" b"a\x000b\x007c\08d\0e\0" "#, + ); + + "b\"\\\r\n x\"".parse::().unwrap(); + "b\"\\\r\n \rx\"".parse::().unwrap_err(); + "b\"\\\r\n \u{a0}x\"".parse::().unwrap_err(); + "br\"\u{a0}\"".parse::().unwrap_err(); +} + +#[test] +fn literal_c_string() { + #[track_caller] + fn assert(literal: Literal, expected: &str) { + assert_eq!(literal.to_string(), expected.trim()); + } + + assert(Literal::c_string(<&CStr>::default()), r#" c"" "#); + assert( + Literal::c_string(CStr::from_bytes_with_nul(b"aA\0").unwrap()), + r#" c"aA" "#, + ); + assert( + Literal::c_string(CStr::from_bytes_with_nul(b"aA\0").unwrap()), + r#" c"aA" "#, + ); + assert( + Literal::c_string(CStr::from_bytes_with_nul(b"\t\0").unwrap()), + r#" c"\t" "#, + ); + assert( + Literal::c_string(CStr::from_bytes_with_nul(b"\xE2\x9D\xA4\0").unwrap()), + r#" c"❤" "#, + ); + assert( + Literal::c_string(CStr::from_bytes_with_nul(b"'\0").unwrap()), + r#" c"'" "#, + ); + assert( + Literal::c_string(CStr::from_bytes_with_nul(b"\"\0").unwrap()), + r#" c"\"" "#, + ); + assert( + Literal::c_string(CStr::from_bytes_with_nul(b"\x7F\xFF\xFE\xCC\xB3\0").unwrap()), + r#" c"\u{7f}\xFF\xFE\u{333}" "#, + ); + + let strings = r###" + c"hello\x80我叫\u{1F980}" // from the RFC + cr"\" + cr##"Hello "world"!"## + c"\t\n\r\"\\" + "###; + + let mut tokens = strings.parse::().unwrap().into_iter(); + + for expected in &[ + r#"c"hello\x80我叫\u{1F980}""#, + r#"cr"\""#, + r###"cr##"Hello "world"!"##"###, + r#"c"\t\n\r\"\\""#, + ] { + match tokens.next().unwrap() { + TokenTree::Literal(literal) => { + assert_eq!(literal.to_string(), *expected); + } + unexpected => panic!("unexpected token: {:?}", unexpected), + } + } + + if let Some(unexpected) = tokens.next() { + panic!("unexpected token: {:?}", unexpected); + } + + for invalid in &[r#"c"\0""#, r#"c"\x00""#, r#"c"\u{0}""#, "c\"\0\""] { + if let Ok(unexpected) = invalid.parse::() { + panic!("unexpected token: {:?}", unexpected); + } + } +} + +#[test] +fn literal_character() { + #[track_caller] + fn assert(literal: Literal, expected: &str) { + assert_eq!(literal.to_string(), expected.trim()); + } + + assert(Literal::character('a'), r#" 'a' "#); + assert(Literal::character('\t'), r#" '\t' "#); + assert(Literal::character('❤'), r#" '❤' "#); + assert(Literal::character('\''), r#" '\'' "#); + assert(Literal::character('"'), r#" '"' "#); + assert(Literal::character('\0'), r#" '\0' "#); + assert(Literal::character('\u{1}'), r#" '\u{1}' "#); +} + +#[test] +fn literal_integer() { + #[track_caller] + fn assert(literal: Literal, expected: &str) { + assert_eq!(literal.to_string(), expected); + } + + assert(Literal::u8_suffixed(10), "10u8"); + assert(Literal::u16_suffixed(10), "10u16"); + assert(Literal::u32_suffixed(10), "10u32"); + assert(Literal::u64_suffixed(10), "10u64"); + assert(Literal::u128_suffixed(10), "10u128"); + assert(Literal::usize_suffixed(10), "10usize"); + + assert(Literal::i8_suffixed(10), "10i8"); + assert(Literal::i16_suffixed(10), "10i16"); + assert(Literal::i32_suffixed(10), "10i32"); + assert(Literal::i64_suffixed(10), "10i64"); + assert(Literal::i128_suffixed(10), "10i128"); + assert(Literal::isize_suffixed(10), "10isize"); + + assert(Literal::u8_unsuffixed(10), "10"); + assert(Literal::u16_unsuffixed(10), "10"); + assert(Literal::u32_unsuffixed(10), "10"); + assert(Literal::u64_unsuffixed(10), "10"); + assert(Literal::u128_unsuffixed(10), "10"); + assert(Literal::usize_unsuffixed(10), "10"); + + assert(Literal::i8_unsuffixed(10), "10"); + assert(Literal::i16_unsuffixed(10), "10"); + assert(Literal::i32_unsuffixed(10), "10"); + assert(Literal::i64_unsuffixed(10), "10"); + assert(Literal::i128_unsuffixed(10), "10"); + assert(Literal::isize_unsuffixed(10), "10"); + + assert(Literal::i32_suffixed(-10), "-10i32"); + assert(Literal::i32_unsuffixed(-10), "-10"); +} + +#[test] +fn literal_float() { + #[track_caller] + fn assert(literal: Literal, expected: &str) { + assert_eq!(literal.to_string(), expected); + } + + assert(Literal::f32_suffixed(10.0), "10f32"); + assert(Literal::f32_suffixed(-10.0), "-10f32"); + assert(Literal::f64_suffixed(10.0), "10f64"); + assert(Literal::f64_suffixed(-10.0), "-10f64"); + + assert(Literal::f32_unsuffixed(10.0), "10.0"); + assert(Literal::f32_unsuffixed(-10.0), "-10.0"); + assert(Literal::f64_unsuffixed(10.0), "10.0"); + assert(Literal::f64_unsuffixed(-10.0), "-10.0"); + + assert( + Literal::f64_unsuffixed(1e100), + "10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.0", + ); +} + +#[test] +fn literal_suffix() { + fn token_count(p: &str) -> usize { + p.parse::().unwrap().into_iter().count() + } + + assert_eq!(token_count("999u256"), 1); + assert_eq!(token_count("999r#u256"), 3); + assert_eq!(token_count("1."), 1); + assert_eq!(token_count("1.f32"), 3); + assert_eq!(token_count("1.0_0"), 1); + assert_eq!(token_count("1._0"), 3); + assert_eq!(token_count("1._m"), 3); + assert_eq!(token_count("\"\"s"), 1); + assert_eq!(token_count("r\"\"r"), 1); + assert_eq!(token_count("r#\"\"#r"), 1); + assert_eq!(token_count("b\"\"b"), 1); + assert_eq!(token_count("br\"\"br"), 1); + assert_eq!(token_count("br#\"\"#br"), 1); + assert_eq!(token_count("c\"\"c"), 1); + assert_eq!(token_count("cr\"\"cr"), 1); + assert_eq!(token_count("cr#\"\"#cr"), 1); + assert_eq!(token_count("'c'c"), 1); + assert_eq!(token_count("b'b'b"), 1); + assert_eq!(token_count("0E"), 1); + assert_eq!(token_count("0o0A"), 1); + assert_eq!(token_count("0E--0"), 4); + assert_eq!(token_count("0.0ECMA"), 1); +} + +#[test] +fn literal_iter_negative() { + let negative_literal = Literal::i32_suffixed(-3); + let tokens = TokenStream::from(TokenTree::Literal(negative_literal)); + let mut iter = tokens.into_iter(); + match iter.next().unwrap() { + TokenTree::Punct(punct) => { + assert_eq!(punct.as_char(), '-'); + assert_eq!(punct.spacing(), Spacing::Alone); + } + unexpected => panic!("unexpected token {:?}", unexpected), + } + match iter.next().unwrap() { + TokenTree::Literal(literal) => { + assert_eq!(literal.to_string(), "3i32"); + } + unexpected => panic!("unexpected token {:?}", unexpected), + } + assert!(iter.next().is_none()); +} + +#[test] +fn literal_parse() { + assert!("1".parse::().is_ok()); + assert!("-1".parse::().is_ok()); + assert!("-1u12".parse::().is_ok()); + assert!("1.0".parse::().is_ok()); + assert!("-1.0".parse::().is_ok()); + assert!("-1.0f12".parse::().is_ok()); + assert!("'a'".parse::().is_ok()); + assert!("\"\n\"".parse::().is_ok()); + assert!("0 1".parse::().is_err()); + assert!(" 0".parse::().is_err()); + assert!("0 ".parse::().is_err()); + assert!("/* comment */0".parse::().is_err()); + assert!("0/* comment */".parse::().is_err()); + assert!("0// comment".parse::().is_err()); + assert!("- 1".parse::().is_err()); + assert!("- 1.0".parse::().is_err()); + assert!("-\"\"".parse::().is_err()); +} + +#[test] +fn literal_span() { + let positive = "0.1".parse::().unwrap(); + let negative = "-0.1".parse::().unwrap(); + let subspan = positive.subspan(1..2); + + #[cfg(not(span_locations))] + { + let _ = negative; + assert!(subspan.is_none()); + } + + #[cfg(span_locations)] + { + assert_eq!(positive.span().start().column, 0); + assert_eq!(positive.span().end().column, 3); + assert_eq!(negative.span().start().column, 0); + assert_eq!(negative.span().end().column, 4); + assert_eq!(subspan.unwrap().source_text().unwrap(), "."); + } + + assert!(positive.subspan(1..4).is_none()); +} + +#[cfg(span_locations)] +#[test] +fn source_text() { + let input = " 𓀕 a z "; + let mut tokens = input + .parse::() + .unwrap() + .into_iter(); + + let first = tokens.next().unwrap(); + assert_eq!("𓀕", first.span().source_text().unwrap()); + + let second = tokens.next().unwrap(); + let third = tokens.next().unwrap(); + assert_eq!("z", third.span().source_text().unwrap()); + assert_eq!("a", second.span().source_text().unwrap()); +} + +#[test] +fn roundtrip() { + fn roundtrip(p: &str) { + println!("parse: {}", p); + let s = p.parse::().unwrap().to_string(); + println!("first: {}", s); + let s2 = s.parse::().unwrap().to_string(); + assert_eq!(s, s2); + } + roundtrip("a"); + roundtrip("<<"); + roundtrip("<<="); + roundtrip( + " + 1 + 1.0 + 1f32 + 2f64 + 1usize + 4isize + 4e10 + 1_000 + 1_0i32 + 8u8 + 9 + 0 + 0xffffffffffffffffffffffffffffffff + 1x + 1u80 + 1f320 + ", + ); + roundtrip("'a"); + roundtrip("'_"); + roundtrip("'static"); + roundtrip(r"'\u{10__FFFF}'"); + roundtrip("\"\\u{10_F0FF__}foo\\u{1_0_0_0__}\""); +} + +#[test] +fn fail() { + fn fail(p: &str) { + if let Ok(s) = p.parse::() { + panic!("should have failed to parse: {}\n{:#?}", p, s); + } + } + fail("' static"); + fail("r#1"); + fail("r#_"); + fail("\"\\u{0000000}\""); // overlong unicode escape (rust allows at most 6 hex digits) + fail("\"\\u{999999}\""); // outside of valid range of char + fail("\"\\u{_0}\""); // leading underscore + fail("\"\\u{}\""); // empty + fail("b\"\r\""); // bare carriage return in byte string + fail("r\"\r\""); // bare carriage return in raw string + fail("\"\\\r \""); // backslash carriage return + fail("'aa'aa"); + fail("br##\"\"#"); + fail("cr##\"\"#"); + fail("\"\\\n\u{85}\r\""); +} + +#[cfg(span_locations)] +#[test] +fn span_test() { + check_spans( + "\ +/// This is a document comment +testing 123 +{ + testing 234 +}", + &[ + (1, 0, 1, 30), // # + (1, 0, 1, 30), // [ ... ] + (1, 0, 1, 30), // doc + (1, 0, 1, 30), // = + (1, 0, 1, 30), // "This is..." + (2, 0, 2, 7), // testing + (2, 8, 2, 11), // 123 + (3, 0, 5, 1), // { ... } + (4, 2, 4, 9), // testing + (4, 10, 4, 13), // 234 + ], + ); +} + +#[cfg(procmacro2_semver_exempt)] +#[test] +fn default_span() { + let start = Span::call_site().start(); + assert_eq!(start.line, 1); + assert_eq!(start.column, 0); + let end = Span::call_site().end(); + assert_eq!(end.line, 1); + assert_eq!(end.column, 0); + let source_file = Span::call_site().source_file(); + assert_eq!(source_file.path().to_string_lossy(), ""); + assert!(!source_file.is_real()); +} + +#[cfg(procmacro2_semver_exempt)] +#[test] +fn span_join() { + let source1 = "aaa\nbbb" + .parse::() + .unwrap() + .into_iter() + .collect::>(); + let source2 = "ccc\nddd" + .parse::() + .unwrap() + .into_iter() + .collect::>(); + + assert!(source1[0].span().source_file() != source2[0].span().source_file()); + assert_eq!( + source1[0].span().source_file(), + source1[1].span().source_file() + ); + + let joined1 = source1[0].span().join(source1[1].span()); + let joined2 = source1[0].span().join(source2[0].span()); + assert!(joined1.is_some()); + assert!(joined2.is_none()); + + let start = joined1.unwrap().start(); + let end = joined1.unwrap().end(); + assert_eq!(start.line, 1); + assert_eq!(start.column, 0); + assert_eq!(end.line, 2); + assert_eq!(end.column, 3); + + assert_eq!( + joined1.unwrap().source_file(), + source1[0].span().source_file() + ); +} + +#[test] +fn no_panic() { + let s = str::from_utf8(b"b\'\xc2\x86 \x00\x00\x00^\"").unwrap(); + assert!(s.parse::().is_err()); +} + +#[test] +fn punct_before_comment() { + let mut tts = TokenStream::from_str("~// comment").unwrap().into_iter(); + match tts.next().unwrap() { + TokenTree::Punct(tt) => { + assert_eq!(tt.as_char(), '~'); + assert_eq!(tt.spacing(), Spacing::Alone); + } + wrong => panic!("wrong token {:?}", wrong), + } +} + +#[test] +fn joint_last_token() { + // This test verifies that we match the behavior of libproc_macro *not* in + // the range nightly-2020-09-06 through nightly-2020-09-10, in which this + // behavior was temporarily broken. + // See https://github.com/rust-lang/rust/issues/76399 + + let joint_punct = Punct::new(':', Spacing::Joint); + let stream = TokenStream::from(TokenTree::Punct(joint_punct)); + let punct = match stream.into_iter().next().unwrap() { + TokenTree::Punct(punct) => punct, + _ => unreachable!(), + }; + assert_eq!(punct.spacing(), Spacing::Joint); +} + +#[test] +fn raw_identifier() { + let mut tts = TokenStream::from_str("r#dyn").unwrap().into_iter(); + match tts.next().unwrap() { + TokenTree::Ident(raw) => assert_eq!("r#dyn", raw.to_string()), + wrong => panic!("wrong token {:?}", wrong), + } + assert!(tts.next().is_none()); +} + +#[test] +fn test_debug_ident() { + let ident = Ident::new("proc_macro", Span::call_site()); + + #[cfg(not(span_locations))] + let expected = "Ident(proc_macro)"; + + #[cfg(span_locations)] + let expected = "Ident { sym: proc_macro }"; + + assert_eq!(expected, format!("{:?}", ident)); +} + +#[test] +fn test_debug_tokenstream() { + let tts = TokenStream::from_str("[a + 1]").unwrap(); + + #[cfg(not(span_locations))] + let expected = "\ +TokenStream [ + Group { + delimiter: Bracket, + stream: TokenStream [ + Ident { + sym: a, + }, + Punct { + char: '+', + spacing: Alone, + }, + Literal { + lit: 1, + }, + ], + }, +]\ + "; + + #[cfg(not(span_locations))] + let expected_before_trailing_commas = "\ +TokenStream [ + Group { + delimiter: Bracket, + stream: TokenStream [ + Ident { + sym: a + }, + Punct { + char: '+', + spacing: Alone + }, + Literal { + lit: 1 + } + ] + } +]\ + "; + + #[cfg(span_locations)] + let expected = "\ +TokenStream [ + Group { + delimiter: Bracket, + stream: TokenStream [ + Ident { + sym: a, + span: bytes(2..3), + }, + Punct { + char: '+', + spacing: Alone, + span: bytes(4..5), + }, + Literal { + lit: 1, + span: bytes(6..7), + }, + ], + span: bytes(1..8), + }, +]\ + "; + + #[cfg(span_locations)] + let expected_before_trailing_commas = "\ +TokenStream [ + Group { + delimiter: Bracket, + stream: TokenStream [ + Ident { + sym: a, + span: bytes(2..3) + }, + Punct { + char: '+', + spacing: Alone, + span: bytes(4..5) + }, + Literal { + lit: 1, + span: bytes(6..7) + } + ], + span: bytes(1..8) + } +]\ + "; + + let actual = format!("{:#?}", tts); + if actual.ends_with(",\n]") { + assert_eq!(expected, actual); + } else { + assert_eq!(expected_before_trailing_commas, actual); + } +} + +#[test] +fn default_tokenstream_is_empty() { + let default_token_stream = ::default(); + + assert!(default_token_stream.is_empty()); +} + +#[test] +fn tokenstream_size_hint() { + let tokens = "a b (c d) e".parse::().unwrap(); + + assert_eq!(tokens.into_iter().size_hint(), (4, Some(4))); +} + +#[test] +fn tuple_indexing() { + // This behavior may change depending on https://github.com/rust-lang/rust/pull/71322 + let mut tokens = "tuple.0.0".parse::().unwrap().into_iter(); + assert_eq!("tuple", tokens.next().unwrap().to_string()); + assert_eq!(".", tokens.next().unwrap().to_string()); + assert_eq!("0.0", tokens.next().unwrap().to_string()); + assert!(tokens.next().is_none()); +} + +#[cfg(span_locations)] +#[test] +fn non_ascii_tokens() { + check_spans("// abc", &[]); + check_spans("// ábc", &[]); + check_spans("// abc x", &[]); + check_spans("// ábc x", &[]); + check_spans("/* abc */ x", &[(1, 10, 1, 11)]); + check_spans("/* ábc */ x", &[(1, 10, 1, 11)]); + check_spans("/* ab\nc */ x", &[(2, 5, 2, 6)]); + check_spans("/* áb\nc */ x", &[(2, 5, 2, 6)]); + check_spans("/*** abc */ x", &[(1, 12, 1, 13)]); + check_spans("/*** ábc */ x", &[(1, 12, 1, 13)]); + check_spans(r#""abc""#, &[(1, 0, 1, 5)]); + check_spans(r#""ábc""#, &[(1, 0, 1, 5)]); + check_spans(r##"r#"abc"#"##, &[(1, 0, 1, 8)]); + check_spans(r##"r#"ábc"#"##, &[(1, 0, 1, 8)]); + check_spans("r#\"a\nc\"#", &[(1, 0, 2, 3)]); + check_spans("r#\"á\nc\"#", &[(1, 0, 2, 3)]); + check_spans("'a'", &[(1, 0, 1, 3)]); + check_spans("'á'", &[(1, 0, 1, 3)]); + check_spans("//! abc", &[(1, 0, 1, 7), (1, 0, 1, 7), (1, 0, 1, 7)]); + check_spans("//! ábc", &[(1, 0, 1, 7), (1, 0, 1, 7), (1, 0, 1, 7)]); + check_spans("//! abc\n", &[(1, 0, 1, 7), (1, 0, 1, 7), (1, 0, 1, 7)]); + check_spans("//! ábc\n", &[(1, 0, 1, 7), (1, 0, 1, 7), (1, 0, 1, 7)]); + check_spans("/*! abc */", &[(1, 0, 1, 10), (1, 0, 1, 10), (1, 0, 1, 10)]); + check_spans("/*! ábc */", &[(1, 0, 1, 10), (1, 0, 1, 10), (1, 0, 1, 10)]); + check_spans("/*! a\nc */", &[(1, 0, 2, 4), (1, 0, 2, 4), (1, 0, 2, 4)]); + check_spans("/*! á\nc */", &[(1, 0, 2, 4), (1, 0, 2, 4), (1, 0, 2, 4)]); + check_spans("abc", &[(1, 0, 1, 3)]); + check_spans("ábc", &[(1, 0, 1, 3)]); + check_spans("ábć", &[(1, 0, 1, 3)]); + check_spans("abc// foo", &[(1, 0, 1, 3)]); + check_spans("ábc// foo", &[(1, 0, 1, 3)]); + check_spans("ábć// foo", &[(1, 0, 1, 3)]); + check_spans("b\"a\\\n c\"", &[(1, 0, 2, 3)]); +} + +#[cfg(span_locations)] +fn check_spans(p: &str, mut lines: &[(usize, usize, usize, usize)]) { + let ts = p.parse::().unwrap(); + check_spans_internal(ts, &mut lines); + assert!(lines.is_empty(), "leftover ranges: {:?}", lines); +} + +#[cfg(span_locations)] +fn check_spans_internal(ts: TokenStream, lines: &mut &[(usize, usize, usize, usize)]) { + for i in ts { + if let Some((&(sline, scol, eline, ecol), rest)) = lines.split_first() { + *lines = rest; + + let start = i.span().start(); + assert_eq!(start.line, sline, "sline did not match for {}", i); + assert_eq!(start.column, scol, "scol did not match for {}", i); + + let end = i.span().end(); + assert_eq!(end.line, eline, "eline did not match for {}", i); + assert_eq!(end.column, ecol, "ecol did not match for {}", i); + + if let TokenTree::Group(g) = i { + check_spans_internal(g.stream().clone(), lines); + } + } + } +} + +#[test] +fn whitespace() { + // space, horizontal tab, vertical tab, form feed, carriage return, line + // feed, non-breaking space, left-to-right mark, right-to-left mark + let various_spaces = " \t\u{b}\u{c}\r\n\u{a0}\u{200e}\u{200f}"; + let tokens = various_spaces.parse::().unwrap(); + assert_eq!(tokens.into_iter().count(), 0); + + let lone_carriage_returns = " \r \r\r\n "; + lone_carriage_returns.parse::().unwrap(); +} + +#[test] +fn byte_order_mark() { + let string = "\u{feff}foo"; + let tokens = string.parse::().unwrap(); + match tokens.into_iter().next().unwrap() { + TokenTree::Ident(ident) => assert_eq!(ident, "foo"), + _ => unreachable!(), + } + + let string = "foo\u{feff}"; + string.parse::().unwrap_err(); +} + +#[cfg(span_locations)] +fn create_span() -> proc_macro2::Span { + let tts: TokenStream = "1".parse().unwrap(); + match tts.into_iter().next().unwrap() { + TokenTree::Literal(literal) => literal.span(), + _ => unreachable!(), + } +} + +#[cfg(span_locations)] +#[test] +fn test_invalidate_current_thread_spans() { + let actual = format!("{:#?}", create_span()); + assert_eq!(actual, "bytes(1..2)"); + let actual = format!("{:#?}", create_span()); + assert_eq!(actual, "bytes(3..4)"); + + proc_macro2::extra::invalidate_current_thread_spans(); + + let actual = format!("{:#?}", create_span()); + // Test that span offsets have been reset after the call + // to invalidate_current_thread_spans() + assert_eq!(actual, "bytes(1..2)"); +} + +#[cfg(span_locations)] +#[test] +#[should_panic(expected = "Invalid span with no related FileInfo!")] +fn test_use_span_after_invalidation() { + let span = create_span(); + + proc_macro2::extra::invalidate_current_thread_spans(); + + span.source_text(); +} diff --git a/vendor/proc-macro2/tests/test_fmt.rs b/vendor/proc-macro2/tests/test_fmt.rs new file mode 100644 index 0000000..86a4c38 --- /dev/null +++ b/vendor/proc-macro2/tests/test_fmt.rs @@ -0,0 +1,28 @@ +#![allow(clippy::from_iter_instead_of_collect)] + +use proc_macro2::{Delimiter, Group, Ident, Span, TokenStream, TokenTree}; +use std::iter; + +#[test] +fn test_fmt_group() { + let ident = Ident::new("x", Span::call_site()); + let inner = TokenStream::from_iter(iter::once(TokenTree::Ident(ident))); + let parens_empty = Group::new(Delimiter::Parenthesis, TokenStream::new()); + let parens_nonempty = Group::new(Delimiter::Parenthesis, inner.clone()); + let brackets_empty = Group::new(Delimiter::Bracket, TokenStream::new()); + let brackets_nonempty = Group::new(Delimiter::Bracket, inner.clone()); + let braces_empty = Group::new(Delimiter::Brace, TokenStream::new()); + let braces_nonempty = Group::new(Delimiter::Brace, inner.clone()); + let none_empty = Group::new(Delimiter::None, TokenStream::new()); + let none_nonempty = Group::new(Delimiter::None, inner); + + // Matches libproc_macro. + assert_eq!("()", parens_empty.to_string()); + assert_eq!("(x)", parens_nonempty.to_string()); + assert_eq!("[]", brackets_empty.to_string()); + assert_eq!("[x]", brackets_nonempty.to_string()); + assert_eq!("{ }", braces_empty.to_string()); + assert_eq!("{ x }", braces_nonempty.to_string()); + assert_eq!("", none_empty.to_string()); + assert_eq!("x", none_nonempty.to_string()); +} diff --git a/vendor/proc-macro2/tests/test_size.rs b/vendor/proc-macro2/tests/test_size.rs new file mode 100644 index 0000000..8b67915 --- /dev/null +++ b/vendor/proc-macro2/tests/test_size.rs @@ -0,0 +1,81 @@ +#![allow(unused_attributes)] + +extern crate proc_macro; + +use std::mem; + +#[rustversion::attr(before(1.64), ignore = "requires Rust 1.64+")] +#[cfg_attr(not(target_pointer_width = "64"), ignore = "only applicable to 64-bit")] +#[cfg_attr(randomize_layout, ignore = "disabled due to randomized layout")] +#[test] +fn test_proc_macro_size() { + assert_eq!(mem::size_of::(), 4); + assert_eq!(mem::size_of::>(), 4); + assert_eq!(mem::size_of::(), 20); + assert_eq!(mem::size_of::(), 12); + assert_eq!(mem::size_of::(), 8); + assert_eq!(mem::size_of::(), 16); + assert_eq!(mem::size_of::(), 4); +} + +#[cfg_attr(not(target_pointer_width = "64"), ignore = "only applicable to 64-bit")] +#[cfg_attr(randomize_layout, ignore = "disabled due to randomized layout")] +#[cfg_attr(wrap_proc_macro, ignore = "wrapper mode")] +#[cfg_attr(span_locations, ignore = "span locations are on")] +#[test] +fn test_proc_macro2_fallback_size_without_locations() { + assert_eq!(mem::size_of::(), 0); + assert_eq!(mem::size_of::>(), 1); + assert_eq!(mem::size_of::(), 16); + assert_eq!(mem::size_of::(), 24); + assert_eq!(mem::size_of::(), 8); + assert_eq!(mem::size_of::(), 24); + assert_eq!(mem::size_of::(), 8); +} + +#[cfg_attr(not(target_pointer_width = "64"), ignore = "only applicable to 64-bit")] +#[cfg_attr(randomize_layout, ignore = "disabled due to randomized layout")] +#[cfg_attr(wrap_proc_macro, ignore = "wrapper mode")] +#[cfg_attr(not(span_locations), ignore = "span locations are off")] +#[test] +fn test_proc_macro2_fallback_size_with_locations() { + assert_eq!(mem::size_of::(), 8); + assert_eq!(mem::size_of::>(), 12); + assert_eq!(mem::size_of::(), 24); + assert_eq!(mem::size_of::(), 32); + assert_eq!(mem::size_of::(), 16); + assert_eq!(mem::size_of::(), 32); + assert_eq!(mem::size_of::(), 8); +} + +#[rustversion::attr(before(1.71), ignore = "requires Rust 1.71+")] +#[cfg_attr(not(target_pointer_width = "64"), ignore = "only applicable to 64-bit")] +#[cfg_attr(randomize_layout, ignore = "disabled due to randomized layout")] +#[cfg_attr(not(wrap_proc_macro), ignore = "fallback mode")] +#[cfg_attr(span_locations, ignore = "span locations are on")] +#[test] +fn test_proc_macro2_wrapper_size_without_locations() { + assert_eq!(mem::size_of::(), 4); + assert_eq!(mem::size_of::>(), 8); + assert_eq!(mem::size_of::(), 24); + assert_eq!(mem::size_of::(), 24); + assert_eq!(mem::size_of::(), 12); + assert_eq!(mem::size_of::(), 24); + assert_eq!(mem::size_of::(), 32); +} + +#[rustversion::attr(before(1.65), ignore = "requires Rust 1.65+")] +#[cfg_attr(not(target_pointer_width = "64"), ignore = "only applicable to 64-bit")] +#[cfg_attr(randomize_layout, ignore = "disabled due to randomized layout")] +#[cfg_attr(not(wrap_proc_macro), ignore = "fallback mode")] +#[cfg_attr(not(span_locations), ignore = "span locations are off")] +#[test] +fn test_proc_macro2_wrapper_size_with_locations() { + assert_eq!(mem::size_of::(), 12); + assert_eq!(mem::size_of::>(), 12); + assert_eq!(mem::size_of::(), 32); + assert_eq!(mem::size_of::(), 32); + assert_eq!(mem::size_of::(), 20); + assert_eq!(mem::size_of::(), 32); + assert_eq!(mem::size_of::(), 32); +} diff --git a/vendor/quote/.cargo-checksum.json b/vendor/quote/.cargo-checksum.json new file mode 100644 index 0000000..2c547c3 --- /dev/null +++ b/vendor/quote/.cargo-checksum.json @@ -0,0 +1 @@ +{"files":{"Cargo.toml":"8bdca3d4bf8c01d302dc8f779c5c546c7e0357601ed3d62771b7cd7a05b459ee","LICENSE-APACHE":"62c7a1e35f56406896d7aa7ca52d0cc0d272ac022b5d2796e7d6905db8a3636a","LICENSE-MIT":"23f18e03dc49df91622fe2a76176497404e46ced8a715d9d2b67a7446571cca3","README.md":"edb299daa2373254c96147303289002b9f424944176a26e5520ee82869caedc6","rust-toolchain.toml":"6bbb61302978c736b2da03e4fb40e3beab908f85d533ab46fd541e637b5f3e0f","src/ext.rs":"9881576cac3e476a4bf04f9b601cf9a53b79399fb0ca9634e8b861ac91709843","src/format.rs":"c595015418f35e6992e710441b9999f09b2afe4678b138039d670d100c0bdd86","src/ident_fragment.rs":"0b3e6c2129e55910fd2d240e1e7efba6f1796801d24352d1c0bfbceb0e8b678f","src/lib.rs":"bdc2340e5f1e84972d2f8d65393465dd4aea20001ae2cd484e867d0d653d60ae","src/runtime.rs":"7f37326edaeac2c42ed806b447eeba12e36dd4b1bc25fbf52f8eb23140f3be7a","src/spanned.rs":"3ccf5120593f35787442c0a37d243e802c5262e7f8b35aed503873008ec035c5","src/to_tokens.rs":"caca09d649e9394d37f065a41d481318c4cb86c345b9cb01f36fbf0f73868e86","tests/compiletest.rs":"4e381aa8ca3eabb7ac14d1e0c3700b3223e47640547a6988cfa13ad68255f60f","tests/test.rs":"05584957f1c30b180c31ef849ee9ec48e6b847f3e655efc0983c20dcfce2131e","tests/ui/does-not-have-iter-interpolated-dup.rs":"ad13eea21d4cdd2ab6c082f633392e1ff20fb0d1af5f2177041e0bf7f30da695","tests/ui/does-not-have-iter-interpolated-dup.stderr":"90a4bdb9267535f5d2785940148338d6b7d905548051d2c9c5dcbd58f2c11d8e","tests/ui/does-not-have-iter-interpolated.rs":"83a5b3f240651adcbe4b6e51076d76d653ad439b37442cf4054f1fd3c073f3b7","tests/ui/does-not-have-iter-interpolated.stderr":"ae7c2739554c862b331705e82781aa4687a4375210cef6ae899a4be4a4ec2d97","tests/ui/does-not-have-iter-separated.rs":"fe413c48331d5e3a7ae5fef6a5892a90c72f610d54595879eb49d0a94154ba3f","tests/ui/does-not-have-iter-separated.stderr":"03fd560979ebcd5aa6f83858bc2c3c01ba6546c16335101275505304895c1ae9","tests/ui/does-not-have-iter.rs":"09dc9499d861b63cebb0848b855b78e2dc9497bfde37ba6339f3625ae009a62f","tests/ui/does-not-have-iter.stderr":"d6da483c29e232ced72059bbdf05d31afb1df9e02954edaa9cfaea1ec6df72dc","tests/ui/not-quotable.rs":"5759d0884943417609f28faadc70254a3e2fd3d9bd6ff7297a3fb70a77fafd8a","tests/ui/not-quotable.stderr":"62f32911c891d7e4617c6f32dca2723598a5c321979fe7ec89b159bd8d9445d9","tests/ui/not-repeatable.rs":"a4b115c04e4e41049a05f5b69450503fbffeba031218b4189cb931839f7f9a9c","tests/ui/not-repeatable.stderr":"bbfb702638374001061251f81d63476851ac28ed743f13db9d65e30dd9bdcf52","tests/ui/wrong-type-span.rs":"6195e35ea844c0c52ba1cff5d790c3a371af6915d137d377834ad984229ef9ea","tests/ui/wrong-type-span.stderr":"cad072e40e0ecc04f375122ae41aede2f0da2a9244492b3fcf70249e59d1b128"},"package":"b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af"} \ No newline at end of file diff --git a/vendor/quote/Cargo.toml b/vendor/quote/Cargo.toml new file mode 100644 index 0000000..af97fc7 --- /dev/null +++ b/vendor/quote/Cargo.toml @@ -0,0 +1,64 @@ +# 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] +edition = "2018" +rust-version = "1.56" +name = "quote" +version = "1.0.37" +authors = ["David Tolnay "] +build = false +autobins = false +autoexamples = false +autotests = false +autobenches = false +description = "Quasi-quoting macro quote!(...)" +documentation = "https://docs.rs/quote/" +readme = "README.md" +keywords = [ + "macros", + "syn", +] +categories = ["development-tools::procedural-macro-helpers"] +license = "MIT OR Apache-2.0" +repository = "https://github.com/dtolnay/quote" + +[package.metadata.docs.rs] +rustdoc-args = ["--generate-link-to-definition"] +targets = ["x86_64-unknown-linux-gnu"] + +[lib] +name = "quote" +path = "src/lib.rs" +doc-scrape-examples = false + +[[test]] +name = "compiletest" +path = "tests/compiletest.rs" + +[[test]] +name = "test" +path = "tests/test.rs" + +[dependencies.proc-macro2] +version = "1.0.80" +default-features = false + +[dev-dependencies.rustversion] +version = "1.0" + +[dev-dependencies.trybuild] +version = "1.0.66" +features = ["diff"] + +[features] +default = ["proc-macro"] +proc-macro = ["proc-macro2/proc-macro"] diff --git a/vendor/quote/LICENSE-APACHE b/vendor/quote/LICENSE-APACHE new file mode 100644 index 0000000..1b5ec8b --- /dev/null +++ b/vendor/quote/LICENSE-APACHE @@ -0,0 +1,176 @@ + 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 diff --git a/vendor/quote/LICENSE-MIT b/vendor/quote/LICENSE-MIT new file mode 100644 index 0000000..31aa793 --- /dev/null +++ b/vendor/quote/LICENSE-MIT @@ -0,0 +1,23 @@ +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/quote/README.md b/vendor/quote/README.md new file mode 100644 index 0000000..58bbf21 --- /dev/null +++ b/vendor/quote/README.md @@ -0,0 +1,271 @@ +Rust Quasi-Quoting +================== + +[github](https://github.com/dtolnay/quote) +[crates.io](https://crates.io/crates/quote) +[docs.rs](https://docs.rs/quote) +[build status](https://github.com/dtolnay/quote/actions?query=branch%3Amaster) + +This crate provides the [`quote!`] macro for turning Rust syntax tree data +structures into tokens of source code. + +[`quote!`]: https://docs.rs/quote/1.0/quote/macro.quote.html + +Procedural macros in Rust receive a stream of tokens as input, execute arbitrary +Rust code to determine how to manipulate those tokens, and produce a stream of +tokens to hand back to the compiler to compile into the caller's crate. +Quasi-quoting is a solution to one piece of that — producing tokens to +return to the compiler. + +The idea of quasi-quoting is that we write *code* that we treat as *data*. +Within the `quote!` macro, we can write what looks like code to our text editor +or IDE. We get all the benefits of the editor's brace matching, syntax +highlighting, indentation, and maybe autocompletion. But rather than compiling +that as code into the current crate, we can treat it as data, pass it around, +mutate it, and eventually hand it back to the compiler as tokens to compile into +the macro caller's crate. + +This crate is motivated by the procedural macro use case, but is a +general-purpose Rust quasi-quoting library and is not specific to procedural +macros. + +```toml +[dependencies] +quote = "1.0" +``` + +*Version requirement: Quote supports rustc 1.56 and up.*
+[*Release notes*](https://github.com/dtolnay/quote/releases) + +
+ +## Syntax + +The quote crate provides a [`quote!`] macro within which you can write Rust code +that gets packaged into a [`TokenStream`] and can be treated as data. You should +think of `TokenStream` as representing a fragment of Rust source code. + +[`TokenStream`]: https://docs.rs/proc-macro2/1.0/proc_macro2/struct.TokenStream.html + +Within the `quote!` macro, interpolation is done with `#var`. Any type +implementing the [`quote::ToTokens`] trait can be interpolated. This includes +most Rust primitive types as well as most of the syntax tree types from [`syn`]. + +[`quote::ToTokens`]: https://docs.rs/quote/1.0/quote/trait.ToTokens.html +[`syn`]: https://github.com/dtolnay/syn + +```rust +let tokens = quote! { + struct SerializeWith #generics #where_clause { + value: &'a #field_ty, + phantom: core::marker::PhantomData<#item_ty>, + } + + impl #generics serde::Serialize for SerializeWith #generics #where_clause { + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + #path(self.value, serializer) + } + } + + SerializeWith { + value: #value, + phantom: core::marker::PhantomData::<#item_ty>, + } +}; +``` + +
+ +## Repetition + +Repetition is done using `#(...)*` or `#(...),*` similar to `macro_rules!`. This +iterates through the elements of any variable interpolated within the repetition +and inserts a copy of the repetition body for each one. The variables in an +interpolation may be a `Vec`, slice, `BTreeSet`, or any `Iterator`. + +- `#(#var)*` — no separators +- `#(#var),*` — the character before the asterisk is used as a separator +- `#( struct #var; )*` — the repetition can contain other things +- `#( #k => println!("{}", #v), )*` — even multiple interpolations + +Note that there is a difference between `#(#var ,)*` and `#(#var),*`—the latter +does not produce a trailing comma. This matches the behavior of delimiters in +`macro_rules!`. + +
+ +## Returning tokens to the compiler + +The `quote!` macro evaluates to an expression of type +`proc_macro2::TokenStream`. Meanwhile Rust procedural macros are expected to +return the type `proc_macro::TokenStream`. + +The difference between the two types is that `proc_macro` types are entirely +specific to procedural macros and cannot ever exist in code outside of a +procedural macro, while `proc_macro2` types may exist anywhere including tests +and non-macro code like main.rs and build.rs. This is why even the procedural +macro ecosystem is largely built around `proc_macro2`, because that ensures the +libraries are unit testable and accessible in non-macro contexts. + +There is a [`From`]-conversion in both directions so returning the output of +`quote!` from a procedural macro usually looks like `tokens.into()` or +`proc_macro::TokenStream::from(tokens)`. + +[`From`]: https://doc.rust-lang.org/std/convert/trait.From.html + +
+ +## Examples + +### Combining quoted fragments + +Usually you don't end up constructing an entire final `TokenStream` in one +piece. Different parts may come from different helper functions. The tokens +produced by `quote!` themselves implement `ToTokens` and so can be interpolated +into later `quote!` invocations to build up a final result. + +```rust +let type_definition = quote! {...}; +let methods = quote! {...}; + +let tokens = quote! { + #type_definition + #methods +}; +``` + +### Constructing identifiers + +Suppose we have an identifier `ident` which came from somewhere in a macro +input and we need to modify it in some way for the macro output. Let's consider +prepending the identifier with an underscore. + +Simply interpolating the identifier next to an underscore will not have the +behavior of concatenating them. The underscore and the identifier will continue +to be two separate tokens as if you had written `_ x`. + +```rust +// incorrect +quote! { + let mut _#ident = 0; +} +``` + +The solution is to build a new identifier token with the correct value. As this +is such a common case, the `format_ident!` macro provides a convenient utility +for doing so correctly. + +```rust +let varname = format_ident!("_{}", ident); +quote! { + let mut #varname = 0; +} +``` + +Alternatively, the APIs provided by Syn and proc-macro2 can be used to directly +build the identifier. This is roughly equivalent to the above, but will not +handle `ident` being a raw identifier. + +```rust +let concatenated = format!("_{}", ident); +let varname = syn::Ident::new(&concatenated, ident.span()); +quote! { + let mut #varname = 0; +} +``` + +### Making method calls + +Let's say our macro requires some type specified in the macro input to have a +constructor called `new`. We have the type in a variable called `field_type` of +type `syn::Type` and want to invoke the constructor. + +```rust +// incorrect +quote! { + let value = #field_type::new(); +} +``` + +This works only sometimes. If `field_type` is `String`, the expanded code +contains `String::new()` which is fine. But if `field_type` is something like +`Vec` then the expanded code is `Vec::new()` which is invalid syntax. +Ordinarily in handwritten Rust we would write `Vec::::new()` but for macros +often the following is more convenient. + +```rust +quote! { + let value = <#field_type>::new(); +} +``` + +This expands to `>::new()` which behaves correctly. + +A similar pattern is appropriate for trait methods. + +```rust +quote! { + let value = <#field_type as core::default::Default>::default(); +} +``` + +
+ +## Hygiene + +Any interpolated tokens preserve the `Span` information provided by their +`ToTokens` implementation. Tokens that originate within a `quote!` invocation +are spanned with [`Span::call_site()`]. + +[`Span::call_site()`]: https://docs.rs/proc-macro2/1.0/proc_macro2/struct.Span.html#method.call_site + +A different span can be provided explicitly through the [`quote_spanned!`] +macro. + +[`quote_spanned!`]: https://docs.rs/quote/1.0/quote/macro.quote_spanned.html + +
+ +## Non-macro code generators + +When using `quote` in a build.rs or main.rs and writing the output out to a +file, consider having the code generator pass the tokens through [prettyplease] +before writing. This way if an error occurs in the generated code it is +convenient for a human to read and debug. + +Be aware that no kind of hygiene or span information is retained when tokens are +written to a file; the conversion from tokens to source code is lossy. + +Example usage in build.rs: + +```rust +let output = quote! { ... }; +let syntax_tree = syn::parse2(output).unwrap(); +let formatted = prettyplease::unparse(&syntax_tree); + +let out_dir = env::var_os("OUT_DIR").unwrap(); +let dest_path = Path::new(&out_dir).join("out.rs"); +fs::write(dest_path, formatted).unwrap(); +``` + +[prettyplease]: https://github.com/dtolnay/prettyplease + +
+ +#### License + + +Licensed under either of Apache License, Version +2.0 or MIT license at your option. + + +
+ + +Unless you explicitly state otherwise, any contribution intentionally submitted +for inclusion in this crate 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/quote/rust-toolchain.toml b/vendor/quote/rust-toolchain.toml new file mode 100644 index 0000000..20fe888 --- /dev/null +++ b/vendor/quote/rust-toolchain.toml @@ -0,0 +1,2 @@ +[toolchain] +components = ["rust-src"] diff --git a/vendor/quote/src/ext.rs b/vendor/quote/src/ext.rs new file mode 100644 index 0000000..92c2315 --- /dev/null +++ b/vendor/quote/src/ext.rs @@ -0,0 +1,110 @@ +use super::ToTokens; +use core::iter; +use proc_macro2::{TokenStream, TokenTree}; + +/// TokenStream extension trait with methods for appending tokens. +/// +/// This trait is sealed and cannot be implemented outside of the `quote` crate. +pub trait TokenStreamExt: private::Sealed { + /// For use by `ToTokens` implementations. + /// + /// Appends the token specified to this list of tokens. + fn append(&mut self, token: U) + where + U: Into; + + /// For use by `ToTokens` implementations. + /// + /// ``` + /// # use quote::{quote, TokenStreamExt, ToTokens}; + /// # use proc_macro2::TokenStream; + /// # + /// struct X; + /// + /// impl ToTokens for X { + /// fn to_tokens(&self, tokens: &mut TokenStream) { + /// tokens.append_all(&[true, false]); + /// } + /// } + /// + /// let tokens = quote!(#X); + /// assert_eq!(tokens.to_string(), "true false"); + /// ``` + fn append_all(&mut self, iter: I) + where + I: IntoIterator, + I::Item: ToTokens; + + /// For use by `ToTokens` implementations. + /// + /// Appends all of the items in the iterator `I`, separated by the tokens + /// `U`. + fn append_separated(&mut self, iter: I, op: U) + where + I: IntoIterator, + I::Item: ToTokens, + U: ToTokens; + + /// For use by `ToTokens` implementations. + /// + /// Appends all tokens in the iterator `I`, appending `U` after each + /// element, including after the last element of the iterator. + fn append_terminated(&mut self, iter: I, term: U) + where + I: IntoIterator, + I::Item: ToTokens, + U: ToTokens; +} + +impl TokenStreamExt for TokenStream { + fn append(&mut self, token: U) + where + U: Into, + { + self.extend(iter::once(token.into())); + } + + fn append_all(&mut self, iter: I) + where + I: IntoIterator, + I::Item: ToTokens, + { + for token in iter { + token.to_tokens(self); + } + } + + fn append_separated(&mut self, iter: I, op: U) + where + I: IntoIterator, + I::Item: ToTokens, + U: ToTokens, + { + for (i, token) in iter.into_iter().enumerate() { + if i > 0 { + op.to_tokens(self); + } + token.to_tokens(self); + } + } + + fn append_terminated(&mut self, iter: I, term: U) + where + I: IntoIterator, + I::Item: ToTokens, + U: ToTokens, + { + for token in iter { + token.to_tokens(self); + term.to_tokens(self); + } + } +} + +mod private { + use proc_macro2::TokenStream; + + pub trait Sealed {} + + impl Sealed for TokenStream {} +} diff --git a/vendor/quote/src/format.rs b/vendor/quote/src/format.rs new file mode 100644 index 0000000..3cddbd2 --- /dev/null +++ b/vendor/quote/src/format.rs @@ -0,0 +1,168 @@ +/// Formatting macro for constructing `Ident`s. +/// +///
+/// +/// # Syntax +/// +/// Syntax is copied from the [`format!`] macro, supporting both positional and +/// named arguments. +/// +/// Only a limited set of formatting traits are supported. The current mapping +/// of format types to traits is: +/// +/// * `{}` ⇒ [`IdentFragment`] +/// * `{:o}` ⇒ [`Octal`](std::fmt::Octal) +/// * `{:x}` ⇒ [`LowerHex`](std::fmt::LowerHex) +/// * `{:X}` ⇒ [`UpperHex`](std::fmt::UpperHex) +/// * `{:b}` ⇒ [`Binary`](std::fmt::Binary) +/// +/// See [`std::fmt`] for more information. +/// +///
+/// +/// # IdentFragment +/// +/// Unlike `format!`, this macro uses the [`IdentFragment`] formatting trait by +/// default. This trait is like `Display`, with a few differences: +/// +/// * `IdentFragment` is only implemented for a limited set of types, such as +/// unsigned integers and strings. +/// * [`Ident`] arguments will have their `r#` prefixes stripped, if present. +/// +/// [`IdentFragment`]: crate::IdentFragment +/// [`Ident`]: proc_macro2::Ident +/// +///
+/// +/// # Hygiene +/// +/// The [`Span`] of the first `Ident` argument is used as the span of the final +/// identifier, falling back to [`Span::call_site`] when no identifiers are +/// provided. +/// +/// ``` +/// # use quote::format_ident; +/// # let ident = format_ident!("Ident"); +/// // If `ident` is an Ident, the span of `my_ident` will be inherited from it. +/// let my_ident = format_ident!("My{}{}", ident, "IsCool"); +/// assert_eq!(my_ident, "MyIdentIsCool"); +/// ``` +/// +/// Alternatively, the span can be overridden by passing the `span` named +/// argument. +/// +/// ``` +/// # use quote::format_ident; +/// # const IGNORE_TOKENS: &'static str = stringify! { +/// let my_span = /* ... */; +/// # }; +/// # let my_span = proc_macro2::Span::call_site(); +/// format_ident!("MyIdent", span = my_span); +/// ``` +/// +/// [`Span`]: proc_macro2::Span +/// [`Span::call_site`]: proc_macro2::Span::call_site +/// +///


+/// +/// # Panics +/// +/// This method will panic if the resulting formatted string is not a valid +/// identifier. +/// +///
+/// +/// # Examples +/// +/// Composing raw and non-raw identifiers: +/// ``` +/// # use quote::format_ident; +/// let my_ident = format_ident!("My{}", "Ident"); +/// assert_eq!(my_ident, "MyIdent"); +/// +/// let raw = format_ident!("r#Raw"); +/// assert_eq!(raw, "r#Raw"); +/// +/// let my_ident_raw = format_ident!("{}Is{}", my_ident, raw); +/// assert_eq!(my_ident_raw, "MyIdentIsRaw"); +/// ``` +/// +/// Integer formatting options: +/// ``` +/// # use quote::format_ident; +/// let num: u32 = 10; +/// +/// let decimal = format_ident!("Id_{}", num); +/// assert_eq!(decimal, "Id_10"); +/// +/// let octal = format_ident!("Id_{:o}", num); +/// assert_eq!(octal, "Id_12"); +/// +/// let binary = format_ident!("Id_{:b}", num); +/// assert_eq!(binary, "Id_1010"); +/// +/// let lower_hex = format_ident!("Id_{:x}", num); +/// assert_eq!(lower_hex, "Id_a"); +/// +/// let upper_hex = format_ident!("Id_{:X}", num); +/// assert_eq!(upper_hex, "Id_A"); +/// ``` +#[macro_export] +macro_rules! format_ident { + ($fmt:expr) => { + $crate::format_ident_impl!([ + $crate::__private::Option::None, + $fmt + ]) + }; + + ($fmt:expr, $($rest:tt)*) => { + $crate::format_ident_impl!([ + $crate::__private::Option::None, + $fmt + ] $($rest)*) + }; +} + +#[macro_export] +#[doc(hidden)] +macro_rules! format_ident_impl { + // Final state + ([$span:expr, $($fmt:tt)*]) => { + $crate::__private::mk_ident( + &$crate::__private::format!($($fmt)*), + $span, + ) + }; + + // Span argument + ([$old:expr, $($fmt:tt)*] span = $span:expr) => { + $crate::format_ident_impl!([$old, $($fmt)*] span = $span,) + }; + ([$old:expr, $($fmt:tt)*] span = $span:expr, $($rest:tt)*) => { + $crate::format_ident_impl!([ + $crate::__private::Option::Some::<$crate::__private::Span>($span), + $($fmt)* + ] $($rest)*) + }; + + // Named argument + ([$span:expr, $($fmt:tt)*] $name:ident = $arg:expr) => { + $crate::format_ident_impl!([$span, $($fmt)*] $name = $arg,) + }; + ([$span:expr, $($fmt:tt)*] $name:ident = $arg:expr, $($rest:tt)*) => { + match $crate::__private::IdentFragmentAdapter(&$arg) { + arg => $crate::format_ident_impl!([$span.or(arg.span()), $($fmt)*, $name = arg] $($rest)*), + } + }; + + // Positional argument + ([$span:expr, $($fmt:tt)*] $arg:expr) => { + $crate::format_ident_impl!([$span, $($fmt)*] $arg,) + }; + ([$span:expr, $($fmt:tt)*] $arg:expr, $($rest:tt)*) => { + match $crate::__private::IdentFragmentAdapter(&$arg) { + arg => $crate::format_ident_impl!([$span.or(arg.span()), $($fmt)*, arg] $($rest)*), + } + }; +} diff --git a/vendor/quote/src/ident_fragment.rs b/vendor/quote/src/ident_fragment.rs new file mode 100644 index 0000000..6c2a9a8 --- /dev/null +++ b/vendor/quote/src/ident_fragment.rs @@ -0,0 +1,88 @@ +use alloc::borrow::Cow; +use core::fmt; +use proc_macro2::{Ident, Span}; + +/// Specialized formatting trait used by `format_ident!`. +/// +/// [`Ident`] arguments formatted using this trait will have their `r#` prefix +/// stripped, if present. +/// +/// See [`format_ident!`] for more information. +/// +/// [`format_ident!`]: crate::format_ident +pub trait IdentFragment { + /// Format this value as an identifier fragment. + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result; + + /// Span associated with this `IdentFragment`. + /// + /// If non-`None`, may be inherited by formatted identifiers. + fn span(&self) -> Option { + None + } +} + +impl IdentFragment for &T { + fn span(&self) -> Option { + ::span(*self) + } + + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + IdentFragment::fmt(*self, f) + } +} + +impl IdentFragment for &mut T { + fn span(&self) -> Option { + ::span(*self) + } + + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + IdentFragment::fmt(*self, f) + } +} + +impl IdentFragment for Ident { + fn span(&self) -> Option { + Some(self.span()) + } + + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + let id = self.to_string(); + if let Some(id) = id.strip_prefix("r#") { + fmt::Display::fmt(id, f) + } else { + fmt::Display::fmt(&id[..], f) + } + } +} + +impl IdentFragment for Cow<'_, T> +where + T: IdentFragment + ToOwned + ?Sized, +{ + fn span(&self) -> Option { + T::span(self) + } + + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + T::fmt(self, f) + } +} + +// Limited set of types which this is implemented for, as we want to avoid types +// which will often include non-identifier characters in their `Display` impl. +macro_rules! ident_fragment_display { + ($($T:ty),*) => { + $( + impl IdentFragment for $T { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fmt::Display::fmt(self, f) + } + } + )* + }; +} + +ident_fragment_display!(bool, str, String, char); +ident_fragment_display!(u8, u16, u32, u64, u128, usize); diff --git a/vendor/quote/src/lib.rs b/vendor/quote/src/lib.rs new file mode 100644 index 0000000..2c72da2 --- /dev/null +++ b/vendor/quote/src/lib.rs @@ -0,0 +1,1464 @@ +//! [![github]](https://github.com/dtolnay/quote) [![crates-io]](https://crates.io/crates/quote) [![docs-rs]](https://docs.rs/quote) +//! +//! [github]: https://img.shields.io/badge/github-8da0cb?style=for-the-badge&labelColor=555555&logo=github +//! [crates-io]: https://img.shields.io/badge/crates.io-fc8d62?style=for-the-badge&labelColor=555555&logo=rust +//! [docs-rs]: https://img.shields.io/badge/docs.rs-66c2a5?style=for-the-badge&labelColor=555555&logo=docs.rs +//! +//!
+//! +//! This crate provides the [`quote!`] macro for turning Rust syntax tree data +//! structures into tokens of source code. +//! +//! [`quote!`]: macro.quote.html +//! +//! Procedural macros in Rust receive a stream of tokens as input, execute +//! arbitrary Rust code to determine how to manipulate those tokens, and produce +//! a stream of tokens to hand back to the compiler to compile into the caller's +//! crate. Quasi-quoting is a solution to one piece of that — producing +//! tokens to return to the compiler. +//! +//! The idea of quasi-quoting is that we write *code* that we treat as *data*. +//! Within the `quote!` macro, we can write what looks like code to our text +//! editor or IDE. We get all the benefits of the editor's brace matching, +//! syntax highlighting, indentation, and maybe autocompletion. But rather than +//! compiling that as code into the current crate, we can treat it as data, pass +//! it around, mutate it, and eventually hand it back to the compiler as tokens +//! to compile into the macro caller's crate. +//! +//! This crate is motivated by the procedural macro use case, but is a +//! general-purpose Rust quasi-quoting library and is not specific to procedural +//! macros. +//! +//! ```toml +//! [dependencies] +//! quote = "1.0" +//! ``` +//! +//!
+//! +//! # Example +//! +//! The following quasi-quoted block of code is something you might find in [a] +//! procedural macro having to do with data structure serialization. The `#var` +//! syntax performs interpolation of runtime variables into the quoted tokens. +//! Check out the documentation of the [`quote!`] macro for more detail about +//! the syntax. See also the [`quote_spanned!`] macro which is important for +//! implementing hygienic procedural macros. +//! +//! [a]: https://serde.rs/ +//! [`quote_spanned!`]: macro.quote_spanned.html +//! +//! ``` +//! # use quote::quote; +//! # +//! # let generics = ""; +//! # let where_clause = ""; +//! # let field_ty = ""; +//! # let item_ty = ""; +//! # let path = ""; +//! # let value = ""; +//! # +//! let tokens = quote! { +//! struct SerializeWith #generics #where_clause { +//! value: &'a #field_ty, +//! phantom: core::marker::PhantomData<#item_ty>, +//! } +//! +//! impl #generics serde::Serialize for SerializeWith #generics #where_clause { +//! fn serialize(&self, serializer: S) -> Result +//! where +//! S: serde::Serializer, +//! { +//! #path(self.value, serializer) +//! } +//! } +//! +//! SerializeWith { +//! value: #value, +//! phantom: core::marker::PhantomData::<#item_ty>, +//! } +//! }; +//! ``` +//! +//!
+//! +//! # Non-macro code generators +//! +//! When using `quote` in a build.rs or main.rs and writing the output out to a +//! file, consider having the code generator pass the tokens through +//! [prettyplease] before writing. This way if an error occurs in the generated +//! code it is convenient for a human to read and debug. +//! +//! [prettyplease]: https://github.com/dtolnay/prettyplease + +// Quote types in rustdoc of other crates get linked to here. +#![doc(html_root_url = "https://docs.rs/quote/1.0.37")] +#![allow( + clippy::doc_markdown, + clippy::missing_errors_doc, + clippy::missing_panics_doc, + clippy::module_name_repetitions, + // false positive https://github.com/rust-lang/rust-clippy/issues/6983 + clippy::wrong_self_convention, +)] + +extern crate alloc; + +#[cfg(feature = "proc-macro")] +extern crate proc_macro; + +mod ext; +mod format; +mod ident_fragment; +mod to_tokens; + +// Not public API. +#[doc(hidden)] +#[path = "runtime.rs"] +pub mod __private; + +pub use crate::ext::TokenStreamExt; +pub use crate::ident_fragment::IdentFragment; +pub use crate::to_tokens::ToTokens; + +// Not public API. +#[doc(hidden)] +pub mod spanned; + +macro_rules! __quote { + ($quote:item) => { + /// The whole point. + /// + /// Performs variable interpolation against the input and produces it as + /// [`proc_macro2::TokenStream`]. + /// + /// Note: for returning tokens to the compiler in a procedural macro, use + /// `.into()` on the result to convert to [`proc_macro::TokenStream`]. + /// + /// [`TokenStream`]: https://docs.rs/proc-macro2/1.0/proc_macro2/struct.TokenStream.html + /// + ///
+ /// + /// # Interpolation + /// + /// Variable interpolation is done with `#var` (similar to `$var` in + /// `macro_rules!` macros). This grabs the `var` variable that is currently in + /// scope and inserts it in that location in the output tokens. Any type + /// implementing the [`ToTokens`] trait can be interpolated. This includes most + /// Rust primitive types as well as most of the syntax tree types from the [Syn] + /// crate. + /// + /// [`ToTokens`]: trait.ToTokens.html + /// [Syn]: https://github.com/dtolnay/syn + /// + /// Repetition is done using `#(...)*` or `#(...),*` again similar to + /// `macro_rules!`. This iterates through the elements of any variable + /// interpolated within the repetition and inserts a copy of the repetition body + /// for each one. The variables in an interpolation may be a `Vec`, slice, + /// `BTreeSet`, or any `Iterator`. + /// + /// - `#(#var)*` — no separators + /// - `#(#var),*` — the character before the asterisk is used as a separator + /// - `#( struct #var; )*` — the repetition can contain other tokens + /// - `#( #k => println!("{}", #v), )*` — even multiple interpolations + /// + ///
+ /// + /// # Hygiene + /// + /// Any interpolated tokens preserve the `Span` information provided by their + /// `ToTokens` implementation. Tokens that originate within the `quote!` + /// invocation are spanned with [`Span::call_site()`]. + /// + /// [`Span::call_site()`]: https://docs.rs/proc-macro2/1.0/proc_macro2/struct.Span.html#method.call_site + /// + /// A different span can be provided through the [`quote_spanned!`] macro. + /// + /// [`quote_spanned!`]: macro.quote_spanned.html + /// + ///
+ /// + /// # Return type + /// + /// The macro evaluates to an expression of type `proc_macro2::TokenStream`. + /// Meanwhile Rust procedural macros are expected to return the type + /// `proc_macro::TokenStream`. + /// + /// The difference between the two types is that `proc_macro` types are entirely + /// specific to procedural macros and cannot ever exist in code outside of a + /// procedural macro, while `proc_macro2` types may exist anywhere including + /// tests and non-macro code like main.rs and build.rs. This is why even the + /// procedural macro ecosystem is largely built around `proc_macro2`, because + /// that ensures the libraries are unit testable and accessible in non-macro + /// contexts. + /// + /// There is a [`From`]-conversion in both directions so returning the output of + /// `quote!` from a procedural macro usually looks like `tokens.into()` or + /// `proc_macro::TokenStream::from(tokens)`. + /// + /// [`From`]: https://doc.rust-lang.org/std/convert/trait.From.html + /// + ///
+ /// + /// # Examples + /// + /// ### Procedural macro + /// + /// The structure of a basic procedural macro is as follows. Refer to the [Syn] + /// crate for further useful guidance on using `quote!` as part of a procedural + /// macro. + /// + /// [Syn]: https://github.com/dtolnay/syn + /// + /// ``` + /// # #[cfg(any())] + /// extern crate proc_macro; + /// # extern crate proc_macro2; + /// + /// # #[cfg(any())] + /// use proc_macro::TokenStream; + /// # use proc_macro2::TokenStream; + /// use quote::quote; + /// + /// # const IGNORE_TOKENS: &'static str = stringify! { + /// #[proc_macro_derive(HeapSize)] + /// # }; + /// pub fn derive_heap_size(input: TokenStream) -> TokenStream { + /// // Parse the input and figure out what implementation to generate... + /// # const IGNORE_TOKENS: &'static str = stringify! { + /// let name = /* ... */; + /// let expr = /* ... */; + /// # }; + /// # + /// # let name = 0; + /// # let expr = 0; + /// + /// let expanded = quote! { + /// // The generated impl. + /// impl heapsize::HeapSize for #name { + /// fn heap_size_of_children(&self) -> usize { + /// #expr + /// } + /// } + /// }; + /// + /// // Hand the output tokens back to the compiler. + /// TokenStream::from(expanded) + /// } + /// ``` + /// + ///


+ /// + /// ### Combining quoted fragments + /// + /// Usually you don't end up constructing an entire final `TokenStream` in one + /// piece. Different parts may come from different helper functions. The tokens + /// produced by `quote!` themselves implement `ToTokens` and so can be + /// interpolated into later `quote!` invocations to build up a final result. + /// + /// ``` + /// # use quote::quote; + /// # + /// let type_definition = quote! {...}; + /// let methods = quote! {...}; + /// + /// let tokens = quote! { + /// #type_definition + /// #methods + /// }; + /// ``` + /// + ///


+ /// + /// ### Constructing identifiers + /// + /// Suppose we have an identifier `ident` which came from somewhere in a macro + /// input and we need to modify it in some way for the macro output. Let's + /// consider prepending the identifier with an underscore. + /// + /// Simply interpolating the identifier next to an underscore will not have the + /// behavior of concatenating them. The underscore and the identifier will + /// continue to be two separate tokens as if you had written `_ x`. + /// + /// ``` + /// # use proc_macro2::{self as syn, Span}; + /// # use quote::quote; + /// # + /// # let ident = syn::Ident::new("i", Span::call_site()); + /// # + /// // incorrect + /// quote! { + /// let mut _#ident = 0; + /// } + /// # ; + /// ``` + /// + /// The solution is to build a new identifier token with the correct value. As + /// this is such a common case, the [`format_ident!`] macro provides a + /// convenient utility for doing so correctly. + /// + /// ``` + /// # use proc_macro2::{Ident, Span}; + /// # use quote::{format_ident, quote}; + /// # + /// # let ident = Ident::new("i", Span::call_site()); + /// # + /// let varname = format_ident!("_{}", ident); + /// quote! { + /// let mut #varname = 0; + /// } + /// # ; + /// ``` + /// + /// Alternatively, the APIs provided by Syn and proc-macro2 can be used to + /// directly build the identifier. This is roughly equivalent to the above, but + /// will not handle `ident` being a raw identifier. + /// + /// ``` + /// # use proc_macro2::{self as syn, Span}; + /// # use quote::quote; + /// # + /// # let ident = syn::Ident::new("i", Span::call_site()); + /// # + /// let concatenated = format!("_{}", ident); + /// let varname = syn::Ident::new(&concatenated, ident.span()); + /// quote! { + /// let mut #varname = 0; + /// } + /// # ; + /// ``` + /// + ///


+ /// + /// ### Making method calls + /// + /// Let's say our macro requires some type specified in the macro input to have + /// a constructor called `new`. We have the type in a variable called + /// `field_type` of type `syn::Type` and want to invoke the constructor. + /// + /// ``` + /// # use quote::quote; + /// # + /// # let field_type = quote!(...); + /// # + /// // incorrect + /// quote! { + /// let value = #field_type::new(); + /// } + /// # ; + /// ``` + /// + /// This works only sometimes. If `field_type` is `String`, the expanded code + /// contains `String::new()` which is fine. But if `field_type` is something + /// like `Vec` then the expanded code is `Vec::new()` which is invalid + /// syntax. Ordinarily in handwritten Rust we would write `Vec::::new()` + /// but for macros often the following is more convenient. + /// + /// ``` + /// # use quote::quote; + /// # + /// # let field_type = quote!(...); + /// # + /// quote! { + /// let value = <#field_type>::new(); + /// } + /// # ; + /// ``` + /// + /// This expands to `>::new()` which behaves correctly. + /// + /// A similar pattern is appropriate for trait methods. + /// + /// ``` + /// # use quote::quote; + /// # + /// # let field_type = quote!(...); + /// # + /// quote! { + /// let value = <#field_type as core::default::Default>::default(); + /// } + /// # ; + /// ``` + /// + ///


+ /// + /// ### Interpolating text inside of doc comments + /// + /// Neither doc comments nor string literals get interpolation behavior in + /// quote: + /// + /// ```compile_fail + /// quote! { + /// /// try to interpolate: #ident + /// /// + /// /// ... + /// } + /// ``` + /// + /// ```compile_fail + /// quote! { + /// #[doc = "try to interpolate: #ident"] + /// } + /// ``` + /// + /// Instead the best way to build doc comments that involve variables is by + /// formatting the doc string literal outside of quote. + /// + /// ```rust + /// # use proc_macro2::{Ident, Span}; + /// # use quote::quote; + /// # + /// # const IGNORE: &str = stringify! { + /// let msg = format!(...); + /// # }; + /// # + /// # let ident = Ident::new("var", Span::call_site()); + /// # let msg = format!("try to interpolate: {}", ident); + /// quote! { + /// #[doc = #msg] + /// /// + /// /// ... + /// } + /// # ; + /// ``` + /// + ///


+ /// + /// ### Indexing into a tuple struct + /// + /// When interpolating indices of a tuple or tuple struct, we need them not to + /// appears suffixed as integer literals by interpolating them as [`syn::Index`] + /// instead. + /// + /// [`syn::Index`]: https://docs.rs/syn/2.0/syn/struct.Index.html + /// + /// ```compile_fail + /// let i = 0usize..self.fields.len(); + /// + /// // expands to 0 + self.0usize.heap_size() + self.1usize.heap_size() + ... + /// // which is not valid syntax + /// quote! { + /// 0 #( + self.#i.heap_size() )* + /// } + /// ``` + /// + /// ``` + /// # use proc_macro2::{Ident, TokenStream}; + /// # use quote::quote; + /// # + /// # mod syn { + /// # use proc_macro2::{Literal, TokenStream}; + /// # use quote::{ToTokens, TokenStreamExt}; + /// # + /// # pub struct Index(usize); + /// # + /// # impl From for Index { + /// # fn from(i: usize) -> Self { + /// # Index(i) + /// # } + /// # } + /// # + /// # impl ToTokens for Index { + /// # fn to_tokens(&self, tokens: &mut TokenStream) { + /// # tokens.append(Literal::usize_unsuffixed(self.0)); + /// # } + /// # } + /// # } + /// # + /// # struct Struct { + /// # fields: Vec, + /// # } + /// # + /// # impl Struct { + /// # fn example(&self) -> TokenStream { + /// let i = (0..self.fields.len()).map(syn::Index::from); + /// + /// // expands to 0 + self.0.heap_size() + self.1.heap_size() + ... + /// quote! { + /// 0 #( + self.#i.heap_size() )* + /// } + /// # } + /// # } + /// ``` + $quote + }; +} + +#[cfg(doc)] +__quote![ + #[macro_export] + macro_rules! quote { + ($($tt:tt)*) => { + ... + }; + } +]; + +#[cfg(not(doc))] +__quote![ + #[macro_export] + macro_rules! quote { + () => { + $crate::__private::TokenStream::new() + }; + + // Special case rule for a single tt, for performance. + ($tt:tt) => {{ + let mut _s = $crate::__private::TokenStream::new(); + $crate::quote_token!{$tt _s} + _s + }}; + + // Special case rules for two tts, for performance. + (# $var:ident) => {{ + let mut _s = $crate::__private::TokenStream::new(); + $crate::ToTokens::to_tokens(&$var, &mut _s); + _s + }}; + ($tt1:tt $tt2:tt) => {{ + let mut _s = $crate::__private::TokenStream::new(); + $crate::quote_token!{$tt1 _s} + $crate::quote_token!{$tt2 _s} + _s + }}; + + // Rule for any other number of tokens. + ($($tt:tt)*) => {{ + let mut _s = $crate::__private::TokenStream::new(); + $crate::quote_each_token!{_s $($tt)*} + _s + }}; + } +]; + +macro_rules! __quote_spanned { + ($quote_spanned:item) => { + /// Same as `quote!`, but applies a given span to all tokens originating within + /// the macro invocation. + /// + ///
+ /// + /// # Syntax + /// + /// A span expression of type [`Span`], followed by `=>`, followed by the tokens + /// to quote. The span expression should be brief — use a variable for + /// anything more than a few characters. There should be no space before the + /// `=>` token. + /// + /// [`Span`]: https://docs.rs/proc-macro2/1.0/proc_macro2/struct.Span.html + /// + /// ``` + /// # use proc_macro2::Span; + /// # use quote::quote_spanned; + /// # + /// # const IGNORE_TOKENS: &'static str = stringify! { + /// let span = /* ... */; + /// # }; + /// # let span = Span::call_site(); + /// # let init = 0; + /// + /// // On one line, use parentheses. + /// let tokens = quote_spanned!(span=> Box::into_raw(Box::new(#init))); + /// + /// // On multiple lines, place the span at the top and use braces. + /// let tokens = quote_spanned! {span=> + /// Box::into_raw(Box::new(#init)) + /// }; + /// ``` + /// + /// The lack of space before the `=>` should look jarring to Rust programmers + /// and this is intentional. The formatting is designed to be visibly + /// off-balance and draw the eye a particular way, due to the span expression + /// being evaluated in the context of the procedural macro and the remaining + /// tokens being evaluated in the generated code. + /// + ///
+ /// + /// # Hygiene + /// + /// Any interpolated tokens preserve the `Span` information provided by their + /// `ToTokens` implementation. Tokens that originate within the `quote_spanned!` + /// invocation are spanned with the given span argument. + /// + ///
+ /// + /// # Example + /// + /// The following procedural macro code uses `quote_spanned!` to assert that a + /// particular Rust type implements the [`Sync`] trait so that references can be + /// safely shared between threads. + /// + /// [`Sync`]: https://doc.rust-lang.org/std/marker/trait.Sync.html + /// + /// ``` + /// # use quote::{quote_spanned, TokenStreamExt, ToTokens}; + /// # use proc_macro2::{Span, TokenStream}; + /// # + /// # struct Type; + /// # + /// # impl Type { + /// # fn span(&self) -> Span { + /// # Span::call_site() + /// # } + /// # } + /// # + /// # impl ToTokens for Type { + /// # fn to_tokens(&self, _tokens: &mut TokenStream) {} + /// # } + /// # + /// # let ty = Type; + /// # let call_site = Span::call_site(); + /// # + /// let ty_span = ty.span(); + /// let assert_sync = quote_spanned! {ty_span=> + /// struct _AssertSync where #ty: Sync; + /// }; + /// ``` + /// + /// If the assertion fails, the user will see an error like the following. The + /// input span of their type is highlighted in the error. + /// + /// ```text + /// error[E0277]: the trait bound `*const (): std::marker::Sync` is not satisfied + /// --> src/main.rs:10:21 + /// | + /// 10 | static ref PTR: *const () = &(); + /// | ^^^^^^^^^ `*const ()` cannot be shared between threads safely + /// ``` + /// + /// In this example it is important for the where-clause to be spanned with the + /// line/column information of the user's input type so that error messages are + /// placed appropriately by the compiler. + $quote_spanned + }; +} + +#[cfg(doc)] +__quote_spanned![ + #[macro_export] + macro_rules! quote_spanned { + ($span:expr=> $($tt:tt)*) => { + ... + }; + } +]; + +#[cfg(not(doc))] +__quote_spanned![ + #[macro_export] + macro_rules! quote_spanned { + ($span:expr=>) => {{ + let _: $crate::__private::Span = $crate::__private::get_span($span).__into_span(); + $crate::__private::TokenStream::new() + }}; + + // Special case rule for a single tt, for performance. + ($span:expr=> $tt:tt) => {{ + let mut _s = $crate::__private::TokenStream::new(); + let _span: $crate::__private::Span = $crate::__private::get_span($span).__into_span(); + $crate::quote_token_spanned!{$tt _s _span} + _s + }}; + + // Special case rules for two tts, for performance. + ($span:expr=> # $var:ident) => {{ + let mut _s = $crate::__private::TokenStream::new(); + let _: $crate::__private::Span = $crate::__private::get_span($span).__into_span(); + $crate::ToTokens::to_tokens(&$var, &mut _s); + _s + }}; + ($span:expr=> $tt1:tt $tt2:tt) => {{ + let mut _s = $crate::__private::TokenStream::new(); + let _span: $crate::__private::Span = $crate::__private::get_span($span).__into_span(); + $crate::quote_token_spanned!{$tt1 _s _span} + $crate::quote_token_spanned!{$tt2 _s _span} + _s + }}; + + // Rule for any other number of tokens. + ($span:expr=> $($tt:tt)*) => {{ + let mut _s = $crate::__private::TokenStream::new(); + let _span: $crate::__private::Span = $crate::__private::get_span($span).__into_span(); + $crate::quote_each_token_spanned!{_s _span $($tt)*} + _s + }}; + } +]; + +// Extract the names of all #metavariables and pass them to the $call macro. +// +// in: pounded_var_names!(then!(...) a #b c #( #d )* #e) +// out: then!(... b); +// then!(... d); +// then!(... e); +#[macro_export] +#[doc(hidden)] +macro_rules! pounded_var_names { + ($call:ident! $extra:tt $($tts:tt)*) => { + $crate::pounded_var_names_with_context!{$call! $extra + (@ $($tts)*) + ($($tts)* @) + } + }; +} + +#[macro_export] +#[doc(hidden)] +macro_rules! pounded_var_names_with_context { + ($call:ident! $extra:tt ($($b1:tt)*) ($($curr:tt)*)) => { + $( + $crate::pounded_var_with_context!{$call! $extra $b1 $curr} + )* + }; +} + +#[macro_export] +#[doc(hidden)] +macro_rules! pounded_var_with_context { + ($call:ident! $extra:tt $b1:tt ( $($inner:tt)* )) => { + $crate::pounded_var_names!{$call! $extra $($inner)*} + }; + + ($call:ident! $extra:tt $b1:tt [ $($inner:tt)* ]) => { + $crate::pounded_var_names!{$call! $extra $($inner)*} + }; + + ($call:ident! $extra:tt $b1:tt { $($inner:tt)* }) => { + $crate::pounded_var_names!{$call! $extra $($inner)*} + }; + + ($call:ident!($($extra:tt)*) # $var:ident) => { + $crate::$call!($($extra)* $var); + }; + + ($call:ident! $extra:tt $b1:tt $curr:tt) => {}; +} + +#[macro_export] +#[doc(hidden)] +macro_rules! quote_bind_into_iter { + ($has_iter:ident $var:ident) => { + // `mut` may be unused if $var occurs multiple times in the list. + #[allow(unused_mut)] + let (mut $var, i) = $var.quote_into_iter(); + let $has_iter = $has_iter | i; + }; +} + +#[macro_export] +#[doc(hidden)] +macro_rules! quote_bind_next_or_break { + ($var:ident) => { + let $var = match $var.next() { + Some(_x) => $crate::__private::RepInterp(_x), + None => break, + }; + }; +} + +// The obvious way to write this macro is as a tt muncher. This implementation +// does something more complex for two reasons. +// +// - With a tt muncher it's easy to hit Rust's built-in recursion_limit, which +// this implementation avoids because it isn't tail recursive. +// +// - Compile times for a tt muncher are quadratic relative to the length of +// the input. This implementation is linear, so it will be faster +// (potentially much faster) for big inputs. However, the constant factors +// of this implementation are higher than that of a tt muncher, so it is +// somewhat slower than a tt muncher if there are many invocations with +// short inputs. +// +// An invocation like this: +// +// quote_each_token!(_s a b c d e f g h i j); +// +// expands to this: +// +// quote_tokens_with_context!(_s +// (@ @ @ @ @ @ a b c d e f g h i j) +// (@ @ @ @ @ a b c d e f g h i j @) +// (@ @ @ @ a b c d e f g h i j @ @) +// (@ @ @ (a) (b) (c) (d) (e) (f) (g) (h) (i) (j) @ @ @) +// (@ @ a b c d e f g h i j @ @ @ @) +// (@ a b c d e f g h i j @ @ @ @ @) +// (a b c d e f g h i j @ @ @ @ @ @) +// ); +// +// which gets transposed and expanded to this: +// +// quote_token_with_context!(_s @ @ @ @ @ @ a); +// quote_token_with_context!(_s @ @ @ @ @ a b); +// quote_token_with_context!(_s @ @ @ @ a b c); +// quote_token_with_context!(_s @ @ @ (a) b c d); +// quote_token_with_context!(_s @ @ a (b) c d e); +// quote_token_with_context!(_s @ a b (c) d e f); +// quote_token_with_context!(_s a b c (d) e f g); +// quote_token_with_context!(_s b c d (e) f g h); +// quote_token_with_context!(_s c d e (f) g h i); +// quote_token_with_context!(_s d e f (g) h i j); +// quote_token_with_context!(_s e f g (h) i j @); +// quote_token_with_context!(_s f g h (i) j @ @); +// quote_token_with_context!(_s g h i (j) @ @ @); +// quote_token_with_context!(_s h i j @ @ @ @); +// quote_token_with_context!(_s i j @ @ @ @ @); +// quote_token_with_context!(_s j @ @ @ @ @ @); +// +// Without having used muncher-style recursion, we get one invocation of +// quote_token_with_context for each original tt, with three tts of context on +// either side. This is enough for the longest possible interpolation form (a +// repetition with separator, as in `# (#var) , *`) to be fully represented with +// the first or last tt in the middle. +// +// The middle tt (surrounded by parentheses) is the tt being processed. +// +// - When it is a `#`, quote_token_with_context can do an interpolation. The +// interpolation kind will depend on the three subsequent tts. +// +// - When it is within a later part of an interpolation, it can be ignored +// because the interpolation has already been done. +// +// - When it is not part of an interpolation it can be pushed as a single +// token into the output. +// +// - When the middle token is an unparenthesized `@`, that call is one of the +// first 3 or last 3 calls of quote_token_with_context and does not +// correspond to one of the original input tokens, so turns into nothing. +#[macro_export] +#[doc(hidden)] +macro_rules! quote_each_token { + ($tokens:ident $($tts:tt)*) => { + $crate::quote_tokens_with_context!{$tokens + (@ @ @ @ @ @ $($tts)*) + (@ @ @ @ @ $($tts)* @) + (@ @ @ @ $($tts)* @ @) + (@ @ @ $(($tts))* @ @ @) + (@ @ $($tts)* @ @ @ @) + (@ $($tts)* @ @ @ @ @) + ($($tts)* @ @ @ @ @ @) + } + }; +} + +// See the explanation on quote_each_token. +#[macro_export] +#[doc(hidden)] +macro_rules! quote_each_token_spanned { + ($tokens:ident $span:ident $($tts:tt)*) => { + $crate::quote_tokens_with_context_spanned!{$tokens $span + (@ @ @ @ @ @ $($tts)*) + (@ @ @ @ @ $($tts)* @) + (@ @ @ @ $($tts)* @ @) + (@ @ @ $(($tts))* @ @ @) + (@ @ $($tts)* @ @ @ @) + (@ $($tts)* @ @ @ @ @) + ($($tts)* @ @ @ @ @ @) + } + }; +} + +// See the explanation on quote_each_token. +#[macro_export] +#[doc(hidden)] +macro_rules! quote_tokens_with_context { + ($tokens:ident + ($($b3:tt)*) ($($b2:tt)*) ($($b1:tt)*) + ($($curr:tt)*) + ($($a1:tt)*) ($($a2:tt)*) ($($a3:tt)*) + ) => { + $( + $crate::quote_token_with_context!{$tokens $b3 $b2 $b1 $curr $a1 $a2 $a3} + )* + }; +} + +// See the explanation on quote_each_token. +#[macro_export] +#[doc(hidden)] +macro_rules! quote_tokens_with_context_spanned { + ($tokens:ident $span:ident + ($($b3:tt)*) ($($b2:tt)*) ($($b1:tt)*) + ($($curr:tt)*) + ($($a1:tt)*) ($($a2:tt)*) ($($a3:tt)*) + ) => { + $( + $crate::quote_token_with_context_spanned!{$tokens $span $b3 $b2 $b1 $curr $a1 $a2 $a3} + )* + }; +} + +// See the explanation on quote_each_token. +#[macro_export] +#[doc(hidden)] +macro_rules! quote_token_with_context { + // Unparenthesized `@` indicates this call does not correspond to one of the + // original input tokens. Ignore it. + ($tokens:ident $b3:tt $b2:tt $b1:tt @ $a1:tt $a2:tt $a3:tt) => {}; + + // A repetition with no separator. + ($tokens:ident $b3:tt $b2:tt $b1:tt (#) ( $($inner:tt)* ) * $a3:tt) => {{ + use $crate::__private::ext::*; + let has_iter = $crate::__private::ThereIsNoIteratorInRepetition; + $crate::pounded_var_names!{quote_bind_into_iter!(has_iter) () $($inner)*} + let _: $crate::__private::HasIterator = has_iter; + // This is `while true` instead of `loop` because if there are no + // iterators used inside of this repetition then the body would not + // contain any `break`, so the compiler would emit unreachable code + // warnings on anything below the loop. We use has_iter to detect and + // fail to compile when there are no iterators, so here we just work + // around the unneeded extra warning. + while true { + $crate::pounded_var_names!{quote_bind_next_or_break!() () $($inner)*} + $crate::quote_each_token!{$tokens $($inner)*} + } + }}; + // ... and one step later. + ($tokens:ident $b3:tt $b2:tt # (( $($inner:tt)* )) * $a2:tt $a3:tt) => {}; + // ... and one step later. + ($tokens:ident $b3:tt # ( $($inner:tt)* ) (*) $a1:tt $a2:tt $a3:tt) => {}; + + // A repetition with separator. + ($tokens:ident $b3:tt $b2:tt $b1:tt (#) ( $($inner:tt)* ) $sep:tt *) => {{ + use $crate::__private::ext::*; + let mut _i = 0usize; + let has_iter = $crate::__private::ThereIsNoIteratorInRepetition; + $crate::pounded_var_names!{quote_bind_into_iter!(has_iter) () $($inner)*} + let _: $crate::__private::HasIterator = has_iter; + while true { + $crate::pounded_var_names!{quote_bind_next_or_break!() () $($inner)*} + if _i > 0 { + $crate::quote_token!{$sep $tokens} + } + _i += 1; + $crate::quote_each_token!{$tokens $($inner)*} + } + }}; + // ... and one step later. + ($tokens:ident $b3:tt $b2:tt # (( $($inner:tt)* )) $sep:tt * $a3:tt) => {}; + // ... and one step later. + ($tokens:ident $b3:tt # ( $($inner:tt)* ) ($sep:tt) * $a2:tt $a3:tt) => {}; + // (A special case for `#(var)**`, where the first `*` is treated as the + // repetition symbol and the second `*` is treated as an ordinary token.) + ($tokens:ident # ( $($inner:tt)* ) * (*) $a1:tt $a2:tt $a3:tt) => { + // https://github.com/dtolnay/quote/issues/130 + $crate::quote_token!{* $tokens} + }; + // ... and one step later. + ($tokens:ident # ( $($inner:tt)* ) $sep:tt (*) $a1:tt $a2:tt $a3:tt) => {}; + + // A non-repetition interpolation. + ($tokens:ident $b3:tt $b2:tt $b1:tt (#) $var:ident $a2:tt $a3:tt) => { + $crate::ToTokens::to_tokens(&$var, &mut $tokens); + }; + // ... and one step later. + ($tokens:ident $b3:tt $b2:tt # ($var:ident) $a1:tt $a2:tt $a3:tt) => {}; + + // An ordinary token, not part of any interpolation. + ($tokens:ident $b3:tt $b2:tt $b1:tt ($curr:tt) $a1:tt $a2:tt $a3:tt) => { + $crate::quote_token!{$curr $tokens} + }; +} + +// See the explanation on quote_each_token, and on the individual rules of +// quote_token_with_context. +#[macro_export] +#[doc(hidden)] +macro_rules! quote_token_with_context_spanned { + ($tokens:ident $span:ident $b3:tt $b2:tt $b1:tt @ $a1:tt $a2:tt $a3:tt) => {}; + + ($tokens:ident $span:ident $b3:tt $b2:tt $b1:tt (#) ( $($inner:tt)* ) * $a3:tt) => {{ + use $crate::__private::ext::*; + let has_iter = $crate::__private::ThereIsNoIteratorInRepetition; + $crate::pounded_var_names!{quote_bind_into_iter!(has_iter) () $($inner)*} + let _: $crate::__private::HasIterator = has_iter; + while true { + $crate::pounded_var_names!{quote_bind_next_or_break!() () $($inner)*} + $crate::quote_each_token_spanned!{$tokens $span $($inner)*} + } + }}; + ($tokens:ident $span:ident $b3:tt $b2:tt # (( $($inner:tt)* )) * $a2:tt $a3:tt) => {}; + ($tokens:ident $span:ident $b3:tt # ( $($inner:tt)* ) (*) $a1:tt $a2:tt $a3:tt) => {}; + + ($tokens:ident $span:ident $b3:tt $b2:tt $b1:tt (#) ( $($inner:tt)* ) $sep:tt *) => {{ + use $crate::__private::ext::*; + let mut _i = 0usize; + let has_iter = $crate::__private::ThereIsNoIteratorInRepetition; + $crate::pounded_var_names!{quote_bind_into_iter!(has_iter) () $($inner)*} + let _: $crate::__private::HasIterator = has_iter; + while true { + $crate::pounded_var_names!{quote_bind_next_or_break!() () $($inner)*} + if _i > 0 { + $crate::quote_token_spanned!{$sep $tokens $span} + } + _i += 1; + $crate::quote_each_token_spanned!{$tokens $span $($inner)*} + } + }}; + ($tokens:ident $span:ident $b3:tt $b2:tt # (( $($inner:tt)* )) $sep:tt * $a3:tt) => {}; + ($tokens:ident $span:ident $b3:tt # ( $($inner:tt)* ) ($sep:tt) * $a2:tt $a3:tt) => {}; + ($tokens:ident $span:ident # ( $($inner:tt)* ) * (*) $a1:tt $a2:tt $a3:tt) => { + // https://github.com/dtolnay/quote/issues/130 + $crate::quote_token_spanned!{* $tokens $span} + }; + ($tokens:ident $span:ident # ( $($inner:tt)* ) $sep:tt (*) $a1:tt $a2:tt $a3:tt) => {}; + + ($tokens:ident $span:ident $b3:tt $b2:tt $b1:tt (#) $var:ident $a2:tt $a3:tt) => { + $crate::ToTokens::to_tokens(&$var, &mut $tokens); + }; + ($tokens:ident $span:ident $b3:tt $b2:tt # ($var:ident) $a1:tt $a2:tt $a3:tt) => {}; + + ($tokens:ident $span:ident $b3:tt $b2:tt $b1:tt ($curr:tt) $a1:tt $a2:tt $a3:tt) => { + $crate::quote_token_spanned!{$curr $tokens $span} + }; +} + +// These rules are ordered by approximate token frequency, at least for the +// first 10 or so, to improve compile times. Having `ident` first is by far the +// most important because it's typically 2-3x more common than the next most +// common token. +// +// Separately, we put the token being matched in the very front so that failing +// rules may fail to match as quickly as possible. +#[macro_export] +#[doc(hidden)] +macro_rules! quote_token { + ($ident:ident $tokens:ident) => { + $crate::__private::push_ident(&mut $tokens, stringify!($ident)); + }; + + (:: $tokens:ident) => { + $crate::__private::push_colon2(&mut $tokens); + }; + + (( $($inner:tt)* ) $tokens:ident) => { + $crate::__private::push_group( + &mut $tokens, + $crate::__private::Delimiter::Parenthesis, + $crate::quote!($($inner)*), + ); + }; + + ([ $($inner:tt)* ] $tokens:ident) => { + $crate::__private::push_group( + &mut $tokens, + $crate::__private::Delimiter::Bracket, + $crate::quote!($($inner)*), + ); + }; + + ({ $($inner:tt)* } $tokens:ident) => { + $crate::__private::push_group( + &mut $tokens, + $crate::__private::Delimiter::Brace, + $crate::quote!($($inner)*), + ); + }; + + (# $tokens:ident) => { + $crate::__private::push_pound(&mut $tokens); + }; + + (, $tokens:ident) => { + $crate::__private::push_comma(&mut $tokens); + }; + + (. $tokens:ident) => { + $crate::__private::push_dot(&mut $tokens); + }; + + (; $tokens:ident) => { + $crate::__private::push_semi(&mut $tokens); + }; + + (: $tokens:ident) => { + $crate::__private::push_colon(&mut $tokens); + }; + + (+ $tokens:ident) => { + $crate::__private::push_add(&mut $tokens); + }; + + (+= $tokens:ident) => { + $crate::__private::push_add_eq(&mut $tokens); + }; + + (& $tokens:ident) => { + $crate::__private::push_and(&mut $tokens); + }; + + (&& $tokens:ident) => { + $crate::__private::push_and_and(&mut $tokens); + }; + + (&= $tokens:ident) => { + $crate::__private::push_and_eq(&mut $tokens); + }; + + (@ $tokens:ident) => { + $crate::__private::push_at(&mut $tokens); + }; + + (! $tokens:ident) => { + $crate::__private::push_bang(&mut $tokens); + }; + + (^ $tokens:ident) => { + $crate::__private::push_caret(&mut $tokens); + }; + + (^= $tokens:ident) => { + $crate::__private::push_caret_eq(&mut $tokens); + }; + + (/ $tokens:ident) => { + $crate::__private::push_div(&mut $tokens); + }; + + (/= $tokens:ident) => { + $crate::__private::push_div_eq(&mut $tokens); + }; + + (.. $tokens:ident) => { + $crate::__private::push_dot2(&mut $tokens); + }; + + (... $tokens:ident) => { + $crate::__private::push_dot3(&mut $tokens); + }; + + (..= $tokens:ident) => { + $crate::__private::push_dot_dot_eq(&mut $tokens); + }; + + (= $tokens:ident) => { + $crate::__private::push_eq(&mut $tokens); + }; + + (== $tokens:ident) => { + $crate::__private::push_eq_eq(&mut $tokens); + }; + + (>= $tokens:ident) => { + $crate::__private::push_ge(&mut $tokens); + }; + + (> $tokens:ident) => { + $crate::__private::push_gt(&mut $tokens); + }; + + (<= $tokens:ident) => { + $crate::__private::push_le(&mut $tokens); + }; + + (< $tokens:ident) => { + $crate::__private::push_lt(&mut $tokens); + }; + + (*= $tokens:ident) => { + $crate::__private::push_mul_eq(&mut $tokens); + }; + + (!= $tokens:ident) => { + $crate::__private::push_ne(&mut $tokens); + }; + + (| $tokens:ident) => { + $crate::__private::push_or(&mut $tokens); + }; + + (|= $tokens:ident) => { + $crate::__private::push_or_eq(&mut $tokens); + }; + + (|| $tokens:ident) => { + $crate::__private::push_or_or(&mut $tokens); + }; + + (? $tokens:ident) => { + $crate::__private::push_question(&mut $tokens); + }; + + (-> $tokens:ident) => { + $crate::__private::push_rarrow(&mut $tokens); + }; + + (<- $tokens:ident) => { + $crate::__private::push_larrow(&mut $tokens); + }; + + (% $tokens:ident) => { + $crate::__private::push_rem(&mut $tokens); + }; + + (%= $tokens:ident) => { + $crate::__private::push_rem_eq(&mut $tokens); + }; + + (=> $tokens:ident) => { + $crate::__private::push_fat_arrow(&mut $tokens); + }; + + (<< $tokens:ident) => { + $crate::__private::push_shl(&mut $tokens); + }; + + (<<= $tokens:ident) => { + $crate::__private::push_shl_eq(&mut $tokens); + }; + + (>> $tokens:ident) => { + $crate::__private::push_shr(&mut $tokens); + }; + + (>>= $tokens:ident) => { + $crate::__private::push_shr_eq(&mut $tokens); + }; + + (* $tokens:ident) => { + $crate::__private::push_star(&mut $tokens); + }; + + (- $tokens:ident) => { + $crate::__private::push_sub(&mut $tokens); + }; + + (-= $tokens:ident) => { + $crate::__private::push_sub_eq(&mut $tokens); + }; + + ($lifetime:lifetime $tokens:ident) => { + $crate::__private::push_lifetime(&mut $tokens, stringify!($lifetime)); + }; + + (_ $tokens:ident) => { + $crate::__private::push_underscore(&mut $tokens); + }; + + ($other:tt $tokens:ident) => { + $crate::__private::parse(&mut $tokens, stringify!($other)); + }; +} + +// See the comment above `quote_token!` about the rule ordering. +#[macro_export] +#[doc(hidden)] +macro_rules! quote_token_spanned { + ($ident:ident $tokens:ident $span:ident) => { + $crate::__private::push_ident_spanned(&mut $tokens, $span, stringify!($ident)); + }; + + (:: $tokens:ident $span:ident) => { + $crate::__private::push_colon2_spanned(&mut $tokens, $span); + }; + + (( $($inner:tt)* ) $tokens:ident $span:ident) => { + $crate::__private::push_group_spanned( + &mut $tokens, + $span, + $crate::__private::Delimiter::Parenthesis, + $crate::quote_spanned!($span=> $($inner)*), + ); + }; + + ([ $($inner:tt)* ] $tokens:ident $span:ident) => { + $crate::__private::push_group_spanned( + &mut $tokens, + $span, + $crate::__private::Delimiter::Bracket, + $crate::quote_spanned!($span=> $($inner)*), + ); + }; + + ({ $($inner:tt)* } $tokens:ident $span:ident) => { + $crate::__private::push_group_spanned( + &mut $tokens, + $span, + $crate::__private::Delimiter::Brace, + $crate::quote_spanned!($span=> $($inner)*), + ); + }; + + (# $tokens:ident $span:ident) => { + $crate::__private::push_pound_spanned(&mut $tokens, $span); + }; + + (, $tokens:ident $span:ident) => { + $crate::__private::push_comma_spanned(&mut $tokens, $span); + }; + + (. $tokens:ident $span:ident) => { + $crate::__private::push_dot_spanned(&mut $tokens, $span); + }; + + (; $tokens:ident $span:ident) => { + $crate::__private::push_semi_spanned(&mut $tokens, $span); + }; + + (: $tokens:ident $span:ident) => { + $crate::__private::push_colon_spanned(&mut $tokens, $span); + }; + + (+ $tokens:ident $span:ident) => { + $crate::__private::push_add_spanned(&mut $tokens, $span); + }; + + (+= $tokens:ident $span:ident) => { + $crate::__private::push_add_eq_spanned(&mut $tokens, $span); + }; + + (& $tokens:ident $span:ident) => { + $crate::__private::push_and_spanned(&mut $tokens, $span); + }; + + (&& $tokens:ident $span:ident) => { + $crate::__private::push_and_and_spanned(&mut $tokens, $span); + }; + + (&= $tokens:ident $span:ident) => { + $crate::__private::push_and_eq_spanned(&mut $tokens, $span); + }; + + (@ $tokens:ident $span:ident) => { + $crate::__private::push_at_spanned(&mut $tokens, $span); + }; + + (! $tokens:ident $span:ident) => { + $crate::__private::push_bang_spanned(&mut $tokens, $span); + }; + + (^ $tokens:ident $span:ident) => { + $crate::__private::push_caret_spanned(&mut $tokens, $span); + }; + + (^= $tokens:ident $span:ident) => { + $crate::__private::push_caret_eq_spanned(&mut $tokens, $span); + }; + + (/ $tokens:ident $span:ident) => { + $crate::__private::push_div_spanned(&mut $tokens, $span); + }; + + (/= $tokens:ident $span:ident) => { + $crate::__private::push_div_eq_spanned(&mut $tokens, $span); + }; + + (.. $tokens:ident $span:ident) => { + $crate::__private::push_dot2_spanned(&mut $tokens, $span); + }; + + (... $tokens:ident $span:ident) => { + $crate::__private::push_dot3_spanned(&mut $tokens, $span); + }; + + (..= $tokens:ident $span:ident) => { + $crate::__private::push_dot_dot_eq_spanned(&mut $tokens, $span); + }; + + (= $tokens:ident $span:ident) => { + $crate::__private::push_eq_spanned(&mut $tokens, $span); + }; + + (== $tokens:ident $span:ident) => { + $crate::__private::push_eq_eq_spanned(&mut $tokens, $span); + }; + + (>= $tokens:ident $span:ident) => { + $crate::__private::push_ge_spanned(&mut $tokens, $span); + }; + + (> $tokens:ident $span:ident) => { + $crate::__private::push_gt_spanned(&mut $tokens, $span); + }; + + (<= $tokens:ident $span:ident) => { + $crate::__private::push_le_spanned(&mut $tokens, $span); + }; + + (< $tokens:ident $span:ident) => { + $crate::__private::push_lt_spanned(&mut $tokens, $span); + }; + + (*= $tokens:ident $span:ident) => { + $crate::__private::push_mul_eq_spanned(&mut $tokens, $span); + }; + + (!= $tokens:ident $span:ident) => { + $crate::__private::push_ne_spanned(&mut $tokens, $span); + }; + + (| $tokens:ident $span:ident) => { + $crate::__private::push_or_spanned(&mut $tokens, $span); + }; + + (|= $tokens:ident $span:ident) => { + $crate::__private::push_or_eq_spanned(&mut $tokens, $span); + }; + + (|| $tokens:ident $span:ident) => { + $crate::__private::push_or_or_spanned(&mut $tokens, $span); + }; + + (? $tokens:ident $span:ident) => { + $crate::__private::push_question_spanned(&mut $tokens, $span); + }; + + (-> $tokens:ident $span:ident) => { + $crate::__private::push_rarrow_spanned(&mut $tokens, $span); + }; + + (<- $tokens:ident $span:ident) => { + $crate::__private::push_larrow_spanned(&mut $tokens, $span); + }; + + (% $tokens:ident $span:ident) => { + $crate::__private::push_rem_spanned(&mut $tokens, $span); + }; + + (%= $tokens:ident $span:ident) => { + $crate::__private::push_rem_eq_spanned(&mut $tokens, $span); + }; + + (=> $tokens:ident $span:ident) => { + $crate::__private::push_fat_arrow_spanned(&mut $tokens, $span); + }; + + (<< $tokens:ident $span:ident) => { + $crate::__private::push_shl_spanned(&mut $tokens, $span); + }; + + (<<= $tokens:ident $span:ident) => { + $crate::__private::push_shl_eq_spanned(&mut $tokens, $span); + }; + + (>> $tokens:ident $span:ident) => { + $crate::__private::push_shr_spanned(&mut $tokens, $span); + }; + + (>>= $tokens:ident $span:ident) => { + $crate::__private::push_shr_eq_spanned(&mut $tokens, $span); + }; + + (* $tokens:ident $span:ident) => { + $crate::__private::push_star_spanned(&mut $tokens, $span); + }; + + (- $tokens:ident $span:ident) => { + $crate::__private::push_sub_spanned(&mut $tokens, $span); + }; + + (-= $tokens:ident $span:ident) => { + $crate::__private::push_sub_eq_spanned(&mut $tokens, $span); + }; + + ($lifetime:lifetime $tokens:ident $span:ident) => { + $crate::__private::push_lifetime_spanned(&mut $tokens, $span, stringify!($lifetime)); + }; + + (_ $tokens:ident $span:ident) => { + $crate::__private::push_underscore_spanned(&mut $tokens, $span); + }; + + ($other:tt $tokens:ident $span:ident) => { + $crate::__private::parse_spanned(&mut $tokens, $span, stringify!($other)); + }; +} diff --git a/vendor/quote/src/runtime.rs b/vendor/quote/src/runtime.rs new file mode 100644 index 0000000..eff044a --- /dev/null +++ b/vendor/quote/src/runtime.rs @@ -0,0 +1,530 @@ +use self::get_span::{GetSpan, GetSpanBase, GetSpanInner}; +use crate::{IdentFragment, ToTokens, TokenStreamExt}; +use core::fmt; +use core::iter; +use core::ops::BitOr; +use proc_macro2::{Group, Ident, Punct, Spacing, TokenTree}; + +#[doc(hidden)] +pub use alloc::format; +#[doc(hidden)] +pub use core::option::Option; + +#[doc(hidden)] +pub type Delimiter = proc_macro2::Delimiter; +#[doc(hidden)] +pub type Span = proc_macro2::Span; +#[doc(hidden)] +pub type TokenStream = proc_macro2::TokenStream; + +#[doc(hidden)] +pub struct HasIterator; // True +#[doc(hidden)] +pub struct ThereIsNoIteratorInRepetition; // False + +impl BitOr for ThereIsNoIteratorInRepetition { + type Output = ThereIsNoIteratorInRepetition; + fn bitor(self, _rhs: ThereIsNoIteratorInRepetition) -> ThereIsNoIteratorInRepetition { + ThereIsNoIteratorInRepetition + } +} + +impl BitOr for HasIterator { + type Output = HasIterator; + fn bitor(self, _rhs: ThereIsNoIteratorInRepetition) -> HasIterator { + HasIterator + } +} + +impl BitOr for ThereIsNoIteratorInRepetition { + type Output = HasIterator; + fn bitor(self, _rhs: HasIterator) -> HasIterator { + HasIterator + } +} + +impl BitOr for HasIterator { + type Output = HasIterator; + fn bitor(self, _rhs: HasIterator) -> HasIterator { + HasIterator + } +} + +/// Extension traits used by the implementation of `quote!`. These are defined +/// in separate traits, rather than as a single trait due to ambiguity issues. +/// +/// These traits expose a `quote_into_iter` method which should allow calling +/// whichever impl happens to be applicable. Calling that method repeatedly on +/// the returned value should be idempotent. +#[doc(hidden)] +pub mod ext { + use super::RepInterp; + use super::{HasIterator as HasIter, ThereIsNoIteratorInRepetition as DoesNotHaveIter}; + use crate::ToTokens; + use alloc::collections::btree_set::{self, BTreeSet}; + use core::slice; + + /// Extension trait providing the `quote_into_iter` method on iterators. + #[doc(hidden)] + pub trait RepIteratorExt: Iterator + Sized { + fn quote_into_iter(self) -> (Self, HasIter) { + (self, HasIter) + } + } + + impl RepIteratorExt for T {} + + /// Extension trait providing the `quote_into_iter` method for + /// non-iterable types. These types interpolate the same value in each + /// iteration of the repetition. + #[doc(hidden)] + pub trait RepToTokensExt { + /// Pretend to be an iterator for the purposes of `quote_into_iter`. + /// This allows repeated calls to `quote_into_iter` to continue + /// correctly returning DoesNotHaveIter. + fn next(&self) -> Option<&Self> { + Some(self) + } + + fn quote_into_iter(&self) -> (&Self, DoesNotHaveIter) { + (self, DoesNotHaveIter) + } + } + + impl RepToTokensExt for T {} + + /// Extension trait providing the `quote_into_iter` method for types that + /// can be referenced as an iterator. + #[doc(hidden)] + pub trait RepAsIteratorExt<'q> { + type Iter: Iterator; + + fn quote_into_iter(&'q self) -> (Self::Iter, HasIter); + } + + impl<'q, 'a, T: RepAsIteratorExt<'q> + ?Sized> RepAsIteratorExt<'q> for &'a T { + type Iter = T::Iter; + + fn quote_into_iter(&'q self) -> (Self::Iter, HasIter) { + ::quote_into_iter(*self) + } + } + + impl<'q, 'a, T: RepAsIteratorExt<'q> + ?Sized> RepAsIteratorExt<'q> for &'a mut T { + type Iter = T::Iter; + + fn quote_into_iter(&'q self) -> (Self::Iter, HasIter) { + ::quote_into_iter(*self) + } + } + + impl<'q, T: 'q> RepAsIteratorExt<'q> for [T] { + type Iter = slice::Iter<'q, T>; + + fn quote_into_iter(&'q self) -> (Self::Iter, HasIter) { + (self.iter(), HasIter) + } + } + + impl<'q, T: 'q> RepAsIteratorExt<'q> for Vec { + type Iter = slice::Iter<'q, T>; + + fn quote_into_iter(&'q self) -> (Self::Iter, HasIter) { + (self.iter(), HasIter) + } + } + + impl<'q, T: 'q> RepAsIteratorExt<'q> for BTreeSet { + type Iter = btree_set::Iter<'q, T>; + + fn quote_into_iter(&'q self) -> (Self::Iter, HasIter) { + (self.iter(), HasIter) + } + } + + impl<'q, T: RepAsIteratorExt<'q>> RepAsIteratorExt<'q> for RepInterp { + type Iter = T::Iter; + + fn quote_into_iter(&'q self) -> (Self::Iter, HasIter) { + self.0.quote_into_iter() + } + } +} + +// Helper type used within interpolations to allow for repeated binding names. +// Implements the relevant traits, and exports a dummy `next()` method. +#[derive(Copy, Clone)] +#[doc(hidden)] +pub struct RepInterp(pub T); + +impl RepInterp { + // This method is intended to look like `Iterator::next`, and is called when + // a name is bound multiple times, as the previous binding will shadow the + // original `Iterator` object. This allows us to avoid advancing the + // iterator multiple times per iteration. + pub fn next(self) -> Option { + Some(self.0) + } +} + +impl Iterator for RepInterp { + type Item = T::Item; + + fn next(&mut self) -> Option { + self.0.next() + } +} + +impl ToTokens for RepInterp { + fn to_tokens(&self, tokens: &mut TokenStream) { + self.0.to_tokens(tokens); + } +} + +#[doc(hidden)] +#[inline] +pub fn get_span(span: T) -> GetSpan { + GetSpan(GetSpanInner(GetSpanBase(span))) +} + +mod get_span { + use core::ops::Deref; + use proc_macro2::extra::DelimSpan; + use proc_macro2::Span; + + pub struct GetSpan(pub(crate) GetSpanInner); + + pub struct GetSpanInner(pub(crate) GetSpanBase); + + pub struct GetSpanBase(pub(crate) T); + + impl GetSpan { + #[inline] + pub fn __into_span(self) -> Span { + ((self.0).0).0 + } + } + + impl GetSpanInner { + #[inline] + pub fn __into_span(&self) -> Span { + (self.0).0.join() + } + } + + impl GetSpanBase { + #[allow(clippy::unused_self)] + pub fn __into_span(&self) -> T { + unreachable!() + } + } + + impl Deref for GetSpan { + type Target = GetSpanInner; + + #[inline] + fn deref(&self) -> &Self::Target { + &self.0 + } + } + + impl Deref for GetSpanInner { + type Target = GetSpanBase; + + #[inline] + fn deref(&self) -> &Self::Target { + &self.0 + } + } +} + +#[doc(hidden)] +pub fn push_group(tokens: &mut TokenStream, delimiter: Delimiter, inner: TokenStream) { + tokens.append(Group::new(delimiter, inner)); +} + +#[doc(hidden)] +pub fn push_group_spanned( + tokens: &mut TokenStream, + span: Span, + delimiter: Delimiter, + inner: TokenStream, +) { + let mut g = Group::new(delimiter, inner); + g.set_span(span); + tokens.append(g); +} + +#[doc(hidden)] +pub fn parse(tokens: &mut TokenStream, s: &str) { + let s: TokenStream = s.parse().expect("invalid token stream"); + tokens.extend(iter::once(s)); +} + +#[doc(hidden)] +pub fn parse_spanned(tokens: &mut TokenStream, span: Span, s: &str) { + let s: TokenStream = s.parse().expect("invalid token stream"); + tokens.extend(s.into_iter().map(|t| respan_token_tree(t, span))); +} + +// Token tree with every span replaced by the given one. +fn respan_token_tree(mut token: TokenTree, span: Span) -> TokenTree { + match &mut token { + TokenTree::Group(g) => { + let stream = g + .stream() + .into_iter() + .map(|token| respan_token_tree(token, span)) + .collect(); + *g = Group::new(g.delimiter(), stream); + g.set_span(span); + } + other => other.set_span(span), + } + token +} + +#[doc(hidden)] +pub fn push_ident(tokens: &mut TokenStream, s: &str) { + let span = Span::call_site(); + push_ident_spanned(tokens, span, s); +} + +#[doc(hidden)] +pub fn push_ident_spanned(tokens: &mut TokenStream, span: Span, s: &str) { + tokens.append(ident_maybe_raw(s, span)); +} + +#[doc(hidden)] +pub fn push_lifetime(tokens: &mut TokenStream, lifetime: &str) { + struct Lifetime<'a> { + name: &'a str, + state: u8, + } + + impl<'a> Iterator for Lifetime<'a> { + type Item = TokenTree; + + fn next(&mut self) -> Option { + match self.state { + 0 => { + self.state = 1; + Some(TokenTree::Punct(Punct::new('\'', Spacing::Joint))) + } + 1 => { + self.state = 2; + Some(TokenTree::Ident(Ident::new(self.name, Span::call_site()))) + } + _ => None, + } + } + } + + tokens.extend(Lifetime { + name: &lifetime[1..], + state: 0, + }); +} + +#[doc(hidden)] +pub fn push_lifetime_spanned(tokens: &mut TokenStream, span: Span, lifetime: &str) { + struct Lifetime<'a> { + name: &'a str, + span: Span, + state: u8, + } + + impl<'a> Iterator for Lifetime<'a> { + type Item = TokenTree; + + fn next(&mut self) -> Option { + match self.state { + 0 => { + self.state = 1; + let mut apostrophe = Punct::new('\'', Spacing::Joint); + apostrophe.set_span(self.span); + Some(TokenTree::Punct(apostrophe)) + } + 1 => { + self.state = 2; + Some(TokenTree::Ident(Ident::new(self.name, self.span))) + } + _ => None, + } + } + } + + tokens.extend(Lifetime { + name: &lifetime[1..], + span, + state: 0, + }); +} + +macro_rules! push_punct { + ($name:ident $spanned:ident $char1:tt) => { + #[doc(hidden)] + pub fn $name(tokens: &mut TokenStream) { + tokens.append(Punct::new($char1, Spacing::Alone)); + } + #[doc(hidden)] + pub fn $spanned(tokens: &mut TokenStream, span: Span) { + let mut punct = Punct::new($char1, Spacing::Alone); + punct.set_span(span); + tokens.append(punct); + } + }; + ($name:ident $spanned:ident $char1:tt $char2:tt) => { + #[doc(hidden)] + pub fn $name(tokens: &mut TokenStream) { + tokens.append(Punct::new($char1, Spacing::Joint)); + tokens.append(Punct::new($char2, Spacing::Alone)); + } + #[doc(hidden)] + pub fn $spanned(tokens: &mut TokenStream, span: Span) { + let mut punct = Punct::new($char1, Spacing::Joint); + punct.set_span(span); + tokens.append(punct); + let mut punct = Punct::new($char2, Spacing::Alone); + punct.set_span(span); + tokens.append(punct); + } + }; + ($name:ident $spanned:ident $char1:tt $char2:tt $char3:tt) => { + #[doc(hidden)] + pub fn $name(tokens: &mut TokenStream) { + tokens.append(Punct::new($char1, Spacing::Joint)); + tokens.append(Punct::new($char2, Spacing::Joint)); + tokens.append(Punct::new($char3, Spacing::Alone)); + } + #[doc(hidden)] + pub fn $spanned(tokens: &mut TokenStream, span: Span) { + let mut punct = Punct::new($char1, Spacing::Joint); + punct.set_span(span); + tokens.append(punct); + let mut punct = Punct::new($char2, Spacing::Joint); + punct.set_span(span); + tokens.append(punct); + let mut punct = Punct::new($char3, Spacing::Alone); + punct.set_span(span); + tokens.append(punct); + } + }; +} + +push_punct!(push_add push_add_spanned '+'); +push_punct!(push_add_eq push_add_eq_spanned '+' '='); +push_punct!(push_and push_and_spanned '&'); +push_punct!(push_and_and push_and_and_spanned '&' '&'); +push_punct!(push_and_eq push_and_eq_spanned '&' '='); +push_punct!(push_at push_at_spanned '@'); +push_punct!(push_bang push_bang_spanned '!'); +push_punct!(push_caret push_caret_spanned '^'); +push_punct!(push_caret_eq push_caret_eq_spanned '^' '='); +push_punct!(push_colon push_colon_spanned ':'); +push_punct!(push_colon2 push_colon2_spanned ':' ':'); +push_punct!(push_comma push_comma_spanned ','); +push_punct!(push_div push_div_spanned '/'); +push_punct!(push_div_eq push_div_eq_spanned '/' '='); +push_punct!(push_dot push_dot_spanned '.'); +push_punct!(push_dot2 push_dot2_spanned '.' '.'); +push_punct!(push_dot3 push_dot3_spanned '.' '.' '.'); +push_punct!(push_dot_dot_eq push_dot_dot_eq_spanned '.' '.' '='); +push_punct!(push_eq push_eq_spanned '='); +push_punct!(push_eq_eq push_eq_eq_spanned '=' '='); +push_punct!(push_ge push_ge_spanned '>' '='); +push_punct!(push_gt push_gt_spanned '>'); +push_punct!(push_le push_le_spanned '<' '='); +push_punct!(push_lt push_lt_spanned '<'); +push_punct!(push_mul_eq push_mul_eq_spanned '*' '='); +push_punct!(push_ne push_ne_spanned '!' '='); +push_punct!(push_or push_or_spanned '|'); +push_punct!(push_or_eq push_or_eq_spanned '|' '='); +push_punct!(push_or_or push_or_or_spanned '|' '|'); +push_punct!(push_pound push_pound_spanned '#'); +push_punct!(push_question push_question_spanned '?'); +push_punct!(push_rarrow push_rarrow_spanned '-' '>'); +push_punct!(push_larrow push_larrow_spanned '<' '-'); +push_punct!(push_rem push_rem_spanned '%'); +push_punct!(push_rem_eq push_rem_eq_spanned '%' '='); +push_punct!(push_fat_arrow push_fat_arrow_spanned '=' '>'); +push_punct!(push_semi push_semi_spanned ';'); +push_punct!(push_shl push_shl_spanned '<' '<'); +push_punct!(push_shl_eq push_shl_eq_spanned '<' '<' '='); +push_punct!(push_shr push_shr_spanned '>' '>'); +push_punct!(push_shr_eq push_shr_eq_spanned '>' '>' '='); +push_punct!(push_star push_star_spanned '*'); +push_punct!(push_sub push_sub_spanned '-'); +push_punct!(push_sub_eq push_sub_eq_spanned '-' '='); + +#[doc(hidden)] +pub fn push_underscore(tokens: &mut TokenStream) { + push_underscore_spanned(tokens, Span::call_site()); +} + +#[doc(hidden)] +pub fn push_underscore_spanned(tokens: &mut TokenStream, span: Span) { + tokens.append(Ident::new("_", span)); +} + +// Helper method for constructing identifiers from the `format_ident!` macro, +// handling `r#` prefixes. +#[doc(hidden)] +pub fn mk_ident(id: &str, span: Option) -> Ident { + let span = span.unwrap_or_else(Span::call_site); + ident_maybe_raw(id, span) +} + +fn ident_maybe_raw(id: &str, span: Span) -> Ident { + if let Some(id) = id.strip_prefix("r#") { + Ident::new_raw(id, span) + } else { + Ident::new(id, span) + } +} + +// Adapts from `IdentFragment` to `fmt::Display` for use by the `format_ident!` +// macro, and exposes span information from these fragments. +// +// This struct also has forwarding implementations of the formatting traits +// `Octal`, `LowerHex`, `UpperHex`, and `Binary` to allow for their use within +// `format_ident!`. +#[derive(Copy, Clone)] +#[doc(hidden)] +pub struct IdentFragmentAdapter(pub T); + +impl IdentFragmentAdapter { + pub fn span(&self) -> Option { + self.0.span() + } +} + +impl fmt::Display for IdentFragmentAdapter { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + IdentFragment::fmt(&self.0, f) + } +} + +impl fmt::Octal for IdentFragmentAdapter { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fmt::Octal::fmt(&self.0, f) + } +} + +impl fmt::LowerHex for IdentFragmentAdapter { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fmt::LowerHex::fmt(&self.0, f) + } +} + +impl fmt::UpperHex for IdentFragmentAdapter { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fmt::UpperHex::fmt(&self.0, f) + } +} + +impl fmt::Binary for IdentFragmentAdapter { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fmt::Binary::fmt(&self.0, f) + } +} diff --git a/vendor/quote/src/spanned.rs b/vendor/quote/src/spanned.rs new file mode 100644 index 0000000..6eba644 --- /dev/null +++ b/vendor/quote/src/spanned.rs @@ -0,0 +1,50 @@ +use crate::ToTokens; +use proc_macro2::extra::DelimSpan; +use proc_macro2::{Span, TokenStream}; + +// Not public API other than via the syn crate. Use syn::spanned::Spanned. +pub trait Spanned: private::Sealed { + fn __span(&self) -> Span; +} + +impl Spanned for Span { + fn __span(&self) -> Span { + *self + } +} + +impl Spanned for DelimSpan { + fn __span(&self) -> Span { + self.join() + } +} + +impl Spanned for T { + fn __span(&self) -> Span { + join_spans(self.into_token_stream()) + } +} + +fn join_spans(tokens: TokenStream) -> Span { + let mut iter = tokens.into_iter().map(|tt| tt.span()); + + let first = match iter.next() { + Some(span) => span, + None => return Span::call_site(), + }; + + iter.fold(None, |_prev, next| Some(next)) + .and_then(|last| first.join(last)) + .unwrap_or(first) +} + +mod private { + use crate::ToTokens; + use proc_macro2::extra::DelimSpan; + use proc_macro2::Span; + + pub trait Sealed {} + impl Sealed for Span {} + impl Sealed for DelimSpan {} + impl Sealed for T {} +} diff --git a/vendor/quote/src/to_tokens.rs b/vendor/quote/src/to_tokens.rs new file mode 100644 index 0000000..2bcb961 --- /dev/null +++ b/vendor/quote/src/to_tokens.rs @@ -0,0 +1,275 @@ +use super::TokenStreamExt; +use alloc::borrow::Cow; +use alloc::rc::Rc; +use core::iter; +use proc_macro2::{Group, Ident, Literal, Punct, Span, TokenStream, TokenTree}; +use std::ffi::{CStr, CString}; + +/// Types that can be interpolated inside a `quote!` invocation. +/// +/// [`quote!`]: macro.quote.html +pub trait ToTokens { + /// Write `self` to the given `TokenStream`. + /// + /// The token append methods provided by the [`TokenStreamExt`] extension + /// trait may be useful for implementing `ToTokens`. + /// + /// [`TokenStreamExt`]: trait.TokenStreamExt.html + /// + /// # Example + /// + /// Example implementation for a struct representing Rust paths like + /// `std::cmp::PartialEq`: + /// + /// ``` + /// use proc_macro2::{TokenTree, Spacing, Span, Punct, TokenStream}; + /// use quote::{TokenStreamExt, ToTokens}; + /// + /// pub struct Path { + /// pub global: bool, + /// pub segments: Vec, + /// } + /// + /// impl ToTokens for Path { + /// fn to_tokens(&self, tokens: &mut TokenStream) { + /// for (i, segment) in self.segments.iter().enumerate() { + /// if i > 0 || self.global { + /// // Double colon `::` + /// tokens.append(Punct::new(':', Spacing::Joint)); + /// tokens.append(Punct::new(':', Spacing::Alone)); + /// } + /// segment.to_tokens(tokens); + /// } + /// } + /// } + /// # + /// # pub struct PathSegment; + /// # + /// # impl ToTokens for PathSegment { + /// # fn to_tokens(&self, tokens: &mut TokenStream) { + /// # unimplemented!() + /// # } + /// # } + /// ``` + fn to_tokens(&self, tokens: &mut TokenStream); + + /// Convert `self` directly into a `TokenStream` object. + /// + /// This method is implicitly implemented using `to_tokens`, and acts as a + /// convenience method for consumers of the `ToTokens` trait. + fn to_token_stream(&self) -> TokenStream { + let mut tokens = TokenStream::new(); + self.to_tokens(&mut tokens); + tokens + } + + /// Convert `self` directly into a `TokenStream` object. + /// + /// This method is implicitly implemented using `to_tokens`, and acts as a + /// convenience method for consumers of the `ToTokens` trait. + fn into_token_stream(self) -> TokenStream + where + Self: Sized, + { + self.to_token_stream() + } +} + +impl<'a, T: ?Sized + ToTokens> ToTokens for &'a T { + fn to_tokens(&self, tokens: &mut TokenStream) { + (**self).to_tokens(tokens); + } +} + +impl<'a, T: ?Sized + ToTokens> ToTokens for &'a mut T { + fn to_tokens(&self, tokens: &mut TokenStream) { + (**self).to_tokens(tokens); + } +} + +impl<'a, T: ?Sized + ToOwned + ToTokens> ToTokens for Cow<'a, T> { + fn to_tokens(&self, tokens: &mut TokenStream) { + (**self).to_tokens(tokens); + } +} + +impl ToTokens for Box { + fn to_tokens(&self, tokens: &mut TokenStream) { + (**self).to_tokens(tokens); + } +} + +impl ToTokens for Rc { + fn to_tokens(&self, tokens: &mut TokenStream) { + (**self).to_tokens(tokens); + } +} + +impl ToTokens for Option { + fn to_tokens(&self, tokens: &mut TokenStream) { + if let Some(t) = self { + t.to_tokens(tokens); + } + } +} + +impl ToTokens for str { + fn to_tokens(&self, tokens: &mut TokenStream) { + tokens.append(Literal::string(self)); + } +} + +impl ToTokens for String { + fn to_tokens(&self, tokens: &mut TokenStream) { + self.as_str().to_tokens(tokens); + } +} + +impl ToTokens for i8 { + fn to_tokens(&self, tokens: &mut TokenStream) { + tokens.append(Literal::i8_suffixed(*self)); + } +} + +impl ToTokens for i16 { + fn to_tokens(&self, tokens: &mut TokenStream) { + tokens.append(Literal::i16_suffixed(*self)); + } +} + +impl ToTokens for i32 { + fn to_tokens(&self, tokens: &mut TokenStream) { + tokens.append(Literal::i32_suffixed(*self)); + } +} + +impl ToTokens for i64 { + fn to_tokens(&self, tokens: &mut TokenStream) { + tokens.append(Literal::i64_suffixed(*self)); + } +} + +impl ToTokens for i128 { + fn to_tokens(&self, tokens: &mut TokenStream) { + tokens.append(Literal::i128_suffixed(*self)); + } +} + +impl ToTokens for isize { + fn to_tokens(&self, tokens: &mut TokenStream) { + tokens.append(Literal::isize_suffixed(*self)); + } +} + +impl ToTokens for u8 { + fn to_tokens(&self, tokens: &mut TokenStream) { + tokens.append(Literal::u8_suffixed(*self)); + } +} + +impl ToTokens for u16 { + fn to_tokens(&self, tokens: &mut TokenStream) { + tokens.append(Literal::u16_suffixed(*self)); + } +} + +impl ToTokens for u32 { + fn to_tokens(&self, tokens: &mut TokenStream) { + tokens.append(Literal::u32_suffixed(*self)); + } +} + +impl ToTokens for u64 { + fn to_tokens(&self, tokens: &mut TokenStream) { + tokens.append(Literal::u64_suffixed(*self)); + } +} + +impl ToTokens for u128 { + fn to_tokens(&self, tokens: &mut TokenStream) { + tokens.append(Literal::u128_suffixed(*self)); + } +} + +impl ToTokens for usize { + fn to_tokens(&self, tokens: &mut TokenStream) { + tokens.append(Literal::usize_suffixed(*self)); + } +} + +impl ToTokens for f32 { + fn to_tokens(&self, tokens: &mut TokenStream) { + tokens.append(Literal::f32_suffixed(*self)); + } +} + +impl ToTokens for f64 { + fn to_tokens(&self, tokens: &mut TokenStream) { + tokens.append(Literal::f64_suffixed(*self)); + } +} + +impl ToTokens for char { + fn to_tokens(&self, tokens: &mut TokenStream) { + tokens.append(Literal::character(*self)); + } +} + +impl ToTokens for bool { + fn to_tokens(&self, tokens: &mut TokenStream) { + let word = if *self { "true" } else { "false" }; + tokens.append(Ident::new(word, Span::call_site())); + } +} + +impl ToTokens for CStr { + fn to_tokens(&self, tokens: &mut TokenStream) { + tokens.append(Literal::c_string(self)); + } +} + +impl ToTokens for CString { + fn to_tokens(&self, tokens: &mut TokenStream) { + tokens.append(Literal::c_string(self)); + } +} + +impl ToTokens for Group { + fn to_tokens(&self, tokens: &mut TokenStream) { + tokens.append(self.clone()); + } +} + +impl ToTokens for Ident { + fn to_tokens(&self, tokens: &mut TokenStream) { + tokens.append(self.clone()); + } +} + +impl ToTokens for Punct { + fn to_tokens(&self, tokens: &mut TokenStream) { + tokens.append(self.clone()); + } +} + +impl ToTokens for Literal { + fn to_tokens(&self, tokens: &mut TokenStream) { + tokens.append(self.clone()); + } +} + +impl ToTokens for TokenTree { + fn to_tokens(&self, tokens: &mut TokenStream) { + tokens.append(self.clone()); + } +} + +impl ToTokens for TokenStream { + fn to_tokens(&self, tokens: &mut TokenStream) { + tokens.extend(iter::once(self.clone())); + } + + fn into_token_stream(self) -> TokenStream { + self + } +} diff --git a/vendor/quote/tests/compiletest.rs b/vendor/quote/tests/compiletest.rs new file mode 100644 index 0000000..23a6a06 --- /dev/null +++ b/vendor/quote/tests/compiletest.rs @@ -0,0 +1,7 @@ +#[rustversion::attr(not(nightly), ignore = "requires nightly")] +#[cfg_attr(miri, ignore = "incompatible with miri")] +#[test] +fn ui() { + let t = trybuild::TestCases::new(); + t.compile_fail("tests/ui/*.rs"); +} diff --git a/vendor/quote/tests/test.rs b/vendor/quote/tests/test.rs new file mode 100644 index 0000000..6ff1402 --- /dev/null +++ b/vendor/quote/tests/test.rs @@ -0,0 +1,565 @@ +#![allow( + clippy::disallowed_names, + clippy::let_underscore_untyped, + clippy::shadow_unrelated, + clippy::unseparated_literal_suffix, + clippy::used_underscore_binding +)] + +extern crate proc_macro; + +use proc_macro2::{Delimiter, Group, Ident, Span, TokenStream}; +use quote::{format_ident, quote, quote_spanned, TokenStreamExt}; +use std::borrow::Cow; +use std::collections::BTreeSet; +use std::ffi::{CStr, CString}; + +struct X; + +impl quote::ToTokens for X { + fn to_tokens(&self, tokens: &mut TokenStream) { + tokens.append(Ident::new("X", Span::call_site())); + } +} + +#[test] +fn test_quote_impl() { + let tokens = quote! { + impl<'a, T: ToTokens> ToTokens for &'a T { + fn to_tokens(&self, tokens: &mut TokenStream) { + (**self).to_tokens(tokens) + } + } + }; + + let expected = concat!( + "impl < 'a , T : ToTokens > ToTokens for & 'a T { ", + "fn to_tokens (& self , tokens : & mut TokenStream) { ", + "(* * self) . to_tokens (tokens) ", + "} ", + "}" + ); + + assert_eq!(expected, tokens.to_string()); +} + +#[test] +fn test_quote_spanned_impl() { + let span = Span::call_site(); + let tokens = quote_spanned! {span=> + impl<'a, T: ToTokens> ToTokens for &'a T { + fn to_tokens(&self, tokens: &mut TokenStream) { + (**self).to_tokens(tokens) + } + } + }; + + let expected = concat!( + "impl < 'a , T : ToTokens > ToTokens for & 'a T { ", + "fn to_tokens (& self , tokens : & mut TokenStream) { ", + "(* * self) . to_tokens (tokens) ", + "} ", + "}" + ); + + assert_eq!(expected, tokens.to_string()); +} + +#[test] +fn test_substitution() { + let x = X; + let tokens = quote!(#x <#x> (#x) [#x] {#x}); + + let expected = "X < X > (X) [X] { X }"; + + assert_eq!(expected, tokens.to_string()); +} + +#[test] +fn test_iter() { + let primes = &[X, X, X, X]; + + assert_eq!("X X X X", quote!(#(#primes)*).to_string()); + + assert_eq!("X , X , X , X ,", quote!(#(#primes,)*).to_string()); + + assert_eq!("X , X , X , X", quote!(#(#primes),*).to_string()); +} + +#[test] +fn test_array() { + let array: [u8; 40] = [0; 40]; + let _ = quote!(#(#array #array)*); + + let ref_array: &[u8; 40] = &[0; 40]; + let _ = quote!(#(#ref_array #ref_array)*); + + let ref_slice: &[u8] = &[0; 40]; + let _ = quote!(#(#ref_slice #ref_slice)*); + + let array: [X; 2] = [X, X]; // !Copy + let _ = quote!(#(#array #array)*); + + let ref_array: &[X; 2] = &[X, X]; + let _ = quote!(#(#ref_array #ref_array)*); + + let ref_slice: &[X] = &[X, X]; + let _ = quote!(#(#ref_slice #ref_slice)*); +} + +#[test] +fn test_advanced() { + let generics = quote!( <'a, T> ); + + let where_clause = quote!( where T: Serialize ); + + let field_ty = quote!(String); + + let item_ty = quote!(Cow<'a, str>); + + let path = quote!(SomeTrait::serialize_with); + + let value = quote!(self.x); + + let tokens = quote! { + struct SerializeWith #generics #where_clause { + value: &'a #field_ty, + phantom: ::std::marker::PhantomData<#item_ty>, + } + + impl #generics ::serde::Serialize for SerializeWith #generics #where_clause { + fn serialize(&self, s: &mut S) -> Result<(), S::Error> + where S: ::serde::Serializer + { + #path(self.value, s) + } + } + + SerializeWith { + value: #value, + phantom: ::std::marker::PhantomData::<#item_ty>, + } + }; + + let expected = concat!( + "struct SerializeWith < 'a , T > where T : Serialize { ", + "value : & 'a String , ", + "phantom : :: std :: marker :: PhantomData < Cow < 'a , str > > , ", + "} ", + "impl < 'a , T > :: serde :: Serialize for SerializeWith < 'a , T > where T : Serialize { ", + "fn serialize < S > (& self , s : & mut S) -> Result < () , S :: Error > ", + "where S : :: serde :: Serializer ", + "{ ", + "SomeTrait :: serialize_with (self . value , s) ", + "} ", + "} ", + "SerializeWith { ", + "value : self . x , ", + "phantom : :: std :: marker :: PhantomData :: < Cow < 'a , str > > , ", + "}" + ); + + assert_eq!(expected, tokens.to_string()); +} + +#[test] +fn test_integer() { + let ii8 = -1i8; + let ii16 = -1i16; + let ii32 = -1i32; + let ii64 = -1i64; + let ii128 = -1i128; + let iisize = -1isize; + let uu8 = 1u8; + let uu16 = 1u16; + let uu32 = 1u32; + let uu64 = 1u64; + let uu128 = 1u128; + let uusize = 1usize; + + let tokens = quote! { + 1 1i32 1u256 + #ii8 #ii16 #ii32 #ii64 #ii128 #iisize + #uu8 #uu16 #uu32 #uu64 #uu128 #uusize + }; + let expected = + "1 1i32 1u256 - 1i8 - 1i16 - 1i32 - 1i64 - 1i128 - 1isize 1u8 1u16 1u32 1u64 1u128 1usize"; + assert_eq!(expected, tokens.to_string()); +} + +#[test] +fn test_floating() { + let e32 = 2.345f32; + + let e64 = 2.345f64; + + let tokens = quote! { + #e32 + #e64 + }; + let expected = concat!("2.345f32 2.345f64"); + assert_eq!(expected, tokens.to_string()); +} + +#[test] +fn test_char() { + let zero = '\u{1}'; + let pound = '#'; + let quote = '"'; + let apost = '\''; + let newline = '\n'; + let heart = '\u{2764}'; + + let tokens = quote! { + #zero #pound #quote #apost #newline #heart + }; + let expected = "'\\u{1}' '#' '\"' '\\'' '\\n' '\u{2764}'"; + assert_eq!(expected, tokens.to_string()); +} + +#[test] +fn test_str() { + let s = "\u{1} a 'b \" c"; + let tokens = quote!(#s); + let expected = "\"\\u{1} a 'b \\\" c\""; + assert_eq!(expected, tokens.to_string()); +} + +#[test] +fn test_string() { + let s = "\u{1} a 'b \" c".to_string(); + let tokens = quote!(#s); + let expected = "\"\\u{1} a 'b \\\" c\""; + assert_eq!(expected, tokens.to_string()); +} + +#[test] +fn test_c_str() { + let s = CStr::from_bytes_with_nul(b"\x01 a 'b \" c\0").unwrap(); + let tokens = quote!(#s); + let expected = "c\"\\u{1} a 'b \\\" c\""; + assert_eq!(expected, tokens.to_string()); +} + +#[test] +fn test_c_string() { + let s = CString::new(&b"\x01 a 'b \" c"[..]).unwrap(); + let tokens = quote!(#s); + let expected = "c\"\\u{1} a 'b \\\" c\""; + assert_eq!(expected, tokens.to_string()); +} + +#[test] +fn test_interpolated_literal() { + macro_rules! m { + ($literal:literal) => { + quote!($literal) + }; + } + + let tokens = m!(1); + let expected = "1"; + assert_eq!(expected, tokens.to_string()); + + let tokens = m!(-1); + let expected = "- 1"; + assert_eq!(expected, tokens.to_string()); + + let tokens = m!(true); + let expected = "true"; + assert_eq!(expected, tokens.to_string()); + + let tokens = m!(-true); + let expected = "- true"; + assert_eq!(expected, tokens.to_string()); +} + +#[test] +fn test_ident() { + let foo = Ident::new("Foo", Span::call_site()); + let bar = Ident::new(&format!("Bar{}", 7), Span::call_site()); + let tokens = quote!(struct #foo; enum #bar {}); + let expected = "struct Foo ; enum Bar7 { }"; + assert_eq!(expected, tokens.to_string()); +} + +#[test] +fn test_underscore() { + let tokens = quote!(let _;); + let expected = "let _ ;"; + assert_eq!(expected, tokens.to_string()); +} + +#[test] +fn test_duplicate() { + let ch = 'x'; + + let tokens = quote!(#ch #ch); + + let expected = "'x' 'x'"; + assert_eq!(expected, tokens.to_string()); +} + +#[test] +fn test_fancy_repetition() { + let foo = vec!["a", "b"]; + let bar = vec![true, false]; + + let tokens = quote! { + #(#foo: #bar),* + }; + + let expected = r#""a" : true , "b" : false"#; + assert_eq!(expected, tokens.to_string()); +} + +#[test] +fn test_nested_fancy_repetition() { + let nested = vec![vec!['a', 'b', 'c'], vec!['x', 'y', 'z']]; + + let tokens = quote! { + #( + #(#nested)* + ),* + }; + + let expected = "'a' 'b' 'c' , 'x' 'y' 'z'"; + assert_eq!(expected, tokens.to_string()); +} + +#[test] +fn test_duplicate_name_repetition() { + let foo = &["a", "b"]; + + let tokens = quote! { + #(#foo: #foo),* + #(#foo: #foo),* + }; + + let expected = r#""a" : "a" , "b" : "b" "a" : "a" , "b" : "b""#; + assert_eq!(expected, tokens.to_string()); +} + +#[test] +fn test_duplicate_name_repetition_no_copy() { + let foo = vec!["a".to_owned(), "b".to_owned()]; + + let tokens = quote! { + #(#foo: #foo),* + }; + + let expected = r#""a" : "a" , "b" : "b""#; + assert_eq!(expected, tokens.to_string()); +} + +#[test] +fn test_btreeset_repetition() { + let mut set = BTreeSet::new(); + set.insert("a".to_owned()); + set.insert("b".to_owned()); + + let tokens = quote! { + #(#set: #set),* + }; + + let expected = r#""a" : "a" , "b" : "b""#; + assert_eq!(expected, tokens.to_string()); +} + +#[test] +fn test_variable_name_conflict() { + // The implementation of `#(...),*` uses the variable `_i` but it should be + // fine, if a little confusing when debugging. + let _i = vec!['a', 'b']; + let tokens = quote! { #(#_i),* }; + let expected = "'a' , 'b'"; + assert_eq!(expected, tokens.to_string()); +} + +#[test] +fn test_nonrep_in_repetition() { + let rep = vec!["a", "b"]; + let nonrep = "c"; + + let tokens = quote! { + #(#rep #rep : #nonrep #nonrep),* + }; + + let expected = r#""a" "a" : "c" "c" , "b" "b" : "c" "c""#; + assert_eq!(expected, tokens.to_string()); +} + +#[test] +fn test_empty_quote() { + let tokens = quote!(); + assert_eq!("", tokens.to_string()); +} + +#[test] +fn test_box_str() { + let b = "str".to_owned().into_boxed_str(); + let tokens = quote! { #b }; + assert_eq!("\"str\"", tokens.to_string()); +} + +#[test] +fn test_cow() { + let owned: Cow = Cow::Owned(Ident::new("owned", Span::call_site())); + + let ident = Ident::new("borrowed", Span::call_site()); + let borrowed = Cow::Borrowed(&ident); + + let tokens = quote! { #owned #borrowed }; + assert_eq!("owned borrowed", tokens.to_string()); +} + +#[test] +fn test_closure() { + fn field_i(i: usize) -> Ident { + format_ident!("__field{}", i) + } + + let fields = (0usize..3) + .map(field_i as fn(_) -> _) + .map(|var| quote! { #var }); + + let tokens = quote! { #(#fields)* }; + assert_eq!("__field0 __field1 __field2", tokens.to_string()); +} + +#[test] +fn test_append_tokens() { + let mut a = quote!(a); + let b = quote!(b); + a.append_all(b); + assert_eq!("a b", a.to_string()); +} + +#[test] +fn test_format_ident() { + let id0 = format_ident!("Aa"); + let id1 = format_ident!("Hello{x}", x = id0); + let id2 = format_ident!("Hello{x}", x = 5usize); + let id3 = format_ident!("Hello{}_{x}", id0, x = 10usize); + let id4 = format_ident!("Aa", span = Span::call_site()); + let id5 = format_ident!("Hello{}", Cow::Borrowed("World")); + + assert_eq!(id0, "Aa"); + assert_eq!(id1, "HelloAa"); + assert_eq!(id2, "Hello5"); + assert_eq!(id3, "HelloAa_10"); + assert_eq!(id4, "Aa"); + assert_eq!(id5, "HelloWorld"); +} + +#[test] +fn test_format_ident_strip_raw() { + let id = format_ident!("r#struct"); + let my_id = format_ident!("MyId{}", id); + let raw_my_id = format_ident!("r#MyId{}", id); + + assert_eq!(id, "r#struct"); + assert_eq!(my_id, "MyIdstruct"); + assert_eq!(raw_my_id, "r#MyIdstruct"); +} + +#[test] +fn test_outer_line_comment() { + let tokens = quote! { + /// doc + }; + let expected = "# [doc = r\" doc\"]"; + assert_eq!(expected, tokens.to_string()); +} + +#[test] +fn test_inner_line_comment() { + let tokens = quote! { + //! doc + }; + let expected = "# ! [doc = r\" doc\"]"; + assert_eq!(expected, tokens.to_string()); +} + +#[test] +fn test_outer_block_comment() { + let tokens = quote! { + /** doc */ + }; + let expected = "# [doc = r\" doc \"]"; + assert_eq!(expected, tokens.to_string()); +} + +#[test] +fn test_inner_block_comment() { + let tokens = quote! { + /*! doc */ + }; + let expected = "# ! [doc = r\" doc \"]"; + assert_eq!(expected, tokens.to_string()); +} + +#[test] +fn test_outer_attr() { + let tokens = quote! { + #[inline] + }; + let expected = "# [inline]"; + assert_eq!(expected, tokens.to_string()); +} + +#[test] +fn test_inner_attr() { + let tokens = quote! { + #![no_std] + }; + let expected = "# ! [no_std]"; + assert_eq!(expected, tokens.to_string()); +} + +// https://github.com/dtolnay/quote/issues/130 +#[test] +fn test_star_after_repetition() { + let c = vec!['0', '1']; + let tokens = quote! { + #( + f(#c); + )* + *out = None; + }; + let expected = "f ('0') ; f ('1') ; * out = None ;"; + assert_eq!(expected, tokens.to_string()); +} + +#[test] +fn test_quote_raw_id() { + let id = quote!(r#raw_id); + assert_eq!(id.to_string(), "r#raw_id"); +} + +#[test] +fn test_type_inference_for_span() { + trait CallSite { + fn get() -> Self; + } + + impl CallSite for Span { + fn get() -> Self { + Span::call_site() + } + } + + let span = Span::call_site(); + let _ = quote_spanned!(span=> ...); + + let delim_span = Group::new(Delimiter::Parenthesis, TokenStream::new()).delim_span(); + let _ = quote_spanned!(delim_span=> ...); + + let inferred = CallSite::get(); + let _ = quote_spanned!(inferred=> ...); + + if false { + let proc_macro_span = proc_macro::Span::call_site(); + let _ = quote_spanned!(proc_macro_span.into()=> ...); + } +} diff --git a/vendor/quote/tests/ui/does-not-have-iter-interpolated-dup.rs b/vendor/quote/tests/ui/does-not-have-iter-interpolated-dup.rs new file mode 100644 index 0000000..0a39f41 --- /dev/null +++ b/vendor/quote/tests/ui/does-not-have-iter-interpolated-dup.rs @@ -0,0 +1,9 @@ +use quote::quote; + +fn main() { + let nonrep = ""; + + // Without some protection against repetitions with no iterator somewhere + // inside, this would loop infinitely. + quote!(#(#nonrep #nonrep)*); +} diff --git a/vendor/quote/tests/ui/does-not-have-iter-interpolated-dup.stderr b/vendor/quote/tests/ui/does-not-have-iter-interpolated-dup.stderr new file mode 100644 index 0000000..99c20a5 --- /dev/null +++ b/vendor/quote/tests/ui/does-not-have-iter-interpolated-dup.stderr @@ -0,0 +1,11 @@ +error[E0308]: mismatched types + --> tests/ui/does-not-have-iter-interpolated-dup.rs:8:5 + | +8 | quote!(#(#nonrep #nonrep)*); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | expected `HasIterator`, found `ThereIsNoIteratorInRepetition` + | expected due to this + | here the type of `has_iter` is inferred to be `ThereIsNoIteratorInRepetition` + | + = note: this error originates in the macro `$crate::quote_token_with_context` which comes from the expansion of the macro `quote` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/vendor/quote/tests/ui/does-not-have-iter-interpolated.rs b/vendor/quote/tests/ui/does-not-have-iter-interpolated.rs new file mode 100644 index 0000000..2c740cc --- /dev/null +++ b/vendor/quote/tests/ui/does-not-have-iter-interpolated.rs @@ -0,0 +1,9 @@ +use quote::quote; + +fn main() { + let nonrep = ""; + + // Without some protection against repetitions with no iterator somewhere + // inside, this would loop infinitely. + quote!(#(#nonrep)*); +} diff --git a/vendor/quote/tests/ui/does-not-have-iter-interpolated.stderr b/vendor/quote/tests/ui/does-not-have-iter-interpolated.stderr new file mode 100644 index 0000000..ef90813 --- /dev/null +++ b/vendor/quote/tests/ui/does-not-have-iter-interpolated.stderr @@ -0,0 +1,11 @@ +error[E0308]: mismatched types + --> tests/ui/does-not-have-iter-interpolated.rs:8:5 + | +8 | quote!(#(#nonrep)*); + | ^^^^^^^^^^^^^^^^^^^ + | | + | expected `HasIterator`, found `ThereIsNoIteratorInRepetition` + | expected due to this + | here the type of `has_iter` is inferred to be `ThereIsNoIteratorInRepetition` + | + = note: this error originates in the macro `$crate::quote_token_with_context` which comes from the expansion of the macro `quote` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/vendor/quote/tests/ui/does-not-have-iter-separated.rs b/vendor/quote/tests/ui/does-not-have-iter-separated.rs new file mode 100644 index 0000000..c027243 --- /dev/null +++ b/vendor/quote/tests/ui/does-not-have-iter-separated.rs @@ -0,0 +1,5 @@ +use quote::quote; + +fn main() { + quote!(#(a b),*); +} diff --git a/vendor/quote/tests/ui/does-not-have-iter-separated.stderr b/vendor/quote/tests/ui/does-not-have-iter-separated.stderr new file mode 100644 index 0000000..7c6e30f --- /dev/null +++ b/vendor/quote/tests/ui/does-not-have-iter-separated.stderr @@ -0,0 +1,10 @@ +error[E0308]: mismatched types + --> tests/ui/does-not-have-iter-separated.rs:4:5 + | +4 | quote!(#(a b),*); + | ^^^^^^^^^^^^^^^^ + | | + | expected `HasIterator`, found `ThereIsNoIteratorInRepetition` + | expected due to this + | + = note: this error originates in the macro `$crate::quote_token_with_context` which comes from the expansion of the macro `quote` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/vendor/quote/tests/ui/does-not-have-iter.rs b/vendor/quote/tests/ui/does-not-have-iter.rs new file mode 100644 index 0000000..8908353 --- /dev/null +++ b/vendor/quote/tests/ui/does-not-have-iter.rs @@ -0,0 +1,5 @@ +use quote::quote; + +fn main() { + quote!(#(a b)*); +} diff --git a/vendor/quote/tests/ui/does-not-have-iter.stderr b/vendor/quote/tests/ui/does-not-have-iter.stderr new file mode 100644 index 0000000..0b13e5c --- /dev/null +++ b/vendor/quote/tests/ui/does-not-have-iter.stderr @@ -0,0 +1,10 @@ +error[E0308]: mismatched types + --> tests/ui/does-not-have-iter.rs:4:5 + | +4 | quote!(#(a b)*); + | ^^^^^^^^^^^^^^^ + | | + | expected `HasIterator`, found `ThereIsNoIteratorInRepetition` + | expected due to this + | + = note: this error originates in the macro `$crate::quote_token_with_context` which comes from the expansion of the macro `quote` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/vendor/quote/tests/ui/not-quotable.rs b/vendor/quote/tests/ui/not-quotable.rs new file mode 100644 index 0000000..f991c18 --- /dev/null +++ b/vendor/quote/tests/ui/not-quotable.rs @@ -0,0 +1,7 @@ +use quote::quote; +use std::net::Ipv4Addr; + +fn main() { + let ip = Ipv4Addr::LOCALHOST; + let _ = quote! { #ip }; +} diff --git a/vendor/quote/tests/ui/not-quotable.stderr b/vendor/quote/tests/ui/not-quotable.stderr new file mode 100644 index 0000000..3196266 --- /dev/null +++ b/vendor/quote/tests/ui/not-quotable.stderr @@ -0,0 +1,20 @@ +error[E0277]: the trait bound `Ipv4Addr: ToTokens` is not satisfied + --> tests/ui/not-quotable.rs:6:13 + | +6 | let _ = quote! { #ip }; + | ^^^^^^^^^^^^^^ + | | + | the trait `ToTokens` is not implemented for `Ipv4Addr` + | required by a bound introduced by this call + | + = help: the following other types implement trait `ToTokens`: + &'a T + &'a mut T + Box + CStr + CString + Cow<'a, T> + Option + Rc + and $N others + = note: this error originates in the macro `quote` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/vendor/quote/tests/ui/not-repeatable.rs b/vendor/quote/tests/ui/not-repeatable.rs new file mode 100644 index 0000000..a8f0fe7 --- /dev/null +++ b/vendor/quote/tests/ui/not-repeatable.rs @@ -0,0 +1,8 @@ +use quote::quote; + +struct Ipv4Addr; + +fn main() { + let ip = Ipv4Addr; + let _ = quote! { #(#ip)* }; +} diff --git a/vendor/quote/tests/ui/not-repeatable.stderr b/vendor/quote/tests/ui/not-repeatable.stderr new file mode 100644 index 0000000..26932bb --- /dev/null +++ b/vendor/quote/tests/ui/not-repeatable.stderr @@ -0,0 +1,34 @@ +error[E0599]: the method `quote_into_iter` exists for struct `Ipv4Addr`, but its trait bounds were not satisfied + --> tests/ui/not-repeatable.rs:7:13 + | +3 | struct Ipv4Addr; + | --------------- method `quote_into_iter` not found for this struct because it doesn't satisfy `Ipv4Addr: Iterator`, `Ipv4Addr: ToTokens`, `Ipv4Addr: ext::RepIteratorExt` or `Ipv4Addr: ext::RepToTokensExt` +... +7 | let _ = quote! { #(#ip)* }; + | ^^^^^^^^^^^^^^^^^^ method cannot be called on `Ipv4Addr` due to unsatisfied trait bounds + | + = note: the following trait bounds were not satisfied: + `Ipv4Addr: Iterator` + which is required by `Ipv4Addr: ext::RepIteratorExt` + `&Ipv4Addr: Iterator` + which is required by `&Ipv4Addr: ext::RepIteratorExt` + `Ipv4Addr: ToTokens` + which is required by `Ipv4Addr: ext::RepToTokensExt` + `&mut Ipv4Addr: Iterator` + which is required by `&mut Ipv4Addr: ext::RepIteratorExt` +note: the traits `Iterator` and `ToTokens` must be implemented + --> src/to_tokens.rs + | + | pub trait ToTokens { + | ^^^^^^^^^^^^^^^^^^ + | + ::: $RUST/core/src/iter/traits/iterator.rs + | + | pub trait Iterator { + | ^^^^^^^^^^^^^^^^^^ + = help: items from traits can only be used if the trait is implemented and in scope + = note: the following traits define an item `quote_into_iter`, perhaps you need to implement one of them: + candidate #1: `ext::RepAsIteratorExt` + candidate #2: `ext::RepIteratorExt` + candidate #3: `ext::RepToTokensExt` + = note: this error originates in the macro `$crate::quote_bind_into_iter` which comes from the expansion of the macro `quote` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/vendor/quote/tests/ui/wrong-type-span.rs b/vendor/quote/tests/ui/wrong-type-span.rs new file mode 100644 index 0000000..d5601c8 --- /dev/null +++ b/vendor/quote/tests/ui/wrong-type-span.rs @@ -0,0 +1,7 @@ +use quote::quote_spanned; + +fn main() { + let span = ""; + let x = 0i32; + quote_spanned!(span=> #x); +} diff --git a/vendor/quote/tests/ui/wrong-type-span.stderr b/vendor/quote/tests/ui/wrong-type-span.stderr new file mode 100644 index 0000000..12ad307 --- /dev/null +++ b/vendor/quote/tests/ui/wrong-type-span.stderr @@ -0,0 +1,10 @@ +error[E0308]: mismatched types + --> tests/ui/wrong-type-span.rs:6:5 + | +6 | quote_spanned!(span=> #x); + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | expected `Span`, found `&str` + | expected due to this + | + = note: this error originates in the macro `quote_spanned` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/vendor/ryu/.cargo-checksum.json b/vendor/ryu/.cargo-checksum.json new file mode 100644 index 0000000..da5e42e --- /dev/null +++ b/vendor/ryu/.cargo-checksum.json @@ -0,0 +1 @@ +{"files":{"Cargo.lock":"2154f7e5f06489f3b42120f2165661fd552aa03b3d1f4f0cfeb380acad362b22","Cargo.toml":"708b4546804f6c500c45fd048921400f4328fe8f7159e0491faa4a64e38a2b0f","LICENSE-APACHE":"62c7a1e35f56406896d7aa7ca52d0cc0d272ac022b5d2796e7d6905db8a3636a","LICENSE-BOOST":"c9bff75738922193e67fa726fa225535870d2aa1059f91452c411736284ad566","README.md":"86f0a92cf076f4983f99926607ea272c9650a5996fa3921fc5ca5abceb0f18db","benches/bench.rs":"703521c8cb9c6959ee305776a9971d24754b6fff5c1737741be04f956a3692e8","examples/upstream_benchmark.rs":"f702d3598a8fac59134a8058ebf74ba90163b1f23ebbd6c5978a7bd8a888d357","src/buffer/mod.rs":"e32f3fa7e994ff704796e58e115c5258e94a79a184d1608864772f2f2f5274fc","src/common.rs":"cae347e97fc30c50a964f80425e8c3e69ece2b8ab81f9b81b9baa7fcec64a001","src/d2s.rs":"f2612785ebe510c935b979dc5f66f6b8c818ca8a4cf0364ce1fe1d41fea39592","src/d2s_full_table.rs":"9b0186acbc6d65dc55c17e16125be707a2bfb920d22b35d33234b4cc38566a36","src/d2s_intrinsics.rs":"bbf15472f4299942312e80a992cbc2f47f85f17ed193f24084534434dbfb26e7","src/d2s_small_table.rs":"db3bbe4002d816785b0ee233c330f19fa7002f31dab47dc6f67b266996fe3ae4","src/digit_table.rs":"02351ca54cb8cb3679f635115dd094f32fd91750e9f66103c1ee9ec3db507072","src/f2s.rs":"cb96f61d8c6c6c941803a7b629f2bf835e1a20ad9d3e5d3454a30ed3391c3515","src/f2s_intrinsics.rs":"97bab98093838e30c60f5135f54f5ccb039ff7d9f35553ac8e74437743ca47e2","src/lib.rs":"8020040eaf88b50ffe542691d4c5a63e9f07e8ae6893ab433ef86762655dc941","src/parse.rs":"7f8aa7e007caf5dcb03abdc4238157724bb742d0823a3b8a01646fa1f1129154","src/pretty/exponent.rs":"fa914ec63b3f86cbdaf7933d7c44e1bc1f93c1239a29a5f86934680a7e957570","src/pretty/mantissa.rs":"40cb00efe1c3fab559ab58389bd519d556548aa18fb261a90dd48138911d039b","src/pretty/mod.rs":"eb0a8c78019f55a1767943821340e8b1278455e0d88bb4f63f4bd3dde340e387","src/s2d.rs":"c804518a771654e3786bde2b776c56e94e198ce6d3fe1e4e5e2f2a9cb9e607e3","src/s2f.rs":"11d528931ce1a01a93f39efb3fe99fdc3041b41fefafb2efd6a338d2a12b628c","tests/common_test.rs":"599781a637d9b9756858aabfe5c38a0734a550debd3d94774f33792b7b3c8240","tests/d2s_intrinsics_test.rs":"15d11b70810bf04f33f8b185bf7f010a436a4edb47fa4648b1a036568c2c5d15","tests/d2s_table_test.rs":"819c39cc94e3462138d3be337d06e7334de126642d34bf1394e03d2df9c0c90c","tests/d2s_test.rs":"d72aaf37c76a4042ecc12b7d6faf844696016bb72bb20d142ecab3bd6c87e29f","tests/exhaustive.rs":"f475ed9008a2cd86ce95abb577a4b01e9fed23fc16f7e217ccffb3b834005fa0","tests/f2s_test.rs":"ad9e6fe46e712c488b876428c144c79bdff0349b41c57eee5506fc3c9c156624","tests/macros/mod.rs":"8e90a674b3960f9516cb38f4eea0e0981ff902c3b33572ebdb6c5528d3ffa72c","tests/s2d_test.rs":"75c3a1044881718db65e05f25c9f6e1d005392dddb2e8dafb799668bb6a9a5c3","tests/s2f_test.rs":"1ec06646cb65229bfe866ec913901a0d8d736668f30b812fc4b00136a43f5142"},"package":"f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f"} \ No newline at end of file diff --git a/vendor/ryu/Cargo.toml b/vendor/ryu/Cargo.toml new file mode 100644 index 0000000..5fa419b --- /dev/null +++ b/vendor/ryu/Cargo.toml @@ -0,0 +1,103 @@ +# 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] +edition = "2018" +rust-version = "1.36" +name = "ryu" +version = "1.0.18" +authors = ["David Tolnay "] +build = false +exclude = [ + "build.rs", + "performance.png", + "chart/**", +] +autobins = false +autoexamples = false +autotests = false +autobenches = false +description = "Fast floating point to string conversion" +documentation = "https://docs.rs/ryu" +readme = "README.md" +keywords = ["float"] +categories = [ + "value-formatting", + "no-std", + "no-std::no-alloc", +] +license = "Apache-2.0 OR BSL-1.0" +repository = "https://github.com/dtolnay/ryu" + +[package.metadata.docs.rs] +rustdoc-args = ["--generate-link-to-definition"] +targets = ["x86_64-unknown-linux-gnu"] + +[lib] +name = "ryu" +path = "src/lib.rs" +doc-scrape-examples = false + +[[example]] +name = "upstream_benchmark" +path = "examples/upstream_benchmark.rs" + +[[test]] +name = "s2f_test" +path = "tests/s2f_test.rs" + +[[test]] +name = "common_test" +path = "tests/common_test.rs" + +[[test]] +name = "s2d_test" +path = "tests/s2d_test.rs" + +[[test]] +name = "d2s_test" +path = "tests/d2s_test.rs" + +[[test]] +name = "f2s_test" +path = "tests/f2s_test.rs" + +[[test]] +name = "d2s_table_test" +path = "tests/d2s_table_test.rs" + +[[test]] +name = "exhaustive" +path = "tests/exhaustive.rs" + +[[test]] +name = "d2s_intrinsics_test" +path = "tests/d2s_intrinsics_test.rs" + +[[bench]] +name = "bench" +path = "benches/bench.rs" + +[dependencies.no-panic] +version = "0.1" +optional = true + +[dev-dependencies.num_cpus] +version = "1.8" + +[dev-dependencies.rand] +version = "0.8" + +[dev-dependencies.rand_xorshift] +version = "0.3" + +[features] +small = [] diff --git a/vendor/ryu/LICENSE-APACHE b/vendor/ryu/LICENSE-APACHE new file mode 100644 index 0000000..1b5ec8b --- /dev/null +++ b/vendor/ryu/LICENSE-APACHE @@ -0,0 +1,176 @@ + 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 diff --git a/vendor/ryu/LICENSE-BOOST b/vendor/ryu/LICENSE-BOOST new file mode 100644 index 0000000..36b7cd9 --- /dev/null +++ b/vendor/ryu/LICENSE-BOOST @@ -0,0 +1,23 @@ +Boost Software License - Version 1.0 - August 17th, 2003 + +Permission is hereby granted, free of charge, to any person or organization +obtaining a copy of the software and accompanying documentation covered by +this license (the "Software") to use, reproduce, display, distribute, +execute, and transmit the Software, and to prepare derivative works of the +Software, and to permit third-parties to whom the Software is furnished to +do so, all subject to the following: + +The copyright notices in the Software and this entire statement, including +the above license grant, this restriction and the following disclaimer, +must be included in all copies of the Software, in whole or in part, and +all derivative works of the Software, unless such copies or derivative +works are solely in the form of machine-executable object code generated by +a source language processor. + +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, TITLE AND NON-INFRINGEMENT. IN NO EVENT +SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN 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/ryu/README.md b/vendor/ryu/README.md new file mode 100644 index 0000000..998ea3e --- /dev/null +++ b/vendor/ryu/README.md @@ -0,0 +1,110 @@ +# Ryū + +[github](https://github.com/dtolnay/ryu) +[crates.io](https://crates.io/crates/ryu) +[docs.rs](https://docs.rs/ryu) +[build status](https://github.com/dtolnay/ryu/actions?query=branch%3Amaster) + +Pure Rust implementation of Ryū, an algorithm to quickly convert floating point +numbers to decimal strings. + +The PLDI'18 paper [*Ryū: fast float-to-string conversion*][paper] by Ulf Adams +includes a complete correctness proof of the algorithm. The paper is available +under the creative commons CC-BY-SA license. + +This Rust implementation is a line-by-line port of Ulf Adams' implementation in +C, [https://github.com/ulfjack/ryu][upstream]. + +*Requirements: this crate supports any compiler version back to rustc 1.36; it +uses nothing from the Rust standard library so is usable from no_std crates.* + +[paper]: https://dl.acm.org/citation.cfm?id=3192369 +[upstream]: https://github.com/ulfjack/ryu/tree/77e767f5e056bab96e895072fc21618ecff2f44b + +```toml +[dependencies] +ryu = "1.0" +``` + +
+ +## Example + +```rust +fn main() { + let mut buffer = ryu::Buffer::new(); + let printed = buffer.format(1.234); + assert_eq!(printed, "1.234"); +} +``` + +
+ +## Performance (lower is better) + +![performance](https://raw.githubusercontent.com/dtolnay/ryu/master/performance.png) + +You can run upstream's benchmarks with: + +```console +$ git clone https://github.com/ulfjack/ryu c-ryu +$ cd c-ryu +$ bazel run -c opt //ryu/benchmark:ryu_benchmark +``` + +And the same benchmark against our implementation with: + +```console +$ git clone https://github.com/dtolnay/ryu rust-ryu +$ cd rust-ryu +$ cargo run --example upstream_benchmark --release +``` + +These benchmarks measure the average time to print a 32-bit float and average +time to print a 64-bit float, where the inputs are distributed as uniform random +bit patterns 32 and 64 bits wide. + +The upstream C code, the unsafe direct Rust port, and the safe pretty Rust API +all perform the same, taking around 21 nanoseconds to format a 32-bit float and +31 nanoseconds to format a 64-bit float. + +There is also a Rust-specific benchmark comparing this implementation to the +standard library which you can run with: + +```console +$ cargo bench +``` + +The benchmark shows Ryū approximately 2-5x faster than the standard library +across a range of f32 and f64 inputs. Measurements are in nanoseconds per +iteration; smaller is better. + +## Formatting + +This library tends to produce more human-readable output than the standard +library's to\_string, which never uses scientific notation. Here are two +examples: + +- *ryu:* 1.23e40, *std:* 12300000000000000000000000000000000000000 +- *ryu:* 1.23e-40, *std:* 0.000000000000000000000000000000000000000123 + +Both libraries print short decimals such as 0.0000123 without scientific +notation. + +
+ +#### License + + +Licensed under either of Apache License, Version +2.0 or Boost Software License 1.0 at your +option. + + +
+ + +Unless you explicitly state otherwise, any contribution intentionally submitted +for inclusion in this crate 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/ryu/benches/bench.rs b/vendor/ryu/benches/bench.rs new file mode 100644 index 0000000..fbc1b70 --- /dev/null +++ b/vendor/ryu/benches/bench.rs @@ -0,0 +1,62 @@ +// cargo bench + +#![feature(test)] +#![allow( + clippy::approx_constant, + clippy::excessive_precision, + clippy::unreadable_literal +)] + +extern crate test; + +use std::io::Write; +use std::{f32, f64}; +use test::{black_box, Bencher}; + +macro_rules! benches { + ($($name:ident($value:expr),)*) => { + mod bench_ryu { + use super::*; + $( + #[bench] + fn $name(b: &mut Bencher) { + let mut buf = ryu::Buffer::new(); + + b.iter(move || { + let value = black_box($value); + let formatted = buf.format_finite(value); + black_box(formatted); + }); + } + )* + } + + mod bench_std_fmt { + use super::*; + $( + #[bench] + fn $name(b: &mut Bencher) { + let mut buf = Vec::with_capacity(20); + + b.iter(|| { + buf.clear(); + let value = black_box($value); + write!(&mut buf, "{}", value).unwrap(); + black_box(buf.as_slice()); + }); + } + )* + } + }; +} + +benches! { + bench_0_f64(0f64), + bench_short_f64(0.1234f64), + bench_e_f64(2.718281828459045f64), + bench_max_f64(f64::MAX), + bench_0_f32(0f32), + bench_short_f32(0.1234f32), + bench_e_f32(2.718281828459045f32), + bench_max_f32(f32::MAX), +} diff --git a/vendor/ryu/examples/upstream_benchmark.rs b/vendor/ryu/examples/upstream_benchmark.rs new file mode 100644 index 0000000..437855b --- /dev/null +++ b/vendor/ryu/examples/upstream_benchmark.rs @@ -0,0 +1,85 @@ +// cargo run --example upstream_benchmark --release + +use rand::{Rng, SeedableRng}; + +const SAMPLES: usize = 10000; +const ITERATIONS: usize = 1000; + +struct MeanAndVariance { + n: i64, + mean: f64, + m2: f64, +} + +impl MeanAndVariance { + fn new() -> Self { + MeanAndVariance { + n: 0, + mean: 0.0, + m2: 0.0, + } + } + + fn update(&mut self, x: f64) { + self.n += 1; + let d = x - self.mean; + self.mean += d / self.n as f64; + let d2 = x - self.mean; + self.m2 += d * d2; + } + + fn variance(&self) -> f64 { + self.m2 / (self.n - 1) as f64 + } + + fn stddev(&self) -> f64 { + self.variance().sqrt() + } +} + +macro_rules! benchmark { + ($name:ident, $ty:ident) => { + fn $name() -> usize { + let mut rng = rand_xorshift::XorShiftRng::from_seed([123u8; 16]); + let mut mv = MeanAndVariance::new(); + let mut throwaway = 0; + for _ in 0..SAMPLES { + let f = loop { + let f = $ty::from_bits(rng.gen()); + if f.is_finite() { + break f; + } + }; + + let t1 = std::time::SystemTime::now(); + for _ in 0..ITERATIONS { + throwaway += ryu::Buffer::new().format_finite(f).len(); + } + let duration = t1.elapsed().unwrap(); + let nanos = duration.as_secs() * 1_000_000_000 + duration.subsec_nanos() as u64; + mv.update(nanos as f64 / ITERATIONS as f64); + } + println!( + "{:12} {:8.3} {:8.3}", + concat!(stringify!($name), ":"), + mv.mean, + mv.stddev(), + ); + throwaway + } + }; +} + +benchmark!(pretty32, f32); +benchmark!(pretty64, f64); + +fn main() { + println!("{:>20}{:>9}", "Average", "Stddev"); + let mut throwaway = 0; + throwaway += pretty32(); + throwaway += pretty64(); + if std::env::var_os("ryu-benchmark").is_some() { + // Prevent the compiler from optimizing the code away. + println!("{}", throwaway); + } +} diff --git a/vendor/ryu/src/buffer/mod.rs b/vendor/ryu/src/buffer/mod.rs new file mode 100644 index 0000000..905ee2f --- /dev/null +++ b/vendor/ryu/src/buffer/mod.rs @@ -0,0 +1,171 @@ +use crate::raw; +use core::mem::MaybeUninit; +use core::{slice, str}; +#[cfg(feature = "no-panic")] +use no_panic::no_panic; + +const NAN: &str = "NaN"; +const INFINITY: &str = "inf"; +const NEG_INFINITY: &str = "-inf"; + +/// Safe API for formatting floating point numbers to text. +/// +/// ## Example +/// +/// ``` +/// let mut buffer = ryu::Buffer::new(); +/// let printed = buffer.format_finite(1.234); +/// assert_eq!(printed, "1.234"); +/// ``` +pub struct Buffer { + bytes: [MaybeUninit; 24], +} + +impl Buffer { + /// This is a cheap operation; you don't need to worry about reusing buffers + /// for efficiency. + #[inline] + #[cfg_attr(feature = "no-panic", no_panic)] + pub fn new() -> Self { + let bytes = [MaybeUninit::::uninit(); 24]; + Buffer { bytes } + } + + /// Print a floating point number into this buffer and return a reference to + /// its string representation within the buffer. + /// + /// # Special cases + /// + /// This function formats NaN as the string "NaN", positive infinity as + /// "inf", and negative infinity as "-inf" to match std::fmt. + /// + /// If your input is known to be finite, you may get better performance by + /// calling the `format_finite` method instead of `format` to avoid the + /// checks for special cases. + #[cfg_attr(feature = "no-panic", inline)] + #[cfg_attr(feature = "no-panic", no_panic)] + pub fn format(&mut self, f: F) -> &str { + if f.is_nonfinite() { + f.format_nonfinite() + } else { + self.format_finite(f) + } + } + + /// Print a floating point number into this buffer and return a reference to + /// its string representation within the buffer. + /// + /// # Special cases + /// + /// This function **does not** check for NaN or infinity. If the input + /// number is not a finite float, the printed representation will be some + /// correctly formatted but unspecified numerical value. + /// + /// Please check [`is_finite`] yourself before calling this function, or + /// check [`is_nan`] and [`is_infinite`] and handle those cases yourself. + /// + /// [`is_finite`]: https://doc.rust-lang.org/std/primitive.f64.html#method.is_finite + /// [`is_nan`]: https://doc.rust-lang.org/std/primitive.f64.html#method.is_nan + /// [`is_infinite`]: https://doc.rust-lang.org/std/primitive.f64.html#method.is_infinite + #[inline] + #[cfg_attr(feature = "no-panic", no_panic)] + pub fn format_finite(&mut self, f: F) -> &str { + unsafe { + let n = f.write_to_ryu_buffer(self.bytes.as_mut_ptr() as *mut u8); + debug_assert!(n <= self.bytes.len()); + let slice = slice::from_raw_parts(self.bytes.as_ptr() as *const u8, n); + str::from_utf8_unchecked(slice) + } + } +} + +impl Copy for Buffer {} + +impl Clone for Buffer { + #[inline] + #[allow(clippy::non_canonical_clone_impl)] // false positive https://github.com/rust-lang/rust-clippy/issues/11072 + fn clone(&self) -> Self { + Buffer::new() + } +} + +impl Default for Buffer { + #[inline] + #[cfg_attr(feature = "no-panic", no_panic)] + fn default() -> Self { + Buffer::new() + } +} + +/// A floating point number, f32 or f64, that can be written into a +/// [`ryu::Buffer`][Buffer]. +/// +/// This trait is sealed and cannot be implemented for types outside of the +/// `ryu` crate. +pub trait Float: Sealed {} +impl Float for f32 {} +impl Float for f64 {} + +pub trait Sealed: Copy { + fn is_nonfinite(self) -> bool; + fn format_nonfinite(self) -> &'static str; + unsafe fn write_to_ryu_buffer(self, result: *mut u8) -> usize; +} + +impl Sealed for f32 { + #[inline] + fn is_nonfinite(self) -> bool { + const EXP_MASK: u32 = 0x7f800000; + let bits = self.to_bits(); + bits & EXP_MASK == EXP_MASK + } + + #[cold] + #[cfg_attr(feature = "no-panic", inline)] + fn format_nonfinite(self) -> &'static str { + const MANTISSA_MASK: u32 = 0x007fffff; + const SIGN_MASK: u32 = 0x80000000; + let bits = self.to_bits(); + if bits & MANTISSA_MASK != 0 { + NAN + } else if bits & SIGN_MASK != 0 { + NEG_INFINITY + } else { + INFINITY + } + } + + #[inline] + unsafe fn write_to_ryu_buffer(self, result: *mut u8) -> usize { + raw::format32(self, result) + } +} + +impl Sealed for f64 { + #[inline] + fn is_nonfinite(self) -> bool { + const EXP_MASK: u64 = 0x7ff0000000000000; + let bits = self.to_bits(); + bits & EXP_MASK == EXP_MASK + } + + #[cold] + #[cfg_attr(feature = "no-panic", inline)] + fn format_nonfinite(self) -> &'static str { + const MANTISSA_MASK: u64 = 0x000fffffffffffff; + const SIGN_MASK: u64 = 0x8000000000000000; + let bits = self.to_bits(); + if bits & MANTISSA_MASK != 0 { + NAN + } else if bits & SIGN_MASK != 0 { + NEG_INFINITY + } else { + INFINITY + } + } + + #[inline] + unsafe fn write_to_ryu_buffer(self, result: *mut u8) -> usize { + raw::format64(self, result) + } +} diff --git a/vendor/ryu/src/common.rs b/vendor/ryu/src/common.rs new file mode 100644 index 0000000..9613036 --- /dev/null +++ b/vendor/ryu/src/common.rs @@ -0,0 +1,95 @@ +// Translated from C to Rust. The original C code can be found at +// https://github.com/ulfjack/ryu and carries the following license: +// +// Copyright 2018 Ulf Adams +// +// The contents of this file may be used under the terms of the Apache License, +// Version 2.0. +// +// (See accompanying file LICENSE-Apache or copy at +// http://www.apache.org/licenses/LICENSE-2.0) +// +// Alternatively, the contents of this file may be used under the terms of +// the Boost Software License, Version 1.0. +// (See accompanying file LICENSE-Boost or copy at +// https://www.boost.org/LICENSE_1_0.txt) +// +// Unless required by applicable law or agreed to in writing, this software +// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. + +// Returns the number of decimal digits in v, which must not contain more than 9 +// digits. +#[cfg_attr(feature = "no-panic", inline)] +pub fn decimal_length9(v: u32) -> u32 { + // Function precondition: v is not a 10-digit number. + // (f2s: 9 digits are sufficient for round-tripping.) + debug_assert!(v < 1000000000); + + if v >= 100000000 { + 9 + } else if v >= 10000000 { + 8 + } else if v >= 1000000 { + 7 + } else if v >= 100000 { + 6 + } else if v >= 10000 { + 5 + } else if v >= 1000 { + 4 + } else if v >= 100 { + 3 + } else if v >= 10 { + 2 + } else { + 1 + } +} + +// Returns e == 0 ? 1 : [log_2(5^e)]; requires 0 <= e <= 3528. +#[cfg_attr(feature = "no-panic", inline)] +#[allow(dead_code)] +pub fn log2_pow5(e: i32) -> i32 /* or u32 -> u32 */ { + // This approximation works up to the point that the multiplication + // overflows at e = 3529. If the multiplication were done in 64 bits, it + // would fail at 5^4004 which is just greater than 2^9297. + debug_assert!(e >= 0); + debug_assert!(e <= 3528); + ((e as u32 * 1217359) >> 19) as i32 +} + +// Returns e == 0 ? 1 : ceil(log_2(5^e)); requires 0 <= e <= 3528. +#[cfg_attr(feature = "no-panic", inline)] +pub fn pow5bits(e: i32) -> i32 /* or u32 -> u32 */ { + // This approximation works up to the point that the multiplication + // overflows at e = 3529. If the multiplication were done in 64 bits, it + // would fail at 5^4004 which is just greater than 2^9297. + debug_assert!(e >= 0); + debug_assert!(e <= 3528); + (((e as u32 * 1217359) >> 19) + 1) as i32 +} + +#[cfg_attr(feature = "no-panic", inline)] +#[allow(dead_code)] +pub fn ceil_log2_pow5(e: i32) -> i32 /* or u32 -> u32 */ { + log2_pow5(e) + 1 +} + +// Returns floor(log_10(2^e)); requires 0 <= e <= 1650. +#[cfg_attr(feature = "no-panic", inline)] +pub fn log10_pow2(e: i32) -> u32 /* or u32 -> u32 */ { + // The first value this approximation fails for is 2^1651 which is just greater than 10^297. + debug_assert!(e >= 0); + debug_assert!(e <= 1650); + (e as u32 * 78913) >> 18 +} + +// Returns floor(log_10(5^e)); requires 0 <= e <= 2620. +#[cfg_attr(feature = "no-panic", inline)] +pub fn log10_pow5(e: i32) -> u32 /* or u32 -> u32 */ { + // The first value this approximation fails for is 5^2621 which is just greater than 10^1832. + debug_assert!(e >= 0); + debug_assert!(e <= 2620); + (e as u32 * 732923) >> 20 +} diff --git a/vendor/ryu/src/d2s.rs b/vendor/ryu/src/d2s.rs new file mode 100644 index 0000000..76a8164 --- /dev/null +++ b/vendor/ryu/src/d2s.rs @@ -0,0 +1,302 @@ +// Translated from C to Rust. The original C code can be found at +// https://github.com/ulfjack/ryu and carries the following license: +// +// Copyright 2018 Ulf Adams +// +// The contents of this file may be used under the terms of the Apache License, +// Version 2.0. +// +// (See accompanying file LICENSE-Apache or copy at +// http://www.apache.org/licenses/LICENSE-2.0) +// +// Alternatively, the contents of this file may be used under the terms of +// the Boost Software License, Version 1.0. +// (See accompanying file LICENSE-Boost or copy at +// https://www.boost.org/LICENSE_1_0.txt) +// +// Unless required by applicable law or agreed to in writing, this software +// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. + +use crate::common::{log10_pow2, log10_pow5, pow5bits}; +#[cfg(not(feature = "small"))] +pub use crate::d2s_full_table::{DOUBLE_POW5_INV_SPLIT, DOUBLE_POW5_SPLIT}; +use crate::d2s_intrinsics::{ + div10, div100, div5, mul_shift_all_64, multiple_of_power_of_2, multiple_of_power_of_5, +}; +#[cfg(feature = "small")] +pub use crate::d2s_small_table::{compute_inv_pow5, compute_pow5}; +use core::mem::MaybeUninit; + +pub const DOUBLE_MANTISSA_BITS: u32 = 52; +pub const DOUBLE_EXPONENT_BITS: u32 = 11; +pub const DOUBLE_BIAS: i32 = 1023; +pub const DOUBLE_POW5_INV_BITCOUNT: i32 = 125; +pub const DOUBLE_POW5_BITCOUNT: i32 = 125; + +#[cfg_attr(feature = "no-panic", inline)] +pub fn decimal_length17(v: u64) -> u32 { + // This is slightly faster than a loop. + // The average output length is 16.38 digits, so we check high-to-low. + // Function precondition: v is not an 18, 19, or 20-digit number. + // (17 digits are sufficient for round-tripping.) + debug_assert!(v < 100000000000000000); + + if v >= 10000000000000000 { + 17 + } else if v >= 1000000000000000 { + 16 + } else if v >= 100000000000000 { + 15 + } else if v >= 10000000000000 { + 14 + } else if v >= 1000000000000 { + 13 + } else if v >= 100000000000 { + 12 + } else if v >= 10000000000 { + 11 + } else if v >= 1000000000 { + 10 + } else if v >= 100000000 { + 9 + } else if v >= 10000000 { + 8 + } else if v >= 1000000 { + 7 + } else if v >= 100000 { + 6 + } else if v >= 10000 { + 5 + } else if v >= 1000 { + 4 + } else if v >= 100 { + 3 + } else if v >= 10 { + 2 + } else { + 1 + } +} + +// A floating decimal representing m * 10^e. +pub struct FloatingDecimal64 { + pub mantissa: u64, + // Decimal exponent's range is -324 to 308 + // inclusive, and can fit in i16 if needed. + pub exponent: i32, +} + +#[cfg_attr(feature = "no-panic", inline)] +pub fn d2d(ieee_mantissa: u64, ieee_exponent: u32) -> FloatingDecimal64 { + let (e2, m2) = if ieee_exponent == 0 { + ( + // We subtract 2 so that the bounds computation has 2 additional bits. + 1 - DOUBLE_BIAS - DOUBLE_MANTISSA_BITS as i32 - 2, + ieee_mantissa, + ) + } else { + ( + ieee_exponent as i32 - DOUBLE_BIAS - DOUBLE_MANTISSA_BITS as i32 - 2, + (1u64 << DOUBLE_MANTISSA_BITS) | ieee_mantissa, + ) + }; + let even = (m2 & 1) == 0; + let accept_bounds = even; + + // Step 2: Determine the interval of valid decimal representations. + let mv = 4 * m2; + // Implicit bool -> int conversion. True is 1, false is 0. + let mm_shift = (ieee_mantissa != 0 || ieee_exponent <= 1) as u32; + // We would compute mp and mm like this: + // uint64_t mp = 4 * m2 + 2; + // uint64_t mm = mv - 1 - mm_shift; + + // Step 3: Convert to a decimal power base using 128-bit arithmetic. + let mut vr: u64; + let mut vp: u64; + let mut vm: u64; + let mut vp_uninit: MaybeUninit = MaybeUninit::uninit(); + let mut vm_uninit: MaybeUninit = MaybeUninit::uninit(); + let e10: i32; + let mut vm_is_trailing_zeros = false; + let mut vr_is_trailing_zeros = false; + if e2 >= 0 { + // I tried special-casing q == 0, but there was no effect on performance. + // This expression is slightly faster than max(0, log10_pow2(e2) - 1). + let q = log10_pow2(e2) - (e2 > 3) as u32; + e10 = q as i32; + let k = DOUBLE_POW5_INV_BITCOUNT + pow5bits(q as i32) - 1; + let i = -e2 + q as i32 + k; + vr = unsafe { + mul_shift_all_64( + m2, + #[cfg(feature = "small")] + &compute_inv_pow5(q), + #[cfg(not(feature = "small"))] + { + debug_assert!(q < DOUBLE_POW5_INV_SPLIT.len() as u32); + DOUBLE_POW5_INV_SPLIT.get_unchecked(q as usize) + }, + i as u32, + vp_uninit.as_mut_ptr(), + vm_uninit.as_mut_ptr(), + mm_shift, + ) + }; + vp = unsafe { vp_uninit.assume_init() }; + vm = unsafe { vm_uninit.assume_init() }; + if q <= 21 { + // This should use q <= 22, but I think 21 is also safe. Smaller values + // may still be safe, but it's more difficult to reason about them. + // Only one of mp, mv, and mm can be a multiple of 5, if any. + let mv_mod5 = (mv as u32).wrapping_sub(5u32.wrapping_mul(div5(mv) as u32)); + if mv_mod5 == 0 { + vr_is_trailing_zeros = multiple_of_power_of_5(mv, q); + } else if accept_bounds { + // Same as min(e2 + (~mm & 1), pow5_factor(mm)) >= q + // <=> e2 + (~mm & 1) >= q && pow5_factor(mm) >= q + // <=> true && pow5_factor(mm) >= q, since e2 >= q. + vm_is_trailing_zeros = multiple_of_power_of_5(mv - 1 - mm_shift as u64, q); + } else { + // Same as min(e2 + 1, pow5_factor(mp)) >= q. + vp -= multiple_of_power_of_5(mv + 2, q) as u64; + } + } + } else { + // This expression is slightly faster than max(0, log10_pow5(-e2) - 1). + let q = log10_pow5(-e2) - (-e2 > 1) as u32; + e10 = q as i32 + e2; + let i = -e2 - q as i32; + let k = pow5bits(i) - DOUBLE_POW5_BITCOUNT; + let j = q as i32 - k; + vr = unsafe { + mul_shift_all_64( + m2, + #[cfg(feature = "small")] + &compute_pow5(i as u32), + #[cfg(not(feature = "small"))] + { + debug_assert!(i < DOUBLE_POW5_SPLIT.len() as i32); + DOUBLE_POW5_SPLIT.get_unchecked(i as usize) + }, + j as u32, + vp_uninit.as_mut_ptr(), + vm_uninit.as_mut_ptr(), + mm_shift, + ) + }; + vp = unsafe { vp_uninit.assume_init() }; + vm = unsafe { vm_uninit.assume_init() }; + if q <= 1 { + // {vr,vp,vm} is trailing zeros if {mv,mp,mm} has at least q trailing 0 bits. + // mv = 4 * m2, so it always has at least two trailing 0 bits. + vr_is_trailing_zeros = true; + if accept_bounds { + // mm = mv - 1 - mm_shift, so it has 1 trailing 0 bit iff mm_shift == 1. + vm_is_trailing_zeros = mm_shift == 1; + } else { + // mp = mv + 2, so it always has at least one trailing 0 bit. + vp -= 1; + } + } else if q < 63 { + // TODO(ulfjack): Use a tighter bound here. + // We want to know if the full product has at least q trailing zeros. + // We need to compute min(p2(mv), p5(mv) - e2) >= q + // <=> p2(mv) >= q && p5(mv) - e2 >= q + // <=> p2(mv) >= q (because -e2 >= q) + vr_is_trailing_zeros = multiple_of_power_of_2(mv, q); + } + } + + // Step 4: Find the shortest decimal representation in the interval of valid representations. + let mut removed = 0i32; + let mut last_removed_digit = 0u8; + // On average, we remove ~2 digits. + let output = if vm_is_trailing_zeros || vr_is_trailing_zeros { + // General case, which happens rarely (~0.7%). + loop { + let vp_div10 = div10(vp); + let vm_div10 = div10(vm); + if vp_div10 <= vm_div10 { + break; + } + let vm_mod10 = (vm as u32).wrapping_sub(10u32.wrapping_mul(vm_div10 as u32)); + let vr_div10 = div10(vr); + let vr_mod10 = (vr as u32).wrapping_sub(10u32.wrapping_mul(vr_div10 as u32)); + vm_is_trailing_zeros &= vm_mod10 == 0; + vr_is_trailing_zeros &= last_removed_digit == 0; + last_removed_digit = vr_mod10 as u8; + vr = vr_div10; + vp = vp_div10; + vm = vm_div10; + removed += 1; + } + if vm_is_trailing_zeros { + loop { + let vm_div10 = div10(vm); + let vm_mod10 = (vm as u32).wrapping_sub(10u32.wrapping_mul(vm_div10 as u32)); + if vm_mod10 != 0 { + break; + } + let vp_div10 = div10(vp); + let vr_div10 = div10(vr); + let vr_mod10 = (vr as u32).wrapping_sub(10u32.wrapping_mul(vr_div10 as u32)); + vr_is_trailing_zeros &= last_removed_digit == 0; + last_removed_digit = vr_mod10 as u8; + vr = vr_div10; + vp = vp_div10; + vm = vm_div10; + removed += 1; + } + } + if vr_is_trailing_zeros && last_removed_digit == 5 && vr % 2 == 0 { + // Round even if the exact number is .....50..0. + last_removed_digit = 4; + } + // We need to take vr + 1 if vr is outside bounds or we need to round up. + vr + ((vr == vm && (!accept_bounds || !vm_is_trailing_zeros)) || last_removed_digit >= 5) + as u64 + } else { + // Specialized for the common case (~99.3%). Percentages below are relative to this. + let mut round_up = false; + let vp_div100 = div100(vp); + let vm_div100 = div100(vm); + // Optimization: remove two digits at a time (~86.2%). + if vp_div100 > vm_div100 { + let vr_div100 = div100(vr); + let vr_mod100 = (vr as u32).wrapping_sub(100u32.wrapping_mul(vr_div100 as u32)); + round_up = vr_mod100 >= 50; + vr = vr_div100; + vp = vp_div100; + vm = vm_div100; + removed += 2; + } + // Loop iterations below (approximately), without optimization above: + // 0: 0.03%, 1: 13.8%, 2: 70.6%, 3: 14.0%, 4: 1.40%, 5: 0.14%, 6+: 0.02% + // Loop iterations below (approximately), with optimization above: + // 0: 70.6%, 1: 27.8%, 2: 1.40%, 3: 0.14%, 4+: 0.02% + loop { + let vp_div10 = div10(vp); + let vm_div10 = div10(vm); + if vp_div10 <= vm_div10 { + break; + } + let vr_div10 = div10(vr); + let vr_mod10 = (vr as u32).wrapping_sub(10u32.wrapping_mul(vr_div10 as u32)); + round_up = vr_mod10 >= 5; + vr = vr_div10; + vp = vp_div10; + vm = vm_div10; + removed += 1; + } + // We need to take vr + 1 if vr is outside bounds or we need to round up. + vr + (vr == vm || round_up) as u64 + }; + let exp = e10 + removed; + + FloatingDecimal64 { + exponent: exp, + mantissa: output, + } +} diff --git a/vendor/ryu/src/d2s_full_table.rs b/vendor/ryu/src/d2s_full_table.rs new file mode 100644 index 0000000..7534ddd --- /dev/null +++ b/vendor/ryu/src/d2s_full_table.rs @@ -0,0 +1,696 @@ +// Translated from C to Rust. The original C code can be found at +// https://github.com/ulfjack/ryu and carries the following license: +// +// Copyright 2018 Ulf Adams +// +// The contents of this file may be used under the terms of the Apache License, +// Version 2.0. +// +// (See accompanying file LICENSE-Apache or copy at +// http://www.apache.org/licenses/LICENSE-2.0) +// +// Alternatively, the contents of this file may be used under the terms of +// the Boost Software License, Version 1.0. +// (See accompanying file LICENSE-Boost or copy at +// https://www.boost.org/LICENSE_1_0.txt) +// +// Unless required by applicable law or agreed to in writing, this software +// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. + +const DOUBLE_POW5_INV_TABLE_SIZE: usize = 342; +const DOUBLE_POW5_TABLE_SIZE: usize = 326; + +pub static DOUBLE_POW5_INV_SPLIT: [(u64, u64); DOUBLE_POW5_INV_TABLE_SIZE] = [ + (1, 2305843009213693952), + (11068046444225730970, 1844674407370955161), + (5165088340638674453, 1475739525896764129), + (7821419487252849886, 1180591620717411303), + (8824922364862649494, 1888946593147858085), + (7059937891890119595, 1511157274518286468), + (13026647942995916322, 1208925819614629174), + (9774590264567735146, 1934281311383406679), + (11509021026396098440, 1547425049106725343), + (16585914450600699399, 1237940039285380274), + (15469416676735388068, 1980704062856608439), + (16064882156130220778, 1584563250285286751), + (9162556910162266299, 1267650600228229401), + (7281393426775805432, 2028240960365167042), + (16893161185646375315, 1622592768292133633), + (2446482504291369283, 1298074214633706907), + (7603720821608101175, 2076918743413931051), + (2393627842544570617, 1661534994731144841), + (16672297533003297786, 1329227995784915872), + (11918280793837635165, 2126764793255865396), + (5845275820328197809, 1701411834604692317), + (15744267100488289217, 1361129467683753853), + (3054734472329800808, 2177807148294006166), + (17201182836831481939, 1742245718635204932), + (6382248639981364905, 1393796574908163946), + (2832900194486363201, 2230074519853062314), + (5955668970331000884, 1784059615882449851), + (1075186361522890384, 1427247692705959881), + (12788344622662355584, 2283596308329535809), + (13920024512871794791, 1826877046663628647), + (3757321980813615186, 1461501637330902918), + (10384555214134712795, 1169201309864722334), + (5547241898389809503, 1870722095783555735), + (4437793518711847602, 1496577676626844588), + (10928932444453298728, 1197262141301475670), + (17486291911125277965, 1915619426082361072), + (6610335899416401726, 1532495540865888858), + (12666966349016942027, 1225996432692711086), + (12888448528943286597, 1961594292308337738), + (17689456452638449924, 1569275433846670190), + (14151565162110759939, 1255420347077336152), + (7885109000409574610, 2008672555323737844), + (9997436015069570011, 1606938044258990275), + (7997948812055656009, 1285550435407192220), + (12796718099289049614, 2056880696651507552), + (2858676849947419045, 1645504557321206042), + (13354987924183666206, 1316403645856964833), + (17678631863951955605, 2106245833371143733), + (3074859046935833515, 1684996666696914987), + (13527933681774397782, 1347997333357531989), + (10576647446613305481, 2156795733372051183), + (15840015586774465031, 1725436586697640946), + (8982663654677661702, 1380349269358112757), + (18061610662226169046, 2208558830972980411), + (10759939715039024913, 1766847064778384329), + (12297300586773130254, 1413477651822707463), + (15986332124095098083, 2261564242916331941), + (9099716884534168143, 1809251394333065553), + (14658471137111155161, 1447401115466452442), + (4348079280205103483, 1157920892373161954), + (14335624477811986218, 1852673427797059126), + (7779150767507678651, 1482138742237647301), + (2533971799264232598, 1185710993790117841), + (15122401323048503126, 1897137590064188545), + (12097921058438802501, 1517710072051350836), + (5988988032009131678, 1214168057641080669), + (16961078480698431330, 1942668892225729070), + (13568862784558745064, 1554135113780583256), + (7165741412905085728, 1243308091024466605), + (11465186260648137165, 1989292945639146568), + (16550846638002330379, 1591434356511317254), + (16930026125143774626, 1273147485209053803), + (4951948911778577463, 2037035976334486086), + (272210314680951647, 1629628781067588869), + (3907117066486671641, 1303703024854071095), + (6251387306378674625, 2085924839766513752), + (16069156289328670670, 1668739871813211001), + (9165976216721026213, 1334991897450568801), + (7286864317269821294, 2135987035920910082), + (16897537898041588005, 1708789628736728065), + (13518030318433270404, 1367031702989382452), + (6871453250525591353, 2187250724783011924), + (9186511415162383406, 1749800579826409539), + (11038557946871817048, 1399840463861127631), + (10282995085511086630, 2239744742177804210), + (8226396068408869304, 1791795793742243368), + (13959814484210916090, 1433436634993794694), + (11267656730511734774, 2293498615990071511), + (5324776569667477496, 1834798892792057209), + (7949170070475892320, 1467839114233645767), + (17427382500606444826, 1174271291386916613), + (5747719112518849781, 1878834066219066582), + (15666221734240810795, 1503067252975253265), + (12532977387392648636, 1202453802380202612), + (5295368560860596524, 1923926083808324180), + (4236294848688477220, 1539140867046659344), + (7078384693692692099, 1231312693637327475), + (11325415509908307358, 1970100309819723960), + (9060332407926645887, 1576080247855779168), + (14626963555825137356, 1260864198284623334), + (12335095245094488799, 2017382717255397335), + (9868076196075591040, 1613906173804317868), + (15273158586344293478, 1291124939043454294), + (13369007293925138595, 2065799902469526871), + (7005857020398200553, 1652639921975621497), + (16672732060544291412, 1322111937580497197), + (11918976037903224966, 2115379100128795516), + (5845832015580669650, 1692303280103036413), + (12055363241948356366, 1353842624082429130), + (841837113407818570, 2166148198531886609), + (4362818505468165179, 1732918558825509287), + (14558301248600263113, 1386334847060407429), + (12225235553534690011, 2218135755296651887), + (2401490813343931363, 1774508604237321510), + (1921192650675145090, 1419606883389857208), + (17831303500047873437, 2271371013423771532), + (6886345170554478103, 1817096810739017226), + (1819727321701672159, 1453677448591213781), + (16213177116328979020, 1162941958872971024), + (14873036941900635463, 1860707134196753639), + (15587778368262418694, 1488565707357402911), + (8780873879868024632, 1190852565885922329), + (2981351763563108441, 1905364105417475727), + (13453127855076217722, 1524291284333980581), + (7073153469319063855, 1219433027467184465), + (11317045550910502167, 1951092843947495144), + (12742985255470312057, 1560874275157996115), + (10194388204376249646, 1248699420126396892), + (1553625868034358140, 1997919072202235028), + (8621598323911307159, 1598335257761788022), + (17965325103354776697, 1278668206209430417), + (13987124906400001422, 2045869129935088668), + (121653480894270168, 1636695303948070935), + (97322784715416134, 1309356243158456748), + (14913111714512307107, 2094969989053530796), + (8241140556867935363, 1675975991242824637), + (17660958889720079260, 1340780792994259709), + (17189487779326395846, 2145249268790815535), + (13751590223461116677, 1716199415032652428), + (18379969808252713988, 1372959532026121942), + (14650556434236701088, 2196735251241795108), + (652398703163629901, 1757388200993436087), + (11589965406756634890, 1405910560794748869), + (7475898206584884855, 2249456897271598191), + (2291369750525997561, 1799565517817278553), + (9211793429904618695, 1439652414253822842), + (18428218302589300235, 2303443862806116547), + (7363877012587619542, 1842755090244893238), + (13269799239553916280, 1474204072195914590), + (10615839391643133024, 1179363257756731672), + (2227947767661371545, 1886981212410770676), + (16539753473096738529, 1509584969928616540), + (13231802778477390823, 1207667975942893232), + (6413489186596184024, 1932268761508629172), + (16198837793502678189, 1545815009206903337), + (5580372605318321905, 1236652007365522670), + (8928596168509315048, 1978643211784836272), + (18210923379033183008, 1582914569427869017), + (7190041073742725760, 1266331655542295214), + (436019273762630246, 2026130648867672343), + (7727513048493924843, 1620904519094137874), + (9871359253537050198, 1296723615275310299), + (4726128361433549347, 2074757784440496479), + (7470251503888749801, 1659806227552397183), + (13354898832594820487, 1327844982041917746), + (13989140502667892133, 2124551971267068394), + (14880661216876224029, 1699641577013654715), + (11904528973500979224, 1359713261610923772), + (4289851098633925465, 2175541218577478036), + (18189276137874781665, 1740432974861982428), + (3483374466074094362, 1392346379889585943), + (1884050330976640656, 2227754207823337509), + (5196589079523222848, 1782203366258670007), + (15225317707844309248, 1425762693006936005), + (5913764258841343181, 2281220308811097609), + (8420360221814984868, 1824976247048878087), + (17804334621677718864, 1459980997639102469), + (17932816512084085415, 1167984798111281975), + (10245762345624985047, 1868775676978051161), + (4507261061758077715, 1495020541582440929), + (7295157664148372495, 1196016433265952743), + (7982903447895485668, 1913626293225524389), + (10075671573058298858, 1530901034580419511), + (4371188443704728763, 1224720827664335609), + (14372599139411386667, 1959553324262936974), + (15187428126271019657, 1567642659410349579), + (15839291315758726049, 1254114127528279663), + (3206773216762499739, 2006582604045247462), + (13633465017635730761, 1605266083236197969), + (14596120828850494932, 1284212866588958375), + (4907049252451240275, 2054740586542333401), + (236290587219081897, 1643792469233866721), + (14946427728742906810, 1315033975387093376), + (16535586736504830250, 2104054360619349402), + (5849771759720043554, 1683243488495479522), + (15747863852001765813, 1346594790796383617), + (10439186904235184007, 2154551665274213788), + (15730047152871967852, 1723641332219371030), + (12584037722297574282, 1378913065775496824), + (9066413911450387881, 2206260905240794919), + (10942479943902220628, 1765008724192635935), + (8753983955121776503, 1412006979354108748), + (10317025513452932081, 2259211166966573997), + (874922781278525018, 1807368933573259198), + (8078635854506640661, 1445895146858607358), + (13841606313089133175, 1156716117486885886), + (14767872471458792434, 1850745787979017418), + (746251532941302978, 1480596630383213935), + (597001226353042382, 1184477304306571148), + (15712597221132509104, 1895163686890513836), + (8880728962164096960, 1516130949512411069), + (10793931984473187891, 1212904759609928855), + (17270291175157100626, 1940647615375886168), + (2748186495899949531, 1552518092300708935), + (2198549196719959625, 1242014473840567148), + (18275073973719576693, 1987223158144907436), + (10930710364233751031, 1589778526515925949), + (12433917106128911148, 1271822821212740759), + (8826220925580526867, 2034916513940385215), + (7060976740464421494, 1627933211152308172), + (16716827836597268165, 1302346568921846537), + (11989529279587987770, 2083754510274954460), + (9591623423670390216, 1667003608219963568), + (15051996368420132820, 1333602886575970854), + (13015147745246481542, 2133764618521553367), + (3033420566713364587, 1707011694817242694), + (6116085268112601993, 1365609355853794155), + (9785736428980163188, 2184974969366070648), + (15207286772667951197, 1747979975492856518), + (1097782973908629988, 1398383980394285215), + (1756452758253807981, 2237414368630856344), + (5094511021344956708, 1789931494904685075), + (4075608817075965366, 1431945195923748060), + (6520974107321544586, 2291112313477996896), + (1527430471115325346, 1832889850782397517), + (12289990821117991246, 1466311880625918013), + (17210690286378213644, 1173049504500734410), + (9090360384495590213, 1876879207201175057), + (18340334751822203140, 1501503365760940045), + (14672267801457762512, 1201202692608752036), + (16096930852848599373, 1921924308174003258), + (1809498238053148529, 1537539446539202607), + (12515645034668249793, 1230031557231362085), + (1578287981759648052, 1968050491570179337), + (12330676829633449412, 1574440393256143469), + (13553890278448669853, 1259552314604914775), + (3239480371808320148, 2015283703367863641), + (17348979556414297411, 1612226962694290912), + (6500486015647617283, 1289781570155432730), + (10400777625036187652, 2063650512248692368), + (15699319729512770768, 1650920409798953894), + (16248804598352126938, 1320736327839163115), + (7551343283653851484, 2113178124542660985), + (6041074626923081187, 1690542499634128788), + (12211557331022285596, 1352433999707303030), + (1091747655926105338, 2163894399531684849), + (4562746939482794594, 1731115519625347879), + (7339546366328145998, 1384892415700278303), + (8053925371383123274, 2215827865120445285), + (6443140297106498619, 1772662292096356228), + (12533209867169019542, 1418129833677084982), + (5295740528502789974, 2269007733883335972), + (15304638867027962949, 1815206187106668777), + (4865013464138549713, 1452164949685335022), + (14960057215536570740, 1161731959748268017), + (9178696285890871890, 1858771135597228828), + (14721654658196518159, 1487016908477783062), + (4398626097073393881, 1189613526782226450), + (7037801755317430209, 1903381642851562320), + (5630241404253944167, 1522705314281249856), + (814844308661245011, 1218164251424999885), + (1303750893857992017, 1949062802279999816), + (15800395974054034906, 1559250241823999852), + (5261619149759407279, 1247400193459199882), + (12107939454356961969, 1995840309534719811), + (5997002748743659252, 1596672247627775849), + (8486951013736837725, 1277337798102220679), + (2511075177753209390, 2043740476963553087), + (13076906586428298482, 1634992381570842469), + (14150874083884549109, 1307993905256673975), + (4194654460505726958, 2092790248410678361), + (18113118827372222859, 1674232198728542688), + (3422448617672047318, 1339385758982834151), + (16543964232501006678, 2143017214372534641), + (9545822571258895019, 1714413771498027713), + (15015355686490936662, 1371531017198422170), + (5577825024675947042, 2194449627517475473), + (11840957649224578280, 1755559702013980378), + (16851463748863483271, 1404447761611184302), + (12204946739213931940, 2247116418577894884), + (13453306206113055875, 1797693134862315907), + (3383947335406624054, 1438154507889852726), + (16482362180876329456, 2301047212623764361), + (9496540929959153242, 1840837770099011489), + (11286581558709232917, 1472670216079209191), + (5339916432225476010, 1178136172863367353), + (4854517476818851293, 1885017876581387765), + (3883613981455081034, 1508014301265110212), + (14174937629389795797, 1206411441012088169), + (11611853762797942306, 1930258305619341071), + (5600134195496443521, 1544206644495472857), + (15548153800622885787, 1235365315596378285), + (6430302007287065643, 1976584504954205257), + (16212288050055383484, 1581267603963364205), + (12969830440044306787, 1265014083170691364), + (9683682259845159889, 2024022533073106183), + (15125643437359948558, 1619218026458484946), + (8411165935146048523, 1295374421166787957), + (17147214310975587960, 2072599073866860731), + (10028422634038560045, 1658079259093488585), + (8022738107230848036, 1326463407274790868), + (9147032156827446534, 2122341451639665389), + (11006974540203867551, 1697873161311732311), + (5116230817421183718, 1358298529049385849), + (15564666937357714594, 2173277646479017358), + (1383687105660440706, 1738622117183213887), + (12174996128754083534, 1390897693746571109), + (8411947361780802685, 2225436309994513775), + (6729557889424642148, 1780349047995611020), + (5383646311539713719, 1424279238396488816), + (1235136468979721303, 2278846781434382106), + (15745504434151418335, 1823077425147505684), + (16285752362063044992, 1458461940118004547), + (5649904260166615347, 1166769552094403638), + (5350498001524674232, 1866831283351045821), + (591049586477829062, 1493465026680836657), + (11540886113407994219, 1194772021344669325), + (18673707743239135, 1911635234151470921), + (14772334225162232601, 1529308187321176736), + (8128518565387875758, 1223446549856941389), + (1937583260394870242, 1957514479771106223), + (8928764237799716840, 1566011583816884978), + (14521709019723594119, 1252809267053507982), + (8477339172590109297, 2004494827285612772), + (17849917782297818407, 1603595861828490217), + (6901236596354434079, 1282876689462792174), + (18420676183650915173, 2052602703140467478), + (3668494502695001169, 1642082162512373983), + (10313493231639821582, 1313665730009899186), + (9122891541139893884, 2101865168015838698), + (14677010862395735754, 1681492134412670958), + (673562245690857633, 1345193707530136767), +]; + +pub static DOUBLE_POW5_SPLIT: [(u64, u64); DOUBLE_POW5_TABLE_SIZE] = [ + (0, 1152921504606846976), + (0, 1441151880758558720), + (0, 1801439850948198400), + (0, 2251799813685248000), + (0, 1407374883553280000), + (0, 1759218604441600000), + (0, 2199023255552000000), + (0, 1374389534720000000), + (0, 1717986918400000000), + (0, 2147483648000000000), + (0, 1342177280000000000), + (0, 1677721600000000000), + (0, 2097152000000000000), + (0, 1310720000000000000), + (0, 1638400000000000000), + (0, 2048000000000000000), + (0, 1280000000000000000), + (0, 1600000000000000000), + (0, 2000000000000000000), + (0, 1250000000000000000), + (0, 1562500000000000000), + (0, 1953125000000000000), + (0, 1220703125000000000), + (0, 1525878906250000000), + (0, 1907348632812500000), + (0, 1192092895507812500), + (0, 1490116119384765625), + (4611686018427387904, 1862645149230957031), + (9799832789158199296, 1164153218269348144), + (12249790986447749120, 1455191522836685180), + (15312238733059686400, 1818989403545856475), + (14528612397897220096, 2273736754432320594), + (13692068767113150464, 1421085471520200371), + (12503399940464050176, 1776356839400250464), + (15629249925580062720, 2220446049250313080), + (9768281203487539200, 1387778780781445675), + (7598665485932036096, 1734723475976807094), + (274959820560269312, 2168404344971008868), + (9395221924704944128, 1355252715606880542), + (2520655369026404352, 1694065894508600678), + (12374191248137781248, 2117582368135750847), + (14651398557727195136, 1323488980084844279), + (13702562178731606016, 1654361225106055349), + (3293144668132343808, 2067951531382569187), + (18199116482078572544, 1292469707114105741), + (8913837547316051968, 1615587133892632177), + (15753982952572452864, 2019483917365790221), + (12152082354571476992, 1262177448353618888), + (15190102943214346240, 1577721810442023610), + (9764256642163156992, 1972152263052529513), + (17631875447420442880, 1232595164407830945), + (8204786253993389888, 1540743955509788682), + (1032610780636961552, 1925929944387235853), + (2951224747111794922, 1203706215242022408), + (3689030933889743652, 1504632769052528010), + (13834660704216955373, 1880790961315660012), + (17870034976990372916, 1175494350822287507), + (17725857702810578241, 1469367938527859384), + (3710578054803671186, 1836709923159824231), + (26536550077201078, 2295887403949780289), + (11545800389866720434, 1434929627468612680), + (14432250487333400542, 1793662034335765850), + (8816941072311974870, 2242077542919707313), + (17039803216263454053, 1401298464324817070), + (12076381983474541759, 1751623080406021338), + (5872105442488401391, 2189528850507526673), + (15199280947623720629, 1368455531567204170), + (9775729147674874978, 1710569414459005213), + (16831347453020981627, 2138211768073756516), + (1296220121283337709, 1336382355046097823), + (15455333206886335848, 1670477943807622278), + (10095794471753144002, 2088097429759527848), + (6309871544845715001, 1305060893599704905), + (12499025449484531656, 1631326116999631131), + (11012095793428276666, 2039157646249538914), + (11494245889320060820, 1274473528905961821), + (532749306367912313, 1593091911132452277), + (5277622651387278295, 1991364888915565346), + (7910200175544436838, 1244603055572228341), + (14499436237857933952, 1555753819465285426), + (8900923260467641632, 1944692274331606783), + (12480606065433357876, 1215432671457254239), + (10989071563364309441, 1519290839321567799), + (9124653435777998898, 1899113549151959749), + (8008751406574943263, 1186945968219974843), + (5399253239791291175, 1483682460274968554), + (15972438586593889776, 1854603075343710692), + (759402079766405302, 1159126922089819183), + (14784310654990170340, 1448908652612273978), + (9257016281882937117, 1811135815765342473), + (16182956370781059300, 2263919769706678091), + (7808504722524468110, 1414949856066673807), + (5148944884728197234, 1768687320083342259), + (1824495087482858639, 2210859150104177824), + (1140309429676786649, 1381786968815111140), + (1425386787095983311, 1727233711018888925), + (6393419502297367043, 2159042138773611156), + (13219259225790630210, 1349401336733506972), + (16524074032238287762, 1686751670916883715), + (16043406521870471799, 2108439588646104644), + (803757039314269066, 1317774742903815403), + (14839754354425000045, 1647218428629769253), + (4714634887749086344, 2059023035787211567), + (9864175832484260821, 1286889397367007229), + (16941905809032713930, 1608611746708759036), + (2730638187581340797, 2010764683385948796), + (10930020904093113806, 1256727927116217997), + (18274212148543780162, 1570909908895272496), + (4396021111970173586, 1963637386119090621), + (5053356204195052443, 1227273366324431638), + (15540067292098591362, 1534091707905539547), + (14813398096695851299, 1917614634881924434), + (13870059828862294966, 1198509146801202771), + (12725888767650480803, 1498136433501503464), + (15907360959563101004, 1872670541876879330), + (14553786618154326031, 1170419088673049581), + (4357175217410743827, 1463023860841311977), + (10058155040190817688, 1828779826051639971), + (7961007781811134206, 2285974782564549964), + (14199001900486734687, 1428734239102843727), + (13137066357181030455, 1785917798878554659), + (11809646928048900164, 2232397248598193324), + (16604401366885338411, 1395248280373870827), + (16143815690179285109, 1744060350467338534), + (10956397575869330579, 2180075438084173168), + (6847748484918331612, 1362547148802608230), + (17783057643002690323, 1703183936003260287), + (17617136035325974999, 2128979920004075359), + (17928239049719816230, 1330612450002547099), + (17798612793722382384, 1663265562503183874), + (13024893955298202172, 2079081953128979843), + (5834715712847682405, 1299426220705612402), + (16516766677914378815, 1624282775882015502), + (11422586310538197711, 2030353469852519378), + (11750802462513761473, 1268970918657824611), + (10076817059714813937, 1586213648322280764), + (12596021324643517422, 1982767060402850955), + (5566670318688504437, 1239229412751781847), + (2346651879933242642, 1549036765939727309), + (7545000868343941206, 1936295957424659136), + (4715625542714963254, 1210184973390411960), + (5894531928393704067, 1512731216738014950), + (16591536947346905892, 1890914020922518687), + (17287239619732898039, 1181821263076574179), + (16997363506238734644, 1477276578845717724), + (2799960309088866689, 1846595723557147156), + (10973347230035317489, 1154122327223216972), + (13716684037544146861, 1442652909029021215), + (12534169028502795672, 1803316136286276519), + (11056025267201106687, 2254145170357845649), + (18439230838069161439, 1408840731473653530), + (13825666510731675991, 1761050914342066913), + (3447025083132431277, 2201313642927583642), + (6766076695385157452, 1375821026829739776), + (8457595869231446815, 1719776283537174720), + (10571994836539308519, 2149720354421468400), + (6607496772837067824, 1343575221513417750), + (17482743002901110588, 1679469026891772187), + (17241742735199000331, 2099336283614715234), + (15387775227926763111, 1312085177259197021), + (5399660979626290177, 1640106471573996277), + (11361262242960250625, 2050133089467495346), + (11712474920277544544, 1281333180917184591), + (10028907631919542777, 1601666476146480739), + (7924448521472040567, 2002083095183100924), + (14176152362774801162, 1251301934489438077), + (3885132398186337741, 1564127418111797597), + (9468101516160310080, 1955159272639746996), + (15140935484454969608, 1221974545399841872), + (479425281859160394, 1527468181749802341), + (5210967620751338397, 1909335227187252926), + (17091912818251750210, 1193334516992033078), + (12141518985959911954, 1491668146240041348), + (15176898732449889943, 1864585182800051685), + (11791404716994875166, 1165365739250032303), + (10127569877816206054, 1456707174062540379), + (8047776328842869663, 1820883967578175474), + (836348374198811271, 2276104959472719343), + (7440246761515338900, 1422565599670449589), + (13911994470321561530, 1778206999588061986), + (8166621051047176104, 2222758749485077483), + (2798295147690791113, 1389224218428173427), + (17332926989895652603, 1736530273035216783), + (17054472718942177850, 2170662841294020979), + (8353202440125167204, 1356664275808763112), + (10441503050156459005, 1695830344760953890), + (3828506775840797949, 2119787930951192363), + (86973725686804766, 1324867456844495227), + (13943775212390669669, 1656084321055619033), + (3594660960206173375, 2070105401319523792), + (2246663100128858359, 1293815875824702370), + (12031700912015848757, 1617269844780877962), + (5816254103165035138, 2021587305976097453), + (5941001823691840913, 1263492066235060908), + (7426252279614801142, 1579365082793826135), + (4671129331091113523, 1974206353492282669), + (5225298841145639904, 1233878970932676668), + (6531623551432049880, 1542348713665845835), + (3552843420862674446, 1927935892082307294), + (16055585193321335241, 1204959932551442058), + (10846109454796893243, 1506199915689302573), + (18169322836923504458, 1882749894611628216), + (11355826773077190286, 1176718684132267635), + (9583097447919099954, 1470898355165334544), + (11978871809898874942, 1838622943956668180), + (14973589762373593678, 2298278679945835225), + (2440964573842414192, 1436424174966147016), + (3051205717303017741, 1795530218707683770), + (13037379183483547984, 2244412773384604712), + (8148361989677217490, 1402757983365377945), + (14797138505523909766, 1753447479206722431), + (13884737113477499304, 2191809349008403039), + (15595489723564518921, 1369880843130251899), + (14882676136028260747, 1712351053912814874), + (9379973133180550126, 2140438817391018593), + (17391698254306313589, 1337774260869386620), + (3292878744173340370, 1672217826086733276), + (4116098430216675462, 2090272282608416595), + (266718509671728212, 1306420176630260372), + (333398137089660265, 1633025220787825465), + (5028433689789463235, 2041281525984781831), + (10060300083759496378, 1275800953740488644), + (12575375104699370472, 1594751192175610805), + (1884160825592049379, 1993438990219513507), + (17318501580490888525, 1245899368887195941), + (7813068920331446945, 1557374211108994927), + (5154650131986920777, 1946717763886243659), + (915813323278131534, 1216698602428902287), + (14979824709379828129, 1520873253036127858), + (9501408849870009354, 1901091566295159823), + (12855909558809837702, 1188182228934474889), + (2234828893230133415, 1485227786168093612), + (2793536116537666769, 1856534732710117015), + (8663489100477123587, 1160334207943823134), + (1605989338741628675, 1450417759929778918), + (11230858710281811652, 1813022199912223647), + (9426887369424876662, 2266277749890279559), + (12809333633531629769, 1416423593681424724), + (16011667041914537212, 1770529492101780905), + (6179525747111007803, 2213161865127226132), + (13085575628799155685, 1383226165704516332), + (16356969535998944606, 1729032707130645415), + (15834525901571292854, 2161290883913306769), + (2979049660840976177, 1350806802445816731), + (17558870131333383934, 1688508503057270913), + (8113529608884566205, 2110635628821588642), + (9682642023980241782, 1319147268013492901), + (16714988548402690132, 1648934085016866126), + (11670363648648586857, 2061167606271082658), + (11905663298832754689, 1288229753919426661), + (1047021068258779650, 1610287192399283327), + (15143834390605638274, 2012858990499104158), + (4853210475701136017, 1258036869061940099), + (1454827076199032118, 1572546086327425124), + (1818533845248790147, 1965682607909281405), + (3442426662494187794, 1228551629943300878), + (13526405364972510550, 1535689537429126097), + (3072948650933474476, 1919611921786407622), + (15755650962115585259, 1199757451116504763), + (15082877684217093670, 1499696813895630954), + (9630225068416591280, 1874621017369538693), + (8324733676974063502, 1171638135855961683), + (5794231077790191473, 1464547669819952104), + (7242788847237739342, 1830684587274940130), + (18276858095901949986, 2288355734093675162), + (16034722328366106645, 1430222333808546976), + (1596658836748081690, 1787777917260683721), + (6607509564362490017, 2234722396575854651), + (1823850468512862308, 1396701497859909157), + (6891499104068465790, 1745876872324886446), + (17837745916940358045, 2182346090406108057), + (4231062170446641922, 1363966306503817536), + (5288827713058302403, 1704957883129771920), + (6611034641322878003, 2131197353912214900), + (13355268687681574560, 1331998346195134312), + (16694085859601968200, 1664997932743917890), + (11644235287647684442, 2081247415929897363), + (4971804045566108824, 1300779634956185852), + (6214755056957636030, 1625974543695232315), + (3156757802769657134, 2032468179619040394), + (6584659645158423613, 1270292612261900246), + (17454196593302805324, 1587865765327375307), + (17206059723201118751, 1984832206659219134), + (6142101308573311315, 1240520129162011959), + (3065940617289251240, 1550650161452514949), + (8444111790038951954, 1938312701815643686), + (665883850346957067, 1211445438634777304), + (832354812933696334, 1514306798293471630), + (10263815553021896226, 1892883497866839537), + (17944099766707154901, 1183052186166774710), + (13206752671529167818, 1478815232708468388), + (16508440839411459773, 1848519040885585485), + (12623618533845856310, 1155324400553490928), + (15779523167307320387, 1444155500691863660), + (1277659885424598868, 1805194375864829576), + (1597074856780748586, 2256492969831036970), + (5609857803915355770, 1410308106144398106), + (16235694291748970521, 1762885132680497632), + (1847873790976661535, 2203606415850622041), + (12684136165428883219, 1377254009906638775), + (11243484188358716120, 1721567512383298469), + (219297180166231438, 2151959390479123087), + (7054589765244976505, 1344974619049451929), + (13429923224983608535, 1681218273811814911), + (12175718012802122765, 2101522842264768639), + (14527352785642408584, 1313451776415480399), + (13547504963625622826, 1641814720519350499), + (12322695186104640628, 2052268400649188124), + (16925056528170176201, 1282667750405742577), + (7321262604930556539, 1603334688007178222), + (18374950293017971482, 2004168360008972777), + (4566814905495150320, 1252605225005607986), + (14931890668723713708, 1565756531257009982), + (9441491299049866327, 1957195664071262478), + (1289246043478778550, 1223247290044539049), + (6223243572775861092, 1529059112555673811), + (3167368447542438461, 1911323890694592264), + (1979605279714024038, 1194577431684120165), + (7086192618069917952, 1493221789605150206), + (18081112809442173248, 1866527237006437757), + (13606538515115052232, 1166579523129023598), + (7784801107039039482, 1458224403911279498), + (507629346944023544, 1822780504889099373), + (5246222702107417334, 2278475631111374216), + (3278889188817135834, 1424047269444608885), + (8710297504448807696, 1780059086805761106), +]; diff --git a/vendor/ryu/src/d2s_intrinsics.rs b/vendor/ryu/src/d2s_intrinsics.rs new file mode 100644 index 0000000..a4e1fb1 --- /dev/null +++ b/vendor/ryu/src/d2s_intrinsics.rs @@ -0,0 +1,89 @@ +// Translated from C to Rust. The original C code can be found at +// https://github.com/ulfjack/ryu and carries the following license: +// +// Copyright 2018 Ulf Adams +// +// The contents of this file may be used under the terms of the Apache License, +// Version 2.0. +// +// (See accompanying file LICENSE-Apache or copy at +// http://www.apache.org/licenses/LICENSE-2.0) +// +// Alternatively, the contents of this file may be used under the terms of +// the Boost Software License, Version 1.0. +// (See accompanying file LICENSE-Boost or copy at +// https://www.boost.org/LICENSE_1_0.txt) +// +// Unless required by applicable law or agreed to in writing, this software +// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. + +use core::ptr; + +#[cfg_attr(feature = "no-panic", inline)] +pub fn div5(x: u64) -> u64 { + x / 5 +} + +#[cfg_attr(feature = "no-panic", inline)] +pub fn div10(x: u64) -> u64 { + x / 10 +} + +#[cfg_attr(feature = "no-panic", inline)] +pub fn div100(x: u64) -> u64 { + x / 100 +} + +#[cfg_attr(feature = "no-panic", inline)] +pub(crate) fn pow5_factor(mut value: u64) -> u32 { + const M_INV_5: u64 = 14757395258967641293; // 5 * m_inv_5 = 1 (mod 2^64) + const N_DIV_5: u64 = 3689348814741910323; // #{ n | n = 0 (mod 2^64) } = 2^64 / 5 + let mut count = 0u32; + loop { + debug_assert!(value != 0); + value = value.wrapping_mul(M_INV_5); + if value > N_DIV_5 { + break; + } + count += 1; + } + count +} + +// Returns true if value is divisible by 5^p. +#[cfg_attr(feature = "no-panic", inline)] +pub fn multiple_of_power_of_5(value: u64, p: u32) -> bool { + // I tried a case distinction on p, but there was no performance difference. + pow5_factor(value) >= p +} + +// Returns true if value is divisible by 2^p. +#[cfg_attr(feature = "no-panic", inline)] +pub fn multiple_of_power_of_2(value: u64, p: u32) -> bool { + debug_assert!(value != 0); + debug_assert!(p < 64); + // __builtin_ctzll doesn't appear to be faster here. + (value & ((1u64 << p) - 1)) == 0 +} + +#[cfg_attr(feature = "no-panic", inline)] +pub fn mul_shift_64(m: u64, mul: &(u64, u64), j: u32) -> u64 { + let b0 = m as u128 * mul.0 as u128; + let b2 = m as u128 * mul.1 as u128; + (((b0 >> 64) + b2) >> (j - 64)) as u64 +} + +#[cfg_attr(feature = "no-panic", inline)] +pub unsafe fn mul_shift_all_64( + m: u64, + mul: &(u64, u64), + j: u32, + vp: *mut u64, + vm: *mut u64, + mm_shift: u32, +) -> u64 { + ptr::write(vp, mul_shift_64(4 * m + 2, mul, j)); + ptr::write(vm, mul_shift_64(4 * m - 1 - mm_shift as u64, mul, j)); + mul_shift_64(4 * m, mul, j) +} diff --git a/vendor/ryu/src/d2s_small_table.rs b/vendor/ryu/src/d2s_small_table.rs new file mode 100644 index 0000000..b6e3223 --- /dev/null +++ b/vendor/ryu/src/d2s_small_table.rs @@ -0,0 +1,142 @@ +// Translated from C to Rust. The original C code can be found at +// https://github.com/ulfjack/ryu and carries the following license: +// +// Copyright 2018 Ulf Adams +// +// The contents of this file may be used under the terms of the Apache License, +// Version 2.0. +// +// (See accompanying file LICENSE-Apache or copy at +// http://www.apache.org/licenses/LICENSE-2.0) +// +// Alternatively, the contents of this file may be used under the terms of +// the Boost Software License, Version 1.0. +// (See accompanying file LICENSE-Boost or copy at +// https://www.boost.org/LICENSE_1_0.txt) +// +// Unless required by applicable law or agreed to in writing, this software +// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. + +use crate::common::pow5bits; + +pub static DOUBLE_POW5_INV_SPLIT2: [(u64, u64); 15] = [ + (1, 2305843009213693952), + (5955668970331000884, 1784059615882449851), + (8982663654677661702, 1380349269358112757), + (7286864317269821294, 2135987035920910082), + (7005857020398200553, 1652639921975621497), + (17965325103354776697, 1278668206209430417), + (8928596168509315048, 1978643211784836272), + (10075671573058298858, 1530901034580419511), + (597001226353042382, 1184477304306571148), + (1527430471115325346, 1832889850782397517), + (12533209867169019542, 1418129833677084982), + (5577825024675947042, 2194449627517475473), + (11006974540203867551, 1697873161311732311), + (10313493231639821582, 1313665730009899186), + (12701016819766672773, 2032799256770390445), +]; + +pub static POW5_INV_OFFSETS: [u32; 19] = [ + 0x54544554, 0x04055545, 0x10041000, 0x00400414, 0x40010000, 0x41155555, 0x00000454, 0x00010044, + 0x40000000, 0x44000041, 0x50454450, 0x55550054, 0x51655554, 0x40004000, 0x01000001, 0x00010500, + 0x51515411, 0x05555554, 0x00000000, +]; + +pub static DOUBLE_POW5_SPLIT2: [(u64, u64); 13] = [ + (0, 1152921504606846976), + (0, 1490116119384765625), + (1032610780636961552, 1925929944387235853), + (7910200175544436838, 1244603055572228341), + (16941905809032713930, 1608611746708759036), + (13024893955298202172, 2079081953128979843), + (6607496772837067824, 1343575221513417750), + (17332926989895652603, 1736530273035216783), + (13037379183483547984, 2244412773384604712), + (1605989338741628675, 1450417759929778918), + (9630225068416591280, 1874621017369538693), + (665883850346957067, 1211445438634777304), + (14931890668723713708, 1565756531257009982), +]; + +pub static POW5_OFFSETS: [u32; 21] = [ + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x40000000, 0x59695995, 0x55545555, 0x56555515, + 0x41150504, 0x40555410, 0x44555145, 0x44504540, 0x45555550, 0x40004000, 0x96440440, 0x55565565, + 0x54454045, 0x40154151, 0x55559155, 0x51405555, 0x00000105, +]; + +pub static DOUBLE_POW5_TABLE: [u64; 26] = [ + 1, + 5, + 25, + 125, + 625, + 3125, + 15625, + 78125, + 390625, + 1953125, + 9765625, + 48828125, + 244140625, + 1220703125, + 6103515625, + 30517578125, + 152587890625, + 762939453125, + 3814697265625, + 19073486328125, + 95367431640625, + 476837158203125, + 2384185791015625, + 11920928955078125, + 59604644775390625, + 298023223876953125, +]; + +// Computes 5^i in the form required by Ryū. +#[cfg_attr(feature = "no-panic", inline)] +pub unsafe fn compute_pow5(i: u32) -> (u64, u64) { + let base = i / DOUBLE_POW5_TABLE.len() as u32; + let base2 = base * DOUBLE_POW5_TABLE.len() as u32; + let offset = i - base2; + debug_assert!(base < DOUBLE_POW5_SPLIT2.len() as u32); + let mul = *DOUBLE_POW5_SPLIT2.get_unchecked(base as usize); + if offset == 0 { + return mul; + } + debug_assert!(offset < DOUBLE_POW5_TABLE.len() as u32); + let m = *DOUBLE_POW5_TABLE.get_unchecked(offset as usize); + let b0 = m as u128 * mul.0 as u128; + let b2 = m as u128 * mul.1 as u128; + let delta = pow5bits(i as i32) - pow5bits(base2 as i32); + debug_assert!(i / 16 < POW5_OFFSETS.len() as u32); + let shifted_sum = (b0 >> delta) + + (b2 << (64 - delta)) + + ((*POW5_OFFSETS.get_unchecked((i / 16) as usize) >> ((i % 16) << 1)) & 3) as u128; + (shifted_sum as u64, (shifted_sum >> 64) as u64) +} + +// Computes 5^-i in the form required by Ryū. +#[cfg_attr(feature = "no-panic", inline)] +pub unsafe fn compute_inv_pow5(i: u32) -> (u64, u64) { + let base = (i + DOUBLE_POW5_TABLE.len() as u32 - 1) / DOUBLE_POW5_TABLE.len() as u32; + let base2 = base * DOUBLE_POW5_TABLE.len() as u32; + let offset = base2 - i; + debug_assert!(base < DOUBLE_POW5_INV_SPLIT2.len() as u32); + let mul = *DOUBLE_POW5_INV_SPLIT2.get_unchecked(base as usize); // 1/5^base2 + if offset == 0 { + return mul; + } + debug_assert!(offset < DOUBLE_POW5_TABLE.len() as u32); + let m = *DOUBLE_POW5_TABLE.get_unchecked(offset as usize); // 5^offset + let b0 = m as u128 * (mul.0 - 1) as u128; + let b2 = m as u128 * mul.1 as u128; // 1/5^base2 * 5^offset = 1/5^(base2-offset) = 1/5^i + let delta = pow5bits(base2 as i32) - pow5bits(i as i32); + debug_assert!(base < POW5_INV_OFFSETS.len() as u32); + let shifted_sum = ((b0 >> delta) + (b2 << (64 - delta))) + + 1 + + ((*POW5_INV_OFFSETS.get_unchecked((i / 16) as usize) >> ((i % 16) << 1)) & 3) as u128; + (shifted_sum as u64, (shifted_sum >> 64) as u64) +} diff --git a/vendor/ryu/src/digit_table.rs b/vendor/ryu/src/digit_table.rs new file mode 100644 index 0000000..d871f03 --- /dev/null +++ b/vendor/ryu/src/digit_table.rs @@ -0,0 +1,28 @@ +// Translated from C to Rust. The original C code can be found at +// https://github.com/ulfjack/ryu and carries the following license: +// +// Copyright 2018 Ulf Adams +// +// The contents of this file may be used under the terms of the Apache License, +// Version 2.0. +// +// (See accompanying file LICENSE-Apache or copy at +// http://www.apache.org/licenses/LICENSE-2.0) +// +// Alternatively, the contents of this file may be used under the terms of +// the Boost Software License, Version 1.0. +// (See accompanying file LICENSE-Boost or copy at +// https://www.boost.org/LICENSE_1_0.txt) +// +// Unless required by applicable law or agreed to in writing, this software +// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. + +// A table of all two-digit numbers. This is used to speed up decimal digit +// generation by copying pairs of digits into the final output. +pub static DIGIT_TABLE: [u8; 200] = *b"\ + 0001020304050607080910111213141516171819\ + 2021222324252627282930313233343536373839\ + 4041424344454647484950515253545556575859\ + 6061626364656667686970717273747576777879\ + 8081828384858687888990919293949596979899"; diff --git a/vendor/ryu/src/f2s.rs b/vendor/ryu/src/f2s.rs new file mode 100644 index 0000000..987fefb --- /dev/null +++ b/vendor/ryu/src/f2s.rs @@ -0,0 +1,178 @@ +// Translated from C to Rust. The original C code can be found at +// https://github.com/ulfjack/ryu and carries the following license: +// +// Copyright 2018 Ulf Adams +// +// The contents of this file may be used under the terms of the Apache License, +// Version 2.0. +// +// (See accompanying file LICENSE-Apache or copy at +// http://www.apache.org/licenses/LICENSE-2.0) +// +// Alternatively, the contents of this file may be used under the terms of +// the Boost Software License, Version 1.0. +// (See accompanying file LICENSE-Boost or copy at +// https://www.boost.org/LICENSE_1_0.txt) +// +// Unless required by applicable law or agreed to in writing, this software +// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. + +use crate::common::{log10_pow2, log10_pow5, pow5bits}; +use crate::f2s_intrinsics::{ + mul_pow5_div_pow2, mul_pow5_inv_div_pow2, multiple_of_power_of_2_32, multiple_of_power_of_5_32, +}; + +pub const FLOAT_MANTISSA_BITS: u32 = 23; +pub const FLOAT_EXPONENT_BITS: u32 = 8; +const FLOAT_BIAS: i32 = 127; +pub use crate::f2s_intrinsics::{FLOAT_POW5_BITCOUNT, FLOAT_POW5_INV_BITCOUNT}; + +// A floating decimal representing m * 10^e. +pub struct FloatingDecimal32 { + pub mantissa: u32, + // Decimal exponent's range is -45 to 38 + // inclusive, and can fit in i16 if needed. + pub exponent: i32, +} + +#[cfg_attr(feature = "no-panic", inline)] +pub fn f2d(ieee_mantissa: u32, ieee_exponent: u32) -> FloatingDecimal32 { + let (e2, m2) = if ieee_exponent == 0 { + ( + // We subtract 2 so that the bounds computation has 2 additional bits. + 1 - FLOAT_BIAS - FLOAT_MANTISSA_BITS as i32 - 2, + ieee_mantissa, + ) + } else { + ( + ieee_exponent as i32 - FLOAT_BIAS - FLOAT_MANTISSA_BITS as i32 - 2, + (1u32 << FLOAT_MANTISSA_BITS) | ieee_mantissa, + ) + }; + let even = (m2 & 1) == 0; + let accept_bounds = even; + + // Step 2: Determine the interval of valid decimal representations. + let mv = 4 * m2; + let mp = 4 * m2 + 2; + // Implicit bool -> int conversion. True is 1, false is 0. + let mm_shift = (ieee_mantissa != 0 || ieee_exponent <= 1) as u32; + let mm = 4 * m2 - 1 - mm_shift; + + // Step 3: Convert to a decimal power base using 64-bit arithmetic. + let mut vr: u32; + let mut vp: u32; + let mut vm: u32; + let e10: i32; + let mut vm_is_trailing_zeros = false; + let mut vr_is_trailing_zeros = false; + let mut last_removed_digit = 0u8; + if e2 >= 0 { + let q = log10_pow2(e2); + e10 = q as i32; + let k = FLOAT_POW5_INV_BITCOUNT + pow5bits(q as i32) - 1; + let i = -e2 + q as i32 + k; + vr = mul_pow5_inv_div_pow2(mv, q, i); + vp = mul_pow5_inv_div_pow2(mp, q, i); + vm = mul_pow5_inv_div_pow2(mm, q, i); + if q != 0 && (vp - 1) / 10 <= vm / 10 { + // We need to know one removed digit even if we are not going to loop below. We could use + // q = X - 1 above, except that would require 33 bits for the result, and we've found that + // 32-bit arithmetic is faster even on 64-bit machines. + let l = FLOAT_POW5_INV_BITCOUNT + pow5bits(q as i32 - 1) - 1; + last_removed_digit = + (mul_pow5_inv_div_pow2(mv, q - 1, -e2 + q as i32 - 1 + l) % 10) as u8; + } + if q <= 9 { + // The largest power of 5 that fits in 24 bits is 5^10, but q <= 9 seems to be safe as well. + // Only one of mp, mv, and mm can be a multiple of 5, if any. + if mv % 5 == 0 { + vr_is_trailing_zeros = multiple_of_power_of_5_32(mv, q); + } else if accept_bounds { + vm_is_trailing_zeros = multiple_of_power_of_5_32(mm, q); + } else { + vp -= multiple_of_power_of_5_32(mp, q) as u32; + } + } + } else { + let q = log10_pow5(-e2); + e10 = q as i32 + e2; + let i = -e2 - q as i32; + let k = pow5bits(i) - FLOAT_POW5_BITCOUNT; + let mut j = q as i32 - k; + vr = mul_pow5_div_pow2(mv, i as u32, j); + vp = mul_pow5_div_pow2(mp, i as u32, j); + vm = mul_pow5_div_pow2(mm, i as u32, j); + if q != 0 && (vp - 1) / 10 <= vm / 10 { + j = q as i32 - 1 - (pow5bits(i + 1) - FLOAT_POW5_BITCOUNT); + last_removed_digit = (mul_pow5_div_pow2(mv, (i + 1) as u32, j) % 10) as u8; + } + if q <= 1 { + // {vr,vp,vm} is trailing zeros if {mv,mp,mm} has at least q trailing 0 bits. + // mv = 4 * m2, so it always has at least two trailing 0 bits. + vr_is_trailing_zeros = true; + if accept_bounds { + // mm = mv - 1 - mm_shift, so it has 1 trailing 0 bit iff mm_shift == 1. + vm_is_trailing_zeros = mm_shift == 1; + } else { + // mp = mv + 2, so it always has at least one trailing 0 bit. + vp -= 1; + } + } else if q < 31 { + // TODO(ulfjack): Use a tighter bound here. + vr_is_trailing_zeros = multiple_of_power_of_2_32(mv, q - 1); + } + } + + // Step 4: Find the shortest decimal representation in the interval of valid representations. + let mut removed = 0i32; + let output = if vm_is_trailing_zeros || vr_is_trailing_zeros { + // General case, which happens rarely (~4.0%). + while vp / 10 > vm / 10 { + vm_is_trailing_zeros &= vm - (vm / 10) * 10 == 0; + vr_is_trailing_zeros &= last_removed_digit == 0; + last_removed_digit = (vr % 10) as u8; + vr /= 10; + vp /= 10; + vm /= 10; + removed += 1; + } + if vm_is_trailing_zeros { + while vm % 10 == 0 { + vr_is_trailing_zeros &= last_removed_digit == 0; + last_removed_digit = (vr % 10) as u8; + vr /= 10; + vp /= 10; + vm /= 10; + removed += 1; + } + } + if vr_is_trailing_zeros && last_removed_digit == 5 && vr % 2 == 0 { + // Round even if the exact number is .....50..0. + last_removed_digit = 4; + } + // We need to take vr + 1 if vr is outside bounds or we need to round up. + vr + ((vr == vm && (!accept_bounds || !vm_is_trailing_zeros)) || last_removed_digit >= 5) + as u32 + } else { + // Specialized for the common case (~96.0%). Percentages below are relative to this. + // Loop iterations below (approximately): + // 0: 13.6%, 1: 70.7%, 2: 14.1%, 3: 1.39%, 4: 0.14%, 5+: 0.01% + while vp / 10 > vm / 10 { + last_removed_digit = (vr % 10) as u8; + vr /= 10; + vp /= 10; + vm /= 10; + removed += 1; + } + // We need to take vr + 1 if vr is outside bounds or we need to round up. + vr + (vr == vm || last_removed_digit >= 5) as u32 + }; + let exp = e10 + removed; + + FloatingDecimal32 { + exponent: exp, + mantissa: output, + } +} diff --git a/vendor/ryu/src/f2s_intrinsics.rs b/vendor/ryu/src/f2s_intrinsics.rs new file mode 100644 index 0000000..1a35218 --- /dev/null +++ b/vendor/ryu/src/f2s_intrinsics.rs @@ -0,0 +1,113 @@ +// Translated from C to Rust. The original C code can be found at +// https://github.com/ulfjack/ryu and carries the following license: +// +// Copyright 2018 Ulf Adams +// +// The contents of this file may be used under the terms of the Apache License, +// Version 2.0. +// +// (See accompanying file LICENSE-Apache or copy at +// http://www.apache.org/licenses/LICENSE-2.0) +// +// Alternatively, the contents of this file may be used under the terms of +// the Boost Software License, Version 1.0. +// (See accompanying file LICENSE-Boost or copy at +// https://www.boost.org/LICENSE_1_0.txt) +// +// Unless required by applicable law or agreed to in writing, this software +// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. + +use crate::d2s; + +pub const FLOAT_POW5_INV_BITCOUNT: i32 = d2s::DOUBLE_POW5_INV_BITCOUNT - 64; +pub const FLOAT_POW5_BITCOUNT: i32 = d2s::DOUBLE_POW5_BITCOUNT - 64; + +#[cfg_attr(feature = "no-panic", inline)] +fn pow5factor_32(mut value: u32) -> u32 { + let mut count = 0u32; + loop { + debug_assert!(value != 0); + let q = value / 5; + let r = value % 5; + if r != 0 { + break; + } + value = q; + count += 1; + } + count +} + +// Returns true if value is divisible by 5^p. +#[cfg_attr(feature = "no-panic", inline)] +pub fn multiple_of_power_of_5_32(value: u32, p: u32) -> bool { + pow5factor_32(value) >= p +} + +// Returns true if value is divisible by 2^p. +#[cfg_attr(feature = "no-panic", inline)] +pub fn multiple_of_power_of_2_32(value: u32, p: u32) -> bool { + // __builtin_ctz doesn't appear to be faster here. + (value & ((1u32 << p) - 1)) == 0 +} + +// It seems to be slightly faster to avoid uint128_t here, although the +// generated code for uint128_t looks slightly nicer. +#[cfg_attr(feature = "no-panic", inline)] +fn mul_shift_32(m: u32, factor: u64, shift: i32) -> u32 { + debug_assert!(shift > 32); + + // The casts here help MSVC to avoid calls to the __allmul library + // function. + let factor_lo = factor as u32; + let factor_hi = (factor >> 32) as u32; + let bits0 = m as u64 * factor_lo as u64; + let bits1 = m as u64 * factor_hi as u64; + + let sum = (bits0 >> 32) + bits1; + let shifted_sum = sum >> (shift - 32); + debug_assert!(shifted_sum <= u32::max_value() as u64); + shifted_sum as u32 +} + +#[cfg_attr(feature = "no-panic", inline)] +pub fn mul_pow5_inv_div_pow2(m: u32, q: u32, j: i32) -> u32 { + #[cfg(feature = "small")] + { + // The inverse multipliers are defined as [2^x / 5^y] + 1; the upper 64 + // bits from the double lookup table are the correct bits for [2^x / + // 5^y], so we have to add 1 here. Note that we rely on the fact that + // the added 1 that's already stored in the table never overflows into + // the upper 64 bits. + let pow5 = unsafe { d2s::compute_inv_pow5(q) }; + mul_shift_32(m, pow5.1 + 1, j) + } + + #[cfg(not(feature = "small"))] + { + debug_assert!(q < d2s::DOUBLE_POW5_INV_SPLIT.len() as u32); + unsafe { + mul_shift_32( + m, + d2s::DOUBLE_POW5_INV_SPLIT.get_unchecked(q as usize).1 + 1, + j, + ) + } + } +} + +#[cfg_attr(feature = "no-panic", inline)] +pub fn mul_pow5_div_pow2(m: u32, i: u32, j: i32) -> u32 { + #[cfg(feature = "small")] + { + let pow5 = unsafe { d2s::compute_pow5(i) }; + mul_shift_32(m, pow5.1, j) + } + + #[cfg(not(feature = "small"))] + { + debug_assert!(i < d2s::DOUBLE_POW5_SPLIT.len() as u32); + unsafe { mul_shift_32(m, d2s::DOUBLE_POW5_SPLIT.get_unchecked(i as usize).1, j) } + } +} diff --git a/vendor/ryu/src/lib.rs b/vendor/ryu/src/lib.rs new file mode 100644 index 0000000..7b8b450 --- /dev/null +++ b/vendor/ryu/src/lib.rs @@ -0,0 +1,125 @@ +//! [![github]](https://github.com/dtolnay/ryu) [![crates-io]](https://crates.io/crates/ryu) [![docs-rs]](https://docs.rs/ryu) +//! +//! [github]: https://img.shields.io/badge/github-8da0cb?style=for-the-badge&labelColor=555555&logo=github +//! [crates-io]: https://img.shields.io/badge/crates.io-fc8d62?style=for-the-badge&labelColor=555555&logo=rust +//! [docs-rs]: https://img.shields.io/badge/docs.rs-66c2a5?style=for-the-badge&labelColor=555555&logo=docs.rs +//! +//!
+//! +//! Pure Rust implementation of Ryū, an algorithm to quickly convert floating +//! point numbers to decimal strings. +//! +//! The PLDI'18 paper [*Ryū: fast float-to-string conversion*][paper] by Ulf +//! Adams includes a complete correctness proof of the algorithm. The paper is +//! available under the creative commons CC-BY-SA license. +//! +//! This Rust implementation is a line-by-line port of Ulf Adams' implementation +//! in C, [https://github.com/ulfjack/ryu][upstream]. +//! +//! [paper]: https://dl.acm.org/citation.cfm?id=3192369 +//! [upstream]: https://github.com/ulfjack/ryu +//! +//! # Example +//! +//! ``` +//! fn main() { +//! let mut buffer = ryu::Buffer::new(); +//! let printed = buffer.format(1.234); +//! assert_eq!(printed, "1.234"); +//! } +//! ``` +//! +//! ## Performance (lower is better) +//! +//! ![performance](https://raw.githubusercontent.com/dtolnay/ryu/master/performance.png) +//! +//! You can run upstream's benchmarks with: +//! +//! ```console +//! $ git clone https://github.com/ulfjack/ryu c-ryu +//! $ cd c-ryu +//! $ bazel run -c opt //ryu/benchmark +//! ``` +//! +//! And the same benchmark against our implementation with: +//! +//! ```console +//! $ git clone https://github.com/dtolnay/ryu rust-ryu +//! $ cd rust-ryu +//! $ cargo run --example upstream_benchmark --release +//! ``` +//! +//! These benchmarks measure the average time to print a 32-bit float and average +//! time to print a 64-bit float, where the inputs are distributed as uniform random +//! bit patterns 32 and 64 bits wide. +//! +//! The upstream C code, the unsafe direct Rust port, and the safe pretty Rust API +//! all perform the same, taking around 21 nanoseconds to format a 32-bit float and +//! 31 nanoseconds to format a 64-bit float. +//! +//! There is also a Rust-specific benchmark comparing this implementation to the +//! standard library which you can run with: +//! +//! ```console +//! $ cargo bench +//! ``` +//! +//! The benchmark shows Ryū approximately 2-5x faster than the standard library +//! across a range of f32 and f64 inputs. Measurements are in nanoseconds per +//! iteration; smaller is better. +//! +//! ## Formatting +//! +//! This library tends to produce more human-readable output than the standard +//! library's to\_string, which never uses scientific notation. Here are two +//! examples: +//! +//! - *ryu:* 1.23e40, *std:* 12300000000000000000000000000000000000000 +//! - *ryu:* 1.23e-40, *std:* 0.000000000000000000000000000000000000000123 +//! +//! Both libraries print short decimals such as 0.0000123 without scientific +//! notation. + +#![no_std] +#![doc(html_root_url = "https://docs.rs/ryu/1.0.18")] +#![cfg_attr(not(check_cfg), allow(unexpected_cfgs))] +#![allow( + clippy::cast_lossless, + clippy::cast_possible_truncation, + clippy::cast_possible_wrap, + clippy::cast_sign_loss, + clippy::checked_conversions, + clippy::doc_markdown, + clippy::expl_impl_clone_on_copy, + clippy::if_not_else, + clippy::many_single_char_names, + clippy::missing_panics_doc, + clippy::module_name_repetitions, + clippy::must_use_candidate, + clippy::needless_doctest_main, + clippy::similar_names, + clippy::too_many_lines, + clippy::unreadable_literal, + clippy::unseparated_literal_suffix, + clippy::wildcard_imports +)] + +mod buffer; +mod common; +mod d2s; +#[cfg(not(feature = "small"))] +mod d2s_full_table; +mod d2s_intrinsics; +#[cfg(feature = "small")] +mod d2s_small_table; +mod digit_table; +mod f2s; +mod f2s_intrinsics; +mod pretty; + +pub use crate::buffer::{Buffer, Float}; + +/// Unsafe functions that mirror the API of the C implementation of Ryū. +pub mod raw { + pub use crate::pretty::{format32, format64}; +} diff --git a/vendor/ryu/src/parse.rs b/vendor/ryu/src/parse.rs new file mode 100644 index 0000000..00f7983 --- /dev/null +++ b/vendor/ryu/src/parse.rs @@ -0,0 +1,19 @@ +use core::fmt::{self, Display}; + +#[derive(Copy, Clone, Debug)] +pub enum Error { + InputTooShort, + InputTooLong, + MalformedInput, +} + +impl Display for Error { + fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + let msg = match self { + Error::InputTooShort => "input too short", + Error::InputTooLong => "input too long", + Error::MalformedInput => "malformed input", + }; + formatter.write_str(msg) + } +} diff --git a/vendor/ryu/src/pretty/exponent.rs b/vendor/ryu/src/pretty/exponent.rs new file mode 100644 index 0000000..529d92b --- /dev/null +++ b/vendor/ryu/src/pretty/exponent.rs @@ -0,0 +1,48 @@ +use crate::digit_table::DIGIT_TABLE; +use core::ptr; + +#[cfg_attr(feature = "no-panic", inline)] +pub unsafe fn write_exponent3(mut k: isize, mut result: *mut u8) -> usize { + let sign = k < 0; + if sign { + *result = b'-'; + result = result.offset(1); + k = -k; + } + + debug_assert!(k < 1000); + if k >= 100 { + *result = b'0' + (k / 100) as u8; + k %= 100; + let d = DIGIT_TABLE.as_ptr().offset(k * 2); + ptr::copy_nonoverlapping(d, result.offset(1), 2); + sign as usize + 3 + } else if k >= 10 { + let d = DIGIT_TABLE.as_ptr().offset(k * 2); + ptr::copy_nonoverlapping(d, result, 2); + sign as usize + 2 + } else { + *result = b'0' + k as u8; + sign as usize + 1 + } +} + +#[cfg_attr(feature = "no-panic", inline)] +pub unsafe fn write_exponent2(mut k: isize, mut result: *mut u8) -> usize { + let sign = k < 0; + if sign { + *result = b'-'; + result = result.offset(1); + k = -k; + } + + debug_assert!(k < 100); + if k >= 10 { + let d = DIGIT_TABLE.as_ptr().offset(k * 2); + ptr::copy_nonoverlapping(d, result, 2); + sign as usize + 2 + } else { + *result = b'0' + k as u8; + sign as usize + 1 + } +} diff --git a/vendor/ryu/src/pretty/mantissa.rs b/vendor/ryu/src/pretty/mantissa.rs new file mode 100644 index 0000000..552dfe3 --- /dev/null +++ b/vendor/ryu/src/pretty/mantissa.rs @@ -0,0 +1,82 @@ +use crate::digit_table::DIGIT_TABLE; +use core::ptr; + +#[cfg_attr(feature = "no-panic", inline)] +pub unsafe fn write_mantissa_long(mut output: u64, mut result: *mut u8) { + if (output >> 32) != 0 { + // One expensive 64-bit division. + let mut output2 = (output - 100_000_000 * (output / 100_000_000)) as u32; + output /= 100_000_000; + + let c = output2 % 10_000; + output2 /= 10_000; + let d = output2 % 10_000; + let c0 = (c % 100) << 1; + let c1 = (c / 100) << 1; + let d0 = (d % 100) << 1; + let d1 = (d / 100) << 1; + ptr::copy_nonoverlapping( + DIGIT_TABLE.as_ptr().offset(c0 as isize), + result.offset(-2), + 2, + ); + ptr::copy_nonoverlapping( + DIGIT_TABLE.as_ptr().offset(c1 as isize), + result.offset(-4), + 2, + ); + ptr::copy_nonoverlapping( + DIGIT_TABLE.as_ptr().offset(d0 as isize), + result.offset(-6), + 2, + ); + ptr::copy_nonoverlapping( + DIGIT_TABLE.as_ptr().offset(d1 as isize), + result.offset(-8), + 2, + ); + result = result.offset(-8); + } + write_mantissa(output as u32, result); +} + +#[cfg_attr(feature = "no-panic", inline)] +pub unsafe fn write_mantissa(mut output: u32, mut result: *mut u8) { + while output >= 10_000 { + let c = output - 10_000 * (output / 10_000); + output /= 10_000; + let c0 = (c % 100) << 1; + let c1 = (c / 100) << 1; + ptr::copy_nonoverlapping( + DIGIT_TABLE.as_ptr().offset(c0 as isize), + result.offset(-2), + 2, + ); + ptr::copy_nonoverlapping( + DIGIT_TABLE.as_ptr().offset(c1 as isize), + result.offset(-4), + 2, + ); + result = result.offset(-4); + } + if output >= 100 { + let c = (output % 100) << 1; + output /= 100; + ptr::copy_nonoverlapping( + DIGIT_TABLE.as_ptr().offset(c as isize), + result.offset(-2), + 2, + ); + result = result.offset(-2); + } + if output >= 10 { + let c = output << 1; + ptr::copy_nonoverlapping( + DIGIT_TABLE.as_ptr().offset(c as isize), + result.offset(-2), + 2, + ); + } else { + *result.offset(-1) = b'0' + output as u8; + } +} diff --git a/vendor/ryu/src/pretty/mod.rs b/vendor/ryu/src/pretty/mod.rs new file mode 100644 index 0000000..f901c5f --- /dev/null +++ b/vendor/ryu/src/pretty/mod.rs @@ -0,0 +1,224 @@ +mod exponent; +mod mantissa; + +use self::exponent::{write_exponent2, write_exponent3}; +use self::mantissa::{write_mantissa, write_mantissa_long}; +use crate::common; +use crate::d2s::{self, d2d, DOUBLE_EXPONENT_BITS, DOUBLE_MANTISSA_BITS}; +use crate::f2s::{f2d, FLOAT_EXPONENT_BITS, FLOAT_MANTISSA_BITS}; +use core::ptr; +#[cfg(feature = "no-panic")] +use no_panic::no_panic; + +/// Print f64 to the given buffer and return number of bytes written. +/// +/// At most 24 bytes will be written. +/// +/// ## Special cases +/// +/// This function **does not** check for NaN or infinity. If the input +/// number is not a finite float, the printed representation will be some +/// correctly formatted but unspecified numerical value. +/// +/// Please check [`is_finite`] yourself before calling this function, or +/// check [`is_nan`] and [`is_infinite`] and handle those cases yourself. +/// +/// [`is_finite`]: https://doc.rust-lang.org/std/primitive.f64.html#method.is_finite +/// [`is_nan`]: https://doc.rust-lang.org/std/primitive.f64.html#method.is_nan +/// [`is_infinite`]: https://doc.rust-lang.org/std/primitive.f64.html#method.is_infinite +/// +/// ## Safety +/// +/// The `result` pointer argument must point to sufficiently many writable bytes +/// to hold Ryū's representation of `f`. +/// +/// ## Example +/// +/// ``` +/// use std::{mem::MaybeUninit, slice, str}; +/// +/// let f = 1.234f64; +/// +/// unsafe { +/// let mut buffer = [MaybeUninit::::uninit(); 24]; +/// let len = ryu::raw::format64(f, buffer.as_mut_ptr() as *mut u8); +/// let slice = slice::from_raw_parts(buffer.as_ptr() as *const u8, len); +/// let print = str::from_utf8_unchecked(slice); +/// assert_eq!(print, "1.234"); +/// } +/// ``` +#[must_use] +#[cfg_attr(feature = "no-panic", no_panic)] +pub unsafe fn format64(f: f64, result: *mut u8) -> usize { + let bits = f.to_bits(); + let sign = ((bits >> (DOUBLE_MANTISSA_BITS + DOUBLE_EXPONENT_BITS)) & 1) != 0; + let ieee_mantissa = bits & ((1u64 << DOUBLE_MANTISSA_BITS) - 1); + let ieee_exponent = + (bits >> DOUBLE_MANTISSA_BITS) as u32 & ((1u32 << DOUBLE_EXPONENT_BITS) - 1); + + let mut index = 0isize; + if sign { + *result = b'-'; + index += 1; + } + + if ieee_exponent == 0 && ieee_mantissa == 0 { + ptr::copy_nonoverlapping(b"0.0".as_ptr(), result.offset(index), 3); + return sign as usize + 3; + } + + let v = d2d(ieee_mantissa, ieee_exponent); + + let length = d2s::decimal_length17(v.mantissa) as isize; + let k = v.exponent as isize; + let kk = length + k; // 10^(kk-1) <= v < 10^kk + debug_assert!(k >= -324); + + if 0 <= k && kk <= 16 { + // 1234e7 -> 12340000000.0 + write_mantissa_long(v.mantissa, result.offset(index + length)); + for i in length..kk { + *result.offset(index + i) = b'0'; + } + *result.offset(index + kk) = b'.'; + *result.offset(index + kk + 1) = b'0'; + index as usize + kk as usize + 2 + } else if 0 < kk && kk <= 16 { + // 1234e-2 -> 12.34 + write_mantissa_long(v.mantissa, result.offset(index + length + 1)); + ptr::copy(result.offset(index + 1), result.offset(index), kk as usize); + *result.offset(index + kk) = b'.'; + index as usize + length as usize + 1 + } else if -5 < kk && kk <= 0 { + // 1234e-6 -> 0.001234 + *result.offset(index) = b'0'; + *result.offset(index + 1) = b'.'; + let offset = 2 - kk; + for i in 2..offset { + *result.offset(index + i) = b'0'; + } + write_mantissa_long(v.mantissa, result.offset(index + length + offset)); + index as usize + length as usize + offset as usize + } else if length == 1 { + // 1e30 + *result.offset(index) = b'0' + v.mantissa as u8; + *result.offset(index + 1) = b'e'; + index as usize + 2 + write_exponent3(kk - 1, result.offset(index + 2)) + } else { + // 1234e30 -> 1.234e33 + write_mantissa_long(v.mantissa, result.offset(index + length + 1)); + *result.offset(index) = *result.offset(index + 1); + *result.offset(index + 1) = b'.'; + *result.offset(index + length + 1) = b'e'; + index as usize + + length as usize + + 2 + + write_exponent3(kk - 1, result.offset(index + length + 2)) + } +} + +/// Print f32 to the given buffer and return number of bytes written. +/// +/// At most 16 bytes will be written. +/// +/// ## Special cases +/// +/// This function **does not** check for NaN or infinity. If the input +/// number is not a finite float, the printed representation will be some +/// correctly formatted but unspecified numerical value. +/// +/// Please check [`is_finite`] yourself before calling this function, or +/// check [`is_nan`] and [`is_infinite`] and handle those cases yourself. +/// +/// [`is_finite`]: https://doc.rust-lang.org/std/primitive.f32.html#method.is_finite +/// [`is_nan`]: https://doc.rust-lang.org/std/primitive.f32.html#method.is_nan +/// [`is_infinite`]: https://doc.rust-lang.org/std/primitive.f32.html#method.is_infinite +/// +/// ## Safety +/// +/// The `result` pointer argument must point to sufficiently many writable bytes +/// to hold Ryū's representation of `f`. +/// +/// ## Example +/// +/// ``` +/// use std::{mem::MaybeUninit, slice, str}; +/// +/// let f = 1.234f32; +/// +/// unsafe { +/// let mut buffer = [MaybeUninit::::uninit(); 16]; +/// let len = ryu::raw::format32(f, buffer.as_mut_ptr() as *mut u8); +/// let slice = slice::from_raw_parts(buffer.as_ptr() as *const u8, len); +/// let print = str::from_utf8_unchecked(slice); +/// assert_eq!(print, "1.234"); +/// } +/// ``` +#[must_use] +#[cfg_attr(feature = "no-panic", no_panic)] +pub unsafe fn format32(f: f32, result: *mut u8) -> usize { + let bits = f.to_bits(); + let sign = ((bits >> (FLOAT_MANTISSA_BITS + FLOAT_EXPONENT_BITS)) & 1) != 0; + let ieee_mantissa = bits & ((1u32 << FLOAT_MANTISSA_BITS) - 1); + let ieee_exponent = (bits >> FLOAT_MANTISSA_BITS) & ((1u32 << FLOAT_EXPONENT_BITS) - 1); + + let mut index = 0isize; + if sign { + *result = b'-'; + index += 1; + } + + if ieee_exponent == 0 && ieee_mantissa == 0 { + ptr::copy_nonoverlapping(b"0.0".as_ptr(), result.offset(index), 3); + return sign as usize + 3; + } + + let v = f2d(ieee_mantissa, ieee_exponent); + + let length = common::decimal_length9(v.mantissa) as isize; + let k = v.exponent as isize; + let kk = length + k; // 10^(kk-1) <= v < 10^kk + debug_assert!(k >= -45); + + if 0 <= k && kk <= 13 { + // 1234e7 -> 12340000000.0 + write_mantissa(v.mantissa, result.offset(index + length)); + for i in length..kk { + *result.offset(index + i) = b'0'; + } + *result.offset(index + kk) = b'.'; + *result.offset(index + kk + 1) = b'0'; + index as usize + kk as usize + 2 + } else if 0 < kk && kk <= 13 { + // 1234e-2 -> 12.34 + write_mantissa(v.mantissa, result.offset(index + length + 1)); + ptr::copy(result.offset(index + 1), result.offset(index), kk as usize); + *result.offset(index + kk) = b'.'; + index as usize + length as usize + 1 + } else if -6 < kk && kk <= 0 { + // 1234e-6 -> 0.001234 + *result.offset(index) = b'0'; + *result.offset(index + 1) = b'.'; + let offset = 2 - kk; + for i in 2..offset { + *result.offset(index + i) = b'0'; + } + write_mantissa(v.mantissa, result.offset(index + length + offset)); + index as usize + length as usize + offset as usize + } else if length == 1 { + // 1e30 + *result.offset(index) = b'0' + v.mantissa as u8; + *result.offset(index + 1) = b'e'; + index as usize + 2 + write_exponent2(kk - 1, result.offset(index + 2)) + } else { + // 1234e30 -> 1.234e33 + write_mantissa(v.mantissa, result.offset(index + length + 1)); + *result.offset(index) = *result.offset(index + 1); + *result.offset(index + 1) = b'.'; + *result.offset(index + length + 1) = b'e'; + index as usize + + length as usize + + 2 + + write_exponent2(kk - 1, result.offset(index + length + 2)) + } +} diff --git a/vendor/ryu/src/s2d.rs b/vendor/ryu/src/s2d.rs new file mode 100644 index 0000000..c6b4fa4 --- /dev/null +++ b/vendor/ryu/src/s2d.rs @@ -0,0 +1,217 @@ +use crate::common::{ceil_log2_pow5, log2_pow5}; +use crate::d2s; +use crate::d2s_intrinsics::{mul_shift_64, multiple_of_power_of_2, multiple_of_power_of_5}; +use crate::parse::Error; +#[cfg(feature = "no-panic")] +use no_panic::no_panic; + +const DOUBLE_EXPONENT_BIAS: usize = 1023; + +fn floor_log2(value: u64) -> u32 { + 63_u32.wrapping_sub(value.leading_zeros()) +} + +#[cfg_attr(feature = "no-panic", no_panic)] +pub fn s2d(buffer: &[u8]) -> Result { + let len = buffer.len(); + if len == 0 { + return Err(Error::InputTooShort); + } + + let mut m10digits = 0; + let mut e10digits = 0; + let mut dot_index = len; + let mut e_index = len; + let mut m10 = 0u64; + let mut e10 = 0i32; + let mut signed_m = false; + let mut signed_e = false; + + let mut i = 0; + if unsafe { *buffer.get_unchecked(0) } == b'-' { + signed_m = true; + i += 1; + } + + while let Some(c) = buffer.get(i).copied() { + if c == b'.' { + if dot_index != len { + return Err(Error::MalformedInput); + } + dot_index = i; + i += 1; + continue; + } + if c < b'0' || c > b'9' { + break; + } + if m10digits >= 17 { + return Err(Error::InputTooLong); + } + m10 = 10 * m10 + (c - b'0') as u64; + if m10 != 0 { + m10digits += 1; + } + i += 1; + } + + if let Some(b'e') | Some(b'E') = buffer.get(i) { + e_index = i; + i += 1; + match buffer.get(i) { + Some(b'-') => { + signed_e = true; + i += 1; + } + Some(b'+') => i += 1, + _ => {} + } + while let Some(c) = buffer.get(i).copied() { + if c < b'0' || c > b'9' { + return Err(Error::MalformedInput); + } + if e10digits > 3 { + // TODO: Be more lenient. Return +/-Infinity or +/-0 instead. + return Err(Error::InputTooLong); + } + e10 = 10 * e10 + (c - b'0') as i32; + if e10 != 0 { + e10digits += 1; + } + i += 1; + } + } + + if i < len { + return Err(Error::MalformedInput); + } + if signed_e { + e10 = -e10; + } + e10 -= if dot_index < e_index { + (e_index - dot_index - 1) as i32 + } else { + 0 + }; + if m10 == 0 { + return Ok(if signed_m { -0.0 } else { 0.0 }); + } + + if m10digits + e10 <= -324 || m10 == 0 { + // Number is less than 1e-324, which should be rounded down to 0; return + // +/-0.0. + let ieee = (signed_m as u64) << (d2s::DOUBLE_EXPONENT_BITS + d2s::DOUBLE_MANTISSA_BITS); + return Ok(f64::from_bits(ieee)); + } + if m10digits + e10 >= 310 { + // Number is larger than 1e+309, which should be rounded to +/-Infinity. + let ieee = ((signed_m as u64) << (d2s::DOUBLE_EXPONENT_BITS + d2s::DOUBLE_MANTISSA_BITS)) + | (0x7ff_u64 << d2s::DOUBLE_MANTISSA_BITS); + return Ok(f64::from_bits(ieee)); + } + + // Convert to binary float m2 * 2^e2, while retaining information about + // whether the conversion was exact (trailing_zeros). + let e2: i32; + let m2: u64; + let mut trailing_zeros: bool; + if e10 >= 0 { + // The length of m * 10^e in bits is: + // log2(m10 * 10^e10) = log2(m10) + e10 log2(10) = log2(m10) + e10 + e10 * log2(5) + // + // We want to compute the DOUBLE_MANTISSA_BITS + 1 top-most bits (+1 for + // the implicit leading one in IEEE format). We therefore choose a + // binary output exponent of + // log2(m10 * 10^e10) - (DOUBLE_MANTISSA_BITS + 1). + // + // We use floor(log2(5^e10)) so that we get at least this many bits; + // better to have an additional bit than to not have enough bits. + e2 = floor_log2(m10) + .wrapping_add(e10 as u32) + .wrapping_add(log2_pow5(e10) as u32) + .wrapping_sub(d2s::DOUBLE_MANTISSA_BITS + 1) as i32; + + // We now compute [m10 * 10^e10 / 2^e2] = [m10 * 5^e10 / 2^(e2-e10)]. + // To that end, we use the DOUBLE_POW5_SPLIT table. + let j = e2 + .wrapping_sub(e10) + .wrapping_sub(ceil_log2_pow5(e10)) + .wrapping_add(d2s::DOUBLE_POW5_BITCOUNT); + debug_assert!(j >= 0); + debug_assert!(e10 < d2s::DOUBLE_POW5_SPLIT.len() as i32); + m2 = mul_shift_64( + m10, + unsafe { d2s::DOUBLE_POW5_SPLIT.get_unchecked(e10 as usize) }, + j as u32, + ); + + // We also compute if the result is exact, i.e., + // [m10 * 10^e10 / 2^e2] == m10 * 10^e10 / 2^e2. + // This can only be the case if 2^e2 divides m10 * 10^e10, which in turn + // requires that the largest power of 2 that divides m10 + e10 is + // greater than e2. If e2 is less than e10, then the result must be + // exact. Otherwise we use the existing multiple_of_power_of_2 function. + trailing_zeros = + e2 < e10 || e2 - e10 < 64 && multiple_of_power_of_2(m10, (e2 - e10) as u32); + } else { + e2 = floor_log2(m10) + .wrapping_add(e10 as u32) + .wrapping_sub(ceil_log2_pow5(-e10) as u32) + .wrapping_sub(d2s::DOUBLE_MANTISSA_BITS + 1) as i32; + let j = e2 + .wrapping_sub(e10) + .wrapping_add(ceil_log2_pow5(-e10)) + .wrapping_sub(1) + .wrapping_add(d2s::DOUBLE_POW5_INV_BITCOUNT); + debug_assert!(-e10 < d2s::DOUBLE_POW5_INV_SPLIT.len() as i32); + m2 = mul_shift_64( + m10, + unsafe { d2s::DOUBLE_POW5_INV_SPLIT.get_unchecked(-e10 as usize) }, + j as u32, + ); + trailing_zeros = multiple_of_power_of_5(m10, -e10 as u32); + } + + // Compute the final IEEE exponent. + let mut ieee_e2 = i32::max(0, e2 + DOUBLE_EXPONENT_BIAS as i32 + floor_log2(m2) as i32) as u32; + + if ieee_e2 > 0x7fe { + // Final IEEE exponent is larger than the maximum representable; return +/-Infinity. + let ieee = ((signed_m as u64) << (d2s::DOUBLE_EXPONENT_BITS + d2s::DOUBLE_MANTISSA_BITS)) + | (0x7ff_u64 << d2s::DOUBLE_MANTISSA_BITS); + return Ok(f64::from_bits(ieee)); + } + + // We need to figure out how much we need to shift m2. The tricky part is + // that we need to take the final IEEE exponent into account, so we need to + // reverse the bias and also special-case the value 0. + let shift = if ieee_e2 == 0 { 1 } else { ieee_e2 as i32 } + .wrapping_sub(e2) + .wrapping_sub(DOUBLE_EXPONENT_BIAS as i32) + .wrapping_sub(d2s::DOUBLE_MANTISSA_BITS as i32); + debug_assert!(shift >= 0); + + // We need to round up if the exact value is more than 0.5 above the value + // we computed. That's equivalent to checking if the last removed bit was 1 + // and either the value was not just trailing zeros or the result would + // otherwise be odd. + // + // We need to update trailing_zeros given that we have the exact output + // exponent ieee_e2 now. + trailing_zeros &= (m2 & ((1_u64 << (shift - 1)) - 1)) == 0; + let last_removed_bit = (m2 >> (shift - 1)) & 1; + let round_up = last_removed_bit != 0 && (!trailing_zeros || ((m2 >> shift) & 1) != 0); + + let mut ieee_m2 = (m2 >> shift).wrapping_add(round_up as u64); + debug_assert!(ieee_m2 <= 1_u64 << (d2s::DOUBLE_MANTISSA_BITS + 1)); + ieee_m2 &= (1_u64 << d2s::DOUBLE_MANTISSA_BITS) - 1; + if ieee_m2 == 0 && round_up { + // Due to how the IEEE represents +/-Infinity, we don't need to check + // for overflow here. + ieee_e2 += 1; + } + let ieee = ((((signed_m as u64) << d2s::DOUBLE_EXPONENT_BITS) | ieee_e2 as u64) + << d2s::DOUBLE_MANTISSA_BITS) + | ieee_m2; + Ok(f64::from_bits(ieee)) +} diff --git a/vendor/ryu/src/s2f.rs b/vendor/ryu/src/s2f.rs new file mode 100644 index 0000000..52a3235 --- /dev/null +++ b/vendor/ryu/src/s2f.rs @@ -0,0 +1,229 @@ +use crate::common::{ceil_log2_pow5, log2_pow5}; +use crate::f2s; +use crate::f2s_intrinsics::{ + mul_pow5_div_pow2, mul_pow5_inv_div_pow2, multiple_of_power_of_2_32, multiple_of_power_of_5_32, +}; +use crate::parse::Error; +#[cfg(feature = "no-panic")] +use no_panic::no_panic; + +const FLOAT_EXPONENT_BIAS: usize = 127; + +fn floor_log2(value: u32) -> u32 { + 31_u32.wrapping_sub(value.leading_zeros()) +} + +#[cfg_attr(feature = "no-panic", no_panic)] +pub fn s2f(buffer: &[u8]) -> Result { + let len = buffer.len(); + if len == 0 { + return Err(Error::InputTooShort); + } + + let mut m10digits = 0; + let mut e10digits = 0; + let mut dot_index = len; + let mut e_index = len; + let mut m10 = 0u32; + let mut e10 = 0i32; + let mut signed_m = false; + let mut signed_e = false; + + let mut i = 0; + if unsafe { *buffer.get_unchecked(0) } == b'-' { + signed_m = true; + i += 1; + } + + while let Some(c) = buffer.get(i).copied() { + if c == b'.' { + if dot_index != len { + return Err(Error::MalformedInput); + } + dot_index = i; + i += 1; + continue; + } + if c < b'0' || c > b'9' { + break; + } + if m10digits >= 9 { + return Err(Error::InputTooLong); + } + m10 = 10 * m10 + (c - b'0') as u32; + if m10 != 0 { + m10digits += 1; + } + i += 1; + } + + if let Some(b'e') | Some(b'E') = buffer.get(i) { + e_index = i; + i += 1; + match buffer.get(i) { + Some(b'-') => { + signed_e = true; + i += 1; + } + Some(b'+') => i += 1, + _ => {} + } + while let Some(c) = buffer.get(i).copied() { + if c < b'0' || c > b'9' { + return Err(Error::MalformedInput); + } + if e10digits > 3 { + // TODO: Be more lenient. Return +/-Infinity or +/-0 instead. + return Err(Error::InputTooLong); + } + e10 = 10 * e10 + (c - b'0') as i32; + if e10 != 0 { + e10digits += 1; + } + i += 1; + } + } + + if i < len { + return Err(Error::MalformedInput); + } + if signed_e { + e10 = -e10; + } + e10 -= if dot_index < e_index { + (e_index - dot_index - 1) as i32 + } else { + 0 + }; + if m10 == 0 { + return Ok(if signed_m { -0.0 } else { 0.0 }); + } + + if m10digits + e10 <= -46 || m10 == 0 { + // Number is less than 1e-46, which should be rounded down to 0; return + // +/-0.0. + let ieee = (signed_m as u32) << (f2s::FLOAT_EXPONENT_BITS + f2s::FLOAT_MANTISSA_BITS); + return Ok(f32::from_bits(ieee)); + } + if m10digits + e10 >= 40 { + // Number is larger than 1e+39, which should be rounded to +/-Infinity. + let ieee = ((signed_m as u32) << (f2s::FLOAT_EXPONENT_BITS + f2s::FLOAT_MANTISSA_BITS)) + | (0xff_u32 << f2s::FLOAT_MANTISSA_BITS); + return Ok(f32::from_bits(ieee)); + } + + // Convert to binary float m2 * 2^e2, while retaining information about + // whether the conversion was exact (trailing_zeros). + let e2: i32; + let m2: u32; + let mut trailing_zeros: bool; + if e10 >= 0 { + // The length of m * 10^e in bits is: + // log2(m10 * 10^e10) = log2(m10) + e10 log2(10) = log2(m10) + e10 + e10 * log2(5) + // + // We want to compute the FLOAT_MANTISSA_BITS + 1 top-most bits (+1 for + // the implicit leading one in IEEE format). We therefore choose a + // binary output exponent of + // log2(m10 * 10^e10) - (FLOAT_MANTISSA_BITS + 1). + // + // We use floor(log2(5^e10)) so that we get at least this many bits; better to + // have an additional bit than to not have enough bits. + e2 = floor_log2(m10) + .wrapping_add(e10 as u32) + .wrapping_add(log2_pow5(e10) as u32) + .wrapping_sub(f2s::FLOAT_MANTISSA_BITS + 1) as i32; + + // We now compute [m10 * 10^e10 / 2^e2] = [m10 * 5^e10 / 2^(e2-e10)]. + // To that end, we use the FLOAT_POW5_SPLIT table. + let j = e2 + .wrapping_sub(e10) + .wrapping_sub(ceil_log2_pow5(e10)) + .wrapping_add(f2s::FLOAT_POW5_BITCOUNT); + debug_assert!(j >= 0); + m2 = mul_pow5_div_pow2(m10, e10 as u32, j); + + // We also compute if the result is exact, i.e., + // [m10 * 10^e10 / 2^e2] == m10 * 10^e10 / 2^e2. + // This can only be the case if 2^e2 divides m10 * 10^e10, which in turn + // requires that the largest power of 2 that divides m10 + e10 is + // greater than e2. If e2 is less than e10, then the result must be + // exact. Otherwise we use the existing multiple_of_power_of_2 function. + trailing_zeros = + e2 < e10 || e2 - e10 < 32 && multiple_of_power_of_2_32(m10, (e2 - e10) as u32); + } else { + e2 = floor_log2(m10) + .wrapping_add(e10 as u32) + .wrapping_sub(ceil_log2_pow5(-e10) as u32) + .wrapping_sub(f2s::FLOAT_MANTISSA_BITS + 1) as i32; + + // We now compute [m10 * 10^e10 / 2^e2] = [m10 / (5^(-e10) 2^(e2-e10))]. + let j = e2 + .wrapping_sub(e10) + .wrapping_add(ceil_log2_pow5(-e10)) + .wrapping_sub(1) + .wrapping_add(f2s::FLOAT_POW5_INV_BITCOUNT); + m2 = mul_pow5_inv_div_pow2(m10, -e10 as u32, j); + + // We also compute if the result is exact, i.e., + // [m10 / (5^(-e10) 2^(e2-e10))] == m10 / (5^(-e10) 2^(e2-e10)) + // + // If e2-e10 >= 0, we need to check whether (5^(-e10) 2^(e2-e10)) + // divides m10, which is the case iff pow5(m10) >= -e10 AND pow2(m10) >= + // e2-e10. + // + // If e2-e10 < 0, we have actually computed [m10 * 2^(e10 e2) / + // 5^(-e10)] above, and we need to check whether 5^(-e10) divides (m10 * + // 2^(e10-e2)), which is the case iff pow5(m10 * 2^(e10-e2)) = pow5(m10) + // >= -e10. + trailing_zeros = (e2 < e10 + || (e2 - e10 < 32 && multiple_of_power_of_2_32(m10, (e2 - e10) as u32))) + && multiple_of_power_of_5_32(m10, -e10 as u32); + } + + // Compute the final IEEE exponent. + let mut ieee_e2 = i32::max(0, e2 + FLOAT_EXPONENT_BIAS as i32 + floor_log2(m2) as i32) as u32; + + if ieee_e2 > 0xfe { + // Final IEEE exponent is larger than the maximum representable; return + // +/-Infinity. + let ieee = ((signed_m as u32) << (f2s::FLOAT_EXPONENT_BITS + f2s::FLOAT_MANTISSA_BITS)) + | (0xff_u32 << f2s::FLOAT_MANTISSA_BITS); + return Ok(f32::from_bits(ieee)); + } + + // We need to figure out how much we need to shift m2. The tricky part is + // that we need to take the final IEEE exponent into account, so we need to + // reverse the bias and also special-case the value 0. + let shift = if ieee_e2 == 0 { 1 } else { ieee_e2 as i32 } + .wrapping_sub(e2) + .wrapping_sub(FLOAT_EXPONENT_BIAS as i32) + .wrapping_sub(f2s::FLOAT_MANTISSA_BITS as i32); + debug_assert!(shift >= 0); + + // We need to round up if the exact value is more than 0.5 above the value + // we computed. That's equivalent to checking if the last removed bit was 1 + // and either the value was not just trailing zeros or the result would + // otherwise be odd. + // + // We need to update trailing_zeros given that we have the exact output + // exponent ieee_e2 now. + trailing_zeros &= (m2 & ((1_u32 << (shift - 1)) - 1)) == 0; + let last_removed_bit = (m2 >> (shift - 1)) & 1; + let round_up = last_removed_bit != 0 && (!trailing_zeros || ((m2 >> shift) & 1) != 0); + + let mut ieee_m2 = (m2 >> shift).wrapping_add(round_up as u32); + debug_assert!(ieee_m2 <= 1_u32 << (f2s::FLOAT_MANTISSA_BITS + 1)); + ieee_m2 &= (1_u32 << f2s::FLOAT_MANTISSA_BITS) - 1; + if ieee_m2 == 0 && round_up { + // Rounding up may overflow the mantissa. + // In this case we move a trailing zero of the mantissa into the + // exponent. + // Due to how the IEEE represents +/-Infinity, we don't need to check + // for overflow here. + ieee_e2 += 1; + } + let ieee = ((((signed_m as u32) << f2s::FLOAT_EXPONENT_BITS) | ieee_e2) + << f2s::FLOAT_MANTISSA_BITS) + | ieee_m2; + Ok(f32::from_bits(ieee)) +} diff --git a/vendor/ryu/tests/common_test.rs b/vendor/ryu/tests/common_test.rs new file mode 100644 index 0000000..e2bc4e1 --- /dev/null +++ b/vendor/ryu/tests/common_test.rs @@ -0,0 +1,91 @@ +// Translated from C to Rust. The original C code can be found at +// https://github.com/ulfjack/ryu and carries the following license: +// +// Copyright 2018 Ulf Adams +// +// The contents of this file may be used under the terms of the Apache License, +// Version 2.0. +// +// (See accompanying file LICENSE-Apache or copy at +// http://www.apache.org/licenses/LICENSE-2.0) +// +// Alternatively, the contents of this file may be used under the terms of +// the Boost Software License, Version 1.0. +// (See accompanying file LICENSE-Boost or copy at +// https://www.boost.org/LICENSE_1_0.txt) +// +// Unless required by applicable law or agreed to in writing, this software +// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. + +#![allow(dead_code)] +#![allow( + clippy::approx_constant, + clippy::cast_possible_wrap, + clippy::cast_sign_loss, + clippy::excessive_precision, + clippy::unreadable_literal, + clippy::wildcard_imports +)] + +#[path = "../src/common.rs"] +mod common; + +use common::{ceil_log2_pow5, decimal_length9, log10_pow2, log10_pow5}; + +#[test] +fn test_decimal_length9() { + assert_eq!(1, decimal_length9(0)); + assert_eq!(1, decimal_length9(1)); + assert_eq!(1, decimal_length9(9)); + assert_eq!(2, decimal_length9(10)); + assert_eq!(2, decimal_length9(99)); + assert_eq!(3, decimal_length9(100)); + assert_eq!(3, decimal_length9(999)); + assert_eq!(9, decimal_length9(999999999)); +} + +#[test] +fn test_ceil_log2_pow5() { + assert_eq!(1, ceil_log2_pow5(0)); + assert_eq!(3, ceil_log2_pow5(1)); + assert_eq!(5, ceil_log2_pow5(2)); + assert_eq!(7, ceil_log2_pow5(3)); + assert_eq!(10, ceil_log2_pow5(4)); + assert_eq!(8192, ceil_log2_pow5(3528)); +} + +#[test] +fn test_log10_pow2() { + assert_eq!(0, log10_pow2(0)); + assert_eq!(0, log10_pow2(1)); + assert_eq!(0, log10_pow2(2)); + assert_eq!(0, log10_pow2(3)); + assert_eq!(1, log10_pow2(4)); + assert_eq!(496, log10_pow2(1650)); +} + +#[test] +fn test_log10_pow5() { + assert_eq!(0, log10_pow5(0)); + assert_eq!(0, log10_pow5(1)); + assert_eq!(1, log10_pow5(2)); + assert_eq!(2, log10_pow5(3)); + assert_eq!(2, log10_pow5(4)); + assert_eq!(1831, log10_pow5(2620)); +} + +#[test] +fn test_float_to_bits() { + assert_eq!(0, 0.0_f32.to_bits()); + assert_eq!(0x40490fda, 3.1415926_f32.to_bits()); +} + +#[test] +fn test_double_to_bits() { + assert_eq!(0, 0.0_f64.to_bits()); + assert_eq!( + 0x400921FB54442D18, + 3.1415926535897932384626433_f64.to_bits(), + ); +} diff --git a/vendor/ryu/tests/d2s_intrinsics_test.rs b/vendor/ryu/tests/d2s_intrinsics_test.rs new file mode 100644 index 0000000..0ac80c9 --- /dev/null +++ b/vendor/ryu/tests/d2s_intrinsics_test.rs @@ -0,0 +1,72 @@ +// Translated from C to Rust. The original C code can be found at +// https://github.com/ulfjack/ryu and carries the following license: +// +// Copyright 2018 Ulf Adams +// +// The contents of this file may be used under the terms of the Apache License, +// Version 2.0. +// +// (See accompanying file LICENSE-Apache or copy at +// http://www.apache.org/licenses/LICENSE-2.0) +// +// Alternatively, the contents of this file may be used under the terms of +// the Boost Software License, Version 1.0. +// (See accompanying file LICENSE-Boost or copy at +// https://www.boost.org/LICENSE_1_0.txt) +// +// Unless required by applicable law or agreed to in writing, this software +// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. + +#![allow(dead_code)] +#![allow( + clippy::cast_lossless, + clippy::cast_possible_truncation, + clippy::unreadable_literal +)] + +#[path = "../src/d2s_intrinsics.rs"] +mod d2s_intrinsics; + +use d2s_intrinsics::pow5_factor; + +#[test] +fn test_pow5_factor() { + assert_eq!(0, pow5_factor(1)); + assert_eq!(0, pow5_factor(2)); + assert_eq!(0, pow5_factor(3)); + assert_eq!(0, pow5_factor(4)); + assert_eq!(1, pow5_factor(5)); + assert_eq!(0, pow5_factor(6)); + assert_eq!(0, pow5_factor(7)); + assert_eq!(0, pow5_factor(8)); + assert_eq!(0, pow5_factor(9)); + assert_eq!(1, pow5_factor(10)); + + assert_eq!(0, pow5_factor(12)); + assert_eq!(0, pow5_factor(14)); + assert_eq!(0, pow5_factor(16)); + assert_eq!(0, pow5_factor(18)); + assert_eq!(1, pow5_factor(20)); + + assert_eq!(2, pow5_factor(5 * 5)); + assert_eq!(3, pow5_factor(5 * 5 * 5)); + assert_eq!(4, pow5_factor(5 * 5 * 5 * 5)); + assert_eq!(5, pow5_factor(5 * 5 * 5 * 5 * 5)); + assert_eq!(6, pow5_factor(5 * 5 * 5 * 5 * 5 * 5)); + assert_eq!(7, pow5_factor(5 * 5 * 5 * 5 * 5 * 5 * 5)); + assert_eq!(8, pow5_factor(5 * 5 * 5 * 5 * 5 * 5 * 5 * 5)); + assert_eq!(9, pow5_factor(5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5)); + assert_eq!(10, pow5_factor(5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5)); + + assert_eq!(0, pow5_factor(42)); + assert_eq!(1, pow5_factor(42 * 5)); + assert_eq!(2, pow5_factor(42 * 5 * 5)); + assert_eq!(3, pow5_factor(42 * 5 * 5 * 5)); + assert_eq!(4, pow5_factor(42 * 5 * 5 * 5 * 5)); + assert_eq!(5, pow5_factor(42 * 5 * 5 * 5 * 5 * 5)); + + assert_eq!(27, pow5_factor(7450580596923828125)); // 5^27, largest power of 5 < 2^64. + assert_eq!(1, pow5_factor(18446744073709551615)); // 2^64 - 1, largest multiple of 5 < 2^64. + assert_eq!(0, pow5_factor(18446744073709551614)); // 2^64 - 2, largest non-multiple of 5 < 2^64. +} diff --git a/vendor/ryu/tests/d2s_table_test.rs b/vendor/ryu/tests/d2s_table_test.rs new file mode 100644 index 0000000..13c4216 --- /dev/null +++ b/vendor/ryu/tests/d2s_table_test.rs @@ -0,0 +1,59 @@ +// Translated from C to Rust. The original C code can be found at +// https://github.com/ulfjack/ryu and carries the following license: +// +// Copyright 2018 Ulf Adams +// +// The contents of this file may be used under the terms of the Apache License, +// Version 2.0. +// +// (See accompanying file LICENSE-Apache or copy at +// http://www.apache.org/licenses/LICENSE-2.0) +// +// Alternatively, the contents of this file may be used under the terms of +// the Boost Software License, Version 1.0. +// (See accompanying file LICENSE-Boost or copy at +// https://www.boost.org/LICENSE_1_0.txt) +// +// Unless required by applicable law or agreed to in writing, this software +// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. + +#![allow(dead_code)] +#![allow( + clippy::cast_lossless, + clippy::cast_possible_truncation, + clippy::cast_possible_wrap, + clippy::cast_sign_loss, + clippy::unreadable_literal, + clippy::unseparated_literal_suffix, + clippy::wildcard_imports +)] + +#[path = "../src/common.rs"] +mod common; + +#[path = "../src/d2s_full_table.rs"] +mod d2s_full_table; + +#[path = "../src/d2s_intrinsics.rs"] +mod d2s_intrinsics; + +#[path = "../src/d2s_small_table.rs"] +mod d2s_small_table; + +use d2s_full_table::{DOUBLE_POW5_INV_SPLIT, DOUBLE_POW5_SPLIT}; +use d2s_small_table::{compute_inv_pow5, compute_pow5}; + +#[test] +fn test_compute_pow5() { + for (i, entry) in DOUBLE_POW5_SPLIT.iter().enumerate() { + assert_eq!(*entry, unsafe { compute_pow5(i as u32) }, "entry {}", i); + } +} + +#[test] +fn test_compute_inv_pow5() { + for (i, entry) in DOUBLE_POW5_INV_SPLIT[..292].iter().enumerate() { + assert_eq!(*entry, unsafe { compute_inv_pow5(i as u32) }, "entry {}", i); + } +} diff --git a/vendor/ryu/tests/d2s_test.rs b/vendor/ryu/tests/d2s_test.rs new file mode 100644 index 0000000..7e8eba6 --- /dev/null +++ b/vendor/ryu/tests/d2s_test.rs @@ -0,0 +1,331 @@ +// Translated from C to Rust. The original C code can be found at +// https://github.com/ulfjack/ryu and carries the following license: +// +// Copyright 2018 Ulf Adams +// +// The contents of this file may be used under the terms of the Apache License, +// Version 2.0. +// +// (See accompanying file LICENSE-Apache or copy at +// http://www.apache.org/licenses/LICENSE-2.0) +// +// Alternatively, the contents of this file may be used under the terms of +// the Boost Software License, Version 1.0. +// (See accompanying file LICENSE-Boost or copy at +// https://www.boost.org/LICENSE_1_0.txt) +// +// Unless required by applicable law or agreed to in writing, this software +// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. + +#![allow( + clippy::approx_constant, + clippy::cast_lossless, + clippy::float_cmp, + clippy::int_plus_one, + clippy::non_ascii_literal, + clippy::unreadable_literal, + clippy::unseparated_literal_suffix +)] + +#[macro_use] +mod macros; + +use std::f64; + +fn pretty(f: f64) -> String { + ryu::Buffer::new().format(f).to_owned() +} + +fn ieee_parts_to_double(sign: bool, ieee_exponent: u32, ieee_mantissa: u64) -> f64 { + assert!(ieee_exponent <= 2047); + assert!(ieee_mantissa <= (1u64 << 53) - 1); + f64::from_bits(((sign as u64) << 63) | ((ieee_exponent as u64) << 52) | ieee_mantissa) +} + +#[test] +fn test_ryu() { + check!(0.3); + check!(1234000000000000.0); + check!(1.234e16); + check!(2.71828); + check!(1.1e128); + check!(1.1e-64); + check!(2.718281828459045); + check!(5e-324); + check!(1.7976931348623157e308); +} + +#[test] +fn test_random() { + let n = if cfg!(miri) { 100 } else { 1000000 }; + let mut buffer = ryu::Buffer::new(); + for _ in 0..n { + let f: f64 = rand::random(); + assert_eq!(f, buffer.format_finite(f).parse().unwrap()); + } +} + +#[test] +#[cfg_attr(miri, ignore)] +fn test_non_finite() { + for i in 0u64..1 << 23 { + let f = f64::from_bits((((1 << 11) - 1) << 52) + (i << 29)); + assert!(!f.is_finite(), "f={}", f); + ryu::Buffer::new().format_finite(f); + } +} + +#[test] +fn test_basic() { + check!(0.0); + check!(-0.0); + check!(1.0); + check!(-1.0); + assert_eq!(pretty(f64::NAN.copysign(1.0)), "NaN"); + assert_eq!(pretty(f64::NAN.copysign(-1.0)), "NaN"); + assert_eq!(pretty(f64::INFINITY), "inf"); + assert_eq!(pretty(f64::NEG_INFINITY), "-inf"); +} + +#[test] +fn test_switch_to_subnormal() { + check!(2.2250738585072014e-308); +} + +#[test] +fn test_min_and_max() { + assert_eq!(f64::from_bits(0x7fefffffffffffff), 1.7976931348623157e308); + check!(1.7976931348623157e308); + assert_eq!(f64::from_bits(1), 5e-324); + check!(5e-324); +} + +#[test] +fn test_lots_of_trailing_zeros() { + check!(2.9802322387695312e-8); +} + +#[test] +fn test_regression() { + check!(-2.109808898695963e16); + check!(4.940656e-318); + check!(1.18575755e-316); + check!(2.989102097996e-312); + check!(9060801153433600.0); + check!(4.708356024711512e18); + check!(9.409340012568248e18); + check!(1.2345678); +} + +#[test] +fn test_looks_like_pow5() { + // These numbers have a mantissa that is a multiple of the largest power of + // 5 that fits, and an exponent that causes the computation for q to result + // in 22, which is a corner case for Ryū. + assert_eq!(f64::from_bits(0x4830F0CF064DD592), 5.764607523034235e39); + check!(5.764607523034235e39); + assert_eq!(f64::from_bits(0x4840F0CF064DD592), 1.152921504606847e40); + check!(1.152921504606847e40); + assert_eq!(f64::from_bits(0x4850F0CF064DD592), 2.305843009213694e40); + check!(2.305843009213694e40); +} + +#[test] +fn test_output_length() { + check!(1.0); // already tested in Basic + check!(1.2); + check!(1.23); + check!(1.234); + check!(1.2345); + check!(1.23456); + check!(1.234567); + check!(1.2345678); // already tested in Regression + check!(1.23456789); + check!(1.234567895); // 1.234567890 would be trimmed + check!(1.2345678901); + check!(1.23456789012); + check!(1.234567890123); + check!(1.2345678901234); + check!(1.23456789012345); + check!(1.234567890123456); + check!(1.2345678901234567); + + // Test 32-bit chunking + check!(4.294967294); // 2^32 - 2 + check!(4.294967295); // 2^32 - 1 + check!(4.294967296); // 2^32 + check!(4.294967297); // 2^32 + 1 + check!(4.294967298); // 2^32 + 2 +} + +// Test min, max shift values in shiftright128 +#[test] +fn test_min_max_shift() { + let max_mantissa = (1u64 << 53) - 1; + + // 32-bit opt-size=0: 49 <= dist <= 50 + // 32-bit opt-size=1: 30 <= dist <= 50 + // 64-bit opt-size=0: 50 <= dist <= 50 + // 64-bit opt-size=1: 30 <= dist <= 50 + assert_eq!(1.7800590868057611E-307, ieee_parts_to_double(false, 4, 0)); + check!(1.7800590868057611e-307); + // 32-bit opt-size=0: 49 <= dist <= 49 + // 32-bit opt-size=1: 28 <= dist <= 49 + // 64-bit opt-size=0: 50 <= dist <= 50 + // 64-bit opt-size=1: 28 <= dist <= 50 + assert_eq!( + 2.8480945388892175E-306, + ieee_parts_to_double(false, 6, max_mantissa) + ); + check!(2.8480945388892175e-306); + // 32-bit opt-size=0: 52 <= dist <= 53 + // 32-bit opt-size=1: 2 <= dist <= 53 + // 64-bit opt-size=0: 53 <= dist <= 53 + // 64-bit opt-size=1: 2 <= dist <= 53 + assert_eq!(2.446494580089078E-296, ieee_parts_to_double(false, 41, 0)); + check!(2.446494580089078e-296); + // 32-bit opt-size=0: 52 <= dist <= 52 + // 32-bit opt-size=1: 2 <= dist <= 52 + // 64-bit opt-size=0: 53 <= dist <= 53 + // 64-bit opt-size=1: 2 <= dist <= 53 + assert_eq!( + 4.8929891601781557E-296, + ieee_parts_to_double(false, 40, max_mantissa) + ); + check!(4.8929891601781557e-296); + + // 32-bit opt-size=0: 57 <= dist <= 58 + // 32-bit opt-size=1: 57 <= dist <= 58 + // 64-bit opt-size=0: 58 <= dist <= 58 + // 64-bit opt-size=1: 58 <= dist <= 58 + assert_eq!(1.8014398509481984E16, ieee_parts_to_double(false, 1077, 0)); + check!(1.8014398509481984e16); + // 32-bit opt-size=0: 57 <= dist <= 57 + // 32-bit opt-size=1: 57 <= dist <= 57 + // 64-bit opt-size=0: 58 <= dist <= 58 + // 64-bit opt-size=1: 58 <= dist <= 58 + assert_eq!( + 3.6028797018963964E16, + ieee_parts_to_double(false, 1076, max_mantissa) + ); + check!(3.6028797018963964e16); + // 32-bit opt-size=0: 51 <= dist <= 52 + // 32-bit opt-size=1: 51 <= dist <= 59 + // 64-bit opt-size=0: 52 <= dist <= 52 + // 64-bit opt-size=1: 52 <= dist <= 59 + assert_eq!(2.900835519859558E-216, ieee_parts_to_double(false, 307, 0)); + check!(2.900835519859558e-216); + // 32-bit opt-size=0: 51 <= dist <= 51 + // 32-bit opt-size=1: 51 <= dist <= 59 + // 64-bit opt-size=0: 52 <= dist <= 52 + // 64-bit opt-size=1: 52 <= dist <= 59 + assert_eq!( + 5.801671039719115E-216, + ieee_parts_to_double(false, 306, max_mantissa) + ); + check!(5.801671039719115e-216); + + // https://github.com/ulfjack/ryu/commit/19e44d16d80236f5de25800f56d82606d1be00b9#commitcomment-30146483 + // 32-bit opt-size=0: 49 <= dist <= 49 + // 32-bit opt-size=1: 44 <= dist <= 49 + // 64-bit opt-size=0: 50 <= dist <= 50 + // 64-bit opt-size=1: 44 <= dist <= 50 + assert_eq!( + 3.196104012172126E-27, + ieee_parts_to_double(false, 934, 0x000FA7161A4D6E0C) + ); + check!(3.196104012172126e-27); +} + +#[test] +fn test_small_integers() { + check!(9007199254740991.0); // 2^53-1 + check!(9007199254740992.0); // 2^53 + + check!(1.0); + check!(12.0); + check!(123.0); + check!(1234.0); + check!(12345.0); + check!(123456.0); + check!(1234567.0); + check!(12345678.0); + check!(123456789.0); + check!(1234567890.0); + check!(1234567895.0); + check!(12345678901.0); + check!(123456789012.0); + check!(1234567890123.0); + check!(12345678901234.0); + check!(123456789012345.0); + check!(1234567890123456.0); + + // 10^i + check!(1.0); + check!(10.0); + check!(100.0); + check!(1000.0); + check!(10000.0); + check!(100000.0); + check!(1000000.0); + check!(10000000.0); + check!(100000000.0); + check!(1000000000.0); + check!(10000000000.0); + check!(100000000000.0); + check!(1000000000000.0); + check!(10000000000000.0); + check!(100000000000000.0); + check!(1000000000000000.0); + + // 10^15 + 10^i + check!(1000000000000001.0); + check!(1000000000000010.0); + check!(1000000000000100.0); + check!(1000000000001000.0); + check!(1000000000010000.0); + check!(1000000000100000.0); + check!(1000000001000000.0); + check!(1000000010000000.0); + check!(1000000100000000.0); + check!(1000001000000000.0); + check!(1000010000000000.0); + check!(1000100000000000.0); + check!(1001000000000000.0); + check!(1010000000000000.0); + check!(1100000000000000.0); + + // Largest power of 2 <= 10^(i+1) + check!(8.0); + check!(64.0); + check!(512.0); + check!(8192.0); + check!(65536.0); + check!(524288.0); + check!(8388608.0); + check!(67108864.0); + check!(536870912.0); + check!(8589934592.0); + check!(68719476736.0); + check!(549755813888.0); + check!(8796093022208.0); + check!(70368744177664.0); + check!(562949953421312.0); + check!(9007199254740992.0); + + // 1000 * (Largest power of 2 <= 10^(i+1)) + check!(8000.0); + check!(64000.0); + check!(512000.0); + check!(8192000.0); + check!(65536000.0); + check!(524288000.0); + check!(8388608000.0); + check!(67108864000.0); + check!(536870912000.0); + check!(8589934592000.0); + check!(68719476736000.0); + check!(549755813888000.0); + check!(8796093022208000.0); +} diff --git a/vendor/ryu/tests/exhaustive.rs b/vendor/ryu/tests/exhaustive.rs new file mode 100644 index 0000000..569bcff --- /dev/null +++ b/vendor/ryu/tests/exhaustive.rs @@ -0,0 +1,52 @@ +#![cfg(exhaustive)] + +use std::str; +use std::sync::atomic::{AtomicUsize, Ordering}; +use std::sync::Arc; +use std::thread; + +#[test] +fn test_exhaustive() { + const BATCH_SIZE: u32 = 1_000_000; + let counter = Arc::new(AtomicUsize::new(0)); + let finished = Arc::new(AtomicUsize::new(0)); + + let mut workers = Vec::new(); + for _ in 0..num_cpus::get() { + let counter = counter.clone(); + let finished = finished.clone(); + workers.push(thread::spawn(move || loop { + let batch = counter.fetch_add(1, Ordering::Relaxed) as u32; + if batch > u32::max_value() / BATCH_SIZE { + return; + } + + let min = batch * BATCH_SIZE; + let max = if batch == u32::max_value() / BATCH_SIZE { + u32::max_value() + } else { + min + BATCH_SIZE - 1 + }; + + let mut bytes = [0u8; 24]; + let mut buffer = ryu::Buffer::new(); + for u in min..=max { + let f = f32::from_bits(u); + if !f.is_finite() { + continue; + } + let n = unsafe { ryu::raw::format32(f, &mut bytes[0]) }; + assert_eq!(Ok(Ok(f)), str::from_utf8(&bytes[..n]).map(str::parse)); + assert_eq!(Ok(f), buffer.format_finite(f).parse()); + } + + let increment = (max - min + 1) as usize; + let update = finished.fetch_add(increment, Ordering::Relaxed); + println!("{}", update + increment); + })); + } + + for w in workers { + w.join().unwrap(); + } +} diff --git a/vendor/ryu/tests/f2s_test.rs b/vendor/ryu/tests/f2s_test.rs new file mode 100644 index 0000000..d6249a3 --- /dev/null +++ b/vendor/ryu/tests/f2s_test.rs @@ -0,0 +1,181 @@ +// Translated from C to Rust. The original C code can be found at +// https://github.com/ulfjack/ryu and carries the following license: +// +// Copyright 2018 Ulf Adams +// +// The contents of this file may be used under the terms of the Apache License, +// Version 2.0. +// +// (See accompanying file LICENSE-Apache or copy at +// http://www.apache.org/licenses/LICENSE-2.0) +// +// Alternatively, the contents of this file may be used under the terms of +// the Boost Software License, Version 1.0. +// (See accompanying file LICENSE-Boost or copy at +// https://www.boost.org/LICENSE_1_0.txt) +// +// Unless required by applicable law or agreed to in writing, this software +// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. + +#![allow( + clippy::approx_constant, + clippy::float_cmp, + clippy::non_ascii_literal, + clippy::unreadable_literal, + clippy::unseparated_literal_suffix +)] + +#[macro_use] +mod macros; + +use std::f32; + +fn pretty(f: f32) -> String { + ryu::Buffer::new().format(f).to_owned() +} + +#[test] +fn test_ryu() { + check!(0.3); + check!(1234000000000.0); + check!(1.234e13); + check!(2.71828); + check!(1.1e32); + check!(1.1e-32); + check!(2.7182817); + check!(1e-45); + check!(3.4028235e38); + check!(-0.001234); +} + +#[test] +fn test_random() { + let n = if cfg!(miri) { 100 } else { 1000000 }; + let mut buffer = ryu::Buffer::new(); + for _ in 0..n { + let f: f32 = rand::random(); + assert_eq!(f, buffer.format_finite(f).parse().unwrap()); + } +} + +#[test] +#[cfg_attr(miri, ignore)] +fn test_non_finite() { + for i in 0u32..1 << 23 { + let f = f32::from_bits((((1 << 8) - 1) << 23) + i); + assert!(!f.is_finite(), "f={}", f); + ryu::Buffer::new().format_finite(f); + } +} + +#[test] +fn test_basic() { + check!(0.0); + check!(-0.0); + check!(1.0); + check!(-1.0); + assert_eq!(pretty(f32::NAN.copysign(1.0)), "NaN"); + assert_eq!(pretty(f32::NAN.copysign(-1.0)), "NaN"); + assert_eq!(pretty(f32::INFINITY), "inf"); + assert_eq!(pretty(f32::NEG_INFINITY), "-inf"); +} + +#[test] +fn test_switch_to_subnormal() { + check!(1.1754944e-38); +} + +#[test] +fn test_min_and_max() { + assert_eq!(f32::from_bits(0x7f7fffff), 3.4028235e38); + check!(3.4028235e38); + assert_eq!(f32::from_bits(1), 1e-45); + check!(1e-45); +} + +// Check that we return the exact boundary if it is the shortest +// representation, but only if the original floating point number is even. +#[test] +fn test_boundary_round_even() { + check!(33554450.0); + check!(9000000000.0); + check!(34366720000.0); +} + +// If the exact value is exactly halfway between two shortest representations, +// then we round to even. It seems like this only makes a difference if the +// last two digits are ...2|5 or ...7|5, and we cut off the 5. +#[test] +fn test_exact_value_round_even() { + check!(305404.12); + check!(8099.0312); +} + +#[test] +fn test_lots_of_trailing_zeros() { + // Pattern for the first test: 00111001100000000000000000000000 + check!(0.00024414062); + check!(0.0024414062); + check!(0.0043945312); + check!(0.0063476562); +} + +#[test] +fn test_regression() { + check!(4.7223665e21); + check!(8388608.0); + check!(16777216.0); + check!(33554436.0); + check!(67131496.0); + check!(1.9310392e-38); + check!(-2.47e-43); + check!(1.993244e-38); + check!(4103.9004); + check!(5339999700.0); + check!(6.0898e-39); + check!(0.0010310042); + check!(2.882326e17); + check!(7.038531e-26); + check!(9.223404e17); + check!(67108870.0); + check!(1e-44); + check!(2.816025e14); + check!(9.223372e18); + check!(1.5846086e29); + check!(1.1811161e19); + check!(5.368709e18); + check!(4.6143166e18); + check!(0.007812537); + check!(1e-45); + check!(1.18697725e20); + check!(1.00014165e-36); + check!(200.0); + check!(33554432.0); +} + +#[test] +fn test_looks_like_pow5() { + // These numbers have a mantissa that is the largest power of 5 that fits, + // and an exponent that causes the computation for q to result in 10, which + // is a corner case for Ryū. + assert_eq!(f32::from_bits(0x5D1502F9), 6.7108864e17); + check!(6.7108864e17); + assert_eq!(f32::from_bits(0x5D9502F9), 1.3421773e18); + check!(1.3421773e18); + assert_eq!(f32::from_bits(0x5E1502F9), 2.6843546e18); + check!(2.6843546e18); +} + +#[test] +fn test_output_length() { + check!(1.0); // already tested in Basic + check!(1.2); + check!(1.23); + check!(1.234); + check!(1.2345); + check!(1.23456); + check!(1.234567); + check!(1.2345678); + check!(1.23456735e-36); +} diff --git a/vendor/ryu/tests/macros/mod.rs b/vendor/ryu/tests/macros/mod.rs new file mode 100644 index 0000000..de6fb46 --- /dev/null +++ b/vendor/ryu/tests/macros/mod.rs @@ -0,0 +1,8 @@ +macro_rules! check { + ($f:tt) => { + assert_eq!(pretty($f), stringify!($f)); + }; + (-$f:tt) => { + assert_eq!(pretty(-$f), concat!("-", stringify!($f))); + }; +} diff --git a/vendor/ryu/tests/s2d_test.rs b/vendor/ryu/tests/s2d_test.rs new file mode 100644 index 0000000..7b42164 --- /dev/null +++ b/vendor/ryu/tests/s2d_test.rs @@ -0,0 +1,167 @@ +// Translated from C to Rust. The original C code can be found at +// https://github.com/ulfjack/ryu and carries the following license: +// +// Copyright 2018 Ulf Adams +// +// The contents of this file may be used under the terms of the Apache License, +// Version 2.0. +// +// (See accompanying file LICENSE-Apache or copy at +// http://www.apache.org/licenses/LICENSE-2.0) +// +// Alternatively, the contents of this file may be used under the terms of +// the Boost Software License, Version 1.0. +// (See accompanying file LICENSE-Boost or copy at +// https://www.boost.org/LICENSE_1_0.txt) +// +// Unless required by applicable law or agreed to in writing, this software +// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. + +#![cfg(not(feature = "small"))] +#![allow(dead_code)] +#![allow( + clippy::cast_lossless, + clippy::cast_possible_truncation, + clippy::cast_possible_wrap, + clippy::cast_sign_loss, + clippy::excessive_precision, + clippy::float_cmp, + clippy::manual_range_contains, + clippy::similar_names, + clippy::too_many_lines, + clippy::unreadable_literal, + clippy::unseparated_literal_suffix, + clippy::wildcard_imports +)] + +#[path = "../src/common.rs"] +mod common; + +#[cfg(not(feature = "small"))] +#[path = "../src/d2s_full_table.rs"] +mod d2s_full_table; + +#[path = "../src/d2s_intrinsics.rs"] +mod d2s_intrinsics; + +#[cfg(feature = "small")] +#[path = "../src/d2s_small_table.rs"] +mod d2s_small_table; + +#[path = "../src/d2s.rs"] +mod d2s; + +#[path = "../src/s2d.rs"] +mod s2d; + +#[path = "../src/parse.rs"] +mod parse; + +use crate::parse::Error; +use crate::s2d::s2d; + +impl PartialEq for Error { + fn eq(&self, other: &Self) -> bool { + *self as u8 == *other as u8 + } +} + +#[test] +fn test_bad_input() { + assert_eq!(Error::MalformedInput, s2d(b"x").unwrap_err()); + assert_eq!(Error::MalformedInput, s2d(b"1..1").unwrap_err()); + assert_eq!(Error::MalformedInput, s2d(b"..").unwrap_err()); + assert_eq!(Error::MalformedInput, s2d(b"1..1").unwrap_err()); + assert_eq!(Error::MalformedInput, s2d(b"1ee1").unwrap_err()); + assert_eq!(Error::MalformedInput, s2d(b"1e.1").unwrap_err()); + assert_eq!(Error::InputTooShort, s2d(b"").unwrap_err()); + assert_eq!(Error::InputTooLong, s2d(b"123456789012345678").unwrap_err()); + assert_eq!(Error::InputTooLong, s2d(b"1e12345").unwrap_err()); +} + +#[test] +fn test_basic() { + assert_eq!(0.0, s2d(b"0").unwrap()); + assert_eq!(-0.0, s2d(b"-0").unwrap()); + assert_eq!(1.0, s2d(b"1").unwrap()); + assert_eq!(2.0, s2d(b"2").unwrap()); + assert_eq!(123456789.0, s2d(b"123456789").unwrap()); + assert_eq!(123.456, s2d(b"123.456").unwrap()); + assert_eq!(123.456, s2d(b"123456e-3").unwrap()); + assert_eq!(123.456, s2d(b"1234.56e-1").unwrap()); + assert_eq!(1.453, s2d(b"1.453").unwrap()); + assert_eq!(1453.0, s2d(b"1.453e+3").unwrap()); + assert_eq!(0.0, s2d(b".0").unwrap()); + assert_eq!(1.0, s2d(b"1e0").unwrap()); + assert_eq!(1.0, s2d(b"1E0").unwrap()); + assert_eq!(1.0, s2d(b"000001.000000").unwrap()); + assert_eq!(0.2316419, s2d(b"0.2316419").unwrap()); +} + +#[test] +fn test_min_max() { + assert_eq!( + 1.7976931348623157e308, + s2d(b"1.7976931348623157e308").unwrap(), + ); + assert_eq!(5E-324, s2d(b"5E-324").unwrap()); +} + +#[test] +fn test_mantissa_rounding_overflow() { + // This results in binary mantissa that is all ones and requires rounding up + // because it is closer to 1 than to the next smaller float. This is a + // regression test that the mantissa overflow is handled correctly by + // increasing the exponent. + assert_eq!(1.0, s2d(b"0.99999999999999999").unwrap()); + // This number overflows the mantissa *and* the IEEE exponent. + assert_eq!(f64::INFINITY, s2d(b"1.7976931348623159e308").unwrap()); +} + +#[test] +fn test_underflow() { + assert_eq!(0.0, s2d(b"2.4e-324").unwrap()); + assert_eq!(0.0, s2d(b"1e-324").unwrap()); + assert_eq!(0.0, s2d(b"9.99999e-325").unwrap()); + // These are just about halfway between 0 and the smallest float. + // The first is just below the halfway point, the second just above. + assert_eq!(0.0, s2d(b"2.4703282292062327e-324").unwrap()); + assert_eq!(5e-324, s2d(b"2.4703282292062328e-324").unwrap()); +} + +#[test] +fn test_overflow() { + assert_eq!(f64::INFINITY, s2d(b"2e308").unwrap()); + assert_eq!(f64::INFINITY, s2d(b"1e309").unwrap()); +} + +#[test] +fn test_table_size_denormal() { + assert_eq!(5e-324, s2d(b"4.9406564584124654e-324").unwrap()); +} + +#[test] +fn test_issue157() { + assert_eq!( + 1.2999999999999999E+154, + s2d(b"1.2999999999999999E+154").unwrap(), + ); +} + +#[test] +fn test_issue173() { + // Denormal boundary + assert_eq!( + 2.2250738585072012e-308, + s2d(b"2.2250738585072012e-308").unwrap(), + ); + assert_eq!( + 2.2250738585072013e-308, + s2d(b"2.2250738585072013e-308").unwrap(), + ); + assert_eq!( + 2.2250738585072014e-308, + s2d(b"2.2250738585072014e-308").unwrap(), + ); +} diff --git a/vendor/ryu/tests/s2f_test.rs b/vendor/ryu/tests/s2f_test.rs new file mode 100644 index 0000000..5bae935 --- /dev/null +++ b/vendor/ryu/tests/s2f_test.rs @@ -0,0 +1,110 @@ +// Translated from C to Rust. The original C code can be found at +// https://github.com/ulfjack/ryu and carries the following license: +// +// Copyright 2018 Ulf Adams +// +// The contents of this file may be used under the terms of the Apache License, +// Version 2.0. +// +// (See accompanying file LICENSE-Apache or copy at +// http://www.apache.org/licenses/LICENSE-2.0) +// +// Alternatively, the contents of this file may be used under the terms of +// the Boost Software License, Version 1.0. +// (See accompanying file LICENSE-Boost or copy at +// https://www.boost.org/LICENSE_1_0.txt) +// +// Unless required by applicable law or agreed to in writing, this software +// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. + +#![allow(dead_code)] +#![allow( + clippy::cast_lossless, + clippy::cast_possible_truncation, + clippy::cast_possible_wrap, + clippy::cast_possible_wrap, + clippy::cast_sign_loss, + clippy::checked_conversions, + clippy::float_cmp, + clippy::manual_range_contains, + clippy::similar_names, + clippy::too_many_lines, + clippy::unreadable_literal, + clippy::unseparated_literal_suffix, + clippy::wildcard_imports +)] + +#[path = "../src/common.rs"] +mod common; + +#[cfg(not(feature = "small"))] +#[path = "../src/d2s_full_table.rs"] +mod d2s_full_table; + +#[path = "../src/d2s_intrinsics.rs"] +mod d2s_intrinsics; + +#[cfg(feature = "small")] +#[path = "../src/d2s_small_table.rs"] +mod d2s_small_table; + +#[path = "../src/d2s.rs"] +mod d2s; + +#[path = "../src/f2s_intrinsics.rs"] +mod f2s_intrinsics; + +#[path = "../src/f2s.rs"] +mod f2s; + +#[path = "../src/s2f.rs"] +mod s2f; + +#[path = "../src/parse.rs"] +mod parse; + +use crate::parse::Error; +use crate::s2f::s2f; + +impl PartialEq for Error { + fn eq(&self, other: &Self) -> bool { + *self as u8 == *other as u8 + } +} + +#[test] +fn test_basic() { + assert_eq!(0.0, s2f(b"0").unwrap()); + assert_eq!(-0.0, s2f(b"-0").unwrap()); + assert_eq!(1.0, s2f(b"1").unwrap()); + assert_eq!(-1.0, s2f(b"-1").unwrap()); + assert_eq!(123456792.0, s2f(b"123456789").unwrap()); + assert_eq!(299792448.0, s2f(b"299792458").unwrap()); +} + +#[test] +fn test_min_max() { + assert_eq!(1e-45, s2f(b"1e-45").unwrap()); + assert_eq!(f32::MIN_POSITIVE, s2f(b"1.1754944e-38").unwrap()); + assert_eq!(f32::MAX, s2f(b"3.4028235e+38").unwrap()); +} + +#[test] +fn test_mantissa_rounding_overflow() { + assert_eq!(1.0, s2f(b"0.999999999").unwrap()); + assert_eq!(f32::INFINITY, s2f(b"3.4028236e+38").unwrap()); + assert_eq!(1.1754944e-38, s2f(b"1.17549430e-38").unwrap()); // FLT_MIN + assert_eq!(1.1754944e-38, s2f(b"1.17549431e-38").unwrap()); + assert_eq!(1.1754944e-38, s2f(b"1.17549432e-38").unwrap()); + assert_eq!(1.1754944e-38, s2f(b"1.17549433e-38").unwrap()); + assert_eq!(1.1754944e-38, s2f(b"1.17549434e-38").unwrap()); + assert_eq!(1.1754944e-38, s2f(b"1.17549435e-38").unwrap()); +} + +#[test] +fn test_trailing_zeros() { + assert_eq!(26843550.0, s2f(b"26843549.5").unwrap()); + assert_eq!(50000004.0, s2f(b"50000002.5").unwrap()); + assert_eq!(99999992.0, s2f(b"99999989.5").unwrap()); +} diff --git a/vendor/serde/.cargo-checksum.json b/vendor/serde/.cargo-checksum.json new file mode 100644 index 0000000..77e49d8 --- /dev/null +++ b/vendor/serde/.cargo-checksum.json @@ -0,0 +1 @@ +{"files":{"Cargo.toml":"6d6add51c2e5e089ce4597070f2a2770d3caaf07da77070b01afe7a2dec19592","LICENSE-APACHE":"62c7a1e35f56406896d7aa7ca52d0cc0d272ac022b5d2796e7d6905db8a3636a","LICENSE-MIT":"23f18e03dc49df91622fe2a76176497404e46ced8a715d9d2b67a7446571cca3","README.md":"731c044fc5f98b37a89e9049c9214267db98763309cb63146b45c029640f82a3","build.rs":"a98eaa82c783fdb4169d1646c06028ec5cb82937d39ee127ec8ed33651d2f238","crates-io.md":"407d92b2932923f8708aaf31db266fd7db32e2b0afa6c569d134b680b74a1920","src/de/ignored_any.rs":"6480f2b2a83dc4764d01b2eec7309729eef2492eede2e5ee98d23a60b05198eb","src/de/impls.rs":"18ed2d8221b04c7fe8f7a757445a04cd1d28c887f46f7a8717afff10eada146f","src/de/mod.rs":"b34735b2e5c9c93e9857540f24cba393f1b767a2ba33d469c2d28f15049e8f6c","src/de/seed.rs":"045d890712a04eb33ffc5a021e5d948a63c89402b8ffeea749df2171b7484f8f","src/de/size_hint.rs":"fff83dc39d30e75e8e611991f9c5399188a1aad23a6462dbca2c8b62655cfedb","src/de/value.rs":"0c485908b1f755e4750af0aefa2132460dadbcf30919c15c06ca795a92d96430","src/format.rs":"c85071b016df643b161859682d21ce34fa0ebf2a3bdbeeea69859da48f5d934f","src/integer128.rs":"29ef30b7d94507b34807090e68173767cdc7aff62edccd38affe69e75338dddc","src/lib.rs":"ff721a04872d840e4a9aabd0cbd98c1a60ae3eefd6237f5c6c1474b9549e4f04","src/macros.rs":"0d4b392ed6fe529fda2c5439c8547fe9717e64f528bfd01f633bb725f98b53cd","src/private/de.rs":"c12df7ee5ac43c9c30389e1f02d2bb5c206b1b850e598963dfedeb303e448f5a","src/private/doc.rs":"b222decb40321190155209e1b8a5a52e3adfaa470047e379e664b71e0320655a","src/private/mod.rs":"b8f0c348621d91dd9da3db83d8877e70bc61ad0a2dc2d6fb57c6fc2c2cbafa26","src/private/ser.rs":"4343ccbe0b345288dce0dbf1023c6082ef42ae7073c911b535e3d9e88c3aa472","src/ser/fmt.rs":"d1cfd9623605413e45a23ef778d97f0ac4da4adaed23739f1f9d7414b30e384b","src/ser/impls.rs":"00b58a84f7c07b2f575219d6d0745fd1258dae9b9c8ec5b9b299a712c482b1a3","src/ser/impossible.rs":"5c325da8e0370ab22abe1e15d8af1dc7a1707b127508f61e720cd7f0caa80593","src/ser/mod.rs":"9aab34f08defdd6be044383ad41aeb59acee3abe7cacb73ac5bc8c70f747a67e","src/std_error.rs":"25a07149e2e468747ffa5a58051c7f93d7b3c0fa0372f012a96c97ec8ab03b97"},"package":"c8e3592472072e6e22e0a54d5904d9febf8508f65fb8552499a1abc7d1078c3a"} \ No newline at end of file diff --git a/vendor/serde/Cargo.toml b/vendor/serde/Cargo.toml new file mode 100644 index 0000000..e6d535d --- /dev/null +++ b/vendor/serde/Cargo.toml @@ -0,0 +1,79 @@ +# 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] +edition = "2018" +rust-version = "1.31" +name = "serde" +version = "1.0.210" +authors = [ + "Erick Tryzelaar ", + "David Tolnay ", +] +build = "build.rs" +autobins = false +autoexamples = false +autotests = false +autobenches = false +description = "A generic serialization/deserialization framework" +homepage = "https://serde.rs" +documentation = "https://docs.rs/serde" +readme = "crates-io.md" +keywords = [ + "serde", + "serialization", + "no_std", +] +categories = [ + "encoding", + "no-std", + "no-std::no-alloc", +] +license = "MIT OR Apache-2.0" +repository = "https://github.com/serde-rs/serde" + +[package.metadata.docs.rs] +features = [ + "derive", + "rc", + "unstable", +] +rustdoc-args = ["--generate-link-to-definition"] +targets = ["x86_64-unknown-linux-gnu"] + +[package.metadata.playground] +features = [ + "derive", + "rc", +] + +[lib] +name = "serde" +path = "src/lib.rs" +doc-scrape-examples = false + +[dependencies.serde_derive] +version = "1" +optional = true + +[dev-dependencies.serde_derive] +version = "1" + +[features] +alloc = [] +default = ["std"] +derive = ["serde_derive"] +rc = [] +std = [] +unstable = [] + +[target."cfg(any())".dependencies.serde_derive] +version = "=1.0.210" diff --git a/vendor/serde/LICENSE-APACHE b/vendor/serde/LICENSE-APACHE new file mode 100644 index 0000000..1b5ec8b --- /dev/null +++ b/vendor/serde/LICENSE-APACHE @@ -0,0 +1,176 @@ + 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 diff --git a/vendor/serde/LICENSE-MIT b/vendor/serde/LICENSE-MIT new file mode 100644 index 0000000..31aa793 --- /dev/null +++ b/vendor/serde/LICENSE-MIT @@ -0,0 +1,23 @@ +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/serde/README.md b/vendor/serde/README.md new file mode 100644 index 0000000..3129294 --- /dev/null +++ b/vendor/serde/README.md @@ -0,0 +1,114 @@ +# Serde   [![Build Status]][actions] [![Latest Version]][crates.io] [![serde msrv]][Rust 1.31] [![serde_derive msrv]][Rust 1.56] + +[Build Status]: https://img.shields.io/github/actions/workflow/status/serde-rs/serde/ci.yml?branch=master +[actions]: https://github.com/serde-rs/serde/actions?query=branch%3Amaster +[Latest Version]: https://img.shields.io/crates/v/serde.svg +[crates.io]: https://crates.io/crates/serde +[serde msrv]: https://img.shields.io/crates/msrv/serde.svg?label=serde%20msrv&color=lightgray +[serde_derive msrv]: https://img.shields.io/crates/msrv/serde_derive.svg?label=serde_derive%20msrv&color=lightgray +[Rust 1.31]: https://blog.rust-lang.org/2018/12/06/Rust-1.31-and-rust-2018.html +[Rust 1.56]: https://blog.rust-lang.org/2021/10/21/Rust-1.56.0.html + +**Serde is a framework for *ser*ializing and *de*serializing Rust data structures efficiently and generically.** + +--- + +You may be looking for: + +- [An overview of Serde](https://serde.rs/) +- [Data formats supported by Serde](https://serde.rs/#data-formats) +- [Setting up `#[derive(Serialize, Deserialize)]`](https://serde.rs/derive.html) +- [Examples](https://serde.rs/examples.html) +- [API documentation](https://docs.rs/serde) +- [Release notes](https://github.com/serde-rs/serde/releases) + +## Serde in action + +
+ +Click to show Cargo.toml. +Run this code in the playground. + + +```toml +[dependencies] + +# The core APIs, including the Serialize and Deserialize traits. Always +# required when using Serde. The "derive" feature is only required when +# using #[derive(Serialize, Deserialize)] to make Serde work with structs +# and enums defined in your crate. +serde = { version = "1.0", features = ["derive"] } + +# Each data format lives in its own crate; the sample code below uses JSON +# but you may be using a different one. +serde_json = "1.0" +``` + +
+

+ +```rust +use serde::{Deserialize, Serialize}; + +#[derive(Serialize, Deserialize, Debug)] +struct Point { + x: i32, + y: i32, +} + +fn main() { + let point = Point { x: 1, y: 2 }; + + // Convert the Point to a JSON string. + let serialized = serde_json::to_string(&point).unwrap(); + + // Prints serialized = {"x":1,"y":2} + println!("serialized = {}", serialized); + + // Convert the JSON string back to a Point. + let deserialized: Point = serde_json::from_str(&serialized).unwrap(); + + // Prints deserialized = Point { x: 1, y: 2 } + println!("deserialized = {:?}", deserialized); +} +``` + +## Getting help + +Serde is one of the most widely used Rust libraries so any place that Rustaceans +congregate will be able to help you out. For chat, consider trying the +[#rust-questions] or [#rust-beginners] channels of the unofficial community +Discord (invite: ), the [#rust-usage] or +[#beginners] channels of the official Rust Project Discord (invite: +), or the [#general][zulip] stream in Zulip. For +asynchronous, consider the [\[rust\] tag on StackOverflow][stackoverflow], the +[/r/rust] subreddit which has a pinned weekly easy questions post, or the Rust +[Discourse forum][discourse]. It's acceptable to file a support issue in this +repo but they tend not to get as many eyes as any of the above and may get +closed without a response after some time. + +[#rust-questions]: https://discord.com/channels/273534239310479360/274215136414400513 +[#rust-beginners]: https://discord.com/channels/273534239310479360/273541522815713281 +[#rust-usage]: https://discord.com/channels/442252698964721669/443150878111694848 +[#beginners]: https://discord.com/channels/442252698964721669/448238009733742612 +[zulip]: https://rust-lang.zulipchat.com/#narrow/stream/122651-general +[stackoverflow]: https://stackoverflow.com/questions/tagged/rust +[/r/rust]: https://www.reddit.com/r/rust +[discourse]: https://users.rust-lang.org + +
+ +#### License + + +Licensed under either of Apache License, Version +2.0 or MIT license at your option. + + +
+ + +Unless you explicitly state otherwise, any contribution intentionally submitted +for inclusion in Serde 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/serde/build.rs b/vendor/serde/build.rs new file mode 100644 index 0000000..8a4f725 --- /dev/null +++ b/vendor/serde/build.rs @@ -0,0 +1,137 @@ +use std::env; +use std::process::Command; +use std::str::{self, FromStr}; + +// The rustc-cfg strings below are *not* public API. Please let us know by +// opening a GitHub issue if your build environment requires some way to enable +// these cfgs other than by executing our build script. +fn main() { + println!("cargo:rerun-if-changed=build.rs"); + + let minor = match rustc_minor_version() { + Some(minor) => minor, + None => return, + }; + + if minor >= 77 { + println!("cargo:rustc-check-cfg=cfg(no_core_cstr)"); + println!("cargo:rustc-check-cfg=cfg(no_core_error)"); + println!("cargo:rustc-check-cfg=cfg(no_core_net)"); + println!("cargo:rustc-check-cfg=cfg(no_core_num_saturating)"); + println!("cargo:rustc-check-cfg=cfg(no_core_try_from)"); + println!("cargo:rustc-check-cfg=cfg(no_diagnostic_namespace)"); + println!("cargo:rustc-check-cfg=cfg(no_float_copysign)"); + println!("cargo:rustc-check-cfg=cfg(no_num_nonzero_signed)"); + println!("cargo:rustc-check-cfg=cfg(no_relaxed_trait_bounds)"); + println!("cargo:rustc-check-cfg=cfg(no_serde_derive)"); + println!("cargo:rustc-check-cfg=cfg(no_std_atomic)"); + println!("cargo:rustc-check-cfg=cfg(no_std_atomic64)"); + println!("cargo:rustc-check-cfg=cfg(no_systemtime_checked_add)"); + println!("cargo:rustc-check-cfg=cfg(no_target_has_atomic)"); + } + + let target = env::var("TARGET").unwrap(); + let emscripten = target == "asmjs-unknown-emscripten" || target == "wasm32-unknown-emscripten"; + + // TryFrom, Atomic types, non-zero signed integers, and SystemTime::checked_add + // stabilized in Rust 1.34: + // https://blog.rust-lang.org/2019/04/11/Rust-1.34.0.html#tryfrom-and-tryinto + // https://blog.rust-lang.org/2019/04/11/Rust-1.34.0.html#library-stabilizations + if minor < 34 { + println!("cargo:rustc-cfg=no_core_try_from"); + println!("cargo:rustc-cfg=no_num_nonzero_signed"); + println!("cargo:rustc-cfg=no_systemtime_checked_add"); + println!("cargo:rustc-cfg=no_relaxed_trait_bounds"); + } + + // f32::copysign and f64::copysign stabilized in Rust 1.35. + // https://blog.rust-lang.org/2019/05/23/Rust-1.35.0.html#copy-the-sign-of-a-floating-point-number-onto-another + if minor < 35 { + println!("cargo:rustc-cfg=no_float_copysign"); + } + + // Current minimum supported version of serde_derive crate is Rust 1.56. + if minor < 56 { + println!("cargo:rustc-cfg=no_serde_derive"); + } + + // Support for #[cfg(target_has_atomic = "...")] stabilized in Rust 1.60. + if minor < 60 { + println!("cargo:rustc-cfg=no_target_has_atomic"); + // Allowlist of archs that support std::sync::atomic module. This is + // based on rustc's compiler/rustc_target/src/spec/*.rs. + let has_atomic64 = target.starts_with("x86_64") + || target.starts_with("i686") + || target.starts_with("aarch64") + || target.starts_with("powerpc64") + || target.starts_with("sparc64") + || target.starts_with("mips64el") + || target.starts_with("riscv64"); + let has_atomic32 = has_atomic64 || emscripten; + if minor < 34 || !has_atomic64 { + println!("cargo:rustc-cfg=no_std_atomic64"); + } + if minor < 34 || !has_atomic32 { + println!("cargo:rustc-cfg=no_std_atomic"); + } + } + + // Support for core::ffi::CStr and alloc::ffi::CString stabilized in Rust 1.64. + // https://blog.rust-lang.org/2022/09/22/Rust-1.64.0.html#c-compatible-ffi-types-in-core-and-alloc + if minor < 64 { + println!("cargo:rustc-cfg=no_core_cstr"); + } + + // Support for core::num::Saturating and std::num::Saturating stabilized in Rust 1.74 + // https://blog.rust-lang.org/2023/11/16/Rust-1.74.0.html#stabilized-apis + if minor < 74 { + println!("cargo:rustc-cfg=no_core_num_saturating"); + } + + // Support for core::net stabilized in Rust 1.77. + // https://blog.rust-lang.org/2024/03/21/Rust-1.77.0.html + if minor < 77 { + println!("cargo:rustc-cfg=no_core_net"); + } + + // Support for the `#[diagnostic]` tool attribute namespace + // https://blog.rust-lang.org/2024/05/02/Rust-1.78.0.html#diagnostic-attributes + if minor < 78 { + println!("cargo:rustc-cfg=no_diagnostic_namespace"); + } + + // The Error trait became available in core in 1.81. + // https://blog.rust-lang.org/2024/09/05/Rust-1.81.0.html#coreerrorerror + if minor < 81 { + println!("cargo:rustc-cfg=no_core_error"); + } +} + +fn rustc_minor_version() -> Option { + let rustc = match env::var_os("RUSTC") { + Some(rustc) => rustc, + None => return None, + }; + + let output = match Command::new(rustc).arg("--version").output() { + Ok(output) => output, + Err(_) => return None, + }; + + let version = match str::from_utf8(&output.stdout) { + Ok(version) => version, + Err(_) => return None, + }; + + let mut pieces = version.split('.'); + if pieces.next() != Some("rustc 1") { + return None; + } + + let next = match pieces.next() { + Some(next) => next, + None => return None, + }; + + u32::from_str(next).ok() +} diff --git a/vendor/serde/crates-io.md b/vendor/serde/crates-io.md new file mode 100644 index 0000000..b49a548 --- /dev/null +++ b/vendor/serde/crates-io.md @@ -0,0 +1,65 @@ + + +**Serde is a framework for *ser*ializing and *de*serializing Rust data structures efficiently and generically.** + +--- + +You may be looking for: + +- [An overview of Serde](https://serde.rs/) +- [Data formats supported by Serde](https://serde.rs/#data-formats) +- [Setting up `#[derive(Serialize, Deserialize)]`](https://serde.rs/derive.html) +- [Examples](https://serde.rs/examples.html) +- [API documentation](https://docs.rs/serde) +- [Release notes](https://github.com/serde-rs/serde/releases) + +## Serde in action + +```rust +use serde::{Deserialize, Serialize}; + +#[derive(Serialize, Deserialize, Debug)] +struct Point { + x: i32, + y: i32, +} + +fn main() { + let point = Point { x: 1, y: 2 }; + + // Convert the Point to a JSON string. + let serialized = serde_json::to_string(&point).unwrap(); + + // Prints serialized = {"x":1,"y":2} + println!("serialized = {}", serialized); + + // Convert the JSON string back to a Point. + let deserialized: Point = serde_json::from_str(&serialized).unwrap(); + + // Prints deserialized = Point { x: 1, y: 2 } + println!("deserialized = {:?}", deserialized); +} +``` + +## Getting help + +Serde is one of the most widely used Rust libraries so any place that Rustaceans +congregate will be able to help you out. For chat, consider trying the +[#rust-questions] or [#rust-beginners] channels of the unofficial community +Discord (invite: ), the [#rust-usage] +or [#beginners] channels of the official Rust Project Discord (invite: +), or the [#general][zulip] stream in Zulip. For +asynchronous, consider the [\[rust\] tag on StackOverflow][stackoverflow], the +[/r/rust] subreddit which has a pinned weekly easy questions post, or the Rust +[Discourse forum][discourse]. It's acceptable to file a support issue in this +repo but they tend not to get as many eyes as any of the above and may get +closed without a response after some time. + +[#rust-questions]: https://discord.com/channels/273534239310479360/274215136414400513 +[#rust-beginners]: https://discord.com/channels/273534239310479360/273541522815713281 +[#rust-usage]: https://discord.com/channels/442252698964721669/443150878111694848 +[#beginners]: https://discord.com/channels/442252698964721669/448238009733742612 +[zulip]: https://rust-lang.zulipchat.com/#narrow/stream/122651-general +[stackoverflow]: https://stackoverflow.com/questions/tagged/rust +[/r/rust]: https://www.reddit.com/r/rust +[discourse]: https://users.rust-lang.org diff --git a/vendor/serde/src/de/ignored_any.rs b/vendor/serde/src/de/ignored_any.rs new file mode 100644 index 0000000..2360a17 --- /dev/null +++ b/vendor/serde/src/de/ignored_any.rs @@ -0,0 +1,238 @@ +use crate::lib::*; + +use crate::de::{ + Deserialize, Deserializer, EnumAccess, Error, MapAccess, SeqAccess, VariantAccess, Visitor, +}; + +/// An efficient way of discarding data from a deserializer. +/// +/// Think of this like `serde_json::Value` in that it can be deserialized from +/// any type, except that it does not store any information about the data that +/// gets deserialized. +/// +/// ```edition2021 +/// use serde::de::{ +/// self, Deserialize, DeserializeSeed, Deserializer, IgnoredAny, SeqAccess, Visitor, +/// }; +/// use std::fmt; +/// use std::marker::PhantomData; +/// +/// /// A seed that can be used to deserialize only the `n`th element of a sequence +/// /// while efficiently discarding elements of any type before or after index `n`. +/// /// +/// /// For example to deserialize only the element at index 3: +/// /// +/// /// ``` +/// /// NthElement::new(3).deserialize(deserializer) +/// /// ``` +/// pub struct NthElement { +/// n: usize, +/// marker: PhantomData, +/// } +/// +/// impl NthElement { +/// pub fn new(n: usize) -> Self { +/// NthElement { +/// n: n, +/// marker: PhantomData, +/// } +/// } +/// } +/// +/// impl<'de, T> Visitor<'de> for NthElement +/// where +/// T: Deserialize<'de>, +/// { +/// type Value = T; +/// +/// fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { +/// write!( +/// formatter, +/// "a sequence in which we care about element {}", +/// self.n +/// ) +/// } +/// +/// fn visit_seq(self, mut seq: A) -> Result +/// where +/// A: SeqAccess<'de>, +/// { +/// // Skip over the first `n` elements. +/// for i in 0..self.n { +/// // It is an error if the sequence ends before we get to element `n`. +/// if seq.next_element::()?.is_none() { +/// return Err(de::Error::invalid_length(i, &self)); +/// } +/// } +/// +/// // Deserialize the one we care about. +/// let nth = match seq.next_element()? { +/// Some(nth) => nth, +/// None => { +/// return Err(de::Error::invalid_length(self.n, &self)); +/// } +/// }; +/// +/// // Skip over any remaining elements in the sequence after `n`. +/// while let Some(IgnoredAny) = seq.next_element()? { +/// // ignore +/// } +/// +/// Ok(nth) +/// } +/// } +/// +/// impl<'de, T> DeserializeSeed<'de> for NthElement +/// where +/// T: Deserialize<'de>, +/// { +/// type Value = T; +/// +/// fn deserialize(self, deserializer: D) -> Result +/// where +/// D: Deserializer<'de>, +/// { +/// deserializer.deserialize_seq(self) +/// } +/// } +/// +/// # fn example<'de, D>(deserializer: D) -> Result<(), D::Error> +/// # where +/// # D: Deserializer<'de>, +/// # { +/// // Deserialize only the sequence element at index 3 from this deserializer. +/// // The element at index 3 is required to be a string. Elements before and +/// // after index 3 are allowed to be of any type. +/// let s: String = NthElement::new(3).deserialize(deserializer)?; +/// # Ok(()) +/// # } +/// ``` +#[derive(Copy, Clone, Debug, Default, PartialEq)] +pub struct IgnoredAny; + +impl<'de> Visitor<'de> for IgnoredAny { + type Value = IgnoredAny; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("anything at all") + } + + #[inline] + fn visit_bool(self, x: bool) -> Result { + let _ = x; + Ok(IgnoredAny) + } + + #[inline] + fn visit_i64(self, x: i64) -> Result { + let _ = x; + Ok(IgnoredAny) + } + + #[inline] + fn visit_i128(self, x: i128) -> Result { + let _ = x; + Ok(IgnoredAny) + } + + #[inline] + fn visit_u64(self, x: u64) -> Result { + let _ = x; + Ok(IgnoredAny) + } + + #[inline] + fn visit_u128(self, x: u128) -> Result { + let _ = x; + Ok(IgnoredAny) + } + + #[inline] + fn visit_f64(self, x: f64) -> Result { + let _ = x; + Ok(IgnoredAny) + } + + #[inline] + fn visit_str(self, s: &str) -> Result + where + E: Error, + { + let _ = s; + Ok(IgnoredAny) + } + + #[inline] + fn visit_none(self) -> Result { + Ok(IgnoredAny) + } + + #[inline] + fn visit_some(self, deserializer: D) -> Result + where + D: Deserializer<'de>, + { + IgnoredAny::deserialize(deserializer) + } + + #[inline] + fn visit_newtype_struct(self, deserializer: D) -> Result + where + D: Deserializer<'de>, + { + IgnoredAny::deserialize(deserializer) + } + + #[inline] + fn visit_unit(self) -> Result { + Ok(IgnoredAny) + } + + #[inline] + fn visit_seq(self, mut seq: A) -> Result + where + A: SeqAccess<'de>, + { + while let Some(IgnoredAny) = tri!(seq.next_element()) { + // Gobble + } + Ok(IgnoredAny) + } + + #[inline] + fn visit_map(self, mut map: A) -> Result + where + A: MapAccess<'de>, + { + while let Some((IgnoredAny, IgnoredAny)) = tri!(map.next_entry()) { + // Gobble + } + Ok(IgnoredAny) + } + + #[inline] + fn visit_bytes(self, bytes: &[u8]) -> Result + where + E: Error, + { + let _ = bytes; + Ok(IgnoredAny) + } + + fn visit_enum(self, data: A) -> Result + where + A: EnumAccess<'de>, + { + tri!(data.variant::()).1.newtype_variant() + } +} + +impl<'de> Deserialize<'de> for IgnoredAny { + #[inline] + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + deserializer.deserialize_ignored_any(IgnoredAny) + } +} diff --git a/vendor/serde/src/de/impls.rs b/vendor/serde/src/de/impls.rs new file mode 100644 index 0000000..2d8c990 --- /dev/null +++ b/vendor/serde/src/de/impls.rs @@ -0,0 +1,3183 @@ +use crate::lib::*; + +use crate::de::{ + Deserialize, Deserializer, EnumAccess, Error, MapAccess, SeqAccess, Unexpected, VariantAccess, + Visitor, +}; + +use crate::seed::InPlaceSeed; + +#[cfg(any(feature = "std", feature = "alloc"))] +use crate::de::size_hint; + +//////////////////////////////////////////////////////////////////////////////// + +struct UnitVisitor; + +impl<'de> Visitor<'de> for UnitVisitor { + type Value = (); + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("unit") + } + + fn visit_unit(self) -> Result + where + E: Error, + { + Ok(()) + } +} + +impl<'de> Deserialize<'de> for () { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + deserializer.deserialize_unit(UnitVisitor) + } +} + +#[cfg(feature = "unstable")] +#[cfg_attr(docsrs, doc(cfg(feature = "unstable")))] +impl<'de> Deserialize<'de> for ! { + fn deserialize(_deserializer: D) -> Result + where + D: Deserializer<'de>, + { + Err(Error::custom("cannot deserialize `!`")) + } +} + +//////////////////////////////////////////////////////////////////////////////// + +struct BoolVisitor; + +impl<'de> Visitor<'de> for BoolVisitor { + type Value = bool; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("a boolean") + } + + fn visit_bool(self, v: bool) -> Result + where + E: Error, + { + Ok(v) + } +} + +impl<'de> Deserialize<'de> for bool { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + deserializer.deserialize_bool(BoolVisitor) + } +} + +//////////////////////////////////////////////////////////////////////////////// + +macro_rules! impl_deserialize_num { + ($primitive:ident, $nonzero:ident $(cfg($($cfg:tt)*))*, $deserialize:ident $($method:ident!($($val:ident : $visit:ident)*);)*) => { + impl_deserialize_num!($primitive, $deserialize $($method!($($val : $visit)*);)*); + + $(#[cfg($($cfg)*)])* + impl<'de> Deserialize<'de> for num::$nonzero { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + struct NonZeroVisitor; + + impl<'de> Visitor<'de> for NonZeroVisitor { + type Value = num::$nonzero; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str(concat!("a nonzero ", stringify!($primitive))) + } + + $($($method!(nonzero $primitive $val : $visit);)*)* + } + + deserializer.$deserialize(NonZeroVisitor) + } + } + + #[cfg(not(no_core_num_saturating))] + impl<'de> Deserialize<'de> for Saturating<$primitive> { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + struct SaturatingVisitor; + + impl<'de> Visitor<'de> for SaturatingVisitor { + type Value = Saturating<$primitive>; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("integer with support for saturating semantics") + } + + $($($method!(saturating $primitive $val : $visit);)*)* + } + + deserializer.$deserialize(SaturatingVisitor) + } + } + }; + + ($primitive:ident, $deserialize:ident $($method:ident!($($val:ident : $visit:ident)*);)*) => { + impl<'de> Deserialize<'de> for $primitive { + #[inline] + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + struct PrimitiveVisitor; + + impl<'de> Visitor<'de> for PrimitiveVisitor { + type Value = $primitive; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str(stringify!($primitive)) + } + + $($($method!($val : $visit);)*)* + } + + deserializer.$deserialize(PrimitiveVisitor) + } + } + }; +} + +macro_rules! num_self { + ($ty:ident : $visit:ident) => { + #[inline] + fn $visit(self, v: $ty) -> Result + where + E: Error, + { + Ok(v) + } + }; + + (nonzero $primitive:ident $ty:ident : $visit:ident) => { + fn $visit(self, v: $ty) -> Result + where + E: Error, + { + if let Some(nonzero) = Self::Value::new(v) { + Ok(nonzero) + } else { + Err(Error::invalid_value(Unexpected::Unsigned(0), &self)) + } + } + }; + + (saturating $primitive:ident $ty:ident : $visit:ident) => { + fn $visit(self, v: $ty) -> Result + where + E: Error, + { + Ok(Saturating(v)) + } + }; +} + +macro_rules! num_as_self { + ($ty:ident : $visit:ident) => { + #[inline] + fn $visit(self, v: $ty) -> Result + where + E: Error, + { + Ok(v as Self::Value) + } + }; + + (nonzero $primitive:ident $ty:ident : $visit:ident) => { + fn $visit(self, v: $ty) -> Result + where + E: Error, + { + if let Some(nonzero) = Self::Value::new(v as $primitive) { + Ok(nonzero) + } else { + Err(Error::invalid_value(Unexpected::Unsigned(0), &self)) + } + } + }; + + (saturating $primitive:ident $ty:ident : $visit:ident) => { + fn $visit(self, v: $ty) -> Result + where + E: Error, + { + Ok(Saturating(v as $primitive)) + } + }; +} + +macro_rules! num_as_copysign_self { + ($ty:ident : $visit:ident) => { + #[inline] + fn $visit(self, v: $ty) -> Result + where + E: Error, + { + #[cfg(any(no_float_copysign, not(feature = "std")))] + { + Ok(v as Self::Value) + } + + #[cfg(all(not(no_float_copysign), feature = "std"))] + { + // Preserve sign of NaN. The `as` produces a nondeterministic sign. + let sign = if v.is_sign_positive() { 1.0 } else { -1.0 }; + Ok((v as Self::Value).copysign(sign)) + } + } + }; +} + +macro_rules! int_to_int { + ($ty:ident : $visit:ident) => { + #[inline] + fn $visit(self, v: $ty) -> Result + where + E: Error, + { + if Self::Value::min_value() as i64 <= v as i64 + && v as i64 <= Self::Value::max_value() as i64 + { + Ok(v as Self::Value) + } else { + Err(Error::invalid_value(Unexpected::Signed(v as i64), &self)) + } + } + }; + + (nonzero $primitive:ident $ty:ident : $visit:ident) => { + fn $visit(self, v: $ty) -> Result + where + E: Error, + { + if $primitive::min_value() as i64 <= v as i64 + && v as i64 <= $primitive::max_value() as i64 + { + if let Some(nonzero) = Self::Value::new(v as $primitive) { + return Ok(nonzero); + } + } + Err(Error::invalid_value(Unexpected::Signed(v as i64), &self)) + } + }; + + (saturating $primitive:ident $ty:ident : $visit:ident) => { + fn $visit(self, v: $ty) -> Result + where + E: Error, + { + if (v as i64) < $primitive::MIN as i64 { + Ok(Saturating($primitive::MIN)) + } else if ($primitive::MAX as i64) < v as i64 { + Ok(Saturating($primitive::MAX)) + } else { + Ok(Saturating(v as $primitive)) + } + } + }; +} + +macro_rules! int_to_uint { + ($ty:ident : $visit:ident) => { + #[inline] + fn $visit(self, v: $ty) -> Result + where + E: Error, + { + if 0 <= v && v as u64 <= Self::Value::max_value() as u64 { + Ok(v as Self::Value) + } else { + Err(Error::invalid_value(Unexpected::Signed(v as i64), &self)) + } + } + }; + + (nonzero $primitive:ident $ty:ident : $visit:ident) => { + fn $visit(self, v: $ty) -> Result + where + E: Error, + { + if 0 < v && v as u64 <= $primitive::max_value() as u64 { + if let Some(nonzero) = Self::Value::new(v as $primitive) { + return Ok(nonzero); + } + } + Err(Error::invalid_value(Unexpected::Signed(v as i64), &self)) + } + }; + + (saturating $primitive:ident $ty:ident : $visit:ident) => { + fn $visit(self, v: $ty) -> Result + where + E: Error, + { + if v < 0 { + Ok(Saturating(0)) + } else if ($primitive::MAX as u64) < v as u64 { + Ok(Saturating($primitive::MAX)) + } else { + Ok(Saturating(v as $primitive)) + } + } + }; +} + +macro_rules! uint_to_self { + ($ty:ident : $visit:ident) => { + #[inline] + fn $visit(self, v: $ty) -> Result + where + E: Error, + { + if v as u64 <= Self::Value::max_value() as u64 { + Ok(v as Self::Value) + } else { + Err(Error::invalid_value(Unexpected::Unsigned(v as u64), &self)) + } + } + }; + + (nonzero $primitive:ident $ty:ident : $visit:ident) => { + fn $visit(self, v: $ty) -> Result + where + E: Error, + { + if v as u64 <= $primitive::max_value() as u64 { + if let Some(nonzero) = Self::Value::new(v as $primitive) { + return Ok(nonzero); + } + } + Err(Error::invalid_value(Unexpected::Unsigned(v as u64), &self)) + } + }; + + (saturating $primitive:ident $ty:ident : $visit:ident) => { + fn $visit(self, v: $ty) -> Result + where + E: Error, + { + if v as u64 <= $primitive::MAX as u64 { + Ok(Saturating(v as $primitive)) + } else { + Ok(Saturating($primitive::MAX)) + } + } + }; +} + +impl_deserialize_num! { + i8, NonZeroI8 cfg(not(no_num_nonzero_signed)), deserialize_i8 + num_self!(i8:visit_i8); + int_to_int!(i16:visit_i16 i32:visit_i32 i64:visit_i64); + uint_to_self!(u8:visit_u8 u16:visit_u16 u32:visit_u32 u64:visit_u64); +} + +impl_deserialize_num! { + i16, NonZeroI16 cfg(not(no_num_nonzero_signed)), deserialize_i16 + num_self!(i16:visit_i16); + num_as_self!(i8:visit_i8); + int_to_int!(i32:visit_i32 i64:visit_i64); + uint_to_self!(u8:visit_u8 u16:visit_u16 u32:visit_u32 u64:visit_u64); +} + +impl_deserialize_num! { + i32, NonZeroI32 cfg(not(no_num_nonzero_signed)), deserialize_i32 + num_self!(i32:visit_i32); + num_as_self!(i8:visit_i8 i16:visit_i16); + int_to_int!(i64:visit_i64); + uint_to_self!(u8:visit_u8 u16:visit_u16 u32:visit_u32 u64:visit_u64); +} + +impl_deserialize_num! { + i64, NonZeroI64 cfg(not(no_num_nonzero_signed)), deserialize_i64 + num_self!(i64:visit_i64); + num_as_self!(i8:visit_i8 i16:visit_i16 i32:visit_i32); + uint_to_self!(u8:visit_u8 u16:visit_u16 u32:visit_u32 u64:visit_u64); +} + +impl_deserialize_num! { + isize, NonZeroIsize cfg(not(no_num_nonzero_signed)), deserialize_i64 + num_as_self!(i8:visit_i8 i16:visit_i16); + int_to_int!(i32:visit_i32 i64:visit_i64); + uint_to_self!(u8:visit_u8 u16:visit_u16 u32:visit_u32 u64:visit_u64); +} + +impl_deserialize_num! { + u8, NonZeroU8, deserialize_u8 + num_self!(u8:visit_u8); + int_to_uint!(i8:visit_i8 i16:visit_i16 i32:visit_i32 i64:visit_i64); + uint_to_self!(u16:visit_u16 u32:visit_u32 u64:visit_u64); +} + +impl_deserialize_num! { + u16, NonZeroU16, deserialize_u16 + num_self!(u16:visit_u16); + num_as_self!(u8:visit_u8); + int_to_uint!(i8:visit_i8 i16:visit_i16 i32:visit_i32 i64:visit_i64); + uint_to_self!(u32:visit_u32 u64:visit_u64); +} + +impl_deserialize_num! { + u32, NonZeroU32, deserialize_u32 + num_self!(u32:visit_u32); + num_as_self!(u8:visit_u8 u16:visit_u16); + int_to_uint!(i8:visit_i8 i16:visit_i16 i32:visit_i32 i64:visit_i64); + uint_to_self!(u64:visit_u64); +} + +impl_deserialize_num! { + u64, NonZeroU64, deserialize_u64 + num_self!(u64:visit_u64); + num_as_self!(u8:visit_u8 u16:visit_u16 u32:visit_u32); + int_to_uint!(i8:visit_i8 i16:visit_i16 i32:visit_i32 i64:visit_i64); +} + +impl_deserialize_num! { + usize, NonZeroUsize, deserialize_u64 + num_as_self!(u8:visit_u8 u16:visit_u16); + int_to_uint!(i8:visit_i8 i16:visit_i16 i32:visit_i32 i64:visit_i64); + uint_to_self!(u32:visit_u32 u64:visit_u64); +} + +impl_deserialize_num! { + f32, deserialize_f32 + num_self!(f32:visit_f32); + num_as_copysign_self!(f64:visit_f64); + num_as_self!(i8:visit_i8 i16:visit_i16 i32:visit_i32 i64:visit_i64); + num_as_self!(u8:visit_u8 u16:visit_u16 u32:visit_u32 u64:visit_u64); +} + +impl_deserialize_num! { + f64, deserialize_f64 + num_self!(f64:visit_f64); + num_as_copysign_self!(f32:visit_f32); + num_as_self!(i8:visit_i8 i16:visit_i16 i32:visit_i32 i64:visit_i64); + num_as_self!(u8:visit_u8 u16:visit_u16 u32:visit_u32 u64:visit_u64); +} + +macro_rules! num_128 { + ($ty:ident : $visit:ident) => { + fn $visit(self, v: $ty) -> Result + where + E: Error, + { + if v as i128 >= Self::Value::min_value() as i128 + && v as u128 <= Self::Value::max_value() as u128 + { + Ok(v as Self::Value) + } else { + Err(Error::invalid_value( + Unexpected::Other(stringify!($ty)), + &self, + )) + } + } + }; + + (nonzero $primitive:ident $ty:ident : $visit:ident) => { + fn $visit(self, v: $ty) -> Result + where + E: Error, + { + if v as i128 >= $primitive::min_value() as i128 + && v as u128 <= $primitive::max_value() as u128 + { + if let Some(nonzero) = Self::Value::new(v as $primitive) { + Ok(nonzero) + } else { + Err(Error::invalid_value(Unexpected::Unsigned(0), &self)) + } + } else { + Err(Error::invalid_value( + Unexpected::Other(stringify!($ty)), + &self, + )) + } + } + }; + + (saturating $primitive:ident $ty:ident : $visit:ident) => { + fn $visit(self, v: $ty) -> Result + where + E: Error, + { + if (v as i128) < $primitive::MIN as i128 { + Ok(Saturating($primitive::MIN)) + } else if ($primitive::MAX as u128) < v as u128 { + Ok(Saturating($primitive::MAX)) + } else { + Ok(Saturating(v as $primitive)) + } + } + }; +} + +impl_deserialize_num! { + i128, NonZeroI128 cfg(not(no_num_nonzero_signed)), deserialize_i128 + num_self!(i128:visit_i128); + num_as_self!(i8:visit_i8 i16:visit_i16 i32:visit_i32 i64:visit_i64); + num_as_self!(u8:visit_u8 u16:visit_u16 u32:visit_u32 u64:visit_u64); + num_128!(u128:visit_u128); +} + +impl_deserialize_num! { + u128, NonZeroU128, deserialize_u128 + num_self!(u128:visit_u128); + num_as_self!(u8:visit_u8 u16:visit_u16 u32:visit_u32 u64:visit_u64); + int_to_uint!(i8:visit_i8 i16:visit_i16 i32:visit_i32 i64:visit_i64); + num_128!(i128:visit_i128); +} + +//////////////////////////////////////////////////////////////////////////////// + +struct CharVisitor; + +impl<'de> Visitor<'de> for CharVisitor { + type Value = char; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("a character") + } + + #[inline] + fn visit_char(self, v: char) -> Result + where + E: Error, + { + Ok(v) + } + + #[inline] + fn visit_str(self, v: &str) -> Result + where + E: Error, + { + let mut iter = v.chars(); + match (iter.next(), iter.next()) { + (Some(c), None) => Ok(c), + _ => Err(Error::invalid_value(Unexpected::Str(v), &self)), + } + } +} + +impl<'de> Deserialize<'de> for char { + #[inline] + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + deserializer.deserialize_char(CharVisitor) + } +} + +//////////////////////////////////////////////////////////////////////////////// + +#[cfg(any(feature = "std", feature = "alloc"))] +struct StringVisitor; +#[cfg(any(feature = "std", feature = "alloc"))] +struct StringInPlaceVisitor<'a>(&'a mut String); + +#[cfg(any(feature = "std", feature = "alloc"))] +impl<'de> Visitor<'de> for StringVisitor { + type Value = String; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("a string") + } + + fn visit_str(self, v: &str) -> Result + where + E: Error, + { + Ok(v.to_owned()) + } + + fn visit_string(self, v: String) -> Result + where + E: Error, + { + Ok(v) + } + + fn visit_bytes(self, v: &[u8]) -> Result + where + E: Error, + { + match str::from_utf8(v) { + Ok(s) => Ok(s.to_owned()), + Err(_) => Err(Error::invalid_value(Unexpected::Bytes(v), &self)), + } + } + + fn visit_byte_buf(self, v: Vec) -> Result + where + E: Error, + { + match String::from_utf8(v) { + Ok(s) => Ok(s), + Err(e) => Err(Error::invalid_value( + Unexpected::Bytes(&e.into_bytes()), + &self, + )), + } + } +} + +#[cfg(any(feature = "std", feature = "alloc"))] +impl<'a, 'de> Visitor<'de> for StringInPlaceVisitor<'a> { + type Value = (); + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("a string") + } + + fn visit_str(self, v: &str) -> Result + where + E: Error, + { + self.0.clear(); + self.0.push_str(v); + Ok(()) + } + + fn visit_string(self, v: String) -> Result + where + E: Error, + { + *self.0 = v; + Ok(()) + } + + fn visit_bytes(self, v: &[u8]) -> Result + where + E: Error, + { + match str::from_utf8(v) { + Ok(s) => { + self.0.clear(); + self.0.push_str(s); + Ok(()) + } + Err(_) => Err(Error::invalid_value(Unexpected::Bytes(v), &self)), + } + } + + fn visit_byte_buf(self, v: Vec) -> Result + where + E: Error, + { + match String::from_utf8(v) { + Ok(s) => { + *self.0 = s; + Ok(()) + } + Err(e) => Err(Error::invalid_value( + Unexpected::Bytes(&e.into_bytes()), + &self, + )), + } + } +} + +#[cfg(any(feature = "std", feature = "alloc"))] +#[cfg_attr(docsrs, doc(cfg(any(feature = "std", feature = "alloc"))))] +impl<'de> Deserialize<'de> for String { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + deserializer.deserialize_string(StringVisitor) + } + + fn deserialize_in_place(deserializer: D, place: &mut Self) -> Result<(), D::Error> + where + D: Deserializer<'de>, + { + deserializer.deserialize_string(StringInPlaceVisitor(place)) + } +} + +//////////////////////////////////////////////////////////////////////////////// + +struct StrVisitor; + +impl<'a> Visitor<'a> for StrVisitor { + type Value = &'a str; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("a borrowed string") + } + + fn visit_borrowed_str(self, v: &'a str) -> Result + where + E: Error, + { + Ok(v) // so easy + } + + fn visit_borrowed_bytes(self, v: &'a [u8]) -> Result + where + E: Error, + { + str::from_utf8(v).map_err(|_| Error::invalid_value(Unexpected::Bytes(v), &self)) + } +} + +impl<'de: 'a, 'a> Deserialize<'de> for &'a str { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + deserializer.deserialize_str(StrVisitor) + } +} + +//////////////////////////////////////////////////////////////////////////////// + +struct BytesVisitor; + +impl<'a> Visitor<'a> for BytesVisitor { + type Value = &'a [u8]; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("a borrowed byte array") + } + + fn visit_borrowed_bytes(self, v: &'a [u8]) -> Result + where + E: Error, + { + Ok(v) + } + + fn visit_borrowed_str(self, v: &'a str) -> Result + where + E: Error, + { + Ok(v.as_bytes()) + } +} + +impl<'de: 'a, 'a> Deserialize<'de> for &'a [u8] { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + deserializer.deserialize_bytes(BytesVisitor) + } +} + +//////////////////////////////////////////////////////////////////////////////// + +#[cfg(any(feature = "std", all(not(no_core_cstr), feature = "alloc")))] +struct CStringVisitor; + +#[cfg(any(feature = "std", all(not(no_core_cstr), feature = "alloc")))] +impl<'de> Visitor<'de> for CStringVisitor { + type Value = CString; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("byte array") + } + + fn visit_seq(self, mut seq: A) -> Result + where + A: SeqAccess<'de>, + { + let capacity = size_hint::cautious::(seq.size_hint()); + let mut values = Vec::::with_capacity(capacity); + + while let Some(value) = tri!(seq.next_element()) { + values.push(value); + } + + CString::new(values).map_err(Error::custom) + } + + fn visit_bytes(self, v: &[u8]) -> Result + where + E: Error, + { + CString::new(v).map_err(Error::custom) + } + + fn visit_byte_buf(self, v: Vec) -> Result + where + E: Error, + { + CString::new(v).map_err(Error::custom) + } + + fn visit_str(self, v: &str) -> Result + where + E: Error, + { + CString::new(v).map_err(Error::custom) + } + + fn visit_string(self, v: String) -> Result + where + E: Error, + { + CString::new(v).map_err(Error::custom) + } +} + +#[cfg(any(feature = "std", all(not(no_core_cstr), feature = "alloc")))] +#[cfg_attr(docsrs, doc(cfg(any(feature = "std", feature = "alloc"))))] +impl<'de> Deserialize<'de> for CString { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + deserializer.deserialize_byte_buf(CStringVisitor) + } +} + +macro_rules! forwarded_impl { + ( + $(#[$attr:meta])* + ($($id:ident),*), $ty:ty, $func:expr + ) => { + $(#[$attr])* + impl<'de $(, $id : Deserialize<'de>,)*> Deserialize<'de> for $ty { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + Deserialize::deserialize(deserializer).map($func) + } + } + } +} + +forwarded_impl! { + #[cfg(any(feature = "std", all(not(no_core_cstr), feature = "alloc")))] + #[cfg_attr(docsrs, doc(cfg(any(feature = "std", feature = "alloc"))))] + (), Box, CString::into_boxed_c_str +} + +forwarded_impl! { + (T), Reverse, Reverse +} + +//////////////////////////////////////////////////////////////////////////////// + +struct OptionVisitor { + marker: PhantomData, +} + +impl<'de, T> Visitor<'de> for OptionVisitor +where + T: Deserialize<'de>, +{ + type Value = Option; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("option") + } + + #[inline] + fn visit_unit(self) -> Result + where + E: Error, + { + Ok(None) + } + + #[inline] + fn visit_none(self) -> Result + where + E: Error, + { + Ok(None) + } + + #[inline] + fn visit_some(self, deserializer: D) -> Result + where + D: Deserializer<'de>, + { + T::deserialize(deserializer).map(Some) + } + + fn __private_visit_untagged_option(self, deserializer: D) -> Result + where + D: Deserializer<'de>, + { + Ok(T::deserialize(deserializer).ok()) + } +} + +impl<'de, T> Deserialize<'de> for Option +where + T: Deserialize<'de>, +{ + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + deserializer.deserialize_option(OptionVisitor { + marker: PhantomData, + }) + } + + // The Some variant's repr is opaque, so we can't play cute tricks with its + // tag to have deserialize_in_place build the content in place unconditionally. + // + // FIXME: investigate whether branching on the old value being Some to + // deserialize_in_place the value is profitable (probably data-dependent?) +} + +//////////////////////////////////////////////////////////////////////////////// + +struct PhantomDataVisitor { + marker: PhantomData, +} + +impl<'de, T> Visitor<'de> for PhantomDataVisitor +where + T: ?Sized, +{ + type Value = PhantomData; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("unit") + } + + #[inline] + fn visit_unit(self) -> Result + where + E: Error, + { + Ok(PhantomData) + } +} + +impl<'de, T> Deserialize<'de> for PhantomData +where + T: ?Sized, +{ + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + let visitor = PhantomDataVisitor { + marker: PhantomData, + }; + deserializer.deserialize_unit_struct("PhantomData", visitor) + } +} + +//////////////////////////////////////////////////////////////////////////////// + +macro_rules! seq_impl { + ( + $(#[$attr:meta])* + $ty:ident , + $access:ident, + $clear:expr, + $with_capacity:expr, + $reserve:expr, + $insert:expr + ) => { + $(#[$attr])* + impl<'de, T $(, $typaram)*> Deserialize<'de> for $ty + where + T: Deserialize<'de> $(+ $tbound1 $(+ $tbound2)*)*, + $($typaram: $bound1 $(+ $bound2)*,)* + { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + struct SeqVisitor { + marker: PhantomData<$ty>, + } + + impl<'de, T $(, $typaram)*> Visitor<'de> for SeqVisitor + where + T: Deserialize<'de> $(+ $tbound1 $(+ $tbound2)*)*, + $($typaram: $bound1 $(+ $bound2)*,)* + { + type Value = $ty; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("a sequence") + } + + #[inline] + fn visit_seq(self, mut $access: A) -> Result + where + A: SeqAccess<'de>, + { + let mut values = $with_capacity; + + while let Some(value) = tri!($access.next_element()) { + $insert(&mut values, value); + } + + Ok(values) + } + } + + let visitor = SeqVisitor { marker: PhantomData }; + deserializer.deserialize_seq(visitor) + } + + fn deserialize_in_place(deserializer: D, place: &mut Self) -> Result<(), D::Error> + where + D: Deserializer<'de>, + { + struct SeqInPlaceVisitor<'a, T: 'a $(, $typaram: 'a)*>(&'a mut $ty); + + impl<'a, 'de, T $(, $typaram)*> Visitor<'de> for SeqInPlaceVisitor<'a, T $(, $typaram)*> + where + T: Deserialize<'de> $(+ $tbound1 $(+ $tbound2)*)*, + $($typaram: $bound1 $(+ $bound2)*,)* + { + type Value = (); + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("a sequence") + } + + #[inline] + fn visit_seq(mut self, mut $access: A) -> Result + where + A: SeqAccess<'de>, + { + $clear(&mut self.0); + $reserve(&mut self.0, size_hint::cautious::($access.size_hint())); + + // FIXME: try to overwrite old values here? (Vec, VecDeque, LinkedList) + while let Some(value) = tri!($access.next_element()) { + $insert(&mut self.0, value); + } + + Ok(()) + } + } + + deserializer.deserialize_seq(SeqInPlaceVisitor(place)) + } + } + } +} + +// Dummy impl of reserve +#[cfg(any(feature = "std", feature = "alloc"))] +fn nop_reserve(_seq: T, _n: usize) {} + +seq_impl!( + #[cfg(any(feature = "std", feature = "alloc"))] + #[cfg_attr(docsrs, doc(cfg(any(feature = "std", feature = "alloc"))))] + BinaryHeap, + seq, + BinaryHeap::clear, + BinaryHeap::with_capacity(size_hint::cautious::(seq.size_hint())), + BinaryHeap::reserve, + BinaryHeap::push +); + +seq_impl!( + #[cfg(any(feature = "std", feature = "alloc"))] + #[cfg_attr(docsrs, doc(cfg(any(feature = "std", feature = "alloc"))))] + BTreeSet, + seq, + BTreeSet::clear, + BTreeSet::new(), + nop_reserve, + BTreeSet::insert +); + +seq_impl!( + #[cfg(any(feature = "std", feature = "alloc"))] + #[cfg_attr(docsrs, doc(cfg(any(feature = "std", feature = "alloc"))))] + LinkedList, + seq, + LinkedList::clear, + LinkedList::new(), + nop_reserve, + LinkedList::push_back +); + +seq_impl!( + #[cfg(feature = "std")] + #[cfg_attr(docsrs, doc(cfg(feature = "std")))] + HashSet, + seq, + HashSet::clear, + HashSet::with_capacity_and_hasher(size_hint::cautious::(seq.size_hint()), S::default()), + HashSet::reserve, + HashSet::insert +); + +seq_impl!( + #[cfg(any(feature = "std", feature = "alloc"))] + #[cfg_attr(docsrs, doc(cfg(any(feature = "std", feature = "alloc"))))] + VecDeque, + seq, + VecDeque::clear, + VecDeque::with_capacity(size_hint::cautious::(seq.size_hint())), + VecDeque::reserve, + VecDeque::push_back +); + +//////////////////////////////////////////////////////////////////////////////// + +#[cfg(any(feature = "std", feature = "alloc"))] +#[cfg_attr(docsrs, doc(cfg(any(feature = "std", feature = "alloc"))))] +impl<'de, T> Deserialize<'de> for Vec +where + T: Deserialize<'de>, +{ + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + struct VecVisitor { + marker: PhantomData, + } + + impl<'de, T> Visitor<'de> for VecVisitor + where + T: Deserialize<'de>, + { + type Value = Vec; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("a sequence") + } + + fn visit_seq(self, mut seq: A) -> Result + where + A: SeqAccess<'de>, + { + let capacity = size_hint::cautious::(seq.size_hint()); + let mut values = Vec::::with_capacity(capacity); + + while let Some(value) = tri!(seq.next_element()) { + values.push(value); + } + + Ok(values) + } + } + + let visitor = VecVisitor { + marker: PhantomData, + }; + deserializer.deserialize_seq(visitor) + } + + fn deserialize_in_place(deserializer: D, place: &mut Self) -> Result<(), D::Error> + where + D: Deserializer<'de>, + { + struct VecInPlaceVisitor<'a, T: 'a>(&'a mut Vec); + + impl<'a, 'de, T> Visitor<'de> for VecInPlaceVisitor<'a, T> + where + T: Deserialize<'de>, + { + type Value = (); + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("a sequence") + } + + fn visit_seq(self, mut seq: A) -> Result + where + A: SeqAccess<'de>, + { + let hint = size_hint::cautious::(seq.size_hint()); + if let Some(additional) = hint.checked_sub(self.0.len()) { + self.0.reserve(additional); + } + + for i in 0..self.0.len() { + let next = { + let next_place = InPlaceSeed(&mut self.0[i]); + tri!(seq.next_element_seed(next_place)) + }; + if next.is_none() { + self.0.truncate(i); + return Ok(()); + } + } + + while let Some(value) = tri!(seq.next_element()) { + self.0.push(value); + } + + Ok(()) + } + } + + deserializer.deserialize_seq(VecInPlaceVisitor(place)) + } +} + +//////////////////////////////////////////////////////////////////////////////// + +struct ArrayVisitor { + marker: PhantomData, +} +struct ArrayInPlaceVisitor<'a, A: 'a>(&'a mut A); + +impl ArrayVisitor { + fn new() -> Self { + ArrayVisitor { + marker: PhantomData, + } + } +} + +impl<'de, T> Visitor<'de> for ArrayVisitor<[T; 0]> { + type Value = [T; 0]; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("an empty array") + } + + #[inline] + fn visit_seq(self, _: A) -> Result + where + A: SeqAccess<'de>, + { + Ok([]) + } +} + +// Does not require T: Deserialize<'de>. +impl<'de, T> Deserialize<'de> for [T; 0] { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + deserializer.deserialize_tuple(0, ArrayVisitor::<[T; 0]>::new()) + } +} + +macro_rules! array_impls { + ($($len:expr => ($($n:tt)+))+) => { + $( + impl<'de, T> Visitor<'de> for ArrayVisitor<[T; $len]> + where + T: Deserialize<'de>, + { + type Value = [T; $len]; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str(concat!("an array of length ", $len)) + } + + #[inline] + fn visit_seq(self, mut seq: A) -> Result + where + A: SeqAccess<'de>, + { + Ok([$( + match tri!(seq.next_element()) { + Some(val) => val, + None => return Err(Error::invalid_length($n, &self)), + } + ),+]) + } + } + + impl<'a, 'de, T> Visitor<'de> for ArrayInPlaceVisitor<'a, [T; $len]> + where + T: Deserialize<'de>, + { + type Value = (); + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str(concat!("an array of length ", $len)) + } + + #[inline] + fn visit_seq(self, mut seq: A) -> Result + where + A: SeqAccess<'de>, + { + let mut fail_idx = None; + for (idx, dest) in self.0[..].iter_mut().enumerate() { + if tri!(seq.next_element_seed(InPlaceSeed(dest))).is_none() { + fail_idx = Some(idx); + break; + } + } + if let Some(idx) = fail_idx { + return Err(Error::invalid_length(idx, &self)); + } + Ok(()) + } + } + + impl<'de, T> Deserialize<'de> for [T; $len] + where + T: Deserialize<'de>, + { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + deserializer.deserialize_tuple($len, ArrayVisitor::<[T; $len]>::new()) + } + + fn deserialize_in_place(deserializer: D, place: &mut Self) -> Result<(), D::Error> + where + D: Deserializer<'de>, + { + deserializer.deserialize_tuple($len, ArrayInPlaceVisitor(place)) + } + } + )+ + } +} + +array_impls! { + 1 => (0) + 2 => (0 1) + 3 => (0 1 2) + 4 => (0 1 2 3) + 5 => (0 1 2 3 4) + 6 => (0 1 2 3 4 5) + 7 => (0 1 2 3 4 5 6) + 8 => (0 1 2 3 4 5 6 7) + 9 => (0 1 2 3 4 5 6 7 8) + 10 => (0 1 2 3 4 5 6 7 8 9) + 11 => (0 1 2 3 4 5 6 7 8 9 10) + 12 => (0 1 2 3 4 5 6 7 8 9 10 11) + 13 => (0 1 2 3 4 5 6 7 8 9 10 11 12) + 14 => (0 1 2 3 4 5 6 7 8 9 10 11 12 13) + 15 => (0 1 2 3 4 5 6 7 8 9 10 11 12 13 14) + 16 => (0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15) + 17 => (0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16) + 18 => (0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17) + 19 => (0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18) + 20 => (0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19) + 21 => (0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20) + 22 => (0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21) + 23 => (0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22) + 24 => (0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23) + 25 => (0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24) + 26 => (0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25) + 27 => (0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26) + 28 => (0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27) + 29 => (0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28) + 30 => (0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29) + 31 => (0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30) + 32 => (0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31) +} + +//////////////////////////////////////////////////////////////////////////////// + +macro_rules! tuple_impls { + ($($len:tt => ($($n:tt $name:ident)+))+) => { + $( + #[cfg_attr(docsrs, doc(hidden))] + impl<'de, $($name),+> Deserialize<'de> for ($($name,)+) + where + $($name: Deserialize<'de>,)+ + { + tuple_impl_body!($len => ($($n $name)+)); + } + )+ + }; +} + +macro_rules! tuple_impl_body { + ($len:tt => ($($n:tt $name:ident)+)) => { + #[inline] + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + struct TupleVisitor<$($name,)+> { + marker: PhantomData<($($name,)+)>, + } + + impl<'de, $($name: Deserialize<'de>),+> Visitor<'de> for TupleVisitor<$($name,)+> { + type Value = ($($name,)+); + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str(concat!("a tuple of size ", $len)) + } + + #[inline] + #[allow(non_snake_case)] + fn visit_seq(self, mut seq: A) -> Result + where + A: SeqAccess<'de>, + { + $( + let $name = match tri!(seq.next_element()) { + Some(value) => value, + None => return Err(Error::invalid_length($n, &self)), + }; + )+ + + Ok(($($name,)+)) + } + } + + deserializer.deserialize_tuple($len, TupleVisitor { marker: PhantomData }) + } + + #[inline] + fn deserialize_in_place(deserializer: D, place: &mut Self) -> Result<(), D::Error> + where + D: Deserializer<'de>, + { + struct TupleInPlaceVisitor<'a, $($name: 'a,)+>(&'a mut ($($name,)+)); + + impl<'a, 'de, $($name: Deserialize<'de>),+> Visitor<'de> for TupleInPlaceVisitor<'a, $($name,)+> { + type Value = (); + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str(concat!("a tuple of size ", $len)) + } + + #[inline] + #[allow(non_snake_case)] + fn visit_seq(self, mut seq: A) -> Result + where + A: SeqAccess<'de>, + { + $( + if tri!(seq.next_element_seed(InPlaceSeed(&mut (self.0).$n))).is_none() { + return Err(Error::invalid_length($n, &self)); + } + )+ + + Ok(()) + } + } + + deserializer.deserialize_tuple($len, TupleInPlaceVisitor(place)) + } + }; +} + +#[cfg_attr(docsrs, doc(fake_variadic))] +#[cfg_attr( + docsrs, + doc = "This trait is implemented for tuples up to 16 items long." +)] +impl<'de, T> Deserialize<'de> for (T,) +where + T: Deserialize<'de>, +{ + tuple_impl_body!(1 => (0 T)); +} + +tuple_impls! { + 2 => (0 T0 1 T1) + 3 => (0 T0 1 T1 2 T2) + 4 => (0 T0 1 T1 2 T2 3 T3) + 5 => (0 T0 1 T1 2 T2 3 T3 4 T4) + 6 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5) + 7 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6) + 8 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7) + 9 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8) + 10 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9) + 11 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10) + 12 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10 11 T11) + 13 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10 11 T11 12 T12) + 14 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10 11 T11 12 T12 13 T13) + 15 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10 11 T11 12 T12 13 T13 14 T14) + 16 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10 11 T11 12 T12 13 T13 14 T14 15 T15) +} + +//////////////////////////////////////////////////////////////////////////////// + +macro_rules! map_impl { + ( + $(#[$attr:meta])* + $ty:ident , + $access:ident, + $with_capacity:expr, + ) => { + $(#[$attr])* + impl<'de, K, V $(, $typaram)*> Deserialize<'de> for $ty + where + K: Deserialize<'de> $(+ $kbound1 $(+ $kbound2)*)*, + V: Deserialize<'de>, + $($typaram: $bound1 $(+ $bound2)*),* + { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + struct MapVisitor { + marker: PhantomData<$ty>, + } + + impl<'de, K, V $(, $typaram)*> Visitor<'de> for MapVisitor + where + K: Deserialize<'de> $(+ $kbound1 $(+ $kbound2)*)*, + V: Deserialize<'de>, + $($typaram: $bound1 $(+ $bound2)*),* + { + type Value = $ty; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("a map") + } + + #[inline] + fn visit_map(self, mut $access: A) -> Result + where + A: MapAccess<'de>, + { + let mut values = $with_capacity; + + while let Some((key, value)) = tri!($access.next_entry()) { + values.insert(key, value); + } + + Ok(values) + } + } + + let visitor = MapVisitor { marker: PhantomData }; + deserializer.deserialize_map(visitor) + } + } + } +} + +map_impl! { + #[cfg(any(feature = "std", feature = "alloc"))] + #[cfg_attr(docsrs, doc(cfg(any(feature = "std", feature = "alloc"))))] + BTreeMap, + map, + BTreeMap::new(), +} + +map_impl! { + #[cfg(feature = "std")] + #[cfg_attr(docsrs, doc(cfg(feature = "std")))] + HashMap, + map, + HashMap::with_capacity_and_hasher(size_hint::cautious::<(K, V)>(map.size_hint()), S::default()), +} + +//////////////////////////////////////////////////////////////////////////////// + +#[cfg(any(feature = "std", not(no_core_net)))] +macro_rules! parse_ip_impl { + ($ty:ty, $expecting:expr, $size:tt) => { + impl<'de> Deserialize<'de> for $ty { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + if deserializer.is_human_readable() { + deserializer.deserialize_str(FromStrVisitor::new($expecting)) + } else { + <[u8; $size]>::deserialize(deserializer).map(<$ty>::from) + } + } + } + }; +} + +#[cfg(any(feature = "std", not(no_core_net)))] +macro_rules! variant_identifier { + ( + $name_kind:ident ($($variant:ident; $bytes:expr; $index:expr),*) + $expecting_message:expr, + $variants_name:ident + ) => { + enum $name_kind { + $($variant),* + } + + static $variants_name: &[&str] = &[$(stringify!($variant)),*]; + + impl<'de> Deserialize<'de> for $name_kind { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + struct KindVisitor; + + impl<'de> Visitor<'de> for KindVisitor { + type Value = $name_kind; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str($expecting_message) + } + + fn visit_u64(self, value: u64) -> Result + where + E: Error, + { + match value { + $( + $index => Ok($name_kind :: $variant), + )* + _ => Err(Error::invalid_value(Unexpected::Unsigned(value), &self),), + } + } + + fn visit_str(self, value: &str) -> Result + where + E: Error, + { + match value { + $( + stringify!($variant) => Ok($name_kind :: $variant), + )* + _ => Err(Error::unknown_variant(value, $variants_name)), + } + } + + fn visit_bytes(self, value: &[u8]) -> Result + where + E: Error, + { + match value { + $( + $bytes => Ok($name_kind :: $variant), + )* + _ => { + match str::from_utf8(value) { + Ok(value) => Err(Error::unknown_variant(value, $variants_name)), + Err(_) => Err(Error::invalid_value(Unexpected::Bytes(value), &self)), + } + } + } + } + } + + deserializer.deserialize_identifier(KindVisitor) + } + } + } +} + +#[cfg(any(feature = "std", not(no_core_net)))] +macro_rules! deserialize_enum { + ( + $name:ident $name_kind:ident ($($variant:ident; $bytes:expr; $index:expr),*) + $expecting_message:expr, + $deserializer:expr + ) => { + variant_identifier! { + $name_kind ($($variant; $bytes; $index),*) + $expecting_message, + VARIANTS + } + + struct EnumVisitor; + impl<'de> Visitor<'de> for EnumVisitor { + type Value = $name; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str(concat!("a ", stringify!($name))) + } + + + fn visit_enum(self, data: A) -> Result + where + A: EnumAccess<'de>, + { + match tri!(data.variant()) { + $( + ($name_kind :: $variant, v) => v.newtype_variant().map($name :: $variant), + )* + } + } + } + $deserializer.deserialize_enum(stringify!($name), VARIANTS, EnumVisitor) + } +} + +#[cfg(any(feature = "std", not(no_core_net)))] +impl<'de> Deserialize<'de> for net::IpAddr { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + if deserializer.is_human_readable() { + deserializer.deserialize_str(FromStrVisitor::new("IP address")) + } else { + use crate::lib::net::IpAddr; + deserialize_enum! { + IpAddr IpAddrKind (V4; b"V4"; 0, V6; b"V6"; 1) + "`V4` or `V6`", + deserializer + } + } + } +} + +#[cfg(any(feature = "std", not(no_core_net)))] +parse_ip_impl!(net::Ipv4Addr, "IPv4 address", 4); + +#[cfg(any(feature = "std", not(no_core_net)))] +parse_ip_impl!(net::Ipv6Addr, "IPv6 address", 16); + +#[cfg(any(feature = "std", not(no_core_net)))] +macro_rules! parse_socket_impl { + ( + $ty:ty, $expecting:tt, + $new:expr, + ) => { + impl<'de> Deserialize<'de> for $ty { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + if deserializer.is_human_readable() { + deserializer.deserialize_str(FromStrVisitor::new($expecting)) + } else { + <(_, u16)>::deserialize(deserializer).map($new) + } + } + } + }; +} + +#[cfg(any(feature = "std", not(no_core_net)))] +impl<'de> Deserialize<'de> for net::SocketAddr { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + if deserializer.is_human_readable() { + deserializer.deserialize_str(FromStrVisitor::new("socket address")) + } else { + use crate::lib::net::SocketAddr; + deserialize_enum! { + SocketAddr SocketAddrKind (V4; b"V4"; 0, V6; b"V6"; 1) + "`V4` or `V6`", + deserializer + } + } + } +} + +#[cfg(any(feature = "std", not(no_core_net)))] +parse_socket_impl! { + net::SocketAddrV4, "IPv4 socket address", + |(ip, port)| net::SocketAddrV4::new(ip, port), +} + +#[cfg(any(feature = "std", not(no_core_net)))] +parse_socket_impl! { + net::SocketAddrV6, "IPv6 socket address", + |(ip, port)| net::SocketAddrV6::new(ip, port, 0, 0), +} + +//////////////////////////////////////////////////////////////////////////////// + +#[cfg(feature = "std")] +struct PathVisitor; + +#[cfg(feature = "std")] +impl<'a> Visitor<'a> for PathVisitor { + type Value = &'a Path; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("a borrowed path") + } + + fn visit_borrowed_str(self, v: &'a str) -> Result + where + E: Error, + { + Ok(v.as_ref()) + } + + fn visit_borrowed_bytes(self, v: &'a [u8]) -> Result + where + E: Error, + { + str::from_utf8(v) + .map(AsRef::as_ref) + .map_err(|_| Error::invalid_value(Unexpected::Bytes(v), &self)) + } +} + +#[cfg(feature = "std")] +#[cfg_attr(docsrs, doc(cfg(feature = "std")))] +impl<'de: 'a, 'a> Deserialize<'de> for &'a Path { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + deserializer.deserialize_str(PathVisitor) + } +} + +#[cfg(feature = "std")] +struct PathBufVisitor; + +#[cfg(feature = "std")] +impl<'de> Visitor<'de> for PathBufVisitor { + type Value = PathBuf; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("path string") + } + + fn visit_str(self, v: &str) -> Result + where + E: Error, + { + Ok(From::from(v)) + } + + fn visit_string(self, v: String) -> Result + where + E: Error, + { + Ok(From::from(v)) + } + + fn visit_bytes(self, v: &[u8]) -> Result + where + E: Error, + { + str::from_utf8(v) + .map(From::from) + .map_err(|_| Error::invalid_value(Unexpected::Bytes(v), &self)) + } + + fn visit_byte_buf(self, v: Vec) -> Result + where + E: Error, + { + String::from_utf8(v) + .map(From::from) + .map_err(|e| Error::invalid_value(Unexpected::Bytes(&e.into_bytes()), &self)) + } +} + +#[cfg(feature = "std")] +#[cfg_attr(docsrs, doc(cfg(feature = "std")))] +impl<'de> Deserialize<'de> for PathBuf { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + deserializer.deserialize_string(PathBufVisitor) + } +} + +forwarded_impl! { + #[cfg(feature = "std")] + #[cfg_attr(docsrs, doc(cfg(feature = "std")))] + (), Box, PathBuf::into_boxed_path +} + +//////////////////////////////////////////////////////////////////////////////// + +// If this were outside of the serde crate, it would just use: +// +// #[derive(Deserialize)] +// #[serde(variant_identifier)] +#[cfg(all(feature = "std", any(unix, windows)))] +variant_identifier! { + OsStringKind (Unix; b"Unix"; 0, Windows; b"Windows"; 1) + "`Unix` or `Windows`", + OSSTR_VARIANTS +} + +#[cfg(all(feature = "std", any(unix, windows)))] +struct OsStringVisitor; + +#[cfg(all(feature = "std", any(unix, windows)))] +impl<'de> Visitor<'de> for OsStringVisitor { + type Value = OsString; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("os string") + } + + #[cfg(unix)] + fn visit_enum(self, data: A) -> Result + where + A: EnumAccess<'de>, + { + use std::os::unix::ffi::OsStringExt; + + match tri!(data.variant()) { + (OsStringKind::Unix, v) => v.newtype_variant().map(OsString::from_vec), + (OsStringKind::Windows, _) => Err(Error::custom( + "cannot deserialize Windows OS string on Unix", + )), + } + } + + #[cfg(windows)] + fn visit_enum(self, data: A) -> Result + where + A: EnumAccess<'de>, + { + use std::os::windows::ffi::OsStringExt; + + match tri!(data.variant()) { + (OsStringKind::Windows, v) => v + .newtype_variant::>() + .map(|vec| OsString::from_wide(&vec)), + (OsStringKind::Unix, _) => Err(Error::custom( + "cannot deserialize Unix OS string on Windows", + )), + } + } +} + +#[cfg(all(feature = "std", any(unix, windows)))] +#[cfg_attr(docsrs, doc(cfg(all(feature = "std", any(unix, windows)))))] +impl<'de> Deserialize<'de> for OsString { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + deserializer.deserialize_enum("OsString", OSSTR_VARIANTS, OsStringVisitor) + } +} + +//////////////////////////////////////////////////////////////////////////////// + +forwarded_impl! { + #[cfg(any(feature = "std", feature = "alloc"))] + #[cfg_attr(docsrs, doc(cfg(any(feature = "std", feature = "alloc"))))] + (T), Box, Box::new +} + +forwarded_impl! { + #[cfg(any(feature = "std", feature = "alloc"))] + #[cfg_attr(docsrs, doc(cfg(any(feature = "std", feature = "alloc"))))] + (T), Box<[T]>, Vec::into_boxed_slice +} + +forwarded_impl! { + #[cfg(any(feature = "std", feature = "alloc"))] + #[cfg_attr(docsrs, doc(cfg(any(feature = "std", feature = "alloc"))))] + (), Box, String::into_boxed_str +} + +forwarded_impl! { + #[cfg(all(feature = "std", any(unix, windows)))] + #[cfg_attr(docsrs, doc(cfg(all(feature = "std", any(unix, windows)))))] + (), Box, OsString::into_boxed_os_str +} + +#[cfg(any(feature = "std", feature = "alloc"))] +#[cfg_attr(docsrs, doc(cfg(any(feature = "std", feature = "alloc"))))] +impl<'de, 'a, T> Deserialize<'de> for Cow<'a, T> +where + T: ?Sized + ToOwned, + T::Owned: Deserialize<'de>, +{ + #[inline] + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + T::Owned::deserialize(deserializer).map(Cow::Owned) + } +} + +//////////////////////////////////////////////////////////////////////////////// + +/// This impl requires the [`"rc"`] Cargo feature of Serde. The resulting +/// `Weak` has a reference count of 0 and cannot be upgraded. +/// +/// [`"rc"`]: https://serde.rs/feature-flags.html#-features-rc +#[cfg(all(feature = "rc", any(feature = "std", feature = "alloc")))] +#[cfg_attr( + docsrs, + doc(cfg(all(feature = "rc", any(feature = "std", feature = "alloc")))) +)] +impl<'de, T> Deserialize<'de> for RcWeak +where + T: Deserialize<'de>, +{ + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + tri!(Option::::deserialize(deserializer)); + Ok(RcWeak::new()) + } +} + +/// This impl requires the [`"rc"`] Cargo feature of Serde. The resulting +/// `Weak` has a reference count of 0 and cannot be upgraded. +/// +/// [`"rc"`]: https://serde.rs/feature-flags.html#-features-rc +#[cfg(all(feature = "rc", any(feature = "std", feature = "alloc")))] +#[cfg_attr( + docsrs, + doc(cfg(all(feature = "rc", any(feature = "std", feature = "alloc")))) +)] +impl<'de, T> Deserialize<'de> for ArcWeak +where + T: Deserialize<'de>, +{ + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + tri!(Option::::deserialize(deserializer)); + Ok(ArcWeak::new()) + } +} + +//////////////////////////////////////////////////////////////////////////////// + +macro_rules! box_forwarded_impl { + ( + $(#[$attr:meta])* + $t:ident + ) => { + $(#[$attr])* + impl<'de, T> Deserialize<'de> for $t + where + T: ?Sized, + Box: Deserialize<'de>, + { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + Box::deserialize(deserializer).map(Into::into) + } + } + }; +} + +box_forwarded_impl! { + /// This impl requires the [`"rc"`] Cargo feature of Serde. + /// + /// Deserializing a data structure containing `Rc` will not attempt to + /// deduplicate `Rc` references to the same data. Every deserialized `Rc` + /// will end up with a strong count of 1. + /// + /// [`"rc"`]: https://serde.rs/feature-flags.html#-features-rc + #[cfg(all(feature = "rc", any(feature = "std", feature = "alloc")))] + #[cfg_attr(docsrs, doc(cfg(all(feature = "rc", any(feature = "std", feature = "alloc")))))] + Rc +} + +box_forwarded_impl! { + /// This impl requires the [`"rc"`] Cargo feature of Serde. + /// + /// Deserializing a data structure containing `Arc` will not attempt to + /// deduplicate `Arc` references to the same data. Every deserialized `Arc` + /// will end up with a strong count of 1. + /// + /// [`"rc"`]: https://serde.rs/feature-flags.html#-features-rc + #[cfg(all(feature = "rc", any(feature = "std", feature = "alloc")))] + #[cfg_attr(docsrs, doc(cfg(all(feature = "rc", any(feature = "std", feature = "alloc")))))] + Arc +} + +//////////////////////////////////////////////////////////////////////////////// + +impl<'de, T> Deserialize<'de> for Cell +where + T: Deserialize<'de> + Copy, +{ + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + T::deserialize(deserializer).map(Cell::new) + } +} + +forwarded_impl! { + (T), RefCell, RefCell::new +} + +forwarded_impl! { + #[cfg(feature = "std")] + #[cfg_attr(docsrs, doc(cfg(feature = "std")))] + (T), Mutex, Mutex::new +} + +forwarded_impl! { + #[cfg(feature = "std")] + #[cfg_attr(docsrs, doc(cfg(feature = "std")))] + (T), RwLock, RwLock::new +} + +//////////////////////////////////////////////////////////////////////////////// + +// This is a cleaned-up version of the impl generated by: +// +// #[derive(Deserialize)] +// #[serde(deny_unknown_fields)] +// struct Duration { +// secs: u64, +// nanos: u32, +// } +impl<'de> Deserialize<'de> for Duration { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + // If this were outside of the serde crate, it would just use: + // + // #[derive(Deserialize)] + // #[serde(field_identifier, rename_all = "lowercase")] + enum Field { + Secs, + Nanos, + } + + impl<'de> Deserialize<'de> for Field { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + struct FieldVisitor; + + impl<'de> Visitor<'de> for FieldVisitor { + type Value = Field; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("`secs` or `nanos`") + } + + fn visit_str(self, value: &str) -> Result + where + E: Error, + { + match value { + "secs" => Ok(Field::Secs), + "nanos" => Ok(Field::Nanos), + _ => Err(Error::unknown_field(value, FIELDS)), + } + } + + fn visit_bytes(self, value: &[u8]) -> Result + where + E: Error, + { + match value { + b"secs" => Ok(Field::Secs), + b"nanos" => Ok(Field::Nanos), + _ => { + let value = crate::__private::from_utf8_lossy(value); + Err(Error::unknown_field(&*value, FIELDS)) + } + } + } + } + + deserializer.deserialize_identifier(FieldVisitor) + } + } + + fn check_overflow(secs: u64, nanos: u32) -> Result<(), E> + where + E: Error, + { + static NANOS_PER_SEC: u32 = 1_000_000_000; + match secs.checked_add((nanos / NANOS_PER_SEC) as u64) { + Some(_) => Ok(()), + None => Err(E::custom("overflow deserializing Duration")), + } + } + + struct DurationVisitor; + + impl<'de> Visitor<'de> for DurationVisitor { + type Value = Duration; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("struct Duration") + } + + fn visit_seq(self, mut seq: A) -> Result + where + A: SeqAccess<'de>, + { + let secs: u64 = match tri!(seq.next_element()) { + Some(value) => value, + None => { + return Err(Error::invalid_length(0, &self)); + } + }; + let nanos: u32 = match tri!(seq.next_element()) { + Some(value) => value, + None => { + return Err(Error::invalid_length(1, &self)); + } + }; + tri!(check_overflow(secs, nanos)); + Ok(Duration::new(secs, nanos)) + } + + fn visit_map(self, mut map: A) -> Result + where + A: MapAccess<'de>, + { + let mut secs: Option = None; + let mut nanos: Option = None; + while let Some(key) = tri!(map.next_key()) { + match key { + Field::Secs => { + if secs.is_some() { + return Err(::duplicate_field("secs")); + } + secs = Some(tri!(map.next_value())); + } + Field::Nanos => { + if nanos.is_some() { + return Err(::duplicate_field("nanos")); + } + nanos = Some(tri!(map.next_value())); + } + } + } + let secs = match secs { + Some(secs) => secs, + None => return Err(::missing_field("secs")), + }; + let nanos = match nanos { + Some(nanos) => nanos, + None => return Err(::missing_field("nanos")), + }; + tri!(check_overflow(secs, nanos)); + Ok(Duration::new(secs, nanos)) + } + } + + const FIELDS: &[&str] = &["secs", "nanos"]; + deserializer.deserialize_struct("Duration", FIELDS, DurationVisitor) + } +} + +//////////////////////////////////////////////////////////////////////////////// + +#[cfg(feature = "std")] +#[cfg_attr(docsrs, doc(cfg(feature = "std")))] +impl<'de> Deserialize<'de> for SystemTime { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + // Reuse duration + enum Field { + Secs, + Nanos, + } + + impl<'de> Deserialize<'de> for Field { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + struct FieldVisitor; + + impl<'de> Visitor<'de> for FieldVisitor { + type Value = Field; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("`secs_since_epoch` or `nanos_since_epoch`") + } + + fn visit_str(self, value: &str) -> Result + where + E: Error, + { + match value { + "secs_since_epoch" => Ok(Field::Secs), + "nanos_since_epoch" => Ok(Field::Nanos), + _ => Err(Error::unknown_field(value, FIELDS)), + } + } + + fn visit_bytes(self, value: &[u8]) -> Result + where + E: Error, + { + match value { + b"secs_since_epoch" => Ok(Field::Secs), + b"nanos_since_epoch" => Ok(Field::Nanos), + _ => { + let value = String::from_utf8_lossy(value); + Err(Error::unknown_field(&value, FIELDS)) + } + } + } + } + + deserializer.deserialize_identifier(FieldVisitor) + } + } + + fn check_overflow(secs: u64, nanos: u32) -> Result<(), E> + where + E: Error, + { + static NANOS_PER_SEC: u32 = 1_000_000_000; + match secs.checked_add((nanos / NANOS_PER_SEC) as u64) { + Some(_) => Ok(()), + None => Err(E::custom("overflow deserializing SystemTime epoch offset")), + } + } + + struct DurationVisitor; + + impl<'de> Visitor<'de> for DurationVisitor { + type Value = Duration; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("struct SystemTime") + } + + fn visit_seq(self, mut seq: A) -> Result + where + A: SeqAccess<'de>, + { + let secs: u64 = match tri!(seq.next_element()) { + Some(value) => value, + None => { + return Err(Error::invalid_length(0, &self)); + } + }; + let nanos: u32 = match tri!(seq.next_element()) { + Some(value) => value, + None => { + return Err(Error::invalid_length(1, &self)); + } + }; + tri!(check_overflow(secs, nanos)); + Ok(Duration::new(secs, nanos)) + } + + fn visit_map(self, mut map: A) -> Result + where + A: MapAccess<'de>, + { + let mut secs: Option = None; + let mut nanos: Option = None; + while let Some(key) = tri!(map.next_key()) { + match key { + Field::Secs => { + if secs.is_some() { + return Err(::duplicate_field( + "secs_since_epoch", + )); + } + secs = Some(tri!(map.next_value())); + } + Field::Nanos => { + if nanos.is_some() { + return Err(::duplicate_field( + "nanos_since_epoch", + )); + } + nanos = Some(tri!(map.next_value())); + } + } + } + let secs = match secs { + Some(secs) => secs, + None => return Err(::missing_field("secs_since_epoch")), + }; + let nanos = match nanos { + Some(nanos) => nanos, + None => return Err(::missing_field("nanos_since_epoch")), + }; + tri!(check_overflow(secs, nanos)); + Ok(Duration::new(secs, nanos)) + } + } + + const FIELDS: &[&str] = &["secs_since_epoch", "nanos_since_epoch"]; + let duration = tri!(deserializer.deserialize_struct("SystemTime", FIELDS, DurationVisitor)); + #[cfg(not(no_systemtime_checked_add))] + let ret = UNIX_EPOCH + .checked_add(duration) + .ok_or_else(|| D::Error::custom("overflow deserializing SystemTime")); + #[cfg(no_systemtime_checked_add)] + let ret = Ok(UNIX_EPOCH + duration); + ret + } +} + +//////////////////////////////////////////////////////////////////////////////// + +// Similar to: +// +// #[derive(Deserialize)] +// #[serde(deny_unknown_fields)] +// struct Range { +// start: Idx, +// end: Idx, +// } +impl<'de, Idx> Deserialize<'de> for Range +where + Idx: Deserialize<'de>, +{ + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + let (start, end) = tri!(deserializer.deserialize_struct( + "Range", + range::FIELDS, + range::RangeVisitor { + expecting: "struct Range", + phantom: PhantomData, + }, + )); + Ok(start..end) + } +} + +impl<'de, Idx> Deserialize<'de> for RangeInclusive +where + Idx: Deserialize<'de>, +{ + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + let (start, end) = tri!(deserializer.deserialize_struct( + "RangeInclusive", + range::FIELDS, + range::RangeVisitor { + expecting: "struct RangeInclusive", + phantom: PhantomData, + }, + )); + Ok(RangeInclusive::new(start, end)) + } +} + +mod range { + use crate::lib::*; + + use crate::de::{Deserialize, Deserializer, Error, MapAccess, SeqAccess, Visitor}; + + pub const FIELDS: &[&str] = &["start", "end"]; + + // If this were outside of the serde crate, it would just use: + // + // #[derive(Deserialize)] + // #[serde(field_identifier, rename_all = "lowercase")] + enum Field { + Start, + End, + } + + impl<'de> Deserialize<'de> for Field { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + struct FieldVisitor; + + impl<'de> Visitor<'de> for FieldVisitor { + type Value = Field; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("`start` or `end`") + } + + fn visit_str(self, value: &str) -> Result + where + E: Error, + { + match value { + "start" => Ok(Field::Start), + "end" => Ok(Field::End), + _ => Err(Error::unknown_field(value, FIELDS)), + } + } + + fn visit_bytes(self, value: &[u8]) -> Result + where + E: Error, + { + match value { + b"start" => Ok(Field::Start), + b"end" => Ok(Field::End), + _ => { + let value = crate::__private::from_utf8_lossy(value); + Err(Error::unknown_field(&*value, FIELDS)) + } + } + } + } + + deserializer.deserialize_identifier(FieldVisitor) + } + } + + pub struct RangeVisitor { + pub expecting: &'static str, + pub phantom: PhantomData, + } + + impl<'de, Idx> Visitor<'de> for RangeVisitor + where + Idx: Deserialize<'de>, + { + type Value = (Idx, Idx); + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str(self.expecting) + } + + fn visit_seq(self, mut seq: A) -> Result + where + A: SeqAccess<'de>, + { + let start: Idx = match tri!(seq.next_element()) { + Some(value) => value, + None => { + return Err(Error::invalid_length(0, &self)); + } + }; + let end: Idx = match tri!(seq.next_element()) { + Some(value) => value, + None => { + return Err(Error::invalid_length(1, &self)); + } + }; + Ok((start, end)) + } + + fn visit_map(self, mut map: A) -> Result + where + A: MapAccess<'de>, + { + let mut start: Option = None; + let mut end: Option = None; + while let Some(key) = tri!(map.next_key()) { + match key { + Field::Start => { + if start.is_some() { + return Err(::duplicate_field("start")); + } + start = Some(tri!(map.next_value())); + } + Field::End => { + if end.is_some() { + return Err(::duplicate_field("end")); + } + end = Some(tri!(map.next_value())); + } + } + } + let start = match start { + Some(start) => start, + None => return Err(::missing_field("start")), + }; + let end = match end { + Some(end) => end, + None => return Err(::missing_field("end")), + }; + Ok((start, end)) + } + } +} + +//////////////////////////////////////////////////////////////////////////////// + +// Similar to: +// +// #[derive(Deserialize)] +// #[serde(deny_unknown_fields)] +// struct RangeFrom { +// start: Idx, +// } +impl<'de, Idx> Deserialize<'de> for RangeFrom +where + Idx: Deserialize<'de>, +{ + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + let start = tri!(deserializer.deserialize_struct( + "RangeFrom", + range_from::FIELDS, + range_from::RangeFromVisitor { + expecting: "struct RangeFrom", + phantom: PhantomData, + }, + )); + Ok(start..) + } +} + +mod range_from { + use crate::lib::*; + + use crate::de::{Deserialize, Deserializer, Error, MapAccess, SeqAccess, Visitor}; + + pub const FIELDS: &[&str] = &["start"]; + + // If this were outside of the serde crate, it would just use: + // + // #[derive(Deserialize)] + // #[serde(field_identifier, rename_all = "lowercase")] + enum Field { + Start, + } + + impl<'de> Deserialize<'de> for Field { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + struct FieldVisitor; + + impl<'de> Visitor<'de> for FieldVisitor { + type Value = Field; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("`start`") + } + + fn visit_str(self, value: &str) -> Result + where + E: Error, + { + match value { + "start" => Ok(Field::Start), + _ => Err(Error::unknown_field(value, FIELDS)), + } + } + + fn visit_bytes(self, value: &[u8]) -> Result + where + E: Error, + { + match value { + b"start" => Ok(Field::Start), + _ => { + let value = crate::__private::from_utf8_lossy(value); + Err(Error::unknown_field(&*value, FIELDS)) + } + } + } + } + + deserializer.deserialize_identifier(FieldVisitor) + } + } + + pub struct RangeFromVisitor { + pub expecting: &'static str, + pub phantom: PhantomData, + } + + impl<'de, Idx> Visitor<'de> for RangeFromVisitor + where + Idx: Deserialize<'de>, + { + type Value = Idx; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str(self.expecting) + } + + fn visit_seq(self, mut seq: A) -> Result + where + A: SeqAccess<'de>, + { + let start: Idx = match tri!(seq.next_element()) { + Some(value) => value, + None => { + return Err(Error::invalid_length(0, &self)); + } + }; + Ok(start) + } + + fn visit_map(self, mut map: A) -> Result + where + A: MapAccess<'de>, + { + let mut start: Option = None; + while let Some(key) = tri!(map.next_key()) { + match key { + Field::Start => { + if start.is_some() { + return Err(::duplicate_field("start")); + } + start = Some(tri!(map.next_value())); + } + } + } + let start = match start { + Some(start) => start, + None => return Err(::missing_field("start")), + }; + Ok(start) + } + } +} + +//////////////////////////////////////////////////////////////////////////////// + +// Similar to: +// +// #[derive(Deserialize)] +// #[serde(deny_unknown_fields)] +// struct RangeTo { +// end: Idx, +// } +impl<'de, Idx> Deserialize<'de> for RangeTo +where + Idx: Deserialize<'de>, +{ + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + let end = tri!(deserializer.deserialize_struct( + "RangeTo", + range_to::FIELDS, + range_to::RangeToVisitor { + expecting: "struct RangeTo", + phantom: PhantomData, + }, + )); + Ok(..end) + } +} + +mod range_to { + use crate::lib::*; + + use crate::de::{Deserialize, Deserializer, Error, MapAccess, SeqAccess, Visitor}; + + pub const FIELDS: &[&str] = &["end"]; + + // If this were outside of the serde crate, it would just use: + // + // #[derive(Deserialize)] + // #[serde(field_identifier, rename_all = "lowercase")] + enum Field { + End, + } + + impl<'de> Deserialize<'de> for Field { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + struct FieldVisitor; + + impl<'de> Visitor<'de> for FieldVisitor { + type Value = Field; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("`end`") + } + + fn visit_str(self, value: &str) -> Result + where + E: Error, + { + match value { + "end" => Ok(Field::End), + _ => Err(Error::unknown_field(value, FIELDS)), + } + } + + fn visit_bytes(self, value: &[u8]) -> Result + where + E: Error, + { + match value { + b"end" => Ok(Field::End), + _ => { + let value = crate::__private::from_utf8_lossy(value); + Err(Error::unknown_field(&*value, FIELDS)) + } + } + } + } + + deserializer.deserialize_identifier(FieldVisitor) + } + } + + pub struct RangeToVisitor { + pub expecting: &'static str, + pub phantom: PhantomData, + } + + impl<'de, Idx> Visitor<'de> for RangeToVisitor + where + Idx: Deserialize<'de>, + { + type Value = Idx; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str(self.expecting) + } + + fn visit_seq(self, mut seq: A) -> Result + where + A: SeqAccess<'de>, + { + let end: Idx = match tri!(seq.next_element()) { + Some(value) => value, + None => { + return Err(Error::invalid_length(0, &self)); + } + }; + Ok(end) + } + + fn visit_map(self, mut map: A) -> Result + where + A: MapAccess<'de>, + { + let mut end: Option = None; + while let Some(key) = tri!(map.next_key()) { + match key { + Field::End => { + if end.is_some() { + return Err(::duplicate_field("end")); + } + end = Some(tri!(map.next_value())); + } + } + } + let end = match end { + Some(end) => end, + None => return Err(::missing_field("end")), + }; + Ok(end) + } + } +} + +//////////////////////////////////////////////////////////////////////////////// + +impl<'de, T> Deserialize<'de> for Bound +where + T: Deserialize<'de>, +{ + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + enum Field { + Unbounded, + Included, + Excluded, + } + + impl<'de> Deserialize<'de> for Field { + #[inline] + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + struct FieldVisitor; + + impl<'de> Visitor<'de> for FieldVisitor { + type Value = Field; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("`Unbounded`, `Included` or `Excluded`") + } + + fn visit_u64(self, value: u64) -> Result + where + E: Error, + { + match value { + 0 => Ok(Field::Unbounded), + 1 => Ok(Field::Included), + 2 => Ok(Field::Excluded), + _ => Err(Error::invalid_value(Unexpected::Unsigned(value), &self)), + } + } + + fn visit_str(self, value: &str) -> Result + where + E: Error, + { + match value { + "Unbounded" => Ok(Field::Unbounded), + "Included" => Ok(Field::Included), + "Excluded" => Ok(Field::Excluded), + _ => Err(Error::unknown_variant(value, VARIANTS)), + } + } + + fn visit_bytes(self, value: &[u8]) -> Result + where + E: Error, + { + match value { + b"Unbounded" => Ok(Field::Unbounded), + b"Included" => Ok(Field::Included), + b"Excluded" => Ok(Field::Excluded), + _ => match str::from_utf8(value) { + Ok(value) => Err(Error::unknown_variant(value, VARIANTS)), + Err(_) => { + Err(Error::invalid_value(Unexpected::Bytes(value), &self)) + } + }, + } + } + } + + deserializer.deserialize_identifier(FieldVisitor) + } + } + + struct BoundVisitor(PhantomData>); + + impl<'de, T> Visitor<'de> for BoundVisitor + where + T: Deserialize<'de>, + { + type Value = Bound; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("enum Bound") + } + + fn visit_enum(self, data: A) -> Result + where + A: EnumAccess<'de>, + { + match tri!(data.variant()) { + (Field::Unbounded, v) => v.unit_variant().map(|()| Bound::Unbounded), + (Field::Included, v) => v.newtype_variant().map(Bound::Included), + (Field::Excluded, v) => v.newtype_variant().map(Bound::Excluded), + } + } + } + + const VARIANTS: &[&str] = &["Unbounded", "Included", "Excluded"]; + + deserializer.deserialize_enum("Bound", VARIANTS, BoundVisitor(PhantomData)) + } +} + +//////////////////////////////////////////////////////////////////////////////// + +impl<'de, T, E> Deserialize<'de> for Result +where + T: Deserialize<'de>, + E: Deserialize<'de>, +{ + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + // If this were outside of the serde crate, it would just use: + // + // #[derive(Deserialize)] + // #[serde(variant_identifier)] + enum Field { + Ok, + Err, + } + + impl<'de> Deserialize<'de> for Field { + #[inline] + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + struct FieldVisitor; + + impl<'de> Visitor<'de> for FieldVisitor { + type Value = Field; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("`Ok` or `Err`") + } + + fn visit_u64(self, value: u64) -> Result + where + E: Error, + { + match value { + 0 => Ok(Field::Ok), + 1 => Ok(Field::Err), + _ => Err(Error::invalid_value(Unexpected::Unsigned(value), &self)), + } + } + + fn visit_str(self, value: &str) -> Result + where + E: Error, + { + match value { + "Ok" => Ok(Field::Ok), + "Err" => Ok(Field::Err), + _ => Err(Error::unknown_variant(value, VARIANTS)), + } + } + + fn visit_bytes(self, value: &[u8]) -> Result + where + E: Error, + { + match value { + b"Ok" => Ok(Field::Ok), + b"Err" => Ok(Field::Err), + _ => match str::from_utf8(value) { + Ok(value) => Err(Error::unknown_variant(value, VARIANTS)), + Err(_) => { + Err(Error::invalid_value(Unexpected::Bytes(value), &self)) + } + }, + } + } + } + + deserializer.deserialize_identifier(FieldVisitor) + } + } + + struct ResultVisitor(PhantomData>); + + impl<'de, T, E> Visitor<'de> for ResultVisitor + where + T: Deserialize<'de>, + E: Deserialize<'de>, + { + type Value = Result; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("enum Result") + } + + fn visit_enum(self, data: A) -> Result + where + A: EnumAccess<'de>, + { + match tri!(data.variant()) { + (Field::Ok, v) => v.newtype_variant().map(Ok), + (Field::Err, v) => v.newtype_variant().map(Err), + } + } + } + + const VARIANTS: &[&str] = &["Ok", "Err"]; + + deserializer.deserialize_enum("Result", VARIANTS, ResultVisitor(PhantomData)) + } +} + +//////////////////////////////////////////////////////////////////////////////// + +impl<'de, T> Deserialize<'de> for Wrapping +where + T: Deserialize<'de>, +{ + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + Deserialize::deserialize(deserializer).map(Wrapping) + } +} + +#[cfg(all(feature = "std", not(no_std_atomic)))] +macro_rules! atomic_impl { + ($($ty:ident $size:expr)*) => { + $( + #[cfg(any(no_target_has_atomic, target_has_atomic = $size))] + #[cfg_attr(docsrs, doc(cfg(all(feature = "std", target_has_atomic = $size))))] + impl<'de> Deserialize<'de> for $ty { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + Deserialize::deserialize(deserializer).map(Self::new) + } + } + )* + }; +} + +#[cfg(all(feature = "std", not(no_std_atomic)))] +atomic_impl! { + AtomicBool "8" + AtomicI8 "8" + AtomicI16 "16" + AtomicI32 "32" + AtomicIsize "ptr" + AtomicU8 "8" + AtomicU16 "16" + AtomicU32 "32" + AtomicUsize "ptr" +} + +#[cfg(all(feature = "std", not(no_std_atomic64)))] +atomic_impl! { + AtomicI64 "64" + AtomicU64 "64" +} + +#[cfg(any(feature = "std", not(no_core_net)))] +struct FromStrVisitor { + expecting: &'static str, + ty: PhantomData, +} + +#[cfg(any(feature = "std", not(no_core_net)))] +impl FromStrVisitor { + fn new(expecting: &'static str) -> Self { + FromStrVisitor { + expecting, + ty: PhantomData, + } + } +} + +#[cfg(any(feature = "std", not(no_core_net)))] +impl<'de, T> Visitor<'de> for FromStrVisitor +where + T: str::FromStr, + T::Err: fmt::Display, +{ + type Value = T; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str(self.expecting) + } + + fn visit_str(self, s: &str) -> Result + where + E: Error, + { + s.parse().map_err(Error::custom) + } +} diff --git a/vendor/serde/src/de/mod.rs b/vendor/serde/src/de/mod.rs new file mode 100644 index 0000000..21cfd04 --- /dev/null +++ b/vendor/serde/src/de/mod.rs @@ -0,0 +1,2335 @@ +//! Generic data structure deserialization framework. +//! +//! The two most important traits in this module are [`Deserialize`] and +//! [`Deserializer`]. +//! +//! - **A type that implements `Deserialize` is a data structure** that can be +//! deserialized from any data format supported by Serde, and conversely +//! - **A type that implements `Deserializer` is a data format** that can +//! deserialize any data structure supported by Serde. +//! +//! # The Deserialize trait +//! +//! Serde provides [`Deserialize`] implementations for many Rust primitive and +//! standard library types. The complete list is below. All of these can be +//! deserialized using Serde out of the box. +//! +//! Additionally, Serde provides a procedural macro called [`serde_derive`] to +//! automatically generate [`Deserialize`] implementations for structs and enums +//! in your program. See the [derive section of the manual] for how to use this. +//! +//! In rare cases it may be necessary to implement [`Deserialize`] manually for +//! some type in your program. See the [Implementing `Deserialize`] section of +//! the manual for more about this. +//! +//! Third-party crates may provide [`Deserialize`] implementations for types +//! that they expose. For example the [`linked-hash-map`] crate provides a +//! [`LinkedHashMap`] type that is deserializable by Serde because the +//! crate provides an implementation of [`Deserialize`] for it. +//! +//! # The Deserializer trait +//! +//! [`Deserializer`] implementations are provided by third-party crates, for +//! example [`serde_json`], [`serde_yaml`] and [`postcard`]. +//! +//! A partial list of well-maintained formats is given on the [Serde +//! website][data formats]. +//! +//! # Implementations of Deserialize provided by Serde +//! +//! This is a slightly different set of types than what is supported for +//! serialization. Some types can be serialized by Serde but not deserialized. +//! One example is `OsStr`. +//! +//! - **Primitive types**: +//! - bool +//! - i8, i16, i32, i64, i128, isize +//! - u8, u16, u32, u64, u128, usize +//! - f32, f64 +//! - char +//! - **Compound types**: +//! - \[T; 0\] through \[T; 32\] +//! - tuples up to size 16 +//! - **Common standard library types**: +//! - String +//! - Option\ +//! - Result\ +//! - PhantomData\ +//! - **Wrapper types**: +//! - Box\ +//! - Box\<\[T\]\> +//! - Box\ +//! - Cow\<'a, T\> +//! - Cell\ +//! - RefCell\ +//! - Mutex\ +//! - RwLock\ +//! - Rc\ *(if* features = \["rc"\] *is enabled)* +//! - Arc\ *(if* features = \["rc"\] *is enabled)* +//! - **Collection types**: +//! - BTreeMap\ +//! - BTreeSet\ +//! - BinaryHeap\ +//! - HashMap\ +//! - HashSet\ +//! - LinkedList\ +//! - VecDeque\ +//! - Vec\ +//! - **Zero-copy types**: +//! - &str +//! - &\[u8\] +//! - **FFI types**: +//! - CString +//! - Box\ +//! - OsString +//! - **Miscellaneous standard library types**: +//! - Duration +//! - SystemTime +//! - Path +//! - PathBuf +//! - Range\ +//! - RangeInclusive\ +//! - Bound\ +//! - num::NonZero* +//! - `!` *(unstable)* +//! - **Net types**: +//! - IpAddr +//! - Ipv4Addr +//! - Ipv6Addr +//! - SocketAddr +//! - SocketAddrV4 +//! - SocketAddrV6 +//! +//! [Implementing `Deserialize`]: https://serde.rs/impl-deserialize.html +//! [`Deserialize`]: ../trait.Deserialize.html +//! [`Deserializer`]: ../trait.Deserializer.html +//! [`LinkedHashMap`]: https://docs.rs/linked-hash-map/*/linked_hash_map/struct.LinkedHashMap.html +//! [`postcard`]: https://github.com/jamesmunns/postcard +//! [`linked-hash-map`]: https://crates.io/crates/linked-hash-map +//! [`serde_derive`]: https://crates.io/crates/serde_derive +//! [`serde_json`]: https://github.com/serde-rs/json +//! [`serde_yaml`]: https://github.com/dtolnay/serde-yaml +//! [derive section of the manual]: https://serde.rs/derive.html +//! [data formats]: https://serde.rs/#data-formats + +use crate::lib::*; + +//////////////////////////////////////////////////////////////////////////////// + +pub mod value; + +mod ignored_any; +mod impls; +pub(crate) mod size_hint; + +pub use self::ignored_any::IgnoredAny; + +#[cfg(all(not(feature = "std"), no_core_error))] +#[doc(no_inline)] +pub use crate::std_error::Error as StdError; +#[cfg(not(any(feature = "std", no_core_error)))] +#[doc(no_inline)] +pub use core::error::Error as StdError; +#[cfg(feature = "std")] +#[doc(no_inline)] +pub use std::error::Error as StdError; + +//////////////////////////////////////////////////////////////////////////////// + +macro_rules! declare_error_trait { + (Error: Sized $(+ $($supertrait:ident)::+)*) => { + /// The `Error` trait allows `Deserialize` implementations to create descriptive + /// error messages belonging to the `Deserializer` against which they are + /// currently running. + /// + /// Every `Deserializer` declares an `Error` type that encompasses both + /// general-purpose deserialization errors as well as errors specific to the + /// particular deserialization format. For example the `Error` type of + /// `serde_json` can represent errors like an invalid JSON escape sequence or an + /// unterminated string literal, in addition to the error cases that are part of + /// this trait. + /// + /// Most deserializers should only need to provide the `Error::custom` method + /// and inherit the default behavior for the other methods. + /// + /// # Example implementation + /// + /// The [example data format] presented on the website shows an error + /// type appropriate for a basic JSON data format. + /// + /// [example data format]: https://serde.rs/data-format.html + pub trait Error: Sized $(+ $($supertrait)::+)* { + /// Raised when there is general error when deserializing a type. + /// + /// The message should not be capitalized and should not end with a period. + /// + /// ```edition2021 + /// # use std::str::FromStr; + /// # + /// # struct IpAddr; + /// # + /// # impl FromStr for IpAddr { + /// # type Err = String; + /// # + /// # fn from_str(_: &str) -> Result { + /// # unimplemented!() + /// # } + /// # } + /// # + /// use serde::de::{self, Deserialize, Deserializer}; + /// + /// impl<'de> Deserialize<'de> for IpAddr { + /// fn deserialize(deserializer: D) -> Result + /// where + /// D: Deserializer<'de>, + /// { + /// let s = String::deserialize(deserializer)?; + /// s.parse().map_err(de::Error::custom) + /// } + /// } + /// ``` + fn custom(msg: T) -> Self + where + T: Display; + + /// Raised when a `Deserialize` receives a type different from what it was + /// expecting. + /// + /// The `unexp` argument provides information about what type was received. + /// This is the type that was present in the input file or other source data + /// of the Deserializer. + /// + /// The `exp` argument provides information about what type was being + /// expected. This is the type that is written in the program. + /// + /// For example if we try to deserialize a String out of a JSON file + /// containing an integer, the unexpected type is the integer and the + /// expected type is the string. + #[cold] + fn invalid_type(unexp: Unexpected, exp: &Expected) -> Self { + Error::custom(format_args!("invalid type: {}, expected {}", unexp, exp)) + } + + /// Raised when a `Deserialize` receives a value of the right type but that + /// is wrong for some other reason. + /// + /// The `unexp` argument provides information about what value was received. + /// This is the value that was present in the input file or other source + /// data of the Deserializer. + /// + /// The `exp` argument provides information about what value was being + /// expected. This is the type that is written in the program. + /// + /// For example if we try to deserialize a String out of some binary data + /// that is not valid UTF-8, the unexpected value is the bytes and the + /// expected value is a string. + #[cold] + fn invalid_value(unexp: Unexpected, exp: &Expected) -> Self { + Error::custom(format_args!("invalid value: {}, expected {}", unexp, exp)) + } + + /// Raised when deserializing a sequence or map and the input data contains + /// too many or too few elements. + /// + /// The `len` argument is the number of elements encountered. The sequence + /// or map may have expected more arguments or fewer arguments. + /// + /// The `exp` argument provides information about what data was being + /// expected. For example `exp` might say that a tuple of size 6 was + /// expected. + #[cold] + fn invalid_length(len: usize, exp: &Expected) -> Self { + Error::custom(format_args!("invalid length {}, expected {}", len, exp)) + } + + /// Raised when a `Deserialize` enum type received a variant with an + /// unrecognized name. + #[cold] + fn unknown_variant(variant: &str, expected: &'static [&'static str]) -> Self { + if expected.is_empty() { + Error::custom(format_args!( + "unknown variant `{}`, there are no variants", + variant + )) + } else { + Error::custom(format_args!( + "unknown variant `{}`, expected {}", + variant, + OneOf { names: expected } + )) + } + } + + /// Raised when a `Deserialize` struct type received a field with an + /// unrecognized name. + #[cold] + fn unknown_field(field: &str, expected: &'static [&'static str]) -> Self { + if expected.is_empty() { + Error::custom(format_args!( + "unknown field `{}`, there are no fields", + field + )) + } else { + Error::custom(format_args!( + "unknown field `{}`, expected {}", + field, + OneOf { names: expected } + )) + } + } + + /// Raised when a `Deserialize` struct type expected to receive a required + /// field with a particular name but that field was not present in the + /// input. + #[cold] + fn missing_field(field: &'static str) -> Self { + Error::custom(format_args!("missing field `{}`", field)) + } + + /// Raised when a `Deserialize` struct type received more than one of the + /// same field. + #[cold] + fn duplicate_field(field: &'static str) -> Self { + Error::custom(format_args!("duplicate field `{}`", field)) + } + } + } +} + +#[cfg(feature = "std")] +declare_error_trait!(Error: Sized + StdError); + +#[cfg(not(feature = "std"))] +declare_error_trait!(Error: Sized + Debug + Display); + +/// `Unexpected` represents an unexpected invocation of any one of the `Visitor` +/// trait methods. +/// +/// This is used as an argument to the `invalid_type`, `invalid_value`, and +/// `invalid_length` methods of the `Error` trait to build error messages. +/// +/// ```edition2021 +/// # use std::fmt; +/// # +/// # use serde::de::{self, Unexpected, Visitor}; +/// # +/// # struct Example; +/// # +/// # impl<'de> Visitor<'de> for Example { +/// # type Value = (); +/// # +/// # fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { +/// # write!(formatter, "definitely not a boolean") +/// # } +/// # +/// fn visit_bool(self, v: bool) -> Result +/// where +/// E: de::Error, +/// { +/// Err(de::Error::invalid_type(Unexpected::Bool(v), &self)) +/// } +/// # } +/// ``` +#[derive(Copy, Clone, PartialEq, Debug)] +pub enum Unexpected<'a> { + /// The input contained a boolean value that was not expected. + Bool(bool), + + /// The input contained an unsigned integer `u8`, `u16`, `u32` or `u64` that + /// was not expected. + Unsigned(u64), + + /// The input contained a signed integer `i8`, `i16`, `i32` or `i64` that + /// was not expected. + Signed(i64), + + /// The input contained a floating point `f32` or `f64` that was not + /// expected. + Float(f64), + + /// The input contained a `char` that was not expected. + Char(char), + + /// The input contained a `&str` or `String` that was not expected. + Str(&'a str), + + /// The input contained a `&[u8]` or `Vec` that was not expected. + Bytes(&'a [u8]), + + /// The input contained a unit `()` that was not expected. + Unit, + + /// The input contained an `Option` that was not expected. + Option, + + /// The input contained a newtype struct that was not expected. + NewtypeStruct, + + /// The input contained a sequence that was not expected. + Seq, + + /// The input contained a map that was not expected. + Map, + + /// The input contained an enum that was not expected. + Enum, + + /// The input contained a unit variant that was not expected. + UnitVariant, + + /// The input contained a newtype variant that was not expected. + NewtypeVariant, + + /// The input contained a tuple variant that was not expected. + TupleVariant, + + /// The input contained a struct variant that was not expected. + StructVariant, + + /// A message stating what uncategorized thing the input contained that was + /// not expected. + /// + /// The message should be a noun or noun phrase, not capitalized and without + /// a period. An example message is "unoriginal superhero". + Other(&'a str), +} + +impl<'a> fmt::Display for Unexpected<'a> { + fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + use self::Unexpected::*; + match *self { + Bool(b) => write!(formatter, "boolean `{}`", b), + Unsigned(i) => write!(formatter, "integer `{}`", i), + Signed(i) => write!(formatter, "integer `{}`", i), + Float(f) => write!(formatter, "floating point `{}`", WithDecimalPoint(f)), + Char(c) => write!(formatter, "character `{}`", c), + Str(s) => write!(formatter, "string {:?}", s), + Bytes(_) => formatter.write_str("byte array"), + Unit => formatter.write_str("unit value"), + Option => formatter.write_str("Option value"), + NewtypeStruct => formatter.write_str("newtype struct"), + Seq => formatter.write_str("sequence"), + Map => formatter.write_str("map"), + Enum => formatter.write_str("enum"), + UnitVariant => formatter.write_str("unit variant"), + NewtypeVariant => formatter.write_str("newtype variant"), + TupleVariant => formatter.write_str("tuple variant"), + StructVariant => formatter.write_str("struct variant"), + Other(other) => formatter.write_str(other), + } + } +} + +/// `Expected` represents an explanation of what data a `Visitor` was expecting +/// to receive. +/// +/// This is used as an argument to the `invalid_type`, `invalid_value`, and +/// `invalid_length` methods of the `Error` trait to build error messages. The +/// message should be a noun or noun phrase that completes the sentence "This +/// Visitor expects to receive ...", for example the message could be "an +/// integer between 0 and 64". The message should not be capitalized and should +/// not end with a period. +/// +/// Within the context of a `Visitor` implementation, the `Visitor` itself +/// (`&self`) is an implementation of this trait. +/// +/// ```edition2021 +/// # use serde::de::{self, Unexpected, Visitor}; +/// # use std::fmt; +/// # +/// # struct Example; +/// # +/// # impl<'de> Visitor<'de> for Example { +/// # type Value = (); +/// # +/// # fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { +/// # write!(formatter, "definitely not a boolean") +/// # } +/// # +/// fn visit_bool(self, v: bool) -> Result +/// where +/// E: de::Error, +/// { +/// Err(de::Error::invalid_type(Unexpected::Bool(v), &self)) +/// } +/// # } +/// ``` +/// +/// Outside of a `Visitor`, `&"..."` can be used. +/// +/// ```edition2021 +/// # use serde::de::{self, Unexpected}; +/// # +/// # fn example() -> Result<(), E> +/// # where +/// # E: de::Error, +/// # { +/// # let v = true; +/// return Err(de::Error::invalid_type( +/// Unexpected::Bool(v), +/// &"a negative integer", +/// )); +/// # } +/// ``` +pub trait Expected { + /// Format an explanation of what data was being expected. Same signature as + /// the `Display` and `Debug` traits. + fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result; +} + +impl<'de, T> Expected for T +where + T: Visitor<'de>, +{ + fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + self.expecting(formatter) + } +} + +impl<'a> Expected for &'a str { + fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str(self) + } +} + +impl<'a> Display for Expected + 'a { + fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + Expected::fmt(self, formatter) + } +} + +//////////////////////////////////////////////////////////////////////////////// + +/// A **data structure** that can be deserialized from any data format supported +/// by Serde. +/// +/// Serde provides `Deserialize` implementations for many Rust primitive and +/// standard library types. The complete list is [here][crate::de]. All of these +/// can be deserialized using Serde out of the box. +/// +/// Additionally, Serde provides a procedural macro called `serde_derive` to +/// automatically generate `Deserialize` implementations for structs and enums +/// in your program. See the [derive section of the manual][derive] for how to +/// use this. +/// +/// In rare cases it may be necessary to implement `Deserialize` manually for +/// some type in your program. See the [Implementing +/// `Deserialize`][impl-deserialize] section of the manual for more about this. +/// +/// Third-party crates may provide `Deserialize` implementations for types that +/// they expose. For example the `linked-hash-map` crate provides a +/// `LinkedHashMap` type that is deserializable by Serde because the crate +/// provides an implementation of `Deserialize` for it. +/// +/// [derive]: https://serde.rs/derive.html +/// [impl-deserialize]: https://serde.rs/impl-deserialize.html +/// +/// # Lifetime +/// +/// The `'de` lifetime of this trait is the lifetime of data that may be +/// borrowed by `Self` when deserialized. See the page [Understanding +/// deserializer lifetimes] for a more detailed explanation of these lifetimes. +/// +/// [Understanding deserializer lifetimes]: https://serde.rs/lifetimes.html +#[cfg_attr( + not(no_diagnostic_namespace), + diagnostic::on_unimplemented( + note = "for local types consider adding `#[derive(serde::Deserialize)]` to your `{Self}` type", + note = "for types from other crates check whether the crate offers a `serde` feature flag", + ) +)] +pub trait Deserialize<'de>: Sized { + /// Deserialize this value from the given Serde deserializer. + /// + /// See the [Implementing `Deserialize`][impl-deserialize] section of the + /// manual for more information about how to implement this method. + /// + /// [impl-deserialize]: https://serde.rs/impl-deserialize.html + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>; + + /// Deserializes a value into `self` from the given Deserializer. + /// + /// The purpose of this method is to allow the deserializer to reuse + /// resources and avoid copies. As such, if this method returns an error, + /// `self` will be in an indeterminate state where some parts of the struct + /// have been overwritten. Although whatever state that is will be + /// memory-safe. + /// + /// This is generally useful when repeatedly deserializing values that + /// are processed one at a time, where the value of `self` doesn't matter + /// when the next deserialization occurs. + /// + /// If you manually implement this, your recursive deserializations should + /// use `deserialize_in_place`. + /// + /// This method is stable and an official public API, but hidden from the + /// documentation because it is almost never what newbies are looking for. + /// Showing it in rustdoc would cause it to be featured more prominently + /// than it deserves. + #[doc(hidden)] + fn deserialize_in_place(deserializer: D, place: &mut Self) -> Result<(), D::Error> + where + D: Deserializer<'de>, + { + // Default implementation just delegates to `deserialize` impl. + *place = tri!(Deserialize::deserialize(deserializer)); + Ok(()) + } +} + +/// A data structure that can be deserialized without borrowing any data from +/// the deserializer. +/// +/// This is primarily useful for trait bounds on functions. For example a +/// `from_str` function may be able to deserialize a data structure that borrows +/// from the input string, but a `from_reader` function may only deserialize +/// owned data. +/// +/// ```edition2021 +/// # use serde::de::{Deserialize, DeserializeOwned}; +/// # use std::io::{Read, Result}; +/// # +/// # trait Ignore { +/// fn from_str<'a, T>(s: &'a str) -> Result +/// where +/// T: Deserialize<'a>; +/// +/// fn from_reader(rdr: R) -> Result +/// where +/// R: Read, +/// T: DeserializeOwned; +/// # } +/// ``` +/// +/// # Lifetime +/// +/// The relationship between `Deserialize` and `DeserializeOwned` in trait +/// bounds is explained in more detail on the page [Understanding deserializer +/// lifetimes]. +/// +/// [Understanding deserializer lifetimes]: https://serde.rs/lifetimes.html +pub trait DeserializeOwned: for<'de> Deserialize<'de> {} +impl DeserializeOwned for T where T: for<'de> Deserialize<'de> {} + +/// `DeserializeSeed` is the stateful form of the `Deserialize` trait. If you +/// ever find yourself looking for a way to pass data into a `Deserialize` impl, +/// this trait is the way to do it. +/// +/// As one example of stateful deserialization consider deserializing a JSON +/// array into an existing buffer. Using the `Deserialize` trait we could +/// deserialize a JSON array into a `Vec` but it would be a freshly allocated +/// `Vec`; there is no way for `Deserialize` to reuse a previously allocated +/// buffer. Using `DeserializeSeed` instead makes this possible as in the +/// example code below. +/// +/// The canonical API for stateless deserialization looks like this: +/// +/// ```edition2021 +/// # use serde::Deserialize; +/// # +/// # enum Error {} +/// # +/// fn func<'de, T: Deserialize<'de>>() -> Result +/// # { +/// # unimplemented!() +/// # } +/// ``` +/// +/// Adjusting an API like this to support stateful deserialization is a matter +/// of accepting a seed as input: +/// +/// ```edition2021 +/// # use serde::de::DeserializeSeed; +/// # +/// # enum Error {} +/// # +/// fn func_seed<'de, T: DeserializeSeed<'de>>(seed: T) -> Result +/// # { +/// # let _ = seed; +/// # unimplemented!() +/// # } +/// ``` +/// +/// In practice the majority of deserialization is stateless. An API expecting a +/// seed can be appeased by passing `std::marker::PhantomData` as a seed in the +/// case of stateless deserialization. +/// +/// # Lifetime +/// +/// The `'de` lifetime of this trait is the lifetime of data that may be +/// borrowed by `Self::Value` when deserialized. See the page [Understanding +/// deserializer lifetimes] for a more detailed explanation of these lifetimes. +/// +/// [Understanding deserializer lifetimes]: https://serde.rs/lifetimes.html +/// +/// # Example +/// +/// Suppose we have JSON that looks like `[[1, 2], [3, 4, 5], [6]]` and we need +/// to deserialize it into a flat representation like `vec![1, 2, 3, 4, 5, 6]`. +/// Allocating a brand new `Vec` for each subarray would be slow. Instead we +/// would like to allocate a single `Vec` and then deserialize each subarray +/// into it. This requires stateful deserialization using the `DeserializeSeed` +/// trait. +/// +/// ```edition2021 +/// use serde::de::{Deserialize, DeserializeSeed, Deserializer, SeqAccess, Visitor}; +/// use std::fmt; +/// use std::marker::PhantomData; +/// +/// // A DeserializeSeed implementation that uses stateful deserialization to +/// // append array elements onto the end of an existing vector. The preexisting +/// // state ("seed") in this case is the Vec. The `deserialize` method of +/// // `ExtendVec` will be traversing the inner arrays of the JSON input and +/// // appending each integer into the existing Vec. +/// struct ExtendVec<'a, T: 'a>(&'a mut Vec); +/// +/// impl<'de, 'a, T> DeserializeSeed<'de> for ExtendVec<'a, T> +/// where +/// T: Deserialize<'de>, +/// { +/// // The return type of the `deserialize` method. This implementation +/// // appends onto an existing vector but does not create any new data +/// // structure, so the return type is (). +/// type Value = (); +/// +/// fn deserialize(self, deserializer: D) -> Result +/// where +/// D: Deserializer<'de>, +/// { +/// // Visitor implementation that will walk an inner array of the JSON +/// // input. +/// struct ExtendVecVisitor<'a, T: 'a>(&'a mut Vec); +/// +/// impl<'de, 'a, T> Visitor<'de> for ExtendVecVisitor<'a, T> +/// where +/// T: Deserialize<'de>, +/// { +/// type Value = (); +/// +/// fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { +/// write!(formatter, "an array of integers") +/// } +/// +/// fn visit_seq(self, mut seq: A) -> Result<(), A::Error> +/// where +/// A: SeqAccess<'de>, +/// { +/// // Decrease the number of reallocations if there are many elements +/// if let Some(size_hint) = seq.size_hint() { +/// self.0.reserve(size_hint); +/// } +/// +/// // Visit each element in the inner array and push it onto +/// // the existing vector. +/// while let Some(elem) = seq.next_element()? { +/// self.0.push(elem); +/// } +/// Ok(()) +/// } +/// } +/// +/// deserializer.deserialize_seq(ExtendVecVisitor(self.0)) +/// } +/// } +/// +/// // Visitor implementation that will walk the outer array of the JSON input. +/// struct FlattenedVecVisitor(PhantomData); +/// +/// impl<'de, T> Visitor<'de> for FlattenedVecVisitor +/// where +/// T: Deserialize<'de>, +/// { +/// // This Visitor constructs a single Vec to hold the flattened +/// // contents of the inner arrays. +/// type Value = Vec; +/// +/// fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { +/// write!(formatter, "an array of arrays") +/// } +/// +/// fn visit_seq(self, mut seq: A) -> Result, A::Error> +/// where +/// A: SeqAccess<'de>, +/// { +/// // Create a single Vec to hold the flattened contents. +/// let mut vec = Vec::new(); +/// +/// // Each iteration through this loop is one inner array. +/// while let Some(()) = seq.next_element_seed(ExtendVec(&mut vec))? { +/// // Nothing to do; inner array has been appended into `vec`. +/// } +/// +/// // Return the finished vec. +/// Ok(vec) +/// } +/// } +/// +/// # fn example<'de, D>(deserializer: D) -> Result<(), D::Error> +/// # where +/// # D: Deserializer<'de>, +/// # { +/// let visitor = FlattenedVecVisitor(PhantomData); +/// let flattened: Vec = deserializer.deserialize_seq(visitor)?; +/// # Ok(()) +/// # } +/// ``` +pub trait DeserializeSeed<'de>: Sized { + /// The type produced by using this seed. + type Value; + + /// Equivalent to the more common `Deserialize::deserialize` method, except + /// with some initial piece of data (the seed) passed in. + fn deserialize(self, deserializer: D) -> Result + where + D: Deserializer<'de>; +} + +impl<'de, T> DeserializeSeed<'de> for PhantomData +where + T: Deserialize<'de>, +{ + type Value = T; + + #[inline] + fn deserialize(self, deserializer: D) -> Result + where + D: Deserializer<'de>, + { + T::deserialize(deserializer) + } +} + +//////////////////////////////////////////////////////////////////////////////// + +/// A **data format** that can deserialize any data structure supported by +/// Serde. +/// +/// The role of this trait is to define the deserialization half of the [Serde +/// data model], which is a way to categorize every Rust data type into one of +/// 29 possible types. Each method of the `Deserializer` trait corresponds to one +/// of the types of the data model. +/// +/// Implementations of `Deserialize` map themselves into this data model by +/// passing to the `Deserializer` a `Visitor` implementation that can receive +/// these various types. +/// +/// The types that make up the Serde data model are: +/// +/// - **14 primitive types** +/// - bool +/// - i8, i16, i32, i64, i128 +/// - u8, u16, u32, u64, u128 +/// - f32, f64 +/// - char +/// - **string** +/// - UTF-8 bytes with a length and no null terminator. +/// - When serializing, all strings are handled equally. When deserializing, +/// there are three flavors of strings: transient, owned, and borrowed. +/// - **byte array** - \[u8\] +/// - Similar to strings, during deserialization byte arrays can be +/// transient, owned, or borrowed. +/// - **option** +/// - Either none or some value. +/// - **unit** +/// - The type of `()` in Rust. It represents an anonymous value containing +/// no data. +/// - **unit_struct** +/// - For example `struct Unit` or `PhantomData`. It represents a named +/// value containing no data. +/// - **unit_variant** +/// - For example the `E::A` and `E::B` in `enum E { A, B }`. +/// - **newtype_struct** +/// - For example `struct Millimeters(u8)`. +/// - **newtype_variant** +/// - For example the `E::N` in `enum E { N(u8) }`. +/// - **seq** +/// - A variably sized heterogeneous sequence of values, for example `Vec` +/// or `HashSet`. When serializing, the length may or may not be known +/// before iterating through all the data. When deserializing, the length +/// is determined by looking at the serialized data. +/// - **tuple** +/// - A statically sized heterogeneous sequence of values for which the +/// length will be known at deserialization time without looking at the +/// serialized data, for example `(u8,)` or `(String, u64, Vec)` or +/// `[u64; 10]`. +/// - **tuple_struct** +/// - A named tuple, for example `struct Rgb(u8, u8, u8)`. +/// - **tuple_variant** +/// - For example the `E::T` in `enum E { T(u8, u8) }`. +/// - **map** +/// - A heterogeneous key-value pairing, for example `BTreeMap`. +/// - **struct** +/// - A heterogeneous key-value pairing in which the keys are strings and +/// will be known at deserialization time without looking at the serialized +/// data, for example `struct S { r: u8, g: u8, b: u8 }`. +/// - **struct_variant** +/// - For example the `E::S` in `enum E { S { r: u8, g: u8, b: u8 } }`. +/// +/// The `Deserializer` trait supports two entry point styles which enables +/// different kinds of deserialization. +/// +/// 1. The `deserialize_any` method. Self-describing data formats like JSON are +/// able to look at the serialized data and tell what it represents. For +/// example the JSON deserializer may see an opening curly brace (`{`) and +/// know that it is seeing a map. If the data format supports +/// `Deserializer::deserialize_any`, it will drive the Visitor using whatever +/// type it sees in the input. JSON uses this approach when deserializing +/// `serde_json::Value` which is an enum that can represent any JSON +/// document. Without knowing what is in a JSON document, we can deserialize +/// it to `serde_json::Value` by going through +/// `Deserializer::deserialize_any`. +/// +/// 2. The various `deserialize_*` methods. Non-self-describing formats like +/// Postcard need to be told what is in the input in order to deserialize it. +/// The `deserialize_*` methods are hints to the deserializer for how to +/// interpret the next piece of input. Non-self-describing formats are not +/// able to deserialize something like `serde_json::Value` which relies on +/// `Deserializer::deserialize_any`. +/// +/// When implementing `Deserialize`, you should avoid relying on +/// `Deserializer::deserialize_any` unless you need to be told by the +/// Deserializer what type is in the input. Know that relying on +/// `Deserializer::deserialize_any` means your data type will be able to +/// deserialize from self-describing formats only, ruling out Postcard and many +/// others. +/// +/// [Serde data model]: https://serde.rs/data-model.html +/// +/// # Lifetime +/// +/// The `'de` lifetime of this trait is the lifetime of data that may be +/// borrowed from the input when deserializing. See the page [Understanding +/// deserializer lifetimes] for a more detailed explanation of these lifetimes. +/// +/// [Understanding deserializer lifetimes]: https://serde.rs/lifetimes.html +/// +/// # Example implementation +/// +/// The [example data format] presented on the website contains example code for +/// a basic JSON `Deserializer`. +/// +/// [example data format]: https://serde.rs/data-format.html +pub trait Deserializer<'de>: Sized { + /// The error type that can be returned if some error occurs during + /// deserialization. + type Error: Error; + + /// Require the `Deserializer` to figure out how to drive the visitor based + /// on what data type is in the input. + /// + /// When implementing `Deserialize`, you should avoid relying on + /// `Deserializer::deserialize_any` unless you need to be told by the + /// Deserializer what type is in the input. Know that relying on + /// `Deserializer::deserialize_any` means your data type will be able to + /// deserialize from self-describing formats only, ruling out Postcard and + /// many others. + fn deserialize_any(self, visitor: V) -> Result + where + V: Visitor<'de>; + + /// Hint that the `Deserialize` type is expecting a `bool` value. + fn deserialize_bool(self, visitor: V) -> Result + where + V: Visitor<'de>; + + /// Hint that the `Deserialize` type is expecting an `i8` value. + fn deserialize_i8(self, visitor: V) -> Result + where + V: Visitor<'de>; + + /// Hint that the `Deserialize` type is expecting an `i16` value. + fn deserialize_i16(self, visitor: V) -> Result + where + V: Visitor<'de>; + + /// Hint that the `Deserialize` type is expecting an `i32` value. + fn deserialize_i32(self, visitor: V) -> Result + where + V: Visitor<'de>; + + /// Hint that the `Deserialize` type is expecting an `i64` value. + fn deserialize_i64(self, visitor: V) -> Result + where + V: Visitor<'de>; + + /// Hint that the `Deserialize` type is expecting an `i128` value. + /// + /// The default behavior unconditionally returns an error. + fn deserialize_i128(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + let _ = visitor; + Err(Error::custom("i128 is not supported")) + } + + /// Hint that the `Deserialize` type is expecting a `u8` value. + fn deserialize_u8(self, visitor: V) -> Result + where + V: Visitor<'de>; + + /// Hint that the `Deserialize` type is expecting a `u16` value. + fn deserialize_u16(self, visitor: V) -> Result + where + V: Visitor<'de>; + + /// Hint that the `Deserialize` type is expecting a `u32` value. + fn deserialize_u32(self, visitor: V) -> Result + where + V: Visitor<'de>; + + /// Hint that the `Deserialize` type is expecting a `u64` value. + fn deserialize_u64(self, visitor: V) -> Result + where + V: Visitor<'de>; + + /// Hint that the `Deserialize` type is expecting an `u128` value. + /// + /// The default behavior unconditionally returns an error. + fn deserialize_u128(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + let _ = visitor; + Err(Error::custom("u128 is not supported")) + } + + /// Hint that the `Deserialize` type is expecting a `f32` value. + fn deserialize_f32(self, visitor: V) -> Result + where + V: Visitor<'de>; + + /// Hint that the `Deserialize` type is expecting a `f64` value. + fn deserialize_f64(self, visitor: V) -> Result + where + V: Visitor<'de>; + + /// Hint that the `Deserialize` type is expecting a `char` value. + fn deserialize_char(self, visitor: V) -> Result + where + V: Visitor<'de>; + + /// Hint that the `Deserialize` type is expecting a string value and does + /// not benefit from taking ownership of buffered data owned by the + /// `Deserializer`. + /// + /// If the `Visitor` would benefit from taking ownership of `String` data, + /// indicate this to the `Deserializer` by using `deserialize_string` + /// instead. + fn deserialize_str(self, visitor: V) -> Result + where + V: Visitor<'de>; + + /// Hint that the `Deserialize` type is expecting a string value and would + /// benefit from taking ownership of buffered data owned by the + /// `Deserializer`. + /// + /// If the `Visitor` would not benefit from taking ownership of `String` + /// data, indicate that to the `Deserializer` by using `deserialize_str` + /// instead. + fn deserialize_string(self, visitor: V) -> Result + where + V: Visitor<'de>; + + /// Hint that the `Deserialize` type is expecting a byte array and does not + /// benefit from taking ownership of buffered data owned by the + /// `Deserializer`. + /// + /// If the `Visitor` would benefit from taking ownership of `Vec` data, + /// indicate this to the `Deserializer` by using `deserialize_byte_buf` + /// instead. + fn deserialize_bytes(self, visitor: V) -> Result + where + V: Visitor<'de>; + + /// Hint that the `Deserialize` type is expecting a byte array and would + /// benefit from taking ownership of buffered data owned by the + /// `Deserializer`. + /// + /// If the `Visitor` would not benefit from taking ownership of `Vec` + /// data, indicate that to the `Deserializer` by using `deserialize_bytes` + /// instead. + fn deserialize_byte_buf(self, visitor: V) -> Result + where + V: Visitor<'de>; + + /// Hint that the `Deserialize` type is expecting an optional value. + /// + /// This allows deserializers that encode an optional value as a nullable + /// value to convert the null value into `None` and a regular value into + /// `Some(value)`. + fn deserialize_option(self, visitor: V) -> Result + where + V: Visitor<'de>; + + /// Hint that the `Deserialize` type is expecting a unit value. + fn deserialize_unit(self, visitor: V) -> Result + where + V: Visitor<'de>; + + /// Hint that the `Deserialize` type is expecting a unit struct with a + /// particular name. + fn deserialize_unit_struct( + self, + name: &'static str, + visitor: V, + ) -> Result + where + V: Visitor<'de>; + + /// Hint that the `Deserialize` type is expecting a newtype struct with a + /// particular name. + fn deserialize_newtype_struct( + self, + name: &'static str, + visitor: V, + ) -> Result + where + V: Visitor<'de>; + + /// Hint that the `Deserialize` type is expecting a sequence of values. + fn deserialize_seq(self, visitor: V) -> Result + where + V: Visitor<'de>; + + /// Hint that the `Deserialize` type is expecting a sequence of values and + /// knows how many values there are without looking at the serialized data. + fn deserialize_tuple(self, len: usize, visitor: V) -> Result + where + V: Visitor<'de>; + + /// Hint that the `Deserialize` type is expecting a tuple struct with a + /// particular name and number of fields. + fn deserialize_tuple_struct( + self, + name: &'static str, + len: usize, + visitor: V, + ) -> Result + where + V: Visitor<'de>; + + /// Hint that the `Deserialize` type is expecting a map of key-value pairs. + fn deserialize_map(self, visitor: V) -> Result + where + V: Visitor<'de>; + + /// Hint that the `Deserialize` type is expecting a struct with a particular + /// name and fields. + fn deserialize_struct( + self, + name: &'static str, + fields: &'static [&'static str], + visitor: V, + ) -> Result + where + V: Visitor<'de>; + + /// Hint that the `Deserialize` type is expecting an enum value with a + /// particular name and possible variants. + fn deserialize_enum( + self, + name: &'static str, + variants: &'static [&'static str], + visitor: V, + ) -> Result + where + V: Visitor<'de>; + + /// Hint that the `Deserialize` type is expecting the name of a struct + /// field or the discriminant of an enum variant. + fn deserialize_identifier(self, visitor: V) -> Result + where + V: Visitor<'de>; + + /// Hint that the `Deserialize` type needs to deserialize a value whose type + /// doesn't matter because it is ignored. + /// + /// Deserializers for non-self-describing formats may not support this mode. + fn deserialize_ignored_any(self, visitor: V) -> Result + where + V: Visitor<'de>; + + /// Determine whether `Deserialize` implementations should expect to + /// deserialize their human-readable form. + /// + /// Some types have a human-readable form that may be somewhat expensive to + /// construct, as well as a binary form that is compact and efficient. + /// Generally text-based formats like JSON and YAML will prefer to use the + /// human-readable one and binary formats like Postcard will prefer the + /// compact one. + /// + /// ```edition2021 + /// # use std::ops::Add; + /// # use std::str::FromStr; + /// # + /// # struct Timestamp; + /// # + /// # impl Timestamp { + /// # const EPOCH: Timestamp = Timestamp; + /// # } + /// # + /// # impl FromStr for Timestamp { + /// # type Err = String; + /// # fn from_str(_: &str) -> Result { + /// # unimplemented!() + /// # } + /// # } + /// # + /// # struct Duration; + /// # + /// # impl Duration { + /// # fn seconds(_: u64) -> Self { unimplemented!() } + /// # } + /// # + /// # impl Add for Timestamp { + /// # type Output = Timestamp; + /// # fn add(self, _: Duration) -> Self::Output { + /// # unimplemented!() + /// # } + /// # } + /// # + /// use serde::de::{self, Deserialize, Deserializer}; + /// + /// impl<'de> Deserialize<'de> for Timestamp { + /// fn deserialize(deserializer: D) -> Result + /// where + /// D: Deserializer<'de>, + /// { + /// if deserializer.is_human_readable() { + /// // Deserialize from a human-readable string like "2015-05-15T17:01:00Z". + /// let s = String::deserialize(deserializer)?; + /// Timestamp::from_str(&s).map_err(de::Error::custom) + /// } else { + /// // Deserialize from a compact binary representation, seconds since + /// // the Unix epoch. + /// let n = u64::deserialize(deserializer)?; + /// Ok(Timestamp::EPOCH + Duration::seconds(n)) + /// } + /// } + /// } + /// ``` + /// + /// The default implementation of this method returns `true`. Data formats + /// may override this to `false` to request a compact form for types that + /// support one. Note that modifying this method to change a format from + /// human-readable to compact or vice versa should be regarded as a breaking + /// change, as a value serialized in human-readable mode is not required to + /// deserialize from the same data in compact mode. + #[inline] + fn is_human_readable(&self) -> bool { + true + } + + // Not public API. + #[cfg(all(not(no_serde_derive), any(feature = "std", feature = "alloc")))] + #[doc(hidden)] + fn __deserialize_content( + self, + _: crate::actually_private::T, + visitor: V, + ) -> Result, Self::Error> + where + V: Visitor<'de, Value = crate::__private::de::Content<'de>>, + { + self.deserialize_any(visitor) + } +} + +//////////////////////////////////////////////////////////////////////////////// + +/// This trait represents a visitor that walks through a deserializer. +/// +/// # Lifetime +/// +/// The `'de` lifetime of this trait is the requirement for lifetime of data +/// that may be borrowed by `Self::Value`. See the page [Understanding +/// deserializer lifetimes] for a more detailed explanation of these lifetimes. +/// +/// [Understanding deserializer lifetimes]: https://serde.rs/lifetimes.html +/// +/// # Example +/// +/// ```edition2021 +/// # use serde::de::{self, Unexpected, Visitor}; +/// # use std::fmt; +/// # +/// /// A visitor that deserializes a long string - a string containing at least +/// /// some minimum number of bytes. +/// struct LongString { +/// min: usize, +/// } +/// +/// impl<'de> Visitor<'de> for LongString { +/// type Value = String; +/// +/// fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { +/// write!(formatter, "a string containing at least {} bytes", self.min) +/// } +/// +/// fn visit_str(self, s: &str) -> Result +/// where +/// E: de::Error, +/// { +/// if s.len() >= self.min { +/// Ok(s.to_owned()) +/// } else { +/// Err(de::Error::invalid_value(Unexpected::Str(s), &self)) +/// } +/// } +/// } +/// ``` +pub trait Visitor<'de>: Sized { + /// The value produced by this visitor. + type Value; + + /// Format a message stating what data this Visitor expects to receive. + /// + /// This is used in error messages. The message should complete the sentence + /// "This Visitor expects to receive ...", for example the message could be + /// "an integer between 0 and 64". The message should not be capitalized and + /// should not end with a period. + /// + /// ```edition2021 + /// # use std::fmt; + /// # + /// # struct S { + /// # max: usize, + /// # } + /// # + /// # impl<'de> serde::de::Visitor<'de> for S { + /// # type Value = (); + /// # + /// fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + /// write!(formatter, "an integer between 0 and {}", self.max) + /// } + /// # } + /// ``` + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result; + + /// The input contains a boolean. + /// + /// The default implementation fails with a type error. + fn visit_bool(self, v: bool) -> Result + where + E: Error, + { + Err(Error::invalid_type(Unexpected::Bool(v), &self)) + } + + /// The input contains an `i8`. + /// + /// The default implementation forwards to [`visit_i64`]. + /// + /// [`visit_i64`]: #method.visit_i64 + fn visit_i8(self, v: i8) -> Result + where + E: Error, + { + self.visit_i64(v as i64) + } + + /// The input contains an `i16`. + /// + /// The default implementation forwards to [`visit_i64`]. + /// + /// [`visit_i64`]: #method.visit_i64 + fn visit_i16(self, v: i16) -> Result + where + E: Error, + { + self.visit_i64(v as i64) + } + + /// The input contains an `i32`. + /// + /// The default implementation forwards to [`visit_i64`]. + /// + /// [`visit_i64`]: #method.visit_i64 + fn visit_i32(self, v: i32) -> Result + where + E: Error, + { + self.visit_i64(v as i64) + } + + /// The input contains an `i64`. + /// + /// The default implementation fails with a type error. + fn visit_i64(self, v: i64) -> Result + where + E: Error, + { + Err(Error::invalid_type(Unexpected::Signed(v), &self)) + } + + /// The input contains a `i128`. + /// + /// The default implementation fails with a type error. + fn visit_i128(self, v: i128) -> Result + where + E: Error, + { + let mut buf = [0u8; 58]; + let mut writer = crate::format::Buf::new(&mut buf); + fmt::Write::write_fmt(&mut writer, format_args!("integer `{}` as i128", v)).unwrap(); + Err(Error::invalid_type( + Unexpected::Other(writer.as_str()), + &self, + )) + } + + /// The input contains a `u8`. + /// + /// The default implementation forwards to [`visit_u64`]. + /// + /// [`visit_u64`]: #method.visit_u64 + fn visit_u8(self, v: u8) -> Result + where + E: Error, + { + self.visit_u64(v as u64) + } + + /// The input contains a `u16`. + /// + /// The default implementation forwards to [`visit_u64`]. + /// + /// [`visit_u64`]: #method.visit_u64 + fn visit_u16(self, v: u16) -> Result + where + E: Error, + { + self.visit_u64(v as u64) + } + + /// The input contains a `u32`. + /// + /// The default implementation forwards to [`visit_u64`]. + /// + /// [`visit_u64`]: #method.visit_u64 + fn visit_u32(self, v: u32) -> Result + where + E: Error, + { + self.visit_u64(v as u64) + } + + /// The input contains a `u64`. + /// + /// The default implementation fails with a type error. + fn visit_u64(self, v: u64) -> Result + where + E: Error, + { + Err(Error::invalid_type(Unexpected::Unsigned(v), &self)) + } + + /// The input contains a `u128`. + /// + /// The default implementation fails with a type error. + fn visit_u128(self, v: u128) -> Result + where + E: Error, + { + let mut buf = [0u8; 57]; + let mut writer = crate::format::Buf::new(&mut buf); + fmt::Write::write_fmt(&mut writer, format_args!("integer `{}` as u128", v)).unwrap(); + Err(Error::invalid_type( + Unexpected::Other(writer.as_str()), + &self, + )) + } + + /// The input contains an `f32`. + /// + /// The default implementation forwards to [`visit_f64`]. + /// + /// [`visit_f64`]: #method.visit_f64 + fn visit_f32(self, v: f32) -> Result + where + E: Error, + { + self.visit_f64(v as f64) + } + + /// The input contains an `f64`. + /// + /// The default implementation fails with a type error. + fn visit_f64(self, v: f64) -> Result + where + E: Error, + { + Err(Error::invalid_type(Unexpected::Float(v), &self)) + } + + /// The input contains a `char`. + /// + /// The default implementation forwards to [`visit_str`] as a one-character + /// string. + /// + /// [`visit_str`]: #method.visit_str + #[inline] + fn visit_char(self, v: char) -> Result + where + E: Error, + { + self.visit_str(v.encode_utf8(&mut [0u8; 4])) + } + + /// The input contains a string. The lifetime of the string is ephemeral and + /// it may be destroyed after this method returns. + /// + /// This method allows the `Deserializer` to avoid a copy by retaining + /// ownership of any buffered data. `Deserialize` implementations that do + /// not benefit from taking ownership of `String` data should indicate that + /// to the deserializer by using `Deserializer::deserialize_str` rather than + /// `Deserializer::deserialize_string`. + /// + /// It is never correct to implement `visit_string` without implementing + /// `visit_str`. Implement neither, both, or just `visit_str`. + fn visit_str(self, v: &str) -> Result + where + E: Error, + { + Err(Error::invalid_type(Unexpected::Str(v), &self)) + } + + /// The input contains a string that lives at least as long as the + /// `Deserializer`. + /// + /// This enables zero-copy deserialization of strings in some formats. For + /// example JSON input containing the JSON string `"borrowed"` can be + /// deserialized with zero copying into a `&'a str` as long as the input + /// data outlives `'a`. + /// + /// The default implementation forwards to `visit_str`. + #[inline] + fn visit_borrowed_str(self, v: &'de str) -> Result + where + E: Error, + { + self.visit_str(v) + } + + /// The input contains a string and ownership of the string is being given + /// to the `Visitor`. + /// + /// This method allows the `Visitor` to avoid a copy by taking ownership of + /// a string created by the `Deserializer`. `Deserialize` implementations + /// that benefit from taking ownership of `String` data should indicate that + /// to the deserializer by using `Deserializer::deserialize_string` rather + /// than `Deserializer::deserialize_str`, although not every deserializer + /// will honor such a request. + /// + /// It is never correct to implement `visit_string` without implementing + /// `visit_str`. Implement neither, both, or just `visit_str`. + /// + /// The default implementation forwards to `visit_str` and then drops the + /// `String`. + #[inline] + #[cfg(any(feature = "std", feature = "alloc"))] + #[cfg_attr(docsrs, doc(cfg(any(feature = "std", feature = "alloc"))))] + fn visit_string(self, v: String) -> Result + where + E: Error, + { + self.visit_str(&v) + } + + /// The input contains a byte array. The lifetime of the byte array is + /// ephemeral and it may be destroyed after this method returns. + /// + /// This method allows the `Deserializer` to avoid a copy by retaining + /// ownership of any buffered data. `Deserialize` implementations that do + /// not benefit from taking ownership of `Vec` data should indicate that + /// to the deserializer by using `Deserializer::deserialize_bytes` rather + /// than `Deserializer::deserialize_byte_buf`. + /// + /// It is never correct to implement `visit_byte_buf` without implementing + /// `visit_bytes`. Implement neither, both, or just `visit_bytes`. + fn visit_bytes(self, v: &[u8]) -> Result + where + E: Error, + { + Err(Error::invalid_type(Unexpected::Bytes(v), &self)) + } + + /// The input contains a byte array that lives at least as long as the + /// `Deserializer`. + /// + /// This enables zero-copy deserialization of bytes in some formats. For + /// example Postcard data containing bytes can be deserialized with zero + /// copying into a `&'a [u8]` as long as the input data outlives `'a`. + /// + /// The default implementation forwards to `visit_bytes`. + #[inline] + fn visit_borrowed_bytes(self, v: &'de [u8]) -> Result + where + E: Error, + { + self.visit_bytes(v) + } + + /// The input contains a byte array and ownership of the byte array is being + /// given to the `Visitor`. + /// + /// This method allows the `Visitor` to avoid a copy by taking ownership of + /// a byte buffer created by the `Deserializer`. `Deserialize` + /// implementations that benefit from taking ownership of `Vec` data + /// should indicate that to the deserializer by using + /// `Deserializer::deserialize_byte_buf` rather than + /// `Deserializer::deserialize_bytes`, although not every deserializer will + /// honor such a request. + /// + /// It is never correct to implement `visit_byte_buf` without implementing + /// `visit_bytes`. Implement neither, both, or just `visit_bytes`. + /// + /// The default implementation forwards to `visit_bytes` and then drops the + /// `Vec`. + #[cfg(any(feature = "std", feature = "alloc"))] + #[cfg_attr(docsrs, doc(cfg(any(feature = "std", feature = "alloc"))))] + fn visit_byte_buf(self, v: Vec) -> Result + where + E: Error, + { + self.visit_bytes(&v) + } + + /// The input contains an optional that is absent. + /// + /// The default implementation fails with a type error. + fn visit_none(self) -> Result + where + E: Error, + { + Err(Error::invalid_type(Unexpected::Option, &self)) + } + + /// The input contains an optional that is present. + /// + /// The default implementation fails with a type error. + fn visit_some(self, deserializer: D) -> Result + where + D: Deserializer<'de>, + { + let _ = deserializer; + Err(Error::invalid_type(Unexpected::Option, &self)) + } + + /// The input contains a unit `()`. + /// + /// The default implementation fails with a type error. + fn visit_unit(self) -> Result + where + E: Error, + { + Err(Error::invalid_type(Unexpected::Unit, &self)) + } + + /// The input contains a newtype struct. + /// + /// The content of the newtype struct may be read from the given + /// `Deserializer`. + /// + /// The default implementation fails with a type error. + fn visit_newtype_struct(self, deserializer: D) -> Result + where + D: Deserializer<'de>, + { + let _ = deserializer; + Err(Error::invalid_type(Unexpected::NewtypeStruct, &self)) + } + + /// The input contains a sequence of elements. + /// + /// The default implementation fails with a type error. + fn visit_seq(self, seq: A) -> Result + where + A: SeqAccess<'de>, + { + let _ = seq; + Err(Error::invalid_type(Unexpected::Seq, &self)) + } + + /// The input contains a key-value map. + /// + /// The default implementation fails with a type error. + fn visit_map(self, map: A) -> Result + where + A: MapAccess<'de>, + { + let _ = map; + Err(Error::invalid_type(Unexpected::Map, &self)) + } + + /// The input contains an enum. + /// + /// The default implementation fails with a type error. + fn visit_enum(self, data: A) -> Result + where + A: EnumAccess<'de>, + { + let _ = data; + Err(Error::invalid_type(Unexpected::Enum, &self)) + } + + // Used when deserializing a flattened Option field. Not public API. + #[doc(hidden)] + fn __private_visit_untagged_option(self, _: D) -> Result + where + D: Deserializer<'de>, + { + Err(()) + } +} + +//////////////////////////////////////////////////////////////////////////////// + +/// Provides a `Visitor` access to each element of a sequence in the input. +/// +/// This is a trait that a `Deserializer` passes to a `Visitor` implementation, +/// which deserializes each item in a sequence. +/// +/// # Lifetime +/// +/// The `'de` lifetime of this trait is the lifetime of data that may be +/// borrowed by deserialized sequence elements. See the page [Understanding +/// deserializer lifetimes] for a more detailed explanation of these lifetimes. +/// +/// [Understanding deserializer lifetimes]: https://serde.rs/lifetimes.html +/// +/// # Example implementation +/// +/// The [example data format] presented on the website demonstrates an +/// implementation of `SeqAccess` for a basic JSON data format. +/// +/// [example data format]: https://serde.rs/data-format.html +pub trait SeqAccess<'de> { + /// The error type that can be returned if some error occurs during + /// deserialization. + type Error: Error; + + /// This returns `Ok(Some(value))` for the next value in the sequence, or + /// `Ok(None)` if there are no more remaining items. + /// + /// `Deserialize` implementations should typically use + /// `SeqAccess::next_element` instead. + fn next_element_seed(&mut self, seed: T) -> Result, Self::Error> + where + T: DeserializeSeed<'de>; + + /// This returns `Ok(Some(value))` for the next value in the sequence, or + /// `Ok(None)` if there are no more remaining items. + /// + /// This method exists as a convenience for `Deserialize` implementations. + /// `SeqAccess` implementations should not override the default behavior. + #[inline] + fn next_element(&mut self) -> Result, Self::Error> + where + T: Deserialize<'de>, + { + self.next_element_seed(PhantomData) + } + + /// Returns the number of elements remaining in the sequence, if known. + #[inline] + fn size_hint(&self) -> Option { + None + } +} + +impl<'de, 'a, A> SeqAccess<'de> for &'a mut A +where + A: ?Sized + SeqAccess<'de>, +{ + type Error = A::Error; + + #[inline] + fn next_element_seed(&mut self, seed: T) -> Result, Self::Error> + where + T: DeserializeSeed<'de>, + { + (**self).next_element_seed(seed) + } + + #[inline] + fn next_element(&mut self) -> Result, Self::Error> + where + T: Deserialize<'de>, + { + (**self).next_element() + } + + #[inline] + fn size_hint(&self) -> Option { + (**self).size_hint() + } +} + +//////////////////////////////////////////////////////////////////////////////// + +/// Provides a `Visitor` access to each entry of a map in the input. +/// +/// This is a trait that a `Deserializer` passes to a `Visitor` implementation. +/// +/// # Lifetime +/// +/// The `'de` lifetime of this trait is the lifetime of data that may be +/// borrowed by deserialized map entries. See the page [Understanding +/// deserializer lifetimes] for a more detailed explanation of these lifetimes. +/// +/// [Understanding deserializer lifetimes]: https://serde.rs/lifetimes.html +/// +/// # Example implementation +/// +/// The [example data format] presented on the website demonstrates an +/// implementation of `MapAccess` for a basic JSON data format. +/// +/// [example data format]: https://serde.rs/data-format.html +pub trait MapAccess<'de> { + /// The error type that can be returned if some error occurs during + /// deserialization. + type Error: Error; + + /// This returns `Ok(Some(key))` for the next key in the map, or `Ok(None)` + /// if there are no more remaining entries. + /// + /// `Deserialize` implementations should typically use + /// `MapAccess::next_key` or `MapAccess::next_entry` instead. + fn next_key_seed(&mut self, seed: K) -> Result, Self::Error> + where + K: DeserializeSeed<'de>; + + /// This returns a `Ok(value)` for the next value in the map. + /// + /// `Deserialize` implementations should typically use + /// `MapAccess::next_value` instead. + /// + /// # Panics + /// + /// Calling `next_value_seed` before `next_key_seed` is incorrect and is + /// allowed to panic or return bogus results. + fn next_value_seed(&mut self, seed: V) -> Result + where + V: DeserializeSeed<'de>; + + /// This returns `Ok(Some((key, value)))` for the next (key-value) pair in + /// the map, or `Ok(None)` if there are no more remaining items. + /// + /// `MapAccess` implementations should override the default behavior if a + /// more efficient implementation is possible. + /// + /// `Deserialize` implementations should typically use + /// `MapAccess::next_entry` instead. + #[inline] + fn next_entry_seed( + &mut self, + kseed: K, + vseed: V, + ) -> Result, Self::Error> + where + K: DeserializeSeed<'de>, + V: DeserializeSeed<'de>, + { + match tri!(self.next_key_seed(kseed)) { + Some(key) => { + let value = tri!(self.next_value_seed(vseed)); + Ok(Some((key, value))) + } + None => Ok(None), + } + } + + /// This returns `Ok(Some(key))` for the next key in the map, or `Ok(None)` + /// if there are no more remaining entries. + /// + /// This method exists as a convenience for `Deserialize` implementations. + /// `MapAccess` implementations should not override the default behavior. + #[inline] + fn next_key(&mut self) -> Result, Self::Error> + where + K: Deserialize<'de>, + { + self.next_key_seed(PhantomData) + } + + /// This returns a `Ok(value)` for the next value in the map. + /// + /// This method exists as a convenience for `Deserialize` implementations. + /// `MapAccess` implementations should not override the default behavior. + /// + /// # Panics + /// + /// Calling `next_value` before `next_key` is incorrect and is allowed to + /// panic or return bogus results. + #[inline] + fn next_value(&mut self) -> Result + where + V: Deserialize<'de>, + { + self.next_value_seed(PhantomData) + } + + /// This returns `Ok(Some((key, value)))` for the next (key-value) pair in + /// the map, or `Ok(None)` if there are no more remaining items. + /// + /// This method exists as a convenience for `Deserialize` implementations. + /// `MapAccess` implementations should not override the default behavior. + #[inline] + fn next_entry(&mut self) -> Result, Self::Error> + where + K: Deserialize<'de>, + V: Deserialize<'de>, + { + self.next_entry_seed(PhantomData, PhantomData) + } + + /// Returns the number of entries remaining in the map, if known. + #[inline] + fn size_hint(&self) -> Option { + None + } +} + +impl<'de, 'a, A> MapAccess<'de> for &'a mut A +where + A: ?Sized + MapAccess<'de>, +{ + type Error = A::Error; + + #[inline] + fn next_key_seed(&mut self, seed: K) -> Result, Self::Error> + where + K: DeserializeSeed<'de>, + { + (**self).next_key_seed(seed) + } + + #[inline] + fn next_value_seed(&mut self, seed: V) -> Result + where + V: DeserializeSeed<'de>, + { + (**self).next_value_seed(seed) + } + + #[inline] + fn next_entry_seed( + &mut self, + kseed: K, + vseed: V, + ) -> Result, Self::Error> + where + K: DeserializeSeed<'de>, + V: DeserializeSeed<'de>, + { + (**self).next_entry_seed(kseed, vseed) + } + + #[inline] + fn next_entry(&mut self) -> Result, Self::Error> + where + K: Deserialize<'de>, + V: Deserialize<'de>, + { + (**self).next_entry() + } + + #[inline] + fn next_key(&mut self) -> Result, Self::Error> + where + K: Deserialize<'de>, + { + (**self).next_key() + } + + #[inline] + fn next_value(&mut self) -> Result + where + V: Deserialize<'de>, + { + (**self).next_value() + } + + #[inline] + fn size_hint(&self) -> Option { + (**self).size_hint() + } +} + +//////////////////////////////////////////////////////////////////////////////// + +/// Provides a `Visitor` access to the data of an enum in the input. +/// +/// `EnumAccess` is created by the `Deserializer` and passed to the +/// `Visitor` in order to identify which variant of an enum to deserialize. +/// +/// # Lifetime +/// +/// The `'de` lifetime of this trait is the lifetime of data that may be +/// borrowed by the deserialized enum variant. See the page [Understanding +/// deserializer lifetimes] for a more detailed explanation of these lifetimes. +/// +/// [Understanding deserializer lifetimes]: https://serde.rs/lifetimes.html +/// +/// # Example implementation +/// +/// The [example data format] presented on the website demonstrates an +/// implementation of `EnumAccess` for a basic JSON data format. +/// +/// [example data format]: https://serde.rs/data-format.html +pub trait EnumAccess<'de>: Sized { + /// The error type that can be returned if some error occurs during + /// deserialization. + type Error: Error; + /// The `Visitor` that will be used to deserialize the content of the enum + /// variant. + type Variant: VariantAccess<'de, Error = Self::Error>; + + /// `variant` is called to identify which variant to deserialize. + /// + /// `Deserialize` implementations should typically use `EnumAccess::variant` + /// instead. + fn variant_seed(self, seed: V) -> Result<(V::Value, Self::Variant), Self::Error> + where + V: DeserializeSeed<'de>; + + /// `variant` is called to identify which variant to deserialize. + /// + /// This method exists as a convenience for `Deserialize` implementations. + /// `EnumAccess` implementations should not override the default behavior. + #[inline] + fn variant(self) -> Result<(V, Self::Variant), Self::Error> + where + V: Deserialize<'de>, + { + self.variant_seed(PhantomData) + } +} + +/// `VariantAccess` is a visitor that is created by the `Deserializer` and +/// passed to the `Deserialize` to deserialize the content of a particular enum +/// variant. +/// +/// # Lifetime +/// +/// The `'de` lifetime of this trait is the lifetime of data that may be +/// borrowed by the deserialized enum variant. See the page [Understanding +/// deserializer lifetimes] for a more detailed explanation of these lifetimes. +/// +/// [Understanding deserializer lifetimes]: https://serde.rs/lifetimes.html +/// +/// # Example implementation +/// +/// The [example data format] presented on the website demonstrates an +/// implementation of `VariantAccess` for a basic JSON data format. +/// +/// [example data format]: https://serde.rs/data-format.html +pub trait VariantAccess<'de>: Sized { + /// The error type that can be returned if some error occurs during + /// deserialization. Must match the error type of our `EnumAccess`. + type Error: Error; + + /// Called when deserializing a variant with no values. + /// + /// If the data contains a different type of variant, the following + /// `invalid_type` error should be constructed: + /// + /// ```edition2021 + /// # use serde::de::{self, value, DeserializeSeed, Visitor, VariantAccess, Unexpected}; + /// # + /// # struct X; + /// # + /// # impl<'de> VariantAccess<'de> for X { + /// # type Error = value::Error; + /// # + /// fn unit_variant(self) -> Result<(), Self::Error> { + /// // What the data actually contained; suppose it is a tuple variant. + /// let unexp = Unexpected::TupleVariant; + /// Err(de::Error::invalid_type(unexp, &"unit variant")) + /// } + /// # + /// # fn newtype_variant_seed(self, _: T) -> Result + /// # where + /// # T: DeserializeSeed<'de>, + /// # { unimplemented!() } + /// # + /// # fn tuple_variant(self, _: usize, _: V) -> Result + /// # where + /// # V: Visitor<'de>, + /// # { unimplemented!() } + /// # + /// # fn struct_variant(self, _: &[&str], _: V) -> Result + /// # where + /// # V: Visitor<'de>, + /// # { unimplemented!() } + /// # } + /// ``` + fn unit_variant(self) -> Result<(), Self::Error>; + + /// Called when deserializing a variant with a single value. + /// + /// `Deserialize` implementations should typically use + /// `VariantAccess::newtype_variant` instead. + /// + /// If the data contains a different type of variant, the following + /// `invalid_type` error should be constructed: + /// + /// ```edition2021 + /// # use serde::de::{self, value, DeserializeSeed, Visitor, VariantAccess, Unexpected}; + /// # + /// # struct X; + /// # + /// # impl<'de> VariantAccess<'de> for X { + /// # type Error = value::Error; + /// # + /// # fn unit_variant(self) -> Result<(), Self::Error> { + /// # unimplemented!() + /// # } + /// # + /// fn newtype_variant_seed(self, _seed: T) -> Result + /// where + /// T: DeserializeSeed<'de>, + /// { + /// // What the data actually contained; suppose it is a unit variant. + /// let unexp = Unexpected::UnitVariant; + /// Err(de::Error::invalid_type(unexp, &"newtype variant")) + /// } + /// # + /// # fn tuple_variant(self, _: usize, _: V) -> Result + /// # where + /// # V: Visitor<'de>, + /// # { unimplemented!() } + /// # + /// # fn struct_variant(self, _: &[&str], _: V) -> Result + /// # where + /// # V: Visitor<'de>, + /// # { unimplemented!() } + /// # } + /// ``` + fn newtype_variant_seed(self, seed: T) -> Result + where + T: DeserializeSeed<'de>; + + /// Called when deserializing a variant with a single value. + /// + /// This method exists as a convenience for `Deserialize` implementations. + /// `VariantAccess` implementations should not override the default + /// behavior. + #[inline] + fn newtype_variant(self) -> Result + where + T: Deserialize<'de>, + { + self.newtype_variant_seed(PhantomData) + } + + /// Called when deserializing a tuple-like variant. + /// + /// The `len` is the number of fields expected in the tuple variant. + /// + /// If the data contains a different type of variant, the following + /// `invalid_type` error should be constructed: + /// + /// ```edition2021 + /// # use serde::de::{self, value, DeserializeSeed, Visitor, VariantAccess, Unexpected}; + /// # + /// # struct X; + /// # + /// # impl<'de> VariantAccess<'de> for X { + /// # type Error = value::Error; + /// # + /// # fn unit_variant(self) -> Result<(), Self::Error> { + /// # unimplemented!() + /// # } + /// # + /// # fn newtype_variant_seed(self, _: T) -> Result + /// # where + /// # T: DeserializeSeed<'de>, + /// # { unimplemented!() } + /// # + /// fn tuple_variant(self, _len: usize, _visitor: V) -> Result + /// where + /// V: Visitor<'de>, + /// { + /// // What the data actually contained; suppose it is a unit variant. + /// let unexp = Unexpected::UnitVariant; + /// Err(de::Error::invalid_type(unexp, &"tuple variant")) + /// } + /// # + /// # fn struct_variant(self, _: &[&str], _: V) -> Result + /// # where + /// # V: Visitor<'de>, + /// # { unimplemented!() } + /// # } + /// ``` + fn tuple_variant(self, len: usize, visitor: V) -> Result + where + V: Visitor<'de>; + + /// Called when deserializing a struct-like variant. + /// + /// The `fields` are the names of the fields of the struct variant. + /// + /// If the data contains a different type of variant, the following + /// `invalid_type` error should be constructed: + /// + /// ```edition2021 + /// # use serde::de::{self, value, DeserializeSeed, Visitor, VariantAccess, Unexpected}; + /// # + /// # struct X; + /// # + /// # impl<'de> VariantAccess<'de> for X { + /// # type Error = value::Error; + /// # + /// # fn unit_variant(self) -> Result<(), Self::Error> { + /// # unimplemented!() + /// # } + /// # + /// # fn newtype_variant_seed(self, _: T) -> Result + /// # where + /// # T: DeserializeSeed<'de>, + /// # { unimplemented!() } + /// # + /// # fn tuple_variant(self, _: usize, _: V) -> Result + /// # where + /// # V: Visitor<'de>, + /// # { unimplemented!() } + /// # + /// fn struct_variant( + /// self, + /// _fields: &'static [&'static str], + /// _visitor: V, + /// ) -> Result + /// where + /// V: Visitor<'de>, + /// { + /// // What the data actually contained; suppose it is a unit variant. + /// let unexp = Unexpected::UnitVariant; + /// Err(de::Error::invalid_type(unexp, &"struct variant")) + /// } + /// # } + /// ``` + fn struct_variant( + self, + fields: &'static [&'static str], + visitor: V, + ) -> Result + where + V: Visitor<'de>; +} + +//////////////////////////////////////////////////////////////////////////////// + +/// Converts an existing value into a `Deserializer` from which other values can +/// be deserialized. +/// +/// # Lifetime +/// +/// The `'de` lifetime of this trait is the lifetime of data that may be +/// borrowed from the resulting `Deserializer`. See the page [Understanding +/// deserializer lifetimes] for a more detailed explanation of these lifetimes. +/// +/// [Understanding deserializer lifetimes]: https://serde.rs/lifetimes.html +/// +/// # Example +/// +/// ```edition2021 +/// use serde::de::{value, Deserialize, IntoDeserializer}; +/// use serde_derive::Deserialize; +/// use std::str::FromStr; +/// +/// #[derive(Deserialize)] +/// enum Setting { +/// On, +/// Off, +/// } +/// +/// impl FromStr for Setting { +/// type Err = value::Error; +/// +/// fn from_str(s: &str) -> Result { +/// Self::deserialize(s.into_deserializer()) +/// } +/// } +/// ``` +pub trait IntoDeserializer<'de, E: Error = value::Error> { + /// The type of the deserializer being converted into. + type Deserializer: Deserializer<'de, Error = E>; + + /// Convert this value into a deserializer. + fn into_deserializer(self) -> Self::Deserializer; +} + +//////////////////////////////////////////////////////////////////////////////// + +/// Used in error messages. +/// +/// - expected `a` +/// - expected `a` or `b` +/// - expected one of `a`, `b`, `c` +/// +/// The slice of names must not be empty. +struct OneOf { + names: &'static [&'static str], +} + +impl Display for OneOf { + fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + match self.names.len() { + 0 => panic!(), // special case elsewhere + 1 => write!(formatter, "`{}`", self.names[0]), + 2 => write!(formatter, "`{}` or `{}`", self.names[0], self.names[1]), + _ => { + tri!(formatter.write_str("one of ")); + for (i, alt) in self.names.iter().enumerate() { + if i > 0 { + tri!(formatter.write_str(", ")); + } + tri!(write!(formatter, "`{}`", alt)); + } + Ok(()) + } + } + } +} + +struct WithDecimalPoint(f64); + +impl Display for WithDecimalPoint { + fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + struct LookForDecimalPoint<'f, 'a> { + formatter: &'f mut fmt::Formatter<'a>, + has_decimal_point: bool, + } + + impl<'f, 'a> fmt::Write for LookForDecimalPoint<'f, 'a> { + fn write_str(&mut self, fragment: &str) -> fmt::Result { + self.has_decimal_point |= fragment.contains('.'); + self.formatter.write_str(fragment) + } + + fn write_char(&mut self, ch: char) -> fmt::Result { + self.has_decimal_point |= ch == '.'; + self.formatter.write_char(ch) + } + } + + if self.0.is_finite() { + let mut writer = LookForDecimalPoint { + formatter, + has_decimal_point: false, + }; + tri!(write!(writer, "{}", self.0)); + if !writer.has_decimal_point { + tri!(formatter.write_str(".0")); + } + } else { + tri!(write!(formatter, "{}", self.0)); + } + Ok(()) + } +} diff --git a/vendor/serde/src/de/seed.rs b/vendor/serde/src/de/seed.rs new file mode 100644 index 0000000..52fb89d --- /dev/null +++ b/vendor/serde/src/de/seed.rs @@ -0,0 +1,19 @@ +use crate::de::{Deserialize, DeserializeSeed, Deserializer}; + +/// A DeserializeSeed helper for implementing deserialize_in_place Visitors. +/// +/// Wraps a mutable reference and calls deserialize_in_place on it. +pub struct InPlaceSeed<'a, T: 'a>(pub &'a mut T); + +impl<'a, 'de, T> DeserializeSeed<'de> for InPlaceSeed<'a, T> +where + T: Deserialize<'de>, +{ + type Value = (); + fn deserialize(self, deserializer: D) -> Result + where + D: Deserializer<'de>, + { + T::deserialize_in_place(deserializer, self.0) + } +} diff --git a/vendor/serde/src/de/size_hint.rs b/vendor/serde/src/de/size_hint.rs new file mode 100644 index 0000000..4a4fe25 --- /dev/null +++ b/vendor/serde/src/de/size_hint.rs @@ -0,0 +1,29 @@ +use crate::lib::*; + +pub fn from_bounds(iter: &I) -> Option +where + I: Iterator, +{ + helper(iter.size_hint()) +} + +#[cfg(any(feature = "std", feature = "alloc"))] +pub fn cautious(hint: Option) -> usize { + const MAX_PREALLOC_BYTES: usize = 1024 * 1024; + + if mem::size_of::() == 0 { + 0 + } else { + cmp::min( + hint.unwrap_or(0), + MAX_PREALLOC_BYTES / mem::size_of::(), + ) + } +} + +fn helper(bounds: (usize, Option)) -> Option { + match bounds { + (lower, Some(upper)) if lower == upper => Some(upper), + _ => None, + } +} diff --git a/vendor/serde/src/de/value.rs b/vendor/serde/src/de/value.rs new file mode 100644 index 0000000..1ec9477 --- /dev/null +++ b/vendor/serde/src/de/value.rs @@ -0,0 +1,1720 @@ +//! Building blocks for deserializing basic values using the `IntoDeserializer` +//! trait. +//! +//! ```edition2021 +//! use serde::de::{value, Deserialize, IntoDeserializer}; +//! use serde_derive::Deserialize; +//! use std::str::FromStr; +//! +//! #[derive(Deserialize)] +//! enum Setting { +//! On, +//! Off, +//! } +//! +//! impl FromStr for Setting { +//! type Err = value::Error; +//! +//! fn from_str(s: &str) -> Result { +//! Self::deserialize(s.into_deserializer()) +//! } +//! } +//! ``` + +use crate::lib::*; + +use self::private::{First, Second}; +use crate::de::{self, size_hint, Deserializer, Expected, IntoDeserializer, SeqAccess, Visitor}; +use crate::ser; + +//////////////////////////////////////////////////////////////////////////////// + +// For structs that contain a PhantomData. We do not want the trait +// bound `E: Clone` inferred by derive(Clone). +macro_rules! impl_copy_clone { + ($ty:ident $(<$lifetime:tt>)*) => { + impl<$($lifetime,)* E> Copy for $ty<$($lifetime,)* E> {} + + impl<$($lifetime,)* E> Clone for $ty<$($lifetime,)* E> { + fn clone(&self) -> Self { + *self + } + } + }; +} + +//////////////////////////////////////////////////////////////////////////////// + +/// A minimal representation of all possible errors that can occur using the +/// `IntoDeserializer` trait. +#[derive(Clone, PartialEq)] +pub struct Error { + err: ErrorImpl, +} + +#[cfg(any(feature = "std", feature = "alloc"))] +type ErrorImpl = Box; +#[cfg(not(any(feature = "std", feature = "alloc")))] +type ErrorImpl = (); + +impl de::Error for Error { + #[cfg(any(feature = "std", feature = "alloc"))] + #[cold] + fn custom(msg: T) -> Self + where + T: Display, + { + Error { + err: msg.to_string().into_boxed_str(), + } + } + + #[cfg(not(any(feature = "std", feature = "alloc")))] + #[cold] + fn custom(msg: T) -> Self + where + T: Display, + { + let _ = msg; + Error { err: () } + } +} + +impl ser::Error for Error { + #[cold] + fn custom(msg: T) -> Self + where + T: Display, + { + de::Error::custom(msg) + } +} + +impl Display for Error { + #[cfg(any(feature = "std", feature = "alloc"))] + fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str(&self.err) + } + + #[cfg(not(any(feature = "std", feature = "alloc")))] + fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("Serde deserialization error") + } +} + +impl Debug for Error { + fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + let mut debug = formatter.debug_tuple("Error"); + #[cfg(any(feature = "std", feature = "alloc"))] + debug.field(&self.err); + debug.finish() + } +} + +#[cfg(feature = "std")] +#[cfg_attr(docsrs, doc(cfg(feature = "std")))] +impl error::Error for Error { + fn description(&self) -> &str { + &self.err + } +} + +//////////////////////////////////////////////////////////////////////////////// + +impl<'de, E> IntoDeserializer<'de, E> for () +where + E: de::Error, +{ + type Deserializer = UnitDeserializer; + + fn into_deserializer(self) -> UnitDeserializer { + UnitDeserializer::new() + } +} + +/// A deserializer holding a `()`. +pub struct UnitDeserializer { + marker: PhantomData, +} + +impl_copy_clone!(UnitDeserializer); + +impl UnitDeserializer { + #[allow(missing_docs)] + pub fn new() -> Self { + UnitDeserializer { + marker: PhantomData, + } + } +} + +impl<'de, E> de::Deserializer<'de> for UnitDeserializer +where + E: de::Error, +{ + type Error = E; + + forward_to_deserialize_any! { + bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string + bytes byte_buf unit unit_struct newtype_struct seq tuple tuple_struct + map struct enum identifier ignored_any + } + + fn deserialize_any(self, visitor: V) -> Result + where + V: de::Visitor<'de>, + { + visitor.visit_unit() + } + + fn deserialize_option(self, visitor: V) -> Result + where + V: de::Visitor<'de>, + { + visitor.visit_none() + } +} + +impl Debug for UnitDeserializer { + fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.debug_struct("UnitDeserializer").finish() + } +} + +//////////////////////////////////////////////////////////////////////////////// + +/// A deserializer that cannot be instantiated. +#[cfg(feature = "unstable")] +#[cfg_attr(docsrs, doc(cfg(feature = "unstable")))] +pub struct NeverDeserializer { + never: !, + marker: PhantomData, +} + +#[cfg(feature = "unstable")] +#[cfg_attr(docsrs, doc(cfg(feature = "unstable")))] +impl<'de, E> IntoDeserializer<'de, E> for ! +where + E: de::Error, +{ + type Deserializer = NeverDeserializer; + + fn into_deserializer(self) -> Self::Deserializer { + self + } +} + +#[cfg(feature = "unstable")] +impl<'de, E> de::Deserializer<'de> for NeverDeserializer +where + E: de::Error, +{ + type Error = E; + + fn deserialize_any(self, _visitor: V) -> Result + where + V: de::Visitor<'de>, + { + self.never + } + + forward_to_deserialize_any! { + bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string + bytes byte_buf option unit unit_struct newtype_struct seq tuple + tuple_struct map struct enum identifier ignored_any + } +} + +//////////////////////////////////////////////////////////////////////////////// + +macro_rules! primitive_deserializer { + ($ty:ty, $doc:tt, $name:ident, $method:ident $($cast:tt)*) => { + #[doc = "A deserializer holding"] + #[doc = $doc] + pub struct $name { + value: $ty, + marker: PhantomData + } + + impl_copy_clone!($name); + + impl<'de, E> IntoDeserializer<'de, E> for $ty + where + E: de::Error, + { + type Deserializer = $name; + + fn into_deserializer(self) -> $name { + $name::new(self) + } + } + + impl $name { + #[allow(missing_docs)] + pub fn new(value: $ty) -> Self { + $name { + value, + marker: PhantomData, + } + } + } + + impl<'de, E> de::Deserializer<'de> for $name + where + E: de::Error, + { + type Error = E; + + forward_to_deserialize_any! { + bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str + string bytes byte_buf option unit unit_struct newtype_struct seq + tuple tuple_struct map struct enum identifier ignored_any + } + + fn deserialize_any(self, visitor: V) -> Result + where + V: de::Visitor<'de>, + { + visitor.$method(self.value $($cast)*) + } + } + + impl Debug for $name { + fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter + .debug_struct(stringify!($name)) + .field("value", &self.value) + .finish() + } + } + } +} + +primitive_deserializer!(bool, "a `bool`.", BoolDeserializer, visit_bool); +primitive_deserializer!(i8, "an `i8`.", I8Deserializer, visit_i8); +primitive_deserializer!(i16, "an `i16`.", I16Deserializer, visit_i16); +primitive_deserializer!(i32, "an `i32`.", I32Deserializer, visit_i32); +primitive_deserializer!(i64, "an `i64`.", I64Deserializer, visit_i64); +primitive_deserializer!(i128, "an `i128`.", I128Deserializer, visit_i128); +primitive_deserializer!(isize, "an `isize`.", IsizeDeserializer, visit_i64 as i64); +primitive_deserializer!(u8, "a `u8`.", U8Deserializer, visit_u8); +primitive_deserializer!(u16, "a `u16`.", U16Deserializer, visit_u16); +primitive_deserializer!(u64, "a `u64`.", U64Deserializer, visit_u64); +primitive_deserializer!(u128, "a `u128`.", U128Deserializer, visit_u128); +primitive_deserializer!(usize, "a `usize`.", UsizeDeserializer, visit_u64 as u64); +primitive_deserializer!(f32, "an `f32`.", F32Deserializer, visit_f32); +primitive_deserializer!(f64, "an `f64`.", F64Deserializer, visit_f64); +primitive_deserializer!(char, "a `char`.", CharDeserializer, visit_char); + +/// A deserializer holding a `u32`. +pub struct U32Deserializer { + value: u32, + marker: PhantomData, +} + +impl_copy_clone!(U32Deserializer); + +impl<'de, E> IntoDeserializer<'de, E> for u32 +where + E: de::Error, +{ + type Deserializer = U32Deserializer; + + fn into_deserializer(self) -> U32Deserializer { + U32Deserializer::new(self) + } +} + +impl U32Deserializer { + #[allow(missing_docs)] + pub fn new(value: u32) -> Self { + U32Deserializer { + value, + marker: PhantomData, + } + } +} + +impl<'de, E> de::Deserializer<'de> for U32Deserializer +where + E: de::Error, +{ + type Error = E; + + forward_to_deserialize_any! { + bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string + bytes byte_buf option unit unit_struct newtype_struct seq tuple + tuple_struct map struct identifier ignored_any + } + + fn deserialize_any(self, visitor: V) -> Result + where + V: de::Visitor<'de>, + { + visitor.visit_u32(self.value) + } + + fn deserialize_enum( + self, + name: &str, + variants: &'static [&'static str], + visitor: V, + ) -> Result + where + V: de::Visitor<'de>, + { + let _ = name; + let _ = variants; + visitor.visit_enum(self) + } +} + +impl<'de, E> de::EnumAccess<'de> for U32Deserializer +where + E: de::Error, +{ + type Error = E; + type Variant = private::UnitOnly; + + fn variant_seed(self, seed: T) -> Result<(T::Value, Self::Variant), Self::Error> + where + T: de::DeserializeSeed<'de>, + { + seed.deserialize(self).map(private::unit_only) + } +} + +impl Debug for U32Deserializer { + fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter + .debug_struct("U32Deserializer") + .field("value", &self.value) + .finish() + } +} + +//////////////////////////////////////////////////////////////////////////////// + +/// A deserializer holding a `&str`. +pub struct StrDeserializer<'a, E> { + value: &'a str, + marker: PhantomData, +} + +impl_copy_clone!(StrDeserializer<'de>); + +impl<'de, 'a, E> IntoDeserializer<'de, E> for &'a str +where + E: de::Error, +{ + type Deserializer = StrDeserializer<'a, E>; + + fn into_deserializer(self) -> StrDeserializer<'a, E> { + StrDeserializer::new(self) + } +} + +impl<'a, E> StrDeserializer<'a, E> { + #[allow(missing_docs)] + pub fn new(value: &'a str) -> Self { + StrDeserializer { + value, + marker: PhantomData, + } + } +} + +impl<'de, 'a, E> de::Deserializer<'de> for StrDeserializer<'a, E> +where + E: de::Error, +{ + type Error = E; + + fn deserialize_any(self, visitor: V) -> Result + where + V: de::Visitor<'de>, + { + visitor.visit_str(self.value) + } + + fn deserialize_enum( + self, + name: &str, + variants: &'static [&'static str], + visitor: V, + ) -> Result + where + V: de::Visitor<'de>, + { + let _ = name; + let _ = variants; + visitor.visit_enum(self) + } + + forward_to_deserialize_any! { + bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string + bytes byte_buf option unit unit_struct newtype_struct seq tuple + tuple_struct map struct identifier ignored_any + } +} + +impl<'de, 'a, E> de::EnumAccess<'de> for StrDeserializer<'a, E> +where + E: de::Error, +{ + type Error = E; + type Variant = private::UnitOnly; + + fn variant_seed(self, seed: T) -> Result<(T::Value, Self::Variant), Self::Error> + where + T: de::DeserializeSeed<'de>, + { + seed.deserialize(self).map(private::unit_only) + } +} + +impl<'a, E> Debug for StrDeserializer<'a, E> { + fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter + .debug_struct("StrDeserializer") + .field("value", &self.value) + .finish() + } +} + +//////////////////////////////////////////////////////////////////////////////// + +/// A deserializer holding a `&str` with a lifetime tied to another +/// deserializer. +pub struct BorrowedStrDeserializer<'de, E> { + value: &'de str, + marker: PhantomData, +} + +impl_copy_clone!(BorrowedStrDeserializer<'de>); + +impl<'de, E> BorrowedStrDeserializer<'de, E> { + /// Create a new borrowed deserializer from the given string. + pub fn new(value: &'de str) -> BorrowedStrDeserializer<'de, E> { + BorrowedStrDeserializer { + value, + marker: PhantomData, + } + } +} + +impl<'de, E> de::Deserializer<'de> for BorrowedStrDeserializer<'de, E> +where + E: de::Error, +{ + type Error = E; + + fn deserialize_any(self, visitor: V) -> Result + where + V: de::Visitor<'de>, + { + visitor.visit_borrowed_str(self.value) + } + + fn deserialize_enum( + self, + name: &str, + variants: &'static [&'static str], + visitor: V, + ) -> Result + where + V: de::Visitor<'de>, + { + let _ = name; + let _ = variants; + visitor.visit_enum(self) + } + + forward_to_deserialize_any! { + bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string + bytes byte_buf option unit unit_struct newtype_struct seq tuple + tuple_struct map struct identifier ignored_any + } +} + +impl<'de, E> de::EnumAccess<'de> for BorrowedStrDeserializer<'de, E> +where + E: de::Error, +{ + type Error = E; + type Variant = private::UnitOnly; + + fn variant_seed(self, seed: T) -> Result<(T::Value, Self::Variant), Self::Error> + where + T: de::DeserializeSeed<'de>, + { + seed.deserialize(self).map(private::unit_only) + } +} + +impl<'de, E> Debug for BorrowedStrDeserializer<'de, E> { + fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter + .debug_struct("BorrowedStrDeserializer") + .field("value", &self.value) + .finish() + } +} + +//////////////////////////////////////////////////////////////////////////////// + +/// A deserializer holding a `String`. +#[cfg(any(feature = "std", feature = "alloc"))] +#[cfg_attr(docsrs, doc(cfg(any(feature = "std", feature = "alloc"))))] +pub struct StringDeserializer { + value: String, + marker: PhantomData, +} + +#[cfg(any(feature = "std", feature = "alloc"))] +impl Clone for StringDeserializer { + fn clone(&self) -> Self { + StringDeserializer { + value: self.value.clone(), + marker: PhantomData, + } + } +} + +#[cfg(any(feature = "std", feature = "alloc"))] +#[cfg_attr(docsrs, doc(cfg(any(feature = "std", feature = "alloc"))))] +impl<'de, E> IntoDeserializer<'de, E> for String +where + E: de::Error, +{ + type Deserializer = StringDeserializer; + + fn into_deserializer(self) -> StringDeserializer { + StringDeserializer::new(self) + } +} + +#[cfg(any(feature = "std", feature = "alloc"))] +impl StringDeserializer { + #[allow(missing_docs)] + pub fn new(value: String) -> Self { + StringDeserializer { + value, + marker: PhantomData, + } + } +} + +#[cfg(any(feature = "std", feature = "alloc"))] +impl<'de, E> de::Deserializer<'de> for StringDeserializer +where + E: de::Error, +{ + type Error = E; + + fn deserialize_any(self, visitor: V) -> Result + where + V: de::Visitor<'de>, + { + visitor.visit_string(self.value) + } + + fn deserialize_enum( + self, + name: &str, + variants: &'static [&'static str], + visitor: V, + ) -> Result + where + V: de::Visitor<'de>, + { + let _ = name; + let _ = variants; + visitor.visit_enum(self) + } + + forward_to_deserialize_any! { + bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string + bytes byte_buf option unit unit_struct newtype_struct seq tuple + tuple_struct map struct identifier ignored_any + } +} + +#[cfg(any(feature = "std", feature = "alloc"))] +impl<'de, E> de::EnumAccess<'de> for StringDeserializer +where + E: de::Error, +{ + type Error = E; + type Variant = private::UnitOnly; + + fn variant_seed(self, seed: T) -> Result<(T::Value, Self::Variant), Self::Error> + where + T: de::DeserializeSeed<'de>, + { + seed.deserialize(self).map(private::unit_only) + } +} + +#[cfg(any(feature = "std", feature = "alloc"))] +impl Debug for StringDeserializer { + fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter + .debug_struct("StringDeserializer") + .field("value", &self.value) + .finish() + } +} + +//////////////////////////////////////////////////////////////////////////////// + +/// A deserializer holding a `Cow`. +#[cfg(any(feature = "std", feature = "alloc"))] +#[cfg_attr(docsrs, doc(cfg(any(feature = "std", feature = "alloc"))))] +pub struct CowStrDeserializer<'a, E> { + value: Cow<'a, str>, + marker: PhantomData, +} + +#[cfg(any(feature = "std", feature = "alloc"))] +impl<'a, E> Clone for CowStrDeserializer<'a, E> { + fn clone(&self) -> Self { + CowStrDeserializer { + value: self.value.clone(), + marker: PhantomData, + } + } +} + +#[cfg(any(feature = "std", feature = "alloc"))] +#[cfg_attr(docsrs, doc(cfg(any(feature = "std", feature = "alloc"))))] +impl<'de, 'a, E> IntoDeserializer<'de, E> for Cow<'a, str> +where + E: de::Error, +{ + type Deserializer = CowStrDeserializer<'a, E>; + + fn into_deserializer(self) -> CowStrDeserializer<'a, E> { + CowStrDeserializer::new(self) + } +} + +#[cfg(any(feature = "std", feature = "alloc"))] +impl<'a, E> CowStrDeserializer<'a, E> { + #[allow(missing_docs)] + pub fn new(value: Cow<'a, str>) -> Self { + CowStrDeserializer { + value, + marker: PhantomData, + } + } +} + +#[cfg(any(feature = "std", feature = "alloc"))] +impl<'de, 'a, E> de::Deserializer<'de> for CowStrDeserializer<'a, E> +where + E: de::Error, +{ + type Error = E; + + fn deserialize_any(self, visitor: V) -> Result + where + V: de::Visitor<'de>, + { + match self.value { + Cow::Borrowed(string) => visitor.visit_str(string), + Cow::Owned(string) => visitor.visit_string(string), + } + } + + fn deserialize_enum( + self, + name: &str, + variants: &'static [&'static str], + visitor: V, + ) -> Result + where + V: de::Visitor<'de>, + { + let _ = name; + let _ = variants; + visitor.visit_enum(self) + } + + forward_to_deserialize_any! { + bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string + bytes byte_buf option unit unit_struct newtype_struct seq tuple + tuple_struct map struct identifier ignored_any + } +} + +#[cfg(any(feature = "std", feature = "alloc"))] +impl<'de, 'a, E> de::EnumAccess<'de> for CowStrDeserializer<'a, E> +where + E: de::Error, +{ + type Error = E; + type Variant = private::UnitOnly; + + fn variant_seed(self, seed: T) -> Result<(T::Value, Self::Variant), Self::Error> + where + T: de::DeserializeSeed<'de>, + { + seed.deserialize(self).map(private::unit_only) + } +} + +#[cfg(any(feature = "std", feature = "alloc"))] +impl<'a, E> Debug for CowStrDeserializer<'a, E> { + fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter + .debug_struct("CowStrDeserializer") + .field("value", &self.value) + .finish() + } +} + +//////////////////////////////////////////////////////////////////////////////// + +/// A deserializer holding a `&[u8]`. Always calls [`Visitor::visit_bytes`]. +pub struct BytesDeserializer<'a, E> { + value: &'a [u8], + marker: PhantomData, +} + +impl<'a, E> BytesDeserializer<'a, E> { + /// Create a new deserializer from the given bytes. + pub fn new(value: &'a [u8]) -> Self { + BytesDeserializer { + value, + marker: PhantomData, + } + } +} + +impl_copy_clone!(BytesDeserializer<'a>); + +impl<'de, 'a, E> IntoDeserializer<'de, E> for &'a [u8] +where + E: de::Error, +{ + type Deserializer = BytesDeserializer<'a, E>; + + fn into_deserializer(self) -> BytesDeserializer<'a, E> { + BytesDeserializer::new(self) + } +} + +impl<'de, 'a, E> Deserializer<'de> for BytesDeserializer<'a, E> +where + E: de::Error, +{ + type Error = E; + + fn deserialize_any(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + visitor.visit_bytes(self.value) + } + + forward_to_deserialize_any! { + bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string + bytes byte_buf option unit unit_struct newtype_struct seq tuple + tuple_struct map struct enum identifier ignored_any + } +} + +impl<'a, E> Debug for BytesDeserializer<'a, E> { + fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter + .debug_struct("BytesDeserializer") + .field("value", &self.value) + .finish() + } +} + +/// A deserializer holding a `&[u8]` with a lifetime tied to another +/// deserializer. Always calls [`Visitor::visit_borrowed_bytes`]. +pub struct BorrowedBytesDeserializer<'de, E> { + value: &'de [u8], + marker: PhantomData, +} + +impl<'de, E> BorrowedBytesDeserializer<'de, E> { + /// Create a new borrowed deserializer from the given borrowed bytes. + pub fn new(value: &'de [u8]) -> Self { + BorrowedBytesDeserializer { + value, + marker: PhantomData, + } + } +} + +impl_copy_clone!(BorrowedBytesDeserializer<'de>); + +impl<'de, E> Deserializer<'de> for BorrowedBytesDeserializer<'de, E> +where + E: de::Error, +{ + type Error = E; + + fn deserialize_any(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + visitor.visit_borrowed_bytes(self.value) + } + + forward_to_deserialize_any! { + bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string + bytes byte_buf option unit unit_struct newtype_struct seq tuple + tuple_struct map struct enum identifier ignored_any + } +} + +impl<'de, E> Debug for BorrowedBytesDeserializer<'de, E> { + fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter + .debug_struct("BorrowedBytesDeserializer") + .field("value", &self.value) + .finish() + } +} + +//////////////////////////////////////////////////////////////////////////////// + +/// A deserializer that iterates over a sequence. +#[derive(Clone)] +pub struct SeqDeserializer { + iter: iter::Fuse, + count: usize, + marker: PhantomData, +} + +impl SeqDeserializer +where + I: Iterator, +{ + /// Construct a new `SeqDeserializer`. + pub fn new(iter: I) -> Self { + SeqDeserializer { + iter: iter.fuse(), + count: 0, + marker: PhantomData, + } + } +} + +impl SeqDeserializer +where + I: Iterator, + E: de::Error, +{ + /// Check for remaining elements after passing a `SeqDeserializer` to + /// `Visitor::visit_seq`. + pub fn end(self) -> Result<(), E> { + let remaining = self.iter.count(); + if remaining == 0 { + Ok(()) + } else { + // First argument is the number of elements in the data, second + // argument is the number of elements expected by the Deserialize. + Err(de::Error::invalid_length( + self.count + remaining, + &ExpectedInSeq(self.count), + )) + } + } +} + +impl<'de, I, T, E> de::Deserializer<'de> for SeqDeserializer +where + I: Iterator, + T: IntoDeserializer<'de, E>, + E: de::Error, +{ + type Error = E; + + fn deserialize_any(mut self, visitor: V) -> Result + where + V: de::Visitor<'de>, + { + let v = tri!(visitor.visit_seq(&mut self)); + tri!(self.end()); + Ok(v) + } + + forward_to_deserialize_any! { + bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string + bytes byte_buf option unit unit_struct newtype_struct seq tuple + tuple_struct map struct enum identifier ignored_any + } +} + +impl<'de, I, T, E> de::SeqAccess<'de> for SeqDeserializer +where + I: Iterator, + T: IntoDeserializer<'de, E>, + E: de::Error, +{ + type Error = E; + + fn next_element_seed(&mut self, seed: V) -> Result, Self::Error> + where + V: de::DeserializeSeed<'de>, + { + match self.iter.next() { + Some(value) => { + self.count += 1; + seed.deserialize(value.into_deserializer()).map(Some) + } + None => Ok(None), + } + } + + fn size_hint(&self) -> Option { + size_hint::from_bounds(&self.iter) + } +} + +struct ExpectedInSeq(usize); + +impl Expected for ExpectedInSeq { + fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + if self.0 == 1 { + formatter.write_str("1 element in sequence") + } else { + write!(formatter, "{} elements in sequence", self.0) + } + } +} + +impl Debug for SeqDeserializer +where + I: Debug, +{ + fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter + .debug_struct("SeqDeserializer") + .field("iter", &self.iter) + .field("count", &self.count) + .finish() + } +} + +//////////////////////////////////////////////////////////////////////////////// + +#[cfg(any(feature = "std", feature = "alloc"))] +#[cfg_attr(docsrs, doc(cfg(any(feature = "std", feature = "alloc"))))] +impl<'de, T, E> IntoDeserializer<'de, E> for Vec +where + T: IntoDeserializer<'de, E>, + E: de::Error, +{ + type Deserializer = SeqDeserializer<::IntoIter, E>; + + fn into_deserializer(self) -> Self::Deserializer { + SeqDeserializer::new(self.into_iter()) + } +} + +#[cfg(any(feature = "std", feature = "alloc"))] +#[cfg_attr(docsrs, doc(cfg(any(feature = "std", feature = "alloc"))))] +impl<'de, T, E> IntoDeserializer<'de, E> for BTreeSet +where + T: IntoDeserializer<'de, E> + Eq + Ord, + E: de::Error, +{ + type Deserializer = SeqDeserializer<::IntoIter, E>; + + fn into_deserializer(self) -> Self::Deserializer { + SeqDeserializer::new(self.into_iter()) + } +} + +#[cfg(feature = "std")] +#[cfg_attr(docsrs, doc(cfg(feature = "std")))] +impl<'de, T, S, E> IntoDeserializer<'de, E> for HashSet +where + T: IntoDeserializer<'de, E> + Eq + Hash, + S: BuildHasher, + E: de::Error, +{ + type Deserializer = SeqDeserializer<::IntoIter, E>; + + fn into_deserializer(self) -> Self::Deserializer { + SeqDeserializer::new(self.into_iter()) + } +} + +//////////////////////////////////////////////////////////////////////////////// + +/// A deserializer holding a `SeqAccess`. +#[derive(Clone, Debug)] +pub struct SeqAccessDeserializer { + seq: A, +} + +impl SeqAccessDeserializer { + /// Construct a new `SeqAccessDeserializer`. + pub fn new(seq: A) -> Self { + SeqAccessDeserializer { seq } + } +} + +impl<'de, A> de::Deserializer<'de> for SeqAccessDeserializer +where + A: de::SeqAccess<'de>, +{ + type Error = A::Error; + + fn deserialize_any(self, visitor: V) -> Result + where + V: de::Visitor<'de>, + { + visitor.visit_seq(self.seq) + } + + forward_to_deserialize_any! { + bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string + bytes byte_buf option unit unit_struct newtype_struct seq tuple + tuple_struct map struct enum identifier ignored_any + } +} + +//////////////////////////////////////////////////////////////////////////////// + +/// A deserializer that iterates over a map. +pub struct MapDeserializer<'de, I, E> +where + I: Iterator, + I::Item: private::Pair, +{ + iter: iter::Fuse, + value: Option>, + count: usize, + lifetime: PhantomData<&'de ()>, + error: PhantomData, +} + +impl<'de, I, E> MapDeserializer<'de, I, E> +where + I: Iterator, + I::Item: private::Pair, +{ + /// Construct a new `MapDeserializer`. + pub fn new(iter: I) -> Self { + MapDeserializer { + iter: iter.fuse(), + value: None, + count: 0, + lifetime: PhantomData, + error: PhantomData, + } + } +} + +impl<'de, I, E> MapDeserializer<'de, I, E> +where + I: Iterator, + I::Item: private::Pair, + E: de::Error, +{ + /// Check for remaining elements after passing a `MapDeserializer` to + /// `Visitor::visit_map`. + pub fn end(self) -> Result<(), E> { + let remaining = self.iter.count(); + if remaining == 0 { + Ok(()) + } else { + // First argument is the number of elements in the data, second + // argument is the number of elements expected by the Deserialize. + Err(de::Error::invalid_length( + self.count + remaining, + &ExpectedInMap(self.count), + )) + } + } +} + +impl<'de, I, E> MapDeserializer<'de, I, E> +where + I: Iterator, + I::Item: private::Pair, +{ + fn next_pair(&mut self) -> Option<(First, Second)> { + match self.iter.next() { + Some(kv) => { + self.count += 1; + Some(private::Pair::split(kv)) + } + None => None, + } + } +} + +impl<'de, I, E> de::Deserializer<'de> for MapDeserializer<'de, I, E> +where + I: Iterator, + I::Item: private::Pair, + First: IntoDeserializer<'de, E>, + Second: IntoDeserializer<'de, E>, + E: de::Error, +{ + type Error = E; + + fn deserialize_any(mut self, visitor: V) -> Result + where + V: de::Visitor<'de>, + { + let value = tri!(visitor.visit_map(&mut self)); + tri!(self.end()); + Ok(value) + } + + fn deserialize_seq(mut self, visitor: V) -> Result + where + V: de::Visitor<'de>, + { + let value = tri!(visitor.visit_seq(&mut self)); + tri!(self.end()); + Ok(value) + } + + fn deserialize_tuple(self, len: usize, visitor: V) -> Result + where + V: de::Visitor<'de>, + { + let _ = len; + self.deserialize_seq(visitor) + } + + forward_to_deserialize_any! { + bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string + bytes byte_buf option unit unit_struct newtype_struct tuple_struct map + struct enum identifier ignored_any + } +} + +impl<'de, I, E> de::MapAccess<'de> for MapDeserializer<'de, I, E> +where + I: Iterator, + I::Item: private::Pair, + First: IntoDeserializer<'de, E>, + Second: IntoDeserializer<'de, E>, + E: de::Error, +{ + type Error = E; + + fn next_key_seed(&mut self, seed: T) -> Result, Self::Error> + where + T: de::DeserializeSeed<'de>, + { + match self.next_pair() { + Some((key, value)) => { + self.value = Some(value); + seed.deserialize(key.into_deserializer()).map(Some) + } + None => Ok(None), + } + } + + fn next_value_seed(&mut self, seed: T) -> Result + where + T: de::DeserializeSeed<'de>, + { + let value = self.value.take(); + // Panic because this indicates a bug in the program rather than an + // expected failure. + let value = value.expect("MapAccess::next_value called before next_key"); + seed.deserialize(value.into_deserializer()) + } + + fn next_entry_seed( + &mut self, + kseed: TK, + vseed: TV, + ) -> Result, Self::Error> + where + TK: de::DeserializeSeed<'de>, + TV: de::DeserializeSeed<'de>, + { + match self.next_pair() { + Some((key, value)) => { + let key = tri!(kseed.deserialize(key.into_deserializer())); + let value = tri!(vseed.deserialize(value.into_deserializer())); + Ok(Some((key, value))) + } + None => Ok(None), + } + } + + fn size_hint(&self) -> Option { + size_hint::from_bounds(&self.iter) + } +} + +impl<'de, I, E> de::SeqAccess<'de> for MapDeserializer<'de, I, E> +where + I: Iterator, + I::Item: private::Pair, + First: IntoDeserializer<'de, E>, + Second: IntoDeserializer<'de, E>, + E: de::Error, +{ + type Error = E; + + fn next_element_seed(&mut self, seed: T) -> Result, Self::Error> + where + T: de::DeserializeSeed<'de>, + { + match self.next_pair() { + Some((k, v)) => { + let de = PairDeserializer(k, v, PhantomData); + seed.deserialize(de).map(Some) + } + None => Ok(None), + } + } + + fn size_hint(&self) -> Option { + size_hint::from_bounds(&self.iter) + } +} + +// Cannot #[derive(Clone)] because of the bound `Second: Clone`. +impl<'de, I, E> Clone for MapDeserializer<'de, I, E> +where + I: Iterator + Clone, + I::Item: private::Pair, + Second: Clone, +{ + fn clone(&self) -> Self { + MapDeserializer { + iter: self.iter.clone(), + value: self.value.clone(), + count: self.count, + lifetime: self.lifetime, + error: self.error, + } + } +} + +impl<'de, I, E> Debug for MapDeserializer<'de, I, E> +where + I: Iterator + Debug, + I::Item: private::Pair, + Second: Debug, +{ + fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter + .debug_struct("MapDeserializer") + .field("iter", &self.iter) + .field("value", &self.value) + .field("count", &self.count) + .finish() + } +} + +// Used in the `impl SeqAccess for MapDeserializer` to visit the map as a +// sequence of pairs. +struct PairDeserializer(A, B, PhantomData); + +impl<'de, A, B, E> de::Deserializer<'de> for PairDeserializer +where + A: IntoDeserializer<'de, E>, + B: IntoDeserializer<'de, E>, + E: de::Error, +{ + type Error = E; + + forward_to_deserialize_any! { + bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string + bytes byte_buf option unit unit_struct newtype_struct tuple_struct map + struct enum identifier ignored_any + } + + fn deserialize_any(self, visitor: V) -> Result + where + V: de::Visitor<'de>, + { + self.deserialize_seq(visitor) + } + + fn deserialize_seq(self, visitor: V) -> Result + where + V: de::Visitor<'de>, + { + let mut pair_visitor = PairVisitor(Some(self.0), Some(self.1), PhantomData); + let pair = tri!(visitor.visit_seq(&mut pair_visitor)); + if pair_visitor.1.is_none() { + Ok(pair) + } else { + let remaining = pair_visitor.size_hint().unwrap(); + // First argument is the number of elements in the data, second + // argument is the number of elements expected by the Deserialize. + Err(de::Error::invalid_length(2, &ExpectedInSeq(2 - remaining))) + } + } + + fn deserialize_tuple(self, len: usize, visitor: V) -> Result + where + V: de::Visitor<'de>, + { + if len == 2 { + self.deserialize_seq(visitor) + } else { + // First argument is the number of elements in the data, second + // argument is the number of elements expected by the Deserialize. + Err(de::Error::invalid_length(2, &ExpectedInSeq(len))) + } + } +} + +struct PairVisitor(Option, Option, PhantomData); + +impl<'de, A, B, E> de::SeqAccess<'de> for PairVisitor +where + A: IntoDeserializer<'de, E>, + B: IntoDeserializer<'de, E>, + E: de::Error, +{ + type Error = E; + + fn next_element_seed(&mut self, seed: T) -> Result, Self::Error> + where + T: de::DeserializeSeed<'de>, + { + if let Some(k) = self.0.take() { + seed.deserialize(k.into_deserializer()).map(Some) + } else if let Some(v) = self.1.take() { + seed.deserialize(v.into_deserializer()).map(Some) + } else { + Ok(None) + } + } + + fn size_hint(&self) -> Option { + if self.0.is_some() { + Some(2) + } else if self.1.is_some() { + Some(1) + } else { + Some(0) + } + } +} + +struct ExpectedInMap(usize); + +impl Expected for ExpectedInMap { + fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + if self.0 == 1 { + formatter.write_str("1 element in map") + } else { + write!(formatter, "{} elements in map", self.0) + } + } +} + +//////////////////////////////////////////////////////////////////////////////// + +#[cfg(any(feature = "std", feature = "alloc"))] +#[cfg_attr(docsrs, doc(cfg(any(feature = "std", feature = "alloc"))))] +impl<'de, K, V, E> IntoDeserializer<'de, E> for BTreeMap +where + K: IntoDeserializer<'de, E> + Eq + Ord, + V: IntoDeserializer<'de, E>, + E: de::Error, +{ + type Deserializer = MapDeserializer<'de, ::IntoIter, E>; + + fn into_deserializer(self) -> Self::Deserializer { + MapDeserializer::new(self.into_iter()) + } +} + +#[cfg(feature = "std")] +#[cfg_attr(docsrs, doc(cfg(feature = "std")))] +impl<'de, K, V, S, E> IntoDeserializer<'de, E> for HashMap +where + K: IntoDeserializer<'de, E> + Eq + Hash, + V: IntoDeserializer<'de, E>, + S: BuildHasher, + E: de::Error, +{ + type Deserializer = MapDeserializer<'de, ::IntoIter, E>; + + fn into_deserializer(self) -> Self::Deserializer { + MapDeserializer::new(self.into_iter()) + } +} + +//////////////////////////////////////////////////////////////////////////////// + +/// A deserializer holding a `MapAccess`. +#[derive(Clone, Debug)] +pub struct MapAccessDeserializer { + map: A, +} + +impl MapAccessDeserializer { + /// Construct a new `MapAccessDeserializer`. + pub fn new(map: A) -> Self { + MapAccessDeserializer { map } + } +} + +impl<'de, A> de::Deserializer<'de> for MapAccessDeserializer +where + A: de::MapAccess<'de>, +{ + type Error = A::Error; + + fn deserialize_any(self, visitor: V) -> Result + where + V: de::Visitor<'de>, + { + visitor.visit_map(self.map) + } + + fn deserialize_enum( + self, + _name: &str, + _variants: &'static [&'static str], + visitor: V, + ) -> Result + where + V: de::Visitor<'de>, + { + visitor.visit_enum(self) + } + + forward_to_deserialize_any! { + bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string + bytes byte_buf option unit unit_struct newtype_struct seq tuple + tuple_struct map struct identifier ignored_any + } +} + +impl<'de, A> de::EnumAccess<'de> for MapAccessDeserializer +where + A: de::MapAccess<'de>, +{ + type Error = A::Error; + type Variant = private::MapAsEnum; + + fn variant_seed(mut self, seed: T) -> Result<(T::Value, Self::Variant), Self::Error> + where + T: de::DeserializeSeed<'de>, + { + match tri!(self.map.next_key_seed(seed)) { + Some(key) => Ok((key, private::map_as_enum(self.map))), + None => Err(de::Error::invalid_type(de::Unexpected::Map, &"enum")), + } + } +} + +//////////////////////////////////////////////////////////////////////////////// + +/// A deserializer holding an `EnumAccess`. +#[derive(Clone, Debug)] +pub struct EnumAccessDeserializer { + access: A, +} + +impl EnumAccessDeserializer { + /// Construct a new `EnumAccessDeserializer`. + pub fn new(access: A) -> Self { + EnumAccessDeserializer { access } + } +} + +impl<'de, A> de::Deserializer<'de> for EnumAccessDeserializer +where + A: de::EnumAccess<'de>, +{ + type Error = A::Error; + + fn deserialize_any(self, visitor: V) -> Result + where + V: de::Visitor<'de>, + { + visitor.visit_enum(self.access) + } + + forward_to_deserialize_any! { + bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string + bytes byte_buf option unit unit_struct newtype_struct seq tuple + tuple_struct map struct enum identifier ignored_any + } +} + +//////////////////////////////////////////////////////////////////////////////// + +mod private { + use crate::lib::*; + + use crate::de::{ + self, DeserializeSeed, Deserializer, MapAccess, Unexpected, VariantAccess, Visitor, + }; + + pub struct UnitOnly { + marker: PhantomData, + } + + pub fn unit_only(t: T) -> (T, UnitOnly) { + ( + t, + UnitOnly { + marker: PhantomData, + }, + ) + } + + impl<'de, E> de::VariantAccess<'de> for UnitOnly + where + E: de::Error, + { + type Error = E; + + fn unit_variant(self) -> Result<(), Self::Error> { + Ok(()) + } + + fn newtype_variant_seed(self, _seed: T) -> Result + where + T: de::DeserializeSeed<'de>, + { + Err(de::Error::invalid_type( + Unexpected::UnitVariant, + &"newtype variant", + )) + } + + fn tuple_variant(self, _len: usize, _visitor: V) -> Result + where + V: de::Visitor<'de>, + { + Err(de::Error::invalid_type( + Unexpected::UnitVariant, + &"tuple variant", + )) + } + + fn struct_variant( + self, + _fields: &'static [&'static str], + _visitor: V, + ) -> Result + where + V: de::Visitor<'de>, + { + Err(de::Error::invalid_type( + Unexpected::UnitVariant, + &"struct variant", + )) + } + } + + pub struct MapAsEnum { + map: A, + } + + pub fn map_as_enum(map: A) -> MapAsEnum { + MapAsEnum { map } + } + + impl<'de, A> VariantAccess<'de> for MapAsEnum + where + A: MapAccess<'de>, + { + type Error = A::Error; + + fn unit_variant(mut self) -> Result<(), Self::Error> { + self.map.next_value() + } + + fn newtype_variant_seed(mut self, seed: T) -> Result + where + T: DeserializeSeed<'de>, + { + self.map.next_value_seed(seed) + } + + fn tuple_variant(mut self, len: usize, visitor: V) -> Result + where + V: Visitor<'de>, + { + self.map.next_value_seed(SeedTupleVariant { len, visitor }) + } + + fn struct_variant( + mut self, + _fields: &'static [&'static str], + visitor: V, + ) -> Result + where + V: Visitor<'de>, + { + self.map.next_value_seed(SeedStructVariant { visitor }) + } + } + + struct SeedTupleVariant { + len: usize, + visitor: V, + } + + impl<'de, V> DeserializeSeed<'de> for SeedTupleVariant + where + V: Visitor<'de>, + { + type Value = V::Value; + + fn deserialize(self, deserializer: D) -> Result + where + D: Deserializer<'de>, + { + deserializer.deserialize_tuple(self.len, self.visitor) + } + } + + struct SeedStructVariant { + visitor: V, + } + + impl<'de, V> DeserializeSeed<'de> for SeedStructVariant + where + V: Visitor<'de>, + { + type Value = V::Value; + + fn deserialize(self, deserializer: D) -> Result + where + D: Deserializer<'de>, + { + deserializer.deserialize_map(self.visitor) + } + } + + /// Avoid having to restate the generic types on `MapDeserializer`. The + /// `Iterator::Item` contains enough information to figure out K and V. + pub trait Pair { + type First; + type Second; + fn split(self) -> (Self::First, Self::Second); + } + + impl Pair for (A, B) { + type First = A; + type Second = B; + fn split(self) -> (A, B) { + self + } + } + + pub type First = ::First; + pub type Second = ::Second; +} diff --git a/vendor/serde/src/format.rs b/vendor/serde/src/format.rs new file mode 100644 index 0000000..9053cc0 --- /dev/null +++ b/vendor/serde/src/format.rs @@ -0,0 +1,30 @@ +use crate::lib::fmt::{self, Write}; +use crate::lib::str; + +pub(super) struct Buf<'a> { + bytes: &'a mut [u8], + offset: usize, +} + +impl<'a> Buf<'a> { + pub fn new(bytes: &'a mut [u8]) -> Self { + Buf { bytes, offset: 0 } + } + + pub fn as_str(&self) -> &str { + let slice = &self.bytes[..self.offset]; + unsafe { str::from_utf8_unchecked(slice) } + } +} + +impl<'a> Write for Buf<'a> { + fn write_str(&mut self, s: &str) -> fmt::Result { + if self.offset + s.len() > self.bytes.len() { + Err(fmt::Error) + } else { + self.bytes[self.offset..self.offset + s.len()].copy_from_slice(s.as_bytes()); + self.offset += s.len(); + Ok(()) + } + } +} diff --git a/vendor/serde/src/integer128.rs b/vendor/serde/src/integer128.rs new file mode 100644 index 0000000..2f94a64 --- /dev/null +++ b/vendor/serde/src/integer128.rs @@ -0,0 +1,9 @@ +// No longer used. Old versions of serde used this macro for supporting targets +// that did not yet have 128-bit integer support. +#[macro_export] +#[doc(hidden)] +macro_rules! serde_if_integer128 { + ($($tt:tt)*) => { + $($tt)* + }; +} diff --git a/vendor/serde/src/lib.rs b/vendor/serde/src/lib.rs new file mode 100644 index 0000000..15710d8 --- /dev/null +++ b/vendor/serde/src/lib.rs @@ -0,0 +1,347 @@ +//! # Serde +//! +//! Serde is a framework for ***ser***ializing and ***de***serializing Rust data +//! structures efficiently and generically. +//! +//! The Serde ecosystem consists of data structures that know how to serialize +//! and deserialize themselves along with data formats that know how to +//! serialize and deserialize other things. Serde provides the layer by which +//! these two groups interact with each other, allowing any supported data +//! structure to be serialized and deserialized using any supported data format. +//! +//! See the Serde website for additional documentation and +//! usage examples. +//! +//! ## Design +//! +//! Where many other languages rely on runtime reflection for serializing data, +//! Serde is instead built on Rust's powerful trait system. A data structure +//! that knows how to serialize and deserialize itself is one that implements +//! Serde's `Serialize` and `Deserialize` traits (or uses Serde's derive +//! attribute to automatically generate implementations at compile time). This +//! avoids any overhead of reflection or runtime type information. In fact in +//! many situations the interaction between data structure and data format can +//! be completely optimized away by the Rust compiler, leaving Serde +//! serialization to perform the same speed as a handwritten serializer for the +//! specific selection of data structure and data format. +//! +//! ## Data formats +//! +//! The following is a partial list of data formats that have been implemented +//! for Serde by the community. +//! +//! - [JSON], the ubiquitous JavaScript Object Notation used by many HTTP APIs. +//! - [Postcard], a no\_std and embedded-systems friendly compact binary format. +//! - [CBOR], a Concise Binary Object Representation designed for small message +//! size without the need for version negotiation. +//! - [YAML], a self-proclaimed human-friendly configuration language that ain't +//! markup language. +//! - [MessagePack], an efficient binary format that resembles a compact JSON. +//! - [TOML], a minimal configuration format used by [Cargo]. +//! - [Pickle], a format common in the Python world. +//! - [RON], a Rusty Object Notation. +//! - [BSON], the data storage and network transfer format used by MongoDB. +//! - [Avro], a binary format used within Apache Hadoop, with support for schema +//! definition. +//! - [JSON5], a superset of JSON including some productions from ES5. +//! - [URL] query strings, in the x-www-form-urlencoded format. +//! - [Starlark], the format used for describing build targets by the Bazel and +//! Buck build systems. *(serialization only)* +//! - [Envy], a way to deserialize environment variables into Rust structs. +//! *(deserialization only)* +//! - [Envy Store], a way to deserialize [AWS Parameter Store] parameters into +//! Rust structs. *(deserialization only)* +//! - [S-expressions], the textual representation of code and data used by the +//! Lisp language family. +//! - [D-Bus]'s binary wire format. +//! - [FlexBuffers], the schemaless cousin of Google's FlatBuffers zero-copy +//! serialization format. +//! - [Bencode], a simple binary format used in the BitTorrent protocol. +//! - [Token streams], for processing Rust procedural macro input. +//! *(deserialization only)* +//! - [DynamoDB Items], the format used by [rusoto_dynamodb] to transfer data to +//! and from DynamoDB. +//! - [Hjson], a syntax extension to JSON designed around human reading and +//! editing. *(deserialization only)* +//! - [CSV], Comma-separated values is a tabular text file format. +//! +//! [JSON]: https://github.com/serde-rs/json +//! [Postcard]: https://github.com/jamesmunns/postcard +//! [CBOR]: https://github.com/enarx/ciborium +//! [YAML]: https://github.com/dtolnay/serde-yaml +//! [MessagePack]: https://github.com/3Hren/msgpack-rust +//! [TOML]: https://docs.rs/toml +//! [Pickle]: https://github.com/birkenfeld/serde-pickle +//! [RON]: https://github.com/ron-rs/ron +//! [BSON]: https://github.com/mongodb/bson-rust +//! [Avro]: https://docs.rs/apache-avro +//! [JSON5]: https://github.com/callum-oakley/json5-rs +//! [URL]: https://docs.rs/serde_qs +//! [Starlark]: https://github.com/dtolnay/serde-starlark +//! [Envy]: https://github.com/softprops/envy +//! [Envy Store]: https://github.com/softprops/envy-store +//! [Cargo]: https://doc.rust-lang.org/cargo/reference/manifest.html +//! [AWS Parameter Store]: https://docs.aws.amazon.com/systems-manager/latest/userguide/systems-manager-parameter-store.html +//! [S-expressions]: https://github.com/rotty/lexpr-rs +//! [D-Bus]: https://docs.rs/zvariant +//! [FlexBuffers]: https://github.com/google/flatbuffers/tree/master/rust/flexbuffers +//! [Bencode]: https://github.com/P3KI/bendy +//! [Token streams]: https://github.com/oxidecomputer/serde_tokenstream +//! [DynamoDB Items]: https://docs.rs/serde_dynamo +//! [rusoto_dynamodb]: https://docs.rs/rusoto_dynamodb +//! [Hjson]: https://github.com/Canop/deser-hjson +//! [CSV]: https://docs.rs/csv + +//////////////////////////////////////////////////////////////////////////////// + +// Serde types in rustdoc of other crates get linked to here. +#![doc(html_root_url = "https://docs.rs/serde/1.0.210")] +// Support using Serde without the standard library! +#![cfg_attr(not(feature = "std"), no_std)] +// Show which crate feature enables conditionally compiled APIs in documentation. +#![cfg_attr(docsrs, feature(doc_cfg, rustdoc_internals))] +#![cfg_attr(docsrs, allow(internal_features))] +// Unstable functionality only if the user asks for it. For tracking and +// discussion of these features please refer to this issue: +// +// https://github.com/serde-rs/serde/issues/812 +#![cfg_attr(feature = "unstable", feature(never_type))] +#![allow(unknown_lints, bare_trait_objects, deprecated)] +// Ignored clippy and clippy_pedantic lints +#![allow( + // clippy bug: https://github.com/rust-lang/rust-clippy/issues/5704 + clippy::unnested_or_patterns, + // clippy bug: https://github.com/rust-lang/rust-clippy/issues/7768 + clippy::semicolon_if_nothing_returned, + // not available in our oldest supported compiler + clippy::empty_enum, + clippy::type_repetition_in_bounds, // https://github.com/rust-lang/rust-clippy/issues/8772 + // integer and float ser/de requires these sorts of casts + clippy::cast_possible_truncation, + clippy::cast_possible_wrap, + clippy::cast_precision_loss, + clippy::cast_sign_loss, + // things are often more readable this way + clippy::cast_lossless, + clippy::module_name_repetitions, + clippy::single_match_else, + clippy::type_complexity, + clippy::use_self, + clippy::zero_prefixed_literal, + // correctly used + clippy::derive_partial_eq_without_eq, + clippy::enum_glob_use, + clippy::explicit_auto_deref, + clippy::incompatible_msrv, + clippy::let_underscore_untyped, + clippy::map_err_ignore, + clippy::new_without_default, + clippy::result_unit_err, + clippy::wildcard_imports, + // not practical + clippy::needless_pass_by_value, + clippy::similar_names, + clippy::too_many_lines, + // preference + clippy::doc_markdown, + clippy::unseparated_literal_suffix, + // false positive + clippy::needless_doctest_main, + // noisy + clippy::missing_errors_doc, + clippy::must_use_candidate, +)] +// Restrictions +#![deny(clippy::question_mark_used)] +// Rustc lints. +#![deny(missing_docs, unused_imports)] + +//////////////////////////////////////////////////////////////////////////////// + +#[cfg(feature = "alloc")] +extern crate alloc; + +/// A facade around all the types we need from the `std`, `core`, and `alloc` +/// crates. This avoids elaborate import wrangling having to happen in every +/// module. +mod lib { + mod core { + #[cfg(not(feature = "std"))] + pub use core::*; + #[cfg(feature = "std")] + pub use std::*; + } + + pub use self::core::{f32, f64}; + pub use self::core::{i16, i32, i64, i8, isize}; + pub use self::core::{iter, num, ptr, str}; + pub use self::core::{u16, u32, u64, u8, usize}; + + #[cfg(any(feature = "std", feature = "alloc"))] + pub use self::core::{cmp, mem, slice}; + + pub use self::core::cell::{Cell, RefCell}; + pub use self::core::clone; + pub use self::core::cmp::Reverse; + pub use self::core::convert; + pub use self::core::default; + pub use self::core::fmt::{self, Debug, Display, Write as FmtWrite}; + pub use self::core::marker::{self, PhantomData}; + pub use self::core::num::Wrapping; + pub use self::core::ops::{Bound, Range, RangeFrom, RangeInclusive, RangeTo}; + pub use self::core::option; + pub use self::core::result; + pub use self::core::time::Duration; + + #[cfg(all(feature = "alloc", not(feature = "std")))] + pub use alloc::borrow::{Cow, ToOwned}; + #[cfg(feature = "std")] + pub use std::borrow::{Cow, ToOwned}; + + #[cfg(all(feature = "alloc", not(feature = "std")))] + pub use alloc::string::{String, ToString}; + #[cfg(feature = "std")] + pub use std::string::{String, ToString}; + + #[cfg(all(feature = "alloc", not(feature = "std")))] + pub use alloc::vec::Vec; + #[cfg(feature = "std")] + pub use std::vec::Vec; + + #[cfg(all(feature = "alloc", not(feature = "std")))] + pub use alloc::boxed::Box; + #[cfg(feature = "std")] + pub use std::boxed::Box; + + #[cfg(all(feature = "rc", feature = "alloc", not(feature = "std")))] + pub use alloc::rc::{Rc, Weak as RcWeak}; + #[cfg(all(feature = "rc", feature = "std"))] + pub use std::rc::{Rc, Weak as RcWeak}; + + #[cfg(all(feature = "rc", feature = "alloc", not(feature = "std")))] + pub use alloc::sync::{Arc, Weak as ArcWeak}; + #[cfg(all(feature = "rc", feature = "std"))] + pub use std::sync::{Arc, Weak as ArcWeak}; + + #[cfg(all(feature = "alloc", not(feature = "std")))] + pub use alloc::collections::{BTreeMap, BTreeSet, BinaryHeap, LinkedList, VecDeque}; + #[cfg(feature = "std")] + pub use std::collections::{BTreeMap, BTreeSet, BinaryHeap, LinkedList, VecDeque}; + + #[cfg(all(not(no_core_cstr), not(feature = "std")))] + pub use self::core::ffi::CStr; + #[cfg(feature = "std")] + pub use std::ffi::CStr; + + #[cfg(all(not(no_core_cstr), feature = "alloc", not(feature = "std")))] + pub use alloc::ffi::CString; + #[cfg(feature = "std")] + pub use std::ffi::CString; + + #[cfg(all(not(no_core_net), not(feature = "std")))] + pub use self::core::net; + #[cfg(feature = "std")] + pub use std::net; + + #[cfg(feature = "std")] + pub use std::error; + + #[cfg(feature = "std")] + pub use std::collections::{HashMap, HashSet}; + #[cfg(feature = "std")] + pub use std::ffi::{OsStr, OsString}; + #[cfg(feature = "std")] + pub use std::hash::{BuildHasher, Hash}; + #[cfg(feature = "std")] + pub use std::io::Write; + #[cfg(feature = "std")] + pub use std::path::{Path, PathBuf}; + #[cfg(feature = "std")] + pub use std::sync::{Mutex, RwLock}; + #[cfg(feature = "std")] + pub use std::time::{SystemTime, UNIX_EPOCH}; + + #[cfg(all(feature = "std", no_target_has_atomic, not(no_std_atomic)))] + pub use std::sync::atomic::{ + AtomicBool, AtomicI16, AtomicI32, AtomicI8, AtomicIsize, AtomicU16, AtomicU32, AtomicU8, + AtomicUsize, Ordering, + }; + #[cfg(all(feature = "std", no_target_has_atomic, not(no_std_atomic64)))] + pub use std::sync::atomic::{AtomicI64, AtomicU64}; + + #[cfg(all(feature = "std", not(no_target_has_atomic)))] + pub use std::sync::atomic::Ordering; + #[cfg(all(feature = "std", not(no_target_has_atomic), target_has_atomic = "8"))] + pub use std::sync::atomic::{AtomicBool, AtomicI8, AtomicU8}; + #[cfg(all(feature = "std", not(no_target_has_atomic), target_has_atomic = "16"))] + pub use std::sync::atomic::{AtomicI16, AtomicU16}; + #[cfg(all(feature = "std", not(no_target_has_atomic), target_has_atomic = "32"))] + pub use std::sync::atomic::{AtomicI32, AtomicU32}; + #[cfg(all(feature = "std", not(no_target_has_atomic), target_has_atomic = "64"))] + pub use std::sync::atomic::{AtomicI64, AtomicU64}; + #[cfg(all(feature = "std", not(no_target_has_atomic), target_has_atomic = "ptr"))] + pub use std::sync::atomic::{AtomicIsize, AtomicUsize}; + + #[cfg(not(no_core_num_saturating))] + pub use self::core::num::Saturating; +} + +// None of this crate's error handling needs the `From::from` error conversion +// performed implicitly by the `?` operator or the standard library's `try!` +// macro. This simplified macro gives a 5.5% improvement in compile time +// compared to standard `try!`, and 9% improvement compared to `?`. +macro_rules! tri { + ($expr:expr) => { + match $expr { + Ok(val) => val, + Err(err) => return Err(err), + } + }; +} + +//////////////////////////////////////////////////////////////////////////////// + +#[macro_use] +mod macros; + +#[macro_use] +mod integer128; + +pub mod de; +pub mod ser; + +mod format; + +#[doc(inline)] +pub use crate::de::{Deserialize, Deserializer}; +#[doc(inline)] +pub use crate::ser::{Serialize, Serializer}; + +// Used by generated code and doc tests. Not public API. +#[doc(hidden)] +#[path = "private/mod.rs"] +pub mod __private; + +#[path = "de/seed.rs"] +mod seed; + +#[cfg(all(not(feature = "std"), no_core_error))] +mod std_error; + +// Re-export #[derive(Serialize, Deserialize)]. +// +// The reason re-exporting is not enabled by default is that disabling it would +// be annoying for crates that provide handwritten impls or data formats. They +// would need to disable default features and then explicitly re-enable std. +#[cfg(feature = "serde_derive")] +extern crate serde_derive; + +/// Derive macro available if serde is built with `features = ["derive"]`. +#[cfg(feature = "serde_derive")] +#[cfg_attr(docsrs, doc(cfg(feature = "derive")))] +pub use serde_derive::{Deserialize, Serialize}; + +#[cfg(all(not(no_serde_derive), any(feature = "std", feature = "alloc")))] +mod actually_private { + pub struct T; +} diff --git a/vendor/serde/src/macros.rs b/vendor/serde/src/macros.rs new file mode 100644 index 0000000..9646cb3 --- /dev/null +++ b/vendor/serde/src/macros.rs @@ -0,0 +1,231 @@ +// Super explicit first paragraph because this shows up at the top level and +// trips up people who are just looking for basic Serialize / Deserialize +// documentation. +// +/// Helper macro when implementing the `Deserializer` part of a new data format +/// for Serde. +/// +/// Some [`Deserializer`] implementations for self-describing formats do not +/// care what hint the [`Visitor`] gives them, they just want to blindly call +/// the [`Visitor`] method corresponding to the data they can tell is in the +/// input. This requires repetitive implementations of all the [`Deserializer`] +/// trait methods. +/// +/// ```edition2021 +/// # use serde::forward_to_deserialize_any; +/// # use serde::de::{value, Deserializer, Visitor}; +/// # +/// # struct MyDeserializer; +/// # +/// # impl<'de> Deserializer<'de> for MyDeserializer { +/// # type Error = value::Error; +/// # +/// # fn deserialize_any(self, _: V) -> Result +/// # where +/// # V: Visitor<'de>, +/// # { +/// # unimplemented!() +/// # } +/// # +/// #[inline] +/// fn deserialize_bool(self, visitor: V) -> Result +/// where +/// V: Visitor<'de>, +/// { +/// self.deserialize_any(visitor) +/// } +/// # +/// # forward_to_deserialize_any! { +/// # i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string +/// # bytes byte_buf option unit unit_struct newtype_struct seq tuple +/// # tuple_struct map struct enum identifier ignored_any +/// # } +/// # } +/// ``` +/// +/// The `forward_to_deserialize_any!` macro implements these simple forwarding +/// methods so that they forward directly to [`Deserializer::deserialize_any`]. +/// You can choose which methods to forward. +/// +/// ```edition2021 +/// # use serde::forward_to_deserialize_any; +/// # use serde::de::{value, Deserializer, Visitor}; +/// # +/// # struct MyDeserializer; +/// # +/// impl<'de> Deserializer<'de> for MyDeserializer { +/// # type Error = value::Error; +/// # +/// fn deserialize_any(self, visitor: V) -> Result +/// where +/// V: Visitor<'de>, +/// { +/// /* ... */ +/// # let _ = visitor; +/// # unimplemented!() +/// } +/// +/// forward_to_deserialize_any! { +/// bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string +/// bytes byte_buf option unit unit_struct newtype_struct seq tuple +/// tuple_struct map struct enum identifier ignored_any +/// } +/// } +/// ``` +/// +/// The macro assumes the convention that your `Deserializer` lifetime parameter +/// is called `'de` and that the `Visitor` type parameters on each method are +/// called `V`. A different type parameter and a different lifetime can be +/// specified explicitly if necessary. +/// +/// ```edition2021 +/// # use serde::forward_to_deserialize_any; +/// # use serde::de::{value, Deserializer, Visitor}; +/// # use std::marker::PhantomData; +/// # +/// # struct MyDeserializer(PhantomData); +/// # +/// # impl<'q, V> Deserializer<'q> for MyDeserializer { +/// # type Error = value::Error; +/// # +/// # fn deserialize_any(self, visitor: W) -> Result +/// # where +/// # W: Visitor<'q>, +/// # { +/// # unimplemented!() +/// # } +/// # +/// forward_to_deserialize_any! { +/// > +/// bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string +/// bytes byte_buf option unit unit_struct newtype_struct seq tuple +/// tuple_struct map struct enum identifier ignored_any +/// } +/// # } +/// ``` +/// +/// [`Deserializer`]: trait.Deserializer.html +/// [`Visitor`]: de/trait.Visitor.html +/// [`Deserializer::deserialize_any`]: trait.Deserializer.html#tymethod.deserialize_any +#[macro_export(local_inner_macros)] +macro_rules! forward_to_deserialize_any { + (<$visitor:ident: Visitor<$lifetime:tt>> $($func:ident)*) => { + $(forward_to_deserialize_any_helper!{$func<$lifetime, $visitor>})* + }; + // This case must be after the previous one. + ($($func:ident)*) => { + $(forward_to_deserialize_any_helper!{$func<'de, V>})* + }; +} + +#[doc(hidden)] +#[macro_export] +macro_rules! forward_to_deserialize_any_method { + ($func:ident<$l:tt, $v:ident>($($arg:ident : $ty:ty),*)) => { + #[inline] + fn $func<$v>(self, $($arg: $ty,)* visitor: $v) -> $crate::__private::Result<$v::Value, >::Error> + where + $v: $crate::de::Visitor<$l>, + { + $( + let _ = $arg; + )* + self.deserialize_any(visitor) + } + }; +} + +#[doc(hidden)] +#[macro_export(local_inner_macros)] +macro_rules! forward_to_deserialize_any_helper { + (bool<$l:tt, $v:ident>) => { + forward_to_deserialize_any_method!{deserialize_bool<$l, $v>()} + }; + (i8<$l:tt, $v:ident>) => { + forward_to_deserialize_any_method!{deserialize_i8<$l, $v>()} + }; + (i16<$l:tt, $v:ident>) => { + forward_to_deserialize_any_method!{deserialize_i16<$l, $v>()} + }; + (i32<$l:tt, $v:ident>) => { + forward_to_deserialize_any_method!{deserialize_i32<$l, $v>()} + }; + (i64<$l:tt, $v:ident>) => { + forward_to_deserialize_any_method!{deserialize_i64<$l, $v>()} + }; + (i128<$l:tt, $v:ident>) => { + forward_to_deserialize_any_method!{deserialize_i128<$l, $v>()} + }; + (u8<$l:tt, $v:ident>) => { + forward_to_deserialize_any_method!{deserialize_u8<$l, $v>()} + }; + (u16<$l:tt, $v:ident>) => { + forward_to_deserialize_any_method!{deserialize_u16<$l, $v>()} + }; + (u32<$l:tt, $v:ident>) => { + forward_to_deserialize_any_method!{deserialize_u32<$l, $v>()} + }; + (u64<$l:tt, $v:ident>) => { + forward_to_deserialize_any_method!{deserialize_u64<$l, $v>()} + }; + (u128<$l:tt, $v:ident>) => { + forward_to_deserialize_any_method!{deserialize_u128<$l, $v>()} + }; + (f32<$l:tt, $v:ident>) => { + forward_to_deserialize_any_method!{deserialize_f32<$l, $v>()} + }; + (f64<$l:tt, $v:ident>) => { + forward_to_deserialize_any_method!{deserialize_f64<$l, $v>()} + }; + (char<$l:tt, $v:ident>) => { + forward_to_deserialize_any_method!{deserialize_char<$l, $v>()} + }; + (str<$l:tt, $v:ident>) => { + forward_to_deserialize_any_method!{deserialize_str<$l, $v>()} + }; + (string<$l:tt, $v:ident>) => { + forward_to_deserialize_any_method!{deserialize_string<$l, $v>()} + }; + (bytes<$l:tt, $v:ident>) => { + forward_to_deserialize_any_method!{deserialize_bytes<$l, $v>()} + }; + (byte_buf<$l:tt, $v:ident>) => { + forward_to_deserialize_any_method!{deserialize_byte_buf<$l, $v>()} + }; + (option<$l:tt, $v:ident>) => { + forward_to_deserialize_any_method!{deserialize_option<$l, $v>()} + }; + (unit<$l:tt, $v:ident>) => { + forward_to_deserialize_any_method!{deserialize_unit<$l, $v>()} + }; + (unit_struct<$l:tt, $v:ident>) => { + forward_to_deserialize_any_method!{deserialize_unit_struct<$l, $v>(name: &'static str)} + }; + (newtype_struct<$l:tt, $v:ident>) => { + forward_to_deserialize_any_method!{deserialize_newtype_struct<$l, $v>(name: &'static str)} + }; + (seq<$l:tt, $v:ident>) => { + forward_to_deserialize_any_method!{deserialize_seq<$l, $v>()} + }; + (tuple<$l:tt, $v:ident>) => { + forward_to_deserialize_any_method!{deserialize_tuple<$l, $v>(len: usize)} + }; + (tuple_struct<$l:tt, $v:ident>) => { + forward_to_deserialize_any_method!{deserialize_tuple_struct<$l, $v>(name: &'static str, len: usize)} + }; + (map<$l:tt, $v:ident>) => { + forward_to_deserialize_any_method!{deserialize_map<$l, $v>()} + }; + (struct<$l:tt, $v:ident>) => { + forward_to_deserialize_any_method!{deserialize_struct<$l, $v>(name: &'static str, fields: &'static [&'static str])} + }; + (enum<$l:tt, $v:ident>) => { + forward_to_deserialize_any_method!{deserialize_enum<$l, $v>(name: &'static str, variants: &'static [&'static str])} + }; + (identifier<$l:tt, $v:ident>) => { + forward_to_deserialize_any_method!{deserialize_identifier<$l, $v>()} + }; + (ignored_any<$l:tt, $v:ident>) => { + forward_to_deserialize_any_method!{deserialize_ignored_any<$l, $v>()} + }; +} diff --git a/vendor/serde/src/private/de.rs b/vendor/serde/src/private/de.rs new file mode 100644 index 0000000..f0eca71 --- /dev/null +++ b/vendor/serde/src/private/de.rs @@ -0,0 +1,2795 @@ +use crate::lib::*; + +use crate::de::value::{BorrowedBytesDeserializer, BytesDeserializer}; +use crate::de::{ + Deserialize, DeserializeSeed, Deserializer, EnumAccess, Error, IntoDeserializer, VariantAccess, + Visitor, +}; + +#[cfg(any(feature = "std", feature = "alloc"))] +use crate::de::{MapAccess, Unexpected}; + +#[cfg(any(feature = "std", feature = "alloc"))] +pub use self::content::{ + Content, ContentDeserializer, ContentRefDeserializer, EnumDeserializer, + InternallyTaggedUnitVisitor, TagContentOtherField, TagContentOtherFieldVisitor, + TagOrContentField, TagOrContentFieldVisitor, TaggedContentVisitor, UntaggedUnitVisitor, +}; + +pub use crate::seed::InPlaceSeed; + +/// If the missing field is of type `Option` then treat is as `None`, +/// otherwise it is an error. +pub fn missing_field<'de, V, E>(field: &'static str) -> Result +where + V: Deserialize<'de>, + E: Error, +{ + struct MissingFieldDeserializer(&'static str, PhantomData); + + impl<'de, E> Deserializer<'de> for MissingFieldDeserializer + where + E: Error, + { + type Error = E; + + fn deserialize_any(self, _visitor: V) -> Result + where + V: Visitor<'de>, + { + Err(Error::missing_field(self.0)) + } + + fn deserialize_option(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + visitor.visit_none() + } + + forward_to_deserialize_any! { + bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string + bytes byte_buf unit unit_struct newtype_struct seq tuple + tuple_struct map struct enum identifier ignored_any + } + } + + let deserializer = MissingFieldDeserializer(field, PhantomData); + Deserialize::deserialize(deserializer) +} + +#[cfg(any(feature = "std", feature = "alloc"))] +pub fn borrow_cow_str<'de: 'a, 'a, D, R>(deserializer: D) -> Result +where + D: Deserializer<'de>, + R: From>, +{ + struct CowStrVisitor; + + impl<'a> Visitor<'a> for CowStrVisitor { + type Value = Cow<'a, str>; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("a string") + } + + fn visit_str(self, v: &str) -> Result + where + E: Error, + { + Ok(Cow::Owned(v.to_owned())) + } + + fn visit_borrowed_str(self, v: &'a str) -> Result + where + E: Error, + { + Ok(Cow::Borrowed(v)) + } + + fn visit_string(self, v: String) -> Result + where + E: Error, + { + Ok(Cow::Owned(v)) + } + + fn visit_bytes(self, v: &[u8]) -> Result + where + E: Error, + { + match str::from_utf8(v) { + Ok(s) => Ok(Cow::Owned(s.to_owned())), + Err(_) => Err(Error::invalid_value(Unexpected::Bytes(v), &self)), + } + } + + fn visit_borrowed_bytes(self, v: &'a [u8]) -> Result + where + E: Error, + { + match str::from_utf8(v) { + Ok(s) => Ok(Cow::Borrowed(s)), + Err(_) => Err(Error::invalid_value(Unexpected::Bytes(v), &self)), + } + } + + fn visit_byte_buf(self, v: Vec) -> Result + where + E: Error, + { + match String::from_utf8(v) { + Ok(s) => Ok(Cow::Owned(s)), + Err(e) => Err(Error::invalid_value( + Unexpected::Bytes(&e.into_bytes()), + &self, + )), + } + } + } + + deserializer.deserialize_str(CowStrVisitor).map(From::from) +} + +#[cfg(any(feature = "std", feature = "alloc"))] +pub fn borrow_cow_bytes<'de: 'a, 'a, D, R>(deserializer: D) -> Result +where + D: Deserializer<'de>, + R: From>, +{ + struct CowBytesVisitor; + + impl<'a> Visitor<'a> for CowBytesVisitor { + type Value = Cow<'a, [u8]>; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("a byte array") + } + + fn visit_str(self, v: &str) -> Result + where + E: Error, + { + Ok(Cow::Owned(v.as_bytes().to_vec())) + } + + fn visit_borrowed_str(self, v: &'a str) -> Result + where + E: Error, + { + Ok(Cow::Borrowed(v.as_bytes())) + } + + fn visit_string(self, v: String) -> Result + where + E: Error, + { + Ok(Cow::Owned(v.into_bytes())) + } + + fn visit_bytes(self, v: &[u8]) -> Result + where + E: Error, + { + Ok(Cow::Owned(v.to_vec())) + } + + fn visit_borrowed_bytes(self, v: &'a [u8]) -> Result + where + E: Error, + { + Ok(Cow::Borrowed(v)) + } + + fn visit_byte_buf(self, v: Vec) -> Result + where + E: Error, + { + Ok(Cow::Owned(v)) + } + } + + deserializer + .deserialize_bytes(CowBytesVisitor) + .map(From::from) +} + +#[cfg(any(feature = "std", feature = "alloc"))] +mod content { + // This module is private and nothing here should be used outside of + // generated code. + // + // We will iterate on the implementation for a few releases and only have to + // worry about backward compatibility for the `untagged` and `tag` attributes + // rather than for this entire mechanism. + // + // This issue is tracking making some of this stuff public: + // https://github.com/serde-rs/serde/issues/741 + + use crate::lib::*; + + use crate::actually_private; + use crate::de::value::{MapDeserializer, SeqDeserializer}; + use crate::de::{ + self, size_hint, Deserialize, DeserializeSeed, Deserializer, EnumAccess, Expected, + IgnoredAny, MapAccess, SeqAccess, Unexpected, Visitor, + }; + + /// Used from generated code to buffer the contents of the Deserializer when + /// deserializing untagged enums and internally tagged enums. + /// + /// Not public API. Use serde-value instead. + #[derive(Debug, Clone)] + pub enum Content<'de> { + Bool(bool), + + U8(u8), + U16(u16), + U32(u32), + U64(u64), + + I8(i8), + I16(i16), + I32(i32), + I64(i64), + + F32(f32), + F64(f64), + + Char(char), + String(String), + Str(&'de str), + ByteBuf(Vec), + Bytes(&'de [u8]), + + None, + Some(Box>), + + Unit, + Newtype(Box>), + Seq(Vec>), + Map(Vec<(Content<'de>, Content<'de>)>), + } + + impl<'de> Content<'de> { + pub fn as_str(&self) -> Option<&str> { + match *self { + Content::Str(x) => Some(x), + Content::String(ref x) => Some(x), + Content::Bytes(x) => str::from_utf8(x).ok(), + Content::ByteBuf(ref x) => str::from_utf8(x).ok(), + _ => None, + } + } + + #[cold] + fn unexpected(&self) -> Unexpected { + match *self { + Content::Bool(b) => Unexpected::Bool(b), + Content::U8(n) => Unexpected::Unsigned(n as u64), + Content::U16(n) => Unexpected::Unsigned(n as u64), + Content::U32(n) => Unexpected::Unsigned(n as u64), + Content::U64(n) => Unexpected::Unsigned(n), + Content::I8(n) => Unexpected::Signed(n as i64), + Content::I16(n) => Unexpected::Signed(n as i64), + Content::I32(n) => Unexpected::Signed(n as i64), + Content::I64(n) => Unexpected::Signed(n), + Content::F32(f) => Unexpected::Float(f as f64), + Content::F64(f) => Unexpected::Float(f), + Content::Char(c) => Unexpected::Char(c), + Content::String(ref s) => Unexpected::Str(s), + Content::Str(s) => Unexpected::Str(s), + Content::ByteBuf(ref b) => Unexpected::Bytes(b), + Content::Bytes(b) => Unexpected::Bytes(b), + Content::None | Content::Some(_) => Unexpected::Option, + Content::Unit => Unexpected::Unit, + Content::Newtype(_) => Unexpected::NewtypeStruct, + Content::Seq(_) => Unexpected::Seq, + Content::Map(_) => Unexpected::Map, + } + } + } + + impl<'de> Deserialize<'de> for Content<'de> { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + // Untagged and internally tagged enums are only supported in + // self-describing formats. + let visitor = ContentVisitor { value: PhantomData }; + deserializer.__deserialize_content(actually_private::T, visitor) + } + } + + impl<'de, E> de::IntoDeserializer<'de, E> for Content<'de> + where + E: de::Error, + { + type Deserializer = ContentDeserializer<'de, E>; + + fn into_deserializer(self) -> Self::Deserializer { + ContentDeserializer::new(self) + } + } + + /// Used to capture data in [`Content`] from other deserializers. + /// Cannot capture externally tagged enums, `i128` and `u128`. + struct ContentVisitor<'de> { + value: PhantomData>, + } + + impl<'de> ContentVisitor<'de> { + fn new() -> Self { + ContentVisitor { value: PhantomData } + } + } + + impl<'de> Visitor<'de> for ContentVisitor<'de> { + type Value = Content<'de>; + + fn expecting(&self, fmt: &mut fmt::Formatter) -> fmt::Result { + fmt.write_str("any value") + } + + fn visit_bool(self, value: bool) -> Result + where + F: de::Error, + { + Ok(Content::Bool(value)) + } + + fn visit_i8(self, value: i8) -> Result + where + F: de::Error, + { + Ok(Content::I8(value)) + } + + fn visit_i16(self, value: i16) -> Result + where + F: de::Error, + { + Ok(Content::I16(value)) + } + + fn visit_i32(self, value: i32) -> Result + where + F: de::Error, + { + Ok(Content::I32(value)) + } + + fn visit_i64(self, value: i64) -> Result + where + F: de::Error, + { + Ok(Content::I64(value)) + } + + fn visit_u8(self, value: u8) -> Result + where + F: de::Error, + { + Ok(Content::U8(value)) + } + + fn visit_u16(self, value: u16) -> Result + where + F: de::Error, + { + Ok(Content::U16(value)) + } + + fn visit_u32(self, value: u32) -> Result + where + F: de::Error, + { + Ok(Content::U32(value)) + } + + fn visit_u64(self, value: u64) -> Result + where + F: de::Error, + { + Ok(Content::U64(value)) + } + + fn visit_f32(self, value: f32) -> Result + where + F: de::Error, + { + Ok(Content::F32(value)) + } + + fn visit_f64(self, value: f64) -> Result + where + F: de::Error, + { + Ok(Content::F64(value)) + } + + fn visit_char(self, value: char) -> Result + where + F: de::Error, + { + Ok(Content::Char(value)) + } + + fn visit_str(self, value: &str) -> Result + where + F: de::Error, + { + Ok(Content::String(value.into())) + } + + fn visit_borrowed_str(self, value: &'de str) -> Result + where + F: de::Error, + { + Ok(Content::Str(value)) + } + + fn visit_string(self, value: String) -> Result + where + F: de::Error, + { + Ok(Content::String(value)) + } + + fn visit_bytes(self, value: &[u8]) -> Result + where + F: de::Error, + { + Ok(Content::ByteBuf(value.into())) + } + + fn visit_borrowed_bytes(self, value: &'de [u8]) -> Result + where + F: de::Error, + { + Ok(Content::Bytes(value)) + } + + fn visit_byte_buf(self, value: Vec) -> Result + where + F: de::Error, + { + Ok(Content::ByteBuf(value)) + } + + fn visit_unit(self) -> Result + where + F: de::Error, + { + Ok(Content::Unit) + } + + fn visit_none(self) -> Result + where + F: de::Error, + { + Ok(Content::None) + } + + fn visit_some(self, deserializer: D) -> Result + where + D: Deserializer<'de>, + { + Deserialize::deserialize(deserializer).map(|v| Content::Some(Box::new(v))) + } + + fn visit_newtype_struct(self, deserializer: D) -> Result + where + D: Deserializer<'de>, + { + Deserialize::deserialize(deserializer).map(|v| Content::Newtype(Box::new(v))) + } + + fn visit_seq(self, mut visitor: V) -> Result + where + V: SeqAccess<'de>, + { + let mut vec = + Vec::::with_capacity(size_hint::cautious::(visitor.size_hint())); + while let Some(e) = tri!(visitor.next_element()) { + vec.push(e); + } + Ok(Content::Seq(vec)) + } + + fn visit_map(self, mut visitor: V) -> Result + where + V: MapAccess<'de>, + { + let mut vec = + Vec::<(Content, Content)>::with_capacity( + size_hint::cautious::<(Content, Content)>(visitor.size_hint()), + ); + while let Some(kv) = tri!(visitor.next_entry()) { + vec.push(kv); + } + Ok(Content::Map(vec)) + } + + fn visit_enum(self, _visitor: V) -> Result + where + V: EnumAccess<'de>, + { + Err(de::Error::custom( + "untagged and internally tagged enums do not support enum input", + )) + } + } + + /// This is the type of the map keys in an internally tagged enum. + /// + /// Not public API. + pub enum TagOrContent<'de> { + Tag, + Content(Content<'de>), + } + + /// Serves as a seed for deserializing a key of internally tagged enum. + /// Cannot capture externally tagged enums, `i128` and `u128`. + struct TagOrContentVisitor<'de> { + name: &'static str, + value: PhantomData>, + } + + impl<'de> TagOrContentVisitor<'de> { + fn new(name: &'static str) -> Self { + TagOrContentVisitor { + name, + value: PhantomData, + } + } + } + + impl<'de> DeserializeSeed<'de> for TagOrContentVisitor<'de> { + type Value = TagOrContent<'de>; + + fn deserialize(self, deserializer: D) -> Result + where + D: Deserializer<'de>, + { + // Internally tagged enums are only supported in self-describing + // formats. + deserializer.deserialize_any(self) + } + } + + impl<'de> Visitor<'de> for TagOrContentVisitor<'de> { + type Value = TagOrContent<'de>; + + fn expecting(&self, fmt: &mut fmt::Formatter) -> fmt::Result { + write!(fmt, "a type tag `{}` or any other value", self.name) + } + + fn visit_bool(self, value: bool) -> Result + where + F: de::Error, + { + ContentVisitor::new() + .visit_bool(value) + .map(TagOrContent::Content) + } + + fn visit_i8(self, value: i8) -> Result + where + F: de::Error, + { + ContentVisitor::new() + .visit_i8(value) + .map(TagOrContent::Content) + } + + fn visit_i16(self, value: i16) -> Result + where + F: de::Error, + { + ContentVisitor::new() + .visit_i16(value) + .map(TagOrContent::Content) + } + + fn visit_i32(self, value: i32) -> Result + where + F: de::Error, + { + ContentVisitor::new() + .visit_i32(value) + .map(TagOrContent::Content) + } + + fn visit_i64(self, value: i64) -> Result + where + F: de::Error, + { + ContentVisitor::new() + .visit_i64(value) + .map(TagOrContent::Content) + } + + fn visit_u8(self, value: u8) -> Result + where + F: de::Error, + { + ContentVisitor::new() + .visit_u8(value) + .map(TagOrContent::Content) + } + + fn visit_u16(self, value: u16) -> Result + where + F: de::Error, + { + ContentVisitor::new() + .visit_u16(value) + .map(TagOrContent::Content) + } + + fn visit_u32(self, value: u32) -> Result + where + F: de::Error, + { + ContentVisitor::new() + .visit_u32(value) + .map(TagOrContent::Content) + } + + fn visit_u64(self, value: u64) -> Result + where + F: de::Error, + { + ContentVisitor::new() + .visit_u64(value) + .map(TagOrContent::Content) + } + + fn visit_f32(self, value: f32) -> Result + where + F: de::Error, + { + ContentVisitor::new() + .visit_f32(value) + .map(TagOrContent::Content) + } + + fn visit_f64(self, value: f64) -> Result + where + F: de::Error, + { + ContentVisitor::new() + .visit_f64(value) + .map(TagOrContent::Content) + } + + fn visit_char(self, value: char) -> Result + where + F: de::Error, + { + ContentVisitor::new() + .visit_char(value) + .map(TagOrContent::Content) + } + + fn visit_str(self, value: &str) -> Result + where + F: de::Error, + { + if value == self.name { + Ok(TagOrContent::Tag) + } else { + ContentVisitor::new() + .visit_str(value) + .map(TagOrContent::Content) + } + } + + fn visit_borrowed_str(self, value: &'de str) -> Result + where + F: de::Error, + { + if value == self.name { + Ok(TagOrContent::Tag) + } else { + ContentVisitor::new() + .visit_borrowed_str(value) + .map(TagOrContent::Content) + } + } + + fn visit_string(self, value: String) -> Result + where + F: de::Error, + { + if value == self.name { + Ok(TagOrContent::Tag) + } else { + ContentVisitor::new() + .visit_string(value) + .map(TagOrContent::Content) + } + } + + fn visit_bytes(self, value: &[u8]) -> Result + where + F: de::Error, + { + if value == self.name.as_bytes() { + Ok(TagOrContent::Tag) + } else { + ContentVisitor::new() + .visit_bytes(value) + .map(TagOrContent::Content) + } + } + + fn visit_borrowed_bytes(self, value: &'de [u8]) -> Result + where + F: de::Error, + { + if value == self.name.as_bytes() { + Ok(TagOrContent::Tag) + } else { + ContentVisitor::new() + .visit_borrowed_bytes(value) + .map(TagOrContent::Content) + } + } + + fn visit_byte_buf(self, value: Vec) -> Result + where + F: de::Error, + { + if value == self.name.as_bytes() { + Ok(TagOrContent::Tag) + } else { + ContentVisitor::new() + .visit_byte_buf(value) + .map(TagOrContent::Content) + } + } + + fn visit_unit(self) -> Result + where + F: de::Error, + { + ContentVisitor::new() + .visit_unit() + .map(TagOrContent::Content) + } + + fn visit_none(self) -> Result + where + F: de::Error, + { + ContentVisitor::new() + .visit_none() + .map(TagOrContent::Content) + } + + fn visit_some(self, deserializer: D) -> Result + where + D: Deserializer<'de>, + { + ContentVisitor::new() + .visit_some(deserializer) + .map(TagOrContent::Content) + } + + fn visit_newtype_struct(self, deserializer: D) -> Result + where + D: Deserializer<'de>, + { + ContentVisitor::new() + .visit_newtype_struct(deserializer) + .map(TagOrContent::Content) + } + + fn visit_seq(self, visitor: V) -> Result + where + V: SeqAccess<'de>, + { + ContentVisitor::new() + .visit_seq(visitor) + .map(TagOrContent::Content) + } + + fn visit_map(self, visitor: V) -> Result + where + V: MapAccess<'de>, + { + ContentVisitor::new() + .visit_map(visitor) + .map(TagOrContent::Content) + } + + fn visit_enum(self, visitor: V) -> Result + where + V: EnumAccess<'de>, + { + ContentVisitor::new() + .visit_enum(visitor) + .map(TagOrContent::Content) + } + } + + /// Used by generated code to deserialize an internally tagged enum. + /// + /// Captures map or sequence from the original deserializer and searches + /// a tag in it (in case of sequence, tag is the first element of sequence). + /// + /// Not public API. + pub struct TaggedContentVisitor { + tag_name: &'static str, + expecting: &'static str, + value: PhantomData, + } + + impl TaggedContentVisitor { + /// Visitor for the content of an internally tagged enum with the given + /// tag name. + pub fn new(name: &'static str, expecting: &'static str) -> Self { + TaggedContentVisitor { + tag_name: name, + expecting, + value: PhantomData, + } + } + } + + impl<'de, T> Visitor<'de> for TaggedContentVisitor + where + T: Deserialize<'de>, + { + type Value = (T, Content<'de>); + + fn expecting(&self, fmt: &mut fmt::Formatter) -> fmt::Result { + fmt.write_str(self.expecting) + } + + fn visit_seq(self, mut seq: S) -> Result + where + S: SeqAccess<'de>, + { + let tag = match tri!(seq.next_element()) { + Some(tag) => tag, + None => { + return Err(de::Error::missing_field(self.tag_name)); + } + }; + let rest = de::value::SeqAccessDeserializer::new(seq); + Ok((tag, tri!(Content::deserialize(rest)))) + } + + fn visit_map(self, mut map: M) -> Result + where + M: MapAccess<'de>, + { + let mut tag = None; + let mut vec = Vec::<(Content, Content)>::with_capacity(size_hint::cautious::<( + Content, + Content, + )>(map.size_hint())); + while let Some(k) = tri!(map.next_key_seed(TagOrContentVisitor::new(self.tag_name))) { + match k { + TagOrContent::Tag => { + if tag.is_some() { + return Err(de::Error::duplicate_field(self.tag_name)); + } + tag = Some(tri!(map.next_value())); + } + TagOrContent::Content(k) => { + let v = tri!(map.next_value()); + vec.push((k, v)); + } + } + } + match tag { + None => Err(de::Error::missing_field(self.tag_name)), + Some(tag) => Ok((tag, Content::Map(vec))), + } + } + } + + /// Used by generated code to deserialize an adjacently tagged enum. + /// + /// Not public API. + pub enum TagOrContentField { + Tag, + Content, + } + + /// Not public API. + pub struct TagOrContentFieldVisitor { + /// Name of the tag field of the adjacently tagged enum + pub tag: &'static str, + /// Name of the content field of the adjacently tagged enum + pub content: &'static str, + } + + impl<'de> DeserializeSeed<'de> for TagOrContentFieldVisitor { + type Value = TagOrContentField; + + fn deserialize(self, deserializer: D) -> Result + where + D: Deserializer<'de>, + { + deserializer.deserialize_identifier(self) + } + } + + impl<'de> Visitor<'de> for TagOrContentFieldVisitor { + type Value = TagOrContentField; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + write!(formatter, "{:?} or {:?}", self.tag, self.content) + } + + fn visit_u64(self, field_index: u64) -> Result + where + E: de::Error, + { + match field_index { + 0 => Ok(TagOrContentField::Tag), + 1 => Ok(TagOrContentField::Content), + _ => Err(de::Error::invalid_value( + Unexpected::Unsigned(field_index), + &self, + )), + } + } + + fn visit_str(self, field: &str) -> Result + where + E: de::Error, + { + if field == self.tag { + Ok(TagOrContentField::Tag) + } else if field == self.content { + Ok(TagOrContentField::Content) + } else { + Err(de::Error::invalid_value(Unexpected::Str(field), &self)) + } + } + + fn visit_bytes(self, field: &[u8]) -> Result + where + E: de::Error, + { + if field == self.tag.as_bytes() { + Ok(TagOrContentField::Tag) + } else if field == self.content.as_bytes() { + Ok(TagOrContentField::Content) + } else { + Err(de::Error::invalid_value(Unexpected::Bytes(field), &self)) + } + } + } + + /// Used by generated code to deserialize an adjacently tagged enum when + /// ignoring unrelated fields is allowed. + /// + /// Not public API. + pub enum TagContentOtherField { + Tag, + Content, + Other, + } + + /// Not public API. + pub struct TagContentOtherFieldVisitor { + /// Name of the tag field of the adjacently tagged enum + pub tag: &'static str, + /// Name of the content field of the adjacently tagged enum + pub content: &'static str, + } + + impl<'de> DeserializeSeed<'de> for TagContentOtherFieldVisitor { + type Value = TagContentOtherField; + + fn deserialize(self, deserializer: D) -> Result + where + D: Deserializer<'de>, + { + deserializer.deserialize_identifier(self) + } + } + + impl<'de> Visitor<'de> for TagContentOtherFieldVisitor { + type Value = TagContentOtherField; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + write!( + formatter, + "{:?}, {:?}, or other ignored fields", + self.tag, self.content + ) + } + + fn visit_u64(self, field_index: u64) -> Result + where + E: de::Error, + { + match field_index { + 0 => Ok(TagContentOtherField::Tag), + 1 => Ok(TagContentOtherField::Content), + _ => Ok(TagContentOtherField::Other), + } + } + + fn visit_str(self, field: &str) -> Result + where + E: de::Error, + { + self.visit_bytes(field.as_bytes()) + } + + fn visit_bytes(self, field: &[u8]) -> Result + where + E: de::Error, + { + if field == self.tag.as_bytes() { + Ok(TagContentOtherField::Tag) + } else if field == self.content.as_bytes() { + Ok(TagContentOtherField::Content) + } else { + Ok(TagContentOtherField::Other) + } + } + } + + /// Not public API + pub struct ContentDeserializer<'de, E> { + content: Content<'de>, + err: PhantomData, + } + + impl<'de, E> ContentDeserializer<'de, E> + where + E: de::Error, + { + #[cold] + fn invalid_type(self, exp: &Expected) -> E { + de::Error::invalid_type(self.content.unexpected(), exp) + } + + fn deserialize_integer(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + match self.content { + Content::U8(v) => visitor.visit_u8(v), + Content::U16(v) => visitor.visit_u16(v), + Content::U32(v) => visitor.visit_u32(v), + Content::U64(v) => visitor.visit_u64(v), + Content::I8(v) => visitor.visit_i8(v), + Content::I16(v) => visitor.visit_i16(v), + Content::I32(v) => visitor.visit_i32(v), + Content::I64(v) => visitor.visit_i64(v), + _ => Err(self.invalid_type(&visitor)), + } + } + + fn deserialize_float(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + match self.content { + Content::F32(v) => visitor.visit_f32(v), + Content::F64(v) => visitor.visit_f64(v), + Content::U8(v) => visitor.visit_u8(v), + Content::U16(v) => visitor.visit_u16(v), + Content::U32(v) => visitor.visit_u32(v), + Content::U64(v) => visitor.visit_u64(v), + Content::I8(v) => visitor.visit_i8(v), + Content::I16(v) => visitor.visit_i16(v), + Content::I32(v) => visitor.visit_i32(v), + Content::I64(v) => visitor.visit_i64(v), + _ => Err(self.invalid_type(&visitor)), + } + } + } + + fn visit_content_seq<'de, V, E>(content: Vec>, visitor: V) -> Result + where + V: Visitor<'de>, + E: de::Error, + { + let seq = content.into_iter().map(ContentDeserializer::new); + let mut seq_visitor = SeqDeserializer::new(seq); + let value = tri!(visitor.visit_seq(&mut seq_visitor)); + tri!(seq_visitor.end()); + Ok(value) + } + + fn visit_content_map<'de, V, E>( + content: Vec<(Content<'de>, Content<'de>)>, + visitor: V, + ) -> Result + where + V: Visitor<'de>, + E: de::Error, + { + let map = content + .into_iter() + .map(|(k, v)| (ContentDeserializer::new(k), ContentDeserializer::new(v))); + let mut map_visitor = MapDeserializer::new(map); + let value = tri!(visitor.visit_map(&mut map_visitor)); + tri!(map_visitor.end()); + Ok(value) + } + + /// Used when deserializing an internally tagged enum because the content + /// will be used exactly once. + impl<'de, E> Deserializer<'de> for ContentDeserializer<'de, E> + where + E: de::Error, + { + type Error = E; + + fn deserialize_any(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + match self.content { + Content::Bool(v) => visitor.visit_bool(v), + Content::U8(v) => visitor.visit_u8(v), + Content::U16(v) => visitor.visit_u16(v), + Content::U32(v) => visitor.visit_u32(v), + Content::U64(v) => visitor.visit_u64(v), + Content::I8(v) => visitor.visit_i8(v), + Content::I16(v) => visitor.visit_i16(v), + Content::I32(v) => visitor.visit_i32(v), + Content::I64(v) => visitor.visit_i64(v), + Content::F32(v) => visitor.visit_f32(v), + Content::F64(v) => visitor.visit_f64(v), + Content::Char(v) => visitor.visit_char(v), + Content::String(v) => visitor.visit_string(v), + Content::Str(v) => visitor.visit_borrowed_str(v), + Content::ByteBuf(v) => visitor.visit_byte_buf(v), + Content::Bytes(v) => visitor.visit_borrowed_bytes(v), + Content::Unit => visitor.visit_unit(), + Content::None => visitor.visit_none(), + Content::Some(v) => visitor.visit_some(ContentDeserializer::new(*v)), + Content::Newtype(v) => visitor.visit_newtype_struct(ContentDeserializer::new(*v)), + Content::Seq(v) => visit_content_seq(v, visitor), + Content::Map(v) => visit_content_map(v, visitor), + } + } + + fn deserialize_bool(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + match self.content { + Content::Bool(v) => visitor.visit_bool(v), + _ => Err(self.invalid_type(&visitor)), + } + } + + fn deserialize_i8(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + self.deserialize_integer(visitor) + } + + fn deserialize_i16(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + self.deserialize_integer(visitor) + } + + fn deserialize_i32(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + self.deserialize_integer(visitor) + } + + fn deserialize_i64(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + self.deserialize_integer(visitor) + } + + fn deserialize_u8(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + self.deserialize_integer(visitor) + } + + fn deserialize_u16(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + self.deserialize_integer(visitor) + } + + fn deserialize_u32(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + self.deserialize_integer(visitor) + } + + fn deserialize_u64(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + self.deserialize_integer(visitor) + } + + fn deserialize_f32(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + self.deserialize_float(visitor) + } + + fn deserialize_f64(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + self.deserialize_float(visitor) + } + + fn deserialize_char(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + match self.content { + Content::Char(v) => visitor.visit_char(v), + Content::String(v) => visitor.visit_string(v), + Content::Str(v) => visitor.visit_borrowed_str(v), + _ => Err(self.invalid_type(&visitor)), + } + } + + fn deserialize_str(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + self.deserialize_string(visitor) + } + + fn deserialize_string(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + match self.content { + Content::String(v) => visitor.visit_string(v), + Content::Str(v) => visitor.visit_borrowed_str(v), + Content::ByteBuf(v) => visitor.visit_byte_buf(v), + Content::Bytes(v) => visitor.visit_borrowed_bytes(v), + _ => Err(self.invalid_type(&visitor)), + } + } + + fn deserialize_bytes(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + self.deserialize_byte_buf(visitor) + } + + fn deserialize_byte_buf(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + match self.content { + Content::String(v) => visitor.visit_string(v), + Content::Str(v) => visitor.visit_borrowed_str(v), + Content::ByteBuf(v) => visitor.visit_byte_buf(v), + Content::Bytes(v) => visitor.visit_borrowed_bytes(v), + Content::Seq(v) => visit_content_seq(v, visitor), + _ => Err(self.invalid_type(&visitor)), + } + } + + fn deserialize_option(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + match self.content { + Content::None => visitor.visit_none(), + Content::Some(v) => visitor.visit_some(ContentDeserializer::new(*v)), + Content::Unit => visitor.visit_unit(), + _ => visitor.visit_some(self), + } + } + + fn deserialize_unit(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + match self.content { + Content::Unit => visitor.visit_unit(), + + // Allow deserializing newtype variant containing unit. + // + // #[derive(Deserialize)] + // #[serde(tag = "result")] + // enum Response { + // Success(T), + // } + // + // We want {"result":"Success"} to deserialize into Response<()>. + Content::Map(ref v) if v.is_empty() => visitor.visit_unit(), + _ => Err(self.invalid_type(&visitor)), + } + } + + fn deserialize_unit_struct( + self, + _name: &'static str, + visitor: V, + ) -> Result + where + V: Visitor<'de>, + { + match self.content { + // As a special case, allow deserializing untagged newtype + // variant containing unit struct. + // + // #[derive(Deserialize)] + // struct Info; + // + // #[derive(Deserialize)] + // #[serde(tag = "topic")] + // enum Message { + // Info(Info), + // } + // + // We want {"topic":"Info"} to deserialize even though + // ordinarily unit structs do not deserialize from empty map/seq. + Content::Map(ref v) if v.is_empty() => visitor.visit_unit(), + Content::Seq(ref v) if v.is_empty() => visitor.visit_unit(), + _ => self.deserialize_any(visitor), + } + } + + fn deserialize_newtype_struct( + self, + _name: &str, + visitor: V, + ) -> Result + where + V: Visitor<'de>, + { + match self.content { + Content::Newtype(v) => visitor.visit_newtype_struct(ContentDeserializer::new(*v)), + _ => visitor.visit_newtype_struct(self), + } + } + + fn deserialize_seq(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + match self.content { + Content::Seq(v) => visit_content_seq(v, visitor), + _ => Err(self.invalid_type(&visitor)), + } + } + + fn deserialize_tuple(self, _len: usize, visitor: V) -> Result + where + V: Visitor<'de>, + { + self.deserialize_seq(visitor) + } + + fn deserialize_tuple_struct( + self, + _name: &'static str, + _len: usize, + visitor: V, + ) -> Result + where + V: Visitor<'de>, + { + self.deserialize_seq(visitor) + } + + fn deserialize_map(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + match self.content { + Content::Map(v) => visit_content_map(v, visitor), + _ => Err(self.invalid_type(&visitor)), + } + } + + fn deserialize_struct( + self, + _name: &'static str, + _fields: &'static [&'static str], + visitor: V, + ) -> Result + where + V: Visitor<'de>, + { + match self.content { + Content::Seq(v) => visit_content_seq(v, visitor), + Content::Map(v) => visit_content_map(v, visitor), + _ => Err(self.invalid_type(&visitor)), + } + } + + fn deserialize_enum( + self, + _name: &str, + _variants: &'static [&'static str], + visitor: V, + ) -> Result + where + V: Visitor<'de>, + { + let (variant, value) = match self.content { + Content::Map(value) => { + let mut iter = value.into_iter(); + let (variant, value) = match iter.next() { + Some(v) => v, + None => { + return Err(de::Error::invalid_value( + de::Unexpected::Map, + &"map with a single key", + )); + } + }; + // enums are encoded in json as maps with a single key:value pair + if iter.next().is_some() { + return Err(de::Error::invalid_value( + de::Unexpected::Map, + &"map with a single key", + )); + } + (variant, Some(value)) + } + s @ Content::String(_) | s @ Content::Str(_) => (s, None), + other => { + return Err(de::Error::invalid_type( + other.unexpected(), + &"string or map", + )); + } + }; + + visitor.visit_enum(EnumDeserializer::new(variant, value)) + } + + fn deserialize_identifier(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + match self.content { + Content::String(v) => visitor.visit_string(v), + Content::Str(v) => visitor.visit_borrowed_str(v), + Content::ByteBuf(v) => visitor.visit_byte_buf(v), + Content::Bytes(v) => visitor.visit_borrowed_bytes(v), + Content::U8(v) => visitor.visit_u8(v), + Content::U64(v) => visitor.visit_u64(v), + _ => Err(self.invalid_type(&visitor)), + } + } + + fn deserialize_ignored_any(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + drop(self); + visitor.visit_unit() + } + + fn __deserialize_content( + self, + _: actually_private::T, + visitor: V, + ) -> Result, Self::Error> + where + V: Visitor<'de, Value = Content<'de>>, + { + let _ = visitor; + Ok(self.content) + } + } + + impl<'de, E> ContentDeserializer<'de, E> { + /// private API, don't use + pub fn new(content: Content<'de>) -> Self { + ContentDeserializer { + content, + err: PhantomData, + } + } + } + + pub struct EnumDeserializer<'de, E> + where + E: de::Error, + { + variant: Content<'de>, + value: Option>, + err: PhantomData, + } + + impl<'de, E> EnumDeserializer<'de, E> + where + E: de::Error, + { + pub fn new(variant: Content<'de>, value: Option>) -> EnumDeserializer<'de, E> { + EnumDeserializer { + variant, + value, + err: PhantomData, + } + } + } + + impl<'de, E> de::EnumAccess<'de> for EnumDeserializer<'de, E> + where + E: de::Error, + { + type Error = E; + type Variant = VariantDeserializer<'de, Self::Error>; + + fn variant_seed(self, seed: V) -> Result<(V::Value, Self::Variant), E> + where + V: de::DeserializeSeed<'de>, + { + let visitor = VariantDeserializer { + value: self.value, + err: PhantomData, + }; + seed.deserialize(ContentDeserializer::new(self.variant)) + .map(|v| (v, visitor)) + } + } + + pub struct VariantDeserializer<'de, E> + where + E: de::Error, + { + value: Option>, + err: PhantomData, + } + + impl<'de, E> de::VariantAccess<'de> for VariantDeserializer<'de, E> + where + E: de::Error, + { + type Error = E; + + fn unit_variant(self) -> Result<(), E> { + match self.value { + Some(value) => de::Deserialize::deserialize(ContentDeserializer::new(value)), + None => Ok(()), + } + } + + fn newtype_variant_seed(self, seed: T) -> Result + where + T: de::DeserializeSeed<'de>, + { + match self.value { + Some(value) => seed.deserialize(ContentDeserializer::new(value)), + None => Err(de::Error::invalid_type( + de::Unexpected::UnitVariant, + &"newtype variant", + )), + } + } + + fn tuple_variant(self, _len: usize, visitor: V) -> Result + where + V: de::Visitor<'de>, + { + match self.value { + Some(Content::Seq(v)) => { + de::Deserializer::deserialize_any(SeqDeserializer::new(v.into_iter()), visitor) + } + Some(other) => Err(de::Error::invalid_type( + other.unexpected(), + &"tuple variant", + )), + None => Err(de::Error::invalid_type( + de::Unexpected::UnitVariant, + &"tuple variant", + )), + } + } + + fn struct_variant( + self, + _fields: &'static [&'static str], + visitor: V, + ) -> Result + where + V: de::Visitor<'de>, + { + match self.value { + Some(Content::Map(v)) => { + de::Deserializer::deserialize_any(MapDeserializer::new(v.into_iter()), visitor) + } + Some(Content::Seq(v)) => { + de::Deserializer::deserialize_any(SeqDeserializer::new(v.into_iter()), visitor) + } + Some(other) => Err(de::Error::invalid_type( + other.unexpected(), + &"struct variant", + )), + None => Err(de::Error::invalid_type( + de::Unexpected::UnitVariant, + &"struct variant", + )), + } + } + } + + /// Not public API. + pub struct ContentRefDeserializer<'a, 'de: 'a, E> { + content: &'a Content<'de>, + err: PhantomData, + } + + impl<'a, 'de, E> ContentRefDeserializer<'a, 'de, E> + where + E: de::Error, + { + #[cold] + fn invalid_type(self, exp: &Expected) -> E { + de::Error::invalid_type(self.content.unexpected(), exp) + } + + fn deserialize_integer(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + match *self.content { + Content::U8(v) => visitor.visit_u8(v), + Content::U16(v) => visitor.visit_u16(v), + Content::U32(v) => visitor.visit_u32(v), + Content::U64(v) => visitor.visit_u64(v), + Content::I8(v) => visitor.visit_i8(v), + Content::I16(v) => visitor.visit_i16(v), + Content::I32(v) => visitor.visit_i32(v), + Content::I64(v) => visitor.visit_i64(v), + _ => Err(self.invalid_type(&visitor)), + } + } + + fn deserialize_float(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + match *self.content { + Content::F32(v) => visitor.visit_f32(v), + Content::F64(v) => visitor.visit_f64(v), + Content::U8(v) => visitor.visit_u8(v), + Content::U16(v) => visitor.visit_u16(v), + Content::U32(v) => visitor.visit_u32(v), + Content::U64(v) => visitor.visit_u64(v), + Content::I8(v) => visitor.visit_i8(v), + Content::I16(v) => visitor.visit_i16(v), + Content::I32(v) => visitor.visit_i32(v), + Content::I64(v) => visitor.visit_i64(v), + _ => Err(self.invalid_type(&visitor)), + } + } + } + + fn visit_content_seq_ref<'a, 'de, V, E>( + content: &'a [Content<'de>], + visitor: V, + ) -> Result + where + V: Visitor<'de>, + E: de::Error, + { + let seq = content.iter().map(ContentRefDeserializer::new); + let mut seq_visitor = SeqDeserializer::new(seq); + let value = tri!(visitor.visit_seq(&mut seq_visitor)); + tri!(seq_visitor.end()); + Ok(value) + } + + fn visit_content_map_ref<'a, 'de, V, E>( + content: &'a [(Content<'de>, Content<'de>)], + visitor: V, + ) -> Result + where + V: Visitor<'de>, + E: de::Error, + { + let map = content.iter().map(|(k, v)| { + ( + ContentRefDeserializer::new(k), + ContentRefDeserializer::new(v), + ) + }); + let mut map_visitor = MapDeserializer::new(map); + let value = tri!(visitor.visit_map(&mut map_visitor)); + tri!(map_visitor.end()); + Ok(value) + } + + /// Used when deserializing an untagged enum because the content may need + /// to be used more than once. + impl<'de, 'a, E> Deserializer<'de> for ContentRefDeserializer<'a, 'de, E> + where + E: de::Error, + { + type Error = E; + + fn deserialize_any(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + match *self.content { + Content::Bool(v) => visitor.visit_bool(v), + Content::U8(v) => visitor.visit_u8(v), + Content::U16(v) => visitor.visit_u16(v), + Content::U32(v) => visitor.visit_u32(v), + Content::U64(v) => visitor.visit_u64(v), + Content::I8(v) => visitor.visit_i8(v), + Content::I16(v) => visitor.visit_i16(v), + Content::I32(v) => visitor.visit_i32(v), + Content::I64(v) => visitor.visit_i64(v), + Content::F32(v) => visitor.visit_f32(v), + Content::F64(v) => visitor.visit_f64(v), + Content::Char(v) => visitor.visit_char(v), + Content::String(ref v) => visitor.visit_str(v), + Content::Str(v) => visitor.visit_borrowed_str(v), + Content::ByteBuf(ref v) => visitor.visit_bytes(v), + Content::Bytes(v) => visitor.visit_borrowed_bytes(v), + Content::Unit => visitor.visit_unit(), + Content::None => visitor.visit_none(), + Content::Some(ref v) => visitor.visit_some(ContentRefDeserializer::new(v)), + Content::Newtype(ref v) => { + visitor.visit_newtype_struct(ContentRefDeserializer::new(v)) + } + Content::Seq(ref v) => visit_content_seq_ref(v, visitor), + Content::Map(ref v) => visit_content_map_ref(v, visitor), + } + } + + fn deserialize_bool(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + match *self.content { + Content::Bool(v) => visitor.visit_bool(v), + _ => Err(self.invalid_type(&visitor)), + } + } + + fn deserialize_i8(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + self.deserialize_integer(visitor) + } + + fn deserialize_i16(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + self.deserialize_integer(visitor) + } + + fn deserialize_i32(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + self.deserialize_integer(visitor) + } + + fn deserialize_i64(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + self.deserialize_integer(visitor) + } + + fn deserialize_u8(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + self.deserialize_integer(visitor) + } + + fn deserialize_u16(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + self.deserialize_integer(visitor) + } + + fn deserialize_u32(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + self.deserialize_integer(visitor) + } + + fn deserialize_u64(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + self.deserialize_integer(visitor) + } + + fn deserialize_f32(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + self.deserialize_float(visitor) + } + + fn deserialize_f64(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + self.deserialize_float(visitor) + } + + fn deserialize_char(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + match *self.content { + Content::Char(v) => visitor.visit_char(v), + Content::String(ref v) => visitor.visit_str(v), + Content::Str(v) => visitor.visit_borrowed_str(v), + _ => Err(self.invalid_type(&visitor)), + } + } + + fn deserialize_str(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + match *self.content { + Content::String(ref v) => visitor.visit_str(v), + Content::Str(v) => visitor.visit_borrowed_str(v), + Content::ByteBuf(ref v) => visitor.visit_bytes(v), + Content::Bytes(v) => visitor.visit_borrowed_bytes(v), + _ => Err(self.invalid_type(&visitor)), + } + } + + fn deserialize_string(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + self.deserialize_str(visitor) + } + + fn deserialize_bytes(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + match *self.content { + Content::String(ref v) => visitor.visit_str(v), + Content::Str(v) => visitor.visit_borrowed_str(v), + Content::ByteBuf(ref v) => visitor.visit_bytes(v), + Content::Bytes(v) => visitor.visit_borrowed_bytes(v), + Content::Seq(ref v) => visit_content_seq_ref(v, visitor), + _ => Err(self.invalid_type(&visitor)), + } + } + + fn deserialize_byte_buf(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + self.deserialize_bytes(visitor) + } + + fn deserialize_option(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + // Covered by tests/test_enum_untagged.rs + // with_optional_field::* + match *self.content { + Content::None => visitor.visit_none(), + Content::Some(ref v) => visitor.visit_some(ContentRefDeserializer::new(v)), + Content::Unit => visitor.visit_unit(), + // This case is to support data formats which do not encode an + // indication whether a value is optional. An example of such a + // format is JSON, and a counterexample is RON. When requesting + // `deserialize_any` in JSON, the data format never performs + // `Visitor::visit_some` but we still must be able to + // deserialize the resulting Content into data structures with + // optional fields. + _ => visitor.visit_some(self), + } + } + + fn deserialize_unit(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + match *self.content { + Content::Unit => visitor.visit_unit(), + _ => Err(self.invalid_type(&visitor)), + } + } + + fn deserialize_unit_struct( + self, + _name: &'static str, + visitor: V, + ) -> Result + where + V: Visitor<'de>, + { + self.deserialize_unit(visitor) + } + + fn deserialize_newtype_struct(self, _name: &str, visitor: V) -> Result + where + V: Visitor<'de>, + { + // Covered by tests/test_enum_untagged.rs + // newtype_struct + match *self.content { + Content::Newtype(ref v) => { + visitor.visit_newtype_struct(ContentRefDeserializer::new(v)) + } + // This case is to support data formats that encode newtype + // structs and their underlying data the same, with no + // indication whether a newtype wrapper was present. For example + // JSON does this, while RON does not. In RON a newtype's name + // is included in the serialized representation and it knows to + // call `Visitor::visit_newtype_struct` from `deserialize_any`. + // JSON's `deserialize_any` never calls `visit_newtype_struct` + // but in this code we still must be able to deserialize the + // resulting Content into newtypes. + _ => visitor.visit_newtype_struct(self), + } + } + + fn deserialize_seq(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + match *self.content { + Content::Seq(ref v) => visit_content_seq_ref(v, visitor), + _ => Err(self.invalid_type(&visitor)), + } + } + + fn deserialize_tuple(self, _len: usize, visitor: V) -> Result + where + V: Visitor<'de>, + { + self.deserialize_seq(visitor) + } + + fn deserialize_tuple_struct( + self, + _name: &'static str, + _len: usize, + visitor: V, + ) -> Result + where + V: Visitor<'de>, + { + self.deserialize_seq(visitor) + } + + fn deserialize_map(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + match *self.content { + Content::Map(ref v) => visit_content_map_ref(v, visitor), + _ => Err(self.invalid_type(&visitor)), + } + } + + fn deserialize_struct( + self, + _name: &'static str, + _fields: &'static [&'static str], + visitor: V, + ) -> Result + where + V: Visitor<'de>, + { + match *self.content { + Content::Seq(ref v) => visit_content_seq_ref(v, visitor), + Content::Map(ref v) => visit_content_map_ref(v, visitor), + _ => Err(self.invalid_type(&visitor)), + } + } + + fn deserialize_enum( + self, + _name: &str, + _variants: &'static [&'static str], + visitor: V, + ) -> Result + where + V: Visitor<'de>, + { + let (variant, value) = match *self.content { + Content::Map(ref value) => { + let mut iter = value.iter(); + let (variant, value) = match iter.next() { + Some(v) => v, + None => { + return Err(de::Error::invalid_value( + de::Unexpected::Map, + &"map with a single key", + )); + } + }; + // enums are encoded in json as maps with a single key:value pair + if iter.next().is_some() { + return Err(de::Error::invalid_value( + de::Unexpected::Map, + &"map with a single key", + )); + } + (variant, Some(value)) + } + ref s @ Content::String(_) | ref s @ Content::Str(_) => (s, None), + ref other => { + return Err(de::Error::invalid_type( + other.unexpected(), + &"string or map", + )); + } + }; + + visitor.visit_enum(EnumRefDeserializer { + variant, + value, + err: PhantomData, + }) + } + + fn deserialize_identifier(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + match *self.content { + Content::String(ref v) => visitor.visit_str(v), + Content::Str(v) => visitor.visit_borrowed_str(v), + Content::ByteBuf(ref v) => visitor.visit_bytes(v), + Content::Bytes(v) => visitor.visit_borrowed_bytes(v), + Content::U8(v) => visitor.visit_u8(v), + Content::U64(v) => visitor.visit_u64(v), + _ => Err(self.invalid_type(&visitor)), + } + } + + fn deserialize_ignored_any(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + visitor.visit_unit() + } + + fn __deserialize_content( + self, + _: actually_private::T, + visitor: V, + ) -> Result, Self::Error> + where + V: Visitor<'de, Value = Content<'de>>, + { + let _ = visitor; + Ok(self.content.clone()) + } + } + + impl<'a, 'de, E> ContentRefDeserializer<'a, 'de, E> { + /// private API, don't use + pub fn new(content: &'a Content<'de>) -> Self { + ContentRefDeserializer { + content, + err: PhantomData, + } + } + } + + impl<'a, 'de: 'a, E> Copy for ContentRefDeserializer<'a, 'de, E> {} + + impl<'a, 'de: 'a, E> Clone for ContentRefDeserializer<'a, 'de, E> { + fn clone(&self) -> Self { + *self + } + } + + struct EnumRefDeserializer<'a, 'de: 'a, E> + where + E: de::Error, + { + variant: &'a Content<'de>, + value: Option<&'a Content<'de>>, + err: PhantomData, + } + + impl<'de, 'a, E> de::EnumAccess<'de> for EnumRefDeserializer<'a, 'de, E> + where + E: de::Error, + { + type Error = E; + type Variant = VariantRefDeserializer<'a, 'de, Self::Error>; + + fn variant_seed(self, seed: V) -> Result<(V::Value, Self::Variant), Self::Error> + where + V: de::DeserializeSeed<'de>, + { + let visitor = VariantRefDeserializer { + value: self.value, + err: PhantomData, + }; + seed.deserialize(ContentRefDeserializer::new(self.variant)) + .map(|v| (v, visitor)) + } + } + + struct VariantRefDeserializer<'a, 'de: 'a, E> + where + E: de::Error, + { + value: Option<&'a Content<'de>>, + err: PhantomData, + } + + impl<'de, 'a, E> de::VariantAccess<'de> for VariantRefDeserializer<'a, 'de, E> + where + E: de::Error, + { + type Error = E; + + fn unit_variant(self) -> Result<(), E> { + match self.value { + Some(value) => de::Deserialize::deserialize(ContentRefDeserializer::new(value)), + // Covered by tests/test_annotations.rs + // test_partially_untagged_adjacently_tagged_enum + // Covered by tests/test_enum_untagged.rs + // newtype_enum::unit + None => Ok(()), + } + } + + fn newtype_variant_seed(self, seed: T) -> Result + where + T: de::DeserializeSeed<'de>, + { + match self.value { + // Covered by tests/test_annotations.rs + // test_partially_untagged_enum_desugared + // test_partially_untagged_enum_generic + // Covered by tests/test_enum_untagged.rs + // newtype_enum::newtype + Some(value) => seed.deserialize(ContentRefDeserializer::new(value)), + None => Err(de::Error::invalid_type( + de::Unexpected::UnitVariant, + &"newtype variant", + )), + } + } + + fn tuple_variant(self, _len: usize, visitor: V) -> Result + where + V: de::Visitor<'de>, + { + match self.value { + // Covered by tests/test_annotations.rs + // test_partially_untagged_enum + // test_partially_untagged_enum_desugared + // Covered by tests/test_enum_untagged.rs + // newtype_enum::tuple0 + // newtype_enum::tuple2 + Some(Content::Seq(v)) => visit_content_seq_ref(v, visitor), + Some(other) => Err(de::Error::invalid_type( + other.unexpected(), + &"tuple variant", + )), + None => Err(de::Error::invalid_type( + de::Unexpected::UnitVariant, + &"tuple variant", + )), + } + } + + fn struct_variant( + self, + _fields: &'static [&'static str], + visitor: V, + ) -> Result + where + V: de::Visitor<'de>, + { + match self.value { + // Covered by tests/test_enum_untagged.rs + // newtype_enum::struct_from_map + Some(Content::Map(v)) => visit_content_map_ref(v, visitor), + // Covered by tests/test_enum_untagged.rs + // newtype_enum::struct_from_seq + // newtype_enum::empty_struct_from_seq + Some(Content::Seq(v)) => visit_content_seq_ref(v, visitor), + Some(other) => Err(de::Error::invalid_type( + other.unexpected(), + &"struct variant", + )), + None => Err(de::Error::invalid_type( + de::Unexpected::UnitVariant, + &"struct variant", + )), + } + } + } + + impl<'de, E> de::IntoDeserializer<'de, E> for ContentDeserializer<'de, E> + where + E: de::Error, + { + type Deserializer = Self; + + fn into_deserializer(self) -> Self { + self + } + } + + impl<'de, 'a, E> de::IntoDeserializer<'de, E> for ContentRefDeserializer<'a, 'de, E> + where + E: de::Error, + { + type Deserializer = Self; + + fn into_deserializer(self) -> Self { + self + } + } + + /// Visitor for deserializing an internally tagged unit variant. + /// + /// Not public API. + pub struct InternallyTaggedUnitVisitor<'a> { + type_name: &'a str, + variant_name: &'a str, + } + + impl<'a> InternallyTaggedUnitVisitor<'a> { + /// Not public API. + pub fn new(type_name: &'a str, variant_name: &'a str) -> Self { + InternallyTaggedUnitVisitor { + type_name, + variant_name, + } + } + } + + impl<'de, 'a> Visitor<'de> for InternallyTaggedUnitVisitor<'a> { + type Value = (); + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + write!( + formatter, + "unit variant {}::{}", + self.type_name, self.variant_name + ) + } + + fn visit_seq(self, _: S) -> Result<(), S::Error> + where + S: SeqAccess<'de>, + { + Ok(()) + } + + fn visit_map(self, mut access: M) -> Result<(), M::Error> + where + M: MapAccess<'de>, + { + while tri!(access.next_entry::()).is_some() {} + Ok(()) + } + } + + /// Visitor for deserializing an untagged unit variant. + /// + /// Not public API. + pub struct UntaggedUnitVisitor<'a> { + type_name: &'a str, + variant_name: &'a str, + } + + impl<'a> UntaggedUnitVisitor<'a> { + /// Not public API. + pub fn new(type_name: &'a str, variant_name: &'a str) -> Self { + UntaggedUnitVisitor { + type_name, + variant_name, + } + } + } + + impl<'de, 'a> Visitor<'de> for UntaggedUnitVisitor<'a> { + type Value = (); + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + write!( + formatter, + "unit variant {}::{}", + self.type_name, self.variant_name + ) + } + + fn visit_unit(self) -> Result<(), E> + where + E: de::Error, + { + Ok(()) + } + + fn visit_none(self) -> Result<(), E> + where + E: de::Error, + { + Ok(()) + } + } +} + +//////////////////////////////////////////////////////////////////////////////// + +// Like `IntoDeserializer` but also implemented for `&[u8]`. This is used for +// the newtype fallthrough case of `field_identifier`. +// +// #[derive(Deserialize)] +// #[serde(field_identifier)] +// enum F { +// A, +// B, +// Other(String), // deserialized using IdentifierDeserializer +// } +pub trait IdentifierDeserializer<'de, E: Error> { + type Deserializer: Deserializer<'de, Error = E>; + + fn from(self) -> Self::Deserializer; +} + +pub struct Borrowed<'de, T: 'de + ?Sized>(pub &'de T); + +impl<'de, E> IdentifierDeserializer<'de, E> for u64 +where + E: Error, +{ + type Deserializer = >::Deserializer; + + fn from(self) -> Self::Deserializer { + self.into_deserializer() + } +} + +pub struct StrDeserializer<'a, E> { + value: &'a str, + marker: PhantomData, +} + +impl<'de, 'a, E> Deserializer<'de> for StrDeserializer<'a, E> +where + E: Error, +{ + type Error = E; + + fn deserialize_any(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + visitor.visit_str(self.value) + } + + forward_to_deserialize_any! { + bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string + bytes byte_buf option unit unit_struct newtype_struct seq tuple + tuple_struct map struct enum identifier ignored_any + } +} + +pub struct BorrowedStrDeserializer<'de, E> { + value: &'de str, + marker: PhantomData, +} + +impl<'de, E> Deserializer<'de> for BorrowedStrDeserializer<'de, E> +where + E: Error, +{ + type Error = E; + + fn deserialize_any(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + visitor.visit_borrowed_str(self.value) + } + + forward_to_deserialize_any! { + bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string + bytes byte_buf option unit unit_struct newtype_struct seq tuple + tuple_struct map struct enum identifier ignored_any + } +} + +impl<'a, E> IdentifierDeserializer<'a, E> for &'a str +where + E: Error, +{ + type Deserializer = StrDeserializer<'a, E>; + + fn from(self) -> Self::Deserializer { + StrDeserializer { + value: self, + marker: PhantomData, + } + } +} + +impl<'de, E> IdentifierDeserializer<'de, E> for Borrowed<'de, str> +where + E: Error, +{ + type Deserializer = BorrowedStrDeserializer<'de, E>; + + fn from(self) -> Self::Deserializer { + BorrowedStrDeserializer { + value: self.0, + marker: PhantomData, + } + } +} + +impl<'a, E> IdentifierDeserializer<'a, E> for &'a [u8] +where + E: Error, +{ + type Deserializer = BytesDeserializer<'a, E>; + + fn from(self) -> Self::Deserializer { + BytesDeserializer::new(self) + } +} + +impl<'de, E> IdentifierDeserializer<'de, E> for Borrowed<'de, [u8]> +where + E: Error, +{ + type Deserializer = BorrowedBytesDeserializer<'de, E>; + + fn from(self) -> Self::Deserializer { + BorrowedBytesDeserializer::new(self.0) + } +} + +#[cfg(any(feature = "std", feature = "alloc"))] +pub struct FlatMapDeserializer<'a, 'de: 'a, E>( + pub &'a mut Vec, Content<'de>)>>, + pub PhantomData, +); + +#[cfg(any(feature = "std", feature = "alloc"))] +impl<'a, 'de, E> FlatMapDeserializer<'a, 'de, E> +where + E: Error, +{ + fn deserialize_other() -> Result { + Err(Error::custom("can only flatten structs and maps")) + } +} + +#[cfg(any(feature = "std", feature = "alloc"))] +macro_rules! forward_to_deserialize_other { + ($($func:ident ($($arg:ty),*))*) => { + $( + fn $func(self, $(_: $arg,)* _visitor: V) -> Result + where + V: Visitor<'de>, + { + Self::deserialize_other() + } + )* + } +} + +#[cfg(any(feature = "std", feature = "alloc"))] +impl<'a, 'de, E> Deserializer<'de> for FlatMapDeserializer<'a, 'de, E> +where + E: Error, +{ + type Error = E; + + fn deserialize_any(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + self.deserialize_map(visitor) + } + + fn deserialize_enum( + self, + name: &'static str, + variants: &'static [&'static str], + visitor: V, + ) -> Result + where + V: Visitor<'de>, + { + for entry in self.0 { + if let Some((key, value)) = flat_map_take_entry(entry, variants) { + return visitor.visit_enum(EnumDeserializer::new(key, Some(value))); + } + } + + Err(Error::custom(format_args!( + "no variant of enum {} found in flattened data", + name + ))) + } + + fn deserialize_map(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + visitor.visit_map(FlatMapAccess { + iter: self.0.iter(), + pending_content: None, + _marker: PhantomData, + }) + } + + fn deserialize_struct( + self, + _: &'static str, + fields: &'static [&'static str], + visitor: V, + ) -> Result + where + V: Visitor<'de>, + { + visitor.visit_map(FlatStructAccess { + iter: self.0.iter_mut(), + pending_content: None, + fields, + _marker: PhantomData, + }) + } + + fn deserialize_newtype_struct(self, _name: &str, visitor: V) -> Result + where + V: Visitor<'de>, + { + visitor.visit_newtype_struct(self) + } + + fn deserialize_option(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + match visitor.__private_visit_untagged_option(self) { + Ok(value) => Ok(value), + Err(()) => Self::deserialize_other(), + } + } + + fn deserialize_unit(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + visitor.visit_unit() + } + + fn deserialize_unit_struct( + self, + _name: &'static str, + visitor: V, + ) -> Result + where + V: Visitor<'de>, + { + visitor.visit_unit() + } + + fn deserialize_ignored_any(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + visitor.visit_unit() + } + + forward_to_deserialize_other! { + deserialize_bool() + deserialize_i8() + deserialize_i16() + deserialize_i32() + deserialize_i64() + deserialize_u8() + deserialize_u16() + deserialize_u32() + deserialize_u64() + deserialize_f32() + deserialize_f64() + deserialize_char() + deserialize_str() + deserialize_string() + deserialize_bytes() + deserialize_byte_buf() + deserialize_seq() + deserialize_tuple(usize) + deserialize_tuple_struct(&'static str, usize) + deserialize_identifier() + } +} + +#[cfg(any(feature = "std", feature = "alloc"))] +struct FlatMapAccess<'a, 'de: 'a, E> { + iter: slice::Iter<'a, Option<(Content<'de>, Content<'de>)>>, + pending_content: Option<&'a Content<'de>>, + _marker: PhantomData, +} + +#[cfg(any(feature = "std", feature = "alloc"))] +impl<'a, 'de, E> MapAccess<'de> for FlatMapAccess<'a, 'de, E> +where + E: Error, +{ + type Error = E; + + fn next_key_seed(&mut self, seed: T) -> Result, Self::Error> + where + T: DeserializeSeed<'de>, + { + for item in &mut self.iter { + // Items in the vector are nulled out when used by a struct. + if let Some((ref key, ref content)) = *item { + // Do not take(), instead borrow this entry. The internally tagged + // enum does its own buffering so we can't tell whether this entry + // is going to be consumed. Borrowing here leaves the entry + // available for later flattened fields. + self.pending_content = Some(content); + return seed.deserialize(ContentRefDeserializer::new(key)).map(Some); + } + } + Ok(None) + } + + fn next_value_seed(&mut self, seed: T) -> Result + where + T: DeserializeSeed<'de>, + { + match self.pending_content.take() { + Some(value) => seed.deserialize(ContentRefDeserializer::new(value)), + None => Err(Error::custom("value is missing")), + } + } +} + +#[cfg(any(feature = "std", feature = "alloc"))] +struct FlatStructAccess<'a, 'de: 'a, E> { + iter: slice::IterMut<'a, Option<(Content<'de>, Content<'de>)>>, + pending_content: Option>, + fields: &'static [&'static str], + _marker: PhantomData, +} + +#[cfg(any(feature = "std", feature = "alloc"))] +impl<'a, 'de, E> MapAccess<'de> for FlatStructAccess<'a, 'de, E> +where + E: Error, +{ + type Error = E; + + fn next_key_seed(&mut self, seed: T) -> Result, Self::Error> + where + T: DeserializeSeed<'de>, + { + for entry in self.iter.by_ref() { + if let Some((key, content)) = flat_map_take_entry(entry, self.fields) { + self.pending_content = Some(content); + return seed.deserialize(ContentDeserializer::new(key)).map(Some); + } + } + Ok(None) + } + + fn next_value_seed(&mut self, seed: T) -> Result + where + T: DeserializeSeed<'de>, + { + match self.pending_content.take() { + Some(value) => seed.deserialize(ContentDeserializer::new(value)), + None => Err(Error::custom("value is missing")), + } + } +} + +/// Claims one key-value pair from a FlatMapDeserializer's field buffer if the +/// field name matches any of the recognized ones. +#[cfg(any(feature = "std", feature = "alloc"))] +fn flat_map_take_entry<'de>( + entry: &mut Option<(Content<'de>, Content<'de>)>, + recognized: &[&str], +) -> Option<(Content<'de>, Content<'de>)> { + // Entries in the FlatMapDeserializer buffer are nulled out as they get + // claimed for deserialization. We only use an entry if it is still present + // and if the field is one recognized by the current data structure. + let is_recognized = match entry { + None => false, + Some((k, _v)) => k.as_str().map_or(false, |name| recognized.contains(&name)), + }; + + if is_recognized { + entry.take() + } else { + None + } +} + +pub struct AdjacentlyTaggedEnumVariantSeed { + pub enum_name: &'static str, + pub variants: &'static [&'static str], + pub fields_enum: PhantomData, +} + +pub struct AdjacentlyTaggedEnumVariantVisitor { + enum_name: &'static str, + fields_enum: PhantomData, +} + +impl<'de, F> Visitor<'de> for AdjacentlyTaggedEnumVariantVisitor +where + F: Deserialize<'de>, +{ + type Value = F; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + write!(formatter, "variant of enum {}", self.enum_name) + } + + fn visit_enum(self, data: A) -> Result + where + A: EnumAccess<'de>, + { + let (variant, variant_access) = tri!(data.variant()); + tri!(variant_access.unit_variant()); + Ok(variant) + } +} + +impl<'de, F> DeserializeSeed<'de> for AdjacentlyTaggedEnumVariantSeed +where + F: Deserialize<'de>, +{ + type Value = F; + + fn deserialize(self, deserializer: D) -> Result + where + D: Deserializer<'de>, + { + deserializer.deserialize_enum( + self.enum_name, + self.variants, + AdjacentlyTaggedEnumVariantVisitor { + enum_name: self.enum_name, + fields_enum: PhantomData, + }, + ) + } +} diff --git a/vendor/serde/src/private/doc.rs b/vendor/serde/src/private/doc.rs new file mode 100644 index 0000000..1f17c8d --- /dev/null +++ b/vendor/serde/src/private/doc.rs @@ -0,0 +1,162 @@ +// Used only by Serde doc tests. Not public API. + +use crate::lib::*; + +use crate::ser; + +#[doc(hidden)] +#[derive(Debug)] +pub struct Error; + +impl ser::Error for Error { + fn custom(_: T) -> Self + where + T: Display, + { + unimplemented!() + } +} + +#[cfg(feature = "std")] +impl error::Error for Error { + fn description(&self) -> &str { + unimplemented!() + } +} + +impl Display for Error { + fn fmt(&self, _: &mut fmt::Formatter) -> fmt::Result { + unimplemented!() + } +} + +#[doc(hidden)] +#[macro_export] +macro_rules! __private_serialize { + () => { + trait Serialize { + fn serialize(&self, serializer: S) -> Result + where + S: $crate::Serializer; + } + }; +} + +#[doc(hidden)] +#[macro_export(local_inner_macros)] +macro_rules! __serialize_unimplemented { + ($($func:ident)*) => { + $( + __serialize_unimplemented_helper!($func); + )* + }; +} + +#[doc(hidden)] +#[macro_export] +macro_rules! __serialize_unimplemented_method { + ($func:ident $(<$t:ident>)* ($($arg:ty),*) -> $ret:ident) => { + fn $func $(<$t>)* (self $(, _: $arg)*) -> $crate::__private::Result + where + $($t: ?Sized + $crate::Serialize,)* + { + unimplemented!() + } + }; +} + +#[doc(hidden)] +#[macro_export(local_inner_macros)] +macro_rules! __serialize_unimplemented_helper { + (bool) => { + __serialize_unimplemented_method!(serialize_bool(bool) -> Ok); + }; + (i8) => { + __serialize_unimplemented_method!(serialize_i8(i8) -> Ok); + }; + (i16) => { + __serialize_unimplemented_method!(serialize_i16(i16) -> Ok); + }; + (i32) => { + __serialize_unimplemented_method!(serialize_i32(i32) -> Ok); + }; + (i64) => { + __serialize_unimplemented_method!(serialize_i64(i64) -> Ok); + }; + (u8) => { + __serialize_unimplemented_method!(serialize_u8(u8) -> Ok); + }; + (u16) => { + __serialize_unimplemented_method!(serialize_u16(u16) -> Ok); + }; + (u32) => { + __serialize_unimplemented_method!(serialize_u32(u32) -> Ok); + }; + (u64) => { + __serialize_unimplemented_method!(serialize_u64(u64) -> Ok); + }; + (f32) => { + __serialize_unimplemented_method!(serialize_f32(f32) -> Ok); + }; + (f64) => { + __serialize_unimplemented_method!(serialize_f64(f64) -> Ok); + }; + (char) => { + __serialize_unimplemented_method!(serialize_char(char) -> Ok); + }; + (str) => { + __serialize_unimplemented_method!(serialize_str(&str) -> Ok); + }; + (bytes) => { + __serialize_unimplemented_method!(serialize_bytes(&[u8]) -> Ok); + }; + (none) => { + __serialize_unimplemented_method!(serialize_none() -> Ok); + }; + (some) => { + __serialize_unimplemented_method!(serialize_some(&T) -> Ok); + }; + (unit) => { + __serialize_unimplemented_method!(serialize_unit() -> Ok); + }; + (unit_struct) => { + __serialize_unimplemented_method!(serialize_unit_struct(&str) -> Ok); + }; + (unit_variant) => { + __serialize_unimplemented_method!(serialize_unit_variant(&str, u32, &str) -> Ok); + }; + (newtype_struct) => { + __serialize_unimplemented_method!(serialize_newtype_struct(&str, &T) -> Ok); + }; + (newtype_variant) => { + __serialize_unimplemented_method!(serialize_newtype_variant(&str, u32, &str, &T) -> Ok); + }; + (seq) => { + type SerializeSeq = $crate::ser::Impossible; + __serialize_unimplemented_method!(serialize_seq(Option) -> SerializeSeq); + }; + (tuple) => { + type SerializeTuple = $crate::ser::Impossible; + __serialize_unimplemented_method!(serialize_tuple(usize) -> SerializeTuple); + }; + (tuple_struct) => { + type SerializeTupleStruct = $crate::ser::Impossible; + __serialize_unimplemented_method!(serialize_tuple_struct(&str, usize) -> SerializeTupleStruct); + }; + (tuple_variant) => { + type SerializeTupleVariant = $crate::ser::Impossible; + __serialize_unimplemented_method!(serialize_tuple_variant(&str, u32, &str, usize) -> SerializeTupleVariant); + }; + (map) => { + type SerializeMap = $crate::ser::Impossible; + __serialize_unimplemented_method!(serialize_map(Option) -> SerializeMap); + }; + (struct) => { + type SerializeStruct = $crate::ser::Impossible; + __serialize_unimplemented_method!(serialize_struct(&str, usize) -> SerializeStruct); + }; + (struct_variant) => { + type SerializeStructVariant = $crate::ser::Impossible; + __serialize_unimplemented_method!(serialize_struct_variant(&str, u32, &str, usize) -> SerializeStructVariant); + }; +} diff --git a/vendor/serde/src/private/mod.rs b/vendor/serde/src/private/mod.rs new file mode 100644 index 0000000..177f850 --- /dev/null +++ b/vendor/serde/src/private/mod.rs @@ -0,0 +1,48 @@ +#[cfg(not(no_serde_derive))] +pub mod de; +#[cfg(not(no_serde_derive))] +pub mod ser; + +// FIXME: #[cfg(doctest)] once https://github.com/rust-lang/rust/issues/67295 is fixed. +pub mod doc; + +pub use crate::lib::clone::Clone; +pub use crate::lib::convert::{From, Into}; +pub use crate::lib::default::Default; +pub use crate::lib::fmt::{self, Formatter}; +pub use crate::lib::marker::PhantomData; +pub use crate::lib::option::Option::{self, None, Some}; +pub use crate::lib::ptr; +pub use crate::lib::result::Result::{self, Err, Ok}; + +pub use self::string::from_utf8_lossy; + +#[cfg(any(feature = "alloc", feature = "std"))] +pub use crate::lib::{ToString, Vec}; + +#[cfg(not(no_core_try_from))] +pub use crate::lib::convert::TryFrom; + +mod string { + use crate::lib::*; + + #[cfg(any(feature = "std", feature = "alloc"))] + pub fn from_utf8_lossy(bytes: &[u8]) -> Cow { + String::from_utf8_lossy(bytes) + } + + // The generated code calls this like: + // + // let value = &_serde::__private::from_utf8_lossy(bytes); + // Err(_serde::de::Error::unknown_variant(value, VARIANTS)) + // + // so it is okay for the return type to be different from the std case as long + // as the above works. + #[cfg(not(any(feature = "std", feature = "alloc")))] + pub fn from_utf8_lossy(bytes: &[u8]) -> &str { + // Three unicode replacement characters if it fails. They look like a + // white-on-black question mark. The user will recognize it as invalid + // UTF-8. + str::from_utf8(bytes).unwrap_or("\u{fffd}\u{fffd}\u{fffd}") + } +} diff --git a/vendor/serde/src/private/ser.rs b/vendor/serde/src/private/ser.rs new file mode 100644 index 0000000..ebfeba9 --- /dev/null +++ b/vendor/serde/src/private/ser.rs @@ -0,0 +1,1360 @@ +use crate::lib::*; + +use crate::ser::{self, Impossible, Serialize, SerializeMap, SerializeStruct, Serializer}; + +#[cfg(any(feature = "std", feature = "alloc"))] +use self::content::{ + Content, ContentSerializer, SerializeStructVariantAsMapValue, SerializeTupleVariantAsMapValue, +}; + +/// Used to check that serde(getter) attributes return the expected type. +/// Not public API. +pub fn constrain(t: &T) -> &T { + t +} + +/// Not public API. +pub fn serialize_tagged_newtype( + serializer: S, + type_ident: &'static str, + variant_ident: &'static str, + tag: &'static str, + variant_name: &'static str, + value: &T, +) -> Result +where + S: Serializer, + T: Serialize, +{ + value.serialize(TaggedSerializer { + type_ident, + variant_ident, + tag, + variant_name, + delegate: serializer, + }) +} + +struct TaggedSerializer { + type_ident: &'static str, + variant_ident: &'static str, + tag: &'static str, + variant_name: &'static str, + delegate: S, +} + +enum Unsupported { + Boolean, + Integer, + Float, + Char, + String, + ByteArray, + Optional, + Sequence, + Tuple, + TupleStruct, + Enum, +} + +impl Display for Unsupported { + fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + match *self { + Unsupported::Boolean => formatter.write_str("a boolean"), + Unsupported::Integer => formatter.write_str("an integer"), + Unsupported::Float => formatter.write_str("a float"), + Unsupported::Char => formatter.write_str("a char"), + Unsupported::String => formatter.write_str("a string"), + Unsupported::ByteArray => formatter.write_str("a byte array"), + Unsupported::Optional => formatter.write_str("an optional"), + Unsupported::Sequence => formatter.write_str("a sequence"), + Unsupported::Tuple => formatter.write_str("a tuple"), + Unsupported::TupleStruct => formatter.write_str("a tuple struct"), + Unsupported::Enum => formatter.write_str("an enum"), + } + } +} + +impl TaggedSerializer +where + S: Serializer, +{ + fn bad_type(self, what: Unsupported) -> S::Error { + ser::Error::custom(format_args!( + "cannot serialize tagged newtype variant {}::{} containing {}", + self.type_ident, self.variant_ident, what + )) + } +} + +impl Serializer for TaggedSerializer +where + S: Serializer, +{ + type Ok = S::Ok; + type Error = S::Error; + + type SerializeSeq = Impossible; + type SerializeTuple = Impossible; + type SerializeTupleStruct = Impossible; + type SerializeMap = S::SerializeMap; + type SerializeStruct = S::SerializeStruct; + + #[cfg(not(any(feature = "std", feature = "alloc")))] + type SerializeTupleVariant = Impossible; + #[cfg(any(feature = "std", feature = "alloc"))] + type SerializeTupleVariant = SerializeTupleVariantAsMapValue; + + #[cfg(not(any(feature = "std", feature = "alloc")))] + type SerializeStructVariant = Impossible; + #[cfg(any(feature = "std", feature = "alloc"))] + type SerializeStructVariant = SerializeStructVariantAsMapValue; + + fn serialize_bool(self, _: bool) -> Result { + Err(self.bad_type(Unsupported::Boolean)) + } + + fn serialize_i8(self, _: i8) -> Result { + Err(self.bad_type(Unsupported::Integer)) + } + + fn serialize_i16(self, _: i16) -> Result { + Err(self.bad_type(Unsupported::Integer)) + } + + fn serialize_i32(self, _: i32) -> Result { + Err(self.bad_type(Unsupported::Integer)) + } + + fn serialize_i64(self, _: i64) -> Result { + Err(self.bad_type(Unsupported::Integer)) + } + + fn serialize_u8(self, _: u8) -> Result { + Err(self.bad_type(Unsupported::Integer)) + } + + fn serialize_u16(self, _: u16) -> Result { + Err(self.bad_type(Unsupported::Integer)) + } + + fn serialize_u32(self, _: u32) -> Result { + Err(self.bad_type(Unsupported::Integer)) + } + + fn serialize_u64(self, _: u64) -> Result { + Err(self.bad_type(Unsupported::Integer)) + } + + fn serialize_f32(self, _: f32) -> Result { + Err(self.bad_type(Unsupported::Float)) + } + + fn serialize_f64(self, _: f64) -> Result { + Err(self.bad_type(Unsupported::Float)) + } + + fn serialize_char(self, _: char) -> Result { + Err(self.bad_type(Unsupported::Char)) + } + + fn serialize_str(self, _: &str) -> Result { + Err(self.bad_type(Unsupported::String)) + } + + fn serialize_bytes(self, _: &[u8]) -> Result { + Err(self.bad_type(Unsupported::ByteArray)) + } + + fn serialize_none(self) -> Result { + Err(self.bad_type(Unsupported::Optional)) + } + + fn serialize_some(self, _: &T) -> Result + where + T: ?Sized + Serialize, + { + Err(self.bad_type(Unsupported::Optional)) + } + + fn serialize_unit(self) -> Result { + let mut map = tri!(self.delegate.serialize_map(Some(1))); + tri!(map.serialize_entry(self.tag, self.variant_name)); + map.end() + } + + fn serialize_unit_struct(self, _: &'static str) -> Result { + let mut map = tri!(self.delegate.serialize_map(Some(1))); + tri!(map.serialize_entry(self.tag, self.variant_name)); + map.end() + } + + fn serialize_unit_variant( + self, + _: &'static str, + _: u32, + inner_variant: &'static str, + ) -> Result { + let mut map = tri!(self.delegate.serialize_map(Some(2))); + tri!(map.serialize_entry(self.tag, self.variant_name)); + tri!(map.serialize_entry(inner_variant, &())); + map.end() + } + + fn serialize_newtype_struct( + self, + _: &'static str, + value: &T, + ) -> Result + where + T: ?Sized + Serialize, + { + value.serialize(self) + } + + fn serialize_newtype_variant( + self, + _: &'static str, + _: u32, + inner_variant: &'static str, + inner_value: &T, + ) -> Result + where + T: ?Sized + Serialize, + { + let mut map = tri!(self.delegate.serialize_map(Some(2))); + tri!(map.serialize_entry(self.tag, self.variant_name)); + tri!(map.serialize_entry(inner_variant, inner_value)); + map.end() + } + + fn serialize_seq(self, _: Option) -> Result { + Err(self.bad_type(Unsupported::Sequence)) + } + + fn serialize_tuple(self, _: usize) -> Result { + Err(self.bad_type(Unsupported::Tuple)) + } + + fn serialize_tuple_struct( + self, + _: &'static str, + _: usize, + ) -> Result { + Err(self.bad_type(Unsupported::TupleStruct)) + } + + #[cfg(not(any(feature = "std", feature = "alloc")))] + fn serialize_tuple_variant( + self, + _: &'static str, + _: u32, + _: &'static str, + _: usize, + ) -> Result { + // Lack of push-based serialization means we need to buffer the content + // of the tuple variant, so it requires std. + Err(self.bad_type(Unsupported::Enum)) + } + + #[cfg(any(feature = "std", feature = "alloc"))] + fn serialize_tuple_variant( + self, + _: &'static str, + _: u32, + inner_variant: &'static str, + len: usize, + ) -> Result { + let mut map = tri!(self.delegate.serialize_map(Some(2))); + tri!(map.serialize_entry(self.tag, self.variant_name)); + tri!(map.serialize_key(inner_variant)); + Ok(SerializeTupleVariantAsMapValue::new( + map, + inner_variant, + len, + )) + } + + fn serialize_map(self, len: Option) -> Result { + let mut map = tri!(self.delegate.serialize_map(len.map(|len| len + 1))); + tri!(map.serialize_entry(self.tag, self.variant_name)); + Ok(map) + } + + fn serialize_struct( + self, + name: &'static str, + len: usize, + ) -> Result { + let mut state = tri!(self.delegate.serialize_struct(name, len + 1)); + tri!(state.serialize_field(self.tag, self.variant_name)); + Ok(state) + } + + #[cfg(not(any(feature = "std", feature = "alloc")))] + fn serialize_struct_variant( + self, + _: &'static str, + _: u32, + _: &'static str, + _: usize, + ) -> Result { + // Lack of push-based serialization means we need to buffer the content + // of the struct variant, so it requires std. + Err(self.bad_type(Unsupported::Enum)) + } + + #[cfg(any(feature = "std", feature = "alloc"))] + fn serialize_struct_variant( + self, + _: &'static str, + _: u32, + inner_variant: &'static str, + len: usize, + ) -> Result { + let mut map = tri!(self.delegate.serialize_map(Some(2))); + tri!(map.serialize_entry(self.tag, self.variant_name)); + tri!(map.serialize_key(inner_variant)); + Ok(SerializeStructVariantAsMapValue::new( + map, + inner_variant, + len, + )) + } + + #[cfg(not(any(feature = "std", feature = "alloc")))] + fn collect_str(self, _: &T) -> Result + where + T: ?Sized + Display, + { + Err(self.bad_type(Unsupported::String)) + } +} + +#[cfg(any(feature = "std", feature = "alloc"))] +mod content { + use crate::lib::*; + + use crate::ser::{self, Serialize, Serializer}; + + pub struct SerializeTupleVariantAsMapValue { + map: M, + name: &'static str, + fields: Vec, + } + + impl SerializeTupleVariantAsMapValue { + pub fn new(map: M, name: &'static str, len: usize) -> Self { + SerializeTupleVariantAsMapValue { + map, + name, + fields: Vec::with_capacity(len), + } + } + } + + impl ser::SerializeTupleVariant for SerializeTupleVariantAsMapValue + where + M: ser::SerializeMap, + { + type Ok = M::Ok; + type Error = M::Error; + + fn serialize_field(&mut self, value: &T) -> Result<(), M::Error> + where + T: ?Sized + Serialize, + { + let value = tri!(value.serialize(ContentSerializer::::new())); + self.fields.push(value); + Ok(()) + } + + fn end(mut self) -> Result { + tri!(self + .map + .serialize_value(&Content::TupleStruct(self.name, self.fields))); + self.map.end() + } + } + + pub struct SerializeStructVariantAsMapValue { + map: M, + name: &'static str, + fields: Vec<(&'static str, Content)>, + } + + impl SerializeStructVariantAsMapValue { + pub fn new(map: M, name: &'static str, len: usize) -> Self { + SerializeStructVariantAsMapValue { + map, + name, + fields: Vec::with_capacity(len), + } + } + } + + impl ser::SerializeStructVariant for SerializeStructVariantAsMapValue + where + M: ser::SerializeMap, + { + type Ok = M::Ok; + type Error = M::Error; + + fn serialize_field(&mut self, key: &'static str, value: &T) -> Result<(), M::Error> + where + T: ?Sized + Serialize, + { + let value = tri!(value.serialize(ContentSerializer::::new())); + self.fields.push((key, value)); + Ok(()) + } + + fn end(mut self) -> Result { + tri!(self + .map + .serialize_value(&Content::Struct(self.name, self.fields))); + self.map.end() + } + } + + pub enum Content { + Bool(bool), + + U8(u8), + U16(u16), + U32(u32), + U64(u64), + + I8(i8), + I16(i16), + I32(i32), + I64(i64), + + F32(f32), + F64(f64), + + Char(char), + String(String), + Bytes(Vec), + + None, + Some(Box), + + Unit, + UnitStruct(&'static str), + UnitVariant(&'static str, u32, &'static str), + NewtypeStruct(&'static str, Box), + NewtypeVariant(&'static str, u32, &'static str, Box), + + Seq(Vec), + Tuple(Vec), + TupleStruct(&'static str, Vec), + TupleVariant(&'static str, u32, &'static str, Vec), + Map(Vec<(Content, Content)>), + Struct(&'static str, Vec<(&'static str, Content)>), + StructVariant( + &'static str, + u32, + &'static str, + Vec<(&'static str, Content)>, + ), + } + + impl Serialize for Content { + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + match *self { + Content::Bool(b) => serializer.serialize_bool(b), + Content::U8(u) => serializer.serialize_u8(u), + Content::U16(u) => serializer.serialize_u16(u), + Content::U32(u) => serializer.serialize_u32(u), + Content::U64(u) => serializer.serialize_u64(u), + Content::I8(i) => serializer.serialize_i8(i), + Content::I16(i) => serializer.serialize_i16(i), + Content::I32(i) => serializer.serialize_i32(i), + Content::I64(i) => serializer.serialize_i64(i), + Content::F32(f) => serializer.serialize_f32(f), + Content::F64(f) => serializer.serialize_f64(f), + Content::Char(c) => serializer.serialize_char(c), + Content::String(ref s) => serializer.serialize_str(s), + Content::Bytes(ref b) => serializer.serialize_bytes(b), + Content::None => serializer.serialize_none(), + Content::Some(ref c) => serializer.serialize_some(&**c), + Content::Unit => serializer.serialize_unit(), + Content::UnitStruct(n) => serializer.serialize_unit_struct(n), + Content::UnitVariant(n, i, v) => serializer.serialize_unit_variant(n, i, v), + Content::NewtypeStruct(n, ref c) => serializer.serialize_newtype_struct(n, &**c), + Content::NewtypeVariant(n, i, v, ref c) => { + serializer.serialize_newtype_variant(n, i, v, &**c) + } + Content::Seq(ref elements) => elements.serialize(serializer), + Content::Tuple(ref elements) => { + use crate::ser::SerializeTuple; + let mut tuple = tri!(serializer.serialize_tuple(elements.len())); + for e in elements { + tri!(tuple.serialize_element(e)); + } + tuple.end() + } + Content::TupleStruct(n, ref fields) => { + use crate::ser::SerializeTupleStruct; + let mut ts = tri!(serializer.serialize_tuple_struct(n, fields.len())); + for f in fields { + tri!(ts.serialize_field(f)); + } + ts.end() + } + Content::TupleVariant(n, i, v, ref fields) => { + use crate::ser::SerializeTupleVariant; + let mut tv = tri!(serializer.serialize_tuple_variant(n, i, v, fields.len())); + for f in fields { + tri!(tv.serialize_field(f)); + } + tv.end() + } + Content::Map(ref entries) => { + use crate::ser::SerializeMap; + let mut map = tri!(serializer.serialize_map(Some(entries.len()))); + for (k, v) in entries { + tri!(map.serialize_entry(k, v)); + } + map.end() + } + Content::Struct(n, ref fields) => { + use crate::ser::SerializeStruct; + let mut s = tri!(serializer.serialize_struct(n, fields.len())); + for &(k, ref v) in fields { + tri!(s.serialize_field(k, v)); + } + s.end() + } + Content::StructVariant(n, i, v, ref fields) => { + use crate::ser::SerializeStructVariant; + let mut sv = tri!(serializer.serialize_struct_variant(n, i, v, fields.len())); + for &(k, ref v) in fields { + tri!(sv.serialize_field(k, v)); + } + sv.end() + } + } + } + } + + pub struct ContentSerializer { + error: PhantomData, + } + + impl ContentSerializer { + pub fn new() -> Self { + ContentSerializer { error: PhantomData } + } + } + + impl Serializer for ContentSerializer + where + E: ser::Error, + { + type Ok = Content; + type Error = E; + + type SerializeSeq = SerializeSeq; + type SerializeTuple = SerializeTuple; + type SerializeTupleStruct = SerializeTupleStruct; + type SerializeTupleVariant = SerializeTupleVariant; + type SerializeMap = SerializeMap; + type SerializeStruct = SerializeStruct; + type SerializeStructVariant = SerializeStructVariant; + + fn serialize_bool(self, v: bool) -> Result { + Ok(Content::Bool(v)) + } + + fn serialize_i8(self, v: i8) -> Result { + Ok(Content::I8(v)) + } + + fn serialize_i16(self, v: i16) -> Result { + Ok(Content::I16(v)) + } + + fn serialize_i32(self, v: i32) -> Result { + Ok(Content::I32(v)) + } + + fn serialize_i64(self, v: i64) -> Result { + Ok(Content::I64(v)) + } + + fn serialize_u8(self, v: u8) -> Result { + Ok(Content::U8(v)) + } + + fn serialize_u16(self, v: u16) -> Result { + Ok(Content::U16(v)) + } + + fn serialize_u32(self, v: u32) -> Result { + Ok(Content::U32(v)) + } + + fn serialize_u64(self, v: u64) -> Result { + Ok(Content::U64(v)) + } + + fn serialize_f32(self, v: f32) -> Result { + Ok(Content::F32(v)) + } + + fn serialize_f64(self, v: f64) -> Result { + Ok(Content::F64(v)) + } + + fn serialize_char(self, v: char) -> Result { + Ok(Content::Char(v)) + } + + fn serialize_str(self, value: &str) -> Result { + Ok(Content::String(value.to_owned())) + } + + fn serialize_bytes(self, value: &[u8]) -> Result { + Ok(Content::Bytes(value.to_owned())) + } + + fn serialize_none(self) -> Result { + Ok(Content::None) + } + + fn serialize_some(self, value: &T) -> Result + where + T: ?Sized + Serialize, + { + Ok(Content::Some(Box::new(tri!(value.serialize(self))))) + } + + fn serialize_unit(self) -> Result { + Ok(Content::Unit) + } + + fn serialize_unit_struct(self, name: &'static str) -> Result { + Ok(Content::UnitStruct(name)) + } + + fn serialize_unit_variant( + self, + name: &'static str, + variant_index: u32, + variant: &'static str, + ) -> Result { + Ok(Content::UnitVariant(name, variant_index, variant)) + } + + fn serialize_newtype_struct(self, name: &'static str, value: &T) -> Result + where + T: ?Sized + Serialize, + { + Ok(Content::NewtypeStruct( + name, + Box::new(tri!(value.serialize(self))), + )) + } + + fn serialize_newtype_variant( + self, + name: &'static str, + variant_index: u32, + variant: &'static str, + value: &T, + ) -> Result + where + T: ?Sized + Serialize, + { + Ok(Content::NewtypeVariant( + name, + variant_index, + variant, + Box::new(tri!(value.serialize(self))), + )) + } + + fn serialize_seq(self, len: Option) -> Result { + Ok(SerializeSeq { + elements: Vec::with_capacity(len.unwrap_or(0)), + error: PhantomData, + }) + } + + fn serialize_tuple(self, len: usize) -> Result { + Ok(SerializeTuple { + elements: Vec::with_capacity(len), + error: PhantomData, + }) + } + + fn serialize_tuple_struct( + self, + name: &'static str, + len: usize, + ) -> Result { + Ok(SerializeTupleStruct { + name, + fields: Vec::with_capacity(len), + error: PhantomData, + }) + } + + fn serialize_tuple_variant( + self, + name: &'static str, + variant_index: u32, + variant: &'static str, + len: usize, + ) -> Result { + Ok(SerializeTupleVariant { + name, + variant_index, + variant, + fields: Vec::with_capacity(len), + error: PhantomData, + }) + } + + fn serialize_map(self, len: Option) -> Result { + Ok(SerializeMap { + entries: Vec::with_capacity(len.unwrap_or(0)), + key: None, + error: PhantomData, + }) + } + + fn serialize_struct( + self, + name: &'static str, + len: usize, + ) -> Result { + Ok(SerializeStruct { + name, + fields: Vec::with_capacity(len), + error: PhantomData, + }) + } + + fn serialize_struct_variant( + self, + name: &'static str, + variant_index: u32, + variant: &'static str, + len: usize, + ) -> Result { + Ok(SerializeStructVariant { + name, + variant_index, + variant, + fields: Vec::with_capacity(len), + error: PhantomData, + }) + } + } + + pub struct SerializeSeq { + elements: Vec, + error: PhantomData, + } + + impl ser::SerializeSeq for SerializeSeq + where + E: ser::Error, + { + type Ok = Content; + type Error = E; + + fn serialize_element(&mut self, value: &T) -> Result<(), E> + where + T: ?Sized + Serialize, + { + let value = tri!(value.serialize(ContentSerializer::::new())); + self.elements.push(value); + Ok(()) + } + + fn end(self) -> Result { + Ok(Content::Seq(self.elements)) + } + } + + pub struct SerializeTuple { + elements: Vec, + error: PhantomData, + } + + impl ser::SerializeTuple for SerializeTuple + where + E: ser::Error, + { + type Ok = Content; + type Error = E; + + fn serialize_element(&mut self, value: &T) -> Result<(), E> + where + T: ?Sized + Serialize, + { + let value = tri!(value.serialize(ContentSerializer::::new())); + self.elements.push(value); + Ok(()) + } + + fn end(self) -> Result { + Ok(Content::Tuple(self.elements)) + } + } + + pub struct SerializeTupleStruct { + name: &'static str, + fields: Vec, + error: PhantomData, + } + + impl ser::SerializeTupleStruct for SerializeTupleStruct + where + E: ser::Error, + { + type Ok = Content; + type Error = E; + + fn serialize_field(&mut self, value: &T) -> Result<(), E> + where + T: ?Sized + Serialize, + { + let value = tri!(value.serialize(ContentSerializer::::new())); + self.fields.push(value); + Ok(()) + } + + fn end(self) -> Result { + Ok(Content::TupleStruct(self.name, self.fields)) + } + } + + pub struct SerializeTupleVariant { + name: &'static str, + variant_index: u32, + variant: &'static str, + fields: Vec, + error: PhantomData, + } + + impl ser::SerializeTupleVariant for SerializeTupleVariant + where + E: ser::Error, + { + type Ok = Content; + type Error = E; + + fn serialize_field(&mut self, value: &T) -> Result<(), E> + where + T: ?Sized + Serialize, + { + let value = tri!(value.serialize(ContentSerializer::::new())); + self.fields.push(value); + Ok(()) + } + + fn end(self) -> Result { + Ok(Content::TupleVariant( + self.name, + self.variant_index, + self.variant, + self.fields, + )) + } + } + + pub struct SerializeMap { + entries: Vec<(Content, Content)>, + key: Option, + error: PhantomData, + } + + impl ser::SerializeMap for SerializeMap + where + E: ser::Error, + { + type Ok = Content; + type Error = E; + + fn serialize_key(&mut self, key: &T) -> Result<(), E> + where + T: ?Sized + Serialize, + { + let key = tri!(key.serialize(ContentSerializer::::new())); + self.key = Some(key); + Ok(()) + } + + fn serialize_value(&mut self, value: &T) -> Result<(), E> + where + T: ?Sized + Serialize, + { + let key = self + .key + .take() + .expect("serialize_value called before serialize_key"); + let value = tri!(value.serialize(ContentSerializer::::new())); + self.entries.push((key, value)); + Ok(()) + } + + fn end(self) -> Result { + Ok(Content::Map(self.entries)) + } + + fn serialize_entry(&mut self, key: &K, value: &V) -> Result<(), E> + where + K: ?Sized + Serialize, + V: ?Sized + Serialize, + { + let key = tri!(key.serialize(ContentSerializer::::new())); + let value = tri!(value.serialize(ContentSerializer::::new())); + self.entries.push((key, value)); + Ok(()) + } + } + + pub struct SerializeStruct { + name: &'static str, + fields: Vec<(&'static str, Content)>, + error: PhantomData, + } + + impl ser::SerializeStruct for SerializeStruct + where + E: ser::Error, + { + type Ok = Content; + type Error = E; + + fn serialize_field(&mut self, key: &'static str, value: &T) -> Result<(), E> + where + T: ?Sized + Serialize, + { + let value = tri!(value.serialize(ContentSerializer::::new())); + self.fields.push((key, value)); + Ok(()) + } + + fn end(self) -> Result { + Ok(Content::Struct(self.name, self.fields)) + } + } + + pub struct SerializeStructVariant { + name: &'static str, + variant_index: u32, + variant: &'static str, + fields: Vec<(&'static str, Content)>, + error: PhantomData, + } + + impl ser::SerializeStructVariant for SerializeStructVariant + where + E: ser::Error, + { + type Ok = Content; + type Error = E; + + fn serialize_field(&mut self, key: &'static str, value: &T) -> Result<(), E> + where + T: ?Sized + Serialize, + { + let value = tri!(value.serialize(ContentSerializer::::new())); + self.fields.push((key, value)); + Ok(()) + } + + fn end(self) -> Result { + Ok(Content::StructVariant( + self.name, + self.variant_index, + self.variant, + self.fields, + )) + } + } +} + +#[cfg(any(feature = "std", feature = "alloc"))] +pub struct FlatMapSerializer<'a, M: 'a>(pub &'a mut M); + +#[cfg(any(feature = "std", feature = "alloc"))] +impl<'a, M> FlatMapSerializer<'a, M> +where + M: SerializeMap + 'a, +{ + fn bad_type(what: Unsupported) -> M::Error { + ser::Error::custom(format_args!( + "can only flatten structs and maps (got {})", + what + )) + } +} + +#[cfg(any(feature = "std", feature = "alloc"))] +impl<'a, M> Serializer for FlatMapSerializer<'a, M> +where + M: SerializeMap + 'a, +{ + type Ok = (); + type Error = M::Error; + + type SerializeSeq = Impossible; + type SerializeTuple = Impossible; + type SerializeTupleStruct = Impossible; + type SerializeMap = FlatMapSerializeMap<'a, M>; + type SerializeStruct = FlatMapSerializeStruct<'a, M>; + type SerializeTupleVariant = FlatMapSerializeTupleVariantAsMapValue<'a, M>; + type SerializeStructVariant = FlatMapSerializeStructVariantAsMapValue<'a, M>; + + fn serialize_bool(self, _: bool) -> Result { + Err(Self::bad_type(Unsupported::Boolean)) + } + + fn serialize_i8(self, _: i8) -> Result { + Err(Self::bad_type(Unsupported::Integer)) + } + + fn serialize_i16(self, _: i16) -> Result { + Err(Self::bad_type(Unsupported::Integer)) + } + + fn serialize_i32(self, _: i32) -> Result { + Err(Self::bad_type(Unsupported::Integer)) + } + + fn serialize_i64(self, _: i64) -> Result { + Err(Self::bad_type(Unsupported::Integer)) + } + + fn serialize_u8(self, _: u8) -> Result { + Err(Self::bad_type(Unsupported::Integer)) + } + + fn serialize_u16(self, _: u16) -> Result { + Err(Self::bad_type(Unsupported::Integer)) + } + + fn serialize_u32(self, _: u32) -> Result { + Err(Self::bad_type(Unsupported::Integer)) + } + + fn serialize_u64(self, _: u64) -> Result { + Err(Self::bad_type(Unsupported::Integer)) + } + + fn serialize_f32(self, _: f32) -> Result { + Err(Self::bad_type(Unsupported::Float)) + } + + fn serialize_f64(self, _: f64) -> Result { + Err(Self::bad_type(Unsupported::Float)) + } + + fn serialize_char(self, _: char) -> Result { + Err(Self::bad_type(Unsupported::Char)) + } + + fn serialize_str(self, _: &str) -> Result { + Err(Self::bad_type(Unsupported::String)) + } + + fn serialize_bytes(self, _: &[u8]) -> Result { + Err(Self::bad_type(Unsupported::ByteArray)) + } + + fn serialize_none(self) -> Result { + Ok(()) + } + + fn serialize_some(self, value: &T) -> Result + where + T: ?Sized + Serialize, + { + value.serialize(self) + } + + fn serialize_unit(self) -> Result { + Ok(()) + } + + fn serialize_unit_struct(self, _: &'static str) -> Result { + Ok(()) + } + + fn serialize_unit_variant( + self, + _: &'static str, + _: u32, + _: &'static str, + ) -> Result { + Err(Self::bad_type(Unsupported::Enum)) + } + + fn serialize_newtype_struct( + self, + _: &'static str, + value: &T, + ) -> Result + where + T: ?Sized + Serialize, + { + value.serialize(self) + } + + fn serialize_newtype_variant( + self, + _: &'static str, + _: u32, + variant: &'static str, + value: &T, + ) -> Result + where + T: ?Sized + Serialize, + { + self.0.serialize_entry(variant, value) + } + + fn serialize_seq(self, _: Option) -> Result { + Err(Self::bad_type(Unsupported::Sequence)) + } + + fn serialize_tuple(self, _: usize) -> Result { + Err(Self::bad_type(Unsupported::Tuple)) + } + + fn serialize_tuple_struct( + self, + _: &'static str, + _: usize, + ) -> Result { + Err(Self::bad_type(Unsupported::TupleStruct)) + } + + fn serialize_tuple_variant( + self, + _: &'static str, + _: u32, + variant: &'static str, + _: usize, + ) -> Result { + tri!(self.0.serialize_key(variant)); + Ok(FlatMapSerializeTupleVariantAsMapValue::new(self.0)) + } + + fn serialize_map(self, _: Option) -> Result { + Ok(FlatMapSerializeMap(self.0)) + } + + fn serialize_struct( + self, + _: &'static str, + _: usize, + ) -> Result { + Ok(FlatMapSerializeStruct(self.0)) + } + + fn serialize_struct_variant( + self, + _: &'static str, + _: u32, + inner_variant: &'static str, + _: usize, + ) -> Result { + tri!(self.0.serialize_key(inner_variant)); + Ok(FlatMapSerializeStructVariantAsMapValue::new( + self.0, + inner_variant, + )) + } +} + +#[cfg(any(feature = "std", feature = "alloc"))] +pub struct FlatMapSerializeMap<'a, M: 'a>(&'a mut M); + +#[cfg(any(feature = "std", feature = "alloc"))] +impl<'a, M> ser::SerializeMap for FlatMapSerializeMap<'a, M> +where + M: SerializeMap + 'a, +{ + type Ok = (); + type Error = M::Error; + + fn serialize_key(&mut self, key: &T) -> Result<(), Self::Error> + where + T: ?Sized + Serialize, + { + self.0.serialize_key(key) + } + + fn serialize_value(&mut self, value: &T) -> Result<(), Self::Error> + where + T: ?Sized + Serialize, + { + self.0.serialize_value(value) + } + + fn serialize_entry(&mut self, key: &K, value: &V) -> Result<(), Self::Error> + where + K: ?Sized + Serialize, + V: ?Sized + Serialize, + { + self.0.serialize_entry(key, value) + } + + fn end(self) -> Result<(), Self::Error> { + Ok(()) + } +} + +#[cfg(any(feature = "std", feature = "alloc"))] +pub struct FlatMapSerializeStruct<'a, M: 'a>(&'a mut M); + +#[cfg(any(feature = "std", feature = "alloc"))] +impl<'a, M> ser::SerializeStruct for FlatMapSerializeStruct<'a, M> +where + M: SerializeMap + 'a, +{ + type Ok = (); + type Error = M::Error; + + fn serialize_field(&mut self, key: &'static str, value: &T) -> Result<(), Self::Error> + where + T: ?Sized + Serialize, + { + self.0.serialize_entry(key, value) + } + + fn end(self) -> Result<(), Self::Error> { + Ok(()) + } +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +#[cfg(any(feature = "std", feature = "alloc"))] +pub struct FlatMapSerializeTupleVariantAsMapValue<'a, M: 'a> { + map: &'a mut M, + fields: Vec, +} + +#[cfg(any(feature = "std", feature = "alloc"))] +impl<'a, M> FlatMapSerializeTupleVariantAsMapValue<'a, M> +where + M: SerializeMap + 'a, +{ + fn new(map: &'a mut M) -> Self { + FlatMapSerializeTupleVariantAsMapValue { + map, + fields: Vec::new(), + } + } +} + +#[cfg(any(feature = "std", feature = "alloc"))] +impl<'a, M> ser::SerializeTupleVariant for FlatMapSerializeTupleVariantAsMapValue<'a, M> +where + M: SerializeMap + 'a, +{ + type Ok = (); + type Error = M::Error; + + fn serialize_field(&mut self, value: &T) -> Result<(), Self::Error> + where + T: ?Sized + Serialize, + { + let value = tri!(value.serialize(ContentSerializer::::new())); + self.fields.push(value); + Ok(()) + } + + fn end(self) -> Result<(), Self::Error> { + tri!(self.map.serialize_value(&Content::Seq(self.fields))); + Ok(()) + } +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +#[cfg(any(feature = "std", feature = "alloc"))] +pub struct FlatMapSerializeStructVariantAsMapValue<'a, M: 'a> { + map: &'a mut M, + name: &'static str, + fields: Vec<(&'static str, Content)>, +} + +#[cfg(any(feature = "std", feature = "alloc"))] +impl<'a, M> FlatMapSerializeStructVariantAsMapValue<'a, M> +where + M: SerializeMap + 'a, +{ + fn new(map: &'a mut M, name: &'static str) -> FlatMapSerializeStructVariantAsMapValue<'a, M> { + FlatMapSerializeStructVariantAsMapValue { + map, + name, + fields: Vec::new(), + } + } +} + +#[cfg(any(feature = "std", feature = "alloc"))] +impl<'a, M> ser::SerializeStructVariant for FlatMapSerializeStructVariantAsMapValue<'a, M> +where + M: SerializeMap + 'a, +{ + type Ok = (); + type Error = M::Error; + + fn serialize_field(&mut self, key: &'static str, value: &T) -> Result<(), Self::Error> + where + T: ?Sized + Serialize, + { + let value = tri!(value.serialize(ContentSerializer::::new())); + self.fields.push((key, value)); + Ok(()) + } + + fn end(self) -> Result<(), Self::Error> { + tri!(self + .map + .serialize_value(&Content::Struct(self.name, self.fields))); + Ok(()) + } +} + +pub struct AdjacentlyTaggedEnumVariant { + pub enum_name: &'static str, + pub variant_index: u32, + pub variant_name: &'static str, +} + +impl Serialize for AdjacentlyTaggedEnumVariant { + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + serializer.serialize_unit_variant(self.enum_name, self.variant_index, self.variant_name) + } +} + +// Error when Serialize for a non_exhaustive remote enum encounters a variant +// that is not recognized. +pub struct CannotSerializeVariant(pub T); + +impl Display for CannotSerializeVariant +where + T: Debug, +{ + fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + write!(formatter, "enum variant cannot be serialized: {:?}", self.0) + } +} diff --git a/vendor/serde/src/ser/fmt.rs b/vendor/serde/src/ser/fmt.rs new file mode 100644 index 0000000..04684ad --- /dev/null +++ b/vendor/serde/src/ser/fmt.rs @@ -0,0 +1,170 @@ +use crate::lib::*; +use crate::ser::{Error, Impossible, Serialize, Serializer}; + +impl Error for fmt::Error { + fn custom(_msg: T) -> Self { + fmt::Error + } +} + +macro_rules! fmt_primitives { + ($($f:ident: $t:ty,)*) => { + $( + fn $f(self, v: $t) -> fmt::Result { + Display::fmt(&v, self) + } + )* + }; +} + +/// ```edition2021 +/// use serde::ser::Serialize; +/// use serde_derive::Serialize; +/// use std::fmt::{self, Display}; +/// +/// #[derive(Serialize)] +/// #[serde(rename_all = "kebab-case")] +/// pub enum MessageType { +/// StartRequest, +/// EndRequest, +/// } +/// +/// impl Display for MessageType { +/// fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { +/// self.serialize(f) +/// } +/// } +/// ``` +impl<'a, 'b> Serializer for &'a mut fmt::Formatter<'b> { + type Ok = (); + type Error = fmt::Error; + type SerializeSeq = Impossible<(), fmt::Error>; + type SerializeTuple = Impossible<(), fmt::Error>; + type SerializeTupleStruct = Impossible<(), fmt::Error>; + type SerializeTupleVariant = Impossible<(), fmt::Error>; + type SerializeMap = Impossible<(), fmt::Error>; + type SerializeStruct = Impossible<(), fmt::Error>; + type SerializeStructVariant = Impossible<(), fmt::Error>; + + fmt_primitives! { + serialize_bool: bool, + serialize_i8: i8, + serialize_i16: i16, + serialize_i32: i32, + serialize_i64: i64, + serialize_i128: i128, + serialize_u8: u8, + serialize_u16: u16, + serialize_u32: u32, + serialize_u64: u64, + serialize_u128: u128, + serialize_f32: f32, + serialize_f64: f64, + serialize_char: char, + serialize_str: &str, + serialize_unit_struct: &'static str, + } + + fn serialize_unit_variant( + self, + _name: &'static str, + _variant_index: u32, + variant: &'static str, + ) -> fmt::Result { + Display::fmt(variant, self) + } + + fn serialize_newtype_struct(self, _name: &'static str, value: &T) -> fmt::Result + where + T: ?Sized + Serialize, + { + Serialize::serialize(value, self) + } + + fn serialize_bytes(self, _v: &[u8]) -> fmt::Result { + Err(fmt::Error) + } + + fn serialize_none(self) -> fmt::Result { + Err(fmt::Error) + } + + fn serialize_some(self, _value: &T) -> fmt::Result + where + T: ?Sized + Serialize, + { + Err(fmt::Error) + } + + fn serialize_unit(self) -> fmt::Result { + Err(fmt::Error) + } + + fn serialize_newtype_variant( + self, + _name: &'static str, + _variant_index: u32, + _variant: &'static str, + _value: &T, + ) -> fmt::Result + where + T: ?Sized + Serialize, + { + Err(fmt::Error) + } + + fn serialize_seq(self, _len: Option) -> Result { + Err(fmt::Error) + } + + fn serialize_tuple(self, _len: usize) -> Result { + Err(fmt::Error) + } + + fn serialize_tuple_struct( + self, + _name: &'static str, + _len: usize, + ) -> Result { + Err(fmt::Error) + } + + fn serialize_tuple_variant( + self, + _name: &'static str, + _variant_index: u32, + _variant: &'static str, + _len: usize, + ) -> Result { + Err(fmt::Error) + } + + fn serialize_map(self, _len: Option) -> Result { + Err(fmt::Error) + } + + fn serialize_struct( + self, + _name: &'static str, + _len: usize, + ) -> Result { + Err(fmt::Error) + } + + fn serialize_struct_variant( + self, + _name: &'static str, + _variant_index: u32, + _variant: &'static str, + _len: usize, + ) -> Result { + Err(fmt::Error) + } + + fn collect_str(self, value: &T) -> fmt::Result + where + T: ?Sized + Display, + { + Display::fmt(value, self) + } +} diff --git a/vendor/serde/src/ser/impls.rs b/vendor/serde/src/ser/impls.rs new file mode 100644 index 0000000..fb574ea --- /dev/null +++ b/vendor/serde/src/ser/impls.rs @@ -0,0 +1,1096 @@ +use crate::lib::*; + +use crate::ser::{Error, Serialize, SerializeTuple, Serializer}; + +//////////////////////////////////////////////////////////////////////////////// + +macro_rules! primitive_impl { + ($ty:ident, $method:ident $($cast:tt)*) => { + impl Serialize for $ty { + #[inline] + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + serializer.$method(*self $($cast)*) + } + } + } +} + +primitive_impl!(bool, serialize_bool); +primitive_impl!(isize, serialize_i64 as i64); +primitive_impl!(i8, serialize_i8); +primitive_impl!(i16, serialize_i16); +primitive_impl!(i32, serialize_i32); +primitive_impl!(i64, serialize_i64); +primitive_impl!(i128, serialize_i128); +primitive_impl!(usize, serialize_u64 as u64); +primitive_impl!(u8, serialize_u8); +primitive_impl!(u16, serialize_u16); +primitive_impl!(u32, serialize_u32); +primitive_impl!(u64, serialize_u64); +primitive_impl!(u128, serialize_u128); +primitive_impl!(f32, serialize_f32); +primitive_impl!(f64, serialize_f64); +primitive_impl!(char, serialize_char); + +//////////////////////////////////////////////////////////////////////////////// + +impl Serialize for str { + #[inline] + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + serializer.serialize_str(self) + } +} + +#[cfg(any(feature = "std", feature = "alloc"))] +#[cfg_attr(docsrs, doc(cfg(any(feature = "std", feature = "alloc"))))] +impl Serialize for String { + #[inline] + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + serializer.serialize_str(self) + } +} + +impl<'a> Serialize for fmt::Arguments<'a> { + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + serializer.collect_str(self) + } +} + +//////////////////////////////////////////////////////////////////////////////// + +#[cfg(any(feature = "std", not(no_core_cstr)))] +#[cfg_attr(docsrs, doc(cfg(feature = "std")))] +impl Serialize for CStr { + #[inline] + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + serializer.serialize_bytes(self.to_bytes()) + } +} + +#[cfg(any(feature = "std", all(not(no_core_cstr), feature = "alloc")))] +#[cfg_attr(docsrs, doc(cfg(any(feature = "std", feature = "alloc"))))] +impl Serialize for CString { + #[inline] + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + serializer.serialize_bytes(self.to_bytes()) + } +} + +//////////////////////////////////////////////////////////////////////////////// + +impl Serialize for Option +where + T: Serialize, +{ + #[inline] + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + match *self { + Some(ref value) => serializer.serialize_some(value), + None => serializer.serialize_none(), + } + } +} + +//////////////////////////////////////////////////////////////////////////////// + +impl Serialize for PhantomData +where + T: ?Sized, +{ + #[inline] + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + serializer.serialize_unit_struct("PhantomData") + } +} + +//////////////////////////////////////////////////////////////////////////////// + +// Does not require T: Serialize. +impl Serialize for [T; 0] { + #[inline] + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + tri!(serializer.serialize_tuple(0)).end() + } +} + +macro_rules! array_impls { + ($($len:tt)+) => { + $( + impl Serialize for [T; $len] + where + T: Serialize, + { + #[inline] + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + let mut seq = tri!(serializer.serialize_tuple($len)); + for e in self { + tri!(seq.serialize_element(e)); + } + seq.end() + } + } + )+ + } +} + +array_impls! { + 01 02 03 04 05 06 07 08 09 10 + 11 12 13 14 15 16 17 18 19 20 + 21 22 23 24 25 26 27 28 29 30 + 31 32 +} + +//////////////////////////////////////////////////////////////////////////////// + +impl Serialize for [T] +where + T: Serialize, +{ + #[inline] + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + serializer.collect_seq(self) + } +} + +#[cfg(not(no_relaxed_trait_bounds))] +macro_rules! seq_impl { + ( + $(#[$attr:meta])* + $ty:ident + ) => { + $(#[$attr])* + impl Serialize for $ty + where + T: Serialize, + { + #[inline] + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + serializer.collect_seq(self) + } + } + } +} + +#[cfg(no_relaxed_trait_bounds)] +macro_rules! seq_impl { + ( + $(#[$attr:meta])* + $ty:ident + ) => { + $(#[$attr])* + impl Serialize for $ty + where + T: Serialize $(+ $tbound1 $(+ $tbound2)*)*, + $($typaram: $bound,)* + { + #[inline] + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + serializer.collect_seq(self) + } + } + } +} + +seq_impl! { + #[cfg(any(feature = "std", feature = "alloc"))] + #[cfg_attr(docsrs, doc(cfg(any(feature = "std", feature = "alloc"))))] + BinaryHeap +} + +seq_impl! { + #[cfg(any(feature = "std", feature = "alloc"))] + #[cfg_attr(docsrs, doc(cfg(any(feature = "std", feature = "alloc"))))] + BTreeSet +} + +seq_impl! { + #[cfg(feature = "std")] + #[cfg_attr(docsrs, doc(cfg(feature = "std")))] + HashSet +} + +seq_impl! { + #[cfg(any(feature = "std", feature = "alloc"))] + #[cfg_attr(docsrs, doc(cfg(any(feature = "std", feature = "alloc"))))] + LinkedList +} + +seq_impl! { + #[cfg(any(feature = "std", feature = "alloc"))] + #[cfg_attr(docsrs, doc(cfg(any(feature = "std", feature = "alloc"))))] + Vec +} + +seq_impl! { + #[cfg(any(feature = "std", feature = "alloc"))] + #[cfg_attr(docsrs, doc(cfg(any(feature = "std", feature = "alloc"))))] + VecDeque +} + +//////////////////////////////////////////////////////////////////////////////// + +impl Serialize for Range +where + Idx: Serialize, +{ + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + use super::SerializeStruct; + let mut state = tri!(serializer.serialize_struct("Range", 2)); + tri!(state.serialize_field("start", &self.start)); + tri!(state.serialize_field("end", &self.end)); + state.end() + } +} + +//////////////////////////////////////////////////////////////////////////////// + +impl Serialize for RangeFrom +where + Idx: Serialize, +{ + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + use super::SerializeStruct; + let mut state = tri!(serializer.serialize_struct("RangeFrom", 1)); + tri!(state.serialize_field("start", &self.start)); + state.end() + } +} + +//////////////////////////////////////////////////////////////////////////////// + +impl Serialize for RangeInclusive +where + Idx: Serialize, +{ + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + use super::SerializeStruct; + let mut state = tri!(serializer.serialize_struct("RangeInclusive", 2)); + tri!(state.serialize_field("start", &self.start())); + tri!(state.serialize_field("end", &self.end())); + state.end() + } +} + +//////////////////////////////////////////////////////////////////////////////// + +impl Serialize for RangeTo +where + Idx: Serialize, +{ + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + use super::SerializeStruct; + let mut state = tri!(serializer.serialize_struct("RangeTo", 1)); + tri!(state.serialize_field("end", &self.end)); + state.end() + } +} + +//////////////////////////////////////////////////////////////////////////////// + +impl Serialize for Bound +where + T: Serialize, +{ + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + match *self { + Bound::Unbounded => serializer.serialize_unit_variant("Bound", 0, "Unbounded"), + Bound::Included(ref value) => { + serializer.serialize_newtype_variant("Bound", 1, "Included", value) + } + Bound::Excluded(ref value) => { + serializer.serialize_newtype_variant("Bound", 2, "Excluded", value) + } + } + } +} + +//////////////////////////////////////////////////////////////////////////////// + +impl Serialize for () { + #[inline] + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + serializer.serialize_unit() + } +} + +#[cfg(feature = "unstable")] +#[cfg_attr(docsrs, doc(cfg(feature = "unstable")))] +impl Serialize for ! { + fn serialize(&self, _serializer: S) -> Result + where + S: Serializer, + { + *self + } +} + +//////////////////////////////////////////////////////////////////////////////// + +macro_rules! tuple_impls { + ($($len:expr => ($($n:tt $name:ident)+))+) => { + $( + #[cfg_attr(docsrs, doc(hidden))] + impl<$($name),+> Serialize for ($($name,)+) + where + $($name: Serialize,)+ + { + tuple_impl_body!($len => ($($n)+)); + } + )+ + }; +} + +macro_rules! tuple_impl_body { + ($len:expr => ($($n:tt)+)) => { + #[inline] + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + let mut tuple = tri!(serializer.serialize_tuple($len)); + $( + tri!(tuple.serialize_element(&self.$n)); + )+ + tuple.end() + } + }; +} + +#[cfg_attr(docsrs, doc(fake_variadic))] +#[cfg_attr( + docsrs, + doc = "This trait is implemented for tuples up to 16 items long." +)] +impl Serialize for (T,) +where + T: Serialize, +{ + tuple_impl_body!(1 => (0)); +} + +tuple_impls! { + 2 => (0 T0 1 T1) + 3 => (0 T0 1 T1 2 T2) + 4 => (0 T0 1 T1 2 T2 3 T3) + 5 => (0 T0 1 T1 2 T2 3 T3 4 T4) + 6 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5) + 7 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6) + 8 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7) + 9 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8) + 10 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9) + 11 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10) + 12 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10 11 T11) + 13 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10 11 T11 12 T12) + 14 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10 11 T11 12 T12 13 T13) + 15 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10 11 T11 12 T12 13 T13 14 T14) + 16 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10 11 T11 12 T12 13 T13 14 T14 15 T15) +} + +//////////////////////////////////////////////////////////////////////////////// + +#[cfg(not(no_relaxed_trait_bounds))] +macro_rules! map_impl { + ( + $(#[$attr:meta])* + $ty:ident + ) => { + $(#[$attr])* + impl Serialize for $ty + where + K: Serialize, + V: Serialize, + { + #[inline] + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + serializer.collect_map(self) + } + } + } +} + +#[cfg(no_relaxed_trait_bounds)] +macro_rules! map_impl { + ( + $(#[$attr:meta])* + $ty:ident + ) => { + $(#[$attr])* + impl Serialize for $ty + where + K: Serialize $(+ $kbound1 $(+ $kbound2)*)*, + V: Serialize, + $($typaram: $bound,)* + { + #[inline] + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + serializer.collect_map(self) + } + } + } +} + +map_impl! { + #[cfg(any(feature = "std", feature = "alloc"))] + #[cfg_attr(docsrs, doc(cfg(any(feature = "std", feature = "alloc"))))] + BTreeMap +} + +map_impl! { + #[cfg(feature = "std")] + #[cfg_attr(docsrs, doc(cfg(feature = "std")))] + HashMap +} + +//////////////////////////////////////////////////////////////////////////////// + +macro_rules! deref_impl { + ( + $(#[$attr:meta])* + <$($desc:tt)+ + ) => { + $(#[$attr])* + impl <$($desc)+ { + #[inline] + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + (**self).serialize(serializer) + } + } + }; +} + +deref_impl! { + <'a, T> Serialize for &'a T where T: ?Sized + Serialize +} + +deref_impl! { + <'a, T> Serialize for &'a mut T where T: ?Sized + Serialize +} + +deref_impl! { + #[cfg(any(feature = "std", feature = "alloc"))] + #[cfg_attr(docsrs, doc(cfg(any(feature = "std", feature = "alloc"))))] + Serialize for Box where T: ?Sized + Serialize +} + +deref_impl! { + /// This impl requires the [`"rc"`] Cargo feature of Serde. + /// + /// Serializing a data structure containing `Rc` will serialize a copy of + /// the contents of the `Rc` each time the `Rc` is referenced within the + /// data structure. Serialization will not attempt to deduplicate these + /// repeated data. + /// + /// [`"rc"`]: https://serde.rs/feature-flags.html#-features-rc + #[cfg(all(feature = "rc", any(feature = "std", feature = "alloc")))] + #[cfg_attr(docsrs, doc(cfg(all(feature = "rc", any(feature = "std", feature = "alloc")))))] + Serialize for Rc where T: ?Sized + Serialize +} + +deref_impl! { + /// This impl requires the [`"rc"`] Cargo feature of Serde. + /// + /// Serializing a data structure containing `Arc` will serialize a copy of + /// the contents of the `Arc` each time the `Arc` is referenced within the + /// data structure. Serialization will not attempt to deduplicate these + /// repeated data. + /// + /// [`"rc"`]: https://serde.rs/feature-flags.html#-features-rc + #[cfg(all(feature = "rc", any(feature = "std", feature = "alloc")))] + #[cfg_attr(docsrs, doc(cfg(all(feature = "rc", any(feature = "std", feature = "alloc")))))] + Serialize for Arc where T: ?Sized + Serialize +} + +deref_impl! { + #[cfg(any(feature = "std", feature = "alloc"))] + #[cfg_attr(docsrs, doc(cfg(any(feature = "std", feature = "alloc"))))] + <'a, T> Serialize for Cow<'a, T> where T: ?Sized + Serialize + ToOwned +} + +//////////////////////////////////////////////////////////////////////////////// + +/// This impl requires the [`"rc"`] Cargo feature of Serde. +/// +/// [`"rc"`]: https://serde.rs/feature-flags.html#-features-rc +#[cfg(all(feature = "rc", any(feature = "std", feature = "alloc")))] +#[cfg_attr( + docsrs, + doc(cfg(all(feature = "rc", any(feature = "std", feature = "alloc")))) +)] +impl Serialize for RcWeak +where + T: ?Sized + Serialize, +{ + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + self.upgrade().serialize(serializer) + } +} + +/// This impl requires the [`"rc"`] Cargo feature of Serde. +/// +/// [`"rc"`]: https://serde.rs/feature-flags.html#-features-rc +#[cfg(all(feature = "rc", any(feature = "std", feature = "alloc")))] +#[cfg_attr( + docsrs, + doc(cfg(all(feature = "rc", any(feature = "std", feature = "alloc")))) +)] +impl Serialize for ArcWeak +where + T: ?Sized + Serialize, +{ + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + self.upgrade().serialize(serializer) + } +} + +//////////////////////////////////////////////////////////////////////////////// + +macro_rules! nonzero_integers { + ($($T:ident,)+) => { + $( + impl Serialize for num::$T { + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + self.get().serialize(serializer) + } + } + )+ + } +} + +nonzero_integers! { + NonZeroU8, + NonZeroU16, + NonZeroU32, + NonZeroU64, + NonZeroU128, + NonZeroUsize, +} + +#[cfg(not(no_num_nonzero_signed))] +nonzero_integers! { + NonZeroI8, + NonZeroI16, + NonZeroI32, + NonZeroI64, + NonZeroI128, + NonZeroIsize, +} + +impl Serialize for Cell +where + T: Serialize + Copy, +{ + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + self.get().serialize(serializer) + } +} + +impl Serialize for RefCell +where + T: ?Sized + Serialize, +{ + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + match self.try_borrow() { + Ok(value) => value.serialize(serializer), + Err(_) => Err(S::Error::custom("already mutably borrowed")), + } + } +} + +#[cfg(feature = "std")] +#[cfg_attr(docsrs, doc(cfg(feature = "std")))] +impl Serialize for Mutex +where + T: ?Sized + Serialize, +{ + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + match self.lock() { + Ok(locked) => locked.serialize(serializer), + Err(_) => Err(S::Error::custom("lock poison error while serializing")), + } + } +} + +#[cfg(feature = "std")] +#[cfg_attr(docsrs, doc(cfg(feature = "std")))] +impl Serialize for RwLock +where + T: ?Sized + Serialize, +{ + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + match self.read() { + Ok(locked) => locked.serialize(serializer), + Err(_) => Err(S::Error::custom("lock poison error while serializing")), + } + } +} + +//////////////////////////////////////////////////////////////////////////////// + +impl Serialize for Result +where + T: Serialize, + E: Serialize, +{ + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + match *self { + Result::Ok(ref value) => serializer.serialize_newtype_variant("Result", 0, "Ok", value), + Result::Err(ref value) => { + serializer.serialize_newtype_variant("Result", 1, "Err", value) + } + } + } +} + +//////////////////////////////////////////////////////////////////////////////// + +impl Serialize for Duration { + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + use super::SerializeStruct; + let mut state = tri!(serializer.serialize_struct("Duration", 2)); + tri!(state.serialize_field("secs", &self.as_secs())); + tri!(state.serialize_field("nanos", &self.subsec_nanos())); + state.end() + } +} + +//////////////////////////////////////////////////////////////////////////////// + +#[cfg(feature = "std")] +#[cfg_attr(docsrs, doc(cfg(feature = "std")))] +impl Serialize for SystemTime { + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + use super::SerializeStruct; + let duration_since_epoch = match self.duration_since(UNIX_EPOCH) { + Ok(duration_since_epoch) => duration_since_epoch, + Err(_) => return Err(S::Error::custom("SystemTime must be later than UNIX_EPOCH")), + }; + let mut state = tri!(serializer.serialize_struct("SystemTime", 2)); + tri!(state.serialize_field("secs_since_epoch", &duration_since_epoch.as_secs())); + tri!(state.serialize_field("nanos_since_epoch", &duration_since_epoch.subsec_nanos())); + state.end() + } +} + +//////////////////////////////////////////////////////////////////////////////// + +/// Serialize a value that implements `Display` as a string, when that string is +/// statically known to never have more than a constant `MAX_LEN` bytes. +/// +/// Panics if the `Display` impl tries to write more than `MAX_LEN` bytes. +#[cfg(any(feature = "std", not(no_core_net)))] +macro_rules! serialize_display_bounded_length { + ($value:expr, $max:expr, $serializer:expr) => {{ + let mut buffer = [0u8; $max]; + let mut writer = crate::format::Buf::new(&mut buffer); + write!(&mut writer, "{}", $value).unwrap(); + $serializer.serialize_str(writer.as_str()) + }}; +} + +#[cfg(any(feature = "std", not(no_core_net)))] +impl Serialize for net::IpAddr { + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + if serializer.is_human_readable() { + match *self { + net::IpAddr::V4(ref a) => a.serialize(serializer), + net::IpAddr::V6(ref a) => a.serialize(serializer), + } + } else { + match *self { + net::IpAddr::V4(ref a) => { + serializer.serialize_newtype_variant("IpAddr", 0, "V4", a) + } + net::IpAddr::V6(ref a) => { + serializer.serialize_newtype_variant("IpAddr", 1, "V6", a) + } + } + } + } +} + +#[cfg(any(feature = "std", not(no_core_net)))] +const DEC_DIGITS_LUT: &[u8] = b"\ + 0001020304050607080910111213141516171819\ + 2021222324252627282930313233343536373839\ + 4041424344454647484950515253545556575859\ + 6061626364656667686970717273747576777879\ + 8081828384858687888990919293949596979899"; + +#[cfg(any(feature = "std", not(no_core_net)))] +#[inline] +fn format_u8(mut n: u8, out: &mut [u8]) -> usize { + if n >= 100 { + let d1 = ((n % 100) << 1) as usize; + n /= 100; + out[0] = b'0' + n; + out[1] = DEC_DIGITS_LUT[d1]; + out[2] = DEC_DIGITS_LUT[d1 + 1]; + 3 + } else if n >= 10 { + let d1 = (n << 1) as usize; + out[0] = DEC_DIGITS_LUT[d1]; + out[1] = DEC_DIGITS_LUT[d1 + 1]; + 2 + } else { + out[0] = b'0' + n; + 1 + } +} + +#[cfg(any(feature = "std", not(no_core_net)))] +#[test] +fn test_format_u8() { + let mut i = 0u8; + + loop { + let mut buf = [0u8; 3]; + let written = format_u8(i, &mut buf); + assert_eq!(i.to_string().as_bytes(), &buf[..written]); + + match i.checked_add(1) { + Some(next) => i = next, + None => break, + } + } +} + +#[cfg(any(feature = "std", not(no_core_net)))] +impl Serialize for net::Ipv4Addr { + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + if serializer.is_human_readable() { + const MAX_LEN: usize = 15; + debug_assert_eq!(MAX_LEN, "101.102.103.104".len()); + let mut buf = [b'.'; MAX_LEN]; + let mut written = format_u8(self.octets()[0], &mut buf); + for oct in &self.octets()[1..] { + // Skip over delimiters that we initialized buf with + written += format_u8(*oct, &mut buf[written + 1..]) + 1; + } + // Safety: We've only written ASCII bytes to the buffer, so it is valid UTF-8 + let buf = unsafe { str::from_utf8_unchecked(&buf[..written]) }; + serializer.serialize_str(buf) + } else { + self.octets().serialize(serializer) + } + } +} + +#[cfg(any(feature = "std", not(no_core_net)))] +impl Serialize for net::Ipv6Addr { + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + if serializer.is_human_readable() { + const MAX_LEN: usize = 39; + debug_assert_eq!(MAX_LEN, "1001:1002:1003:1004:1005:1006:1007:1008".len()); + serialize_display_bounded_length!(self, MAX_LEN, serializer) + } else { + self.octets().serialize(serializer) + } + } +} + +#[cfg(any(feature = "std", not(no_core_net)))] +impl Serialize for net::SocketAddr { + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + if serializer.is_human_readable() { + match *self { + net::SocketAddr::V4(ref addr) => addr.serialize(serializer), + net::SocketAddr::V6(ref addr) => addr.serialize(serializer), + } + } else { + match *self { + net::SocketAddr::V4(ref addr) => { + serializer.serialize_newtype_variant("SocketAddr", 0, "V4", addr) + } + net::SocketAddr::V6(ref addr) => { + serializer.serialize_newtype_variant("SocketAddr", 1, "V6", addr) + } + } + } + } +} + +#[cfg(any(feature = "std", not(no_core_net)))] +impl Serialize for net::SocketAddrV4 { + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + if serializer.is_human_readable() { + const MAX_LEN: usize = 21; + debug_assert_eq!(MAX_LEN, "101.102.103.104:65000".len()); + serialize_display_bounded_length!(self, MAX_LEN, serializer) + } else { + (self.ip(), self.port()).serialize(serializer) + } + } +} + +#[cfg(any(feature = "std", not(no_core_net)))] +impl Serialize for net::SocketAddrV6 { + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + if serializer.is_human_readable() { + const MAX_LEN: usize = 58; + debug_assert_eq!( + MAX_LEN, + "[1001:1002:1003:1004:1005:1006:1007:1008%4294967295]:65000".len() + ); + serialize_display_bounded_length!(self, MAX_LEN, serializer) + } else { + (self.ip(), self.port()).serialize(serializer) + } + } +} + +//////////////////////////////////////////////////////////////////////////////// + +#[cfg(feature = "std")] +#[cfg_attr(docsrs, doc(cfg(feature = "std")))] +impl Serialize for Path { + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + match self.to_str() { + Some(s) => s.serialize(serializer), + None => Err(Error::custom("path contains invalid UTF-8 characters")), + } + } +} + +#[cfg(feature = "std")] +#[cfg_attr(docsrs, doc(cfg(feature = "std")))] +impl Serialize for PathBuf { + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + self.as_path().serialize(serializer) + } +} + +#[cfg(all(feature = "std", any(unix, windows)))] +#[cfg_attr(docsrs, doc(cfg(all(feature = "std", any(unix, windows)))))] +impl Serialize for OsStr { + #[cfg(unix)] + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + use std::os::unix::ffi::OsStrExt; + serializer.serialize_newtype_variant("OsString", 0, "Unix", self.as_bytes()) + } + + #[cfg(windows)] + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + use std::os::windows::ffi::OsStrExt; + let val = self.encode_wide().collect::>(); + serializer.serialize_newtype_variant("OsString", 1, "Windows", &val) + } +} + +#[cfg(all(feature = "std", any(unix, windows)))] +#[cfg_attr(docsrs, doc(cfg(all(feature = "std", any(unix, windows)))))] +impl Serialize for OsString { + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + self.as_os_str().serialize(serializer) + } +} + +//////////////////////////////////////////////////////////////////////////////// + +impl Serialize for Wrapping +where + T: Serialize, +{ + #[inline] + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + self.0.serialize(serializer) + } +} + +#[cfg(not(no_core_num_saturating))] +impl Serialize for Saturating +where + T: Serialize, +{ + #[inline] + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + self.0.serialize(serializer) + } +} + +impl Serialize for Reverse +where + T: Serialize, +{ + #[inline] + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + self.0.serialize(serializer) + } +} + +//////////////////////////////////////////////////////////////////////////////// + +#[cfg(all(feature = "std", not(no_std_atomic)))] +macro_rules! atomic_impl { + ($($ty:ident $size:expr)*) => { + $( + #[cfg(any(no_target_has_atomic, target_has_atomic = $size))] + #[cfg_attr(docsrs, doc(cfg(all(feature = "std", target_has_atomic = $size))))] + impl Serialize for $ty { + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + // Matches the atomic ordering used in libcore for the Debug impl + self.load(Ordering::Relaxed).serialize(serializer) + } + } + )* + } +} + +#[cfg(all(feature = "std", not(no_std_atomic)))] +atomic_impl! { + AtomicBool "8" + AtomicI8 "8" + AtomicI16 "16" + AtomicI32 "32" + AtomicIsize "ptr" + AtomicU8 "8" + AtomicU16 "16" + AtomicU32 "32" + AtomicUsize "ptr" +} + +#[cfg(all(feature = "std", not(no_std_atomic64)))] +atomic_impl! { + AtomicI64 "64" + AtomicU64 "64" +} diff --git a/vendor/serde/src/ser/impossible.rs b/vendor/serde/src/ser/impossible.rs new file mode 100644 index 0000000..6432d57 --- /dev/null +++ b/vendor/serde/src/ser/impossible.rs @@ -0,0 +1,216 @@ +//! This module contains `Impossible` serializer and its implementations. + +use crate::lib::*; + +use crate::ser::{ + self, Serialize, SerializeMap, SerializeSeq, SerializeStruct, SerializeStructVariant, + SerializeTuple, SerializeTupleStruct, SerializeTupleVariant, +}; + +/// Helper type for implementing a `Serializer` that does not support +/// serializing one of the compound types. +/// +/// This type cannot be instantiated, but implements every one of the traits +/// corresponding to the [`Serializer`] compound types: [`SerializeSeq`], +/// [`SerializeTuple`], [`SerializeTupleStruct`], [`SerializeTupleVariant`], +/// [`SerializeMap`], [`SerializeStruct`], and [`SerializeStructVariant`]. +/// +/// ```edition2021 +/// # use serde::ser::{Serializer, Impossible}; +/// # use serde::__private::doc::Error; +/// # +/// # struct MySerializer; +/// # +/// impl Serializer for MySerializer { +/// type Ok = (); +/// type Error = Error; +/// +/// type SerializeSeq = Impossible<(), Error>; +/// /* other associated types */ +/// +/// /// This data format does not support serializing sequences. +/// fn serialize_seq(self, +/// len: Option) +/// -> Result { +/// // Given Impossible cannot be instantiated, the only +/// // thing we can do here is to return an error. +/// # stringify! { +/// Err(...) +/// # }; +/// # unimplemented!() +/// } +/// +/// /* other Serializer methods */ +/// # serde::__serialize_unimplemented! { +/// # bool i8 i16 i32 i64 u8 u16 u32 u64 f32 f64 char str bytes none some +/// # unit unit_struct unit_variant newtype_struct newtype_variant +/// # tuple tuple_struct tuple_variant map struct struct_variant +/// # } +/// } +/// ``` +/// +/// [`Serializer`]: trait.Serializer.html +/// [`SerializeSeq`]: trait.SerializeSeq.html +/// [`SerializeTuple`]: trait.SerializeTuple.html +/// [`SerializeTupleStruct`]: trait.SerializeTupleStruct.html +/// [`SerializeTupleVariant`]: trait.SerializeTupleVariant.html +/// [`SerializeMap`]: trait.SerializeMap.html +/// [`SerializeStruct`]: trait.SerializeStruct.html +/// [`SerializeStructVariant`]: trait.SerializeStructVariant.html +pub struct Impossible { + void: Void, + ok: PhantomData, + error: PhantomData, +} + +enum Void {} + +impl SerializeSeq for Impossible +where + Error: ser::Error, +{ + type Ok = Ok; + type Error = Error; + + fn serialize_element(&mut self, value: &T) -> Result<(), Error> + where + T: ?Sized + Serialize, + { + let _ = value; + match self.void {} + } + + fn end(self) -> Result { + match self.void {} + } +} + +impl SerializeTuple for Impossible +where + Error: ser::Error, +{ + type Ok = Ok; + type Error = Error; + + fn serialize_element(&mut self, value: &T) -> Result<(), Error> + where + T: ?Sized + Serialize, + { + let _ = value; + match self.void {} + } + + fn end(self) -> Result { + match self.void {} + } +} + +impl SerializeTupleStruct for Impossible +where + Error: ser::Error, +{ + type Ok = Ok; + type Error = Error; + + fn serialize_field(&mut self, value: &T) -> Result<(), Error> + where + T: ?Sized + Serialize, + { + let _ = value; + match self.void {} + } + + fn end(self) -> Result { + match self.void {} + } +} + +impl SerializeTupleVariant for Impossible +where + Error: ser::Error, +{ + type Ok = Ok; + type Error = Error; + + fn serialize_field(&mut self, value: &T) -> Result<(), Error> + where + T: ?Sized + Serialize, + { + let _ = value; + match self.void {} + } + + fn end(self) -> Result { + match self.void {} + } +} + +impl SerializeMap for Impossible +where + Error: ser::Error, +{ + type Ok = Ok; + type Error = Error; + + fn serialize_key(&mut self, key: &T) -> Result<(), Error> + where + T: ?Sized + Serialize, + { + let _ = key; + match self.void {} + } + + fn serialize_value(&mut self, value: &T) -> Result<(), Error> + where + T: ?Sized + Serialize, + { + let _ = value; + match self.void {} + } + + fn end(self) -> Result { + match self.void {} + } +} + +impl SerializeStruct for Impossible +where + Error: ser::Error, +{ + type Ok = Ok; + type Error = Error; + + fn serialize_field(&mut self, key: &'static str, value: &T) -> Result<(), Error> + where + T: ?Sized + Serialize, + { + let _ = key; + let _ = value; + match self.void {} + } + + fn end(self) -> Result { + match self.void {} + } +} + +impl SerializeStructVariant for Impossible +where + Error: ser::Error, +{ + type Ok = Ok; + type Error = Error; + + fn serialize_field(&mut self, key: &'static str, value: &T) -> Result<(), Error> + where + T: ?Sized + Serialize, + { + let _ = key; + let _ = value; + match self.void {} + } + + fn end(self) -> Result { + match self.void {} + } +} diff --git a/vendor/serde/src/ser/mod.rs b/vendor/serde/src/ser/mod.rs new file mode 100644 index 0000000..fb0033e --- /dev/null +++ b/vendor/serde/src/ser/mod.rs @@ -0,0 +1,1954 @@ +//! Generic data structure serialization framework. +//! +//! The two most important traits in this module are [`Serialize`] and +//! [`Serializer`]. +//! +//! - **A type that implements `Serialize` is a data structure** that can be +//! serialized to any data format supported by Serde, and conversely +//! - **A type that implements `Serializer` is a data format** that can +//! serialize any data structure supported by Serde. +//! +//! # The Serialize trait +//! +//! Serde provides [`Serialize`] implementations for many Rust primitive and +//! standard library types. The complete list is below. All of these can be +//! serialized using Serde out of the box. +//! +//! Additionally, Serde provides a procedural macro called [`serde_derive`] to +//! automatically generate [`Serialize`] implementations for structs and enums +//! in your program. See the [derive section of the manual] for how to use this. +//! +//! In rare cases it may be necessary to implement [`Serialize`] manually for +//! some type in your program. See the [Implementing `Serialize`] section of the +//! manual for more about this. +//! +//! Third-party crates may provide [`Serialize`] implementations for types that +//! they expose. For example the [`linked-hash-map`] crate provides a +//! [`LinkedHashMap`] type that is serializable by Serde because the crate +//! provides an implementation of [`Serialize`] for it. +//! +//! # The Serializer trait +//! +//! [`Serializer`] implementations are provided by third-party crates, for +//! example [`serde_json`], [`serde_yaml`] and [`postcard`]. +//! +//! A partial list of well-maintained formats is given on the [Serde +//! website][data formats]. +//! +//! # Implementations of Serialize provided by Serde +//! +//! - **Primitive types**: +//! - bool +//! - i8, i16, i32, i64, i128, isize +//! - u8, u16, u32, u64, u128, usize +//! - f32, f64 +//! - char +//! - str +//! - &T and &mut T +//! - **Compound types**: +//! - \[T\] +//! - \[T; 0\] through \[T; 32\] +//! - tuples up to size 16 +//! - **Common standard library types**: +//! - String +//! - Option\ +//! - Result\ +//! - PhantomData\ +//! - **Wrapper types**: +//! - Box\ +//! - Cow\<'a, T\> +//! - Cell\ +//! - RefCell\ +//! - Mutex\ +//! - RwLock\ +//! - Rc\ *(if* features = \["rc"\] *is enabled)* +//! - Arc\ *(if* features = \["rc"\] *is enabled)* +//! - **Collection types**: +//! - BTreeMap\ +//! - BTreeSet\ +//! - BinaryHeap\ +//! - HashMap\ +//! - HashSet\ +//! - LinkedList\ +//! - VecDeque\ +//! - Vec\ +//! - **FFI types**: +//! - CStr +//! - CString +//! - OsStr +//! - OsString +//! - **Miscellaneous standard library types**: +//! - Duration +//! - SystemTime +//! - Path +//! - PathBuf +//! - Range\ +//! - RangeInclusive\ +//! - Bound\ +//! - num::NonZero* +//! - `!` *(unstable)* +//! - **Net types**: +//! - IpAddr +//! - Ipv4Addr +//! - Ipv6Addr +//! - SocketAddr +//! - SocketAddrV4 +//! - SocketAddrV6 +//! +//! [Implementing `Serialize`]: https://serde.rs/impl-serialize.html +//! [`LinkedHashMap`]: https://docs.rs/linked-hash-map/*/linked_hash_map/struct.LinkedHashMap.html +//! [`Serialize`]: ../trait.Serialize.html +//! [`Serializer`]: ../trait.Serializer.html +//! [`postcard`]: https://github.com/jamesmunns/postcard +//! [`linked-hash-map`]: https://crates.io/crates/linked-hash-map +//! [`serde_derive`]: https://crates.io/crates/serde_derive +//! [`serde_json`]: https://github.com/serde-rs/json +//! [`serde_yaml`]: https://github.com/dtolnay/serde-yaml +//! [derive section of the manual]: https://serde.rs/derive.html +//! [data formats]: https://serde.rs/#data-formats + +use crate::lib::*; + +mod fmt; +mod impls; +mod impossible; + +pub use self::impossible::Impossible; + +#[cfg(all(not(feature = "std"), no_core_error))] +#[doc(no_inline)] +pub use crate::std_error::Error as StdError; +#[cfg(not(any(feature = "std", no_core_error)))] +#[doc(no_inline)] +pub use core::error::Error as StdError; +#[cfg(feature = "std")] +#[doc(no_inline)] +pub use std::error::Error as StdError; + +//////////////////////////////////////////////////////////////////////////////// + +macro_rules! declare_error_trait { + (Error: Sized $(+ $($supertrait:ident)::+)*) => { + /// Trait used by `Serialize` implementations to generically construct + /// errors belonging to the `Serializer` against which they are + /// currently running. + /// + /// # Example implementation + /// + /// The [example data format] presented on the website shows an error + /// type appropriate for a basic JSON data format. + /// + /// [example data format]: https://serde.rs/data-format.html + pub trait Error: Sized $(+ $($supertrait)::+)* { + /// Used when a [`Serialize`] implementation encounters any error + /// while serializing a type. + /// + /// The message should not be capitalized and should not end with a + /// period. + /// + /// For example, a filesystem [`Path`] may refuse to serialize + /// itself if it contains invalid UTF-8 data. + /// + /// ```edition2021 + /// # struct Path; + /// # + /// # impl Path { + /// # fn to_str(&self) -> Option<&str> { + /// # unimplemented!() + /// # } + /// # } + /// # + /// use serde::ser::{self, Serialize, Serializer}; + /// + /// impl Serialize for Path { + /// fn serialize(&self, serializer: S) -> Result + /// where + /// S: Serializer, + /// { + /// match self.to_str() { + /// Some(s) => serializer.serialize_str(s), + /// None => Err(ser::Error::custom("path contains invalid UTF-8 characters")), + /// } + /// } + /// } + /// ``` + /// + /// [`Path`]: https://doc.rust-lang.org/std/path/struct.Path.html + /// [`Serialize`]: ../trait.Serialize.html + fn custom(msg: T) -> Self + where + T: Display; + } + } +} + +#[cfg(feature = "std")] +declare_error_trait!(Error: Sized + StdError); + +#[cfg(not(feature = "std"))] +declare_error_trait!(Error: Sized + Debug + Display); + +//////////////////////////////////////////////////////////////////////////////// + +/// A **data structure** that can be serialized into any data format supported +/// by Serde. +/// +/// Serde provides `Serialize` implementations for many Rust primitive and +/// standard library types. The complete list is [here][crate::ser]. All of +/// these can be serialized using Serde out of the box. +/// +/// Additionally, Serde provides a procedural macro called [`serde_derive`] to +/// automatically generate `Serialize` implementations for structs and enums in +/// your program. See the [derive section of the manual] for how to use this. +/// +/// In rare cases it may be necessary to implement `Serialize` manually for some +/// type in your program. See the [Implementing `Serialize`] section of the +/// manual for more about this. +/// +/// Third-party crates may provide `Serialize` implementations for types that +/// they expose. For example the [`linked-hash-map`] crate provides a +/// [`LinkedHashMap`] type that is serializable by Serde because the crate +/// provides an implementation of `Serialize` for it. +/// +/// [Implementing `Serialize`]: https://serde.rs/impl-serialize.html +/// [`LinkedHashMap`]: https://docs.rs/linked-hash-map/*/linked_hash_map/struct.LinkedHashMap.html +/// [`linked-hash-map`]: https://crates.io/crates/linked-hash-map +/// [`serde_derive`]: https://crates.io/crates/serde_derive +/// [derive section of the manual]: https://serde.rs/derive.html +#[cfg_attr( + not(no_diagnostic_namespace), + diagnostic::on_unimplemented( + note = "for local types consider adding `#[derive(serde::Serialize)]` to your `{Self}` type", + note = "for types from other crates check whether the crate offers a `serde` feature flag", + ) +)] +pub trait Serialize { + /// Serialize this value into the given Serde serializer. + /// + /// See the [Implementing `Serialize`] section of the manual for more + /// information about how to implement this method. + /// + /// ```edition2021 + /// use serde::ser::{Serialize, SerializeStruct, Serializer}; + /// + /// struct Person { + /// name: String, + /// age: u8, + /// phones: Vec, + /// } + /// + /// // This is what #[derive(Serialize)] would generate. + /// impl Serialize for Person { + /// fn serialize(&self, serializer: S) -> Result + /// where + /// S: Serializer, + /// { + /// let mut s = serializer.serialize_struct("Person", 3)?; + /// s.serialize_field("name", &self.name)?; + /// s.serialize_field("age", &self.age)?; + /// s.serialize_field("phones", &self.phones)?; + /// s.end() + /// } + /// } + /// ``` + /// + /// [Implementing `Serialize`]: https://serde.rs/impl-serialize.html + fn serialize(&self, serializer: S) -> Result + where + S: Serializer; +} + +//////////////////////////////////////////////////////////////////////////////// + +/// A **data format** that can serialize any data structure supported by Serde. +/// +/// The role of this trait is to define the serialization half of the [Serde +/// data model], which is a way to categorize every Rust data structure into one +/// of 29 possible types. Each method of the `Serializer` trait corresponds to +/// one of the types of the data model. +/// +/// Implementations of `Serialize` map themselves into this data model by +/// invoking exactly one of the `Serializer` methods. +/// +/// The types that make up the Serde data model are: +/// +/// - **14 primitive types** +/// - bool +/// - i8, i16, i32, i64, i128 +/// - u8, u16, u32, u64, u128 +/// - f32, f64 +/// - char +/// - **string** +/// - UTF-8 bytes with a length and no null terminator. +/// - When serializing, all strings are handled equally. When deserializing, +/// there are three flavors of strings: transient, owned, and borrowed. +/// - **byte array** - \[u8\] +/// - Similar to strings, during deserialization byte arrays can be +/// transient, owned, or borrowed. +/// - **option** +/// - Either none or some value. +/// - **unit** +/// - The type of `()` in Rust. It represents an anonymous value containing +/// no data. +/// - **unit_struct** +/// - For example `struct Unit` or `PhantomData`. It represents a named +/// value containing no data. +/// - **unit_variant** +/// - For example the `E::A` and `E::B` in `enum E { A, B }`. +/// - **newtype_struct** +/// - For example `struct Millimeters(u8)`. +/// - **newtype_variant** +/// - For example the `E::N` in `enum E { N(u8) }`. +/// - **seq** +/// - A variably sized heterogeneous sequence of values, for example +/// `Vec` or `HashSet`. When serializing, the length may or may not +/// be known before iterating through all the data. When deserializing, +/// the length is determined by looking at the serialized data. +/// - **tuple** +/// - A statically sized heterogeneous sequence of values for which the +/// length will be known at deserialization time without looking at the +/// serialized data, for example `(u8,)` or `(String, u64, Vec)` or +/// `[u64; 10]`. +/// - **tuple_struct** +/// - A named tuple, for example `struct Rgb(u8, u8, u8)`. +/// - **tuple_variant** +/// - For example the `E::T` in `enum E { T(u8, u8) }`. +/// - **map** +/// - A heterogeneous key-value pairing, for example `BTreeMap`. +/// - **struct** +/// - A heterogeneous key-value pairing in which the keys are strings and +/// will be known at deserialization time without looking at the +/// serialized data, for example `struct S { r: u8, g: u8, b: u8 }`. +/// - **struct_variant** +/// - For example the `E::S` in `enum E { S { r: u8, g: u8, b: u8 } }`. +/// +/// Many Serde serializers produce text or binary data as output, for example +/// JSON or Postcard. This is not a requirement of the `Serializer` trait, and +/// there are serializers that do not produce text or binary output. One example +/// is the `serde_json::value::Serializer` (distinct from the main `serde_json` +/// serializer) that produces a `serde_json::Value` data structure in memory as +/// output. +/// +/// [Serde data model]: https://serde.rs/data-model.html +/// +/// # Example implementation +/// +/// The [example data format] presented on the website contains example code for +/// a basic JSON `Serializer`. +/// +/// [example data format]: https://serde.rs/data-format.html +pub trait Serializer: Sized { + /// The output type produced by this `Serializer` during successful + /// serialization. Most serializers that produce text or binary output + /// should set `Ok = ()` and serialize into an [`io::Write`] or buffer + /// contained within the `Serializer` instance. Serializers that build + /// in-memory data structures may be simplified by using `Ok` to propagate + /// the data structure around. + /// + /// [`io::Write`]: https://doc.rust-lang.org/std/io/trait.Write.html + type Ok; + + /// The error type when some error occurs during serialization. + type Error: Error; + + /// Type returned from [`serialize_seq`] for serializing the content of the + /// sequence. + /// + /// [`serialize_seq`]: #tymethod.serialize_seq + type SerializeSeq: SerializeSeq; + + /// Type returned from [`serialize_tuple`] for serializing the content of + /// the tuple. + /// + /// [`serialize_tuple`]: #tymethod.serialize_tuple + type SerializeTuple: SerializeTuple; + + /// Type returned from [`serialize_tuple_struct`] for serializing the + /// content of the tuple struct. + /// + /// [`serialize_tuple_struct`]: #tymethod.serialize_tuple_struct + type SerializeTupleStruct: SerializeTupleStruct; + + /// Type returned from [`serialize_tuple_variant`] for serializing the + /// content of the tuple variant. + /// + /// [`serialize_tuple_variant`]: #tymethod.serialize_tuple_variant + type SerializeTupleVariant: SerializeTupleVariant; + + /// Type returned from [`serialize_map`] for serializing the content of the + /// map. + /// + /// [`serialize_map`]: #tymethod.serialize_map + type SerializeMap: SerializeMap; + + /// Type returned from [`serialize_struct`] for serializing the content of + /// the struct. + /// + /// [`serialize_struct`]: #tymethod.serialize_struct + type SerializeStruct: SerializeStruct; + + /// Type returned from [`serialize_struct_variant`] for serializing the + /// content of the struct variant. + /// + /// [`serialize_struct_variant`]: #tymethod.serialize_struct_variant + type SerializeStructVariant: SerializeStructVariant; + + /// Serialize a `bool` value. + /// + /// ```edition2021 + /// # use serde::Serializer; + /// # + /// # serde::__private_serialize!(); + /// # + /// impl Serialize for bool { + /// fn serialize(&self, serializer: S) -> Result + /// where + /// S: Serializer, + /// { + /// serializer.serialize_bool(*self) + /// } + /// } + /// ``` + fn serialize_bool(self, v: bool) -> Result; + + /// Serialize an `i8` value. + /// + /// If the format does not differentiate between `i8` and `i64`, a + /// reasonable implementation would be to cast the value to `i64` and + /// forward to `serialize_i64`. + /// + /// ```edition2021 + /// # use serde::Serializer; + /// # + /// # serde::__private_serialize!(); + /// # + /// impl Serialize for i8 { + /// fn serialize(&self, serializer: S) -> Result + /// where + /// S: Serializer, + /// { + /// serializer.serialize_i8(*self) + /// } + /// } + /// ``` + fn serialize_i8(self, v: i8) -> Result; + + /// Serialize an `i16` value. + /// + /// If the format does not differentiate between `i16` and `i64`, a + /// reasonable implementation would be to cast the value to `i64` and + /// forward to `serialize_i64`. + /// + /// ```edition2021 + /// # use serde::Serializer; + /// # + /// # serde::__private_serialize!(); + /// # + /// impl Serialize for i16 { + /// fn serialize(&self, serializer: S) -> Result + /// where + /// S: Serializer, + /// { + /// serializer.serialize_i16(*self) + /// } + /// } + /// ``` + fn serialize_i16(self, v: i16) -> Result; + + /// Serialize an `i32` value. + /// + /// If the format does not differentiate between `i32` and `i64`, a + /// reasonable implementation would be to cast the value to `i64` and + /// forward to `serialize_i64`. + /// + /// ```edition2021 + /// # use serde::Serializer; + /// # + /// # serde::__private_serialize!(); + /// # + /// impl Serialize for i32 { + /// fn serialize(&self, serializer: S) -> Result + /// where + /// S: Serializer, + /// { + /// serializer.serialize_i32(*self) + /// } + /// } + /// ``` + fn serialize_i32(self, v: i32) -> Result; + + /// Serialize an `i64` value. + /// + /// ```edition2021 + /// # use serde::Serializer; + /// # + /// # serde::__private_serialize!(); + /// # + /// impl Serialize for i64 { + /// fn serialize(&self, serializer: S) -> Result + /// where + /// S: Serializer, + /// { + /// serializer.serialize_i64(*self) + /// } + /// } + /// ``` + fn serialize_i64(self, v: i64) -> Result; + + /// Serialize an `i128` value. + /// + /// ```edition2021 + /// # use serde::Serializer; + /// # + /// # serde::__private_serialize!(); + /// # + /// impl Serialize for i128 { + /// fn serialize(&self, serializer: S) -> Result + /// where + /// S: Serializer, + /// { + /// serializer.serialize_i128(*self) + /// } + /// } + /// ``` + /// + /// The default behavior unconditionally returns an error. + fn serialize_i128(self, v: i128) -> Result { + let _ = v; + Err(Error::custom("i128 is not supported")) + } + + /// Serialize a `u8` value. + /// + /// If the format does not differentiate between `u8` and `u64`, a + /// reasonable implementation would be to cast the value to `u64` and + /// forward to `serialize_u64`. + /// + /// ```edition2021 + /// # use serde::Serializer; + /// # + /// # serde::__private_serialize!(); + /// # + /// impl Serialize for u8 { + /// fn serialize(&self, serializer: S) -> Result + /// where + /// S: Serializer, + /// { + /// serializer.serialize_u8(*self) + /// } + /// } + /// ``` + fn serialize_u8(self, v: u8) -> Result; + + /// Serialize a `u16` value. + /// + /// If the format does not differentiate between `u16` and `u64`, a + /// reasonable implementation would be to cast the value to `u64` and + /// forward to `serialize_u64`. + /// + /// ```edition2021 + /// # use serde::Serializer; + /// # + /// # serde::__private_serialize!(); + /// # + /// impl Serialize for u16 { + /// fn serialize(&self, serializer: S) -> Result + /// where + /// S: Serializer, + /// { + /// serializer.serialize_u16(*self) + /// } + /// } + /// ``` + fn serialize_u16(self, v: u16) -> Result; + + /// Serialize a `u32` value. + /// + /// If the format does not differentiate between `u32` and `u64`, a + /// reasonable implementation would be to cast the value to `u64` and + /// forward to `serialize_u64`. + /// + /// ```edition2021 + /// # use serde::Serializer; + /// # + /// # serde::__private_serialize!(); + /// # + /// impl Serialize for u32 { + /// fn serialize(&self, serializer: S) -> Result + /// where + /// S: Serializer, + /// { + /// serializer.serialize_u32(*self) + /// } + /// } + /// ``` + fn serialize_u32(self, v: u32) -> Result; + + /// Serialize a `u64` value. + /// + /// ```edition2021 + /// # use serde::Serializer; + /// # + /// # serde::__private_serialize!(); + /// # + /// impl Serialize for u64 { + /// fn serialize(&self, serializer: S) -> Result + /// where + /// S: Serializer, + /// { + /// serializer.serialize_u64(*self) + /// } + /// } + /// ``` + fn serialize_u64(self, v: u64) -> Result; + + /// Serialize a `u128` value. + /// + /// ```edition2021 + /// # use serde::Serializer; + /// # + /// # serde::__private_serialize!(); + /// # + /// impl Serialize for u128 { + /// fn serialize(&self, serializer: S) -> Result + /// where + /// S: Serializer, + /// { + /// serializer.serialize_u128(*self) + /// } + /// } + /// ``` + /// + /// The default behavior unconditionally returns an error. + fn serialize_u128(self, v: u128) -> Result { + let _ = v; + Err(Error::custom("u128 is not supported")) + } + + /// Serialize an `f32` value. + /// + /// If the format does not differentiate between `f32` and `f64`, a + /// reasonable implementation would be to cast the value to `f64` and + /// forward to `serialize_f64`. + /// + /// ```edition2021 + /// # use serde::Serializer; + /// # + /// # serde::__private_serialize!(); + /// # + /// impl Serialize for f32 { + /// fn serialize(&self, serializer: S) -> Result + /// where + /// S: Serializer, + /// { + /// serializer.serialize_f32(*self) + /// } + /// } + /// ``` + fn serialize_f32(self, v: f32) -> Result; + + /// Serialize an `f64` value. + /// + /// ```edition2021 + /// # use serde::Serializer; + /// # + /// # serde::__private_serialize!(); + /// # + /// impl Serialize for f64 { + /// fn serialize(&self, serializer: S) -> Result + /// where + /// S: Serializer, + /// { + /// serializer.serialize_f64(*self) + /// } + /// } + /// ``` + fn serialize_f64(self, v: f64) -> Result; + + /// Serialize a character. + /// + /// If the format does not support characters, it is reasonable to serialize + /// it as a single element `str` or a `u32`. + /// + /// ```edition2021 + /// # use serde::Serializer; + /// # + /// # serde::__private_serialize!(); + /// # + /// impl Serialize for char { + /// fn serialize(&self, serializer: S) -> Result + /// where + /// S: Serializer, + /// { + /// serializer.serialize_char(*self) + /// } + /// } + /// ``` + fn serialize_char(self, v: char) -> Result; + + /// Serialize a `&str`. + /// + /// ```edition2021 + /// # use serde::Serializer; + /// # + /// # serde::__private_serialize!(); + /// # + /// impl Serialize for str { + /// fn serialize(&self, serializer: S) -> Result + /// where + /// S: Serializer, + /// { + /// serializer.serialize_str(self) + /// } + /// } + /// ``` + fn serialize_str(self, v: &str) -> Result; + + /// Serialize a chunk of raw byte data. + /// + /// Enables serializers to serialize byte slices more compactly or more + /// efficiently than other types of slices. If no efficient implementation + /// is available, a reasonable implementation would be to forward to + /// `serialize_seq`. If forwarded, the implementation looks usually just + /// like this: + /// + /// ```edition2021 + /// # use serde::ser::{Serializer, SerializeSeq}; + /// # use serde::__private::doc::Error; + /// # + /// # struct MySerializer; + /// # + /// # impl Serializer for MySerializer { + /// # type Ok = (); + /// # type Error = Error; + /// # + /// fn serialize_bytes(self, v: &[u8]) -> Result { + /// let mut seq = self.serialize_seq(Some(v.len()))?; + /// for b in v { + /// seq.serialize_element(b)?; + /// } + /// seq.end() + /// } + /// # + /// # serde::__serialize_unimplemented! { + /// # bool i8 i16 i32 i64 u8 u16 u32 u64 f32 f64 char str none some + /// # unit unit_struct unit_variant newtype_struct newtype_variant + /// # seq tuple tuple_struct tuple_variant map struct struct_variant + /// # } + /// # } + /// ``` + fn serialize_bytes(self, v: &[u8]) -> Result; + + /// Serialize a [`None`] value. + /// + /// ```edition2021 + /// # use serde::{Serialize, Serializer}; + /// # + /// # enum Option { + /// # Some(T), + /// # None, + /// # } + /// # + /// # use self::Option::{Some, None}; + /// # + /// impl Serialize for Option + /// where + /// T: Serialize, + /// { + /// fn serialize(&self, serializer: S) -> Result + /// where + /// S: Serializer, + /// { + /// match *self { + /// Some(ref value) => serializer.serialize_some(value), + /// None => serializer.serialize_none(), + /// } + /// } + /// } + /// # + /// # fn main() {} + /// ``` + /// + /// [`None`]: https://doc.rust-lang.org/std/option/enum.Option.html#variant.None + fn serialize_none(self) -> Result; + + /// Serialize a [`Some(T)`] value. + /// + /// ```edition2021 + /// # use serde::{Serialize, Serializer}; + /// # + /// # enum Option { + /// # Some(T), + /// # None, + /// # } + /// # + /// # use self::Option::{Some, None}; + /// # + /// impl Serialize for Option + /// where + /// T: Serialize, + /// { + /// fn serialize(&self, serializer: S) -> Result + /// where + /// S: Serializer, + /// { + /// match *self { + /// Some(ref value) => serializer.serialize_some(value), + /// None => serializer.serialize_none(), + /// } + /// } + /// } + /// # + /// # fn main() {} + /// ``` + /// + /// [`Some(T)`]: https://doc.rust-lang.org/std/option/enum.Option.html#variant.Some + fn serialize_some(self, value: &T) -> Result + where + T: ?Sized + Serialize; + + /// Serialize a `()` value. + /// + /// ```edition2021 + /// # use serde::Serializer; + /// # + /// # serde::__private_serialize!(); + /// # + /// impl Serialize for () { + /// fn serialize(&self, serializer: S) -> Result + /// where + /// S: Serializer, + /// { + /// serializer.serialize_unit() + /// } + /// } + /// ``` + fn serialize_unit(self) -> Result; + + /// Serialize a unit struct like `struct Unit` or `PhantomData`. + /// + /// A reasonable implementation would be to forward to `serialize_unit`. + /// + /// ```edition2021 + /// use serde::{Serialize, Serializer}; + /// + /// struct Nothing; + /// + /// impl Serialize for Nothing { + /// fn serialize(&self, serializer: S) -> Result + /// where + /// S: Serializer, + /// { + /// serializer.serialize_unit_struct("Nothing") + /// } + /// } + /// ``` + fn serialize_unit_struct(self, name: &'static str) -> Result; + + /// Serialize a unit variant like `E::A` in `enum E { A, B }`. + /// + /// The `name` is the name of the enum, the `variant_index` is the index of + /// this variant within the enum, and the `variant` is the name of the + /// variant. + /// + /// ```edition2021 + /// use serde::{Serialize, Serializer}; + /// + /// enum E { + /// A, + /// B, + /// } + /// + /// impl Serialize for E { + /// fn serialize(&self, serializer: S) -> Result + /// where + /// S: Serializer, + /// { + /// match *self { + /// E::A => serializer.serialize_unit_variant("E", 0, "A"), + /// E::B => serializer.serialize_unit_variant("E", 1, "B"), + /// } + /// } + /// } + /// ``` + fn serialize_unit_variant( + self, + name: &'static str, + variant_index: u32, + variant: &'static str, + ) -> Result; + + /// Serialize a newtype struct like `struct Millimeters(u8)`. + /// + /// Serializers are encouraged to treat newtype structs as insignificant + /// wrappers around the data they contain. A reasonable implementation would + /// be to forward to `value.serialize(self)`. + /// + /// ```edition2021 + /// use serde::{Serialize, Serializer}; + /// + /// struct Millimeters(u8); + /// + /// impl Serialize for Millimeters { + /// fn serialize(&self, serializer: S) -> Result + /// where + /// S: Serializer, + /// { + /// serializer.serialize_newtype_struct("Millimeters", &self.0) + /// } + /// } + /// ``` + fn serialize_newtype_struct( + self, + name: &'static str, + value: &T, + ) -> Result + where + T: ?Sized + Serialize; + + /// Serialize a newtype variant like `E::N` in `enum E { N(u8) }`. + /// + /// The `name` is the name of the enum, the `variant_index` is the index of + /// this variant within the enum, and the `variant` is the name of the + /// variant. The `value` is the data contained within this newtype variant. + /// + /// ```edition2021 + /// use serde::{Serialize, Serializer}; + /// + /// enum E { + /// M(String), + /// N(u8), + /// } + /// + /// impl Serialize for E { + /// fn serialize(&self, serializer: S) -> Result + /// where + /// S: Serializer, + /// { + /// match *self { + /// E::M(ref s) => serializer.serialize_newtype_variant("E", 0, "M", s), + /// E::N(n) => serializer.serialize_newtype_variant("E", 1, "N", &n), + /// } + /// } + /// } + /// ``` + fn serialize_newtype_variant( + self, + name: &'static str, + variant_index: u32, + variant: &'static str, + value: &T, + ) -> Result + where + T: ?Sized + Serialize; + + /// Begin to serialize a variably sized sequence. This call must be + /// followed by zero or more calls to `serialize_element`, then a call to + /// `end`. + /// + /// The argument is the number of elements in the sequence, which may or may + /// not be computable before the sequence is iterated. Some serializers only + /// support sequences whose length is known up front. + /// + /// ```edition2021 + /// # use std::marker::PhantomData; + /// # + /// # struct Vec(PhantomData); + /// # + /// # impl Vec { + /// # fn len(&self) -> usize { + /// # unimplemented!() + /// # } + /// # } + /// # + /// # impl<'a, T> IntoIterator for &'a Vec { + /// # type Item = &'a T; + /// # type IntoIter = Box>; + /// # + /// # fn into_iter(self) -> Self::IntoIter { + /// # unimplemented!() + /// # } + /// # } + /// # + /// use serde::ser::{Serialize, SerializeSeq, Serializer}; + /// + /// impl Serialize for Vec + /// where + /// T: Serialize, + /// { + /// fn serialize(&self, serializer: S) -> Result + /// where + /// S: Serializer, + /// { + /// let mut seq = serializer.serialize_seq(Some(self.len()))?; + /// for element in self { + /// seq.serialize_element(element)?; + /// } + /// seq.end() + /// } + /// } + /// ``` + fn serialize_seq(self, len: Option) -> Result; + + /// Begin to serialize a statically sized sequence whose length will be + /// known at deserialization time without looking at the serialized data. + /// This call must be followed by zero or more calls to `serialize_element`, + /// then a call to `end`. + /// + /// ```edition2021 + /// use serde::ser::{Serialize, SerializeTuple, Serializer}; + /// + /// # mod fool { + /// # trait Serialize {} + /// impl Serialize for (A, B, C) + /// # {} + /// # } + /// # + /// # struct Tuple3(A, B, C); + /// # + /// # impl Serialize for Tuple3 + /// where + /// A: Serialize, + /// B: Serialize, + /// C: Serialize, + /// { + /// fn serialize(&self, serializer: S) -> Result + /// where + /// S: Serializer, + /// { + /// let mut tup = serializer.serialize_tuple(3)?; + /// tup.serialize_element(&self.0)?; + /// tup.serialize_element(&self.1)?; + /// tup.serialize_element(&self.2)?; + /// tup.end() + /// } + /// } + /// ``` + /// + /// ```edition2021 + /// use serde::ser::{Serialize, SerializeTuple, Serializer}; + /// + /// const VRAM_SIZE: usize = 386; + /// struct Vram([u16; VRAM_SIZE]); + /// + /// impl Serialize for Vram { + /// fn serialize(&self, serializer: S) -> Result + /// where + /// S: Serializer, + /// { + /// let mut seq = serializer.serialize_tuple(VRAM_SIZE)?; + /// for element in &self.0[..] { + /// seq.serialize_element(element)?; + /// } + /// seq.end() + /// } + /// } + /// ``` + fn serialize_tuple(self, len: usize) -> Result; + + /// Begin to serialize a tuple struct like `struct Rgb(u8, u8, u8)`. This + /// call must be followed by zero or more calls to `serialize_field`, then a + /// call to `end`. + /// + /// The `name` is the name of the tuple struct and the `len` is the number + /// of data fields that will be serialized. + /// + /// ```edition2021 + /// use serde::ser::{Serialize, SerializeTupleStruct, Serializer}; + /// + /// struct Rgb(u8, u8, u8); + /// + /// impl Serialize for Rgb { + /// fn serialize(&self, serializer: S) -> Result + /// where + /// S: Serializer, + /// { + /// let mut ts = serializer.serialize_tuple_struct("Rgb", 3)?; + /// ts.serialize_field(&self.0)?; + /// ts.serialize_field(&self.1)?; + /// ts.serialize_field(&self.2)?; + /// ts.end() + /// } + /// } + /// ``` + fn serialize_tuple_struct( + self, + name: &'static str, + len: usize, + ) -> Result; + + /// Begin to serialize a tuple variant like `E::T` in `enum E { T(u8, u8) + /// }`. This call must be followed by zero or more calls to + /// `serialize_field`, then a call to `end`. + /// + /// The `name` is the name of the enum, the `variant_index` is the index of + /// this variant within the enum, the `variant` is the name of the variant, + /// and the `len` is the number of data fields that will be serialized. + /// + /// ```edition2021 + /// use serde::ser::{Serialize, SerializeTupleVariant, Serializer}; + /// + /// enum E { + /// T(u8, u8), + /// U(String, u32, u32), + /// } + /// + /// impl Serialize for E { + /// fn serialize(&self, serializer: S) -> Result + /// where + /// S: Serializer, + /// { + /// match *self { + /// E::T(ref a, ref b) => { + /// let mut tv = serializer.serialize_tuple_variant("E", 0, "T", 2)?; + /// tv.serialize_field(a)?; + /// tv.serialize_field(b)?; + /// tv.end() + /// } + /// E::U(ref a, ref b, ref c) => { + /// let mut tv = serializer.serialize_tuple_variant("E", 1, "U", 3)?; + /// tv.serialize_field(a)?; + /// tv.serialize_field(b)?; + /// tv.serialize_field(c)?; + /// tv.end() + /// } + /// } + /// } + /// } + /// ``` + fn serialize_tuple_variant( + self, + name: &'static str, + variant_index: u32, + variant: &'static str, + len: usize, + ) -> Result; + + /// Begin to serialize a map. This call must be followed by zero or more + /// calls to `serialize_key` and `serialize_value`, then a call to `end`. + /// + /// The argument is the number of elements in the map, which may or may not + /// be computable before the map is iterated. Some serializers only support + /// maps whose length is known up front. + /// + /// ```edition2021 + /// # use std::marker::PhantomData; + /// # + /// # struct HashMap(PhantomData, PhantomData); + /// # + /// # impl HashMap { + /// # fn len(&self) -> usize { + /// # unimplemented!() + /// # } + /// # } + /// # + /// # impl<'a, K, V> IntoIterator for &'a HashMap { + /// # type Item = (&'a K, &'a V); + /// # type IntoIter = Box>; + /// # + /// # fn into_iter(self) -> Self::IntoIter { + /// # unimplemented!() + /// # } + /// # } + /// # + /// use serde::ser::{Serialize, SerializeMap, Serializer}; + /// + /// impl Serialize for HashMap + /// where + /// K: Serialize, + /// V: Serialize, + /// { + /// fn serialize(&self, serializer: S) -> Result + /// where + /// S: Serializer, + /// { + /// let mut map = serializer.serialize_map(Some(self.len()))?; + /// for (k, v) in self { + /// map.serialize_entry(k, v)?; + /// } + /// map.end() + /// } + /// } + /// ``` + fn serialize_map(self, len: Option) -> Result; + + /// Begin to serialize a struct like `struct Rgb { r: u8, g: u8, b: u8 }`. + /// This call must be followed by zero or more calls to `serialize_field`, + /// then a call to `end`. + /// + /// The `name` is the name of the struct and the `len` is the number of + /// data fields that will be serialized. `len` does not include fields + /// which are skipped with [`SerializeStruct::skip_field`]. + /// + /// ```edition2021 + /// use serde::ser::{Serialize, SerializeStruct, Serializer}; + /// + /// struct Rgb { + /// r: u8, + /// g: u8, + /// b: u8, + /// } + /// + /// impl Serialize for Rgb { + /// fn serialize(&self, serializer: S) -> Result + /// where + /// S: Serializer, + /// { + /// let mut rgb = serializer.serialize_struct("Rgb", 3)?; + /// rgb.serialize_field("r", &self.r)?; + /// rgb.serialize_field("g", &self.g)?; + /// rgb.serialize_field("b", &self.b)?; + /// rgb.end() + /// } + /// } + /// ``` + fn serialize_struct( + self, + name: &'static str, + len: usize, + ) -> Result; + + /// Begin to serialize a struct variant like `E::S` in `enum E { S { r: u8, + /// g: u8, b: u8 } }`. This call must be followed by zero or more calls to + /// `serialize_field`, then a call to `end`. + /// + /// The `name` is the name of the enum, the `variant_index` is the index of + /// this variant within the enum, the `variant` is the name of the variant, + /// and the `len` is the number of data fields that will be serialized. + /// `len` does not include fields which are skipped with + /// [`SerializeStructVariant::skip_field`]. + /// + /// ```edition2021 + /// use serde::ser::{Serialize, SerializeStructVariant, Serializer}; + /// + /// enum E { + /// S { r: u8, g: u8, b: u8 }, + /// } + /// + /// impl Serialize for E { + /// fn serialize(&self, serializer: S) -> Result + /// where + /// S: Serializer, + /// { + /// match *self { + /// E::S { + /// ref r, + /// ref g, + /// ref b, + /// } => { + /// let mut sv = serializer.serialize_struct_variant("E", 0, "S", 3)?; + /// sv.serialize_field("r", r)?; + /// sv.serialize_field("g", g)?; + /// sv.serialize_field("b", b)?; + /// sv.end() + /// } + /// } + /// } + /// } + /// ``` + fn serialize_struct_variant( + self, + name: &'static str, + variant_index: u32, + variant: &'static str, + len: usize, + ) -> Result; + + /// Collect an iterator as a sequence. + /// + /// The default implementation serializes each item yielded by the iterator + /// using [`serialize_seq`]. Implementors should not need to override this + /// method. + /// + /// ```edition2021 + /// use serde::{Serialize, Serializer}; + /// + /// struct SecretlyOneHigher { + /// data: Vec, + /// } + /// + /// impl Serialize for SecretlyOneHigher { + /// fn serialize(&self, serializer: S) -> Result + /// where + /// S: Serializer, + /// { + /// serializer.collect_seq(self.data.iter().map(|x| x + 1)) + /// } + /// } + /// ``` + /// + /// [`serialize_seq`]: #tymethod.serialize_seq + fn collect_seq(self, iter: I) -> Result + where + I: IntoIterator, + ::Item: Serialize, + { + let mut iter = iter.into_iter(); + let mut serializer = tri!(self.serialize_seq(iterator_len_hint(&iter))); + tri!(iter.try_for_each(|item| serializer.serialize_element(&item))); + serializer.end() + } + + /// Collect an iterator as a map. + /// + /// The default implementation serializes each pair yielded by the iterator + /// using [`serialize_map`]. Implementors should not need to override this + /// method. + /// + /// ```edition2021 + /// use serde::{Serialize, Serializer}; + /// use std::collections::BTreeSet; + /// + /// struct MapToUnit { + /// keys: BTreeSet, + /// } + /// + /// // Serializes as a map in which the values are all unit. + /// impl Serialize for MapToUnit { + /// fn serialize(&self, serializer: S) -> Result + /// where + /// S: Serializer, + /// { + /// serializer.collect_map(self.keys.iter().map(|k| (k, ()))) + /// } + /// } + /// ``` + /// + /// [`serialize_map`]: #tymethod.serialize_map + fn collect_map(self, iter: I) -> Result + where + K: Serialize, + V: Serialize, + I: IntoIterator, + { + let mut iter = iter.into_iter(); + let mut serializer = tri!(self.serialize_map(iterator_len_hint(&iter))); + tri!(iter.try_for_each(|(key, value)| serializer.serialize_entry(&key, &value))); + serializer.end() + } + + /// Serialize a string produced by an implementation of `Display`. + /// + /// The default implementation builds a heap-allocated [`String`] and + /// delegates to [`serialize_str`]. Serializers are encouraged to provide a + /// more efficient implementation if possible. + /// + /// ```edition2021 + /// # struct DateTime; + /// # + /// # impl DateTime { + /// # fn naive_local(&self) -> () { () } + /// # fn offset(&self) -> () { () } + /// # } + /// # + /// use serde::{Serialize, Serializer}; + /// + /// impl Serialize for DateTime { + /// fn serialize(&self, serializer: S) -> Result + /// where + /// S: Serializer, + /// { + /// serializer.collect_str(&format_args!("{:?}{:?}", self.naive_local(), self.offset())) + /// } + /// } + /// ``` + /// + /// [`String`]: https://doc.rust-lang.org/std/string/struct.String.html + /// [`serialize_str`]: #tymethod.serialize_str + #[cfg(any(feature = "std", feature = "alloc"))] + fn collect_str(self, value: &T) -> Result + where + T: ?Sized + Display, + { + self.serialize_str(&value.to_string()) + } + + /// Serialize a string produced by an implementation of `Display`. + /// + /// Serializers that use `no_std` are required to provide an implementation + /// of this method. If no more sensible behavior is possible, the + /// implementation is expected to return an error. + /// + /// ```edition2021 + /// # struct DateTime; + /// # + /// # impl DateTime { + /// # fn naive_local(&self) -> () { () } + /// # fn offset(&self) -> () { () } + /// # } + /// # + /// use serde::{Serialize, Serializer}; + /// + /// impl Serialize for DateTime { + /// fn serialize(&self, serializer: S) -> Result + /// where + /// S: Serializer, + /// { + /// serializer.collect_str(&format_args!("{:?}{:?}", self.naive_local(), self.offset())) + /// } + /// } + /// ``` + #[cfg(not(any(feature = "std", feature = "alloc")))] + fn collect_str(self, value: &T) -> Result + where + T: ?Sized + Display; + + /// Determine whether `Serialize` implementations should serialize in + /// human-readable form. + /// + /// Some types have a human-readable form that may be somewhat expensive to + /// construct, as well as a binary form that is compact and efficient. + /// Generally text-based formats like JSON and YAML will prefer to use the + /// human-readable one and binary formats like Postcard will prefer the + /// compact one. + /// + /// ```edition2021 + /// # use std::fmt::{self, Display}; + /// # + /// # struct Timestamp; + /// # + /// # impl Timestamp { + /// # fn seconds_since_epoch(&self) -> u64 { unimplemented!() } + /// # } + /// # + /// # impl Display for Timestamp { + /// # fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + /// # unimplemented!() + /// # } + /// # } + /// # + /// use serde::{Serialize, Serializer}; + /// + /// impl Serialize for Timestamp { + /// fn serialize(&self, serializer: S) -> Result + /// where + /// S: Serializer, + /// { + /// if serializer.is_human_readable() { + /// // Serialize to a human-readable string "2015-05-15T17:01:00Z". + /// self.to_string().serialize(serializer) + /// } else { + /// // Serialize to a compact binary representation. + /// self.seconds_since_epoch().serialize(serializer) + /// } + /// } + /// } + /// ``` + /// + /// The default implementation of this method returns `true`. Data formats + /// may override this to `false` to request a compact form for types that + /// support one. Note that modifying this method to change a format from + /// human-readable to compact or vice versa should be regarded as a breaking + /// change, as a value serialized in human-readable mode is not required to + /// deserialize from the same data in compact mode. + #[inline] + fn is_human_readable(&self) -> bool { + true + } +} + +/// Returned from `Serializer::serialize_seq`. +/// +/// # Example use +/// +/// ```edition2021 +/// # use std::marker::PhantomData; +/// # +/// # struct Vec(PhantomData); +/// # +/// # impl Vec { +/// # fn len(&self) -> usize { +/// # unimplemented!() +/// # } +/// # } +/// # +/// # impl<'a, T> IntoIterator for &'a Vec { +/// # type Item = &'a T; +/// # type IntoIter = Box>; +/// # fn into_iter(self) -> Self::IntoIter { +/// # unimplemented!() +/// # } +/// # } +/// # +/// use serde::ser::{Serialize, SerializeSeq, Serializer}; +/// +/// impl Serialize for Vec +/// where +/// T: Serialize, +/// { +/// fn serialize(&self, serializer: S) -> Result +/// where +/// S: Serializer, +/// { +/// let mut seq = serializer.serialize_seq(Some(self.len()))?; +/// for element in self { +/// seq.serialize_element(element)?; +/// } +/// seq.end() +/// } +/// } +/// ``` +/// +/// # Example implementation +/// +/// The [example data format] presented on the website demonstrates an +/// implementation of `SerializeSeq` for a basic JSON data format. +/// +/// [example data format]: https://serde.rs/data-format.html +pub trait SerializeSeq { + /// Must match the `Ok` type of our `Serializer`. + type Ok; + + /// Must match the `Error` type of our `Serializer`. + type Error: Error; + + /// Serialize a sequence element. + fn serialize_element(&mut self, value: &T) -> Result<(), Self::Error> + where + T: ?Sized + Serialize; + + /// Finish serializing a sequence. + fn end(self) -> Result; +} + +/// Returned from `Serializer::serialize_tuple`. +/// +/// # Example use +/// +/// ```edition2021 +/// use serde::ser::{Serialize, SerializeTuple, Serializer}; +/// +/// # mod fool { +/// # trait Serialize {} +/// impl Serialize for (A, B, C) +/// # {} +/// # } +/// # +/// # struct Tuple3(A, B, C); +/// # +/// # impl Serialize for Tuple3 +/// where +/// A: Serialize, +/// B: Serialize, +/// C: Serialize, +/// { +/// fn serialize(&self, serializer: S) -> Result +/// where +/// S: Serializer, +/// { +/// let mut tup = serializer.serialize_tuple(3)?; +/// tup.serialize_element(&self.0)?; +/// tup.serialize_element(&self.1)?; +/// tup.serialize_element(&self.2)?; +/// tup.end() +/// } +/// } +/// ``` +/// +/// ```edition2021 +/// # use std::marker::PhantomData; +/// # +/// # struct Array(PhantomData); +/// # +/// # impl Array { +/// # fn len(&self) -> usize { +/// # unimplemented!() +/// # } +/// # } +/// # +/// # impl<'a, T> IntoIterator for &'a Array { +/// # type Item = &'a T; +/// # type IntoIter = Box>; +/// # fn into_iter(self) -> Self::IntoIter { +/// # unimplemented!() +/// # } +/// # } +/// # +/// use serde::ser::{Serialize, SerializeTuple, Serializer}; +/// +/// # mod fool { +/// # trait Serialize {} +/// impl Serialize for [T; 16] +/// # {} +/// # } +/// # +/// # impl Serialize for Array +/// where +/// T: Serialize, +/// { +/// fn serialize(&self, serializer: S) -> Result +/// where +/// S: Serializer, +/// { +/// let mut seq = serializer.serialize_tuple(16)?; +/// for element in self { +/// seq.serialize_element(element)?; +/// } +/// seq.end() +/// } +/// } +/// ``` +/// +/// # Example implementation +/// +/// The [example data format] presented on the website demonstrates an +/// implementation of `SerializeTuple` for a basic JSON data format. +/// +/// [example data format]: https://serde.rs/data-format.html +pub trait SerializeTuple { + /// Must match the `Ok` type of our `Serializer`. + type Ok; + + /// Must match the `Error` type of our `Serializer`. + type Error: Error; + + /// Serialize a tuple element. + fn serialize_element(&mut self, value: &T) -> Result<(), Self::Error> + where + T: ?Sized + Serialize; + + /// Finish serializing a tuple. + fn end(self) -> Result; +} + +/// Returned from `Serializer::serialize_tuple_struct`. +/// +/// # Example use +/// +/// ```edition2021 +/// use serde::ser::{Serialize, SerializeTupleStruct, Serializer}; +/// +/// struct Rgb(u8, u8, u8); +/// +/// impl Serialize for Rgb { +/// fn serialize(&self, serializer: S) -> Result +/// where +/// S: Serializer, +/// { +/// let mut ts = serializer.serialize_tuple_struct("Rgb", 3)?; +/// ts.serialize_field(&self.0)?; +/// ts.serialize_field(&self.1)?; +/// ts.serialize_field(&self.2)?; +/// ts.end() +/// } +/// } +/// ``` +/// +/// # Example implementation +/// +/// The [example data format] presented on the website demonstrates an +/// implementation of `SerializeTupleStruct` for a basic JSON data format. +/// +/// [example data format]: https://serde.rs/data-format.html +pub trait SerializeTupleStruct { + /// Must match the `Ok` type of our `Serializer`. + type Ok; + + /// Must match the `Error` type of our `Serializer`. + type Error: Error; + + /// Serialize a tuple struct field. + fn serialize_field(&mut self, value: &T) -> Result<(), Self::Error> + where + T: ?Sized + Serialize; + + /// Finish serializing a tuple struct. + fn end(self) -> Result; +} + +/// Returned from `Serializer::serialize_tuple_variant`. +/// +/// # Example use +/// +/// ```edition2021 +/// use serde::ser::{Serialize, SerializeTupleVariant, Serializer}; +/// +/// enum E { +/// T(u8, u8), +/// U(String, u32, u32), +/// } +/// +/// impl Serialize for E { +/// fn serialize(&self, serializer: S) -> Result +/// where +/// S: Serializer, +/// { +/// match *self { +/// E::T(ref a, ref b) => { +/// let mut tv = serializer.serialize_tuple_variant("E", 0, "T", 2)?; +/// tv.serialize_field(a)?; +/// tv.serialize_field(b)?; +/// tv.end() +/// } +/// E::U(ref a, ref b, ref c) => { +/// let mut tv = serializer.serialize_tuple_variant("E", 1, "U", 3)?; +/// tv.serialize_field(a)?; +/// tv.serialize_field(b)?; +/// tv.serialize_field(c)?; +/// tv.end() +/// } +/// } +/// } +/// } +/// ``` +/// +/// # Example implementation +/// +/// The [example data format] presented on the website demonstrates an +/// implementation of `SerializeTupleVariant` for a basic JSON data format. +/// +/// [example data format]: https://serde.rs/data-format.html +pub trait SerializeTupleVariant { + /// Must match the `Ok` type of our `Serializer`. + type Ok; + + /// Must match the `Error` type of our `Serializer`. + type Error: Error; + + /// Serialize a tuple variant field. + fn serialize_field(&mut self, value: &T) -> Result<(), Self::Error> + where + T: ?Sized + Serialize; + + /// Finish serializing a tuple variant. + fn end(self) -> Result; +} + +/// Returned from `Serializer::serialize_map`. +/// +/// # Example use +/// +/// ```edition2021 +/// # use std::marker::PhantomData; +/// # +/// # struct HashMap(PhantomData, PhantomData); +/// # +/// # impl HashMap { +/// # fn len(&self) -> usize { +/// # unimplemented!() +/// # } +/// # } +/// # +/// # impl<'a, K, V> IntoIterator for &'a HashMap { +/// # type Item = (&'a K, &'a V); +/// # type IntoIter = Box>; +/// # +/// # fn into_iter(self) -> Self::IntoIter { +/// # unimplemented!() +/// # } +/// # } +/// # +/// use serde::ser::{Serialize, SerializeMap, Serializer}; +/// +/// impl Serialize for HashMap +/// where +/// K: Serialize, +/// V: Serialize, +/// { +/// fn serialize(&self, serializer: S) -> Result +/// where +/// S: Serializer, +/// { +/// let mut map = serializer.serialize_map(Some(self.len()))?; +/// for (k, v) in self { +/// map.serialize_entry(k, v)?; +/// } +/// map.end() +/// } +/// } +/// ``` +/// +/// # Example implementation +/// +/// The [example data format] presented on the website demonstrates an +/// implementation of `SerializeMap` for a basic JSON data format. +/// +/// [example data format]: https://serde.rs/data-format.html +pub trait SerializeMap { + /// Must match the `Ok` type of our `Serializer`. + type Ok; + + /// Must match the `Error` type of our `Serializer`. + type Error: Error; + + /// Serialize a map key. + /// + /// If possible, `Serialize` implementations are encouraged to use + /// `serialize_entry` instead as it may be implemented more efficiently in + /// some formats compared to a pair of calls to `serialize_key` and + /// `serialize_value`. + fn serialize_key(&mut self, key: &T) -> Result<(), Self::Error> + where + T: ?Sized + Serialize; + + /// Serialize a map value. + /// + /// # Panics + /// + /// Calling `serialize_value` before `serialize_key` is incorrect and is + /// allowed to panic or produce bogus results. + fn serialize_value(&mut self, value: &T) -> Result<(), Self::Error> + where + T: ?Sized + Serialize; + + /// Serialize a map entry consisting of a key and a value. + /// + /// Some [`Serialize`] types are not able to hold a key and value in memory + /// at the same time so `SerializeMap` implementations are required to + /// support [`serialize_key`] and [`serialize_value`] individually. The + /// `serialize_entry` method allows serializers to optimize for the case + /// where key and value are both available. [`Serialize`] implementations + /// are encouraged to use `serialize_entry` if possible. + /// + /// The default implementation delegates to [`serialize_key`] and + /// [`serialize_value`]. This is appropriate for serializers that do not + /// care about performance or are not able to optimize `serialize_entry` any + /// better than this. + /// + /// [`Serialize`]: ../trait.Serialize.html + /// [`serialize_key`]: #tymethod.serialize_key + /// [`serialize_value`]: #tymethod.serialize_value + fn serialize_entry(&mut self, key: &K, value: &V) -> Result<(), Self::Error> + where + K: ?Sized + Serialize, + V: ?Sized + Serialize, + { + tri!(self.serialize_key(key)); + self.serialize_value(value) + } + + /// Finish serializing a map. + fn end(self) -> Result; +} + +/// Returned from `Serializer::serialize_struct`. +/// +/// # Example use +/// +/// ```edition2021 +/// use serde::ser::{Serialize, SerializeStruct, Serializer}; +/// +/// struct Rgb { +/// r: u8, +/// g: u8, +/// b: u8, +/// } +/// +/// impl Serialize for Rgb { +/// fn serialize(&self, serializer: S) -> Result +/// where +/// S: Serializer, +/// { +/// let mut rgb = serializer.serialize_struct("Rgb", 3)?; +/// rgb.serialize_field("r", &self.r)?; +/// rgb.serialize_field("g", &self.g)?; +/// rgb.serialize_field("b", &self.b)?; +/// rgb.end() +/// } +/// } +/// ``` +/// +/// # Example implementation +/// +/// The [example data format] presented on the website demonstrates an +/// implementation of `SerializeStruct` for a basic JSON data format. +/// +/// [example data format]: https://serde.rs/data-format.html +pub trait SerializeStruct { + /// Must match the `Ok` type of our `Serializer`. + type Ok; + + /// Must match the `Error` type of our `Serializer`. + type Error: Error; + + /// Serialize a struct field. + fn serialize_field(&mut self, key: &'static str, value: &T) -> Result<(), Self::Error> + where + T: ?Sized + Serialize; + + /// Indicate that a struct field has been skipped. + /// + /// The default implementation does nothing. + #[inline] + fn skip_field(&mut self, key: &'static str) -> Result<(), Self::Error> { + let _ = key; + Ok(()) + } + + /// Finish serializing a struct. + fn end(self) -> Result; +} + +/// Returned from `Serializer::serialize_struct_variant`. +/// +/// # Example use +/// +/// ```edition2021 +/// use serde::ser::{Serialize, SerializeStructVariant, Serializer}; +/// +/// enum E { +/// S { r: u8, g: u8, b: u8 }, +/// } +/// +/// impl Serialize for E { +/// fn serialize(&self, serializer: S) -> Result +/// where +/// S: Serializer, +/// { +/// match *self { +/// E::S { +/// ref r, +/// ref g, +/// ref b, +/// } => { +/// let mut sv = serializer.serialize_struct_variant("E", 0, "S", 3)?; +/// sv.serialize_field("r", r)?; +/// sv.serialize_field("g", g)?; +/// sv.serialize_field("b", b)?; +/// sv.end() +/// } +/// } +/// } +/// } +/// ``` +/// +/// # Example implementation +/// +/// The [example data format] presented on the website demonstrates an +/// implementation of `SerializeStructVariant` for a basic JSON data format. +/// +/// [example data format]: https://serde.rs/data-format.html +pub trait SerializeStructVariant { + /// Must match the `Ok` type of our `Serializer`. + type Ok; + + /// Must match the `Error` type of our `Serializer`. + type Error: Error; + + /// Serialize a struct variant field. + fn serialize_field(&mut self, key: &'static str, value: &T) -> Result<(), Self::Error> + where + T: ?Sized + Serialize; + + /// Indicate that a struct variant field has been skipped. + /// + /// The default implementation does nothing. + #[inline] + fn skip_field(&mut self, key: &'static str) -> Result<(), Self::Error> { + let _ = key; + Ok(()) + } + + /// Finish serializing a struct variant. + fn end(self) -> Result; +} + +fn iterator_len_hint(iter: &I) -> Option +where + I: Iterator, +{ + match iter.size_hint() { + (lo, Some(hi)) if lo == hi => Some(lo), + _ => None, + } +} diff --git a/vendor/serde/src/std_error.rs b/vendor/serde/src/std_error.rs new file mode 100644 index 0000000..f15a4d7 --- /dev/null +++ b/vendor/serde/src/std_error.rs @@ -0,0 +1,48 @@ +use crate::lib::{Debug, Display}; + +/// Either a re-export of std::error::Error or a new identical trait, depending +/// on whether Serde's "std" feature is enabled. +/// +/// Serde's error traits [`serde::ser::Error`] and [`serde::de::Error`] require +/// [`std::error::Error`] as a supertrait, but only when Serde is built with +/// "std" enabled. Data formats that don't care about no\_std support should +/// generally provide their error types with a `std::error::Error` impl +/// directly: +/// +/// ```edition2021 +/// #[derive(Debug)] +/// struct MySerError {...} +/// +/// impl serde::ser::Error for MySerError {...} +/// +/// impl std::fmt::Display for MySerError {...} +/// +/// // We don't support no_std! +/// impl std::error::Error for MySerError {} +/// ``` +/// +/// Data formats that *do* support no\_std may either have a "std" feature of +/// their own: +/// +/// ```toml +/// [features] +/// std = ["serde/std"] +/// ``` +/// +/// ```edition2021 +/// #[cfg(feature = "std")] +/// impl std::error::Error for MySerError {} +/// ``` +/// +/// ... or else provide the std Error impl unconditionally via Serde's +/// re-export: +/// +/// ```edition2021 +/// impl serde::ser::StdError for MySerError {} +/// ``` +pub trait Error: Debug + Display { + /// The underlying cause of this error, if any. + fn source(&self) -> Option<&(Error + 'static)> { + None + } +} diff --git a/vendor/serde_derive/.cargo-checksum.json b/vendor/serde_derive/.cargo-checksum.json new file mode 100644 index 0000000..0927fc9 --- /dev/null +++ b/vendor/serde_derive/.cargo-checksum.json @@ -0,0 +1 @@ +{"files":{"Cargo.toml":"f02849531e614dd38ab37ad86c0e4f5bf16ede7becaa75ebbb6604170ea294e6","LICENSE-APACHE":"62c7a1e35f56406896d7aa7ca52d0cc0d272ac022b5d2796e7d6905db8a3636a","LICENSE-MIT":"23f18e03dc49df91622fe2a76176497404e46ced8a715d9d2b67a7446571cca3","README.md":"731c044fc5f98b37a89e9049c9214267db98763309cb63146b45c029640f82a3","crates-io.md":"407d92b2932923f8708aaf31db266fd7db32e2b0afa6c569d134b680b74a1920","src/bound.rs":"6c5c20785ac95af9480f8d0de35a7e844cc36a16012f6468db148acd03cb15c2","src/de.rs":"e0a2186fb31e24b95cdfc499b1adad295bb3eac0448a41fc37f7609cadda52c7","src/dummy.rs":"9533dfee23f20d92ea75734c739022820c2787ded0d54f459feacdeb770ec912","src/fragment.rs":"6757cb4c3131d4300f093572efc273c4ab5a20e3e1efb54a311dcfa52d0bd6eb","src/internals/ast.rs":"171478e83d203193cd96f2c9c922bd240214e05fdf76add73fb7e029784bace8","src/internals/attr.rs":"8ab89c54ec7713a16767971507733f6692eff1919fe7add6911b33c40dfc45a7","src/internals/case.rs":"10c8dda2b32d8c6c6b63cf09cdc63d02375af7e95ecefe8fecb34f93b65191bb","src/internals/check.rs":"d842eb9912fd29311060b67f3bc62c438eb7b5d86093355acb4de7eee02a0ef8","src/internals/ctxt.rs":"83a4e6fbe0e439d578478883594407e03f2f340541be479bdf0b04a202633a37","src/internals/mod.rs":"ed021ca635c18132a0e5c3d90f21b7f65def0a61e946421a30200b5b9ab6ad43","src/internals/receiver.rs":"710f875da3bad3e2a7fc1df40ab6805bb5e971b6a2a04c1b643b8a0aa29e8496","src/internals/respan.rs":"899753859c58ce5f532a3ec4584796a52f13ed5a0533191e48c953ba5c1b52ff","src/internals/symbol.rs":"d619e88caa3c7a09b03014257f2b349ee922290062d9b97b4dd19d0e64532690","src/lib.rs":"67d0a9e8509324573bf42467f98eb3d9e4e15da67410a3e23bb87bdbd742f5ed","src/pretend.rs":"7facc10a5b805564dd95735ae11118ec17ca6adcc49a59764e7c920e27b9fc4a","src/ser.rs":"120588172988a1078af4a090fbe6ffc2f9ba3ac6993f9baebea17cfe5ac6e7fa","src/this.rs":"87818dc80cbb521b51938a653d09daf10aafc220bb10425948de82ad670fcb85"},"package":"243902eda00fad750862fc144cea25caca5e20d615af0a81bee94ca738f1df1f"} \ No newline at end of file diff --git a/vendor/serde_derive/Cargo.toml b/vendor/serde_derive/Cargo.toml new file mode 100644 index 0000000..2bd5bb3 --- /dev/null +++ b/vendor/serde_derive/Cargo.toml @@ -0,0 +1,79 @@ +# 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] +edition = "2015" +rust-version = "1.56" +name = "serde_derive" +version = "1.0.210" +authors = [ + "Erick Tryzelaar ", + "David Tolnay ", +] +build = false +exclude = ["build.rs"] +autobins = false +autoexamples = false +autotests = false +autobenches = false +description = "Macros 1.1 implementation of #[derive(Serialize, Deserialize)]" +homepage = "https://serde.rs" +documentation = "https://serde.rs/derive.html" +readme = "crates-io.md" +keywords = [ + "serde", + "serialization", + "no_std", + "derive", +] +categories = [ + "no-std", + "no-std::no-alloc", +] +license = "MIT OR Apache-2.0" +repository = "https://github.com/serde-rs/serde" + +[package.metadata.docs.rs] +rustdoc-args = ["--generate-link-to-definition"] +targets = ["x86_64-unknown-linux-gnu"] + +[lib] +name = "serde_derive" +path = "src/lib.rs" +proc-macro = true + +[dependencies.proc-macro2] +version = "1.0.74" +features = ["proc-macro"] +default-features = false + +[dependencies.quote] +version = "1.0.35" +features = ["proc-macro"] +default-features = false + +[dependencies.syn] +version = "2.0.46" +features = [ + "clone-impls", + "derive", + "parsing", + "printing", + "proc-macro", +] +default-features = false + +[dev-dependencies.serde] +version = "1" + +[features] +default = [] +deserialize_in_place = [] diff --git a/vendor/serde_derive/LICENSE-APACHE b/vendor/serde_derive/LICENSE-APACHE new file mode 100644 index 0000000..1b5ec8b --- /dev/null +++ b/vendor/serde_derive/LICENSE-APACHE @@ -0,0 +1,176 @@ + 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 diff --git a/vendor/serde_derive/LICENSE-MIT b/vendor/serde_derive/LICENSE-MIT new file mode 100644 index 0000000..31aa793 --- /dev/null +++ b/vendor/serde_derive/LICENSE-MIT @@ -0,0 +1,23 @@ +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/serde_derive/README.md b/vendor/serde_derive/README.md new file mode 100644 index 0000000..3129294 --- /dev/null +++ b/vendor/serde_derive/README.md @@ -0,0 +1,114 @@ +# Serde   [![Build Status]][actions] [![Latest Version]][crates.io] [![serde msrv]][Rust 1.31] [![serde_derive msrv]][Rust 1.56] + +[Build Status]: https://img.shields.io/github/actions/workflow/status/serde-rs/serde/ci.yml?branch=master +[actions]: https://github.com/serde-rs/serde/actions?query=branch%3Amaster +[Latest Version]: https://img.shields.io/crates/v/serde.svg +[crates.io]: https://crates.io/crates/serde +[serde msrv]: https://img.shields.io/crates/msrv/serde.svg?label=serde%20msrv&color=lightgray +[serde_derive msrv]: https://img.shields.io/crates/msrv/serde_derive.svg?label=serde_derive%20msrv&color=lightgray +[Rust 1.31]: https://blog.rust-lang.org/2018/12/06/Rust-1.31-and-rust-2018.html +[Rust 1.56]: https://blog.rust-lang.org/2021/10/21/Rust-1.56.0.html + +**Serde is a framework for *ser*ializing and *de*serializing Rust data structures efficiently and generically.** + +--- + +You may be looking for: + +- [An overview of Serde](https://serde.rs/) +- [Data formats supported by Serde](https://serde.rs/#data-formats) +- [Setting up `#[derive(Serialize, Deserialize)]`](https://serde.rs/derive.html) +- [Examples](https://serde.rs/examples.html) +- [API documentation](https://docs.rs/serde) +- [Release notes](https://github.com/serde-rs/serde/releases) + +## Serde in action + + +

+ +```rust +use serde::{Deserialize, Serialize}; + +#[derive(Serialize, Deserialize, Debug)] +struct Point { + x: i32, + y: i32, +} + +fn main() { + let point = Point { x: 1, y: 2 }; + + // Convert the Point to a JSON string. + let serialized = serde_json::to_string(&point).unwrap(); + + // Prints serialized = {"x":1,"y":2} + println!("serialized = {}", serialized); + + // Convert the JSON string back to a Point. + let deserialized: Point = serde_json::from_str(&serialized).unwrap(); + + // Prints deserialized = Point { x: 1, y: 2 } + println!("deserialized = {:?}", deserialized); +} +``` + +## Getting help + +Serde is one of the most widely used Rust libraries so any place that Rustaceans +congregate will be able to help you out. For chat, consider trying the +[#rust-questions] or [#rust-beginners] channels of the unofficial community +Discord (invite: ), the [#rust-usage] or +[#beginners] channels of the official Rust Project Discord (invite: +), or the [#general][zulip] stream in Zulip. For +asynchronous, consider the [\[rust\] tag on StackOverflow][stackoverflow], the +[/r/rust] subreddit which has a pinned weekly easy questions post, or the Rust +[Discourse forum][discourse]. It's acceptable to file a support issue in this +repo but they tend not to get as many eyes as any of the above and may get +closed without a response after some time. + +[#rust-questions]: https://discord.com/channels/273534239310479360/274215136414400513 +[#rust-beginners]: https://discord.com/channels/273534239310479360/273541522815713281 +[#rust-usage]: https://discord.com/channels/442252698964721669/443150878111694848 +[#beginners]: https://discord.com/channels/442252698964721669/448238009733742612 +[zulip]: https://rust-lang.zulipchat.com/#narrow/stream/122651-general +[stackoverflow]: https://stackoverflow.com/questions/tagged/rust +[/r/rust]: https://www.reddit.com/r/rust +[discourse]: https://users.rust-lang.org + +
+ +#### License + + +Licensed under either of Apache License, Version +2.0 or MIT license at your option. + + +
+ + +Unless you explicitly state otherwise, any contribution intentionally submitted +for inclusion in Serde 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/serde_derive/crates-io.md b/vendor/serde_derive/crates-io.md new file mode 100644 index 0000000..b49a548 --- /dev/null +++ b/vendor/serde_derive/crates-io.md @@ -0,0 +1,65 @@ + + +**Serde is a framework for *ser*ializing and *de*serializing Rust data structures efficiently and generically.** + +--- + +You may be looking for: + +- [An overview of Serde](https://serde.rs/) +- [Data formats supported by Serde](https://serde.rs/#data-formats) +- [Setting up `#[derive(Serialize, Deserialize)]`](https://serde.rs/derive.html) +- [Examples](https://serde.rs/examples.html) +- [API documentation](https://docs.rs/serde) +- [Release notes](https://github.com/serde-rs/serde/releases) + +## Serde in action + +```rust +use serde::{Deserialize, Serialize}; + +#[derive(Serialize, Deserialize, Debug)] +struct Point { + x: i32, + y: i32, +} + +fn main() { + let point = Point { x: 1, y: 2 }; + + // Convert the Point to a JSON string. + let serialized = serde_json::to_string(&point).unwrap(); + + // Prints serialized = {"x":1,"y":2} + println!("serialized = {}", serialized); + + // Convert the JSON string back to a Point. + let deserialized: Point = serde_json::from_str(&serialized).unwrap(); + + // Prints deserialized = Point { x: 1, y: 2 } + println!("deserialized = {:?}", deserialized); +} +``` + +## Getting help + +Serde is one of the most widely used Rust libraries so any place that Rustaceans +congregate will be able to help you out. For chat, consider trying the +[#rust-questions] or [#rust-beginners] channels of the unofficial community +Discord (invite: ), the [#rust-usage] +or [#beginners] channels of the official Rust Project Discord (invite: +), or the [#general][zulip] stream in Zulip. For +asynchronous, consider the [\[rust\] tag on StackOverflow][stackoverflow], the +[/r/rust] subreddit which has a pinned weekly easy questions post, or the Rust +[Discourse forum][discourse]. It's acceptable to file a support issue in this +repo but they tend not to get as many eyes as any of the above and may get +closed without a response after some time. + +[#rust-questions]: https://discord.com/channels/273534239310479360/274215136414400513 +[#rust-beginners]: https://discord.com/channels/273534239310479360/273541522815713281 +[#rust-usage]: https://discord.com/channels/442252698964721669/443150878111694848 +[#beginners]: https://discord.com/channels/442252698964721669/448238009733742612 +[zulip]: https://rust-lang.zulipchat.com/#narrow/stream/122651-general +[stackoverflow]: https://stackoverflow.com/questions/tagged/rust +[/r/rust]: https://www.reddit.com/r/rust +[discourse]: https://users.rust-lang.org diff --git a/vendor/serde_derive/src/bound.rs b/vendor/serde_derive/src/bound.rs new file mode 100644 index 0000000..fe8ccff --- /dev/null +++ b/vendor/serde_derive/src/bound.rs @@ -0,0 +1,408 @@ +use crate::internals::ast::{Container, Data}; +use crate::internals::{attr, ungroup}; +use proc_macro2::Span; +use std::collections::HashSet; +use syn::punctuated::{Pair, Punctuated}; +use syn::Token; + +// Remove the default from every type parameter because in the generated impls +// they look like associated types: "error: associated type bindings are not +// allowed here". +pub fn without_defaults(generics: &syn::Generics) -> syn::Generics { + syn::Generics { + params: generics + .params + .iter() + .map(|param| match param { + syn::GenericParam::Type(param) => syn::GenericParam::Type(syn::TypeParam { + eq_token: None, + default: None, + ..param.clone() + }), + _ => param.clone(), + }) + .collect(), + ..generics.clone() + } +} + +pub fn with_where_predicates( + generics: &syn::Generics, + predicates: &[syn::WherePredicate], +) -> syn::Generics { + let mut generics = generics.clone(); + generics + .make_where_clause() + .predicates + .extend(predicates.iter().cloned()); + generics +} + +pub fn with_where_predicates_from_fields( + cont: &Container, + generics: &syn::Generics, + from_field: fn(&attr::Field) -> Option<&[syn::WherePredicate]>, +) -> syn::Generics { + let predicates = cont + .data + .all_fields() + .filter_map(|field| from_field(&field.attrs)) + .flat_map(<[syn::WherePredicate]>::to_vec); + + let mut generics = generics.clone(); + generics.make_where_clause().predicates.extend(predicates); + generics +} + +pub fn with_where_predicates_from_variants( + cont: &Container, + generics: &syn::Generics, + from_variant: fn(&attr::Variant) -> Option<&[syn::WherePredicate]>, +) -> syn::Generics { + let variants = match &cont.data { + Data::Enum(variants) => variants, + Data::Struct(_, _) => { + return generics.clone(); + } + }; + + let predicates = variants + .iter() + .filter_map(|variant| from_variant(&variant.attrs)) + .flat_map(<[syn::WherePredicate]>::to_vec); + + let mut generics = generics.clone(); + generics.make_where_clause().predicates.extend(predicates); + generics +} + +// Puts the given bound on any generic type parameters that are used in fields +// for which filter returns true. +// +// For example, the following struct needs the bound `A: Serialize, B: +// Serialize`. +// +// struct S<'b, A, B: 'b, C> { +// a: A, +// b: Option<&'b B> +// #[serde(skip_serializing)] +// c: C, +// } +pub fn with_bound( + cont: &Container, + generics: &syn::Generics, + filter: fn(&attr::Field, Option<&attr::Variant>) -> bool, + bound: &syn::Path, +) -> syn::Generics { + struct FindTyParams<'ast> { + // Set of all generic type parameters on the current struct (A, B, C in + // the example). Initialized up front. + all_type_params: HashSet, + + // Set of generic type parameters used in fields for which filter + // returns true (A and B in the example). Filled in as the visitor sees + // them. + relevant_type_params: HashSet, + + // Fields whose type is an associated type of one of the generic type + // parameters. + associated_type_usage: Vec<&'ast syn::TypePath>, + } + + impl<'ast> FindTyParams<'ast> { + fn visit_field(&mut self, field: &'ast syn::Field) { + if let syn::Type::Path(ty) = ungroup(&field.ty) { + if let Some(Pair::Punctuated(t, _)) = ty.path.segments.pairs().next() { + if self.all_type_params.contains(&t.ident) { + self.associated_type_usage.push(ty); + } + } + } + self.visit_type(&field.ty); + } + + fn visit_path(&mut self, path: &'ast syn::Path) { + if let Some(seg) = path.segments.last() { + if seg.ident == "PhantomData" { + // Hardcoded exception, because PhantomData implements + // Serialize and Deserialize whether or not T implements it. + return; + } + } + if path.leading_colon.is_none() && path.segments.len() == 1 { + let id = &path.segments[0].ident; + if self.all_type_params.contains(id) { + self.relevant_type_params.insert(id.clone()); + } + } + for segment in &path.segments { + self.visit_path_segment(segment); + } + } + + // Everything below is simply traversing the syntax tree. + + fn visit_type(&mut self, ty: &'ast syn::Type) { + match ty { + #![cfg_attr(all(test, exhaustive), deny(non_exhaustive_omitted_patterns))] + syn::Type::Array(ty) => self.visit_type(&ty.elem), + syn::Type::BareFn(ty) => { + for arg in &ty.inputs { + self.visit_type(&arg.ty); + } + self.visit_return_type(&ty.output); + } + syn::Type::Group(ty) => self.visit_type(&ty.elem), + syn::Type::ImplTrait(ty) => { + for bound in &ty.bounds { + self.visit_type_param_bound(bound); + } + } + syn::Type::Macro(ty) => self.visit_macro(&ty.mac), + syn::Type::Paren(ty) => self.visit_type(&ty.elem), + syn::Type::Path(ty) => { + if let Some(qself) = &ty.qself { + self.visit_type(&qself.ty); + } + self.visit_path(&ty.path); + } + syn::Type::Ptr(ty) => self.visit_type(&ty.elem), + syn::Type::Reference(ty) => self.visit_type(&ty.elem), + syn::Type::Slice(ty) => self.visit_type(&ty.elem), + syn::Type::TraitObject(ty) => { + for bound in &ty.bounds { + self.visit_type_param_bound(bound); + } + } + syn::Type::Tuple(ty) => { + for elem in &ty.elems { + self.visit_type(elem); + } + } + + syn::Type::Infer(_) | syn::Type::Never(_) | syn::Type::Verbatim(_) => {} + + _ => {} + } + } + + fn visit_path_segment(&mut self, segment: &'ast syn::PathSegment) { + self.visit_path_arguments(&segment.arguments); + } + + fn visit_path_arguments(&mut self, arguments: &'ast syn::PathArguments) { + match arguments { + syn::PathArguments::None => {} + syn::PathArguments::AngleBracketed(arguments) => { + for arg in &arguments.args { + match arg { + #![cfg_attr(all(test, exhaustive), deny(non_exhaustive_omitted_patterns))] + syn::GenericArgument::Type(arg) => self.visit_type(arg), + syn::GenericArgument::AssocType(arg) => self.visit_type(&arg.ty), + syn::GenericArgument::Lifetime(_) + | syn::GenericArgument::Const(_) + | syn::GenericArgument::AssocConst(_) + | syn::GenericArgument::Constraint(_) => {} + _ => {} + } + } + } + syn::PathArguments::Parenthesized(arguments) => { + for argument in &arguments.inputs { + self.visit_type(argument); + } + self.visit_return_type(&arguments.output); + } + } + } + + fn visit_return_type(&mut self, return_type: &'ast syn::ReturnType) { + match return_type { + syn::ReturnType::Default => {} + syn::ReturnType::Type(_, output) => self.visit_type(output), + } + } + + fn visit_type_param_bound(&mut self, bound: &'ast syn::TypeParamBound) { + match bound { + #![cfg_attr(all(test, exhaustive), deny(non_exhaustive_omitted_patterns))] + syn::TypeParamBound::Trait(bound) => self.visit_path(&bound.path), + syn::TypeParamBound::Lifetime(_) | syn::TypeParamBound::Verbatim(_) => {} + _ => {} + } + } + + // Type parameter should not be considered used by a macro path. + // + // struct TypeMacro { + // mac: T!(), + // marker: PhantomData, + // } + fn visit_macro(&mut self, _mac: &'ast syn::Macro) {} + } + + let all_type_params = generics + .type_params() + .map(|param| param.ident.clone()) + .collect(); + + let mut visitor = FindTyParams { + all_type_params, + relevant_type_params: HashSet::new(), + associated_type_usage: Vec::new(), + }; + match &cont.data { + Data::Enum(variants) => { + for variant in variants { + let relevant_fields = variant + .fields + .iter() + .filter(|field| filter(&field.attrs, Some(&variant.attrs))); + for field in relevant_fields { + visitor.visit_field(field.original); + } + } + } + Data::Struct(_, fields) => { + for field in fields.iter().filter(|field| filter(&field.attrs, None)) { + visitor.visit_field(field.original); + } + } + } + + let relevant_type_params = visitor.relevant_type_params; + let associated_type_usage = visitor.associated_type_usage; + let new_predicates = generics + .type_params() + .map(|param| param.ident.clone()) + .filter(|id| relevant_type_params.contains(id)) + .map(|id| syn::TypePath { + qself: None, + path: id.into(), + }) + .chain(associated_type_usage.into_iter().cloned()) + .map(|bounded_ty| { + syn::WherePredicate::Type(syn::PredicateType { + lifetimes: None, + // the type parameter that is being bounded e.g. T + bounded_ty: syn::Type::Path(bounded_ty), + colon_token: ::default(), + // the bound e.g. Serialize + bounds: vec![syn::TypeParamBound::Trait(syn::TraitBound { + paren_token: None, + modifier: syn::TraitBoundModifier::None, + lifetimes: None, + path: bound.clone(), + })] + .into_iter() + .collect(), + }) + }); + + let mut generics = generics.clone(); + generics + .make_where_clause() + .predicates + .extend(new_predicates); + generics +} + +pub fn with_self_bound( + cont: &Container, + generics: &syn::Generics, + bound: &syn::Path, +) -> syn::Generics { + let mut generics = generics.clone(); + generics + .make_where_clause() + .predicates + .push(syn::WherePredicate::Type(syn::PredicateType { + lifetimes: None, + // the type that is being bounded e.g. MyStruct<'a, T> + bounded_ty: type_of_item(cont), + colon_token: ::default(), + // the bound e.g. Default + bounds: vec![syn::TypeParamBound::Trait(syn::TraitBound { + paren_token: None, + modifier: syn::TraitBoundModifier::None, + lifetimes: None, + path: bound.clone(), + })] + .into_iter() + .collect(), + })); + generics +} + +pub fn with_lifetime_bound(generics: &syn::Generics, lifetime: &str) -> syn::Generics { + let bound = syn::Lifetime::new(lifetime, Span::call_site()); + let def = syn::LifetimeParam { + attrs: Vec::new(), + lifetime: bound.clone(), + colon_token: None, + bounds: Punctuated::new(), + }; + + let params = Some(syn::GenericParam::Lifetime(def)) + .into_iter() + .chain(generics.params.iter().cloned().map(|mut param| { + match &mut param { + syn::GenericParam::Lifetime(param) => { + param.bounds.push(bound.clone()); + } + syn::GenericParam::Type(param) => { + param + .bounds + .push(syn::TypeParamBound::Lifetime(bound.clone())); + } + syn::GenericParam::Const(_) => {} + } + param + })) + .collect(); + + syn::Generics { + params, + ..generics.clone() + } +} + +fn type_of_item(cont: &Container) -> syn::Type { + syn::Type::Path(syn::TypePath { + qself: None, + path: syn::Path { + leading_colon: None, + segments: vec![syn::PathSegment { + ident: cont.ident.clone(), + arguments: syn::PathArguments::AngleBracketed( + syn::AngleBracketedGenericArguments { + colon2_token: None, + lt_token: ::default(), + args: cont + .generics + .params + .iter() + .map(|param| match param { + syn::GenericParam::Type(param) => { + syn::GenericArgument::Type(syn::Type::Path(syn::TypePath { + qself: None, + path: param.ident.clone().into(), + })) + } + syn::GenericParam::Lifetime(param) => { + syn::GenericArgument::Lifetime(param.lifetime.clone()) + } + syn::GenericParam::Const(_) => { + panic!("Serde does not support const generics yet"); + } + }) + .collect(), + gt_token: ]>::default(), + }, + ), + }] + .into_iter() + .collect(), + }, + }) +} diff --git a/vendor/serde_derive/src/de.rs b/vendor/serde_derive/src/de.rs new file mode 100644 index 0000000..996e97e --- /dev/null +++ b/vendor/serde_derive/src/de.rs @@ -0,0 +1,3172 @@ +use crate::fragment::{Expr, Fragment, Match, Stmts}; +use crate::internals::ast::{Container, Data, Field, Style, Variant}; +use crate::internals::{attr, replace_receiver, ungroup, Ctxt, Derive}; +use crate::{bound, dummy, pretend, this}; +use proc_macro2::{Literal, Span, TokenStream}; +use quote::{quote, quote_spanned, ToTokens}; +use std::collections::BTreeSet; +use std::ptr; +use syn::punctuated::Punctuated; +use syn::spanned::Spanned; +use syn::{parse_quote, Ident, Index, Member}; + +pub fn expand_derive_deserialize(input: &mut syn::DeriveInput) -> syn::Result { + replace_receiver(input); + + let ctxt = Ctxt::new(); + let cont = match Container::from_ast(&ctxt, input, Derive::Deserialize) { + Some(cont) => cont, + None => return Err(ctxt.check().unwrap_err()), + }; + precondition(&ctxt, &cont); + ctxt.check()?; + + let ident = &cont.ident; + let params = Parameters::new(&cont); + let (de_impl_generics, _, ty_generics, where_clause) = split_with_de_lifetime(¶ms); + let body = Stmts(deserialize_body(&cont, ¶ms)); + let delife = params.borrowed.de_lifetime(); + let serde = cont.attrs.serde_path(); + + let impl_block = if let Some(remote) = cont.attrs.remote() { + let vis = &input.vis; + let used = pretend::pretend_used(&cont, params.is_packed); + quote! { + impl #de_impl_generics #ident #ty_generics #where_clause { + #vis fn deserialize<__D>(__deserializer: __D) -> #serde::__private::Result<#remote #ty_generics, __D::Error> + where + __D: #serde::Deserializer<#delife>, + { + #used + #body + } + } + } + } else { + let fn_deserialize_in_place = deserialize_in_place_body(&cont, ¶ms); + + quote! { + #[automatically_derived] + impl #de_impl_generics #serde::Deserialize<#delife> for #ident #ty_generics #where_clause { + fn deserialize<__D>(__deserializer: __D) -> #serde::__private::Result + where + __D: #serde::Deserializer<#delife>, + { + #body + } + + #fn_deserialize_in_place + } + } + }; + + Ok(dummy::wrap_in_const( + cont.attrs.custom_serde_path(), + impl_block, + )) +} + +fn precondition(cx: &Ctxt, cont: &Container) { + precondition_sized(cx, cont); + precondition_no_de_lifetime(cx, cont); +} + +fn precondition_sized(cx: &Ctxt, cont: &Container) { + if let Data::Struct(_, fields) = &cont.data { + if let Some(last) = fields.last() { + if let syn::Type::Slice(_) = ungroup(last.ty) { + cx.error_spanned_by( + cont.original, + "cannot deserialize a dynamically sized struct", + ); + } + } + } +} + +fn precondition_no_de_lifetime(cx: &Ctxt, cont: &Container) { + if let BorrowedLifetimes::Borrowed(_) = borrowed_lifetimes(cont) { + for param in cont.generics.lifetimes() { + if param.lifetime.to_string() == "'de" { + cx.error_spanned_by( + ¶m.lifetime, + "cannot deserialize when there is a lifetime parameter called 'de", + ); + return; + } + } + } +} + +struct Parameters { + /// Name of the type the `derive` is on. + local: syn::Ident, + + /// Path to the type the impl is for. Either a single `Ident` for local + /// types (does not include generic parameters) or `some::remote::Path` for + /// remote types. + this_type: syn::Path, + + /// Same as `this_type` but using `::` for generic parameters for use in + /// expression position. + this_value: syn::Path, + + /// Generics including any explicit and inferred bounds for the impl. + generics: syn::Generics, + + /// Lifetimes borrowed from the deserializer. These will become bounds on + /// the `'de` lifetime of the deserializer. + borrowed: BorrowedLifetimes, + + /// At least one field has a serde(getter) attribute, implying that the + /// remote type has a private field. + has_getter: bool, + + /// Type has a repr(packed) attribute. + is_packed: bool, +} + +impl Parameters { + fn new(cont: &Container) -> Self { + let local = cont.ident.clone(); + let this_type = this::this_type(cont); + let this_value = this::this_value(cont); + let borrowed = borrowed_lifetimes(cont); + let generics = build_generics(cont, &borrowed); + let has_getter = cont.data.has_getter(); + let is_packed = cont.attrs.is_packed(); + + Parameters { + local, + this_type, + this_value, + generics, + borrowed, + has_getter, + is_packed, + } + } + + /// Type name to use in error messages and `&'static str` arguments to + /// various Deserializer methods. + fn type_name(&self) -> String { + self.this_type.segments.last().unwrap().ident.to_string() + } +} + +// All the generics in the input, plus a bound `T: Deserialize` for each generic +// field type that will be deserialized by us, plus a bound `T: Default` for +// each generic field type that will be set to a default value. +fn build_generics(cont: &Container, borrowed: &BorrowedLifetimes) -> syn::Generics { + let generics = bound::without_defaults(cont.generics); + + let generics = bound::with_where_predicates_from_fields(cont, &generics, attr::Field::de_bound); + + let generics = + bound::with_where_predicates_from_variants(cont, &generics, attr::Variant::de_bound); + + match cont.attrs.de_bound() { + Some(predicates) => bound::with_where_predicates(&generics, predicates), + None => { + let generics = match *cont.attrs.default() { + attr::Default::Default => bound::with_self_bound( + cont, + &generics, + &parse_quote!(_serde::__private::Default), + ), + attr::Default::None | attr::Default::Path(_) => generics, + }; + + let delife = borrowed.de_lifetime(); + let generics = bound::with_bound( + cont, + &generics, + needs_deserialize_bound, + &parse_quote!(_serde::Deserialize<#delife>), + ); + + bound::with_bound( + cont, + &generics, + requires_default, + &parse_quote!(_serde::__private::Default), + ) + } + } +} + +// Fields with a `skip_deserializing` or `deserialize_with` attribute, or which +// belong to a variant with a `skip_deserializing` or `deserialize_with` +// attribute, are not deserialized by us so we do not generate a bound. Fields +// with a `bound` attribute specify their own bound so we do not generate one. +// All other fields may need a `T: Deserialize` bound where T is the type of the +// field. +fn needs_deserialize_bound(field: &attr::Field, variant: Option<&attr::Variant>) -> bool { + !field.skip_deserializing() + && field.deserialize_with().is_none() + && field.de_bound().is_none() + && variant.map_or(true, |variant| { + !variant.skip_deserializing() + && variant.deserialize_with().is_none() + && variant.de_bound().is_none() + }) +} + +// Fields with a `default` attribute (not `default=...`), and fields with a +// `skip_deserializing` attribute that do not also have `default=...`. +fn requires_default(field: &attr::Field, _variant: Option<&attr::Variant>) -> bool { + if let attr::Default::Default = *field.default() { + true + } else { + false + } +} + +enum BorrowedLifetimes { + Borrowed(BTreeSet), + Static, +} + +impl BorrowedLifetimes { + fn de_lifetime(&self) -> syn::Lifetime { + match *self { + BorrowedLifetimes::Borrowed(_) => syn::Lifetime::new("'de", Span::call_site()), + BorrowedLifetimes::Static => syn::Lifetime::new("'static", Span::call_site()), + } + } + + fn de_lifetime_param(&self) -> Option { + match self { + BorrowedLifetimes::Borrowed(bounds) => Some(syn::LifetimeParam { + attrs: Vec::new(), + lifetime: syn::Lifetime::new("'de", Span::call_site()), + colon_token: None, + bounds: bounds.iter().cloned().collect(), + }), + BorrowedLifetimes::Static => None, + } + } +} + +// The union of lifetimes borrowed by each field of the container. +// +// These turn into bounds on the `'de` lifetime of the Deserialize impl. If +// lifetimes `'a` and `'b` are borrowed but `'c` is not, the impl is: +// +// impl<'de: 'a + 'b, 'a, 'b, 'c> Deserialize<'de> for S<'a, 'b, 'c> +// +// If any borrowed lifetime is `'static`, then `'de: 'static` would be redundant +// and we use plain `'static` instead of `'de`. +fn borrowed_lifetimes(cont: &Container) -> BorrowedLifetimes { + let mut lifetimes = BTreeSet::new(); + for field in cont.data.all_fields() { + if !field.attrs.skip_deserializing() { + lifetimes.extend(field.attrs.borrowed_lifetimes().iter().cloned()); + } + } + if lifetimes.iter().any(|b| b.to_string() == "'static") { + BorrowedLifetimes::Static + } else { + BorrowedLifetimes::Borrowed(lifetimes) + } +} + +fn deserialize_body(cont: &Container, params: &Parameters) -> Fragment { + if cont.attrs.transparent() { + deserialize_transparent(cont, params) + } else if let Some(type_from) = cont.attrs.type_from() { + deserialize_from(type_from) + } else if let Some(type_try_from) = cont.attrs.type_try_from() { + deserialize_try_from(type_try_from) + } else if let attr::Identifier::No = cont.attrs.identifier() { + match &cont.data { + Data::Enum(variants) => deserialize_enum(params, variants, &cont.attrs), + Data::Struct(Style::Struct, fields) => { + deserialize_struct(params, fields, &cont.attrs, StructForm::Struct) + } + Data::Struct(Style::Tuple, fields) | Data::Struct(Style::Newtype, fields) => { + deserialize_tuple(params, fields, &cont.attrs, TupleForm::Tuple) + } + Data::Struct(Style::Unit, _) => deserialize_unit_struct(params, &cont.attrs), + } + } else { + match &cont.data { + Data::Enum(variants) => deserialize_custom_identifier(params, variants, &cont.attrs), + Data::Struct(_, _) => unreachable!("checked in serde_derive_internals"), + } + } +} + +#[cfg(feature = "deserialize_in_place")] +fn deserialize_in_place_body(cont: &Container, params: &Parameters) -> Option { + // Only remote derives have getters, and we do not generate + // deserialize_in_place for remote derives. + assert!(!params.has_getter); + + if cont.attrs.transparent() + || cont.attrs.type_from().is_some() + || cont.attrs.type_try_from().is_some() + || cont.attrs.identifier().is_some() + || cont + .data + .all_fields() + .all(|f| f.attrs.deserialize_with().is_some()) + { + return None; + } + + let code = match &cont.data { + Data::Struct(Style::Struct, fields) => { + deserialize_struct_in_place(params, fields, &cont.attrs)? + } + Data::Struct(Style::Tuple, fields) | Data::Struct(Style::Newtype, fields) => { + deserialize_tuple_in_place(params, fields, &cont.attrs) + } + Data::Enum(_) | Data::Struct(Style::Unit, _) => { + return None; + } + }; + + let delife = params.borrowed.de_lifetime(); + let stmts = Stmts(code); + + let fn_deserialize_in_place = quote_block! { + fn deserialize_in_place<__D>(__deserializer: __D, __place: &mut Self) -> _serde::__private::Result<(), __D::Error> + where + __D: _serde::Deserializer<#delife>, + { + #stmts + } + }; + + Some(Stmts(fn_deserialize_in_place)) +} + +#[cfg(not(feature = "deserialize_in_place"))] +fn deserialize_in_place_body(_cont: &Container, _params: &Parameters) -> Option { + None +} + +fn deserialize_transparent(cont: &Container, params: &Parameters) -> Fragment { + let fields = match &cont.data { + Data::Struct(_, fields) => fields, + Data::Enum(_) => unreachable!(), + }; + + let this_value = ¶ms.this_value; + let transparent_field = fields.iter().find(|f| f.attrs.transparent()).unwrap(); + + let path = match transparent_field.attrs.deserialize_with() { + Some(path) => quote!(#path), + None => { + let span = transparent_field.original.span(); + quote_spanned!(span=> _serde::Deserialize::deserialize) + } + }; + + let assign = fields.iter().map(|field| { + let member = &field.member; + if ptr::eq(field, transparent_field) { + quote!(#member: __transparent) + } else { + let value = match field.attrs.default() { + attr::Default::Default => quote!(_serde::__private::Default::default()), + attr::Default::Path(path) => quote!(#path()), + attr::Default::None => quote!(_serde::__private::PhantomData), + }; + quote!(#member: #value) + } + }); + + quote_block! { + _serde::__private::Result::map( + #path(__deserializer), + |__transparent| #this_value { #(#assign),* }) + } +} + +fn deserialize_from(type_from: &syn::Type) -> Fragment { + quote_block! { + _serde::__private::Result::map( + <#type_from as _serde::Deserialize>::deserialize(__deserializer), + _serde::__private::From::from) + } +} + +fn deserialize_try_from(type_try_from: &syn::Type) -> Fragment { + quote_block! { + _serde::__private::Result::and_then( + <#type_try_from as _serde::Deserialize>::deserialize(__deserializer), + |v| _serde::__private::TryFrom::try_from(v).map_err(_serde::de::Error::custom)) + } +} + +fn deserialize_unit_struct(params: &Parameters, cattrs: &attr::Container) -> Fragment { + let this_type = ¶ms.this_type; + let this_value = ¶ms.this_value; + let type_name = cattrs.name().deserialize_name(); + let (de_impl_generics, de_ty_generics, ty_generics, where_clause) = + split_with_de_lifetime(params); + let delife = params.borrowed.de_lifetime(); + + let expecting = format!("unit struct {}", params.type_name()); + let expecting = cattrs.expecting().unwrap_or(&expecting); + + quote_block! { + #[doc(hidden)] + struct __Visitor #de_impl_generics #where_clause { + marker: _serde::__private::PhantomData<#this_type #ty_generics>, + lifetime: _serde::__private::PhantomData<&#delife ()>, + } + + impl #de_impl_generics _serde::de::Visitor<#delife> for __Visitor #de_ty_generics #where_clause { + type Value = #this_type #ty_generics; + + fn expecting(&self, __formatter: &mut _serde::__private::Formatter) -> _serde::__private::fmt::Result { + _serde::__private::Formatter::write_str(__formatter, #expecting) + } + + #[inline] + fn visit_unit<__E>(self) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + _serde::__private::Ok(#this_value) + } + } + + _serde::Deserializer::deserialize_unit_struct( + __deserializer, + #type_name, + __Visitor { + marker: _serde::__private::PhantomData::<#this_type #ty_generics>, + lifetime: _serde::__private::PhantomData, + }, + ) + } +} + +enum TupleForm<'a> { + Tuple, + /// Contains a variant name + ExternallyTagged(&'a syn::Ident), + /// Contains a variant name and an intermediate deserializer from which actual + /// deserialization will be performed + Untagged(&'a syn::Ident, TokenStream), +} + +fn deserialize_tuple( + params: &Parameters, + fields: &[Field], + cattrs: &attr::Container, + form: TupleForm, +) -> Fragment { + assert!( + !has_flatten(fields), + "tuples and tuple variants cannot have flatten fields" + ); + + let field_count = fields + .iter() + .filter(|field| !field.attrs.skip_deserializing()) + .count(); + + let this_type = ¶ms.this_type; + let this_value = ¶ms.this_value; + let (de_impl_generics, de_ty_generics, ty_generics, where_clause) = + split_with_de_lifetime(params); + let delife = params.borrowed.de_lifetime(); + + // If there are getters (implying private fields), construct the local type + // and use an `Into` conversion to get the remote type. If there are no + // getters then construct the target type directly. + let construct = if params.has_getter { + let local = ¶ms.local; + quote!(#local) + } else { + quote!(#this_value) + }; + + let type_path = match form { + TupleForm::Tuple => construct, + TupleForm::ExternallyTagged(variant_ident) | TupleForm::Untagged(variant_ident, _) => { + quote!(#construct::#variant_ident) + } + }; + let expecting = match form { + TupleForm::Tuple => format!("tuple struct {}", params.type_name()), + TupleForm::ExternallyTagged(variant_ident) | TupleForm::Untagged(variant_ident, _) => { + format!("tuple variant {}::{}", params.type_name(), variant_ident) + } + }; + let expecting = cattrs.expecting().unwrap_or(&expecting); + + let nfields = fields.len(); + + let visit_newtype_struct = match form { + TupleForm::Tuple if nfields == 1 => { + Some(deserialize_newtype_struct(&type_path, params, &fields[0])) + } + _ => None, + }; + + let visit_seq = Stmts(deserialize_seq( + &type_path, params, fields, false, cattrs, expecting, + )); + + let visitor_expr = quote! { + __Visitor { + marker: _serde::__private::PhantomData::<#this_type #ty_generics>, + lifetime: _serde::__private::PhantomData, + } + }; + let dispatch = match form { + TupleForm::Tuple if nfields == 1 => { + let type_name = cattrs.name().deserialize_name(); + quote! { + _serde::Deserializer::deserialize_newtype_struct(__deserializer, #type_name, #visitor_expr) + } + } + TupleForm::Tuple => { + let type_name = cattrs.name().deserialize_name(); + quote! { + _serde::Deserializer::deserialize_tuple_struct(__deserializer, #type_name, #field_count, #visitor_expr) + } + } + TupleForm::ExternallyTagged(_) => quote! { + _serde::de::VariantAccess::tuple_variant(__variant, #field_count, #visitor_expr) + }, + TupleForm::Untagged(_, deserializer) => quote! { + _serde::Deserializer::deserialize_tuple(#deserializer, #field_count, #visitor_expr) + }, + }; + + let visitor_var = if field_count == 0 { + quote!(_) + } else { + quote!(mut __seq) + }; + + quote_block! { + #[doc(hidden)] + struct __Visitor #de_impl_generics #where_clause { + marker: _serde::__private::PhantomData<#this_type #ty_generics>, + lifetime: _serde::__private::PhantomData<&#delife ()>, + } + + impl #de_impl_generics _serde::de::Visitor<#delife> for __Visitor #de_ty_generics #where_clause { + type Value = #this_type #ty_generics; + + fn expecting(&self, __formatter: &mut _serde::__private::Formatter) -> _serde::__private::fmt::Result { + _serde::__private::Formatter::write_str(__formatter, #expecting) + } + + #visit_newtype_struct + + #[inline] + fn visit_seq<__A>(self, #visitor_var: __A) -> _serde::__private::Result + where + __A: _serde::de::SeqAccess<#delife>, + { + #visit_seq + } + } + + #dispatch + } +} + +#[cfg(feature = "deserialize_in_place")] +fn deserialize_tuple_in_place( + params: &Parameters, + fields: &[Field], + cattrs: &attr::Container, +) -> Fragment { + assert!( + !has_flatten(fields), + "tuples and tuple variants cannot have flatten fields" + ); + + let field_count = fields + .iter() + .filter(|field| !field.attrs.skip_deserializing()) + .count(); + + let this_type = ¶ms.this_type; + let (de_impl_generics, de_ty_generics, ty_generics, where_clause) = + split_with_de_lifetime(params); + let delife = params.borrowed.de_lifetime(); + + let expecting = format!("tuple struct {}", params.type_name()); + let expecting = cattrs.expecting().unwrap_or(&expecting); + + let nfields = fields.len(); + + let visit_newtype_struct = if nfields == 1 { + // We do not generate deserialize_in_place if every field has a + // deserialize_with. + assert!(fields[0].attrs.deserialize_with().is_none()); + + Some(quote! { + #[inline] + fn visit_newtype_struct<__E>(self, __e: __E) -> _serde::__private::Result + where + __E: _serde::Deserializer<#delife>, + { + _serde::Deserialize::deserialize_in_place(__e, &mut self.place.0) + } + }) + } else { + None + }; + + let visit_seq = Stmts(deserialize_seq_in_place(params, fields, cattrs, expecting)); + + let visitor_expr = quote! { + __Visitor { + place: __place, + lifetime: _serde::__private::PhantomData, + } + }; + + let type_name = cattrs.name().deserialize_name(); + let dispatch = if nfields == 1 { + quote!(_serde::Deserializer::deserialize_newtype_struct(__deserializer, #type_name, #visitor_expr)) + } else { + quote!(_serde::Deserializer::deserialize_tuple_struct(__deserializer, #type_name, #field_count, #visitor_expr)) + }; + + let visitor_var = if field_count == 0 { + quote!(_) + } else { + quote!(mut __seq) + }; + + let in_place_impl_generics = de_impl_generics.in_place(); + let in_place_ty_generics = de_ty_generics.in_place(); + let place_life = place_lifetime(); + + quote_block! { + #[doc(hidden)] + struct __Visitor #in_place_impl_generics #where_clause { + place: &#place_life mut #this_type #ty_generics, + lifetime: _serde::__private::PhantomData<&#delife ()>, + } + + impl #in_place_impl_generics _serde::de::Visitor<#delife> for __Visitor #in_place_ty_generics #where_clause { + type Value = (); + + fn expecting(&self, __formatter: &mut _serde::__private::Formatter) -> _serde::__private::fmt::Result { + _serde::__private::Formatter::write_str(__formatter, #expecting) + } + + #visit_newtype_struct + + #[inline] + fn visit_seq<__A>(self, #visitor_var: __A) -> _serde::__private::Result + where + __A: _serde::de::SeqAccess<#delife>, + { + #visit_seq + } + } + + #dispatch + } +} + +fn deserialize_seq( + type_path: &TokenStream, + params: &Parameters, + fields: &[Field], + is_struct: bool, + cattrs: &attr::Container, + expecting: &str, +) -> Fragment { + let vars = (0..fields.len()).map(field_i as fn(_) -> _); + + let deserialized_count = fields + .iter() + .filter(|field| !field.attrs.skip_deserializing()) + .count(); + let expecting = if deserialized_count == 1 { + format!("{} with 1 element", expecting) + } else { + format!("{} with {} elements", expecting, deserialized_count) + }; + let expecting = cattrs.expecting().unwrap_or(&expecting); + + let mut index_in_seq = 0_usize; + let let_values = vars.clone().zip(fields).map(|(var, field)| { + if field.attrs.skip_deserializing() { + let default = Expr(expr_is_missing(field, cattrs)); + quote! { + let #var = #default; + } + } else { + let visit = match field.attrs.deserialize_with() { + None => { + let field_ty = field.ty; + let span = field.original.span(); + let func = + quote_spanned!(span=> _serde::de::SeqAccess::next_element::<#field_ty>); + quote!(#func(&mut __seq)?) + } + Some(path) => { + let (wrapper, wrapper_ty) = wrap_deserialize_field_with(params, field.ty, path); + quote!({ + #wrapper + _serde::__private::Option::map( + _serde::de::SeqAccess::next_element::<#wrapper_ty>(&mut __seq)?, + |__wrap| __wrap.value) + }) + } + }; + let value_if_none = expr_is_missing_seq(None, index_in_seq, field, cattrs, expecting); + let assign = quote! { + let #var = match #visit { + _serde::__private::Some(__value) => __value, + _serde::__private::None => #value_if_none, + }; + }; + index_in_seq += 1; + assign + } + }); + + let mut result = if is_struct { + let names = fields.iter().map(|f| &f.member); + quote! { + #type_path { #( #names: #vars ),* } + } + } else { + quote! { + #type_path ( #(#vars),* ) + } + }; + + if params.has_getter { + let this_type = ¶ms.this_type; + let (_, ty_generics, _) = params.generics.split_for_impl(); + result = quote! { + _serde::__private::Into::<#this_type #ty_generics>::into(#result) + }; + } + + let let_default = match cattrs.default() { + attr::Default::Default => Some(quote!( + let __default: Self::Value = _serde::__private::Default::default(); + )), + attr::Default::Path(path) => Some(quote!( + let __default: Self::Value = #path(); + )), + attr::Default::None => { + // We don't need the default value, to prevent an unused variable warning + // we'll leave the line empty. + None + } + }; + + quote_block! { + #let_default + #(#let_values)* + _serde::__private::Ok(#result) + } +} + +#[cfg(feature = "deserialize_in_place")] +fn deserialize_seq_in_place( + params: &Parameters, + fields: &[Field], + cattrs: &attr::Container, + expecting: &str, +) -> Fragment { + let deserialized_count = fields + .iter() + .filter(|field| !field.attrs.skip_deserializing()) + .count(); + let expecting = if deserialized_count == 1 { + format!("{} with 1 element", expecting) + } else { + format!("{} with {} elements", expecting, deserialized_count) + }; + let expecting = cattrs.expecting().unwrap_or(&expecting); + + let mut index_in_seq = 0usize; + let write_values = fields.iter().map(|field| { + let member = &field.member; + + if field.attrs.skip_deserializing() { + let default = Expr(expr_is_missing(field, cattrs)); + quote! { + self.place.#member = #default; + } + } else { + let value_if_none = expr_is_missing_seq(Some(quote!(self.place.#member = )), index_in_seq, field, cattrs, expecting); + let write = match field.attrs.deserialize_with() { + None => { + quote! { + if let _serde::__private::None = _serde::de::SeqAccess::next_element_seed(&mut __seq, + _serde::__private::de::InPlaceSeed(&mut self.place.#member))? + { + #value_if_none; + } + } + } + Some(path) => { + let (wrapper, wrapper_ty) = wrap_deserialize_field_with(params, field.ty, path); + quote!({ + #wrapper + match _serde::de::SeqAccess::next_element::<#wrapper_ty>(&mut __seq)? { + _serde::__private::Some(__wrap) => { + self.place.#member = __wrap.value; + } + _serde::__private::None => { + #value_if_none; + } + } + }) + } + }; + index_in_seq += 1; + write + } + }); + + let this_type = ¶ms.this_type; + let (_, ty_generics, _) = params.generics.split_for_impl(); + let let_default = match cattrs.default() { + attr::Default::Default => Some(quote!( + let __default: #this_type #ty_generics = _serde::__private::Default::default(); + )), + attr::Default::Path(path) => Some(quote!( + let __default: #this_type #ty_generics = #path(); + )), + attr::Default::None => { + // We don't need the default value, to prevent an unused variable warning + // we'll leave the line empty. + None + } + }; + + quote_block! { + #let_default + #(#write_values)* + _serde::__private::Ok(()) + } +} + +fn deserialize_newtype_struct( + type_path: &TokenStream, + params: &Parameters, + field: &Field, +) -> TokenStream { + let delife = params.borrowed.de_lifetime(); + let field_ty = field.ty; + + let value = match field.attrs.deserialize_with() { + None => { + let span = field.original.span(); + let func = quote_spanned!(span=> <#field_ty as _serde::Deserialize>::deserialize); + quote! { + #func(__e)? + } + } + Some(path) => { + quote! { + #path(__e)? + } + } + }; + + let mut result = quote!(#type_path(__field0)); + if params.has_getter { + let this_type = ¶ms.this_type; + let (_, ty_generics, _) = params.generics.split_for_impl(); + result = quote! { + _serde::__private::Into::<#this_type #ty_generics>::into(#result) + }; + } + + quote! { + #[inline] + fn visit_newtype_struct<__E>(self, __e: __E) -> _serde::__private::Result + where + __E: _serde::Deserializer<#delife>, + { + let __field0: #field_ty = #value; + _serde::__private::Ok(#result) + } + } +} + +enum StructForm<'a> { + Struct, + /// Contains a variant name + ExternallyTagged(&'a syn::Ident), + /// Contains a variant name and an intermediate deserializer from which actual + /// deserialization will be performed + InternallyTagged(&'a syn::Ident, TokenStream), + /// Contains a variant name and an intermediate deserializer from which actual + /// deserialization will be performed + Untagged(&'a syn::Ident, TokenStream), +} + +fn deserialize_struct( + params: &Parameters, + fields: &[Field], + cattrs: &attr::Container, + form: StructForm, +) -> Fragment { + let this_type = ¶ms.this_type; + let this_value = ¶ms.this_value; + let (de_impl_generics, de_ty_generics, ty_generics, where_clause) = + split_with_de_lifetime(params); + let delife = params.borrowed.de_lifetime(); + + // If there are getters (implying private fields), construct the local type + // and use an `Into` conversion to get the remote type. If there are no + // getters then construct the target type directly. + let construct = if params.has_getter { + let local = ¶ms.local; + quote!(#local) + } else { + quote!(#this_value) + }; + + let type_path = match form { + StructForm::Struct => construct, + StructForm::ExternallyTagged(variant_ident) + | StructForm::InternallyTagged(variant_ident, _) + | StructForm::Untagged(variant_ident, _) => quote!(#construct::#variant_ident), + }; + let expecting = match form { + StructForm::Struct => format!("struct {}", params.type_name()), + StructForm::ExternallyTagged(variant_ident) + | StructForm::InternallyTagged(variant_ident, _) + | StructForm::Untagged(variant_ident, _) => { + format!("struct variant {}::{}", params.type_name(), variant_ident) + } + }; + let expecting = cattrs.expecting().unwrap_or(&expecting); + + let field_names_idents: Vec<_> = fields + .iter() + .enumerate() + // Skip fields that shouldn't be deserialized or that were flattened, + // so they don't appear in the storage in their literal form + .filter(|&(_, field)| !field.attrs.skip_deserializing() && !field.attrs.flatten()) + .map(|(i, field)| { + ( + field.attrs.name().deserialize_name(), + field_i(i), + field.attrs.aliases(), + ) + }) + .collect(); + + let has_flatten = has_flatten(fields); + let field_visitor = deserialize_field_identifier(&field_names_idents, cattrs, has_flatten); + + // untagged struct variants do not get a visit_seq method. The same applies to + // structs that only have a map representation. + let visit_seq = match form { + StructForm::Untagged(..) => None, + _ if has_flatten => None, + _ => { + let mut_seq = if field_names_idents.is_empty() { + quote!(_) + } else { + quote!(mut __seq) + }; + + let visit_seq = Stmts(deserialize_seq( + &type_path, params, fields, true, cattrs, expecting, + )); + + Some(quote! { + #[inline] + fn visit_seq<__A>(self, #mut_seq: __A) -> _serde::__private::Result + where + __A: _serde::de::SeqAccess<#delife>, + { + #visit_seq + } + }) + } + }; + let visit_map = Stmts(deserialize_map( + &type_path, + params, + fields, + cattrs, + has_flatten, + )); + + let visitor_seed = match form { + StructForm::ExternallyTagged(..) if has_flatten => Some(quote! { + impl #de_impl_generics _serde::de::DeserializeSeed<#delife> for __Visitor #de_ty_generics #where_clause { + type Value = #this_type #ty_generics; + + fn deserialize<__D>(self, __deserializer: __D) -> _serde::__private::Result + where + __D: _serde::Deserializer<#delife>, + { + _serde::Deserializer::deserialize_map(__deserializer, self) + } + } + }), + _ => None, + }; + + let fields_stmt = if has_flatten { + None + } else { + let field_names = field_names_idents + .iter() + .flat_map(|&(_, _, aliases)| aliases); + + Some(quote! { + #[doc(hidden)] + const FIELDS: &'static [&'static str] = &[ #(#field_names),* ]; + }) + }; + + let visitor_expr = quote! { + __Visitor { + marker: _serde::__private::PhantomData::<#this_type #ty_generics>, + lifetime: _serde::__private::PhantomData, + } + }; + let dispatch = match form { + StructForm::Struct if has_flatten => quote! { + _serde::Deserializer::deserialize_map(__deserializer, #visitor_expr) + }, + StructForm::Struct => { + let type_name = cattrs.name().deserialize_name(); + quote! { + _serde::Deserializer::deserialize_struct(__deserializer, #type_name, FIELDS, #visitor_expr) + } + } + StructForm::ExternallyTagged(_) if has_flatten => quote! { + _serde::de::VariantAccess::newtype_variant_seed(__variant, #visitor_expr) + }, + StructForm::ExternallyTagged(_) => quote! { + _serde::de::VariantAccess::struct_variant(__variant, FIELDS, #visitor_expr) + }, + StructForm::InternallyTagged(_, deserializer) => quote! { + _serde::Deserializer::deserialize_any(#deserializer, #visitor_expr) + }, + StructForm::Untagged(_, deserializer) => quote! { + _serde::Deserializer::deserialize_any(#deserializer, #visitor_expr) + }, + }; + + quote_block! { + #field_visitor + + #[doc(hidden)] + struct __Visitor #de_impl_generics #where_clause { + marker: _serde::__private::PhantomData<#this_type #ty_generics>, + lifetime: _serde::__private::PhantomData<&#delife ()>, + } + + impl #de_impl_generics _serde::de::Visitor<#delife> for __Visitor #de_ty_generics #where_clause { + type Value = #this_type #ty_generics; + + fn expecting(&self, __formatter: &mut _serde::__private::Formatter) -> _serde::__private::fmt::Result { + _serde::__private::Formatter::write_str(__formatter, #expecting) + } + + #visit_seq + + #[inline] + fn visit_map<__A>(self, mut __map: __A) -> _serde::__private::Result + where + __A: _serde::de::MapAccess<#delife>, + { + #visit_map + } + } + + #visitor_seed + + #fields_stmt + + #dispatch + } +} + +#[cfg(feature = "deserialize_in_place")] +fn deserialize_struct_in_place( + params: &Parameters, + fields: &[Field], + cattrs: &attr::Container, +) -> Option { + // for now we do not support in_place deserialization for structs that + // are represented as map. + if has_flatten(fields) { + return None; + } + + let this_type = ¶ms.this_type; + let (de_impl_generics, de_ty_generics, ty_generics, where_clause) = + split_with_de_lifetime(params); + let delife = params.borrowed.de_lifetime(); + + let expecting = format!("struct {}", params.type_name()); + let expecting = cattrs.expecting().unwrap_or(&expecting); + + let field_names_idents: Vec<_> = fields + .iter() + .enumerate() + .filter(|&(_, field)| !field.attrs.skip_deserializing()) + .map(|(i, field)| { + ( + field.attrs.name().deserialize_name(), + field_i(i), + field.attrs.aliases(), + ) + }) + .collect(); + + let field_visitor = deserialize_field_identifier(&field_names_idents, cattrs, false); + + let mut_seq = if field_names_idents.is_empty() { + quote!(_) + } else { + quote!(mut __seq) + }; + let visit_seq = Stmts(deserialize_seq_in_place(params, fields, cattrs, expecting)); + let visit_map = Stmts(deserialize_map_in_place(params, fields, cattrs)); + let field_names = field_names_idents + .iter() + .flat_map(|&(_, _, aliases)| aliases); + let type_name = cattrs.name().deserialize_name(); + + let in_place_impl_generics = de_impl_generics.in_place(); + let in_place_ty_generics = de_ty_generics.in_place(); + let place_life = place_lifetime(); + + Some(quote_block! { + #field_visitor + + #[doc(hidden)] + struct __Visitor #in_place_impl_generics #where_clause { + place: &#place_life mut #this_type #ty_generics, + lifetime: _serde::__private::PhantomData<&#delife ()>, + } + + impl #in_place_impl_generics _serde::de::Visitor<#delife> for __Visitor #in_place_ty_generics #where_clause { + type Value = (); + + fn expecting(&self, __formatter: &mut _serde::__private::Formatter) -> _serde::__private::fmt::Result { + _serde::__private::Formatter::write_str(__formatter, #expecting) + } + + #[inline] + fn visit_seq<__A>(self, #mut_seq: __A) -> _serde::__private::Result + where + __A: _serde::de::SeqAccess<#delife>, + { + #visit_seq + } + + #[inline] + fn visit_map<__A>(self, mut __map: __A) -> _serde::__private::Result + where + __A: _serde::de::MapAccess<#delife>, + { + #visit_map + } + } + + #[doc(hidden)] + const FIELDS: &'static [&'static str] = &[ #(#field_names),* ]; + + _serde::Deserializer::deserialize_struct(__deserializer, #type_name, FIELDS, __Visitor { + place: __place, + lifetime: _serde::__private::PhantomData, + }) + }) +} + +fn deserialize_enum( + params: &Parameters, + variants: &[Variant], + cattrs: &attr::Container, +) -> Fragment { + // The variants have already been checked (in ast.rs) that all untagged variants appear at the end + match variants.iter().position(|var| var.attrs.untagged()) { + Some(variant_idx) => { + let (tagged, untagged) = variants.split_at(variant_idx); + let tagged_frag = Expr(deserialize_homogeneous_enum(params, tagged, cattrs)); + deserialize_untagged_enum_after(params, untagged, cattrs, Some(tagged_frag)) + } + None => deserialize_homogeneous_enum(params, variants, cattrs), + } +} + +fn deserialize_homogeneous_enum( + params: &Parameters, + variants: &[Variant], + cattrs: &attr::Container, +) -> Fragment { + match cattrs.tag() { + attr::TagType::External => deserialize_externally_tagged_enum(params, variants, cattrs), + attr::TagType::Internal { tag } => { + deserialize_internally_tagged_enum(params, variants, cattrs, tag) + } + attr::TagType::Adjacent { tag, content } => { + deserialize_adjacently_tagged_enum(params, variants, cattrs, tag, content) + } + attr::TagType::None => deserialize_untagged_enum(params, variants, cattrs), + } +} + +fn prepare_enum_variant_enum(variants: &[Variant]) -> (TokenStream, Stmts) { + let mut deserialized_variants = variants + .iter() + .enumerate() + .filter(|&(_, variant)| !variant.attrs.skip_deserializing()); + + let variant_names_idents: Vec<_> = deserialized_variants + .clone() + .map(|(i, variant)| { + ( + variant.attrs.name().deserialize_name(), + field_i(i), + variant.attrs.aliases(), + ) + }) + .collect(); + + let fallthrough = deserialized_variants + .position(|(_, variant)| variant.attrs.other()) + .map(|other_idx| { + let ignore_variant = variant_names_idents[other_idx].1.clone(); + quote!(_serde::__private::Ok(__Field::#ignore_variant)) + }); + + let variants_stmt = { + let variant_names = variant_names_idents.iter().map(|(name, _, _)| name); + quote! { + #[doc(hidden)] + const VARIANTS: &'static [&'static str] = &[ #(#variant_names),* ]; + } + }; + + let variant_visitor = Stmts(deserialize_generated_identifier( + &variant_names_idents, + false, // variant identifiers do not depend on the presence of flatten fields + true, + None, + fallthrough, + )); + + (variants_stmt, variant_visitor) +} + +fn deserialize_externally_tagged_enum( + params: &Parameters, + variants: &[Variant], + cattrs: &attr::Container, +) -> Fragment { + let this_type = ¶ms.this_type; + let (de_impl_generics, de_ty_generics, ty_generics, where_clause) = + split_with_de_lifetime(params); + let delife = params.borrowed.de_lifetime(); + + let type_name = cattrs.name().deserialize_name(); + let expecting = format!("enum {}", params.type_name()); + let expecting = cattrs.expecting().unwrap_or(&expecting); + + let (variants_stmt, variant_visitor) = prepare_enum_variant_enum(variants); + + // Match arms to extract a variant from a string + let variant_arms = variants + .iter() + .enumerate() + .filter(|&(_, variant)| !variant.attrs.skip_deserializing()) + .map(|(i, variant)| { + let variant_name = field_i(i); + + let block = Match(deserialize_externally_tagged_variant( + params, variant, cattrs, + )); + + quote! { + (__Field::#variant_name, __variant) => #block + } + }); + + let all_skipped = variants + .iter() + .all(|variant| variant.attrs.skip_deserializing()); + let match_variant = if all_skipped { + // This is an empty enum like `enum Impossible {}` or an enum in which + // all variants have `#[serde(skip_deserializing)]`. + quote! { + // FIXME: Once feature(exhaustive_patterns) is stable: + // let _serde::__private::Err(__err) = _serde::de::EnumAccess::variant::<__Field>(__data); + // _serde::__private::Err(__err) + _serde::__private::Result::map( + _serde::de::EnumAccess::variant::<__Field>(__data), + |(__impossible, _)| match __impossible {}) + } + } else { + quote! { + match _serde::de::EnumAccess::variant(__data)? { + #(#variant_arms)* + } + } + }; + + quote_block! { + #variant_visitor + + #[doc(hidden)] + struct __Visitor #de_impl_generics #where_clause { + marker: _serde::__private::PhantomData<#this_type #ty_generics>, + lifetime: _serde::__private::PhantomData<&#delife ()>, + } + + impl #de_impl_generics _serde::de::Visitor<#delife> for __Visitor #de_ty_generics #where_clause { + type Value = #this_type #ty_generics; + + fn expecting(&self, __formatter: &mut _serde::__private::Formatter) -> _serde::__private::fmt::Result { + _serde::__private::Formatter::write_str(__formatter, #expecting) + } + + fn visit_enum<__A>(self, __data: __A) -> _serde::__private::Result + where + __A: _serde::de::EnumAccess<#delife>, + { + #match_variant + } + } + + #variants_stmt + + _serde::Deserializer::deserialize_enum( + __deserializer, + #type_name, + VARIANTS, + __Visitor { + marker: _serde::__private::PhantomData::<#this_type #ty_generics>, + lifetime: _serde::__private::PhantomData, + }, + ) + } +} + +fn deserialize_internally_tagged_enum( + params: &Parameters, + variants: &[Variant], + cattrs: &attr::Container, + tag: &str, +) -> Fragment { + let (variants_stmt, variant_visitor) = prepare_enum_variant_enum(variants); + + // Match arms to extract a variant from a string + let variant_arms = variants + .iter() + .enumerate() + .filter(|&(_, variant)| !variant.attrs.skip_deserializing()) + .map(|(i, variant)| { + let variant_name = field_i(i); + + let block = Match(deserialize_internally_tagged_variant( + params, + variant, + cattrs, + quote!(__deserializer), + )); + + quote! { + __Field::#variant_name => #block + } + }); + + let expecting = format!("internally tagged enum {}", params.type_name()); + let expecting = cattrs.expecting().unwrap_or(&expecting); + + quote_block! { + #variant_visitor + + #variants_stmt + + let (__tag, __content) = _serde::Deserializer::deserialize_any( + __deserializer, + _serde::__private::de::TaggedContentVisitor::<__Field>::new(#tag, #expecting))?; + let __deserializer = _serde::__private::de::ContentDeserializer::<__D::Error>::new(__content); + + match __tag { + #(#variant_arms)* + } + } +} + +fn deserialize_adjacently_tagged_enum( + params: &Parameters, + variants: &[Variant], + cattrs: &attr::Container, + tag: &str, + content: &str, +) -> Fragment { + let this_type = ¶ms.this_type; + let this_value = ¶ms.this_value; + let (de_impl_generics, de_ty_generics, ty_generics, where_clause) = + split_with_de_lifetime(params); + let delife = params.borrowed.de_lifetime(); + + let (variants_stmt, variant_visitor) = prepare_enum_variant_enum(variants); + + let variant_arms: &Vec<_> = &variants + .iter() + .enumerate() + .filter(|&(_, variant)| !variant.attrs.skip_deserializing()) + .map(|(i, variant)| { + let variant_index = field_i(i); + + let block = Match(deserialize_untagged_variant( + params, + variant, + cattrs, + quote!(__deserializer), + )); + + quote! { + __Field::#variant_index => #block + } + }) + .collect(); + + let rust_name = params.type_name(); + let expecting = format!("adjacently tagged enum {}", rust_name); + let expecting = cattrs.expecting().unwrap_or(&expecting); + let type_name = cattrs.name().deserialize_name(); + let deny_unknown_fields = cattrs.deny_unknown_fields(); + + // If unknown fields are allowed, we pick the visitor that can step over + // those. Otherwise we pick the visitor that fails on unknown keys. + let field_visitor_ty = if deny_unknown_fields { + quote! { _serde::__private::de::TagOrContentFieldVisitor } + } else { + quote! { _serde::__private::de::TagContentOtherFieldVisitor } + }; + + let tag_or_content = quote! { + #field_visitor_ty { + tag: #tag, + content: #content, + } + }; + + let variant_seed = quote! { + _serde::__private::de::AdjacentlyTaggedEnumVariantSeed::<__Field> { + enum_name: #rust_name, + variants: VARIANTS, + fields_enum: _serde::__private::PhantomData + } + }; + + let mut missing_content = quote! { + _serde::__private::Err(<__A::Error as _serde::de::Error>::missing_field(#content)) + }; + let mut missing_content_fallthrough = quote!(); + let missing_content_arms = variants + .iter() + .enumerate() + .filter(|&(_, variant)| !variant.attrs.skip_deserializing()) + .filter_map(|(i, variant)| { + let variant_index = field_i(i); + let variant_ident = &variant.ident; + + let arm = match variant.style { + Style::Unit => quote! { + _serde::__private::Ok(#this_value::#variant_ident) + }, + Style::Newtype if variant.attrs.deserialize_with().is_none() => { + let span = variant.original.span(); + let func = quote_spanned!(span=> _serde::__private::de::missing_field); + quote! { + #func(#content).map(#this_value::#variant_ident) + } + } + _ => { + missing_content_fallthrough = quote!(_ => #missing_content); + return None; + } + }; + Some(quote! { + __Field::#variant_index => #arm, + }) + }) + .collect::>(); + if !missing_content_arms.is_empty() { + missing_content = quote! { + match __field { + #(#missing_content_arms)* + #missing_content_fallthrough + } + }; + } + + // Advance the map by one key, returning early in case of error. + let next_key = quote! { + _serde::de::MapAccess::next_key_seed(&mut __map, #tag_or_content)? + }; + + let variant_from_map = quote! { + _serde::de::MapAccess::next_value_seed(&mut __map, #variant_seed)? + }; + + // When allowing unknown fields, we want to transparently step through keys + // we don't care about until we find `tag`, `content`, or run out of keys. + let next_relevant_key = if deny_unknown_fields { + next_key + } else { + quote!({ + let mut __rk : _serde::__private::Option<_serde::__private::de::TagOrContentField> = _serde::__private::None; + while let _serde::__private::Some(__k) = #next_key { + match __k { + _serde::__private::de::TagContentOtherField::Other => { + let _ = _serde::de::MapAccess::next_value::<_serde::de::IgnoredAny>(&mut __map)?; + continue; + }, + _serde::__private::de::TagContentOtherField::Tag => { + __rk = _serde::__private::Some(_serde::__private::de::TagOrContentField::Tag); + break; + } + _serde::__private::de::TagContentOtherField::Content => { + __rk = _serde::__private::Some(_serde::__private::de::TagOrContentField::Content); + break; + } + } + } + + __rk + }) + }; + + // Step through remaining keys, looking for duplicates of previously-seen + // keys. When unknown fields are denied, any key that isn't a duplicate will + // at this point immediately produce an error. + let visit_remaining_keys = quote! { + match #next_relevant_key { + _serde::__private::Some(_serde::__private::de::TagOrContentField::Tag) => { + _serde::__private::Err(<__A::Error as _serde::de::Error>::duplicate_field(#tag)) + } + _serde::__private::Some(_serde::__private::de::TagOrContentField::Content) => { + _serde::__private::Err(<__A::Error as _serde::de::Error>::duplicate_field(#content)) + } + _serde::__private::None => _serde::__private::Ok(__ret), + } + }; + + let finish_content_then_tag = if variant_arms.is_empty() { + quote! { + match #variant_from_map {} + } + } else { + quote! { + let __ret = match #variant_from_map { + // Deserialize the buffered content now that we know the variant. + #(#variant_arms)* + }?; + // Visit remaining keys, looking for duplicates. + #visit_remaining_keys + } + }; + + quote_block! { + #variant_visitor + + #variants_stmt + + #[doc(hidden)] + struct __Seed #de_impl_generics #where_clause { + field: __Field, + marker: _serde::__private::PhantomData<#this_type #ty_generics>, + lifetime: _serde::__private::PhantomData<&#delife ()>, + } + + impl #de_impl_generics _serde::de::DeserializeSeed<#delife> for __Seed #de_ty_generics #where_clause { + type Value = #this_type #ty_generics; + + fn deserialize<__D>(self, __deserializer: __D) -> _serde::__private::Result + where + __D: _serde::Deserializer<#delife>, + { + match self.field { + #(#variant_arms)* + } + } + } + + #[doc(hidden)] + struct __Visitor #de_impl_generics #where_clause { + marker: _serde::__private::PhantomData<#this_type #ty_generics>, + lifetime: _serde::__private::PhantomData<&#delife ()>, + } + + impl #de_impl_generics _serde::de::Visitor<#delife> for __Visitor #de_ty_generics #where_clause { + type Value = #this_type #ty_generics; + + fn expecting(&self, __formatter: &mut _serde::__private::Formatter) -> _serde::__private::fmt::Result { + _serde::__private::Formatter::write_str(__formatter, #expecting) + } + + fn visit_map<__A>(self, mut __map: __A) -> _serde::__private::Result + where + __A: _serde::de::MapAccess<#delife>, + { + // Visit the first relevant key. + match #next_relevant_key { + // First key is the tag. + _serde::__private::Some(_serde::__private::de::TagOrContentField::Tag) => { + // Parse the tag. + let __field = #variant_from_map; + // Visit the second key. + match #next_relevant_key { + // Second key is a duplicate of the tag. + _serde::__private::Some(_serde::__private::de::TagOrContentField::Tag) => { + _serde::__private::Err(<__A::Error as _serde::de::Error>::duplicate_field(#tag)) + } + // Second key is the content. + _serde::__private::Some(_serde::__private::de::TagOrContentField::Content) => { + let __ret = _serde::de::MapAccess::next_value_seed(&mut __map, + __Seed { + field: __field, + marker: _serde::__private::PhantomData, + lifetime: _serde::__private::PhantomData, + })?; + // Visit remaining keys, looking for duplicates. + #visit_remaining_keys + } + // There is no second key; might be okay if the we have a unit variant. + _serde::__private::None => #missing_content + } + } + // First key is the content. + _serde::__private::Some(_serde::__private::de::TagOrContentField::Content) => { + // Buffer up the content. + let __content = _serde::de::MapAccess::next_value::<_serde::__private::de::Content>(&mut __map)?; + // Visit the second key. + match #next_relevant_key { + // Second key is the tag. + _serde::__private::Some(_serde::__private::de::TagOrContentField::Tag) => { + let __deserializer = _serde::__private::de::ContentDeserializer::<__A::Error>::new(__content); + #finish_content_then_tag + } + // Second key is a duplicate of the content. + _serde::__private::Some(_serde::__private::de::TagOrContentField::Content) => { + _serde::__private::Err(<__A::Error as _serde::de::Error>::duplicate_field(#content)) + } + // There is no second key. + _serde::__private::None => { + _serde::__private::Err(<__A::Error as _serde::de::Error>::missing_field(#tag)) + } + } + } + // There is no first key. + _serde::__private::None => { + _serde::__private::Err(<__A::Error as _serde::de::Error>::missing_field(#tag)) + } + } + } + + fn visit_seq<__A>(self, mut __seq: __A) -> _serde::__private::Result + where + __A: _serde::de::SeqAccess<#delife>, + { + // Visit the first element - the tag. + match _serde::de::SeqAccess::next_element(&mut __seq)? { + _serde::__private::Some(__field) => { + // Visit the second element - the content. + match _serde::de::SeqAccess::next_element_seed( + &mut __seq, + __Seed { + field: __field, + marker: _serde::__private::PhantomData, + lifetime: _serde::__private::PhantomData, + }, + )? { + _serde::__private::Some(__ret) => _serde::__private::Ok(__ret), + // There is no second element. + _serde::__private::None => { + _serde::__private::Err(_serde::de::Error::invalid_length(1, &self)) + } + } + } + // There is no first element. + _serde::__private::None => { + _serde::__private::Err(_serde::de::Error::invalid_length(0, &self)) + } + } + } + } + + #[doc(hidden)] + const FIELDS: &'static [&'static str] = &[#tag, #content]; + _serde::Deserializer::deserialize_struct( + __deserializer, + #type_name, + FIELDS, + __Visitor { + marker: _serde::__private::PhantomData::<#this_type #ty_generics>, + lifetime: _serde::__private::PhantomData, + }, + ) + } +} + +fn deserialize_untagged_enum( + params: &Parameters, + variants: &[Variant], + cattrs: &attr::Container, +) -> Fragment { + let first_attempt = None; + deserialize_untagged_enum_after(params, variants, cattrs, first_attempt) +} + +fn deserialize_untagged_enum_after( + params: &Parameters, + variants: &[Variant], + cattrs: &attr::Container, + first_attempt: Option, +) -> Fragment { + let attempts = variants + .iter() + .filter(|variant| !variant.attrs.skip_deserializing()) + .map(|variant| { + Expr(deserialize_untagged_variant( + params, + variant, + cattrs, + quote!(__deserializer), + )) + }); + // TODO this message could be better by saving the errors from the failed + // attempts. The heuristic used by TOML was to count the number of fields + // processed before an error, and use the error that happened after the + // largest number of fields. I'm not sure I like that. Maybe it would be + // better to save all the errors and combine them into one message that + // explains why none of the variants matched. + let fallthrough_msg = format!( + "data did not match any variant of untagged enum {}", + params.type_name() + ); + let fallthrough_msg = cattrs.expecting().unwrap_or(&fallthrough_msg); + + // Ignore any error associated with non-untagged deserialization so that we + // can fall through to the untagged variants. This may be infallible so we + // need to provide the error type. + let first_attempt = first_attempt.map(|expr| { + quote! { + if let _serde::__private::Result::<_, __D::Error>::Ok(__ok) = (|| #expr)() { + return _serde::__private::Ok(__ok); + } + } + }); + + quote_block! { + let __content = <_serde::__private::de::Content as _serde::Deserialize>::deserialize(__deserializer)?; + let __deserializer = _serde::__private::de::ContentRefDeserializer::<__D::Error>::new(&__content); + + #first_attempt + + #( + if let _serde::__private::Ok(__ok) = #attempts { + return _serde::__private::Ok(__ok); + } + )* + + _serde::__private::Err(_serde::de::Error::custom(#fallthrough_msg)) + } +} + +fn deserialize_externally_tagged_variant( + params: &Parameters, + variant: &Variant, + cattrs: &attr::Container, +) -> Fragment { + if let Some(path) = variant.attrs.deserialize_with() { + let (wrapper, wrapper_ty, unwrap_fn) = wrap_deserialize_variant_with(params, variant, path); + return quote_block! { + #wrapper + _serde::__private::Result::map( + _serde::de::VariantAccess::newtype_variant::<#wrapper_ty>(__variant), #unwrap_fn) + }; + } + + let variant_ident = &variant.ident; + + match variant.style { + Style::Unit => { + let this_value = ¶ms.this_value; + quote_block! { + _serde::de::VariantAccess::unit_variant(__variant)?; + _serde::__private::Ok(#this_value::#variant_ident) + } + } + Style::Newtype => deserialize_externally_tagged_newtype_variant( + variant_ident, + params, + &variant.fields[0], + cattrs, + ), + Style::Tuple => deserialize_tuple( + params, + &variant.fields, + cattrs, + TupleForm::ExternallyTagged(variant_ident), + ), + Style::Struct => deserialize_struct( + params, + &variant.fields, + cattrs, + StructForm::ExternallyTagged(variant_ident), + ), + } +} + +// Generates significant part of the visit_seq and visit_map bodies of visitors +// for the variants of internally tagged enum. +fn deserialize_internally_tagged_variant( + params: &Parameters, + variant: &Variant, + cattrs: &attr::Container, + deserializer: TokenStream, +) -> Fragment { + if variant.attrs.deserialize_with().is_some() { + return deserialize_untagged_variant(params, variant, cattrs, deserializer); + } + + let variant_ident = &variant.ident; + + match effective_style(variant) { + Style::Unit => { + let this_value = ¶ms.this_value; + let type_name = params.type_name(); + let variant_name = variant.ident.to_string(); + let default = variant.fields.first().map(|field| { + let default = Expr(expr_is_missing(field, cattrs)); + quote!((#default)) + }); + quote_block! { + _serde::Deserializer::deserialize_any(#deserializer, _serde::__private::de::InternallyTaggedUnitVisitor::new(#type_name, #variant_name))?; + _serde::__private::Ok(#this_value::#variant_ident #default) + } + } + Style::Newtype => deserialize_untagged_newtype_variant( + variant_ident, + params, + &variant.fields[0], + &deserializer, + ), + Style::Struct => deserialize_struct( + params, + &variant.fields, + cattrs, + StructForm::InternallyTagged(variant_ident, deserializer), + ), + Style::Tuple => unreachable!("checked in serde_derive_internals"), + } +} + +fn deserialize_untagged_variant( + params: &Parameters, + variant: &Variant, + cattrs: &attr::Container, + deserializer: TokenStream, +) -> Fragment { + if let Some(path) = variant.attrs.deserialize_with() { + let unwrap_fn = unwrap_to_variant_closure(params, variant, false); + return quote_block! { + _serde::__private::Result::map(#path(#deserializer), #unwrap_fn) + }; + } + + let variant_ident = &variant.ident; + + match effective_style(variant) { + Style::Unit => { + let this_value = ¶ms.this_value; + let type_name = params.type_name(); + let variant_name = variant.ident.to_string(); + let default = variant.fields.first().map(|field| { + let default = Expr(expr_is_missing(field, cattrs)); + quote!((#default)) + }); + quote_expr! { + match _serde::Deserializer::deserialize_any( + #deserializer, + _serde::__private::de::UntaggedUnitVisitor::new(#type_name, #variant_name) + ) { + _serde::__private::Ok(()) => _serde::__private::Ok(#this_value::#variant_ident #default), + _serde::__private::Err(__err) => _serde::__private::Err(__err), + } + } + } + Style::Newtype => deserialize_untagged_newtype_variant( + variant_ident, + params, + &variant.fields[0], + &deserializer, + ), + Style::Tuple => deserialize_tuple( + params, + &variant.fields, + cattrs, + TupleForm::Untagged(variant_ident, deserializer), + ), + Style::Struct => deserialize_struct( + params, + &variant.fields, + cattrs, + StructForm::Untagged(variant_ident, deserializer), + ), + } +} + +fn deserialize_externally_tagged_newtype_variant( + variant_ident: &syn::Ident, + params: &Parameters, + field: &Field, + cattrs: &attr::Container, +) -> Fragment { + let this_value = ¶ms.this_value; + + if field.attrs.skip_deserializing() { + let default = Expr(expr_is_missing(field, cattrs)); + return quote_block! { + _serde::de::VariantAccess::unit_variant(__variant)?; + _serde::__private::Ok(#this_value::#variant_ident(#default)) + }; + } + + match field.attrs.deserialize_with() { + None => { + let field_ty = field.ty; + let span = field.original.span(); + let func = + quote_spanned!(span=> _serde::de::VariantAccess::newtype_variant::<#field_ty>); + quote_expr! { + _serde::__private::Result::map(#func(__variant), #this_value::#variant_ident) + } + } + Some(path) => { + let (wrapper, wrapper_ty) = wrap_deserialize_field_with(params, field.ty, path); + quote_block! { + #wrapper + _serde::__private::Result::map( + _serde::de::VariantAccess::newtype_variant::<#wrapper_ty>(__variant), + |__wrapper| #this_value::#variant_ident(__wrapper.value)) + } + } + } +} + +fn deserialize_untagged_newtype_variant( + variant_ident: &syn::Ident, + params: &Parameters, + field: &Field, + deserializer: &TokenStream, +) -> Fragment { + let this_value = ¶ms.this_value; + let field_ty = field.ty; + match field.attrs.deserialize_with() { + None => { + let span = field.original.span(); + let func = quote_spanned!(span=> <#field_ty as _serde::Deserialize>::deserialize); + quote_expr! { + _serde::__private::Result::map(#func(#deserializer), #this_value::#variant_ident) + } + } + Some(path) => { + quote_block! { + let __value: _serde::__private::Result<#field_ty, _> = #path(#deserializer); + _serde::__private::Result::map(__value, #this_value::#variant_ident) + } + } + } +} + +fn deserialize_generated_identifier( + fields: &[(&str, Ident, &BTreeSet)], + has_flatten: bool, + is_variant: bool, + ignore_variant: Option, + fallthrough: Option, +) -> Fragment { + let this_value = quote!(__Field); + let field_idents: &Vec<_> = &fields.iter().map(|(_, ident, _)| ident).collect(); + + let visitor_impl = Stmts(deserialize_identifier( + &this_value, + fields, + is_variant, + fallthrough, + None, + !is_variant && has_flatten, + None, + )); + + let lifetime = if !is_variant && has_flatten { + Some(quote!(<'de>)) + } else { + None + }; + + quote_block! { + #[allow(non_camel_case_types)] + #[doc(hidden)] + enum __Field #lifetime { + #(#field_idents,)* + #ignore_variant + } + + #[doc(hidden)] + struct __FieldVisitor; + + impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { + type Value = __Field #lifetime; + + #visitor_impl + } + + impl<'de> _serde::Deserialize<'de> for __Field #lifetime { + #[inline] + fn deserialize<__D>(__deserializer: __D) -> _serde::__private::Result + where + __D: _serde::Deserializer<'de>, + { + _serde::Deserializer::deserialize_identifier(__deserializer, __FieldVisitor) + } + } + } +} + +/// Generates enum and its `Deserialize` implementation that represents each +/// non-skipped field of the struct +fn deserialize_field_identifier( + fields: &[(&str, Ident, &BTreeSet)], + cattrs: &attr::Container, + has_flatten: bool, +) -> Stmts { + let (ignore_variant, fallthrough) = if has_flatten { + let ignore_variant = quote!(__other(_serde::__private::de::Content<'de>),); + let fallthrough = quote!(_serde::__private::Ok(__Field::__other(__value))); + (Some(ignore_variant), Some(fallthrough)) + } else if cattrs.deny_unknown_fields() { + (None, None) + } else { + let ignore_variant = quote!(__ignore,); + let fallthrough = quote!(_serde::__private::Ok(__Field::__ignore)); + (Some(ignore_variant), Some(fallthrough)) + }; + + Stmts(deserialize_generated_identifier( + fields, + has_flatten, + false, + ignore_variant, + fallthrough, + )) +} + +// Generates `Deserialize::deserialize` body for an enum with +// `serde(field_identifier)` or `serde(variant_identifier)` attribute. +fn deserialize_custom_identifier( + params: &Parameters, + variants: &[Variant], + cattrs: &attr::Container, +) -> Fragment { + let is_variant = match cattrs.identifier() { + attr::Identifier::Variant => true, + attr::Identifier::Field => false, + attr::Identifier::No => unreachable!(), + }; + + let this_type = params.this_type.to_token_stream(); + let this_value = params.this_value.to_token_stream(); + + let (ordinary, fallthrough, fallthrough_borrowed) = if let Some(last) = variants.last() { + let last_ident = &last.ident; + if last.attrs.other() { + // Process `serde(other)` attribute. It would always be found on the + // last variant (checked in `check_identifier`), so all preceding + // are ordinary variants. + let ordinary = &variants[..variants.len() - 1]; + let fallthrough = quote!(_serde::__private::Ok(#this_value::#last_ident)); + (ordinary, Some(fallthrough), None) + } else if let Style::Newtype = last.style { + let ordinary = &variants[..variants.len() - 1]; + let fallthrough = |value| { + quote! { + _serde::__private::Result::map( + _serde::Deserialize::deserialize( + _serde::__private::de::IdentifierDeserializer::from(#value) + ), + #this_value::#last_ident) + } + }; + ( + ordinary, + Some(fallthrough(quote!(__value))), + Some(fallthrough(quote!(_serde::__private::de::Borrowed( + __value + )))), + ) + } else { + (variants, None, None) + } + } else { + (variants, None, None) + }; + + let names_idents: Vec<_> = ordinary + .iter() + .map(|variant| { + ( + variant.attrs.name().deserialize_name(), + variant.ident.clone(), + variant.attrs.aliases(), + ) + }) + .collect(); + + let names = names_idents.iter().flat_map(|&(_, _, aliases)| aliases); + + let names_const = if fallthrough.is_some() { + None + } else if is_variant { + let variants = quote! { + #[doc(hidden)] + const VARIANTS: &'static [&'static str] = &[ #(#names),* ]; + }; + Some(variants) + } else { + let fields = quote! { + #[doc(hidden)] + const FIELDS: &'static [&'static str] = &[ #(#names),* ]; + }; + Some(fields) + }; + + let (de_impl_generics, de_ty_generics, ty_generics, where_clause) = + split_with_de_lifetime(params); + let delife = params.borrowed.de_lifetime(); + let visitor_impl = Stmts(deserialize_identifier( + &this_value, + &names_idents, + is_variant, + fallthrough, + fallthrough_borrowed, + false, + cattrs.expecting(), + )); + + quote_block! { + #names_const + + #[doc(hidden)] + struct __FieldVisitor #de_impl_generics #where_clause { + marker: _serde::__private::PhantomData<#this_type #ty_generics>, + lifetime: _serde::__private::PhantomData<&#delife ()>, + } + + impl #de_impl_generics _serde::de::Visitor<#delife> for __FieldVisitor #de_ty_generics #where_clause { + type Value = #this_type #ty_generics; + + #visitor_impl + } + + let __visitor = __FieldVisitor { + marker: _serde::__private::PhantomData::<#this_type #ty_generics>, + lifetime: _serde::__private::PhantomData, + }; + _serde::Deserializer::deserialize_identifier(__deserializer, __visitor) + } +} + +fn deserialize_identifier( + this_value: &TokenStream, + fields: &[(&str, Ident, &BTreeSet)], + is_variant: bool, + fallthrough: Option, + fallthrough_borrowed: Option, + collect_other_fields: bool, + expecting: Option<&str>, +) -> Fragment { + let str_mapping = fields.iter().map(|(_, ident, aliases)| { + // `aliases` also contains a main name + quote!(#(#aliases)|* => _serde::__private::Ok(#this_value::#ident)) + }); + let bytes_mapping = fields.iter().map(|(_, ident, aliases)| { + // `aliases` also contains a main name + let aliases = aliases + .iter() + .map(|alias| Literal::byte_string(alias.as_bytes())); + quote!(#(#aliases)|* => _serde::__private::Ok(#this_value::#ident)) + }); + + let expecting = expecting.unwrap_or(if is_variant { + "variant identifier" + } else { + "field identifier" + }); + + let bytes_to_str = if fallthrough.is_some() || collect_other_fields { + None + } else { + Some(quote! { + let __value = &_serde::__private::from_utf8_lossy(__value); + }) + }; + + let ( + value_as_str_content, + value_as_borrowed_str_content, + value_as_bytes_content, + value_as_borrowed_bytes_content, + ) = if collect_other_fields { + ( + Some(quote! { + let __value = _serde::__private::de::Content::String(_serde::__private::ToString::to_string(__value)); + }), + Some(quote! { + let __value = _serde::__private::de::Content::Str(__value); + }), + Some(quote! { + let __value = _serde::__private::de::Content::ByteBuf(__value.to_vec()); + }), + Some(quote! { + let __value = _serde::__private::de::Content::Bytes(__value); + }), + ) + } else { + (None, None, None, None) + }; + + let fallthrough_arm_tokens; + let fallthrough_arm = if let Some(fallthrough) = &fallthrough { + fallthrough + } else if is_variant { + fallthrough_arm_tokens = quote! { + _serde::__private::Err(_serde::de::Error::unknown_variant(__value, VARIANTS)) + }; + &fallthrough_arm_tokens + } else { + fallthrough_arm_tokens = quote! { + _serde::__private::Err(_serde::de::Error::unknown_field(__value, FIELDS)) + }; + &fallthrough_arm_tokens + }; + + let visit_other = if collect_other_fields { + quote! { + fn visit_bool<__E>(self, __value: bool) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + _serde::__private::Ok(__Field::__other(_serde::__private::de::Content::Bool(__value))) + } + + fn visit_i8<__E>(self, __value: i8) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + _serde::__private::Ok(__Field::__other(_serde::__private::de::Content::I8(__value))) + } + + fn visit_i16<__E>(self, __value: i16) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + _serde::__private::Ok(__Field::__other(_serde::__private::de::Content::I16(__value))) + } + + fn visit_i32<__E>(self, __value: i32) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + _serde::__private::Ok(__Field::__other(_serde::__private::de::Content::I32(__value))) + } + + fn visit_i64<__E>(self, __value: i64) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + _serde::__private::Ok(__Field::__other(_serde::__private::de::Content::I64(__value))) + } + + fn visit_u8<__E>(self, __value: u8) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + _serde::__private::Ok(__Field::__other(_serde::__private::de::Content::U8(__value))) + } + + fn visit_u16<__E>(self, __value: u16) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + _serde::__private::Ok(__Field::__other(_serde::__private::de::Content::U16(__value))) + } + + fn visit_u32<__E>(self, __value: u32) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + _serde::__private::Ok(__Field::__other(_serde::__private::de::Content::U32(__value))) + } + + fn visit_u64<__E>(self, __value: u64) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + _serde::__private::Ok(__Field::__other(_serde::__private::de::Content::U64(__value))) + } + + fn visit_f32<__E>(self, __value: f32) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + _serde::__private::Ok(__Field::__other(_serde::__private::de::Content::F32(__value))) + } + + fn visit_f64<__E>(self, __value: f64) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + _serde::__private::Ok(__Field::__other(_serde::__private::de::Content::F64(__value))) + } + + fn visit_char<__E>(self, __value: char) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + _serde::__private::Ok(__Field::__other(_serde::__private::de::Content::Char(__value))) + } + + fn visit_unit<__E>(self) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + _serde::__private::Ok(__Field::__other(_serde::__private::de::Content::Unit)) + } + } + } else { + let u64_mapping = fields.iter().enumerate().map(|(i, (_, ident, _))| { + let i = i as u64; + quote!(#i => _serde::__private::Ok(#this_value::#ident)) + }); + + let u64_fallthrough_arm_tokens; + let u64_fallthrough_arm = if let Some(fallthrough) = &fallthrough { + fallthrough + } else { + let index_expecting = if is_variant { "variant" } else { "field" }; + let fallthrough_msg = format!("{} index 0 <= i < {}", index_expecting, fields.len()); + u64_fallthrough_arm_tokens = quote! { + _serde::__private::Err(_serde::de::Error::invalid_value( + _serde::de::Unexpected::Unsigned(__value), + &#fallthrough_msg, + )) + }; + &u64_fallthrough_arm_tokens + }; + + quote! { + fn visit_u64<__E>(self, __value: u64) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + #(#u64_mapping,)* + _ => #u64_fallthrough_arm, + } + } + } + }; + + let visit_borrowed = if fallthrough_borrowed.is_some() || collect_other_fields { + let str_mapping = str_mapping.clone(); + let bytes_mapping = bytes_mapping.clone(); + let fallthrough_borrowed_arm = fallthrough_borrowed.as_ref().unwrap_or(fallthrough_arm); + Some(quote! { + fn visit_borrowed_str<__E>(self, __value: &'de str) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + #(#str_mapping,)* + _ => { + #value_as_borrowed_str_content + #fallthrough_borrowed_arm + } + } + } + + fn visit_borrowed_bytes<__E>(self, __value: &'de [u8]) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + #(#bytes_mapping,)* + _ => { + #bytes_to_str + #value_as_borrowed_bytes_content + #fallthrough_borrowed_arm + } + } + } + }) + } else { + None + }; + + quote_block! { + fn expecting(&self, __formatter: &mut _serde::__private::Formatter) -> _serde::__private::fmt::Result { + _serde::__private::Formatter::write_str(__formatter, #expecting) + } + + #visit_other + + fn visit_str<__E>(self, __value: &str) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + #(#str_mapping,)* + _ => { + #value_as_str_content + #fallthrough_arm + } + } + } + + fn visit_bytes<__E>(self, __value: &[u8]) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + #(#bytes_mapping,)* + _ => { + #bytes_to_str + #value_as_bytes_content + #fallthrough_arm + } + } + } + + #visit_borrowed + } +} + +fn deserialize_map( + struct_path: &TokenStream, + params: &Parameters, + fields: &[Field], + cattrs: &attr::Container, + has_flatten: bool, +) -> Fragment { + // Create the field names for the fields. + let fields_names: Vec<_> = fields + .iter() + .enumerate() + .map(|(i, field)| (field, field_i(i))) + .collect(); + + // Declare each field that will be deserialized. + let let_values = fields_names + .iter() + .filter(|&&(field, _)| !field.attrs.skip_deserializing() && !field.attrs.flatten()) + .map(|(field, name)| { + let field_ty = field.ty; + quote! { + let mut #name: _serde::__private::Option<#field_ty> = _serde::__private::None; + } + }); + + // Collect contents for flatten fields into a buffer + let let_collect = if has_flatten { + Some(quote! { + let mut __collect = _serde::__private::Vec::<_serde::__private::Option<( + _serde::__private::de::Content, + _serde::__private::de::Content + )>>::new(); + }) + } else { + None + }; + + // Match arms to extract a value for a field. + let value_arms = fields_names + .iter() + .filter(|&&(field, _)| !field.attrs.skip_deserializing() && !field.attrs.flatten()) + .map(|(field, name)| { + let deser_name = field.attrs.name().deserialize_name(); + + let visit = match field.attrs.deserialize_with() { + None => { + let field_ty = field.ty; + let span = field.original.span(); + let func = + quote_spanned!(span=> _serde::de::MapAccess::next_value::<#field_ty>); + quote! { + #func(&mut __map)? + } + } + Some(path) => { + let (wrapper, wrapper_ty) = wrap_deserialize_field_with(params, field.ty, path); + quote!({ + #wrapper + match _serde::de::MapAccess::next_value::<#wrapper_ty>(&mut __map) { + _serde::__private::Ok(__wrapper) => __wrapper.value, + _serde::__private::Err(__err) => { + return _serde::__private::Err(__err); + } + } + }) + } + }; + quote! { + __Field::#name => { + if _serde::__private::Option::is_some(&#name) { + return _serde::__private::Err(<__A::Error as _serde::de::Error>::duplicate_field(#deser_name)); + } + #name = _serde::__private::Some(#visit); + } + } + }); + + // Visit ignored values to consume them + let ignored_arm = if has_flatten { + Some(quote! { + __Field::__other(__name) => { + __collect.push(_serde::__private::Some(( + __name, + _serde::de::MapAccess::next_value(&mut __map)?))); + } + }) + } else if cattrs.deny_unknown_fields() { + None + } else { + Some(quote! { + _ => { let _ = _serde::de::MapAccess::next_value::<_serde::de::IgnoredAny>(&mut __map)?; } + }) + }; + + let all_skipped = fields.iter().all(|field| field.attrs.skip_deserializing()); + let match_keys = if cattrs.deny_unknown_fields() && all_skipped { + quote! { + // FIXME: Once feature(exhaustive_patterns) is stable: + // let _serde::__private::None::<__Field> = _serde::de::MapAccess::next_key(&mut __map)?; + _serde::__private::Option::map( + _serde::de::MapAccess::next_key::<__Field>(&mut __map)?, + |__impossible| match __impossible {}); + } + } else { + quote! { + while let _serde::__private::Some(__key) = _serde::de::MapAccess::next_key::<__Field>(&mut __map)? { + match __key { + #(#value_arms)* + #ignored_arm + } + } + } + }; + + let extract_values = fields_names + .iter() + .filter(|&&(field, _)| !field.attrs.skip_deserializing() && !field.attrs.flatten()) + .map(|(field, name)| { + let missing_expr = Match(expr_is_missing(field, cattrs)); + + quote! { + let #name = match #name { + _serde::__private::Some(#name) => #name, + _serde::__private::None => #missing_expr + }; + } + }); + + let extract_collected = fields_names + .iter() + .filter(|&&(field, _)| field.attrs.flatten() && !field.attrs.skip_deserializing()) + .map(|(field, name)| { + let field_ty = field.ty; + let func = match field.attrs.deserialize_with() { + None => { + let span = field.original.span(); + quote_spanned!(span=> _serde::de::Deserialize::deserialize) + } + Some(path) => quote!(#path), + }; + quote! { + let #name: #field_ty = #func( + _serde::__private::de::FlatMapDeserializer( + &mut __collect, + _serde::__private::PhantomData))?; + } + }); + + let collected_deny_unknown_fields = if has_flatten && cattrs.deny_unknown_fields() { + Some(quote! { + if let _serde::__private::Some(_serde::__private::Some((__key, _))) = + __collect.into_iter().filter(_serde::__private::Option::is_some).next() + { + if let _serde::__private::Some(__key) = __key.as_str() { + return _serde::__private::Err( + _serde::de::Error::custom(format_args!("unknown field `{}`", &__key))); + } else { + return _serde::__private::Err( + _serde::de::Error::custom(format_args!("unexpected map key"))); + } + } + }) + } else { + None + }; + + let result = fields_names.iter().map(|(field, name)| { + let member = &field.member; + if field.attrs.skip_deserializing() { + let value = Expr(expr_is_missing(field, cattrs)); + quote!(#member: #value) + } else { + quote!(#member: #name) + } + }); + + let let_default = match cattrs.default() { + attr::Default::Default => Some(quote!( + let __default: Self::Value = _serde::__private::Default::default(); + )), + attr::Default::Path(path) => Some(quote!( + let __default: Self::Value = #path(); + )), + attr::Default::None => { + // We don't need the default value, to prevent an unused variable warning + // we'll leave the line empty. + None + } + }; + + let mut result = quote!(#struct_path { #(#result),* }); + if params.has_getter { + let this_type = ¶ms.this_type; + let (_, ty_generics, _) = params.generics.split_for_impl(); + result = quote! { + _serde::__private::Into::<#this_type #ty_generics>::into(#result) + }; + } + + quote_block! { + #(#let_values)* + + #let_collect + + #match_keys + + #let_default + + #(#extract_values)* + + #(#extract_collected)* + + #collected_deny_unknown_fields + + _serde::__private::Ok(#result) + } +} + +#[cfg(feature = "deserialize_in_place")] +fn deserialize_map_in_place( + params: &Parameters, + fields: &[Field], + cattrs: &attr::Container, +) -> Fragment { + assert!( + !has_flatten(fields), + "inplace deserialization of maps does not support flatten fields" + ); + + // Create the field names for the fields. + let fields_names: Vec<_> = fields + .iter() + .enumerate() + .map(|(i, field)| (field, field_i(i))) + .collect(); + + // For deserialize_in_place, declare booleans for each field that will be + // deserialized. + let let_flags = fields_names + .iter() + .filter(|&&(field, _)| !field.attrs.skip_deserializing()) + .map(|(_, name)| { + quote! { + let mut #name: bool = false; + } + }); + + // Match arms to extract a value for a field. + let value_arms_from = fields_names + .iter() + .filter(|&&(field, _)| !field.attrs.skip_deserializing()) + .map(|(field, name)| { + let deser_name = field.attrs.name().deserialize_name(); + let member = &field.member; + + let visit = match field.attrs.deserialize_with() { + None => { + quote! { + _serde::de::MapAccess::next_value_seed(&mut __map, _serde::__private::de::InPlaceSeed(&mut self.place.#member))? + } + } + Some(path) => { + let (wrapper, wrapper_ty) = wrap_deserialize_field_with(params, field.ty, path); + quote!({ + #wrapper + self.place.#member = match _serde::de::MapAccess::next_value::<#wrapper_ty>(&mut __map) { + _serde::__private::Ok(__wrapper) => __wrapper.value, + _serde::__private::Err(__err) => { + return _serde::__private::Err(__err); + } + }; + }) + } + }; + quote! { + __Field::#name => { + if #name { + return _serde::__private::Err(<__A::Error as _serde::de::Error>::duplicate_field(#deser_name)); + } + #visit; + #name = true; + } + } + }); + + // Visit ignored values to consume them + let ignored_arm = if cattrs.deny_unknown_fields() { + None + } else { + Some(quote! { + _ => { let _ = _serde::de::MapAccess::next_value::<_serde::de::IgnoredAny>(&mut __map)?; } + }) + }; + + let all_skipped = fields.iter().all(|field| field.attrs.skip_deserializing()); + + let match_keys = if cattrs.deny_unknown_fields() && all_skipped { + quote! { + // FIXME: Once feature(exhaustive_patterns) is stable: + // let _serde::__private::None::<__Field> = _serde::de::MapAccess::next_key(&mut __map)?; + _serde::__private::Option::map( + _serde::de::MapAccess::next_key::<__Field>(&mut __map)?, + |__impossible| match __impossible {}); + } + } else { + quote! { + while let _serde::__private::Some(__key) = _serde::de::MapAccess::next_key::<__Field>(&mut __map)? { + match __key { + #(#value_arms_from)* + #ignored_arm + } + } + } + }; + + let check_flags = fields_names + .iter() + .filter(|&&(field, _)| !field.attrs.skip_deserializing()) + .map(|(field, name)| { + let missing_expr = expr_is_missing(field, cattrs); + // If missing_expr unconditionally returns an error, don't try + // to assign its value to self.place. + if field.attrs.default().is_none() + && cattrs.default().is_none() + && field.attrs.deserialize_with().is_some() + { + let missing_expr = Stmts(missing_expr); + quote! { + if !#name { + #missing_expr; + } + } + } else { + let member = &field.member; + let missing_expr = Expr(missing_expr); + quote! { + if !#name { + self.place.#member = #missing_expr; + }; + } + } + }); + + let this_type = ¶ms.this_type; + let (_, _, ty_generics, _) = split_with_de_lifetime(params); + + let let_default = match cattrs.default() { + attr::Default::Default => Some(quote!( + let __default: #this_type #ty_generics = _serde::__private::Default::default(); + )), + attr::Default::Path(path) => Some(quote!( + let __default: #this_type #ty_generics = #path(); + )), + attr::Default::None => { + // We don't need the default value, to prevent an unused variable warning + // we'll leave the line empty. + None + } + }; + + quote_block! { + #(#let_flags)* + + #match_keys + + #let_default + + #(#check_flags)* + + _serde::__private::Ok(()) + } +} + +fn field_i(i: usize) -> Ident { + Ident::new(&format!("__field{}", i), Span::call_site()) +} + +/// This function wraps the expression in `#[serde(deserialize_with = "...")]` +/// in a trait to prevent it from accessing the internal `Deserialize` state. +fn wrap_deserialize_with( + params: &Parameters, + value_ty: &TokenStream, + deserialize_with: &syn::ExprPath, +) -> (TokenStream, TokenStream) { + let this_type = ¶ms.this_type; + let (de_impl_generics, de_ty_generics, ty_generics, where_clause) = + split_with_de_lifetime(params); + let delife = params.borrowed.de_lifetime(); + + let wrapper = quote! { + #[doc(hidden)] + struct __DeserializeWith #de_impl_generics #where_clause { + value: #value_ty, + phantom: _serde::__private::PhantomData<#this_type #ty_generics>, + lifetime: _serde::__private::PhantomData<&#delife ()>, + } + + impl #de_impl_generics _serde::Deserialize<#delife> for __DeserializeWith #de_ty_generics #where_clause { + fn deserialize<__D>(__deserializer: __D) -> _serde::__private::Result + where + __D: _serde::Deserializer<#delife>, + { + _serde::__private::Ok(__DeserializeWith { + value: #deserialize_with(__deserializer)?, + phantom: _serde::__private::PhantomData, + lifetime: _serde::__private::PhantomData, + }) + } + } + }; + + let wrapper_ty = quote!(__DeserializeWith #de_ty_generics); + + (wrapper, wrapper_ty) +} + +fn wrap_deserialize_field_with( + params: &Parameters, + field_ty: &syn::Type, + deserialize_with: &syn::ExprPath, +) -> (TokenStream, TokenStream) { + wrap_deserialize_with(params, "e!(#field_ty), deserialize_with) +} + +fn wrap_deserialize_variant_with( + params: &Parameters, + variant: &Variant, + deserialize_with: &syn::ExprPath, +) -> (TokenStream, TokenStream, TokenStream) { + let field_tys = variant.fields.iter().map(|field| field.ty); + let (wrapper, wrapper_ty) = + wrap_deserialize_with(params, "e!((#(#field_tys),*)), deserialize_with); + + let unwrap_fn = unwrap_to_variant_closure(params, variant, true); + + (wrapper, wrapper_ty, unwrap_fn) +} + +// Generates closure that converts single input parameter to the final value. +fn unwrap_to_variant_closure( + params: &Parameters, + variant: &Variant, + with_wrapper: bool, +) -> TokenStream { + let this_value = ¶ms.this_value; + let variant_ident = &variant.ident; + + let (arg, wrapper) = if with_wrapper { + (quote! { __wrap }, quote! { __wrap.value }) + } else { + let field_tys = variant.fields.iter().map(|field| field.ty); + (quote! { __wrap: (#(#field_tys),*) }, quote! { __wrap }) + }; + + let field_access = (0..variant.fields.len()).map(|n| { + Member::Unnamed(Index { + index: n as u32, + span: Span::call_site(), + }) + }); + + match variant.style { + Style::Struct if variant.fields.len() == 1 => { + let member = &variant.fields[0].member; + quote! { + |#arg| #this_value::#variant_ident { #member: #wrapper } + } + } + Style::Struct => { + let members = variant.fields.iter().map(|field| &field.member); + quote! { + |#arg| #this_value::#variant_ident { #(#members: #wrapper.#field_access),* } + } + } + Style::Tuple => quote! { + |#arg| #this_value::#variant_ident(#(#wrapper.#field_access),*) + }, + Style::Newtype => quote! { + |#arg| #this_value::#variant_ident(#wrapper) + }, + Style::Unit => quote! { + |#arg| #this_value::#variant_ident + }, + } +} + +fn expr_is_missing(field: &Field, cattrs: &attr::Container) -> Fragment { + match field.attrs.default() { + attr::Default::Default => { + let span = field.original.span(); + let func = quote_spanned!(span=> _serde::__private::Default::default); + return quote_expr!(#func()); + } + attr::Default::Path(path) => { + return quote_expr!(#path()); + } + attr::Default::None => { /* below */ } + } + + match *cattrs.default() { + attr::Default::Default | attr::Default::Path(_) => { + let member = &field.member; + return quote_expr!(__default.#member); + } + attr::Default::None => { /* below */ } + } + + let name = field.attrs.name().deserialize_name(); + match field.attrs.deserialize_with() { + None => { + let span = field.original.span(); + let func = quote_spanned!(span=> _serde::__private::de::missing_field); + quote_expr! { + #func(#name)? + } + } + Some(_) => { + quote_expr! { + return _serde::__private::Err(<__A::Error as _serde::de::Error>::missing_field(#name)) + } + } + } +} + +fn expr_is_missing_seq( + assign_to: Option, + index: usize, + field: &Field, + cattrs: &attr::Container, + expecting: &str, +) -> TokenStream { + match field.attrs.default() { + attr::Default::Default => { + let span = field.original.span(); + return quote_spanned!(span=> #assign_to _serde::__private::Default::default()); + } + attr::Default::Path(path) => { + return quote_spanned!(path.span()=> #assign_to #path()); + } + attr::Default::None => { /* below */ } + } + + match *cattrs.default() { + attr::Default::Default | attr::Default::Path(_) => { + let member = &field.member; + quote!(#assign_to __default.#member) + } + attr::Default::None => quote!( + return _serde::__private::Err(_serde::de::Error::invalid_length(#index, &#expecting)) + ), + } +} + +fn effective_style(variant: &Variant) -> Style { + match variant.style { + Style::Newtype if variant.fields[0].attrs.skip_deserializing() => Style::Unit, + other => other, + } +} + +/// True if there is any field with a `#[serde(flatten)]` attribute, other than +/// fields which are skipped. +fn has_flatten(fields: &[Field]) -> bool { + fields + .iter() + .any(|field| field.attrs.flatten() && !field.attrs.skip_deserializing()) +} + +struct DeImplGenerics<'a>(&'a Parameters); +#[cfg(feature = "deserialize_in_place")] +struct InPlaceImplGenerics<'a>(&'a Parameters); + +impl<'a> ToTokens for DeImplGenerics<'a> { + fn to_tokens(&self, tokens: &mut TokenStream) { + let mut generics = self.0.generics.clone(); + if let Some(de_lifetime) = self.0.borrowed.de_lifetime_param() { + generics.params = Some(syn::GenericParam::Lifetime(de_lifetime)) + .into_iter() + .chain(generics.params) + .collect(); + } + let (impl_generics, _, _) = generics.split_for_impl(); + impl_generics.to_tokens(tokens); + } +} + +#[cfg(feature = "deserialize_in_place")] +impl<'a> ToTokens for InPlaceImplGenerics<'a> { + fn to_tokens(&self, tokens: &mut TokenStream) { + let place_lifetime = place_lifetime(); + let mut generics = self.0.generics.clone(); + + // Add lifetime for `&'place mut Self, and `'a: 'place` + for param in &mut generics.params { + match param { + syn::GenericParam::Lifetime(param) => { + param.bounds.push(place_lifetime.lifetime.clone()); + } + syn::GenericParam::Type(param) => { + param.bounds.push(syn::TypeParamBound::Lifetime( + place_lifetime.lifetime.clone(), + )); + } + syn::GenericParam::Const(_) => {} + } + } + generics.params = Some(syn::GenericParam::Lifetime(place_lifetime)) + .into_iter() + .chain(generics.params) + .collect(); + if let Some(de_lifetime) = self.0.borrowed.de_lifetime_param() { + generics.params = Some(syn::GenericParam::Lifetime(de_lifetime)) + .into_iter() + .chain(generics.params) + .collect(); + } + let (impl_generics, _, _) = generics.split_for_impl(); + impl_generics.to_tokens(tokens); + } +} + +#[cfg(feature = "deserialize_in_place")] +impl<'a> DeImplGenerics<'a> { + fn in_place(self) -> InPlaceImplGenerics<'a> { + InPlaceImplGenerics(self.0) + } +} + +struct DeTypeGenerics<'a>(&'a Parameters); +#[cfg(feature = "deserialize_in_place")] +struct InPlaceTypeGenerics<'a>(&'a Parameters); + +fn de_type_generics_to_tokens( + mut generics: syn::Generics, + borrowed: &BorrowedLifetimes, + tokens: &mut TokenStream, +) { + if borrowed.de_lifetime_param().is_some() { + let def = syn::LifetimeParam { + attrs: Vec::new(), + lifetime: syn::Lifetime::new("'de", Span::call_site()), + colon_token: None, + bounds: Punctuated::new(), + }; + // Prepend 'de lifetime to list of generics + generics.params = Some(syn::GenericParam::Lifetime(def)) + .into_iter() + .chain(generics.params) + .collect(); + } + let (_, ty_generics, _) = generics.split_for_impl(); + ty_generics.to_tokens(tokens); +} + +impl<'a> ToTokens for DeTypeGenerics<'a> { + fn to_tokens(&self, tokens: &mut TokenStream) { + de_type_generics_to_tokens(self.0.generics.clone(), &self.0.borrowed, tokens); + } +} + +#[cfg(feature = "deserialize_in_place")] +impl<'a> ToTokens for InPlaceTypeGenerics<'a> { + fn to_tokens(&self, tokens: &mut TokenStream) { + let mut generics = self.0.generics.clone(); + generics.params = Some(syn::GenericParam::Lifetime(place_lifetime())) + .into_iter() + .chain(generics.params) + .collect(); + + de_type_generics_to_tokens(generics, &self.0.borrowed, tokens); + } +} + +#[cfg(feature = "deserialize_in_place")] +impl<'a> DeTypeGenerics<'a> { + fn in_place(self) -> InPlaceTypeGenerics<'a> { + InPlaceTypeGenerics(self.0) + } +} + +#[cfg(feature = "deserialize_in_place")] +fn place_lifetime() -> syn::LifetimeParam { + syn::LifetimeParam { + attrs: Vec::new(), + lifetime: syn::Lifetime::new("'place", Span::call_site()), + colon_token: None, + bounds: Punctuated::new(), + } +} + +fn split_with_de_lifetime( + params: &Parameters, +) -> ( + DeImplGenerics, + DeTypeGenerics, + syn::TypeGenerics, + Option<&syn::WhereClause>, +) { + let de_impl_generics = DeImplGenerics(params); + let de_ty_generics = DeTypeGenerics(params); + let (_, ty_generics, where_clause) = params.generics.split_for_impl(); + (de_impl_generics, de_ty_generics, ty_generics, where_clause) +} diff --git a/vendor/serde_derive/src/dummy.rs b/vendor/serde_derive/src/dummy.rs new file mode 100644 index 0000000..095f950 --- /dev/null +++ b/vendor/serde_derive/src/dummy.rs @@ -0,0 +1,23 @@ +use proc_macro2::TokenStream; +use quote::quote; + +pub fn wrap_in_const(serde_path: Option<&syn::Path>, code: TokenStream) -> TokenStream { + let use_serde = match serde_path { + Some(path) => quote! { + use #path as _serde; + }, + None => quote! { + #[allow(unused_extern_crates, clippy::useless_attribute)] + extern crate serde as _serde; + }, + }; + + quote! { + #[doc(hidden)] + #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] + const _: () = { + #use_serde + #code + }; + } +} diff --git a/vendor/serde_derive/src/fragment.rs b/vendor/serde_derive/src/fragment.rs new file mode 100644 index 0000000..6627c26 --- /dev/null +++ b/vendor/serde_derive/src/fragment.rs @@ -0,0 +1,74 @@ +use proc_macro2::TokenStream; +use quote::ToTokens; +use syn::{token, Token}; + +pub enum Fragment { + /// Tokens that can be used as an expression. + Expr(TokenStream), + /// Tokens that can be used inside a block. The surrounding curly braces are + /// not part of these tokens. + Block(TokenStream), +} + +macro_rules! quote_expr { + ($($tt:tt)*) => { + $crate::fragment::Fragment::Expr(quote!($($tt)*)) + } +} + +macro_rules! quote_block { + ($($tt:tt)*) => { + $crate::fragment::Fragment::Block(quote!($($tt)*)) + } +} + +/// Interpolate a fragment in place of an expression. This involves surrounding +/// Block fragments in curly braces. +pub struct Expr(pub Fragment); +impl ToTokens for Expr { + fn to_tokens(&self, out: &mut TokenStream) { + match &self.0 { + Fragment::Expr(expr) => expr.to_tokens(out), + Fragment::Block(block) => { + token::Brace::default().surround(out, |out| block.to_tokens(out)); + } + } + } +} + +/// Interpolate a fragment as the statements of a block. +pub struct Stmts(pub Fragment); +impl ToTokens for Stmts { + fn to_tokens(&self, out: &mut TokenStream) { + match &self.0 { + Fragment::Expr(expr) => expr.to_tokens(out), + Fragment::Block(block) => block.to_tokens(out), + } + } +} + +/// Interpolate a fragment as the value part of a `match` expression. This +/// involves putting a comma after expressions and curly braces around blocks. +pub struct Match(pub Fragment); +impl ToTokens for Match { + fn to_tokens(&self, out: &mut TokenStream) { + match &self.0 { + Fragment::Expr(expr) => { + expr.to_tokens(out); + ::default().to_tokens(out); + } + Fragment::Block(block) => { + token::Brace::default().surround(out, |out| block.to_tokens(out)); + } + } + } +} + +impl AsRef for Fragment { + fn as_ref(&self) -> &TokenStream { + match self { + Fragment::Expr(expr) => expr, + Fragment::Block(block) => block, + } + } +} diff --git a/vendor/serde_derive/src/internals/ast.rs b/vendor/serde_derive/src/internals/ast.rs new file mode 100644 index 0000000..3293823 --- /dev/null +++ b/vendor/serde_derive/src/internals/ast.rs @@ -0,0 +1,205 @@ +//! A Serde ast, parsed from the Syn ast and ready to generate Rust code. + +use crate::internals::{attr, check, Ctxt, Derive}; +use syn::punctuated::Punctuated; +use syn::Token; + +/// A source data structure annotated with `#[derive(Serialize)]` and/or `#[derive(Deserialize)]`, +/// parsed into an internal representation. +pub struct Container<'a> { + /// The struct or enum name (without generics). + pub ident: syn::Ident, + /// Attributes on the structure, parsed for Serde. + pub attrs: attr::Container, + /// The contents of the struct or enum. + pub data: Data<'a>, + /// Any generics on the struct or enum. + pub generics: &'a syn::Generics, + /// Original input. + pub original: &'a syn::DeriveInput, +} + +/// The fields of a struct or enum. +/// +/// Analogous to `syn::Data`. +pub enum Data<'a> { + Enum(Vec>), + Struct(Style, Vec>), +} + +/// A variant of an enum. +pub struct Variant<'a> { + pub ident: syn::Ident, + pub attrs: attr::Variant, + pub style: Style, + pub fields: Vec>, + pub original: &'a syn::Variant, +} + +/// A field of a struct. +pub struct Field<'a> { + pub member: syn::Member, + pub attrs: attr::Field, + pub ty: &'a syn::Type, + pub original: &'a syn::Field, +} + +#[derive(Copy, Clone)] +pub enum Style { + /// Named fields. + Struct, + /// Many unnamed fields. + Tuple, + /// One unnamed field. + Newtype, + /// No fields. + Unit, +} + +impl<'a> Container<'a> { + /// Convert the raw Syn ast into a parsed container object, collecting errors in `cx`. + pub fn from_ast( + cx: &Ctxt, + item: &'a syn::DeriveInput, + derive: Derive, + ) -> Option> { + let attrs = attr::Container::from_ast(cx, item); + + let mut data = match &item.data { + syn::Data::Enum(data) => Data::Enum(enum_from_ast(cx, &data.variants, attrs.default())), + syn::Data::Struct(data) => { + let (style, fields) = struct_from_ast(cx, &data.fields, None, attrs.default()); + Data::Struct(style, fields) + } + syn::Data::Union(_) => { + cx.error_spanned_by(item, "Serde does not support derive for unions"); + return None; + } + }; + + match &mut data { + Data::Enum(variants) => { + for variant in variants { + variant.attrs.rename_by_rules(attrs.rename_all_rules()); + for field in &mut variant.fields { + field.attrs.rename_by_rules( + variant + .attrs + .rename_all_rules() + .or(attrs.rename_all_fields_rules()), + ); + } + } + } + Data::Struct(_, fields) => { + for field in fields { + field.attrs.rename_by_rules(attrs.rename_all_rules()); + } + } + } + + let mut item = Container { + ident: item.ident.clone(), + attrs, + data, + generics: &item.generics, + original: item, + }; + check::check(cx, &mut item, derive); + Some(item) + } +} + +impl<'a> Data<'a> { + pub fn all_fields(&'a self) -> Box> + 'a> { + match self { + Data::Enum(variants) => { + Box::new(variants.iter().flat_map(|variant| variant.fields.iter())) + } + Data::Struct(_, fields) => Box::new(fields.iter()), + } + } + + pub fn has_getter(&self) -> bool { + self.all_fields().any(|f| f.attrs.getter().is_some()) + } +} + +fn enum_from_ast<'a>( + cx: &Ctxt, + variants: &'a Punctuated, + container_default: &attr::Default, +) -> Vec> { + let variants: Vec = variants + .iter() + .map(|variant| { + let attrs = attr::Variant::from_ast(cx, variant); + let (style, fields) = + struct_from_ast(cx, &variant.fields, Some(&attrs), container_default); + Variant { + ident: variant.ident.clone(), + attrs, + style, + fields, + original: variant, + } + }) + .collect(); + + let index_of_last_tagged_variant = variants + .iter() + .rposition(|variant| !variant.attrs.untagged()); + if let Some(index_of_last_tagged_variant) = index_of_last_tagged_variant { + for variant in &variants[..index_of_last_tagged_variant] { + if variant.attrs.untagged() { + cx.error_spanned_by(&variant.ident, "all variants with the #[serde(untagged)] attribute must be placed at the end of the enum"); + } + } + } + + variants +} + +fn struct_from_ast<'a>( + cx: &Ctxt, + fields: &'a syn::Fields, + attrs: Option<&attr::Variant>, + container_default: &attr::Default, +) -> (Style, Vec>) { + match fields { + syn::Fields::Named(fields) => ( + Style::Struct, + fields_from_ast(cx, &fields.named, attrs, container_default), + ), + syn::Fields::Unnamed(fields) if fields.unnamed.len() == 1 => ( + Style::Newtype, + fields_from_ast(cx, &fields.unnamed, attrs, container_default), + ), + syn::Fields::Unnamed(fields) => ( + Style::Tuple, + fields_from_ast(cx, &fields.unnamed, attrs, container_default), + ), + syn::Fields::Unit => (Style::Unit, Vec::new()), + } +} + +fn fields_from_ast<'a>( + cx: &Ctxt, + fields: &'a Punctuated, + attrs: Option<&attr::Variant>, + container_default: &attr::Default, +) -> Vec> { + fields + .iter() + .enumerate() + .map(|(i, field)| Field { + member: match &field.ident { + Some(ident) => syn::Member::Named(ident.clone()), + None => syn::Member::Unnamed(i.into()), + }, + attrs: attr::Field::from_ast(cx, i, field, attrs, container_default), + ty: &field.ty, + original: field, + }) + .collect() +} diff --git a/vendor/serde_derive/src/internals/attr.rs b/vendor/serde_derive/src/internals/attr.rs new file mode 100644 index 0000000..ac5f5d9 --- /dev/null +++ b/vendor/serde_derive/src/internals/attr.rs @@ -0,0 +1,1871 @@ +use crate::internals::symbol::*; +use crate::internals::{ungroup, Ctxt}; +use proc_macro2::{Spacing, Span, TokenStream, TokenTree}; +use quote::ToTokens; +use std::borrow::Cow; +use std::collections::BTreeSet; +use std::iter::FromIterator; +use syn::meta::ParseNestedMeta; +use syn::parse::ParseStream; +use syn::punctuated::Punctuated; +use syn::{parse_quote, token, Ident, Lifetime, Token}; + +// This module handles parsing of `#[serde(...)]` attributes. The entrypoints +// are `attr::Container::from_ast`, `attr::Variant::from_ast`, and +// `attr::Field::from_ast`. Each returns an instance of the corresponding +// struct. Note that none of them return a Result. Unrecognized, malformed, or +// duplicated attributes result in a span_err but otherwise are ignored. The +// user will see errors simultaneously for all bad attributes in the crate +// rather than just the first. + +pub use crate::internals::case::RenameRule; + +struct Attr<'c, T> { + cx: &'c Ctxt, + name: Symbol, + tokens: TokenStream, + value: Option, +} + +impl<'c, T> Attr<'c, T> { + fn none(cx: &'c Ctxt, name: Symbol) -> Self { + Attr { + cx, + name, + tokens: TokenStream::new(), + value: None, + } + } + + fn set(&mut self, obj: A, value: T) { + let tokens = obj.into_token_stream(); + + if self.value.is_some() { + let msg = format!("duplicate serde attribute `{}`", self.name); + self.cx.error_spanned_by(tokens, msg); + } else { + self.tokens = tokens; + self.value = Some(value); + } + } + + fn set_opt(&mut self, obj: A, value: Option) { + if let Some(value) = value { + self.set(obj, value); + } + } + + fn set_if_none(&mut self, value: T) { + if self.value.is_none() { + self.value = Some(value); + } + } + + fn get(self) -> Option { + self.value + } + + fn get_with_tokens(self) -> Option<(TokenStream, T)> { + match self.value { + Some(v) => Some((self.tokens, v)), + None => None, + } + } +} + +struct BoolAttr<'c>(Attr<'c, ()>); + +impl<'c> BoolAttr<'c> { + fn none(cx: &'c Ctxt, name: Symbol) -> Self { + BoolAttr(Attr::none(cx, name)) + } + + fn set_true(&mut self, obj: A) { + self.0.set(obj, ()); + } + + fn get(&self) -> bool { + self.0.value.is_some() + } +} + +struct VecAttr<'c, T> { + cx: &'c Ctxt, + name: Symbol, + first_dup_tokens: TokenStream, + values: Vec, +} + +impl<'c, T> VecAttr<'c, T> { + fn none(cx: &'c Ctxt, name: Symbol) -> Self { + VecAttr { + cx, + name, + first_dup_tokens: TokenStream::new(), + values: Vec::new(), + } + } + + fn insert(&mut self, obj: A, value: T) { + if self.values.len() == 1 { + self.first_dup_tokens = obj.into_token_stream(); + } + self.values.push(value); + } + + fn at_most_one(mut self) -> Option { + if self.values.len() > 1 { + let dup_token = self.first_dup_tokens; + let msg = format!("duplicate serde attribute `{}`", self.name); + self.cx.error_spanned_by(dup_token, msg); + None + } else { + self.values.pop() + } + } + + fn get(self) -> Vec { + self.values + } +} + +pub struct Name { + serialize: String, + serialize_renamed: bool, + deserialize: String, + deserialize_renamed: bool, + deserialize_aliases: BTreeSet, +} + +fn unraw(ident: &Ident) -> String { + ident.to_string().trim_start_matches("r#").to_owned() +} + +impl Name { + fn from_attrs( + source_name: String, + ser_name: Attr, + de_name: Attr, + de_aliases: Option>, + ) -> Name { + let mut alias_set = BTreeSet::new(); + if let Some(de_aliases) = de_aliases { + for alias_name in de_aliases.get() { + alias_set.insert(alias_name); + } + } + + let ser_name = ser_name.get(); + let ser_renamed = ser_name.is_some(); + let de_name = de_name.get(); + let de_renamed = de_name.is_some(); + Name { + serialize: ser_name.unwrap_or_else(|| source_name.clone()), + serialize_renamed: ser_renamed, + deserialize: de_name.unwrap_or(source_name), + deserialize_renamed: de_renamed, + deserialize_aliases: alias_set, + } + } + + /// Return the container name for the container when serializing. + pub fn serialize_name(&self) -> &str { + &self.serialize + } + + /// Return the container name for the container when deserializing. + pub fn deserialize_name(&self) -> &str { + &self.deserialize + } + + fn deserialize_aliases(&self) -> &BTreeSet { + &self.deserialize_aliases + } +} + +#[derive(Copy, Clone)] +pub struct RenameAllRules { + pub serialize: RenameRule, + pub deserialize: RenameRule, +} + +impl RenameAllRules { + /// Returns a new `RenameAllRules` with the individual rules of `self` and + /// `other_rules` joined by `RenameRules::or`. + pub fn or(self, other_rules: Self) -> Self { + Self { + serialize: self.serialize.or(other_rules.serialize), + deserialize: self.deserialize.or(other_rules.deserialize), + } + } +} + +/// Represents struct or enum attribute information. +pub struct Container { + name: Name, + transparent: bool, + deny_unknown_fields: bool, + default: Default, + rename_all_rules: RenameAllRules, + rename_all_fields_rules: RenameAllRules, + ser_bound: Option>, + de_bound: Option>, + tag: TagType, + type_from: Option, + type_try_from: Option, + type_into: Option, + remote: Option, + identifier: Identifier, + serde_path: Option, + is_packed: bool, + /// Error message generated when type can't be deserialized + expecting: Option, + non_exhaustive: bool, +} + +/// Styles of representing an enum. +pub enum TagType { + /// The default. + /// + /// ```json + /// {"variant1": {"key1": "value1", "key2": "value2"}} + /// ``` + External, + + /// `#[serde(tag = "type")]` + /// + /// ```json + /// {"type": "variant1", "key1": "value1", "key2": "value2"} + /// ``` + Internal { tag: String }, + + /// `#[serde(tag = "t", content = "c")]` + /// + /// ```json + /// {"t": "variant1", "c": {"key1": "value1", "key2": "value2"}} + /// ``` + Adjacent { tag: String, content: String }, + + /// `#[serde(untagged)]` + /// + /// ```json + /// {"key1": "value1", "key2": "value2"} + /// ``` + None, +} + +/// Whether this enum represents the fields of a struct or the variants of an +/// enum. +#[derive(Copy, Clone)] +pub enum Identifier { + /// It does not. + No, + + /// This enum represents the fields of a struct. All of the variants must be + /// unit variants, except possibly one which is annotated with + /// `#[serde(other)]` and is a newtype variant. + Field, + + /// This enum represents the variants of an enum. All of the variants must + /// be unit variants. + Variant, +} + +impl Identifier { + #[cfg(feature = "deserialize_in_place")] + pub fn is_some(self) -> bool { + match self { + Identifier::No => false, + Identifier::Field | Identifier::Variant => true, + } + } +} + +impl Container { + /// Extract out the `#[serde(...)]` attributes from an item. + pub fn from_ast(cx: &Ctxt, item: &syn::DeriveInput) -> Self { + let mut ser_name = Attr::none(cx, RENAME); + let mut de_name = Attr::none(cx, RENAME); + let mut transparent = BoolAttr::none(cx, TRANSPARENT); + let mut deny_unknown_fields = BoolAttr::none(cx, DENY_UNKNOWN_FIELDS); + let mut default = Attr::none(cx, DEFAULT); + let mut rename_all_ser_rule = Attr::none(cx, RENAME_ALL); + let mut rename_all_de_rule = Attr::none(cx, RENAME_ALL); + let mut rename_all_fields_ser_rule = Attr::none(cx, RENAME_ALL_FIELDS); + let mut rename_all_fields_de_rule = Attr::none(cx, RENAME_ALL_FIELDS); + let mut ser_bound = Attr::none(cx, BOUND); + let mut de_bound = Attr::none(cx, BOUND); + let mut untagged = BoolAttr::none(cx, UNTAGGED); + let mut internal_tag = Attr::none(cx, TAG); + let mut content = Attr::none(cx, CONTENT); + let mut type_from = Attr::none(cx, FROM); + let mut type_try_from = Attr::none(cx, TRY_FROM); + let mut type_into = Attr::none(cx, INTO); + let mut remote = Attr::none(cx, REMOTE); + let mut field_identifier = BoolAttr::none(cx, FIELD_IDENTIFIER); + let mut variant_identifier = BoolAttr::none(cx, VARIANT_IDENTIFIER); + let mut serde_path = Attr::none(cx, CRATE); + let mut expecting = Attr::none(cx, EXPECTING); + let mut non_exhaustive = false; + + for attr in &item.attrs { + if attr.path() != SERDE { + non_exhaustive |= + matches!(&attr.meta, syn::Meta::Path(path) if path == NON_EXHAUSTIVE); + continue; + } + + if let syn::Meta::List(meta) = &attr.meta { + if meta.tokens.is_empty() { + continue; + } + } + + if let Err(err) = attr.parse_nested_meta(|meta| { + if meta.path == RENAME { + // #[serde(rename = "foo")] + // #[serde(rename(serialize = "foo", deserialize = "bar"))] + let (ser, de) = get_renames(cx, RENAME, &meta)?; + ser_name.set_opt(&meta.path, ser.as_ref().map(syn::LitStr::value)); + de_name.set_opt(&meta.path, de.as_ref().map(syn::LitStr::value)); + } else if meta.path == RENAME_ALL { + // #[serde(rename_all = "foo")] + // #[serde(rename_all(serialize = "foo", deserialize = "bar"))] + let one_name = meta.input.peek(Token![=]); + let (ser, de) = get_renames(cx, RENAME_ALL, &meta)?; + if let Some(ser) = ser { + match RenameRule::from_str(&ser.value()) { + Ok(rename_rule) => rename_all_ser_rule.set(&meta.path, rename_rule), + Err(err) => cx.error_spanned_by(ser, err), + } + } + if let Some(de) = de { + match RenameRule::from_str(&de.value()) { + Ok(rename_rule) => rename_all_de_rule.set(&meta.path, rename_rule), + Err(err) => { + if !one_name { + cx.error_spanned_by(de, err); + } + } + } + } + } else if meta.path == RENAME_ALL_FIELDS { + // #[serde(rename_all_fields = "foo")] + // #[serde(rename_all_fields(serialize = "foo", deserialize = "bar"))] + let one_name = meta.input.peek(Token![=]); + let (ser, de) = get_renames(cx, RENAME_ALL_FIELDS, &meta)?; + + match item.data { + syn::Data::Enum(_) => { + if let Some(ser) = ser { + match RenameRule::from_str(&ser.value()) { + Ok(rename_rule) => { + rename_all_fields_ser_rule.set(&meta.path, rename_rule); + } + Err(err) => cx.error_spanned_by(ser, err), + } + } + if let Some(de) = de { + match RenameRule::from_str(&de.value()) { + Ok(rename_rule) => { + rename_all_fields_de_rule.set(&meta.path, rename_rule); + } + Err(err) => { + if !one_name { + cx.error_spanned_by(de, err); + } + } + } + } + } + syn::Data::Struct(_) => { + let msg = "#[serde(rename_all_fields)] can only be used on enums"; + cx.syn_error(meta.error(msg)); + } + syn::Data::Union(_) => { + let msg = "#[serde(rename_all_fields)] can only be used on enums"; + cx.syn_error(meta.error(msg)); + } + } + } else if meta.path == TRANSPARENT { + // #[serde(transparent)] + transparent.set_true(meta.path); + } else if meta.path == DENY_UNKNOWN_FIELDS { + // #[serde(deny_unknown_fields)] + deny_unknown_fields.set_true(meta.path); + } else if meta.path == DEFAULT { + if meta.input.peek(Token![=]) { + // #[serde(default = "...")] + if let Some(path) = parse_lit_into_expr_path(cx, DEFAULT, &meta)? { + match &item.data { + syn::Data::Struct(syn::DataStruct { fields, .. }) => match fields { + syn::Fields::Named(_) | syn::Fields::Unnamed(_) => { + default.set(&meta.path, Default::Path(path)); + } + syn::Fields::Unit => { + let msg = "#[serde(default = \"...\")] can only be used on structs that have fields"; + cx.syn_error(meta.error(msg)); + } + }, + syn::Data::Enum(_) => { + let msg = "#[serde(default = \"...\")] can only be used on structs"; + cx.syn_error(meta.error(msg)); + } + syn::Data::Union(_) => { + let msg = "#[serde(default = \"...\")] can only be used on structs"; + cx.syn_error(meta.error(msg)); + } + } + } + } else { + // #[serde(default)] + match &item.data { + syn::Data::Struct(syn::DataStruct { fields, .. }) => match fields { + syn::Fields::Named(_) | syn::Fields::Unnamed(_) => { + default.set(meta.path, Default::Default); + } + syn::Fields::Unit => { + let msg = "#[serde(default)] can only be used on structs that have fields"; + cx.error_spanned_by(fields, msg); + } + }, + syn::Data::Enum(_) => { + let msg = "#[serde(default)] can only be used on structs"; + cx.syn_error(meta.error(msg)); + } + syn::Data::Union(_) => { + let msg = "#[serde(default)] can only be used on structs"; + cx.syn_error(meta.error(msg)); + } + } + } + } else if meta.path == BOUND { + // #[serde(bound = "T: SomeBound")] + // #[serde(bound(serialize = "...", deserialize = "..."))] + let (ser, de) = get_where_predicates(cx, &meta)?; + ser_bound.set_opt(&meta.path, ser); + de_bound.set_opt(&meta.path, de); + } else if meta.path == UNTAGGED { + // #[serde(untagged)] + match item.data { + syn::Data::Enum(_) => { + untagged.set_true(&meta.path); + } + syn::Data::Struct(_) => { + let msg = "#[serde(untagged)] can only be used on enums"; + cx.syn_error(meta.error(msg)); + } + syn::Data::Union(_) => { + let msg = "#[serde(untagged)] can only be used on enums"; + cx.syn_error(meta.error(msg)); + } + } + } else if meta.path == TAG { + // #[serde(tag = "type")] + if let Some(s) = get_lit_str(cx, TAG, &meta)? { + match &item.data { + syn::Data::Enum(_) => { + internal_tag.set(&meta.path, s.value()); + } + syn::Data::Struct(syn::DataStruct { fields, .. }) => match fields { + syn::Fields::Named(_) => { + internal_tag.set(&meta.path, s.value()); + } + syn::Fields::Unnamed(_) | syn::Fields::Unit => { + let msg = "#[serde(tag = \"...\")] can only be used on enums and structs with named fields"; + cx.syn_error(meta.error(msg)); + } + }, + syn::Data::Union(_) => { + let msg = "#[serde(tag = \"...\")] can only be used on enums and structs with named fields"; + cx.syn_error(meta.error(msg)); + } + } + } + } else if meta.path == CONTENT { + // #[serde(content = "c")] + if let Some(s) = get_lit_str(cx, CONTENT, &meta)? { + match &item.data { + syn::Data::Enum(_) => { + content.set(&meta.path, s.value()); + } + syn::Data::Struct(_) => { + let msg = "#[serde(content = \"...\")] can only be used on enums"; + cx.syn_error(meta.error(msg)); + } + syn::Data::Union(_) => { + let msg = "#[serde(content = \"...\")] can only be used on enums"; + cx.syn_error(meta.error(msg)); + } + } + } + } else if meta.path == FROM { + // #[serde(from = "Type")] + if let Some(from_ty) = parse_lit_into_ty(cx, FROM, &meta)? { + type_from.set_opt(&meta.path, Some(from_ty)); + } + } else if meta.path == TRY_FROM { + // #[serde(try_from = "Type")] + if let Some(try_from_ty) = parse_lit_into_ty(cx, TRY_FROM, &meta)? { + type_try_from.set_opt(&meta.path, Some(try_from_ty)); + } + } else if meta.path == INTO { + // #[serde(into = "Type")] + if let Some(into_ty) = parse_lit_into_ty(cx, INTO, &meta)? { + type_into.set_opt(&meta.path, Some(into_ty)); + } + } else if meta.path == REMOTE { + // #[serde(remote = "...")] + if let Some(path) = parse_lit_into_path(cx, REMOTE, &meta)? { + if is_primitive_path(&path, "Self") { + remote.set(&meta.path, item.ident.clone().into()); + } else { + remote.set(&meta.path, path); + } + } + } else if meta.path == FIELD_IDENTIFIER { + // #[serde(field_identifier)] + field_identifier.set_true(&meta.path); + } else if meta.path == VARIANT_IDENTIFIER { + // #[serde(variant_identifier)] + variant_identifier.set_true(&meta.path); + } else if meta.path == CRATE { + // #[serde(crate = "foo")] + if let Some(path) = parse_lit_into_path(cx, CRATE, &meta)? { + serde_path.set(&meta.path, path); + } + } else if meta.path == EXPECTING { + // #[serde(expecting = "a message")] + if let Some(s) = get_lit_str(cx, EXPECTING, &meta)? { + expecting.set(&meta.path, s.value()); + } + } else { + let path = meta.path.to_token_stream().to_string().replace(' ', ""); + return Err( + meta.error(format_args!("unknown serde container attribute `{}`", path)) + ); + } + Ok(()) + }) { + cx.syn_error(err); + } + } + + let mut is_packed = false; + for attr in &item.attrs { + if attr.path() == REPR { + let _ = attr.parse_args_with(|input: ParseStream| { + while let Some(token) = input.parse()? { + if let TokenTree::Ident(ident) = token { + is_packed |= ident == "packed"; + } + } + Ok(()) + }); + } + } + + Container { + name: Name::from_attrs(unraw(&item.ident), ser_name, de_name, None), + transparent: transparent.get(), + deny_unknown_fields: deny_unknown_fields.get(), + default: default.get().unwrap_or(Default::None), + rename_all_rules: RenameAllRules { + serialize: rename_all_ser_rule.get().unwrap_or(RenameRule::None), + deserialize: rename_all_de_rule.get().unwrap_or(RenameRule::None), + }, + rename_all_fields_rules: RenameAllRules { + serialize: rename_all_fields_ser_rule.get().unwrap_or(RenameRule::None), + deserialize: rename_all_fields_de_rule.get().unwrap_or(RenameRule::None), + }, + ser_bound: ser_bound.get(), + de_bound: de_bound.get(), + tag: decide_tag(cx, item, untagged, internal_tag, content), + type_from: type_from.get(), + type_try_from: type_try_from.get(), + type_into: type_into.get(), + remote: remote.get(), + identifier: decide_identifier(cx, item, field_identifier, variant_identifier), + serde_path: serde_path.get(), + is_packed, + expecting: expecting.get(), + non_exhaustive, + } + } + + pub fn name(&self) -> &Name { + &self.name + } + + pub fn rename_all_rules(&self) -> RenameAllRules { + self.rename_all_rules + } + + pub fn rename_all_fields_rules(&self) -> RenameAllRules { + self.rename_all_fields_rules + } + + pub fn transparent(&self) -> bool { + self.transparent + } + + pub fn deny_unknown_fields(&self) -> bool { + self.deny_unknown_fields + } + + pub fn default(&self) -> &Default { + &self.default + } + + pub fn ser_bound(&self) -> Option<&[syn::WherePredicate]> { + self.ser_bound.as_ref().map(|vec| &vec[..]) + } + + pub fn de_bound(&self) -> Option<&[syn::WherePredicate]> { + self.de_bound.as_ref().map(|vec| &vec[..]) + } + + pub fn tag(&self) -> &TagType { + &self.tag + } + + pub fn type_from(&self) -> Option<&syn::Type> { + self.type_from.as_ref() + } + + pub fn type_try_from(&self) -> Option<&syn::Type> { + self.type_try_from.as_ref() + } + + pub fn type_into(&self) -> Option<&syn::Type> { + self.type_into.as_ref() + } + + pub fn remote(&self) -> Option<&syn::Path> { + self.remote.as_ref() + } + + pub fn is_packed(&self) -> bool { + self.is_packed + } + + pub fn identifier(&self) -> Identifier { + self.identifier + } + + pub fn custom_serde_path(&self) -> Option<&syn::Path> { + self.serde_path.as_ref() + } + + pub fn serde_path(&self) -> Cow { + self.custom_serde_path() + .map_or_else(|| Cow::Owned(parse_quote!(_serde)), Cow::Borrowed) + } + + /// Error message generated when type can't be deserialized. + /// If `None`, default message will be used + pub fn expecting(&self) -> Option<&str> { + self.expecting.as_ref().map(String::as_ref) + } + + pub fn non_exhaustive(&self) -> bool { + self.non_exhaustive + } +} + +fn decide_tag( + cx: &Ctxt, + item: &syn::DeriveInput, + untagged: BoolAttr, + internal_tag: Attr, + content: Attr, +) -> TagType { + match ( + untagged.0.get_with_tokens(), + internal_tag.get_with_tokens(), + content.get_with_tokens(), + ) { + (None, None, None) => TagType::External, + (Some(_), None, None) => TagType::None, + (None, Some((_, tag)), None) => { + // Check that there are no tuple variants. + if let syn::Data::Enum(data) = &item.data { + for variant in &data.variants { + match &variant.fields { + syn::Fields::Named(_) | syn::Fields::Unit => {} + syn::Fields::Unnamed(fields) => { + if fields.unnamed.len() != 1 { + let msg = + "#[serde(tag = \"...\")] cannot be used with tuple variants"; + cx.error_spanned_by(variant, msg); + break; + } + } + } + } + } + TagType::Internal { tag } + } + (Some((untagged_tokens, ())), Some((tag_tokens, _)), None) => { + let msg = "enum cannot be both untagged and internally tagged"; + cx.error_spanned_by(untagged_tokens, msg); + cx.error_spanned_by(tag_tokens, msg); + TagType::External // doesn't matter, will error + } + (None, None, Some((content_tokens, _))) => { + let msg = "#[serde(tag = \"...\", content = \"...\")] must be used together"; + cx.error_spanned_by(content_tokens, msg); + TagType::External + } + (Some((untagged_tokens, ())), None, Some((content_tokens, _))) => { + let msg = "untagged enum cannot have #[serde(content = \"...\")]"; + cx.error_spanned_by(untagged_tokens, msg); + cx.error_spanned_by(content_tokens, msg); + TagType::External + } + (None, Some((_, tag)), Some((_, content))) => TagType::Adjacent { tag, content }, + (Some((untagged_tokens, ())), Some((tag_tokens, _)), Some((content_tokens, _))) => { + let msg = "untagged enum cannot have #[serde(tag = \"...\", content = \"...\")]"; + cx.error_spanned_by(untagged_tokens, msg); + cx.error_spanned_by(tag_tokens, msg); + cx.error_spanned_by(content_tokens, msg); + TagType::External + } + } +} + +fn decide_identifier( + cx: &Ctxt, + item: &syn::DeriveInput, + field_identifier: BoolAttr, + variant_identifier: BoolAttr, +) -> Identifier { + match ( + &item.data, + field_identifier.0.get_with_tokens(), + variant_identifier.0.get_with_tokens(), + ) { + (_, None, None) => Identifier::No, + (_, Some((field_identifier_tokens, ())), Some((variant_identifier_tokens, ()))) => { + let msg = + "#[serde(field_identifier)] and #[serde(variant_identifier)] cannot both be set"; + cx.error_spanned_by(field_identifier_tokens, msg); + cx.error_spanned_by(variant_identifier_tokens, msg); + Identifier::No + } + (syn::Data::Enum(_), Some(_), None) => Identifier::Field, + (syn::Data::Enum(_), None, Some(_)) => Identifier::Variant, + (syn::Data::Struct(syn::DataStruct { struct_token, .. }), Some(_), None) => { + let msg = "#[serde(field_identifier)] can only be used on an enum"; + cx.error_spanned_by(struct_token, msg); + Identifier::No + } + (syn::Data::Union(syn::DataUnion { union_token, .. }), Some(_), None) => { + let msg = "#[serde(field_identifier)] can only be used on an enum"; + cx.error_spanned_by(union_token, msg); + Identifier::No + } + (syn::Data::Struct(syn::DataStruct { struct_token, .. }), None, Some(_)) => { + let msg = "#[serde(variant_identifier)] can only be used on an enum"; + cx.error_spanned_by(struct_token, msg); + Identifier::No + } + (syn::Data::Union(syn::DataUnion { union_token, .. }), None, Some(_)) => { + let msg = "#[serde(variant_identifier)] can only be used on an enum"; + cx.error_spanned_by(union_token, msg); + Identifier::No + } + } +} + +/// Represents variant attribute information +pub struct Variant { + name: Name, + rename_all_rules: RenameAllRules, + ser_bound: Option>, + de_bound: Option>, + skip_deserializing: bool, + skip_serializing: bool, + other: bool, + serialize_with: Option, + deserialize_with: Option, + borrow: Option, + untagged: bool, +} + +struct BorrowAttribute { + path: syn::Path, + lifetimes: Option>, +} + +impl Variant { + pub fn from_ast(cx: &Ctxt, variant: &syn::Variant) -> Self { + let mut ser_name = Attr::none(cx, RENAME); + let mut de_name = Attr::none(cx, RENAME); + let mut de_aliases = VecAttr::none(cx, RENAME); + let mut skip_deserializing = BoolAttr::none(cx, SKIP_DESERIALIZING); + let mut skip_serializing = BoolAttr::none(cx, SKIP_SERIALIZING); + let mut rename_all_ser_rule = Attr::none(cx, RENAME_ALL); + let mut rename_all_de_rule = Attr::none(cx, RENAME_ALL); + let mut ser_bound = Attr::none(cx, BOUND); + let mut de_bound = Attr::none(cx, BOUND); + let mut other = BoolAttr::none(cx, OTHER); + let mut serialize_with = Attr::none(cx, SERIALIZE_WITH); + let mut deserialize_with = Attr::none(cx, DESERIALIZE_WITH); + let mut borrow = Attr::none(cx, BORROW); + let mut untagged = BoolAttr::none(cx, UNTAGGED); + + for attr in &variant.attrs { + if attr.path() != SERDE { + continue; + } + + if let syn::Meta::List(meta) = &attr.meta { + if meta.tokens.is_empty() { + continue; + } + } + + if let Err(err) = attr.parse_nested_meta(|meta| { + if meta.path == RENAME { + // #[serde(rename = "foo")] + // #[serde(rename(serialize = "foo", deserialize = "bar"))] + let (ser, de) = get_multiple_renames(cx, &meta)?; + ser_name.set_opt(&meta.path, ser.as_ref().map(syn::LitStr::value)); + for de_value in de { + de_name.set_if_none(de_value.value()); + de_aliases.insert(&meta.path, de_value.value()); + } + } else if meta.path == ALIAS { + // #[serde(alias = "foo")] + if let Some(s) = get_lit_str(cx, ALIAS, &meta)? { + de_aliases.insert(&meta.path, s.value()); + } + } else if meta.path == RENAME_ALL { + // #[serde(rename_all = "foo")] + // #[serde(rename_all(serialize = "foo", deserialize = "bar"))] + let one_name = meta.input.peek(Token![=]); + let (ser, de) = get_renames(cx, RENAME_ALL, &meta)?; + if let Some(ser) = ser { + match RenameRule::from_str(&ser.value()) { + Ok(rename_rule) => rename_all_ser_rule.set(&meta.path, rename_rule), + Err(err) => cx.error_spanned_by(ser, err), + } + } + if let Some(de) = de { + match RenameRule::from_str(&de.value()) { + Ok(rename_rule) => rename_all_de_rule.set(&meta.path, rename_rule), + Err(err) => { + if !one_name { + cx.error_spanned_by(de, err); + } + } + } + } + } else if meta.path == SKIP { + // #[serde(skip)] + skip_serializing.set_true(&meta.path); + skip_deserializing.set_true(&meta.path); + } else if meta.path == SKIP_DESERIALIZING { + // #[serde(skip_deserializing)] + skip_deserializing.set_true(&meta.path); + } else if meta.path == SKIP_SERIALIZING { + // #[serde(skip_serializing)] + skip_serializing.set_true(&meta.path); + } else if meta.path == OTHER { + // #[serde(other)] + other.set_true(&meta.path); + } else if meta.path == BOUND { + // #[serde(bound = "T: SomeBound")] + // #[serde(bound(serialize = "...", deserialize = "..."))] + let (ser, de) = get_where_predicates(cx, &meta)?; + ser_bound.set_opt(&meta.path, ser); + de_bound.set_opt(&meta.path, de); + } else if meta.path == WITH { + // #[serde(with = "...")] + if let Some(path) = parse_lit_into_expr_path(cx, WITH, &meta)? { + let mut ser_path = path.clone(); + ser_path + .path + .segments + .push(Ident::new("serialize", Span::call_site()).into()); + serialize_with.set(&meta.path, ser_path); + let mut de_path = path; + de_path + .path + .segments + .push(Ident::new("deserialize", Span::call_site()).into()); + deserialize_with.set(&meta.path, de_path); + } + } else if meta.path == SERIALIZE_WITH { + // #[serde(serialize_with = "...")] + if let Some(path) = parse_lit_into_expr_path(cx, SERIALIZE_WITH, &meta)? { + serialize_with.set(&meta.path, path); + } + } else if meta.path == DESERIALIZE_WITH { + // #[serde(deserialize_with = "...")] + if let Some(path) = parse_lit_into_expr_path(cx, DESERIALIZE_WITH, &meta)? { + deserialize_with.set(&meta.path, path); + } + } else if meta.path == BORROW { + let borrow_attribute = if meta.input.peek(Token![=]) { + // #[serde(borrow = "'a + 'b")] + let lifetimes = parse_lit_into_lifetimes(cx, &meta)?; + BorrowAttribute { + path: meta.path.clone(), + lifetimes: Some(lifetimes), + } + } else { + // #[serde(borrow)] + BorrowAttribute { + path: meta.path.clone(), + lifetimes: None, + } + }; + match &variant.fields { + syn::Fields::Unnamed(fields) if fields.unnamed.len() == 1 => { + borrow.set(&meta.path, borrow_attribute); + } + _ => { + let msg = "#[serde(borrow)] may only be used on newtype variants"; + cx.error_spanned_by(variant, msg); + } + } + } else if meta.path == UNTAGGED { + untagged.set_true(&meta.path); + } else { + let path = meta.path.to_token_stream().to_string().replace(' ', ""); + return Err( + meta.error(format_args!("unknown serde variant attribute `{}`", path)) + ); + } + Ok(()) + }) { + cx.syn_error(err); + } + } + + Variant { + name: Name::from_attrs(unraw(&variant.ident), ser_name, de_name, Some(de_aliases)), + rename_all_rules: RenameAllRules { + serialize: rename_all_ser_rule.get().unwrap_or(RenameRule::None), + deserialize: rename_all_de_rule.get().unwrap_or(RenameRule::None), + }, + ser_bound: ser_bound.get(), + de_bound: de_bound.get(), + skip_deserializing: skip_deserializing.get(), + skip_serializing: skip_serializing.get(), + other: other.get(), + serialize_with: serialize_with.get(), + deserialize_with: deserialize_with.get(), + borrow: borrow.get(), + untagged: untagged.get(), + } + } + + pub fn name(&self) -> &Name { + &self.name + } + + pub fn aliases(&self) -> &BTreeSet { + self.name.deserialize_aliases() + } + + pub fn rename_by_rules(&mut self, rules: RenameAllRules) { + if !self.name.serialize_renamed { + self.name.serialize = rules.serialize.apply_to_variant(&self.name.serialize); + } + if !self.name.deserialize_renamed { + self.name.deserialize = rules.deserialize.apply_to_variant(&self.name.deserialize); + } + self.name + .deserialize_aliases + .insert(self.name.deserialize.clone()); + } + + pub fn rename_all_rules(&self) -> RenameAllRules { + self.rename_all_rules + } + + pub fn ser_bound(&self) -> Option<&[syn::WherePredicate]> { + self.ser_bound.as_ref().map(|vec| &vec[..]) + } + + pub fn de_bound(&self) -> Option<&[syn::WherePredicate]> { + self.de_bound.as_ref().map(|vec| &vec[..]) + } + + pub fn skip_deserializing(&self) -> bool { + self.skip_deserializing + } + + pub fn skip_serializing(&self) -> bool { + self.skip_serializing + } + + pub fn other(&self) -> bool { + self.other + } + + pub fn serialize_with(&self) -> Option<&syn::ExprPath> { + self.serialize_with.as_ref() + } + + pub fn deserialize_with(&self) -> Option<&syn::ExprPath> { + self.deserialize_with.as_ref() + } + + pub fn untagged(&self) -> bool { + self.untagged + } +} + +/// Represents field attribute information +pub struct Field { + name: Name, + skip_serializing: bool, + skip_deserializing: bool, + skip_serializing_if: Option, + default: Default, + serialize_with: Option, + deserialize_with: Option, + ser_bound: Option>, + de_bound: Option>, + borrowed_lifetimes: BTreeSet, + getter: Option, + flatten: bool, + transparent: bool, +} + +/// Represents the default to use for a field when deserializing. +pub enum Default { + /// Field must always be specified because it does not have a default. + None, + /// The default is given by `std::default::Default::default()`. + Default, + /// The default is given by this function. + Path(syn::ExprPath), +} + +impl Default { + pub fn is_none(&self) -> bool { + match self { + Default::None => true, + Default::Default | Default::Path(_) => false, + } + } +} + +impl Field { + /// Extract out the `#[serde(...)]` attributes from a struct field. + pub fn from_ast( + cx: &Ctxt, + index: usize, + field: &syn::Field, + attrs: Option<&Variant>, + container_default: &Default, + ) -> Self { + let mut ser_name = Attr::none(cx, RENAME); + let mut de_name = Attr::none(cx, RENAME); + let mut de_aliases = VecAttr::none(cx, RENAME); + let mut skip_serializing = BoolAttr::none(cx, SKIP_SERIALIZING); + let mut skip_deserializing = BoolAttr::none(cx, SKIP_DESERIALIZING); + let mut skip_serializing_if = Attr::none(cx, SKIP_SERIALIZING_IF); + let mut default = Attr::none(cx, DEFAULT); + let mut serialize_with = Attr::none(cx, SERIALIZE_WITH); + let mut deserialize_with = Attr::none(cx, DESERIALIZE_WITH); + let mut ser_bound = Attr::none(cx, BOUND); + let mut de_bound = Attr::none(cx, BOUND); + let mut borrowed_lifetimes = Attr::none(cx, BORROW); + let mut getter = Attr::none(cx, GETTER); + let mut flatten = BoolAttr::none(cx, FLATTEN); + + let ident = match &field.ident { + Some(ident) => unraw(ident), + None => index.to_string(), + }; + + if let Some(borrow_attribute) = attrs.and_then(|variant| variant.borrow.as_ref()) { + if let Ok(borrowable) = borrowable_lifetimes(cx, &ident, field) { + if let Some(lifetimes) = &borrow_attribute.lifetimes { + for lifetime in lifetimes { + if !borrowable.contains(lifetime) { + let msg = + format!("field `{}` does not have lifetime {}", ident, lifetime); + cx.error_spanned_by(field, msg); + } + } + borrowed_lifetimes.set(&borrow_attribute.path, lifetimes.clone()); + } else { + borrowed_lifetimes.set(&borrow_attribute.path, borrowable); + } + } + } + + for attr in &field.attrs { + if attr.path() != SERDE { + continue; + } + + if let syn::Meta::List(meta) = &attr.meta { + if meta.tokens.is_empty() { + continue; + } + } + + if let Err(err) = attr.parse_nested_meta(|meta| { + if meta.path == RENAME { + // #[serde(rename = "foo")] + // #[serde(rename(serialize = "foo", deserialize = "bar"))] + let (ser, de) = get_multiple_renames(cx, &meta)?; + ser_name.set_opt(&meta.path, ser.as_ref().map(syn::LitStr::value)); + for de_value in de { + de_name.set_if_none(de_value.value()); + de_aliases.insert(&meta.path, de_value.value()); + } + } else if meta.path == ALIAS { + // #[serde(alias = "foo")] + if let Some(s) = get_lit_str(cx, ALIAS, &meta)? { + de_aliases.insert(&meta.path, s.value()); + } + } else if meta.path == DEFAULT { + if meta.input.peek(Token![=]) { + // #[serde(default = "...")] + if let Some(path) = parse_lit_into_expr_path(cx, DEFAULT, &meta)? { + default.set(&meta.path, Default::Path(path)); + } + } else { + // #[serde(default)] + default.set(&meta.path, Default::Default); + } + } else if meta.path == SKIP_SERIALIZING { + // #[serde(skip_serializing)] + skip_serializing.set_true(&meta.path); + } else if meta.path == SKIP_DESERIALIZING { + // #[serde(skip_deserializing)] + skip_deserializing.set_true(&meta.path); + } else if meta.path == SKIP { + // #[serde(skip)] + skip_serializing.set_true(&meta.path); + skip_deserializing.set_true(&meta.path); + } else if meta.path == SKIP_SERIALIZING_IF { + // #[serde(skip_serializing_if = "...")] + if let Some(path) = parse_lit_into_expr_path(cx, SKIP_SERIALIZING_IF, &meta)? { + skip_serializing_if.set(&meta.path, path); + } + } else if meta.path == SERIALIZE_WITH { + // #[serde(serialize_with = "...")] + if let Some(path) = parse_lit_into_expr_path(cx, SERIALIZE_WITH, &meta)? { + serialize_with.set(&meta.path, path); + } + } else if meta.path == DESERIALIZE_WITH { + // #[serde(deserialize_with = "...")] + if let Some(path) = parse_lit_into_expr_path(cx, DESERIALIZE_WITH, &meta)? { + deserialize_with.set(&meta.path, path); + } + } else if meta.path == WITH { + // #[serde(with = "...")] + if let Some(path) = parse_lit_into_expr_path(cx, WITH, &meta)? { + let mut ser_path = path.clone(); + ser_path + .path + .segments + .push(Ident::new("serialize", Span::call_site()).into()); + serialize_with.set(&meta.path, ser_path); + let mut de_path = path; + de_path + .path + .segments + .push(Ident::new("deserialize", Span::call_site()).into()); + deserialize_with.set(&meta.path, de_path); + } + } else if meta.path == BOUND { + // #[serde(bound = "T: SomeBound")] + // #[serde(bound(serialize = "...", deserialize = "..."))] + let (ser, de) = get_where_predicates(cx, &meta)?; + ser_bound.set_opt(&meta.path, ser); + de_bound.set_opt(&meta.path, de); + } else if meta.path == BORROW { + if meta.input.peek(Token![=]) { + // #[serde(borrow = "'a + 'b")] + let lifetimes = parse_lit_into_lifetimes(cx, &meta)?; + if let Ok(borrowable) = borrowable_lifetimes(cx, &ident, field) { + for lifetime in &lifetimes { + if !borrowable.contains(lifetime) { + let msg = format!( + "field `{}` does not have lifetime {}", + ident, lifetime, + ); + cx.error_spanned_by(field, msg); + } + } + borrowed_lifetimes.set(&meta.path, lifetimes); + } + } else { + // #[serde(borrow)] + if let Ok(borrowable) = borrowable_lifetimes(cx, &ident, field) { + borrowed_lifetimes.set(&meta.path, borrowable); + } + } + } else if meta.path == GETTER { + // #[serde(getter = "...")] + if let Some(path) = parse_lit_into_expr_path(cx, GETTER, &meta)? { + getter.set(&meta.path, path); + } + } else if meta.path == FLATTEN { + // #[serde(flatten)] + flatten.set_true(&meta.path); + } else { + let path = meta.path.to_token_stream().to_string().replace(' ', ""); + return Err( + meta.error(format_args!("unknown serde field attribute `{}`", path)) + ); + } + Ok(()) + }) { + cx.syn_error(err); + } + } + + // Is skip_deserializing, initialize the field to Default::default() unless a + // different default is specified by `#[serde(default = "...")]` on + // ourselves or our container (e.g. the struct we are in). + if let Default::None = *container_default { + if skip_deserializing.0.value.is_some() { + default.set_if_none(Default::Default); + } + } + + let mut borrowed_lifetimes = borrowed_lifetimes.get().unwrap_or_default(); + if !borrowed_lifetimes.is_empty() { + // Cow and Cow<[u8]> never borrow by default: + // + // impl<'de, 'a, T: ?Sized> Deserialize<'de> for Cow<'a, T> + // + // A #[serde(borrow)] attribute enables borrowing that corresponds + // roughly to these impls: + // + // impl<'de: 'a, 'a> Deserialize<'de> for Cow<'a, str> + // impl<'de: 'a, 'a> Deserialize<'de> for Cow<'a, [u8]> + if is_cow(&field.ty, is_str) { + let mut path = syn::Path { + leading_colon: None, + segments: Punctuated::new(), + }; + let span = Span::call_site(); + path.segments.push(Ident::new("_serde", span).into()); + path.segments.push(Ident::new("__private", span).into()); + path.segments.push(Ident::new("de", span).into()); + path.segments + .push(Ident::new("borrow_cow_str", span).into()); + let expr = syn::ExprPath { + attrs: Vec::new(), + qself: None, + path, + }; + deserialize_with.set_if_none(expr); + } else if is_cow(&field.ty, is_slice_u8) { + let mut path = syn::Path { + leading_colon: None, + segments: Punctuated::new(), + }; + let span = Span::call_site(); + path.segments.push(Ident::new("_serde", span).into()); + path.segments.push(Ident::new("__private", span).into()); + path.segments.push(Ident::new("de", span).into()); + path.segments + .push(Ident::new("borrow_cow_bytes", span).into()); + let expr = syn::ExprPath { + attrs: Vec::new(), + qself: None, + path, + }; + deserialize_with.set_if_none(expr); + } + } else if is_implicitly_borrowed(&field.ty) { + // Types &str and &[u8] are always implicitly borrowed. No need for + // a #[serde(borrow)]. + collect_lifetimes(&field.ty, &mut borrowed_lifetimes); + } + + Field { + name: Name::from_attrs(ident, ser_name, de_name, Some(de_aliases)), + skip_serializing: skip_serializing.get(), + skip_deserializing: skip_deserializing.get(), + skip_serializing_if: skip_serializing_if.get(), + default: default.get().unwrap_or(Default::None), + serialize_with: serialize_with.get(), + deserialize_with: deserialize_with.get(), + ser_bound: ser_bound.get(), + de_bound: de_bound.get(), + borrowed_lifetimes, + getter: getter.get(), + flatten: flatten.get(), + transparent: false, + } + } + + pub fn name(&self) -> &Name { + &self.name + } + + pub fn aliases(&self) -> &BTreeSet { + self.name.deserialize_aliases() + } + + pub fn rename_by_rules(&mut self, rules: RenameAllRules) { + if !self.name.serialize_renamed { + self.name.serialize = rules.serialize.apply_to_field(&self.name.serialize); + } + if !self.name.deserialize_renamed { + self.name.deserialize = rules.deserialize.apply_to_field(&self.name.deserialize); + } + self.name + .deserialize_aliases + .insert(self.name.deserialize.clone()); + } + + pub fn skip_serializing(&self) -> bool { + self.skip_serializing + } + + pub fn skip_deserializing(&self) -> bool { + self.skip_deserializing + } + + pub fn skip_serializing_if(&self) -> Option<&syn::ExprPath> { + self.skip_serializing_if.as_ref() + } + + pub fn default(&self) -> &Default { + &self.default + } + + pub fn serialize_with(&self) -> Option<&syn::ExprPath> { + self.serialize_with.as_ref() + } + + pub fn deserialize_with(&self) -> Option<&syn::ExprPath> { + self.deserialize_with.as_ref() + } + + pub fn ser_bound(&self) -> Option<&[syn::WherePredicate]> { + self.ser_bound.as_ref().map(|vec| &vec[..]) + } + + pub fn de_bound(&self) -> Option<&[syn::WherePredicate]> { + self.de_bound.as_ref().map(|vec| &vec[..]) + } + + pub fn borrowed_lifetimes(&self) -> &BTreeSet { + &self.borrowed_lifetimes + } + + pub fn getter(&self) -> Option<&syn::ExprPath> { + self.getter.as_ref() + } + + pub fn flatten(&self) -> bool { + self.flatten + } + + pub fn transparent(&self) -> bool { + self.transparent + } + + pub fn mark_transparent(&mut self) { + self.transparent = true; + } +} + +type SerAndDe = (Option, Option); + +fn get_ser_and_de<'c, T, F, R>( + cx: &'c Ctxt, + attr_name: Symbol, + meta: &ParseNestedMeta, + f: F, +) -> syn::Result<(VecAttr<'c, T>, VecAttr<'c, T>)> +where + T: Clone, + F: Fn(&Ctxt, Symbol, Symbol, &ParseNestedMeta) -> syn::Result, + R: Into>, +{ + let mut ser_meta = VecAttr::none(cx, attr_name); + let mut de_meta = VecAttr::none(cx, attr_name); + + let lookahead = meta.input.lookahead1(); + if lookahead.peek(Token![=]) { + if let Some(both) = f(cx, attr_name, attr_name, meta)?.into() { + ser_meta.insert(&meta.path, both.clone()); + de_meta.insert(&meta.path, both); + } + } else if lookahead.peek(token::Paren) { + meta.parse_nested_meta(|meta| { + if meta.path == SERIALIZE { + if let Some(v) = f(cx, attr_name, SERIALIZE, &meta)?.into() { + ser_meta.insert(&meta.path, v); + } + } else if meta.path == DESERIALIZE { + if let Some(v) = f(cx, attr_name, DESERIALIZE, &meta)?.into() { + de_meta.insert(&meta.path, v); + } + } else { + return Err(meta.error(format_args!( + "malformed {0} attribute, expected `{0}(serialize = ..., deserialize = ...)`", + attr_name, + ))); + } + Ok(()) + })?; + } else { + return Err(lookahead.error()); + } + + Ok((ser_meta, de_meta)) +} + +fn get_renames( + cx: &Ctxt, + attr_name: Symbol, + meta: &ParseNestedMeta, +) -> syn::Result> { + let (ser, de) = get_ser_and_de(cx, attr_name, meta, get_lit_str2)?; + Ok((ser.at_most_one(), de.at_most_one())) +} + +fn get_multiple_renames( + cx: &Ctxt, + meta: &ParseNestedMeta, +) -> syn::Result<(Option, Vec)> { + let (ser, de) = get_ser_and_de(cx, RENAME, meta, get_lit_str2)?; + Ok((ser.at_most_one(), de.get())) +} + +fn get_where_predicates( + cx: &Ctxt, + meta: &ParseNestedMeta, +) -> syn::Result>> { + let (ser, de) = get_ser_and_de(cx, BOUND, meta, parse_lit_into_where)?; + Ok((ser.at_most_one(), de.at_most_one())) +} + +fn get_lit_str( + cx: &Ctxt, + attr_name: Symbol, + meta: &ParseNestedMeta, +) -> syn::Result> { + get_lit_str2(cx, attr_name, attr_name, meta) +} + +fn get_lit_str2( + cx: &Ctxt, + attr_name: Symbol, + meta_item_name: Symbol, + meta: &ParseNestedMeta, +) -> syn::Result> { + let expr: syn::Expr = meta.value()?.parse()?; + let mut value = &expr; + while let syn::Expr::Group(e) = value { + value = &e.expr; + } + if let syn::Expr::Lit(syn::ExprLit { + lit: syn::Lit::Str(lit), + .. + }) = value + { + let suffix = lit.suffix(); + if !suffix.is_empty() { + cx.error_spanned_by( + lit, + format!("unexpected suffix `{}` on string literal", suffix), + ); + } + Ok(Some(lit.clone())) + } else { + cx.error_spanned_by( + expr, + format!( + "expected serde {} attribute to be a string: `{} = \"...\"`", + attr_name, meta_item_name + ), + ); + Ok(None) + } +} + +fn parse_lit_into_path( + cx: &Ctxt, + attr_name: Symbol, + meta: &ParseNestedMeta, +) -> syn::Result> { + let string = match get_lit_str(cx, attr_name, meta)? { + Some(string) => string, + None => return Ok(None), + }; + + Ok(match string.parse() { + Ok(path) => Some(path), + Err(_) => { + cx.error_spanned_by( + &string, + format!("failed to parse path: {:?}", string.value()), + ); + None + } + }) +} + +fn parse_lit_into_expr_path( + cx: &Ctxt, + attr_name: Symbol, + meta: &ParseNestedMeta, +) -> syn::Result> { + let string = match get_lit_str(cx, attr_name, meta)? { + Some(string) => string, + None => return Ok(None), + }; + + Ok(match string.parse() { + Ok(expr) => Some(expr), + Err(_) => { + cx.error_spanned_by( + &string, + format!("failed to parse path: {:?}", string.value()), + ); + None + } + }) +} + +fn parse_lit_into_where( + cx: &Ctxt, + attr_name: Symbol, + meta_item_name: Symbol, + meta: &ParseNestedMeta, +) -> syn::Result> { + let string = match get_lit_str2(cx, attr_name, meta_item_name, meta)? { + Some(string) => string, + None => return Ok(Vec::new()), + }; + + Ok( + match string.parse_with(Punctuated::::parse_terminated) { + Ok(predicates) => Vec::from_iter(predicates), + Err(err) => { + cx.error_spanned_by(string, err); + Vec::new() + } + }, + ) +} + +fn parse_lit_into_ty( + cx: &Ctxt, + attr_name: Symbol, + meta: &ParseNestedMeta, +) -> syn::Result> { + let string = match get_lit_str(cx, attr_name, meta)? { + Some(string) => string, + None => return Ok(None), + }; + + Ok(match string.parse() { + Ok(ty) => Some(ty), + Err(_) => { + cx.error_spanned_by( + &string, + format!("failed to parse type: {} = {:?}", attr_name, string.value()), + ); + None + } + }) +} + +// Parses a string literal like "'a + 'b + 'c" containing a nonempty list of +// lifetimes separated by `+`. +fn parse_lit_into_lifetimes( + cx: &Ctxt, + meta: &ParseNestedMeta, +) -> syn::Result> { + let string = match get_lit_str(cx, BORROW, meta)? { + Some(string) => string, + None => return Ok(BTreeSet::new()), + }; + + if let Ok(lifetimes) = string.parse_with(|input: ParseStream| { + let mut set = BTreeSet::new(); + while !input.is_empty() { + let lifetime: Lifetime = input.parse()?; + if !set.insert(lifetime.clone()) { + cx.error_spanned_by( + &string, + format!("duplicate borrowed lifetime `{}`", lifetime), + ); + } + if input.is_empty() { + break; + } + input.parse::()?; + } + Ok(set) + }) { + if lifetimes.is_empty() { + cx.error_spanned_by(string, "at least one lifetime must be borrowed"); + } + return Ok(lifetimes); + } + + cx.error_spanned_by( + &string, + format!("failed to parse borrowed lifetimes: {:?}", string.value()), + ); + Ok(BTreeSet::new()) +} + +fn is_implicitly_borrowed(ty: &syn::Type) -> bool { + is_implicitly_borrowed_reference(ty) || is_option(ty, is_implicitly_borrowed_reference) +} + +fn is_implicitly_borrowed_reference(ty: &syn::Type) -> bool { + is_reference(ty, is_str) || is_reference(ty, is_slice_u8) +} + +// Whether the type looks like it might be `std::borrow::Cow` where elem="T". +// This can have false negatives and false positives. +// +// False negative: +// +// use std::borrow::Cow as Pig; +// +// #[derive(Deserialize)] +// struct S<'a> { +// #[serde(borrow)] +// pig: Pig<'a, str>, +// } +// +// False positive: +// +// type str = [i16]; +// +// #[derive(Deserialize)] +// struct S<'a> { +// #[serde(borrow)] +// cow: Cow<'a, str>, +// } +fn is_cow(ty: &syn::Type, elem: fn(&syn::Type) -> bool) -> bool { + let path = match ungroup(ty) { + syn::Type::Path(ty) => &ty.path, + _ => { + return false; + } + }; + let seg = match path.segments.last() { + Some(seg) => seg, + None => { + return false; + } + }; + let args = match &seg.arguments { + syn::PathArguments::AngleBracketed(bracketed) => &bracketed.args, + _ => { + return false; + } + }; + seg.ident == "Cow" + && args.len() == 2 + && match (&args[0], &args[1]) { + (syn::GenericArgument::Lifetime(_), syn::GenericArgument::Type(arg)) => elem(arg), + _ => false, + } +} + +fn is_option(ty: &syn::Type, elem: fn(&syn::Type) -> bool) -> bool { + let path = match ungroup(ty) { + syn::Type::Path(ty) => &ty.path, + _ => { + return false; + } + }; + let seg = match path.segments.last() { + Some(seg) => seg, + None => { + return false; + } + }; + let args = match &seg.arguments { + syn::PathArguments::AngleBracketed(bracketed) => &bracketed.args, + _ => { + return false; + } + }; + seg.ident == "Option" + && args.len() == 1 + && match &args[0] { + syn::GenericArgument::Type(arg) => elem(arg), + _ => false, + } +} + +// Whether the type looks like it might be `&T` where elem="T". This can have +// false negatives and false positives. +// +// False negative: +// +// type Yarn = str; +// +// #[derive(Deserialize)] +// struct S<'a> { +// r: &'a Yarn, +// } +// +// False positive: +// +// type str = [i16]; +// +// #[derive(Deserialize)] +// struct S<'a> { +// r: &'a str, +// } +fn is_reference(ty: &syn::Type, elem: fn(&syn::Type) -> bool) -> bool { + match ungroup(ty) { + syn::Type::Reference(ty) => ty.mutability.is_none() && elem(&ty.elem), + _ => false, + } +} + +fn is_str(ty: &syn::Type) -> bool { + is_primitive_type(ty, "str") +} + +fn is_slice_u8(ty: &syn::Type) -> bool { + match ungroup(ty) { + syn::Type::Slice(ty) => is_primitive_type(&ty.elem, "u8"), + _ => false, + } +} + +fn is_primitive_type(ty: &syn::Type, primitive: &str) -> bool { + match ungroup(ty) { + syn::Type::Path(ty) => ty.qself.is_none() && is_primitive_path(&ty.path, primitive), + _ => false, + } +} + +fn is_primitive_path(path: &syn::Path, primitive: &str) -> bool { + path.leading_colon.is_none() + && path.segments.len() == 1 + && path.segments[0].ident == primitive + && path.segments[0].arguments.is_empty() +} + +// All lifetimes that this type could borrow from a Deserializer. +// +// For example a type `S<'a, 'b>` could borrow `'a` and `'b`. On the other hand +// a type `for<'a> fn(&'a str)` could not borrow `'a` from the Deserializer. +// +// This is used when there is an explicit or implicit `#[serde(borrow)]` +// attribute on the field so there must be at least one borrowable lifetime. +fn borrowable_lifetimes( + cx: &Ctxt, + name: &str, + field: &syn::Field, +) -> Result, ()> { + let mut lifetimes = BTreeSet::new(); + collect_lifetimes(&field.ty, &mut lifetimes); + if lifetimes.is_empty() { + let msg = format!("field `{}` has no lifetimes to borrow", name); + cx.error_spanned_by(field, msg); + Err(()) + } else { + Ok(lifetimes) + } +} + +fn collect_lifetimes(ty: &syn::Type, out: &mut BTreeSet) { + match ty { + #![cfg_attr(all(test, exhaustive), deny(non_exhaustive_omitted_patterns))] + syn::Type::Slice(ty) => { + collect_lifetimes(&ty.elem, out); + } + syn::Type::Array(ty) => { + collect_lifetimes(&ty.elem, out); + } + syn::Type::Ptr(ty) => { + collect_lifetimes(&ty.elem, out); + } + syn::Type::Reference(ty) => { + out.extend(ty.lifetime.iter().cloned()); + collect_lifetimes(&ty.elem, out); + } + syn::Type::Tuple(ty) => { + for elem in &ty.elems { + collect_lifetimes(elem, out); + } + } + syn::Type::Path(ty) => { + if let Some(qself) = &ty.qself { + collect_lifetimes(&qself.ty, out); + } + for seg in &ty.path.segments { + if let syn::PathArguments::AngleBracketed(bracketed) = &seg.arguments { + for arg in &bracketed.args { + match arg { + syn::GenericArgument::Lifetime(lifetime) => { + out.insert(lifetime.clone()); + } + syn::GenericArgument::Type(ty) => { + collect_lifetimes(ty, out); + } + syn::GenericArgument::AssocType(binding) => { + collect_lifetimes(&binding.ty, out); + } + syn::GenericArgument::Const(_) + | syn::GenericArgument::AssocConst(_) + | syn::GenericArgument::Constraint(_) + | _ => {} + } + } + } + } + } + syn::Type::Paren(ty) => { + collect_lifetimes(&ty.elem, out); + } + syn::Type::Group(ty) => { + collect_lifetimes(&ty.elem, out); + } + syn::Type::Macro(ty) => { + collect_lifetimes_from_tokens(ty.mac.tokens.clone(), out); + } + syn::Type::BareFn(_) + | syn::Type::Never(_) + | syn::Type::TraitObject(_) + | syn::Type::ImplTrait(_) + | syn::Type::Infer(_) + | syn::Type::Verbatim(_) => {} + + _ => {} + } +} + +fn collect_lifetimes_from_tokens(tokens: TokenStream, out: &mut BTreeSet) { + let mut iter = tokens.into_iter(); + while let Some(tt) = iter.next() { + match &tt { + TokenTree::Punct(op) if op.as_char() == '\'' && op.spacing() == Spacing::Joint => { + if let Some(TokenTree::Ident(ident)) = iter.next() { + out.insert(syn::Lifetime { + apostrophe: op.span(), + ident, + }); + } + } + TokenTree::Group(group) => { + let tokens = group.stream(); + collect_lifetimes_from_tokens(tokens, out); + } + _ => {} + } + } +} diff --git a/vendor/serde_derive/src/internals/case.rs b/vendor/serde_derive/src/internals/case.rs new file mode 100644 index 0000000..8c8c02e --- /dev/null +++ b/vendor/serde_derive/src/internals/case.rs @@ -0,0 +1,200 @@ +//! Code to convert the Rust-styled field/variant (e.g. `my_field`, `MyType`) to the +//! case of the source (e.g. `my-field`, `MY_FIELD`). + +use self::RenameRule::*; +use std::fmt::{self, Debug, Display}; + +/// The different possible ways to change case of fields in a struct, or variants in an enum. +#[derive(Copy, Clone, PartialEq)] +pub enum RenameRule { + /// Don't apply a default rename rule. + None, + /// Rename direct children to "lowercase" style. + LowerCase, + /// Rename direct children to "UPPERCASE" style. + UpperCase, + /// Rename direct children to "PascalCase" style, as typically used for + /// enum variants. + PascalCase, + /// Rename direct children to "camelCase" style. + CamelCase, + /// Rename direct children to "snake_case" style, as commonly used for + /// fields. + SnakeCase, + /// Rename direct children to "SCREAMING_SNAKE_CASE" style, as commonly + /// used for constants. + ScreamingSnakeCase, + /// Rename direct children to "kebab-case" style. + KebabCase, + /// Rename direct children to "SCREAMING-KEBAB-CASE" style. + ScreamingKebabCase, +} + +static RENAME_RULES: &[(&str, RenameRule)] = &[ + ("lowercase", LowerCase), + ("UPPERCASE", UpperCase), + ("PascalCase", PascalCase), + ("camelCase", CamelCase), + ("snake_case", SnakeCase), + ("SCREAMING_SNAKE_CASE", ScreamingSnakeCase), + ("kebab-case", KebabCase), + ("SCREAMING-KEBAB-CASE", ScreamingKebabCase), +]; + +impl RenameRule { + pub fn from_str(rename_all_str: &str) -> Result { + for (name, rule) in RENAME_RULES { + if rename_all_str == *name { + return Ok(*rule); + } + } + Err(ParseError { + unknown: rename_all_str, + }) + } + + /// Apply a renaming rule to an enum variant, returning the version expected in the source. + pub fn apply_to_variant(self, variant: &str) -> String { + match self { + None | PascalCase => variant.to_owned(), + LowerCase => variant.to_ascii_lowercase(), + UpperCase => variant.to_ascii_uppercase(), + CamelCase => variant[..1].to_ascii_lowercase() + &variant[1..], + SnakeCase => { + let mut snake = String::new(); + for (i, ch) in variant.char_indices() { + if i > 0 && ch.is_uppercase() { + snake.push('_'); + } + snake.push(ch.to_ascii_lowercase()); + } + snake + } + ScreamingSnakeCase => SnakeCase.apply_to_variant(variant).to_ascii_uppercase(), + KebabCase => SnakeCase.apply_to_variant(variant).replace('_', "-"), + ScreamingKebabCase => ScreamingSnakeCase + .apply_to_variant(variant) + .replace('_', "-"), + } + } + + /// Apply a renaming rule to a struct field, returning the version expected in the source. + pub fn apply_to_field(self, field: &str) -> String { + match self { + None | LowerCase | SnakeCase => field.to_owned(), + UpperCase => field.to_ascii_uppercase(), + PascalCase => { + let mut pascal = String::new(); + let mut capitalize = true; + for ch in field.chars() { + if ch == '_' { + capitalize = true; + } else if capitalize { + pascal.push(ch.to_ascii_uppercase()); + capitalize = false; + } else { + pascal.push(ch); + } + } + pascal + } + CamelCase => { + let pascal = PascalCase.apply_to_field(field); + pascal[..1].to_ascii_lowercase() + &pascal[1..] + } + ScreamingSnakeCase => field.to_ascii_uppercase(), + KebabCase => field.replace('_', "-"), + ScreamingKebabCase => ScreamingSnakeCase.apply_to_field(field).replace('_', "-"), + } + } + + /// Returns the `RenameRule` if it is not `None`, `rule_b` otherwise. + pub fn or(self, rule_b: Self) -> Self { + match self { + None => rule_b, + _ => self, + } + } +} + +pub struct ParseError<'a> { + unknown: &'a str, +} + +impl<'a> Display for ParseError<'a> { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.write_str("unknown rename rule `rename_all = ")?; + Debug::fmt(self.unknown, f)?; + f.write_str("`, expected one of ")?; + for (i, (name, _rule)) in RENAME_RULES.iter().enumerate() { + if i > 0 { + f.write_str(", ")?; + } + Debug::fmt(name, f)?; + } + Ok(()) + } +} + +#[test] +fn rename_variants() { + for &(original, lower, upper, camel, snake, screaming, kebab, screaming_kebab) in &[ + ( + "Outcome", "outcome", "OUTCOME", "outcome", "outcome", "OUTCOME", "outcome", "OUTCOME", + ), + ( + "VeryTasty", + "verytasty", + "VERYTASTY", + "veryTasty", + "very_tasty", + "VERY_TASTY", + "very-tasty", + "VERY-TASTY", + ), + ("A", "a", "A", "a", "a", "A", "a", "A"), + ("Z42", "z42", "Z42", "z42", "z42", "Z42", "z42", "Z42"), + ] { + assert_eq!(None.apply_to_variant(original), original); + assert_eq!(LowerCase.apply_to_variant(original), lower); + assert_eq!(UpperCase.apply_to_variant(original), upper); + assert_eq!(PascalCase.apply_to_variant(original), original); + assert_eq!(CamelCase.apply_to_variant(original), camel); + assert_eq!(SnakeCase.apply_to_variant(original), snake); + assert_eq!(ScreamingSnakeCase.apply_to_variant(original), screaming); + assert_eq!(KebabCase.apply_to_variant(original), kebab); + assert_eq!( + ScreamingKebabCase.apply_to_variant(original), + screaming_kebab + ); + } +} + +#[test] +fn rename_fields() { + for &(original, upper, pascal, camel, screaming, kebab, screaming_kebab) in &[ + ( + "outcome", "OUTCOME", "Outcome", "outcome", "OUTCOME", "outcome", "OUTCOME", + ), + ( + "very_tasty", + "VERY_TASTY", + "VeryTasty", + "veryTasty", + "VERY_TASTY", + "very-tasty", + "VERY-TASTY", + ), + ("a", "A", "A", "a", "A", "a", "A"), + ("z42", "Z42", "Z42", "z42", "Z42", "z42", "Z42"), + ] { + assert_eq!(None.apply_to_field(original), original); + assert_eq!(UpperCase.apply_to_field(original), upper); + assert_eq!(PascalCase.apply_to_field(original), pascal); + assert_eq!(CamelCase.apply_to_field(original), camel); + assert_eq!(SnakeCase.apply_to_field(original), original); + assert_eq!(ScreamingSnakeCase.apply_to_field(original), screaming); + assert_eq!(KebabCase.apply_to_field(original), kebab); + assert_eq!(ScreamingKebabCase.apply_to_field(original), screaming_kebab); + } +} diff --git a/vendor/serde_derive/src/internals/check.rs b/vendor/serde_derive/src/internals/check.rs new file mode 100644 index 0000000..52b0f37 --- /dev/null +++ b/vendor/serde_derive/src/internals/check.rs @@ -0,0 +1,477 @@ +use crate::internals::ast::{Container, Data, Field, Style}; +use crate::internals::attr::{Default, Identifier, TagType}; +use crate::internals::{ungroup, Ctxt, Derive}; +use syn::{Member, Type}; + +// Cross-cutting checks that require looking at more than a single attrs object. +// Simpler checks should happen when parsing and building the attrs. +pub fn check(cx: &Ctxt, cont: &mut Container, derive: Derive) { + check_default_on_tuple(cx, cont); + check_remote_generic(cx, cont); + check_getter(cx, cont); + check_flatten(cx, cont); + check_identifier(cx, cont); + check_variant_skip_attrs(cx, cont); + check_internal_tag_field_name_conflict(cx, cont); + check_adjacent_tag_conflict(cx, cont); + check_transparent(cx, cont, derive); + check_from_and_try_from(cx, cont); +} + +// If some field of a tuple struct is marked #[serde(default)] then all fields +// after it must also be marked with that attribute, or the struct must have a +// container-level serde(default) attribute. A field's default value is only +// used for tuple fields if the sequence is exhausted at that point; that means +// all subsequent fields will fail to deserialize if they don't have their own +// default. +fn check_default_on_tuple(cx: &Ctxt, cont: &Container) { + if let Default::None = cont.attrs.default() { + if let Data::Struct(Style::Tuple, fields) = &cont.data { + let mut first_default_index = None; + for (i, field) in fields.iter().enumerate() { + // Skipped fields automatically get the #[serde(default)] + // attribute. We are interested only on non-skipped fields here. + if field.attrs.skip_deserializing() { + continue; + } + if let Default::None = field.attrs.default() { + if let Some(first) = first_default_index { + cx.error_spanned_by( + field.ty, + format!("field must have #[serde(default)] because previous field {} has #[serde(default)]", first), + ); + } + continue; + } + if first_default_index.is_none() { + first_default_index = Some(i); + } + } + } + } +} + +// Remote derive definition type must have either all of the generics of the +// remote type: +// +// #[serde(remote = "Generic")] +// struct Generic {…} +// +// or none of them, i.e. defining impls for one concrete instantiation of the +// remote type only: +// +// #[serde(remote = "Generic")] +// struct ConcreteDef {…} +// +fn check_remote_generic(cx: &Ctxt, cont: &Container) { + if let Some(remote) = cont.attrs.remote() { + let local_has_generic = !cont.generics.params.is_empty(); + let remote_has_generic = !remote.segments.last().unwrap().arguments.is_none(); + if local_has_generic && remote_has_generic { + cx.error_spanned_by(remote, "remove generic parameters from this path"); + } + } +} + +// Getters are only allowed inside structs (not enums) with the `remote` +// attribute. +fn check_getter(cx: &Ctxt, cont: &Container) { + match cont.data { + Data::Enum(_) => { + if cont.data.has_getter() { + cx.error_spanned_by( + cont.original, + "#[serde(getter = \"...\")] is not allowed in an enum", + ); + } + } + Data::Struct(_, _) => { + if cont.data.has_getter() && cont.attrs.remote().is_none() { + cx.error_spanned_by( + cont.original, + "#[serde(getter = \"...\")] can only be used in structs that have #[serde(remote = \"...\")]", + ); + } + } + } +} + +// Flattening has some restrictions we can test. +fn check_flatten(cx: &Ctxt, cont: &Container) { + match &cont.data { + Data::Enum(variants) => { + for variant in variants { + for field in &variant.fields { + check_flatten_field(cx, variant.style, field); + } + } + } + Data::Struct(style, fields) => { + for field in fields { + check_flatten_field(cx, *style, field); + } + } + } +} + +fn check_flatten_field(cx: &Ctxt, style: Style, field: &Field) { + if !field.attrs.flatten() { + return; + } + match style { + Style::Tuple => { + cx.error_spanned_by( + field.original, + "#[serde(flatten)] cannot be used on tuple structs", + ); + } + Style::Newtype => { + cx.error_spanned_by( + field.original, + "#[serde(flatten)] cannot be used on newtype structs", + ); + } + _ => {} + } +} + +// The `other` attribute must be used at most once and it must be the last +// variant of an enum. +// +// Inside a `variant_identifier` all variants must be unit variants. Inside a +// `field_identifier` all but possibly one variant must be unit variants. The +// last variant may be a newtype variant which is an implicit "other" case. +fn check_identifier(cx: &Ctxt, cont: &Container) { + let variants = match &cont.data { + Data::Enum(variants) => variants, + Data::Struct(_, _) => return, + }; + + for (i, variant) in variants.iter().enumerate() { + match ( + variant.style, + cont.attrs.identifier(), + variant.attrs.other(), + cont.attrs.tag(), + ) { + // The `other` attribute may not be used in a variant_identifier. + (_, Identifier::Variant, true, _) => { + cx.error_spanned_by( + variant.original, + "#[serde(other)] may not be used on a variant identifier", + ); + } + + // Variant with `other` attribute cannot appear in untagged enum + (_, Identifier::No, true, &TagType::None) => { + cx.error_spanned_by( + variant.original, + "#[serde(other)] cannot appear on untagged enum", + ); + } + + // Variant with `other` attribute must be the last one. + (Style::Unit, Identifier::Field, true, _) | (Style::Unit, Identifier::No, true, _) => { + if i < variants.len() - 1 { + cx.error_spanned_by( + variant.original, + "#[serde(other)] must be on the last variant", + ); + } + } + + // Variant with `other` attribute must be a unit variant. + (_, Identifier::Field, true, _) | (_, Identifier::No, true, _) => { + cx.error_spanned_by( + variant.original, + "#[serde(other)] must be on a unit variant", + ); + } + + // Any sort of variant is allowed if this is not an identifier. + (_, Identifier::No, false, _) => {} + + // Unit variant without `other` attribute is always fine. + (Style::Unit, _, false, _) => {} + + // The last field is allowed to be a newtype catch-all. + (Style::Newtype, Identifier::Field, false, _) => { + if i < variants.len() - 1 { + cx.error_spanned_by( + variant.original, + format!("`{}` must be the last variant", variant.ident), + ); + } + } + + (_, Identifier::Field, false, _) => { + cx.error_spanned_by( + variant.original, + "#[serde(field_identifier)] may only contain unit variants", + ); + } + + (_, Identifier::Variant, false, _) => { + cx.error_spanned_by( + variant.original, + "#[serde(variant_identifier)] may only contain unit variants", + ); + } + } + } +} + +// Skip-(de)serializing attributes are not allowed on variants marked +// (de)serialize_with. +fn check_variant_skip_attrs(cx: &Ctxt, cont: &Container) { + let variants = match &cont.data { + Data::Enum(variants) => variants, + Data::Struct(_, _) => return, + }; + + for variant in variants { + if variant.attrs.serialize_with().is_some() { + if variant.attrs.skip_serializing() { + cx.error_spanned_by( + variant.original, + format!( + "variant `{}` cannot have both #[serde(serialize_with)] and #[serde(skip_serializing)]", + variant.ident + ), + ); + } + + for field in &variant.fields { + let member = member_message(&field.member); + + if field.attrs.skip_serializing() { + cx.error_spanned_by( + variant.original, + format!( + "variant `{}` cannot have both #[serde(serialize_with)] and a field {} marked with #[serde(skip_serializing)]", + variant.ident, member + ), + ); + } + + if field.attrs.skip_serializing_if().is_some() { + cx.error_spanned_by( + variant.original, + format!( + "variant `{}` cannot have both #[serde(serialize_with)] and a field {} marked with #[serde(skip_serializing_if)]", + variant.ident, member + ), + ); + } + } + } + + if variant.attrs.deserialize_with().is_some() { + if variant.attrs.skip_deserializing() { + cx.error_spanned_by( + variant.original, + format!( + "variant `{}` cannot have both #[serde(deserialize_with)] and #[serde(skip_deserializing)]", + variant.ident + ), + ); + } + + for field in &variant.fields { + if field.attrs.skip_deserializing() { + let member = member_message(&field.member); + + cx.error_spanned_by( + variant.original, + format!( + "variant `{}` cannot have both #[serde(deserialize_with)] and a field {} marked with #[serde(skip_deserializing)]", + variant.ident, member + ), + ); + } + } + } + } +} + +// The tag of an internally-tagged struct variant must not be the same as either +// one of its fields, as this would result in duplicate keys in the serialized +// output and/or ambiguity in the to-be-deserialized input. +fn check_internal_tag_field_name_conflict(cx: &Ctxt, cont: &Container) { + let variants = match &cont.data { + Data::Enum(variants) => variants, + Data::Struct(_, _) => return, + }; + + let tag = match cont.attrs.tag() { + TagType::Internal { tag } => tag.as_str(), + TagType::External | TagType::Adjacent { .. } | TagType::None => return, + }; + + let diagnose_conflict = || { + cx.error_spanned_by( + cont.original, + format!("variant field name `{}` conflicts with internal tag", tag), + ); + }; + + for variant in variants { + match variant.style { + Style::Struct => { + if variant.attrs.untagged() { + continue; + } + for field in &variant.fields { + let check_ser = + !(field.attrs.skip_serializing() || variant.attrs.skip_serializing()); + let check_de = + !(field.attrs.skip_deserializing() || variant.attrs.skip_deserializing()); + let name = field.attrs.name(); + let ser_name = name.serialize_name(); + + if check_ser && ser_name == tag { + diagnose_conflict(); + return; + } + + for de_name in field.attrs.aliases() { + if check_de && de_name == tag { + diagnose_conflict(); + return; + } + } + } + } + Style::Unit | Style::Newtype | Style::Tuple => {} + } + } +} + +// In the case of adjacently-tagged enums, the type and the contents tag must +// differ, for the same reason. +fn check_adjacent_tag_conflict(cx: &Ctxt, cont: &Container) { + let (type_tag, content_tag) = match cont.attrs.tag() { + TagType::Adjacent { tag, content } => (tag, content), + TagType::Internal { .. } | TagType::External | TagType::None => return, + }; + + if type_tag == content_tag { + cx.error_spanned_by( + cont.original, + format!( + "enum tags `{}` for type and content conflict with each other", + type_tag + ), + ); + } +} + +// Enums and unit structs cannot be transparent. +fn check_transparent(cx: &Ctxt, cont: &mut Container, derive: Derive) { + if !cont.attrs.transparent() { + return; + } + + if cont.attrs.type_from().is_some() { + cx.error_spanned_by( + cont.original, + "#[serde(transparent)] is not allowed with #[serde(from = \"...\")]", + ); + } + + if cont.attrs.type_try_from().is_some() { + cx.error_spanned_by( + cont.original, + "#[serde(transparent)] is not allowed with #[serde(try_from = \"...\")]", + ); + } + + if cont.attrs.type_into().is_some() { + cx.error_spanned_by( + cont.original, + "#[serde(transparent)] is not allowed with #[serde(into = \"...\")]", + ); + } + + let fields = match &mut cont.data { + Data::Enum(_) => { + cx.error_spanned_by( + cont.original, + "#[serde(transparent)] is not allowed on an enum", + ); + return; + } + Data::Struct(Style::Unit, _) => { + cx.error_spanned_by( + cont.original, + "#[serde(transparent)] is not allowed on a unit struct", + ); + return; + } + Data::Struct(_, fields) => fields, + }; + + let mut transparent_field = None; + + for field in fields { + if allow_transparent(field, derive) { + if transparent_field.is_some() { + cx.error_spanned_by( + cont.original, + "#[serde(transparent)] requires struct to have at most one transparent field", + ); + return; + } + transparent_field = Some(field); + } + } + + match transparent_field { + Some(transparent_field) => transparent_field.attrs.mark_transparent(), + None => match derive { + Derive::Serialize => { + cx.error_spanned_by( + cont.original, + "#[serde(transparent)] requires at least one field that is not skipped", + ); + } + Derive::Deserialize => { + cx.error_spanned_by( + cont.original, + "#[serde(transparent)] requires at least one field that is neither skipped nor has a default", + ); + } + }, + } +} + +fn member_message(member: &Member) -> String { + match member { + Member::Named(ident) => format!("`{}`", ident), + Member::Unnamed(i) => format!("#{}", i.index), + } +} + +fn allow_transparent(field: &Field, derive: Derive) -> bool { + if let Type::Path(ty) = ungroup(field.ty) { + if let Some(seg) = ty.path.segments.last() { + if seg.ident == "PhantomData" { + return false; + } + } + } + + match derive { + Derive::Serialize => !field.attrs.skip_serializing(), + Derive::Deserialize => !field.attrs.skip_deserializing() && field.attrs.default().is_none(), + } +} + +fn check_from_and_try_from(cx: &Ctxt, cont: &mut Container) { + if cont.attrs.type_from().is_some() && cont.attrs.type_try_from().is_some() { + cx.error_spanned_by( + cont.original, + "#[serde(from = \"...\")] and #[serde(try_from = \"...\")] conflict with each other", + ); + } +} diff --git a/vendor/serde_derive/src/internals/ctxt.rs b/vendor/serde_derive/src/internals/ctxt.rs new file mode 100644 index 0000000..a47bfa4 --- /dev/null +++ b/vendor/serde_derive/src/internals/ctxt.rs @@ -0,0 +1,68 @@ +use quote::ToTokens; +use std::cell::RefCell; +use std::fmt::Display; +use std::thread; + +/// A type to collect errors together and format them. +/// +/// Dropping this object will cause a panic. It must be consumed using `check`. +/// +/// References can be shared since this type uses run-time exclusive mut checking. +#[derive(Default)] +pub struct Ctxt { + // The contents will be set to `None` during checking. This is so that checking can be + // enforced. + errors: RefCell>>, +} + +impl Ctxt { + /// Create a new context object. + /// + /// This object contains no errors, but will still trigger a panic if it is not `check`ed. + pub fn new() -> Self { + Ctxt { + errors: RefCell::new(Some(Vec::new())), + } + } + + /// Add an error to the context object with a tokenenizable object. + /// + /// The object is used for spanning in error messages. + pub fn error_spanned_by(&self, obj: A, msg: T) { + self.errors + .borrow_mut() + .as_mut() + .unwrap() + // Curb monomorphization from generating too many identical methods. + .push(syn::Error::new_spanned(obj.into_token_stream(), msg)); + } + + /// Add one of Syn's parse errors. + pub fn syn_error(&self, err: syn::Error) { + self.errors.borrow_mut().as_mut().unwrap().push(err); + } + + /// Consume this object, producing a formatted error string if there are errors. + pub fn check(self) -> syn::Result<()> { + let mut errors = self.errors.borrow_mut().take().unwrap().into_iter(); + + let mut combined = match errors.next() { + Some(first) => first, + None => return Ok(()), + }; + + for rest in errors { + combined.combine(rest); + } + + Err(combined) + } +} + +impl Drop for Ctxt { + fn drop(&mut self) { + if !thread::panicking() && self.errors.borrow().is_some() { + panic!("forgot to check for errors"); + } + } +} diff --git a/vendor/serde_derive/src/internals/mod.rs b/vendor/serde_derive/src/internals/mod.rs new file mode 100644 index 0000000..f98ef08 --- /dev/null +++ b/vendor/serde_derive/src/internals/mod.rs @@ -0,0 +1,27 @@ +pub mod ast; +pub mod attr; + +mod case; +mod check; +mod ctxt; +mod receiver; +mod respan; +mod symbol; + +use syn::Type; + +pub use self::ctxt::Ctxt; +pub use self::receiver::replace_receiver; + +#[derive(Copy, Clone)] +pub enum Derive { + Serialize, + Deserialize, +} + +pub fn ungroup(mut ty: &Type) -> &Type { + while let Type::Group(group) = ty { + ty = &group.elem; + } + ty +} diff --git a/vendor/serde_derive/src/internals/receiver.rs b/vendor/serde_derive/src/internals/receiver.rs new file mode 100644 index 0000000..852e857 --- /dev/null +++ b/vendor/serde_derive/src/internals/receiver.rs @@ -0,0 +1,292 @@ +use crate::internals::respan::respan; +use proc_macro2::Span; +use quote::ToTokens; +use std::mem; +use syn::punctuated::Punctuated; +use syn::{ + parse_quote, Data, DeriveInput, Expr, ExprPath, GenericArgument, GenericParam, Generics, Macro, + Path, PathArguments, QSelf, ReturnType, Token, Type, TypeParamBound, TypePath, WherePredicate, +}; + +pub fn replace_receiver(input: &mut DeriveInput) { + let self_ty = { + let ident = &input.ident; + let ty_generics = input.generics.split_for_impl().1; + parse_quote!(#ident #ty_generics) + }; + let mut visitor = ReplaceReceiver(&self_ty); + visitor.visit_generics_mut(&mut input.generics); + visitor.visit_data_mut(&mut input.data); +} + +struct ReplaceReceiver<'a>(&'a TypePath); + +impl ReplaceReceiver<'_> { + fn self_ty(&self, span: Span) -> TypePath { + let tokens = self.0.to_token_stream(); + let respanned = respan(tokens, span); + syn::parse2(respanned).unwrap() + } + + fn self_to_qself(&self, qself: &mut Option, path: &mut Path) { + if path.leading_colon.is_some() || path.segments[0].ident != "Self" { + return; + } + + if path.segments.len() == 1 { + self.self_to_expr_path(path); + return; + } + + let span = path.segments[0].ident.span(); + *qself = Some(QSelf { + lt_token: Token![<](span), + ty: Box::new(Type::Path(self.self_ty(span))), + position: 0, + as_token: None, + gt_token: Token![>](span), + }); + + path.leading_colon = Some(**path.segments.pairs().next().unwrap().punct().unwrap()); + + let segments = mem::replace(&mut path.segments, Punctuated::new()); + path.segments = segments.into_pairs().skip(1).collect(); + } + + fn self_to_expr_path(&self, path: &mut Path) { + let self_ty = self.self_ty(path.segments[0].ident.span()); + let variant = mem::replace(path, self_ty.path); + for segment in &mut path.segments { + if let PathArguments::AngleBracketed(bracketed) = &mut segment.arguments { + if bracketed.colon2_token.is_none() && !bracketed.args.is_empty() { + bracketed.colon2_token = Some(::default()); + } + } + } + if variant.segments.len() > 1 { + path.segments.push_punct(::default()); + path.segments.extend(variant.segments.into_pairs().skip(1)); + } + } +} + +impl ReplaceReceiver<'_> { + // `Self` -> `Receiver` + fn visit_type_mut(&mut self, ty: &mut Type) { + let span = if let Type::Path(node) = ty { + if node.qself.is_none() && node.path.is_ident("Self") { + node.path.segments[0].ident.span() + } else { + self.visit_type_path_mut(node); + return; + } + } else { + self.visit_type_mut_impl(ty); + return; + }; + *ty = Type::Path(self.self_ty(span)); + } + + // `Self::Assoc` -> `::Assoc` + fn visit_type_path_mut(&mut self, ty: &mut TypePath) { + if ty.qself.is_none() { + self.self_to_qself(&mut ty.qself, &mut ty.path); + } + self.visit_type_path_mut_impl(ty); + } + + // `Self::method` -> `::method` + fn visit_expr_path_mut(&mut self, expr: &mut ExprPath) { + if expr.qself.is_none() { + self.self_to_qself(&mut expr.qself, &mut expr.path); + } + self.visit_expr_path_mut_impl(expr); + } + + // Everything below is simply traversing the syntax tree. + + fn visit_type_mut_impl(&mut self, ty: &mut Type) { + match ty { + #![cfg_attr(all(test, exhaustive), deny(non_exhaustive_omitted_patterns))] + Type::Array(ty) => { + self.visit_type_mut(&mut ty.elem); + self.visit_expr_mut(&mut ty.len); + } + Type::BareFn(ty) => { + for arg in &mut ty.inputs { + self.visit_type_mut(&mut arg.ty); + } + self.visit_return_type_mut(&mut ty.output); + } + Type::Group(ty) => self.visit_type_mut(&mut ty.elem), + Type::ImplTrait(ty) => { + for bound in &mut ty.bounds { + self.visit_type_param_bound_mut(bound); + } + } + Type::Macro(ty) => self.visit_macro_mut(&mut ty.mac), + Type::Paren(ty) => self.visit_type_mut(&mut ty.elem), + Type::Path(ty) => { + if let Some(qself) = &mut ty.qself { + self.visit_type_mut(&mut qself.ty); + } + self.visit_path_mut(&mut ty.path); + } + Type::Ptr(ty) => self.visit_type_mut(&mut ty.elem), + Type::Reference(ty) => self.visit_type_mut(&mut ty.elem), + Type::Slice(ty) => self.visit_type_mut(&mut ty.elem), + Type::TraitObject(ty) => { + for bound in &mut ty.bounds { + self.visit_type_param_bound_mut(bound); + } + } + Type::Tuple(ty) => { + for elem in &mut ty.elems { + self.visit_type_mut(elem); + } + } + + Type::Infer(_) | Type::Never(_) | Type::Verbatim(_) => {} + + _ => {} + } + } + + fn visit_type_path_mut_impl(&mut self, ty: &mut TypePath) { + if let Some(qself) = &mut ty.qself { + self.visit_type_mut(&mut qself.ty); + } + self.visit_path_mut(&mut ty.path); + } + + fn visit_expr_path_mut_impl(&mut self, expr: &mut ExprPath) { + if let Some(qself) = &mut expr.qself { + self.visit_type_mut(&mut qself.ty); + } + self.visit_path_mut(&mut expr.path); + } + + fn visit_path_mut(&mut self, path: &mut Path) { + for segment in &mut path.segments { + self.visit_path_arguments_mut(&mut segment.arguments); + } + } + + fn visit_path_arguments_mut(&mut self, arguments: &mut PathArguments) { + match arguments { + PathArguments::None => {} + PathArguments::AngleBracketed(arguments) => { + for arg in &mut arguments.args { + match arg { + #![cfg_attr(all(test, exhaustive), deny(non_exhaustive_omitted_patterns))] + GenericArgument::Type(arg) => self.visit_type_mut(arg), + GenericArgument::AssocType(arg) => self.visit_type_mut(&mut arg.ty), + GenericArgument::Lifetime(_) + | GenericArgument::Const(_) + | GenericArgument::AssocConst(_) + | GenericArgument::Constraint(_) => {} + _ => {} + } + } + } + PathArguments::Parenthesized(arguments) => { + for argument in &mut arguments.inputs { + self.visit_type_mut(argument); + } + self.visit_return_type_mut(&mut arguments.output); + } + } + } + + fn visit_return_type_mut(&mut self, return_type: &mut ReturnType) { + match return_type { + ReturnType::Default => {} + ReturnType::Type(_, output) => self.visit_type_mut(output), + } + } + + fn visit_type_param_bound_mut(&mut self, bound: &mut TypeParamBound) { + match bound { + #![cfg_attr(all(test, exhaustive), deny(non_exhaustive_omitted_patterns))] + TypeParamBound::Trait(bound) => self.visit_path_mut(&mut bound.path), + TypeParamBound::Lifetime(_) | TypeParamBound::Verbatim(_) => {} + _ => {} + } + } + + fn visit_generics_mut(&mut self, generics: &mut Generics) { + for param in &mut generics.params { + match param { + GenericParam::Type(param) => { + for bound in &mut param.bounds { + self.visit_type_param_bound_mut(bound); + } + } + GenericParam::Lifetime(_) | GenericParam::Const(_) => {} + } + } + if let Some(where_clause) = &mut generics.where_clause { + for predicate in &mut where_clause.predicates { + match predicate { + #![cfg_attr(all(test, exhaustive), deny(non_exhaustive_omitted_patterns))] + WherePredicate::Type(predicate) => { + self.visit_type_mut(&mut predicate.bounded_ty); + for bound in &mut predicate.bounds { + self.visit_type_param_bound_mut(bound); + } + } + WherePredicate::Lifetime(_) => {} + _ => {} + } + } + } + } + + fn visit_data_mut(&mut self, data: &mut Data) { + match data { + Data::Struct(data) => { + for field in &mut data.fields { + self.visit_type_mut(&mut field.ty); + } + } + Data::Enum(data) => { + for variant in &mut data.variants { + for field in &mut variant.fields { + self.visit_type_mut(&mut field.ty); + } + } + } + Data::Union(_) => {} + } + } + + fn visit_expr_mut(&mut self, expr: &mut Expr) { + match expr { + Expr::Binary(expr) => { + self.visit_expr_mut(&mut expr.left); + self.visit_expr_mut(&mut expr.right); + } + Expr::Call(expr) => { + self.visit_expr_mut(&mut expr.func); + for arg in &mut expr.args { + self.visit_expr_mut(arg); + } + } + Expr::Cast(expr) => { + self.visit_expr_mut(&mut expr.expr); + self.visit_type_mut(&mut expr.ty); + } + Expr::Field(expr) => self.visit_expr_mut(&mut expr.base), + Expr::Index(expr) => { + self.visit_expr_mut(&mut expr.expr); + self.visit_expr_mut(&mut expr.index); + } + Expr::Paren(expr) => self.visit_expr_mut(&mut expr.expr), + Expr::Path(expr) => self.visit_expr_path_mut(expr), + Expr::Unary(expr) => self.visit_expr_mut(&mut expr.expr), + _ => {} + } + } + + fn visit_macro_mut(&mut self, _mac: &mut Macro) {} +} diff --git a/vendor/serde_derive/src/internals/respan.rs b/vendor/serde_derive/src/internals/respan.rs new file mode 100644 index 0000000..dcec701 --- /dev/null +++ b/vendor/serde_derive/src/internals/respan.rs @@ -0,0 +1,16 @@ +use proc_macro2::{Group, Span, TokenStream, TokenTree}; + +pub(crate) fn respan(stream: TokenStream, span: Span) -> TokenStream { + stream + .into_iter() + .map(|token| respan_token(token, span)) + .collect() +} + +fn respan_token(mut token: TokenTree, span: Span) -> TokenTree { + if let TokenTree::Group(g) = &mut token { + *g = Group::new(g.delimiter(), respan(g.stream(), span)); + } + token.set_span(span); + token +} diff --git a/vendor/serde_derive/src/internals/symbol.rs b/vendor/serde_derive/src/internals/symbol.rs new file mode 100644 index 0000000..572391a --- /dev/null +++ b/vendor/serde_derive/src/internals/symbol.rs @@ -0,0 +1,71 @@ +use std::fmt::{self, Display}; +use syn::{Ident, Path}; + +#[derive(Copy, Clone)] +pub struct Symbol(&'static str); + +pub const ALIAS: Symbol = Symbol("alias"); +pub const BORROW: Symbol = Symbol("borrow"); +pub const BOUND: Symbol = Symbol("bound"); +pub const CONTENT: Symbol = Symbol("content"); +pub const CRATE: Symbol = Symbol("crate"); +pub const DEFAULT: Symbol = Symbol("default"); +pub const DENY_UNKNOWN_FIELDS: Symbol = Symbol("deny_unknown_fields"); +pub const DESERIALIZE: Symbol = Symbol("deserialize"); +pub const DESERIALIZE_WITH: Symbol = Symbol("deserialize_with"); +pub const EXPECTING: Symbol = Symbol("expecting"); +pub const FIELD_IDENTIFIER: Symbol = Symbol("field_identifier"); +pub const FLATTEN: Symbol = Symbol("flatten"); +pub const FROM: Symbol = Symbol("from"); +pub const GETTER: Symbol = Symbol("getter"); +pub const INTO: Symbol = Symbol("into"); +pub const NON_EXHAUSTIVE: Symbol = Symbol("non_exhaustive"); +pub const OTHER: Symbol = Symbol("other"); +pub const REMOTE: Symbol = Symbol("remote"); +pub const RENAME: Symbol = Symbol("rename"); +pub const RENAME_ALL: Symbol = Symbol("rename_all"); +pub const RENAME_ALL_FIELDS: Symbol = Symbol("rename_all_fields"); +pub const REPR: Symbol = Symbol("repr"); +pub const SERDE: Symbol = Symbol("serde"); +pub const SERIALIZE: Symbol = Symbol("serialize"); +pub const SERIALIZE_WITH: Symbol = Symbol("serialize_with"); +pub const SKIP: Symbol = Symbol("skip"); +pub const SKIP_DESERIALIZING: Symbol = Symbol("skip_deserializing"); +pub const SKIP_SERIALIZING: Symbol = Symbol("skip_serializing"); +pub const SKIP_SERIALIZING_IF: Symbol = Symbol("skip_serializing_if"); +pub const TAG: Symbol = Symbol("tag"); +pub const TRANSPARENT: Symbol = Symbol("transparent"); +pub const TRY_FROM: Symbol = Symbol("try_from"); +pub const UNTAGGED: Symbol = Symbol("untagged"); +pub const VARIANT_IDENTIFIER: Symbol = Symbol("variant_identifier"); +pub const WITH: Symbol = Symbol("with"); + +impl PartialEq for Ident { + fn eq(&self, word: &Symbol) -> bool { + self == word.0 + } +} + +impl<'a> PartialEq for &'a Ident { + fn eq(&self, word: &Symbol) -> bool { + *self == word.0 + } +} + +impl PartialEq for Path { + fn eq(&self, word: &Symbol) -> bool { + self.is_ident(word.0) + } +} + +impl<'a> PartialEq for &'a Path { + fn eq(&self, word: &Symbol) -> bool { + self.is_ident(word.0) + } +} + +impl Display for Symbol { + fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str(self.0) + } +} diff --git a/vendor/serde_derive/src/lib.rs b/vendor/serde_derive/src/lib.rs new file mode 100644 index 0000000..bedd1cb --- /dev/null +++ b/vendor/serde_derive/src/lib.rs @@ -0,0 +1,102 @@ +//! This crate provides Serde's two derive macros. +//! +//! ```edition2021 +//! # use serde_derive::{Deserialize, Serialize}; +//! # +//! #[derive(Serialize, Deserialize)] +//! # struct S; +//! # +//! # fn main() {} +//! ``` +//! +//! Please refer to [https://serde.rs/derive.html] for how to set this up. +//! +//! [https://serde.rs/derive.html]: https://serde.rs/derive.html + +#![doc(html_root_url = "https://docs.rs/serde_derive/1.0.210")] +#![cfg_attr(not(check_cfg), allow(unexpected_cfgs))] +// Ignored clippy lints +#![allow( + // clippy false positive: https://github.com/rust-lang/rust-clippy/issues/7054 + clippy::branches_sharing_code, + clippy::cognitive_complexity, + // clippy bug: https://github.com/rust-lang/rust-clippy/issues/7575 + clippy::collapsible_match, + clippy::derive_partial_eq_without_eq, + clippy::enum_variant_names, + // clippy bug: https://github.com/rust-lang/rust-clippy/issues/6797 + clippy::manual_map, + clippy::match_like_matches_macro, + clippy::needless_pass_by_value, + clippy::too_many_arguments, + clippy::trivially_copy_pass_by_ref, + clippy::used_underscore_binding, + clippy::wildcard_in_or_patterns, + // clippy bug: https://github.com/rust-lang/rust-clippy/issues/5704 + clippy::unnested_or_patterns, +)] +// Ignored clippy_pedantic lints +#![allow( + clippy::cast_possible_truncation, + clippy::checked_conversions, + clippy::doc_markdown, + clippy::enum_glob_use, + clippy::indexing_slicing, + clippy::items_after_statements, + clippy::let_underscore_untyped, + clippy::manual_assert, + clippy::map_err_ignore, + clippy::match_same_arms, + // clippy bug: https://github.com/rust-lang/rust-clippy/issues/6984 + clippy::match_wildcard_for_single_variants, + clippy::module_name_repetitions, + clippy::must_use_candidate, + clippy::similar_names, + clippy::single_match_else, + clippy::struct_excessive_bools, + clippy::too_many_lines, + clippy::unseparated_literal_suffix, + clippy::unused_self, + clippy::use_self, + clippy::wildcard_imports +)] +#![cfg_attr(all(test, exhaustive), feature(non_exhaustive_omitted_patterns_lint))] + +extern crate proc_macro2; +extern crate quote; +extern crate syn; + +extern crate proc_macro; + +mod internals; + +use proc_macro::TokenStream; +use syn::parse_macro_input; +use syn::DeriveInput; + +#[macro_use] +mod bound; +#[macro_use] +mod fragment; + +mod de; +mod dummy; +mod pretend; +mod ser; +mod this; + +#[proc_macro_derive(Serialize, attributes(serde))] +pub fn derive_serialize(input: TokenStream) -> TokenStream { + let mut input = parse_macro_input!(input as DeriveInput); + ser::expand_derive_serialize(&mut input) + .unwrap_or_else(syn::Error::into_compile_error) + .into() +} + +#[proc_macro_derive(Deserialize, attributes(serde))] +pub fn derive_deserialize(input: TokenStream) -> TokenStream { + let mut input = parse_macro_input!(input as DeriveInput); + de::expand_derive_deserialize(&mut input) + .unwrap_or_else(syn::Error::into_compile_error) + .into() +} diff --git a/vendor/serde_derive/src/pretend.rs b/vendor/serde_derive/src/pretend.rs new file mode 100644 index 0000000..2c9e779 --- /dev/null +++ b/vendor/serde_derive/src/pretend.rs @@ -0,0 +1,185 @@ +use crate::internals::ast::{Container, Data, Field, Style, Variant}; +use proc_macro2::TokenStream; +use quote::{format_ident, quote}; + +// Suppress dead_code warnings that would otherwise appear when using a remote +// derive. Other than this pretend code, a struct annotated with remote derive +// never has its fields referenced and an enum annotated with remote derive +// never has its variants constructed. +// +// warning: field is never used: `i` +// --> src/main.rs:4:20 +// | +// 4 | struct StructDef { i: i32 } +// | ^^^^^^ +// +// warning: variant is never constructed: `V` +// --> src/main.rs:8:16 +// | +// 8 | enum EnumDef { V } +// | ^ +// +pub fn pretend_used(cont: &Container, is_packed: bool) -> TokenStream { + let pretend_fields = pretend_fields_used(cont, is_packed); + let pretend_variants = pretend_variants_used(cont); + + quote! { + #pretend_fields + #pretend_variants + } +} + +// For structs with named fields, expands to: +// +// match None::<&T> { +// Some(T { a: __v0, b: __v1 }) => {} +// _ => {} +// } +// +// For packed structs on sufficiently new rustc, expands to: +// +// match None::<&T> { +// Some(__v @ T { a: _, b: _ }) => { +// let _ = addr_of!(__v.a); +// let _ = addr_of!(__v.b); +// } +// _ => {} +// } +// +// For packed structs on older rustc, we assume Sized and !Drop, and expand to: +// +// match None:: { +// Some(T { a: __v0, b: __v1 }) => {} +// _ => {} +// } +// +// For enums, expands to the following but only including struct variants: +// +// match None::<&T> { +// Some(T::A { a: __v0 }) => {} +// Some(T::B { b: __v0 }) => {} +// _ => {} +// } +// +fn pretend_fields_used(cont: &Container, is_packed: bool) -> TokenStream { + match &cont.data { + Data::Enum(variants) => pretend_fields_used_enum(cont, variants), + Data::Struct(Style::Struct | Style::Tuple | Style::Newtype, fields) => { + if is_packed { + pretend_fields_used_struct_packed(cont, fields) + } else { + pretend_fields_used_struct(cont, fields) + } + } + Data::Struct(Style::Unit, _) => quote!(), + } +} + +fn pretend_fields_used_struct(cont: &Container, fields: &[Field]) -> TokenStream { + let type_ident = &cont.ident; + let (_, ty_generics, _) = cont.generics.split_for_impl(); + + let members = fields.iter().map(|field| &field.member); + let placeholders = (0usize..).map(|i| format_ident!("__v{}", i)); + + quote! { + match _serde::__private::None::<&#type_ident #ty_generics> { + _serde::__private::Some(#type_ident { #(#members: #placeholders),* }) => {} + _ => {} + } + } +} + +fn pretend_fields_used_struct_packed(cont: &Container, fields: &[Field]) -> TokenStream { + let type_ident = &cont.ident; + let (_, ty_generics, _) = cont.generics.split_for_impl(); + + let members = fields.iter().map(|field| &field.member).collect::>(); + + quote! { + match _serde::__private::None::<&#type_ident #ty_generics> { + _serde::__private::Some(__v @ #type_ident { #(#members: _),* }) => { + #( + let _ = _serde::__private::ptr::addr_of!(__v.#members); + )* + } + _ => {} + } + } +} + +fn pretend_fields_used_enum(cont: &Container, variants: &[Variant]) -> TokenStream { + let type_ident = &cont.ident; + let (_, ty_generics, _) = cont.generics.split_for_impl(); + + let patterns = variants + .iter() + .filter_map(|variant| match variant.style { + Style::Struct | Style::Tuple | Style::Newtype => { + let variant_ident = &variant.ident; + let members = variant.fields.iter().map(|field| &field.member); + let placeholders = (0usize..).map(|i| format_ident!("__v{}", i)); + Some(quote!(#type_ident::#variant_ident { #(#members: #placeholders),* })) + } + Style::Unit => None, + }) + .collect::>(); + + quote! { + match _serde::__private::None::<&#type_ident #ty_generics> { + #( + _serde::__private::Some(#patterns) => {} + )* + _ => {} + } + } +} + +// Expands to one of these per enum variant: +// +// match None { +// Some((__v0, __v1,)) => { +// let _ = E::V { a: __v0, b: __v1 }; +// } +// _ => {} +// } +// +fn pretend_variants_used(cont: &Container) -> TokenStream { + let variants = match &cont.data { + Data::Enum(variants) => variants, + Data::Struct(_, _) => { + return quote!(); + } + }; + + let type_ident = &cont.ident; + let (_, ty_generics, _) = cont.generics.split_for_impl(); + let turbofish = ty_generics.as_turbofish(); + + let cases = variants.iter().map(|variant| { + let variant_ident = &variant.ident; + let placeholders = &(0..variant.fields.len()) + .map(|i| format_ident!("__v{}", i)) + .collect::>(); + + let pat = match variant.style { + Style::Struct => { + let members = variant.fields.iter().map(|field| &field.member); + quote!({ #(#members: #placeholders),* }) + } + Style::Tuple | Style::Newtype => quote!(( #(#placeholders),* )), + Style::Unit => quote!(), + }; + + quote! { + match _serde::__private::None { + _serde::__private::Some((#(#placeholders,)*)) => { + let _ = #type_ident::#variant_ident #turbofish #pat; + } + _ => {} + } + } + }); + + quote!(#(#cases)*) +} diff --git a/vendor/serde_derive/src/ser.rs b/vendor/serde_derive/src/ser.rs new file mode 100644 index 0000000..35f8ca4 --- /dev/null +++ b/vendor/serde_derive/src/ser.rs @@ -0,0 +1,1350 @@ +use crate::fragment::{Fragment, Match, Stmts}; +use crate::internals::ast::{Container, Data, Field, Style, Variant}; +use crate::internals::{attr, replace_receiver, Ctxt, Derive}; +use crate::{bound, dummy, pretend, this}; +use proc_macro2::{Span, TokenStream}; +use quote::{quote, quote_spanned}; +use syn::spanned::Spanned; +use syn::{parse_quote, Ident, Index, Member}; + +pub fn expand_derive_serialize(input: &mut syn::DeriveInput) -> syn::Result { + replace_receiver(input); + + let ctxt = Ctxt::new(); + let cont = match Container::from_ast(&ctxt, input, Derive::Serialize) { + Some(cont) => cont, + None => return Err(ctxt.check().unwrap_err()), + }; + precondition(&ctxt, &cont); + ctxt.check()?; + + let ident = &cont.ident; + let params = Parameters::new(&cont); + let (impl_generics, ty_generics, where_clause) = params.generics.split_for_impl(); + let body = Stmts(serialize_body(&cont, ¶ms)); + let serde = cont.attrs.serde_path(); + + let impl_block = if let Some(remote) = cont.attrs.remote() { + let vis = &input.vis; + let used = pretend::pretend_used(&cont, params.is_packed); + quote! { + impl #impl_generics #ident #ty_generics #where_clause { + #vis fn serialize<__S>(__self: &#remote #ty_generics, __serializer: __S) -> #serde::__private::Result<__S::Ok, __S::Error> + where + __S: #serde::Serializer, + { + #used + #body + } + } + } + } else { + quote! { + #[automatically_derived] + impl #impl_generics #serde::Serialize for #ident #ty_generics #where_clause { + fn serialize<__S>(&self, __serializer: __S) -> #serde::__private::Result<__S::Ok, __S::Error> + where + __S: #serde::Serializer, + { + #body + } + } + } + }; + + Ok(dummy::wrap_in_const( + cont.attrs.custom_serde_path(), + impl_block, + )) +} + +fn precondition(cx: &Ctxt, cont: &Container) { + match cont.attrs.identifier() { + attr::Identifier::No => {} + attr::Identifier::Field => { + cx.error_spanned_by(cont.original, "field identifiers cannot be serialized"); + } + attr::Identifier::Variant => { + cx.error_spanned_by(cont.original, "variant identifiers cannot be serialized"); + } + } +} + +struct Parameters { + /// Variable holding the value being serialized. Either `self` for local + /// types or `__self` for remote types. + self_var: Ident, + + /// Path to the type the impl is for. Either a single `Ident` for local + /// types (does not include generic parameters) or `some::remote::Path` for + /// remote types. + this_type: syn::Path, + + /// Same as `this_type` but using `::` for generic parameters for use in + /// expression position. + this_value: syn::Path, + + /// Generics including any explicit and inferred bounds for the impl. + generics: syn::Generics, + + /// Type has a `serde(remote = "...")` attribute. + is_remote: bool, + + /// Type has a repr(packed) attribute. + is_packed: bool, +} + +impl Parameters { + fn new(cont: &Container) -> Self { + let is_remote = cont.attrs.remote().is_some(); + let self_var = if is_remote { + Ident::new("__self", Span::call_site()) + } else { + Ident::new("self", Span::call_site()) + }; + + let this_type = this::this_type(cont); + let this_value = this::this_value(cont); + let is_packed = cont.attrs.is_packed(); + let generics = build_generics(cont); + + Parameters { + self_var, + this_type, + this_value, + generics, + is_remote, + is_packed, + } + } + + /// Type name to use in error messages and `&'static str` arguments to + /// various Serializer methods. + fn type_name(&self) -> String { + self.this_type.segments.last().unwrap().ident.to_string() + } +} + +// All the generics in the input, plus a bound `T: Serialize` for each generic +// field type that will be serialized by us. +fn build_generics(cont: &Container) -> syn::Generics { + let generics = bound::without_defaults(cont.generics); + + let generics = + bound::with_where_predicates_from_fields(cont, &generics, attr::Field::ser_bound); + + let generics = + bound::with_where_predicates_from_variants(cont, &generics, attr::Variant::ser_bound); + + match cont.attrs.ser_bound() { + Some(predicates) => bound::with_where_predicates(&generics, predicates), + None => bound::with_bound( + cont, + &generics, + needs_serialize_bound, + &parse_quote!(_serde::Serialize), + ), + } +} + +// Fields with a `skip_serializing` or `serialize_with` attribute, or which +// belong to a variant with a 'skip_serializing` or `serialize_with` attribute, +// are not serialized by us so we do not generate a bound. Fields with a `bound` +// attribute specify their own bound so we do not generate one. All other fields +// may need a `T: Serialize` bound where T is the type of the field. +fn needs_serialize_bound(field: &attr::Field, variant: Option<&attr::Variant>) -> bool { + !field.skip_serializing() + && field.serialize_with().is_none() + && field.ser_bound().is_none() + && variant.map_or(true, |variant| { + !variant.skip_serializing() + && variant.serialize_with().is_none() + && variant.ser_bound().is_none() + }) +} + +fn serialize_body(cont: &Container, params: &Parameters) -> Fragment { + if cont.attrs.transparent() { + serialize_transparent(cont, params) + } else if let Some(type_into) = cont.attrs.type_into() { + serialize_into(params, type_into) + } else { + match &cont.data { + Data::Enum(variants) => serialize_enum(params, variants, &cont.attrs), + Data::Struct(Style::Struct, fields) => serialize_struct(params, fields, &cont.attrs), + Data::Struct(Style::Tuple, fields) => { + serialize_tuple_struct(params, fields, &cont.attrs) + } + Data::Struct(Style::Newtype, fields) => { + serialize_newtype_struct(params, &fields[0], &cont.attrs) + } + Data::Struct(Style::Unit, _) => serialize_unit_struct(&cont.attrs), + } + } +} + +fn serialize_transparent(cont: &Container, params: &Parameters) -> Fragment { + let fields = match &cont.data { + Data::Struct(_, fields) => fields, + Data::Enum(_) => unreachable!(), + }; + + let self_var = ¶ms.self_var; + let transparent_field = fields.iter().find(|f| f.attrs.transparent()).unwrap(); + let member = &transparent_field.member; + + let path = match transparent_field.attrs.serialize_with() { + Some(path) => quote!(#path), + None => { + let span = transparent_field.original.span(); + quote_spanned!(span=> _serde::Serialize::serialize) + } + }; + + quote_block! { + #path(&#self_var.#member, __serializer) + } +} + +fn serialize_into(params: &Parameters, type_into: &syn::Type) -> Fragment { + let self_var = ¶ms.self_var; + quote_block! { + _serde::Serialize::serialize( + &_serde::__private::Into::<#type_into>::into(_serde::__private::Clone::clone(#self_var)), + __serializer) + } +} + +fn serialize_unit_struct(cattrs: &attr::Container) -> Fragment { + let type_name = cattrs.name().serialize_name(); + + quote_expr! { + _serde::Serializer::serialize_unit_struct(__serializer, #type_name) + } +} + +fn serialize_newtype_struct( + params: &Parameters, + field: &Field, + cattrs: &attr::Container, +) -> Fragment { + let type_name = cattrs.name().serialize_name(); + + let mut field_expr = get_member( + params, + field, + &Member::Unnamed(Index { + index: 0, + span: Span::call_site(), + }), + ); + if let Some(path) = field.attrs.serialize_with() { + field_expr = wrap_serialize_field_with(params, field.ty, path, &field_expr); + } + + let span = field.original.span(); + let func = quote_spanned!(span=> _serde::Serializer::serialize_newtype_struct); + quote_expr! { + #func(__serializer, #type_name, #field_expr) + } +} + +fn serialize_tuple_struct( + params: &Parameters, + fields: &[Field], + cattrs: &attr::Container, +) -> Fragment { + let serialize_stmts = + serialize_tuple_struct_visitor(fields, params, false, &TupleTrait::SerializeTupleStruct); + + let type_name = cattrs.name().serialize_name(); + + let mut serialized_fields = fields + .iter() + .enumerate() + .filter(|(_, field)| !field.attrs.skip_serializing()) + .peekable(); + + let let_mut = mut_if(serialized_fields.peek().is_some()); + + let len = serialized_fields + .map(|(i, field)| match field.attrs.skip_serializing_if() { + None => quote!(1), + Some(path) => { + let index = syn::Index { + index: i as u32, + span: Span::call_site(), + }; + let field_expr = get_member(params, field, &Member::Unnamed(index)); + quote!(if #path(#field_expr) { 0 } else { 1 }) + } + }) + .fold(quote!(0), |sum, expr| quote!(#sum + #expr)); + + quote_block! { + let #let_mut __serde_state = _serde::Serializer::serialize_tuple_struct(__serializer, #type_name, #len)?; + #(#serialize_stmts)* + _serde::ser::SerializeTupleStruct::end(__serde_state) + } +} + +fn serialize_struct(params: &Parameters, fields: &[Field], cattrs: &attr::Container) -> Fragment { + assert!( + fields.len() as u64 <= u64::from(u32::MAX), + "too many fields in {}: {}, maximum supported count is {}", + cattrs.name().serialize_name(), + fields.len(), + u32::MAX, + ); + + let has_non_skipped_flatten = fields + .iter() + .any(|field| field.attrs.flatten() && !field.attrs.skip_serializing()); + if has_non_skipped_flatten { + serialize_struct_as_map(params, fields, cattrs) + } else { + serialize_struct_as_struct(params, fields, cattrs) + } +} + +fn serialize_struct_tag_field(cattrs: &attr::Container, struct_trait: &StructTrait) -> TokenStream { + match cattrs.tag() { + attr::TagType::Internal { tag } => { + let type_name = cattrs.name().serialize_name(); + let func = struct_trait.serialize_field(Span::call_site()); + quote! { + #func(&mut __serde_state, #tag, #type_name)?; + } + } + _ => quote! {}, + } +} + +fn serialize_struct_as_struct( + params: &Parameters, + fields: &[Field], + cattrs: &attr::Container, +) -> Fragment { + let serialize_fields = + serialize_struct_visitor(fields, params, false, &StructTrait::SerializeStruct); + + let type_name = cattrs.name().serialize_name(); + + let tag_field = serialize_struct_tag_field(cattrs, &StructTrait::SerializeStruct); + let tag_field_exists = !tag_field.is_empty(); + + let mut serialized_fields = fields + .iter() + .filter(|&field| !field.attrs.skip_serializing()) + .peekable(); + + let let_mut = mut_if(serialized_fields.peek().is_some() || tag_field_exists); + + let len = serialized_fields + .map(|field| match field.attrs.skip_serializing_if() { + None => quote!(1), + Some(path) => { + let field_expr = get_member(params, field, &field.member); + quote!(if #path(#field_expr) { 0 } else { 1 }) + } + }) + .fold( + quote!(#tag_field_exists as usize), + |sum, expr| quote!(#sum + #expr), + ); + + quote_block! { + let #let_mut __serde_state = _serde::Serializer::serialize_struct(__serializer, #type_name, #len)?; + #tag_field + #(#serialize_fields)* + _serde::ser::SerializeStruct::end(__serde_state) + } +} + +fn serialize_struct_as_map( + params: &Parameters, + fields: &[Field], + cattrs: &attr::Container, +) -> Fragment { + let serialize_fields = + serialize_struct_visitor(fields, params, false, &StructTrait::SerializeMap); + + let tag_field = serialize_struct_tag_field(cattrs, &StructTrait::SerializeMap); + let tag_field_exists = !tag_field.is_empty(); + + let mut serialized_fields = fields + .iter() + .filter(|&field| !field.attrs.skip_serializing()) + .peekable(); + + let let_mut = mut_if(serialized_fields.peek().is_some() || tag_field_exists); + + quote_block! { + let #let_mut __serde_state = _serde::Serializer::serialize_map(__serializer, _serde::__private::None)?; + #tag_field + #(#serialize_fields)* + _serde::ser::SerializeMap::end(__serde_state) + } +} + +fn serialize_enum(params: &Parameters, variants: &[Variant], cattrs: &attr::Container) -> Fragment { + assert!(variants.len() as u64 <= u64::from(u32::MAX)); + + let self_var = ¶ms.self_var; + + let mut arms: Vec<_> = variants + .iter() + .enumerate() + .map(|(variant_index, variant)| { + serialize_variant(params, variant, variant_index as u32, cattrs) + }) + .collect(); + + if cattrs.remote().is_some() && cattrs.non_exhaustive() { + arms.push(quote! { + ref unrecognized => _serde::__private::Err(_serde::ser::Error::custom(_serde::__private::ser::CannotSerializeVariant(unrecognized))), + }); + } + + quote_expr! { + match *#self_var { + #(#arms)* + } + } +} + +fn serialize_variant( + params: &Parameters, + variant: &Variant, + variant_index: u32, + cattrs: &attr::Container, +) -> TokenStream { + let this_value = ¶ms.this_value; + let variant_ident = &variant.ident; + + if variant.attrs.skip_serializing() { + let skipped_msg = format!( + "the enum variant {}::{} cannot be serialized", + params.type_name(), + variant_ident + ); + let skipped_err = quote! { + _serde::__private::Err(_serde::ser::Error::custom(#skipped_msg)) + }; + let fields_pat = match variant.style { + Style::Unit => quote!(), + Style::Newtype | Style::Tuple => quote!((..)), + Style::Struct => quote!({ .. }), + }; + quote! { + #this_value::#variant_ident #fields_pat => #skipped_err, + } + } else { + // variant wasn't skipped + let case = match variant.style { + Style::Unit => { + quote! { + #this_value::#variant_ident + } + } + Style::Newtype => { + quote! { + #this_value::#variant_ident(ref __field0) + } + } + Style::Tuple => { + let field_names = (0..variant.fields.len()) + .map(|i| Ident::new(&format!("__field{}", i), Span::call_site())); + quote! { + #this_value::#variant_ident(#(ref #field_names),*) + } + } + Style::Struct => { + let members = variant.fields.iter().map(|f| &f.member); + quote! { + #this_value::#variant_ident { #(ref #members),* } + } + } + }; + + let body = Match(match (cattrs.tag(), variant.attrs.untagged()) { + (attr::TagType::External, false) => { + serialize_externally_tagged_variant(params, variant, variant_index, cattrs) + } + (attr::TagType::Internal { tag }, false) => { + serialize_internally_tagged_variant(params, variant, cattrs, tag) + } + (attr::TagType::Adjacent { tag, content }, false) => { + serialize_adjacently_tagged_variant( + params, + variant, + cattrs, + variant_index, + tag, + content, + ) + } + (attr::TagType::None, _) | (_, true) => { + serialize_untagged_variant(params, variant, cattrs) + } + }); + + quote! { + #case => #body + } + } +} + +fn serialize_externally_tagged_variant( + params: &Parameters, + variant: &Variant, + variant_index: u32, + cattrs: &attr::Container, +) -> Fragment { + let type_name = cattrs.name().serialize_name(); + let variant_name = variant.attrs.name().serialize_name(); + + if let Some(path) = variant.attrs.serialize_with() { + let ser = wrap_serialize_variant_with(params, path, variant); + return quote_expr! { + _serde::Serializer::serialize_newtype_variant( + __serializer, + #type_name, + #variant_index, + #variant_name, + #ser, + ) + }; + } + + match effective_style(variant) { + Style::Unit => { + quote_expr! { + _serde::Serializer::serialize_unit_variant( + __serializer, + #type_name, + #variant_index, + #variant_name, + ) + } + } + Style::Newtype => { + let field = &variant.fields[0]; + let mut field_expr = quote!(__field0); + if let Some(path) = field.attrs.serialize_with() { + field_expr = wrap_serialize_field_with(params, field.ty, path, &field_expr); + } + + let span = field.original.span(); + let func = quote_spanned!(span=> _serde::Serializer::serialize_newtype_variant); + quote_expr! { + #func( + __serializer, + #type_name, + #variant_index, + #variant_name, + #field_expr, + ) + } + } + Style::Tuple => serialize_tuple_variant( + TupleVariant::ExternallyTagged { + type_name, + variant_index, + variant_name, + }, + params, + &variant.fields, + ), + Style::Struct => serialize_struct_variant( + StructVariant::ExternallyTagged { + variant_index, + variant_name, + }, + params, + &variant.fields, + type_name, + ), + } +} + +fn serialize_internally_tagged_variant( + params: &Parameters, + variant: &Variant, + cattrs: &attr::Container, + tag: &str, +) -> Fragment { + let type_name = cattrs.name().serialize_name(); + let variant_name = variant.attrs.name().serialize_name(); + + let enum_ident_str = params.type_name(); + let variant_ident_str = variant.ident.to_string(); + + if let Some(path) = variant.attrs.serialize_with() { + let ser = wrap_serialize_variant_with(params, path, variant); + return quote_expr! { + _serde::__private::ser::serialize_tagged_newtype( + __serializer, + #enum_ident_str, + #variant_ident_str, + #tag, + #variant_name, + #ser, + ) + }; + } + + match effective_style(variant) { + Style::Unit => { + quote_block! { + let mut __struct = _serde::Serializer::serialize_struct( + __serializer, #type_name, 1)?; + _serde::ser::SerializeStruct::serialize_field( + &mut __struct, #tag, #variant_name)?; + _serde::ser::SerializeStruct::end(__struct) + } + } + Style::Newtype => { + let field = &variant.fields[0]; + let mut field_expr = quote!(__field0); + if let Some(path) = field.attrs.serialize_with() { + field_expr = wrap_serialize_field_with(params, field.ty, path, &field_expr); + } + + let span = field.original.span(); + let func = quote_spanned!(span=> _serde::__private::ser::serialize_tagged_newtype); + quote_expr! { + #func( + __serializer, + #enum_ident_str, + #variant_ident_str, + #tag, + #variant_name, + #field_expr, + ) + } + } + Style::Struct => serialize_struct_variant( + StructVariant::InternallyTagged { tag, variant_name }, + params, + &variant.fields, + type_name, + ), + Style::Tuple => unreachable!("checked in serde_derive_internals"), + } +} + +fn serialize_adjacently_tagged_variant( + params: &Parameters, + variant: &Variant, + cattrs: &attr::Container, + variant_index: u32, + tag: &str, + content: &str, +) -> Fragment { + let this_type = ¶ms.this_type; + let type_name = cattrs.name().serialize_name(); + let variant_name = variant.attrs.name().serialize_name(); + let serialize_variant = quote! { + &_serde::__private::ser::AdjacentlyTaggedEnumVariant { + enum_name: #type_name, + variant_index: #variant_index, + variant_name: #variant_name, + } + }; + + let inner = Stmts(if let Some(path) = variant.attrs.serialize_with() { + let ser = wrap_serialize_variant_with(params, path, variant); + quote_expr! { + _serde::Serialize::serialize(#ser, __serializer) + } + } else { + match effective_style(variant) { + Style::Unit => { + return quote_block! { + let mut __struct = _serde::Serializer::serialize_struct( + __serializer, #type_name, 1)?; + _serde::ser::SerializeStruct::serialize_field( + &mut __struct, #tag, #serialize_variant)?; + _serde::ser::SerializeStruct::end(__struct) + }; + } + Style::Newtype => { + let field = &variant.fields[0]; + let mut field_expr = quote!(__field0); + if let Some(path) = field.attrs.serialize_with() { + field_expr = wrap_serialize_field_with(params, field.ty, path, &field_expr); + } + + let span = field.original.span(); + let func = quote_spanned!(span=> _serde::ser::SerializeStruct::serialize_field); + return quote_block! { + let mut __struct = _serde::Serializer::serialize_struct( + __serializer, #type_name, 2)?; + _serde::ser::SerializeStruct::serialize_field( + &mut __struct, #tag, #serialize_variant)?; + #func( + &mut __struct, #content, #field_expr)?; + _serde::ser::SerializeStruct::end(__struct) + }; + } + Style::Tuple => { + serialize_tuple_variant(TupleVariant::Untagged, params, &variant.fields) + } + Style::Struct => serialize_struct_variant( + StructVariant::Untagged, + params, + &variant.fields, + variant_name, + ), + } + }); + + let fields_ty = variant.fields.iter().map(|f| &f.ty); + let fields_ident: &[_] = &match variant.style { + Style::Unit => { + if variant.attrs.serialize_with().is_some() { + vec![] + } else { + unreachable!() + } + } + Style::Newtype => vec![Member::Named(Ident::new("__field0", Span::call_site()))], + Style::Tuple => (0..variant.fields.len()) + .map(|i| Member::Named(Ident::new(&format!("__field{}", i), Span::call_site()))) + .collect(), + Style::Struct => variant.fields.iter().map(|f| f.member.clone()).collect(), + }; + + let (_, ty_generics, where_clause) = params.generics.split_for_impl(); + + let wrapper_generics = if fields_ident.is_empty() { + params.generics.clone() + } else { + bound::with_lifetime_bound(¶ms.generics, "'__a") + }; + let (wrapper_impl_generics, wrapper_ty_generics, _) = wrapper_generics.split_for_impl(); + + quote_block! { + #[doc(hidden)] + struct __AdjacentlyTagged #wrapper_generics #where_clause { + data: (#(&'__a #fields_ty,)*), + phantom: _serde::__private::PhantomData<#this_type #ty_generics>, + } + + impl #wrapper_impl_generics _serde::Serialize for __AdjacentlyTagged #wrapper_ty_generics #where_clause { + fn serialize<__S>(&self, __serializer: __S) -> _serde::__private::Result<__S::Ok, __S::Error> + where + __S: _serde::Serializer, + { + // Elements that have skip_serializing will be unused. + #[allow(unused_variables)] + let (#(#fields_ident,)*) = self.data; + #inner + } + } + + let mut __struct = _serde::Serializer::serialize_struct( + __serializer, #type_name, 2)?; + _serde::ser::SerializeStruct::serialize_field( + &mut __struct, #tag, #serialize_variant)?; + _serde::ser::SerializeStruct::serialize_field( + &mut __struct, #content, &__AdjacentlyTagged { + data: (#(#fields_ident,)*), + phantom: _serde::__private::PhantomData::<#this_type #ty_generics>, + })?; + _serde::ser::SerializeStruct::end(__struct) + } +} + +fn serialize_untagged_variant( + params: &Parameters, + variant: &Variant, + cattrs: &attr::Container, +) -> Fragment { + if let Some(path) = variant.attrs.serialize_with() { + let ser = wrap_serialize_variant_with(params, path, variant); + return quote_expr! { + _serde::Serialize::serialize(#ser, __serializer) + }; + } + + match effective_style(variant) { + Style::Unit => { + quote_expr! { + _serde::Serializer::serialize_unit(__serializer) + } + } + Style::Newtype => { + let field = &variant.fields[0]; + let mut field_expr = quote!(__field0); + if let Some(path) = field.attrs.serialize_with() { + field_expr = wrap_serialize_field_with(params, field.ty, path, &field_expr); + } + + let span = field.original.span(); + let func = quote_spanned!(span=> _serde::Serialize::serialize); + quote_expr! { + #func(#field_expr, __serializer) + } + } + Style::Tuple => serialize_tuple_variant(TupleVariant::Untagged, params, &variant.fields), + Style::Struct => { + let type_name = cattrs.name().serialize_name(); + serialize_struct_variant(StructVariant::Untagged, params, &variant.fields, type_name) + } + } +} + +enum TupleVariant<'a> { + ExternallyTagged { + type_name: &'a str, + variant_index: u32, + variant_name: &'a str, + }, + Untagged, +} + +fn serialize_tuple_variant( + context: TupleVariant, + params: &Parameters, + fields: &[Field], +) -> Fragment { + let tuple_trait = match context { + TupleVariant::ExternallyTagged { .. } => TupleTrait::SerializeTupleVariant, + TupleVariant::Untagged => TupleTrait::SerializeTuple, + }; + + let serialize_stmts = serialize_tuple_struct_visitor(fields, params, true, &tuple_trait); + + let mut serialized_fields = fields + .iter() + .enumerate() + .filter(|(_, field)| !field.attrs.skip_serializing()) + .peekable(); + + let let_mut = mut_if(serialized_fields.peek().is_some()); + + let len = serialized_fields + .map(|(i, field)| match field.attrs.skip_serializing_if() { + None => quote!(1), + Some(path) => { + let field_expr = Ident::new(&format!("__field{}", i), Span::call_site()); + quote!(if #path(#field_expr) { 0 } else { 1 }) + } + }) + .fold(quote!(0), |sum, expr| quote!(#sum + #expr)); + + match context { + TupleVariant::ExternallyTagged { + type_name, + variant_index, + variant_name, + } => { + quote_block! { + let #let_mut __serde_state = _serde::Serializer::serialize_tuple_variant( + __serializer, + #type_name, + #variant_index, + #variant_name, + #len)?; + #(#serialize_stmts)* + _serde::ser::SerializeTupleVariant::end(__serde_state) + } + } + TupleVariant::Untagged => { + quote_block! { + let #let_mut __serde_state = _serde::Serializer::serialize_tuple( + __serializer, + #len)?; + #(#serialize_stmts)* + _serde::ser::SerializeTuple::end(__serde_state) + } + } + } +} + +enum StructVariant<'a> { + ExternallyTagged { + variant_index: u32, + variant_name: &'a str, + }, + InternallyTagged { + tag: &'a str, + variant_name: &'a str, + }, + Untagged, +} + +fn serialize_struct_variant( + context: StructVariant, + params: &Parameters, + fields: &[Field], + name: &str, +) -> Fragment { + if fields.iter().any(|field| field.attrs.flatten()) { + return serialize_struct_variant_with_flatten(context, params, fields, name); + } + + let struct_trait = match context { + StructVariant::ExternallyTagged { .. } => StructTrait::SerializeStructVariant, + StructVariant::InternallyTagged { .. } | StructVariant::Untagged => { + StructTrait::SerializeStruct + } + }; + + let serialize_fields = serialize_struct_visitor(fields, params, true, &struct_trait); + + let mut serialized_fields = fields + .iter() + .filter(|&field| !field.attrs.skip_serializing()) + .peekable(); + + let let_mut = mut_if(serialized_fields.peek().is_some()); + + let len = serialized_fields + .map(|field| { + let member = &field.member; + + match field.attrs.skip_serializing_if() { + Some(path) => quote!(if #path(#member) { 0 } else { 1 }), + None => quote!(1), + } + }) + .fold(quote!(0), |sum, expr| quote!(#sum + #expr)); + + match context { + StructVariant::ExternallyTagged { + variant_index, + variant_name, + } => { + quote_block! { + let #let_mut __serde_state = _serde::Serializer::serialize_struct_variant( + __serializer, + #name, + #variant_index, + #variant_name, + #len, + )?; + #(#serialize_fields)* + _serde::ser::SerializeStructVariant::end(__serde_state) + } + } + StructVariant::InternallyTagged { tag, variant_name } => { + quote_block! { + let mut __serde_state = _serde::Serializer::serialize_struct( + __serializer, + #name, + #len + 1, + )?; + _serde::ser::SerializeStruct::serialize_field( + &mut __serde_state, + #tag, + #variant_name, + )?; + #(#serialize_fields)* + _serde::ser::SerializeStruct::end(__serde_state) + } + } + StructVariant::Untagged => { + quote_block! { + let #let_mut __serde_state = _serde::Serializer::serialize_struct( + __serializer, + #name, + #len, + )?; + #(#serialize_fields)* + _serde::ser::SerializeStruct::end(__serde_state) + } + } + } +} + +fn serialize_struct_variant_with_flatten( + context: StructVariant, + params: &Parameters, + fields: &[Field], + name: &str, +) -> Fragment { + let struct_trait = StructTrait::SerializeMap; + let serialize_fields = serialize_struct_visitor(fields, params, true, &struct_trait); + + let mut serialized_fields = fields + .iter() + .filter(|&field| !field.attrs.skip_serializing()) + .peekable(); + + let let_mut = mut_if(serialized_fields.peek().is_some()); + + match context { + StructVariant::ExternallyTagged { + variant_index, + variant_name, + } => { + let this_type = ¶ms.this_type; + let fields_ty = fields.iter().map(|f| &f.ty); + let members = &fields.iter().map(|f| &f.member).collect::>(); + + let (_, ty_generics, where_clause) = params.generics.split_for_impl(); + let wrapper_generics = bound::with_lifetime_bound(¶ms.generics, "'__a"); + let (wrapper_impl_generics, wrapper_ty_generics, _) = wrapper_generics.split_for_impl(); + + quote_block! { + #[doc(hidden)] + struct __EnumFlatten #wrapper_generics #where_clause { + data: (#(&'__a #fields_ty,)*), + phantom: _serde::__private::PhantomData<#this_type #ty_generics>, + } + + impl #wrapper_impl_generics _serde::Serialize for __EnumFlatten #wrapper_ty_generics #where_clause { + fn serialize<__S>(&self, __serializer: __S) -> _serde::__private::Result<__S::Ok, __S::Error> + where + __S: _serde::Serializer, + { + let (#(#members,)*) = self.data; + let #let_mut __serde_state = _serde::Serializer::serialize_map( + __serializer, + _serde::__private::None)?; + #(#serialize_fields)* + _serde::ser::SerializeMap::end(__serde_state) + } + } + + _serde::Serializer::serialize_newtype_variant( + __serializer, + #name, + #variant_index, + #variant_name, + &__EnumFlatten { + data: (#(#members,)*), + phantom: _serde::__private::PhantomData::<#this_type #ty_generics>, + }) + } + } + StructVariant::InternallyTagged { tag, variant_name } => { + quote_block! { + let #let_mut __serde_state = _serde::Serializer::serialize_map( + __serializer, + _serde::__private::None)?; + _serde::ser::SerializeMap::serialize_entry( + &mut __serde_state, + #tag, + #variant_name, + )?; + #(#serialize_fields)* + _serde::ser::SerializeMap::end(__serde_state) + } + } + StructVariant::Untagged => { + quote_block! { + let #let_mut __serde_state = _serde::Serializer::serialize_map( + __serializer, + _serde::__private::None)?; + #(#serialize_fields)* + _serde::ser::SerializeMap::end(__serde_state) + } + } + } +} + +fn serialize_tuple_struct_visitor( + fields: &[Field], + params: &Parameters, + is_enum: bool, + tuple_trait: &TupleTrait, +) -> Vec { + fields + .iter() + .enumerate() + .filter(|(_, field)| !field.attrs.skip_serializing()) + .map(|(i, field)| { + let mut field_expr = if is_enum { + let id = Ident::new(&format!("__field{}", i), Span::call_site()); + quote!(#id) + } else { + get_member( + params, + field, + &Member::Unnamed(Index { + index: i as u32, + span: Span::call_site(), + }), + ) + }; + + let skip = field + .attrs + .skip_serializing_if() + .map(|path| quote!(#path(#field_expr))); + + if let Some(path) = field.attrs.serialize_with() { + field_expr = wrap_serialize_field_with(params, field.ty, path, &field_expr); + } + + let span = field.original.span(); + let func = tuple_trait.serialize_element(span); + let ser = quote! { + #func(&mut __serde_state, #field_expr)?; + }; + + match skip { + None => ser, + Some(skip) => quote!(if !#skip { #ser }), + } + }) + .collect() +} + +fn serialize_struct_visitor( + fields: &[Field], + params: &Parameters, + is_enum: bool, + struct_trait: &StructTrait, +) -> Vec { + fields + .iter() + .filter(|&field| !field.attrs.skip_serializing()) + .map(|field| { + let member = &field.member; + + let mut field_expr = if is_enum { + quote!(#member) + } else { + get_member(params, field, member) + }; + + let key_expr = field.attrs.name().serialize_name(); + + let skip = field + .attrs + .skip_serializing_if() + .map(|path| quote!(#path(#field_expr))); + + if let Some(path) = field.attrs.serialize_with() { + field_expr = wrap_serialize_field_with(params, field.ty, path, &field_expr); + } + + let span = field.original.span(); + let ser = if field.attrs.flatten() { + let func = quote_spanned!(span=> _serde::Serialize::serialize); + quote! { + #func(&#field_expr, _serde::__private::ser::FlatMapSerializer(&mut __serde_state))?; + } + } else { + let func = struct_trait.serialize_field(span); + quote! { + #func(&mut __serde_state, #key_expr, #field_expr)?; + } + }; + + match skip { + None => ser, + Some(skip) => { + if let Some(skip_func) = struct_trait.skip_field(span) { + quote! { + if !#skip { + #ser + } else { + #skip_func(&mut __serde_state, #key_expr)?; + } + } + } else { + quote! { + if !#skip { + #ser + } + } + } + } + } + }) + .collect() +} + +fn wrap_serialize_field_with( + params: &Parameters, + field_ty: &syn::Type, + serialize_with: &syn::ExprPath, + field_expr: &TokenStream, +) -> TokenStream { + wrap_serialize_with(params, serialize_with, &[field_ty], &[quote!(#field_expr)]) +} + +fn wrap_serialize_variant_with( + params: &Parameters, + serialize_with: &syn::ExprPath, + variant: &Variant, +) -> TokenStream { + let field_tys: Vec<_> = variant.fields.iter().map(|field| field.ty).collect(); + let field_exprs: Vec<_> = variant + .fields + .iter() + .map(|field| { + let id = match &field.member { + Member::Named(ident) => ident.clone(), + Member::Unnamed(member) => { + Ident::new(&format!("__field{}", member.index), Span::call_site()) + } + }; + quote!(#id) + }) + .collect(); + wrap_serialize_with( + params, + serialize_with, + field_tys.as_slice(), + field_exprs.as_slice(), + ) +} + +fn wrap_serialize_with( + params: &Parameters, + serialize_with: &syn::ExprPath, + field_tys: &[&syn::Type], + field_exprs: &[TokenStream], +) -> TokenStream { + let this_type = ¶ms.this_type; + let (_, ty_generics, where_clause) = params.generics.split_for_impl(); + + let wrapper_generics = if field_exprs.is_empty() { + params.generics.clone() + } else { + bound::with_lifetime_bound(¶ms.generics, "'__a") + }; + let (wrapper_impl_generics, wrapper_ty_generics, _) = wrapper_generics.split_for_impl(); + + let field_access = (0..field_exprs.len()).map(|n| { + Member::Unnamed(Index { + index: n as u32, + span: Span::call_site(), + }) + }); + + quote!({ + #[doc(hidden)] + struct __SerializeWith #wrapper_impl_generics #where_clause { + values: (#(&'__a #field_tys, )*), + phantom: _serde::__private::PhantomData<#this_type #ty_generics>, + } + + impl #wrapper_impl_generics _serde::Serialize for __SerializeWith #wrapper_ty_generics #where_clause { + fn serialize<__S>(&self, __s: __S) -> _serde::__private::Result<__S::Ok, __S::Error> + where + __S: _serde::Serializer, + { + #serialize_with(#(self.values.#field_access, )* __s) + } + } + + &__SerializeWith { + values: (#(#field_exprs, )*), + phantom: _serde::__private::PhantomData::<#this_type #ty_generics>, + } + }) +} + +// Serialization of an empty struct results in code like: +// +// let mut __serde_state = serializer.serialize_struct("S", 0)?; +// _serde::ser::SerializeStruct::end(__serde_state) +// +// where we want to omit the `mut` to avoid a warning. +fn mut_if(is_mut: bool) -> Option { + if is_mut { + Some(quote!(mut)) + } else { + None + } +} + +fn get_member(params: &Parameters, field: &Field, member: &Member) -> TokenStream { + let self_var = ¶ms.self_var; + match (params.is_remote, field.attrs.getter()) { + (false, None) => { + if params.is_packed { + quote!(&{#self_var.#member}) + } else { + quote!(&#self_var.#member) + } + } + (true, None) => { + let inner = if params.is_packed { + quote!(&{#self_var.#member}) + } else { + quote!(&#self_var.#member) + }; + let ty = field.ty; + quote!(_serde::__private::ser::constrain::<#ty>(#inner)) + } + (true, Some(getter)) => { + let ty = field.ty; + quote!(_serde::__private::ser::constrain::<#ty>(&#getter(#self_var))) + } + (false, Some(_)) => { + unreachable!("getter is only allowed for remote impls"); + } + } +} + +fn effective_style(variant: &Variant) -> Style { + match variant.style { + Style::Newtype if variant.fields[0].attrs.skip_serializing() => Style::Unit, + other => other, + } +} + +enum StructTrait { + SerializeMap, + SerializeStruct, + SerializeStructVariant, +} + +impl StructTrait { + fn serialize_field(&self, span: Span) -> TokenStream { + match *self { + StructTrait::SerializeMap => { + quote_spanned!(span=> _serde::ser::SerializeMap::serialize_entry) + } + StructTrait::SerializeStruct => { + quote_spanned!(span=> _serde::ser::SerializeStruct::serialize_field) + } + StructTrait::SerializeStructVariant => { + quote_spanned!(span=> _serde::ser::SerializeStructVariant::serialize_field) + } + } + } + + fn skip_field(&self, span: Span) -> Option { + match *self { + StructTrait::SerializeMap => None, + StructTrait::SerializeStruct => { + Some(quote_spanned!(span=> _serde::ser::SerializeStruct::skip_field)) + } + StructTrait::SerializeStructVariant => { + Some(quote_spanned!(span=> _serde::ser::SerializeStructVariant::skip_field)) + } + } + } +} + +enum TupleTrait { + SerializeTuple, + SerializeTupleStruct, + SerializeTupleVariant, +} + +impl TupleTrait { + fn serialize_element(&self, span: Span) -> TokenStream { + match *self { + TupleTrait::SerializeTuple => { + quote_spanned!(span=> _serde::ser::SerializeTuple::serialize_element) + } + TupleTrait::SerializeTupleStruct => { + quote_spanned!(span=> _serde::ser::SerializeTupleStruct::serialize_field) + } + TupleTrait::SerializeTupleVariant => { + quote_spanned!(span=> _serde::ser::SerializeTupleVariant::serialize_field) + } + } + } +} diff --git a/vendor/serde_derive/src/this.rs b/vendor/serde_derive/src/this.rs new file mode 100644 index 0000000..941cea4 --- /dev/null +++ b/vendor/serde_derive/src/this.rs @@ -0,0 +1,32 @@ +use crate::internals::ast::Container; +use syn::{Path, PathArguments, Token}; + +pub fn this_type(cont: &Container) -> Path { + if let Some(remote) = cont.attrs.remote() { + let mut this = remote.clone(); + for segment in &mut this.segments { + if let PathArguments::AngleBracketed(arguments) = &mut segment.arguments { + arguments.colon2_token = None; + } + } + this + } else { + Path::from(cont.ident.clone()) + } +} + +pub fn this_value(cont: &Container) -> Path { + if let Some(remote) = cont.attrs.remote() { + let mut this = remote.clone(); + for segment in &mut this.segments { + if let PathArguments::AngleBracketed(arguments) = &mut segment.arguments { + if arguments.colon2_token.is_none() { + arguments.colon2_token = Some(Token![::](arguments.lt_token.span)); + } + } + } + this + } else { + Path::from(cont.ident.clone()) + } +} diff --git a/vendor/serde_json/.cargo-checksum.json b/vendor/serde_json/.cargo-checksum.json new file mode 100644 index 0000000..cff1066 --- /dev/null +++ b/vendor/serde_json/.cargo-checksum.json @@ -0,0 +1 @@ +{"files":{"CONTRIBUTING.md":"f5270cafba66223a7b51ffc0d286075a17bb7cd88762fc80d333d3102629f4d8","Cargo.toml":"2e03342769ddead827c9391f2e7b0138d9c41c12c177f65ff0989b0c4ed87e6c","LICENSE-APACHE":"62c7a1e35f56406896d7aa7ca52d0cc0d272ac022b5d2796e7d6905db8a3636a","LICENSE-MIT":"23f18e03dc49df91622fe2a76176497404e46ced8a715d9d2b67a7446571cca3","README.md":"f223b99630bae262eb2b88bb95d0f496db8f1ff4e94e43dbfc8d95d3a6c98d8f","build.rs":"1630d0bbfc936b0975d840cec5cfb5910d861b6afeeeeabe11000a2c202d571d","src/de.rs":"07438495907da5fea2aee3dd735f83892482af3e5a0405fc7fe7801271ad4d85","src/error.rs":"a9b5de0a82f95608b51b8e8875c7c49f94fb60b9f976fc6277aec0213926dec9","src/io/core.rs":"60ba28f67a9acaecf8964b611efba416b13f9f2bae4befc329fdf0e037293802","src/io/mod.rs":"fd1ed5080495cab21117f6f7d3c2c9e3687cad0c69a0cd087b08a145a9e672da","src/iter.rs":"f832c469cd7999d26ba9b76baa69b257a212a7edb3dfdf9b1d1bb35e8da85fa9","src/lexical/algorithm.rs":"bd6106e5d8875c9ff1c1d57256b459a4f0992d14a0df1a5fffcd3d3cbdccee8c","src/lexical/bhcomp.rs":"26f39d52008225a6b377d7246d326940d44200e160a7b4652733e712e1a45a04","src/lexical/bignum.rs":"db688e8112389998d0f91906f6857e28f9b510a8b4065ad476c8e8be2f77becf","src/lexical/cached.rs":"0e127398691f8042c19cde209e7f4b0161f0f3150342430145929f711e6fdac8","src/lexical/cached_float80.rs":"0f8f74a22cb7d871322a9893bffd0255ca10bf9dffd13afb2462dd3d7f51805f","src/lexical/digit.rs":"9502805adbc3da059131d1fac0a802e17065b36cd7472606b3af24e3241d5cb8","src/lexical/errors.rs":"3d9f6de6245533bcb101dfd718cfed61d59dc293f6768cedae28aa13ace164f5","src/lexical/exponent.rs":"51f19443008e8884b15c7d5d4b1f1cfbd5673a9d1da02f1af39fcf20e315f01f","src/lexical/float.rs":"fe356213c92a049f4bef2f58bc0e3a26866ca06b8c1d74d0f961c5b883852cad","src/lexical/large_powers.rs":"18d697b846b44ecb61bfaaa3b881e0696f9b7bb6be582623e9d3a8a176a48d2f","src/lexical/large_powers32.rs":"c70b57a727960beec258758a4d4a1050f8eaf3b4e60027c663a2bfb0246e0153","src/lexical/large_powers64.rs":"e7af83ce3159b5fc4669fc5a231e767d8af21bacaece52a0a48951198965b197","src/lexical/math.rs":"00519897ba54fb282102549a8c2a973af1f6534fcba1e283436b00141baccc13","src/lexical/mod.rs":"ace2ccea2cd541f019a84b9eeb3b9ecd88daf6bccbe9edf0eac00b62704f47c4","src/lexical/num.rs":"2d06111d28616221995f7b4d4f13625b8d902884921268b0e02e544f871a5339","src/lexical/parse.rs":"c2bfac4c70a19938ced61e991f4ec606764887cf12bac1a0978b5b5318a56aac","src/lexical/rounding.rs":"4762af3612880b17468ff2a1bb800c8e99f08330ae439699dd53d8dc5463ad13","src/lexical/shift.rs":"bc1ed053dd63d45ac9c35302f18de9f00d94027f28af4ab749c9248439de832a","src/lexical/small_powers.rs":"73c56b7b83310c6fefa898fb94771c65bdc251c1579ab105151da43935ea02be","src/lib.rs":"09de789368d6619d7d3c4f2415f4551f21c44beb00e29d9877a8890f8721d6f0","src/macros.rs":"f917820b8e568b46b3fb4568bb131860d41d272446418d5708659b4bab246266","src/map.rs":"2d80b15ddf300d8c09941c5399ee3dab35c3c398029be9275274fc5306bbbe80","src/number.rs":"97c13c61a575156f1963b10f572b32c3e79b3ba250f0610e886675b153d36fc1","src/raw.rs":"74f5937706324c9325acc42597ff0a226faeaae38d270ab61ba6283e37616c86","src/read.rs":"6873d67c56234479bc50b665a844530d55a0f2d4adc7efdf123e4b81e52af100","src/ser.rs":"8e8981887d7b0949dc33caba04ca3ea20e1deafa5a947acd9cfc7bc8b9b9923f","src/value/de.rs":"890d88303ce0036a5efd1c57378dab7f8c45dabd798cece2248c2d9db52fa011","src/value/from.rs":"f355d23945edf8e64ff8e55ae124a09bbb58fb03cf9795331b767de6b45372e4","src/value/index.rs":"8afacb0fef798745c3be102fcb7a8cc407536c918a73a90dfc613ae4fc49a5e6","src/value/mod.rs":"063b36e08e830718141cf1e06fb499edf40522303785f6e7971f4ee538742597","src/value/partial_eq.rs":"655fd0bf3ab1d6669444a55ab849f43bb333032de8ca8f1ee95e1068da43ee22","src/value/ser.rs":"5c22325737d29aa3b3c7906c73f38edb432321f695a68ee580747c4cb03b7db3","tests/compiletest.rs":"4e381aa8ca3eabb7ac14d1e0c3700b3223e47640547a6988cfa13ad68255f60f","tests/debug.rs":"a8451217c1e127ad6e653ef11e0513525ee350e1e37dd575758a8ee9301b28fb","tests/lexical.rs":"8ee6e617ef62a090de49ac2a930130a6913ab5316100781543c7788f89ef99c2","tests/lexical/algorithm.rs":"da378df9ee24bfa033968d5c94e91b58e52c39bf6c825dec51c3eb7250cc5874","tests/lexical/exponent.rs":"dc8fa8d05e561ff256f8b09385291768c7f45e5ad6cb878ef9194757aa014386","tests/lexical/float.rs":"0440f2d85c993bcccd925096d7f4136bf624ffd66b3c7ee565d158390685eb11","tests/lexical/math.rs":"4142ef090f563df1f6b14c9a4e6d4723535fa816dca3febc94b3423240e9db20","tests/lexical/num.rs":"e0bdc3b4facd579e9cfdf87c8bae107ed227c63cf9ef920fd85e9febb985c693","tests/lexical/parse.rs":"a11f09bb003a3a024548008cf78bf76526ed71b00077d1989f45eb8cebc93b9c","tests/lexical/rounding.rs":"6c56e39ba534616c1b2146e8efa6eb57aed322e683bf23183cd32a61fae6447e","tests/macros/mod.rs":"93aa1d54af20bc2c55b6ae8db73c1414cda2626eb9fa7bd57b9d613a3c6e6a19","tests/map.rs":"232a980d98b0ceac022ad34d25b0a0fc613389784222a45da4f5650a9414a847","tests/regression.rs":"4551a0770c53631d66da2399e3d213b5fe023b3fb9cc02438842eeb688dbe400","tests/regression/issue1004.rs":"38d7e3b6c515b881078ebd21ca8063d2ca105cd319695d29538f879e37f091b5","tests/regression/issue520.rs":"f95b362e45c57b431720c48eb47f7ddddf4078195d6859df523dc32950ce980a","tests/regression/issue795.rs":"37ff26744b1f950dd212565c6e3f276268882f7724cc589ac8b21ca8bd608413","tests/regression/issue845.rs":"10d2895cd1412cb6630f0a59db367f79ee672edb501151c7581e9921b5a84b92","tests/regression/issue953.rs":"b2cddc761f5ca6639900c173765a8a5868528a896924e5e925db2696469208f7","tests/stream.rs":"794b672b52eb8f1696b32b8dd125a660fc19b83fcfef5390896b02149b5f0a9b","tests/test.rs":"a3953e6010e31a9f30b6a8dbabec37daf14f18244ae547bb5c1058c54ebf3283","tests/ui/missing_colon.rs":"d07e0c34d98eb43465f0a0310f2c0b5d5b0d26d243b352a1c6bbe6ad3b27eda9","tests/ui/missing_colon.stderr":"a543cf9931a6224ba74f4592ea551f19438752c09427c649cd0211d363e88e75","tests/ui/missing_comma.rs":"b8a9662f99c3e6dd2b6417892c37640578ce91d3a8365bf10c1f686a3227aa87","tests/ui/missing_comma.stderr":"eae626cf93c97abd105066e624ca4e8cb096784413b9d2564cf9414a8492bc4d","tests/ui/missing_value.rs":"bca25d67127fb88e7c191c7b03af5a4ce8a9abb630f3d2e6a6c1e77e213dc9a4","tests/ui/missing_value.stderr":"a03be58cfa3d80cf1bd967bc8473933e87226db69c7967710084b13ca43bccdc","tests/ui/not_found.rs":"d0a7adb309879ff65aee115b52cc33d36f4bad353cf97c4effc34a6128c2bee3","tests/ui/not_found.stderr":"359b751c0c21fab6d460daef4d5f73a265f7769c9b578f98ea3cb6cbf2387643","tests/ui/parse_expr.rs":"32e6d51f528db3d1ab0ed1e24765b865be393565c26f77413c5aa39d601ac563","tests/ui/parse_expr.stderr":"4fcd0a014fbce31c9266bab8527d6e6b6806a0e21d9e0275ce713137856073ce","tests/ui/parse_key.rs":"18829b2af320d5cf8a0a5cd3aaf84c7e92cc874651c30e45a3acafb76c2d8b93","tests/ui/parse_key.stderr":"20cf0d2898749f3c36780fc065f5049ee809e74cb6f0ef776f43f45e01596ee3","tests/ui/unexpected_after_array_element.rs":"a343fc3104431720bdfcf330bcc3cfcd98c8dec3e951133b495242478b0b7eb3","tests/ui/unexpected_after_array_element.stderr":"8df615998fa3057bb9ed865981a35cdbb771625337048f0ad3fba7734e607adf","tests/ui/unexpected_after_map_entry.rs":"6e3bd2def435ca610e346bbc75cdbaf61963eb2ef1885bb5f76781ba1fac37ef","tests/ui/unexpected_after_map_entry.stderr":"b1985c89075ab48b2158bd1705ed766d37854b3d4620ab257cc8bc319d224f17","tests/ui/unexpected_colon.rs":"a313cff3fed4be4c33f1eda5d0c5c98147fb835a56d36470d9f367352c1d61ef","tests/ui/unexpected_colon.stderr":"b2288742fa6a4a7eb65d2ae899bcfed8795b57bd04958da227d60928a8df26c5","tests/ui/unexpected_comma.rs":"55a8b684bde1ce905837cce719fd457d8898b61cebc27e5b420d05cb6be97256","tests/ui/unexpected_comma.stderr":"4c103ca63ff15e2ca659242cc0eae0612bf050e7580da62f1cf50de8082aa7dc"},"package":"6dbcf9b78a125ee667ae19388837dd12294b858d101fdd393cb9d5501ef09eb2"} \ No newline at end of file diff --git a/vendor/serde_json/CONTRIBUTING.md b/vendor/serde_json/CONTRIBUTING.md new file mode 100644 index 0000000..26e1578 --- /dev/null +++ b/vendor/serde_json/CONTRIBUTING.md @@ -0,0 +1,46 @@ +# Contributing to Serde + +Serde welcomes contribution from everyone in the form of suggestions, bug +reports, pull requests, and feedback. This document gives some guidance if you +are thinking of helping us. + +## Submitting bug reports and feature requests + +Serde development is spread across lots of repositories. In general, prefer to +open issues against the main [serde-rs/serde] repository unless the topic is +clearly specific to JSON. + +[serde-rs/serde]: https://github.com/serde-rs/serde + +When reporting a bug or asking for help, please include enough details so that +the people helping you can reproduce the behavior you are seeing. For some tips +on how to approach this, read about how to produce a [Minimal, Complete, and +Verifiable example]. + +[Minimal, Complete, and Verifiable example]: https://stackoverflow.com/help/mcve + +When making a feature request, please make it clear what problem you intend to +solve with the feature, any ideas for how Serde could support solving that +problem, any possible alternatives, and any disadvantages. + +## Running the test suite + +We encourage you to check that the test suite passes locally before submitting a +pull request with your changes. If anything does not pass, typically it will be +easier to iterate and fix it locally than waiting for the CI servers to run +tests for you. + +The test suite requires a nightly compiler. + +```sh +# Run the full test suite, including doc test and compile-tests +cargo test +``` + +## Conduct + +In all Serde-related forums, we follow the [Rust Code of Conduct]. For +escalation or moderation issues please contact Erick (erick.tryzelaar@gmail.com) +instead of the Rust moderation team. + +[Rust Code of Conduct]: https://www.rust-lang.org/policies/code-of-conduct diff --git a/vendor/serde_json/Cargo.toml b/vendor/serde_json/Cargo.toml new file mode 100644 index 0000000..94bd2b3 --- /dev/null +++ b/vendor/serde_json/Cargo.toml @@ -0,0 +1,149 @@ +# 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] +edition = "2021" +rust-version = "1.56" +name = "serde_json" +version = "1.0.129" +authors = [ + "Erick Tryzelaar ", + "David Tolnay ", +] +build = "build.rs" +autolib = false +autobins = false +autoexamples = false +autotests = false +autobenches = false +description = "A JSON serialization file format" +documentation = "https://docs.rs/serde_json" +readme = "README.md" +keywords = [ + "json", + "serde", + "serialization", +] +categories = [ + "encoding", + "parser-implementations", + "no-std", +] +license = "MIT OR Apache-2.0" +repository = "https://github.com/serde-rs/json" + +[package.metadata.docs.rs] +features = [ + "preserve_order", + "raw_value", + "unbounded_depth", +] +rustdoc-args = ["--generate-link-to-definition"] +targets = ["x86_64-unknown-linux-gnu"] + +[package.metadata.playground] +features = ["raw_value"] + +[lib] +name = "serde_json" +path = "src/lib.rs" +doc-scrape-examples = false + +[[test]] +name = "compiletest" +path = "tests/compiletest.rs" + +[[test]] +name = "debug" +path = "tests/debug.rs" + +[[test]] +name = "lexical" +path = "tests/lexical.rs" + +[[test]] +name = "map" +path = "tests/map.rs" + +[[test]] +name = "regression" +path = "tests/regression.rs" + +[[test]] +name = "stream" +path = "tests/stream.rs" + +[[test]] +name = "test" +path = "tests/test.rs" + +[dependencies.indexmap] +version = "2.2.3" +optional = true + +[dependencies.itoa] +version = "1.0" + +[dependencies.memchr] +version = "2" +default-features = false + +[dependencies.ryu] +version = "1.0" + +[dependencies.serde] +version = "1.0.194" +default-features = false + +[dev-dependencies.automod] +version = "1.0.11" + +[dev-dependencies.indoc] +version = "2.0.2" + +[dev-dependencies.ref-cast] +version = "1.0.18" + +[dev-dependencies.rustversion] +version = "1.0.13" + +[dev-dependencies.serde] +version = "1.0.194" +features = ["derive"] + +[dev-dependencies.serde_bytes] +version = "0.11.10" + +[dev-dependencies.serde_derive] +version = "1.0.166" + +[dev-dependencies.serde_stacker] +version = "0.1.8" + +[dev-dependencies.trybuild] +version = "1.0.81" +features = ["diff"] + +[features] +alloc = ["serde/alloc"] +arbitrary_precision = [] +default = ["std"] +float_roundtrip = [] +preserve_order = [ + "indexmap", + "std", +] +raw_value = [] +std = [ + "memchr/std", + "serde/std", +] +unbounded_depth = [] diff --git a/vendor/serde_json/LICENSE-APACHE b/vendor/serde_json/LICENSE-APACHE new file mode 100644 index 0000000..1b5ec8b --- /dev/null +++ b/vendor/serde_json/LICENSE-APACHE @@ -0,0 +1,176 @@ + 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 diff --git a/vendor/serde_json/LICENSE-MIT b/vendor/serde_json/LICENSE-MIT new file mode 100644 index 0000000..31aa793 --- /dev/null +++ b/vendor/serde_json/LICENSE-MIT @@ -0,0 +1,23 @@ +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/serde_json/README.md b/vendor/serde_json/README.md new file mode 100644 index 0000000..be70b7b --- /dev/null +++ b/vendor/serde_json/README.md @@ -0,0 +1,390 @@ +# Serde JSON   [![Build Status]][actions] [![Latest Version]][crates.io] [![Rustc Version 1.36+]][rustc] + +[Build Status]: https://img.shields.io/github/actions/workflow/status/serde-rs/json/ci.yml?branch=master +[actions]: https://github.com/serde-rs/json/actions?query=branch%3Amaster +[Latest Version]: https://img.shields.io/crates/v/serde_json.svg +[crates.io]: https://crates.io/crates/serde\_json +[Rustc Version 1.36+]: https://img.shields.io/badge/rustc-1.36+-lightgray.svg +[rustc]: https://blog.rust-lang.org/2019/07/04/Rust-1.36.0.html + +**Serde is a framework for *ser*ializing and *de*serializing Rust data structures efficiently and generically.** + +--- + +```toml +[dependencies] +serde_json = "1.0" +``` + +You may be looking for: + +- [JSON API documentation](https://docs.rs/serde_json) +- [Serde API documentation](https://docs.rs/serde) +- [Detailed documentation about Serde](https://serde.rs/) +- [Setting up `#[derive(Serialize, Deserialize)]`](https://serde.rs/derive.html) +- [Release notes](https://github.com/serde-rs/json/releases) + +JSON is a ubiquitous open-standard format that uses human-readable text to +transmit data objects consisting of key-value pairs. + +```json +{ + "name": "John Doe", + "age": 43, + "address": { + "street": "10 Downing Street", + "city": "London" + }, + "phones": [ + "+44 1234567", + "+44 2345678" + ] +} +``` + +There are three common ways that you might find yourself needing to work with +JSON data in Rust. + + - **As text data.** An unprocessed string of JSON data that you receive on an + HTTP endpoint, read from a file, or prepare to send to a remote server. + - **As an untyped or loosely typed representation.** Maybe you want to check + that some JSON data is valid before passing it on, but without knowing the + structure of what it contains. Or you want to do very basic manipulations + like insert a key in a particular spot. + - **As a strongly typed Rust data structure.** When you expect all or most of + your data to conform to a particular structure and want to get real work done + without JSON's loosey-goosey nature tripping you up. + +Serde JSON provides efficient, flexible, safe ways of converting data between +each of these representations. + +## Operating on untyped JSON values + +Any valid JSON data can be manipulated in the following recursive enum +representation. This data structure is [`serde_json::Value`][value]. + +```rust +enum Value { + Null, + Bool(bool), + Number(Number), + String(String), + Array(Vec), + Object(Map), +} +``` + +A string of JSON data can be parsed into a `serde_json::Value` by the +[`serde_json::from_str`][from_str] function. There is also +[`from_slice`][from_slice] for parsing from a byte slice `&[u8]` and +[`from_reader`][from_reader] for parsing from any `io::Read` like a File or a +TCP stream. + +
+ + + +
+ +```rust +use serde_json::{Result, Value}; + +fn untyped_example() -> Result<()> { + // Some JSON input data as a &str. Maybe this comes from the user. + let data = r#" + { + "name": "John Doe", + "age": 43, + "phones": [ + "+44 1234567", + "+44 2345678" + ] + }"#; + + // Parse the string of data into serde_json::Value. + let v: Value = serde_json::from_str(data)?; + + // Access parts of the data by indexing with square brackets. + println!("Please call {} at the number {}", v["name"], v["phones"][0]); + + Ok(()) +} +``` + +The result of square bracket indexing like `v["name"]` is a borrow of the data +at that index, so the type is `&Value`. A JSON map can be indexed with string +keys, while a JSON array can be indexed with integer keys. If the type of the +data is not right for the type with which it is being indexed, or if a map does +not contain the key being indexed, or if the index into a vector is out of +bounds, the returned element is `Value::Null`. + +When a `Value` is printed, it is printed as a JSON string. So in the code above, +the output looks like `Please call "John Doe" at the number "+44 1234567"`. The +quotation marks appear because `v["name"]` is a `&Value` containing a JSON +string and its JSON representation is `"John Doe"`. Printing as a plain string +without quotation marks involves converting from a JSON string to a Rust string +with [`as_str()`] or avoiding the use of `Value` as described in the following +section. + +[`as_str()`]: https://docs.rs/serde_json/1/serde_json/enum.Value.html#method.as_str + +The `Value` representation is sufficient for very basic tasks but can be tedious +to work with for anything more significant. Error handling is verbose to +implement correctly, for example imagine trying to detect the presence of +unrecognized fields in the input data. The compiler is powerless to help you +when you make a mistake, for example imagine typoing `v["name"]` as `v["nmae"]` +in one of the dozens of places it is used in your code. + +## Parsing JSON as strongly typed data structures + +Serde provides a powerful way of mapping JSON data into Rust data structures +largely automatically. + +
+ + + +
+ +```rust +use serde::{Deserialize, Serialize}; +use serde_json::Result; + +#[derive(Serialize, Deserialize)] +struct Person { + name: String, + age: u8, + phones: Vec, +} + +fn typed_example() -> Result<()> { + // Some JSON input data as a &str. Maybe this comes from the user. + let data = r#" + { + "name": "John Doe", + "age": 43, + "phones": [ + "+44 1234567", + "+44 2345678" + ] + }"#; + + // Parse the string of data into a Person object. This is exactly the + // same function as the one that produced serde_json::Value above, but + // now we are asking it for a Person as output. + let p: Person = serde_json::from_str(data)?; + + // Do things just like with any other Rust data structure. + println!("Please call {} at the number {}", p.name, p.phones[0]); + + Ok(()) +} +``` + +This is the same `serde_json::from_str` function as before, but this time we +assign the return value to a variable of type `Person` so Serde will +automatically interpret the input data as a `Person` and produce informative +error messages if the layout does not conform to what a `Person` is expected to +look like. + +Any type that implements Serde's `Deserialize` trait can be deserialized this +way. This includes built-in Rust standard library types like `Vec` and +`HashMap`, as well as any structs or enums annotated with +`#[derive(Deserialize)]`. + +Once we have `p` of type `Person`, our IDE and the Rust compiler can help us use +it correctly like they do for any other Rust code. The IDE can autocomplete +field names to prevent typos, which was impossible in the `serde_json::Value` +representation. And the Rust compiler can check that when we write +`p.phones[0]`, then `p.phones` is guaranteed to be a `Vec` so indexing +into it makes sense and produces a `String`. + +The necessary setup for using Serde's derive macros is explained on the *[Using +derive]* page of the Serde site. + +[Using derive]: https://serde.rs/derive.html + +## Constructing JSON values + +Serde JSON provides a [`json!` macro][macro] to build `serde_json::Value` +objects with very natural JSON syntax. + +
+ + + +
+ +```rust +use serde_json::json; + +fn main() { + // The type of `john` is `serde_json::Value` + let john = json!({ + "name": "John Doe", + "age": 43, + "phones": [ + "+44 1234567", + "+44 2345678" + ] + }); + + println!("first phone number: {}", john["phones"][0]); + + // Convert to a string of JSON and print it out + println!("{}", john.to_string()); +} +``` + +The `Value::to_string()` function converts a `serde_json::Value` into a `String` +of JSON text. + +One neat thing about the `json!` macro is that variables and expressions can be +interpolated directly into the JSON value as you are building it. Serde will +check at compile time that the value you are interpolating is able to be +represented as JSON. + +
+ + + +
+ +```rust +let full_name = "John Doe"; +let age_last_year = 42; + +// The type of `john` is `serde_json::Value` +let john = json!({ + "name": full_name, + "age": age_last_year + 1, + "phones": [ + format!("+44 {}", random_phone()) + ] +}); +``` + +This is amazingly convenient, but we have the problem we had before with +`Value`: the IDE and Rust compiler cannot help us if we get it wrong. Serde JSON +provides a better way of serializing strongly-typed data structures into JSON +text. + +## Creating JSON by serializing data structures + +A data structure can be converted to a JSON string by +[`serde_json::to_string`][to_string]. There is also +[`serde_json::to_vec`][to_vec] which serializes to a `Vec` and +[`serde_json::to_writer`][to_writer] which serializes to any `io::Write` +such as a File or a TCP stream. + +
+ + + +
+ +```rust +use serde::{Deserialize, Serialize}; +use serde_json::Result; + +#[derive(Serialize, Deserialize)] +struct Address { + street: String, + city: String, +} + +fn print_an_address() -> Result<()> { + // Some data structure. + let address = Address { + street: "10 Downing Street".to_owned(), + city: "London".to_owned(), + }; + + // Serialize it to a JSON string. + let j = serde_json::to_string(&address)?; + + // Print, write to a file, or send to an HTTP server. + println!("{}", j); + + Ok(()) +} +``` + +Any type that implements Serde's `Serialize` trait can be serialized this way. +This includes built-in Rust standard library types like `Vec` and `HashMap`, as well as any structs or enums annotated with `#[derive(Serialize)]`. + +## Performance + +It is fast. You should expect in the ballpark of 500 to 1000 megabytes per +second deserialization and 600 to 900 megabytes per second serialization, +depending on the characteristics of your data. This is competitive with the +fastest C and C++ JSON libraries or even 30% faster for many use cases. +Benchmarks live in the [serde-rs/json-benchmark] repo. + +[serde-rs/json-benchmark]: https://github.com/serde-rs/json-benchmark + +## Getting help + +Serde is one of the most widely used Rust libraries, so any place that +Rustaceans congregate will be able to help you out. For chat, consider trying +the [#rust-questions] or [#rust-beginners] channels of the unofficial community +Discord (invite: ), the [#rust-usage] or +[#beginners] channels of the official Rust Project Discord (invite: +), or the [#general][zulip] stream in Zulip. For +asynchronous, consider the [\[rust\] tag on StackOverflow][stackoverflow], the +[/r/rust] subreddit which has a pinned weekly easy questions post, or the Rust +[Discourse forum][discourse]. It's acceptable to file a support issue in this +repo, but they tend not to get as many eyes as any of the above and may get +closed without a response after some time. + +[#rust-questions]: https://discord.com/channels/273534239310479360/274215136414400513 +[#rust-beginners]: https://discord.com/channels/273534239310479360/273541522815713281 +[#rust-usage]: https://discord.com/channels/442252698964721669/443150878111694848 +[#beginners]: https://discord.com/channels/442252698964721669/448238009733742612 +[zulip]: https://rust-lang.zulipchat.com/#narrow/stream/122651-general +[stackoverflow]: https://stackoverflow.com/questions/tagged/rust +[/r/rust]: https://www.reddit.com/r/rust +[discourse]: https://users.rust-lang.org + +## No-std support + +As long as there is a memory allocator, it is possible to use serde_json without +the rest of the Rust standard library. Disable the default "std" feature and +enable the "alloc" feature: + +```toml +[dependencies] +serde_json = { version = "1.0", default-features = false, features = ["alloc"] } +``` + +For JSON support in Serde without a memory allocator, please see the +[`serde-json-core`] crate. + +[`serde-json-core`]: https://github.com/rust-embedded-community/serde-json-core + +[value]: https://docs.rs/serde_json/1/serde_json/value/enum.Value.html +[from_str]: https://docs.rs/serde_json/1/serde_json/de/fn.from_str.html +[from_slice]: https://docs.rs/serde_json/1/serde_json/de/fn.from_slice.html +[from_reader]: https://docs.rs/serde_json/1/serde_json/de/fn.from_reader.html +[to_string]: https://docs.rs/serde_json/1/serde_json/ser/fn.to_string.html +[to_vec]: https://docs.rs/serde_json/1/serde_json/ser/fn.to_vec.html +[to_writer]: https://docs.rs/serde_json/1/serde_json/ser/fn.to_writer.html +[macro]: https://docs.rs/serde_json/1/serde_json/macro.json.html + +
+ +#### License + + +Licensed under either of Apache License, Version +2.0 or MIT license at your option. + + +
+ + +Unless you explicitly state otherwise, any contribution intentionally submitted +for inclusion in this crate 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/serde_json/build.rs b/vendor/serde_json/build.rs new file mode 100644 index 0000000..29907ea --- /dev/null +++ b/vendor/serde_json/build.rs @@ -0,0 +1,29 @@ +use std::env; + +fn main() { + println!("cargo:rerun-if-changed=build.rs"); + + println!("cargo:rustc-check-cfg=cfg(fast_arithmetic, values(\"32\", \"64\"))"); + + // Decide ideal limb width for arithmetic in the float parser and string + // parser. + let target_arch = env::var_os("CARGO_CFG_TARGET_ARCH").unwrap(); + let target_pointer_width = env::var_os("CARGO_CFG_TARGET_POINTER_WIDTH").unwrap(); + if target_arch == "aarch64" + || target_arch == "loongarch64" + || target_arch == "mips64" + || target_arch == "powerpc64" + || target_arch == "wasm32" + || target_arch == "x86_64" + || target_pointer_width == "64" + { + // The above list of architectures are ones that have native support for + // 64-bit arithmetic, but which have some targets using a smaller + // pointer width. Examples include aarch64-unknown-linux-gnu_ilp32 and + // x86_64-unknown-linux-gnux32. So our choice of limb width is not + // equivalent to using usize everywhere. + println!("cargo:rustc-cfg=fast_arithmetic=\"64\""); + } else { + println!("cargo:rustc-cfg=fast_arithmetic=\"32\""); + } +} diff --git a/vendor/serde_json/src/de.rs b/vendor/serde_json/src/de.rs new file mode 100644 index 0000000..7959a66 --- /dev/null +++ b/vendor/serde_json/src/de.rs @@ -0,0 +1,2683 @@ +//! Deserialize JSON data to a Rust data structure. + +use crate::error::{Error, ErrorCode, Result}; +#[cfg(feature = "float_roundtrip")] +use crate::lexical; +use crate::number::Number; +use crate::read::{self, Fused, Reference}; +use alloc::string::String; +use alloc::vec::Vec; +#[cfg(feature = "float_roundtrip")] +use core::iter; +use core::iter::FusedIterator; +use core::marker::PhantomData; +use core::result; +use core::str::FromStr; +use serde::de::{self, Expected, Unexpected}; +use serde::forward_to_deserialize_any; + +#[cfg(feature = "arbitrary_precision")] +use crate::number::NumberDeserializer; + +pub use crate::read::{Read, SliceRead, StrRead}; + +#[cfg(feature = "std")] +#[cfg_attr(docsrs, doc(cfg(feature = "std")))] +pub use crate::read::IoRead; + +////////////////////////////////////////////////////////////////////////////// + +/// A structure that deserializes JSON into Rust values. +pub struct Deserializer { + read: R, + scratch: Vec, + remaining_depth: u8, + #[cfg(feature = "float_roundtrip")] + single_precision: bool, + #[cfg(feature = "unbounded_depth")] + disable_recursion_limit: bool, +} + +impl<'de, R> Deserializer +where + R: read::Read<'de>, +{ + /// Create a JSON deserializer from one of the possible serde_json input + /// sources. + /// + /// Typically it is more convenient to use one of these methods instead: + /// + /// - Deserializer::from_str + /// - Deserializer::from_slice + /// - Deserializer::from_reader + pub fn new(read: R) -> Self { + Deserializer { + read, + scratch: Vec::new(), + remaining_depth: 128, + #[cfg(feature = "float_roundtrip")] + single_precision: false, + #[cfg(feature = "unbounded_depth")] + disable_recursion_limit: false, + } + } +} + +#[cfg(feature = "std")] +impl Deserializer> +where + R: crate::io::Read, +{ + /// Creates a JSON deserializer from an `io::Read`. + /// + /// Reader-based deserializers do not support deserializing borrowed types + /// like `&str`, since the `std::io::Read` trait has no non-copying methods + /// -- everything it does involves copying bytes out of the data source. + pub fn from_reader(reader: R) -> Self { + Deserializer::new(read::IoRead::new(reader)) + } +} + +impl<'a> Deserializer> { + /// Creates a JSON deserializer from a `&[u8]`. + pub fn from_slice(bytes: &'a [u8]) -> Self { + Deserializer::new(read::SliceRead::new(bytes)) + } +} + +impl<'a> Deserializer> { + /// Creates a JSON deserializer from a `&str`. + pub fn from_str(s: &'a str) -> Self { + Deserializer::new(read::StrRead::new(s)) + } +} + +macro_rules! overflow { + ($a:ident * 10 + $b:ident, $c:expr) => { + match $c { + c => $a >= c / 10 && ($a > c / 10 || $b > c % 10), + } + }; +} + +pub(crate) enum ParserNumber { + F64(f64), + U64(u64), + I64(i64), + #[cfg(feature = "arbitrary_precision")] + String(String), +} + +impl ParserNumber { + fn visit<'de, V>(self, visitor: V) -> Result + where + V: de::Visitor<'de>, + { + match self { + ParserNumber::F64(x) => visitor.visit_f64(x), + ParserNumber::U64(x) => visitor.visit_u64(x), + ParserNumber::I64(x) => visitor.visit_i64(x), + #[cfg(feature = "arbitrary_precision")] + ParserNumber::String(x) => visitor.visit_map(NumberDeserializer { number: x.into() }), + } + } + + fn invalid_type(self, exp: &dyn Expected) -> Error { + match self { + ParserNumber::F64(x) => de::Error::invalid_type(Unexpected::Float(x), exp), + ParserNumber::U64(x) => de::Error::invalid_type(Unexpected::Unsigned(x), exp), + ParserNumber::I64(x) => de::Error::invalid_type(Unexpected::Signed(x), exp), + #[cfg(feature = "arbitrary_precision")] + ParserNumber::String(_) => de::Error::invalid_type(Unexpected::Other("number"), exp), + } + } +} + +impl<'de, R: Read<'de>> Deserializer { + /// The `Deserializer::end` method should be called after a value has been fully deserialized. + /// This allows the `Deserializer` to validate that the input stream is at the end or that it + /// only has trailing whitespace. + pub fn end(&mut self) -> Result<()> { + match tri!(self.parse_whitespace()) { + Some(_) => Err(self.peek_error(ErrorCode::TrailingCharacters)), + None => Ok(()), + } + } + + /// Turn a JSON deserializer into an iterator over values of type T. + pub fn into_iter(self) -> StreamDeserializer<'de, R, T> + where + T: de::Deserialize<'de>, + { + // This cannot be an implementation of std::iter::IntoIterator because + // we need the caller to choose what T is. + let offset = self.read.byte_offset(); + StreamDeserializer { + de: self, + offset, + failed: false, + output: PhantomData, + lifetime: PhantomData, + } + } + + /// Parse arbitrarily deep JSON structures without any consideration for + /// overflowing the stack. + /// + /// You will want to provide some other way to protect against stack + /// overflows, such as by wrapping your Deserializer in the dynamically + /// growing stack adapter provided by the serde_stacker crate. Additionally + /// you will need to be careful around other recursive operations on the + /// parsed result which may overflow the stack after deserialization has + /// completed, including, but not limited to, Display and Debug and Drop + /// impls. + /// + /// *This method is only available if serde_json is built with the + /// `"unbounded_depth"` feature.* + /// + /// # Examples + /// + /// ``` + /// use serde::Deserialize; + /// use serde_json::Value; + /// + /// fn main() { + /// let mut json = String::new(); + /// for _ in 0..10000 { + /// json = format!("[{}]", json); + /// } + /// + /// let mut deserializer = serde_json::Deserializer::from_str(&json); + /// deserializer.disable_recursion_limit(); + /// let deserializer = serde_stacker::Deserializer::new(&mut deserializer); + /// let value = Value::deserialize(deserializer).unwrap(); + /// + /// carefully_drop_nested_arrays(value); + /// } + /// + /// fn carefully_drop_nested_arrays(value: Value) { + /// let mut stack = vec![value]; + /// while let Some(value) = stack.pop() { + /// if let Value::Array(array) = value { + /// stack.extend(array); + /// } + /// } + /// } + /// ``` + #[cfg(feature = "unbounded_depth")] + #[cfg_attr(docsrs, doc(cfg(feature = "unbounded_depth")))] + pub fn disable_recursion_limit(&mut self) { + self.disable_recursion_limit = true; + } + + pub(crate) fn peek(&mut self) -> Result> { + self.read.peek() + } + + fn peek_or_null(&mut self) -> Result { + Ok(tri!(self.peek()).unwrap_or(b'\x00')) + } + + fn eat_char(&mut self) { + self.read.discard(); + } + + fn next_char(&mut self) -> Result> { + self.read.next() + } + + fn next_char_or_null(&mut self) -> Result { + Ok(tri!(self.next_char()).unwrap_or(b'\x00')) + } + + /// Error caused by a byte from next_char(). + #[cold] + fn error(&self, reason: ErrorCode) -> Error { + let position = self.read.position(); + Error::syntax(reason, position.line, position.column) + } + + /// Error caused by a byte from peek(). + #[cold] + fn peek_error(&self, reason: ErrorCode) -> Error { + let position = self.read.peek_position(); + Error::syntax(reason, position.line, position.column) + } + + /// Returns the first non-whitespace byte without consuming it, or `None` if + /// EOF is encountered. + fn parse_whitespace(&mut self) -> Result> { + loop { + match tri!(self.peek()) { + Some(b' ' | b'\n' | b'\t' | b'\r') => { + self.eat_char(); + } + other => { + return Ok(other); + } + } + } + } + + #[cold] + fn peek_invalid_type(&mut self, exp: &dyn Expected) -> Error { + let err = match self.peek_or_null().unwrap_or(b'\x00') { + b'n' => { + self.eat_char(); + if let Err(err) = self.parse_ident(b"ull") { + return err; + } + de::Error::invalid_type(Unexpected::Unit, exp) + } + b't' => { + self.eat_char(); + if let Err(err) = self.parse_ident(b"rue") { + return err; + } + de::Error::invalid_type(Unexpected::Bool(true), exp) + } + b'f' => { + self.eat_char(); + if let Err(err) = self.parse_ident(b"alse") { + return err; + } + de::Error::invalid_type(Unexpected::Bool(false), exp) + } + b'-' => { + self.eat_char(); + match self.parse_any_number(false) { + Ok(n) => n.invalid_type(exp), + Err(err) => return err, + } + } + b'0'..=b'9' => match self.parse_any_number(true) { + Ok(n) => n.invalid_type(exp), + Err(err) => return err, + }, + b'"' => { + self.eat_char(); + self.scratch.clear(); + match self.read.parse_str(&mut self.scratch) { + Ok(s) => de::Error::invalid_type(Unexpected::Str(&s), exp), + Err(err) => return err, + } + } + b'[' => de::Error::invalid_type(Unexpected::Seq, exp), + b'{' => de::Error::invalid_type(Unexpected::Map, exp), + _ => self.peek_error(ErrorCode::ExpectedSomeValue), + }; + + self.fix_position(err) + } + + pub(crate) fn deserialize_number<'any, V>(&mut self, visitor: V) -> Result + where + V: de::Visitor<'any>, + { + let peek = match tri!(self.parse_whitespace()) { + Some(b) => b, + None => { + return Err(self.peek_error(ErrorCode::EofWhileParsingValue)); + } + }; + + let value = match peek { + b'-' => { + self.eat_char(); + tri!(self.parse_integer(false)).visit(visitor) + } + b'0'..=b'9' => tri!(self.parse_integer(true)).visit(visitor), + _ => Err(self.peek_invalid_type(&visitor)), + }; + + match value { + Ok(value) => Ok(value), + Err(err) => Err(self.fix_position(err)), + } + } + + #[cfg(feature = "float_roundtrip")] + pub(crate) fn do_deserialize_f32<'any, V>(&mut self, visitor: V) -> Result + where + V: de::Visitor<'any>, + { + self.single_precision = true; + let val = self.deserialize_number(visitor); + self.single_precision = false; + val + } + + pub(crate) fn do_deserialize_i128<'any, V>(&mut self, visitor: V) -> Result + where + V: de::Visitor<'any>, + { + let mut buf = String::new(); + + match tri!(self.parse_whitespace()) { + Some(b'-') => { + self.eat_char(); + buf.push('-'); + } + Some(_) => {} + None => { + return Err(self.peek_error(ErrorCode::EofWhileParsingValue)); + } + }; + + tri!(self.scan_integer128(&mut buf)); + + let value = match buf.parse() { + Ok(int) => visitor.visit_i128(int), + Err(_) => { + return Err(self.error(ErrorCode::NumberOutOfRange)); + } + }; + + match value { + Ok(value) => Ok(value), + Err(err) => Err(self.fix_position(err)), + } + } + + pub(crate) fn do_deserialize_u128<'any, V>(&mut self, visitor: V) -> Result + where + V: de::Visitor<'any>, + { + match tri!(self.parse_whitespace()) { + Some(b'-') => { + return Err(self.peek_error(ErrorCode::NumberOutOfRange)); + } + Some(_) => {} + None => { + return Err(self.peek_error(ErrorCode::EofWhileParsingValue)); + } + } + + let mut buf = String::new(); + tri!(self.scan_integer128(&mut buf)); + + let value = match buf.parse() { + Ok(int) => visitor.visit_u128(int), + Err(_) => { + return Err(self.error(ErrorCode::NumberOutOfRange)); + } + }; + + match value { + Ok(value) => Ok(value), + Err(err) => Err(self.fix_position(err)), + } + } + + fn scan_integer128(&mut self, buf: &mut String) -> Result<()> { + match tri!(self.next_char_or_null()) { + b'0' => { + buf.push('0'); + // There can be only one leading '0'. + match tri!(self.peek_or_null()) { + b'0'..=b'9' => Err(self.peek_error(ErrorCode::InvalidNumber)), + _ => Ok(()), + } + } + c @ b'1'..=b'9' => { + buf.push(c as char); + while let c @ b'0'..=b'9' = tri!(self.peek_or_null()) { + self.eat_char(); + buf.push(c as char); + } + Ok(()) + } + _ => Err(self.error(ErrorCode::InvalidNumber)), + } + } + + #[cold] + fn fix_position(&self, err: Error) -> Error { + err.fix_position(move |code| self.error(code)) + } + + fn parse_ident(&mut self, ident: &[u8]) -> Result<()> { + for expected in ident { + match tri!(self.next_char()) { + None => { + return Err(self.error(ErrorCode::EofWhileParsingValue)); + } + Some(next) => { + if next != *expected { + return Err(self.error(ErrorCode::ExpectedSomeIdent)); + } + } + } + } + + Ok(()) + } + + fn parse_integer(&mut self, positive: bool) -> Result { + let next = match tri!(self.next_char()) { + Some(b) => b, + None => { + return Err(self.error(ErrorCode::EofWhileParsingValue)); + } + }; + + match next { + b'0' => { + // There can be only one leading '0'. + match tri!(self.peek_or_null()) { + b'0'..=b'9' => Err(self.peek_error(ErrorCode::InvalidNumber)), + _ => self.parse_number(positive, 0), + } + } + c @ b'1'..=b'9' => { + let mut significand = (c - b'0') as u64; + + loop { + match tri!(self.peek_or_null()) { + c @ b'0'..=b'9' => { + let digit = (c - b'0') as u64; + + // We need to be careful with overflow. If we can, + // try to keep the number as a `u64` until we grow + // too large. At that point, switch to parsing the + // value as a `f64`. + if overflow!(significand * 10 + digit, u64::MAX) { + return Ok(ParserNumber::F64(tri!( + self.parse_long_integer(positive, significand), + ))); + } + + self.eat_char(); + significand = significand * 10 + digit; + } + _ => { + return self.parse_number(positive, significand); + } + } + } + } + _ => Err(self.error(ErrorCode::InvalidNumber)), + } + } + + fn parse_number(&mut self, positive: bool, significand: u64) -> Result { + Ok(match tri!(self.peek_or_null()) { + b'.' => ParserNumber::F64(tri!(self.parse_decimal(positive, significand, 0))), + b'e' | b'E' => ParserNumber::F64(tri!(self.parse_exponent(positive, significand, 0))), + _ => { + if positive { + ParserNumber::U64(significand) + } else { + let neg = (significand as i64).wrapping_neg(); + + // Convert into a float if we underflow, or on `-0`. + if neg >= 0 { + ParserNumber::F64(-(significand as f64)) + } else { + ParserNumber::I64(neg) + } + } + } + }) + } + + fn parse_decimal( + &mut self, + positive: bool, + mut significand: u64, + exponent_before_decimal_point: i32, + ) -> Result { + self.eat_char(); + + let mut exponent_after_decimal_point = 0; + while let c @ b'0'..=b'9' = tri!(self.peek_or_null()) { + let digit = (c - b'0') as u64; + + if overflow!(significand * 10 + digit, u64::MAX) { + let exponent = exponent_before_decimal_point + exponent_after_decimal_point; + return self.parse_decimal_overflow(positive, significand, exponent); + } + + self.eat_char(); + significand = significand * 10 + digit; + exponent_after_decimal_point -= 1; + } + + // Error if there is not at least one digit after the decimal point. + if exponent_after_decimal_point == 0 { + match tri!(self.peek()) { + Some(_) => return Err(self.peek_error(ErrorCode::InvalidNumber)), + None => return Err(self.peek_error(ErrorCode::EofWhileParsingValue)), + } + } + + let exponent = exponent_before_decimal_point + exponent_after_decimal_point; + match tri!(self.peek_or_null()) { + b'e' | b'E' => self.parse_exponent(positive, significand, exponent), + _ => self.f64_from_parts(positive, significand, exponent), + } + } + + fn parse_exponent( + &mut self, + positive: bool, + significand: u64, + starting_exp: i32, + ) -> Result { + self.eat_char(); + + let positive_exp = match tri!(self.peek_or_null()) { + b'+' => { + self.eat_char(); + true + } + b'-' => { + self.eat_char(); + false + } + _ => true, + }; + + let next = match tri!(self.next_char()) { + Some(b) => b, + None => { + return Err(self.error(ErrorCode::EofWhileParsingValue)); + } + }; + + // Make sure a digit follows the exponent place. + let mut exp = match next { + c @ b'0'..=b'9' => (c - b'0') as i32, + _ => { + return Err(self.error(ErrorCode::InvalidNumber)); + } + }; + + while let c @ b'0'..=b'9' = tri!(self.peek_or_null()) { + self.eat_char(); + let digit = (c - b'0') as i32; + + if overflow!(exp * 10 + digit, i32::MAX) { + let zero_significand = significand == 0; + return self.parse_exponent_overflow(positive, zero_significand, positive_exp); + } + + exp = exp * 10 + digit; + } + + let final_exp = if positive_exp { + starting_exp.saturating_add(exp) + } else { + starting_exp.saturating_sub(exp) + }; + + self.f64_from_parts(positive, significand, final_exp) + } + + #[cfg(feature = "float_roundtrip")] + fn f64_from_parts(&mut self, positive: bool, significand: u64, exponent: i32) -> Result { + let f = if self.single_precision { + lexical::parse_concise_float::(significand, exponent) as f64 + } else { + lexical::parse_concise_float::(significand, exponent) + }; + + if f.is_infinite() { + Err(self.error(ErrorCode::NumberOutOfRange)) + } else { + Ok(if positive { f } else { -f }) + } + } + + #[cfg(not(feature = "float_roundtrip"))] + fn f64_from_parts( + &mut self, + positive: bool, + significand: u64, + mut exponent: i32, + ) -> Result { + let mut f = significand as f64; + loop { + match POW10.get(exponent.wrapping_abs() as usize) { + Some(&pow) => { + if exponent >= 0 { + f *= pow; + if f.is_infinite() { + return Err(self.error(ErrorCode::NumberOutOfRange)); + } + } else { + f /= pow; + } + break; + } + None => { + if f == 0.0 { + break; + } + if exponent >= 0 { + return Err(self.error(ErrorCode::NumberOutOfRange)); + } + f /= 1e308; + exponent += 308; + } + } + } + Ok(if positive { f } else { -f }) + } + + #[cfg(feature = "float_roundtrip")] + #[cold] + #[inline(never)] + fn parse_long_integer(&mut self, positive: bool, partial_significand: u64) -> Result { + // To deserialize floats we'll first push the integer and fraction + // parts, both as byte strings, into the scratch buffer and then feed + // both slices to lexical's parser. For example if the input is + // `12.34e5` we'll push b"1234" into scratch and then pass b"12" and + // b"34" to lexical. `integer_end` will be used to track where to split + // the scratch buffer. + // + // Note that lexical expects the integer part to contain *no* leading + // zeroes and the fraction part to contain *no* trailing zeroes. The + // first requirement is already handled by the integer parsing logic. + // The second requirement will be enforced just before passing the + // slices to lexical in f64_long_from_parts. + self.scratch.clear(); + self.scratch + .extend_from_slice(itoa::Buffer::new().format(partial_significand).as_bytes()); + + loop { + match tri!(self.peek_or_null()) { + c @ b'0'..=b'9' => { + self.scratch.push(c); + self.eat_char(); + } + b'.' => { + self.eat_char(); + return self.parse_long_decimal(positive, self.scratch.len()); + } + b'e' | b'E' => { + return self.parse_long_exponent(positive, self.scratch.len()); + } + _ => { + return self.f64_long_from_parts(positive, self.scratch.len(), 0); + } + } + } + } + + #[cfg(not(feature = "float_roundtrip"))] + #[cold] + #[inline(never)] + fn parse_long_integer(&mut self, positive: bool, significand: u64) -> Result { + let mut exponent = 0; + loop { + match tri!(self.peek_or_null()) { + b'0'..=b'9' => { + self.eat_char(); + // This could overflow... if your integer is gigabytes long. + // Ignore that possibility. + exponent += 1; + } + b'.' => { + return self.parse_decimal(positive, significand, exponent); + } + b'e' | b'E' => { + return self.parse_exponent(positive, significand, exponent); + } + _ => { + return self.f64_from_parts(positive, significand, exponent); + } + } + } + } + + #[cfg(feature = "float_roundtrip")] + #[cold] + fn parse_long_decimal(&mut self, positive: bool, integer_end: usize) -> Result { + let mut at_least_one_digit = integer_end < self.scratch.len(); + while let c @ b'0'..=b'9' = tri!(self.peek_or_null()) { + self.scratch.push(c); + self.eat_char(); + at_least_one_digit = true; + } + + if !at_least_one_digit { + match tri!(self.peek()) { + Some(_) => return Err(self.peek_error(ErrorCode::InvalidNumber)), + None => return Err(self.peek_error(ErrorCode::EofWhileParsingValue)), + } + } + + match tri!(self.peek_or_null()) { + b'e' | b'E' => self.parse_long_exponent(positive, integer_end), + _ => self.f64_long_from_parts(positive, integer_end, 0), + } + } + + #[cfg(feature = "float_roundtrip")] + fn parse_long_exponent(&mut self, positive: bool, integer_end: usize) -> Result { + self.eat_char(); + + let positive_exp = match tri!(self.peek_or_null()) { + b'+' => { + self.eat_char(); + true + } + b'-' => { + self.eat_char(); + false + } + _ => true, + }; + + let next = match tri!(self.next_char()) { + Some(b) => b, + None => { + return Err(self.error(ErrorCode::EofWhileParsingValue)); + } + }; + + // Make sure a digit follows the exponent place. + let mut exp = match next { + c @ b'0'..=b'9' => (c - b'0') as i32, + _ => { + return Err(self.error(ErrorCode::InvalidNumber)); + } + }; + + while let c @ b'0'..=b'9' = tri!(self.peek_or_null()) { + self.eat_char(); + let digit = (c - b'0') as i32; + + if overflow!(exp * 10 + digit, i32::MAX) { + let zero_significand = self.scratch.iter().all(|&digit| digit == b'0'); + return self.parse_exponent_overflow(positive, zero_significand, positive_exp); + } + + exp = exp * 10 + digit; + } + + let final_exp = if positive_exp { exp } else { -exp }; + + self.f64_long_from_parts(positive, integer_end, final_exp) + } + + // This cold code should not be inlined into the middle of the hot + // decimal-parsing loop above. + #[cfg(feature = "float_roundtrip")] + #[cold] + #[inline(never)] + fn parse_decimal_overflow( + &mut self, + positive: bool, + significand: u64, + exponent: i32, + ) -> Result { + let mut buffer = itoa::Buffer::new(); + let significand = buffer.format(significand); + let fraction_digits = -exponent as usize; + self.scratch.clear(); + if let Some(zeros) = fraction_digits.checked_sub(significand.len() + 1) { + self.scratch.extend(iter::repeat(b'0').take(zeros + 1)); + } + self.scratch.extend_from_slice(significand.as_bytes()); + let integer_end = self.scratch.len() - fraction_digits; + self.parse_long_decimal(positive, integer_end) + } + + #[cfg(not(feature = "float_roundtrip"))] + #[cold] + #[inline(never)] + fn parse_decimal_overflow( + &mut self, + positive: bool, + significand: u64, + exponent: i32, + ) -> Result { + // The next multiply/add would overflow, so just ignore all further + // digits. + while let b'0'..=b'9' = tri!(self.peek_or_null()) { + self.eat_char(); + } + + match tri!(self.peek_or_null()) { + b'e' | b'E' => self.parse_exponent(positive, significand, exponent), + _ => self.f64_from_parts(positive, significand, exponent), + } + } + + // This cold code should not be inlined into the middle of the hot + // exponent-parsing loop above. + #[cold] + #[inline(never)] + fn parse_exponent_overflow( + &mut self, + positive: bool, + zero_significand: bool, + positive_exp: bool, + ) -> Result { + // Error instead of +/- infinity. + if !zero_significand && positive_exp { + return Err(self.error(ErrorCode::NumberOutOfRange)); + } + + while let b'0'..=b'9' = tri!(self.peek_or_null()) { + self.eat_char(); + } + Ok(if positive { 0.0 } else { -0.0 }) + } + + #[cfg(feature = "float_roundtrip")] + fn f64_long_from_parts( + &mut self, + positive: bool, + integer_end: usize, + exponent: i32, + ) -> Result { + let integer = &self.scratch[..integer_end]; + let fraction = &self.scratch[integer_end..]; + + let f = if self.single_precision { + lexical::parse_truncated_float::(integer, fraction, exponent) as f64 + } else { + lexical::parse_truncated_float::(integer, fraction, exponent) + }; + + if f.is_infinite() { + Err(self.error(ErrorCode::NumberOutOfRange)) + } else { + Ok(if positive { f } else { -f }) + } + } + + fn parse_any_signed_number(&mut self) -> Result { + let peek = match tri!(self.peek()) { + Some(b) => b, + None => { + return Err(self.peek_error(ErrorCode::EofWhileParsingValue)); + } + }; + + let value = match peek { + b'-' => { + self.eat_char(); + self.parse_any_number(false) + } + b'0'..=b'9' => self.parse_any_number(true), + _ => Err(self.peek_error(ErrorCode::InvalidNumber)), + }; + + let value = match tri!(self.peek()) { + Some(_) => Err(self.peek_error(ErrorCode::InvalidNumber)), + None => value, + }; + + match value { + Ok(value) => Ok(value), + // The de::Error impl creates errors with unknown line and column. + // Fill in the position here by looking at the current index in the + // input. There is no way to tell whether this should call `error` + // or `peek_error` so pick the one that seems correct more often. + // Worst case, the position is off by one character. + Err(err) => Err(self.fix_position(err)), + } + } + + #[cfg(not(feature = "arbitrary_precision"))] + fn parse_any_number(&mut self, positive: bool) -> Result { + self.parse_integer(positive) + } + + #[cfg(feature = "arbitrary_precision")] + fn parse_any_number(&mut self, positive: bool) -> Result { + let mut buf = String::with_capacity(16); + if !positive { + buf.push('-'); + } + tri!(self.scan_integer(&mut buf)); + if positive { + if let Ok(unsigned) = buf.parse() { + return Ok(ParserNumber::U64(unsigned)); + } + } else { + if let Ok(signed) = buf.parse() { + return Ok(ParserNumber::I64(signed)); + } + } + Ok(ParserNumber::String(buf)) + } + + #[cfg(feature = "arbitrary_precision")] + fn scan_or_eof(&mut self, buf: &mut String) -> Result { + match tri!(self.next_char()) { + Some(b) => { + buf.push(b as char); + Ok(b) + } + None => Err(self.error(ErrorCode::EofWhileParsingValue)), + } + } + + #[cfg(feature = "arbitrary_precision")] + fn scan_integer(&mut self, buf: &mut String) -> Result<()> { + match tri!(self.scan_or_eof(buf)) { + b'0' => { + // There can be only one leading '0'. + match tri!(self.peek_or_null()) { + b'0'..=b'9' => Err(self.peek_error(ErrorCode::InvalidNumber)), + _ => self.scan_number(buf), + } + } + b'1'..=b'9' => loop { + match tri!(self.peek_or_null()) { + c @ b'0'..=b'9' => { + self.eat_char(); + buf.push(c as char); + } + _ => { + return self.scan_number(buf); + } + } + }, + _ => Err(self.error(ErrorCode::InvalidNumber)), + } + } + + #[cfg(feature = "arbitrary_precision")] + fn scan_number(&mut self, buf: &mut String) -> Result<()> { + match tri!(self.peek_or_null()) { + b'.' => self.scan_decimal(buf), + e @ (b'e' | b'E') => self.scan_exponent(e as char, buf), + _ => Ok(()), + } + } + + #[cfg(feature = "arbitrary_precision")] + fn scan_decimal(&mut self, buf: &mut String) -> Result<()> { + self.eat_char(); + buf.push('.'); + + let mut at_least_one_digit = false; + while let c @ b'0'..=b'9' = tri!(self.peek_or_null()) { + self.eat_char(); + buf.push(c as char); + at_least_one_digit = true; + } + + if !at_least_one_digit { + match tri!(self.peek()) { + Some(_) => return Err(self.peek_error(ErrorCode::InvalidNumber)), + None => return Err(self.peek_error(ErrorCode::EofWhileParsingValue)), + } + } + + match tri!(self.peek_or_null()) { + e @ (b'e' | b'E') => self.scan_exponent(e as char, buf), + _ => Ok(()), + } + } + + #[cfg(feature = "arbitrary_precision")] + fn scan_exponent(&mut self, e: char, buf: &mut String) -> Result<()> { + self.eat_char(); + buf.push(e); + + match tri!(self.peek_or_null()) { + b'+' => { + self.eat_char(); + buf.push('+'); + } + b'-' => { + self.eat_char(); + buf.push('-'); + } + _ => {} + } + + // Make sure a digit follows the exponent place. + match tri!(self.scan_or_eof(buf)) { + b'0'..=b'9' => {} + _ => { + return Err(self.error(ErrorCode::InvalidNumber)); + } + } + + while let c @ b'0'..=b'9' = tri!(self.peek_or_null()) { + self.eat_char(); + buf.push(c as char); + } + + Ok(()) + } + + fn parse_object_colon(&mut self) -> Result<()> { + match tri!(self.parse_whitespace()) { + Some(b':') => { + self.eat_char(); + Ok(()) + } + Some(_) => Err(self.peek_error(ErrorCode::ExpectedColon)), + None => Err(self.peek_error(ErrorCode::EofWhileParsingObject)), + } + } + + fn end_seq(&mut self) -> Result<()> { + match tri!(self.parse_whitespace()) { + Some(b']') => { + self.eat_char(); + Ok(()) + } + Some(b',') => { + self.eat_char(); + match self.parse_whitespace() { + Ok(Some(b']')) => Err(self.peek_error(ErrorCode::TrailingComma)), + _ => Err(self.peek_error(ErrorCode::TrailingCharacters)), + } + } + Some(_) => Err(self.peek_error(ErrorCode::TrailingCharacters)), + None => Err(self.peek_error(ErrorCode::EofWhileParsingList)), + } + } + + fn end_map(&mut self) -> Result<()> { + match tri!(self.parse_whitespace()) { + Some(b'}') => { + self.eat_char(); + Ok(()) + } + Some(b',') => Err(self.peek_error(ErrorCode::TrailingComma)), + Some(_) => Err(self.peek_error(ErrorCode::TrailingCharacters)), + None => Err(self.peek_error(ErrorCode::EofWhileParsingObject)), + } + } + + fn ignore_value(&mut self) -> Result<()> { + self.scratch.clear(); + let mut enclosing = None; + + loop { + let peek = match tri!(self.parse_whitespace()) { + Some(b) => b, + None => { + return Err(self.peek_error(ErrorCode::EofWhileParsingValue)); + } + }; + + let frame = match peek { + b'n' => { + self.eat_char(); + tri!(self.parse_ident(b"ull")); + None + } + b't' => { + self.eat_char(); + tri!(self.parse_ident(b"rue")); + None + } + b'f' => { + self.eat_char(); + tri!(self.parse_ident(b"alse")); + None + } + b'-' => { + self.eat_char(); + tri!(self.ignore_integer()); + None + } + b'0'..=b'9' => { + tri!(self.ignore_integer()); + None + } + b'"' => { + self.eat_char(); + tri!(self.read.ignore_str()); + None + } + frame @ (b'[' | b'{') => { + self.scratch.extend(enclosing.take()); + self.eat_char(); + Some(frame) + } + _ => return Err(self.peek_error(ErrorCode::ExpectedSomeValue)), + }; + + let (mut accept_comma, mut frame) = match frame { + Some(frame) => (false, frame), + None => match enclosing.take() { + Some(frame) => (true, frame), + None => match self.scratch.pop() { + Some(frame) => (true, frame), + None => return Ok(()), + }, + }, + }; + + loop { + match tri!(self.parse_whitespace()) { + Some(b',') if accept_comma => { + self.eat_char(); + break; + } + Some(b']') if frame == b'[' => {} + Some(b'}') if frame == b'{' => {} + Some(_) => { + if accept_comma { + return Err(self.peek_error(match frame { + b'[' => ErrorCode::ExpectedListCommaOrEnd, + b'{' => ErrorCode::ExpectedObjectCommaOrEnd, + _ => unreachable!(), + })); + } else { + break; + } + } + None => { + return Err(self.peek_error(match frame { + b'[' => ErrorCode::EofWhileParsingList, + b'{' => ErrorCode::EofWhileParsingObject, + _ => unreachable!(), + })); + } + } + + self.eat_char(); + frame = match self.scratch.pop() { + Some(frame) => frame, + None => return Ok(()), + }; + accept_comma = true; + } + + if frame == b'{' { + match tri!(self.parse_whitespace()) { + Some(b'"') => self.eat_char(), + Some(_) => return Err(self.peek_error(ErrorCode::KeyMustBeAString)), + None => return Err(self.peek_error(ErrorCode::EofWhileParsingObject)), + } + tri!(self.read.ignore_str()); + match tri!(self.parse_whitespace()) { + Some(b':') => self.eat_char(), + Some(_) => return Err(self.peek_error(ErrorCode::ExpectedColon)), + None => return Err(self.peek_error(ErrorCode::EofWhileParsingObject)), + } + } + + enclosing = Some(frame); + } + } + + fn ignore_integer(&mut self) -> Result<()> { + match tri!(self.next_char_or_null()) { + b'0' => { + // There can be only one leading '0'. + if let b'0'..=b'9' = tri!(self.peek_or_null()) { + return Err(self.peek_error(ErrorCode::InvalidNumber)); + } + } + b'1'..=b'9' => { + while let b'0'..=b'9' = tri!(self.peek_or_null()) { + self.eat_char(); + } + } + _ => { + return Err(self.error(ErrorCode::InvalidNumber)); + } + } + + match tri!(self.peek_or_null()) { + b'.' => self.ignore_decimal(), + b'e' | b'E' => self.ignore_exponent(), + _ => Ok(()), + } + } + + fn ignore_decimal(&mut self) -> Result<()> { + self.eat_char(); + + let mut at_least_one_digit = false; + while let b'0'..=b'9' = tri!(self.peek_or_null()) { + self.eat_char(); + at_least_one_digit = true; + } + + if !at_least_one_digit { + return Err(self.peek_error(ErrorCode::InvalidNumber)); + } + + match tri!(self.peek_or_null()) { + b'e' | b'E' => self.ignore_exponent(), + _ => Ok(()), + } + } + + fn ignore_exponent(&mut self) -> Result<()> { + self.eat_char(); + + match tri!(self.peek_or_null()) { + b'+' | b'-' => self.eat_char(), + _ => {} + } + + // Make sure a digit follows the exponent place. + match tri!(self.next_char_or_null()) { + b'0'..=b'9' => {} + _ => { + return Err(self.error(ErrorCode::InvalidNumber)); + } + } + + while let b'0'..=b'9' = tri!(self.peek_or_null()) { + self.eat_char(); + } + + Ok(()) + } + + #[cfg(feature = "raw_value")] + fn deserialize_raw_value(&mut self, visitor: V) -> Result + where + V: de::Visitor<'de>, + { + tri!(self.parse_whitespace()); + self.read.begin_raw_buffering(); + tri!(self.ignore_value()); + self.read.end_raw_buffering(visitor) + } +} + +impl FromStr for Number { + type Err = Error; + + fn from_str(s: &str) -> result::Result { + Deserializer::from_str(s) + .parse_any_signed_number() + .map(Into::into) + } +} + +#[cfg(not(feature = "float_roundtrip"))] +static POW10: [f64; 309] = [ + 1e000, 1e001, 1e002, 1e003, 1e004, 1e005, 1e006, 1e007, 1e008, 1e009, // + 1e010, 1e011, 1e012, 1e013, 1e014, 1e015, 1e016, 1e017, 1e018, 1e019, // + 1e020, 1e021, 1e022, 1e023, 1e024, 1e025, 1e026, 1e027, 1e028, 1e029, // + 1e030, 1e031, 1e032, 1e033, 1e034, 1e035, 1e036, 1e037, 1e038, 1e039, // + 1e040, 1e041, 1e042, 1e043, 1e044, 1e045, 1e046, 1e047, 1e048, 1e049, // + 1e050, 1e051, 1e052, 1e053, 1e054, 1e055, 1e056, 1e057, 1e058, 1e059, // + 1e060, 1e061, 1e062, 1e063, 1e064, 1e065, 1e066, 1e067, 1e068, 1e069, // + 1e070, 1e071, 1e072, 1e073, 1e074, 1e075, 1e076, 1e077, 1e078, 1e079, // + 1e080, 1e081, 1e082, 1e083, 1e084, 1e085, 1e086, 1e087, 1e088, 1e089, // + 1e090, 1e091, 1e092, 1e093, 1e094, 1e095, 1e096, 1e097, 1e098, 1e099, // + 1e100, 1e101, 1e102, 1e103, 1e104, 1e105, 1e106, 1e107, 1e108, 1e109, // + 1e110, 1e111, 1e112, 1e113, 1e114, 1e115, 1e116, 1e117, 1e118, 1e119, // + 1e120, 1e121, 1e122, 1e123, 1e124, 1e125, 1e126, 1e127, 1e128, 1e129, // + 1e130, 1e131, 1e132, 1e133, 1e134, 1e135, 1e136, 1e137, 1e138, 1e139, // + 1e140, 1e141, 1e142, 1e143, 1e144, 1e145, 1e146, 1e147, 1e148, 1e149, // + 1e150, 1e151, 1e152, 1e153, 1e154, 1e155, 1e156, 1e157, 1e158, 1e159, // + 1e160, 1e161, 1e162, 1e163, 1e164, 1e165, 1e166, 1e167, 1e168, 1e169, // + 1e170, 1e171, 1e172, 1e173, 1e174, 1e175, 1e176, 1e177, 1e178, 1e179, // + 1e180, 1e181, 1e182, 1e183, 1e184, 1e185, 1e186, 1e187, 1e188, 1e189, // + 1e190, 1e191, 1e192, 1e193, 1e194, 1e195, 1e196, 1e197, 1e198, 1e199, // + 1e200, 1e201, 1e202, 1e203, 1e204, 1e205, 1e206, 1e207, 1e208, 1e209, // + 1e210, 1e211, 1e212, 1e213, 1e214, 1e215, 1e216, 1e217, 1e218, 1e219, // + 1e220, 1e221, 1e222, 1e223, 1e224, 1e225, 1e226, 1e227, 1e228, 1e229, // + 1e230, 1e231, 1e232, 1e233, 1e234, 1e235, 1e236, 1e237, 1e238, 1e239, // + 1e240, 1e241, 1e242, 1e243, 1e244, 1e245, 1e246, 1e247, 1e248, 1e249, // + 1e250, 1e251, 1e252, 1e253, 1e254, 1e255, 1e256, 1e257, 1e258, 1e259, // + 1e260, 1e261, 1e262, 1e263, 1e264, 1e265, 1e266, 1e267, 1e268, 1e269, // + 1e270, 1e271, 1e272, 1e273, 1e274, 1e275, 1e276, 1e277, 1e278, 1e279, // + 1e280, 1e281, 1e282, 1e283, 1e284, 1e285, 1e286, 1e287, 1e288, 1e289, // + 1e290, 1e291, 1e292, 1e293, 1e294, 1e295, 1e296, 1e297, 1e298, 1e299, // + 1e300, 1e301, 1e302, 1e303, 1e304, 1e305, 1e306, 1e307, 1e308, +]; + +macro_rules! deserialize_number { + ($method:ident) => { + deserialize_number!($method, deserialize_number); + }; + + ($method:ident, $using:ident) => { + fn $method(self, visitor: V) -> Result + where + V: de::Visitor<'de>, + { + self.$using(visitor) + } + }; +} + +#[cfg(not(feature = "unbounded_depth"))] +macro_rules! if_checking_recursion_limit { + ($($body:tt)*) => { + $($body)* + }; +} + +#[cfg(feature = "unbounded_depth")] +macro_rules! if_checking_recursion_limit { + ($this:ident $($body:tt)*) => { + if !$this.disable_recursion_limit { + $this $($body)* + } + }; +} + +macro_rules! check_recursion { + ($this:ident $($body:tt)*) => { + if_checking_recursion_limit! { + $this.remaining_depth -= 1; + if $this.remaining_depth == 0 { + return Err($this.peek_error(ErrorCode::RecursionLimitExceeded)); + } + } + + $this $($body)* + + if_checking_recursion_limit! { + $this.remaining_depth += 1; + } + }; +} + +impl<'de, R: Read<'de>> de::Deserializer<'de> for &mut Deserializer { + type Error = Error; + + #[inline] + fn deserialize_any(self, visitor: V) -> Result + where + V: de::Visitor<'de>, + { + let peek = match tri!(self.parse_whitespace()) { + Some(b) => b, + None => { + return Err(self.peek_error(ErrorCode::EofWhileParsingValue)); + } + }; + + let value = match peek { + b'n' => { + self.eat_char(); + tri!(self.parse_ident(b"ull")); + visitor.visit_unit() + } + b't' => { + self.eat_char(); + tri!(self.parse_ident(b"rue")); + visitor.visit_bool(true) + } + b'f' => { + self.eat_char(); + tri!(self.parse_ident(b"alse")); + visitor.visit_bool(false) + } + b'-' => { + self.eat_char(); + tri!(self.parse_any_number(false)).visit(visitor) + } + b'0'..=b'9' => tri!(self.parse_any_number(true)).visit(visitor), + b'"' => { + self.eat_char(); + self.scratch.clear(); + match tri!(self.read.parse_str(&mut self.scratch)) { + Reference::Borrowed(s) => visitor.visit_borrowed_str(s), + Reference::Copied(s) => visitor.visit_str(s), + } + } + b'[' => { + check_recursion! { + self.eat_char(); + let ret = visitor.visit_seq(SeqAccess::new(self)); + } + + match (ret, self.end_seq()) { + (Ok(ret), Ok(())) => Ok(ret), + (Err(err), _) | (_, Err(err)) => Err(err), + } + } + b'{' => { + check_recursion! { + self.eat_char(); + let ret = visitor.visit_map(MapAccess::new(self)); + } + + match (ret, self.end_map()) { + (Ok(ret), Ok(())) => Ok(ret), + (Err(err), _) | (_, Err(err)) => Err(err), + } + } + _ => Err(self.peek_error(ErrorCode::ExpectedSomeValue)), + }; + + match value { + Ok(value) => Ok(value), + // The de::Error impl creates errors with unknown line and column. + // Fill in the position here by looking at the current index in the + // input. There is no way to tell whether this should call `error` + // or `peek_error` so pick the one that seems correct more often. + // Worst case, the position is off by one character. + Err(err) => Err(self.fix_position(err)), + } + } + + fn deserialize_bool(self, visitor: V) -> Result + where + V: de::Visitor<'de>, + { + let peek = match tri!(self.parse_whitespace()) { + Some(b) => b, + None => { + return Err(self.peek_error(ErrorCode::EofWhileParsingValue)); + } + }; + + let value = match peek { + b't' => { + self.eat_char(); + tri!(self.parse_ident(b"rue")); + visitor.visit_bool(true) + } + b'f' => { + self.eat_char(); + tri!(self.parse_ident(b"alse")); + visitor.visit_bool(false) + } + _ => Err(self.peek_invalid_type(&visitor)), + }; + + match value { + Ok(value) => Ok(value), + Err(err) => Err(self.fix_position(err)), + } + } + + deserialize_number!(deserialize_i8); + deserialize_number!(deserialize_i16); + deserialize_number!(deserialize_i32); + deserialize_number!(deserialize_i64); + deserialize_number!(deserialize_u8); + deserialize_number!(deserialize_u16); + deserialize_number!(deserialize_u32); + deserialize_number!(deserialize_u64); + #[cfg(not(feature = "float_roundtrip"))] + deserialize_number!(deserialize_f32); + deserialize_number!(deserialize_f64); + + #[cfg(feature = "float_roundtrip")] + deserialize_number!(deserialize_f32, do_deserialize_f32); + deserialize_number!(deserialize_i128, do_deserialize_i128); + deserialize_number!(deserialize_u128, do_deserialize_u128); + + fn deserialize_char(self, visitor: V) -> Result + where + V: de::Visitor<'de>, + { + self.deserialize_str(visitor) + } + + fn deserialize_str(self, visitor: V) -> Result + where + V: de::Visitor<'de>, + { + let peek = match tri!(self.parse_whitespace()) { + Some(b) => b, + None => { + return Err(self.peek_error(ErrorCode::EofWhileParsingValue)); + } + }; + + let value = match peek { + b'"' => { + self.eat_char(); + self.scratch.clear(); + match tri!(self.read.parse_str(&mut self.scratch)) { + Reference::Borrowed(s) => visitor.visit_borrowed_str(s), + Reference::Copied(s) => visitor.visit_str(s), + } + } + _ => Err(self.peek_invalid_type(&visitor)), + }; + + match value { + Ok(value) => Ok(value), + Err(err) => Err(self.fix_position(err)), + } + } + + fn deserialize_string(self, visitor: V) -> Result + where + V: de::Visitor<'de>, + { + self.deserialize_str(visitor) + } + + /// Parses a JSON string as bytes. Note that this function does not check + /// whether the bytes represent a valid UTF-8 string. + /// + /// The relevant part of the JSON specification is Section 8.2 of [RFC + /// 7159]: + /// + /// > When all the strings represented in a JSON text are composed entirely + /// > of Unicode characters (however escaped), then that JSON text is + /// > interoperable in the sense that all software implementations that + /// > parse it will agree on the contents of names and of string values in + /// > objects and arrays. + /// > + /// > However, the ABNF in this specification allows member names and string + /// > values to contain bit sequences that cannot encode Unicode characters; + /// > for example, "\uDEAD" (a single unpaired UTF-16 surrogate). Instances + /// > of this have been observed, for example, when a library truncates a + /// > UTF-16 string without checking whether the truncation split a + /// > surrogate pair. The behavior of software that receives JSON texts + /// > containing such values is unpredictable; for example, implementations + /// > might return different values for the length of a string value or even + /// > suffer fatal runtime exceptions. + /// + /// [RFC 7159]: https://tools.ietf.org/html/rfc7159 + /// + /// The behavior of serde_json is specified to fail on non-UTF-8 strings + /// when deserializing into Rust UTF-8 string types such as String, and + /// succeed with the bytes representing the [WTF-8] encoding of code points + /// when deserializing using this method. + /// + /// [WTF-8]: https://simonsapin.github.io/wtf-8 + /// + /// Escape sequences are processed as usual, and for `\uXXXX` escapes it is + /// still checked if the hex number represents a valid Unicode code point. + /// + /// # Examples + /// + /// You can use this to parse JSON strings containing invalid UTF-8 bytes, + /// or unpaired surrogates. + /// + /// ``` + /// use serde_bytes::ByteBuf; + /// + /// fn look_at_bytes() -> Result<(), serde_json::Error> { + /// let json_data = b"\"some bytes: \xe5\x00\xe5\""; + /// let bytes: ByteBuf = serde_json::from_slice(json_data)?; + /// + /// assert_eq!(b'\xe5', bytes[12]); + /// assert_eq!(b'\0', bytes[13]); + /// assert_eq!(b'\xe5', bytes[14]); + /// + /// Ok(()) + /// } + /// # + /// # look_at_bytes().unwrap(); + /// ``` + /// + /// Backslash escape sequences like `\n` are still interpreted and required + /// to be valid. `\u` escape sequences are required to represent a valid + /// Unicode code point or lone surrogate. + /// + /// ``` + /// use serde_bytes::ByteBuf; + /// + /// fn look_at_bytes() -> Result<(), serde_json::Error> { + /// let json_data = b"\"lone surrogate: \\uD801\""; + /// let bytes: ByteBuf = serde_json::from_slice(json_data)?; + /// let expected = b"lone surrogate: \xED\xA0\x81"; + /// assert_eq!(expected, bytes.as_slice()); + /// Ok(()) + /// } + /// # + /// # look_at_bytes(); + /// ``` + fn deserialize_bytes(self, visitor: V) -> Result + where + V: de::Visitor<'de>, + { + let peek = match tri!(self.parse_whitespace()) { + Some(b) => b, + None => { + return Err(self.peek_error(ErrorCode::EofWhileParsingValue)); + } + }; + + let value = match peek { + b'"' => { + self.eat_char(); + self.scratch.clear(); + match tri!(self.read.parse_str_raw(&mut self.scratch)) { + Reference::Borrowed(b) => visitor.visit_borrowed_bytes(b), + Reference::Copied(b) => visitor.visit_bytes(b), + } + } + b'[' => self.deserialize_seq(visitor), + _ => Err(self.peek_invalid_type(&visitor)), + }; + + match value { + Ok(value) => Ok(value), + Err(err) => Err(self.fix_position(err)), + } + } + + #[inline] + fn deserialize_byte_buf(self, visitor: V) -> Result + where + V: de::Visitor<'de>, + { + self.deserialize_bytes(visitor) + } + + /// Parses a `null` as a None, and any other values as a `Some(...)`. + #[inline] + fn deserialize_option(self, visitor: V) -> Result + where + V: de::Visitor<'de>, + { + match tri!(self.parse_whitespace()) { + Some(b'n') => { + self.eat_char(); + tri!(self.parse_ident(b"ull")); + visitor.visit_none() + } + _ => visitor.visit_some(self), + } + } + + fn deserialize_unit(self, visitor: V) -> Result + where + V: de::Visitor<'de>, + { + let peek = match tri!(self.parse_whitespace()) { + Some(b) => b, + None => { + return Err(self.peek_error(ErrorCode::EofWhileParsingValue)); + } + }; + + let value = match peek { + b'n' => { + self.eat_char(); + tri!(self.parse_ident(b"ull")); + visitor.visit_unit() + } + _ => Err(self.peek_invalid_type(&visitor)), + }; + + match value { + Ok(value) => Ok(value), + Err(err) => Err(self.fix_position(err)), + } + } + + fn deserialize_unit_struct(self, _name: &'static str, visitor: V) -> Result + where + V: de::Visitor<'de>, + { + self.deserialize_unit(visitor) + } + + /// Parses a newtype struct as the underlying value. + #[inline] + fn deserialize_newtype_struct(self, name: &str, visitor: V) -> Result + where + V: de::Visitor<'de>, + { + #[cfg(feature = "raw_value")] + { + if name == crate::raw::TOKEN { + return self.deserialize_raw_value(visitor); + } + } + + let _ = name; + visitor.visit_newtype_struct(self) + } + + fn deserialize_seq(self, visitor: V) -> Result + where + V: de::Visitor<'de>, + { + let peek = match tri!(self.parse_whitespace()) { + Some(b) => b, + None => { + return Err(self.peek_error(ErrorCode::EofWhileParsingValue)); + } + }; + + let value = match peek { + b'[' => { + check_recursion! { + self.eat_char(); + let ret = visitor.visit_seq(SeqAccess::new(self)); + } + + match (ret, self.end_seq()) { + (Ok(ret), Ok(())) => Ok(ret), + (Err(err), _) | (_, Err(err)) => Err(err), + } + } + _ => Err(self.peek_invalid_type(&visitor)), + }; + + match value { + Ok(value) => Ok(value), + Err(err) => Err(self.fix_position(err)), + } + } + + fn deserialize_tuple(self, _len: usize, visitor: V) -> Result + where + V: de::Visitor<'de>, + { + self.deserialize_seq(visitor) + } + + fn deserialize_tuple_struct( + self, + _name: &'static str, + _len: usize, + visitor: V, + ) -> Result + where + V: de::Visitor<'de>, + { + self.deserialize_seq(visitor) + } + + fn deserialize_map(self, visitor: V) -> Result + where + V: de::Visitor<'de>, + { + let peek = match tri!(self.parse_whitespace()) { + Some(b) => b, + None => { + return Err(self.peek_error(ErrorCode::EofWhileParsingValue)); + } + }; + + let value = match peek { + b'{' => { + check_recursion! { + self.eat_char(); + let ret = visitor.visit_map(MapAccess::new(self)); + } + + match (ret, self.end_map()) { + (Ok(ret), Ok(())) => Ok(ret), + (Err(err), _) | (_, Err(err)) => Err(err), + } + } + _ => Err(self.peek_invalid_type(&visitor)), + }; + + match value { + Ok(value) => Ok(value), + Err(err) => Err(self.fix_position(err)), + } + } + + fn deserialize_struct( + self, + _name: &'static str, + _fields: &'static [&'static str], + visitor: V, + ) -> Result + where + V: de::Visitor<'de>, + { + let peek = match tri!(self.parse_whitespace()) { + Some(b) => b, + None => { + return Err(self.peek_error(ErrorCode::EofWhileParsingValue)); + } + }; + + let value = match peek { + b'[' => { + check_recursion! { + self.eat_char(); + let ret = visitor.visit_seq(SeqAccess::new(self)); + } + + match (ret, self.end_seq()) { + (Ok(ret), Ok(())) => Ok(ret), + (Err(err), _) | (_, Err(err)) => Err(err), + } + } + b'{' => { + check_recursion! { + self.eat_char(); + let ret = visitor.visit_map(MapAccess::new(self)); + } + + match (ret, self.end_map()) { + (Ok(ret), Ok(())) => Ok(ret), + (Err(err), _) | (_, Err(err)) => Err(err), + } + } + _ => Err(self.peek_invalid_type(&visitor)), + }; + + match value { + Ok(value) => Ok(value), + Err(err) => Err(self.fix_position(err)), + } + } + + /// Parses an enum as an object like `{"$KEY":$VALUE}`, where $VALUE is either a straight + /// value, a `[..]`, or a `{..}`. + #[inline] + fn deserialize_enum( + self, + _name: &str, + _variants: &'static [&'static str], + visitor: V, + ) -> Result + where + V: de::Visitor<'de>, + { + match tri!(self.parse_whitespace()) { + Some(b'{') => { + check_recursion! { + self.eat_char(); + let ret = visitor.visit_enum(VariantAccess::new(self)); + } + let value = tri!(ret); + + match tri!(self.parse_whitespace()) { + Some(b'}') => { + self.eat_char(); + Ok(value) + } + Some(_) => Err(self.error(ErrorCode::ExpectedSomeValue)), + None => Err(self.error(ErrorCode::EofWhileParsingObject)), + } + } + Some(b'"') => visitor.visit_enum(UnitVariantAccess::new(self)), + Some(_) => Err(self.peek_error(ErrorCode::ExpectedSomeValue)), + None => Err(self.peek_error(ErrorCode::EofWhileParsingValue)), + } + } + + fn deserialize_identifier(self, visitor: V) -> Result + where + V: de::Visitor<'de>, + { + self.deserialize_str(visitor) + } + + fn deserialize_ignored_any(self, visitor: V) -> Result + where + V: de::Visitor<'de>, + { + tri!(self.ignore_value()); + visitor.visit_unit() + } +} + +struct SeqAccess<'a, R: 'a> { + de: &'a mut Deserializer, + first: bool, +} + +impl<'a, R: 'a> SeqAccess<'a, R> { + fn new(de: &'a mut Deserializer) -> Self { + SeqAccess { de, first: true } + } +} + +impl<'de, 'a, R: Read<'de> + 'a> de::SeqAccess<'de> for SeqAccess<'a, R> { + type Error = Error; + + fn next_element_seed(&mut self, seed: T) -> Result> + where + T: de::DeserializeSeed<'de>, + { + let peek = match tri!(self.de.parse_whitespace()) { + Some(b']') => { + return Ok(None); + } + Some(b',') if !self.first => { + self.de.eat_char(); + tri!(self.de.parse_whitespace()) + } + Some(b) => { + if self.first { + self.first = false; + Some(b) + } else { + return Err(self.de.peek_error(ErrorCode::ExpectedListCommaOrEnd)); + } + } + None => { + return Err(self.de.peek_error(ErrorCode::EofWhileParsingList)); + } + }; + + match peek { + Some(b']') => Err(self.de.peek_error(ErrorCode::TrailingComma)), + Some(_) => Ok(Some(tri!(seed.deserialize(&mut *self.de)))), + None => Err(self.de.peek_error(ErrorCode::EofWhileParsingValue)), + } + } +} + +struct MapAccess<'a, R: 'a> { + de: &'a mut Deserializer, + first: bool, +} + +impl<'a, R: 'a> MapAccess<'a, R> { + fn new(de: &'a mut Deserializer) -> Self { + MapAccess { de, first: true } + } +} + +impl<'de, 'a, R: Read<'de> + 'a> de::MapAccess<'de> for MapAccess<'a, R> { + type Error = Error; + + fn next_key_seed(&mut self, seed: K) -> Result> + where + K: de::DeserializeSeed<'de>, + { + let peek = match tri!(self.de.parse_whitespace()) { + Some(b'}') => { + return Ok(None); + } + Some(b',') if !self.first => { + self.de.eat_char(); + tri!(self.de.parse_whitespace()) + } + Some(b) => { + if self.first { + self.first = false; + Some(b) + } else { + return Err(self.de.peek_error(ErrorCode::ExpectedObjectCommaOrEnd)); + } + } + None => { + return Err(self.de.peek_error(ErrorCode::EofWhileParsingObject)); + } + }; + + match peek { + Some(b'"') => seed.deserialize(MapKey { de: &mut *self.de }).map(Some), + Some(b'}') => Err(self.de.peek_error(ErrorCode::TrailingComma)), + Some(_) => Err(self.de.peek_error(ErrorCode::KeyMustBeAString)), + None => Err(self.de.peek_error(ErrorCode::EofWhileParsingValue)), + } + } + + fn next_value_seed(&mut self, seed: V) -> Result + where + V: de::DeserializeSeed<'de>, + { + tri!(self.de.parse_object_colon()); + + seed.deserialize(&mut *self.de) + } +} + +struct VariantAccess<'a, R: 'a> { + de: &'a mut Deserializer, +} + +impl<'a, R: 'a> VariantAccess<'a, R> { + fn new(de: &'a mut Deserializer) -> Self { + VariantAccess { de } + } +} + +impl<'de, 'a, R: Read<'de> + 'a> de::EnumAccess<'de> for VariantAccess<'a, R> { + type Error = Error; + type Variant = Self; + + fn variant_seed(self, seed: V) -> Result<(V::Value, Self)> + where + V: de::DeserializeSeed<'de>, + { + let val = tri!(seed.deserialize(&mut *self.de)); + tri!(self.de.parse_object_colon()); + Ok((val, self)) + } +} + +impl<'de, 'a, R: Read<'de> + 'a> de::VariantAccess<'de> for VariantAccess<'a, R> { + type Error = Error; + + fn unit_variant(self) -> Result<()> { + de::Deserialize::deserialize(self.de) + } + + fn newtype_variant_seed(self, seed: T) -> Result + where + T: de::DeserializeSeed<'de>, + { + seed.deserialize(self.de) + } + + fn tuple_variant(self, _len: usize, visitor: V) -> Result + where + V: de::Visitor<'de>, + { + de::Deserializer::deserialize_seq(self.de, visitor) + } + + fn struct_variant(self, fields: &'static [&'static str], visitor: V) -> Result + where + V: de::Visitor<'de>, + { + de::Deserializer::deserialize_struct(self.de, "", fields, visitor) + } +} + +struct UnitVariantAccess<'a, R: 'a> { + de: &'a mut Deserializer, +} + +impl<'a, R: 'a> UnitVariantAccess<'a, R> { + fn new(de: &'a mut Deserializer) -> Self { + UnitVariantAccess { de } + } +} + +impl<'de, 'a, R: Read<'de> + 'a> de::EnumAccess<'de> for UnitVariantAccess<'a, R> { + type Error = Error; + type Variant = Self; + + fn variant_seed(self, seed: V) -> Result<(V::Value, Self)> + where + V: de::DeserializeSeed<'de>, + { + let variant = tri!(seed.deserialize(&mut *self.de)); + Ok((variant, self)) + } +} + +impl<'de, 'a, R: Read<'de> + 'a> de::VariantAccess<'de> for UnitVariantAccess<'a, R> { + type Error = Error; + + fn unit_variant(self) -> Result<()> { + Ok(()) + } + + fn newtype_variant_seed(self, _seed: T) -> Result + where + T: de::DeserializeSeed<'de>, + { + Err(de::Error::invalid_type( + Unexpected::UnitVariant, + &"newtype variant", + )) + } + + fn tuple_variant(self, _len: usize, _visitor: V) -> Result + where + V: de::Visitor<'de>, + { + Err(de::Error::invalid_type( + Unexpected::UnitVariant, + &"tuple variant", + )) + } + + fn struct_variant(self, _fields: &'static [&'static str], _visitor: V) -> Result + where + V: de::Visitor<'de>, + { + Err(de::Error::invalid_type( + Unexpected::UnitVariant, + &"struct variant", + )) + } +} + +/// Only deserialize from this after peeking a '"' byte! Otherwise it may +/// deserialize invalid JSON successfully. +struct MapKey<'a, R: 'a> { + de: &'a mut Deserializer, +} + +macro_rules! deserialize_numeric_key { + ($method:ident) => { + fn $method(self, visitor: V) -> Result + where + V: de::Visitor<'de>, + { + self.deserialize_number(visitor) + } + }; + + ($method:ident, $delegate:ident) => { + fn $method(self, visitor: V) -> Result + where + V: de::Visitor<'de>, + { + self.de.eat_char(); + + match tri!(self.de.peek()) { + Some(b'0'..=b'9' | b'-') => {} + _ => return Err(self.de.error(ErrorCode::ExpectedNumericKey)), + } + + let value = tri!(self.de.$delegate(visitor)); + + match tri!(self.de.peek()) { + Some(b'"') => self.de.eat_char(), + _ => return Err(self.de.peek_error(ErrorCode::ExpectedDoubleQuote)), + } + + Ok(value) + } + }; +} + +impl<'de, 'a, R> MapKey<'a, R> +where + R: Read<'de>, +{ + deserialize_numeric_key!(deserialize_number, deserialize_number); +} + +impl<'de, 'a, R> de::Deserializer<'de> for MapKey<'a, R> +where + R: Read<'de>, +{ + type Error = Error; + + #[inline] + fn deserialize_any(self, visitor: V) -> Result + where + V: de::Visitor<'de>, + { + self.de.eat_char(); + self.de.scratch.clear(); + match tri!(self.de.read.parse_str(&mut self.de.scratch)) { + Reference::Borrowed(s) => visitor.visit_borrowed_str(s), + Reference::Copied(s) => visitor.visit_str(s), + } + } + + deserialize_numeric_key!(deserialize_i8); + deserialize_numeric_key!(deserialize_i16); + deserialize_numeric_key!(deserialize_i32); + deserialize_numeric_key!(deserialize_i64); + deserialize_numeric_key!(deserialize_i128, deserialize_i128); + deserialize_numeric_key!(deserialize_u8); + deserialize_numeric_key!(deserialize_u16); + deserialize_numeric_key!(deserialize_u32); + deserialize_numeric_key!(deserialize_u64); + deserialize_numeric_key!(deserialize_u128, deserialize_u128); + #[cfg(not(feature = "float_roundtrip"))] + deserialize_numeric_key!(deserialize_f32); + #[cfg(feature = "float_roundtrip")] + deserialize_numeric_key!(deserialize_f32, deserialize_f32); + deserialize_numeric_key!(deserialize_f64); + + fn deserialize_bool(self, visitor: V) -> Result + where + V: de::Visitor<'de>, + { + self.de.eat_char(); + + let peek = match tri!(self.de.next_char()) { + Some(b) => b, + None => { + return Err(self.de.peek_error(ErrorCode::EofWhileParsingValue)); + } + }; + + let value = match peek { + b't' => { + tri!(self.de.parse_ident(b"rue\"")); + visitor.visit_bool(true) + } + b'f' => { + tri!(self.de.parse_ident(b"alse\"")); + visitor.visit_bool(false) + } + _ => { + self.de.scratch.clear(); + let s = tri!(self.de.read.parse_str(&mut self.de.scratch)); + Err(de::Error::invalid_type(Unexpected::Str(&s), &visitor)) + } + }; + + match value { + Ok(value) => Ok(value), + Err(err) => Err(self.de.fix_position(err)), + } + } + + #[inline] + fn deserialize_option(self, visitor: V) -> Result + where + V: de::Visitor<'de>, + { + // Map keys cannot be null. + visitor.visit_some(self) + } + + #[inline] + fn deserialize_newtype_struct(self, name: &'static str, visitor: V) -> Result + where + V: de::Visitor<'de>, + { + #[cfg(feature = "raw_value")] + { + if name == crate::raw::TOKEN { + return self.de.deserialize_raw_value(visitor); + } + } + + let _ = name; + visitor.visit_newtype_struct(self) + } + + #[inline] + fn deserialize_enum( + self, + name: &'static str, + variants: &'static [&'static str], + visitor: V, + ) -> Result + where + V: de::Visitor<'de>, + { + self.de.deserialize_enum(name, variants, visitor) + } + + #[inline] + fn deserialize_bytes(self, visitor: V) -> Result + where + V: de::Visitor<'de>, + { + self.de.deserialize_bytes(visitor) + } + + #[inline] + fn deserialize_byte_buf(self, visitor: V) -> Result + where + V: de::Visitor<'de>, + { + self.de.deserialize_bytes(visitor) + } + + forward_to_deserialize_any! { + char str string unit unit_struct seq tuple tuple_struct map struct + identifier ignored_any + } +} + +////////////////////////////////////////////////////////////////////////////// + +/// Iterator that deserializes a stream into multiple JSON values. +/// +/// A stream deserializer can be created from any JSON deserializer using the +/// `Deserializer::into_iter` method. +/// +/// The data can consist of any JSON value. Values need to be a self-delineating value e.g. +/// arrays, objects, or strings, or be followed by whitespace or a self-delineating value. +/// +/// ``` +/// use serde_json::{Deserializer, Value}; +/// +/// fn main() { +/// let data = "{\"k\": 3}1\"cool\"\"stuff\" 3{} [0, 1, 2]"; +/// +/// let stream = Deserializer::from_str(data).into_iter::(); +/// +/// for value in stream { +/// println!("{}", value.unwrap()); +/// } +/// } +/// ``` +pub struct StreamDeserializer<'de, R, T> { + de: Deserializer, + offset: usize, + failed: bool, + output: PhantomData, + lifetime: PhantomData<&'de ()>, +} + +impl<'de, R, T> StreamDeserializer<'de, R, T> +where + R: read::Read<'de>, + T: de::Deserialize<'de>, +{ + /// Create a JSON stream deserializer from one of the possible serde_json + /// input sources. + /// + /// Typically it is more convenient to use one of these methods instead: + /// + /// - Deserializer::from_str(...).into_iter() + /// - Deserializer::from_slice(...).into_iter() + /// - Deserializer::from_reader(...).into_iter() + pub fn new(read: R) -> Self { + let offset = read.byte_offset(); + StreamDeserializer { + de: Deserializer::new(read), + offset, + failed: false, + output: PhantomData, + lifetime: PhantomData, + } + } + + /// Returns the number of bytes so far deserialized into a successful `T`. + /// + /// If a stream deserializer returns an EOF error, new data can be joined to + /// `old_data[stream.byte_offset()..]` to try again. + /// + /// ``` + /// let data = b"[0] [1] ["; + /// + /// let de = serde_json::Deserializer::from_slice(data); + /// let mut stream = de.into_iter::>(); + /// assert_eq!(0, stream.byte_offset()); + /// + /// println!("{:?}", stream.next()); // [0] + /// assert_eq!(3, stream.byte_offset()); + /// + /// println!("{:?}", stream.next()); // [1] + /// assert_eq!(7, stream.byte_offset()); + /// + /// println!("{:?}", stream.next()); // error + /// assert_eq!(8, stream.byte_offset()); + /// + /// // If err.is_eof(), can join the remaining data to new data and continue. + /// let remaining = &data[stream.byte_offset()..]; + /// ``` + /// + /// *Note:* In the future this method may be changed to return the number of + /// bytes so far deserialized into a successful T *or* syntactically valid + /// JSON skipped over due to a type error. See [serde-rs/json#70] for an + /// example illustrating this. + /// + /// [serde-rs/json#70]: https://github.com/serde-rs/json/issues/70 + pub fn byte_offset(&self) -> usize { + self.offset + } + + fn peek_end_of_value(&mut self) -> Result<()> { + match tri!(self.de.peek()) { + Some(b' ' | b'\n' | b'\t' | b'\r' | b'"' | b'[' | b']' | b'{' | b'}' | b',' | b':') + | None => Ok(()), + Some(_) => { + let position = self.de.read.peek_position(); + Err(Error::syntax( + ErrorCode::TrailingCharacters, + position.line, + position.column, + )) + } + } + } +} + +impl<'de, R, T> Iterator for StreamDeserializer<'de, R, T> +where + R: Read<'de>, + T: de::Deserialize<'de>, +{ + type Item = Result; + + fn next(&mut self) -> Option> { + if R::should_early_return_if_failed && self.failed { + return None; + } + + // skip whitespaces, if any + // this helps with trailing whitespaces, since whitespaces between + // values are handled for us. + match self.de.parse_whitespace() { + Ok(None) => { + self.offset = self.de.read.byte_offset(); + None + } + Ok(Some(b)) => { + // If the value does not have a clear way to show the end of the value + // (like numbers, null, true etc.) we have to look for whitespace or + // the beginning of a self-delineated value. + let self_delineated_value = match b { + b'[' | b'"' | b'{' => true, + _ => false, + }; + self.offset = self.de.read.byte_offset(); + let result = de::Deserialize::deserialize(&mut self.de); + + Some(match result { + Ok(value) => { + self.offset = self.de.read.byte_offset(); + if self_delineated_value { + Ok(value) + } else { + self.peek_end_of_value().map(|()| value) + } + } + Err(e) => { + self.de.read.set_failed(&mut self.failed); + Err(e) + } + }) + } + Err(e) => { + self.de.read.set_failed(&mut self.failed); + Some(Err(e)) + } + } + } +} + +impl<'de, R, T> FusedIterator for StreamDeserializer<'de, R, T> +where + R: Read<'de> + Fused, + T: de::Deserialize<'de>, +{ +} + +////////////////////////////////////////////////////////////////////////////// + +fn from_trait<'de, R, T>(read: R) -> Result +where + R: Read<'de>, + T: de::Deserialize<'de>, +{ + let mut de = Deserializer::new(read); + let value = tri!(de::Deserialize::deserialize(&mut de)); + + // Make sure the whole stream has been consumed. + tri!(de.end()); + Ok(value) +} + +/// Deserialize an instance of type `T` from an I/O stream of JSON. +/// +/// The content of the I/O stream is deserialized directly from the stream +/// without being buffered in memory by serde_json. +/// +/// When reading from a source against which short reads are not efficient, such +/// as a [`File`], you will want to apply your own buffering because serde_json +/// will not buffer the input. See [`std::io::BufReader`]. +/// +/// It is expected that the input stream ends after the deserialized object. +/// If the stream does not end, such as in the case of a persistent socket connection, +/// this function will not return. It is possible instead to deserialize from a prefix of an input +/// stream without looking for EOF by managing your own [`Deserializer`]. +/// +/// Note that counter to intuition, this function is usually slower than +/// reading a file completely into memory and then applying [`from_str`] +/// or [`from_slice`] on it. See [issue #160]. +/// +/// [`File`]: https://doc.rust-lang.org/std/fs/struct.File.html +/// [`std::io::BufReader`]: https://doc.rust-lang.org/std/io/struct.BufReader.html +/// [`from_str`]: ./fn.from_str.html +/// [`from_slice`]: ./fn.from_slice.html +/// [issue #160]: https://github.com/serde-rs/json/issues/160 +/// +/// # Example +/// +/// Reading the contents of a file. +/// +/// ``` +/// use serde::Deserialize; +/// +/// use std::error::Error; +/// use std::fs::File; +/// use std::io::BufReader; +/// use std::path::Path; +/// +/// #[derive(Deserialize, Debug)] +/// struct User { +/// fingerprint: String, +/// location: String, +/// } +/// +/// fn read_user_from_file>(path: P) -> Result> { +/// // Open the file in read-only mode with buffer. +/// let file = File::open(path)?; +/// let reader = BufReader::new(file); +/// +/// // Read the JSON contents of the file as an instance of `User`. +/// let u = serde_json::from_reader(reader)?; +/// +/// // Return the `User`. +/// Ok(u) +/// } +/// +/// fn main() { +/// # } +/// # fn fake_main() { +/// let u = read_user_from_file("test.json").unwrap(); +/// println!("{:#?}", u); +/// } +/// ``` +/// +/// Reading from a persistent socket connection. +/// +/// ``` +/// use serde::Deserialize; +/// +/// use std::error::Error; +/// use std::net::{TcpListener, TcpStream}; +/// +/// #[derive(Deserialize, Debug)] +/// struct User { +/// fingerprint: String, +/// location: String, +/// } +/// +/// fn read_user_from_stream(tcp_stream: TcpStream) -> Result> { +/// let mut de = serde_json::Deserializer::from_reader(tcp_stream); +/// let u = User::deserialize(&mut de)?; +/// +/// Ok(u) +/// } +/// +/// fn main() { +/// # } +/// # fn fake_main() { +/// let listener = TcpListener::bind("127.0.0.1:4000").unwrap(); +/// +/// for stream in listener.incoming() { +/// println!("{:#?}", read_user_from_stream(stream.unwrap())); +/// } +/// } +/// ``` +/// +/// # Errors +/// +/// This conversion can fail if the structure of the input does not match the +/// structure expected by `T`, for example if `T` is a struct type but the input +/// contains something other than a JSON map. It can also fail if the structure +/// is correct but `T`'s implementation of `Deserialize` decides that something +/// is wrong with the data, for example required struct fields are missing from +/// the JSON map or some number is too big to fit in the expected primitive +/// type. +#[cfg(feature = "std")] +#[cfg_attr(docsrs, doc(cfg(feature = "std")))] +pub fn from_reader(rdr: R) -> Result +where + R: crate::io::Read, + T: de::DeserializeOwned, +{ + from_trait(read::IoRead::new(rdr)) +} + +/// Deserialize an instance of type `T` from bytes of JSON text. +/// +/// # Example +/// +/// ``` +/// use serde::Deserialize; +/// +/// #[derive(Deserialize, Debug)] +/// struct User { +/// fingerprint: String, +/// location: String, +/// } +/// +/// fn main() { +/// // The type of `j` is `&[u8]` +/// let j = b" +/// { +/// \"fingerprint\": \"0xF9BA143B95FF6D82\", +/// \"location\": \"Menlo Park, CA\" +/// }"; +/// +/// let u: User = serde_json::from_slice(j).unwrap(); +/// println!("{:#?}", u); +/// } +/// ``` +/// +/// # Errors +/// +/// This conversion can fail if the structure of the input does not match the +/// structure expected by `T`, for example if `T` is a struct type but the input +/// contains something other than a JSON map. It can also fail if the structure +/// is correct but `T`'s implementation of `Deserialize` decides that something +/// is wrong with the data, for example required struct fields are missing from +/// the JSON map or some number is too big to fit in the expected primitive +/// type. +pub fn from_slice<'a, T>(v: &'a [u8]) -> Result +where + T: de::Deserialize<'a>, +{ + from_trait(read::SliceRead::new(v)) +} + +/// Deserialize an instance of type `T` from a string of JSON text. +/// +/// # Example +/// +/// ``` +/// use serde::Deserialize; +/// +/// #[derive(Deserialize, Debug)] +/// struct User { +/// fingerprint: String, +/// location: String, +/// } +/// +/// fn main() { +/// // The type of `j` is `&str` +/// let j = " +/// { +/// \"fingerprint\": \"0xF9BA143B95FF6D82\", +/// \"location\": \"Menlo Park, CA\" +/// }"; +/// +/// let u: User = serde_json::from_str(j).unwrap(); +/// println!("{:#?}", u); +/// } +/// ``` +/// +/// # Errors +/// +/// This conversion can fail if the structure of the input does not match the +/// structure expected by `T`, for example if `T` is a struct type but the input +/// contains something other than a JSON map. It can also fail if the structure +/// is correct but `T`'s implementation of `Deserialize` decides that something +/// is wrong with the data, for example required struct fields are missing from +/// the JSON map or some number is too big to fit in the expected primitive +/// type. +pub fn from_str<'a, T>(s: &'a str) -> Result +where + T: de::Deserialize<'a>, +{ + from_trait(read::StrRead::new(s)) +} diff --git a/vendor/serde_json/src/error.rs b/vendor/serde_json/src/error.rs new file mode 100644 index 0000000..fbf9eb1 --- /dev/null +++ b/vendor/serde_json/src/error.rs @@ -0,0 +1,541 @@ +//! When serializing or deserializing JSON goes wrong. + +use crate::io; +use alloc::boxed::Box; +use alloc::string::{String, ToString}; +use core::fmt::{self, Debug, Display}; +use core::result; +use core::str::FromStr; +use serde::{de, ser}; +#[cfg(feature = "std")] +use std::error; +#[cfg(feature = "std")] +use std::io::ErrorKind; + +/// This type represents all possible errors that can occur when serializing or +/// deserializing JSON data. +pub struct Error { + /// This `Box` allows us to keep the size of `Error` as small as possible. A + /// larger `Error` type was substantially slower due to all the functions + /// that pass around `Result`. + err: Box, +} + +/// Alias for a `Result` with the error type `serde_json::Error`. +pub type Result = result::Result; + +impl Error { + /// One-based line number at which the error was detected. + /// + /// Characters in the first line of the input (before the first newline + /// character) are in line 1. + pub fn line(&self) -> usize { + self.err.line + } + + /// One-based column number at which the error was detected. + /// + /// The first character in the input and any characters immediately + /// following a newline character are in column 1. + /// + /// Note that errors may occur in column 0, for example if a read from an + /// I/O stream fails immediately following a previously read newline + /// character. + pub fn column(&self) -> usize { + self.err.column + } + + /// Categorizes the cause of this error. + /// + /// - `Category::Io` - failure to read or write bytes on an I/O stream + /// - `Category::Syntax` - input that is not syntactically valid JSON + /// - `Category::Data` - input data that is semantically incorrect + /// - `Category::Eof` - unexpected end of the input data + pub fn classify(&self) -> Category { + match self.err.code { + ErrorCode::Message(_) => Category::Data, + ErrorCode::Io(_) => Category::Io, + ErrorCode::EofWhileParsingList + | ErrorCode::EofWhileParsingObject + | ErrorCode::EofWhileParsingString + | ErrorCode::EofWhileParsingValue => Category::Eof, + ErrorCode::ExpectedColon + | ErrorCode::ExpectedListCommaOrEnd + | ErrorCode::ExpectedObjectCommaOrEnd + | ErrorCode::ExpectedSomeIdent + | ErrorCode::ExpectedSomeValue + | ErrorCode::ExpectedDoubleQuote + | ErrorCode::InvalidEscape + | ErrorCode::InvalidNumber + | ErrorCode::NumberOutOfRange + | ErrorCode::InvalidUnicodeCodePoint + | ErrorCode::ControlCharacterWhileParsingString + | ErrorCode::KeyMustBeAString + | ErrorCode::ExpectedNumericKey + | ErrorCode::FloatKeyMustBeFinite + | ErrorCode::LoneLeadingSurrogateInHexEscape + | ErrorCode::TrailingComma + | ErrorCode::TrailingCharacters + | ErrorCode::UnexpectedEndOfHexEscape + | ErrorCode::RecursionLimitExceeded => Category::Syntax, + } + } + + /// Returns true if this error was caused by a failure to read or write + /// bytes on an I/O stream. + pub fn is_io(&self) -> bool { + self.classify() == Category::Io + } + + /// Returns true if this error was caused by input that was not + /// syntactically valid JSON. + pub fn is_syntax(&self) -> bool { + self.classify() == Category::Syntax + } + + /// Returns true if this error was caused by input data that was + /// semantically incorrect. + /// + /// For example, JSON containing a number is semantically incorrect when the + /// type being deserialized into holds a String. + pub fn is_data(&self) -> bool { + self.classify() == Category::Data + } + + /// Returns true if this error was caused by prematurely reaching the end of + /// the input data. + /// + /// Callers that process streaming input may be interested in retrying the + /// deserialization once more data is available. + pub fn is_eof(&self) -> bool { + self.classify() == Category::Eof + } + + /// The kind reported by the underlying standard library I/O error, if this + /// error was caused by a failure to read or write bytes on an I/O stream. + /// + /// # Example + /// + /// ``` + /// use serde_json::Value; + /// use std::io::{self, ErrorKind, Read}; + /// use std::process; + /// + /// struct ReaderThatWillTimeOut<'a>(&'a [u8]); + /// + /// impl<'a> Read for ReaderThatWillTimeOut<'a> { + /// fn read(&mut self, buf: &mut [u8]) -> io::Result { + /// if self.0.is_empty() { + /// Err(io::Error::new(ErrorKind::TimedOut, "timed out")) + /// } else { + /// self.0.read(buf) + /// } + /// } + /// } + /// + /// fn main() { + /// let reader = ReaderThatWillTimeOut(br#" {"k": "#); + /// + /// let _: Value = match serde_json::from_reader(reader) { + /// Ok(value) => value, + /// Err(error) => { + /// if error.io_error_kind() == Some(ErrorKind::TimedOut) { + /// // Maybe this application needs to retry certain kinds of errors. + /// + /// # return; + /// } else { + /// eprintln!("error: {}", error); + /// process::exit(1); + /// } + /// } + /// }; + /// } + /// ``` + #[cfg(feature = "std")] + pub fn io_error_kind(&self) -> Option { + if let ErrorCode::Io(io_error) = &self.err.code { + Some(io_error.kind()) + } else { + None + } + } +} + +/// Categorizes the cause of a `serde_json::Error`. +#[derive(Copy, Clone, PartialEq, Eq, Debug)] +pub enum Category { + /// The error was caused by a failure to read or write bytes on an I/O + /// stream. + Io, + + /// The error was caused by input that was not syntactically valid JSON. + Syntax, + + /// The error was caused by input data that was semantically incorrect. + /// + /// For example, JSON containing a number is semantically incorrect when the + /// type being deserialized into holds a String. + Data, + + /// The error was caused by prematurely reaching the end of the input data. + /// + /// Callers that process streaming input may be interested in retrying the + /// deserialization once more data is available. + Eof, +} + +#[cfg(feature = "std")] +#[allow(clippy::fallible_impl_from)] +impl From for io::Error { + /// Convert a `serde_json::Error` into an `io::Error`. + /// + /// JSON syntax and data errors are turned into `InvalidData` I/O errors. + /// EOF errors are turned into `UnexpectedEof` I/O errors. + /// + /// ``` + /// use std::io; + /// + /// enum MyError { + /// Io(io::Error), + /// Json(serde_json::Error), + /// } + /// + /// impl From for MyError { + /// fn from(err: serde_json::Error) -> MyError { + /// use serde_json::error::Category; + /// match err.classify() { + /// Category::Io => { + /// MyError::Io(err.into()) + /// } + /// Category::Syntax | Category::Data | Category::Eof => { + /// MyError::Json(err) + /// } + /// } + /// } + /// } + /// ``` + fn from(j: Error) -> Self { + if let ErrorCode::Io(err) = j.err.code { + err + } else { + match j.classify() { + Category::Io => unreachable!(), + Category::Syntax | Category::Data => io::Error::new(ErrorKind::InvalidData, j), + Category::Eof => io::Error::new(ErrorKind::UnexpectedEof, j), + } + } + } +} + +struct ErrorImpl { + code: ErrorCode, + line: usize, + column: usize, +} + +pub(crate) enum ErrorCode { + /// Catchall for syntax error messages + Message(Box), + + /// Some I/O error occurred while serializing or deserializing. + Io(io::Error), + + /// EOF while parsing a list. + EofWhileParsingList, + + /// EOF while parsing an object. + EofWhileParsingObject, + + /// EOF while parsing a string. + EofWhileParsingString, + + /// EOF while parsing a JSON value. + EofWhileParsingValue, + + /// Expected this character to be a `':'`. + ExpectedColon, + + /// Expected this character to be either a `','` or a `']'`. + ExpectedListCommaOrEnd, + + /// Expected this character to be either a `','` or a `'}'`. + ExpectedObjectCommaOrEnd, + + /// Expected to parse either a `true`, `false`, or a `null`. + ExpectedSomeIdent, + + /// Expected this character to start a JSON value. + ExpectedSomeValue, + + /// Expected this character to be a `"`. + ExpectedDoubleQuote, + + /// Invalid hex escape code. + InvalidEscape, + + /// Invalid number. + InvalidNumber, + + /// Number is bigger than the maximum value of its type. + NumberOutOfRange, + + /// Invalid unicode code point. + InvalidUnicodeCodePoint, + + /// Control character found while parsing a string. + ControlCharacterWhileParsingString, + + /// Object key is not a string. + KeyMustBeAString, + + /// Contents of key were supposed to be a number. + ExpectedNumericKey, + + /// Object key is a non-finite float value. + FloatKeyMustBeFinite, + + /// Lone leading surrogate in hex escape. + LoneLeadingSurrogateInHexEscape, + + /// JSON has a comma after the last value in an array or map. + TrailingComma, + + /// JSON has non-whitespace trailing characters after the value. + TrailingCharacters, + + /// Unexpected end of hex escape. + UnexpectedEndOfHexEscape, + + /// Encountered nesting of JSON maps and arrays more than 128 layers deep. + RecursionLimitExceeded, +} + +impl Error { + #[cold] + pub(crate) fn syntax(code: ErrorCode, line: usize, column: usize) -> Self { + Error { + err: Box::new(ErrorImpl { code, line, column }), + } + } + + // Not public API. Should be pub(crate). + // + // Update `eager_json` crate when this function changes. + #[doc(hidden)] + #[cold] + pub fn io(error: io::Error) -> Self { + Error { + err: Box::new(ErrorImpl { + code: ErrorCode::Io(error), + line: 0, + column: 0, + }), + } + } + + #[cold] + pub(crate) fn fix_position(self, f: F) -> Self + where + F: FnOnce(ErrorCode) -> Error, + { + if self.err.line == 0 { + f(self.err.code) + } else { + self + } + } +} + +impl Display for ErrorCode { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match self { + ErrorCode::Message(msg) => f.write_str(msg), + ErrorCode::Io(err) => Display::fmt(err, f), + ErrorCode::EofWhileParsingList => f.write_str("EOF while parsing a list"), + ErrorCode::EofWhileParsingObject => f.write_str("EOF while parsing an object"), + ErrorCode::EofWhileParsingString => f.write_str("EOF while parsing a string"), + ErrorCode::EofWhileParsingValue => f.write_str("EOF while parsing a value"), + ErrorCode::ExpectedColon => f.write_str("expected `:`"), + ErrorCode::ExpectedListCommaOrEnd => f.write_str("expected `,` or `]`"), + ErrorCode::ExpectedObjectCommaOrEnd => f.write_str("expected `,` or `}`"), + ErrorCode::ExpectedSomeIdent => f.write_str("expected ident"), + ErrorCode::ExpectedSomeValue => f.write_str("expected value"), + ErrorCode::ExpectedDoubleQuote => f.write_str("expected `\"`"), + ErrorCode::InvalidEscape => f.write_str("invalid escape"), + ErrorCode::InvalidNumber => f.write_str("invalid number"), + ErrorCode::NumberOutOfRange => f.write_str("number out of range"), + ErrorCode::InvalidUnicodeCodePoint => f.write_str("invalid unicode code point"), + ErrorCode::ControlCharacterWhileParsingString => { + f.write_str("control character (\\u0000-\\u001F) found while parsing a string") + } + ErrorCode::KeyMustBeAString => f.write_str("key must be a string"), + ErrorCode::ExpectedNumericKey => { + f.write_str("invalid value: expected key to be a number in quotes") + } + ErrorCode::FloatKeyMustBeFinite => { + f.write_str("float key must be finite (got NaN or +/-inf)") + } + ErrorCode::LoneLeadingSurrogateInHexEscape => { + f.write_str("lone leading surrogate in hex escape") + } + ErrorCode::TrailingComma => f.write_str("trailing comma"), + ErrorCode::TrailingCharacters => f.write_str("trailing characters"), + ErrorCode::UnexpectedEndOfHexEscape => f.write_str("unexpected end of hex escape"), + ErrorCode::RecursionLimitExceeded => f.write_str("recursion limit exceeded"), + } + } +} + +impl serde::de::StdError for Error { + #[cfg(feature = "std")] + fn source(&self) -> Option<&(dyn error::Error + 'static)> { + match &self.err.code { + ErrorCode::Io(err) => err.source(), + _ => None, + } + } +} + +impl Display for Error { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + Display::fmt(&*self.err, f) + } +} + +impl Display for ErrorImpl { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + if self.line == 0 { + Display::fmt(&self.code, f) + } else { + write!( + f, + "{} at line {} column {}", + self.code, self.line, self.column + ) + } + } +} + +// Remove two layers of verbosity from the debug representation. Humans often +// end up seeing this representation because it is what unwrap() shows. +impl Debug for Error { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!( + f, + "Error({:?}, line: {}, column: {})", + self.err.code.to_string(), + self.err.line, + self.err.column + ) + } +} + +impl de::Error for Error { + #[cold] + fn custom(msg: T) -> Error { + make_error(msg.to_string()) + } + + #[cold] + fn invalid_type(unexp: de::Unexpected, exp: &dyn de::Expected) -> Self { + Error::custom(format_args!( + "invalid type: {}, expected {}", + JsonUnexpected(unexp), + exp, + )) + } + + #[cold] + fn invalid_value(unexp: de::Unexpected, exp: &dyn de::Expected) -> Self { + Error::custom(format_args!( + "invalid value: {}, expected {}", + JsonUnexpected(unexp), + exp, + )) + } +} + +impl ser::Error for Error { + #[cold] + fn custom(msg: T) -> Error { + make_error(msg.to_string()) + } +} + +struct JsonUnexpected<'a>(de::Unexpected<'a>); + +impl<'a> Display for JsonUnexpected<'a> { + fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + match self.0 { + de::Unexpected::Unit => formatter.write_str("null"), + de::Unexpected::Float(value) => write!( + formatter, + "floating point `{}`", + ryu::Buffer::new().format(value), + ), + unexp => Display::fmt(&unexp, formatter), + } + } +} + +// Parse our own error message that looks like "{} at line {} column {}" to work +// around erased-serde round-tripping the error through de::Error::custom. +fn make_error(mut msg: String) -> Error { + let (line, column) = parse_line_col(&mut msg).unwrap_or((0, 0)); + Error { + err: Box::new(ErrorImpl { + code: ErrorCode::Message(msg.into_boxed_str()), + line, + column, + }), + } +} + +fn parse_line_col(msg: &mut String) -> Option<(usize, usize)> { + let start_of_suffix = match msg.rfind(" at line ") { + Some(index) => index, + None => return None, + }; + + // Find start and end of line number. + let start_of_line = start_of_suffix + " at line ".len(); + let mut end_of_line = start_of_line; + while starts_with_digit(&msg[end_of_line..]) { + end_of_line += 1; + } + + if !msg[end_of_line..].starts_with(" column ") { + return None; + } + + // Find start and end of column number. + let start_of_column = end_of_line + " column ".len(); + let mut end_of_column = start_of_column; + while starts_with_digit(&msg[end_of_column..]) { + end_of_column += 1; + } + + if end_of_column < msg.len() { + return None; + } + + // Parse numbers. + let line = match usize::from_str(&msg[start_of_line..end_of_line]) { + Ok(line) => line, + Err(_) => return None, + }; + let column = match usize::from_str(&msg[start_of_column..end_of_column]) { + Ok(column) => column, + Err(_) => return None, + }; + + msg.truncate(start_of_suffix); + Some((line, column)) +} + +fn starts_with_digit(slice: &str) -> bool { + match slice.as_bytes().first() { + None => false, + Some(&byte) => byte >= b'0' && byte <= b'9', + } +} diff --git a/vendor/serde_json/src/io/core.rs b/vendor/serde_json/src/io/core.rs new file mode 100644 index 0000000..54c8ddf --- /dev/null +++ b/vendor/serde_json/src/io/core.rs @@ -0,0 +1,79 @@ +//! Reimplements core logic and types from `std::io` in an `alloc`-friendly +//! fashion. + +use alloc::vec::Vec; +use core::fmt::{self, Display}; +use core::result; + +pub enum ErrorKind { + Other, +} + +// I/O errors can never occur in no-std mode. All our no-std I/O implementations +// are infallible. +pub struct Error; + +impl Display for Error { + fn fmt(&self, _formatter: &mut fmt::Formatter<'_>) -> fmt::Result { + unreachable!() + } +} + +impl Error { + pub(crate) fn new(_kind: ErrorKind, _error: &'static str) -> Error { + Error + } +} + +pub type Result = result::Result; + +pub trait Write { + fn write(&mut self, buf: &[u8]) -> Result; + + fn write_all(&mut self, buf: &[u8]) -> Result<()> { + // All our Write impls in no_std mode always write the whole buffer in + // one call infallibly. + let result = self.write(buf); + debug_assert!(result.is_ok()); + debug_assert_eq!(result.unwrap_or(0), buf.len()); + Ok(()) + } + + fn flush(&mut self) -> Result<()>; +} + +impl Write for &mut W { + #[inline] + fn write(&mut self, buf: &[u8]) -> Result { + (*self).write(buf) + } + + #[inline] + fn write_all(&mut self, buf: &[u8]) -> Result<()> { + (*self).write_all(buf) + } + + #[inline] + fn flush(&mut self) -> Result<()> { + (*self).flush() + } +} + +impl Write for Vec { + #[inline] + fn write(&mut self, buf: &[u8]) -> Result { + self.extend_from_slice(buf); + Ok(buf.len()) + } + + #[inline] + fn write_all(&mut self, buf: &[u8]) -> Result<()> { + self.extend_from_slice(buf); + Ok(()) + } + + #[inline] + fn flush(&mut self) -> Result<()> { + Ok(()) + } +} diff --git a/vendor/serde_json/src/io/mod.rs b/vendor/serde_json/src/io/mod.rs new file mode 100644 index 0000000..9dee4a0 --- /dev/null +++ b/vendor/serde_json/src/io/mod.rs @@ -0,0 +1,20 @@ +//! A tiny, `no_std`-friendly facade around `std::io`. +//! Reexports types from `std` when available; otherwise reimplements and +//! provides some of the core logic. +//! +//! The main reason that `std::io` hasn't found itself reexported as part of +//! the `core` crate is the `std::io::{Read, Write}` traits' reliance on +//! `std::io::Error`, which may contain internally a heap-allocated `Box` +//! and/or now relying on OS-specific `std::backtrace::Backtrace`. + +pub use self::imp::{Error, ErrorKind, Result, Write}; + +#[cfg(not(feature = "std"))] +#[path = "core.rs"] +mod imp; + +#[cfg(feature = "std")] +use std::io as imp; + +#[cfg(feature = "std")] +pub use std::io::{Bytes, Read}; diff --git a/vendor/serde_json/src/iter.rs b/vendor/serde_json/src/iter.rs new file mode 100644 index 0000000..9792916 --- /dev/null +++ b/vendor/serde_json/src/iter.rs @@ -0,0 +1,70 @@ +use crate::io; + +pub struct LineColIterator { + iter: I, + + /// Index of the current line. Characters in the first line of the input + /// (before the first newline character) are in line 1. + line: usize, + + /// Index of the current column. The first character in the input and any + /// characters immediately following a newline character are in column 1. + /// The column is 0 immediately after a newline character has been read. + col: usize, + + /// Byte offset of the start of the current line. This is the sum of lengths + /// of all previous lines. Keeping track of things this way allows efficient + /// computation of the current line, column, and byte offset while only + /// updating one of the counters in `next()` in the common case. + start_of_line: usize, +} + +impl LineColIterator +where + I: Iterator>, +{ + pub fn new(iter: I) -> LineColIterator { + LineColIterator { + iter, + line: 1, + col: 0, + start_of_line: 0, + } + } + + pub fn line(&self) -> usize { + self.line + } + + pub fn col(&self) -> usize { + self.col + } + + pub fn byte_offset(&self) -> usize { + self.start_of_line + self.col + } +} + +impl Iterator for LineColIterator +where + I: Iterator>, +{ + type Item = io::Result; + + fn next(&mut self) -> Option> { + match self.iter.next() { + None => None, + Some(Ok(b'\n')) => { + self.start_of_line += self.col + 1; + self.line += 1; + self.col = 0; + Some(Ok(b'\n')) + } + Some(Ok(c)) => { + self.col += 1; + Some(Ok(c)) + } + Some(Err(e)) => Some(Err(e)), + } + } +} diff --git a/vendor/serde_json/src/lexical/algorithm.rs b/vendor/serde_json/src/lexical/algorithm.rs new file mode 100644 index 0000000..eaa5e7e --- /dev/null +++ b/vendor/serde_json/src/lexical/algorithm.rs @@ -0,0 +1,196 @@ +// Adapted from https://github.com/Alexhuszagh/rust-lexical. + +//! Algorithms to efficiently convert strings to floats. + +use super::bhcomp::*; +use super::cached::*; +use super::errors::*; +use super::float::ExtendedFloat; +use super::num::*; +use super::small_powers::*; + +// FAST +// ---- + +/// Convert mantissa to exact value for a non-base2 power. +/// +/// Returns the resulting float and if the value can be represented exactly. +pub(crate) fn fast_path(mantissa: u64, exponent: i32) -> Option +where + F: Float, +{ + // `mantissa >> (F::MANTISSA_SIZE+1) != 0` effectively checks if the + // value has a no bits above the hidden bit, which is what we want. + let (min_exp, max_exp) = F::exponent_limit(); + let shift_exp = F::mantissa_limit(); + let mantissa_size = F::MANTISSA_SIZE + 1; + if mantissa == 0 { + Some(F::ZERO) + } else if mantissa >> mantissa_size != 0 { + // Would require truncation of the mantissa. + None + } else if exponent == 0 { + // 0 exponent, same as value, exact representation. + let float = F::as_cast(mantissa); + Some(float) + } else if exponent >= min_exp && exponent <= max_exp { + // Value can be exactly represented, return the value. + // Do not use powi, since powi can incrementally introduce + // error. + let float = F::as_cast(mantissa); + Some(float.pow10(exponent)) + } else if exponent >= 0 && exponent <= max_exp + shift_exp { + // Check to see if we have a disguised fast-path, where the + // number of digits in the mantissa is very small, but and + // so digits can be shifted from the exponent to the mantissa. + // https://www.exploringbinary.com/fast-path-decimal-to-floating-point-conversion/ + let small_powers = POW10_64; + let shift = exponent - max_exp; + let power = small_powers[shift as usize]; + + // Compute the product of the power, if it overflows, + // prematurely return early, otherwise, if we didn't overshoot, + // we can get an exact value. + let value = match mantissa.checked_mul(power) { + None => return None, + Some(value) => value, + }; + if value >> mantissa_size != 0 { + None + } else { + // Use powi, since it's correct, and faster on + // the fast-path. + let float = F::as_cast(value); + Some(float.pow10(max_exp)) + } + } else { + // Cannot be exactly represented, exponent too small or too big, + // would require truncation. + None + } +} + +// MODERATE +// -------- + +/// Multiply the floating-point by the exponent. +/// +/// Multiply by pre-calculated powers of the base, modify the extended- +/// float, and return if new value and if the value can be represented +/// accurately. +fn multiply_exponent_extended(fp: &mut ExtendedFloat, exponent: i32, truncated: bool) -> bool +where + F: Float, +{ + let powers = ExtendedFloat::get_powers(); + let exponent = exponent.saturating_add(powers.bias); + let small_index = exponent % powers.step; + let large_index = exponent / powers.step; + if exponent < 0 { + // Guaranteed underflow (assign 0). + fp.mant = 0; + true + } else if large_index as usize >= powers.large.len() { + // Overflow (assign infinity) + fp.mant = 1 << 63; + fp.exp = 0x7FF; + true + } else { + // Within the valid exponent range, multiply by the large and small + // exponents and return the resulting value. + + // Track errors to as a factor of unit in last-precision. + let mut errors: u32 = 0; + if truncated { + errors += u64::error_halfscale(); + } + + // Multiply by the small power. + // Check if we can directly multiply by an integer, if not, + // use extended-precision multiplication. + match fp + .mant + .overflowing_mul(powers.get_small_int(small_index as usize)) + { + // Overflow, multiplication unsuccessful, go slow path. + (_, true) => { + fp.normalize(); + fp.imul(&powers.get_small(small_index as usize)); + errors += u64::error_halfscale(); + } + // No overflow, multiplication successful. + (mant, false) => { + fp.mant = mant; + fp.normalize(); + } + } + + // Multiply by the large power + fp.imul(&powers.get_large(large_index as usize)); + if errors > 0 { + errors += 1; + } + errors += u64::error_halfscale(); + + // Normalize the floating point (and the errors). + let shift = fp.normalize(); + errors <<= shift; + + u64::error_is_accurate::(errors, fp) + } +} + +/// Create a precise native float using an intermediate extended-precision float. +/// +/// Return the float approximation and if the value can be accurately +/// represented with mantissa bits of precision. +#[inline] +pub(crate) fn moderate_path( + mantissa: u64, + exponent: i32, + truncated: bool, +) -> (ExtendedFloat, bool) +where + F: Float, +{ + let mut fp = ExtendedFloat { + mant: mantissa, + exp: 0, + }; + let valid = multiply_exponent_extended::(&mut fp, exponent, truncated); + (fp, valid) +} + +// FALLBACK +// -------- + +/// Fallback path when the fast path does not work. +/// +/// Uses the moderate path, if applicable, otherwise, uses the slow path +/// as required. +pub(crate) fn fallback_path( + integer: &[u8], + fraction: &[u8], + mantissa: u64, + exponent: i32, + mantissa_exponent: i32, + truncated: bool, +) -> F +where + F: Float, +{ + // Moderate path (use an extended 80-bit representation). + let (fp, valid) = moderate_path::(mantissa, mantissa_exponent, truncated); + if valid { + return fp.into_float::(); + } + + // Slow path, fast path didn't work. + let b = fp.into_downward_float::(); + if b.is_special() { + // We have a non-finite number, we get to leave early. + b + } else { + bhcomp(b, integer, fraction, exponent) + } +} diff --git a/vendor/serde_json/src/lexical/bhcomp.rs b/vendor/serde_json/src/lexical/bhcomp.rs new file mode 100644 index 0000000..e52b1c9 --- /dev/null +++ b/vendor/serde_json/src/lexical/bhcomp.rs @@ -0,0 +1,218 @@ +// Adapted from https://github.com/Alexhuszagh/rust-lexical. + +//! Compare the mantissa to the halfway representation of the float. +//! +//! Compares the actual significant digits of the mantissa to the +//! theoretical digits from `b+h`, scaled into the proper range. + +use super::bignum::*; +use super::digit::*; +use super::exponent::*; +use super::float::*; +use super::math::*; +use super::num::*; +use super::rounding::*; +use core::{cmp, mem}; + +// MANTISSA + +/// Parse the full mantissa into a big integer. +/// +/// Max digits is the maximum number of digits plus one. +fn parse_mantissa(integer: &[u8], fraction: &[u8]) -> Bigint +where + F: Float, +{ + // Main loop + let small_powers = POW10_LIMB; + let step = small_powers.len() - 2; + let max_digits = F::MAX_DIGITS - 1; + let mut counter = 0; + let mut value: Limb = 0; + let mut i: usize = 0; + let mut result = Bigint::default(); + + // Iteratively process all the data in the mantissa. + for &digit in integer.iter().chain(fraction) { + // We've parsed the max digits using small values, add to bignum + if counter == step { + result.imul_small(small_powers[counter]); + result.iadd_small(value); + counter = 0; + value = 0; + } + + value *= 10; + value += as_limb(to_digit(digit).unwrap()); + + i += 1; + counter += 1; + if i == max_digits { + break; + } + } + + // We will always have a remainder, as long as we entered the loop + // once, or counter % step is 0. + if counter != 0 { + result.imul_small(small_powers[counter]); + result.iadd_small(value); + } + + // If we have any remaining digits after the last value, we need + // to add a 1 after the rest of the array, it doesn't matter where, + // just move it up. This is good for the worst-possible float + // representation. We also need to return an index. + // Since we already trimmed trailing zeros, we know there has + // to be a non-zero digit if there are any left. + if i < integer.len() + fraction.len() { + result.imul_small(10); + result.iadd_small(1); + } + + result +} + +// FLOAT OPS + +/// Calculate `b` from a representation of `b` as a float. +#[inline] +pub(super) fn b_extended(f: F) -> ExtendedFloat { + ExtendedFloat::from_float(f) +} + +/// Calculate `b+h` from a representation of `b` as a float. +#[inline] +pub(super) fn bh_extended(f: F) -> ExtendedFloat { + // None of these can overflow. + let b = b_extended(f); + ExtendedFloat { + mant: (b.mant << 1) + 1, + exp: b.exp - 1, + } +} + +// ROUNDING + +/// Custom round-nearest, tie-event algorithm for bhcomp. +#[inline] +fn round_nearest_tie_even(fp: &mut ExtendedFloat, shift: i32, is_truncated: bool) { + let (mut is_above, mut is_halfway) = round_nearest(fp, shift); + if is_halfway && is_truncated { + is_above = true; + is_halfway = false; + } + tie_even(fp, is_above, is_halfway); +} + +// BHCOMP + +/// Calculate the mantissa for a big integer with a positive exponent. +fn large_atof(mantissa: Bigint, exponent: i32) -> F +where + F: Float, +{ + let bits = mem::size_of::() * 8; + + // Simple, we just need to multiply by the power of the radix. + // Now, we can calculate the mantissa and the exponent from this. + // The binary exponent is the binary exponent for the mantissa + // shifted to the hidden bit. + let mut bigmant = mantissa; + bigmant.imul_pow10(exponent as u32); + + // Get the exact representation of the float from the big integer. + let (mant, is_truncated) = bigmant.hi64(); + let exp = bigmant.bit_length() as i32 - bits as i32; + let mut fp = ExtendedFloat { mant, exp }; + fp.round_to_native::(|fp, shift| round_nearest_tie_even(fp, shift, is_truncated)); + into_float(fp) +} + +/// Calculate the mantissa for a big integer with a negative exponent. +/// +/// This invokes the comparison with `b+h`. +fn small_atof(mantissa: Bigint, exponent: i32, f: F) -> F +where + F: Float, +{ + // Get the significant digits and radix exponent for the real digits. + let mut real_digits = mantissa; + let real_exp = exponent; + debug_assert!(real_exp < 0); + + // Get the significant digits and the binary exponent for `b+h`. + let theor = bh_extended(f); + let mut theor_digits = Bigint::from_u64(theor.mant); + let theor_exp = theor.exp; + + // We need to scale the real digits and `b+h` digits to be the same + // order. We currently have `real_exp`, in `radix`, that needs to be + // shifted to `theor_digits` (since it is negative), and `theor_exp` + // to either `theor_digits` or `real_digits` as a power of 2 (since it + // may be positive or negative). Try to remove as many powers of 2 + // as possible. All values are relative to `theor_digits`, that is, + // reflect the power you need to multiply `theor_digits` by. + + // Can remove a power-of-two, since the radix is 10. + // Both are on opposite-sides of equation, can factor out a + // power of two. + // + // Example: 10^-10, 2^-10 -> ( 0, 10, 0) + // Example: 10^-10, 2^-15 -> (-5, 10, 0) + // Example: 10^-10, 2^-5 -> ( 5, 10, 0) + // Example: 10^-10, 2^5 -> (15, 10, 0) + let binary_exp = theor_exp - real_exp; + let halfradix_exp = -real_exp; + let radix_exp = 0; + + // Carry out our multiplication. + if halfradix_exp != 0 { + theor_digits.imul_pow5(halfradix_exp as u32); + } + if radix_exp != 0 { + theor_digits.imul_pow10(radix_exp as u32); + } + if binary_exp > 0 { + theor_digits.imul_pow2(binary_exp as u32); + } else if binary_exp < 0 { + real_digits.imul_pow2(-binary_exp as u32); + } + + // Compare real digits to theoretical digits and round the float. + match real_digits.compare(&theor_digits) { + cmp::Ordering::Greater => f.next_positive(), + cmp::Ordering::Less => f, + cmp::Ordering::Equal => f.round_positive_even(), + } +} + +/// Calculate the exact value of the float. +/// +/// Note: fraction must not have trailing zeros. +pub(crate) fn bhcomp(b: F, integer: &[u8], mut fraction: &[u8], exponent: i32) -> F +where + F: Float, +{ + // Calculate the number of integer digits and use that to determine + // where the significant digits start in the fraction. + let integer_digits = integer.len(); + let fraction_digits = fraction.len(); + let digits_start = if integer_digits == 0 { + let start = fraction.iter().take_while(|&x| *x == b'0').count(); + fraction = &fraction[start..]; + start + } else { + 0 + }; + let sci_exp = scientific_exponent(exponent, integer_digits, digits_start); + let count = F::MAX_DIGITS.min(integer_digits + fraction_digits - digits_start); + let scaled_exponent = sci_exp + 1 - count as i32; + + let mantissa = parse_mantissa::(integer, fraction); + if scaled_exponent >= 0 { + large_atof(mantissa, scaled_exponent) + } else { + small_atof(mantissa, scaled_exponent, b) + } +} diff --git a/vendor/serde_json/src/lexical/bignum.rs b/vendor/serde_json/src/lexical/bignum.rs new file mode 100644 index 0000000..4fa7eed --- /dev/null +++ b/vendor/serde_json/src/lexical/bignum.rs @@ -0,0 +1,34 @@ +// Adapted from https://github.com/Alexhuszagh/rust-lexical. + +//! Big integer type definition. + +use super::math::*; +#[allow(unused_imports)] +use alloc::vec::Vec; + +/// Storage for a big integer type. +#[derive(Clone, PartialEq, Eq)] +pub(crate) struct Bigint { + /// Internal storage for the Bigint, in little-endian order. + pub(crate) data: Vec, +} + +impl Default for Bigint { + fn default() -> Self { + Bigint { + data: Vec::with_capacity(20), + } + } +} + +impl Math for Bigint { + #[inline] + fn data(&self) -> &Vec { + &self.data + } + + #[inline] + fn data_mut(&mut self) -> &mut Vec { + &mut self.data + } +} diff --git a/vendor/serde_json/src/lexical/cached.rs b/vendor/serde_json/src/lexical/cached.rs new file mode 100644 index 0000000..ef5a9fe --- /dev/null +++ b/vendor/serde_json/src/lexical/cached.rs @@ -0,0 +1,82 @@ +// Adapted from https://github.com/Alexhuszagh/rust-lexical. + +//! Cached powers trait for extended-precision floats. + +use super::cached_float80; +use super::float::ExtendedFloat; + +// POWERS + +/// Precalculated powers that uses two-separate arrays for memory-efficiency. +#[doc(hidden)] +pub(crate) struct ExtendedFloatArray { + // Pre-calculated mantissa for the powers. + pub mant: &'static [u64], + // Pre-calculated binary exponents for the powers. + pub exp: &'static [i32], +} + +/// Allow indexing of values without bounds checking +impl ExtendedFloatArray { + #[inline] + pub fn get_extended_float(&self, index: usize) -> ExtendedFloat { + let mant = self.mant[index]; + let exp = self.exp[index]; + ExtendedFloat { mant, exp } + } + + #[inline] + pub fn len(&self) -> usize { + self.mant.len() + } +} + +// MODERATE PATH POWERS + +/// Precalculated powers of base N for the moderate path. +#[doc(hidden)] +pub(crate) struct ModeratePathPowers { + // Pre-calculated small powers. + pub small: ExtendedFloatArray, + // Pre-calculated large powers. + pub large: ExtendedFloatArray, + /// Pre-calculated small powers as 64-bit integers + pub small_int: &'static [u64], + // Step between large powers and number of small powers. + pub step: i32, + // Exponent bias for the large powers. + pub bias: i32, +} + +/// Allow indexing of values without bounds checking +impl ModeratePathPowers { + #[inline] + pub fn get_small(&self, index: usize) -> ExtendedFloat { + self.small.get_extended_float(index) + } + + #[inline] + pub fn get_large(&self, index: usize) -> ExtendedFloat { + self.large.get_extended_float(index) + } + + #[inline] + pub fn get_small_int(&self, index: usize) -> u64 { + self.small_int[index] + } +} + +// CACHED EXTENDED POWERS + +/// Cached powers as a trait for a floating-point type. +pub(crate) trait ModeratePathCache { + /// Get cached powers. + fn get_powers() -> &'static ModeratePathPowers; +} + +impl ModeratePathCache for ExtendedFloat { + #[inline] + fn get_powers() -> &'static ModeratePathPowers { + cached_float80::get_powers() + } +} diff --git a/vendor/serde_json/src/lexical/cached_float80.rs b/vendor/serde_json/src/lexical/cached_float80.rs new file mode 100644 index 0000000..9beda3d --- /dev/null +++ b/vendor/serde_json/src/lexical/cached_float80.rs @@ -0,0 +1,206 @@ +// Adapted from https://github.com/Alexhuszagh/rust-lexical. + +//! Cached exponents for basen values with 80-bit extended floats. +//! +//! Exact versions of base**n as an extended-precision float, with both +//! large and small powers. Use the large powers to minimize the amount +//! of compounded error. +//! +//! These values were calculated using Python, using the arbitrary-precision +//! integer to calculate exact extended-representation of each value. +//! These values are all normalized. + +use super::cached::{ExtendedFloatArray, ModeratePathPowers}; + +// LOW-LEVEL +// --------- + +// BASE10 + +const BASE10_SMALL_MANTISSA: [u64; 10] = [ + 9223372036854775808, // 10^0 + 11529215046068469760, // 10^1 + 14411518807585587200, // 10^2 + 18014398509481984000, // 10^3 + 11258999068426240000, // 10^4 + 14073748835532800000, // 10^5 + 17592186044416000000, // 10^6 + 10995116277760000000, // 10^7 + 13743895347200000000, // 10^8 + 17179869184000000000, // 10^9 +]; +const BASE10_SMALL_EXPONENT: [i32; 10] = [ + -63, // 10^0 + -60, // 10^1 + -57, // 10^2 + -54, // 10^3 + -50, // 10^4 + -47, // 10^5 + -44, // 10^6 + -40, // 10^7 + -37, // 10^8 + -34, // 10^9 +]; +const BASE10_LARGE_MANTISSA: [u64; 66] = [ + 11555125961253852697, // 10^-350 + 13451937075301367670, // 10^-340 + 15660115838168849784, // 10^-330 + 18230774251475056848, // 10^-320 + 10611707258198326947, // 10^-310 + 12353653155963782858, // 10^-300 + 14381545078898527261, // 10^-290 + 16742321987285426889, // 10^-280 + 9745314011399999080, // 10^-270 + 11345038669416679861, // 10^-260 + 13207363278391631158, // 10^-250 + 15375394465392026070, // 10^-240 + 17899314949046850752, // 10^-230 + 10418772551374772303, // 10^-220 + 12129047596099288555, // 10^-210 + 14120069793541087484, // 10^-200 + 16437924692338667210, // 10^-190 + 9568131466127621947, // 10^-180 + 11138771039116687545, // 10^-170 + 12967236152753102995, // 10^-160 + 15095849699286165408, // 10^-150 + 17573882009934360870, // 10^-140 + 10229345649675443343, // 10^-130 + 11908525658859223294, // 10^-120 + 13863348470604074297, // 10^-110 + 16139061738043178685, // 10^-100 + 9394170331095332911, // 10^-90 + 10936253623915059621, // 10^-80 + 12731474852090538039, // 10^-70 + 14821387422376473014, // 10^-60 + 17254365866976409468, // 10^-50 + 10043362776618689222, // 10^-40 + 11692013098647223345, // 10^-30 + 13611294676837538538, // 10^-20 + 15845632502852867518, // 10^-10 + 9223372036854775808, // 10^0 + 10737418240000000000, // 10^10 + 12500000000000000000, // 10^20 + 14551915228366851806, // 10^30 + 16940658945086006781, // 10^40 + 9860761315262647567, // 10^50 + 11479437019748901445, // 10^60 + 13363823550460978230, // 10^70 + 15557538194652854267, // 10^80 + 18111358157653424735, // 10^90 + 10542197943230523224, // 10^100 + 12272733663244316382, // 10^110 + 14287342391028437277, // 10^120 + 16632655625031838749, // 10^130 + 9681479787123295682, // 10^140 + 11270725851789228247, // 10^150 + 13120851772591970218, // 10^160 + 15274681817498023410, // 10^170 + 17782069995880619867, // 10^180 + 10350527006597618960, // 10^190 + 12049599325514420588, // 10^200 + 14027579833653779454, // 10^210 + 16330252207878254650, // 10^220 + 9505457831475799117, // 10^230 + 11065809325636130661, // 10^240 + 12882297539194266616, // 10^250 + 14996968138956309548, // 10^260 + 17458768723248864463, // 10^270 + 10162340898095201970, // 10^280 + 11830521861667747109, // 10^290 + 13772540099066387756, // 10^300 +]; +const BASE10_LARGE_EXPONENT: [i32; 66] = [ + -1226, // 10^-350 + -1193, // 10^-340 + -1160, // 10^-330 + -1127, // 10^-320 + -1093, // 10^-310 + -1060, // 10^-300 + -1027, // 10^-290 + -994, // 10^-280 + -960, // 10^-270 + -927, // 10^-260 + -894, // 10^-250 + -861, // 10^-240 + -828, // 10^-230 + -794, // 10^-220 + -761, // 10^-210 + -728, // 10^-200 + -695, // 10^-190 + -661, // 10^-180 + -628, // 10^-170 + -595, // 10^-160 + -562, // 10^-150 + -529, // 10^-140 + -495, // 10^-130 + -462, // 10^-120 + -429, // 10^-110 + -396, // 10^-100 + -362, // 10^-90 + -329, // 10^-80 + -296, // 10^-70 + -263, // 10^-60 + -230, // 10^-50 + -196, // 10^-40 + -163, // 10^-30 + -130, // 10^-20 + -97, // 10^-10 + -63, // 10^0 + -30, // 10^10 + 3, // 10^20 + 36, // 10^30 + 69, // 10^40 + 103, // 10^50 + 136, // 10^60 + 169, // 10^70 + 202, // 10^80 + 235, // 10^90 + 269, // 10^100 + 302, // 10^110 + 335, // 10^120 + 368, // 10^130 + 402, // 10^140 + 435, // 10^150 + 468, // 10^160 + 501, // 10^170 + 534, // 10^180 + 568, // 10^190 + 601, // 10^200 + 634, // 10^210 + 667, // 10^220 + 701, // 10^230 + 734, // 10^240 + 767, // 10^250 + 800, // 10^260 + 833, // 10^270 + 867, // 10^280 + 900, // 10^290 + 933, // 10^300 +]; +const BASE10_SMALL_INT_POWERS: [u64; 10] = [ + 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000, +]; +const BASE10_STEP: i32 = 10; +const BASE10_BIAS: i32 = 350; + +// HIGH LEVEL +// ---------- + +const BASE10_POWERS: ModeratePathPowers = ModeratePathPowers { + small: ExtendedFloatArray { + mant: &BASE10_SMALL_MANTISSA, + exp: &BASE10_SMALL_EXPONENT, + }, + large: ExtendedFloatArray { + mant: &BASE10_LARGE_MANTISSA, + exp: &BASE10_LARGE_EXPONENT, + }, + small_int: &BASE10_SMALL_INT_POWERS, + step: BASE10_STEP, + bias: BASE10_BIAS, +}; + +/// Get powers from base. +pub(crate) fn get_powers() -> &'static ModeratePathPowers { + &BASE10_POWERS +} diff --git a/vendor/serde_json/src/lexical/digit.rs b/vendor/serde_json/src/lexical/digit.rs new file mode 100644 index 0000000..3d150a1 --- /dev/null +++ b/vendor/serde_json/src/lexical/digit.rs @@ -0,0 +1,18 @@ +// Adapted from https://github.com/Alexhuszagh/rust-lexical. + +//! Helpers to convert and add digits from characters. + +// Convert u8 to digit. +#[inline] +pub(crate) fn to_digit(c: u8) -> Option { + (c as char).to_digit(10) +} + +// Add digit to mantissa. +#[inline] +pub(crate) fn add_digit(value: u64, digit: u32) -> Option { + match value.checked_mul(10) { + None => None, + Some(n) => n.checked_add(digit as u64), + } +} diff --git a/vendor/serde_json/src/lexical/errors.rs b/vendor/serde_json/src/lexical/errors.rs new file mode 100644 index 0000000..f4f41cd --- /dev/null +++ b/vendor/serde_json/src/lexical/errors.rs @@ -0,0 +1,132 @@ +// Adapted from https://github.com/Alexhuszagh/rust-lexical. + +//! Estimate the error in an 80-bit approximation of a float. +//! +//! This estimates the error in a floating-point representation. +//! +//! This implementation is loosely based off the Golang implementation, +//! found here: + +use super::float::*; +use super::num::*; +use super::rounding::*; + +pub(crate) trait FloatErrors { + /// Get the full error scale. + fn error_scale() -> u32; + /// Get the half error scale. + fn error_halfscale() -> u32; + /// Determine if the number of errors is tolerable for float precision. + fn error_is_accurate(count: u32, fp: &ExtendedFloat) -> bool; +} + +/// Check if the error is accurate with a round-nearest rounding scheme. +#[inline] +fn nearest_error_is_accurate(errors: u64, fp: &ExtendedFloat, extrabits: u64) -> bool { + // Round-to-nearest, need to use the halfway point. + if extrabits == 65 { + // Underflow, we have a shift larger than the mantissa. + // Representation is valid **only** if the value is close enough + // overflow to the next bit within errors. If it overflows, + // the representation is **not** valid. + !fp.mant.overflowing_add(errors).1 + } else { + let mask: u64 = lower_n_mask(extrabits); + let extra: u64 = fp.mant & mask; + + // Round-to-nearest, need to check if we're close to halfway. + // IE, b10100 | 100000, where `|` signifies the truncation point. + let halfway: u64 = lower_n_halfway(extrabits); + let cmp1 = halfway.wrapping_sub(errors) < extra; + let cmp2 = extra < halfway.wrapping_add(errors); + + // If both comparisons are true, we have significant rounding error, + // and the value cannot be exactly represented. Otherwise, the + // representation is valid. + !(cmp1 && cmp2) + } +} + +impl FloatErrors for u64 { + #[inline] + fn error_scale() -> u32 { + 8 + } + + #[inline] + fn error_halfscale() -> u32 { + u64::error_scale() / 2 + } + + #[inline] + fn error_is_accurate(count: u32, fp: &ExtendedFloat) -> bool { + // Determine if extended-precision float is a good approximation. + // If the error has affected too many units, the float will be + // inaccurate, or if the representation is too close to halfway + // that any operations could affect this halfway representation. + // See the documentation for dtoa for more information. + let bias = -(F::EXPONENT_BIAS - F::MANTISSA_SIZE); + let denormal_exp = bias - 63; + // This is always a valid u32, since (denormal_exp - fp.exp) + // will always be positive and the significand size is {23, 52}. + let extrabits = if fp.exp <= denormal_exp { + 64 - F::MANTISSA_SIZE + denormal_exp - fp.exp + } else { + 63 - F::MANTISSA_SIZE + }; + + // Our logic is as follows: we want to determine if the actual + // mantissa and the errors during calculation differ significantly + // from the rounding point. The rounding point for round-nearest + // is the halfway point, IE, this when the truncated bits start + // with b1000..., while the rounding point for the round-toward + // is when the truncated bits are equal to 0. + // To do so, we can check whether the rounding point +/- the error + // are >/< the actual lower n bits. + // + // For whether we need to use signed or unsigned types for this + // analysis, see this example, using u8 rather than u64 to simplify + // things. + // + // # Comparisons + // cmp1 = (halfway - errors) < extra + // cmp1 = extra < (halfway + errors) + // + // # Large Extrabits, Low Errors + // + // extrabits = 8 + // halfway = 0b10000000 + // extra = 0b10000010 + // errors = 0b00000100 + // halfway - errors = 0b01111100 + // halfway + errors = 0b10000100 + // + // Unsigned: + // halfway - errors = 124 + // halfway + errors = 132 + // extra = 130 + // cmp1 = true + // cmp2 = true + // Signed: + // halfway - errors = 124 + // halfway + errors = -124 + // extra = -126 + // cmp1 = false + // cmp2 = true + // + // # Conclusion + // + // Since errors will always be small, and since we want to detect + // if the representation is accurate, we need to use an **unsigned** + // type for comparisons. + + let extrabits = extrabits as u64; + let errors = count as u64; + if extrabits > 65 { + // Underflow, we have a literal 0. + return true; + } + + nearest_error_is_accurate(errors, fp, extrabits) + } +} diff --git a/vendor/serde_json/src/lexical/exponent.rs b/vendor/serde_json/src/lexical/exponent.rs new file mode 100644 index 0000000..5e27de8 --- /dev/null +++ b/vendor/serde_json/src/lexical/exponent.rs @@ -0,0 +1,50 @@ +// Adapted from https://github.com/Alexhuszagh/rust-lexical. + +//! Utilities to calculate exponents. + +/// Convert usize into i32 without overflow. +/// +/// This is needed to ensure when adjusting the exponent relative to +/// the mantissa we do not overflow for comically-long exponents. +#[inline] +fn into_i32(value: usize) -> i32 { + if value > i32::MAX as usize { + i32::MAX + } else { + value as i32 + } +} + +// EXPONENT CALCULATION + +// Calculate the scientific notation exponent without overflow. +// +// For example, 0.1 would be -1, and 10 would be 1 in base 10. +#[inline] +pub(crate) fn scientific_exponent( + exponent: i32, + integer_digits: usize, + fraction_start: usize, +) -> i32 { + if integer_digits == 0 { + let fraction_start = into_i32(fraction_start); + exponent.saturating_sub(fraction_start).saturating_sub(1) + } else { + let integer_shift = into_i32(integer_digits - 1); + exponent.saturating_add(integer_shift) + } +} + +// Calculate the mantissa exponent without overflow. +// +// Remove the number of digits that contributed to the mantissa past +// the dot, and add the number of truncated digits from the mantissa, +// to calculate the scaling factor for the mantissa from a raw exponent. +#[inline] +pub(crate) fn mantissa_exponent(exponent: i32, fraction_digits: usize, truncated: usize) -> i32 { + if fraction_digits > truncated { + exponent.saturating_sub(into_i32(fraction_digits - truncated)) + } else { + exponent.saturating_add(into_i32(truncated - fraction_digits)) + } +} diff --git a/vendor/serde_json/src/lexical/float.rs b/vendor/serde_json/src/lexical/float.rs new file mode 100644 index 0000000..2d434a2 --- /dev/null +++ b/vendor/serde_json/src/lexical/float.rs @@ -0,0 +1,183 @@ +// Adapted from https://github.com/Alexhuszagh/rust-lexical. + +// FLOAT TYPE + +use super::num::*; +use super::rounding::*; +use super::shift::*; + +/// Extended precision floating-point type. +/// +/// Private implementation, exposed only for testing purposes. +#[doc(hidden)] +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub(crate) struct ExtendedFloat { + /// Mantissa for the extended-precision float. + pub mant: u64, + /// Binary exponent for the extended-precision float. + pub exp: i32, +} + +impl ExtendedFloat { + // PROPERTIES + + // OPERATIONS + + /// Multiply two normalized extended-precision floats, as if by `a*b`. + /// + /// The precision is maximal when the numbers are normalized, however, + /// decent precision will occur as long as both values have high bits + /// set. The result is not normalized. + /// + /// Algorithm: + /// 1. Non-signed multiplication of mantissas (requires 2x as many bits as input). + /// 2. Normalization of the result (not done here). + /// 3. Addition of exponents. + pub(crate) fn mul(&self, b: &ExtendedFloat) -> ExtendedFloat { + // Logic check, values must be decently normalized prior to multiplication. + debug_assert!((self.mant & u64::HIMASK != 0) && (b.mant & u64::HIMASK != 0)); + + // Extract high-and-low masks. + let ah = self.mant >> u64::HALF; + let al = self.mant & u64::LOMASK; + let bh = b.mant >> u64::HALF; + let bl = b.mant & u64::LOMASK; + + // Get our products + let ah_bl = ah * bl; + let al_bh = al * bh; + let al_bl = al * bl; + let ah_bh = ah * bh; + + let mut tmp = (ah_bl & u64::LOMASK) + (al_bh & u64::LOMASK) + (al_bl >> u64::HALF); + // round up + tmp += 1 << (u64::HALF - 1); + + ExtendedFloat { + mant: ah_bh + (ah_bl >> u64::HALF) + (al_bh >> u64::HALF) + (tmp >> u64::HALF), + exp: self.exp + b.exp + u64::FULL, + } + } + + /// Multiply in-place, as if by `a*b`. + /// + /// The result is not normalized. + #[inline] + pub(crate) fn imul(&mut self, b: &ExtendedFloat) { + *self = self.mul(b); + } + + // NORMALIZE + + /// Normalize float-point number. + /// + /// Shift the mantissa so the number of leading zeros is 0, or the value + /// itself is 0. + /// + /// Get the number of bytes shifted. + #[inline] + pub(crate) fn normalize(&mut self) -> u32 { + // Note: + // Using the cltz intrinsic via leading_zeros is way faster (~10x) + // than shifting 1-bit at a time, via while loop, and also way + // faster (~2x) than an unrolled loop that checks at 32, 16, 4, + // 2, and 1 bit. + // + // Using a modulus of pow2 (which will get optimized to a bitwise + // and with 0x3F or faster) is slightly slower than an if/then, + // however, removing the if/then will likely optimize more branched + // code as it removes conditional logic. + + // Calculate the number of leading zeros, and then zero-out + // any overflowing bits, to avoid shl overflow when self.mant == 0. + let shift = if self.mant == 0 { + 0 + } else { + self.mant.leading_zeros() + }; + shl(self, shift as i32); + shift + } + + // ROUND + + /// Lossy round float-point number to native mantissa boundaries. + #[inline] + pub(crate) fn round_to_native(&mut self, algorithm: Algorithm) + where + F: Float, + Algorithm: FnOnce(&mut ExtendedFloat, i32), + { + round_to_native::(self, algorithm); + } + + // FROM + + /// Create extended float from native float. + #[inline] + pub fn from_float(f: F) -> ExtendedFloat { + from_float(f) + } + + // INTO + + /// Convert into default-rounded, lower-precision native float. + #[inline] + pub(crate) fn into_float(mut self) -> F { + self.round_to_native::(round_nearest_tie_even); + into_float(self) + } + + /// Convert into downward-rounded, lower-precision native float. + #[inline] + pub(crate) fn into_downward_float(mut self) -> F { + self.round_to_native::(round_downward); + into_float(self) + } +} + +// FROM FLOAT + +// Import ExtendedFloat from native float. +#[inline] +pub(crate) fn from_float(f: F) -> ExtendedFloat +where + F: Float, +{ + ExtendedFloat { + mant: u64::as_cast(f.mantissa()), + exp: f.exponent(), + } +} + +// INTO FLOAT + +// Export extended-precision float to native float. +// +// The extended-precision float must be in native float representation, +// with overflow/underflow appropriately handled. +#[inline] +pub(crate) fn into_float(fp: ExtendedFloat) -> F +where + F: Float, +{ + // Export floating-point number. + if fp.mant == 0 || fp.exp < F::DENORMAL_EXPONENT { + // sub-denormal, underflow + F::ZERO + } else if fp.exp >= F::MAX_EXPONENT { + // overflow + F::from_bits(F::INFINITY_BITS) + } else { + // calculate the exp and fraction bits, and return a float from bits. + let exp: u64; + if (fp.exp == F::DENORMAL_EXPONENT) && (fp.mant & F::HIDDEN_BIT_MASK.as_u64()) == 0 { + exp = 0; + } else { + exp = (fp.exp + F::EXPONENT_BIAS) as u64; + } + let exp = exp << F::MANTISSA_SIZE; + let mant = fp.mant & F::MANTISSA_MASK.as_u64(); + F::from_bits(F::Unsigned::as_cast(mant | exp)) + } +} diff --git a/vendor/serde_json/src/lexical/large_powers.rs b/vendor/serde_json/src/lexical/large_powers.rs new file mode 100644 index 0000000..af2c8a6 --- /dev/null +++ b/vendor/serde_json/src/lexical/large_powers.rs @@ -0,0 +1,9 @@ +// Adapted from https://github.com/Alexhuszagh/rust-lexical. + +//! Precalculated large powers for limbs. + +#[cfg(fast_arithmetic = "32")] +pub(crate) use super::large_powers32::*; + +#[cfg(fast_arithmetic = "64")] +pub(crate) use super::large_powers64::*; diff --git a/vendor/serde_json/src/lexical/large_powers32.rs b/vendor/serde_json/src/lexical/large_powers32.rs new file mode 100644 index 0000000..eb8582f --- /dev/null +++ b/vendor/serde_json/src/lexical/large_powers32.rs @@ -0,0 +1,183 @@ +// Adapted from https://github.com/Alexhuszagh/rust-lexical. + +//! Precalculated large powers for 32-bit limbs. + +/// Large powers (`&[u32]`) for base5 operations. +const POW5_1: [u32; 1] = [5]; +const POW5_2: [u32; 1] = [25]; +const POW5_3: [u32; 1] = [625]; +const POW5_4: [u32; 1] = [390625]; +const POW5_5: [u32; 2] = [2264035265, 35]; +const POW5_6: [u32; 3] = [2242703233, 762134875, 1262]; +const POW5_7: [u32; 5] = [3211403009, 1849224548, 3668416493, 3913284084, 1593091]; +const POW5_8: [u32; 10] = [ + 781532673, 64985353, 253049085, 594863151, 3553621484, 3288652808, 3167596762, 2788392729, + 3911132675, 590, +]; +const POW5_9: [u32; 19] = [ + 2553183233, 3201533787, 3638140786, 303378311, 1809731782, 3477761648, 3583367183, 649228654, + 2915460784, 487929380, 1011012442, 1677677582, 3428152256, 1710878487, 1438394610, 2161952759, + 4100910556, 1608314830, 349175, +]; +const POW5_10: [u32; 38] = [ + 4234999809, 2012377703, 2408924892, 1570150255, 3090844311, 3273530073, 1187251475, 2498123591, + 3364452033, 1148564857, 687371067, 2854068671, 1883165473, 505794538, 2988060450, 3159489326, + 2531348317, 3215191468, 849106862, 3892080979, 3288073877, 2242451748, 4183778142, 2995818208, + 2477501924, 325481258, 2487842652, 1774082830, 1933815724, 2962865281, 1168579910, 2724829000, + 2360374019, 2315984659, 2360052375, 3251779801, 1664357844, 28, +]; +const POW5_11: [u32; 75] = [ + 689565697, 4116392818, 1853628763, 516071302, 2568769159, 365238920, 336250165, 1283268122, + 3425490969, 248595470, 2305176814, 2111925499, 507770399, 2681111421, 589114268, 591287751, + 1708941527, 4098957707, 475844916, 3378731398, 2452339615, 2817037361, 2678008327, 1656645978, + 2383430340, 73103988, 448667107, 2329420453, 3124020241, 3625235717, 3208634035, 2412059158, + 2981664444, 4117622508, 838560765, 3069470027, 270153238, 1802868219, 3692709886, 2161737865, + 2159912357, 2585798786, 837488486, 4237238160, 2540319504, 3798629246, 3748148874, 1021550776, + 2386715342, 1973637538, 1823520457, 1146713475, 833971519, 3277251466, 905620390, 26278816, + 2680483154, 2294040859, 373297482, 5996609, 4109575006, 512575049, 917036550, 1942311753, + 2816916778, 3248920332, 1192784020, 3537586671, 2456567643, 2925660628, 759380297, 888447942, + 3559939476, 3654687237, 805, +]; +const POW5_12: [u32; 149] = [ + 322166785, 3809044581, 2994556223, 1239584207, 3962455841, 4001882964, 3053876612, 915114683, + 2783289745, 785739093, 4253185907, 3931164994, 1370983858, 2553556126, 3360742076, 2255410929, + 422849554, 2457422215, 3539495362, 1720790602, 1908931983, 1470596141, 592794347, 4219465164, + 4085652704, 941661409, 2534650953, 885063988, 2355909854, 2812815516, 767256131, 3821757683, + 2155151105, 3817418473, 281116564, 2834395026, 2821201622, 2524625843, 1511330880, 2572352493, + 330571332, 2951088579, 2730271766, 4044456479, 4212286644, 2444937588, 3603420843, 2387148597, + 1142537539, 3299235429, 1751012624, 861228086, 2873722519, 230498814, 1023297821, 2553128038, + 3421129895, 2651917435, 2042981258, 1606787143, 2228751918, 447345732, 1930371132, 1784132011, + 3612538790, 2275925090, 2487567871, 1080427616, 2009179183, 3383506781, 3899054063, 1950782960, + 2168622213, 2717674390, 3616636027, 2079341593, 1530129217, 1461057425, 2406264415, 3674671357, + 2972036238, 2019354295, 1455849819, 1866918619, 1324269294, 424891864, 2722422332, 2641594816, + 1400249021, 3482963993, 3734946379, 225889849, 1891545473, 777383150, 3589824633, 4117601611, + 4220028667, 334453379, 1083130821, 1060342180, 4208163139, 1489826908, 4163762246, 1096580926, + 689301528, 2336054516, 1782865703, 4175148410, 3398369392, 2329412588, 3001580596, 59740741, + 3202189932, 3351895776, 246185302, 718535188, 3772647488, 4151666556, 4055698133, 2461934110, + 2281316281, 3466396836, 3536023465, 1064267812, 2955456354, 2423805422, 3627960790, 1325057500, + 3876919979, 2009959531, 175455101, 184092852, 2358785571, 3842977831, 2485266289, 487121622, + 4159252710, 4075707558, 459389244, 300652075, 2521346588, 3458976673, 888631636, 2076098096, + 3844514585, 2363697580, 3729421522, 3051115477, 649395, +]; +const POW5_13: [u32; 298] = [ + 711442433, 3564261005, 2399042279, 4170849936, 4010295575, 1423987028, 330414929, 1349249065, + 4213813618, 3852031822, 4040843590, 2154565331, 3094013374, 1159028371, 3227065538, 2115927092, + 2085102554, 488590542, 2609619432, 3602898805, 3812736528, 3269439096, 23816114, 253984538, + 1035905997, 2942969204, 3400787671, 338562688, 1637191975, 740509713, 2264962817, 3410753922, + 4162231428, 2282041228, 1759373012, 3155367777, 4278913285, 1420532801, 1981002276, 438054990, + 1006507643, 1142697287, 1332538012, 2029019521, 3949305784, 818392641, 2491288846, 2716584663, + 3648886102, 556814413, 444795339, 4071412999, 1066321706, 4253169466, 2510832316, 672091442, + 4083256000, 2165985028, 1841538484, 3549854235, 364431512, 3707648143, 1162785440, 2268641545, + 281340310, 735693841, 848809228, 1700785200, 2919703985, 4094234344, 58530286, 965505005, + 1000010347, 3381961808, 3040089923, 1973852082, 2890971585, 1019960210, 4292895237, 2821887841, + 3756675650, 3951282907, 3885870583, 1008791145, 503998487, 1881258362, 1949332730, 392996726, + 2012973814, 3970014187, 2461725150, 2942547730, 3728066699, 2766901132, 3778532841, 1085564064, + 2278673896, 1116879805, 3448726271, 774279411, 157211670, 1506320155, 531168605, 1362654525, + 956967721, 2148871960, 769186085, 4186232894, 2055679604, 3248365487, 3981268013, 3975787984, + 2489510517, 3309046495, 212771124, 933418041, 3371839114, 562115198, 1853601831, 757336096, + 1354633440, 1486083256, 2872126393, 522920738, 1141587749, 3210903262, 1926940553, 3054024853, + 2021162538, 2262742000, 1877899947, 3147002868, 669840763, 4158174590, 4238502559, 1023731922, + 3386840011, 829588074, 3449720188, 2835142880, 2999162007, 813056473, 482949569, 638108879, + 3067201471, 1026714238, 4004452838, 2383667807, 3999477803, 771648919, 630660440, 3827121348, + 176185980, 2878191002, 2666149832, 3909811063, 2429163983, 2665690412, 907266128, 4269332098, + 2022665808, 1527122180, 3072053668, 1072477492, 3006022924, 549664855, 2800340954, 37352654, + 1212772743, 2711280533, 3029527946, 2511120040, 1305308377, 3474662224, 4226330922, 442988428, + 954940108, 3274548099, 4212288177, 2688499880, 3982226758, 3922609956, 1279948029, 1939943640, + 3650489901, 2733364929, 2494263275, 1864579964, 1225941120, 2390465139, 1267503249, 3533240729, + 904410805, 2842550015, 2517736241, 1796069820, 3335274381, 673539835, 1924694759, 3598098235, + 2792633405, 16535707, 3703535497, 3592841791, 2929082877, 1317622811, 294990855, 1396706563, + 2383271770, 3853857605, 277813677, 277580220, 1101318484, 3761974115, 1132150143, 2544692622, + 3419825776, 743770306, 1695464553, 1548693232, 2421159615, 2575672031, 2678971806, 1591267897, + 626546738, 3823443129, 267710932, 1455435162, 2353985540, 3248523795, 335348168, 3872552561, + 2814522612, 2634118860, 3503767026, 1301019273, 1414467789, 722985138, 3070909565, 4253482569, + 3744939841, 558142907, 2229819389, 13833173, 77003966, 2763671364, 3905603970, 2931990126, + 2280419384, 1879090457, 2934846267, 4284933164, 2331863845, 62191163, 3178861020, 1522063815, + 785672270, 1215568492, 2936443917, 802972489, 2956820173, 3916732783, 2893572089, 1391232801, + 3168640330, 2396859648, 894950918, 1103583736, 961991865, 2807302642, 305977505, 3054505899, + 1048256994, 781017659, 2459278754, 3164823415, 537658277, 905753687, 464963300, 4149131560, + 1029507924, 2278300961, 1231291503, 414073408, 3630740085, 2345841814, 475358196, 3258243317, + 4167625072, 4178911231, 2927355042, 655438830, 3138378018, 623200562, 2785714112, 273403236, + 807993669, 98, +]; +const POW5_14: [u32; 595] = [ + 1691320321, 2671006246, 1682531301, 2072858707, 1240508969, 3108358191, 1125119096, 2470144952, + 1610099978, 1690632660, 1941696884, 2663506355, 1006364675, 3909158537, 4147711374, 1072663936, + 4078768933, 745751659, 4123687570, 471458681, 655028926, 4113407388, 3945524552, 985625313, + 1254424514, 2127508744, 570530434, 945388122, 3194649404, 2589065070, 2731705399, 202030749, + 2090780394, 3348662271, 1481754777, 1130635472, 4025144705, 1924486271, 2578567861, 125491448, + 1558036315, 994248173, 3817216711, 763950077, 1030439870, 959586474, 3845661701, 483795093, + 1637944470, 2275463649, 3398804829, 1758016486, 2665513698, 2004912571, 1094885097, 4223064276, + 3307819021, 651121777, 1757003305, 3603542336, 129917786, 2215974994, 3042386306, 2205352757, + 3944939700, 3710987569, 97967515, 1217242524, 930630949, 3660328512, 1787663098, 1784141600, + 2500542892, 4034561586, 3444961378, 785043562, 3869499367, 885623728, 2625011087, 3053789617, + 1965731793, 3900511934, 2648823592, 3851062028, 3321968688, 799195417, 1011847510, 1369129160, + 1348009103, 2876796955, 2915408967, 3305284948, 263399535, 1715990604, 2645821294, 1587844552, + 2624912049, 3035631499, 2306636348, 3499275462, 675152704, 854794152, 4004972748, 1739996642, + 1333476491, 4012621867, 3658792931, 3297985728, 2864481726, 3066357406, 785287846, 1671499798, + 433044045, 1919608025, 264833858, 3999983367, 1116778570, 1301982149, 4213901070, 4081649357, + 536169226, 1389008649, 188923873, 373495152, 2551132278, 1800758715, 3951840330, 2632334454, + 3118778225, 1034046547, 1862428410, 3037609062, 1994608505, 29051798, 2571685694, 264151332, + 2260643090, 2717535964, 3508441116, 3283713017, 1903365635, 923575694, 1219598101, 2288281570, + 3676533911, 1014136356, 555142354, 2389170030, 4185108175, 884862419, 836141292, 2957159173, + 1997444768, 4233903127, 2876184692, 3089125070, 1480848293, 1097600237, 299700527, 2507669891, + 2982628312, 2114881043, 2529576251, 2812279824, 2987750993, 4241938954, 2204775591, 1037094060, + 829315638, 1231047149, 52608178, 3735136637, 3455232602, 962039123, 488286513, 50685385, + 3516451821, 843975207, 1572355722, 675489076, 2428445672, 1555117248, 3708476086, 10375249, + 4172112346, 2117510871, 2227658327, 3187664554, 3050656558, 328034318, 3179601324, 1247769761, + 3439263953, 1431538938, 2962525068, 1213366289, 3813013550, 2651093719, 1860661503, 3933716208, + 264320617, 789980519, 2257856172, 102000748, 977269860, 1113845122, 3008928583, 1461738106, + 557786285, 2926560363, 1038106190, 3643478847, 828004507, 457818698, 1933056971, 373408056, + 2076808229, 3160935130, 2781854874, 2519636100, 177606000, 4237103862, 3977834316, 1621936232, + 2599050516, 319893558, 3343370366, 765044144, 976657331, 7026264, 294277429, 3829376742, + 3029627280, 2705178718, 3614653880, 230519152, 3288033233, 293525479, 3805751881, 3227511198, + 2520308544, 3648103003, 1111086184, 437622105, 2232033852, 3239146386, 584244184, 1450926016, + 2462430443, 3226534010, 298582169, 4214576928, 1762099469, 964985185, 1585788148, 1641127666, + 787006566, 2315956284, 3258232694, 2275058964, 2541003317, 1508235863, 2613339827, 4080647514, + 1152057965, 3149266279, 731345410, 914737650, 65395712, 1884566942, 1379520432, 2611027720, + 4163073378, 2619704967, 2746552541, 1388822415, 3005141199, 843440249, 4288674003, 3136174279, + 4051522914, 4144149433, 3427566947, 3419023197, 3758479825, 3893877676, 96899594, 1657725776, + 253618880, 434129337, 1499045748, 2996992534, 4036042074, 2110713869, 906222950, 928326225, + 2541827893, 1604330202, 226792470, 4022228930, 815850898, 1466012310, 3377712199, 292769859, + 2822055597, 3225701344, 3052947004, 385831222, 705324593, 4030158636, 3540280538, 2982120874, + 2136414455, 255762046, 3852783591, 3262064164, 2358991588, 3756586117, 4143612643, 3326743817, + 2897365738, 807711264, 3719310016, 3721264861, 3627337076, 944539331, 3640975513, 3712525681, + 1162911839, 2008243316, 2179489649, 2867584109, 261861553, 3570253908, 2062868357, 2220328623, + 3857004679, 3744109002, 4138041873, 1451860932, 2364975637, 2802161722, 2680106834, 753401584, + 1223182946, 1245401957, 4163377735, 3565815922, 2216942838, 4036140094, 71979081, 3924559643, + 400477238, 551750683, 1174153235, 859969898, 1185921017, 1711399735, 812991545, 4051735761, + 3549118738, 1631653329, 3631835958, 3648867800, 1206500363, 2155893137, 361030362, 3454286017, + 2505909489, 1083595169, 453595313, 1510564703, 1706163902, 1632924345, 1381875722, 1661526119, + 1082778324, 3571910052, 1140625929, 851544870, 1145546234, 2938573139, 907528924, 1304752338, + 1764668294, 1788942063, 1700368828, 104979467, 1413911959, 3327497828, 1956384744, 1272712474, + 2815637534, 3307809377, 1320574940, 1111968962, 4073107827, 434096622, 169451929, 3201183459, + 3331028877, 2852366972, 3369830128, 2924794558, 3106537952, 3739481231, 1612955817, 4138608722, + 2721281595, 2755775390, 843505117, 982234295, 1157276611, 814674632, 4246504726, 3532006708, + 992340967, 1647538031, 204696133, 193866982, 3899126129, 300851698, 1379496684, 1759463683, + 1354782756, 1374637239, 3410883240, 1073406229, 3038431791, 1053909855, 3607043270, 173719711, + 3733903830, 171820911, 1573050589, 932781534, 4183534770, 2158849555, 372245998, 3573073830, + 841339264, 2759200520, 1610547277, 2603293319, 3890906486, 1557138278, 3964109906, 677238797, + 537994297, 1124184993, 4287078344, 4207654540, 2943022776, 2977947524, 3255359985, 4098397558, + 2274666217, 2915862060, 243524940, 2467726756, 2869020032, 507521339, 3403121914, 522051455, + 1803903108, 3471254194, 473535371, 1948602036, 3352095732, 3116527002, 1795743673, 775867940, + 2551469548, 3757442064, 3162525227, 3765412747, 3040105484, 1927625810, 48214767, 2997207130, + 1342349989, 2536583992, 1501320191, 3592287317, 887432730, 967585477, 3334212779, 948663609, + 1064513472, 15386372, 2465931737, 3230242590, 3036652803, 2063155087, 1927500726, 2821790499, + 2187774383, 501520074, 3688568496, 3606711121, 2576459247, 3176542345, 378322447, 156541411, + 1400607301, 1406179107, 677848877, 2253753529, 193196070, 4207435024, 4166396241, 509467541, + 2906024136, 1221753746, 3375413222, 431327897, 2749265123, 2848827671, 3412997614, 2051920238, + 1283516885, 1300498239, 1957256104, 2634010560, 3531900395, 360276850, 1461184973, 2012063967, + 2873572430, 2914608609, 4289554777, 1539331673, 1859532928, 4213441063, 538215691, 3512720863, + 4258743698, 3040408445, 982396546, 343095663, 4138069496, 1021581857, 214185242, 1968079460, + 2864275059, 3347192726, 4096783459, 3259169450, 3707808869, 142485006, 399610869, 230556456, + 2219467721, 4191227798, 2242548189, 3136366572, 179755707, 3464881829, 452317775, 3887426070, + 3446430233, 1473370015, 1576807208, 3964523248, 419325089, 2373067114, 1596072055, 1928415752, + 3635452689, 1005598891, 3335462724, 3290848636, 3669078247, 1178176812, 2110774376, 3068593619, + 1253036518, 908857731, 3631223047, 4138506423, 2903592318, 3596915748, 3289036113, 3721512676, + 2704409359, 3386016968, 3676268074, 2185259502, 1096257611, 3360076717, 3548676554, 170167319, + 3360064287, 3899940843, 9640, +]; + +pub(crate) const POW5: [&'static [u32]; 14] = [ + &POW5_1, &POW5_2, &POW5_3, &POW5_4, &POW5_5, &POW5_6, &POW5_7, &POW5_8, &POW5_9, &POW5_10, + &POW5_11, &POW5_12, &POW5_13, &POW5_14, +]; diff --git a/vendor/serde_json/src/lexical/large_powers64.rs b/vendor/serde_json/src/lexical/large_powers64.rs new file mode 100644 index 0000000..96554ea --- /dev/null +++ b/vendor/serde_json/src/lexical/large_powers64.rs @@ -0,0 +1,625 @@ +// Adapted from https://github.com/Alexhuszagh/rust-lexical. + +//! Precalculated large powers for 64-bit limbs. + +/// Large powers (`&[u64]`) for base5 operations. +const POW5_1: [u64; 1] = [5]; +const POW5_2: [u64; 1] = [25]; +const POW5_3: [u64; 1] = [625]; +const POW5_4: [u64; 1] = [390625]; +const POW5_5: [u64; 1] = [152587890625]; +const POW5_6: [u64; 2] = [3273344365508751233, 1262]; +const POW5_7: [u64; 3] = [7942358959831785217, 16807427164405733357, 1593091]; +const POW5_8: [u64; 5] = [ + 279109966635548161, + 2554917779393558781, + 14124656261812188652, + 11976055582626787546, + 2537941837315, +]; +const POW5_9: [u64; 10] = [ + 13750482914757213185, + 1302999927698857842, + 14936872543252795590, + 2788415840139466767, + 2095640732773017264, + 7205570348933370714, + 7348167152523113408, + 9285516396840364274, + 6907659600622710236, + 349175, +]; +const POW5_10: [u64; 19] = [ + 8643096425819600897, + 6743743997439985372, + 14059704609098336919, + 10729359125898331411, + 4933048501514368705, + 12258131603170554683, + 2172371001088594721, + 13569903330219142946, + 13809142207969578845, + 16716360519037769646, + 9631256923806107285, + 12866941232305103710, + 1397931361048440292, + 7619627737732970332, + 12725409486282665900, + 11703051443360963910, + 9947078370803086083, + 13966287901448440471, + 121923442132, +]; +const POW5_11: [u64; 38] = [ + 17679772531488845825, + 2216509366347768155, + 1568689219195129479, + 5511594616325588277, + 1067709417009240089, + 9070650952098657518, + 11515285870634858015, + 2539561553659505564, + 17604889300961091799, + 14511540856854204724, + 12099083339557485471, + 7115240299237943815, + 313979240050606788, + 10004784664717172195, + 15570268847930131473, + 10359715202835930803, + 17685054012115162812, + 13183273382855797757, + 7743260039872919062, + 9284593436392572926, + 11105921222066415013, + 18198799323400703846, + 16314988383739458320, + 4387527177871570570, + 8476708682254672590, + 4925096874831034057, + 14075687868072027455, + 112866656203221926, + 9852830467773230418, + 25755239915196746, + 2201493076310172510, + 8342165458688466438, + 13954006576066379050, + 15193819059903295636, + 12565616718911389531, + 3815854855847885129, + 15696762163583540628, + 805, +]; +const POW5_12: [u64; 75] = [ + 16359721904723189761, + 5323973632697650495, + 17187956456762001185, + 3930387638628283780, + 3374723710406992273, + 16884225088663222131, + 10967440051041439154, + 9686916182456720060, + 10554548046311730194, + 7390739362393647554, + 6316162333127736719, + 18122464886584070891, + 4044404959645932768, + 3801320885861987401, + 12080950653257274590, + 16414324262488991299, + 16395687498836410113, + 12173633940896186260, + 10843185433142632150, + 11048169832730399808, + 12674828934734683716, + 17370808310130582550, + 10500926985433408692, + 10252725158410704555, + 14170108270502067523, + 3698946465517688080, + 989984870770509463, + 10965601426733943069, + 11389898658438335655, + 6901098232861256586, + 1921335291173932590, + 7662788640922083388, + 9775023833308395430, + 4640401278902814207, + 14532050972198413359, + 8378549018693130223, + 11672322628395371653, + 8930704142764178555, + 6275193859483102017, + 15782593304269205087, + 8673060659034172558, + 8018354414354334043, + 1824896661540749038, + 11345563346725559868, + 14959216444480821949, + 970189517688324683, + 3338835207603007873, + 17684964260791738489, + 1436466329061721851, + 4554134986752476101, + 6398757850768963907, + 4709779218751158342, + 10033277748582410264, + 17932125878679265063, + 10004750887749091440, + 256584531835386932, + 14396282740722731628, + 3086085133731396950, + 17831272085689600064, + 10573926491412564693, + 14888061047859191737, + 4570995450261499817, + 10410165022312935266, + 5691078631447480790, + 8632710455805418155, + 790672778942823293, + 16505464105756800547, + 2092171438149740401, + 17505030673829275878, + 1291290830058928444, + 14856191690683232796, + 8916773426496500052, + 10152003807578858265, + 13104441193763861714, + 649395, +]; +const POW5_13: [u64; 149] = [ + 15308384451594534913, + 17913664074042735335, + 6115977719198531863, + 5794980608663993169, + 16544350702855106930, + 9253787637781258566, + 4977988951675168190, + 9087837664087448770, + 2098480401110016986, + 15474332540882100712, + 14042133997396540944, + 1090855284423485362, + 12639956485351058381, + 1454115676006639319, + 3180465001342538023, + 14649076551958697729, + 9801292446545910916, + 13552201410826594004, + 6101141927469189381, + 1881431857880609316, + 4907847477899433595, + 8714572486973123228, + 3514969632331374520, + 11667642286891470094, + 2391499697425323350, + 17486585679659076043, + 18267223761882105642, + 2886610765822313148, + 9302834862968900288, + 15246507846733637044, + 15924227519624562840, + 9743741243284697760, + 3159780987244964246, + 7304816812369628428, + 17584602612559717809, + 4146812420657846766, + 14525415362681041515, + 8477630142371600195, + 4380695748062263745, + 12119915994367943173, + 16970630866565485122, + 4332724980155264503, + 8079943140620527639, + 1687908087554405626, + 17051081099834002166, + 12638146269730763230, + 11883749876933445771, + 4662462156371383785, + 4796962238316531176, + 3325504751659868927, + 6469595803187862550, + 5852556621152583005, + 9229334792448387881, + 17979733373938620709, + 13951623534175792756, + 17075879371091039277, + 14212246479457938037, + 4008999959804158260, + 2414266395366403722, + 3252733766253918247, + 6382678985007829216, + 2245927470982310841, + 13790724502051307301, + 13116936866733148041, + 9718402891306794538, + 13516274400356104875, + 17859223875778049403, + 4396895129099725471, + 3563053650368467915, + 12176845952536972668, + 3492050964335269015, + 2740656767075170753, + 4409704077614761919, + 10237775279597492710, + 3314206875098230827, + 16437361028114095448, + 12361736225407656572, + 16792510651790145480, + 11449053143229929935, + 18336641737580333136, + 6558939822118891088, + 4606255756908155300, + 2360792578991605004, + 160428430149144538, + 11644861220729221511, + 10785178451159739786, + 14923560618031934681, + 1902620814992781610, + 14064076995338910412, + 11547019064112212657, + 16847481479966225734, + 8331994491163145469, + 11739712981738851885, + 8008309968651120619, + 10266969595459035264, + 15175153381217702033, + 12208659352573720245, + 7714061140750342961, + 2892831567213510541, + 15453714249045017319, + 71020323573871677, + 15431137995750602633, + 5659146884637671933, + 5998809010488554503, + 16552192379299157850, + 1192197967194298797, + 16157555793424861524, + 10929371590994640255, + 3194469143425738352, + 6651586784672005225, + 11062427140788057791, + 6834443579468668318, + 16421563197797455922, + 6251046422506172884, + 13952303462156793860, + 16632486601871393224, + 11313454360291325172, + 5587835232504462834, + 3105197524618514637, + 18268568531031972989, + 2397205535804309313, + 59413027864729597, + 11869878125348715710, + 12592801707270523266, + 8070632061321113656, + 18403647807860650811, + 267109013517069093, + 6537214311028855260, + 5220826919973709902, + 3448740582779163661, + 16822239213112884941, + 5975299384311048185, + 10294433804430712138, + 4739856055412448774, + 12057273038326387897, + 13119002941950056609, + 3354445304051737058, + 13592813067499314594, + 3890182464434078629, + 17820384357466425060, + 9785228118969879380, + 1778431746734556271, + 10075313876350055029, + 13994048489400919028, + 17948287074199726448, + 2815088342305858722, + 2676626035777198370, + 1174257960026283968, + 421714788677, +]; +const POW5_14: [u64; 298] = [ + 11471884475673051137, + 8902860357476377573, + 13350296775839230505, + 10609191786344608888, + 7261211985859587338, + 11439672689354862964, + 16789708072300570627, + 4607056528866348430, + 3202978990421512997, + 2024899620433984146, + 17666950207239811774, + 4233228489390288200, + 9137580478688460738, + 4060411066587388546, + 11119949806060600124, + 867715462473090103, + 14382394941384869610, + 4856042377419278489, + 8265605599571137921, + 538981667666252469, + 4270263388700786523, + 3281140600308898503, + 4121392524544394174, + 2077884106245940229, + 9773041957329767574, + 7550623316597646685, + 8611033926449791714, + 18137922955420802793, + 2796546741236224013, + 15477096484628446761, + 9517540128113714010, + 9471917970500821378, + 15938570248662483124, + 5228016831978462619, + 15720991252586974501, + 7662829825220776698, + 17328310068068434348, + 3371736428170309730, + 3803724952191098855, + 13115926536504376719, + 16752571196153442257, + 16540185467776259880, + 3432518182450051120, + 5880364967211798870, + 12355748840305392783, + 14196090758536469575, + 7370123524686686319, + 6819740424617592686, + 13037938013537368753, + 15029273671291927100, + 3671312928327205696, + 7473228676544792780, + 17234079691312938123, + 14164740848093544419, + 13169904779481875902, + 7179036968465894054, + 8244653688947194445, + 17179797746073799490, + 5591970751047577674, + 17530550506268329742, + 5965746721852312330, + 1604149463243472865, + 7734199791463116918, + 11305790396015856714, + 4441196105025505137, + 13046431581185664762, + 124776524294606713, + 1134521334706523966, + 11671728093344476434, + 14103440020972933148, + 3966727403013869059, + 9828094508409132821, + 4355682486381147287, + 10261407143988481234, + 3800455155249557199, + 12700901937937547500, + 18184475466894579360, + 13267691151779895412, + 4714157123477697445, + 10770360171308585263, + 9083344917597998040, + 12078649873810212155, + 18218989082046199377, + 4454285072780637351, + 5287307245618354742, + 16042289702059031730, + 4131926574212754010, + 217692071448455473, + 3624845916216282093, + 2901203491797614218, + 6679177724033967080, + 44561358851332790, + 9094639944041587162, + 13690915012276084311, + 1408896670826320686, + 5359130319612337580, + 6148412925099835601, + 5211368532286409612, + 11386360825549027374, + 16895182466965795071, + 3392940493846427241, + 438089879085393580, + 4783928372776399972, + 6278117363595909959, + 12569481049412674733, + 15648622492570893902, + 1966316336235305115, + 1603775390515993547, + 13576113010204316709, + 10821754650102840474, + 18198222517222903152, + 6966163076615302988, + 1373932372410129684, + 3285839581819684990, + 30177575069719475, + 16447047871247307061, + 11618654126674833808, + 990072222556306872, + 1260682336135768017, + 13862055046689532489, + 15668483092844698432, + 1879572630092764264, + 13912027797058626108, + 6231679788219816920, + 13857858054844167403, + 18101470072534728857, + 4144579812461609229, + 7048589655616599284, + 9946956499532694630, + 9771303850109874038, + 6477823708780339765, + 17526247621747041971, + 13525995675852669549, + 3928768291901239810, + 8094153383078124544, + 11214278667728965552, + 11251547162596832610, + 5964946855123292381, + 3622548288590237903, + 13469765967150053587, + 17798986288523466082, + 14684592818807932259, + 16724077276802963921, + 7119877993753121290, + 1864571304902781632, + 12871984921385213812, + 9065447042604670298, + 3987130777300360550, + 6890545752116901685, + 17275341711601865750, + 6296474927799264658, + 1257436973037243463, + 13854281781965301421, + 1657132483318662716, + 17309399540017292849, + 12808111630089217242, + 1098489625264462071, + 14010458905686364135, + 16134414519481621220, + 14288255900328821475, + 3469093466388187882, + 15982710881468295872, + 4056765540058056052, + 15945176389096104089, + 8625339365793505375, + 12316179968863788913, + 15334123773538054321, + 9536238824220581765, + 16080825720106203271, + 6235695225418121745, + 12035192956458019349, + 3235835166714703698, + 5348960676912581218, + 15315062772709464647, + 17335089708021308662, + 16855855317958414409, + 2369751139431140406, + 3693542588628609043, + 7350405893393987577, + 17402072586341663801, + 7007897690013647122, + 15671767872059304758, + 9259490518292347915, + 14836045474406130394, + 4654005815464502513, + 6487825998330548401, + 7013356660323385022, + 7136200343936679946, + 15341236858676437716, + 3657357368867197449, + 12621075530054608378, + 5603868621997066972, + 7683447656788439942, + 450883379216880060, + 14291494350184945047, + 5466258454997635048, + 14206933098432772126, + 4775870327277641692, + 1864430798867181939, + 13748978265070608793, + 12250822864261576589, + 12561896977498605296, + 16060949594257359328, + 17775189113543311529, + 11835965177892927035, + 4218664174878121437, + 3499000902478111683, + 15169853304359126294, + 7076121963053575143, + 832652347668916805, + 1292148207755194737, + 7556838978364207852, + 5904021986723518500, + 4610244652288570024, + 4526508363195533871, + 746120481022614726, + 737965197247830486, + 4006266184415762653, + 9272188239892688050, + 15346235246415709678, + 11850675997347533184, + 11181059668610842701, + 6687857983250662774, + 2908718488661492818, + 4828337780126983225, + 18071738646453002184, + 12790187227727197880, + 17602483480871623153, + 12523532189621855977, + 10598805712727696716, + 2179787555896149376, + 2242193929457337594, + 14908923241136742532, + 8369182018012550027, + 13385381554043022324, + 3332327430110633913, + 16138090784046208492, + 16172324607469047339, + 8279089815915615244, + 12872906602736235247, + 10894545290539475621, + 15428756545851905023, + 4155747980686992922, + 4074479178894544043, + 66083965608603584, + 13873786284662268377, + 8861183628277687555, + 12119497911296021430, + 2154012318305274287, + 15490706314503067312, + 13643145488710608367, + 672340241093017103, + 6039493278284091973, + 9679797700977436461, + 18070795828318171174, + 2188146431134935377, + 5247392385741514952, + 1852539214842869734, + 12235621681634112739, + 8812930319623534062, + 5585597406294108629, + 11312989214475901864, + 1547377291787797995, + 8641748937186208205, + 12518148659168623694, + 6611379197521520985, + 18096591571068008576, + 15087021227100112139, + 13058454842015958418, + 1473584652966833794, + 4387660670140018168, + 8452836916843525402, + 14376083294443363955, + 13998026203969090659, + 611968444648172645, + 990232438801273845, + 18001186324715561929, + 13470591857250177501, + 14881554140239420091, + 16696367836720124495, + 6328076032778459673, + 17027497695968504616, + 10192245646262428833, + 8282482589527318647, + 4319014353374321425, + 14134087271041670980, + 5060230880114618599, + 13179509240430058600, + 3903514232614801894, + 17774749744702165255, + 15448635507030969726, + 15983775238358480209, + 14542832143965487887, + 9385618098039514666, + 14431419612662304843, + 730863073501675978, + 16750118380379734815, + 9640, +]; + +pub(crate) const POW5: [&[u64]; 14] = [ + &POW5_1, &POW5_2, &POW5_3, &POW5_4, &POW5_5, &POW5_6, &POW5_7, &POW5_8, &POW5_9, &POW5_10, + &POW5_11, &POW5_12, &POW5_13, &POW5_14, +]; diff --git a/vendor/serde_json/src/lexical/math.rs b/vendor/serde_json/src/lexical/math.rs new file mode 100644 index 0000000..2e900f1 --- /dev/null +++ b/vendor/serde_json/src/lexical/math.rs @@ -0,0 +1,884 @@ +// Adapted from https://github.com/Alexhuszagh/rust-lexical. + +//! Building-blocks for arbitrary-precision math. +//! +//! These algorithms assume little-endian order for the large integer +//! buffers, so for a `vec![0, 1, 2, 3]`, `3` is the most significant limb, +//! and `0` is the least significant limb. + +use super::large_powers; +use super::num::*; +use super::small_powers::*; +use alloc::vec::Vec; +use core::{cmp, iter, mem}; + +// ALIASES +// ------- + +// Type for a single limb of the big integer. +// +// A limb is analogous to a digit in base10, except, it stores 32-bit +// or 64-bit numbers instead. +// +// This should be all-known 64-bit platforms supported by Rust. +// https://forge.rust-lang.org/platform-support.html +// +// Platforms where native 128-bit multiplication is explicitly supported: +// - x86_64 (Supported via `MUL`). +// - mips64 (Supported via `DMULTU`, which `HI` and `LO` can be read-from). +// +// Platforms where native 64-bit multiplication is supported and +// you can extract hi-lo for 64-bit multiplications. +// aarch64 (Requires `UMULH` and `MUL` to capture high and low bits). +// powerpc64 (Requires `MULHDU` and `MULLD` to capture high and low bits). +// +// Platforms where native 128-bit multiplication is not supported, +// requiring software emulation. +// sparc64 (`UMUL` only supported double-word arguments). + +// 32-BIT LIMB +#[cfg(fast_arithmetic = "32")] +pub type Limb = u32; + +#[cfg(fast_arithmetic = "32")] +pub const POW5_LIMB: &[Limb] = &POW5_32; + +#[cfg(fast_arithmetic = "32")] +pub const POW10_LIMB: &[Limb] = &POW10_32; + +#[cfg(fast_arithmetic = "32")] +type Wide = u64; + +// 64-BIT LIMB +#[cfg(fast_arithmetic = "64")] +pub type Limb = u64; + +#[cfg(fast_arithmetic = "64")] +pub const POW5_LIMB: &[Limb] = &POW5_64; + +#[cfg(fast_arithmetic = "64")] +pub const POW10_LIMB: &[Limb] = &POW10_64; + +#[cfg(fast_arithmetic = "64")] +type Wide = u128; + +/// Cast to limb type. +#[inline] +pub(crate) fn as_limb(t: T) -> Limb { + Limb::as_cast(t) +} + +/// Cast to wide type. +#[inline] +fn as_wide(t: T) -> Wide { + Wide::as_cast(t) +} + +// SPLIT +// ----- + +/// Split u64 into limbs, in little-endian order. +#[inline] +#[cfg(fast_arithmetic = "32")] +fn split_u64(x: u64) -> [Limb; 2] { + [as_limb(x), as_limb(x >> 32)] +} + +/// Split u64 into limbs, in little-endian order. +#[inline] +#[cfg(fast_arithmetic = "64")] +fn split_u64(x: u64) -> [Limb; 1] { + [as_limb(x)] +} + +// HI64 +// ---- + +// NONZERO + +/// Check if any of the remaining bits are non-zero. +#[inline] +pub fn nonzero(x: &[T], rindex: usize) -> bool { + let len = x.len(); + let slc = &x[..len - rindex]; + slc.iter().rev().any(|&x| x != T::ZERO) +} + +/// Shift 64-bit integer to high 64-bits. +#[inline] +fn u64_to_hi64_1(r0: u64) -> (u64, bool) { + debug_assert!(r0 != 0); + let ls = r0.leading_zeros(); + (r0 << ls, false) +} + +/// Shift 2 64-bit integers to high 64-bits. +#[inline] +fn u64_to_hi64_2(r0: u64, r1: u64) -> (u64, bool) { + debug_assert!(r0 != 0); + let ls = r0.leading_zeros(); + let rs = 64 - ls; + let v = match ls { + 0 => r0, + _ => (r0 << ls) | (r1 >> rs), + }; + let n = r1 << ls != 0; + (v, n) +} + +/// Trait to export the high 64-bits from a little-endian slice. +trait Hi64: AsRef<[T]> { + /// Get the hi64 bits from a 1-limb slice. + fn hi64_1(&self) -> (u64, bool); + + /// Get the hi64 bits from a 2-limb slice. + fn hi64_2(&self) -> (u64, bool); + + /// Get the hi64 bits from a 3-limb slice. + fn hi64_3(&self) -> (u64, bool); + + /// High-level exporter to extract the high 64 bits from a little-endian slice. + #[inline] + fn hi64(&self) -> (u64, bool) { + match self.as_ref().len() { + 0 => (0, false), + 1 => self.hi64_1(), + 2 => self.hi64_2(), + _ => self.hi64_3(), + } + } +} + +impl Hi64 for [u32] { + #[inline] + fn hi64_1(&self) -> (u64, bool) { + debug_assert!(self.len() == 1); + let r0 = self[0] as u64; + u64_to_hi64_1(r0) + } + + #[inline] + fn hi64_2(&self) -> (u64, bool) { + debug_assert!(self.len() == 2); + let r0 = (self[1] as u64) << 32; + let r1 = self[0] as u64; + u64_to_hi64_1(r0 | r1) + } + + #[inline] + fn hi64_3(&self) -> (u64, bool) { + debug_assert!(self.len() >= 3); + let r0 = self[self.len() - 1] as u64; + let r1 = (self[self.len() - 2] as u64) << 32; + let r2 = self[self.len() - 3] as u64; + let (v, n) = u64_to_hi64_2(r0, r1 | r2); + (v, n || nonzero(self, 3)) + } +} + +impl Hi64 for [u64] { + #[inline] + fn hi64_1(&self) -> (u64, bool) { + debug_assert!(self.len() == 1); + let r0 = self[0]; + u64_to_hi64_1(r0) + } + + #[inline] + fn hi64_2(&self) -> (u64, bool) { + debug_assert!(self.len() >= 2); + let r0 = self[self.len() - 1]; + let r1 = self[self.len() - 2]; + let (v, n) = u64_to_hi64_2(r0, r1); + (v, n || nonzero(self, 2)) + } + + #[inline] + fn hi64_3(&self) -> (u64, bool) { + self.hi64_2() + } +} + +// SCALAR +// ------ + +// Scalar-to-scalar operations, for building-blocks for arbitrary-precision +// operations. + +mod scalar { + use super::*; + + // ADDITION + + /// Add two small integers and return the resulting value and if overflow happens. + #[inline] + pub fn add(x: Limb, y: Limb) -> (Limb, bool) { + x.overflowing_add(y) + } + + /// AddAssign two small integers and return if overflow happens. + #[inline] + pub fn iadd(x: &mut Limb, y: Limb) -> bool { + let t = add(*x, y); + *x = t.0; + t.1 + } + + // SUBTRACTION + + /// Subtract two small integers and return the resulting value and if overflow happens. + #[inline] + pub fn sub(x: Limb, y: Limb) -> (Limb, bool) { + x.overflowing_sub(y) + } + + /// SubAssign two small integers and return if overflow happens. + #[inline] + pub fn isub(x: &mut Limb, y: Limb) -> bool { + let t = sub(*x, y); + *x = t.0; + t.1 + } + + // MULTIPLICATION + + /// Multiply two small integers (with carry) (and return the overflow contribution). + /// + /// Returns the (low, high) components. + #[inline] + pub fn mul(x: Limb, y: Limb, carry: Limb) -> (Limb, Limb) { + // Cannot overflow, as long as wide is 2x as wide. This is because + // the following is always true: + // `Wide::max_value() - (Narrow::max_value() * Narrow::max_value()) >= Narrow::max_value()` + let z: Wide = as_wide(x) * as_wide(y) + as_wide(carry); + let bits = mem::size_of::() * 8; + (as_limb(z), as_limb(z >> bits)) + } + + /// Multiply two small integers (with carry) (and return if overflow happens). + #[inline] + pub fn imul(x: &mut Limb, y: Limb, carry: Limb) -> Limb { + let t = mul(*x, y, carry); + *x = t.0; + t.1 + } +} // scalar + +// SMALL +// ----- + +// Large-to-small operations, to modify a big integer from a native scalar. + +mod small { + use super::*; + + // ADDITION + + /// Implied AddAssign implementation for adding a small integer to bigint. + /// + /// Allows us to choose a start-index in x to store, to allow incrementing + /// from a non-zero start. + #[inline] + pub fn iadd_impl(x: &mut Vec, y: Limb, xstart: usize) { + if x.len() <= xstart { + x.push(y); + } else { + // Initial add + let mut carry = scalar::iadd(&mut x[xstart], y); + + // Increment until overflow stops occurring. + let mut size = xstart + 1; + while carry && size < x.len() { + carry = scalar::iadd(&mut x[size], 1); + size += 1; + } + + // If we overflowed the buffer entirely, need to add 1 to the end + // of the buffer. + if carry { + x.push(1); + } + } + } + + /// AddAssign small integer to bigint. + #[inline] + pub fn iadd(x: &mut Vec, y: Limb) { + iadd_impl(x, y, 0); + } + + // SUBTRACTION + + /// SubAssign small integer to bigint. + /// Does not do overflowing subtraction. + #[inline] + pub fn isub_impl(x: &mut Vec, y: Limb, xstart: usize) { + debug_assert!(x.len() > xstart && (x[xstart] >= y || x.len() > xstart + 1)); + + // Initial subtraction + let mut carry = scalar::isub(&mut x[xstart], y); + + // Increment until overflow stops occurring. + let mut size = xstart + 1; + while carry && size < x.len() { + carry = scalar::isub(&mut x[size], 1); + size += 1; + } + normalize(x); + } + + // MULTIPLICATION + + /// MulAssign small integer to bigint. + #[inline] + pub fn imul(x: &mut Vec, y: Limb) { + // Multiply iteratively over all elements, adding the carry each time. + let mut carry: Limb = 0; + for xi in &mut *x { + carry = scalar::imul(xi, y, carry); + } + + // Overflow of value, add to end. + if carry != 0 { + x.push(carry); + } + } + + /// Mul small integer to bigint. + #[inline] + pub fn mul(x: &[Limb], y: Limb) -> Vec { + let mut z = Vec::::default(); + z.extend_from_slice(x); + imul(&mut z, y); + z + } + + /// MulAssign by a power. + /// + /// Theoretically... + /// + /// Use an exponentiation by squaring method, since it reduces the time + /// complexity of the multiplication to ~`O(log(n))` for the squaring, + /// and `O(n*m)` for the result. Since `m` is typically a lower-order + /// factor, this significantly reduces the number of multiplications + /// we need to do. Iteratively multiplying by small powers follows + /// the nth triangular number series, which scales as `O(p^2)`, but + /// where `p` is `n+m`. In short, it scales very poorly. + /// + /// Practically.... + /// + /// Exponentiation by Squaring: + /// running 2 tests + /// test bigcomp_f32_lexical ... bench: 1,018 ns/iter (+/- 78) + /// test bigcomp_f64_lexical ... bench: 3,639 ns/iter (+/- 1,007) + /// + /// Exponentiation by Iterative Small Powers: + /// running 2 tests + /// test bigcomp_f32_lexical ... bench: 518 ns/iter (+/- 31) + /// test bigcomp_f64_lexical ... bench: 583 ns/iter (+/- 47) + /// + /// Exponentiation by Iterative Large Powers (of 2): + /// running 2 tests + /// test bigcomp_f32_lexical ... bench: 671 ns/iter (+/- 31) + /// test bigcomp_f64_lexical ... bench: 1,394 ns/iter (+/- 47) + /// + /// Even using worst-case scenarios, exponentiation by squaring is + /// significantly slower for our workloads. Just multiply by small powers, + /// in simple cases, and use precalculated large powers in other cases. + pub fn imul_pow5(x: &mut Vec, n: u32) { + use super::large::KARATSUBA_CUTOFF; + + let small_powers = POW5_LIMB; + let large_powers = large_powers::POW5; + + if n == 0 { + // No exponent, just return. + // The 0-index of the large powers is `2^0`, which is 1, so we want + // to make sure we don't take that path with a literal 0. + return; + } + + // We want to use the asymptotically faster algorithm if we're going + // to be using Karabatsu multiplication sometime during the result, + // otherwise, just use exponentiation by squaring. + let bit_length = 32 - n.leading_zeros() as usize; + debug_assert!(bit_length != 0 && bit_length <= large_powers.len()); + if x.len() + large_powers[bit_length - 1].len() < 2 * KARATSUBA_CUTOFF { + // We can use iterative small powers to make this faster for the + // easy cases. + + // Multiply by the largest small power until n < step. + let step = small_powers.len() - 1; + let power = small_powers[step]; + let mut n = n as usize; + while n >= step { + imul(x, power); + n -= step; + } + + // Multiply by the remainder. + imul(x, small_powers[n]); + } else { + // In theory, this code should be asymptotically a lot faster, + // in practice, our small::imul seems to be the limiting step, + // and large imul is slow as well. + + // Multiply by higher order powers. + let mut idx: usize = 0; + let mut bit: usize = 1; + let mut n = n as usize; + while n != 0 { + if n & bit != 0 { + debug_assert!(idx < large_powers.len()); + large::imul(x, large_powers[idx]); + n ^= bit; + } + idx += 1; + bit <<= 1; + } + } + } + + // BIT LENGTH + + /// Get number of leading zero bits in the storage. + #[inline] + pub fn leading_zeros(x: &[Limb]) -> usize { + x.last().map_or(0, |x| x.leading_zeros() as usize) + } + + /// Calculate the bit-length of the big-integer. + #[inline] + pub fn bit_length(x: &[Limb]) -> usize { + let bits = mem::size_of::() * 8; + // Avoid overflowing, calculate via total number of bits + // minus leading zero bits. + let nlz = leading_zeros(x); + bits.checked_mul(x.len()) + .map_or_else(usize::max_value, |v| v - nlz) + } + + // SHL + + /// Shift-left bits inside a buffer. + /// + /// Assumes `n < Limb::BITS`, IE, internally shifting bits. + #[inline] + pub fn ishl_bits(x: &mut Vec, n: usize) { + // Need to shift by the number of `bits % Limb::BITS)`. + let bits = mem::size_of::() * 8; + debug_assert!(n < bits); + if n == 0 { + return; + } + + // Internally, for each item, we shift left by n, and add the previous + // right shifted limb-bits. + // For example, we transform (for u8) shifted left 2, to: + // b10100100 b01000010 + // b10 b10010001 b00001000 + let rshift = bits - n; + let lshift = n; + let mut prev: Limb = 0; + for xi in &mut *x { + let tmp = *xi; + *xi <<= lshift; + *xi |= prev >> rshift; + prev = tmp; + } + + // Always push the carry, even if it creates a non-normal result. + let carry = prev >> rshift; + if carry != 0 { + x.push(carry); + } + } + + /// Shift-left `n` digits inside a buffer. + /// + /// Assumes `n` is not 0. + #[inline] + pub fn ishl_limbs(x: &mut Vec, n: usize) { + debug_assert!(n != 0); + if !x.is_empty() { + x.reserve(n); + x.splice(..0, iter::repeat(0).take(n)); + } + } + + /// Shift-left buffer by n bits. + #[inline] + pub fn ishl(x: &mut Vec, n: usize) { + let bits = mem::size_of::() * 8; + // Need to pad with zeros for the number of `bits / Limb::BITS`, + // and shift-left with carry for `bits % Limb::BITS`. + let rem = n % bits; + let div = n / bits; + ishl_bits(x, rem); + if div != 0 { + ishl_limbs(x, div); + } + } + + // NORMALIZE + + /// Normalize the container by popping any leading zeros. + #[inline] + pub fn normalize(x: &mut Vec) { + // Remove leading zero if we cause underflow. Since we're dividing + // by a small power, we have at max 1 int removed. + while x.last() == Some(&0) { + x.pop(); + } + } +} // small + +// LARGE +// ----- + +// Large-to-large operations, to modify a big integer from a native scalar. + +mod large { + use super::*; + + // RELATIVE OPERATORS + + /// Compare `x` to `y`, in little-endian order. + #[inline] + pub fn compare(x: &[Limb], y: &[Limb]) -> cmp::Ordering { + if x.len() > y.len() { + cmp::Ordering::Greater + } else if x.len() < y.len() { + cmp::Ordering::Less + } else { + let iter = x.iter().rev().zip(y.iter().rev()); + for (&xi, &yi) in iter { + if xi > yi { + return cmp::Ordering::Greater; + } else if xi < yi { + return cmp::Ordering::Less; + } + } + // Equal case. + cmp::Ordering::Equal + } + } + + /// Check if x is less than y. + #[inline] + pub fn less(x: &[Limb], y: &[Limb]) -> bool { + compare(x, y) == cmp::Ordering::Less + } + + /// Check if x is greater than or equal to y. + #[inline] + pub fn greater_equal(x: &[Limb], y: &[Limb]) -> bool { + !less(x, y) + } + + // ADDITION + + /// Implied AddAssign implementation for bigints. + /// + /// Allows us to choose a start-index in x to store, so we can avoid + /// padding the buffer with zeros when not needed, optimized for vectors. + pub fn iadd_impl(x: &mut Vec, y: &[Limb], xstart: usize) { + // The effective x buffer is from `xstart..x.len()`, so we need to treat + // that as the current range. If the effective y buffer is longer, need + // to resize to that, + the start index. + if y.len() > x.len() - xstart { + x.resize(y.len() + xstart, 0); + } + + // Iteratively add elements from y to x. + let mut carry = false; + for (xi, yi) in x[xstart..].iter_mut().zip(y.iter()) { + // Only one op of the two can overflow, since we added at max + // Limb::max_value() + Limb::max_value(). Add the previous carry, + // and store the current carry for the next. + let mut tmp = scalar::iadd(xi, *yi); + if carry { + tmp |= scalar::iadd(xi, 1); + } + carry = tmp; + } + + // Overflow from the previous bit. + if carry { + small::iadd_impl(x, 1, y.len() + xstart); + } + } + + /// AddAssign bigint to bigint. + #[inline] + pub fn iadd(x: &mut Vec, y: &[Limb]) { + iadd_impl(x, y, 0); + } + + /// Add bigint to bigint. + #[inline] + pub fn add(x: &[Limb], y: &[Limb]) -> Vec { + let mut z = Vec::::default(); + z.extend_from_slice(x); + iadd(&mut z, y); + z + } + + // SUBTRACTION + + /// SubAssign bigint to bigint. + pub fn isub(x: &mut Vec, y: &[Limb]) { + // Basic underflow checks. + debug_assert!(greater_equal(x, y)); + + // Iteratively add elements from y to x. + let mut carry = false; + for (xi, yi) in x.iter_mut().zip(y.iter()) { + // Only one op of the two can overflow, since we added at max + // Limb::max_value() + Limb::max_value(). Add the previous carry, + // and store the current carry for the next. + let mut tmp = scalar::isub(xi, *yi); + if carry { + tmp |= scalar::isub(xi, 1); + } + carry = tmp; + } + + if carry { + small::isub_impl(x, 1, y.len()); + } else { + small::normalize(x); + } + } + + // MULTIPLICATION + + /// Number of digits to bottom-out to asymptotically slow algorithms. + /// + /// Karatsuba tends to out-perform long-multiplication at ~320-640 bits, + /// so we go halfway, while Newton division tends to out-perform + /// Algorithm D at ~1024 bits. We can toggle this for optimal performance. + pub const KARATSUBA_CUTOFF: usize = 32; + + /// Grade-school multiplication algorithm. + /// + /// Slow, naive algorithm, using limb-bit bases and just shifting left for + /// each iteration. This could be optimized with numerous other algorithms, + /// but it's extremely simple, and works in O(n*m) time, which is fine + /// by me. Each iteration, of which there are `m` iterations, requires + /// `n` multiplications, and `n` additions, or grade-school multiplication. + fn long_mul(x: &[Limb], y: &[Limb]) -> Vec { + // Using the immutable value, multiply by all the scalars in y, using + // the algorithm defined above. Use a single buffer to avoid + // frequent reallocations. Handle the first case to avoid a redundant + // addition, since we know y.len() >= 1. + let mut z: Vec = small::mul(x, y[0]); + z.resize(x.len() + y.len(), 0); + + // Handle the iterative cases. + for (i, &yi) in y[1..].iter().enumerate() { + let zi: Vec = small::mul(x, yi); + iadd_impl(&mut z, &zi, i + 1); + } + + small::normalize(&mut z); + + z + } + + /// Split two buffers into halfway, into (lo, hi). + #[inline] + pub fn karatsuba_split(z: &[Limb], m: usize) -> (&[Limb], &[Limb]) { + (&z[..m], &z[m..]) + } + + /// Karatsuba multiplication algorithm with roughly equal input sizes. + /// + /// Assumes `y.len() >= x.len()`. + fn karatsuba_mul(x: &[Limb], y: &[Limb]) -> Vec { + if y.len() <= KARATSUBA_CUTOFF { + // Bottom-out to long division for small cases. + long_mul(x, y) + } else if x.len() < y.len() / 2 { + karatsuba_uneven_mul(x, y) + } else { + // Do our 3 multiplications. + let m = y.len() / 2; + let (xl, xh) = karatsuba_split(x, m); + let (yl, yh) = karatsuba_split(y, m); + let sumx = add(xl, xh); + let sumy = add(yl, yh); + let z0 = karatsuba_mul(xl, yl); + let mut z1 = karatsuba_mul(&sumx, &sumy); + let z2 = karatsuba_mul(xh, yh); + // Properly scale z1, which is `z1 - z2 - zo`. + isub(&mut z1, &z2); + isub(&mut z1, &z0); + + // Create our result, which is equal to, in little-endian order: + // [z0, z1 - z2 - z0, z2] + // z1 must be shifted m digits (2^(32m)) over. + // z2 must be shifted 2*m digits (2^(64m)) over. + let len = z0.len().max(m + z1.len()).max(2 * m + z2.len()); + let mut result = z0; + result.reserve_exact(len - result.len()); + iadd_impl(&mut result, &z1, m); + iadd_impl(&mut result, &z2, 2 * m); + + result + } + } + + /// Karatsuba multiplication algorithm where y is substantially larger than x. + /// + /// Assumes `y.len() >= x.len()`. + fn karatsuba_uneven_mul(x: &[Limb], mut y: &[Limb]) -> Vec { + let mut result = Vec::::default(); + result.resize(x.len() + y.len(), 0); + + // This effectively is like grade-school multiplication between + // two numbers, except we're using splits on `y`, and the intermediate + // step is a Karatsuba multiplication. + let mut start = 0; + while !y.is_empty() { + let m = x.len().min(y.len()); + let (yl, yh) = karatsuba_split(y, m); + let prod = karatsuba_mul(x, yl); + iadd_impl(&mut result, &prod, start); + y = yh; + start += m; + } + small::normalize(&mut result); + + result + } + + /// Forwarder to the proper Karatsuba algorithm. + #[inline] + fn karatsuba_mul_fwd(x: &[Limb], y: &[Limb]) -> Vec { + if x.len() < y.len() { + karatsuba_mul(x, y) + } else { + karatsuba_mul(y, x) + } + } + + /// MulAssign bigint to bigint. + #[inline] + pub fn imul(x: &mut Vec, y: &[Limb]) { + if y.len() == 1 { + small::imul(x, y[0]); + } else { + // We're not really in a condition where using Karatsuba + // multiplication makes sense, so we're just going to use long + // division. ~20% speedup compared to: + // *x = karatsuba_mul_fwd(x, y); + *x = karatsuba_mul_fwd(x, y); + } + } +} // large + +// TRAITS +// ------ + +/// Traits for shared operations for big integers. +/// +/// None of these are implemented using normal traits, since these +/// are very expensive operations, and we want to deliberately +/// and explicitly use these functions. +pub(crate) trait Math: Clone + Sized + Default { + // DATA + + /// Get access to the underlying data + fn data(&self) -> &Vec; + + /// Get access to the underlying data + fn data_mut(&mut self) -> &mut Vec; + + // RELATIVE OPERATIONS + + /// Compare self to y. + #[inline] + fn compare(&self, y: &Self) -> cmp::Ordering { + large::compare(self.data(), y.data()) + } + + // PROPERTIES + + /// Get the high 64-bits from the bigint and if there are remaining bits. + #[inline] + fn hi64(&self) -> (u64, bool) { + self.data().as_slice().hi64() + } + + /// Calculate the bit-length of the big-integer. + /// Returns usize::max_value() if the value overflows, + /// IE, if `self.data().len() > usize::max_value() / 8`. + #[inline] + fn bit_length(&self) -> usize { + small::bit_length(self.data()) + } + + // INTEGER CONVERSIONS + + /// Create new big integer from u64. + #[inline] + fn from_u64(x: u64) -> Self { + let mut v = Self::default(); + let slc = split_u64(x); + v.data_mut().extend_from_slice(&slc); + v.normalize(); + v + } + + // NORMALIZE + + /// Normalize the integer, so any leading zero values are removed. + #[inline] + fn normalize(&mut self) { + small::normalize(self.data_mut()); + } + + // ADDITION + + /// AddAssign small integer. + #[inline] + fn iadd_small(&mut self, y: Limb) { + small::iadd(self.data_mut(), y); + } + + // MULTIPLICATION + + /// MulAssign small integer. + #[inline] + fn imul_small(&mut self, y: Limb) { + small::imul(self.data_mut(), y); + } + + /// Multiply by a power of 2. + #[inline] + fn imul_pow2(&mut self, n: u32) { + self.ishl(n as usize); + } + + /// Multiply by a power of 5. + #[inline] + fn imul_pow5(&mut self, n: u32) { + small::imul_pow5(self.data_mut(), n); + } + + /// MulAssign by a power of 10. + #[inline] + fn imul_pow10(&mut self, n: u32) { + self.imul_pow5(n); + self.imul_pow2(n); + } + + // SHIFTS + + /// Shift-left the entire buffer n bits. + #[inline] + fn ishl(&mut self, n: usize) { + small::ishl(self.data_mut(), n); + } +} diff --git a/vendor/serde_json/src/lexical/mod.rs b/vendor/serde_json/src/lexical/mod.rs new file mode 100644 index 0000000..aeed406 --- /dev/null +++ b/vendor/serde_json/src/lexical/mod.rs @@ -0,0 +1,38 @@ +// The code in this module is derived from the `lexical` crate by @Alexhuszagh +// which the author condensed into this minimal subset for use in serde_json. +// For the serde_json use case we care more about reliably round tripping all +// possible floating point values than about parsing any arbitrarily long string +// of digits with perfect accuracy, as the latter would take a high cost in +// compile time and performance. +// +// Dual licensed as MIT and Apache 2.0 just like the rest of serde_json, but +// copyright Alexander Huszagh. + +//! Fast, minimal float-parsing algorithm. + +// MODULES +pub(crate) mod algorithm; +mod bhcomp; +mod bignum; +mod cached; +mod cached_float80; +mod digit; +mod errors; +pub(crate) mod exponent; +pub(crate) mod float; +mod large_powers; +pub(crate) mod math; +pub(crate) mod num; +pub(crate) mod parse; +pub(crate) mod rounding; +mod shift; +mod small_powers; + +#[cfg(fast_arithmetic = "32")] +mod large_powers32; + +#[cfg(fast_arithmetic = "64")] +mod large_powers64; + +// API +pub use self::parse::{parse_concise_float, parse_truncated_float}; diff --git a/vendor/serde_json/src/lexical/num.rs b/vendor/serde_json/src/lexical/num.rs new file mode 100644 index 0000000..3f39140 --- /dev/null +++ b/vendor/serde_json/src/lexical/num.rs @@ -0,0 +1,421 @@ +// Adapted from https://github.com/Alexhuszagh/rust-lexical. + +//! Utilities for Rust numbers. + +use core::ops; + +/// Precalculated values of radix**i for i in range [0, arr.len()-1]. +/// Each value can be **exactly** represented as that type. +const F32_POW10: [f32; 11] = [ + 1.0, + 10.0, + 100.0, + 1000.0, + 10000.0, + 100000.0, + 1000000.0, + 10000000.0, + 100000000.0, + 1000000000.0, + 10000000000.0, +]; + +/// Precalculated values of radix**i for i in range [0, arr.len()-1]. +/// Each value can be **exactly** represented as that type. +const F64_POW10: [f64; 23] = [ + 1.0, + 10.0, + 100.0, + 1000.0, + 10000.0, + 100000.0, + 1000000.0, + 10000000.0, + 100000000.0, + 1000000000.0, + 10000000000.0, + 100000000000.0, + 1000000000000.0, + 10000000000000.0, + 100000000000000.0, + 1000000000000000.0, + 10000000000000000.0, + 100000000000000000.0, + 1000000000000000000.0, + 10000000000000000000.0, + 100000000000000000000.0, + 1000000000000000000000.0, + 10000000000000000000000.0, +]; + +/// Type that can be converted to primitive with `as`. +pub trait AsPrimitive: Sized + Copy + PartialOrd { + fn as_u32(self) -> u32; + fn as_u64(self) -> u64; + fn as_u128(self) -> u128; + fn as_usize(self) -> usize; + fn as_f32(self) -> f32; + fn as_f64(self) -> f64; +} + +macro_rules! as_primitive_impl { + ($($ty:ident)*) => { + $( + impl AsPrimitive for $ty { + #[inline] + fn as_u32(self) -> u32 { + self as u32 + } + + #[inline] + fn as_u64(self) -> u64 { + self as u64 + } + + #[inline] + fn as_u128(self) -> u128 { + self as u128 + } + + #[inline] + fn as_usize(self) -> usize { + self as usize + } + + #[inline] + fn as_f32(self) -> f32 { + self as f32 + } + + #[inline] + fn as_f64(self) -> f64 { + self as f64 + } + } + )* + }; +} + +as_primitive_impl! { u32 u64 u128 usize f32 f64 } + +/// An interface for casting between machine scalars. +pub trait AsCast: AsPrimitive { + /// Creates a number from another value that can be converted into + /// a primitive via the `AsPrimitive` trait. + fn as_cast(n: N) -> Self; +} + +macro_rules! as_cast_impl { + ($ty:ident, $method:ident) => { + impl AsCast for $ty { + #[inline] + fn as_cast(n: N) -> Self { + n.$method() + } + } + }; +} + +as_cast_impl!(u32, as_u32); +as_cast_impl!(u64, as_u64); +as_cast_impl!(u128, as_u128); +as_cast_impl!(usize, as_usize); +as_cast_impl!(f32, as_f32); +as_cast_impl!(f64, as_f64); + +/// Numerical type trait. +pub trait Number: AsCast + ops::Add {} + +macro_rules! number_impl { + ($($ty:ident)*) => { + $( + impl Number for $ty {} + )* + }; +} + +number_impl! { u32 u64 u128 usize f32 f64 } + +/// Defines a trait that supports integral operations. +pub trait Integer: Number + ops::BitAnd + ops::Shr { + const ZERO: Self; +} + +macro_rules! integer_impl { + ($($ty:tt)*) => { + $( + impl Integer for $ty { + const ZERO: Self = 0; + } + )* + }; +} + +integer_impl! { u32 u64 u128 usize } + +/// Type trait for the mantissa type. +pub trait Mantissa: Integer { + /// Mask to extract the high bits from the integer. + const HIMASK: Self; + /// Mask to extract the low bits from the integer. + const LOMASK: Self; + /// Full size of the integer, in bits. + const FULL: i32; + /// Half size of the integer, in bits. + const HALF: i32 = Self::FULL / 2; +} + +impl Mantissa for u64 { + const HIMASK: u64 = 0xFFFFFFFF00000000; + const LOMASK: u64 = 0x00000000FFFFFFFF; + const FULL: i32 = 64; +} + +/// Get exact exponent limit for radix. +pub trait Float: Number { + /// Unsigned type of the same size. + type Unsigned: Integer; + + /// Literal zero. + const ZERO: Self; + /// Maximum number of digits that can contribute in the mantissa. + /// + /// We can exactly represent a float in radix `b` from radix 2 if + /// `b` is divisible by 2. This function calculates the exact number of + /// digits required to exactly represent that float. + /// + /// According to the "Handbook of Floating Point Arithmetic", + /// for IEEE754, with emin being the min exponent, p2 being the + /// precision, and b being the radix, the number of digits follows as: + /// + /// `−emin + p2 + ⌊(emin + 1) log(2, b) − log(1 − 2^(−p2), b)⌋` + /// + /// For f32, this follows as: + /// emin = -126 + /// p2 = 24 + /// + /// For f64, this follows as: + /// emin = -1022 + /// p2 = 53 + /// + /// In Python: + /// `-emin + p2 + math.floor((emin+1)*math.log(2, b) - math.log(1-2**(-p2), b))` + /// + /// This was used to calculate the maximum number of digits for [2, 36]. + const MAX_DIGITS: usize; + + // MASKS + + /// Bitmask for the exponent, including the hidden bit. + const EXPONENT_MASK: Self::Unsigned; + /// Bitmask for the hidden bit in exponent, which is an implicit 1 in the fraction. + const HIDDEN_BIT_MASK: Self::Unsigned; + /// Bitmask for the mantissa (fraction), excluding the hidden bit. + const MANTISSA_MASK: Self::Unsigned; + + // PROPERTIES + + /// Positive infinity as bits. + const INFINITY_BITS: Self::Unsigned; + /// Size of the significand (mantissa) without hidden bit. + const MANTISSA_SIZE: i32; + /// Bias of the exponent + const EXPONENT_BIAS: i32; + /// Exponent portion of a denormal float. + const DENORMAL_EXPONENT: i32; + /// Maximum exponent value in float. + const MAX_EXPONENT: i32; + + // ROUNDING + + /// Default number of bits to shift (or 64 - mantissa size - 1). + const DEFAULT_SHIFT: i32; + /// Mask to determine if a full-carry occurred (1 in bit above hidden bit). + const CARRY_MASK: u64; + + /// Get min and max exponent limits (exact) from radix. + fn exponent_limit() -> (i32, i32); + + /// Get the number of digits that can be shifted from exponent to mantissa. + fn mantissa_limit() -> i32; + + // Re-exported methods from std. + fn pow10(self, n: i32) -> Self; + fn from_bits(u: Self::Unsigned) -> Self; + fn to_bits(self) -> Self::Unsigned; + fn is_sign_positive(self) -> bool; + + /// Returns true if the float is a denormal. + #[inline] + fn is_denormal(self) -> bool { + self.to_bits() & Self::EXPONENT_MASK == Self::Unsigned::ZERO + } + + /// Returns true if the float is a NaN or Infinite. + #[inline] + fn is_special(self) -> bool { + self.to_bits() & Self::EXPONENT_MASK == Self::EXPONENT_MASK + } + + /// Returns true if the float is infinite. + #[inline] + fn is_inf(self) -> bool { + self.is_special() && (self.to_bits() & Self::MANTISSA_MASK) == Self::Unsigned::ZERO + } + + /// Get exponent component from the float. + #[inline] + fn exponent(self) -> i32 { + if self.is_denormal() { + return Self::DENORMAL_EXPONENT; + } + + let bits = self.to_bits(); + let biased_e = ((bits & Self::EXPONENT_MASK) >> Self::MANTISSA_SIZE).as_u32(); + biased_e as i32 - Self::EXPONENT_BIAS + } + + /// Get mantissa (significand) component from float. + #[inline] + fn mantissa(self) -> Self::Unsigned { + let bits = self.to_bits(); + let s = bits & Self::MANTISSA_MASK; + if !self.is_denormal() { + s + Self::HIDDEN_BIT_MASK + } else { + s + } + } + + /// Get next greater float for a positive float. + /// Value must be >= 0.0 and < INFINITY. + #[inline] + fn next_positive(self) -> Self { + debug_assert!(self.is_sign_positive() && !self.is_inf()); + Self::from_bits(self.to_bits() + Self::Unsigned::as_cast(1u32)) + } + + /// Round a positive number to even. + #[inline] + fn round_positive_even(self) -> Self { + if self.mantissa() & Self::Unsigned::as_cast(1u32) == Self::Unsigned::as_cast(1u32) { + self.next_positive() + } else { + self + } + } +} + +impl Float for f32 { + type Unsigned = u32; + + const ZERO: f32 = 0.0; + const MAX_DIGITS: usize = 114; + const EXPONENT_MASK: u32 = 0x7F800000; + const HIDDEN_BIT_MASK: u32 = 0x00800000; + const MANTISSA_MASK: u32 = 0x007FFFFF; + const INFINITY_BITS: u32 = 0x7F800000; + const MANTISSA_SIZE: i32 = 23; + const EXPONENT_BIAS: i32 = 127 + Self::MANTISSA_SIZE; + const DENORMAL_EXPONENT: i32 = 1 - Self::EXPONENT_BIAS; + const MAX_EXPONENT: i32 = 0xFF - Self::EXPONENT_BIAS; + const DEFAULT_SHIFT: i32 = u64::FULL - f32::MANTISSA_SIZE - 1; + const CARRY_MASK: u64 = 0x1000000; + + #[inline] + fn exponent_limit() -> (i32, i32) { + (-10, 10) + } + + #[inline] + fn mantissa_limit() -> i32 { + 7 + } + + #[inline] + fn pow10(self, n: i32) -> f32 { + // Check the exponent is within bounds in debug builds. + debug_assert!({ + let (min, max) = Self::exponent_limit(); + n >= min && n <= max + }); + + if n > 0 { + self * F32_POW10[n as usize] + } else { + self / F32_POW10[-n as usize] + } + } + + #[inline] + fn from_bits(u: u32) -> f32 { + f32::from_bits(u) + } + + #[inline] + fn to_bits(self) -> u32 { + f32::to_bits(self) + } + + #[inline] + fn is_sign_positive(self) -> bool { + f32::is_sign_positive(self) + } +} + +impl Float for f64 { + type Unsigned = u64; + + const ZERO: f64 = 0.0; + const MAX_DIGITS: usize = 769; + const EXPONENT_MASK: u64 = 0x7FF0000000000000; + const HIDDEN_BIT_MASK: u64 = 0x0010000000000000; + const MANTISSA_MASK: u64 = 0x000FFFFFFFFFFFFF; + const INFINITY_BITS: u64 = 0x7FF0000000000000; + const MANTISSA_SIZE: i32 = 52; + const EXPONENT_BIAS: i32 = 1023 + Self::MANTISSA_SIZE; + const DENORMAL_EXPONENT: i32 = 1 - Self::EXPONENT_BIAS; + const MAX_EXPONENT: i32 = 0x7FF - Self::EXPONENT_BIAS; + const DEFAULT_SHIFT: i32 = u64::FULL - f64::MANTISSA_SIZE - 1; + const CARRY_MASK: u64 = 0x20000000000000; + + #[inline] + fn exponent_limit() -> (i32, i32) { + (-22, 22) + } + + #[inline] + fn mantissa_limit() -> i32 { + 15 + } + + #[inline] + fn pow10(self, n: i32) -> f64 { + // Check the exponent is within bounds in debug builds. + debug_assert!({ + let (min, max) = Self::exponent_limit(); + n >= min && n <= max + }); + + if n > 0 { + self * F64_POW10[n as usize] + } else { + self / F64_POW10[-n as usize] + } + } + + #[inline] + fn from_bits(u: u64) -> f64 { + f64::from_bits(u) + } + + #[inline] + fn to_bits(self) -> u64 { + f64::to_bits(self) + } + + #[inline] + fn is_sign_positive(self) -> bool { + f64::is_sign_positive(self) + } +} diff --git a/vendor/serde_json/src/lexical/parse.rs b/vendor/serde_json/src/lexical/parse.rs new file mode 100644 index 0000000..e3d7f1e --- /dev/null +++ b/vendor/serde_json/src/lexical/parse.rs @@ -0,0 +1,83 @@ +// Adapted from https://github.com/Alexhuszagh/rust-lexical. + +use super::algorithm::*; +use super::bhcomp::*; +use super::digit::*; +use super::exponent::*; +use super::num::*; + +// PARSERS +// ------- + +/// Parse float for which the entire integer and fraction parts fit into a 64 +/// bit mantissa. +pub fn parse_concise_float(mantissa: u64, mant_exp: i32) -> F +where + F: Float, +{ + if let Some(float) = fast_path(mantissa, mant_exp) { + return float; + } + + // Moderate path (use an extended 80-bit representation). + let truncated = false; + let (fp, valid) = moderate_path::(mantissa, mant_exp, truncated); + if valid { + return fp.into_float::(); + } + + let b = fp.into_downward_float::(); + if b.is_special() { + // We have a non-finite number, we get to leave early. + return b; + } + + // Slow path, fast path didn't work. + let mut buffer = itoa::Buffer::new(); + let integer = buffer.format(mantissa).as_bytes(); + let fraction = &[]; + bhcomp(b, integer, fraction, mant_exp) +} + +/// Parse float from extracted float components. +/// +/// * `integer` - Slice containing the integer digits. +/// * `fraction` - Slice containing the fraction digits. +/// * `exponent` - Parsed, 32-bit exponent. +/// +/// Precondition: The integer must not have leading zeros. +pub fn parse_truncated_float(integer: &[u8], mut fraction: &[u8], exponent: i32) -> F +where + F: Float, +{ + // Trim trailing zeroes from the fraction part. + while fraction.last() == Some(&b'0') { + fraction = &fraction[..fraction.len() - 1]; + } + + // Calculate the number of truncated digits. + let mut truncated = 0; + let mut mantissa: u64 = 0; + let mut iter = integer.iter().chain(fraction); + for &c in &mut iter { + mantissa = match add_digit(mantissa, to_digit(c).unwrap()) { + Some(v) => v, + None => { + truncated = 1 + iter.count(); + break; + } + }; + } + + let mant_exp = mantissa_exponent(exponent, fraction.len(), truncated); + let is_truncated = true; + + fallback_path( + integer, + fraction, + mantissa, + exponent, + mant_exp, + is_truncated, + ) +} diff --git a/vendor/serde_json/src/lexical/rounding.rs b/vendor/serde_json/src/lexical/rounding.rs new file mode 100644 index 0000000..6344875 --- /dev/null +++ b/vendor/serde_json/src/lexical/rounding.rs @@ -0,0 +1,231 @@ +// Adapted from https://github.com/Alexhuszagh/rust-lexical. + +//! Defines rounding schemes for floating-point numbers. + +use super::float::ExtendedFloat; +use super::num::*; +use super::shift::*; +use core::mem; + +// MASKS + +/// Calculate a scalar factor of 2 above the halfway point. +#[inline] +pub(crate) fn nth_bit(n: u64) -> u64 { + let bits: u64 = mem::size_of::() as u64 * 8; + debug_assert!(n < bits, "nth_bit() overflow in shl."); + + 1 << n +} + +/// Generate a bitwise mask for the lower `n` bits. +#[inline] +pub(crate) fn lower_n_mask(n: u64) -> u64 { + let bits: u64 = mem::size_of::() as u64 * 8; + debug_assert!(n <= bits, "lower_n_mask() overflow in shl."); + + if n == bits { + u64::MAX + } else { + (1 << n) - 1 + } +} + +/// Calculate the halfway point for the lower `n` bits. +#[inline] +pub(crate) fn lower_n_halfway(n: u64) -> u64 { + let bits: u64 = mem::size_of::() as u64 * 8; + debug_assert!(n <= bits, "lower_n_halfway() overflow in shl."); + + if n == 0 { + 0 + } else { + nth_bit(n - 1) + } +} + +/// Calculate a bitwise mask with `n` 1 bits starting at the `bit` position. +#[inline] +pub(crate) fn internal_n_mask(bit: u64, n: u64) -> u64 { + let bits: u64 = mem::size_of::() as u64 * 8; + debug_assert!(bit <= bits, "internal_n_halfway() overflow in shl."); + debug_assert!(n <= bits, "internal_n_halfway() overflow in shl."); + debug_assert!(bit >= n, "internal_n_halfway() overflow in sub."); + + lower_n_mask(bit) ^ lower_n_mask(bit - n) +} + +// NEAREST ROUNDING + +// Shift right N-bytes and round to the nearest. +// +// Return if we are above halfway and if we are halfway. +#[inline] +pub(crate) fn round_nearest(fp: &mut ExtendedFloat, shift: i32) -> (bool, bool) { + // Extract the truncated bits using mask. + // Calculate if the value of the truncated bits are either above + // the mid-way point, or equal to it. + // + // For example, for 4 truncated bytes, the mask would be b1111 + // and the midway point would be b1000. + let mask: u64 = lower_n_mask(shift as u64); + let halfway: u64 = lower_n_halfway(shift as u64); + + let truncated_bits = fp.mant & mask; + let is_above = truncated_bits > halfway; + let is_halfway = truncated_bits == halfway; + + // Bit shift so the leading bit is in the hidden bit. + overflowing_shr(fp, shift); + + (is_above, is_halfway) +} + +// Tie rounded floating point to event. +#[inline] +pub(crate) fn tie_even(fp: &mut ExtendedFloat, is_above: bool, is_halfway: bool) { + // Extract the last bit after shifting (and determine if it is odd). + let is_odd = fp.mant & 1 == 1; + + // Calculate if we need to roundup. + // We need to roundup if we are above halfway, or if we are odd + // and at half-way (need to tie-to-even). + if is_above || (is_odd && is_halfway) { + fp.mant += 1; + } +} + +// Shift right N-bytes and round nearest, tie-to-even. +// +// Floating-point arithmetic uses round to nearest, ties to even, +// which rounds to the nearest value, if the value is halfway in between, +// round to an even value. +#[inline] +pub(crate) fn round_nearest_tie_even(fp: &mut ExtendedFloat, shift: i32) { + let (is_above, is_halfway) = round_nearest(fp, shift); + tie_even(fp, is_above, is_halfway); +} + +// DIRECTED ROUNDING + +// Shift right N-bytes and round towards a direction. +// +// Return if we have any truncated bytes. +#[inline] +fn round_toward(fp: &mut ExtendedFloat, shift: i32) -> bool { + let mask: u64 = lower_n_mask(shift as u64); + let truncated_bits = fp.mant & mask; + + // Bit shift so the leading bit is in the hidden bit. + overflowing_shr(fp, shift); + + truncated_bits != 0 +} + +// Round down. +#[inline] +fn downard(_: &mut ExtendedFloat, _: bool) {} + +// Shift right N-bytes and round toward zero. +// +// Floating-point arithmetic defines round toward zero, which rounds +// towards positive zero. +#[inline] +pub(crate) fn round_downward(fp: &mut ExtendedFloat, shift: i32) { + // Bit shift so the leading bit is in the hidden bit. + // No rounding schemes, so we just ignore everything else. + let is_truncated = round_toward(fp, shift); + downard(fp, is_truncated); +} + +// ROUND TO FLOAT + +// Shift the ExtendedFloat fraction to the fraction bits in a native float. +// +// Floating-point arithmetic uses round to nearest, ties to even, +// which rounds to the nearest value, if the value is halfway in between, +// round to an even value. +#[inline] +pub(crate) fn round_to_float(fp: &mut ExtendedFloat, algorithm: Algorithm) +where + F: Float, + Algorithm: FnOnce(&mut ExtendedFloat, i32), +{ + // Calculate the difference to allow a single calculation + // rather than a loop, to minimize the number of ops required. + // This does underflow detection. + let final_exp = fp.exp + F::DEFAULT_SHIFT; + if final_exp < F::DENORMAL_EXPONENT { + // We would end up with a denormal exponent, try to round to more + // digits. Only shift right if we can avoid zeroing out the value, + // which requires the exponent diff to be < M::BITS. The value + // is already normalized, so we shouldn't have any issue zeroing + // out the value. + let diff = F::DENORMAL_EXPONENT - fp.exp; + if diff <= u64::FULL { + // We can avoid underflow, can get a valid representation. + algorithm(fp, diff); + } else { + // Certain underflow, assign literal 0s. + fp.mant = 0; + fp.exp = 0; + } + } else { + algorithm(fp, F::DEFAULT_SHIFT); + } + + if fp.mant & F::CARRY_MASK == F::CARRY_MASK { + // Roundup carried over to 1 past the hidden bit. + shr(fp, 1); + } +} + +// AVOID OVERFLOW/UNDERFLOW + +// Avoid overflow for large values, shift left as needed. +// +// Shift until a 1-bit is in the hidden bit, if the mantissa is not 0. +#[inline] +pub(crate) fn avoid_overflow(fp: &mut ExtendedFloat) +where + F: Float, +{ + // Calculate the difference to allow a single calculation + // rather than a loop, minimizing the number of ops required. + if fp.exp >= F::MAX_EXPONENT { + let diff = fp.exp - F::MAX_EXPONENT; + if diff <= F::MANTISSA_SIZE { + // Our overflow mask needs to start at the hidden bit, or at + // `F::MANTISSA_SIZE+1`, and needs to have `diff+1` bits set, + // to see if our value overflows. + let bit = (F::MANTISSA_SIZE + 1) as u64; + let n = (diff + 1) as u64; + let mask = internal_n_mask(bit, n); + if (fp.mant & mask) == 0 { + // If we have no 1-bit in the hidden-bit position, + // which is index 0, we need to shift 1. + let shift = diff + 1; + shl(fp, shift); + } + } + } +} + +// ROUND TO NATIVE + +// Round an extended-precision float to a native float representation. +#[inline] +pub(crate) fn round_to_native(fp: &mut ExtendedFloat, algorithm: Algorithm) +where + F: Float, + Algorithm: FnOnce(&mut ExtendedFloat, i32), +{ + // Shift all the way left, to ensure a consistent representation. + // The following right-shifts do not work for a non-normalized number. + fp.normalize(); + + // Round so the fraction is in a native mantissa representation, + // and avoid overflow/underflow. + round_to_float::(fp, algorithm); + avoid_overflow::(fp); +} diff --git a/vendor/serde_json/src/lexical/shift.rs b/vendor/serde_json/src/lexical/shift.rs new file mode 100644 index 0000000..a0bae01 --- /dev/null +++ b/vendor/serde_json/src/lexical/shift.rs @@ -0,0 +1,46 @@ +// Adapted from https://github.com/Alexhuszagh/rust-lexical. + +//! Bit-shift helpers. + +use super::float::ExtendedFloat; +use core::mem; + +// Shift extended-precision float right `shift` bytes. +#[inline] +pub(crate) fn shr(fp: &mut ExtendedFloat, shift: i32) { + let bits: u64 = mem::size_of::() as u64 * 8; + debug_assert!((shift as u64) < bits, "shr() overflow in shift right."); + + fp.mant >>= shift; + fp.exp += shift; +} + +// Shift extended-precision float right `shift` bytes. +// +// Accepts when the shift is the same as the type size, and +// sets the value to 0. +#[inline] +pub(crate) fn overflowing_shr(fp: &mut ExtendedFloat, shift: i32) { + let bits: u64 = mem::size_of::() as u64 * 8; + debug_assert!( + (shift as u64) <= bits, + "overflowing_shr() overflow in shift right." + ); + + fp.mant = if shift as u64 == bits { + 0 + } else { + fp.mant >> shift + }; + fp.exp += shift; +} + +// Shift extended-precision float left `shift` bytes. +#[inline] +pub(crate) fn shl(fp: &mut ExtendedFloat, shift: i32) { + let bits: u64 = mem::size_of::() as u64 * 8; + debug_assert!((shift as u64) < bits, "shl() overflow in shift left."); + + fp.mant <<= shift; + fp.exp -= shift; +} diff --git a/vendor/serde_json/src/lexical/small_powers.rs b/vendor/serde_json/src/lexical/small_powers.rs new file mode 100644 index 0000000..29b83a1 --- /dev/null +++ b/vendor/serde_json/src/lexical/small_powers.rs @@ -0,0 +1,70 @@ +// Adapted from https://github.com/Alexhuszagh/rust-lexical. + +//! Pre-computed small powers. + +// 32 BIT +#[cfg(fast_arithmetic = "32")] +pub(crate) const POW5_32: [u32; 14] = [ + 1, 5, 25, 125, 625, 3125, 15625, 78125, 390625, 1953125, 9765625, 48828125, 244140625, + 1220703125, +]; + +#[cfg(fast_arithmetic = "32")] +pub(crate) const POW10_32: [u32; 10] = [ + 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000, +]; + +// 64 BIT +#[cfg(fast_arithmetic = "64")] +pub(crate) const POW5_64: [u64; 28] = [ + 1, + 5, + 25, + 125, + 625, + 3125, + 15625, + 78125, + 390625, + 1953125, + 9765625, + 48828125, + 244140625, + 1220703125, + 6103515625, + 30517578125, + 152587890625, + 762939453125, + 3814697265625, + 19073486328125, + 95367431640625, + 476837158203125, + 2384185791015625, + 11920928955078125, + 59604644775390625, + 298023223876953125, + 1490116119384765625, + 7450580596923828125, +]; +pub(crate) const POW10_64: [u64; 20] = [ + 1, + 10, + 100, + 1000, + 10000, + 100000, + 1000000, + 10000000, + 100000000, + 1000000000, + 10000000000, + 100000000000, + 1000000000000, + 10000000000000, + 100000000000000, + 1000000000000000, + 10000000000000000, + 100000000000000000, + 1000000000000000000, + 10000000000000000000, +]; diff --git a/vendor/serde_json/src/lib.rs b/vendor/serde_json/src/lib.rs new file mode 100644 index 0000000..bb07494 --- /dev/null +++ b/vendor/serde_json/src/lib.rs @@ -0,0 +1,435 @@ +//! # Serde JSON +//! +//! JSON is a ubiquitous open-standard format that uses human-readable text to +//! transmit data objects consisting of key-value pairs. +//! +//! ```json +//! { +//! "name": "John Doe", +//! "age": 43, +//! "address": { +//! "street": "10 Downing Street", +//! "city": "London" +//! }, +//! "phones": [ +//! "+44 1234567", +//! "+44 2345678" +//! ] +//! } +//! ``` +//! +//! There are three common ways that you might find yourself needing to work +//! with JSON data in Rust. +//! +//! - **As text data.** An unprocessed string of JSON data that you receive on +//! an HTTP endpoint, read from a file, or prepare to send to a remote +//! server. +//! - **As an untyped or loosely typed representation.** Maybe you want to +//! check that some JSON data is valid before passing it on, but without +//! knowing the structure of what it contains. Or you want to do very basic +//! manipulations like insert a key in a particular spot. +//! - **As a strongly typed Rust data structure.** When you expect all or most +//! of your data to conform to a particular structure and want to get real +//! work done without JSON's loosey-goosey nature tripping you up. +//! +//! Serde JSON provides efficient, flexible, safe ways of converting data +//! between each of these representations. +//! +//! # Operating on untyped JSON values +//! +//! Any valid JSON data can be manipulated in the following recursive enum +//! representation. This data structure is [`serde_json::Value`][value]. +//! +//! ``` +//! # use serde_json::{Number, Map}; +//! # +//! # #[allow(dead_code)] +//! enum Value { +//! Null, +//! Bool(bool), +//! Number(Number), +//! String(String), +//! Array(Vec), +//! Object(Map), +//! } +//! ``` +//! +//! A string of JSON data can be parsed into a `serde_json::Value` by the +//! [`serde_json::from_str`][from_str] function. There is also [`from_slice`] +//! for parsing from a byte slice `&[u8]` and [`from_reader`] for parsing from +//! any `io::Read` like a File or a TCP stream. +//! +//! ``` +//! use serde_json::{Result, Value}; +//! +//! fn untyped_example() -> Result<()> { +//! // Some JSON input data as a &str. Maybe this comes from the user. +//! let data = r#" +//! { +//! "name": "John Doe", +//! "age": 43, +//! "phones": [ +//! "+44 1234567", +//! "+44 2345678" +//! ] +//! }"#; +//! +//! // Parse the string of data into serde_json::Value. +//! let v: Value = serde_json::from_str(data)?; +//! +//! // Access parts of the data by indexing with square brackets. +//! println!("Please call {} at the number {}", v["name"], v["phones"][0]); +//! +//! Ok(()) +//! } +//! # +//! # fn main() { +//! # untyped_example().unwrap(); +//! # } +//! ``` +//! +//! The result of square bracket indexing like `v["name"]` is a borrow of the +//! data at that index, so the type is `&Value`. A JSON map can be indexed with +//! string keys, while a JSON array can be indexed with integer keys. If the +//! type of the data is not right for the type with which it is being indexed, +//! or if a map does not contain the key being indexed, or if the index into a +//! vector is out of bounds, the returned element is `Value::Null`. +//! +//! When a `Value` is printed, it is printed as a JSON string. So in the code +//! above, the output looks like `Please call "John Doe" at the number "+44 +//! 1234567"`. The quotation marks appear because `v["name"]` is a `&Value` +//! containing a JSON string and its JSON representation is `"John Doe"`. +//! Printing as a plain string without quotation marks involves converting from +//! a JSON string to a Rust string with [`as_str()`] or avoiding the use of +//! `Value` as described in the following section. +//! +//! [`as_str()`]: crate::Value::as_str +//! +//! The `Value` representation is sufficient for very basic tasks but can be +//! tedious to work with for anything more significant. Error handling is +//! verbose to implement correctly, for example imagine trying to detect the +//! presence of unrecognized fields in the input data. The compiler is powerless +//! to help you when you make a mistake, for example imagine typoing `v["name"]` +//! as `v["nmae"]` in one of the dozens of places it is used in your code. +//! +//! # Parsing JSON as strongly typed data structures +//! +//! Serde provides a powerful way of mapping JSON data into Rust data structures +//! largely automatically. +//! +//! ``` +//! use serde::{Deserialize, Serialize}; +//! use serde_json::Result; +//! +//! #[derive(Serialize, Deserialize)] +//! struct Person { +//! name: String, +//! age: u8, +//! phones: Vec, +//! } +//! +//! fn typed_example() -> Result<()> { +//! // Some JSON input data as a &str. Maybe this comes from the user. +//! let data = r#" +//! { +//! "name": "John Doe", +//! "age": 43, +//! "phones": [ +//! "+44 1234567", +//! "+44 2345678" +//! ] +//! }"#; +//! +//! // Parse the string of data into a Person object. This is exactly the +//! // same function as the one that produced serde_json::Value above, but +//! // now we are asking it for a Person as output. +//! let p: Person = serde_json::from_str(data)?; +//! +//! // Do things just like with any other Rust data structure. +//! println!("Please call {} at the number {}", p.name, p.phones[0]); +//! +//! Ok(()) +//! } +//! # +//! # fn main() { +//! # typed_example().unwrap(); +//! # } +//! ``` +//! +//! This is the same `serde_json::from_str` function as before, but this time we +//! assign the return value to a variable of type `Person` so Serde will +//! automatically interpret the input data as a `Person` and produce informative +//! error messages if the layout does not conform to what a `Person` is expected +//! to look like. +//! +//! Any type that implements Serde's `Deserialize` trait can be deserialized +//! this way. This includes built-in Rust standard library types like `Vec` +//! and `HashMap`, as well as any structs or enums annotated with +//! `#[derive(Deserialize)]`. +//! +//! Once we have `p` of type `Person`, our IDE and the Rust compiler can help us +//! use it correctly like they do for any other Rust code. The IDE can +//! autocomplete field names to prevent typos, which was impossible in the +//! `serde_json::Value` representation. And the Rust compiler can check that +//! when we write `p.phones[0]`, then `p.phones` is guaranteed to be a +//! `Vec` so indexing into it makes sense and produces a `String`. +//! +//! # Constructing JSON values +//! +//! Serde JSON provides a [`json!` macro][macro] to build `serde_json::Value` +//! objects with very natural JSON syntax. +//! +//! ``` +//! use serde_json::json; +//! +//! fn main() { +//! // The type of `john` is `serde_json::Value` +//! let john = json!({ +//! "name": "John Doe", +//! "age": 43, +//! "phones": [ +//! "+44 1234567", +//! "+44 2345678" +//! ] +//! }); +//! +//! println!("first phone number: {}", john["phones"][0]); +//! +//! // Convert to a string of JSON and print it out +//! println!("{}", john.to_string()); +//! } +//! ``` +//! +//! The `Value::to_string()` function converts a `serde_json::Value` into a +//! `String` of JSON text. +//! +//! One neat thing about the `json!` macro is that variables and expressions can +//! be interpolated directly into the JSON value as you are building it. Serde +//! will check at compile time that the value you are interpolating is able to +//! be represented as JSON. +//! +//! ``` +//! # use serde_json::json; +//! # +//! # fn random_phone() -> u16 { 0 } +//! # +//! let full_name = "John Doe"; +//! let age_last_year = 42; +//! +//! // The type of `john` is `serde_json::Value` +//! let john = json!({ +//! "name": full_name, +//! "age": age_last_year + 1, +//! "phones": [ +//! format!("+44 {}", random_phone()) +//! ] +//! }); +//! ``` +//! +//! This is amazingly convenient, but we have the problem we had before with +//! `Value`: the IDE and Rust compiler cannot help us if we get it wrong. Serde +//! JSON provides a better way of serializing strongly-typed data structures +//! into JSON text. +//! +//! # Creating JSON by serializing data structures +//! +//! A data structure can be converted to a JSON string by +//! [`serde_json::to_string`][to_string]. There is also +//! [`serde_json::to_vec`][to_vec] which serializes to a `Vec` and +//! [`serde_json::to_writer`][to_writer] which serializes to any `io::Write` +//! such as a File or a TCP stream. +//! +//! ``` +//! use serde::{Deserialize, Serialize}; +//! use serde_json::Result; +//! +//! #[derive(Serialize, Deserialize)] +//! struct Address { +//! street: String, +//! city: String, +//! } +//! +//! fn print_an_address() -> Result<()> { +//! // Some data structure. +//! let address = Address { +//! street: "10 Downing Street".to_owned(), +//! city: "London".to_owned(), +//! }; +//! +//! // Serialize it to a JSON string. +//! let j = serde_json::to_string(&address)?; +//! +//! // Print, write to a file, or send to an HTTP server. +//! println!("{}", j); +//! +//! Ok(()) +//! } +//! # +//! # fn main() { +//! # print_an_address().unwrap(); +//! # } +//! ``` +//! +//! Any type that implements Serde's `Serialize` trait can be serialized this +//! way. This includes built-in Rust standard library types like `Vec` and +//! `HashMap`, as well as any structs or enums annotated with +//! `#[derive(Serialize)]`. +//! +//! # No-std support +//! +//! As long as there is a memory allocator, it is possible to use serde_json +//! without the rest of the Rust standard library. Disable the default "std" +//! feature and enable the "alloc" feature: +//! +//! ```toml +//! [dependencies] +//! serde_json = { version = "1.0", default-features = false, features = ["alloc"] } +//! ``` +//! +//! For JSON support in Serde without a memory allocator, please see the +//! [`serde-json-core`] crate. +//! +//! [value]: crate::value::Value +//! [from_str]: crate::de::from_str +//! [from_slice]: crate::de::from_slice +//! [from_reader]: crate::de::from_reader +//! [to_string]: crate::ser::to_string +//! [to_vec]: crate::ser::to_vec +//! [to_writer]: crate::ser::to_writer +//! [macro]: crate::json +//! [`serde-json-core`]: https://github.com/rust-embedded-community/serde-json-core + +#![doc(html_root_url = "https://docs.rs/serde_json/1.0.129")] +// Ignored clippy lints +#![allow( + clippy::collapsible_else_if, + clippy::comparison_chain, + clippy::deprecated_cfg_attr, + clippy::doc_markdown, + clippy::excessive_precision, + clippy::explicit_auto_deref, + clippy::float_cmp, + clippy::manual_range_contains, + clippy::match_like_matches_macro, + clippy::match_single_binding, + clippy::needless_doctest_main, + clippy::needless_late_init, + clippy::needless_lifetimes, + clippy::return_self_not_must_use, + clippy::transmute_ptr_to_ptr, + clippy::unconditional_recursion, // https://github.com/rust-lang/rust-clippy/issues/12133 + clippy::unnecessary_wraps +)] +// Ignored clippy_pedantic lints +#![allow( + // Deserializer::from_str, into_iter + clippy::should_implement_trait, + // integer and float ser/de requires these sorts of casts + clippy::cast_possible_truncation, + clippy::cast_possible_wrap, + clippy::cast_precision_loss, + clippy::cast_sign_loss, + // correctly used + clippy::enum_glob_use, + clippy::if_not_else, + clippy::integer_division, + clippy::let_underscore_untyped, + clippy::map_err_ignore, + clippy::match_same_arms, + clippy::similar_names, + clippy::unused_self, + clippy::wildcard_imports, + // things are often more readable this way + clippy::cast_lossless, + clippy::items_after_statements, + clippy::module_name_repetitions, + clippy::redundant_else, + clippy::shadow_unrelated, + clippy::single_match_else, + clippy::too_many_lines, + clippy::unreadable_literal, + clippy::unseparated_literal_suffix, + clippy::use_self, + clippy::zero_prefixed_literal, + // we support older compilers + clippy::checked_conversions, + clippy::mem_replace_with_default, + // noisy + clippy::missing_errors_doc, + clippy::must_use_candidate, +)] +// Restrictions +#![deny(clippy::question_mark_used)] +#![allow(non_upper_case_globals)] +#![deny(missing_docs)] +#![no_std] +#![cfg_attr(docsrs, feature(doc_cfg))] + +#[cfg(not(any(feature = "std", feature = "alloc")))] +compile_error! { + "serde_json requires that either `std` (default) or `alloc` feature is enabled" +} + +extern crate alloc; + +#[cfg(feature = "std")] +extern crate std; + +// Not public API. Used from macro-generated code. +#[doc(hidden)] +pub mod __private { + #[doc(hidden)] + pub use alloc::vec; +} + +#[cfg(feature = "std")] +#[cfg_attr(docsrs, doc(cfg(feature = "std")))] +#[doc(inline)] +pub use crate::de::from_reader; +#[doc(inline)] +pub use crate::de::{from_slice, from_str, Deserializer, StreamDeserializer}; +#[doc(inline)] +pub use crate::error::{Error, Result}; +#[doc(inline)] +pub use crate::ser::{to_string, to_string_pretty, to_vec, to_vec_pretty}; +#[cfg(feature = "std")] +#[cfg_attr(docsrs, doc(cfg(feature = "std")))] +#[doc(inline)] +pub use crate::ser::{to_writer, to_writer_pretty, Serializer}; +#[doc(inline)] +pub use crate::value::{from_value, to_value, Map, Number, Value}; + +// We only use our own error type; no need for From conversions provided by the +// standard library's try! macro. This reduces lines of LLVM IR by 4%. +macro_rules! tri { + ($e:expr $(,)?) => { + match $e { + core::result::Result::Ok(val) => val, + core::result::Result::Err(err) => return core::result::Result::Err(err), + } + }; +} + +#[macro_use] +mod macros; + +pub mod de; +pub mod error; +pub mod map; +#[cfg(feature = "std")] +#[cfg_attr(docsrs, doc(cfg(feature = "std")))] +pub mod ser; +#[cfg(not(feature = "std"))] +mod ser; +pub mod value; + +mod io; +#[cfg(feature = "std")] +mod iter; +#[cfg(feature = "float_roundtrip")] +mod lexical; +mod number; +mod read; + +#[cfg(feature = "raw_value")] +mod raw; diff --git a/vendor/serde_json/src/macros.rs b/vendor/serde_json/src/macros.rs new file mode 100644 index 0000000..c47bdf9 --- /dev/null +++ b/vendor/serde_json/src/macros.rs @@ -0,0 +1,303 @@ +/// Construct a `serde_json::Value` from a JSON literal. +/// +/// ``` +/// # use serde_json::json; +/// # +/// let value = json!({ +/// "code": 200, +/// "success": true, +/// "payload": { +/// "features": [ +/// "serde", +/// "json" +/// ], +/// "homepage": null +/// } +/// }); +/// ``` +/// +/// Variables or expressions can be interpolated into the JSON literal. Any type +/// interpolated into an array element or object value must implement Serde's +/// `Serialize` trait, while any type interpolated into a object key must +/// implement `Into`. If the `Serialize` implementation of the +/// interpolated type decides to fail, or if the interpolated type contains a +/// map with non-string keys, the `json!` macro will panic. +/// +/// ``` +/// # use serde_json::json; +/// # +/// let code = 200; +/// let features = vec!["serde", "json"]; +/// +/// let value = json!({ +/// "code": code, +/// "success": code == 200, +/// "payload": { +/// features[0]: features[1] +/// } +/// }); +/// ``` +/// +/// Trailing commas are allowed inside both arrays and objects. +/// +/// ``` +/// # use serde_json::json; +/// # +/// let value = json!([ +/// "notice", +/// "the", +/// "trailing", +/// "comma -->", +/// ]); +/// ``` +#[macro_export] +macro_rules! json { + // Hide distracting implementation details from the generated rustdoc. + ($($json:tt)+) => { + $crate::json_internal!($($json)+) + }; +} + +// Rocket relies on this because they export their own `json!` with a different +// doc comment than ours, and various Rust bugs prevent them from calling our +// `json!` from their `json!` so they call `json_internal!` directly. Check with +// @SergioBenitez before making breaking changes to this macro. +// +// Changes are fine as long as `json_internal!` does not call any new helper +// macros and can still be invoked as `json_internal!($($json)+)`. +#[macro_export] +#[doc(hidden)] +macro_rules! json_internal { + ////////////////////////////////////////////////////////////////////////// + // TT muncher for parsing the inside of an array [...]. Produces a vec![...] + // of the elements. + // + // Must be invoked as: json_internal!(@array [] $($tt)*) + ////////////////////////////////////////////////////////////////////////// + + // Done with trailing comma. + (@array [$($elems:expr,)*]) => { + $crate::__private::vec![$($elems,)*] + }; + + // Done without trailing comma. + (@array [$($elems:expr),*]) => { + $crate::__private::vec![$($elems),*] + }; + + // Next element is `null`. + (@array [$($elems:expr,)*] null $($rest:tt)*) => { + $crate::json_internal!(@array [$($elems,)* $crate::json_internal!(null)] $($rest)*) + }; + + // Next element is `true`. + (@array [$($elems:expr,)*] true $($rest:tt)*) => { + $crate::json_internal!(@array [$($elems,)* $crate::json_internal!(true)] $($rest)*) + }; + + // Next element is `false`. + (@array [$($elems:expr,)*] false $($rest:tt)*) => { + $crate::json_internal!(@array [$($elems,)* $crate::json_internal!(false)] $($rest)*) + }; + + // Next element is an array. + (@array [$($elems:expr,)*] [$($array:tt)*] $($rest:tt)*) => { + $crate::json_internal!(@array [$($elems,)* $crate::json_internal!([$($array)*])] $($rest)*) + }; + + // Next element is a map. + (@array [$($elems:expr,)*] {$($map:tt)*} $($rest:tt)*) => { + $crate::json_internal!(@array [$($elems,)* $crate::json_internal!({$($map)*})] $($rest)*) + }; + + // Next element is an expression followed by comma. + (@array [$($elems:expr,)*] $next:expr, $($rest:tt)*) => { + $crate::json_internal!(@array [$($elems,)* $crate::json_internal!($next),] $($rest)*) + }; + + // Last element is an expression with no trailing comma. + (@array [$($elems:expr,)*] $last:expr) => { + $crate::json_internal!(@array [$($elems,)* $crate::json_internal!($last)]) + }; + + // Comma after the most recent element. + (@array [$($elems:expr),*] , $($rest:tt)*) => { + $crate::json_internal!(@array [$($elems,)*] $($rest)*) + }; + + // Unexpected token after most recent element. + (@array [$($elems:expr),*] $unexpected:tt $($rest:tt)*) => { + $crate::json_unexpected!($unexpected) + }; + + ////////////////////////////////////////////////////////////////////////// + // TT muncher for parsing the inside of an object {...}. Each entry is + // inserted into the given map variable. + // + // Must be invoked as: json_internal!(@object $map () ($($tt)*) ($($tt)*)) + // + // We require two copies of the input tokens so that we can match on one + // copy and trigger errors on the other copy. + ////////////////////////////////////////////////////////////////////////// + + // Done. + (@object $object:ident () () ()) => {}; + + // Insert the current entry followed by trailing comma. + (@object $object:ident [$($key:tt)+] ($value:expr) , $($rest:tt)*) => { + let _ = $object.insert(($($key)+).into(), $value); + $crate::json_internal!(@object $object () ($($rest)*) ($($rest)*)); + }; + + // Current entry followed by unexpected token. + (@object $object:ident [$($key:tt)+] ($value:expr) $unexpected:tt $($rest:tt)*) => { + $crate::json_unexpected!($unexpected); + }; + + // Insert the last entry without trailing comma. + (@object $object:ident [$($key:tt)+] ($value:expr)) => { + let _ = $object.insert(($($key)+).into(), $value); + }; + + // Next value is `null`. + (@object $object:ident ($($key:tt)+) (: null $($rest:tt)*) $copy:tt) => { + $crate::json_internal!(@object $object [$($key)+] ($crate::json_internal!(null)) $($rest)*); + }; + + // Next value is `true`. + (@object $object:ident ($($key:tt)+) (: true $($rest:tt)*) $copy:tt) => { + $crate::json_internal!(@object $object [$($key)+] ($crate::json_internal!(true)) $($rest)*); + }; + + // Next value is `false`. + (@object $object:ident ($($key:tt)+) (: false $($rest:tt)*) $copy:tt) => { + $crate::json_internal!(@object $object [$($key)+] ($crate::json_internal!(false)) $($rest)*); + }; + + // Next value is an array. + (@object $object:ident ($($key:tt)+) (: [$($array:tt)*] $($rest:tt)*) $copy:tt) => { + $crate::json_internal!(@object $object [$($key)+] ($crate::json_internal!([$($array)*])) $($rest)*); + }; + + // Next value is a map. + (@object $object:ident ($($key:tt)+) (: {$($map:tt)*} $($rest:tt)*) $copy:tt) => { + $crate::json_internal!(@object $object [$($key)+] ($crate::json_internal!({$($map)*})) $($rest)*); + }; + + // Next value is an expression followed by comma. + (@object $object:ident ($($key:tt)+) (: $value:expr , $($rest:tt)*) $copy:tt) => { + $crate::json_internal!(@object $object [$($key)+] ($crate::json_internal!($value)) , $($rest)*); + }; + + // Last value is an expression with no trailing comma. + (@object $object:ident ($($key:tt)+) (: $value:expr) $copy:tt) => { + $crate::json_internal!(@object $object [$($key)+] ($crate::json_internal!($value))); + }; + + // Missing value for last entry. Trigger a reasonable error message. + (@object $object:ident ($($key:tt)+) (:) $copy:tt) => { + // "unexpected end of macro invocation" + $crate::json_internal!(); + }; + + // Missing colon and value for last entry. Trigger a reasonable error + // message. + (@object $object:ident ($($key:tt)+) () $copy:tt) => { + // "unexpected end of macro invocation" + $crate::json_internal!(); + }; + + // Misplaced colon. Trigger a reasonable error message. + (@object $object:ident () (: $($rest:tt)*) ($colon:tt $($copy:tt)*)) => { + // Takes no arguments so "no rules expected the token `:`". + $crate::json_unexpected!($colon); + }; + + // Found a comma inside a key. Trigger a reasonable error message. + (@object $object:ident ($($key:tt)*) (, $($rest:tt)*) ($comma:tt $($copy:tt)*)) => { + // Takes no arguments so "no rules expected the token `,`". + $crate::json_unexpected!($comma); + }; + + // Key is fully parenthesized. This avoids clippy double_parens false + // positives because the parenthesization may be necessary here. + (@object $object:ident () (($key:expr) : $($rest:tt)*) $copy:tt) => { + $crate::json_internal!(@object $object ($key) (: $($rest)*) (: $($rest)*)); + }; + + // Refuse to absorb colon token into key expression. + (@object $object:ident ($($key:tt)*) (: $($unexpected:tt)+) $copy:tt) => { + $crate::json_expect_expr_comma!($($unexpected)+); + }; + + // Munch a token into the current key. + (@object $object:ident ($($key:tt)*) ($tt:tt $($rest:tt)*) $copy:tt) => { + $crate::json_internal!(@object $object ($($key)* $tt) ($($rest)*) ($($rest)*)); + }; + + ////////////////////////////////////////////////////////////////////////// + // The main implementation. + // + // Must be invoked as: json_internal!($($json)+) + ////////////////////////////////////////////////////////////////////////// + + (null) => { + $crate::Value::Null + }; + + (true) => { + $crate::Value::Bool(true) + }; + + (false) => { + $crate::Value::Bool(false) + }; + + ([]) => { + $crate::Value::Array($crate::__private::vec![]) + }; + + ([ $($tt:tt)+ ]) => { + $crate::Value::Array($crate::json_internal!(@array [] $($tt)+)) + }; + + ({}) => { + $crate::Value::Object($crate::Map::new()) + }; + + ({ $($tt:tt)+ }) => { + $crate::Value::Object({ + let mut object = $crate::Map::new(); + $crate::json_internal!(@object object () ($($tt)+) ($($tt)+)); + object + }) + }; + + // Any Serialize type: numbers, strings, struct literals, variables etc. + // Must be below every other rule. + ($other:expr) => { + $crate::to_value(&$other).unwrap() + }; +} + +// Used by old versions of Rocket. +// Unused since https://github.com/rwf2/Rocket/commit/c74bcfd40a47b35330db6cafb88e4f3da83e0d17 +#[macro_export] +#[doc(hidden)] +macro_rules! json_internal_vec { + ($($content:tt)*) => { + vec![$($content)*] + }; +} + +#[macro_export] +#[doc(hidden)] +macro_rules! json_unexpected { + () => {}; +} + +#[macro_export] +#[doc(hidden)] +macro_rules! json_expect_expr_comma { + ($e:expr , $($tt:tt)*) => {}; +} diff --git a/vendor/serde_json/src/map.rs b/vendor/serde_json/src/map.rs new file mode 100644 index 0000000..7ff325b --- /dev/null +++ b/vendor/serde_json/src/map.rs @@ -0,0 +1,1139 @@ +//! A map of String to serde_json::Value. +//! +//! By default the map is backed by a [`BTreeMap`]. Enable the `preserve_order` +//! feature of serde_json to use [`IndexMap`] instead. +//! +//! [`BTreeMap`]: https://doc.rust-lang.org/std/collections/struct.BTreeMap.html +//! [`IndexMap`]: https://docs.rs/indexmap/*/indexmap/map/struct.IndexMap.html + +use crate::value::Value; +use alloc::string::String; +#[cfg(feature = "preserve_order")] +use alloc::vec::Vec; +use core::borrow::Borrow; +use core::fmt::{self, Debug}; +use core::hash::{Hash, Hasher}; +use core::iter::FusedIterator; +#[cfg(feature = "preserve_order")] +use core::mem; +use core::ops; +use serde::de; + +#[cfg(not(feature = "preserve_order"))] +use alloc::collections::{btree_map, BTreeMap}; +#[cfg(feature = "preserve_order")] +use indexmap::IndexMap; + +/// Represents a JSON key/value type. +pub struct Map { + map: MapImpl, +} + +#[cfg(not(feature = "preserve_order"))] +type MapImpl = BTreeMap; +#[cfg(feature = "preserve_order")] +type MapImpl = IndexMap; + +impl Map { + /// Makes a new empty Map. + #[inline] + pub fn new() -> Self { + Map { + map: MapImpl::new(), + } + } + + /// Makes a new empty Map with the given initial capacity. + #[inline] + pub fn with_capacity(capacity: usize) -> Self { + Map { + #[cfg(not(feature = "preserve_order"))] + map: { + // does not support with_capacity + let _ = capacity; + BTreeMap::new() + }, + #[cfg(feature = "preserve_order")] + map: IndexMap::with_capacity(capacity), + } + } + + /// Clears the map, removing all values. + #[inline] + pub fn clear(&mut self) { + self.map.clear(); + } + + /// Returns a reference to the value corresponding to the key. + /// + /// The key may be any borrowed form of the map's key type, but the ordering + /// on the borrowed form *must* match the ordering on the key type. + #[inline] + pub fn get(&self, key: &Q) -> Option<&Value> + where + String: Borrow, + Q: ?Sized + Ord + Eq + Hash, + { + self.map.get(key) + } + + /// Returns true if the map contains a value for the specified key. + /// + /// The key may be any borrowed form of the map's key type, but the ordering + /// on the borrowed form *must* match the ordering on the key type. + #[inline] + pub fn contains_key(&self, key: &Q) -> bool + where + String: Borrow, + Q: ?Sized + Ord + Eq + Hash, + { + self.map.contains_key(key) + } + + /// Returns a mutable reference to the value corresponding to the key. + /// + /// The key may be any borrowed form of the map's key type, but the ordering + /// on the borrowed form *must* match the ordering on the key type. + #[inline] + pub fn get_mut(&mut self, key: &Q) -> Option<&mut Value> + where + String: Borrow, + Q: ?Sized + Ord + Eq + Hash, + { + self.map.get_mut(key) + } + + /// Returns the key-value pair matching the given key. + /// + /// The key may be any borrowed form of the map's key type, but the ordering + /// on the borrowed form *must* match the ordering on the key type. + #[inline] + pub fn get_key_value(&self, key: &Q) -> Option<(&String, &Value)> + where + String: Borrow, + Q: ?Sized + Ord + Eq + Hash, + { + self.map.get_key_value(key) + } + + /// Inserts a key-value pair into the map. + /// + /// If the map did not have this key present, `None` is returned. + /// + /// If the map did have this key present, the value is updated, and the old + /// value is returned. + #[inline] + pub fn insert(&mut self, k: String, v: Value) -> Option { + self.map.insert(k, v) + } + + /// Insert a key-value pair in the map at the given index. + /// + /// If the map did not have this key present, `None` is returned. + /// + /// If the map did have this key present, the key is moved to the new + /// position, the value is updated, and the old value is returned. + #[cfg(feature = "preserve_order")] + #[cfg_attr(docsrs, doc(cfg(feature = "preserve_order")))] + #[inline] + pub fn shift_insert(&mut self, index: usize, k: String, v: Value) -> Option { + self.map.shift_insert(index, k, v) + } + + /// Removes a key from the map, returning the value at the key if the key + /// was previously in the map. + /// + /// The key may be any borrowed form of the map's key type, but the ordering + /// on the borrowed form *must* match the ordering on the key type. + /// + /// If serde_json's "preserve_order" is enabled, `.remove(key)` is + /// equivalent to [`.swap_remove(key)`][Self::swap_remove], replacing this + /// entry's position with the last element. If you need to preserve the + /// relative order of the keys in the map, use + /// [`.shift_remove(key)`][Self::shift_remove] instead. + #[inline] + pub fn remove(&mut self, key: &Q) -> Option + where + String: Borrow, + Q: ?Sized + Ord + Eq + Hash, + { + #[cfg(feature = "preserve_order")] + return self.swap_remove(key); + #[cfg(not(feature = "preserve_order"))] + return self.map.remove(key); + } + + /// Removes a key from the map, returning the stored key and value if the + /// key was previously in the map. + /// + /// The key may be any borrowed form of the map's key type, but the ordering + /// on the borrowed form *must* match the ordering on the key type. + /// + /// If serde_json's "preserve_order" is enabled, `.remove_entry(key)` is + /// equivalent to [`.swap_remove_entry(key)`][Self::swap_remove_entry], + /// replacing this entry's position with the last element. If you need to + /// preserve the relative order of the keys in the map, use + /// [`.shift_remove_entry(key)`][Self::shift_remove_entry] instead. + #[inline] + pub fn remove_entry(&mut self, key: &Q) -> Option<(String, Value)> + where + String: Borrow, + Q: ?Sized + Ord + Eq + Hash, + { + #[cfg(feature = "preserve_order")] + return self.swap_remove_entry(key); + #[cfg(not(feature = "preserve_order"))] + return self.map.remove_entry(key); + } + + /// Removes and returns the value corresponding to the key from the map. + /// + /// Like [`Vec::swap_remove`], the entry is removed by swapping it with the + /// last element of the map and popping it off. This perturbs the position + /// of what used to be the last element! + /// + /// [`Vec::swap_remove`]: std::vec::Vec::swap_remove + #[cfg(feature = "preserve_order")] + #[cfg_attr(docsrs, doc(cfg(feature = "preserve_order")))] + #[inline] + pub fn swap_remove(&mut self, key: &Q) -> Option + where + String: Borrow, + Q: ?Sized + Ord + Eq + Hash, + { + self.map.swap_remove(key) + } + + /// Remove and return the key-value pair. + /// + /// Like [`Vec::swap_remove`], the entry is removed by swapping it with the + /// last element of the map and popping it off. This perturbs the position + /// of what used to be the last element! + /// + /// [`Vec::swap_remove`]: std::vec::Vec::swap_remove + #[cfg(feature = "preserve_order")] + #[cfg_attr(docsrs, doc(cfg(feature = "preserve_order")))] + #[inline] + pub fn swap_remove_entry(&mut self, key: &Q) -> Option<(String, Value)> + where + String: Borrow, + Q: ?Sized + Ord + Eq + Hash, + { + self.map.swap_remove_entry(key) + } + + /// Removes and returns the value corresponding to the key from the map. + /// + /// Like [`Vec::remove`], the entry is removed by shifting all of the + /// elements that follow it, preserving their relative order. This perturbs + /// the index of all of those elements! + /// + /// [`Vec::remove`]: std::vec::Vec::remove + #[cfg(feature = "preserve_order")] + #[cfg_attr(docsrs, doc(cfg(feature = "preserve_order")))] + #[inline] + pub fn shift_remove(&mut self, key: &Q) -> Option + where + String: Borrow, + Q: ?Sized + Ord + Eq + Hash, + { + self.map.shift_remove(key) + } + + /// Remove and return the key-value pair. + /// + /// Like [`Vec::remove`], the entry is removed by shifting all of the + /// elements that follow it, preserving their relative order. This perturbs + /// the index of all of those elements! + /// + /// [`Vec::remove`]: std::vec::Vec::remove + #[cfg(feature = "preserve_order")] + #[cfg_attr(docsrs, doc(cfg(feature = "preserve_order")))] + #[inline] + pub fn shift_remove_entry(&mut self, key: &Q) -> Option<(String, Value)> + where + String: Borrow, + Q: ?Sized + Ord + Eq + Hash, + { + self.map.shift_remove_entry(key) + } + + /// Moves all elements from other into self, leaving other empty. + #[inline] + pub fn append(&mut self, other: &mut Self) { + #[cfg(feature = "preserve_order")] + self.map + .extend(mem::replace(&mut other.map, MapImpl::default())); + #[cfg(not(feature = "preserve_order"))] + self.map.append(&mut other.map); + } + + /// Gets the given key's corresponding entry in the map for in-place + /// manipulation. + pub fn entry(&mut self, key: S) -> Entry + where + S: Into, + { + #[cfg(not(feature = "preserve_order"))] + use alloc::collections::btree_map::Entry as EntryImpl; + #[cfg(feature = "preserve_order")] + use indexmap::map::Entry as EntryImpl; + + match self.map.entry(key.into()) { + EntryImpl::Vacant(vacant) => Entry::Vacant(VacantEntry { vacant }), + EntryImpl::Occupied(occupied) => Entry::Occupied(OccupiedEntry { occupied }), + } + } + + /// Returns the number of elements in the map. + #[inline] + pub fn len(&self) -> usize { + self.map.len() + } + + /// Returns true if the map contains no elements. + #[inline] + pub fn is_empty(&self) -> bool { + self.map.is_empty() + } + + /// Gets an iterator over the entries of the map. + #[inline] + pub fn iter(&self) -> Iter { + Iter { + iter: self.map.iter(), + } + } + + /// Gets a mutable iterator over the entries of the map. + #[inline] + pub fn iter_mut(&mut self) -> IterMut { + IterMut { + iter: self.map.iter_mut(), + } + } + + /// Gets an iterator over the keys of the map. + #[inline] + pub fn keys(&self) -> Keys { + Keys { + iter: self.map.keys(), + } + } + + /// Gets an iterator over the values of the map. + #[inline] + pub fn values(&self) -> Values { + Values { + iter: self.map.values(), + } + } + + /// Gets an iterator over mutable values of the map. + #[inline] + pub fn values_mut(&mut self) -> ValuesMut { + ValuesMut { + iter: self.map.values_mut(), + } + } + + /// Retains only the elements specified by the predicate. + /// + /// In other words, remove all pairs `(k, v)` such that `f(&k, &mut v)` + /// returns `false`. + #[inline] + pub fn retain(&mut self, f: F) + where + F: FnMut(&String, &mut Value) -> bool, + { + self.map.retain(f); + } + + /// Sorts this map's entries in-place using `str`'s usual ordering. + /// + /// If serde_json's "preserve_order" feature is not enabled, this method + /// does no work because all JSON maps are always kept in a sorted state. + /// + /// If serde_json's "preserve_order" feature is enabled, this method + /// destroys the original source order or insertion order of this map in + /// favor of an alphanumerical order that matches how a BTreeMap with the + /// same contents would be ordered. This takes **O(n log n + c)** time where + /// _n_ is the length of the map and _c_ is the capacity. + /// + /// Other maps nested within the values of this map are not sorted. If you + /// need the entire data structure to be sorted at all levels, you must also + /// call `map.`[`values_mut`]`().for_each(`[`Value::sort_all_objects`]`)`. + /// + /// [`values_mut`]: Map::values_mut + #[inline] + pub fn sort_keys(&mut self) { + #[cfg(feature = "preserve_order")] + self.map.sort_unstable_keys(); + } +} + +#[allow(clippy::derivable_impls)] // clippy bug: https://github.com/rust-lang/rust-clippy/issues/7655 +impl Default for Map { + #[inline] + fn default() -> Self { + Map { + map: MapImpl::new(), + } + } +} + +impl Clone for Map { + #[inline] + fn clone(&self) -> Self { + Map { + map: self.map.clone(), + } + } + + #[inline] + fn clone_from(&mut self, source: &Self) { + self.map.clone_from(&source.map); + } +} + +impl PartialEq for Map { + #[inline] + fn eq(&self, other: &Self) -> bool { + self.map.eq(&other.map) + } +} + +impl Eq for Map {} + +impl Hash for Map { + fn hash(&self, state: &mut H) { + #[cfg(not(feature = "preserve_order"))] + { + self.map.hash(state); + } + + #[cfg(feature = "preserve_order")] + { + let mut kv = Vec::from_iter(&self.map); + kv.sort_unstable_by(|a, b| a.0.cmp(b.0)); + kv.hash(state); + } + } +} + +/// Access an element of this map. Panics if the given key is not present in the +/// map. +/// +/// ``` +/// # use serde_json::Value; +/// # +/// # let val = &Value::String("".to_owned()); +/// # let _ = +/// match val { +/// Value::String(s) => Some(s.as_str()), +/// Value::Array(arr) => arr[0].as_str(), +/// Value::Object(map) => map["type"].as_str(), +/// _ => None, +/// } +/// # ; +/// ``` +impl ops::Index<&Q> for Map +where + String: Borrow, + Q: ?Sized + Ord + Eq + Hash, +{ + type Output = Value; + + fn index(&self, index: &Q) -> &Value { + self.map.index(index) + } +} + +/// Mutably access an element of this map. Panics if the given key is not +/// present in the map. +/// +/// ``` +/// # use serde_json::json; +/// # +/// # let mut map = serde_json::Map::new(); +/// # map.insert("key".to_owned(), serde_json::Value::Null); +/// # +/// map["key"] = json!("value"); +/// ``` +impl ops::IndexMut<&Q> for Map +where + String: Borrow, + Q: ?Sized + Ord + Eq + Hash, +{ + fn index_mut(&mut self, index: &Q) -> &mut Value { + self.map.get_mut(index).expect("no entry found for key") + } +} + +impl Debug for Map { + #[inline] + fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> { + self.map.fmt(formatter) + } +} + +#[cfg(any(feature = "std", feature = "alloc"))] +impl serde::ser::Serialize for Map { + #[inline] + fn serialize(&self, serializer: S) -> Result + where + S: serde::ser::Serializer, + { + use serde::ser::SerializeMap; + let mut map = tri!(serializer.serialize_map(Some(self.len()))); + for (k, v) in self { + tri!(map.serialize_entry(k, v)); + } + map.end() + } +} + +impl<'de> de::Deserialize<'de> for Map { + #[inline] + fn deserialize(deserializer: D) -> Result + where + D: de::Deserializer<'de>, + { + struct Visitor; + + impl<'de> de::Visitor<'de> for Visitor { + type Value = Map; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("a map") + } + + #[inline] + fn visit_unit(self) -> Result + where + E: de::Error, + { + Ok(Map::new()) + } + + #[cfg(any(feature = "std", feature = "alloc"))] + #[inline] + fn visit_map(self, mut visitor: V) -> Result + where + V: de::MapAccess<'de>, + { + let mut values = Map::new(); + + while let Some((key, value)) = tri!(visitor.next_entry()) { + values.insert(key, value); + } + + Ok(values) + } + } + + deserializer.deserialize_map(Visitor) + } +} + +impl FromIterator<(String, Value)> for Map { + fn from_iter(iter: T) -> Self + where + T: IntoIterator, + { + Map { + map: FromIterator::from_iter(iter), + } + } +} + +impl Extend<(String, Value)> for Map { + fn extend(&mut self, iter: T) + where + T: IntoIterator, + { + self.map.extend(iter); + } +} + +macro_rules! delegate_iterator { + (($name:ident $($generics:tt)*) => $item:ty) => { + impl $($generics)* Iterator for $name $($generics)* { + type Item = $item; + #[inline] + fn next(&mut self) -> Option { + self.iter.next() + } + #[inline] + fn size_hint(&self) -> (usize, Option) { + self.iter.size_hint() + } + } + + impl $($generics)* DoubleEndedIterator for $name $($generics)* { + #[inline] + fn next_back(&mut self) -> Option { + self.iter.next_back() + } + } + + impl $($generics)* ExactSizeIterator for $name $($generics)* { + #[inline] + fn len(&self) -> usize { + self.iter.len() + } + } + + impl $($generics)* FusedIterator for $name $($generics)* {} + } +} + +////////////////////////////////////////////////////////////////////////////// + +/// A view into a single entry in a map, which may either be vacant or occupied. +/// This enum is constructed from the [`entry`] method on [`Map`]. +/// +/// [`entry`]: struct.Map.html#method.entry +/// [`Map`]: struct.Map.html +pub enum Entry<'a> { + /// A vacant Entry. + Vacant(VacantEntry<'a>), + /// An occupied Entry. + Occupied(OccupiedEntry<'a>), +} + +/// A vacant Entry. It is part of the [`Entry`] enum. +/// +/// [`Entry`]: enum.Entry.html +pub struct VacantEntry<'a> { + vacant: VacantEntryImpl<'a>, +} + +/// An occupied Entry. It is part of the [`Entry`] enum. +/// +/// [`Entry`]: enum.Entry.html +pub struct OccupiedEntry<'a> { + occupied: OccupiedEntryImpl<'a>, +} + +#[cfg(not(feature = "preserve_order"))] +type VacantEntryImpl<'a> = btree_map::VacantEntry<'a, String, Value>; +#[cfg(feature = "preserve_order")] +type VacantEntryImpl<'a> = indexmap::map::VacantEntry<'a, String, Value>; + +#[cfg(not(feature = "preserve_order"))] +type OccupiedEntryImpl<'a> = btree_map::OccupiedEntry<'a, String, Value>; +#[cfg(feature = "preserve_order")] +type OccupiedEntryImpl<'a> = indexmap::map::OccupiedEntry<'a, String, Value>; + +impl<'a> Entry<'a> { + /// Returns a reference to this entry's key. + /// + /// # Examples + /// + /// ``` + /// let mut map = serde_json::Map::new(); + /// assert_eq!(map.entry("serde").key(), &"serde"); + /// ``` + pub fn key(&self) -> &String { + match self { + Entry::Vacant(e) => e.key(), + Entry::Occupied(e) => e.key(), + } + } + + /// Ensures a value is in the entry by inserting the default if empty, and + /// returns a mutable reference to the value in the entry. + /// + /// # Examples + /// + /// ``` + /// # use serde_json::json; + /// # + /// let mut map = serde_json::Map::new(); + /// map.entry("serde").or_insert(json!(12)); + /// + /// assert_eq!(map["serde"], 12); + /// ``` + pub fn or_insert(self, default: Value) -> &'a mut Value { + match self { + Entry::Vacant(entry) => entry.insert(default), + Entry::Occupied(entry) => entry.into_mut(), + } + } + + /// Ensures a value is in the entry by inserting the result of the default + /// function if empty, and returns a mutable reference to the value in the + /// entry. + /// + /// # Examples + /// + /// ``` + /// # use serde_json::json; + /// # + /// let mut map = serde_json::Map::new(); + /// map.entry("serde").or_insert_with(|| json!("hoho")); + /// + /// assert_eq!(map["serde"], "hoho".to_owned()); + /// ``` + pub fn or_insert_with(self, default: F) -> &'a mut Value + where + F: FnOnce() -> Value, + { + match self { + Entry::Vacant(entry) => entry.insert(default()), + Entry::Occupied(entry) => entry.into_mut(), + } + } + + /// Provides in-place mutable access to an occupied entry before any + /// potential inserts into the map. + /// + /// # Examples + /// + /// ``` + /// # use serde_json::json; + /// # + /// let mut map = serde_json::Map::new(); + /// map.entry("serde") + /// .and_modify(|e| *e = json!("rust")) + /// .or_insert(json!("cpp")); + /// + /// assert_eq!(map["serde"], "cpp"); + /// + /// map.entry("serde") + /// .and_modify(|e| *e = json!("rust")) + /// .or_insert(json!("cpp")); + /// + /// assert_eq!(map["serde"], "rust"); + /// ``` + pub fn and_modify(self, f: F) -> Self + where + F: FnOnce(&mut Value), + { + match self { + Entry::Occupied(mut entry) => { + f(entry.get_mut()); + Entry::Occupied(entry) + } + Entry::Vacant(entry) => Entry::Vacant(entry), + } + } +} + +impl<'a> VacantEntry<'a> { + /// Gets a reference to the key that would be used when inserting a value + /// through the VacantEntry. + /// + /// # Examples + /// + /// ``` + /// use serde_json::map::Entry; + /// + /// let mut map = serde_json::Map::new(); + /// + /// match map.entry("serde") { + /// Entry::Vacant(vacant) => { + /// assert_eq!(vacant.key(), &"serde"); + /// } + /// Entry::Occupied(_) => unimplemented!(), + /// } + /// ``` + #[inline] + pub fn key(&self) -> &String { + self.vacant.key() + } + + /// Sets the value of the entry with the VacantEntry's key, and returns a + /// mutable reference to it. + /// + /// # Examples + /// + /// ``` + /// # use serde_json::json; + /// # + /// use serde_json::map::Entry; + /// + /// let mut map = serde_json::Map::new(); + /// + /// match map.entry("serde") { + /// Entry::Vacant(vacant) => { + /// vacant.insert(json!("hoho")); + /// } + /// Entry::Occupied(_) => unimplemented!(), + /// } + /// ``` + #[inline] + pub fn insert(self, value: Value) -> &'a mut Value { + self.vacant.insert(value) + } +} + +impl<'a> OccupiedEntry<'a> { + /// Gets a reference to the key in the entry. + /// + /// # Examples + /// + /// ``` + /// # use serde_json::json; + /// # + /// use serde_json::map::Entry; + /// + /// let mut map = serde_json::Map::new(); + /// map.insert("serde".to_owned(), json!(12)); + /// + /// match map.entry("serde") { + /// Entry::Occupied(occupied) => { + /// assert_eq!(occupied.key(), &"serde"); + /// } + /// Entry::Vacant(_) => unimplemented!(), + /// } + /// ``` + #[inline] + pub fn key(&self) -> &String { + self.occupied.key() + } + + /// Gets a reference to the value in the entry. + /// + /// # Examples + /// + /// ``` + /// # use serde_json::json; + /// # + /// use serde_json::map::Entry; + /// + /// let mut map = serde_json::Map::new(); + /// map.insert("serde".to_owned(), json!(12)); + /// + /// match map.entry("serde") { + /// Entry::Occupied(occupied) => { + /// assert_eq!(occupied.get(), 12); + /// } + /// Entry::Vacant(_) => unimplemented!(), + /// } + /// ``` + #[inline] + pub fn get(&self) -> &Value { + self.occupied.get() + } + + /// Gets a mutable reference to the value in the entry. + /// + /// # Examples + /// + /// ``` + /// # use serde_json::json; + /// # + /// use serde_json::map::Entry; + /// + /// let mut map = serde_json::Map::new(); + /// map.insert("serde".to_owned(), json!([1, 2, 3])); + /// + /// match map.entry("serde") { + /// Entry::Occupied(mut occupied) => { + /// occupied.get_mut().as_array_mut().unwrap().push(json!(4)); + /// } + /// Entry::Vacant(_) => unimplemented!(), + /// } + /// + /// assert_eq!(map["serde"].as_array().unwrap().len(), 4); + /// ``` + #[inline] + pub fn get_mut(&mut self) -> &mut Value { + self.occupied.get_mut() + } + + /// Converts the entry into a mutable reference to its value. + /// + /// # Examples + /// + /// ``` + /// # use serde_json::json; + /// # + /// use serde_json::map::Entry; + /// + /// let mut map = serde_json::Map::new(); + /// map.insert("serde".to_owned(), json!([1, 2, 3])); + /// + /// match map.entry("serde") { + /// Entry::Occupied(mut occupied) => { + /// occupied.into_mut().as_array_mut().unwrap().push(json!(4)); + /// } + /// Entry::Vacant(_) => unimplemented!(), + /// } + /// + /// assert_eq!(map["serde"].as_array().unwrap().len(), 4); + /// ``` + #[inline] + pub fn into_mut(self) -> &'a mut Value { + self.occupied.into_mut() + } + + /// Sets the value of the entry with the `OccupiedEntry`'s key, and returns + /// the entry's old value. + /// + /// # Examples + /// + /// ``` + /// # use serde_json::json; + /// # + /// use serde_json::map::Entry; + /// + /// let mut map = serde_json::Map::new(); + /// map.insert("serde".to_owned(), json!(12)); + /// + /// match map.entry("serde") { + /// Entry::Occupied(mut occupied) => { + /// assert_eq!(occupied.insert(json!(13)), 12); + /// assert_eq!(occupied.get(), 13); + /// } + /// Entry::Vacant(_) => unimplemented!(), + /// } + /// ``` + #[inline] + pub fn insert(&mut self, value: Value) -> Value { + self.occupied.insert(value) + } + + /// Takes the value of the entry out of the map, and returns it. + /// + /// If serde_json's "preserve_order" is enabled, `.remove()` is + /// equivalent to [`.swap_remove()`][Self::swap_remove], replacing this + /// entry's position with the last element. If you need to preserve the + /// relative order of the keys in the map, use + /// [`.shift_remove()`][Self::shift_remove] instead. + /// + /// # Examples + /// + /// ``` + /// # use serde_json::json; + /// # + /// use serde_json::map::Entry; + /// + /// let mut map = serde_json::Map::new(); + /// map.insert("serde".to_owned(), json!(12)); + /// + /// match map.entry("serde") { + /// Entry::Occupied(occupied) => { + /// assert_eq!(occupied.remove(), 12); + /// } + /// Entry::Vacant(_) => unimplemented!(), + /// } + /// ``` + #[inline] + pub fn remove(self) -> Value { + #[cfg(feature = "preserve_order")] + return self.swap_remove(); + #[cfg(not(feature = "preserve_order"))] + return self.occupied.remove(); + } + + /// Takes the value of the entry out of the map, and returns it. + /// + /// Like [`Vec::swap_remove`], the entry is removed by swapping it with the + /// last element of the map and popping it off. This perturbs the position + /// of what used to be the last element! + /// + /// [`Vec::swap_remove`]: std::vec::Vec::swap_remove + #[cfg(feature = "preserve_order")] + #[cfg_attr(docsrs, doc(cfg(feature = "preserve_order")))] + #[inline] + pub fn swap_remove(self) -> Value { + self.occupied.swap_remove() + } + + /// Takes the value of the entry out of the map, and returns it. + /// + /// Like [`Vec::remove`], the entry is removed by shifting all of the + /// elements that follow it, preserving their relative order. This perturbs + /// the index of all of those elements! + /// + /// [`Vec::remove`]: std::vec::Vec::remove + #[cfg(feature = "preserve_order")] + #[cfg_attr(docsrs, doc(cfg(feature = "preserve_order")))] + #[inline] + pub fn shift_remove(self) -> Value { + self.occupied.shift_remove() + } + + /// Removes the entry from the map, returning the stored key and value. + /// + /// If serde_json's "preserve_order" is enabled, `.remove_entry()` is + /// equivalent to [`.swap_remove_entry()`][Self::swap_remove_entry], + /// replacing this entry's position with the last element. If you need to + /// preserve the relative order of the keys in the map, use + /// [`.shift_remove_entry()`][Self::shift_remove_entry] instead. + /// + /// # Examples + /// + /// ``` + /// # use serde_json::json; + /// # + /// use serde_json::map::Entry; + /// + /// let mut map = serde_json::Map::new(); + /// map.insert("serde".to_owned(), json!(12)); + /// + /// match map.entry("serde") { + /// Entry::Occupied(occupied) => { + /// let (key, value) = occupied.remove_entry(); + /// assert_eq!(key, "serde"); + /// assert_eq!(value, 12); + /// } + /// Entry::Vacant(_) => unimplemented!(), + /// } + /// ``` + #[inline] + pub fn remove_entry(self) -> (String, Value) { + #[cfg(feature = "preserve_order")] + return self.swap_remove_entry(); + #[cfg(not(feature = "preserve_order"))] + return self.occupied.remove_entry(); + } + + /// Removes the entry from the map, returning the stored key and value. + /// + /// Like [`Vec::swap_remove`], the entry is removed by swapping it with the + /// last element of the map and popping it off. This perturbs the position + /// of what used to be the last element! + /// + /// [`Vec::swap_remove`]: std::vec::Vec::swap_remove + #[cfg(feature = "preserve_order")] + #[cfg_attr(docsrs, doc(cfg(feature = "preserve_order")))] + #[inline] + pub fn swap_remove_entry(self) -> (String, Value) { + self.occupied.swap_remove_entry() + } + + /// Removes the entry from the map, returning the stored key and value. + /// + /// Like [`Vec::remove`], the entry is removed by shifting all of the + /// elements that follow it, preserving their relative order. This perturbs + /// the index of all of those elements! + /// + /// [`Vec::remove`]: std::vec::Vec::remove + #[cfg(feature = "preserve_order")] + #[cfg_attr(docsrs, doc(cfg(feature = "preserve_order")))] + #[inline] + pub fn shift_remove_entry(self) -> (String, Value) { + self.occupied.shift_remove_entry() + } +} + +////////////////////////////////////////////////////////////////////////////// + +impl<'a> IntoIterator for &'a Map { + type Item = (&'a String, &'a Value); + type IntoIter = Iter<'a>; + #[inline] + fn into_iter(self) -> Self::IntoIter { + Iter { + iter: self.map.iter(), + } + } +} + +/// An iterator over a serde_json::Map's entries. +pub struct Iter<'a> { + iter: IterImpl<'a>, +} + +#[cfg(not(feature = "preserve_order"))] +type IterImpl<'a> = btree_map::Iter<'a, String, Value>; +#[cfg(feature = "preserve_order")] +type IterImpl<'a> = indexmap::map::Iter<'a, String, Value>; + +delegate_iterator!((Iter<'a>) => (&'a String, &'a Value)); + +////////////////////////////////////////////////////////////////////////////// + +impl<'a> IntoIterator for &'a mut Map { + type Item = (&'a String, &'a mut Value); + type IntoIter = IterMut<'a>; + #[inline] + fn into_iter(self) -> Self::IntoIter { + IterMut { + iter: self.map.iter_mut(), + } + } +} + +/// A mutable iterator over a serde_json::Map's entries. +pub struct IterMut<'a> { + iter: IterMutImpl<'a>, +} + +#[cfg(not(feature = "preserve_order"))] +type IterMutImpl<'a> = btree_map::IterMut<'a, String, Value>; +#[cfg(feature = "preserve_order")] +type IterMutImpl<'a> = indexmap::map::IterMut<'a, String, Value>; + +delegate_iterator!((IterMut<'a>) => (&'a String, &'a mut Value)); + +////////////////////////////////////////////////////////////////////////////// + +impl IntoIterator for Map { + type Item = (String, Value); + type IntoIter = IntoIter; + #[inline] + fn into_iter(self) -> Self::IntoIter { + IntoIter { + iter: self.map.into_iter(), + } + } +} + +/// An owning iterator over a serde_json::Map's entries. +pub struct IntoIter { + iter: IntoIterImpl, +} + +#[cfg(not(feature = "preserve_order"))] +type IntoIterImpl = btree_map::IntoIter; +#[cfg(feature = "preserve_order")] +type IntoIterImpl = indexmap::map::IntoIter; + +delegate_iterator!((IntoIter) => (String, Value)); + +////////////////////////////////////////////////////////////////////////////// + +/// An iterator over a serde_json::Map's keys. +pub struct Keys<'a> { + iter: KeysImpl<'a>, +} + +#[cfg(not(feature = "preserve_order"))] +type KeysImpl<'a> = btree_map::Keys<'a, String, Value>; +#[cfg(feature = "preserve_order")] +type KeysImpl<'a> = indexmap::map::Keys<'a, String, Value>; + +delegate_iterator!((Keys<'a>) => &'a String); + +////////////////////////////////////////////////////////////////////////////// + +/// An iterator over a serde_json::Map's values. +pub struct Values<'a> { + iter: ValuesImpl<'a>, +} + +#[cfg(not(feature = "preserve_order"))] +type ValuesImpl<'a> = btree_map::Values<'a, String, Value>; +#[cfg(feature = "preserve_order")] +type ValuesImpl<'a> = indexmap::map::Values<'a, String, Value>; + +delegate_iterator!((Values<'a>) => &'a Value); + +////////////////////////////////////////////////////////////////////////////// + +/// A mutable iterator over a serde_json::Map's values. +pub struct ValuesMut<'a> { + iter: ValuesMutImpl<'a>, +} + +#[cfg(not(feature = "preserve_order"))] +type ValuesMutImpl<'a> = btree_map::ValuesMut<'a, String, Value>; +#[cfg(feature = "preserve_order")] +type ValuesMutImpl<'a> = indexmap::map::ValuesMut<'a, String, Value>; + +delegate_iterator!((ValuesMut<'a>) => &'a mut Value); diff --git a/vendor/serde_json/src/number.rs b/vendor/serde_json/src/number.rs new file mode 100644 index 0000000..3ba0846 --- /dev/null +++ b/vendor/serde_json/src/number.rs @@ -0,0 +1,801 @@ +use crate::de::ParserNumber; +use crate::error::Error; +#[cfg(feature = "arbitrary_precision")] +use crate::error::ErrorCode; +#[cfg(feature = "arbitrary_precision")] +use alloc::borrow::ToOwned; +#[cfg(feature = "arbitrary_precision")] +use alloc::string::{String, ToString}; +use core::fmt::{self, Debug, Display}; +#[cfg(not(feature = "arbitrary_precision"))] +use core::hash::{Hash, Hasher}; +use serde::de::{self, Unexpected, Visitor}; +#[cfg(feature = "arbitrary_precision")] +use serde::de::{IntoDeserializer, MapAccess}; +use serde::{forward_to_deserialize_any, Deserialize, Deserializer, Serialize, Serializer}; + +#[cfg(feature = "arbitrary_precision")] +pub(crate) const TOKEN: &str = "$serde_json::private::Number"; + +/// Represents a JSON number, whether integer or floating point. +#[derive(Clone, PartialEq, Eq, Hash)] +pub struct Number { + n: N, +} + +#[cfg(not(feature = "arbitrary_precision"))] +#[derive(Copy, Clone)] +enum N { + PosInt(u64), + /// Always less than zero. + NegInt(i64), + /// Always finite. + Float(f64), +} + +#[cfg(not(feature = "arbitrary_precision"))] +impl PartialEq for N { + fn eq(&self, other: &Self) -> bool { + match (self, other) { + (N::PosInt(a), N::PosInt(b)) => a == b, + (N::NegInt(a), N::NegInt(b)) => a == b, + (N::Float(a), N::Float(b)) => a == b, + _ => false, + } + } +} + +// Implementing Eq is fine since any float values are always finite. +#[cfg(not(feature = "arbitrary_precision"))] +impl Eq for N {} + +#[cfg(not(feature = "arbitrary_precision"))] +impl Hash for N { + fn hash(&self, h: &mut H) { + match *self { + N::PosInt(i) => i.hash(h), + N::NegInt(i) => i.hash(h), + N::Float(f) => { + if f == 0.0f64 { + // There are 2 zero representations, +0 and -0, which + // compare equal but have different bits. We use the +0 hash + // for both so that hash(+0) == hash(-0). + 0.0f64.to_bits().hash(h); + } else { + f.to_bits().hash(h); + } + } + } + } +} + +#[cfg(feature = "arbitrary_precision")] +type N = String; + +impl Number { + /// Returns true if the `Number` is an integer between `i64::MIN` and + /// `i64::MAX`. + /// + /// For any Number on which `is_i64` returns true, `as_i64` is guaranteed to + /// return the integer value. + /// + /// ``` + /// # use serde_json::json; + /// # + /// let big = i64::MAX as u64 + 10; + /// let v = json!({ "a": 64, "b": big, "c": 256.0 }); + /// + /// assert!(v["a"].is_i64()); + /// + /// // Greater than i64::MAX. + /// assert!(!v["b"].is_i64()); + /// + /// // Numbers with a decimal point are not considered integers. + /// assert!(!v["c"].is_i64()); + /// ``` + #[inline] + pub fn is_i64(&self) -> bool { + #[cfg(not(feature = "arbitrary_precision"))] + match self.n { + N::PosInt(v) => v <= i64::MAX as u64, + N::NegInt(_) => true, + N::Float(_) => false, + } + #[cfg(feature = "arbitrary_precision")] + self.as_i64().is_some() + } + + /// Returns true if the `Number` is an integer between zero and `u64::MAX`. + /// + /// For any Number on which `is_u64` returns true, `as_u64` is guaranteed to + /// return the integer value. + /// + /// ``` + /// # use serde_json::json; + /// # + /// let v = json!({ "a": 64, "b": -64, "c": 256.0 }); + /// + /// assert!(v["a"].is_u64()); + /// + /// // Negative integer. + /// assert!(!v["b"].is_u64()); + /// + /// // Numbers with a decimal point are not considered integers. + /// assert!(!v["c"].is_u64()); + /// ``` + #[inline] + pub fn is_u64(&self) -> bool { + #[cfg(not(feature = "arbitrary_precision"))] + match self.n { + N::PosInt(_) => true, + N::NegInt(_) | N::Float(_) => false, + } + #[cfg(feature = "arbitrary_precision")] + self.as_u64().is_some() + } + + /// Returns true if the `Number` can be represented by f64. + /// + /// For any Number on which `is_f64` returns true, `as_f64` is guaranteed to + /// return the floating point value. + /// + /// Currently this function returns true if and only if both `is_i64` and + /// `is_u64` return false but this is not a guarantee in the future. + /// + /// ``` + /// # use serde_json::json; + /// # + /// let v = json!({ "a": 256.0, "b": 64, "c": -64 }); + /// + /// assert!(v["a"].is_f64()); + /// + /// // Integers. + /// assert!(!v["b"].is_f64()); + /// assert!(!v["c"].is_f64()); + /// ``` + #[inline] + pub fn is_f64(&self) -> bool { + #[cfg(not(feature = "arbitrary_precision"))] + match self.n { + N::Float(_) => true, + N::PosInt(_) | N::NegInt(_) => false, + } + #[cfg(feature = "arbitrary_precision")] + { + for c in self.n.chars() { + if c == '.' || c == 'e' || c == 'E' { + return self.n.parse::().ok().map_or(false, f64::is_finite); + } + } + false + } + } + + /// If the `Number` is an integer, represent it as i64 if possible. Returns + /// None otherwise. + /// + /// ``` + /// # use serde_json::json; + /// # + /// let big = i64::MAX as u64 + 10; + /// let v = json!({ "a": 64, "b": big, "c": 256.0 }); + /// + /// assert_eq!(v["a"].as_i64(), Some(64)); + /// assert_eq!(v["b"].as_i64(), None); + /// assert_eq!(v["c"].as_i64(), None); + /// ``` + #[inline] + pub fn as_i64(&self) -> Option { + #[cfg(not(feature = "arbitrary_precision"))] + match self.n { + N::PosInt(n) => { + if n <= i64::MAX as u64 { + Some(n as i64) + } else { + None + } + } + N::NegInt(n) => Some(n), + N::Float(_) => None, + } + #[cfg(feature = "arbitrary_precision")] + self.n.parse().ok() + } + + /// If the `Number` is an integer, represent it as u64 if possible. Returns + /// None otherwise. + /// + /// ``` + /// # use serde_json::json; + /// # + /// let v = json!({ "a": 64, "b": -64, "c": 256.0 }); + /// + /// assert_eq!(v["a"].as_u64(), Some(64)); + /// assert_eq!(v["b"].as_u64(), None); + /// assert_eq!(v["c"].as_u64(), None); + /// ``` + #[inline] + pub fn as_u64(&self) -> Option { + #[cfg(not(feature = "arbitrary_precision"))] + match self.n { + N::PosInt(n) => Some(n), + N::NegInt(_) | N::Float(_) => None, + } + #[cfg(feature = "arbitrary_precision")] + self.n.parse().ok() + } + + /// Represents the number as f64 if possible. Returns None otherwise. + /// + /// ``` + /// # use serde_json::json; + /// # + /// let v = json!({ "a": 256.0, "b": 64, "c": -64 }); + /// + /// assert_eq!(v["a"].as_f64(), Some(256.0)); + /// assert_eq!(v["b"].as_f64(), Some(64.0)); + /// assert_eq!(v["c"].as_f64(), Some(-64.0)); + /// ``` + #[inline] + pub fn as_f64(&self) -> Option { + #[cfg(not(feature = "arbitrary_precision"))] + match self.n { + N::PosInt(n) => Some(n as f64), + N::NegInt(n) => Some(n as f64), + N::Float(n) => Some(n), + } + #[cfg(feature = "arbitrary_precision")] + self.n.parse::().ok().filter(|float| float.is_finite()) + } + + /// Converts a finite `f64` to a `Number`. Infinite or NaN values are not JSON + /// numbers. + /// + /// ``` + /// # use std::f64; + /// # + /// # use serde_json::Number; + /// # + /// assert!(Number::from_f64(256.0).is_some()); + /// + /// assert!(Number::from_f64(f64::NAN).is_none()); + /// ``` + #[inline] + pub fn from_f64(f: f64) -> Option { + if f.is_finite() { + let n = { + #[cfg(not(feature = "arbitrary_precision"))] + { + N::Float(f) + } + #[cfg(feature = "arbitrary_precision")] + { + ryu::Buffer::new().format_finite(f).to_owned() + } + }; + Some(Number { n }) + } else { + None + } + } + + /// Returns the exact original JSON representation that this Number was + /// parsed from. + /// + /// For numbers constructed not via parsing, such as by `From`, returns + /// the JSON representation that serde\_json would serialize for this + /// number. + /// + /// ``` + /// # use serde_json::Number; + /// for value in [ + /// "7", + /// "12.34", + /// "34e-56789", + /// "0.0123456789000000012345678900000001234567890000123456789", + /// "343412345678910111213141516171819202122232425262728293034", + /// "-343412345678910111213141516171819202122232425262728293031", + /// ] { + /// let number: Number = serde_json::from_str(value).unwrap(); + /// assert_eq!(number.as_str(), value); + /// } + /// ``` + #[cfg(feature = "arbitrary_precision")] + #[cfg_attr(docsrs, doc(cfg(feature = "arbitrary_precision")))] + pub fn as_str(&self) -> &str { + &self.n + } + + pub(crate) fn as_f32(&self) -> Option { + #[cfg(not(feature = "arbitrary_precision"))] + match self.n { + N::PosInt(n) => Some(n as f32), + N::NegInt(n) => Some(n as f32), + N::Float(n) => Some(n as f32), + } + #[cfg(feature = "arbitrary_precision")] + self.n.parse::().ok().filter(|float| float.is_finite()) + } + + pub(crate) fn from_f32(f: f32) -> Option { + if f.is_finite() { + let n = { + #[cfg(not(feature = "arbitrary_precision"))] + { + N::Float(f as f64) + } + #[cfg(feature = "arbitrary_precision")] + { + ryu::Buffer::new().format_finite(f).to_owned() + } + }; + Some(Number { n }) + } else { + None + } + } + + #[cfg(feature = "arbitrary_precision")] + /// Not public API. Only tests use this. + #[doc(hidden)] + #[inline] + pub fn from_string_unchecked(n: String) -> Self { + Number { n } + } +} + +impl Display for Number { + #[cfg(not(feature = "arbitrary_precision"))] + fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + match self.n { + N::PosInt(u) => formatter.write_str(itoa::Buffer::new().format(u)), + N::NegInt(i) => formatter.write_str(itoa::Buffer::new().format(i)), + N::Float(f) => formatter.write_str(ryu::Buffer::new().format_finite(f)), + } + } + + #[cfg(feature = "arbitrary_precision")] + fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + Display::fmt(&self.n, formatter) + } +} + +impl Debug for Number { + fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + write!(formatter, "Number({})", self) + } +} + +impl Serialize for Number { + #[cfg(not(feature = "arbitrary_precision"))] + #[inline] + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + match self.n { + N::PosInt(u) => serializer.serialize_u64(u), + N::NegInt(i) => serializer.serialize_i64(i), + N::Float(f) => serializer.serialize_f64(f), + } + } + + #[cfg(feature = "arbitrary_precision")] + #[inline] + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + use serde::ser::SerializeStruct; + + let mut s = tri!(serializer.serialize_struct(TOKEN, 1)); + tri!(s.serialize_field(TOKEN, &self.n)); + s.end() + } +} + +impl<'de> Deserialize<'de> for Number { + #[inline] + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + struct NumberVisitor; + + impl<'de> Visitor<'de> for NumberVisitor { + type Value = Number; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("a JSON number") + } + + #[inline] + fn visit_i64(self, value: i64) -> Result { + Ok(value.into()) + } + + #[inline] + fn visit_u64(self, value: u64) -> Result { + Ok(value.into()) + } + + #[inline] + fn visit_f64(self, value: f64) -> Result + where + E: de::Error, + { + Number::from_f64(value).ok_or_else(|| de::Error::custom("not a JSON number")) + } + + #[cfg(feature = "arbitrary_precision")] + #[inline] + fn visit_map(self, mut visitor: V) -> Result + where + V: de::MapAccess<'de>, + { + let value = tri!(visitor.next_key::()); + if value.is_none() { + return Err(de::Error::invalid_type(Unexpected::Map, &self)); + } + let v: NumberFromString = tri!(visitor.next_value()); + Ok(v.value) + } + } + + deserializer.deserialize_any(NumberVisitor) + } +} + +#[cfg(feature = "arbitrary_precision")] +struct NumberKey; + +#[cfg(feature = "arbitrary_precision")] +impl<'de> de::Deserialize<'de> for NumberKey { + fn deserialize(deserializer: D) -> Result + where + D: de::Deserializer<'de>, + { + struct FieldVisitor; + + impl<'de> de::Visitor<'de> for FieldVisitor { + type Value = (); + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("a valid number field") + } + + fn visit_str(self, s: &str) -> Result<(), E> + where + E: de::Error, + { + if s == TOKEN { + Ok(()) + } else { + Err(de::Error::custom("expected field with custom name")) + } + } + } + + tri!(deserializer.deserialize_identifier(FieldVisitor)); + Ok(NumberKey) + } +} + +#[cfg(feature = "arbitrary_precision")] +pub struct NumberFromString { + pub value: Number, +} + +#[cfg(feature = "arbitrary_precision")] +impl<'de> de::Deserialize<'de> for NumberFromString { + fn deserialize(deserializer: D) -> Result + where + D: de::Deserializer<'de>, + { + struct Visitor; + + impl<'de> de::Visitor<'de> for Visitor { + type Value = NumberFromString; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("string containing a number") + } + + fn visit_str(self, s: &str) -> Result + where + E: de::Error, + { + let n = tri!(s.parse().map_err(de::Error::custom)); + Ok(NumberFromString { value: n }) + } + } + + deserializer.deserialize_str(Visitor) + } +} + +#[cfg(feature = "arbitrary_precision")] +fn invalid_number() -> Error { + Error::syntax(ErrorCode::InvalidNumber, 0, 0) +} + +macro_rules! deserialize_any { + (@expand [$($num_string:tt)*]) => { + #[cfg(not(feature = "arbitrary_precision"))] + #[inline] + fn deserialize_any(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + match self.n { + N::PosInt(u) => visitor.visit_u64(u), + N::NegInt(i) => visitor.visit_i64(i), + N::Float(f) => visitor.visit_f64(f), + } + } + + #[cfg(feature = "arbitrary_precision")] + #[inline] + fn deserialize_any(self, visitor: V) -> Result + where V: Visitor<'de> + { + if let Some(u) = self.as_u64() { + return visitor.visit_u64(u); + } else if let Some(i) = self.as_i64() { + return visitor.visit_i64(i); + } else if let Some(f) = self.as_f64() { + if ryu::Buffer::new().format_finite(f) == self.n || f.to_string() == self.n { + return visitor.visit_f64(f); + } + } + + visitor.visit_map(NumberDeserializer { + number: Some(self.$($num_string)*), + }) + } + }; + + (owned) => { + deserialize_any!(@expand [n]); + }; + + (ref) => { + deserialize_any!(@expand [n.clone()]); + }; +} + +macro_rules! deserialize_number { + ($deserialize:ident => $visit:ident) => { + #[cfg(not(feature = "arbitrary_precision"))] + fn $deserialize(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + self.deserialize_any(visitor) + } + + #[cfg(feature = "arbitrary_precision")] + fn $deserialize(self, visitor: V) -> Result + where + V: de::Visitor<'de>, + { + visitor.$visit(tri!(self.n.parse().map_err(|_| invalid_number()))) + } + }; +} + +impl<'de> Deserializer<'de> for Number { + type Error = Error; + + deserialize_any!(owned); + + deserialize_number!(deserialize_i8 => visit_i8); + deserialize_number!(deserialize_i16 => visit_i16); + deserialize_number!(deserialize_i32 => visit_i32); + deserialize_number!(deserialize_i64 => visit_i64); + deserialize_number!(deserialize_i128 => visit_i128); + deserialize_number!(deserialize_u8 => visit_u8); + deserialize_number!(deserialize_u16 => visit_u16); + deserialize_number!(deserialize_u32 => visit_u32); + deserialize_number!(deserialize_u64 => visit_u64); + deserialize_number!(deserialize_u128 => visit_u128); + deserialize_number!(deserialize_f32 => visit_f32); + deserialize_number!(deserialize_f64 => visit_f64); + + forward_to_deserialize_any! { + bool char str string bytes byte_buf option unit unit_struct + newtype_struct seq tuple tuple_struct map struct enum identifier + ignored_any + } +} + +impl<'de> Deserializer<'de> for &Number { + type Error = Error; + + deserialize_any!(ref); + + deserialize_number!(deserialize_i8 => visit_i8); + deserialize_number!(deserialize_i16 => visit_i16); + deserialize_number!(deserialize_i32 => visit_i32); + deserialize_number!(deserialize_i64 => visit_i64); + deserialize_number!(deserialize_i128 => visit_i128); + deserialize_number!(deserialize_u8 => visit_u8); + deserialize_number!(deserialize_u16 => visit_u16); + deserialize_number!(deserialize_u32 => visit_u32); + deserialize_number!(deserialize_u64 => visit_u64); + deserialize_number!(deserialize_u128 => visit_u128); + deserialize_number!(deserialize_f32 => visit_f32); + deserialize_number!(deserialize_f64 => visit_f64); + + forward_to_deserialize_any! { + bool char str string bytes byte_buf option unit unit_struct + newtype_struct seq tuple tuple_struct map struct enum identifier + ignored_any + } +} + +#[cfg(feature = "arbitrary_precision")] +pub(crate) struct NumberDeserializer { + pub number: Option, +} + +#[cfg(feature = "arbitrary_precision")] +impl<'de> MapAccess<'de> for NumberDeserializer { + type Error = Error; + + fn next_key_seed(&mut self, seed: K) -> Result, Error> + where + K: de::DeserializeSeed<'de>, + { + if self.number.is_none() { + return Ok(None); + } + seed.deserialize(NumberFieldDeserializer).map(Some) + } + + fn next_value_seed(&mut self, seed: V) -> Result + where + V: de::DeserializeSeed<'de>, + { + seed.deserialize(self.number.take().unwrap().into_deserializer()) + } +} + +#[cfg(feature = "arbitrary_precision")] +struct NumberFieldDeserializer; + +#[cfg(feature = "arbitrary_precision")] +impl<'de> Deserializer<'de> for NumberFieldDeserializer { + type Error = Error; + + fn deserialize_any(self, visitor: V) -> Result + where + V: de::Visitor<'de>, + { + visitor.visit_borrowed_str(TOKEN) + } + + forward_to_deserialize_any! { + bool u8 u16 u32 u64 u128 i8 i16 i32 i64 i128 f32 f64 char str string seq + bytes byte_buf map struct option unit newtype_struct ignored_any + unit_struct tuple_struct tuple enum identifier + } +} + +impl From for Number { + fn from(value: ParserNumber) -> Self { + let n = match value { + ParserNumber::F64(f) => { + #[cfg(not(feature = "arbitrary_precision"))] + { + N::Float(f) + } + #[cfg(feature = "arbitrary_precision")] + { + ryu::Buffer::new().format_finite(f).to_owned() + } + } + ParserNumber::U64(u) => { + #[cfg(not(feature = "arbitrary_precision"))] + { + N::PosInt(u) + } + #[cfg(feature = "arbitrary_precision")] + { + itoa::Buffer::new().format(u).to_owned() + } + } + ParserNumber::I64(i) => { + #[cfg(not(feature = "arbitrary_precision"))] + { + N::NegInt(i) + } + #[cfg(feature = "arbitrary_precision")] + { + itoa::Buffer::new().format(i).to_owned() + } + } + #[cfg(feature = "arbitrary_precision")] + ParserNumber::String(s) => s, + }; + Number { n } + } +} + +macro_rules! impl_from_unsigned { + ( + $($ty:ty),* + ) => { + $( + impl From<$ty> for Number { + #[inline] + fn from(u: $ty) -> Self { + let n = { + #[cfg(not(feature = "arbitrary_precision"))] + { N::PosInt(u as u64) } + #[cfg(feature = "arbitrary_precision")] + { + itoa::Buffer::new().format(u).to_owned() + } + }; + Number { n } + } + } + )* + }; +} + +macro_rules! impl_from_signed { + ( + $($ty:ty),* + ) => { + $( + impl From<$ty> for Number { + #[inline] + fn from(i: $ty) -> Self { + let n = { + #[cfg(not(feature = "arbitrary_precision"))] + { + if i < 0 { + N::NegInt(i as i64) + } else { + N::PosInt(i as u64) + } + } + #[cfg(feature = "arbitrary_precision")] + { + itoa::Buffer::new().format(i).to_owned() + } + }; + Number { n } + } + } + )* + }; +} + +impl_from_unsigned!(u8, u16, u32, u64, usize); +impl_from_signed!(i8, i16, i32, i64, isize); + +#[cfg(feature = "arbitrary_precision")] +impl_from_unsigned!(u128); +#[cfg(feature = "arbitrary_precision")] +impl_from_signed!(i128); + +impl Number { + #[cfg(not(feature = "arbitrary_precision"))] + #[cold] + pub(crate) fn unexpected(&self) -> Unexpected { + match self.n { + N::PosInt(u) => Unexpected::Unsigned(u), + N::NegInt(i) => Unexpected::Signed(i), + N::Float(f) => Unexpected::Float(f), + } + } + + #[cfg(feature = "arbitrary_precision")] + #[cold] + pub(crate) fn unexpected(&self) -> Unexpected { + Unexpected::Other("number") + } +} diff --git a/vendor/serde_json/src/raw.rs b/vendor/serde_json/src/raw.rs new file mode 100644 index 0000000..22d1444 --- /dev/null +++ b/vendor/serde_json/src/raw.rs @@ -0,0 +1,777 @@ +use crate::error::Error; +use alloc::borrow::ToOwned; +use alloc::boxed::Box; +use alloc::string::String; +use core::fmt::{self, Debug, Display}; +use core::mem; +use serde::de::value::BorrowedStrDeserializer; +use serde::de::{ + self, Deserialize, DeserializeSeed, Deserializer, IntoDeserializer, MapAccess, Unexpected, + Visitor, +}; +use serde::forward_to_deserialize_any; +use serde::ser::{Serialize, SerializeStruct, Serializer}; + +/// Reference to a range of bytes encompassing a single valid JSON value in the +/// input data. +/// +/// A `RawValue` can be used to defer parsing parts of a payload until later, +/// or to avoid parsing it at all in the case that part of the payload just +/// needs to be transferred verbatim into a different output object. +/// +/// When serializing, a value of this type will retain its original formatting +/// and will not be minified or pretty-printed. +/// +/// # Note +/// +/// `RawValue` is only available if serde\_json is built with the `"raw_value"` +/// feature. +/// +/// ```toml +/// [dependencies] +/// serde_json = { version = "1.0", features = ["raw_value"] } +/// ``` +/// +/// # Example +/// +/// ``` +/// use serde::{Deserialize, Serialize}; +/// use serde_json::{Result, value::RawValue}; +/// +/// #[derive(Deserialize)] +/// struct Input<'a> { +/// code: u32, +/// #[serde(borrow)] +/// payload: &'a RawValue, +/// } +/// +/// #[derive(Serialize)] +/// struct Output<'a> { +/// info: (u32, &'a RawValue), +/// } +/// +/// // Efficiently rearrange JSON input containing separate "code" and "payload" +/// // keys into a single "info" key holding an array of code and payload. +/// // +/// // This could be done equivalently using serde_json::Value as the type for +/// // payload, but &RawValue will perform better because it does not require +/// // memory allocation. The correct range of bytes is borrowed from the input +/// // data and pasted verbatim into the output. +/// fn rearrange(input: &str) -> Result { +/// let input: Input = serde_json::from_str(input)?; +/// +/// let output = Output { +/// info: (input.code, input.payload), +/// }; +/// +/// serde_json::to_string(&output) +/// } +/// +/// fn main() -> Result<()> { +/// let out = rearrange(r#" {"code": 200, "payload": {}} "#)?; +/// +/// assert_eq!(out, r#"{"info":[200,{}]}"#); +/// +/// Ok(()) +/// } +/// ``` +/// +/// # Ownership +/// +/// The typical usage of `RawValue` will be in the borrowed form: +/// +/// ``` +/// # use serde::Deserialize; +/// # use serde_json::value::RawValue; +/// # +/// #[derive(Deserialize)] +/// struct SomeStruct<'a> { +/// #[serde(borrow)] +/// raw_value: &'a RawValue, +/// } +/// ``` +/// +/// The borrowed form is suitable when deserializing through +/// [`serde_json::from_str`] and [`serde_json::from_slice`] which support +/// borrowing from the input data without memory allocation. +/// +/// When deserializing through [`serde_json::from_reader`] you will need to use +/// the boxed form of `RawValue` instead. This is almost as efficient but +/// involves buffering the raw value from the I/O stream into memory. +/// +/// [`serde_json::from_str`]: ../fn.from_str.html +/// [`serde_json::from_slice`]: ../fn.from_slice.html +/// [`serde_json::from_reader`]: ../fn.from_reader.html +/// +/// ``` +/// # use serde::Deserialize; +/// # use serde_json::value::RawValue; +/// # +/// #[derive(Deserialize)] +/// struct SomeStruct { +/// raw_value: Box, +/// } +/// ``` +#[cfg_attr(docsrs, doc(cfg(feature = "raw_value")))] +#[repr(transparent)] +pub struct RawValue { + json: str, +} + +impl RawValue { + fn from_borrowed(json: &str) -> &Self { + unsafe { mem::transmute::<&str, &RawValue>(json) } + } + + fn from_owned(json: Box) -> Box { + unsafe { mem::transmute::, Box>(json) } + } + + fn into_owned(raw_value: Box) -> Box { + unsafe { mem::transmute::, Box>(raw_value) } + } +} + +impl Clone for Box { + fn clone(&self) -> Self { + (**self).to_owned() + } +} + +impl ToOwned for RawValue { + type Owned = Box; + + fn to_owned(&self) -> Self::Owned { + RawValue::from_owned(self.json.to_owned().into_boxed_str()) + } +} + +impl Default for Box { + fn default() -> Self { + RawValue::from_borrowed("null").to_owned() + } +} + +impl Debug for RawValue { + fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter + .debug_tuple("RawValue") + .field(&format_args!("{}", &self.json)) + .finish() + } +} + +impl Display for RawValue { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.write_str(&self.json) + } +} + +impl RawValue { + /// Convert an owned `String` of JSON data to an owned `RawValue`. + /// + /// This function is equivalent to `serde_json::from_str::>` + /// except that we avoid an allocation and memcpy if both of the following + /// are true: + /// + /// - the input has no leading or trailing whitespace, and + /// - the input has capacity equal to its length. + pub fn from_string(json: String) -> Result, Error> { + let borrowed = tri!(crate::from_str::<&Self>(&json)); + if borrowed.json.len() < json.len() { + return Ok(borrowed.to_owned()); + } + Ok(Self::from_owned(json.into_boxed_str())) + } + + /// Access the JSON text underlying a raw value. + /// + /// # Example + /// + /// ``` + /// use serde::Deserialize; + /// use serde_json::{Result, value::RawValue}; + /// + /// #[derive(Deserialize)] + /// struct Response<'a> { + /// code: u32, + /// #[serde(borrow)] + /// payload: &'a RawValue, + /// } + /// + /// fn process(input: &str) -> Result<()> { + /// let response: Response = serde_json::from_str(input)?; + /// + /// let payload = response.payload.get(); + /// if payload.starts_with('{') { + /// // handle a payload which is a JSON map + /// } else { + /// // handle any other type + /// } + /// + /// Ok(()) + /// } + /// + /// fn main() -> Result<()> { + /// process(r#" {"code": 200, "payload": {}} "#)?; + /// Ok(()) + /// } + /// ``` + pub fn get(&self) -> &str { + &self.json + } +} + +impl From> for Box { + fn from(raw_value: Box) -> Self { + RawValue::into_owned(raw_value) + } +} + +/// Convert a `T` into a boxed `RawValue`. +/// +/// # Example +/// +/// ``` +/// // Upstream crate +/// # #[derive(Serialize)] +/// pub struct Thing { +/// foo: String, +/// bar: Option, +/// extra_data: Box, +/// } +/// +/// // Local crate +/// use serde::Serialize; +/// use serde_json::value::{to_raw_value, RawValue}; +/// +/// #[derive(Serialize)] +/// struct MyExtraData { +/// a: u32, +/// b: u32, +/// } +/// +/// let my_thing = Thing { +/// foo: "FooVal".into(), +/// bar: None, +/// extra_data: to_raw_value(&MyExtraData { a: 1, b: 2 }).unwrap(), +/// }; +/// # assert_eq!( +/// # serde_json::to_value(my_thing).unwrap(), +/// # serde_json::json!({ +/// # "foo": "FooVal", +/// # "bar": null, +/// # "extra_data": { "a": 1, "b": 2 } +/// # }) +/// # ); +/// ``` +/// +/// # Errors +/// +/// This conversion can fail if `T`'s implementation of `Serialize` decides to +/// fail, or if `T` contains a map with non-string keys. +/// +/// ``` +/// use std::collections::BTreeMap; +/// +/// // The keys in this map are vectors, not strings. +/// let mut map = BTreeMap::new(); +/// map.insert(vec![32, 64], "x86"); +/// +/// println!("{}", serde_json::value::to_raw_value(&map).unwrap_err()); +/// ``` +#[cfg_attr(docsrs, doc(cfg(feature = "raw_value")))] +pub fn to_raw_value(value: &T) -> Result, Error> +where + T: ?Sized + Serialize, +{ + let json_string = tri!(crate::to_string(value)); + Ok(RawValue::from_owned(json_string.into_boxed_str())) +} + +pub const TOKEN: &str = "$serde_json::private::RawValue"; + +impl Serialize for RawValue { + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + let mut s = tri!(serializer.serialize_struct(TOKEN, 1)); + tri!(s.serialize_field(TOKEN, &self.json)); + s.end() + } +} + +impl<'de: 'a, 'a> Deserialize<'de> for &'a RawValue { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + struct ReferenceVisitor; + + impl<'de> Visitor<'de> for ReferenceVisitor { + type Value = &'de RawValue; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + write!(formatter, "any valid JSON value") + } + + fn visit_map(self, mut visitor: V) -> Result + where + V: MapAccess<'de>, + { + let value = tri!(visitor.next_key::()); + if value.is_none() { + return Err(de::Error::invalid_type(Unexpected::Map, &self)); + } + visitor.next_value_seed(ReferenceFromString) + } + } + + deserializer.deserialize_newtype_struct(TOKEN, ReferenceVisitor) + } +} + +impl<'de> Deserialize<'de> for Box { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + struct BoxedVisitor; + + impl<'de> Visitor<'de> for BoxedVisitor { + type Value = Box; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + write!(formatter, "any valid JSON value") + } + + fn visit_map(self, mut visitor: V) -> Result + where + V: MapAccess<'de>, + { + let value = tri!(visitor.next_key::()); + if value.is_none() { + return Err(de::Error::invalid_type(Unexpected::Map, &self)); + } + visitor.next_value_seed(BoxedFromString) + } + } + + deserializer.deserialize_newtype_struct(TOKEN, BoxedVisitor) + } +} + +struct RawKey; + +impl<'de> Deserialize<'de> for RawKey { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + struct FieldVisitor; + + impl<'de> Visitor<'de> for FieldVisitor { + type Value = (); + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("raw value") + } + + fn visit_str(self, s: &str) -> Result<(), E> + where + E: de::Error, + { + if s == TOKEN { + Ok(()) + } else { + Err(de::Error::custom("unexpected raw value")) + } + } + } + + tri!(deserializer.deserialize_identifier(FieldVisitor)); + Ok(RawKey) + } +} + +pub struct ReferenceFromString; + +impl<'de> DeserializeSeed<'de> for ReferenceFromString { + type Value = &'de RawValue; + + fn deserialize(self, deserializer: D) -> Result + where + D: Deserializer<'de>, + { + deserializer.deserialize_str(self) + } +} + +impl<'de> Visitor<'de> for ReferenceFromString { + type Value = &'de RawValue; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("raw value") + } + + fn visit_borrowed_str(self, s: &'de str) -> Result + where + E: de::Error, + { + Ok(RawValue::from_borrowed(s)) + } +} + +pub struct BoxedFromString; + +impl<'de> DeserializeSeed<'de> for BoxedFromString { + type Value = Box; + + fn deserialize(self, deserializer: D) -> Result + where + D: Deserializer<'de>, + { + deserializer.deserialize_str(self) + } +} + +impl<'de> Visitor<'de> for BoxedFromString { + type Value = Box; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("raw value") + } + + fn visit_str(self, s: &str) -> Result + where + E: de::Error, + { + Ok(RawValue::from_owned(s.to_owned().into_boxed_str())) + } + + #[cfg(any(feature = "std", feature = "alloc"))] + fn visit_string(self, s: String) -> Result + where + E: de::Error, + { + Ok(RawValue::from_owned(s.into_boxed_str())) + } +} + +struct RawKeyDeserializer; + +impl<'de> Deserializer<'de> for RawKeyDeserializer { + type Error = Error; + + fn deserialize_any(self, visitor: V) -> Result + where + V: de::Visitor<'de>, + { + visitor.visit_borrowed_str(TOKEN) + } + + forward_to_deserialize_any! { + bool u8 u16 u32 u64 u128 i8 i16 i32 i64 i128 f32 f64 char str string seq + bytes byte_buf map struct option unit newtype_struct ignored_any + unit_struct tuple_struct tuple enum identifier + } +} + +pub struct OwnedRawDeserializer { + pub raw_value: Option, +} + +impl<'de> MapAccess<'de> for OwnedRawDeserializer { + type Error = Error; + + fn next_key_seed(&mut self, seed: K) -> Result, Error> + where + K: de::DeserializeSeed<'de>, + { + if self.raw_value.is_none() { + return Ok(None); + } + seed.deserialize(RawKeyDeserializer).map(Some) + } + + fn next_value_seed(&mut self, seed: V) -> Result + where + V: de::DeserializeSeed<'de>, + { + seed.deserialize(self.raw_value.take().unwrap().into_deserializer()) + } +} + +pub struct BorrowedRawDeserializer<'de> { + pub raw_value: Option<&'de str>, +} + +impl<'de> MapAccess<'de> for BorrowedRawDeserializer<'de> { + type Error = Error; + + fn next_key_seed(&mut self, seed: K) -> Result, Error> + where + K: de::DeserializeSeed<'de>, + { + if self.raw_value.is_none() { + return Ok(None); + } + seed.deserialize(RawKeyDeserializer).map(Some) + } + + fn next_value_seed(&mut self, seed: V) -> Result + where + V: de::DeserializeSeed<'de>, + { + seed.deserialize(BorrowedStrDeserializer::new(self.raw_value.take().unwrap())) + } +} + +impl<'de> IntoDeserializer<'de, Error> for &'de RawValue { + type Deserializer = &'de RawValue; + + fn into_deserializer(self) -> Self::Deserializer { + self + } +} + +impl<'de> Deserializer<'de> for &'de RawValue { + type Error = Error; + + fn deserialize_any(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + crate::Deserializer::from_str(&self.json).deserialize_any(visitor) + } + + fn deserialize_bool(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + crate::Deserializer::from_str(&self.json).deserialize_bool(visitor) + } + + fn deserialize_i8(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + crate::Deserializer::from_str(&self.json).deserialize_i8(visitor) + } + + fn deserialize_i16(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + crate::Deserializer::from_str(&self.json).deserialize_i16(visitor) + } + + fn deserialize_i32(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + crate::Deserializer::from_str(&self.json).deserialize_i32(visitor) + } + + fn deserialize_i64(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + crate::Deserializer::from_str(&self.json).deserialize_i64(visitor) + } + + fn deserialize_i128(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + crate::Deserializer::from_str(&self.json).deserialize_i128(visitor) + } + + fn deserialize_u8(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + crate::Deserializer::from_str(&self.json).deserialize_u8(visitor) + } + + fn deserialize_u16(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + crate::Deserializer::from_str(&self.json).deserialize_u16(visitor) + } + + fn deserialize_u32(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + crate::Deserializer::from_str(&self.json).deserialize_u32(visitor) + } + + fn deserialize_u64(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + crate::Deserializer::from_str(&self.json).deserialize_u64(visitor) + } + + fn deserialize_u128(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + crate::Deserializer::from_str(&self.json).deserialize_u128(visitor) + } + + fn deserialize_f32(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + crate::Deserializer::from_str(&self.json).deserialize_f32(visitor) + } + + fn deserialize_f64(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + crate::Deserializer::from_str(&self.json).deserialize_f64(visitor) + } + + fn deserialize_char(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + crate::Deserializer::from_str(&self.json).deserialize_char(visitor) + } + + fn deserialize_str(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + crate::Deserializer::from_str(&self.json).deserialize_str(visitor) + } + + fn deserialize_string(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + crate::Deserializer::from_str(&self.json).deserialize_string(visitor) + } + + fn deserialize_bytes(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + crate::Deserializer::from_str(&self.json).deserialize_bytes(visitor) + } + + fn deserialize_byte_buf(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + crate::Deserializer::from_str(&self.json).deserialize_byte_buf(visitor) + } + + fn deserialize_option(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + crate::Deserializer::from_str(&self.json).deserialize_option(visitor) + } + + fn deserialize_unit(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + crate::Deserializer::from_str(&self.json).deserialize_unit(visitor) + } + + fn deserialize_unit_struct(self, name: &'static str, visitor: V) -> Result + where + V: Visitor<'de>, + { + crate::Deserializer::from_str(&self.json).deserialize_unit_struct(name, visitor) + } + + fn deserialize_newtype_struct( + self, + name: &'static str, + visitor: V, + ) -> Result + where + V: Visitor<'de>, + { + crate::Deserializer::from_str(&self.json).deserialize_newtype_struct(name, visitor) + } + + fn deserialize_seq(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + crate::Deserializer::from_str(&self.json).deserialize_seq(visitor) + } + + fn deserialize_tuple(self, len: usize, visitor: V) -> Result + where + V: Visitor<'de>, + { + crate::Deserializer::from_str(&self.json).deserialize_tuple(len, visitor) + } + + fn deserialize_tuple_struct( + self, + name: &'static str, + len: usize, + visitor: V, + ) -> Result + where + V: Visitor<'de>, + { + crate::Deserializer::from_str(&self.json).deserialize_tuple_struct(name, len, visitor) + } + + fn deserialize_map(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + crate::Deserializer::from_str(&self.json).deserialize_map(visitor) + } + + fn deserialize_struct( + self, + name: &'static str, + fields: &'static [&'static str], + visitor: V, + ) -> Result + where + V: Visitor<'de>, + { + crate::Deserializer::from_str(&self.json).deserialize_struct(name, fields, visitor) + } + + fn deserialize_enum( + self, + name: &'static str, + variants: &'static [&'static str], + visitor: V, + ) -> Result + where + V: Visitor<'de>, + { + crate::Deserializer::from_str(&self.json).deserialize_enum(name, variants, visitor) + } + + fn deserialize_identifier(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + crate::Deserializer::from_str(&self.json).deserialize_identifier(visitor) + } + + fn deserialize_ignored_any(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + crate::Deserializer::from_str(&self.json).deserialize_ignored_any(visitor) + } +} diff --git a/vendor/serde_json/src/read.rs b/vendor/serde_json/src/read.rs new file mode 100644 index 0000000..a3aa5d1 --- /dev/null +++ b/vendor/serde_json/src/read.rs @@ -0,0 +1,1076 @@ +use crate::error::{Error, ErrorCode, Result}; +use alloc::vec::Vec; +use core::cmp; +use core::mem; +use core::ops::Deref; +use core::str; + +#[cfg(feature = "std")] +use crate::io; +#[cfg(feature = "std")] +use crate::iter::LineColIterator; + +#[cfg(feature = "raw_value")] +use crate::raw::BorrowedRawDeserializer; +#[cfg(all(feature = "raw_value", feature = "std"))] +use crate::raw::OwnedRawDeserializer; +#[cfg(all(feature = "raw_value", feature = "std"))] +use alloc::string::String; +#[cfg(feature = "raw_value")] +use serde::de::Visitor; + +/// Trait used by the deserializer for iterating over input. This is manually +/// "specialized" for iterating over `&[u8]`. Once feature(specialization) is +/// stable we can use actual specialization. +/// +/// This trait is sealed and cannot be implemented for types outside of +/// `serde_json`. +pub trait Read<'de>: private::Sealed { + #[doc(hidden)] + fn next(&mut self) -> Result>; + #[doc(hidden)] + fn peek(&mut self) -> Result>; + + /// Only valid after a call to peek(). Discards the peeked byte. + #[doc(hidden)] + fn discard(&mut self); + + /// Position of the most recent call to next(). + /// + /// The most recent call was probably next() and not peek(), but this method + /// should try to return a sensible result if the most recent call was + /// actually peek() because we don't always know. + /// + /// Only called in case of an error, so performance is not important. + #[doc(hidden)] + fn position(&self) -> Position; + + /// Position of the most recent call to peek(). + /// + /// The most recent call was probably peek() and not next(), but this method + /// should try to return a sensible result if the most recent call was + /// actually next() because we don't always know. + /// + /// Only called in case of an error, so performance is not important. + #[doc(hidden)] + fn peek_position(&self) -> Position; + + /// Offset from the beginning of the input to the next byte that would be + /// returned by next() or peek(). + #[doc(hidden)] + fn byte_offset(&self) -> usize; + + /// Assumes the previous byte was a quotation mark. Parses a JSON-escaped + /// string until the next quotation mark using the given scratch space if + /// necessary. The scratch space is initially empty. + #[doc(hidden)] + fn parse_str<'s>(&'s mut self, scratch: &'s mut Vec) -> Result>; + + /// Assumes the previous byte was a quotation mark. Parses a JSON-escaped + /// string until the next quotation mark using the given scratch space if + /// necessary. The scratch space is initially empty. + /// + /// This function returns the raw bytes in the string with escape sequences + /// expanded but without performing unicode validation. + #[doc(hidden)] + fn parse_str_raw<'s>( + &'s mut self, + scratch: &'s mut Vec, + ) -> Result>; + + /// Assumes the previous byte was a quotation mark. Parses a JSON-escaped + /// string until the next quotation mark but discards the data. + #[doc(hidden)] + fn ignore_str(&mut self) -> Result<()>; + + /// Assumes the previous byte was a hex escape sequence ('\u') in a string. + /// Parses next hexadecimal sequence. + #[doc(hidden)] + fn decode_hex_escape(&mut self) -> Result; + + /// Switch raw buffering mode on. + /// + /// This is used when deserializing `RawValue`. + #[cfg(feature = "raw_value")] + #[doc(hidden)] + fn begin_raw_buffering(&mut self); + + /// Switch raw buffering mode off and provides the raw buffered data to the + /// given visitor. + #[cfg(feature = "raw_value")] + #[doc(hidden)] + fn end_raw_buffering(&mut self, visitor: V) -> Result + where + V: Visitor<'de>; + + /// Whether StreamDeserializer::next needs to check the failed flag. True + /// for IoRead, false for StrRead and SliceRead which can track failure by + /// truncating their input slice to avoid the extra check on every next + /// call. + #[doc(hidden)] + const should_early_return_if_failed: bool; + + /// Mark a persistent failure of StreamDeserializer, either by setting the + /// flag or by truncating the input data. + #[doc(hidden)] + fn set_failed(&mut self, failed: &mut bool); +} + +pub struct Position { + pub line: usize, + pub column: usize, +} + +pub enum Reference<'b, 'c, T> +where + T: ?Sized + 'static, +{ + Borrowed(&'b T), + Copied(&'c T), +} + +impl<'b, 'c, T> Deref for Reference<'b, 'c, T> +where + T: ?Sized + 'static, +{ + type Target = T; + + fn deref(&self) -> &Self::Target { + match *self { + Reference::Borrowed(b) => b, + Reference::Copied(c) => c, + } + } +} + +/// JSON input source that reads from a std::io input stream. +#[cfg(feature = "std")] +#[cfg_attr(docsrs, doc(cfg(feature = "std")))] +pub struct IoRead +where + R: io::Read, +{ + iter: LineColIterator>, + /// Temporary storage of peeked byte. + ch: Option, + #[cfg(feature = "raw_value")] + raw_buffer: Option>, +} + +/// JSON input source that reads from a slice of bytes. +// +// This is more efficient than other iterators because peek() can be read-only +// and we can compute line/col position only if an error happens. +pub struct SliceRead<'a> { + slice: &'a [u8], + /// Index of the *next* byte that will be returned by next() or peek(). + index: usize, + #[cfg(feature = "raw_value")] + raw_buffering_start_index: usize, +} + +/// JSON input source that reads from a UTF-8 string. +// +// Able to elide UTF-8 checks by assuming that the input is valid UTF-8. +pub struct StrRead<'a> { + delegate: SliceRead<'a>, + #[cfg(feature = "raw_value")] + data: &'a str, +} + +// Prevent users from implementing the Read trait. +mod private { + pub trait Sealed {} +} + +////////////////////////////////////////////////////////////////////////////// + +#[cfg(feature = "std")] +impl IoRead +where + R: io::Read, +{ + /// Create a JSON input source to read from a std::io input stream. + pub fn new(reader: R) -> Self { + IoRead { + iter: LineColIterator::new(reader.bytes()), + ch: None, + #[cfg(feature = "raw_value")] + raw_buffer: None, + } + } +} + +#[cfg(feature = "std")] +impl private::Sealed for IoRead where R: io::Read {} + +#[cfg(feature = "std")] +impl IoRead +where + R: io::Read, +{ + fn parse_str_bytes<'s, T, F>( + &'s mut self, + scratch: &'s mut Vec, + validate: bool, + result: F, + ) -> Result + where + T: 's, + F: FnOnce(&'s Self, &'s [u8]) -> Result, + { + loop { + let ch = tri!(next_or_eof(self)); + if !is_escape(ch, true) { + scratch.push(ch); + continue; + } + match ch { + b'"' => { + return result(self, scratch); + } + b'\\' => { + tri!(parse_escape(self, validate, scratch)); + } + _ => { + if validate { + return error(self, ErrorCode::ControlCharacterWhileParsingString); + } + scratch.push(ch); + } + } + } + } +} + +#[cfg(feature = "std")] +impl<'de, R> Read<'de> for IoRead +where + R: io::Read, +{ + #[inline] + fn next(&mut self) -> Result> { + match self.ch.take() { + Some(ch) => { + #[cfg(feature = "raw_value")] + { + if let Some(buf) = &mut self.raw_buffer { + buf.push(ch); + } + } + Ok(Some(ch)) + } + None => match self.iter.next() { + Some(Err(err)) => Err(Error::io(err)), + Some(Ok(ch)) => { + #[cfg(feature = "raw_value")] + { + if let Some(buf) = &mut self.raw_buffer { + buf.push(ch); + } + } + Ok(Some(ch)) + } + None => Ok(None), + }, + } + } + + #[inline] + fn peek(&mut self) -> Result> { + match self.ch { + Some(ch) => Ok(Some(ch)), + None => match self.iter.next() { + Some(Err(err)) => Err(Error::io(err)), + Some(Ok(ch)) => { + self.ch = Some(ch); + Ok(self.ch) + } + None => Ok(None), + }, + } + } + + #[cfg(not(feature = "raw_value"))] + #[inline] + fn discard(&mut self) { + self.ch = None; + } + + #[cfg(feature = "raw_value")] + fn discard(&mut self) { + if let Some(ch) = self.ch.take() { + if let Some(buf) = &mut self.raw_buffer { + buf.push(ch); + } + } + } + + fn position(&self) -> Position { + Position { + line: self.iter.line(), + column: self.iter.col(), + } + } + + fn peek_position(&self) -> Position { + // The LineColIterator updates its position during peek() so it has the + // right one here. + self.position() + } + + fn byte_offset(&self) -> usize { + match self.ch { + Some(_) => self.iter.byte_offset() - 1, + None => self.iter.byte_offset(), + } + } + + fn parse_str<'s>(&'s mut self, scratch: &'s mut Vec) -> Result> { + self.parse_str_bytes(scratch, true, as_str) + .map(Reference::Copied) + } + + fn parse_str_raw<'s>( + &'s mut self, + scratch: &'s mut Vec, + ) -> Result> { + self.parse_str_bytes(scratch, false, |_, bytes| Ok(bytes)) + .map(Reference::Copied) + } + + fn ignore_str(&mut self) -> Result<()> { + loop { + let ch = tri!(next_or_eof(self)); + if !is_escape(ch, true) { + continue; + } + match ch { + b'"' => { + return Ok(()); + } + b'\\' => { + tri!(ignore_escape(self)); + } + _ => { + return error(self, ErrorCode::ControlCharacterWhileParsingString); + } + } + } + } + + fn decode_hex_escape(&mut self) -> Result { + let a = tri!(next_or_eof(self)); + let b = tri!(next_or_eof(self)); + let c = tri!(next_or_eof(self)); + let d = tri!(next_or_eof(self)); + match decode_four_hex_digits(a, b, c, d) { + Some(val) => Ok(val), + None => error(self, ErrorCode::InvalidEscape), + } + } + + #[cfg(feature = "raw_value")] + fn begin_raw_buffering(&mut self) { + self.raw_buffer = Some(Vec::new()); + } + + #[cfg(feature = "raw_value")] + fn end_raw_buffering(&mut self, visitor: V) -> Result + where + V: Visitor<'de>, + { + let raw = self.raw_buffer.take().unwrap(); + let raw = match String::from_utf8(raw) { + Ok(raw) => raw, + Err(_) => return error(self, ErrorCode::InvalidUnicodeCodePoint), + }; + visitor.visit_map(OwnedRawDeserializer { + raw_value: Some(raw), + }) + } + + const should_early_return_if_failed: bool = true; + + #[inline] + #[cold] + fn set_failed(&mut self, failed: &mut bool) { + *failed = true; + } +} + +////////////////////////////////////////////////////////////////////////////// + +impl<'a> SliceRead<'a> { + /// Create a JSON input source to read from a slice of bytes. + pub fn new(slice: &'a [u8]) -> Self { + SliceRead { + slice, + index: 0, + #[cfg(feature = "raw_value")] + raw_buffering_start_index: 0, + } + } + + fn position_of_index(&self, i: usize) -> Position { + let start_of_line = match memchr::memrchr(b'\n', &self.slice[..i]) { + Some(position) => position + 1, + None => 0, + }; + Position { + line: 1 + memchr::memchr_iter(b'\n', &self.slice[..start_of_line]).count(), + column: i - start_of_line, + } + } + + fn skip_to_escape(&mut self, forbid_control_characters: bool) { + // Immediately bail-out on empty strings and consecutive escapes (e.g. \u041b\u0435) + if self.index == self.slice.len() + || is_escape(self.slice[self.index], forbid_control_characters) + { + return; + } + self.index += 1; + + let rest = &self.slice[self.index..]; + + if !forbid_control_characters { + self.index += memchr::memchr2(b'"', b'\\', rest).unwrap_or(rest.len()); + return; + } + + // We wish to find the first byte in range 0x00..=0x1F or " or \. Ideally, we'd use + // something akin to memchr3, but the memchr crate does not support this at the moment. + // Therefore, we use a variation on Mycroft's algorithm [1] to provide performance better + // than a naive loop. It runs faster than equivalent two-pass memchr2+SWAR code on + // benchmarks and it's cross-platform, so probably the right fit. + // [1]: https://groups.google.com/forum/#!original/comp.lang.c/2HtQXvg7iKc/xOJeipH6KLMJ + + #[cfg(fast_arithmetic = "64")] + type Chunk = u64; + #[cfg(fast_arithmetic = "32")] + type Chunk = u32; + + const STEP: usize = mem::size_of::(); + const ONE_BYTES: Chunk = Chunk::MAX / 255; // 0x0101...01 + + for chunk in rest.chunks_exact(STEP) { + let chars = Chunk::from_le_bytes(chunk.try_into().unwrap()); + let contains_ctrl = chars.wrapping_sub(ONE_BYTES * 0x20) & !chars; + let chars_quote = chars ^ (ONE_BYTES * Chunk::from(b'"')); + let contains_quote = chars_quote.wrapping_sub(ONE_BYTES) & !chars_quote; + let chars_backslash = chars ^ (ONE_BYTES * Chunk::from(b'\\')); + let contains_backslash = chars_backslash.wrapping_sub(ONE_BYTES) & !chars_backslash; + let masked = (contains_ctrl | contains_quote | contains_backslash) & (ONE_BYTES << 7); + if masked != 0 { + // SAFETY: chunk is in-bounds for slice + self.index = unsafe { chunk.as_ptr().offset_from(self.slice.as_ptr()) } as usize + + masked.trailing_zeros() as usize / 8; + return; + } + } + + self.index += rest.len() / STEP * STEP; + self.skip_to_escape_slow(); + } + + #[cold] + #[inline(never)] + fn skip_to_escape_slow(&mut self) { + while self.index < self.slice.len() && !is_escape(self.slice[self.index], true) { + self.index += 1; + } + } + + /// The big optimization here over IoRead is that if the string contains no + /// backslash escape sequences, the returned &str is a slice of the raw JSON + /// data so we avoid copying into the scratch space. + fn parse_str_bytes<'s, T, F>( + &'s mut self, + scratch: &'s mut Vec, + validate: bool, + result: F, + ) -> Result> + where + T: ?Sized + 's, + F: for<'f> FnOnce(&'s Self, &'f [u8]) -> Result<&'f T>, + { + // Index of the first byte not yet copied into the scratch space. + let mut start = self.index; + + loop { + self.skip_to_escape(validate); + if self.index == self.slice.len() { + return error(self, ErrorCode::EofWhileParsingString); + } + match self.slice[self.index] { + b'"' => { + if scratch.is_empty() { + // Fast path: return a slice of the raw JSON without any + // copying. + let borrowed = &self.slice[start..self.index]; + self.index += 1; + return result(self, borrowed).map(Reference::Borrowed); + } else { + scratch.extend_from_slice(&self.slice[start..self.index]); + self.index += 1; + return result(self, scratch).map(Reference::Copied); + } + } + b'\\' => { + scratch.extend_from_slice(&self.slice[start..self.index]); + self.index += 1; + tri!(parse_escape(self, validate, scratch)); + start = self.index; + } + _ => { + self.index += 1; + return error(self, ErrorCode::ControlCharacterWhileParsingString); + } + } + } + } +} + +impl<'a> private::Sealed for SliceRead<'a> {} + +impl<'a> Read<'a> for SliceRead<'a> { + #[inline] + fn next(&mut self) -> Result> { + // `Ok(self.slice.get(self.index).map(|ch| { self.index += 1; *ch }))` + // is about 10% slower. + Ok(if self.index < self.slice.len() { + let ch = self.slice[self.index]; + self.index += 1; + Some(ch) + } else { + None + }) + } + + #[inline] + fn peek(&mut self) -> Result> { + // `Ok(self.slice.get(self.index).map(|ch| *ch))` is about 10% slower + // for some reason. + Ok(if self.index < self.slice.len() { + Some(self.slice[self.index]) + } else { + None + }) + } + + #[inline] + fn discard(&mut self) { + self.index += 1; + } + + fn position(&self) -> Position { + self.position_of_index(self.index) + } + + fn peek_position(&self) -> Position { + // Cap it at slice.len() just in case the most recent call was next() + // and it returned the last byte. + self.position_of_index(cmp::min(self.slice.len(), self.index + 1)) + } + + fn byte_offset(&self) -> usize { + self.index + } + + fn parse_str<'s>(&'s mut self, scratch: &'s mut Vec) -> Result> { + self.parse_str_bytes(scratch, true, as_str) + } + + fn parse_str_raw<'s>( + &'s mut self, + scratch: &'s mut Vec, + ) -> Result> { + self.parse_str_bytes(scratch, false, |_, bytes| Ok(bytes)) + } + + fn ignore_str(&mut self) -> Result<()> { + loop { + self.skip_to_escape(true); + if self.index == self.slice.len() { + return error(self, ErrorCode::EofWhileParsingString); + } + match self.slice[self.index] { + b'"' => { + self.index += 1; + return Ok(()); + } + b'\\' => { + self.index += 1; + tri!(ignore_escape(self)); + } + _ => { + return error(self, ErrorCode::ControlCharacterWhileParsingString); + } + } + } + } + + #[inline] + fn decode_hex_escape(&mut self) -> Result { + match self.slice[self.index..] { + [a, b, c, d, ..] => { + self.index += 4; + match decode_four_hex_digits(a, b, c, d) { + Some(val) => Ok(val), + None => error(self, ErrorCode::InvalidEscape), + } + } + _ => { + self.index = self.slice.len(); + error(self, ErrorCode::EofWhileParsingString) + } + } + } + + #[cfg(feature = "raw_value")] + fn begin_raw_buffering(&mut self) { + self.raw_buffering_start_index = self.index; + } + + #[cfg(feature = "raw_value")] + fn end_raw_buffering(&mut self, visitor: V) -> Result + where + V: Visitor<'a>, + { + let raw = &self.slice[self.raw_buffering_start_index..self.index]; + let raw = match str::from_utf8(raw) { + Ok(raw) => raw, + Err(_) => return error(self, ErrorCode::InvalidUnicodeCodePoint), + }; + visitor.visit_map(BorrowedRawDeserializer { + raw_value: Some(raw), + }) + } + + const should_early_return_if_failed: bool = false; + + #[inline] + #[cold] + fn set_failed(&mut self, _failed: &mut bool) { + self.slice = &self.slice[..self.index]; + } +} + +////////////////////////////////////////////////////////////////////////////// + +impl<'a> StrRead<'a> { + /// Create a JSON input source to read from a UTF-8 string. + pub fn new(s: &'a str) -> Self { + StrRead { + delegate: SliceRead::new(s.as_bytes()), + #[cfg(feature = "raw_value")] + data: s, + } + } +} + +impl<'a> private::Sealed for StrRead<'a> {} + +impl<'a> Read<'a> for StrRead<'a> { + #[inline] + fn next(&mut self) -> Result> { + self.delegate.next() + } + + #[inline] + fn peek(&mut self) -> Result> { + self.delegate.peek() + } + + #[inline] + fn discard(&mut self) { + self.delegate.discard(); + } + + fn position(&self) -> Position { + self.delegate.position() + } + + fn peek_position(&self) -> Position { + self.delegate.peek_position() + } + + fn byte_offset(&self) -> usize { + self.delegate.byte_offset() + } + + fn parse_str<'s>(&'s mut self, scratch: &'s mut Vec) -> Result> { + self.delegate.parse_str_bytes(scratch, true, |_, bytes| { + // The deserialization input came in as &str with a UTF-8 guarantee, + // and the \u-escapes are checked along the way, so don't need to + // check here. + Ok(unsafe { str::from_utf8_unchecked(bytes) }) + }) + } + + fn parse_str_raw<'s>( + &'s mut self, + scratch: &'s mut Vec, + ) -> Result> { + self.delegate.parse_str_raw(scratch) + } + + fn ignore_str(&mut self) -> Result<()> { + self.delegate.ignore_str() + } + + fn decode_hex_escape(&mut self) -> Result { + self.delegate.decode_hex_escape() + } + + #[cfg(feature = "raw_value")] + fn begin_raw_buffering(&mut self) { + self.delegate.begin_raw_buffering(); + } + + #[cfg(feature = "raw_value")] + fn end_raw_buffering(&mut self, visitor: V) -> Result + where + V: Visitor<'a>, + { + let raw = &self.data[self.delegate.raw_buffering_start_index..self.delegate.index]; + visitor.visit_map(BorrowedRawDeserializer { + raw_value: Some(raw), + }) + } + + const should_early_return_if_failed: bool = false; + + #[inline] + #[cold] + fn set_failed(&mut self, failed: &mut bool) { + self.delegate.set_failed(failed); + } +} + +////////////////////////////////////////////////////////////////////////////// + +impl<'de, R> private::Sealed for &mut R where R: Read<'de> {} + +impl<'de, R> Read<'de> for &mut R +where + R: Read<'de>, +{ + fn next(&mut self) -> Result> { + R::next(self) + } + + fn peek(&mut self) -> Result> { + R::peek(self) + } + + fn discard(&mut self) { + R::discard(self); + } + + fn position(&self) -> Position { + R::position(self) + } + + fn peek_position(&self) -> Position { + R::peek_position(self) + } + + fn byte_offset(&self) -> usize { + R::byte_offset(self) + } + + fn parse_str<'s>(&'s mut self, scratch: &'s mut Vec) -> Result> { + R::parse_str(self, scratch) + } + + fn parse_str_raw<'s>( + &'s mut self, + scratch: &'s mut Vec, + ) -> Result> { + R::parse_str_raw(self, scratch) + } + + fn ignore_str(&mut self) -> Result<()> { + R::ignore_str(self) + } + + fn decode_hex_escape(&mut self) -> Result { + R::decode_hex_escape(self) + } + + #[cfg(feature = "raw_value")] + fn begin_raw_buffering(&mut self) { + R::begin_raw_buffering(self); + } + + #[cfg(feature = "raw_value")] + fn end_raw_buffering(&mut self, visitor: V) -> Result + where + V: Visitor<'de>, + { + R::end_raw_buffering(self, visitor) + } + + const should_early_return_if_failed: bool = R::should_early_return_if_failed; + + fn set_failed(&mut self, failed: &mut bool) { + R::set_failed(self, failed); + } +} + +////////////////////////////////////////////////////////////////////////////// + +/// Marker for whether StreamDeserializer can implement FusedIterator. +pub trait Fused: private::Sealed {} +impl<'a> Fused for SliceRead<'a> {} +impl<'a> Fused for StrRead<'a> {} + +fn is_escape(ch: u8, including_control_characters: bool) -> bool { + ch == b'"' || ch == b'\\' || (including_control_characters && ch < 0x20) +} + +fn next_or_eof<'de, R>(read: &mut R) -> Result +where + R: ?Sized + Read<'de>, +{ + match tri!(read.next()) { + Some(b) => Ok(b), + None => error(read, ErrorCode::EofWhileParsingString), + } +} + +fn peek_or_eof<'de, R>(read: &mut R) -> Result +where + R: ?Sized + Read<'de>, +{ + match tri!(read.peek()) { + Some(b) => Ok(b), + None => error(read, ErrorCode::EofWhileParsingString), + } +} + +fn error<'de, R, T>(read: &R, reason: ErrorCode) -> Result +where + R: ?Sized + Read<'de>, +{ + let position = read.position(); + Err(Error::syntax(reason, position.line, position.column)) +} + +fn as_str<'de, 's, R: Read<'de>>(read: &R, slice: &'s [u8]) -> Result<&'s str> { + str::from_utf8(slice).or_else(|_| error(read, ErrorCode::InvalidUnicodeCodePoint)) +} + +/// Parses a JSON escape sequence and appends it into the scratch space. Assumes +/// the previous byte read was a backslash. +fn parse_escape<'de, R: Read<'de>>( + read: &mut R, + validate: bool, + scratch: &mut Vec, +) -> Result<()> { + let ch = tri!(next_or_eof(read)); + + match ch { + b'"' => scratch.push(b'"'), + b'\\' => scratch.push(b'\\'), + b'/' => scratch.push(b'/'), + b'b' => scratch.push(b'\x08'), + b'f' => scratch.push(b'\x0c'), + b'n' => scratch.push(b'\n'), + b'r' => scratch.push(b'\r'), + b't' => scratch.push(b'\t'), + b'u' => return parse_unicode_escape(read, validate, scratch), + _ => return error(read, ErrorCode::InvalidEscape), + } + + Ok(()) +} + +/// Parses a JSON \u escape and appends it into the scratch space. Assumes `\u` +/// has just been read. +#[cold] +fn parse_unicode_escape<'de, R: Read<'de>>( + read: &mut R, + validate: bool, + scratch: &mut Vec, +) -> Result<()> { + let mut n = tri!(read.decode_hex_escape()); + + // Non-BMP characters are encoded as a sequence of two hex escapes, + // representing UTF-16 surrogates. If deserializing a utf-8 string the + // surrogates are required to be paired, whereas deserializing a byte string + // accepts lone surrogates. + if validate && n >= 0xDC00 && n <= 0xDFFF { + // XXX: This is actually a trailing surrogate. + return error(read, ErrorCode::LoneLeadingSurrogateInHexEscape); + } + + loop { + if n < 0xD800 || n > 0xDBFF { + // Every u16 outside of the surrogate ranges is guaranteed to be a + // legal char. + push_wtf8_codepoint(n as u32, scratch); + return Ok(()); + } + + // n is a leading surrogate, we now expect a trailing surrogate. + let n1 = n; + + if tri!(peek_or_eof(read)) == b'\\' { + read.discard(); + } else { + return if validate { + read.discard(); + error(read, ErrorCode::UnexpectedEndOfHexEscape) + } else { + push_wtf8_codepoint(n1 as u32, scratch); + Ok(()) + }; + } + + if tri!(peek_or_eof(read)) == b'u' { + read.discard(); + } else { + return if validate { + read.discard(); + error(read, ErrorCode::UnexpectedEndOfHexEscape) + } else { + push_wtf8_codepoint(n1 as u32, scratch); + // The \ prior to this byte started an escape sequence, so we + // need to parse that now. This recursive call does not blow the + // stack on malicious input because the escape is not \u, so it + // will be handled by one of the easy nonrecursive cases. + parse_escape(read, validate, scratch) + }; + } + + let n2 = tri!(read.decode_hex_escape()); + + if n2 < 0xDC00 || n2 > 0xDFFF { + if validate { + return error(read, ErrorCode::LoneLeadingSurrogateInHexEscape); + } + push_wtf8_codepoint(n1 as u32, scratch); + // If n2 is a leading surrogate, we need to restart. + n = n2; + continue; + } + + // This value is in range U+10000..=U+10FFFF, which is always a valid + // codepoint. + let n = (((n1 - 0xD800) as u32) << 10 | (n2 - 0xDC00) as u32) + 0x1_0000; + push_wtf8_codepoint(n, scratch); + return Ok(()); + } +} + +/// Adds a WTF-8 codepoint to the end of the buffer. This is a more efficient +/// implementation of String::push. The codepoint may be a surrogate. +#[inline] +fn push_wtf8_codepoint(n: u32, scratch: &mut Vec) { + if n < 0x80 { + scratch.push(n as u8); + return; + } + + scratch.reserve(4); + + unsafe { + let ptr = scratch.as_mut_ptr().add(scratch.len()); + + let encoded_len = match n { + 0..=0x7F => unreachable!(), + 0x80..=0x7FF => { + ptr.write((n >> 6 & 0b0001_1111) as u8 | 0b1100_0000); + 2 + } + 0x800..=0xFFFF => { + ptr.write((n >> 12 & 0b0000_1111) as u8 | 0b1110_0000); + ptr.add(1).write((n >> 6 & 0b0011_1111) as u8 | 0b1000_0000); + 3 + } + 0x1_0000..=0x10_FFFF => { + ptr.write((n >> 18 & 0b0000_0111) as u8 | 0b1111_0000); + ptr.add(1) + .write((n >> 12 & 0b0011_1111) as u8 | 0b1000_0000); + ptr.add(2).write((n >> 6 & 0b0011_1111) as u8 | 0b1000_0000); + 4 + } + 0x11_0000.. => unreachable!(), + }; + ptr.add(encoded_len - 1) + .write((n & 0b0011_1111) as u8 | 0b1000_0000); + + scratch.set_len(scratch.len() + encoded_len); + } +} + +/// Parses a JSON escape sequence and discards the value. Assumes the previous +/// byte read was a backslash. +fn ignore_escape<'de, R>(read: &mut R) -> Result<()> +where + R: ?Sized + Read<'de>, +{ + let ch = tri!(next_or_eof(read)); + + match ch { + b'"' | b'\\' | b'/' | b'b' | b'f' | b'n' | b'r' | b't' => {} + b'u' => { + // At this point we don't care if the codepoint is valid. We just + // want to consume it. We don't actually know what is valid or not + // at this point, because that depends on if this string will + // ultimately be parsed into a string or a byte buffer in the "real" + // parse. + + tri!(read.decode_hex_escape()); + } + _ => { + return error(read, ErrorCode::InvalidEscape); + } + } + + Ok(()) +} + +const fn decode_hex_val_slow(val: u8) -> Option { + match val { + b'0'..=b'9' => Some(val - b'0'), + b'A'..=b'F' => Some(val - b'A' + 10), + b'a'..=b'f' => Some(val - b'a' + 10), + _ => None, + } +} + +const fn build_hex_table(shift: usize) -> [i16; 256] { + let mut table = [0; 256]; + let mut ch = 0; + while ch < 256 { + table[ch] = match decode_hex_val_slow(ch as u8) { + Some(val) => (val as i16) << shift, + None => -1, + }; + ch += 1; + } + table +} + +static HEX0: [i16; 256] = build_hex_table(0); +static HEX1: [i16; 256] = build_hex_table(4); + +fn decode_four_hex_digits(a: u8, b: u8, c: u8, d: u8) -> Option { + let a = HEX1[a as usize] as i32; + let b = HEX0[b as usize] as i32; + let c = HEX1[c as usize] as i32; + let d = HEX0[d as usize] as i32; + + let codepoint = ((a | b) << 8) | c | d; + + // A single sign bit check. + if codepoint >= 0 { + Some(codepoint as u16) + } else { + None + } +} diff --git a/vendor/serde_json/src/ser.rs b/vendor/serde_json/src/ser.rs new file mode 100644 index 0000000..6956671 --- /dev/null +++ b/vendor/serde_json/src/ser.rs @@ -0,0 +1,2249 @@ +//! Serialize a Rust data structure into JSON data. + +use crate::error::{Error, ErrorCode, Result}; +use crate::io; +use alloc::string::String; +#[cfg(feature = "raw_value")] +use alloc::string::ToString; +use alloc::vec::Vec; +use core::fmt::{self, Display}; +use core::num::FpCategory; +use serde::ser::{self, Impossible, Serialize}; + +/// A structure for serializing Rust values into JSON. +#[cfg_attr(docsrs, doc(cfg(feature = "std")))] +pub struct Serializer { + writer: W, + formatter: F, +} + +impl Serializer +where + W: io::Write, +{ + /// Creates a new JSON serializer. + #[inline] + pub fn new(writer: W) -> Self { + Serializer::with_formatter(writer, CompactFormatter) + } +} + +impl<'a, W> Serializer> +where + W: io::Write, +{ + /// Creates a new JSON pretty print serializer. + #[inline] + pub fn pretty(writer: W) -> Self { + Serializer::with_formatter(writer, PrettyFormatter::new()) + } +} + +impl Serializer +where + W: io::Write, + F: Formatter, +{ + /// Creates a new JSON visitor whose output will be written to the writer + /// specified. + #[inline] + pub fn with_formatter(writer: W, formatter: F) -> Self { + Serializer { writer, formatter } + } + + /// Unwrap the `Writer` from the `Serializer`. + #[inline] + pub fn into_inner(self) -> W { + self.writer + } +} + +impl<'a, W, F> ser::Serializer for &'a mut Serializer +where + W: io::Write, + F: Formatter, +{ + type Ok = (); + type Error = Error; + + type SerializeSeq = Compound<'a, W, F>; + type SerializeTuple = Compound<'a, W, F>; + type SerializeTupleStruct = Compound<'a, W, F>; + type SerializeTupleVariant = Compound<'a, W, F>; + type SerializeMap = Compound<'a, W, F>; + type SerializeStruct = Compound<'a, W, F>; + type SerializeStructVariant = Compound<'a, W, F>; + + #[inline] + fn serialize_bool(self, value: bool) -> Result<()> { + self.formatter + .write_bool(&mut self.writer, value) + .map_err(Error::io) + } + + #[inline] + fn serialize_i8(self, value: i8) -> Result<()> { + self.formatter + .write_i8(&mut self.writer, value) + .map_err(Error::io) + } + + #[inline] + fn serialize_i16(self, value: i16) -> Result<()> { + self.formatter + .write_i16(&mut self.writer, value) + .map_err(Error::io) + } + + #[inline] + fn serialize_i32(self, value: i32) -> Result<()> { + self.formatter + .write_i32(&mut self.writer, value) + .map_err(Error::io) + } + + #[inline] + fn serialize_i64(self, value: i64) -> Result<()> { + self.formatter + .write_i64(&mut self.writer, value) + .map_err(Error::io) + } + + fn serialize_i128(self, value: i128) -> Result<()> { + self.formatter + .write_i128(&mut self.writer, value) + .map_err(Error::io) + } + + #[inline] + fn serialize_u8(self, value: u8) -> Result<()> { + self.formatter + .write_u8(&mut self.writer, value) + .map_err(Error::io) + } + + #[inline] + fn serialize_u16(self, value: u16) -> Result<()> { + self.formatter + .write_u16(&mut self.writer, value) + .map_err(Error::io) + } + + #[inline] + fn serialize_u32(self, value: u32) -> Result<()> { + self.formatter + .write_u32(&mut self.writer, value) + .map_err(Error::io) + } + + #[inline] + fn serialize_u64(self, value: u64) -> Result<()> { + self.formatter + .write_u64(&mut self.writer, value) + .map_err(Error::io) + } + + fn serialize_u128(self, value: u128) -> Result<()> { + self.formatter + .write_u128(&mut self.writer, value) + .map_err(Error::io) + } + + #[inline] + fn serialize_f32(self, value: f32) -> Result<()> { + match value.classify() { + FpCategory::Nan | FpCategory::Infinite => self + .formatter + .write_null(&mut self.writer) + .map_err(Error::io), + _ => self + .formatter + .write_f32(&mut self.writer, value) + .map_err(Error::io), + } + } + + #[inline] + fn serialize_f64(self, value: f64) -> Result<()> { + match value.classify() { + FpCategory::Nan | FpCategory::Infinite => self + .formatter + .write_null(&mut self.writer) + .map_err(Error::io), + _ => self + .formatter + .write_f64(&mut self.writer, value) + .map_err(Error::io), + } + } + + #[inline] + fn serialize_char(self, value: char) -> Result<()> { + // A char encoded as UTF-8 takes 4 bytes at most. + let mut buf = [0; 4]; + self.serialize_str(value.encode_utf8(&mut buf)) + } + + #[inline] + fn serialize_str(self, value: &str) -> Result<()> { + format_escaped_str(&mut self.writer, &mut self.formatter, value).map_err(Error::io) + } + + #[inline] + fn serialize_bytes(self, value: &[u8]) -> Result<()> { + self.formatter + .write_byte_array(&mut self.writer, value) + .map_err(Error::io) + } + + #[inline] + fn serialize_unit(self) -> Result<()> { + self.formatter + .write_null(&mut self.writer) + .map_err(Error::io) + } + + #[inline] + fn serialize_unit_struct(self, _name: &'static str) -> Result<()> { + self.serialize_unit() + } + + #[inline] + fn serialize_unit_variant( + self, + _name: &'static str, + _variant_index: u32, + variant: &'static str, + ) -> Result<()> { + self.serialize_str(variant) + } + + /// Serialize newtypes without an object wrapper. + #[inline] + fn serialize_newtype_struct(self, _name: &'static str, value: &T) -> Result<()> + where + T: ?Sized + Serialize, + { + value.serialize(self) + } + + #[inline] + fn serialize_newtype_variant( + self, + _name: &'static str, + _variant_index: u32, + variant: &'static str, + value: &T, + ) -> Result<()> + where + T: ?Sized + Serialize, + { + tri!(self + .formatter + .begin_object(&mut self.writer) + .map_err(Error::io)); + tri!(self + .formatter + .begin_object_key(&mut self.writer, true) + .map_err(Error::io)); + tri!(self.serialize_str(variant)); + tri!(self + .formatter + .end_object_key(&mut self.writer) + .map_err(Error::io)); + tri!(self + .formatter + .begin_object_value(&mut self.writer) + .map_err(Error::io)); + tri!(value.serialize(&mut *self)); + tri!(self + .formatter + .end_object_value(&mut self.writer) + .map_err(Error::io)); + self.formatter + .end_object(&mut self.writer) + .map_err(Error::io) + } + + #[inline] + fn serialize_none(self) -> Result<()> { + self.serialize_unit() + } + + #[inline] + fn serialize_some(self, value: &T) -> Result<()> + where + T: ?Sized + Serialize, + { + value.serialize(self) + } + + #[inline] + fn serialize_seq(self, len: Option) -> Result { + tri!(self + .formatter + .begin_array(&mut self.writer) + .map_err(Error::io)); + if len == Some(0) { + tri!(self + .formatter + .end_array(&mut self.writer) + .map_err(Error::io)); + Ok(Compound::Map { + ser: self, + state: State::Empty, + }) + } else { + Ok(Compound::Map { + ser: self, + state: State::First, + }) + } + } + + #[inline] + fn serialize_tuple(self, len: usize) -> Result { + self.serialize_seq(Some(len)) + } + + #[inline] + fn serialize_tuple_struct( + self, + _name: &'static str, + len: usize, + ) -> Result { + self.serialize_seq(Some(len)) + } + + #[inline] + fn serialize_tuple_variant( + self, + _name: &'static str, + _variant_index: u32, + variant: &'static str, + len: usize, + ) -> Result { + tri!(self + .formatter + .begin_object(&mut self.writer) + .map_err(Error::io)); + tri!(self + .formatter + .begin_object_key(&mut self.writer, true) + .map_err(Error::io)); + tri!(self.serialize_str(variant)); + tri!(self + .formatter + .end_object_key(&mut self.writer) + .map_err(Error::io)); + tri!(self + .formatter + .begin_object_value(&mut self.writer) + .map_err(Error::io)); + self.serialize_seq(Some(len)) + } + + #[inline] + fn serialize_map(self, len: Option) -> Result { + tri!(self + .formatter + .begin_object(&mut self.writer) + .map_err(Error::io)); + if len == Some(0) { + tri!(self + .formatter + .end_object(&mut self.writer) + .map_err(Error::io)); + Ok(Compound::Map { + ser: self, + state: State::Empty, + }) + } else { + Ok(Compound::Map { + ser: self, + state: State::First, + }) + } + } + + #[inline] + fn serialize_struct(self, name: &'static str, len: usize) -> Result { + match name { + #[cfg(feature = "arbitrary_precision")] + crate::number::TOKEN => Ok(Compound::Number { ser: self }), + #[cfg(feature = "raw_value")] + crate::raw::TOKEN => Ok(Compound::RawValue { ser: self }), + _ => self.serialize_map(Some(len)), + } + } + + #[inline] + fn serialize_struct_variant( + self, + _name: &'static str, + _variant_index: u32, + variant: &'static str, + len: usize, + ) -> Result { + tri!(self + .formatter + .begin_object(&mut self.writer) + .map_err(Error::io)); + tri!(self + .formatter + .begin_object_key(&mut self.writer, true) + .map_err(Error::io)); + tri!(self.serialize_str(variant)); + tri!(self + .formatter + .end_object_key(&mut self.writer) + .map_err(Error::io)); + tri!(self + .formatter + .begin_object_value(&mut self.writer) + .map_err(Error::io)); + self.serialize_map(Some(len)) + } + + fn collect_str(self, value: &T) -> Result<()> + where + T: ?Sized + Display, + { + use self::fmt::Write; + + struct Adapter<'ser, W: 'ser, F: 'ser> { + writer: &'ser mut W, + formatter: &'ser mut F, + error: Option, + } + + impl<'ser, W, F> Write for Adapter<'ser, W, F> + where + W: io::Write, + F: Formatter, + { + fn write_str(&mut self, s: &str) -> fmt::Result { + debug_assert!(self.error.is_none()); + match format_escaped_str_contents(self.writer, self.formatter, s) { + Ok(()) => Ok(()), + Err(err) => { + self.error = Some(err); + Err(fmt::Error) + } + } + } + } + + tri!(self + .formatter + .begin_string(&mut self.writer) + .map_err(Error::io)); + let mut adapter = Adapter { + writer: &mut self.writer, + formatter: &mut self.formatter, + error: None, + }; + match write!(adapter, "{}", value) { + Ok(()) => debug_assert!(adapter.error.is_none()), + Err(fmt::Error) => { + return Err(Error::io(adapter.error.expect("there should be an error"))); + } + } + self.formatter + .end_string(&mut self.writer) + .map_err(Error::io) + } +} + +// Not public API. Should be pub(crate). +#[doc(hidden)] +#[derive(Eq, PartialEq)] +pub enum State { + Empty, + First, + Rest, +} + +// Not public API. Should be pub(crate). +#[doc(hidden)] +pub enum Compound<'a, W: 'a, F: 'a> { + Map { + ser: &'a mut Serializer, + state: State, + }, + #[cfg(feature = "arbitrary_precision")] + Number { ser: &'a mut Serializer }, + #[cfg(feature = "raw_value")] + RawValue { ser: &'a mut Serializer }, +} + +impl<'a, W, F> ser::SerializeSeq for Compound<'a, W, F> +where + W: io::Write, + F: Formatter, +{ + type Ok = (); + type Error = Error; + + #[inline] + fn serialize_element(&mut self, value: &T) -> Result<()> + where + T: ?Sized + Serialize, + { + match self { + Compound::Map { ser, state } => { + tri!(ser + .formatter + .begin_array_value(&mut ser.writer, *state == State::First) + .map_err(Error::io)); + *state = State::Rest; + tri!(value.serialize(&mut **ser)); + ser.formatter + .end_array_value(&mut ser.writer) + .map_err(Error::io) + } + #[cfg(feature = "arbitrary_precision")] + Compound::Number { .. } => unreachable!(), + #[cfg(feature = "raw_value")] + Compound::RawValue { .. } => unreachable!(), + } + } + + #[inline] + fn end(self) -> Result<()> { + match self { + Compound::Map { ser, state } => match state { + State::Empty => Ok(()), + _ => ser.formatter.end_array(&mut ser.writer).map_err(Error::io), + }, + #[cfg(feature = "arbitrary_precision")] + Compound::Number { .. } => unreachable!(), + #[cfg(feature = "raw_value")] + Compound::RawValue { .. } => unreachable!(), + } + } +} + +impl<'a, W, F> ser::SerializeTuple for Compound<'a, W, F> +where + W: io::Write, + F: Formatter, +{ + type Ok = (); + type Error = Error; + + #[inline] + fn serialize_element(&mut self, value: &T) -> Result<()> + where + T: ?Sized + Serialize, + { + ser::SerializeSeq::serialize_element(self, value) + } + + #[inline] + fn end(self) -> Result<()> { + ser::SerializeSeq::end(self) + } +} + +impl<'a, W, F> ser::SerializeTupleStruct for Compound<'a, W, F> +where + W: io::Write, + F: Formatter, +{ + type Ok = (); + type Error = Error; + + #[inline] + fn serialize_field(&mut self, value: &T) -> Result<()> + where + T: ?Sized + Serialize, + { + ser::SerializeSeq::serialize_element(self, value) + } + + #[inline] + fn end(self) -> Result<()> { + ser::SerializeSeq::end(self) + } +} + +impl<'a, W, F> ser::SerializeTupleVariant for Compound<'a, W, F> +where + W: io::Write, + F: Formatter, +{ + type Ok = (); + type Error = Error; + + #[inline] + fn serialize_field(&mut self, value: &T) -> Result<()> + where + T: ?Sized + Serialize, + { + ser::SerializeSeq::serialize_element(self, value) + } + + #[inline] + fn end(self) -> Result<()> { + match self { + Compound::Map { ser, state } => { + match state { + State::Empty => {} + _ => tri!(ser.formatter.end_array(&mut ser.writer).map_err(Error::io)), + } + tri!(ser + .formatter + .end_object_value(&mut ser.writer) + .map_err(Error::io)); + ser.formatter.end_object(&mut ser.writer).map_err(Error::io) + } + #[cfg(feature = "arbitrary_precision")] + Compound::Number { .. } => unreachable!(), + #[cfg(feature = "raw_value")] + Compound::RawValue { .. } => unreachable!(), + } + } +} + +impl<'a, W, F> ser::SerializeMap for Compound<'a, W, F> +where + W: io::Write, + F: Formatter, +{ + type Ok = (); + type Error = Error; + + #[inline] + fn serialize_key(&mut self, key: &T) -> Result<()> + where + T: ?Sized + Serialize, + { + match self { + Compound::Map { ser, state } => { + tri!(ser + .formatter + .begin_object_key(&mut ser.writer, *state == State::First) + .map_err(Error::io)); + *state = State::Rest; + + tri!(key.serialize(MapKeySerializer { ser: *ser })); + + ser.formatter + .end_object_key(&mut ser.writer) + .map_err(Error::io) + } + #[cfg(feature = "arbitrary_precision")] + Compound::Number { .. } => unreachable!(), + #[cfg(feature = "raw_value")] + Compound::RawValue { .. } => unreachable!(), + } + } + + #[inline] + fn serialize_value(&mut self, value: &T) -> Result<()> + where + T: ?Sized + Serialize, + { + match self { + Compound::Map { ser, .. } => { + tri!(ser + .formatter + .begin_object_value(&mut ser.writer) + .map_err(Error::io)); + tri!(value.serialize(&mut **ser)); + ser.formatter + .end_object_value(&mut ser.writer) + .map_err(Error::io) + } + #[cfg(feature = "arbitrary_precision")] + Compound::Number { .. } => unreachable!(), + #[cfg(feature = "raw_value")] + Compound::RawValue { .. } => unreachable!(), + } + } + + #[inline] + fn end(self) -> Result<()> { + match self { + Compound::Map { ser, state } => match state { + State::Empty => Ok(()), + _ => ser.formatter.end_object(&mut ser.writer).map_err(Error::io), + }, + #[cfg(feature = "arbitrary_precision")] + Compound::Number { .. } => unreachable!(), + #[cfg(feature = "raw_value")] + Compound::RawValue { .. } => unreachable!(), + } + } +} + +impl<'a, W, F> ser::SerializeStruct for Compound<'a, W, F> +where + W: io::Write, + F: Formatter, +{ + type Ok = (); + type Error = Error; + + #[inline] + fn serialize_field(&mut self, key: &'static str, value: &T) -> Result<()> + where + T: ?Sized + Serialize, + { + match self { + Compound::Map { .. } => ser::SerializeMap::serialize_entry(self, key, value), + #[cfg(feature = "arbitrary_precision")] + Compound::Number { ser, .. } => { + if key == crate::number::TOKEN { + value.serialize(NumberStrEmitter(ser)) + } else { + Err(invalid_number()) + } + } + #[cfg(feature = "raw_value")] + Compound::RawValue { ser, .. } => { + if key == crate::raw::TOKEN { + value.serialize(RawValueStrEmitter(ser)) + } else { + Err(invalid_raw_value()) + } + } + } + } + + #[inline] + fn end(self) -> Result<()> { + match self { + Compound::Map { .. } => ser::SerializeMap::end(self), + #[cfg(feature = "arbitrary_precision")] + Compound::Number { .. } => Ok(()), + #[cfg(feature = "raw_value")] + Compound::RawValue { .. } => Ok(()), + } + } +} + +impl<'a, W, F> ser::SerializeStructVariant for Compound<'a, W, F> +where + W: io::Write, + F: Formatter, +{ + type Ok = (); + type Error = Error; + + #[inline] + fn serialize_field(&mut self, key: &'static str, value: &T) -> Result<()> + where + T: ?Sized + Serialize, + { + match *self { + Compound::Map { .. } => ser::SerializeStruct::serialize_field(self, key, value), + #[cfg(feature = "arbitrary_precision")] + Compound::Number { .. } => unreachable!(), + #[cfg(feature = "raw_value")] + Compound::RawValue { .. } => unreachable!(), + } + } + + #[inline] + fn end(self) -> Result<()> { + match self { + Compound::Map { ser, state } => { + match state { + State::Empty => {} + _ => tri!(ser.formatter.end_object(&mut ser.writer).map_err(Error::io)), + } + tri!(ser + .formatter + .end_object_value(&mut ser.writer) + .map_err(Error::io)); + ser.formatter.end_object(&mut ser.writer).map_err(Error::io) + } + #[cfg(feature = "arbitrary_precision")] + Compound::Number { .. } => unreachable!(), + #[cfg(feature = "raw_value")] + Compound::RawValue { .. } => unreachable!(), + } + } +} + +struct MapKeySerializer<'a, W: 'a, F: 'a> { + ser: &'a mut Serializer, +} + +#[cfg(feature = "arbitrary_precision")] +fn invalid_number() -> Error { + Error::syntax(ErrorCode::InvalidNumber, 0, 0) +} + +#[cfg(feature = "raw_value")] +fn invalid_raw_value() -> Error { + Error::syntax(ErrorCode::ExpectedSomeValue, 0, 0) +} + +fn key_must_be_a_string() -> Error { + Error::syntax(ErrorCode::KeyMustBeAString, 0, 0) +} + +fn float_key_must_be_finite() -> Error { + Error::syntax(ErrorCode::FloatKeyMustBeFinite, 0, 0) +} + +impl<'a, W, F> ser::Serializer for MapKeySerializer<'a, W, F> +where + W: io::Write, + F: Formatter, +{ + type Ok = (); + type Error = Error; + + #[inline] + fn serialize_str(self, value: &str) -> Result<()> { + self.ser.serialize_str(value) + } + + #[inline] + fn serialize_unit_variant( + self, + _name: &'static str, + _variant_index: u32, + variant: &'static str, + ) -> Result<()> { + self.ser.serialize_str(variant) + } + + #[inline] + fn serialize_newtype_struct(self, _name: &'static str, value: &T) -> Result<()> + where + T: ?Sized + Serialize, + { + value.serialize(self) + } + + type SerializeSeq = Impossible<(), Error>; + type SerializeTuple = Impossible<(), Error>; + type SerializeTupleStruct = Impossible<(), Error>; + type SerializeTupleVariant = Impossible<(), Error>; + type SerializeMap = Impossible<(), Error>; + type SerializeStruct = Impossible<(), Error>; + type SerializeStructVariant = Impossible<(), Error>; + + fn serialize_bool(self, value: bool) -> Result<()> { + tri!(self + .ser + .formatter + .begin_string(&mut self.ser.writer) + .map_err(Error::io)); + tri!(self + .ser + .formatter + .write_bool(&mut self.ser.writer, value) + .map_err(Error::io)); + self.ser + .formatter + .end_string(&mut self.ser.writer) + .map_err(Error::io) + } + + fn serialize_i8(self, value: i8) -> Result<()> { + tri!(self + .ser + .formatter + .begin_string(&mut self.ser.writer) + .map_err(Error::io)); + tri!(self + .ser + .formatter + .write_i8(&mut self.ser.writer, value) + .map_err(Error::io)); + self.ser + .formatter + .end_string(&mut self.ser.writer) + .map_err(Error::io) + } + + fn serialize_i16(self, value: i16) -> Result<()> { + tri!(self + .ser + .formatter + .begin_string(&mut self.ser.writer) + .map_err(Error::io)); + tri!(self + .ser + .formatter + .write_i16(&mut self.ser.writer, value) + .map_err(Error::io)); + self.ser + .formatter + .end_string(&mut self.ser.writer) + .map_err(Error::io) + } + + fn serialize_i32(self, value: i32) -> Result<()> { + tri!(self + .ser + .formatter + .begin_string(&mut self.ser.writer) + .map_err(Error::io)); + tri!(self + .ser + .formatter + .write_i32(&mut self.ser.writer, value) + .map_err(Error::io)); + self.ser + .formatter + .end_string(&mut self.ser.writer) + .map_err(Error::io) + } + + fn serialize_i64(self, value: i64) -> Result<()> { + tri!(self + .ser + .formatter + .begin_string(&mut self.ser.writer) + .map_err(Error::io)); + tri!(self + .ser + .formatter + .write_i64(&mut self.ser.writer, value) + .map_err(Error::io)); + self.ser + .formatter + .end_string(&mut self.ser.writer) + .map_err(Error::io) + } + + fn serialize_i128(self, value: i128) -> Result<()> { + tri!(self + .ser + .formatter + .begin_string(&mut self.ser.writer) + .map_err(Error::io)); + tri!(self + .ser + .formatter + .write_i128(&mut self.ser.writer, value) + .map_err(Error::io)); + self.ser + .formatter + .end_string(&mut self.ser.writer) + .map_err(Error::io) + } + + fn serialize_u8(self, value: u8) -> Result<()> { + tri!(self + .ser + .formatter + .begin_string(&mut self.ser.writer) + .map_err(Error::io)); + tri!(self + .ser + .formatter + .write_u8(&mut self.ser.writer, value) + .map_err(Error::io)); + self.ser + .formatter + .end_string(&mut self.ser.writer) + .map_err(Error::io) + } + + fn serialize_u16(self, value: u16) -> Result<()> { + tri!(self + .ser + .formatter + .begin_string(&mut self.ser.writer) + .map_err(Error::io)); + tri!(self + .ser + .formatter + .write_u16(&mut self.ser.writer, value) + .map_err(Error::io)); + self.ser + .formatter + .end_string(&mut self.ser.writer) + .map_err(Error::io) + } + + fn serialize_u32(self, value: u32) -> Result<()> { + tri!(self + .ser + .formatter + .begin_string(&mut self.ser.writer) + .map_err(Error::io)); + tri!(self + .ser + .formatter + .write_u32(&mut self.ser.writer, value) + .map_err(Error::io)); + self.ser + .formatter + .end_string(&mut self.ser.writer) + .map_err(Error::io) + } + + fn serialize_u64(self, value: u64) -> Result<()> { + tri!(self + .ser + .formatter + .begin_string(&mut self.ser.writer) + .map_err(Error::io)); + tri!(self + .ser + .formatter + .write_u64(&mut self.ser.writer, value) + .map_err(Error::io)); + self.ser + .formatter + .end_string(&mut self.ser.writer) + .map_err(Error::io) + } + + fn serialize_u128(self, value: u128) -> Result<()> { + tri!(self + .ser + .formatter + .begin_string(&mut self.ser.writer) + .map_err(Error::io)); + tri!(self + .ser + .formatter + .write_u128(&mut self.ser.writer, value) + .map_err(Error::io)); + self.ser + .formatter + .end_string(&mut self.ser.writer) + .map_err(Error::io) + } + + fn serialize_f32(self, value: f32) -> Result<()> { + if !value.is_finite() { + return Err(float_key_must_be_finite()); + } + + tri!(self + .ser + .formatter + .begin_string(&mut self.ser.writer) + .map_err(Error::io)); + tri!(self + .ser + .formatter + .write_f32(&mut self.ser.writer, value) + .map_err(Error::io)); + self.ser + .formatter + .end_string(&mut self.ser.writer) + .map_err(Error::io) + } + + fn serialize_f64(self, value: f64) -> Result<()> { + if !value.is_finite() { + return Err(float_key_must_be_finite()); + } + + tri!(self + .ser + .formatter + .begin_string(&mut self.ser.writer) + .map_err(Error::io)); + tri!(self + .ser + .formatter + .write_f64(&mut self.ser.writer, value) + .map_err(Error::io)); + self.ser + .formatter + .end_string(&mut self.ser.writer) + .map_err(Error::io) + } + + fn serialize_char(self, value: char) -> Result<()> { + self.ser.serialize_str(value.encode_utf8(&mut [0u8; 4])) + } + + fn serialize_bytes(self, _value: &[u8]) -> Result<()> { + Err(key_must_be_a_string()) + } + + fn serialize_unit(self) -> Result<()> { + Err(key_must_be_a_string()) + } + + fn serialize_unit_struct(self, _name: &'static str) -> Result<()> { + Err(key_must_be_a_string()) + } + + fn serialize_newtype_variant( + self, + _name: &'static str, + _variant_index: u32, + _variant: &'static str, + _value: &T, + ) -> Result<()> + where + T: ?Sized + Serialize, + { + Err(key_must_be_a_string()) + } + + fn serialize_none(self) -> Result<()> { + Err(key_must_be_a_string()) + } + + fn serialize_some(self, value: &T) -> Result<()> + where + T: ?Sized + Serialize, + { + value.serialize(self) + } + + fn serialize_seq(self, _len: Option) -> Result { + Err(key_must_be_a_string()) + } + + fn serialize_tuple(self, _len: usize) -> Result { + Err(key_must_be_a_string()) + } + + fn serialize_tuple_struct( + self, + _name: &'static str, + _len: usize, + ) -> Result { + Err(key_must_be_a_string()) + } + + fn serialize_tuple_variant( + self, + _name: &'static str, + _variant_index: u32, + _variant: &'static str, + _len: usize, + ) -> Result { + Err(key_must_be_a_string()) + } + + fn serialize_map(self, _len: Option) -> Result { + Err(key_must_be_a_string()) + } + + fn serialize_struct(self, _name: &'static str, _len: usize) -> Result { + Err(key_must_be_a_string()) + } + + fn serialize_struct_variant( + self, + _name: &'static str, + _variant_index: u32, + _variant: &'static str, + _len: usize, + ) -> Result { + Err(key_must_be_a_string()) + } + + fn collect_str(self, value: &T) -> Result<()> + where + T: ?Sized + Display, + { + self.ser.collect_str(value) + } +} + +#[cfg(feature = "arbitrary_precision")] +struct NumberStrEmitter<'a, W: 'a + io::Write, F: 'a + Formatter>(&'a mut Serializer); + +#[cfg(feature = "arbitrary_precision")] +impl<'a, W: io::Write, F: Formatter> ser::Serializer for NumberStrEmitter<'a, W, F> { + type Ok = (); + type Error = Error; + + type SerializeSeq = Impossible<(), Error>; + type SerializeTuple = Impossible<(), Error>; + type SerializeTupleStruct = Impossible<(), Error>; + type SerializeTupleVariant = Impossible<(), Error>; + type SerializeMap = Impossible<(), Error>; + type SerializeStruct = Impossible<(), Error>; + type SerializeStructVariant = Impossible<(), Error>; + + fn serialize_bool(self, _v: bool) -> Result<()> { + Err(invalid_number()) + } + + fn serialize_i8(self, _v: i8) -> Result<()> { + Err(invalid_number()) + } + + fn serialize_i16(self, _v: i16) -> Result<()> { + Err(invalid_number()) + } + + fn serialize_i32(self, _v: i32) -> Result<()> { + Err(invalid_number()) + } + + fn serialize_i64(self, _v: i64) -> Result<()> { + Err(invalid_number()) + } + + fn serialize_i128(self, _v: i128) -> Result<()> { + Err(invalid_number()) + } + + fn serialize_u8(self, _v: u8) -> Result<()> { + Err(invalid_number()) + } + + fn serialize_u16(self, _v: u16) -> Result<()> { + Err(invalid_number()) + } + + fn serialize_u32(self, _v: u32) -> Result<()> { + Err(invalid_number()) + } + + fn serialize_u64(self, _v: u64) -> Result<()> { + Err(invalid_number()) + } + + fn serialize_u128(self, _v: u128) -> Result<()> { + Err(invalid_number()) + } + + fn serialize_f32(self, _v: f32) -> Result<()> { + Err(invalid_number()) + } + + fn serialize_f64(self, _v: f64) -> Result<()> { + Err(invalid_number()) + } + + fn serialize_char(self, _v: char) -> Result<()> { + Err(invalid_number()) + } + + fn serialize_str(self, value: &str) -> Result<()> { + let NumberStrEmitter(serializer) = self; + serializer + .formatter + .write_number_str(&mut serializer.writer, value) + .map_err(Error::io) + } + + fn serialize_bytes(self, _value: &[u8]) -> Result<()> { + Err(invalid_number()) + } + + fn serialize_none(self) -> Result<()> { + Err(invalid_number()) + } + + fn serialize_some(self, _value: &T) -> Result<()> + where + T: ?Sized + Serialize, + { + Err(invalid_number()) + } + + fn serialize_unit(self) -> Result<()> { + Err(invalid_number()) + } + + fn serialize_unit_struct(self, _name: &'static str) -> Result<()> { + Err(invalid_number()) + } + + fn serialize_unit_variant( + self, + _name: &'static str, + _variant_index: u32, + _variant: &'static str, + ) -> Result<()> { + Err(invalid_number()) + } + + fn serialize_newtype_struct(self, _name: &'static str, _value: &T) -> Result<()> + where + T: ?Sized + Serialize, + { + Err(invalid_number()) + } + + fn serialize_newtype_variant( + self, + _name: &'static str, + _variant_index: u32, + _variant: &'static str, + _value: &T, + ) -> Result<()> + where + T: ?Sized + Serialize, + { + Err(invalid_number()) + } + + fn serialize_seq(self, _len: Option) -> Result { + Err(invalid_number()) + } + + fn serialize_tuple(self, _len: usize) -> Result { + Err(invalid_number()) + } + + fn serialize_tuple_struct( + self, + _name: &'static str, + _len: usize, + ) -> Result { + Err(invalid_number()) + } + + fn serialize_tuple_variant( + self, + _name: &'static str, + _variant_index: u32, + _variant: &'static str, + _len: usize, + ) -> Result { + Err(invalid_number()) + } + + fn serialize_map(self, _len: Option) -> Result { + Err(invalid_number()) + } + + fn serialize_struct(self, _name: &'static str, _len: usize) -> Result { + Err(invalid_number()) + } + + fn serialize_struct_variant( + self, + _name: &'static str, + _variant_index: u32, + _variant: &'static str, + _len: usize, + ) -> Result { + Err(invalid_number()) + } +} + +#[cfg(feature = "raw_value")] +struct RawValueStrEmitter<'a, W: 'a + io::Write, F: 'a + Formatter>(&'a mut Serializer); + +#[cfg(feature = "raw_value")] +impl<'a, W: io::Write, F: Formatter> ser::Serializer for RawValueStrEmitter<'a, W, F> { + type Ok = (); + type Error = Error; + + type SerializeSeq = Impossible<(), Error>; + type SerializeTuple = Impossible<(), Error>; + type SerializeTupleStruct = Impossible<(), Error>; + type SerializeTupleVariant = Impossible<(), Error>; + type SerializeMap = Impossible<(), Error>; + type SerializeStruct = Impossible<(), Error>; + type SerializeStructVariant = Impossible<(), Error>; + + fn serialize_bool(self, _v: bool) -> Result<()> { + Err(ser::Error::custom("expected RawValue")) + } + + fn serialize_i8(self, _v: i8) -> Result<()> { + Err(ser::Error::custom("expected RawValue")) + } + + fn serialize_i16(self, _v: i16) -> Result<()> { + Err(ser::Error::custom("expected RawValue")) + } + + fn serialize_i32(self, _v: i32) -> Result<()> { + Err(ser::Error::custom("expected RawValue")) + } + + fn serialize_i64(self, _v: i64) -> Result<()> { + Err(ser::Error::custom("expected RawValue")) + } + + fn serialize_i128(self, _v: i128) -> Result<()> { + Err(ser::Error::custom("expected RawValue")) + } + + fn serialize_u8(self, _v: u8) -> Result<()> { + Err(ser::Error::custom("expected RawValue")) + } + + fn serialize_u16(self, _v: u16) -> Result<()> { + Err(ser::Error::custom("expected RawValue")) + } + + fn serialize_u32(self, _v: u32) -> Result<()> { + Err(ser::Error::custom("expected RawValue")) + } + + fn serialize_u64(self, _v: u64) -> Result<()> { + Err(ser::Error::custom("expected RawValue")) + } + + fn serialize_u128(self, _v: u128) -> Result<()> { + Err(ser::Error::custom("expected RawValue")) + } + + fn serialize_f32(self, _v: f32) -> Result<()> { + Err(ser::Error::custom("expected RawValue")) + } + + fn serialize_f64(self, _v: f64) -> Result<()> { + Err(ser::Error::custom("expected RawValue")) + } + + fn serialize_char(self, _v: char) -> Result<()> { + Err(ser::Error::custom("expected RawValue")) + } + + fn serialize_str(self, value: &str) -> Result<()> { + let RawValueStrEmitter(serializer) = self; + serializer + .formatter + .write_raw_fragment(&mut serializer.writer, value) + .map_err(Error::io) + } + + fn serialize_bytes(self, _value: &[u8]) -> Result<()> { + Err(ser::Error::custom("expected RawValue")) + } + + fn serialize_none(self) -> Result<()> { + Err(ser::Error::custom("expected RawValue")) + } + + fn serialize_some(self, _value: &T) -> Result<()> + where + T: ?Sized + Serialize, + { + Err(ser::Error::custom("expected RawValue")) + } + + fn serialize_unit(self) -> Result<()> { + Err(ser::Error::custom("expected RawValue")) + } + + fn serialize_unit_struct(self, _name: &'static str) -> Result<()> { + Err(ser::Error::custom("expected RawValue")) + } + + fn serialize_unit_variant( + self, + _name: &'static str, + _variant_index: u32, + _variant: &'static str, + ) -> Result<()> { + Err(ser::Error::custom("expected RawValue")) + } + + fn serialize_newtype_struct(self, _name: &'static str, _value: &T) -> Result<()> + where + T: ?Sized + Serialize, + { + Err(ser::Error::custom("expected RawValue")) + } + + fn serialize_newtype_variant( + self, + _name: &'static str, + _variant_index: u32, + _variant: &'static str, + _value: &T, + ) -> Result<()> + where + T: ?Sized + Serialize, + { + Err(ser::Error::custom("expected RawValue")) + } + + fn serialize_seq(self, _len: Option) -> Result { + Err(ser::Error::custom("expected RawValue")) + } + + fn serialize_tuple(self, _len: usize) -> Result { + Err(ser::Error::custom("expected RawValue")) + } + + fn serialize_tuple_struct( + self, + _name: &'static str, + _len: usize, + ) -> Result { + Err(ser::Error::custom("expected RawValue")) + } + + fn serialize_tuple_variant( + self, + _name: &'static str, + _variant_index: u32, + _variant: &'static str, + _len: usize, + ) -> Result { + Err(ser::Error::custom("expected RawValue")) + } + + fn serialize_map(self, _len: Option) -> Result { + Err(ser::Error::custom("expected RawValue")) + } + + fn serialize_struct(self, _name: &'static str, _len: usize) -> Result { + Err(ser::Error::custom("expected RawValue")) + } + + fn serialize_struct_variant( + self, + _name: &'static str, + _variant_index: u32, + _variant: &'static str, + _len: usize, + ) -> Result { + Err(ser::Error::custom("expected RawValue")) + } + + fn collect_str(self, value: &T) -> Result + where + T: ?Sized + Display, + { + self.serialize_str(&value.to_string()) + } +} + +/// Represents a character escape code in a type-safe manner. +pub enum CharEscape { + /// An escaped quote `"` + Quote, + /// An escaped reverse solidus `\` + ReverseSolidus, + /// An escaped solidus `/` + Solidus, + /// An escaped backspace character (usually escaped as `\b`) + Backspace, + /// An escaped form feed character (usually escaped as `\f`) + FormFeed, + /// An escaped line feed character (usually escaped as `\n`) + LineFeed, + /// An escaped carriage return character (usually escaped as `\r`) + CarriageReturn, + /// An escaped tab character (usually escaped as `\t`) + Tab, + /// An escaped ASCII plane control character (usually escaped as + /// `\u00XX` where `XX` are two hex characters) + AsciiControl(u8), +} + +impl CharEscape { + #[inline] + fn from_escape_table(escape: u8, byte: u8) -> CharEscape { + match escape { + self::BB => CharEscape::Backspace, + self::TT => CharEscape::Tab, + self::NN => CharEscape::LineFeed, + self::FF => CharEscape::FormFeed, + self::RR => CharEscape::CarriageReturn, + self::QU => CharEscape::Quote, + self::BS => CharEscape::ReverseSolidus, + self::UU => CharEscape::AsciiControl(byte), + _ => unreachable!(), + } + } +} + +/// This trait abstracts away serializing the JSON control characters, which allows the user to +/// optionally pretty print the JSON output. +pub trait Formatter { + /// Writes a `null` value to the specified writer. + #[inline] + fn write_null(&mut self, writer: &mut W) -> io::Result<()> + where + W: ?Sized + io::Write, + { + writer.write_all(b"null") + } + + /// Writes a `true` or `false` value to the specified writer. + #[inline] + fn write_bool(&mut self, writer: &mut W, value: bool) -> io::Result<()> + where + W: ?Sized + io::Write, + { + let s = if value { + b"true" as &[u8] + } else { + b"false" as &[u8] + }; + writer.write_all(s) + } + + /// Writes an integer value like `-123` to the specified writer. + #[inline] + fn write_i8(&mut self, writer: &mut W, value: i8) -> io::Result<()> + where + W: ?Sized + io::Write, + { + let mut buffer = itoa::Buffer::new(); + let s = buffer.format(value); + writer.write_all(s.as_bytes()) + } + + /// Writes an integer value like `-123` to the specified writer. + #[inline] + fn write_i16(&mut self, writer: &mut W, value: i16) -> io::Result<()> + where + W: ?Sized + io::Write, + { + let mut buffer = itoa::Buffer::new(); + let s = buffer.format(value); + writer.write_all(s.as_bytes()) + } + + /// Writes an integer value like `-123` to the specified writer. + #[inline] + fn write_i32(&mut self, writer: &mut W, value: i32) -> io::Result<()> + where + W: ?Sized + io::Write, + { + let mut buffer = itoa::Buffer::new(); + let s = buffer.format(value); + writer.write_all(s.as_bytes()) + } + + /// Writes an integer value like `-123` to the specified writer. + #[inline] + fn write_i64(&mut self, writer: &mut W, value: i64) -> io::Result<()> + where + W: ?Sized + io::Write, + { + let mut buffer = itoa::Buffer::new(); + let s = buffer.format(value); + writer.write_all(s.as_bytes()) + } + + /// Writes an integer value like `-123` to the specified writer. + #[inline] + fn write_i128(&mut self, writer: &mut W, value: i128) -> io::Result<()> + where + W: ?Sized + io::Write, + { + let mut buffer = itoa::Buffer::new(); + let s = buffer.format(value); + writer.write_all(s.as_bytes()) + } + + /// Writes an integer value like `123` to the specified writer. + #[inline] + fn write_u8(&mut self, writer: &mut W, value: u8) -> io::Result<()> + where + W: ?Sized + io::Write, + { + let mut buffer = itoa::Buffer::new(); + let s = buffer.format(value); + writer.write_all(s.as_bytes()) + } + + /// Writes an integer value like `123` to the specified writer. + #[inline] + fn write_u16(&mut self, writer: &mut W, value: u16) -> io::Result<()> + where + W: ?Sized + io::Write, + { + let mut buffer = itoa::Buffer::new(); + let s = buffer.format(value); + writer.write_all(s.as_bytes()) + } + + /// Writes an integer value like `123` to the specified writer. + #[inline] + fn write_u32(&mut self, writer: &mut W, value: u32) -> io::Result<()> + where + W: ?Sized + io::Write, + { + let mut buffer = itoa::Buffer::new(); + let s = buffer.format(value); + writer.write_all(s.as_bytes()) + } + + /// Writes an integer value like `123` to the specified writer. + #[inline] + fn write_u64(&mut self, writer: &mut W, value: u64) -> io::Result<()> + where + W: ?Sized + io::Write, + { + let mut buffer = itoa::Buffer::new(); + let s = buffer.format(value); + writer.write_all(s.as_bytes()) + } + + /// Writes an integer value like `123` to the specified writer. + #[inline] + fn write_u128(&mut self, writer: &mut W, value: u128) -> io::Result<()> + where + W: ?Sized + io::Write, + { + let mut buffer = itoa::Buffer::new(); + let s = buffer.format(value); + writer.write_all(s.as_bytes()) + } + + /// Writes a floating point value like `-31.26e+12` to the specified writer. + #[inline] + fn write_f32(&mut self, writer: &mut W, value: f32) -> io::Result<()> + where + W: ?Sized + io::Write, + { + let mut buffer = ryu::Buffer::new(); + let s = buffer.format_finite(value); + writer.write_all(s.as_bytes()) + } + + /// Writes a floating point value like `-31.26e+12` to the specified writer. + #[inline] + fn write_f64(&mut self, writer: &mut W, value: f64) -> io::Result<()> + where + W: ?Sized + io::Write, + { + let mut buffer = ryu::Buffer::new(); + let s = buffer.format_finite(value); + writer.write_all(s.as_bytes()) + } + + /// Writes a number that has already been rendered to a string. + #[inline] + fn write_number_str(&mut self, writer: &mut W, value: &str) -> io::Result<()> + where + W: ?Sized + io::Write, + { + writer.write_all(value.as_bytes()) + } + + /// Called before each series of `write_string_fragment` and + /// `write_char_escape`. Writes a `"` to the specified writer. + #[inline] + fn begin_string(&mut self, writer: &mut W) -> io::Result<()> + where + W: ?Sized + io::Write, + { + writer.write_all(b"\"") + } + + /// Called after each series of `write_string_fragment` and + /// `write_char_escape`. Writes a `"` to the specified writer. + #[inline] + fn end_string(&mut self, writer: &mut W) -> io::Result<()> + where + W: ?Sized + io::Write, + { + writer.write_all(b"\"") + } + + /// Writes a string fragment that doesn't need any escaping to the + /// specified writer. + #[inline] + fn write_string_fragment(&mut self, writer: &mut W, fragment: &str) -> io::Result<()> + where + W: ?Sized + io::Write, + { + writer.write_all(fragment.as_bytes()) + } + + /// Writes a character escape code to the specified writer. + #[inline] + fn write_char_escape(&mut self, writer: &mut W, char_escape: CharEscape) -> io::Result<()> + where + W: ?Sized + io::Write, + { + use self::CharEscape::*; + + let s = match char_escape { + Quote => b"\\\"", + ReverseSolidus => b"\\\\", + Solidus => b"\\/", + Backspace => b"\\b", + FormFeed => b"\\f", + LineFeed => b"\\n", + CarriageReturn => b"\\r", + Tab => b"\\t", + AsciiControl(byte) => { + static HEX_DIGITS: [u8; 16] = *b"0123456789abcdef"; + let bytes = &[ + b'\\', + b'u', + b'0', + b'0', + HEX_DIGITS[(byte >> 4) as usize], + HEX_DIGITS[(byte & 0xF) as usize], + ]; + return writer.write_all(bytes); + } + }; + + writer.write_all(s) + } + + /// Writes the representation of a byte array. Formatters can choose whether + /// to represent bytes as a JSON array of integers (the default), or some + /// JSON string encoding like hex or base64. + fn write_byte_array(&mut self, writer: &mut W, value: &[u8]) -> io::Result<()> + where + W: ?Sized + io::Write, + { + tri!(self.begin_array(writer)); + let mut first = true; + for byte in value { + tri!(self.begin_array_value(writer, first)); + tri!(self.write_u8(writer, *byte)); + tri!(self.end_array_value(writer)); + first = false; + } + self.end_array(writer) + } + + /// Called before every array. Writes a `[` to the specified + /// writer. + #[inline] + fn begin_array(&mut self, writer: &mut W) -> io::Result<()> + where + W: ?Sized + io::Write, + { + writer.write_all(b"[") + } + + /// Called after every array. Writes a `]` to the specified + /// writer. + #[inline] + fn end_array(&mut self, writer: &mut W) -> io::Result<()> + where + W: ?Sized + io::Write, + { + writer.write_all(b"]") + } + + /// Called before every array value. Writes a `,` if needed to + /// the specified writer. + #[inline] + fn begin_array_value(&mut self, writer: &mut W, first: bool) -> io::Result<()> + where + W: ?Sized + io::Write, + { + if first { + Ok(()) + } else { + writer.write_all(b",") + } + } + + /// Called after every array value. + #[inline] + fn end_array_value(&mut self, _writer: &mut W) -> io::Result<()> + where + W: ?Sized + io::Write, + { + Ok(()) + } + + /// Called before every object. Writes a `{` to the specified + /// writer. + #[inline] + fn begin_object(&mut self, writer: &mut W) -> io::Result<()> + where + W: ?Sized + io::Write, + { + writer.write_all(b"{") + } + + /// Called after every object. Writes a `}` to the specified + /// writer. + #[inline] + fn end_object(&mut self, writer: &mut W) -> io::Result<()> + where + W: ?Sized + io::Write, + { + writer.write_all(b"}") + } + + /// Called before every object key. + #[inline] + fn begin_object_key(&mut self, writer: &mut W, first: bool) -> io::Result<()> + where + W: ?Sized + io::Write, + { + if first { + Ok(()) + } else { + writer.write_all(b",") + } + } + + /// Called after every object key. A `:` should be written to the + /// specified writer by either this method or + /// `begin_object_value`. + #[inline] + fn end_object_key(&mut self, _writer: &mut W) -> io::Result<()> + where + W: ?Sized + io::Write, + { + Ok(()) + } + + /// Called before every object value. A `:` should be written to + /// the specified writer by either this method or + /// `end_object_key`. + #[inline] + fn begin_object_value(&mut self, writer: &mut W) -> io::Result<()> + where + W: ?Sized + io::Write, + { + writer.write_all(b":") + } + + /// Called after every object value. + #[inline] + fn end_object_value(&mut self, _writer: &mut W) -> io::Result<()> + where + W: ?Sized + io::Write, + { + Ok(()) + } + + /// Writes a raw JSON fragment that doesn't need any escaping to the + /// specified writer. + #[inline] + fn write_raw_fragment(&mut self, writer: &mut W, fragment: &str) -> io::Result<()> + where + W: ?Sized + io::Write, + { + writer.write_all(fragment.as_bytes()) + } +} + +/// This structure compacts a JSON value with no extra whitespace. +#[derive(Clone, Debug)] +pub struct CompactFormatter; + +impl Formatter for CompactFormatter {} + +/// This structure pretty prints a JSON value to make it human readable. +#[derive(Clone, Debug)] +pub struct PrettyFormatter<'a> { + current_indent: usize, + has_value: bool, + indent: &'a [u8], +} + +impl<'a> PrettyFormatter<'a> { + /// Construct a pretty printer formatter that defaults to using two spaces for indentation. + pub fn new() -> Self { + PrettyFormatter::with_indent(b" ") + } + + /// Construct a pretty printer formatter that uses the `indent` string for indentation. + pub fn with_indent(indent: &'a [u8]) -> Self { + PrettyFormatter { + current_indent: 0, + has_value: false, + indent, + } + } +} + +impl<'a> Default for PrettyFormatter<'a> { + fn default() -> Self { + PrettyFormatter::new() + } +} + +impl<'a> Formatter for PrettyFormatter<'a> { + #[inline] + fn begin_array(&mut self, writer: &mut W) -> io::Result<()> + where + W: ?Sized + io::Write, + { + self.current_indent += 1; + self.has_value = false; + writer.write_all(b"[") + } + + #[inline] + fn end_array(&mut self, writer: &mut W) -> io::Result<()> + where + W: ?Sized + io::Write, + { + self.current_indent -= 1; + + if self.has_value { + tri!(writer.write_all(b"\n")); + tri!(indent(writer, self.current_indent, self.indent)); + } + + writer.write_all(b"]") + } + + #[inline] + fn begin_array_value(&mut self, writer: &mut W, first: bool) -> io::Result<()> + where + W: ?Sized + io::Write, + { + tri!(writer.write_all(if first { b"\n" } else { b",\n" })); + indent(writer, self.current_indent, self.indent) + } + + #[inline] + fn end_array_value(&mut self, _writer: &mut W) -> io::Result<()> + where + W: ?Sized + io::Write, + { + self.has_value = true; + Ok(()) + } + + #[inline] + fn begin_object(&mut self, writer: &mut W) -> io::Result<()> + where + W: ?Sized + io::Write, + { + self.current_indent += 1; + self.has_value = false; + writer.write_all(b"{") + } + + #[inline] + fn end_object(&mut self, writer: &mut W) -> io::Result<()> + where + W: ?Sized + io::Write, + { + self.current_indent -= 1; + + if self.has_value { + tri!(writer.write_all(b"\n")); + tri!(indent(writer, self.current_indent, self.indent)); + } + + writer.write_all(b"}") + } + + #[inline] + fn begin_object_key(&mut self, writer: &mut W, first: bool) -> io::Result<()> + where + W: ?Sized + io::Write, + { + tri!(writer.write_all(if first { b"\n" } else { b",\n" })); + indent(writer, self.current_indent, self.indent) + } + + #[inline] + fn begin_object_value(&mut self, writer: &mut W) -> io::Result<()> + where + W: ?Sized + io::Write, + { + writer.write_all(b": ") + } + + #[inline] + fn end_object_value(&mut self, _writer: &mut W) -> io::Result<()> + where + W: ?Sized + io::Write, + { + self.has_value = true; + Ok(()) + } +} + +fn format_escaped_str(writer: &mut W, formatter: &mut F, value: &str) -> io::Result<()> +where + W: ?Sized + io::Write, + F: ?Sized + Formatter, +{ + tri!(formatter.begin_string(writer)); + tri!(format_escaped_str_contents(writer, formatter, value)); + formatter.end_string(writer) +} + +fn format_escaped_str_contents( + writer: &mut W, + formatter: &mut F, + value: &str, +) -> io::Result<()> +where + W: ?Sized + io::Write, + F: ?Sized + Formatter, +{ + let bytes = value.as_bytes(); + + let mut start = 0; + + for (i, &byte) in bytes.iter().enumerate() { + let escape = ESCAPE[byte as usize]; + if escape == 0 { + continue; + } + + if start < i { + tri!(formatter.write_string_fragment(writer, &value[start..i])); + } + + let char_escape = CharEscape::from_escape_table(escape, byte); + tri!(formatter.write_char_escape(writer, char_escape)); + + start = i + 1; + } + + if start == bytes.len() { + return Ok(()); + } + + formatter.write_string_fragment(writer, &value[start..]) +} + +const BB: u8 = b'b'; // \x08 +const TT: u8 = b't'; // \x09 +const NN: u8 = b'n'; // \x0A +const FF: u8 = b'f'; // \x0C +const RR: u8 = b'r'; // \x0D +const QU: u8 = b'"'; // \x22 +const BS: u8 = b'\\'; // \x5C +const UU: u8 = b'u'; // \x00...\x1F except the ones above +const __: u8 = 0; + +// Lookup table of escape sequences. A value of b'x' at index i means that byte +// i is escaped as "\x" in JSON. A value of 0 means that byte i is not escaped. +static ESCAPE: [u8; 256] = [ + // 1 2 3 4 5 6 7 8 9 A B C D E F + UU, UU, UU, UU, UU, UU, UU, UU, BB, TT, NN, UU, FF, RR, UU, UU, // 0 + UU, UU, UU, UU, UU, UU, UU, UU, UU, UU, UU, UU, UU, UU, UU, UU, // 1 + __, __, QU, __, __, __, __, __, __, __, __, __, __, __, __, __, // 2 + __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // 3 + __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // 4 + __, __, __, __, __, __, __, __, __, __, __, __, BS, __, __, __, // 5 + __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // 6 + __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // 7 + __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // 8 + __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // 9 + __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // A + __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // B + __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // C + __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // D + __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // E + __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // F +]; + +/// Serialize the given data structure as JSON into the I/O stream. +/// +/// Serialization guarantees it only feeds valid UTF-8 sequences to the writer. +/// +/// # Errors +/// +/// Serialization can fail if `T`'s implementation of `Serialize` decides to +/// fail, or if `T` contains a map with non-string keys. +#[inline] +#[cfg_attr(docsrs, doc(cfg(feature = "std")))] +pub fn to_writer(writer: W, value: &T) -> Result<()> +where + W: io::Write, + T: ?Sized + Serialize, +{ + let mut ser = Serializer::new(writer); + value.serialize(&mut ser) +} + +/// Serialize the given data structure as pretty-printed JSON into the I/O +/// stream. +/// +/// Serialization guarantees it only feeds valid UTF-8 sequences to the writer. +/// +/// # Errors +/// +/// Serialization can fail if `T`'s implementation of `Serialize` decides to +/// fail, or if `T` contains a map with non-string keys. +#[inline] +#[cfg_attr(docsrs, doc(cfg(feature = "std")))] +pub fn to_writer_pretty(writer: W, value: &T) -> Result<()> +where + W: io::Write, + T: ?Sized + Serialize, +{ + let mut ser = Serializer::pretty(writer); + value.serialize(&mut ser) +} + +/// Serialize the given data structure as a JSON byte vector. +/// +/// # Errors +/// +/// Serialization can fail if `T`'s implementation of `Serialize` decides to +/// fail, or if `T` contains a map with non-string keys. +#[inline] +pub fn to_vec(value: &T) -> Result> +where + T: ?Sized + Serialize, +{ + let mut writer = Vec::with_capacity(128); + tri!(to_writer(&mut writer, value)); + Ok(writer) +} + +/// Serialize the given data structure as a pretty-printed JSON byte vector. +/// +/// # Errors +/// +/// Serialization can fail if `T`'s implementation of `Serialize` decides to +/// fail, or if `T` contains a map with non-string keys. +#[inline] +pub fn to_vec_pretty(value: &T) -> Result> +where + T: ?Sized + Serialize, +{ + let mut writer = Vec::with_capacity(128); + tri!(to_writer_pretty(&mut writer, value)); + Ok(writer) +} + +/// Serialize the given data structure as a String of JSON. +/// +/// # Errors +/// +/// Serialization can fail if `T`'s implementation of `Serialize` decides to +/// fail, or if `T` contains a map with non-string keys. +#[inline] +pub fn to_string(value: &T) -> Result +where + T: ?Sized + Serialize, +{ + let vec = tri!(to_vec(value)); + let string = unsafe { + // We do not emit invalid UTF-8. + String::from_utf8_unchecked(vec) + }; + Ok(string) +} + +/// Serialize the given data structure as a pretty-printed String of JSON. +/// +/// # Errors +/// +/// Serialization can fail if `T`'s implementation of `Serialize` decides to +/// fail, or if `T` contains a map with non-string keys. +#[inline] +pub fn to_string_pretty(value: &T) -> Result +where + T: ?Sized + Serialize, +{ + let vec = tri!(to_vec_pretty(value)); + let string = unsafe { + // We do not emit invalid UTF-8. + String::from_utf8_unchecked(vec) + }; + Ok(string) +} + +fn indent(wr: &mut W, n: usize, s: &[u8]) -> io::Result<()> +where + W: ?Sized + io::Write, +{ + for _ in 0..n { + tri!(wr.write_all(s)); + } + + Ok(()) +} diff --git a/vendor/serde_json/src/value/de.rs b/vendor/serde_json/src/value/de.rs new file mode 100644 index 0000000..9367256 --- /dev/null +++ b/vendor/serde_json/src/value/de.rs @@ -0,0 +1,1423 @@ +use crate::error::{Error, ErrorCode}; +use crate::map::Map; +use crate::number::Number; +use crate::value::Value; +use alloc::borrow::{Cow, ToOwned}; +use alloc::string::String; +#[cfg(feature = "raw_value")] +use alloc::string::ToString; +use alloc::vec::{self, Vec}; +use core::fmt; +use core::slice; +use core::str::FromStr; +use serde::de::{ + self, Deserialize, DeserializeSeed, EnumAccess, Expected, IntoDeserializer, MapAccess, + SeqAccess, Unexpected, VariantAccess, Visitor, +}; +use serde::forward_to_deserialize_any; + +#[cfg(feature = "arbitrary_precision")] +use crate::number::NumberFromString; + +impl<'de> Deserialize<'de> for Value { + #[inline] + fn deserialize(deserializer: D) -> Result + where + D: serde::Deserializer<'de>, + { + struct ValueVisitor; + + impl<'de> Visitor<'de> for ValueVisitor { + type Value = Value; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("any valid JSON value") + } + + #[inline] + fn visit_bool(self, value: bool) -> Result { + Ok(Value::Bool(value)) + } + + #[inline] + fn visit_i64(self, value: i64) -> Result { + Ok(Value::Number(value.into())) + } + + #[inline] + fn visit_u64(self, value: u64) -> Result { + Ok(Value::Number(value.into())) + } + + #[inline] + fn visit_f64(self, value: f64) -> Result { + Ok(Number::from_f64(value).map_or(Value::Null, Value::Number)) + } + + #[cfg(any(feature = "std", feature = "alloc"))] + #[inline] + fn visit_str(self, value: &str) -> Result + where + E: serde::de::Error, + { + self.visit_string(String::from(value)) + } + + #[cfg(any(feature = "std", feature = "alloc"))] + #[inline] + fn visit_string(self, value: String) -> Result { + Ok(Value::String(value)) + } + + #[inline] + fn visit_none(self) -> Result { + Ok(Value::Null) + } + + #[inline] + fn visit_some(self, deserializer: D) -> Result + where + D: serde::Deserializer<'de>, + { + Deserialize::deserialize(deserializer) + } + + #[inline] + fn visit_unit(self) -> Result { + Ok(Value::Null) + } + + #[inline] + fn visit_seq(self, mut visitor: V) -> Result + where + V: SeqAccess<'de>, + { + let mut vec = Vec::new(); + + while let Some(elem) = tri!(visitor.next_element()) { + vec.push(elem); + } + + Ok(Value::Array(vec)) + } + + #[cfg(any(feature = "std", feature = "alloc"))] + fn visit_map(self, mut visitor: V) -> Result + where + V: MapAccess<'de>, + { + match tri!(visitor.next_key_seed(KeyClassifier)) { + #[cfg(feature = "arbitrary_precision")] + Some(KeyClass::Number) => { + let number: NumberFromString = tri!(visitor.next_value()); + Ok(Value::Number(number.value)) + } + #[cfg(feature = "raw_value")] + Some(KeyClass::RawValue) => { + let value = tri!(visitor.next_value_seed(crate::raw::BoxedFromString)); + crate::from_str(value.get()).map_err(de::Error::custom) + } + Some(KeyClass::Map(first_key)) => { + let mut values = Map::new(); + + values.insert(first_key, tri!(visitor.next_value())); + while let Some((key, value)) = tri!(visitor.next_entry()) { + values.insert(key, value); + } + + Ok(Value::Object(values)) + } + None => Ok(Value::Object(Map::new())), + } + } + } + + deserializer.deserialize_any(ValueVisitor) + } +} + +impl FromStr for Value { + type Err = Error; + fn from_str(s: &str) -> Result { + super::super::de::from_str(s) + } +} + +macro_rules! deserialize_number { + ($method:ident) => { + #[cfg(not(feature = "arbitrary_precision"))] + fn $method(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + match self { + Value::Number(n) => n.deserialize_any(visitor), + _ => Err(self.invalid_type(&visitor)), + } + } + + #[cfg(feature = "arbitrary_precision")] + fn $method(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + match self { + Value::Number(n) => n.$method(visitor), + _ => self.deserialize_any(visitor), + } + } + }; +} + +fn visit_array<'de, V>(array: Vec, visitor: V) -> Result +where + V: Visitor<'de>, +{ + let len = array.len(); + let mut deserializer = SeqDeserializer::new(array); + let seq = tri!(visitor.visit_seq(&mut deserializer)); + let remaining = deserializer.iter.len(); + if remaining == 0 { + Ok(seq) + } else { + Err(serde::de::Error::invalid_length( + len, + &"fewer elements in array", + )) + } +} + +fn visit_object<'de, V>(object: Map, visitor: V) -> Result +where + V: Visitor<'de>, +{ + let len = object.len(); + let mut deserializer = MapDeserializer::new(object); + let map = tri!(visitor.visit_map(&mut deserializer)); + let remaining = deserializer.iter.len(); + if remaining == 0 { + Ok(map) + } else { + Err(serde::de::Error::invalid_length( + len, + &"fewer elements in map", + )) + } +} + +impl<'de> serde::Deserializer<'de> for Value { + type Error = Error; + + #[inline] + fn deserialize_any(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + match self { + Value::Null => visitor.visit_unit(), + Value::Bool(v) => visitor.visit_bool(v), + Value::Number(n) => n.deserialize_any(visitor), + #[cfg(any(feature = "std", feature = "alloc"))] + Value::String(v) => visitor.visit_string(v), + #[cfg(not(any(feature = "std", feature = "alloc")))] + Value::String(_) => unreachable!(), + Value::Array(v) => visit_array(v, visitor), + Value::Object(v) => visit_object(v, visitor), + } + } + + deserialize_number!(deserialize_i8); + deserialize_number!(deserialize_i16); + deserialize_number!(deserialize_i32); + deserialize_number!(deserialize_i64); + deserialize_number!(deserialize_i128); + deserialize_number!(deserialize_u8); + deserialize_number!(deserialize_u16); + deserialize_number!(deserialize_u32); + deserialize_number!(deserialize_u64); + deserialize_number!(deserialize_u128); + deserialize_number!(deserialize_f32); + deserialize_number!(deserialize_f64); + + #[inline] + fn deserialize_option(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + match self { + Value::Null => visitor.visit_none(), + _ => visitor.visit_some(self), + } + } + + #[inline] + fn deserialize_enum( + self, + _name: &str, + _variants: &'static [&'static str], + visitor: V, + ) -> Result + where + V: Visitor<'de>, + { + let (variant, value) = match self { + Value::Object(value) => { + let mut iter = value.into_iter(); + let (variant, value) = match iter.next() { + Some(v) => v, + None => { + return Err(serde::de::Error::invalid_value( + Unexpected::Map, + &"map with a single key", + )); + } + }; + // enums are encoded in json as maps with a single key:value pair + if iter.next().is_some() { + return Err(serde::de::Error::invalid_value( + Unexpected::Map, + &"map with a single key", + )); + } + (variant, Some(value)) + } + Value::String(variant) => (variant, None), + other => { + return Err(serde::de::Error::invalid_type( + other.unexpected(), + &"string or map", + )); + } + }; + + visitor.visit_enum(EnumDeserializer { variant, value }) + } + + #[inline] + fn deserialize_newtype_struct( + self, + name: &'static str, + visitor: V, + ) -> Result + where + V: Visitor<'de>, + { + #[cfg(feature = "raw_value")] + { + if name == crate::raw::TOKEN { + return visitor.visit_map(crate::raw::OwnedRawDeserializer { + raw_value: Some(self.to_string()), + }); + } + } + + let _ = name; + visitor.visit_newtype_struct(self) + } + + fn deserialize_bool(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + match self { + Value::Bool(v) => visitor.visit_bool(v), + _ => Err(self.invalid_type(&visitor)), + } + } + + fn deserialize_char(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + self.deserialize_string(visitor) + } + + fn deserialize_str(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + self.deserialize_string(visitor) + } + + fn deserialize_string(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + match self { + #[cfg(any(feature = "std", feature = "alloc"))] + Value::String(v) => visitor.visit_string(v), + _ => Err(self.invalid_type(&visitor)), + } + } + + fn deserialize_bytes(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + self.deserialize_byte_buf(visitor) + } + + fn deserialize_byte_buf(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + match self { + #[cfg(any(feature = "std", feature = "alloc"))] + Value::String(v) => visitor.visit_string(v), + Value::Array(v) => visit_array(v, visitor), + _ => Err(self.invalid_type(&visitor)), + } + } + + fn deserialize_unit(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + match self { + Value::Null => visitor.visit_unit(), + _ => Err(self.invalid_type(&visitor)), + } + } + + fn deserialize_unit_struct(self, _name: &'static str, visitor: V) -> Result + where + V: Visitor<'de>, + { + self.deserialize_unit(visitor) + } + + fn deserialize_seq(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + match self { + Value::Array(v) => visit_array(v, visitor), + _ => Err(self.invalid_type(&visitor)), + } + } + + fn deserialize_tuple(self, _len: usize, visitor: V) -> Result + where + V: Visitor<'de>, + { + self.deserialize_seq(visitor) + } + + fn deserialize_tuple_struct( + self, + _name: &'static str, + _len: usize, + visitor: V, + ) -> Result + where + V: Visitor<'de>, + { + self.deserialize_seq(visitor) + } + + fn deserialize_map(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + match self { + Value::Object(v) => visit_object(v, visitor), + _ => Err(self.invalid_type(&visitor)), + } + } + + fn deserialize_struct( + self, + _name: &'static str, + _fields: &'static [&'static str], + visitor: V, + ) -> Result + where + V: Visitor<'de>, + { + match self { + Value::Array(v) => visit_array(v, visitor), + Value::Object(v) => visit_object(v, visitor), + _ => Err(self.invalid_type(&visitor)), + } + } + + fn deserialize_identifier(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + self.deserialize_string(visitor) + } + + fn deserialize_ignored_any(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + drop(self); + visitor.visit_unit() + } +} + +struct EnumDeserializer { + variant: String, + value: Option, +} + +impl<'de> EnumAccess<'de> for EnumDeserializer { + type Error = Error; + type Variant = VariantDeserializer; + + fn variant_seed(self, seed: V) -> Result<(V::Value, VariantDeserializer), Error> + where + V: DeserializeSeed<'de>, + { + let variant = self.variant.into_deserializer(); + let visitor = VariantDeserializer { value: self.value }; + seed.deserialize(variant).map(|v| (v, visitor)) + } +} + +impl<'de> IntoDeserializer<'de, Error> for Value { + type Deserializer = Self; + + fn into_deserializer(self) -> Self::Deserializer { + self + } +} + +impl<'de> IntoDeserializer<'de, Error> for &'de Value { + type Deserializer = Self; + + fn into_deserializer(self) -> Self::Deserializer { + self + } +} + +struct VariantDeserializer { + value: Option, +} + +impl<'de> VariantAccess<'de> for VariantDeserializer { + type Error = Error; + + fn unit_variant(self) -> Result<(), Error> { + match self.value { + Some(value) => Deserialize::deserialize(value), + None => Ok(()), + } + } + + fn newtype_variant_seed(self, seed: T) -> Result + where + T: DeserializeSeed<'de>, + { + match self.value { + Some(value) => seed.deserialize(value), + None => Err(serde::de::Error::invalid_type( + Unexpected::UnitVariant, + &"newtype variant", + )), + } + } + + fn tuple_variant(self, _len: usize, visitor: V) -> Result + where + V: Visitor<'de>, + { + match self.value { + Some(Value::Array(v)) => { + if v.is_empty() { + visitor.visit_unit() + } else { + visit_array(v, visitor) + } + } + Some(other) => Err(serde::de::Error::invalid_type( + other.unexpected(), + &"tuple variant", + )), + None => Err(serde::de::Error::invalid_type( + Unexpected::UnitVariant, + &"tuple variant", + )), + } + } + + fn struct_variant( + self, + _fields: &'static [&'static str], + visitor: V, + ) -> Result + where + V: Visitor<'de>, + { + match self.value { + Some(Value::Object(v)) => visit_object(v, visitor), + Some(other) => Err(serde::de::Error::invalid_type( + other.unexpected(), + &"struct variant", + )), + None => Err(serde::de::Error::invalid_type( + Unexpected::UnitVariant, + &"struct variant", + )), + } + } +} + +struct SeqDeserializer { + iter: vec::IntoIter, +} + +impl SeqDeserializer { + fn new(vec: Vec) -> Self { + SeqDeserializer { + iter: vec.into_iter(), + } + } +} + +impl<'de> SeqAccess<'de> for SeqDeserializer { + type Error = Error; + + fn next_element_seed(&mut self, seed: T) -> Result, Error> + where + T: DeserializeSeed<'de>, + { + match self.iter.next() { + Some(value) => seed.deserialize(value).map(Some), + None => Ok(None), + } + } + + fn size_hint(&self) -> Option { + match self.iter.size_hint() { + (lower, Some(upper)) if lower == upper => Some(upper), + _ => None, + } + } +} + +struct MapDeserializer { + iter: as IntoIterator>::IntoIter, + value: Option, +} + +impl MapDeserializer { + fn new(map: Map) -> Self { + MapDeserializer { + iter: map.into_iter(), + value: None, + } + } +} + +impl<'de> MapAccess<'de> for MapDeserializer { + type Error = Error; + + fn next_key_seed(&mut self, seed: T) -> Result, Error> + where + T: DeserializeSeed<'de>, + { + match self.iter.next() { + Some((key, value)) => { + self.value = Some(value); + let key_de = MapKeyDeserializer { + key: Cow::Owned(key), + }; + seed.deserialize(key_de).map(Some) + } + None => Ok(None), + } + } + + fn next_value_seed(&mut self, seed: T) -> Result + where + T: DeserializeSeed<'de>, + { + match self.value.take() { + Some(value) => seed.deserialize(value), + None => Err(serde::de::Error::custom("value is missing")), + } + } + + fn size_hint(&self) -> Option { + match self.iter.size_hint() { + (lower, Some(upper)) if lower == upper => Some(upper), + _ => None, + } + } +} + +macro_rules! deserialize_value_ref_number { + ($method:ident) => { + #[cfg(not(feature = "arbitrary_precision"))] + fn $method(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + match self { + Value::Number(n) => n.deserialize_any(visitor), + _ => Err(self.invalid_type(&visitor)), + } + } + + #[cfg(feature = "arbitrary_precision")] + fn $method(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + match self { + Value::Number(n) => n.$method(visitor), + _ => self.deserialize_any(visitor), + } + } + }; +} + +fn visit_array_ref<'de, V>(array: &'de [Value], visitor: V) -> Result +where + V: Visitor<'de>, +{ + let len = array.len(); + let mut deserializer = SeqRefDeserializer::new(array); + let seq = tri!(visitor.visit_seq(&mut deserializer)); + let remaining = deserializer.iter.len(); + if remaining == 0 { + Ok(seq) + } else { + Err(serde::de::Error::invalid_length( + len, + &"fewer elements in array", + )) + } +} + +fn visit_object_ref<'de, V>(object: &'de Map, visitor: V) -> Result +where + V: Visitor<'de>, +{ + let len = object.len(); + let mut deserializer = MapRefDeserializer::new(object); + let map = tri!(visitor.visit_map(&mut deserializer)); + let remaining = deserializer.iter.len(); + if remaining == 0 { + Ok(map) + } else { + Err(serde::de::Error::invalid_length( + len, + &"fewer elements in map", + )) + } +} + +impl<'de> serde::Deserializer<'de> for &'de Value { + type Error = Error; + + fn deserialize_any(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + match self { + Value::Null => visitor.visit_unit(), + Value::Bool(v) => visitor.visit_bool(*v), + Value::Number(n) => n.deserialize_any(visitor), + Value::String(v) => visitor.visit_borrowed_str(v), + Value::Array(v) => visit_array_ref(v, visitor), + Value::Object(v) => visit_object_ref(v, visitor), + } + } + + deserialize_value_ref_number!(deserialize_i8); + deserialize_value_ref_number!(deserialize_i16); + deserialize_value_ref_number!(deserialize_i32); + deserialize_value_ref_number!(deserialize_i64); + deserialize_number!(deserialize_i128); + deserialize_value_ref_number!(deserialize_u8); + deserialize_value_ref_number!(deserialize_u16); + deserialize_value_ref_number!(deserialize_u32); + deserialize_value_ref_number!(deserialize_u64); + deserialize_number!(deserialize_u128); + deserialize_value_ref_number!(deserialize_f32); + deserialize_value_ref_number!(deserialize_f64); + + fn deserialize_option(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + match *self { + Value::Null => visitor.visit_none(), + _ => visitor.visit_some(self), + } + } + + fn deserialize_enum( + self, + _name: &str, + _variants: &'static [&'static str], + visitor: V, + ) -> Result + where + V: Visitor<'de>, + { + let (variant, value) = match self { + Value::Object(value) => { + let mut iter = value.into_iter(); + let (variant, value) = match iter.next() { + Some(v) => v, + None => { + return Err(serde::de::Error::invalid_value( + Unexpected::Map, + &"map with a single key", + )); + } + }; + // enums are encoded in json as maps with a single key:value pair + if iter.next().is_some() { + return Err(serde::de::Error::invalid_value( + Unexpected::Map, + &"map with a single key", + )); + } + (variant, Some(value)) + } + Value::String(variant) => (variant, None), + other => { + return Err(serde::de::Error::invalid_type( + other.unexpected(), + &"string or map", + )); + } + }; + + visitor.visit_enum(EnumRefDeserializer { variant, value }) + } + + #[inline] + fn deserialize_newtype_struct( + self, + name: &'static str, + visitor: V, + ) -> Result + where + V: Visitor<'de>, + { + #[cfg(feature = "raw_value")] + { + if name == crate::raw::TOKEN { + return visitor.visit_map(crate::raw::OwnedRawDeserializer { + raw_value: Some(self.to_string()), + }); + } + } + + let _ = name; + visitor.visit_newtype_struct(self) + } + + fn deserialize_bool(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + match *self { + Value::Bool(v) => visitor.visit_bool(v), + _ => Err(self.invalid_type(&visitor)), + } + } + + fn deserialize_char(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + self.deserialize_str(visitor) + } + + fn deserialize_str(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + match self { + Value::String(v) => visitor.visit_borrowed_str(v), + _ => Err(self.invalid_type(&visitor)), + } + } + + fn deserialize_string(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + self.deserialize_str(visitor) + } + + fn deserialize_bytes(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + match self { + Value::String(v) => visitor.visit_borrowed_str(v), + Value::Array(v) => visit_array_ref(v, visitor), + _ => Err(self.invalid_type(&visitor)), + } + } + + fn deserialize_byte_buf(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + self.deserialize_bytes(visitor) + } + + fn deserialize_unit(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + match *self { + Value::Null => visitor.visit_unit(), + _ => Err(self.invalid_type(&visitor)), + } + } + + fn deserialize_unit_struct(self, _name: &'static str, visitor: V) -> Result + where + V: Visitor<'de>, + { + self.deserialize_unit(visitor) + } + + fn deserialize_seq(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + match self { + Value::Array(v) => visit_array_ref(v, visitor), + _ => Err(self.invalid_type(&visitor)), + } + } + + fn deserialize_tuple(self, _len: usize, visitor: V) -> Result + where + V: Visitor<'de>, + { + self.deserialize_seq(visitor) + } + + fn deserialize_tuple_struct( + self, + _name: &'static str, + _len: usize, + visitor: V, + ) -> Result + where + V: Visitor<'de>, + { + self.deserialize_seq(visitor) + } + + fn deserialize_map(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + match self { + Value::Object(v) => visit_object_ref(v, visitor), + _ => Err(self.invalid_type(&visitor)), + } + } + + fn deserialize_struct( + self, + _name: &'static str, + _fields: &'static [&'static str], + visitor: V, + ) -> Result + where + V: Visitor<'de>, + { + match self { + Value::Array(v) => visit_array_ref(v, visitor), + Value::Object(v) => visit_object_ref(v, visitor), + _ => Err(self.invalid_type(&visitor)), + } + } + + fn deserialize_identifier(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + self.deserialize_str(visitor) + } + + fn deserialize_ignored_any(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + visitor.visit_unit() + } +} + +struct EnumRefDeserializer<'de> { + variant: &'de str, + value: Option<&'de Value>, +} + +impl<'de> EnumAccess<'de> for EnumRefDeserializer<'de> { + type Error = Error; + type Variant = VariantRefDeserializer<'de>; + + fn variant_seed(self, seed: V) -> Result<(V::Value, Self::Variant), Error> + where + V: DeserializeSeed<'de>, + { + let variant = self.variant.into_deserializer(); + let visitor = VariantRefDeserializer { value: self.value }; + seed.deserialize(variant).map(|v| (v, visitor)) + } +} + +struct VariantRefDeserializer<'de> { + value: Option<&'de Value>, +} + +impl<'de> VariantAccess<'de> for VariantRefDeserializer<'de> { + type Error = Error; + + fn unit_variant(self) -> Result<(), Error> { + match self.value { + Some(value) => Deserialize::deserialize(value), + None => Ok(()), + } + } + + fn newtype_variant_seed(self, seed: T) -> Result + where + T: DeserializeSeed<'de>, + { + match self.value { + Some(value) => seed.deserialize(value), + None => Err(serde::de::Error::invalid_type( + Unexpected::UnitVariant, + &"newtype variant", + )), + } + } + + fn tuple_variant(self, _len: usize, visitor: V) -> Result + where + V: Visitor<'de>, + { + match self.value { + Some(Value::Array(v)) => { + if v.is_empty() { + visitor.visit_unit() + } else { + visit_array_ref(v, visitor) + } + } + Some(other) => Err(serde::de::Error::invalid_type( + other.unexpected(), + &"tuple variant", + )), + None => Err(serde::de::Error::invalid_type( + Unexpected::UnitVariant, + &"tuple variant", + )), + } + } + + fn struct_variant( + self, + _fields: &'static [&'static str], + visitor: V, + ) -> Result + where + V: Visitor<'de>, + { + match self.value { + Some(Value::Object(v)) => visit_object_ref(v, visitor), + Some(other) => Err(serde::de::Error::invalid_type( + other.unexpected(), + &"struct variant", + )), + None => Err(serde::de::Error::invalid_type( + Unexpected::UnitVariant, + &"struct variant", + )), + } + } +} + +struct SeqRefDeserializer<'de> { + iter: slice::Iter<'de, Value>, +} + +impl<'de> SeqRefDeserializer<'de> { + fn new(slice: &'de [Value]) -> Self { + SeqRefDeserializer { iter: slice.iter() } + } +} + +impl<'de> SeqAccess<'de> for SeqRefDeserializer<'de> { + type Error = Error; + + fn next_element_seed(&mut self, seed: T) -> Result, Error> + where + T: DeserializeSeed<'de>, + { + match self.iter.next() { + Some(value) => seed.deserialize(value).map(Some), + None => Ok(None), + } + } + + fn size_hint(&self) -> Option { + match self.iter.size_hint() { + (lower, Some(upper)) if lower == upper => Some(upper), + _ => None, + } + } +} + +struct MapRefDeserializer<'de> { + iter: <&'de Map as IntoIterator>::IntoIter, + value: Option<&'de Value>, +} + +impl<'de> MapRefDeserializer<'de> { + fn new(map: &'de Map) -> Self { + MapRefDeserializer { + iter: map.into_iter(), + value: None, + } + } +} + +impl<'de> MapAccess<'de> for MapRefDeserializer<'de> { + type Error = Error; + + fn next_key_seed(&mut self, seed: T) -> Result, Error> + where + T: DeserializeSeed<'de>, + { + match self.iter.next() { + Some((key, value)) => { + self.value = Some(value); + let key_de = MapKeyDeserializer { + key: Cow::Borrowed(&**key), + }; + seed.deserialize(key_de).map(Some) + } + None => Ok(None), + } + } + + fn next_value_seed(&mut self, seed: T) -> Result + where + T: DeserializeSeed<'de>, + { + match self.value.take() { + Some(value) => seed.deserialize(value), + None => Err(serde::de::Error::custom("value is missing")), + } + } + + fn size_hint(&self) -> Option { + match self.iter.size_hint() { + (lower, Some(upper)) if lower == upper => Some(upper), + _ => None, + } + } +} + +struct MapKeyDeserializer<'de> { + key: Cow<'de, str>, +} + +macro_rules! deserialize_numeric_key { + ($method:ident) => { + deserialize_numeric_key!($method, deserialize_number); + }; + + ($method:ident, $using:ident) => { + fn $method(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + let mut de = crate::Deserializer::from_str(&self.key); + + match tri!(de.peek()) { + Some(b'0'..=b'9' | b'-') => {} + _ => return Err(Error::syntax(ErrorCode::ExpectedNumericKey, 0, 0)), + } + + let number = tri!(de.$using(visitor)); + + if tri!(de.peek()).is_some() { + return Err(Error::syntax(ErrorCode::ExpectedNumericKey, 0, 0)); + } + + Ok(number) + } + }; +} + +impl<'de> serde::Deserializer<'de> for MapKeyDeserializer<'de> { + type Error = Error; + + fn deserialize_any(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + BorrowedCowStrDeserializer::new(self.key).deserialize_any(visitor) + } + + deserialize_numeric_key!(deserialize_i8); + deserialize_numeric_key!(deserialize_i16); + deserialize_numeric_key!(deserialize_i32); + deserialize_numeric_key!(deserialize_i64); + deserialize_numeric_key!(deserialize_u8); + deserialize_numeric_key!(deserialize_u16); + deserialize_numeric_key!(deserialize_u32); + deserialize_numeric_key!(deserialize_u64); + #[cfg(not(feature = "float_roundtrip"))] + deserialize_numeric_key!(deserialize_f32); + deserialize_numeric_key!(deserialize_f64); + + #[cfg(feature = "float_roundtrip")] + deserialize_numeric_key!(deserialize_f32, do_deserialize_f32); + deserialize_numeric_key!(deserialize_i128, do_deserialize_i128); + deserialize_numeric_key!(deserialize_u128, do_deserialize_u128); + + fn deserialize_bool(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + if self.key == "true" { + visitor.visit_bool(true) + } else if self.key == "false" { + visitor.visit_bool(false) + } else { + Err(serde::de::Error::invalid_type( + Unexpected::Str(&self.key), + &visitor, + )) + } + } + + #[inline] + fn deserialize_option(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + // Map keys cannot be null. + visitor.visit_some(self) + } + + #[inline] + fn deserialize_newtype_struct( + self, + _name: &'static str, + visitor: V, + ) -> Result + where + V: Visitor<'de>, + { + visitor.visit_newtype_struct(self) + } + + fn deserialize_enum( + self, + name: &'static str, + variants: &'static [&'static str], + visitor: V, + ) -> Result + where + V: Visitor<'de>, + { + self.key + .into_deserializer() + .deserialize_enum(name, variants, visitor) + } + + forward_to_deserialize_any! { + char str string bytes byte_buf unit unit_struct seq tuple tuple_struct + map struct identifier ignored_any + } +} + +struct KeyClassifier; + +enum KeyClass { + Map(String), + #[cfg(feature = "arbitrary_precision")] + Number, + #[cfg(feature = "raw_value")] + RawValue, +} + +impl<'de> DeserializeSeed<'de> for KeyClassifier { + type Value = KeyClass; + + fn deserialize(self, deserializer: D) -> Result + where + D: serde::Deserializer<'de>, + { + deserializer.deserialize_str(self) + } +} + +impl<'de> Visitor<'de> for KeyClassifier { + type Value = KeyClass; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("a string key") + } + + fn visit_str(self, s: &str) -> Result + where + E: de::Error, + { + match s { + #[cfg(feature = "arbitrary_precision")] + crate::number::TOKEN => Ok(KeyClass::Number), + #[cfg(feature = "raw_value")] + crate::raw::TOKEN => Ok(KeyClass::RawValue), + _ => Ok(KeyClass::Map(s.to_owned())), + } + } + + #[cfg(any(feature = "std", feature = "alloc"))] + fn visit_string(self, s: String) -> Result + where + E: de::Error, + { + match s.as_str() { + #[cfg(feature = "arbitrary_precision")] + crate::number::TOKEN => Ok(KeyClass::Number), + #[cfg(feature = "raw_value")] + crate::raw::TOKEN => Ok(KeyClass::RawValue), + _ => Ok(KeyClass::Map(s)), + } + } +} + +impl Value { + #[cold] + fn invalid_type(&self, exp: &dyn Expected) -> E + where + E: serde::de::Error, + { + serde::de::Error::invalid_type(self.unexpected(), exp) + } + + #[cold] + fn unexpected(&self) -> Unexpected { + match self { + Value::Null => Unexpected::Unit, + Value::Bool(b) => Unexpected::Bool(*b), + Value::Number(n) => n.unexpected(), + Value::String(s) => Unexpected::Str(s), + Value::Array(_) => Unexpected::Seq, + Value::Object(_) => Unexpected::Map, + } + } +} + +struct BorrowedCowStrDeserializer<'de> { + value: Cow<'de, str>, +} + +impl<'de> BorrowedCowStrDeserializer<'de> { + fn new(value: Cow<'de, str>) -> Self { + BorrowedCowStrDeserializer { value } + } +} + +impl<'de> de::Deserializer<'de> for BorrowedCowStrDeserializer<'de> { + type Error = Error; + + fn deserialize_any(self, visitor: V) -> Result + where + V: de::Visitor<'de>, + { + match self.value { + Cow::Borrowed(string) => visitor.visit_borrowed_str(string), + #[cfg(any(feature = "std", feature = "alloc"))] + Cow::Owned(string) => visitor.visit_string(string), + #[cfg(not(any(feature = "std", feature = "alloc")))] + Cow::Owned(_) => unreachable!(), + } + } + + fn deserialize_enum( + self, + _name: &str, + _variants: &'static [&'static str], + visitor: V, + ) -> Result + where + V: de::Visitor<'de>, + { + visitor.visit_enum(self) + } + + forward_to_deserialize_any! { + bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string + bytes byte_buf option unit unit_struct newtype_struct seq tuple + tuple_struct map struct identifier ignored_any + } +} + +impl<'de> de::EnumAccess<'de> for BorrowedCowStrDeserializer<'de> { + type Error = Error; + type Variant = UnitOnly; + + fn variant_seed(self, seed: T) -> Result<(T::Value, Self::Variant), Error> + where + T: de::DeserializeSeed<'de>, + { + let value = tri!(seed.deserialize(self)); + Ok((value, UnitOnly)) + } +} + +struct UnitOnly; + +impl<'de> de::VariantAccess<'de> for UnitOnly { + type Error = Error; + + fn unit_variant(self) -> Result<(), Error> { + Ok(()) + } + + fn newtype_variant_seed(self, _seed: T) -> Result + where + T: de::DeserializeSeed<'de>, + { + Err(de::Error::invalid_type( + Unexpected::UnitVariant, + &"newtype variant", + )) + } + + fn tuple_variant(self, _len: usize, _visitor: V) -> Result + where + V: de::Visitor<'de>, + { + Err(de::Error::invalid_type( + Unexpected::UnitVariant, + &"tuple variant", + )) + } + + fn struct_variant( + self, + _fields: &'static [&'static str], + _visitor: V, + ) -> Result + where + V: de::Visitor<'de>, + { + Err(de::Error::invalid_type( + Unexpected::UnitVariant, + &"struct variant", + )) + } +} diff --git a/vendor/serde_json/src/value/from.rs b/vendor/serde_json/src/value/from.rs new file mode 100644 index 0000000..2dae925 --- /dev/null +++ b/vendor/serde_json/src/value/from.rs @@ -0,0 +1,278 @@ +use super::Value; +use crate::map::Map; +use crate::number::Number; +use alloc::borrow::{Cow, ToOwned}; +use alloc::string::String; +use alloc::vec::Vec; + +macro_rules! from_integer { + ($($ty:ident)*) => { + $( + impl From<$ty> for Value { + fn from(n: $ty) -> Self { + Value::Number(n.into()) + } + } + )* + }; +} + +from_integer! { + i8 i16 i32 i64 isize + u8 u16 u32 u64 usize +} + +#[cfg(feature = "arbitrary_precision")] +from_integer! { + i128 u128 +} + +impl From for Value { + /// Convert 32-bit floating point number to `Value::Number`, or + /// `Value::Null` if infinite or NaN. + /// + /// # Examples + /// + /// ``` + /// use serde_json::Value; + /// + /// let f: f32 = 13.37; + /// let x: Value = f.into(); + /// ``` + fn from(f: f32) -> Self { + Number::from_f32(f).map_or(Value::Null, Value::Number) + } +} + +impl From for Value { + /// Convert 64-bit floating point number to `Value::Number`, or + /// `Value::Null` if infinite or NaN. + /// + /// # Examples + /// + /// ``` + /// use serde_json::Value; + /// + /// let f: f64 = 13.37; + /// let x: Value = f.into(); + /// ``` + fn from(f: f64) -> Self { + Number::from_f64(f).map_or(Value::Null, Value::Number) + } +} + +impl From for Value { + /// Convert boolean to `Value::Bool`. + /// + /// # Examples + /// + /// ``` + /// use serde_json::Value; + /// + /// let b = false; + /// let x: Value = b.into(); + /// ``` + fn from(f: bool) -> Self { + Value::Bool(f) + } +} + +impl From for Value { + /// Convert `String` to `Value::String`. + /// + /// # Examples + /// + /// ``` + /// use serde_json::Value; + /// + /// let s: String = "lorem".to_owned(); + /// let x: Value = s.into(); + /// ``` + fn from(f: String) -> Self { + Value::String(f) + } +} + +impl From<&str> for Value { + /// Convert string slice to `Value::String`. + /// + /// # Examples + /// + /// ``` + /// use serde_json::Value; + /// + /// let s: &str = "lorem"; + /// let x: Value = s.into(); + /// ``` + fn from(f: &str) -> Self { + Value::String(f.to_owned()) + } +} + +impl<'a> From> for Value { + /// Convert copy-on-write string to `Value::String`. + /// + /// # Examples + /// + /// ``` + /// use serde_json::Value; + /// use std::borrow::Cow; + /// + /// let s: Cow = Cow::Borrowed("lorem"); + /// let x: Value = s.into(); + /// ``` + /// + /// ``` + /// use serde_json::Value; + /// use std::borrow::Cow; + /// + /// let s: Cow = Cow::Owned("lorem".to_owned()); + /// let x: Value = s.into(); + /// ``` + fn from(f: Cow<'a, str>) -> Self { + Value::String(f.into_owned()) + } +} + +impl From for Value { + /// Convert `Number` to `Value::Number`. + /// + /// # Examples + /// + /// ``` + /// use serde_json::{Number, Value}; + /// + /// let n = Number::from(7); + /// let x: Value = n.into(); + /// ``` + fn from(f: Number) -> Self { + Value::Number(f) + } +} + +impl From> for Value { + /// Convert map (with string keys) to `Value::Object`. + /// + /// # Examples + /// + /// ``` + /// use serde_json::{Map, Value}; + /// + /// let mut m = Map::new(); + /// m.insert("Lorem".to_owned(), "ipsum".into()); + /// let x: Value = m.into(); + /// ``` + fn from(f: Map) -> Self { + Value::Object(f) + } +} + +impl> From> for Value { + /// Convert a `Vec` to `Value::Array`. + /// + /// # Examples + /// + /// ``` + /// use serde_json::Value; + /// + /// let v = vec!["lorem", "ipsum", "dolor"]; + /// let x: Value = v.into(); + /// ``` + fn from(f: Vec) -> Self { + Value::Array(f.into_iter().map(Into::into).collect()) + } +} + +impl> From<&[T]> for Value { + /// Convert a slice to `Value::Array`. + /// + /// # Examples + /// + /// ``` + /// use serde_json::Value; + /// + /// let v: &[&str] = &["lorem", "ipsum", "dolor"]; + /// let x: Value = v.into(); + /// ``` + fn from(f: &[T]) -> Self { + Value::Array(f.iter().cloned().map(Into::into).collect()) + } +} + +impl> FromIterator for Value { + /// Create a `Value::Array` by collecting an iterator of array elements. + /// + /// # Examples + /// + /// ``` + /// use serde_json::Value; + /// + /// let v = std::iter::repeat(42).take(5); + /// let x: Value = v.collect(); + /// ``` + /// + /// ``` + /// use serde_json::Value; + /// + /// let v: Vec<_> = vec!["lorem", "ipsum", "dolor"]; + /// let x: Value = v.into_iter().collect(); + /// ``` + /// + /// ``` + /// use std::iter::FromIterator; + /// use serde_json::Value; + /// + /// let x: Value = Value::from_iter(vec!["lorem", "ipsum", "dolor"]); + /// ``` + fn from_iter>(iter: I) -> Self { + Value::Array(iter.into_iter().map(Into::into).collect()) + } +} + +impl, V: Into> FromIterator<(K, V)> for Value { + /// Create a `Value::Object` by collecting an iterator of key-value pairs. + /// + /// # Examples + /// + /// ``` + /// use serde_json::Value; + /// + /// let v: Vec<_> = vec![("lorem", 40), ("ipsum", 2)]; + /// let x: Value = v.into_iter().collect(); + /// ``` + fn from_iter>(iter: I) -> Self { + Value::Object( + iter.into_iter() + .map(|(k, v)| (k.into(), v.into())) + .collect(), + ) + } +} + +impl From<()> for Value { + /// Convert `()` to `Value::Null`. + /// + /// # Examples + /// + /// ``` + /// use serde_json::Value; + /// + /// let u = (); + /// let x: Value = u.into(); + /// ``` + fn from((): ()) -> Self { + Value::Null + } +} + +impl From> for Value +where + T: Into, +{ + fn from(opt: Option) -> Self { + match opt { + None => Value::Null, + Some(value) => Into::into(value), + } + } +} diff --git a/vendor/serde_json/src/value/index.rs b/vendor/serde_json/src/value/index.rs new file mode 100644 index 0000000..4e41a39 --- /dev/null +++ b/vendor/serde_json/src/value/index.rs @@ -0,0 +1,258 @@ +use super::Value; +use crate::map::Map; +use alloc::borrow::ToOwned; +use alloc::string::String; +use core::fmt::{self, Display}; +use core::ops; + +/// A type that can be used to index into a `serde_json::Value`. +/// +/// The [`get`] and [`get_mut`] methods of `Value` accept any type that +/// implements `Index`, as does the [square-bracket indexing operator]. This +/// trait is implemented for strings which are used as the index into a JSON +/// map, and for `usize` which is used as the index into a JSON array. +/// +/// [`get`]: ../enum.Value.html#method.get +/// [`get_mut`]: ../enum.Value.html#method.get_mut +/// [square-bracket indexing operator]: ../enum.Value.html#impl-Index%3CI%3E-for-Value +/// +/// This trait is sealed and cannot be implemented for types outside of +/// `serde_json`. +/// +/// # Examples +/// +/// ``` +/// # use serde_json::json; +/// # +/// let data = json!({ "inner": [1, 2, 3] }); +/// +/// // Data is a JSON map so it can be indexed with a string. +/// let inner = &data["inner"]; +/// +/// // Inner is a JSON array so it can be indexed with an integer. +/// let first = &inner[0]; +/// +/// assert_eq!(first, 1); +/// ``` +pub trait Index: private::Sealed { + /// Return None if the key is not already in the array or object. + #[doc(hidden)] + fn index_into<'v>(&self, v: &'v Value) -> Option<&'v Value>; + + /// Return None if the key is not already in the array or object. + #[doc(hidden)] + fn index_into_mut<'v>(&self, v: &'v mut Value) -> Option<&'v mut Value>; + + /// Panic if array index out of bounds. If key is not already in the object, + /// insert it with a value of null. Panic if Value is a type that cannot be + /// indexed into, except if Value is null then it can be treated as an empty + /// object. + #[doc(hidden)] + fn index_or_insert<'v>(&self, v: &'v mut Value) -> &'v mut Value; +} + +impl Index for usize { + fn index_into<'v>(&self, v: &'v Value) -> Option<&'v Value> { + match v { + Value::Array(vec) => vec.get(*self), + _ => None, + } + } + fn index_into_mut<'v>(&self, v: &'v mut Value) -> Option<&'v mut Value> { + match v { + Value::Array(vec) => vec.get_mut(*self), + _ => None, + } + } + fn index_or_insert<'v>(&self, v: &'v mut Value) -> &'v mut Value { + match v { + Value::Array(vec) => { + let len = vec.len(); + vec.get_mut(*self).unwrap_or_else(|| { + panic!( + "cannot access index {} of JSON array of length {}", + self, len + ) + }) + } + _ => panic!("cannot access index {} of JSON {}", self, Type(v)), + } + } +} + +impl Index for str { + fn index_into<'v>(&self, v: &'v Value) -> Option<&'v Value> { + match v { + Value::Object(map) => map.get(self), + _ => None, + } + } + fn index_into_mut<'v>(&self, v: &'v mut Value) -> Option<&'v mut Value> { + match v { + Value::Object(map) => map.get_mut(self), + _ => None, + } + } + fn index_or_insert<'v>(&self, v: &'v mut Value) -> &'v mut Value { + if let Value::Null = v { + *v = Value::Object(Map::new()); + } + match v { + Value::Object(map) => map.entry(self.to_owned()).or_insert(Value::Null), + _ => panic!("cannot access key {:?} in JSON {}", self, Type(v)), + } + } +} + +impl Index for String { + fn index_into<'v>(&self, v: &'v Value) -> Option<&'v Value> { + self[..].index_into(v) + } + fn index_into_mut<'v>(&self, v: &'v mut Value) -> Option<&'v mut Value> { + self[..].index_into_mut(v) + } + fn index_or_insert<'v>(&self, v: &'v mut Value) -> &'v mut Value { + self[..].index_or_insert(v) + } +} + +impl Index for &T +where + T: ?Sized + Index, +{ + fn index_into<'v>(&self, v: &'v Value) -> Option<&'v Value> { + (**self).index_into(v) + } + fn index_into_mut<'v>(&self, v: &'v mut Value) -> Option<&'v mut Value> { + (**self).index_into_mut(v) + } + fn index_or_insert<'v>(&self, v: &'v mut Value) -> &'v mut Value { + (**self).index_or_insert(v) + } +} + +// Prevent users from implementing the Index trait. +mod private { + pub trait Sealed {} + impl Sealed for usize {} + impl Sealed for str {} + impl Sealed for alloc::string::String {} + impl Sealed for &T where T: ?Sized + Sealed {} +} + +/// Used in panic messages. +struct Type<'a>(&'a Value); + +impl<'a> Display for Type<'a> { + fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + match *self.0 { + Value::Null => formatter.write_str("null"), + Value::Bool(_) => formatter.write_str("boolean"), + Value::Number(_) => formatter.write_str("number"), + Value::String(_) => formatter.write_str("string"), + Value::Array(_) => formatter.write_str("array"), + Value::Object(_) => formatter.write_str("object"), + } + } +} + +// The usual semantics of Index is to panic on invalid indexing. +// +// That said, the usual semantics are for things like Vec and BTreeMap which +// have different use cases than Value. If you are working with a Vec, you know +// that you are working with a Vec and you can get the len of the Vec and make +// sure your indices are within bounds. The Value use cases are more +// loosey-goosey. You got some JSON from an endpoint and you want to pull values +// out of it. Outside of this Index impl, you already have the option of using +// value.as_array() and working with the Vec directly, or matching on +// Value::Array and getting the Vec directly. The Index impl means you can skip +// that and index directly into the thing using a concise syntax. You don't have +// to check the type, you don't have to check the len, it is all about what you +// expect the Value to look like. +// +// Basically the use cases that would be well served by panicking here are +// better served by using one of the other approaches: get and get_mut, +// as_array, or match. The value of this impl is that it adds a way of working +// with Value that is not well served by the existing approaches: concise and +// careless and sometimes that is exactly what you want. +impl ops::Index for Value +where + I: Index, +{ + type Output = Value; + + /// Index into a `serde_json::Value` using the syntax `value[0]` or + /// `value["k"]`. + /// + /// Returns `Value::Null` if the type of `self` does not match the type of + /// the index, for example if the index is a string and `self` is an array + /// or a number. Also returns `Value::Null` if the given key does not exist + /// in the map or the given index is not within the bounds of the array. + /// + /// For retrieving deeply nested values, you should have a look at the + /// `Value::pointer` method. + /// + /// # Examples + /// + /// ``` + /// # use serde_json::json; + /// # + /// let data = json!({ + /// "x": { + /// "y": ["z", "zz"] + /// } + /// }); + /// + /// assert_eq!(data["x"]["y"], json!(["z", "zz"])); + /// assert_eq!(data["x"]["y"][0], json!("z")); + /// + /// assert_eq!(data["a"], json!(null)); // returns null for undefined values + /// assert_eq!(data["a"]["b"], json!(null)); // does not panic + /// ``` + fn index(&self, index: I) -> &Value { + static NULL: Value = Value::Null; + index.index_into(self).unwrap_or(&NULL) + } +} + +impl ops::IndexMut for Value +where + I: Index, +{ + /// Write into a `serde_json::Value` using the syntax `value[0] = ...` or + /// `value["k"] = ...`. + /// + /// If the index is a number, the value must be an array of length bigger + /// than the index. Indexing into a value that is not an array or an array + /// that is too small will panic. + /// + /// If the index is a string, the value must be an object or null which is + /// treated like an empty object. If the key is not already present in the + /// object, it will be inserted with a value of null. Indexing into a value + /// that is neither an object nor null will panic. + /// + /// # Examples + /// + /// ``` + /// # use serde_json::json; + /// # + /// let mut data = json!({ "x": 0 }); + /// + /// // replace an existing key + /// data["x"] = json!(1); + /// + /// // insert a new key + /// data["y"] = json!([false, false, false]); + /// + /// // replace an array value + /// data["y"][0] = json!(true); + /// + /// // inserted a deeply nested key + /// data["a"]["b"]["c"]["d"] = json!(true); + /// + /// println!("{}", data); + /// ``` + fn index_mut(&mut self, index: I) -> &mut Value { + index.index_or_insert(self) + } +} diff --git a/vendor/serde_json/src/value/mod.rs b/vendor/serde_json/src/value/mod.rs new file mode 100644 index 0000000..6b40f9a --- /dev/null +++ b/vendor/serde_json/src/value/mod.rs @@ -0,0 +1,1035 @@ +//! The Value enum, a loosely typed way of representing any valid JSON value. +//! +//! # Constructing JSON +//! +//! Serde JSON provides a [`json!` macro][macro] to build `serde_json::Value` +//! objects with very natural JSON syntax. +//! +//! ``` +//! use serde_json::json; +//! +//! fn main() { +//! // The type of `john` is `serde_json::Value` +//! let john = json!({ +//! "name": "John Doe", +//! "age": 43, +//! "phones": [ +//! "+44 1234567", +//! "+44 2345678" +//! ] +//! }); +//! +//! println!("first phone number: {}", john["phones"][0]); +//! +//! // Convert to a string of JSON and print it out +//! println!("{}", john.to_string()); +//! } +//! ``` +//! +//! The `Value::to_string()` function converts a `serde_json::Value` into a +//! `String` of JSON text. +//! +//! One neat thing about the `json!` macro is that variables and expressions can +//! be interpolated directly into the JSON value as you are building it. Serde +//! will check at compile time that the value you are interpolating is able to +//! be represented as JSON. +//! +//! ``` +//! # use serde_json::json; +//! # +//! # fn random_phone() -> u16 { 0 } +//! # +//! let full_name = "John Doe"; +//! let age_last_year = 42; +//! +//! // The type of `john` is `serde_json::Value` +//! let john = json!({ +//! "name": full_name, +//! "age": age_last_year + 1, +//! "phones": [ +//! format!("+44 {}", random_phone()) +//! ] +//! }); +//! ``` +//! +//! A string of JSON data can be parsed into a `serde_json::Value` by the +//! [`serde_json::from_str`][from_str] function. There is also +//! [`from_slice`][from_slice] for parsing from a byte slice `&[u8]` and +//! [`from_reader`][from_reader] for parsing from any `io::Read` like a File or +//! a TCP stream. +//! +//! ``` +//! use serde_json::{json, Value, Error}; +//! +//! fn untyped_example() -> Result<(), Error> { +//! // Some JSON input data as a &str. Maybe this comes from the user. +//! let data = r#" +//! { +//! "name": "John Doe", +//! "age": 43, +//! "phones": [ +//! "+44 1234567", +//! "+44 2345678" +//! ] +//! }"#; +//! +//! // Parse the string of data into serde_json::Value. +//! let v: Value = serde_json::from_str(data)?; +//! +//! // Access parts of the data by indexing with square brackets. +//! println!("Please call {} at the number {}", v["name"], v["phones"][0]); +//! +//! Ok(()) +//! } +//! # +//! # untyped_example().unwrap(); +//! ``` +//! +//! [macro]: crate::json +//! [from_str]: crate::de::from_str +//! [from_slice]: crate::de::from_slice +//! [from_reader]: crate::de::from_reader + +use crate::error::Error; +use crate::io; +use alloc::string::String; +use alloc::vec::Vec; +use core::fmt::{self, Debug, Display}; +use core::mem; +use core::str; +use serde::de::DeserializeOwned; +use serde::ser::Serialize; + +pub use self::index::Index; +pub use self::ser::Serializer; +pub use crate::map::Map; +pub use crate::number::Number; + +#[cfg(feature = "raw_value")] +#[cfg_attr(docsrs, doc(cfg(feature = "raw_value")))] +pub use crate::raw::{to_raw_value, RawValue}; + +/// Represents any valid JSON value. +/// +/// See the [`serde_json::value` module documentation](self) for usage examples. +#[derive(Clone, Eq, PartialEq, Hash)] +pub enum Value { + /// Represents a JSON null value. + /// + /// ``` + /// # use serde_json::json; + /// # + /// let v = json!(null); + /// ``` + Null, + + /// Represents a JSON boolean. + /// + /// ``` + /// # use serde_json::json; + /// # + /// let v = json!(true); + /// ``` + Bool(bool), + + /// Represents a JSON number, whether integer or floating point. + /// + /// ``` + /// # use serde_json::json; + /// # + /// let v = json!(12.5); + /// ``` + Number(Number), + + /// Represents a JSON string. + /// + /// ``` + /// # use serde_json::json; + /// # + /// let v = json!("a string"); + /// ``` + String(String), + + /// Represents a JSON array. + /// + /// ``` + /// # use serde_json::json; + /// # + /// let v = json!(["an", "array"]); + /// ``` + Array(Vec), + + /// Represents a JSON object. + /// + /// By default the map is backed by a BTreeMap. Enable the `preserve_order` + /// feature of serde_json to use IndexMap instead, which preserves + /// entries in the order they are inserted into the map. In particular, this + /// allows JSON data to be deserialized into a Value and serialized to a + /// string while retaining the order of map keys in the input. + /// + /// ``` + /// # use serde_json::json; + /// # + /// let v = json!({ "an": "object" }); + /// ``` + Object(Map), +} + +impl Debug for Value { + fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + match self { + Value::Null => formatter.write_str("Null"), + Value::Bool(boolean) => write!(formatter, "Bool({})", boolean), + Value::Number(number) => Debug::fmt(number, formatter), + Value::String(string) => write!(formatter, "String({:?})", string), + Value::Array(vec) => { + tri!(formatter.write_str("Array ")); + Debug::fmt(vec, formatter) + } + Value::Object(map) => { + tri!(formatter.write_str("Object ")); + Debug::fmt(map, formatter) + } + } + } +} + +impl Display for Value { + /// Display a JSON value as a string. + /// + /// ``` + /// # use serde_json::json; + /// # + /// let json = json!({ "city": "London", "street": "10 Downing Street" }); + /// + /// // Compact format: + /// // + /// // {"city":"London","street":"10 Downing Street"} + /// let compact = format!("{}", json); + /// assert_eq!(compact, + /// "{\"city\":\"London\",\"street\":\"10 Downing Street\"}"); + /// + /// // Pretty format: + /// // + /// // { + /// // "city": "London", + /// // "street": "10 Downing Street" + /// // } + /// let pretty = format!("{:#}", json); + /// assert_eq!(pretty, + /// "{\n \"city\": \"London\",\n \"street\": \"10 Downing Street\"\n}"); + /// ``` + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + struct WriterFormatter<'a, 'b: 'a> { + inner: &'a mut fmt::Formatter<'b>, + } + + impl<'a, 'b> io::Write for WriterFormatter<'a, 'b> { + fn write(&mut self, buf: &[u8]) -> io::Result { + // Safety: the serializer below only emits valid utf8 when using + // the default formatter. + let s = unsafe { str::from_utf8_unchecked(buf) }; + tri!(self.inner.write_str(s).map_err(io_error)); + Ok(buf.len()) + } + + fn flush(&mut self) -> io::Result<()> { + Ok(()) + } + } + + fn io_error(_: fmt::Error) -> io::Error { + // Error value does not matter because Display impl just maps it + // back to fmt::Error. + io::Error::new(io::ErrorKind::Other, "fmt error") + } + + let alternate = f.alternate(); + let mut wr = WriterFormatter { inner: f }; + if alternate { + // {:#} + super::ser::to_writer_pretty(&mut wr, self).map_err(|_| fmt::Error) + } else { + // {} + super::ser::to_writer(&mut wr, self).map_err(|_| fmt::Error) + } + } +} + +fn parse_index(s: &str) -> Option { + if s.starts_with('+') || (s.starts_with('0') && s.len() != 1) { + return None; + } + s.parse().ok() +} + +impl Value { + /// Index into a JSON array or map. A string index can be used to access a + /// value in a map, and a usize index can be used to access an element of an + /// array. + /// + /// Returns `None` if the type of `self` does not match the type of the + /// index, for example if the index is a string and `self` is an array or a + /// number. Also returns `None` if the given key does not exist in the map + /// or the given index is not within the bounds of the array. + /// + /// ``` + /// # use serde_json::json; + /// # + /// let object = json!({ "A": 65, "B": 66, "C": 67 }); + /// assert_eq!(*object.get("A").unwrap(), json!(65)); + /// + /// let array = json!([ "A", "B", "C" ]); + /// assert_eq!(*array.get(2).unwrap(), json!("C")); + /// + /// assert_eq!(array.get("A"), None); + /// ``` + /// + /// Square brackets can also be used to index into a value in a more concise + /// way. This returns `Value::Null` in cases where `get` would have returned + /// `None`. + /// + /// ``` + /// # use serde_json::json; + /// # + /// let object = json!({ + /// "A": ["a", "á", "à"], + /// "B": ["b", "b́"], + /// "C": ["c", "ć", "ć̣", "ḉ"], + /// }); + /// assert_eq!(object["B"][0], json!("b")); + /// + /// assert_eq!(object["D"], json!(null)); + /// assert_eq!(object[0]["x"]["y"]["z"], json!(null)); + /// ``` + pub fn get(&self, index: I) -> Option<&Value> { + index.index_into(self) + } + + /// Mutably index into a JSON array or map. A string index can be used to + /// access a value in a map, and a usize index can be used to access an + /// element of an array. + /// + /// Returns `None` if the type of `self` does not match the type of the + /// index, for example if the index is a string and `self` is an array or a + /// number. Also returns `None` if the given key does not exist in the map + /// or the given index is not within the bounds of the array. + /// + /// ``` + /// # use serde_json::json; + /// # + /// let mut object = json!({ "A": 65, "B": 66, "C": 67 }); + /// *object.get_mut("A").unwrap() = json!(69); + /// + /// let mut array = json!([ "A", "B", "C" ]); + /// *array.get_mut(2).unwrap() = json!("D"); + /// ``` + pub fn get_mut(&mut self, index: I) -> Option<&mut Value> { + index.index_into_mut(self) + } + + /// Returns true if the `Value` is an Object. Returns false otherwise. + /// + /// For any Value on which `is_object` returns true, `as_object` and + /// `as_object_mut` are guaranteed to return the map representation of the + /// object. + /// + /// ``` + /// # use serde_json::json; + /// # + /// let obj = json!({ "a": { "nested": true }, "b": ["an", "array"] }); + /// + /// assert!(obj.is_object()); + /// assert!(obj["a"].is_object()); + /// + /// // array, not an object + /// assert!(!obj["b"].is_object()); + /// ``` + pub fn is_object(&self) -> bool { + self.as_object().is_some() + } + + /// If the `Value` is an Object, returns the associated Map. Returns None + /// otherwise. + /// + /// ``` + /// # use serde_json::json; + /// # + /// let v = json!({ "a": { "nested": true }, "b": ["an", "array"] }); + /// + /// // The length of `{"nested": true}` is 1 entry. + /// assert_eq!(v["a"].as_object().unwrap().len(), 1); + /// + /// // The array `["an", "array"]` is not an object. + /// assert_eq!(v["b"].as_object(), None); + /// ``` + pub fn as_object(&self) -> Option<&Map> { + match self { + Value::Object(map) => Some(map), + _ => None, + } + } + + /// If the `Value` is an Object, returns the associated mutable Map. + /// Returns None otherwise. + /// + /// ``` + /// # use serde_json::json; + /// # + /// let mut v = json!({ "a": { "nested": true } }); + /// + /// v["a"].as_object_mut().unwrap().clear(); + /// assert_eq!(v, json!({ "a": {} })); + /// ``` + pub fn as_object_mut(&mut self) -> Option<&mut Map> { + match self { + Value::Object(map) => Some(map), + _ => None, + } + } + + /// Returns true if the `Value` is an Array. Returns false otherwise. + /// + /// For any Value on which `is_array` returns true, `as_array` and + /// `as_array_mut` are guaranteed to return the vector representing the + /// array. + /// + /// ``` + /// # use serde_json::json; + /// # + /// let obj = json!({ "a": ["an", "array"], "b": { "an": "object" } }); + /// + /// assert!(obj["a"].is_array()); + /// + /// // an object, not an array + /// assert!(!obj["b"].is_array()); + /// ``` + pub fn is_array(&self) -> bool { + self.as_array().is_some() + } + + /// If the `Value` is an Array, returns the associated vector. Returns None + /// otherwise. + /// + /// ``` + /// # use serde_json::json; + /// # + /// let v = json!({ "a": ["an", "array"], "b": { "an": "object" } }); + /// + /// // The length of `["an", "array"]` is 2 elements. + /// assert_eq!(v["a"].as_array().unwrap().len(), 2); + /// + /// // The object `{"an": "object"}` is not an array. + /// assert_eq!(v["b"].as_array(), None); + /// ``` + pub fn as_array(&self) -> Option<&Vec> { + match self { + Value::Array(array) => Some(array), + _ => None, + } + } + + /// If the `Value` is an Array, returns the associated mutable vector. + /// Returns None otherwise. + /// + /// ``` + /// # use serde_json::json; + /// # + /// let mut v = json!({ "a": ["an", "array"] }); + /// + /// v["a"].as_array_mut().unwrap().clear(); + /// assert_eq!(v, json!({ "a": [] })); + /// ``` + pub fn as_array_mut(&mut self) -> Option<&mut Vec> { + match self { + Value::Array(list) => Some(list), + _ => None, + } + } + + /// Returns true if the `Value` is a String. Returns false otherwise. + /// + /// For any Value on which `is_string` returns true, `as_str` is guaranteed + /// to return the string slice. + /// + /// ``` + /// # use serde_json::json; + /// # + /// let v = json!({ "a": "some string", "b": false }); + /// + /// assert!(v["a"].is_string()); + /// + /// // The boolean `false` is not a string. + /// assert!(!v["b"].is_string()); + /// ``` + pub fn is_string(&self) -> bool { + self.as_str().is_some() + } + + /// If the `Value` is a String, returns the associated str. Returns None + /// otherwise. + /// + /// ``` + /// # use serde_json::json; + /// # + /// let v = json!({ "a": "some string", "b": false }); + /// + /// assert_eq!(v["a"].as_str(), Some("some string")); + /// + /// // The boolean `false` is not a string. + /// assert_eq!(v["b"].as_str(), None); + /// + /// // JSON values are printed in JSON representation, so strings are in quotes. + /// // + /// // The value is: "some string" + /// println!("The value is: {}", v["a"]); + /// + /// // Rust strings are printed without quotes. + /// // + /// // The value is: some string + /// println!("The value is: {}", v["a"].as_str().unwrap()); + /// ``` + pub fn as_str(&self) -> Option<&str> { + match self { + Value::String(s) => Some(s), + _ => None, + } + } + + /// Returns true if the `Value` is a Number. Returns false otherwise. + /// + /// ``` + /// # use serde_json::json; + /// # + /// let v = json!({ "a": 1, "b": "2" }); + /// + /// assert!(v["a"].is_number()); + /// + /// // The string `"2"` is a string, not a number. + /// assert!(!v["b"].is_number()); + /// ``` + pub fn is_number(&self) -> bool { + match *self { + Value::Number(_) => true, + _ => false, + } + } + + /// If the `Value` is a Number, returns the associated [`Number`]. Returns + /// None otherwise. + /// + /// ``` + /// # use serde_json::{json, Number}; + /// # + /// let v = json!({ "a": 1, "b": 2.2, "c": -3, "d": "4" }); + /// + /// assert_eq!(v["a"].as_number(), Some(&Number::from(1u64))); + /// assert_eq!(v["b"].as_number(), Some(&Number::from_f64(2.2).unwrap())); + /// assert_eq!(v["c"].as_number(), Some(&Number::from(-3i64))); + /// + /// // The string `"4"` is not a number. + /// assert_eq!(v["d"].as_number(), None); + /// ``` + pub fn as_number(&self) -> Option<&Number> { + match self { + Value::Number(number) => Some(number), + _ => None, + } + } + + /// Returns true if the `Value` is an integer between `i64::MIN` and + /// `i64::MAX`. + /// + /// For any Value on which `is_i64` returns true, `as_i64` is guaranteed to + /// return the integer value. + /// + /// ``` + /// # use serde_json::json; + /// # + /// let big = i64::max_value() as u64 + 10; + /// let v = json!({ "a": 64, "b": big, "c": 256.0 }); + /// + /// assert!(v["a"].is_i64()); + /// + /// // Greater than i64::MAX. + /// assert!(!v["b"].is_i64()); + /// + /// // Numbers with a decimal point are not considered integers. + /// assert!(!v["c"].is_i64()); + /// ``` + pub fn is_i64(&self) -> bool { + match self { + Value::Number(n) => n.is_i64(), + _ => false, + } + } + + /// Returns true if the `Value` is an integer between zero and `u64::MAX`. + /// + /// For any Value on which `is_u64` returns true, `as_u64` is guaranteed to + /// return the integer value. + /// + /// ``` + /// # use serde_json::json; + /// # + /// let v = json!({ "a": 64, "b": -64, "c": 256.0 }); + /// + /// assert!(v["a"].is_u64()); + /// + /// // Negative integer. + /// assert!(!v["b"].is_u64()); + /// + /// // Numbers with a decimal point are not considered integers. + /// assert!(!v["c"].is_u64()); + /// ``` + pub fn is_u64(&self) -> bool { + match self { + Value::Number(n) => n.is_u64(), + _ => false, + } + } + + /// Returns true if the `Value` is a number that can be represented by f64. + /// + /// For any Value on which `is_f64` returns true, `as_f64` is guaranteed to + /// return the floating point value. + /// + /// Currently this function returns true if and only if both `is_i64` and + /// `is_u64` return false but this is not a guarantee in the future. + /// + /// ``` + /// # use serde_json::json; + /// # + /// let v = json!({ "a": 256.0, "b": 64, "c": -64 }); + /// + /// assert!(v["a"].is_f64()); + /// + /// // Integers. + /// assert!(!v["b"].is_f64()); + /// assert!(!v["c"].is_f64()); + /// ``` + pub fn is_f64(&self) -> bool { + match self { + Value::Number(n) => n.is_f64(), + _ => false, + } + } + + /// If the `Value` is an integer, represent it as i64 if possible. Returns + /// None otherwise. + /// + /// ``` + /// # use serde_json::json; + /// # + /// let big = i64::max_value() as u64 + 10; + /// let v = json!({ "a": 64, "b": big, "c": 256.0 }); + /// + /// assert_eq!(v["a"].as_i64(), Some(64)); + /// assert_eq!(v["b"].as_i64(), None); + /// assert_eq!(v["c"].as_i64(), None); + /// ``` + pub fn as_i64(&self) -> Option { + match self { + Value::Number(n) => n.as_i64(), + _ => None, + } + } + + /// If the `Value` is an integer, represent it as u64 if possible. Returns + /// None otherwise. + /// + /// ``` + /// # use serde_json::json; + /// # + /// let v = json!({ "a": 64, "b": -64, "c": 256.0 }); + /// + /// assert_eq!(v["a"].as_u64(), Some(64)); + /// assert_eq!(v["b"].as_u64(), None); + /// assert_eq!(v["c"].as_u64(), None); + /// ``` + pub fn as_u64(&self) -> Option { + match self { + Value::Number(n) => n.as_u64(), + _ => None, + } + } + + /// If the `Value` is a number, represent it as f64 if possible. Returns + /// None otherwise. + /// + /// ``` + /// # use serde_json::json; + /// # + /// let v = json!({ "a": 256.0, "b": 64, "c": -64 }); + /// + /// assert_eq!(v["a"].as_f64(), Some(256.0)); + /// assert_eq!(v["b"].as_f64(), Some(64.0)); + /// assert_eq!(v["c"].as_f64(), Some(-64.0)); + /// ``` + pub fn as_f64(&self) -> Option { + match self { + Value::Number(n) => n.as_f64(), + _ => None, + } + } + + /// Returns true if the `Value` is a Boolean. Returns false otherwise. + /// + /// For any Value on which `is_boolean` returns true, `as_bool` is + /// guaranteed to return the boolean value. + /// + /// ``` + /// # use serde_json::json; + /// # + /// let v = json!({ "a": false, "b": "false" }); + /// + /// assert!(v["a"].is_boolean()); + /// + /// // The string `"false"` is a string, not a boolean. + /// assert!(!v["b"].is_boolean()); + /// ``` + pub fn is_boolean(&self) -> bool { + self.as_bool().is_some() + } + + /// If the `Value` is a Boolean, returns the associated bool. Returns None + /// otherwise. + /// + /// ``` + /// # use serde_json::json; + /// # + /// let v = json!({ "a": false, "b": "false" }); + /// + /// assert_eq!(v["a"].as_bool(), Some(false)); + /// + /// // The string `"false"` is a string, not a boolean. + /// assert_eq!(v["b"].as_bool(), None); + /// ``` + pub fn as_bool(&self) -> Option { + match *self { + Value::Bool(b) => Some(b), + _ => None, + } + } + + /// Returns true if the `Value` is a Null. Returns false otherwise. + /// + /// For any Value on which `is_null` returns true, `as_null` is guaranteed + /// to return `Some(())`. + /// + /// ``` + /// # use serde_json::json; + /// # + /// let v = json!({ "a": null, "b": false }); + /// + /// assert!(v["a"].is_null()); + /// + /// // The boolean `false` is not null. + /// assert!(!v["b"].is_null()); + /// ``` + pub fn is_null(&self) -> bool { + self.as_null().is_some() + } + + /// If the `Value` is a Null, returns (). Returns None otherwise. + /// + /// ``` + /// # use serde_json::json; + /// # + /// let v = json!({ "a": null, "b": false }); + /// + /// assert_eq!(v["a"].as_null(), Some(())); + /// + /// // The boolean `false` is not null. + /// assert_eq!(v["b"].as_null(), None); + /// ``` + pub fn as_null(&self) -> Option<()> { + match *self { + Value::Null => Some(()), + _ => None, + } + } + + /// Looks up a value by a JSON Pointer. + /// + /// JSON Pointer defines a string syntax for identifying a specific value + /// within a JavaScript Object Notation (JSON) document. + /// + /// A Pointer is a Unicode string with the reference tokens separated by `/`. + /// Inside tokens `/` is replaced by `~1` and `~` is replaced by `~0`. The + /// addressed value is returned and if there is no such value `None` is + /// returned. + /// + /// For more information read [RFC6901](https://tools.ietf.org/html/rfc6901). + /// + /// # Examples + /// + /// ``` + /// # use serde_json::json; + /// # + /// let data = json!({ + /// "x": { + /// "y": ["z", "zz"] + /// } + /// }); + /// + /// assert_eq!(data.pointer("/x/y/1").unwrap(), &json!("zz")); + /// assert_eq!(data.pointer("/a/b/c"), None); + /// ``` + pub fn pointer(&self, pointer: &str) -> Option<&Value> { + if pointer.is_empty() { + return Some(self); + } + if !pointer.starts_with('/') { + return None; + } + pointer + .split('/') + .skip(1) + .map(|x| x.replace("~1", "/").replace("~0", "~")) + .try_fold(self, |target, token| match target { + Value::Object(map) => map.get(&token), + Value::Array(list) => parse_index(&token).and_then(|x| list.get(x)), + _ => None, + }) + } + + /// Looks up a value by a JSON Pointer and returns a mutable reference to + /// that value. + /// + /// JSON Pointer defines a string syntax for identifying a specific value + /// within a JavaScript Object Notation (JSON) document. + /// + /// A Pointer is a Unicode string with the reference tokens separated by `/`. + /// Inside tokens `/` is replaced by `~1` and `~` is replaced by `~0`. The + /// addressed value is returned and if there is no such value `None` is + /// returned. + /// + /// For more information read [RFC6901](https://tools.ietf.org/html/rfc6901). + /// + /// # Example of Use + /// + /// ``` + /// use serde_json::Value; + /// + /// fn main() { + /// let s = r#"{"x": 1.0, "y": 2.0}"#; + /// let mut value: Value = serde_json::from_str(s).unwrap(); + /// + /// // Check value using read-only pointer + /// assert_eq!(value.pointer("/x"), Some(&1.0.into())); + /// // Change value with direct assignment + /// *value.pointer_mut("/x").unwrap() = 1.5.into(); + /// // Check that new value was written + /// assert_eq!(value.pointer("/x"), Some(&1.5.into())); + /// // Or change the value only if it exists + /// value.pointer_mut("/x").map(|v| *v = 1.5.into()); + /// + /// // "Steal" ownership of a value. Can replace with any valid Value. + /// let old_x = value.pointer_mut("/x").map(Value::take).unwrap(); + /// assert_eq!(old_x, 1.5); + /// assert_eq!(value.pointer("/x").unwrap(), &Value::Null); + /// } + /// ``` + pub fn pointer_mut(&mut self, pointer: &str) -> Option<&mut Value> { + if pointer.is_empty() { + return Some(self); + } + if !pointer.starts_with('/') { + return None; + } + pointer + .split('/') + .skip(1) + .map(|x| x.replace("~1", "/").replace("~0", "~")) + .try_fold(self, |target, token| match target { + Value::Object(map) => map.get_mut(&token), + Value::Array(list) => parse_index(&token).and_then(move |x| list.get_mut(x)), + _ => None, + }) + } + + /// Takes the value out of the `Value`, leaving a `Null` in its place. + /// + /// ``` + /// # use serde_json::json; + /// # + /// let mut v = json!({ "x": "y" }); + /// assert_eq!(v["x"].take(), json!("y")); + /// assert_eq!(v, json!({ "x": null })); + /// ``` + pub fn take(&mut self) -> Value { + mem::replace(self, Value::Null) + } + + /// Reorders the entries of all `Value::Object` nested within this JSON + /// value according to `str`'s usual ordering. + /// + /// If serde_json's "preserve_order" feature is not enabled, this method + /// does no work because all JSON maps are always kept in a sorted state. + /// + /// If serde_json's "preserve_order" feature is enabled, this method + /// destroys the original source order or insertion order of the JSON + /// objects in favor of an alphanumerical order that matches how a BTreeMap + /// with the same contents would be ordered. + pub fn sort_all_objects(&mut self) { + #[cfg(feature = "preserve_order")] + { + match self { + Value::Object(map) => { + map.sort_keys(); + map.values_mut().for_each(Value::sort_all_objects); + } + Value::Array(list) => { + list.iter_mut().for_each(Value::sort_all_objects); + } + _ => {} + } + } + } +} + +/// The default value is `Value::Null`. +/// +/// This is useful for handling omitted `Value` fields when deserializing. +/// +/// # Examples +/// +/// ``` +/// # use serde::Deserialize; +/// use serde_json::Value; +/// +/// #[derive(Deserialize)] +/// struct Settings { +/// level: i32, +/// #[serde(default)] +/// extras: Value, +/// } +/// +/// # fn try_main() -> Result<(), serde_json::Error> { +/// let data = r#" { "level": 42 } "#; +/// let s: Settings = serde_json::from_str(data)?; +/// +/// assert_eq!(s.level, 42); +/// assert_eq!(s.extras, Value::Null); +/// # +/// # Ok(()) +/// # } +/// # +/// # try_main().unwrap() +/// ``` +impl Default for Value { + fn default() -> Value { + Value::Null + } +} + +mod de; +mod from; +mod index; +mod partial_eq; +mod ser; + +/// Convert a `T` into `serde_json::Value` which is an enum that can represent +/// any valid JSON data. +/// +/// # Example +/// +/// ``` +/// use serde::Serialize; +/// use serde_json::json; +/// use std::error::Error; +/// +/// #[derive(Serialize)] +/// struct User { +/// fingerprint: String, +/// location: String, +/// } +/// +/// fn compare_json_values() -> Result<(), Box> { +/// let u = User { +/// fingerprint: "0xF9BA143B95FF6D82".to_owned(), +/// location: "Menlo Park, CA".to_owned(), +/// }; +/// +/// // The type of `expected` is `serde_json::Value` +/// let expected = json!({ +/// "fingerprint": "0xF9BA143B95FF6D82", +/// "location": "Menlo Park, CA", +/// }); +/// +/// let v = serde_json::to_value(u).unwrap(); +/// assert_eq!(v, expected); +/// +/// Ok(()) +/// } +/// # +/// # compare_json_values().unwrap(); +/// ``` +/// +/// # Errors +/// +/// This conversion can fail if `T`'s implementation of `Serialize` decides to +/// fail, or if `T` contains a map with non-string keys. +/// +/// ``` +/// use std::collections::BTreeMap; +/// +/// fn main() { +/// // The keys in this map are vectors, not strings. +/// let mut map = BTreeMap::new(); +/// map.insert(vec![32, 64], "x86"); +/// +/// println!("{}", serde_json::to_value(map).unwrap_err()); +/// } +/// ``` +// Taking by value is more friendly to iterator adapters, option and result +// consumers, etc. See https://github.com/serde-rs/json/pull/149. +pub fn to_value(value: T) -> Result +where + T: Serialize, +{ + value.serialize(Serializer) +} + +/// Interpret a `serde_json::Value` as an instance of type `T`. +/// +/// # Example +/// +/// ``` +/// use serde::Deserialize; +/// use serde_json::json; +/// +/// #[derive(Deserialize, Debug)] +/// struct User { +/// fingerprint: String, +/// location: String, +/// } +/// +/// fn main() { +/// // The type of `j` is `serde_json::Value` +/// let j = json!({ +/// "fingerprint": "0xF9BA143B95FF6D82", +/// "location": "Menlo Park, CA" +/// }); +/// +/// let u: User = serde_json::from_value(j).unwrap(); +/// println!("{:#?}", u); +/// } +/// ``` +/// +/// # Errors +/// +/// This conversion can fail if the structure of the Value does not match the +/// structure expected by `T`, for example if `T` is a struct type but the Value +/// contains something other than a JSON map. It can also fail if the structure +/// is correct but `T`'s implementation of `Deserialize` decides that something +/// is wrong with the data, for example required struct fields are missing from +/// the JSON map or some number is too big to fit in the expected primitive +/// type. +pub fn from_value(value: Value) -> Result +where + T: DeserializeOwned, +{ + T::deserialize(value) +} diff --git a/vendor/serde_json/src/value/partial_eq.rs b/vendor/serde_json/src/value/partial_eq.rs new file mode 100644 index 0000000..46c1dbc --- /dev/null +++ b/vendor/serde_json/src/value/partial_eq.rs @@ -0,0 +1,103 @@ +use super::Value; +use alloc::string::String; + +fn eq_i64(value: &Value, other: i64) -> bool { + value.as_i64().map_or(false, |i| i == other) +} + +fn eq_u64(value: &Value, other: u64) -> bool { + value.as_u64().map_or(false, |i| i == other) +} + +fn eq_f32(value: &Value, other: f32) -> bool { + match value { + Value::Number(n) => n.as_f32().map_or(false, |i| i == other), + _ => false, + } +} + +fn eq_f64(value: &Value, other: f64) -> bool { + value.as_f64().map_or(false, |i| i == other) +} + +fn eq_bool(value: &Value, other: bool) -> bool { + value.as_bool().map_or(false, |i| i == other) +} + +fn eq_str(value: &Value, other: &str) -> bool { + value.as_str().map_or(false, |i| i == other) +} + +impl PartialEq for Value { + fn eq(&self, other: &str) -> bool { + eq_str(self, other) + } +} + +impl PartialEq<&str> for Value { + fn eq(&self, other: &&str) -> bool { + eq_str(self, *other) + } +} + +impl PartialEq for str { + fn eq(&self, other: &Value) -> bool { + eq_str(other, self) + } +} + +impl PartialEq for &str { + fn eq(&self, other: &Value) -> bool { + eq_str(other, *self) + } +} + +impl PartialEq for Value { + fn eq(&self, other: &String) -> bool { + eq_str(self, other.as_str()) + } +} + +impl PartialEq for String { + fn eq(&self, other: &Value) -> bool { + eq_str(other, self.as_str()) + } +} + +macro_rules! partialeq_numeric { + ($($eq:ident [$($ty:ty)*])*) => { + $($( + impl PartialEq<$ty> for Value { + fn eq(&self, other: &$ty) -> bool { + $eq(self, *other as _) + } + } + + impl PartialEq for $ty { + fn eq(&self, other: &Value) -> bool { + $eq(other, *self as _) + } + } + + impl<'a> PartialEq<$ty> for &'a Value { + fn eq(&self, other: &$ty) -> bool { + $eq(*self, *other as _) + } + } + + impl<'a> PartialEq<$ty> for &'a mut Value { + fn eq(&self, other: &$ty) -> bool { + $eq(*self, *other as _) + } + } + )*)* + } +} + +partialeq_numeric! { + eq_i64[i8 i16 i32 i64 isize] + eq_u64[u8 u16 u32 u64 usize] + eq_f32[f32] + eq_f64[f64] + eq_bool[bool] +} diff --git a/vendor/serde_json/src/value/ser.rs b/vendor/serde_json/src/value/ser.rs new file mode 100644 index 0000000..a681934 --- /dev/null +++ b/vendor/serde_json/src/value/ser.rs @@ -0,0 +1,1063 @@ +use crate::error::{Error, ErrorCode, Result}; +use crate::map::Map; +use crate::value::{to_value, Value}; +use alloc::borrow::ToOwned; +use alloc::string::{String, ToString}; +use alloc::vec::Vec; +use core::fmt::Display; +use core::result; +use serde::ser::{Impossible, Serialize}; + +impl Serialize for Value { + #[inline] + fn serialize(&self, serializer: S) -> result::Result + where + S: ::serde::Serializer, + { + match self { + Value::Null => serializer.serialize_unit(), + Value::Bool(b) => serializer.serialize_bool(*b), + Value::Number(n) => n.serialize(serializer), + Value::String(s) => serializer.serialize_str(s), + Value::Array(v) => v.serialize(serializer), + #[cfg(any(feature = "std", feature = "alloc"))] + Value::Object(m) => { + use serde::ser::SerializeMap; + let mut map = tri!(serializer.serialize_map(Some(m.len()))); + for (k, v) in m { + tri!(map.serialize_entry(k, v)); + } + map.end() + } + #[cfg(not(any(feature = "std", feature = "alloc")))] + Value::Object(_) => unreachable!(), + } + } +} + +/// Serializer whose output is a `Value`. +/// +/// This is the serializer that backs [`serde_json::to_value`][crate::to_value]. +/// Unlike the main serde_json serializer which goes from some serializable +/// value of type `T` to JSON text, this one goes from `T` to +/// `serde_json::Value`. +/// +/// The `to_value` function is implementable as: +/// +/// ``` +/// use serde::Serialize; +/// use serde_json::{Error, Value}; +/// +/// pub fn to_value(input: T) -> Result +/// where +/// T: Serialize, +/// { +/// input.serialize(serde_json::value::Serializer) +/// } +/// ``` +pub struct Serializer; + +impl serde::Serializer for Serializer { + type Ok = Value; + type Error = Error; + + type SerializeSeq = SerializeVec; + type SerializeTuple = SerializeVec; + type SerializeTupleStruct = SerializeVec; + type SerializeTupleVariant = SerializeTupleVariant; + type SerializeMap = SerializeMap; + type SerializeStruct = SerializeMap; + type SerializeStructVariant = SerializeStructVariant; + + #[inline] + fn serialize_bool(self, value: bool) -> Result { + Ok(Value::Bool(value)) + } + + #[inline] + fn serialize_i8(self, value: i8) -> Result { + self.serialize_i64(value as i64) + } + + #[inline] + fn serialize_i16(self, value: i16) -> Result { + self.serialize_i64(value as i64) + } + + #[inline] + fn serialize_i32(self, value: i32) -> Result { + self.serialize_i64(value as i64) + } + + fn serialize_i64(self, value: i64) -> Result { + Ok(Value::Number(value.into())) + } + + fn serialize_i128(self, value: i128) -> Result { + #[cfg(feature = "arbitrary_precision")] + { + Ok(Value::Number(value.into())) + } + + #[cfg(not(feature = "arbitrary_precision"))] + { + if let Ok(value) = u64::try_from(value) { + Ok(Value::Number(value.into())) + } else if let Ok(value) = i64::try_from(value) { + Ok(Value::Number(value.into())) + } else { + Err(Error::syntax(ErrorCode::NumberOutOfRange, 0, 0)) + } + } + } + + #[inline] + fn serialize_u8(self, value: u8) -> Result { + self.serialize_u64(value as u64) + } + + #[inline] + fn serialize_u16(self, value: u16) -> Result { + self.serialize_u64(value as u64) + } + + #[inline] + fn serialize_u32(self, value: u32) -> Result { + self.serialize_u64(value as u64) + } + + #[inline] + fn serialize_u64(self, value: u64) -> Result { + Ok(Value::Number(value.into())) + } + + fn serialize_u128(self, value: u128) -> Result { + #[cfg(feature = "arbitrary_precision")] + { + Ok(Value::Number(value.into())) + } + + #[cfg(not(feature = "arbitrary_precision"))] + { + if let Ok(value) = u64::try_from(value) { + Ok(Value::Number(value.into())) + } else { + Err(Error::syntax(ErrorCode::NumberOutOfRange, 0, 0)) + } + } + } + + #[inline] + fn serialize_f32(self, float: f32) -> Result { + Ok(Value::from(float)) + } + + #[inline] + fn serialize_f64(self, float: f64) -> Result { + Ok(Value::from(float)) + } + + #[inline] + fn serialize_char(self, value: char) -> Result { + let mut s = String::new(); + s.push(value); + Ok(Value::String(s)) + } + + #[inline] + fn serialize_str(self, value: &str) -> Result { + Ok(Value::String(value.to_owned())) + } + + fn serialize_bytes(self, value: &[u8]) -> Result { + let vec = value.iter().map(|&b| Value::Number(b.into())).collect(); + Ok(Value::Array(vec)) + } + + #[inline] + fn serialize_unit(self) -> Result { + Ok(Value::Null) + } + + #[inline] + fn serialize_unit_struct(self, _name: &'static str) -> Result { + self.serialize_unit() + } + + #[inline] + fn serialize_unit_variant( + self, + _name: &'static str, + _variant_index: u32, + variant: &'static str, + ) -> Result { + self.serialize_str(variant) + } + + #[inline] + fn serialize_newtype_struct(self, _name: &'static str, value: &T) -> Result + where + T: ?Sized + Serialize, + { + value.serialize(self) + } + + fn serialize_newtype_variant( + self, + _name: &'static str, + _variant_index: u32, + variant: &'static str, + value: &T, + ) -> Result + where + T: ?Sized + Serialize, + { + let mut values = Map::new(); + values.insert(String::from(variant), tri!(to_value(value))); + Ok(Value::Object(values)) + } + + #[inline] + fn serialize_none(self) -> Result { + self.serialize_unit() + } + + #[inline] + fn serialize_some(self, value: &T) -> Result + where + T: ?Sized + Serialize, + { + value.serialize(self) + } + + fn serialize_seq(self, len: Option) -> Result { + Ok(SerializeVec { + vec: Vec::with_capacity(len.unwrap_or(0)), + }) + } + + fn serialize_tuple(self, len: usize) -> Result { + self.serialize_seq(Some(len)) + } + + fn serialize_tuple_struct( + self, + _name: &'static str, + len: usize, + ) -> Result { + self.serialize_seq(Some(len)) + } + + fn serialize_tuple_variant( + self, + _name: &'static str, + _variant_index: u32, + variant: &'static str, + len: usize, + ) -> Result { + Ok(SerializeTupleVariant { + name: String::from(variant), + vec: Vec::with_capacity(len), + }) + } + + fn serialize_map(self, _len: Option) -> Result { + Ok(SerializeMap::Map { + map: Map::new(), + next_key: None, + }) + } + + fn serialize_struct(self, name: &'static str, len: usize) -> Result { + match name { + #[cfg(feature = "arbitrary_precision")] + crate::number::TOKEN => Ok(SerializeMap::Number { out_value: None }), + #[cfg(feature = "raw_value")] + crate::raw::TOKEN => Ok(SerializeMap::RawValue { out_value: None }), + _ => self.serialize_map(Some(len)), + } + } + + fn serialize_struct_variant( + self, + _name: &'static str, + _variant_index: u32, + variant: &'static str, + _len: usize, + ) -> Result { + Ok(SerializeStructVariant { + name: String::from(variant), + map: Map::new(), + }) + } + + fn collect_str(self, value: &T) -> Result + where + T: ?Sized + Display, + { + Ok(Value::String(value.to_string())) + } +} + +pub struct SerializeVec { + vec: Vec, +} + +pub struct SerializeTupleVariant { + name: String, + vec: Vec, +} + +pub enum SerializeMap { + Map { + map: Map, + next_key: Option, + }, + #[cfg(feature = "arbitrary_precision")] + Number { out_value: Option }, + #[cfg(feature = "raw_value")] + RawValue { out_value: Option }, +} + +pub struct SerializeStructVariant { + name: String, + map: Map, +} + +impl serde::ser::SerializeSeq for SerializeVec { + type Ok = Value; + type Error = Error; + + fn serialize_element(&mut self, value: &T) -> Result<()> + where + T: ?Sized + Serialize, + { + self.vec.push(tri!(to_value(value))); + Ok(()) + } + + fn end(self) -> Result { + Ok(Value::Array(self.vec)) + } +} + +impl serde::ser::SerializeTuple for SerializeVec { + type Ok = Value; + type Error = Error; + + fn serialize_element(&mut self, value: &T) -> Result<()> + where + T: ?Sized + Serialize, + { + serde::ser::SerializeSeq::serialize_element(self, value) + } + + fn end(self) -> Result { + serde::ser::SerializeSeq::end(self) + } +} + +impl serde::ser::SerializeTupleStruct for SerializeVec { + type Ok = Value; + type Error = Error; + + fn serialize_field(&mut self, value: &T) -> Result<()> + where + T: ?Sized + Serialize, + { + serde::ser::SerializeSeq::serialize_element(self, value) + } + + fn end(self) -> Result { + serde::ser::SerializeSeq::end(self) + } +} + +impl serde::ser::SerializeTupleVariant for SerializeTupleVariant { + type Ok = Value; + type Error = Error; + + fn serialize_field(&mut self, value: &T) -> Result<()> + where + T: ?Sized + Serialize, + { + self.vec.push(tri!(to_value(value))); + Ok(()) + } + + fn end(self) -> Result { + let mut object = Map::new(); + + object.insert(self.name, Value::Array(self.vec)); + + Ok(Value::Object(object)) + } +} + +impl serde::ser::SerializeMap for SerializeMap { + type Ok = Value; + type Error = Error; + + fn serialize_key(&mut self, key: &T) -> Result<()> + where + T: ?Sized + Serialize, + { + match self { + SerializeMap::Map { next_key, .. } => { + *next_key = Some(tri!(key.serialize(MapKeySerializer))); + Ok(()) + } + #[cfg(feature = "arbitrary_precision")] + SerializeMap::Number { .. } => unreachable!(), + #[cfg(feature = "raw_value")] + SerializeMap::RawValue { .. } => unreachable!(), + } + } + + fn serialize_value(&mut self, value: &T) -> Result<()> + where + T: ?Sized + Serialize, + { + match self { + SerializeMap::Map { map, next_key } => { + let key = next_key.take(); + // Panic because this indicates a bug in the program rather than an + // expected failure. + let key = key.expect("serialize_value called before serialize_key"); + map.insert(key, tri!(to_value(value))); + Ok(()) + } + #[cfg(feature = "arbitrary_precision")] + SerializeMap::Number { .. } => unreachable!(), + #[cfg(feature = "raw_value")] + SerializeMap::RawValue { .. } => unreachable!(), + } + } + + fn end(self) -> Result { + match self { + SerializeMap::Map { map, .. } => Ok(Value::Object(map)), + #[cfg(feature = "arbitrary_precision")] + SerializeMap::Number { .. } => unreachable!(), + #[cfg(feature = "raw_value")] + SerializeMap::RawValue { .. } => unreachable!(), + } + } +} + +struct MapKeySerializer; + +fn key_must_be_a_string() -> Error { + Error::syntax(ErrorCode::KeyMustBeAString, 0, 0) +} + +fn float_key_must_be_finite() -> Error { + Error::syntax(ErrorCode::FloatKeyMustBeFinite, 0, 0) +} + +impl serde::Serializer for MapKeySerializer { + type Ok = String; + type Error = Error; + + type SerializeSeq = Impossible; + type SerializeTuple = Impossible; + type SerializeTupleStruct = Impossible; + type SerializeTupleVariant = Impossible; + type SerializeMap = Impossible; + type SerializeStruct = Impossible; + type SerializeStructVariant = Impossible; + + #[inline] + fn serialize_unit_variant( + self, + _name: &'static str, + _variant_index: u32, + variant: &'static str, + ) -> Result { + Ok(variant.to_owned()) + } + + #[inline] + fn serialize_newtype_struct(self, _name: &'static str, value: &T) -> Result + where + T: ?Sized + Serialize, + { + value.serialize(self) + } + + fn serialize_bool(self, value: bool) -> Result { + Ok(if value { "true" } else { "false" }.to_owned()) + } + + fn serialize_i8(self, value: i8) -> Result { + Ok(itoa::Buffer::new().format(value).to_owned()) + } + + fn serialize_i16(self, value: i16) -> Result { + Ok(itoa::Buffer::new().format(value).to_owned()) + } + + fn serialize_i32(self, value: i32) -> Result { + Ok(itoa::Buffer::new().format(value).to_owned()) + } + + fn serialize_i64(self, value: i64) -> Result { + Ok(itoa::Buffer::new().format(value).to_owned()) + } + + fn serialize_i128(self, value: i128) -> Result { + Ok(itoa::Buffer::new().format(value).to_owned()) + } + + fn serialize_u8(self, value: u8) -> Result { + Ok(itoa::Buffer::new().format(value).to_owned()) + } + + fn serialize_u16(self, value: u16) -> Result { + Ok(itoa::Buffer::new().format(value).to_owned()) + } + + fn serialize_u32(self, value: u32) -> Result { + Ok(itoa::Buffer::new().format(value).to_owned()) + } + + fn serialize_u64(self, value: u64) -> Result { + Ok(itoa::Buffer::new().format(value).to_owned()) + } + + fn serialize_u128(self, value: u128) -> Result { + Ok(itoa::Buffer::new().format(value).to_owned()) + } + + fn serialize_f32(self, value: f32) -> Result { + if value.is_finite() { + Ok(ryu::Buffer::new().format_finite(value).to_owned()) + } else { + Err(float_key_must_be_finite()) + } + } + + fn serialize_f64(self, value: f64) -> Result { + if value.is_finite() { + Ok(ryu::Buffer::new().format_finite(value).to_owned()) + } else { + Err(float_key_must_be_finite()) + } + } + + #[inline] + fn serialize_char(self, value: char) -> Result { + Ok({ + let mut s = String::new(); + s.push(value); + s + }) + } + + #[inline] + fn serialize_str(self, value: &str) -> Result { + Ok(value.to_owned()) + } + + fn serialize_bytes(self, _value: &[u8]) -> Result { + Err(key_must_be_a_string()) + } + + fn serialize_unit(self) -> Result { + Err(key_must_be_a_string()) + } + + fn serialize_unit_struct(self, _name: &'static str) -> Result { + Err(key_must_be_a_string()) + } + + fn serialize_newtype_variant( + self, + _name: &'static str, + _variant_index: u32, + _variant: &'static str, + _value: &T, + ) -> Result + where + T: ?Sized + Serialize, + { + Err(key_must_be_a_string()) + } + + fn serialize_none(self) -> Result { + Err(key_must_be_a_string()) + } + + fn serialize_some(self, _value: &T) -> Result + where + T: ?Sized + Serialize, + { + Err(key_must_be_a_string()) + } + + fn serialize_seq(self, _len: Option) -> Result { + Err(key_must_be_a_string()) + } + + fn serialize_tuple(self, _len: usize) -> Result { + Err(key_must_be_a_string()) + } + + fn serialize_tuple_struct( + self, + _name: &'static str, + _len: usize, + ) -> Result { + Err(key_must_be_a_string()) + } + + fn serialize_tuple_variant( + self, + _name: &'static str, + _variant_index: u32, + _variant: &'static str, + _len: usize, + ) -> Result { + Err(key_must_be_a_string()) + } + + fn serialize_map(self, _len: Option) -> Result { + Err(key_must_be_a_string()) + } + + fn serialize_struct(self, _name: &'static str, _len: usize) -> Result { + Err(key_must_be_a_string()) + } + + fn serialize_struct_variant( + self, + _name: &'static str, + _variant_index: u32, + _variant: &'static str, + _len: usize, + ) -> Result { + Err(key_must_be_a_string()) + } + + fn collect_str(self, value: &T) -> Result + where + T: ?Sized + Display, + { + Ok(value.to_string()) + } +} + +impl serde::ser::SerializeStruct for SerializeMap { + type Ok = Value; + type Error = Error; + + fn serialize_field(&mut self, key: &'static str, value: &T) -> Result<()> + where + T: ?Sized + Serialize, + { + match self { + SerializeMap::Map { .. } => serde::ser::SerializeMap::serialize_entry(self, key, value), + #[cfg(feature = "arbitrary_precision")] + SerializeMap::Number { out_value } => { + if key == crate::number::TOKEN { + *out_value = Some(tri!(value.serialize(NumberValueEmitter))); + Ok(()) + } else { + Err(invalid_number()) + } + } + #[cfg(feature = "raw_value")] + SerializeMap::RawValue { out_value } => { + if key == crate::raw::TOKEN { + *out_value = Some(tri!(value.serialize(RawValueEmitter))); + Ok(()) + } else { + Err(invalid_raw_value()) + } + } + } + } + + fn end(self) -> Result { + match self { + SerializeMap::Map { .. } => serde::ser::SerializeMap::end(self), + #[cfg(feature = "arbitrary_precision")] + SerializeMap::Number { out_value, .. } => { + Ok(out_value.expect("number value was not emitted")) + } + #[cfg(feature = "raw_value")] + SerializeMap::RawValue { out_value, .. } => { + Ok(out_value.expect("raw value was not emitted")) + } + } + } +} + +impl serde::ser::SerializeStructVariant for SerializeStructVariant { + type Ok = Value; + type Error = Error; + + fn serialize_field(&mut self, key: &'static str, value: &T) -> Result<()> + where + T: ?Sized + Serialize, + { + self.map.insert(String::from(key), tri!(to_value(value))); + Ok(()) + } + + fn end(self) -> Result { + let mut object = Map::new(); + + object.insert(self.name, Value::Object(self.map)); + + Ok(Value::Object(object)) + } +} + +#[cfg(feature = "arbitrary_precision")] +struct NumberValueEmitter; + +#[cfg(feature = "arbitrary_precision")] +fn invalid_number() -> Error { + Error::syntax(ErrorCode::InvalidNumber, 0, 0) +} + +#[cfg(feature = "arbitrary_precision")] +impl serde::ser::Serializer for NumberValueEmitter { + type Ok = Value; + type Error = Error; + + type SerializeSeq = Impossible; + type SerializeTuple = Impossible; + type SerializeTupleStruct = Impossible; + type SerializeTupleVariant = Impossible; + type SerializeMap = Impossible; + type SerializeStruct = Impossible; + type SerializeStructVariant = Impossible; + + fn serialize_bool(self, _v: bool) -> Result { + Err(invalid_number()) + } + + fn serialize_i8(self, _v: i8) -> Result { + Err(invalid_number()) + } + + fn serialize_i16(self, _v: i16) -> Result { + Err(invalid_number()) + } + + fn serialize_i32(self, _v: i32) -> Result { + Err(invalid_number()) + } + + fn serialize_i64(self, _v: i64) -> Result { + Err(invalid_number()) + } + + fn serialize_u8(self, _v: u8) -> Result { + Err(invalid_number()) + } + + fn serialize_u16(self, _v: u16) -> Result { + Err(invalid_number()) + } + + fn serialize_u32(self, _v: u32) -> Result { + Err(invalid_number()) + } + + fn serialize_u64(self, _v: u64) -> Result { + Err(invalid_number()) + } + + fn serialize_f32(self, _v: f32) -> Result { + Err(invalid_number()) + } + + fn serialize_f64(self, _v: f64) -> Result { + Err(invalid_number()) + } + + fn serialize_char(self, _v: char) -> Result { + Err(invalid_number()) + } + + fn serialize_str(self, value: &str) -> Result { + let n = tri!(value.to_owned().parse()); + Ok(Value::Number(n)) + } + + fn serialize_bytes(self, _value: &[u8]) -> Result { + Err(invalid_number()) + } + + fn serialize_none(self) -> Result { + Err(invalid_number()) + } + + fn serialize_some(self, _value: &T) -> Result + where + T: ?Sized + Serialize, + { + Err(invalid_number()) + } + + fn serialize_unit(self) -> Result { + Err(invalid_number()) + } + + fn serialize_unit_struct(self, _name: &'static str) -> Result { + Err(invalid_number()) + } + + fn serialize_unit_variant( + self, + _name: &'static str, + _variant_index: u32, + _variant: &'static str, + ) -> Result { + Err(invalid_number()) + } + + fn serialize_newtype_struct(self, _name: &'static str, _value: &T) -> Result + where + T: ?Sized + Serialize, + { + Err(invalid_number()) + } + + fn serialize_newtype_variant( + self, + _name: &'static str, + _variant_index: u32, + _variant: &'static str, + _value: &T, + ) -> Result + where + T: ?Sized + Serialize, + { + Err(invalid_number()) + } + + fn serialize_seq(self, _len: Option) -> Result { + Err(invalid_number()) + } + + fn serialize_tuple(self, _len: usize) -> Result { + Err(invalid_number()) + } + + fn serialize_tuple_struct( + self, + _name: &'static str, + _len: usize, + ) -> Result { + Err(invalid_number()) + } + + fn serialize_tuple_variant( + self, + _name: &'static str, + _variant_index: u32, + _variant: &'static str, + _len: usize, + ) -> Result { + Err(invalid_number()) + } + + fn serialize_map(self, _len: Option) -> Result { + Err(invalid_number()) + } + + fn serialize_struct(self, _name: &'static str, _len: usize) -> Result { + Err(invalid_number()) + } + + fn serialize_struct_variant( + self, + _name: &'static str, + _variant_index: u32, + _variant: &'static str, + _len: usize, + ) -> Result { + Err(invalid_number()) + } +} + +#[cfg(feature = "raw_value")] +struct RawValueEmitter; + +#[cfg(feature = "raw_value")] +fn invalid_raw_value() -> Error { + Error::syntax(ErrorCode::ExpectedSomeValue, 0, 0) +} + +#[cfg(feature = "raw_value")] +impl serde::ser::Serializer for RawValueEmitter { + type Ok = Value; + type Error = Error; + + type SerializeSeq = Impossible; + type SerializeTuple = Impossible; + type SerializeTupleStruct = Impossible; + type SerializeTupleVariant = Impossible; + type SerializeMap = Impossible; + type SerializeStruct = Impossible; + type SerializeStructVariant = Impossible; + + fn serialize_bool(self, _v: bool) -> Result { + Err(invalid_raw_value()) + } + + fn serialize_i8(self, _v: i8) -> Result { + Err(invalid_raw_value()) + } + + fn serialize_i16(self, _v: i16) -> Result { + Err(invalid_raw_value()) + } + + fn serialize_i32(self, _v: i32) -> Result { + Err(invalid_raw_value()) + } + + fn serialize_i64(self, _v: i64) -> Result { + Err(invalid_raw_value()) + } + + fn serialize_u8(self, _v: u8) -> Result { + Err(invalid_raw_value()) + } + + fn serialize_u16(self, _v: u16) -> Result { + Err(invalid_raw_value()) + } + + fn serialize_u32(self, _v: u32) -> Result { + Err(invalid_raw_value()) + } + + fn serialize_u64(self, _v: u64) -> Result { + Err(invalid_raw_value()) + } + + fn serialize_f32(self, _v: f32) -> Result { + Err(invalid_raw_value()) + } + + fn serialize_f64(self, _v: f64) -> Result { + Err(invalid_raw_value()) + } + + fn serialize_char(self, _v: char) -> Result { + Err(invalid_raw_value()) + } + + fn serialize_str(self, value: &str) -> Result { + crate::from_str(value) + } + + fn serialize_bytes(self, _value: &[u8]) -> Result { + Err(invalid_raw_value()) + } + + fn serialize_none(self) -> Result { + Err(invalid_raw_value()) + } + + fn serialize_some(self, _value: &T) -> Result + where + T: ?Sized + Serialize, + { + Err(invalid_raw_value()) + } + + fn serialize_unit(self) -> Result { + Err(invalid_raw_value()) + } + + fn serialize_unit_struct(self, _name: &'static str) -> Result { + Err(invalid_raw_value()) + } + + fn serialize_unit_variant( + self, + _name: &'static str, + _variant_index: u32, + _variant: &'static str, + ) -> Result { + Err(invalid_raw_value()) + } + + fn serialize_newtype_struct(self, _name: &'static str, _value: &T) -> Result + where + T: ?Sized + Serialize, + { + Err(invalid_raw_value()) + } + + fn serialize_newtype_variant( + self, + _name: &'static str, + _variant_index: u32, + _variant: &'static str, + _value: &T, + ) -> Result + where + T: ?Sized + Serialize, + { + Err(invalid_raw_value()) + } + + fn serialize_seq(self, _len: Option) -> Result { + Err(invalid_raw_value()) + } + + fn serialize_tuple(self, _len: usize) -> Result { + Err(invalid_raw_value()) + } + + fn serialize_tuple_struct( + self, + _name: &'static str, + _len: usize, + ) -> Result { + Err(invalid_raw_value()) + } + + fn serialize_tuple_variant( + self, + _name: &'static str, + _variant_index: u32, + _variant: &'static str, + _len: usize, + ) -> Result { + Err(invalid_raw_value()) + } + + fn serialize_map(self, _len: Option) -> Result { + Err(invalid_raw_value()) + } + + fn serialize_struct(self, _name: &'static str, _len: usize) -> Result { + Err(invalid_raw_value()) + } + + fn serialize_struct_variant( + self, + _name: &'static str, + _variant_index: u32, + _variant: &'static str, + _len: usize, + ) -> Result { + Err(invalid_raw_value()) + } + + fn collect_str(self, value: &T) -> Result + where + T: ?Sized + Display, + { + self.serialize_str(&value.to_string()) + } +} diff --git a/vendor/serde_json/tests/compiletest.rs b/vendor/serde_json/tests/compiletest.rs new file mode 100644 index 0000000..23a6a06 --- /dev/null +++ b/vendor/serde_json/tests/compiletest.rs @@ -0,0 +1,7 @@ +#[rustversion::attr(not(nightly), ignore = "requires nightly")] +#[cfg_attr(miri, ignore = "incompatible with miri")] +#[test] +fn ui() { + let t = trybuild::TestCases::new(); + t.compile_fail("tests/ui/*.rs"); +} diff --git a/vendor/serde_json/tests/debug.rs b/vendor/serde_json/tests/debug.rs new file mode 100644 index 0000000..8ddcf5a --- /dev/null +++ b/vendor/serde_json/tests/debug.rs @@ -0,0 +1,81 @@ +use indoc::indoc; +use serde_json::{json, Number, Value}; + +#[test] +fn number() { + assert_eq!(format!("{:?}", Number::from(1)), "Number(1)"); + assert_eq!(format!("{:?}", Number::from(-1)), "Number(-1)"); + assert_eq!( + format!("{:?}", Number::from_f64(1.0).unwrap()), + "Number(1.0)" + ); +} + +#[test] +fn value_null() { + assert_eq!(format!("{:?}", json!(null)), "Null"); +} + +#[test] +fn value_bool() { + assert_eq!(format!("{:?}", json!(true)), "Bool(true)"); + assert_eq!(format!("{:?}", json!(false)), "Bool(false)"); +} + +#[test] +fn value_number() { + assert_eq!(format!("{:?}", json!(1)), "Number(1)"); + assert_eq!(format!("{:?}", json!(-1)), "Number(-1)"); + assert_eq!(format!("{:?}", json!(1.0)), "Number(1.0)"); + assert_eq!(Number::from_f64(1.0).unwrap().to_string(), "1.0"); // not just "1" + assert_eq!(Number::from_f64(12e40).unwrap().to_string(), "1.2e41"); +} + +#[test] +fn value_string() { + assert_eq!(format!("{:?}", json!("s")), "String(\"s\")"); +} + +#[test] +fn value_array() { + assert_eq!(format!("{:?}", json!([])), "Array []"); +} + +#[test] +fn value_object() { + assert_eq!(format!("{:?}", json!({})), "Object {}"); +} + +#[test] +fn error() { + let err = serde_json::from_str::("{0}").unwrap_err(); + let expected = "Error(\"key must be a string\", line: 1, column: 2)"; + assert_eq!(format!("{:?}", err), expected); +} + +#[test] +fn indented() { + let j = json!({ + "Array": [true], + "Bool": true, + "EmptyArray": [], + "EmptyObject": {}, + "Null": null, + "Number": 1, + "String": "...", + }); + let expected = indoc! {r#" + Object { + "Array": Array [ + Bool(true), + ], + "Bool": Bool(true), + "EmptyArray": Array [], + "EmptyObject": Object {}, + "Null": Null, + "Number": Number(1), + "String": String("..."), + }"# + }; + assert_eq!(format!("{:#?}", j), expected); +} diff --git a/vendor/serde_json/tests/lexical.rs b/vendor/serde_json/tests/lexical.rs new file mode 100644 index 0000000..368c844 --- /dev/null +++ b/vendor/serde_json/tests/lexical.rs @@ -0,0 +1,48 @@ +#![allow( + clippy::cast_lossless, + clippy::cast_possible_truncation, + clippy::cast_possible_wrap, + clippy::cast_precision_loss, + clippy::cast_sign_loss, + clippy::comparison_chain, + clippy::doc_markdown, + clippy::excessive_precision, + clippy::float_cmp, + clippy::if_not_else, + clippy::let_underscore_untyped, + clippy::module_name_repetitions, + clippy::needless_late_init, + clippy::shadow_unrelated, + clippy::similar_names, + clippy::single_match_else, + clippy::too_many_lines, + clippy::unreadable_literal, + clippy::unseparated_literal_suffix, + clippy::wildcard_imports +)] + +extern crate alloc; + +#[path = "../src/lexical/mod.rs"] +mod lexical; + +#[path = "lexical/algorithm.rs"] +mod algorithm; + +#[path = "lexical/exponent.rs"] +mod exponent; + +#[path = "lexical/float.rs"] +mod float; + +#[path = "lexical/math.rs"] +mod math; + +#[path = "lexical/num.rs"] +mod num; + +#[path = "lexical/parse.rs"] +mod parse; + +#[path = "lexical/rounding.rs"] +mod rounding; diff --git a/vendor/serde_json/tests/lexical/algorithm.rs b/vendor/serde_json/tests/lexical/algorithm.rs new file mode 100644 index 0000000..7f3a2c6 --- /dev/null +++ b/vendor/serde_json/tests/lexical/algorithm.rs @@ -0,0 +1,110 @@ +// Adapted from https://github.com/Alexhuszagh/rust-lexical. + +use crate::lexical::algorithm::*; +use crate::lexical::num::Float; + +#[test] +fn float_fast_path_test() { + // valid + let mantissa = (1 << f32::MANTISSA_SIZE) - 1; + let (min_exp, max_exp) = f32::exponent_limit(); + for exp in min_exp..=max_exp { + let f = fast_path::(mantissa, exp); + assert!(f.is_some(), "should be valid {:?}.", (mantissa, exp)); + } + + // Check slightly above valid exponents + let f = fast_path::(123, 15); + assert_eq!(f, Some(1.23e+17)); + + // Exponent is 1 too high, pushes over the mantissa. + let f = fast_path::(123, 16); + assert!(f.is_none()); + + // Mantissa is too large, checked_mul should overflow. + let f = fast_path::(mantissa, 11); + assert!(f.is_none()); + + // invalid exponents + let (min_exp, max_exp) = f32::exponent_limit(); + let f = fast_path::(mantissa, min_exp - 1); + assert!(f.is_none(), "exponent under min_exp"); + + let f = fast_path::(mantissa, max_exp + 1); + assert!(f.is_none(), "exponent above max_exp"); +} + +#[test] +fn double_fast_path_test() { + // valid + let mantissa = (1 << f64::MANTISSA_SIZE) - 1; + let (min_exp, max_exp) = f64::exponent_limit(); + for exp in min_exp..=max_exp { + let f = fast_path::(mantissa, exp); + assert!(f.is_some(), "should be valid {:?}.", (mantissa, exp)); + } + + // invalid exponents + let (min_exp, max_exp) = f64::exponent_limit(); + let f = fast_path::(mantissa, min_exp - 1); + assert!(f.is_none(), "exponent under min_exp"); + + let f = fast_path::(mantissa, max_exp + 1); + assert!(f.is_none(), "exponent above max_exp"); + + assert_eq!( + Some(0.04628372940652459), + fast_path::(4628372940652459, -17) + ); + assert_eq!(None, fast_path::(26383446160308229, -272)); +} + +#[test] +fn moderate_path_test() { + let (f, valid) = moderate_path::(1234567890, -1, false); + assert!(valid, "should be valid"); + assert_eq!(f.into_float::(), 123456789.0); + + let (f, valid) = moderate_path::(1234567891, -1, false); + assert!(valid, "should be valid"); + assert_eq!(f.into_float::(), 123456789.1); + + let (f, valid) = moderate_path::(12345678912, -2, false); + assert!(valid, "should be valid"); + assert_eq!(f.into_float::(), 123456789.12); + + let (f, valid) = moderate_path::(123456789123, -3, false); + assert!(valid, "should be valid"); + assert_eq!(f.into_float::(), 123456789.123); + + let (f, valid) = moderate_path::(1234567891234, -4, false); + assert!(valid, "should be valid"); + assert_eq!(f.into_float::(), 123456789.1234); + + let (f, valid) = moderate_path::(12345678912345, -5, false); + assert!(valid, "should be valid"); + assert_eq!(f.into_float::(), 123456789.12345); + + let (f, valid) = moderate_path::(123456789123456, -6, false); + assert!(valid, "should be valid"); + assert_eq!(f.into_float::(), 123456789.123456); + + let (f, valid) = moderate_path::(1234567891234567, -7, false); + assert!(valid, "should be valid"); + assert_eq!(f.into_float::(), 123456789.1234567); + + let (f, valid) = moderate_path::(12345678912345679, -8, false); + assert!(valid, "should be valid"); + assert_eq!(f.into_float::(), 123456789.12345679); + + let (f, valid) = moderate_path::(4628372940652459, -17, false); + assert!(valid, "should be valid"); + assert_eq!(f.into_float::(), 0.04628372940652459); + + let (f, valid) = moderate_path::(26383446160308229, -272, false); + assert!(valid, "should be valid"); + assert_eq!(f.into_float::(), 2.6383446160308229e-256); + + let (_, valid) = moderate_path::(26383446160308230, -272, false); + assert!(!valid, "should be invalid"); +} diff --git a/vendor/serde_json/tests/lexical/exponent.rs b/vendor/serde_json/tests/lexical/exponent.rs new file mode 100644 index 0000000..c109ff0 --- /dev/null +++ b/vendor/serde_json/tests/lexical/exponent.rs @@ -0,0 +1,36 @@ +// Adapted from https://github.com/Alexhuszagh/rust-lexical. + +use crate::lexical::exponent::*; + +#[test] +fn scientific_exponent_test() { + // 0 digits in the integer + assert_eq!(scientific_exponent(0, 0, 5), -6); + assert_eq!(scientific_exponent(10, 0, 5), 4); + assert_eq!(scientific_exponent(-10, 0, 5), -16); + + // >0 digits in the integer + assert_eq!(scientific_exponent(0, 1, 5), 0); + assert_eq!(scientific_exponent(0, 2, 5), 1); + assert_eq!(scientific_exponent(0, 2, 20), 1); + assert_eq!(scientific_exponent(10, 2, 20), 11); + assert_eq!(scientific_exponent(-10, 2, 20), -9); + + // Underflow + assert_eq!(scientific_exponent(i32::MIN, 0, 0), i32::MIN); + assert_eq!(scientific_exponent(i32::MIN, 0, 5), i32::MIN); + + // Overflow + assert_eq!(scientific_exponent(i32::MAX, 0, 0), i32::MAX - 1); + assert_eq!(scientific_exponent(i32::MAX, 5, 0), i32::MAX); +} + +#[test] +fn mantissa_exponent_test() { + assert_eq!(mantissa_exponent(10, 5, 0), 5); + assert_eq!(mantissa_exponent(0, 5, 0), -5); + assert_eq!(mantissa_exponent(i32::MAX, 5, 0), i32::MAX - 5); + assert_eq!(mantissa_exponent(i32::MAX, 0, 5), i32::MAX); + assert_eq!(mantissa_exponent(i32::MIN, 5, 0), i32::MIN); + assert_eq!(mantissa_exponent(i32::MIN, 0, 5), i32::MIN + 5); +} diff --git a/vendor/serde_json/tests/lexical/float.rs b/vendor/serde_json/tests/lexical/float.rs new file mode 100644 index 0000000..c87e7e1 --- /dev/null +++ b/vendor/serde_json/tests/lexical/float.rs @@ -0,0 +1,581 @@ +// Adapted from https://github.com/Alexhuszagh/rust-lexical. + +use crate::lexical::float::ExtendedFloat; +use crate::lexical::rounding::round_nearest_tie_even; +use std::{f32, f64}; + +// NORMALIZE + +fn check_normalize(mant: u64, exp: i32, shift: u32, r_mant: u64, r_exp: i32) { + let mut x = ExtendedFloat { mant, exp }; + assert_eq!(x.normalize(), shift); + assert_eq!( + x, + ExtendedFloat { + mant: r_mant, + exp: r_exp + } + ); +} + +#[test] +fn normalize_test() { + // F32 + // 0 + check_normalize(0, 0, 0, 0, 0); + + // min value + check_normalize(1, -149, 63, 9223372036854775808, -212); + + // 1.0e-40 + check_normalize(71362, -149, 47, 10043308644012916736, -196); + + // 1.0e-20 + check_normalize(12379400, -90, 40, 13611294244890214400, -130); + + // 1.0 + check_normalize(8388608, -23, 40, 9223372036854775808, -63); + + // 1e20 + check_normalize(11368684, 43, 40, 12500000250510966784, 3); + + // max value + check_normalize(16777213, 104, 40, 18446740775174668288, 64); + + // F64 + + // min value + check_normalize(1, -1074, 63, 9223372036854775808, -1137); + + // 1.0e-250 + check_normalize(6448907850777164, -883, 11, 13207363278391631872, -894); + + // 1.0e-150 + check_normalize(7371020360979573, -551, 11, 15095849699286165504, -562); + + // 1.0e-45 + check_normalize(6427752177035961, -202, 11, 13164036458569648128, -213); + + // 1.0e-40 + check_normalize(4903985730770844, -185, 11, 10043362776618688512, -196); + + // 1.0e-20 + check_normalize(6646139978924579, -119, 11, 13611294676837537792, -130); + + // 1.0 + check_normalize(4503599627370496, -52, 11, 9223372036854775808, -63); + + // 1e20 + check_normalize(6103515625000000, 14, 11, 12500000000000000000, 3); + + // 1e40 + check_normalize(8271806125530277, 80, 11, 16940658945086007296, 69); + + // 1e150 + check_normalize(5503284107318959, 446, 11, 11270725851789228032, 435); + + // 1e250 + check_normalize(6290184345309700, 778, 11, 12882297539194265600, 767); + + // max value + check_normalize(9007199254740991, 971, 11, 18446744073709549568, 960); +} + +// ROUND + +fn check_round_to_f32(mant: u64, exp: i32, r_mant: u64, r_exp: i32) { + let mut x = ExtendedFloat { mant, exp }; + x.round_to_native::(round_nearest_tie_even); + assert_eq!( + x, + ExtendedFloat { + mant: r_mant, + exp: r_exp + } + ); +} + +#[test] +fn round_to_f32_test() { + // This is lossy, so some of these values are **slightly** rounded. + + // underflow + check_round_to_f32(9223372036854775808, -213, 0, -149); + + // min value + check_round_to_f32(9223372036854775808, -212, 1, -149); + + // 1.0e-40 + check_round_to_f32(10043308644012916736, -196, 71362, -149); + + // 1.0e-20 + check_round_to_f32(13611294244890214400, -130, 12379400, -90); + + // 1.0 + check_round_to_f32(9223372036854775808, -63, 8388608, -23); + + // 1e20 + check_round_to_f32(12500000250510966784, 3, 11368684, 43); + + // max value + check_round_to_f32(18446740775174668288, 64, 16777213, 104); + + // overflow + check_round_to_f32(18446740775174668288, 65, 16777213, 105); +} + +fn check_round_to_f64(mant: u64, exp: i32, r_mant: u64, r_exp: i32) { + let mut x = ExtendedFloat { mant, exp }; + x.round_to_native::(round_nearest_tie_even); + assert_eq!( + x, + ExtendedFloat { + mant: r_mant, + exp: r_exp + } + ); +} + +#[test] +fn round_to_f64_test() { + // This is lossy, so some of these values are **slightly** rounded. + + // underflow + check_round_to_f64(9223372036854775808, -1138, 0, -1074); + + // min value + check_round_to_f64(9223372036854775808, -1137, 1, -1074); + + // 1.0e-250 + check_round_to_f64(15095849699286165504, -562, 7371020360979573, -551); + + // 1.0e-150 + check_round_to_f64(15095849699286165504, -562, 7371020360979573, -551); + + // 1.0e-45 + check_round_to_f64(13164036458569648128, -213, 6427752177035961, -202); + + // 1.0e-40 + check_round_to_f64(10043362776618688512, -196, 4903985730770844, -185); + + // 1.0e-20 + check_round_to_f64(13611294676837537792, -130, 6646139978924579, -119); + + // 1.0 + check_round_to_f64(9223372036854775808, -63, 4503599627370496, -52); + + // 1e20 + check_round_to_f64(12500000000000000000, 3, 6103515625000000, 14); + + // 1e40 + check_round_to_f64(16940658945086007296, 69, 8271806125530277, 80); + + // 1e150 + check_round_to_f64(11270725851789228032, 435, 5503284107318959, 446); + + // 1e250 + check_round_to_f64(12882297539194265600, 767, 6290184345309700, 778); + + // max value + check_round_to_f64(18446744073709549568, 960, 9007199254740991, 971); + + // Bug fixes + // 1.2345e-308 + check_round_to_f64(10234494226754558294, -1086, 2498655817078750, -1074); +} + +fn assert_normalized_eq(mut x: ExtendedFloat, mut y: ExtendedFloat) { + x.normalize(); + y.normalize(); + assert_eq!(x, y); +} + +#[test] +fn from_float() { + let values: [f32; 26] = [ + 1e-40, 2e-40, 1e-35, 2e-35, 1e-30, 2e-30, 1e-25, 2e-25, 1e-20, 2e-20, 1e-15, 2e-15, 1e-10, + 2e-10, 1e-5, 2e-5, 1.0, 2.0, 1e5, 2e5, 1e10, 2e10, 1e15, 2e15, 1e20, 2e20, + ]; + for value in &values { + assert_normalized_eq( + ExtendedFloat::from_float(*value), + ExtendedFloat::from_float(*value as f64), + ); + } +} + +// TO + +// Sample of interesting numbers to check during standard test builds. +const INTEGERS: [u64; 32] = [ + 0, // 0x0 + 1, // 0x1 + 7, // 0x7 + 15, // 0xF + 112, // 0x70 + 119, // 0x77 + 127, // 0x7F + 240, // 0xF0 + 247, // 0xF7 + 255, // 0xFF + 2032, // 0x7F0 + 2039, // 0x7F7 + 2047, // 0x7FF + 4080, // 0xFF0 + 4087, // 0xFF7 + 4095, // 0xFFF + 65520, // 0xFFF0 + 65527, // 0xFFF7 + 65535, // 0xFFFF + 1048560, // 0xFFFF0 + 1048567, // 0xFFFF7 + 1048575, // 0xFFFFF + 16777200, // 0xFFFFF0 + 16777207, // 0xFFFFF7 + 16777215, // 0xFFFFFF + 268435440, // 0xFFFFFF0 + 268435447, // 0xFFFFFF7 + 268435455, // 0xFFFFFFF + 4294967280, // 0xFFFFFFF0 + 4294967287, // 0xFFFFFFF7 + 4294967295, // 0xFFFFFFFF + 18446744073709551615, // 0xFFFFFFFFFFFFFFFF +]; + +#[test] +fn to_f32_test() { + // underflow + let x = ExtendedFloat { + mant: 9223372036854775808, + exp: -213, + }; + assert_eq!(x.into_float::(), 0.0); + + // min value + let x = ExtendedFloat { + mant: 9223372036854775808, + exp: -212, + }; + assert_eq!(x.into_float::(), 1e-45); + + // 1.0e-40 + let x = ExtendedFloat { + mant: 10043308644012916736, + exp: -196, + }; + assert_eq!(x.into_float::(), 1e-40); + + // 1.0e-20 + let x = ExtendedFloat { + mant: 13611294244890214400, + exp: -130, + }; + assert_eq!(x.into_float::(), 1e-20); + + // 1.0 + let x = ExtendedFloat { + mant: 9223372036854775808, + exp: -63, + }; + assert_eq!(x.into_float::(), 1.0); + + // 1e20 + let x = ExtendedFloat { + mant: 12500000250510966784, + exp: 3, + }; + assert_eq!(x.into_float::(), 1e20); + + // max value + let x = ExtendedFloat { + mant: 18446740775174668288, + exp: 64, + }; + assert_eq!(x.into_float::(), 3.402823e38); + + // almost max, high exp + let x = ExtendedFloat { + mant: 1048575, + exp: 108, + }; + assert_eq!(x.into_float::(), 3.4028204e38); + + // max value + 1 + let x = ExtendedFloat { + mant: 16777216, + exp: 104, + }; + assert_eq!(x.into_float::(), f32::INFINITY); + + // max value + 1 + let x = ExtendedFloat { + mant: 1048576, + exp: 108, + }; + assert_eq!(x.into_float::(), f32::INFINITY); + + // 1e40 + let x = ExtendedFloat { + mant: 16940658945086007296, + exp: 69, + }; + assert_eq!(x.into_float::(), f32::INFINITY); + + // Integers. + for int in &INTEGERS { + let fp = ExtendedFloat { mant: *int, exp: 0 }; + assert_eq!(fp.into_float::(), *int as f32, "{:?} as f32", *int); + } +} + +#[test] +fn to_f64_test() { + // underflow + let x = ExtendedFloat { + mant: 9223372036854775808, + exp: -1138, + }; + assert_eq!(x.into_float::(), 0.0); + + // min value + let x = ExtendedFloat { + mant: 9223372036854775808, + exp: -1137, + }; + assert_eq!(x.into_float::(), 5e-324); + + // 1.0e-250 + let x = ExtendedFloat { + mant: 13207363278391631872, + exp: -894, + }; + assert_eq!(x.into_float::(), 1e-250); + + // 1.0e-150 + let x = ExtendedFloat { + mant: 15095849699286165504, + exp: -562, + }; + assert_eq!(x.into_float::(), 1e-150); + + // 1.0e-45 + let x = ExtendedFloat { + mant: 13164036458569648128, + exp: -213, + }; + assert_eq!(x.into_float::(), 1e-45); + + // 1.0e-40 + let x = ExtendedFloat { + mant: 10043362776618688512, + exp: -196, + }; + assert_eq!(x.into_float::(), 1e-40); + + // 1.0e-20 + let x = ExtendedFloat { + mant: 13611294676837537792, + exp: -130, + }; + assert_eq!(x.into_float::(), 1e-20); + + // 1.0 + let x = ExtendedFloat { + mant: 9223372036854775808, + exp: -63, + }; + assert_eq!(x.into_float::(), 1.0); + + // 1e20 + let x = ExtendedFloat { + mant: 12500000000000000000, + exp: 3, + }; + assert_eq!(x.into_float::(), 1e20); + + // 1e40 + let x = ExtendedFloat { + mant: 16940658945086007296, + exp: 69, + }; + assert_eq!(x.into_float::(), 1e40); + + // 1e150 + let x = ExtendedFloat { + mant: 11270725851789228032, + exp: 435, + }; + assert_eq!(x.into_float::(), 1e150); + + // 1e250 + let x = ExtendedFloat { + mant: 12882297539194265600, + exp: 767, + }; + assert_eq!(x.into_float::(), 1e250); + + // max value + let x = ExtendedFloat { + mant: 9007199254740991, + exp: 971, + }; + assert_eq!(x.into_float::(), 1.7976931348623157e308); + + // max value + let x = ExtendedFloat { + mant: 18446744073709549568, + exp: 960, + }; + assert_eq!(x.into_float::(), 1.7976931348623157e308); + + // overflow + let x = ExtendedFloat { + mant: 9007199254740992, + exp: 971, + }; + assert_eq!(x.into_float::(), f64::INFINITY); + + // overflow + let x = ExtendedFloat { + mant: 18446744073709549568, + exp: 961, + }; + assert_eq!(x.into_float::(), f64::INFINITY); + + // Underflow + // Adapted from failures in strtod. + let x = ExtendedFloat { + exp: -1139, + mant: 18446744073709550712, + }; + assert_eq!(x.into_float::(), 0.0); + + let x = ExtendedFloat { + exp: -1139, + mant: 18446744073709551460, + }; + assert_eq!(x.into_float::(), 0.0); + + let x = ExtendedFloat { + exp: -1138, + mant: 9223372036854776103, + }; + assert_eq!(x.into_float::(), 5e-324); + + // Integers. + for int in &INTEGERS { + let fp = ExtendedFloat { mant: *int, exp: 0 }; + assert_eq!(fp.into_float::(), *int as f64, "{:?} as f64", *int); + } +} + +// OPERATIONS + +fn check_mul(a: ExtendedFloat, b: ExtendedFloat, c: ExtendedFloat) { + let r = a.mul(&b); + assert_eq!(r, c); +} + +#[test] +fn mul_test() { + // Normalized (64-bit mantissa) + let a = ExtendedFloat { + mant: 13164036458569648128, + exp: -213, + }; + let b = ExtendedFloat { + mant: 9223372036854775808, + exp: -62, + }; + let c = ExtendedFloat { + mant: 6582018229284824064, + exp: -211, + }; + check_mul(a, b, c); + + // Check with integers + // 64-bit mantissa + let mut a = ExtendedFloat { mant: 10, exp: 0 }; + let mut b = ExtendedFloat { mant: 10, exp: 0 }; + a.normalize(); + b.normalize(); + assert_eq!(a.mul(&b).into_float::(), 100.0); + + // Check both values need high bits set. + let a = ExtendedFloat { + mant: 1 << 32, + exp: -31, + }; + let b = ExtendedFloat { + mant: 1 << 32, + exp: -31, + }; + assert_eq!(a.mul(&b).into_float::(), 4.0); + + // Check both values need high bits set. + let a = ExtendedFloat { + mant: 10 << 31, + exp: -31, + }; + let b = ExtendedFloat { + mant: 10 << 31, + exp: -31, + }; + assert_eq!(a.mul(&b).into_float::(), 100.0); +} + +fn check_imul(mut a: ExtendedFloat, b: ExtendedFloat, c: ExtendedFloat) { + a.imul(&b); + assert_eq!(a, c); +} + +#[test] +fn imul_test() { + // Normalized (64-bit mantissa) + let a = ExtendedFloat { + mant: 13164036458569648128, + exp: -213, + }; + let b = ExtendedFloat { + mant: 9223372036854775808, + exp: -62, + }; + let c = ExtendedFloat { + mant: 6582018229284824064, + exp: -211, + }; + check_imul(a, b, c); + + // Check with integers + // 64-bit mantissa + let mut a = ExtendedFloat { mant: 10, exp: 0 }; + let mut b = ExtendedFloat { mant: 10, exp: 0 }; + a.normalize(); + b.normalize(); + a.imul(&b); + assert_eq!(a.into_float::(), 100.0); + + // Check both values need high bits set. + let mut a = ExtendedFloat { + mant: 1 << 32, + exp: -31, + }; + let b = ExtendedFloat { + mant: 1 << 32, + exp: -31, + }; + a.imul(&b); + assert_eq!(a.into_float::(), 4.0); + + // Check both values need high bits set. + let mut a = ExtendedFloat { + mant: 10 << 31, + exp: -31, + }; + let b = ExtendedFloat { + mant: 10 << 31, + exp: -31, + }; + a.imul(&b); + assert_eq!(a.into_float::(), 100.0); +} diff --git a/vendor/serde_json/tests/lexical/math.rs b/vendor/serde_json/tests/lexical/math.rs new file mode 100644 index 0000000..454eaa6 --- /dev/null +++ b/vendor/serde_json/tests/lexical/math.rs @@ -0,0 +1,211 @@ +// Adapted from https://github.com/Alexhuszagh/rust-lexical. + +use crate::lexical::math::{Limb, Math}; +use std::cmp; + +#[derive(Clone, Default)] +struct Bigint { + data: Vec, +} + +impl Math for Bigint { + fn data(&self) -> &Vec { + &self.data + } + + fn data_mut(&mut self) -> &mut Vec { + &mut self.data + } +} + +#[cfg(fast_arithmetic = "32")] +pub(crate) fn from_u32(x: &[u32]) -> Vec { + x.iter().cloned().collect() +} + +#[cfg(fast_arithmetic = "64")] +pub(crate) fn from_u32(x: &[u32]) -> Vec { + let mut v = Vec::::default(); + for xi in x.chunks(2) { + match xi.len() { + 1 => v.push(xi[0] as u64), + 2 => v.push(((xi[1] as u64) << 32) | (xi[0] as u64)), + _ => unreachable!(), + } + } + + v +} + +#[test] +fn compare_test() { + // Simple + let x = Bigint { + data: from_u32(&[1]), + }; + let y = Bigint { + data: from_u32(&[2]), + }; + assert_eq!(x.compare(&y), cmp::Ordering::Less); + assert_eq!(x.compare(&x), cmp::Ordering::Equal); + assert_eq!(y.compare(&x), cmp::Ordering::Greater); + + // Check asymmetric + let x = Bigint { + data: from_u32(&[5, 1]), + }; + let y = Bigint { + data: from_u32(&[2]), + }; + assert_eq!(x.compare(&y), cmp::Ordering::Greater); + assert_eq!(x.compare(&x), cmp::Ordering::Equal); + assert_eq!(y.compare(&x), cmp::Ordering::Less); + + // Check when we use reverse ordering properly. + let x = Bigint { + data: from_u32(&[5, 1, 9]), + }; + let y = Bigint { + data: from_u32(&[6, 2, 8]), + }; + assert_eq!(x.compare(&y), cmp::Ordering::Greater); + assert_eq!(x.compare(&x), cmp::Ordering::Equal); + assert_eq!(y.compare(&x), cmp::Ordering::Less); + + // Complex scenario, check it properly uses reverse ordering. + let x = Bigint { + data: from_u32(&[0, 1, 9]), + }; + let y = Bigint { + data: from_u32(&[4294967295, 0, 9]), + }; + assert_eq!(x.compare(&y), cmp::Ordering::Greater); + assert_eq!(x.compare(&x), cmp::Ordering::Equal); + assert_eq!(y.compare(&x), cmp::Ordering::Less); +} + +#[test] +fn hi64_test() { + assert_eq!(Bigint::from_u64(0xA).hi64(), (0xA000000000000000, false)); + assert_eq!(Bigint::from_u64(0xAB).hi64(), (0xAB00000000000000, false)); + assert_eq!( + Bigint::from_u64(0xAB00000000).hi64(), + (0xAB00000000000000, false) + ); + assert_eq!( + Bigint::from_u64(0xA23456789A).hi64(), + (0xA23456789A000000, false) + ); +} + +#[test] +fn bit_length_test() { + let x = Bigint { + data: from_u32(&[0, 0, 0, 1]), + }; + assert_eq!(x.bit_length(), 97); + + let x = Bigint { + data: from_u32(&[0, 0, 0, 3]), + }; + assert_eq!(x.bit_length(), 98); + + let x = Bigint { + data: from_u32(&[1 << 31]), + }; + assert_eq!(x.bit_length(), 32); +} + +#[test] +fn iadd_small_test() { + // Overflow check (single) + // This should set all the internal data values to 0, the top + // value to (1<<31), and the bottom value to (4>>1). + // This is because the max_value + 1 leads to all 0s, we set the + // topmost bit to 1. + let mut x = Bigint { + data: from_u32(&[4294967295]), + }; + x.iadd_small(5); + assert_eq!(x.data, from_u32(&[4, 1])); + + // No overflow, single value + let mut x = Bigint { + data: from_u32(&[5]), + }; + x.iadd_small(7); + assert_eq!(x.data, from_u32(&[12])); + + // Single carry, internal overflow + let mut x = Bigint::from_u64(0x80000000FFFFFFFF); + x.iadd_small(7); + assert_eq!(x.data, from_u32(&[6, 0x80000001])); + + // Double carry, overflow + let mut x = Bigint::from_u64(0xFFFFFFFFFFFFFFFF); + x.iadd_small(7); + assert_eq!(x.data, from_u32(&[6, 0, 1])); +} + +#[test] +fn imul_small_test() { + // No overflow check, 1-int. + let mut x = Bigint { + data: from_u32(&[5]), + }; + x.imul_small(7); + assert_eq!(x.data, from_u32(&[35])); + + // No overflow check, 2-ints. + let mut x = Bigint::from_u64(0x4000000040000); + x.imul_small(5); + assert_eq!(x.data, from_u32(&[0x00140000, 0x140000])); + + // Overflow, 1 carry. + let mut x = Bigint { + data: from_u32(&[0x33333334]), + }; + x.imul_small(5); + assert_eq!(x.data, from_u32(&[4, 1])); + + // Overflow, 1 carry, internal. + let mut x = Bigint::from_u64(0x133333334); + x.imul_small(5); + assert_eq!(x.data, from_u32(&[4, 6])); + + // Overflow, 2 carries. + let mut x = Bigint::from_u64(0x3333333333333334); + x.imul_small(5); + assert_eq!(x.data, from_u32(&[4, 0, 1])); +} + +#[test] +fn shl_test() { + // Pattern generated via `''.join(["1" +"0"*i for i in range(20)])` + let mut big = Bigint { + data: from_u32(&[0xD2210408]), + }; + big.ishl(5); + assert_eq!(big.data, from_u32(&[0x44208100, 0x1A])); + big.ishl(32); + assert_eq!(big.data, from_u32(&[0, 0x44208100, 0x1A])); + big.ishl(27); + assert_eq!(big.data, from_u32(&[0, 0, 0xD2210408])); + + // 96-bits of previous pattern + let mut big = Bigint { + data: from_u32(&[0x20020010, 0x8040100, 0xD2210408]), + }; + big.ishl(5); + assert_eq!(big.data, from_u32(&[0x400200, 0x802004, 0x44208101, 0x1A])); + big.ishl(32); + assert_eq!( + big.data, + from_u32(&[0, 0x400200, 0x802004, 0x44208101, 0x1A]) + ); + big.ishl(27); + assert_eq!( + big.data, + from_u32(&[0, 0, 0x20020010, 0x8040100, 0xD2210408]) + ); +} diff --git a/vendor/serde_json/tests/lexical/num.rs b/vendor/serde_json/tests/lexical/num.rs new file mode 100644 index 0000000..e7d0865 --- /dev/null +++ b/vendor/serde_json/tests/lexical/num.rs @@ -0,0 +1,75 @@ +// Adapted from https://github.com/Alexhuszagh/rust-lexical. + +use crate::lexical::num::{AsPrimitive, Float, Integer, Number}; + +fn check_as_primitive(t: T) { + let _: u32 = t.as_u32(); + let _: u64 = t.as_u64(); + let _: u128 = t.as_u128(); + let _: usize = t.as_usize(); + let _: f32 = t.as_f32(); + let _: f64 = t.as_f64(); +} + +#[test] +fn as_primitive_test() { + check_as_primitive(1u32); + check_as_primitive(1u64); + check_as_primitive(1u128); + check_as_primitive(1usize); + check_as_primitive(1f32); + check_as_primitive(1f64); +} + +fn check_number(x: T, y: T) { + // Copy, partialeq, partialord + let _ = x; + assert!(x < y); + assert!(x != y); + + // Operations + let _ = y + x; + + // Conversions already tested. +} + +#[test] +fn number_test() { + check_number(1u32, 5); + check_number(1u64, 5); + check_number(1u128, 5); + check_number(1usize, 5); + check_number(1f32, 5.0); + check_number(1f64, 5.0); +} + +fn check_integer(x: T) { + // Bitwise operations + let _ = x & T::ZERO; +} + +#[test] +fn integer_test() { + check_integer(65u32); + check_integer(65u64); + check_integer(65u128); + check_integer(65usize); +} + +fn check_float(x: T) { + // Check functions + let _ = x.pow10(5); + let _ = x.to_bits(); + assert!(T::from_bits(x.to_bits()) == x); + + // Check properties + let _ = x.to_bits() & T::EXPONENT_MASK; + let _ = x.to_bits() & T::HIDDEN_BIT_MASK; + let _ = x.to_bits() & T::MANTISSA_MASK; +} + +#[test] +fn float_test() { + check_float(123f32); + check_float(123f64); +} diff --git a/vendor/serde_json/tests/lexical/parse.rs b/vendor/serde_json/tests/lexical/parse.rs new file mode 100644 index 0000000..03ec1a9 --- /dev/null +++ b/vendor/serde_json/tests/lexical/parse.rs @@ -0,0 +1,204 @@ +// Adapted from https://github.com/Alexhuszagh/rust-lexical. + +use crate::lexical::num::Float; +use crate::lexical::{parse_concise_float, parse_truncated_float}; +use core::f64; +use core::fmt::Debug; + +fn check_concise_float(mantissa: u64, exponent: i32, expected: F) +where + F: Float + Debug, +{ + assert_eq!(parse_concise_float::(mantissa, exponent), expected); +} + +fn check_truncated_float(integer: &str, fraction: &str, exponent: i32, expected: F) +where + F: Float + Debug, +{ + let integer = integer.as_bytes(); + let fraction = fraction.as_bytes(); + assert_eq!( + parse_truncated_float::(integer, fraction, exponent), + expected, + ); +} + +#[test] +fn parse_f32_test() { + check_concise_float(0, 0, 0.0_f32); + check_concise_float(12345, -4, 1.2345_f32); + check_concise_float(12345, -3, 12.345_f32); + check_concise_float(123456789, -4, 12345.6789_f32); + check_concise_float(12345, 6, 1.2345e10_f32); + check_concise_float(12345, -42, 1.2345e-38_f32); + + // Check expected rounding, using borderline cases. + // Round-down, halfway + check_concise_float(16777216, 0, 16777216.0_f32); + check_concise_float(16777217, 0, 16777216.0_f32); + check_concise_float(16777218, 0, 16777218.0_f32); + check_concise_float(33554432, 0, 33554432.0_f32); + check_concise_float(33554434, 0, 33554432.0_f32); + check_concise_float(33554436, 0, 33554436.0_f32); + check_concise_float(17179869184, 0, 17179869184.0_f32); + check_concise_float(17179870208, 0, 17179869184.0_f32); + check_concise_float(17179871232, 0, 17179871232.0_f32); + + // Round-up, halfway + check_concise_float(16777218, 0, 16777218.0_f32); + check_concise_float(16777219, 0, 16777220.0_f32); + check_concise_float(16777220, 0, 16777220.0_f32); + + check_concise_float(33554436, 0, 33554436.0_f32); + check_concise_float(33554438, 0, 33554440.0_f32); + check_concise_float(33554440, 0, 33554440.0_f32); + + check_concise_float(17179871232, 0, 17179871232.0_f32); + check_concise_float(17179872256, 0, 17179873280.0_f32); + check_concise_float(17179873280, 0, 17179873280.0_f32); + + // Round-up, above halfway + check_concise_float(33554435, 0, 33554436.0_f32); + check_concise_float(17179870209, 0, 17179871232.0_f32); + + // Check exactly halfway, round-up at halfway + check_truncated_float("1", "00000017881393432617187499", 0, 1.0000001_f32); + check_truncated_float("1", "000000178813934326171875", 0, 1.0000002_f32); + check_truncated_float("1", "00000017881393432617187501", 0, 1.0000002_f32); +} + +#[test] +fn parse_f64_test() { + check_concise_float(0, 0, 0.0_f64); + check_concise_float(12345, -4, 1.2345_f64); + check_concise_float(12345, -3, 12.345_f64); + check_concise_float(123456789, -4, 12345.6789_f64); + check_concise_float(12345, 6, 1.2345e10_f64); + check_concise_float(12345, -312, 1.2345e-308_f64); + + // Check expected rounding, using borderline cases. + // Round-down, halfway + check_concise_float(9007199254740992, 0, 9007199254740992.0_f64); + check_concise_float(9007199254740993, 0, 9007199254740992.0_f64); + check_concise_float(9007199254740994, 0, 9007199254740994.0_f64); + + check_concise_float(18014398509481984, 0, 18014398509481984.0_f64); + check_concise_float(18014398509481986, 0, 18014398509481984.0_f64); + check_concise_float(18014398509481988, 0, 18014398509481988.0_f64); + + check_concise_float(9223372036854775808, 0, 9223372036854775808.0_f64); + check_concise_float(9223372036854776832, 0, 9223372036854775808.0_f64); + check_concise_float(9223372036854777856, 0, 9223372036854777856.0_f64); + + check_truncated_float( + "11417981541647679048466287755595961091061972992", + "", + 0, + 11417981541647679048466287755595961091061972992.0_f64, + ); + check_truncated_float( + "11417981541647680316116887983825362587765178368", + "", + 0, + 11417981541647679048466287755595961091061972992.0_f64, + ); + check_truncated_float( + "11417981541647681583767488212054764084468383744", + "", + 0, + 11417981541647681583767488212054764084468383744.0_f64, + ); + + // Round-up, halfway + check_concise_float(9007199254740994, 0, 9007199254740994.0_f64); + check_concise_float(9007199254740995, 0, 9007199254740996.0_f64); + check_concise_float(9007199254740996, 0, 9007199254740996.0_f64); + + check_concise_float(18014398509481988, 0, 18014398509481988.0_f64); + check_concise_float(18014398509481990, 0, 18014398509481992.0_f64); + check_concise_float(18014398509481992, 0, 18014398509481992.0_f64); + + check_concise_float(9223372036854777856, 0, 9223372036854777856.0_f64); + check_concise_float(9223372036854778880, 0, 9223372036854779904.0_f64); + check_concise_float(9223372036854779904, 0, 9223372036854779904.0_f64); + + check_truncated_float( + "11417981541647681583767488212054764084468383744", + "", + 0, + 11417981541647681583767488212054764084468383744.0_f64, + ); + check_truncated_float( + "11417981541647682851418088440284165581171589120", + "", + 0, + 11417981541647684119068688668513567077874794496.0_f64, + ); + check_truncated_float( + "11417981541647684119068688668513567077874794496", + "", + 0, + 11417981541647684119068688668513567077874794496.0_f64, + ); + + // Round-up, above halfway + check_concise_float(9223372036854776833, 0, 9223372036854777856.0_f64); + check_truncated_float( + "11417981541647680316116887983825362587765178369", + "", + 0, + 11417981541647681583767488212054764084468383744.0_f64, + ); + + // Rounding error + // Adapted from failures in strtod. + check_concise_float(22250738585072014, -324, 2.2250738585072014e-308_f64); + check_truncated_float("2", "2250738585072011360574097967091319759348195463516456480234261097248222220210769455165295239081350879141491589130396211068700864386945946455276572074078206217433799881410632673292535522868813721490129811224514518898490572223072852551331557550159143974763979834118019993239625482890171070818506906306666559949382757725720157630626906633326475653000092458883164330377797918696120494973903778297049050510806099407302629371289589500035837999672072543043602840788957717961509455167482434710307026091446215722898802581825451803257070188608721131280795122334262883686223215037756666225039825343359745688844239002654981983854879482922068947216898310996983658468140228542433306603398508864458040010349339704275671864433837704860378616227717385456230658746790140867233276367187499", -308, 2.225073858507201e-308_f64); + check_truncated_float("2", "22507385850720113605740979670913197593481954635164564802342610972482222202107694551652952390813508791414915891303962110687008643869459464552765720740782062174337998814106326732925355228688137214901298112245145188984905722230728525513315575501591439747639798341180199932396254828901710708185069063066665599493827577257201576306269066333264756530000924588831643303777979186961204949739037782970490505108060994073026293712895895000358379996720725430436028407889577179615094551674824347103070260914462157228988025818254518032570701886087211312807951223342628836862232150377566662250398253433597456888442390026549819838548794829220689472168983109969836584681402285424333066033985088644580400103493397042756718644338377048603786162277173854562306587467901408672332763671875", -308, 2.2250738585072014e-308_f64); + check_truncated_float("2", "2250738585072011360574097967091319759348195463516456480234261097248222220210769455165295239081350879141491589130396211068700864386945946455276572074078206217433799881410632673292535522868813721490129811224514518898490572223072852551331557550159143974763979834118019993239625482890171070818506906306666559949382757725720157630626906633326475653000092458883164330377797918696120494973903778297049050510806099407302629371289589500035837999672072543043602840788957717961509455167482434710307026091446215722898802581825451803257070188608721131280795122334262883686223215037756666225039825343359745688844239002654981983854879482922068947216898310996983658468140228542433306603398508864458040010349339704275671864433837704860378616227717385456230658746790140867233276367187501", -308, 2.2250738585072014e-308_f64); + check_truncated_float("179769313486231580793728971405303415079934132710037826936173778980444968292764750946649017977587207096330286416692887910946555547851940402630657488671505820681908902000708383676273854845817711531764475730270069855571366959622842914819860834936475292719074168444365510704342711559699508093042880177904174497791", "9999999999999999999999999999999999999999999999999999999999999999999999", 0, 1.7976931348623157e+308_f64); + check_truncated_float("7", "4109846876186981626485318930233205854758970392148714663837852375101326090531312779794975454245398856969484704316857659638998506553390969459816219401617281718945106978546710679176872575177347315553307795408549809608457500958111373034747658096871009590975442271004757307809711118935784838675653998783503015228055934046593739791790738723868299395818481660169122019456499931289798411362062484498678713572180352209017023903285791732520220528974020802906854021606612375549983402671300035812486479041385743401875520901590172592547146296175134159774938718574737870961645638908718119841271673056017045493004705269590165763776884908267986972573366521765567941072508764337560846003984904972149117463085539556354188641513168478436313080237596295773983001708984374999", -324, 5.0e-324_f64); + check_truncated_float("7", "4109846876186981626485318930233205854758970392148714663837852375101326090531312779794975454245398856969484704316857659638998506553390969459816219401617281718945106978546710679176872575177347315553307795408549809608457500958111373034747658096871009590975442271004757307809711118935784838675653998783503015228055934046593739791790738723868299395818481660169122019456499931289798411362062484498678713572180352209017023903285791732520220528974020802906854021606612375549983402671300035812486479041385743401875520901590172592547146296175134159774938718574737870961645638908718119841271673056017045493004705269590165763776884908267986972573366521765567941072508764337560846003984904972149117463085539556354188641513168478436313080237596295773983001708984375", -324, 1.0e-323_f64); + check_truncated_float("7", "4109846876186981626485318930233205854758970392148714663837852375101326090531312779794975454245398856969484704316857659638998506553390969459816219401617281718945106978546710679176872575177347315553307795408549809608457500958111373034747658096871009590975442271004757307809711118935784838675653998783503015228055934046593739791790738723868299395818481660169122019456499931289798411362062484498678713572180352209017023903285791732520220528974020802906854021606612375549983402671300035812486479041385743401875520901590172592547146296175134159774938718574737870961645638908718119841271673056017045493004705269590165763776884908267986972573366521765567941072508764337560846003984904972149117463085539556354188641513168478436313080237596295773983001708984375001", -324, 1.0e-323_f64); + check_truncated_float("", "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000024703282292062327208828439643411068618252990130716238221279284125033775363510437593264991818081799618989828234772285886546332835517796989819938739800539093906315035659515570226392290858392449105184435931802849936536152500319370457678249219365623669863658480757001585769269903706311928279558551332927834338409351978015531246597263579574622766465272827220056374006485499977096599470454020828166226237857393450736339007967761930577506740176324673600968951340535537458516661134223766678604162159680461914467291840300530057530849048765391711386591646239524912623653881879636239373280423891018672348497668235089863388587925628302755995657524455507255189313690836254779186948667994968324049705821028513185451396213837722826145437693412532098591327667236328125", 0, 0.0_f64); + + // Rounding error + // Adapted from: + // https://www.exploringbinary.com/how-glibc-strtod-works/ + check_truncated_float("", "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000022250738585072008890245868760858598876504231122409594654935248025624400092282356951787758888037591552642309780950434312085877387158357291821993020294379224223559819827501242041788969571311791082261043971979604000454897391938079198936081525613113376149842043271751033627391549782731594143828136275113838604094249464942286316695429105080201815926642134996606517803095075913058719846423906068637102005108723282784678843631944515866135041223479014792369585208321597621066375401613736583044193603714778355306682834535634005074073040135602968046375918583163124224521599262546494300836851861719422417646455137135420132217031370496583210154654068035397417906022589503023501937519773030945763173210852507299305089761582519159720757232455434770912461317493580281734466552734375", 0, 2.2250738585072011e-308_f64); + + // Rounding error + // Adapted from test-parse-random failures. + check_concise_float(1009, -31, 1.009e-28_f64); + check_concise_float(18294, 304, f64::INFINITY); + + // Rounding error + // Adapted from a @dangrabcad's issue #20. + check_concise_float(7689539722041643, 149, 7.689539722041643e164_f64); + check_truncated_float("768953972204164300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "", 0, 7.689539722041643e164_f64); + check_truncated_float("768953972204164300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "0", 0, 7.689539722041643e164_f64); + + // Check other cases similar to @dangrabcad's issue #20. + check_truncated_float("9223372036854776833", "0", 0, 9223372036854777856.0_f64); + check_truncated_float( + "11417981541647680316116887983825362587765178369", + "0", + 0, + 11417981541647681583767488212054764084468383744.0_f64, + ); + check_concise_float(90071992547409950, -1, 9007199254740996.0_f64); + check_concise_float(180143985094819900, -1, 18014398509481992.0_f64); + check_truncated_float("9223372036854778880", "0", 0, 9223372036854779904.0_f64); + check_truncated_float( + "11417981541647682851418088440284165581171589120", + "0", + 0, + 11417981541647684119068688668513567077874794496.0_f64, + ); + + // Check other cases ostensibly identified via proptest. + check_truncated_float("71610528364411830000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "0", 0, 71610528364411830000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.0_f64); + check_truncated_float("126769393745745060000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "0", 0, 126769393745745060000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.0_f64); + check_truncated_float("38652960461239320000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "0", 0, 38652960461239320000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.0_f64); +} diff --git a/vendor/serde_json/tests/lexical/rounding.rs b/vendor/serde_json/tests/lexical/rounding.rs new file mode 100644 index 0000000..7ea1771 --- /dev/null +++ b/vendor/serde_json/tests/lexical/rounding.rs @@ -0,0 +1,316 @@ +// Adapted from https://github.com/Alexhuszagh/rust-lexical. + +use crate::lexical::float::ExtendedFloat; +use crate::lexical::num::Float; +use crate::lexical::rounding::*; + +// MASKS + +#[test] +fn lower_n_mask_test() { + assert_eq!(lower_n_mask(0u64), 0b0); + assert_eq!(lower_n_mask(1u64), 0b1); + assert_eq!(lower_n_mask(2u64), 0b11); + assert_eq!(lower_n_mask(10u64), 0b1111111111); + assert_eq!(lower_n_mask(32u64), 0b11111111111111111111111111111111); +} + +#[test] +fn lower_n_halfway_test() { + assert_eq!(lower_n_halfway(0u64), 0b0); + assert_eq!(lower_n_halfway(1u64), 0b1); + assert_eq!(lower_n_halfway(2u64), 0b10); + assert_eq!(lower_n_halfway(10u64), 0b1000000000); + assert_eq!(lower_n_halfway(32u64), 0b10000000000000000000000000000000); +} + +#[test] +fn nth_bit_test() { + assert_eq!(nth_bit(0u64), 0b1); + assert_eq!(nth_bit(1u64), 0b10); + assert_eq!(nth_bit(2u64), 0b100); + assert_eq!(nth_bit(10u64), 0b10000000000); + assert_eq!(nth_bit(31u64), 0b10000000000000000000000000000000); +} + +#[test] +fn internal_n_mask_test() { + assert_eq!(internal_n_mask(1u64, 0u64), 0b0); + assert_eq!(internal_n_mask(1u64, 1u64), 0b1); + assert_eq!(internal_n_mask(2u64, 1u64), 0b10); + assert_eq!(internal_n_mask(4u64, 2u64), 0b1100); + assert_eq!(internal_n_mask(10u64, 2u64), 0b1100000000); + assert_eq!(internal_n_mask(10u64, 4u64), 0b1111000000); + assert_eq!( + internal_n_mask(32u64, 4u64), + 0b11110000000000000000000000000000 + ); +} + +// NEAREST ROUNDING + +#[test] +fn round_nearest_test() { + // Check exactly halfway (b'1100000') + let mut fp = ExtendedFloat { mant: 0x60, exp: 0 }; + let (above, halfway) = round_nearest(&mut fp, 6); + assert!(!above); + assert!(halfway); + assert_eq!(fp.mant, 1); + + // Check above halfway (b'1100001') + let mut fp = ExtendedFloat { mant: 0x61, exp: 0 }; + let (above, halfway) = round_nearest(&mut fp, 6); + assert!(above); + assert!(!halfway); + assert_eq!(fp.mant, 1); + + // Check below halfway (b'1011111') + let mut fp = ExtendedFloat { mant: 0x5F, exp: 0 }; + let (above, halfway) = round_nearest(&mut fp, 6); + assert!(!above); + assert!(!halfway); + assert_eq!(fp.mant, 1); +} + +// DIRECTED ROUNDING + +#[test] +fn round_downward_test() { + // b0000000 + let mut fp = ExtendedFloat { mant: 0x00, exp: 0 }; + round_downward(&mut fp, 6); + assert_eq!(fp.mant, 0); + + // b1000000 + let mut fp = ExtendedFloat { mant: 0x40, exp: 0 }; + round_downward(&mut fp, 6); + assert_eq!(fp.mant, 1); + + // b1100000 + let mut fp = ExtendedFloat { mant: 0x60, exp: 0 }; + round_downward(&mut fp, 6); + assert_eq!(fp.mant, 1); + + // b1110000 + let mut fp = ExtendedFloat { mant: 0x70, exp: 0 }; + round_downward(&mut fp, 6); + assert_eq!(fp.mant, 1); +} + +#[test] +fn round_nearest_tie_even_test() { + // Check round-up, halfway + let mut fp = ExtendedFloat { mant: 0x60, exp: 0 }; + round_nearest_tie_even(&mut fp, 6); + assert_eq!(fp.mant, 2); + + // Check round-down, halfway + let mut fp = ExtendedFloat { mant: 0x20, exp: 0 }; + round_nearest_tie_even(&mut fp, 6); + assert_eq!(fp.mant, 0); + + // Check round-up, above halfway + let mut fp = ExtendedFloat { mant: 0x61, exp: 0 }; + round_nearest_tie_even(&mut fp, 6); + assert_eq!(fp.mant, 2); + + let mut fp = ExtendedFloat { mant: 0x21, exp: 0 }; + round_nearest_tie_even(&mut fp, 6); + assert_eq!(fp.mant, 1); + + // Check round-down, below halfway + let mut fp = ExtendedFloat { mant: 0x5F, exp: 0 }; + round_nearest_tie_even(&mut fp, 6); + assert_eq!(fp.mant, 1); + + let mut fp = ExtendedFloat { mant: 0x1F, exp: 0 }; + round_nearest_tie_even(&mut fp, 6); + assert_eq!(fp.mant, 0); +} + +// HIGH-LEVEL + +#[test] +fn round_to_float_test() { + // Denormal + let mut fp = ExtendedFloat { + mant: 1 << 63, + exp: f64::DENORMAL_EXPONENT - 15, + }; + round_to_float::(&mut fp, round_nearest_tie_even); + assert_eq!(fp.mant, 1 << 48); + assert_eq!(fp.exp, f64::DENORMAL_EXPONENT); + + // Halfway, round-down (b'1000000000000000000000000000000000000000000000000000010000000000') + let mut fp = ExtendedFloat { + mant: 0x8000000000000400, + exp: -63, + }; + round_to_float::(&mut fp, round_nearest_tie_even); + assert_eq!(fp.mant, 1 << 52); + assert_eq!(fp.exp, -52); + + // Halfway, round-up (b'1000000000000000000000000000000000000000000000000000110000000000') + let mut fp = ExtendedFloat { + mant: 0x8000000000000C00, + exp: -63, + }; + round_to_float::(&mut fp, round_nearest_tie_even); + assert_eq!(fp.mant, (1 << 52) + 2); + assert_eq!(fp.exp, -52); + + // Above halfway + let mut fp = ExtendedFloat { + mant: 0x8000000000000401, + exp: -63, + }; + round_to_float::(&mut fp, round_nearest_tie_even); + assert_eq!(fp.mant, (1 << 52) + 1); + assert_eq!(fp.exp, -52); + + let mut fp = ExtendedFloat { + mant: 0x8000000000000C01, + exp: -63, + }; + round_to_float::(&mut fp, round_nearest_tie_even); + assert_eq!(fp.mant, (1 << 52) + 2); + assert_eq!(fp.exp, -52); + + // Below halfway + let mut fp = ExtendedFloat { + mant: 0x80000000000003FF, + exp: -63, + }; + round_to_float::(&mut fp, round_nearest_tie_even); + assert_eq!(fp.mant, 1 << 52); + assert_eq!(fp.exp, -52); + + let mut fp = ExtendedFloat { + mant: 0x8000000000000BFF, + exp: -63, + }; + round_to_float::(&mut fp, round_nearest_tie_even); + assert_eq!(fp.mant, (1 << 52) + 1); + assert_eq!(fp.exp, -52); +} + +#[test] +fn avoid_overflow_test() { + // Avoid overflow, fails by 1 + let mut fp = ExtendedFloat { + mant: 0xFFFFFFFFFFFF, + exp: f64::MAX_EXPONENT + 5, + }; + avoid_overflow::(&mut fp); + assert_eq!(fp.mant, 0xFFFFFFFFFFFF); + assert_eq!(fp.exp, f64::MAX_EXPONENT + 5); + + // Avoid overflow, succeeds + let mut fp = ExtendedFloat { + mant: 0xFFFFFFFFFFFF, + exp: f64::MAX_EXPONENT + 4, + }; + avoid_overflow::(&mut fp); + assert_eq!(fp.mant, 0x1FFFFFFFFFFFE0); + assert_eq!(fp.exp, f64::MAX_EXPONENT - 1); +} + +#[test] +fn round_to_native_test() { + // Overflow + let mut fp = ExtendedFloat { + mant: 0xFFFFFFFFFFFF, + exp: f64::MAX_EXPONENT + 4, + }; + round_to_native::(&mut fp, round_nearest_tie_even); + assert_eq!(fp.mant, 0x1FFFFFFFFFFFE0); + assert_eq!(fp.exp, f64::MAX_EXPONENT - 1); + + // Need denormal + let mut fp = ExtendedFloat { + mant: 1, + exp: f64::DENORMAL_EXPONENT + 48, + }; + round_to_native::(&mut fp, round_nearest_tie_even); + assert_eq!(fp.mant, 1 << 48); + assert_eq!(fp.exp, f64::DENORMAL_EXPONENT); + + // Halfway, round-down (b'10000000000000000000000000000000000000000000000000000100000') + let mut fp = ExtendedFloat { + mant: 0x400000000000020, + exp: -58, + }; + round_to_native::(&mut fp, round_nearest_tie_even); + assert_eq!(fp.mant, 1 << 52); + assert_eq!(fp.exp, -52); + + // Halfway, round-up (b'10000000000000000000000000000000000000000000000000001100000') + let mut fp = ExtendedFloat { + mant: 0x400000000000060, + exp: -58, + }; + round_to_native::(&mut fp, round_nearest_tie_even); + assert_eq!(fp.mant, (1 << 52) + 2); + assert_eq!(fp.exp, -52); + + // Above halfway + let mut fp = ExtendedFloat { + mant: 0x400000000000021, + exp: -58, + }; + round_to_native::(&mut fp, round_nearest_tie_even); + assert_eq!(fp.mant, (1 << 52) + 1); + assert_eq!(fp.exp, -52); + + let mut fp = ExtendedFloat { + mant: 0x400000000000061, + exp: -58, + }; + round_to_native::(&mut fp, round_nearest_tie_even); + assert_eq!(fp.mant, (1 << 52) + 2); + assert_eq!(fp.exp, -52); + + // Below halfway + let mut fp = ExtendedFloat { + mant: 0x40000000000001F, + exp: -58, + }; + round_to_native::(&mut fp, round_nearest_tie_even); + assert_eq!(fp.mant, 1 << 52); + assert_eq!(fp.exp, -52); + + let mut fp = ExtendedFloat { + mant: 0x40000000000005F, + exp: -58, + }; + round_to_native::(&mut fp, round_nearest_tie_even); + assert_eq!(fp.mant, (1 << 52) + 1); + assert_eq!(fp.exp, -52); + + // Underflow + // Adapted from failures in strtod. + let mut fp = ExtendedFloat { + exp: -1139, + mant: 18446744073709550712, + }; + round_to_native::(&mut fp, round_nearest_tie_even); + assert_eq!(fp.mant, 0); + assert_eq!(fp.exp, 0); + + let mut fp = ExtendedFloat { + exp: -1139, + mant: 18446744073709551460, + }; + round_to_native::(&mut fp, round_nearest_tie_even); + assert_eq!(fp.mant, 0); + assert_eq!(fp.exp, 0); + + let mut fp = ExtendedFloat { + exp: -1138, + mant: 9223372036854776103, + }; + round_to_native::(&mut fp, round_nearest_tie_even); + assert_eq!(fp.mant, 1); + assert_eq!(fp.exp, -1074); +} diff --git a/vendor/serde_json/tests/macros/mod.rs b/vendor/serde_json/tests/macros/mod.rs new file mode 100644 index 0000000..aaf820f --- /dev/null +++ b/vendor/serde_json/tests/macros/mod.rs @@ -0,0 +1,61 @@ +#![allow(unused_macro_rules)] + +macro_rules! json_str { + ([]) => { + "[]" + }; + ([ $e0:tt $(, $e:tt)* $(,)? ]) => { + concat!("[", + json_str!($e0), + $(",", json_str!($e),)* + "]") + }; + ({}) => { + "{}" + }; + ({ $k0:tt : $v0:tt $(, $k:tt : $v:tt)* $(,)? }) => { + concat!("{", + stringify!($k0), ":", json_str!($v0), + $(",", stringify!($k), ":", json_str!($v),)* + "}") + }; + (($other:tt)) => { + $other + }; + ($other:tt) => { + stringify!($other) + }; +} + +macro_rules! pretty_str { + ($json:tt) => { + pretty_str_impl!("", $json) + }; +} + +macro_rules! pretty_str_impl { + ($indent:expr, []) => { + "[]" + }; + ($indent:expr, [ $e0:tt $(, $e:tt)* $(,)? ]) => { + concat!("[\n ", + $indent, pretty_str_impl!(concat!(" ", $indent), $e0), + $(",\n ", $indent, pretty_str_impl!(concat!(" ", $indent), $e),)* + "\n", $indent, "]") + }; + ($indent:expr, {}) => { + "{}" + }; + ($indent:expr, { $k0:tt : $v0:tt $(, $k:tt : $v:tt)* $(,)? }) => { + concat!("{\n ", + $indent, stringify!($k0), ": ", pretty_str_impl!(concat!(" ", $indent), $v0), + $(",\n ", $indent, stringify!($k), ": ", pretty_str_impl!(concat!(" ", $indent), $v),)* + "\n", $indent, "}") + }; + ($indent:expr, ($other:tt)) => { + $other + }; + ($indent:expr, $other:tt) => { + stringify!($other) + }; +} diff --git a/vendor/serde_json/tests/map.rs b/vendor/serde_json/tests/map.rs new file mode 100644 index 0000000..aa3cb25 --- /dev/null +++ b/vendor/serde_json/tests/map.rs @@ -0,0 +1,57 @@ +use serde_json::{from_str, Map, Value}; + +#[test] +fn test_preserve_order() { + // Sorted order + #[cfg(not(feature = "preserve_order"))] + const EXPECTED: &[&str] = &["a", "b", "c"]; + + // Insertion order + #[cfg(feature = "preserve_order")] + const EXPECTED: &[&str] = &["b", "a", "c"]; + + let v: Value = from_str(r#"{"b":null,"a":null,"c":null}"#).unwrap(); + let keys: Vec<_> = v.as_object().unwrap().keys().collect(); + assert_eq!(keys, EXPECTED); +} + +#[test] +#[cfg(feature = "preserve_order")] +fn test_shift_insert() { + let mut v: Value = from_str(r#"{"b":null,"a":null,"c":null}"#).unwrap(); + let val = v.as_object_mut().unwrap(); + val.shift_insert(0, "d".to_owned(), Value::Null); + + let keys: Vec<_> = val.keys().collect(); + assert_eq!(keys, &["d", "b", "a", "c"]); +} + +#[test] +fn test_append() { + // Sorted order + #[cfg(not(feature = "preserve_order"))] + const EXPECTED: &[&str] = &["a", "b", "c"]; + + // Insertion order + #[cfg(feature = "preserve_order")] + const EXPECTED: &[&str] = &["b", "a", "c"]; + + let mut v: Value = from_str(r#"{"b":null,"a":null,"c":null}"#).unwrap(); + let val = v.as_object_mut().unwrap(); + let mut m = Map::new(); + m.append(val); + let keys: Vec<_> = m.keys().collect(); + + assert_eq!(keys, EXPECTED); + assert!(val.is_empty()); +} + +#[test] +fn test_retain() { + let mut v: Value = from_str(r#"{"b":null,"a":null,"c":null}"#).unwrap(); + let val = v.as_object_mut().unwrap(); + val.retain(|k, _| k.as_str() != "b"); + + let keys: Vec<_> = val.keys().collect(); + assert_eq!(keys, &["a", "c"]); +} diff --git a/vendor/serde_json/tests/regression.rs b/vendor/serde_json/tests/regression.rs new file mode 100644 index 0000000..22cca82 --- /dev/null +++ b/vendor/serde_json/tests/regression.rs @@ -0,0 +1,5 @@ +#![allow(clippy::needless_lifetimes)] + +mod regression { + automod::dir!("tests/regression"); +} diff --git a/vendor/serde_json/tests/regression/issue1004.rs b/vendor/serde_json/tests/regression/issue1004.rs new file mode 100644 index 0000000..c09fb96 --- /dev/null +++ b/vendor/serde_json/tests/regression/issue1004.rs @@ -0,0 +1,12 @@ +#![cfg(feature = "arbitrary_precision")] + +#[test] +fn test() { + let float = 5.55f32; + let value = serde_json::to_value(float).unwrap(); + let json = serde_json::to_string(&value).unwrap(); + + // If the f32 were cast to f64 by Value before serialization, then this + // would incorrectly serialize as 5.550000190734863. + assert_eq!(json, "5.55"); +} diff --git a/vendor/serde_json/tests/regression/issue520.rs b/vendor/serde_json/tests/regression/issue520.rs new file mode 100644 index 0000000..730ecc6 --- /dev/null +++ b/vendor/serde_json/tests/regression/issue520.rs @@ -0,0 +1,20 @@ +#![allow(clippy::float_cmp)] + +use serde_derive::{Deserialize, Serialize}; + +#[derive(Serialize, Deserialize, Debug)] +#[serde(tag = "type", content = "data")] +enum E { + Float(f32), +} + +#[test] +fn test() { + let e = E::Float(159.1); + let v = serde_json::to_value(e).unwrap(); + let e = serde_json::from_value::(v).unwrap(); + + match e { + E::Float(f) => assert_eq!(f, 159.1), + } +} diff --git a/vendor/serde_json/tests/regression/issue795.rs b/vendor/serde_json/tests/regression/issue795.rs new file mode 100644 index 0000000..411e8af --- /dev/null +++ b/vendor/serde_json/tests/regression/issue795.rs @@ -0,0 +1,62 @@ +#![allow(clippy::assertions_on_result_states)] + +use serde::de::{ + Deserialize, Deserializer, EnumAccess, IgnoredAny, MapAccess, VariantAccess, Visitor, +}; +use serde_json::json; +use std::fmt; + +#[derive(Debug)] +pub enum Enum { + Variant { + #[allow(dead_code)] + x: u8, + }, +} + +impl<'de> Deserialize<'de> for Enum { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + struct EnumVisitor; + + impl<'de> Visitor<'de> for EnumVisitor { + type Value = Enum; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("enum Enum") + } + + fn visit_enum(self, data: A) -> Result + where + A: EnumAccess<'de>, + { + let (IgnoredAny, variant) = data.variant()?; + variant.struct_variant(&["x"], self) + } + + fn visit_map(self, mut data: A) -> Result + where + A: MapAccess<'de>, + { + let mut x = 0; + if let Some((IgnoredAny, value)) = data.next_entry()? { + x = value; + } + Ok(Enum::Variant { x }) + } + } + + deserializer.deserialize_enum("Enum", &["Variant"], EnumVisitor) + } +} + +#[test] +fn test() { + let s = r#" {"Variant":{"x":0,"y":0}} "#; + assert!(serde_json::from_str::(s).is_err()); + + let j = json!({"Variant":{"x":0,"y":0}}); + assert!(serde_json::from_value::(j).is_err()); +} diff --git a/vendor/serde_json/tests/regression/issue845.rs b/vendor/serde_json/tests/regression/issue845.rs new file mode 100644 index 0000000..7b6564d --- /dev/null +++ b/vendor/serde_json/tests/regression/issue845.rs @@ -0,0 +1,74 @@ +#![allow(clippy::trait_duplication_in_bounds)] // https://github.com/rust-lang/rust-clippy/issues/8757 + +use serde::{Deserialize, Deserializer}; +use std::fmt::{self, Display}; +use std::marker::PhantomData; +use std::str::FromStr; + +pub struct NumberVisitor { + marker: PhantomData, +} + +impl<'de, T> serde::de::Visitor<'de> for NumberVisitor +where + T: TryFrom + TryFrom + FromStr, + >::Error: Display, + >::Error: Display, + ::Err: Display, +{ + type Value = T; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("an integer or string") + } + + fn visit_u64(self, v: u64) -> Result + where + E: serde::de::Error, + { + T::try_from(v).map_err(serde::de::Error::custom) + } + + fn visit_i64(self, v: i64) -> Result + where + E: serde::de::Error, + { + T::try_from(v).map_err(serde::de::Error::custom) + } + + fn visit_str(self, v: &str) -> Result + where + E: serde::de::Error, + { + v.parse().map_err(serde::de::Error::custom) + } +} + +fn deserialize_integer_or_string<'de, D, T>(deserializer: D) -> Result +where + D: Deserializer<'de>, + T: TryFrom + TryFrom + FromStr, + >::Error: Display, + >::Error: Display, + ::Err: Display, +{ + deserializer.deserialize_any(NumberVisitor { + marker: PhantomData, + }) +} + +#[derive(Deserialize, Debug)] +pub struct Struct { + #[serde(deserialize_with = "deserialize_integer_or_string")] + #[allow(dead_code)] + pub i: i64, +} + +#[test] +fn test() { + let j = r#" {"i":100} "#; + println!("{:?}", serde_json::from_str::(j).unwrap()); + + let j = r#" {"i":"100"} "#; + println!("{:?}", serde_json::from_str::(j).unwrap()); +} diff --git a/vendor/serde_json/tests/regression/issue953.rs b/vendor/serde_json/tests/regression/issue953.rs new file mode 100644 index 0000000..771aa52 --- /dev/null +++ b/vendor/serde_json/tests/regression/issue953.rs @@ -0,0 +1,9 @@ +use serde_json::Value; + +#[test] +fn test() { + let x1 = serde_json::from_str::("18446744073709551615."); + assert!(x1.is_err()); + let x2 = serde_json::from_str::("18446744073709551616."); + assert!(x2.is_err()); +} diff --git a/vendor/serde_json/tests/stream.rs b/vendor/serde_json/tests/stream.rs new file mode 100644 index 0000000..fa52ced --- /dev/null +++ b/vendor/serde_json/tests/stream.rs @@ -0,0 +1,182 @@ +#![allow(clippy::assertions_on_result_states)] + +use serde_json::{json, Deserializer, Value}; + +// Rustfmt issue https://github.com/rust-lang-nursery/rustfmt/issues/2740 +#[rustfmt::skip] +macro_rules! test_stream { + ($data:expr, $ty:ty, |$stream:ident| $test:block) => { + { + let de = Deserializer::from_str($data); + let mut $stream = de.into_iter::<$ty>(); + assert_eq!($stream.byte_offset(), 0); + $test + } + { + let de = Deserializer::from_slice($data.as_bytes()); + let mut $stream = de.into_iter::<$ty>(); + assert_eq!($stream.byte_offset(), 0); + $test + } + { + let mut bytes = $data.as_bytes(); + let de = Deserializer::from_reader(&mut bytes); + let mut $stream = de.into_iter::<$ty>(); + assert_eq!($stream.byte_offset(), 0); + $test + } + }; +} + +#[test] +fn test_json_stream_newlines() { + let data = "{\"x\":39} {\"x\":40}{\"x\":41}\n{\"x\":42}"; + + test_stream!(data, Value, |stream| { + assert_eq!(stream.next().unwrap().unwrap()["x"], 39); + assert_eq!(stream.byte_offset(), 8); + + assert_eq!(stream.next().unwrap().unwrap()["x"], 40); + assert_eq!(stream.byte_offset(), 17); + + assert_eq!(stream.next().unwrap().unwrap()["x"], 41); + assert_eq!(stream.byte_offset(), 25); + + assert_eq!(stream.next().unwrap().unwrap()["x"], 42); + assert_eq!(stream.byte_offset(), 34); + + assert!(stream.next().is_none()); + assert_eq!(stream.byte_offset(), 34); + }); +} + +#[test] +fn test_json_stream_trailing_whitespaces() { + let data = "{\"x\":42} \t\n"; + + test_stream!(data, Value, |stream| { + assert_eq!(stream.next().unwrap().unwrap()["x"], 42); + assert_eq!(stream.byte_offset(), 8); + + assert!(stream.next().is_none()); + assert_eq!(stream.byte_offset(), 11); + }); +} + +#[test] +fn test_json_stream_truncated() { + let data = "{\"x\":40}\n{\"x\":"; + + test_stream!(data, Value, |stream| { + assert_eq!(stream.next().unwrap().unwrap()["x"], 40); + assert_eq!(stream.byte_offset(), 8); + + assert!(stream.next().unwrap().unwrap_err().is_eof()); + assert_eq!(stream.byte_offset(), 9); + }); +} + +#[test] +fn test_json_stream_truncated_decimal() { + let data = "{\"x\":4."; + + test_stream!(data, Value, |stream| { + assert!(stream.next().unwrap().unwrap_err().is_eof()); + assert_eq!(stream.byte_offset(), 0); + }); +} + +#[test] +fn test_json_stream_truncated_negative() { + let data = "{\"x\":-"; + + test_stream!(data, Value, |stream| { + assert!(stream.next().unwrap().unwrap_err().is_eof()); + assert_eq!(stream.byte_offset(), 0); + }); +} + +#[test] +fn test_json_stream_truncated_exponent() { + let data = "{\"x\":4e"; + + test_stream!(data, Value, |stream| { + assert!(stream.next().unwrap().unwrap_err().is_eof()); + assert_eq!(stream.byte_offset(), 0); + }); +} + +#[test] +fn test_json_stream_empty() { + let data = ""; + + test_stream!(data, Value, |stream| { + assert!(stream.next().is_none()); + assert_eq!(stream.byte_offset(), 0); + }); +} + +#[test] +fn test_json_stream_primitive() { + let data = "{} true{}1[]\nfalse\"hey\"2 "; + + test_stream!(data, Value, |stream| { + assert_eq!(stream.next().unwrap().unwrap(), json!({})); + assert_eq!(stream.byte_offset(), 2); + + assert_eq!(stream.next().unwrap().unwrap(), true); + assert_eq!(stream.byte_offset(), 7); + + assert_eq!(stream.next().unwrap().unwrap(), json!({})); + assert_eq!(stream.byte_offset(), 9); + + assert_eq!(stream.next().unwrap().unwrap(), 1); + assert_eq!(stream.byte_offset(), 10); + + assert_eq!(stream.next().unwrap().unwrap(), json!([])); + assert_eq!(stream.byte_offset(), 12); + + assert_eq!(stream.next().unwrap().unwrap(), false); + assert_eq!(stream.byte_offset(), 18); + + assert_eq!(stream.next().unwrap().unwrap(), "hey"); + assert_eq!(stream.byte_offset(), 23); + + assert_eq!(stream.next().unwrap().unwrap(), 2); + assert_eq!(stream.byte_offset(), 24); + + assert!(stream.next().is_none()); + assert_eq!(stream.byte_offset(), 25); + }); +} + +#[test] +fn test_json_stream_invalid_literal() { + let data = "truefalse"; + + test_stream!(data, Value, |stream| { + let second = stream.next().unwrap().unwrap_err(); + assert_eq!(second.to_string(), "trailing characters at line 1 column 5"); + }); +} + +#[test] +fn test_json_stream_invalid_number() { + let data = "1true"; + + test_stream!(data, Value, |stream| { + let second = stream.next().unwrap().unwrap_err(); + assert_eq!(second.to_string(), "trailing characters at line 1 column 2"); + }); +} + +#[test] +fn test_error() { + let data = "true wrong false"; + + test_stream!(data, Value, |stream| { + assert_eq!(stream.next().unwrap().unwrap(), true); + assert!(stream.next().unwrap().is_err()); + assert!(stream.next().is_none()); + }); +} diff --git a/vendor/serde_json/tests/test.rs b/vendor/serde_json/tests/test.rs new file mode 100644 index 0000000..d41a233 --- /dev/null +++ b/vendor/serde_json/tests/test.rs @@ -0,0 +1,2560 @@ +#![allow( + clippy::assertions_on_result_states, + clippy::byte_char_slices, + clippy::cast_precision_loss, + clippy::derive_partial_eq_without_eq, + clippy::excessive_precision, + clippy::float_cmp, + clippy::incompatible_msrv, // https://github.com/rust-lang/rust-clippy/issues/12257 + clippy::items_after_statements, + clippy::large_digit_groups, + clippy::let_underscore_untyped, + clippy::shadow_unrelated, + clippy::too_many_lines, + clippy::unreadable_literal, + clippy::unseparated_literal_suffix, + clippy::vec_init_then_push, + clippy::zero_sized_map_values +)] + +#[macro_use] +mod macros; + +#[cfg(feature = "raw_value")] +use ref_cast::RefCast; +use serde::de::{self, IgnoredAny, IntoDeserializer}; +use serde::ser::{self, SerializeMap, SerializeSeq, Serializer}; +use serde::{Deserialize, Serialize}; +use serde_bytes::{ByteBuf, Bytes}; +#[cfg(feature = "raw_value")] +use serde_json::value::RawValue; +use serde_json::{ + from_reader, from_slice, from_str, from_value, json, to_string, to_string_pretty, to_value, + to_vec, Deserializer, Number, Value, +}; +use std::collections::BTreeMap; +#[cfg(feature = "raw_value")] +use std::collections::HashMap; +use std::fmt::{self, Debug}; +use std::hash::BuildHasher; +#[cfg(feature = "raw_value")] +use std::hash::{Hash, Hasher}; +use std::io; +use std::iter; +use std::marker::PhantomData; +use std::mem; +use std::str::FromStr; +use std::{f32, f64}; + +macro_rules! treemap { + () => { + BTreeMap::new() + }; + ($($k:expr => $v:expr),+ $(,)?) => { + { + let mut m = BTreeMap::new(); + $( + m.insert($k, $v); + )+ + m + } + }; +} + +#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)] +#[serde(deny_unknown_fields)] +enum Animal { + Dog, + Frog(String, Vec), + Cat { age: usize, name: String }, + AntHive(Vec), +} + +#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)] +struct Inner { + a: (), + b: usize, + c: Vec, +} + +#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)] +struct Outer { + inner: Vec, +} + +fn test_encode_ok(errors: &[(T, &str)]) +where + T: PartialEq + Debug + ser::Serialize, +{ + for &(ref value, out) in errors { + let out = out.to_string(); + + let s = to_string(value).unwrap(); + assert_eq!(s, out); + + let v = to_value(value).unwrap(); + let s = to_string(&v).unwrap(); + assert_eq!(s, out); + } +} + +fn test_pretty_encode_ok(errors: &[(T, &str)]) +where + T: PartialEq + Debug + ser::Serialize, +{ + for &(ref value, out) in errors { + let out = out.to_string(); + + let s = to_string_pretty(value).unwrap(); + assert_eq!(s, out); + + let v = to_value(value).unwrap(); + let s = to_string_pretty(&v).unwrap(); + assert_eq!(s, out); + } +} + +#[test] +fn test_write_null() { + let tests = &[((), "null")]; + test_encode_ok(tests); + test_pretty_encode_ok(tests); +} + +#[test] +fn test_write_u64() { + let tests = &[(3u64, "3"), (u64::MAX, &u64::MAX.to_string())]; + test_encode_ok(tests); + test_pretty_encode_ok(tests); +} + +#[test] +fn test_write_i64() { + let tests = &[ + (3i64, "3"), + (-2i64, "-2"), + (-1234i64, "-1234"), + (i64::MIN, &i64::MIN.to_string()), + ]; + test_encode_ok(tests); + test_pretty_encode_ok(tests); +} + +#[test] +fn test_write_f64() { + let tests = &[ + (3.0, "3.0"), + (3.1, "3.1"), + (-1.5, "-1.5"), + (0.5, "0.5"), + (f64::MIN, "-1.7976931348623157e308"), + (f64::MAX, "1.7976931348623157e308"), + (f64::EPSILON, "2.220446049250313e-16"), + ]; + test_encode_ok(tests); + test_pretty_encode_ok(tests); +} + +#[test] +fn test_encode_nonfinite_float_yields_null() { + let v = to_value(f64::NAN.copysign(1.0)).unwrap(); + assert!(v.is_null()); + + let v = to_value(f64::NAN.copysign(-1.0)).unwrap(); + assert!(v.is_null()); + + let v = to_value(f64::INFINITY).unwrap(); + assert!(v.is_null()); + + let v = to_value(-f64::INFINITY).unwrap(); + assert!(v.is_null()); + + let v = to_value(f32::NAN.copysign(1.0)).unwrap(); + assert!(v.is_null()); + + let v = to_value(f32::NAN.copysign(-1.0)).unwrap(); + assert!(v.is_null()); + + let v = to_value(f32::INFINITY).unwrap(); + assert!(v.is_null()); + + let v = to_value(-f32::INFINITY).unwrap(); + assert!(v.is_null()); +} + +#[test] +fn test_write_str() { + let tests = &[("", "\"\""), ("foo", "\"foo\"")]; + test_encode_ok(tests); + test_pretty_encode_ok(tests); +} + +#[test] +fn test_write_bool() { + let tests = &[(true, "true"), (false, "false")]; + test_encode_ok(tests); + test_pretty_encode_ok(tests); +} + +#[test] +fn test_write_char() { + let tests = &[ + ('n', "\"n\""), + ('"', "\"\\\"\""), + ('\\', "\"\\\\\""), + ('/', "\"/\""), + ('\x08', "\"\\b\""), + ('\x0C', "\"\\f\""), + ('\n', "\"\\n\""), + ('\r', "\"\\r\""), + ('\t', "\"\\t\""), + ('\x0B', "\"\\u000b\""), + ('\u{3A3}', "\"\u{3A3}\""), + ]; + test_encode_ok(tests); + test_pretty_encode_ok(tests); +} + +#[test] +fn test_write_list() { + test_encode_ok(&[ + (vec![], "[]"), + (vec![true], "[true]"), + (vec![true, false], "[true,false]"), + ]); + + test_encode_ok(&[ + (vec![vec![], vec![], vec![]], "[[],[],[]]"), + (vec![vec![1, 2, 3], vec![], vec![]], "[[1,2,3],[],[]]"), + (vec![vec![], vec![1, 2, 3], vec![]], "[[],[1,2,3],[]]"), + (vec![vec![], vec![], vec![1, 2, 3]], "[[],[],[1,2,3]]"), + ]); + + test_pretty_encode_ok(&[ + (vec![vec![], vec![], vec![]], pretty_str!([[], [], []])), + ( + vec![vec![1, 2, 3], vec![], vec![]], + pretty_str!([[1, 2, 3], [], []]), + ), + ( + vec![vec![], vec![1, 2, 3], vec![]], + pretty_str!([[], [1, 2, 3], []]), + ), + ( + vec![vec![], vec![], vec![1, 2, 3]], + pretty_str!([[], [], [1, 2, 3]]), + ), + ]); + + test_pretty_encode_ok(&[ + (vec![], "[]"), + (vec![true], pretty_str!([true])), + (vec![true, false], pretty_str!([true, false])), + ]); + + let long_test_list = json!([false, null, ["foo\nbar", 3.5]]); + + test_encode_ok(&[( + long_test_list.clone(), + json_str!([false, null, ["foo\nbar", 3.5]]), + )]); + + test_pretty_encode_ok(&[( + long_test_list, + pretty_str!([false, null, ["foo\nbar", 3.5]]), + )]); +} + +#[test] +fn test_write_object() { + test_encode_ok(&[ + (treemap!(), "{}"), + (treemap!("a".to_owned() => true), "{\"a\":true}"), + ( + treemap!( + "a".to_owned() => true, + "b".to_owned() => false, + ), + "{\"a\":true,\"b\":false}", + ), + ]); + + test_encode_ok(&[ + ( + treemap![ + "a".to_owned() => treemap![], + "b".to_owned() => treemap![], + "c".to_owned() => treemap![], + ], + "{\"a\":{},\"b\":{},\"c\":{}}", + ), + ( + treemap![ + "a".to_owned() => treemap![ + "a".to_owned() => treemap!["a" => vec![1,2,3]], + "b".to_owned() => treemap![], + "c".to_owned() => treemap![], + ], + "b".to_owned() => treemap![], + "c".to_owned() => treemap![], + ], + "{\"a\":{\"a\":{\"a\":[1,2,3]},\"b\":{},\"c\":{}},\"b\":{},\"c\":{}}", + ), + ( + treemap![ + "a".to_owned() => treemap![], + "b".to_owned() => treemap![ + "a".to_owned() => treemap!["a" => vec![1,2,3]], + "b".to_owned() => treemap![], + "c".to_owned() => treemap![], + ], + "c".to_owned() => treemap![], + ], + "{\"a\":{},\"b\":{\"a\":{\"a\":[1,2,3]},\"b\":{},\"c\":{}},\"c\":{}}", + ), + ( + treemap![ + "a".to_owned() => treemap![], + "b".to_owned() => treemap![], + "c".to_owned() => treemap![ + "a".to_owned() => treemap!["a" => vec![1,2,3]], + "b".to_owned() => treemap![], + "c".to_owned() => treemap![], + ], + ], + "{\"a\":{},\"b\":{},\"c\":{\"a\":{\"a\":[1,2,3]},\"b\":{},\"c\":{}}}", + ), + ]); + + test_encode_ok(&[(treemap!['c' => ()], "{\"c\":null}")]); + + test_pretty_encode_ok(&[ + ( + treemap![ + "a".to_owned() => treemap![], + "b".to_owned() => treemap![], + "c".to_owned() => treemap![], + ], + pretty_str!({ + "a": {}, + "b": {}, + "c": {} + }), + ), + ( + treemap![ + "a".to_owned() => treemap![ + "a".to_owned() => treemap!["a" => vec![1,2,3]], + "b".to_owned() => treemap![], + "c".to_owned() => treemap![], + ], + "b".to_owned() => treemap![], + "c".to_owned() => treemap![], + ], + pretty_str!({ + "a": { + "a": { + "a": [ + 1, + 2, + 3 + ] + }, + "b": {}, + "c": {} + }, + "b": {}, + "c": {} + }), + ), + ( + treemap![ + "a".to_owned() => treemap![], + "b".to_owned() => treemap![ + "a".to_owned() => treemap!["a" => vec![1,2,3]], + "b".to_owned() => treemap![], + "c".to_owned() => treemap![], + ], + "c".to_owned() => treemap![], + ], + pretty_str!({ + "a": {}, + "b": { + "a": { + "a": [ + 1, + 2, + 3 + ] + }, + "b": {}, + "c": {} + }, + "c": {} + }), + ), + ( + treemap![ + "a".to_owned() => treemap![], + "b".to_owned() => treemap![], + "c".to_owned() => treemap![ + "a".to_owned() => treemap!["a" => vec![1,2,3]], + "b".to_owned() => treemap![], + "c".to_owned() => treemap![], + ], + ], + pretty_str!({ + "a": {}, + "b": {}, + "c": { + "a": { + "a": [ + 1, + 2, + 3 + ] + }, + "b": {}, + "c": {} + } + }), + ), + ]); + + test_pretty_encode_ok(&[ + (treemap!(), "{}"), + ( + treemap!("a".to_owned() => true), + pretty_str!({ + "a": true + }), + ), + ( + treemap!( + "a".to_owned() => true, + "b".to_owned() => false, + ), + pretty_str!( { + "a": true, + "b": false + }), + ), + ]); + + let complex_obj = json!({ + "b": [ + {"c": "\x0c\x1f\r"}, + {"d": ""} + ] + }); + + test_encode_ok(&[( + complex_obj.clone(), + json_str!({ + "b": [ + { + "c": (r#""\f\u001f\r""#) + }, + { + "d": "" + } + ] + }), + )]); + + test_pretty_encode_ok(&[( + complex_obj, + pretty_str!({ + "b": [ + { + "c": (r#""\f\u001f\r""#) + }, + { + "d": "" + } + ] + }), + )]); +} + +#[test] +fn test_write_tuple() { + test_encode_ok(&[((5,), "[5]")]); + + test_pretty_encode_ok(&[((5,), pretty_str!([5]))]); + + test_encode_ok(&[((5, (6, "abc")), "[5,[6,\"abc\"]]")]); + + test_pretty_encode_ok(&[((5, (6, "abc")), pretty_str!([5, [6, "abc"]]))]); +} + +#[test] +fn test_write_enum() { + test_encode_ok(&[ + (Animal::Dog, "\"Dog\""), + ( + Animal::Frog("Henry".to_owned(), vec![]), + "{\"Frog\":[\"Henry\",[]]}", + ), + ( + Animal::Frog("Henry".to_owned(), vec![349]), + "{\"Frog\":[\"Henry\",[349]]}", + ), + ( + Animal::Frog("Henry".to_owned(), vec![349, 102]), + "{\"Frog\":[\"Henry\",[349,102]]}", + ), + ( + Animal::Cat { + age: 5, + name: "Kate".to_owned(), + }, + "{\"Cat\":{\"age\":5,\"name\":\"Kate\"}}", + ), + ( + Animal::AntHive(vec!["Bob".to_owned(), "Stuart".to_owned()]), + "{\"AntHive\":[\"Bob\",\"Stuart\"]}", + ), + ]); + + test_pretty_encode_ok(&[ + (Animal::Dog, "\"Dog\""), + ( + Animal::Frog("Henry".to_owned(), vec![]), + pretty_str!({ + "Frog": [ + "Henry", + [] + ] + }), + ), + ( + Animal::Frog("Henry".to_owned(), vec![349]), + pretty_str!({ + "Frog": [ + "Henry", + [ + 349 + ] + ] + }), + ), + ( + Animal::Frog("Henry".to_owned(), vec![349, 102]), + pretty_str!({ + "Frog": [ + "Henry", + [ + 349, + 102 + ] + ] + }), + ), + ]); +} + +#[test] +fn test_write_option() { + test_encode_ok(&[(None, "null"), (Some("jodhpurs"), "\"jodhpurs\"")]); + + test_encode_ok(&[ + (None, "null"), + (Some(vec!["foo", "bar"]), "[\"foo\",\"bar\"]"), + ]); + + test_pretty_encode_ok(&[(None, "null"), (Some("jodhpurs"), "\"jodhpurs\"")]); + + test_pretty_encode_ok(&[ + (None, "null"), + (Some(vec!["foo", "bar"]), pretty_str!(["foo", "bar"])), + ]); +} + +#[test] +fn test_write_newtype_struct() { + #[derive(Serialize, PartialEq, Debug)] + struct Newtype(BTreeMap); + + let inner = Newtype(treemap!(String::from("inner") => 123)); + let outer = treemap!(String::from("outer") => to_value(&inner).unwrap()); + + test_encode_ok(&[(inner, r#"{"inner":123}"#)]); + + test_encode_ok(&[(outer, r#"{"outer":{"inner":123}}"#)]); +} + +#[test] +fn test_deserialize_number_to_untagged_enum() { + #[derive(Eq, PartialEq, Deserialize, Debug)] + #[serde(untagged)] + enum E { + N(i64), + } + + assert_eq!(E::N(0), E::deserialize(Number::from(0)).unwrap()); +} + +fn test_parse_ok(tests: Vec<(&str, T)>) +where + T: Clone + Debug + PartialEq + ser::Serialize + de::DeserializeOwned, +{ + for (s, value) in tests { + let v: T = from_str(s).unwrap(); + assert_eq!(v, value.clone()); + + let v: T = from_slice(s.as_bytes()).unwrap(); + assert_eq!(v, value.clone()); + + // Make sure we can deserialize into a `Value`. + let json_value: Value = from_str(s).unwrap(); + assert_eq!(json_value, to_value(&value).unwrap()); + + // Make sure we can deserialize from a `&Value`. + let v = T::deserialize(&json_value).unwrap(); + assert_eq!(v, value); + + // Make sure we can deserialize from a `Value`. + let v: T = from_value(json_value.clone()).unwrap(); + assert_eq!(v, value); + + // Make sure we can round trip back to `Value`. + let json_value2: Value = from_value(json_value.clone()).unwrap(); + assert_eq!(json_value2, json_value); + + // Make sure we can fully ignore. + let twoline = s.to_owned() + "\n3735928559"; + let mut de = Deserializer::from_str(&twoline); + IgnoredAny::deserialize(&mut de).unwrap(); + assert_eq!(0xDEAD_BEEF, u64::deserialize(&mut de).unwrap()); + + // Make sure every prefix is an EOF error, except that a prefix of a + // number may be a valid number. + if !json_value.is_number() { + for (i, _) in s.trim_end().char_indices() { + assert!(from_str::(&s[..i]).unwrap_err().is_eof()); + assert!(from_str::(&s[..i]).unwrap_err().is_eof()); + } + } + } +} + +// For testing representations that the deserializer accepts but the serializer +// never generates. These do not survive a round-trip through Value. +fn test_parse_unusual_ok(tests: Vec<(&str, T)>) +where + T: Clone + Debug + PartialEq + ser::Serialize + de::DeserializeOwned, +{ + for (s, value) in tests { + let v: T = from_str(s).unwrap(); + assert_eq!(v, value.clone()); + + let v: T = from_slice(s.as_bytes()).unwrap(); + assert_eq!(v, value.clone()); + } +} + +macro_rules! test_parse_err { + ($name:ident::<$($ty:ty),*>($arg:expr) => $expected:expr) => { + let actual = $name::<$($ty),*>($arg).unwrap_err().to_string(); + assert_eq!(actual, $expected, "unexpected {} error", stringify!($name)); + }; +} + +fn test_parse_err(errors: &[(&str, &'static str)]) +where + T: Debug + PartialEq + de::DeserializeOwned, +{ + for &(s, err) in errors { + test_parse_err!(from_str::(s) => err); + test_parse_err!(from_slice::(s.as_bytes()) => err); + } +} + +fn test_parse_slice_err(errors: &[(&[u8], &'static str)]) +where + T: Debug + PartialEq + de::DeserializeOwned, +{ + for &(s, err) in errors { + test_parse_err!(from_slice::(s) => err); + } +} + +fn test_fromstr_parse_err(errors: &[(&str, &'static str)]) +where + T: Debug + PartialEq + FromStr, + ::Err: ToString, +{ + for &(s, err) in errors { + let actual = s.parse::().unwrap_err().to_string(); + assert_eq!(actual, err, "unexpected parsing error"); + } +} + +#[test] +fn test_parse_null() { + test_parse_err::<()>(&[ + ("n", "EOF while parsing a value at line 1 column 1"), + ("nul", "EOF while parsing a value at line 1 column 3"), + ("nulla", "trailing characters at line 1 column 5"), + ]); + + test_parse_ok(vec![("null", ())]); +} + +#[test] +fn test_parse_bool() { + test_parse_err::(&[ + ("t", "EOF while parsing a value at line 1 column 1"), + ("truz", "expected ident at line 1 column 4"), + ("f", "EOF while parsing a value at line 1 column 1"), + ("faz", "expected ident at line 1 column 3"), + ("truea", "trailing characters at line 1 column 5"), + ("falsea", "trailing characters at line 1 column 6"), + ]); + + test_parse_ok(vec![ + ("true", true), + (" true ", true), + ("false", false), + (" false ", false), + ]); +} + +#[test] +fn test_parse_char() { + test_parse_err::(&[ + ( + "\"ab\"", + "invalid value: string \"ab\", expected a character at line 1 column 4", + ), + ( + "10", + "invalid type: integer `10`, expected a character at line 1 column 2", + ), + ]); + + test_parse_ok(vec![ + ("\"n\"", 'n'), + ("\"\\\"\"", '"'), + ("\"\\\\\"", '\\'), + ("\"/\"", '/'), + ("\"\\b\"", '\x08'), + ("\"\\f\"", '\x0C'), + ("\"\\n\"", '\n'), + ("\"\\r\"", '\r'), + ("\"\\t\"", '\t'), + ("\"\\u000b\"", '\x0B'), + ("\"\\u000B\"", '\x0B'), + ("\"\u{3A3}\"", '\u{3A3}'), + ]); +} + +#[test] +fn test_parse_number_errors() { + test_parse_err::(&[ + ("+", "expected value at line 1 column 1"), + (".", "expected value at line 1 column 1"), + ("-", "EOF while parsing a value at line 1 column 1"), + ("00", "invalid number at line 1 column 2"), + ("0x80", "trailing characters at line 1 column 2"), + ("\\0", "expected value at line 1 column 1"), + (".0", "expected value at line 1 column 1"), + ("0.", "EOF while parsing a value at line 1 column 2"), + ("1.", "EOF while parsing a value at line 1 column 2"), + ("1.a", "invalid number at line 1 column 3"), + ("1.e1", "invalid number at line 1 column 3"), + ("1e", "EOF while parsing a value at line 1 column 2"), + ("1e+", "EOF while parsing a value at line 1 column 3"), + ("1a", "trailing characters at line 1 column 2"), + ( + "100e777777777777777777777777777", + "number out of range at line 1 column 14", + ), + ( + "-100e777777777777777777777777777", + "number out of range at line 1 column 15", + ), + ( + "1000000000000000000000000000000000000000000000000000000000000\ + 000000000000000000000000000000000000000000000000000000000000\ + 000000000000000000000000000000000000000000000000000000000000\ + 000000000000000000000000000000000000000000000000000000000000\ + 000000000000000000000000000000000000000000000000000000000000\ + 000000000", // 1e309 + "number out of range at line 1 column 310", + ), + ( + "1000000000000000000000000000000000000000000000000000000000000\ + 000000000000000000000000000000000000000000000000000000000000\ + 000000000000000000000000000000000000000000000000000000000000\ + 000000000000000000000000000000000000000000000000000000000000\ + 000000000000000000000000000000000000000000000000000000000000\ + .0e9", // 1e309 + "number out of range at line 1 column 305", + ), + ( + "1000000000000000000000000000000000000000000000000000000000000\ + 000000000000000000000000000000000000000000000000000000000000\ + 000000000000000000000000000000000000000000000000000000000000\ + 000000000000000000000000000000000000000000000000000000000000\ + 000000000000000000000000000000000000000000000000000000000000\ + e9", // 1e309 + "number out of range at line 1 column 303", + ), + ]); +} + +#[test] +fn test_parse_i64() { + test_parse_ok(vec![ + ("-2", -2), + ("-1234", -1234), + (" -1234 ", -1234), + (&i64::MIN.to_string(), i64::MIN), + (&i64::MAX.to_string(), i64::MAX), + ]); +} + +#[test] +fn test_parse_u64() { + test_parse_ok(vec![ + ("0", 0u64), + ("3", 3u64), + ("1234", 1234), + (&u64::MAX.to_string(), u64::MAX), + ]); +} + +#[test] +fn test_parse_negative_zero() { + for negative_zero in &[ + "-0", + "-0.0", + "-0e2", + "-0.0e2", + "-1e-400", + "-1e-4000000000000000000000000000000000000000000000000", + ] { + assert!( + from_str::(negative_zero).unwrap().is_sign_negative(), + "should have been negative: {:?}", + negative_zero, + ); + assert!( + from_str::(negative_zero).unwrap().is_sign_negative(), + "should have been negative: {:?}", + negative_zero, + ); + } +} + +#[test] +fn test_parse_f64() { + test_parse_ok(vec![ + ("0.0", 0.0f64), + ("3.0", 3.0f64), + ("3.1", 3.1), + ("-1.2", -1.2), + ("0.4", 0.4), + // Edge case from: + // https://github.com/serde-rs/json/issues/536#issuecomment-583714900 + ("2.638344616030823e-256", 2.638344616030823e-256), + ]); + + #[cfg(not(feature = "arbitrary_precision"))] + test_parse_ok(vec![ + // With arbitrary-precision enabled, this parses as Number{"3.00"} + // but the float is Number{"3.0"} + ("3.00", 3.0f64), + ("0.4e5", 0.4e5), + ("0.4e+5", 0.4e5), + ("0.4e15", 0.4e15), + ("0.4e+15", 0.4e15), + ("0.4e-01", 0.4e-1), + (" 0.4e-01 ", 0.4e-1), + ("0.4e-001", 0.4e-1), + ("0.4e-0", 0.4e0), + ("0.00e00", 0.0), + ("0.00e+00", 0.0), + ("0.00e-00", 0.0), + ("3.5E-2147483647", 0.0), + ("0.0100000000000000000001", 0.01), + ( + &format!("{}", (i64::MIN as f64) - 1.0), + (i64::MIN as f64) - 1.0, + ), + ( + &format!("{}", (u64::MAX as f64) + 1.0), + (u64::MAX as f64) + 1.0, + ), + (&format!("{}", f64::EPSILON), f64::EPSILON), + ( + "0.0000000000000000000000000000000000000000000000000123e50", + 1.23, + ), + ("100e-777777777777777777777777777", 0.0), + ( + "1010101010101010101010101010101010101010", + 10101010101010101010e20, + ), + ( + "0.1010101010101010101010101010101010101010", + 0.1010101010101010101, + ), + ("0e1000000000000000000000000000000000000000000000", 0.0), + ( + "1000000000000000000000000000000000000000000000000000000000000\ + 000000000000000000000000000000000000000000000000000000000000\ + 000000000000000000000000000000000000000000000000000000000000\ + 000000000000000000000000000000000000000000000000000000000000\ + 000000000000000000000000000000000000000000000000000000000000\ + 00000000", + 1e308, + ), + ( + "1000000000000000000000000000000000000000000000000000000000000\ + 000000000000000000000000000000000000000000000000000000000000\ + 000000000000000000000000000000000000000000000000000000000000\ + 000000000000000000000000000000000000000000000000000000000000\ + 000000000000000000000000000000000000000000000000000000000000\ + .0e8", + 1e308, + ), + ( + "1000000000000000000000000000000000000000000000000000000000000\ + 000000000000000000000000000000000000000000000000000000000000\ + 000000000000000000000000000000000000000000000000000000000000\ + 000000000000000000000000000000000000000000000000000000000000\ + 000000000000000000000000000000000000000000000000000000000000\ + e8", + 1e308, + ), + ( + "1000000000000000000000000000000000000000000000000000000000000\ + 000000000000000000000000000000000000000000000000000000000000\ + 000000000000000000000000000000000000000000000000000000000000\ + 000000000000000000000000000000000000000000000000000000000000\ + 000000000000000000000000000000000000000000000000000000000000\ + 000000000000000000e-10", + 1e308, + ), + ]); +} + +#[test] +fn test_value_as_f64() { + let v = serde_json::from_str::("1e1000"); + + #[cfg(not(feature = "arbitrary_precision"))] + assert!(v.is_err()); + + #[cfg(feature = "arbitrary_precision")] + assert_eq!(v.unwrap().as_f64(), None); +} + +// Test roundtrip with some values that were not perfectly roundtripped by the +// old f64 deserializer. +#[cfg(feature = "float_roundtrip")] +#[test] +fn test_roundtrip_f64() { + for &float in &[ + // Samples from quickcheck-ing roundtrip with `input: f64`. Comments + // indicate the value returned by the old deserializer. + 51.24817837550540_4, // 51.2481783755054_1 + -93.3113703768803_3, // -93.3113703768803_2 + -36.5739948427534_36, // -36.5739948427534_4 + 52.31400820410624_4, // 52.31400820410624_ + 97.4536532003468_5, // 97.4536532003468_4 + // Samples from `rng.next_u64` + `f64::from_bits` + `is_finite` filter. + 2.0030397744267762e-253, + 7.101215824554616e260, + 1.769268377902049e74, + -1.6727517818542075e58, + 3.9287532173373315e299, + ] { + let json = serde_json::to_string(&float).unwrap(); + let output: f64 = serde_json::from_str(&json).unwrap(); + assert_eq!(float, output); + } +} + +#[test] +fn test_roundtrip_f32() { + // This number has 1 ULP error if parsed via f64 and converted to f32. + // https://github.com/serde-rs/json/pull/671#issuecomment-628534468 + let float = 7.038531e-26; + let json = serde_json::to_string(&float).unwrap(); + let output: f32 = serde_json::from_str(&json).unwrap(); + assert_eq!(float, output); +} + +#[test] +fn test_serialize_char() { + let value = json!( + ({ + let mut map = BTreeMap::new(); + map.insert('c', ()); + map + }) + ); + assert_eq!(&Value::Null, value.get("c").unwrap()); +} + +#[cfg(feature = "arbitrary_precision")] +#[test] +fn test_malicious_number() { + #[derive(Serialize)] + #[serde(rename = "$serde_json::private::Number")] + struct S { + #[serde(rename = "$serde_json::private::Number")] + f: &'static str, + } + + let actual = serde_json::to_value(&S { f: "not a number" }) + .unwrap_err() + .to_string(); + assert_eq!(actual, "invalid number at line 1 column 1"); +} + +#[test] +fn test_parse_number() { + test_parse_ok(vec![ + ("0.0", Number::from_f64(0.0f64).unwrap()), + ("3.0", Number::from_f64(3.0f64).unwrap()), + ("3.1", Number::from_f64(3.1).unwrap()), + ("-1.2", Number::from_f64(-1.2).unwrap()), + ("0.4", Number::from_f64(0.4).unwrap()), + ]); + + test_fromstr_parse_err::(&[ + (" 1.0", "invalid number at line 1 column 1"), + ("1.0 ", "invalid number at line 1 column 4"), + ("\t1.0", "invalid number at line 1 column 1"), + ("1.0\t", "invalid number at line 1 column 4"), + ]); + + #[cfg(feature = "arbitrary_precision")] + test_parse_ok(vec![ + ("1e999", Number::from_string_unchecked("1e999".to_owned())), + ("1e+999", Number::from_string_unchecked("1e+999".to_owned())), + ("-1e999", Number::from_string_unchecked("-1e999".to_owned())), + ("1e-999", Number::from_string_unchecked("1e-999".to_owned())), + ("1E999", Number::from_string_unchecked("1E999".to_owned())), + ("1E+999", Number::from_string_unchecked("1E+999".to_owned())), + ("-1E999", Number::from_string_unchecked("-1E999".to_owned())), + ("1E-999", Number::from_string_unchecked("1E-999".to_owned())), + ("1E+000", Number::from_string_unchecked("1E+000".to_owned())), + ( + "2.3e999", + Number::from_string_unchecked("2.3e999".to_owned()), + ), + ( + "-2.3e999", + Number::from_string_unchecked("-2.3e999".to_owned()), + ), + ]); +} + +#[test] +fn test_parse_string() { + test_parse_err::(&[ + ("\"", "EOF while parsing a string at line 1 column 1"), + ("\"lol", "EOF while parsing a string at line 1 column 4"), + ("\"lol\"a", "trailing characters at line 1 column 6"), + ( + "\"\\uD83C\\uFFFF\"", + "lone leading surrogate in hex escape at line 1 column 13", + ), + ( + "\"\n\"", + "control character (\\u0000-\\u001F) found while parsing a string at line 2 column 0", + ), + ( + "\"\x1F\"", + "control character (\\u0000-\\u001F) found while parsing a string at line 1 column 2", + ), + ]); + + test_parse_slice_err::(&[ + ( + &[b'"', 159, 146, 150, b'"'], + "invalid unicode code point at line 1 column 5", + ), + ( + &[b'"', b'\\', b'n', 159, 146, 150, b'"'], + "invalid unicode code point at line 1 column 7", + ), + ( + &[b'"', b'\\', b'u', 48, 48, 51], + "EOF while parsing a string at line 1 column 6", + ), + ( + &[b'"', b'\\', b'u', 250, 48, 51, 48, b'"'], + "invalid escape at line 1 column 7", + ), + ( + &[b'"', b'\\', b'u', 48, 250, 51, 48, b'"'], + "invalid escape at line 1 column 7", + ), + ( + &[b'"', b'\\', b'u', 48, 48, 250, 48, b'"'], + "invalid escape at line 1 column 7", + ), + ( + &[b'"', b'\\', b'u', 48, 48, 51, 250, b'"'], + "invalid escape at line 1 column 7", + ), + ( + &[b'"', b'\n', b'"'], + "control character (\\u0000-\\u001F) found while parsing a string at line 2 column 0", + ), + ( + &[b'"', b'\x1F', b'"'], + "control character (\\u0000-\\u001F) found while parsing a string at line 1 column 2", + ), + ]); + + test_parse_ok(vec![ + ("\"\"", String::new()), + ("\"foo\"", "foo".to_owned()), + (" \"foo\" ", "foo".to_owned()), + ("\"\\\"\"", "\"".to_owned()), + ("\"\\b\"", "\x08".to_owned()), + ("\"\\n\"", "\n".to_owned()), + ("\"\\r\"", "\r".to_owned()), + ("\"\\t\"", "\t".to_owned()), + ("\"\\u12ab\"", "\u{12ab}".to_owned()), + ("\"\\uAB12\"", "\u{AB12}".to_owned()), + ("\"\\uD83C\\uDF95\"", "\u{1F395}".to_owned()), + ]); +} + +#[test] +fn test_parse_list() { + test_parse_err::>(&[ + ("[", "EOF while parsing a list at line 1 column 1"), + ("[ ", "EOF while parsing a list at line 1 column 2"), + ("[1", "EOF while parsing a list at line 1 column 2"), + ("[1,", "EOF while parsing a value at line 1 column 3"), + ("[1,]", "trailing comma at line 1 column 4"), + ("[1 2]", "expected `,` or `]` at line 1 column 4"), + ("[]a", "trailing characters at line 1 column 3"), + ]); + + test_parse_ok(vec![ + ("[]", vec![]), + ("[ ]", vec![]), + ("[null]", vec![()]), + (" [ null ] ", vec![()]), + ]); + + test_parse_ok(vec![("[true]", vec![true])]); + + test_parse_ok(vec![("[3,1]", vec![3u64, 1]), (" [ 3 , 1 ] ", vec![3, 1])]); + + test_parse_ok(vec![("[[3], [1, 2]]", vec![vec![3u64], vec![1, 2]])]); + + test_parse_ok(vec![("[1]", (1u64,))]); + + test_parse_ok(vec![("[1, 2]", (1u64, 2u64))]); + + test_parse_ok(vec![("[1, 2, 3]", (1u64, 2u64, 3u64))]); + + test_parse_ok(vec![("[1, [2, 3]]", (1u64, (2u64, 3u64)))]); +} + +#[test] +fn test_parse_object() { + test_parse_err::>(&[ + ("{", "EOF while parsing an object at line 1 column 1"), + ("{ ", "EOF while parsing an object at line 1 column 2"), + ("{1", "key must be a string at line 1 column 2"), + ("{ \"a\"", "EOF while parsing an object at line 1 column 5"), + ("{\"a\"", "EOF while parsing an object at line 1 column 4"), + ("{\"a\" ", "EOF while parsing an object at line 1 column 5"), + ("{\"a\" 1", "expected `:` at line 1 column 6"), + ("{\"a\":", "EOF while parsing a value at line 1 column 5"), + ("{\"a\":1", "EOF while parsing an object at line 1 column 6"), + ("{\"a\":1 1", "expected `,` or `}` at line 1 column 8"), + ("{\"a\":1,", "EOF while parsing a value at line 1 column 7"), + ("{}a", "trailing characters at line 1 column 3"), + ]); + + test_parse_ok(vec![ + ("{}", treemap!()), + ("{ }", treemap!()), + ("{\"a\":3}", treemap!("a".to_owned() => 3u64)), + ("{ \"a\" : 3 }", treemap!("a".to_owned() => 3)), + ( + "{\"a\":3,\"b\":4}", + treemap!("a".to_owned() => 3, "b".to_owned() => 4), + ), + ( + " { \"a\" : 3 , \"b\" : 4 } ", + treemap!("a".to_owned() => 3, "b".to_owned() => 4), + ), + ]); + + test_parse_ok(vec![( + "{\"a\": {\"b\": 3, \"c\": 4}}", + treemap!( + "a".to_owned() => treemap!( + "b".to_owned() => 3u64, + "c".to_owned() => 4, + ), + ), + )]); + + test_parse_ok(vec![("{\"c\":null}", treemap!('c' => ()))]); +} + +#[test] +fn test_parse_struct() { + test_parse_err::(&[ + ( + "5", + "invalid type: integer `5`, expected struct Outer at line 1 column 1", + ), + ( + "\"hello\"", + "invalid type: string \"hello\", expected struct Outer at line 1 column 7", + ), + ( + "{\"inner\": true}", + "invalid type: boolean `true`, expected a sequence at line 1 column 14", + ), + ("{}", "missing field `inner` at line 1 column 2"), + ( + r#"{"inner": [{"b": 42, "c": []}]}"#, + "missing field `a` at line 1 column 29", + ), + ]); + + test_parse_ok(vec![ + ( + "{ + \"inner\": [] + }", + Outer { inner: vec![] }, + ), + ( + "{ + \"inner\": [ + { \"a\": null, \"b\": 2, \"c\": [\"abc\", \"xyz\"] } + ] + }", + Outer { + inner: vec![Inner { + a: (), + b: 2, + c: vec!["abc".to_owned(), "xyz".to_owned()], + }], + }, + ), + ]); + + let v: Outer = from_str( + "[ + [ + [ null, 2, [\"abc\", \"xyz\"] ] + ] + ]", + ) + .unwrap(); + + assert_eq!( + v, + Outer { + inner: vec![Inner { + a: (), + b: 2, + c: vec!["abc".to_owned(), "xyz".to_owned()], + }], + } + ); + + let j = json!([null, 2, []]); + Inner::deserialize(&j).unwrap(); + Inner::deserialize(j).unwrap(); +} + +#[test] +fn test_parse_option() { + test_parse_ok(vec![ + ("null", None::), + ("\"jodhpurs\"", Some("jodhpurs".to_owned())), + ]); + + #[derive(Clone, Debug, PartialEq, Serialize, Deserialize)] + struct Foo { + x: Option, + } + + let value: Foo = from_str("{}").unwrap(); + assert_eq!(value, Foo { x: None }); + + test_parse_ok(vec![ + ("{\"x\": null}", Foo { x: None }), + ("{\"x\": 5}", Foo { x: Some(5) }), + ]); +} + +#[test] +fn test_parse_enum_errors() { + test_parse_err::( + &[ + ("{}", "expected value at line 1 column 2"), + ("[]", "expected value at line 1 column 1"), + ("\"unknown\"", + "unknown variant `unknown`, expected one of `Dog`, `Frog`, `Cat`, `AntHive` at line 1 column 9"), + ("{\"unknown\":null}", + "unknown variant `unknown`, expected one of `Dog`, `Frog`, `Cat`, `AntHive` at line 1 column 10"), + ("{\"Dog\":", "EOF while parsing a value at line 1 column 7"), + ("{\"Dog\":}", "expected value at line 1 column 8"), + ("{\"Dog\":{}}", "invalid type: map, expected unit at line 1 column 7"), + ("\"Frog\"", "invalid type: unit variant, expected tuple variant"), + ("\"Frog\" 0 ", "invalid type: unit variant, expected tuple variant"), + ("{\"Frog\":{}}", + "invalid type: map, expected tuple variant Animal::Frog at line 1 column 8"), + ("{\"Cat\":[]}", "invalid length 0, expected struct variant Animal::Cat with 2 elements at line 1 column 9"), + ("{\"Cat\":[0]}", "invalid length 1, expected struct variant Animal::Cat with 2 elements at line 1 column 10"), + ("{\"Cat\":[0, \"\", 2]}", "trailing characters at line 1 column 16"), + ("{\"Cat\":{\"age\": 5, \"name\": \"Kate\", \"foo\":\"bar\"}", + "unknown field `foo`, expected `age` or `name` at line 1 column 39"), + + // JSON does not allow trailing commas in data structures + ("{\"Cat\":[0, \"Kate\",]}", "trailing comma at line 1 column 19"), + ("{\"Cat\":{\"age\": 2, \"name\": \"Kate\",}}", + "trailing comma at line 1 column 34"), + ], + ); +} + +#[test] +fn test_parse_enum() { + test_parse_ok(vec![ + ("\"Dog\"", Animal::Dog), + (" \"Dog\" ", Animal::Dog), + ( + "{\"Frog\":[\"Henry\",[]]}", + Animal::Frog("Henry".to_owned(), vec![]), + ), + ( + " { \"Frog\": [ \"Henry\" , [ 349, 102 ] ] } ", + Animal::Frog("Henry".to_owned(), vec![349, 102]), + ), + ( + "{\"Cat\": {\"age\": 5, \"name\": \"Kate\"}}", + Animal::Cat { + age: 5, + name: "Kate".to_owned(), + }, + ), + ( + " { \"Cat\" : { \"age\" : 5 , \"name\" : \"Kate\" } } ", + Animal::Cat { + age: 5, + name: "Kate".to_owned(), + }, + ), + ( + " { \"AntHive\" : [\"Bob\", \"Stuart\"] } ", + Animal::AntHive(vec!["Bob".to_owned(), "Stuart".to_owned()]), + ), + ]); + + test_parse_unusual_ok(vec![ + ("{\"Dog\":null}", Animal::Dog), + (" { \"Dog\" : null } ", Animal::Dog), + ]); + + test_parse_ok(vec![( + concat!( + "{", + " \"a\": \"Dog\",", + " \"b\": {\"Frog\":[\"Henry\", []]}", + "}" + ), + treemap!( + "a".to_owned() => Animal::Dog, + "b".to_owned() => Animal::Frog("Henry".to_owned(), vec![]), + ), + )]); +} + +#[test] +fn test_parse_trailing_whitespace() { + test_parse_ok(vec![ + ("[1, 2] ", vec![1u64, 2]), + ("[1, 2]\n", vec![1, 2]), + ("[1, 2]\t", vec![1, 2]), + ("[1, 2]\t \n", vec![1, 2]), + ]); +} + +#[test] +fn test_multiline_errors() { + test_parse_err::>(&[( + "{\n \"foo\":\n \"bar\"", + "EOF while parsing an object at line 3 column 6", + )]); +} + +#[test] +fn test_missing_option_field() { + #[derive(Debug, PartialEq, Deserialize)] + struct Foo { + x: Option, + } + + let value: Foo = from_str("{}").unwrap(); + assert_eq!(value, Foo { x: None }); + + let value: Foo = from_str("{\"x\": 5}").unwrap(); + assert_eq!(value, Foo { x: Some(5) }); + + let value: Foo = from_value(json!({})).unwrap(); + assert_eq!(value, Foo { x: None }); + + let value: Foo = from_value(json!({"x": 5})).unwrap(); + assert_eq!(value, Foo { x: Some(5) }); +} + +#[test] +fn test_missing_nonoption_field() { + #[derive(Debug, PartialEq, Deserialize)] + struct Foo { + x: u32, + } + + test_parse_err::(&[("{}", "missing field `x` at line 1 column 2")]); +} + +#[test] +fn test_missing_renamed_field() { + #[derive(Debug, PartialEq, Deserialize)] + struct Foo { + #[serde(rename = "y")] + x: Option, + } + + let value: Foo = from_str("{}").unwrap(); + assert_eq!(value, Foo { x: None }); + + let value: Foo = from_str("{\"y\": 5}").unwrap(); + assert_eq!(value, Foo { x: Some(5) }); + + let value: Foo = from_value(json!({})).unwrap(); + assert_eq!(value, Foo { x: None }); + + let value: Foo = from_value(json!({"y": 5})).unwrap(); + assert_eq!(value, Foo { x: Some(5) }); +} + +#[test] +fn test_serialize_seq_with_no_len() { + #[derive(Clone, Debug, PartialEq)] + struct MyVec(Vec); + + impl ser::Serialize for MyVec + where + T: ser::Serialize, + { + fn serialize(&self, serializer: S) -> Result + where + S: ser::Serializer, + { + let mut seq = serializer.serialize_seq(None)?; + for elem in &self.0 { + seq.serialize_element(elem)?; + } + seq.end() + } + } + + struct Visitor { + marker: PhantomData>, + } + + impl<'de, T> de::Visitor<'de> for Visitor + where + T: de::Deserialize<'de>, + { + type Value = MyVec; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("array") + } + + fn visit_unit(self) -> Result, E> + where + E: de::Error, + { + Ok(MyVec(Vec::new())) + } + + fn visit_seq(self, mut visitor: V) -> Result, V::Error> + where + V: de::SeqAccess<'de>, + { + let mut values = Vec::new(); + + while let Some(value) = visitor.next_element()? { + values.push(value); + } + + Ok(MyVec(values)) + } + } + + impl<'de, T> de::Deserialize<'de> for MyVec + where + T: de::Deserialize<'de>, + { + fn deserialize(deserializer: D) -> Result, D::Error> + where + D: de::Deserializer<'de>, + { + deserializer.deserialize_map(Visitor { + marker: PhantomData, + }) + } + } + + let mut vec = Vec::new(); + vec.push(MyVec(Vec::new())); + vec.push(MyVec(Vec::new())); + let vec: MyVec> = MyVec(vec); + + test_encode_ok(&[(vec.clone(), "[[],[]]")]); + + let s = to_string_pretty(&vec).unwrap(); + let expected = pretty_str!([[], []]); + assert_eq!(s, expected); +} + +#[test] +fn test_serialize_map_with_no_len() { + #[derive(Clone, Debug, PartialEq)] + struct MyMap(BTreeMap); + + impl ser::Serialize for MyMap + where + K: ser::Serialize + Ord, + V: ser::Serialize, + { + fn serialize(&self, serializer: S) -> Result + where + S: ser::Serializer, + { + let mut map = serializer.serialize_map(None)?; + for (k, v) in &self.0 { + map.serialize_entry(k, v)?; + } + map.end() + } + } + + struct Visitor { + marker: PhantomData>, + } + + impl<'de, K, V> de::Visitor<'de> for Visitor + where + K: de::Deserialize<'de> + Eq + Ord, + V: de::Deserialize<'de>, + { + type Value = MyMap; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("map") + } + + fn visit_unit(self) -> Result, E> + where + E: de::Error, + { + Ok(MyMap(BTreeMap::new())) + } + + fn visit_map(self, mut visitor: Visitor) -> Result, Visitor::Error> + where + Visitor: de::MapAccess<'de>, + { + let mut values = BTreeMap::new(); + + while let Some((key, value)) = visitor.next_entry()? { + values.insert(key, value); + } + + Ok(MyMap(values)) + } + } + + impl<'de, K, V> de::Deserialize<'de> for MyMap + where + K: de::Deserialize<'de> + Eq + Ord, + V: de::Deserialize<'de>, + { + fn deserialize(deserializer: D) -> Result, D::Error> + where + D: de::Deserializer<'de>, + { + deserializer.deserialize_map(Visitor { + marker: PhantomData, + }) + } + } + + let mut map = BTreeMap::new(); + map.insert("a", MyMap(BTreeMap::new())); + map.insert("b", MyMap(BTreeMap::new())); + let map: MyMap<_, MyMap> = MyMap(map); + + test_encode_ok(&[(map.clone(), "{\"a\":{},\"b\":{}}")]); + + let s = to_string_pretty(&map).unwrap(); + let expected = pretty_str!({ + "a": {}, + "b": {} + }); + assert_eq!(s, expected); +} + +#[cfg(not(miri))] +#[test] +fn test_deserialize_from_stream() { + use serde_json::to_writer; + use std::net::{TcpListener, TcpStream}; + use std::thread; + + #[derive(Debug, PartialEq, Serialize, Deserialize)] + struct Message { + message: String, + } + + let l = TcpListener::bind("localhost:20000").unwrap(); + + thread::spawn(|| { + let l = l; + for stream in l.incoming() { + let mut stream = stream.unwrap(); + let read_stream = stream.try_clone().unwrap(); + + let mut de = Deserializer::from_reader(read_stream); + let request = Message::deserialize(&mut de).unwrap(); + let response = Message { + message: request.message, + }; + to_writer(&mut stream, &response).unwrap(); + } + }); + + let mut stream = TcpStream::connect("localhost:20000").unwrap(); + let request = Message { + message: "hi there".to_owned(), + }; + to_writer(&mut stream, &request).unwrap(); + + let mut de = Deserializer::from_reader(stream); + let response = Message::deserialize(&mut de).unwrap(); + + assert_eq!(request, response); +} + +#[test] +fn test_serialize_rejects_adt_keys() { + let map = treemap!( + Some("a") => 2, + Some("b") => 4, + None => 6, + ); + + let err = to_vec(&map).unwrap_err(); + assert_eq!(err.to_string(), "key must be a string"); +} + +#[test] +fn test_bytes_ser() { + let buf = vec![]; + let bytes = Bytes::new(&buf); + assert_eq!(to_string(&bytes).unwrap(), "[]".to_owned()); + + let buf = vec![1, 2, 3]; + let bytes = Bytes::new(&buf); + assert_eq!(to_string(&bytes).unwrap(), "[1,2,3]".to_owned()); +} + +#[test] +fn test_byte_buf_ser() { + let bytes = ByteBuf::new(); + assert_eq!(to_string(&bytes).unwrap(), "[]".to_owned()); + + let bytes = ByteBuf::from(vec![1, 2, 3]); + assert_eq!(to_string(&bytes).unwrap(), "[1,2,3]".to_owned()); +} + +#[test] +fn test_byte_buf_de() { + let bytes = ByteBuf::new(); + let v: ByteBuf = from_str("[]").unwrap(); + assert_eq!(v, bytes); + + let bytes = ByteBuf::from(vec![1, 2, 3]); + let v: ByteBuf = from_str("[1, 2, 3]").unwrap(); + assert_eq!(v, bytes); +} + +#[test] +fn test_byte_buf_de_invalid_surrogates() { + let bytes = ByteBuf::from(vec![237, 160, 188]); + let v: ByteBuf = from_str(r#""\ud83c""#).unwrap(); + assert_eq!(v, bytes); + + let bytes = ByteBuf::from(vec![237, 160, 188, 10]); + let v: ByteBuf = from_str(r#""\ud83c\n""#).unwrap(); + assert_eq!(v, bytes); + + let bytes = ByteBuf::from(vec![237, 160, 188, 32]); + let v: ByteBuf = from_str(r#""\ud83c ""#).unwrap(); + assert_eq!(v, bytes); + + let res = from_str::(r#""\ud83c\!""#); + assert!(res.is_err()); + + let res = from_str::(r#""\ud83c\u""#); + assert!(res.is_err()); + + // lone trailing surrogate + let bytes = ByteBuf::from(vec![237, 176, 129]); + let v: ByteBuf = from_str(r#""\udc01""#).unwrap(); + assert_eq!(v, bytes); + + // leading surrogate followed by other leading surrogate + let bytes = ByteBuf::from(vec![237, 160, 188, 237, 160, 188]); + let v: ByteBuf = from_str(r#""\ud83c\ud83c""#).unwrap(); + assert_eq!(v, bytes); + + // leading surrogate followed by "a" (U+0061) in \u encoding + let bytes = ByteBuf::from(vec![237, 160, 188, 97]); + let v: ByteBuf = from_str(r#""\ud83c\u0061""#).unwrap(); + assert_eq!(v, bytes); + + // leading surrogate followed by U+0080 + let bytes = ByteBuf::from(vec![237, 160, 188, 194, 128]); + let v: ByteBuf = from_str(r#""\ud83c\u0080""#).unwrap(); + assert_eq!(v, bytes); + + // leading surrogate followed by U+FFFF + let bytes = ByteBuf::from(vec![237, 160, 188, 239, 191, 191]); + let v: ByteBuf = from_str(r#""\ud83c\uffff""#).unwrap(); + assert_eq!(v, bytes); +} + +#[test] +fn test_byte_buf_de_surrogate_pair() { + // leading surrogate followed by trailing surrogate + let bytes = ByteBuf::from(vec![240, 159, 128, 128]); + let v: ByteBuf = from_str(r#""\ud83c\udc00""#).unwrap(); + assert_eq!(v, bytes); + + // leading surrogate followed by a surrogate pair + let bytes = ByteBuf::from(vec![237, 160, 188, 240, 159, 128, 128]); + let v: ByteBuf = from_str(r#""\ud83c\ud83c\udc00""#).unwrap(); + assert_eq!(v, bytes); +} + +#[cfg(feature = "raw_value")] +#[test] +fn test_raw_de_invalid_surrogates() { + use serde_json::value::RawValue; + + assert!(from_str::>(r#""\ud83c""#).is_ok()); + assert!(from_str::>(r#""\ud83c\n""#).is_ok()); + assert!(from_str::>(r#""\ud83c ""#).is_ok()); + assert!(from_str::>(r#""\udc01 ""#).is_ok()); + assert!(from_str::>(r#""\udc01\!""#).is_err()); + assert!(from_str::>(r#""\udc01\u""#).is_err()); + assert!(from_str::>(r#""\ud83c\ud83c""#).is_ok()); + assert!(from_str::>(r#""\ud83c\u0061""#).is_ok()); + assert!(from_str::>(r#""\ud83c\u0080""#).is_ok()); + assert!(from_str::>(r#""\ud83c\uffff""#).is_ok()); +} + +#[cfg(feature = "raw_value")] +#[test] +fn test_raw_de_surrogate_pair() { + use serde_json::value::RawValue; + + assert!(from_str::>(r#""\ud83c\udc00""#).is_ok()); +} + +#[test] +fn test_byte_buf_de_multiple() { + let s: Vec = from_str(r#"["ab\nc", "cd\ne"]"#).unwrap(); + let a = ByteBuf::from(b"ab\nc".to_vec()); + let b = ByteBuf::from(b"cd\ne".to_vec()); + assert_eq!(vec![a, b], s); +} + +#[test] +fn test_json_pointer() { + // Test case taken from https://tools.ietf.org/html/rfc6901#page-5 + let data: Value = from_str( + r#"{ + "foo": ["bar", "baz"], + "": 0, + "a/b": 1, + "c%d": 2, + "e^f": 3, + "g|h": 4, + "i\\j": 5, + "k\"l": 6, + " ": 7, + "m~n": 8 + }"#, + ) + .unwrap(); + assert_eq!(data.pointer("").unwrap(), &data); + assert_eq!(data.pointer("/foo").unwrap(), &json!(["bar", "baz"])); + assert_eq!(data.pointer("/foo/0").unwrap(), &json!("bar")); + assert_eq!(data.pointer("/").unwrap(), &json!(0)); + assert_eq!(data.pointer("/a~1b").unwrap(), &json!(1)); + assert_eq!(data.pointer("/c%d").unwrap(), &json!(2)); + assert_eq!(data.pointer("/e^f").unwrap(), &json!(3)); + assert_eq!(data.pointer("/g|h").unwrap(), &json!(4)); + assert_eq!(data.pointer("/i\\j").unwrap(), &json!(5)); + assert_eq!(data.pointer("/k\"l").unwrap(), &json!(6)); + assert_eq!(data.pointer("/ ").unwrap(), &json!(7)); + assert_eq!(data.pointer("/m~0n").unwrap(), &json!(8)); + // Invalid pointers + assert!(data.pointer("/unknown").is_none()); + assert!(data.pointer("/e^f/ertz").is_none()); + assert!(data.pointer("/foo/00").is_none()); + assert!(data.pointer("/foo/01").is_none()); +} + +#[test] +fn test_json_pointer_mut() { + // Test case taken from https://tools.ietf.org/html/rfc6901#page-5 + let mut data: Value = from_str( + r#"{ + "foo": ["bar", "baz"], + "": 0, + "a/b": 1, + "c%d": 2, + "e^f": 3, + "g|h": 4, + "i\\j": 5, + "k\"l": 6, + " ": 7, + "m~n": 8 + }"#, + ) + .unwrap(); + + // Basic pointer checks + assert_eq!(data.pointer_mut("/foo").unwrap(), &json!(["bar", "baz"])); + assert_eq!(data.pointer_mut("/foo/0").unwrap(), &json!("bar")); + assert_eq!(data.pointer_mut("/").unwrap(), 0); + assert_eq!(data.pointer_mut("/a~1b").unwrap(), 1); + assert_eq!(data.pointer_mut("/c%d").unwrap(), 2); + assert_eq!(data.pointer_mut("/e^f").unwrap(), 3); + assert_eq!(data.pointer_mut("/g|h").unwrap(), 4); + assert_eq!(data.pointer_mut("/i\\j").unwrap(), 5); + assert_eq!(data.pointer_mut("/k\"l").unwrap(), 6); + assert_eq!(data.pointer_mut("/ ").unwrap(), 7); + assert_eq!(data.pointer_mut("/m~0n").unwrap(), 8); + + // Invalid pointers + assert!(data.pointer_mut("/unknown").is_none()); + assert!(data.pointer_mut("/e^f/ertz").is_none()); + assert!(data.pointer_mut("/foo/00").is_none()); + assert!(data.pointer_mut("/foo/01").is_none()); + + // Mutable pointer checks + *data.pointer_mut("/").unwrap() = 100.into(); + assert_eq!(data.pointer("/").unwrap(), 100); + *data.pointer_mut("/foo/0").unwrap() = json!("buzz"); + assert_eq!(data.pointer("/foo/0").unwrap(), &json!("buzz")); + + // Example of ownership stealing + assert_eq!( + data.pointer_mut("/a~1b") + .map(|m| mem::replace(m, json!(null))) + .unwrap(), + 1 + ); + assert_eq!(data.pointer("/a~1b").unwrap(), &json!(null)); + + // Need to compare against a clone so we don't anger the borrow checker + // by taking out two references to a mutable value + let mut d2 = data.clone(); + assert_eq!(data.pointer_mut("").unwrap(), &mut d2); +} + +#[test] +fn test_stack_overflow() { + let brackets: String = iter::repeat('[') + .take(127) + .chain(iter::repeat(']').take(127)) + .collect(); + let _: Value = from_str(&brackets).unwrap(); + + let brackets = "[".repeat(129); + test_parse_err::(&[(&brackets, "recursion limit exceeded at line 1 column 128")]); +} + +#[test] +#[cfg(feature = "unbounded_depth")] +fn test_disable_recursion_limit() { + let brackets: String = iter::repeat('[') + .take(140) + .chain(iter::repeat(']').take(140)) + .collect(); + + let mut deserializer = Deserializer::from_str(&brackets); + deserializer.disable_recursion_limit(); + Value::deserialize(&mut deserializer).unwrap(); +} + +#[test] +fn test_integer_key() { + // map with integer keys + let map = treemap!( + 1 => 2, + -1 => 6, + ); + let j = r#"{"-1":6,"1":2}"#; + test_encode_ok(&[(&map, j)]); + test_parse_ok(vec![(j, map)]); + + test_parse_err::>(&[ + ( + r#"{"x":null}"#, + "invalid value: expected key to be a number in quotes at line 1 column 2", + ), + ( + r#"{" 123":null}"#, + "invalid value: expected key to be a number in quotes at line 1 column 2", + ), + (r#"{"123 ":null}"#, "expected `\"` at line 1 column 6"), + ]); + + let err = from_value::>(json!({" 123":null})).unwrap_err(); + assert_eq!( + err.to_string(), + "invalid value: expected key to be a number in quotes", + ); + + let err = from_value::>(json!({"123 ":null})).unwrap_err(); + assert_eq!( + err.to_string(), + "invalid value: expected key to be a number in quotes", + ); +} + +#[test] +fn test_integer128_key() { + let map = treemap! { + 100000000000000000000000000000000000000u128 => (), + }; + let j = r#"{"100000000000000000000000000000000000000":null}"#; + assert_eq!(to_string(&map).unwrap(), j); + assert_eq!(from_str::>(j).unwrap(), map); +} + +#[test] +fn test_float_key() { + #[derive(Eq, PartialEq, Ord, PartialOrd, Debug, Clone)] + struct Float; + impl Serialize for Float { + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + serializer.serialize_f32(1.23) + } + } + impl<'de> Deserialize<'de> for Float { + fn deserialize(deserializer: D) -> Result + where + D: de::Deserializer<'de>, + { + f32::deserialize(deserializer).map(|_| Float) + } + } + + // map with float key + let map = treemap!(Float => "x".to_owned()); + let j = r#"{"1.23":"x"}"#; + + test_encode_ok(&[(&map, j)]); + test_parse_ok(vec![(j, map)]); + + let j = r#"{"x": null}"#; + test_parse_err::>(&[( + j, + "invalid value: expected key to be a number in quotes at line 1 column 2", + )]); +} + +#[test] +fn test_deny_non_finite_f32_key() { + // We store float bits so that we can derive Ord, and other traits. In a + // real context the code might involve a crate like ordered-float. + + #[derive(Eq, PartialEq, Ord, PartialOrd, Debug, Clone)] + struct F32Bits(u32); + impl Serialize for F32Bits { + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + serializer.serialize_f32(f32::from_bits(self.0)) + } + } + + let map = treemap!(F32Bits(f32::INFINITY.to_bits()) => "x".to_owned()); + assert!(serde_json::to_string(&map).is_err()); + assert!(serde_json::to_value(map).is_err()); + + let map = treemap!(F32Bits(f32::NEG_INFINITY.to_bits()) => "x".to_owned()); + assert!(serde_json::to_string(&map).is_err()); + assert!(serde_json::to_value(map).is_err()); + + let map = treemap!(F32Bits(f32::NAN.to_bits()) => "x".to_owned()); + assert!(serde_json::to_string(&map).is_err()); + assert!(serde_json::to_value(map).is_err()); +} + +#[test] +fn test_deny_non_finite_f64_key() { + // We store float bits so that we can derive Ord, and other traits. In a + // real context the code might involve a crate like ordered-float. + + #[derive(Eq, PartialEq, Ord, PartialOrd, Debug, Clone)] + struct F64Bits(u64); + impl Serialize for F64Bits { + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + serializer.serialize_f64(f64::from_bits(self.0)) + } + } + + let map = treemap!(F64Bits(f64::INFINITY.to_bits()) => "x".to_owned()); + assert!(serde_json::to_string(&map).is_err()); + assert!(serde_json::to_value(map).is_err()); + + let map = treemap!(F64Bits(f64::NEG_INFINITY.to_bits()) => "x".to_owned()); + assert!(serde_json::to_string(&map).is_err()); + assert!(serde_json::to_value(map).is_err()); + + let map = treemap!(F64Bits(f64::NAN.to_bits()) => "x".to_owned()); + assert!(serde_json::to_string(&map).is_err()); + assert!(serde_json::to_value(map).is_err()); +} + +#[test] +fn test_boolean_key() { + let map = treemap!(false => 0, true => 1); + let j = r#"{"false":0,"true":1}"#; + test_encode_ok(&[(&map, j)]); + test_parse_ok(vec![(j, map)]); +} + +#[test] +fn test_borrowed_key() { + let map: BTreeMap<&str, ()> = from_str("{\"borrowed\":null}").unwrap(); + let expected = treemap! { "borrowed" => () }; + assert_eq!(map, expected); + + #[derive(Deserialize, Debug, Ord, PartialOrd, Eq, PartialEq)] + struct NewtypeStr<'a>(&'a str); + + let map: BTreeMap = from_str("{\"borrowed\":null}").unwrap(); + let expected = treemap! { NewtypeStr("borrowed") => () }; + assert_eq!(map, expected); +} + +#[test] +fn test_effectively_string_keys() { + #[derive(Eq, PartialEq, Ord, PartialOrd, Debug, Clone, Serialize, Deserialize)] + enum Enum { + One, + Two, + } + let map = treemap! { + Enum::One => 1, + Enum::Two => 2, + }; + let expected = r#"{"One":1,"Two":2}"#; + test_encode_ok(&[(&map, expected)]); + test_parse_ok(vec![(expected, map)]); + + #[derive(Eq, PartialEq, Ord, PartialOrd, Debug, Clone, Serialize, Deserialize)] + struct Wrapper(String); + let map = treemap! { + Wrapper("zero".to_owned()) => 0, + Wrapper("one".to_owned()) => 1, + }; + let expected = r#"{"one":1,"zero":0}"#; + test_encode_ok(&[(&map, expected)]); + test_parse_ok(vec![(expected, map)]); +} + +#[test] +fn test_json_macro() { + // This is tricky because the <...> is not a single TT and the comma inside + // looks like an array element separator. + let _ = json!([ + as Clone>::clone(&Ok(())), + as Clone>::clone(&Err(())) + ]); + + // Same thing but in the map values. + let _ = json!({ + "ok": as Clone>::clone(&Ok(())), + "err": as Clone>::clone(&Err(())) + }); + + // It works in map keys but only if they are parenthesized. + let _ = json!({ + ( as Clone>::clone(&Ok("")).unwrap()): "ok", + ( as Clone>::clone(&Err("")).unwrap_err()): "err" + }); + + #[deny(unused_results)] + let _ = json!({ "architecture": [true, null] }); +} + +#[test] +fn issue_220() { + #[derive(Debug, PartialEq, Eq, Deserialize)] + enum E { + V(u8), + } + + assert!(from_str::(r#" "V"0 "#).is_err()); + + assert_eq!(from_str::(r#"{"V": 0}"#).unwrap(), E::V(0)); +} + +#[test] +fn test_partialeq_number() { + macro_rules! number_partialeq_ok { + ($($n:expr)*) => { + $( + let value = to_value($n).unwrap(); + let s = $n.to_string(); + assert_eq!(value, $n); + assert_eq!($n, value); + assert_ne!(value, s); + )* + }; + } + + number_partialeq_ok!(0 1 100 + i8::MIN i8::MAX i16::MIN i16::MAX i32::MIN i32::MAX i64::MIN i64::MAX + u8::MIN u8::MAX u16::MIN u16::MAX u32::MIN u32::MAX u64::MIN u64::MAX + f32::MIN f32::MAX f32::MIN_EXP f32::MAX_EXP f32::MIN_POSITIVE + f64::MIN f64::MAX f64::MIN_EXP f64::MAX_EXP f64::MIN_POSITIVE + f32::consts::E f32::consts::PI f32::consts::LN_2 f32::consts::LOG2_E + f64::consts::E f64::consts::PI f64::consts::LN_2 f64::consts::LOG2_E + ); +} + +#[test] +fn test_partialeq_string() { + let v = to_value("42").unwrap(); + assert_eq!(v, "42"); + assert_eq!("42", v); + assert_ne!(v, 42); + assert_eq!(v, String::from("42")); + assert_eq!(String::from("42"), v); +} + +#[test] +fn test_partialeq_bool() { + let v = to_value(true).unwrap(); + assert_eq!(v, true); + assert_eq!(true, v); + assert_ne!(v, false); + assert_ne!(v, "true"); + assert_ne!(v, 1); + assert_ne!(v, 0); +} + +struct FailReader(io::ErrorKind); + +impl io::Read for FailReader { + fn read(&mut self, _: &mut [u8]) -> io::Result { + Err(io::Error::new(self.0, "oh no!")) + } +} + +#[test] +fn test_category() { + assert!(from_str::("123").unwrap_err().is_data()); + + assert!(from_str::("]").unwrap_err().is_syntax()); + + assert!(from_str::("").unwrap_err().is_eof()); + assert!(from_str::("\"").unwrap_err().is_eof()); + assert!(from_str::("\"\\").unwrap_err().is_eof()); + assert!(from_str::("\"\\u").unwrap_err().is_eof()); + assert!(from_str::("\"\\u0").unwrap_err().is_eof()); + assert!(from_str::("\"\\u00").unwrap_err().is_eof()); + assert!(from_str::("\"\\u000").unwrap_err().is_eof()); + + assert!(from_str::>("[").unwrap_err().is_eof()); + assert!(from_str::>("[0").unwrap_err().is_eof()); + assert!(from_str::>("[0,").unwrap_err().is_eof()); + + assert!(from_str::>("{") + .unwrap_err() + .is_eof()); + assert!(from_str::>("{\"k\"") + .unwrap_err() + .is_eof()); + assert!(from_str::>("{\"k\":") + .unwrap_err() + .is_eof()); + assert!(from_str::>("{\"k\":0") + .unwrap_err() + .is_eof()); + assert!(from_str::>("{\"k\":0,") + .unwrap_err() + .is_eof()); + + let fail = FailReader(io::ErrorKind::NotConnected); + assert!(from_reader::<_, String>(fail).unwrap_err().is_io()); +} + +#[test] +// Clippy false positive: https://github.com/Manishearth/rust-clippy/issues/292 +#[allow(clippy::needless_lifetimes)] +fn test_into_io_error() { + fn io_error<'de, T: Deserialize<'de> + Debug>(j: &'static str) -> io::Error { + from_str::(j).unwrap_err().into() + } + + assert_eq!( + io_error::("\"\\u").kind(), + io::ErrorKind::UnexpectedEof + ); + assert_eq!(io_error::("0").kind(), io::ErrorKind::InvalidData); + assert_eq!(io_error::("]").kind(), io::ErrorKind::InvalidData); + + let fail = FailReader(io::ErrorKind::NotConnected); + let io_err: io::Error = from_reader::<_, u8>(fail).unwrap_err().into(); + assert_eq!(io_err.kind(), io::ErrorKind::NotConnected); +} + +#[test] +fn test_borrow() { + let s: &str = from_str("\"borrowed\"").unwrap(); + assert_eq!("borrowed", s); + + let s: &str = from_slice(b"\"borrowed\"").unwrap(); + assert_eq!("borrowed", s); +} + +#[test] +fn null_invalid_type() { + let err = serde_json::from_str::("null").unwrap_err(); + assert_eq!( + format!("{}", err), + String::from("invalid type: null, expected a string at line 1 column 4") + ); +} + +#[test] +fn test_integer128() { + let signed = &[i128::MIN, -1, 0, 1, i128::MAX]; + let unsigned = &[0, 1, u128::MAX]; + + for integer128 in signed { + let expected = integer128.to_string(); + assert_eq!(to_string(integer128).unwrap(), expected); + assert_eq!(from_str::(&expected).unwrap(), *integer128); + } + + for integer128 in unsigned { + let expected = integer128.to_string(); + assert_eq!(to_string(integer128).unwrap(), expected); + assert_eq!(from_str::(&expected).unwrap(), *integer128); + } + + test_parse_err::(&[ + ( + "-170141183460469231731687303715884105729", + "number out of range at line 1 column 40", + ), + ( + "170141183460469231731687303715884105728", + "number out of range at line 1 column 39", + ), + ]); + + test_parse_err::(&[ + ("-1", "number out of range at line 1 column 1"), + ( + "340282366920938463463374607431768211456", + "number out of range at line 1 column 39", + ), + ]); +} + +#[test] +fn test_integer128_to_value() { + let signed = &[i128::from(i64::MIN), i128::from(u64::MAX)]; + let unsigned = &[0, u128::from(u64::MAX)]; + + for integer128 in signed { + let expected = integer128.to_string(); + assert_eq!(to_value(integer128).unwrap().to_string(), expected); + } + + for integer128 in unsigned { + let expected = integer128.to_string(); + assert_eq!(to_value(integer128).unwrap().to_string(), expected); + } + + if !cfg!(feature = "arbitrary_precision") { + let err = to_value(u128::from(u64::MAX) + 1).unwrap_err(); + assert_eq!(err.to_string(), "number out of range"); + } +} + +#[cfg(feature = "raw_value")] +#[test] +fn test_borrowed_raw_value() { + #[derive(Serialize, Deserialize)] + struct Wrapper<'a> { + a: i8, + #[serde(borrow)] + b: &'a RawValue, + c: i8, + } + + let wrapper_from_str: Wrapper = + serde_json::from_str(r#"{"a": 1, "b": {"foo": 2}, "c": 3}"#).unwrap(); + assert_eq!(r#"{"foo": 2}"#, wrapper_from_str.b.get()); + + let wrapper_to_string = serde_json::to_string(&wrapper_from_str).unwrap(); + assert_eq!(r#"{"a":1,"b":{"foo": 2},"c":3}"#, wrapper_to_string); + + let wrapper_to_value = serde_json::to_value(&wrapper_from_str).unwrap(); + assert_eq!(json!({"a": 1, "b": {"foo": 2}, "c": 3}), wrapper_to_value); + + let array_from_str: Vec<&RawValue> = + serde_json::from_str(r#"["a", 42, {"foo": "bar"}, null]"#).unwrap(); + assert_eq!(r#""a""#, array_from_str[0].get()); + assert_eq!("42", array_from_str[1].get()); + assert_eq!(r#"{"foo": "bar"}"#, array_from_str[2].get()); + assert_eq!("null", array_from_str[3].get()); + + let array_to_string = serde_json::to_string(&array_from_str).unwrap(); + assert_eq!(r#"["a",42,{"foo": "bar"},null]"#, array_to_string); +} + +#[cfg(feature = "raw_value")] +#[test] +fn test_raw_value_in_map_key() { + #[derive(RefCast)] + #[repr(transparent)] + struct RawMapKey(RawValue); + + #[allow(unknown_lints)] + #[allow(non_local_definitions)] // false positive: https://github.com/rust-lang/rust/issues/121621 + impl<'de> Deserialize<'de> for &'de RawMapKey { + fn deserialize(deserializer: D) -> Result + where + D: serde::Deserializer<'de>, + { + let raw_value = <&RawValue>::deserialize(deserializer)?; + Ok(RawMapKey::ref_cast(raw_value)) + } + } + + impl PartialEq for RawMapKey { + fn eq(&self, other: &Self) -> bool { + self.0.get() == other.0.get() + } + } + + impl Eq for RawMapKey {} + + impl Hash for RawMapKey { + fn hash(&self, hasher: &mut H) { + self.0.get().hash(hasher); + } + } + + let map_from_str: HashMap<&RawMapKey, &RawValue> = + serde_json::from_str(r#" {"\\k":"\\v"} "#).unwrap(); + let (map_k, map_v) = map_from_str.into_iter().next().unwrap(); + assert_eq!("\"\\\\k\"", map_k.0.get()); + assert_eq!("\"\\\\v\"", map_v.get()); +} + +#[cfg(feature = "raw_value")] +#[test] +fn test_boxed_raw_value() { + #[derive(Serialize, Deserialize)] + struct Wrapper { + a: i8, + b: Box, + c: i8, + } + + let wrapper_from_str: Wrapper = + serde_json::from_str(r#"{"a": 1, "b": {"foo": 2}, "c": 3}"#).unwrap(); + assert_eq!(r#"{"foo": 2}"#, wrapper_from_str.b.get()); + + let wrapper_from_reader: Wrapper = + serde_json::from_reader(br#"{"a": 1, "b": {"foo": 2}, "c": 3}"#.as_ref()).unwrap(); + assert_eq!(r#"{"foo": 2}"#, wrapper_from_reader.b.get()); + + let wrapper_from_value: Wrapper = + serde_json::from_value(json!({"a": 1, "b": {"foo": 2}, "c": 3})).unwrap(); + assert_eq!(r#"{"foo":2}"#, wrapper_from_value.b.get()); + + let wrapper_to_string = serde_json::to_string(&wrapper_from_str).unwrap(); + assert_eq!(r#"{"a":1,"b":{"foo": 2},"c":3}"#, wrapper_to_string); + + let wrapper_to_value = serde_json::to_value(&wrapper_from_str).unwrap(); + assert_eq!(json!({"a": 1, "b": {"foo": 2}, "c": 3}), wrapper_to_value); + + let array_from_str: Vec> = + serde_json::from_str(r#"["a", 42, {"foo": "bar"}, null]"#).unwrap(); + assert_eq!(r#""a""#, array_from_str[0].get()); + assert_eq!("42", array_from_str[1].get()); + assert_eq!(r#"{"foo": "bar"}"#, array_from_str[2].get()); + assert_eq!("null", array_from_str[3].get()); + + let array_from_reader: Vec> = + serde_json::from_reader(br#"["a", 42, {"foo": "bar"}, null]"#.as_ref()).unwrap(); + assert_eq!(r#""a""#, array_from_reader[0].get()); + assert_eq!("42", array_from_reader[1].get()); + assert_eq!(r#"{"foo": "bar"}"#, array_from_reader[2].get()); + assert_eq!("null", array_from_reader[3].get()); + + let array_to_string = serde_json::to_string(&array_from_str).unwrap(); + assert_eq!(r#"["a",42,{"foo": "bar"},null]"#, array_to_string); +} + +#[cfg(feature = "raw_value")] +#[test] +fn test_raw_invalid_utf8() { + let j = &[b'"', b'\xCE', b'\xF8', b'"']; + let value_err = serde_json::from_slice::(j).unwrap_err(); + let raw_value_err = serde_json::from_slice::>(j).unwrap_err(); + + assert_eq!( + value_err.to_string(), + "invalid unicode code point at line 1 column 4", + ); + assert_eq!( + raw_value_err.to_string(), + "invalid unicode code point at line 1 column 4", + ); +} + +#[cfg(feature = "raw_value")] +#[test] +fn test_serialize_unsized_value_to_raw_value() { + assert_eq!( + serde_json::value::to_raw_value("foobar").unwrap().get(), + r#""foobar""#, + ); +} + +#[test] +fn test_borrow_in_map_key() { + #[derive(Deserialize, Debug)] + struct Outer { + #[allow(dead_code)] + map: BTreeMap, + } + + #[derive(Ord, PartialOrd, Eq, PartialEq, Debug)] + struct MyMapKey(usize); + + impl<'de> Deserialize<'de> for MyMapKey { + fn deserialize(deserializer: D) -> Result + where + D: de::Deserializer<'de>, + { + let s = <&str>::deserialize(deserializer)?; + let n = s.parse().map_err(de::Error::custom)?; + Ok(MyMapKey(n)) + } + } + + let value = json!({ "map": { "1": null } }); + Outer::deserialize(&value).unwrap(); +} + +#[test] +fn test_value_into_deserializer() { + #[derive(Deserialize)] + struct Outer { + inner: Inner, + } + + #[derive(Deserialize)] + struct Inner { + string: String, + } + + let mut map = BTreeMap::new(); + map.insert("inner", json!({ "string": "Hello World" })); + + let outer = Outer::deserialize(serde::de::value::MapDeserializer::new( + map.iter().map(|(k, v)| (*k, v)), + )) + .unwrap(); + assert_eq!(outer.inner.string, "Hello World"); + + let outer = Outer::deserialize(map.into_deserializer()).unwrap(); + assert_eq!(outer.inner.string, "Hello World"); +} + +#[test] +fn hash_positive_and_negative_zero() { + let rand = std::hash::RandomState::new(); + + let k1 = serde_json::from_str::("0.0").unwrap(); + let k2 = serde_json::from_str::("-0.0").unwrap(); + if cfg!(feature = "arbitrary_precision") { + assert_ne!(k1, k2); + assert_ne!(rand.hash_one(k1), rand.hash_one(k2)); + } else { + assert_eq!(k1, k2); + assert_eq!(rand.hash_one(k1), rand.hash_one(k2)); + } +} + +#[test] +fn test_control_character_search() { + // Different space circumstances + for n in 0..16 { + for m in 0..16 { + test_parse_err::(&[( + &format!("\"{}\n{}\"", " ".repeat(n), " ".repeat(m)), + "control character (\\u0000-\\u001F) found while parsing a string at line 2 column 0", + )]); + } + } + + // Multiple occurrences + test_parse_err::(&[( + "\"\t\n\r\"", + "control character (\\u0000-\\u001F) found while parsing a string at line 1 column 2", + )]); +} diff --git a/vendor/serde_json/tests/ui/missing_colon.rs b/vendor/serde_json/tests/ui/missing_colon.rs new file mode 100644 index 0000000..d93b7b9 --- /dev/null +++ b/vendor/serde_json/tests/ui/missing_colon.rs @@ -0,0 +1,5 @@ +use serde_json::json; + +fn main() { + json!({ "a" }); +} diff --git a/vendor/serde_json/tests/ui/missing_colon.stderr b/vendor/serde_json/tests/ui/missing_colon.stderr new file mode 100644 index 0000000..d5f6466 --- /dev/null +++ b/vendor/serde_json/tests/ui/missing_colon.stderr @@ -0,0 +1,12 @@ +error: unexpected end of macro invocation + --> tests/ui/missing_colon.rs:4:5 + | +4 | json!({ "a" }); + | ^^^^^^^^^^^^^^ missing tokens in macro arguments + | +note: while trying to match `@` + --> src/macros.rs + | + | (@array [$($elems:expr,)*]) => { + | ^ + = note: this error originates in the macro `$crate::json_internal` which comes from the expansion of the macro `json` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/vendor/serde_json/tests/ui/missing_comma.rs b/vendor/serde_json/tests/ui/missing_comma.rs new file mode 100644 index 0000000..8818c3e --- /dev/null +++ b/vendor/serde_json/tests/ui/missing_comma.rs @@ -0,0 +1,5 @@ +use serde_json::json; + +fn main() { + json!({ "1": "" "2": "" }); +} diff --git a/vendor/serde_json/tests/ui/missing_comma.stderr b/vendor/serde_json/tests/ui/missing_comma.stderr new file mode 100644 index 0000000..bafa0f8 --- /dev/null +++ b/vendor/serde_json/tests/ui/missing_comma.stderr @@ -0,0 +1,13 @@ +error: no rules expected the token `"2"` + --> tests/ui/missing_comma.rs:4:21 + | +4 | json!({ "1": "" "2": "" }); + | -^^^ no rules expected this token in macro call + | | + | help: missing comma here + | +note: while trying to match `,` + --> src/macros.rs + | + | ($e:expr , $($tt:tt)*) => {}; + | ^ diff --git a/vendor/serde_json/tests/ui/missing_value.rs b/vendor/serde_json/tests/ui/missing_value.rs new file mode 100644 index 0000000..0ba14e2 --- /dev/null +++ b/vendor/serde_json/tests/ui/missing_value.rs @@ -0,0 +1,5 @@ +use serde_json::json; + +fn main() { + json!({ "a" : }); +} diff --git a/vendor/serde_json/tests/ui/missing_value.stderr b/vendor/serde_json/tests/ui/missing_value.stderr new file mode 100644 index 0000000..69f6ca3 --- /dev/null +++ b/vendor/serde_json/tests/ui/missing_value.stderr @@ -0,0 +1,12 @@ +error: unexpected end of macro invocation + --> tests/ui/missing_value.rs:4:5 + | +4 | json!({ "a" : }); + | ^^^^^^^^^^^^^^^^ missing tokens in macro arguments + | +note: while trying to match `@` + --> src/macros.rs + | + | (@array [$($elems:expr,)*]) => { + | ^ + = note: this error originates in the macro `$crate::json_internal` which comes from the expansion of the macro `json` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/vendor/serde_json/tests/ui/not_found.rs b/vendor/serde_json/tests/ui/not_found.rs new file mode 100644 index 0000000..2df6870 --- /dev/null +++ b/vendor/serde_json/tests/ui/not_found.rs @@ -0,0 +1,5 @@ +use serde_json::json; + +fn main() { + json!({ "a" : x }); +} diff --git a/vendor/serde_json/tests/ui/not_found.stderr b/vendor/serde_json/tests/ui/not_found.stderr new file mode 100644 index 0000000..6fec180 --- /dev/null +++ b/vendor/serde_json/tests/ui/not_found.stderr @@ -0,0 +1,5 @@ +error[E0425]: cannot find value `x` in this scope + --> tests/ui/not_found.rs:4:19 + | +4 | json!({ "a" : x }); + | ^ not found in this scope diff --git a/vendor/serde_json/tests/ui/parse_expr.rs b/vendor/serde_json/tests/ui/parse_expr.rs new file mode 100644 index 0000000..e7f1805 --- /dev/null +++ b/vendor/serde_json/tests/ui/parse_expr.rs @@ -0,0 +1,5 @@ +use serde_json::json; + +fn main() { + json!({ "a" : ~ }); +} diff --git a/vendor/serde_json/tests/ui/parse_expr.stderr b/vendor/serde_json/tests/ui/parse_expr.stderr new file mode 100644 index 0000000..cd3e1c9 --- /dev/null +++ b/vendor/serde_json/tests/ui/parse_expr.stderr @@ -0,0 +1,11 @@ +error: no rules expected the token `~` + --> tests/ui/parse_expr.rs:4:19 + | +4 | json!({ "a" : ~ }); + | ^ no rules expected this token in macro call + | +note: while trying to match meta-variable `$e:expr` + --> src/macros.rs + | + | ($e:expr , $($tt:tt)*) => {}; + | ^^^^^^^ diff --git a/vendor/serde_json/tests/ui/parse_key.rs b/vendor/serde_json/tests/ui/parse_key.rs new file mode 100644 index 0000000..858bd71 --- /dev/null +++ b/vendor/serde_json/tests/ui/parse_key.rs @@ -0,0 +1,5 @@ +use serde_json::json; + +fn main() { + json!({ "".s : true }); +} diff --git a/vendor/serde_json/tests/ui/parse_key.stderr b/vendor/serde_json/tests/ui/parse_key.stderr new file mode 100644 index 0000000..15662dc --- /dev/null +++ b/vendor/serde_json/tests/ui/parse_key.stderr @@ -0,0 +1,5 @@ +error[E0609]: no field `s` on type `&'static str` + --> tests/ui/parse_key.rs:4:16 + | +4 | json!({ "".s : true }); + | ^ unknown field diff --git a/vendor/serde_json/tests/ui/unexpected_after_array_element.rs b/vendor/serde_json/tests/ui/unexpected_after_array_element.rs new file mode 100644 index 0000000..226c58c --- /dev/null +++ b/vendor/serde_json/tests/ui/unexpected_after_array_element.rs @@ -0,0 +1,5 @@ +use serde_json::json; + +fn main() { + json!([ true => ]); +} diff --git a/vendor/serde_json/tests/ui/unexpected_after_array_element.stderr b/vendor/serde_json/tests/ui/unexpected_after_array_element.stderr new file mode 100644 index 0000000..ef449f7 --- /dev/null +++ b/vendor/serde_json/tests/ui/unexpected_after_array_element.stderr @@ -0,0 +1,7 @@ +error: no rules expected the token `=>` + --> tests/ui/unexpected_after_array_element.rs:4:18 + | +4 | json!([ true => ]); + | ^^ no rules expected this token in macro call + | + = note: while trying to match end of macro diff --git a/vendor/serde_json/tests/ui/unexpected_after_map_entry.rs b/vendor/serde_json/tests/ui/unexpected_after_map_entry.rs new file mode 100644 index 0000000..0dfb731 --- /dev/null +++ b/vendor/serde_json/tests/ui/unexpected_after_map_entry.rs @@ -0,0 +1,5 @@ +use serde_json::json; + +fn main() { + json!({ "k": true => }); +} diff --git a/vendor/serde_json/tests/ui/unexpected_after_map_entry.stderr b/vendor/serde_json/tests/ui/unexpected_after_map_entry.stderr new file mode 100644 index 0000000..c62d90b --- /dev/null +++ b/vendor/serde_json/tests/ui/unexpected_after_map_entry.stderr @@ -0,0 +1,7 @@ +error: no rules expected the token `=>` + --> tests/ui/unexpected_after_map_entry.rs:4:23 + | +4 | json!({ "k": true => }); + | ^^ no rules expected this token in macro call + | + = note: while trying to match end of macro diff --git a/vendor/serde_json/tests/ui/unexpected_colon.rs b/vendor/serde_json/tests/ui/unexpected_colon.rs new file mode 100644 index 0000000..e767ea6 --- /dev/null +++ b/vendor/serde_json/tests/ui/unexpected_colon.rs @@ -0,0 +1,5 @@ +use serde_json::json; + +fn main() { + json!({ : true }); +} diff --git a/vendor/serde_json/tests/ui/unexpected_colon.stderr b/vendor/serde_json/tests/ui/unexpected_colon.stderr new file mode 100644 index 0000000..7e47726 --- /dev/null +++ b/vendor/serde_json/tests/ui/unexpected_colon.stderr @@ -0,0 +1,7 @@ +error: no rules expected the token `:` + --> tests/ui/unexpected_colon.rs:4:13 + | +4 | json!({ : true }); + | ^ no rules expected this token in macro call + | + = note: while trying to match end of macro diff --git a/vendor/serde_json/tests/ui/unexpected_comma.rs b/vendor/serde_json/tests/ui/unexpected_comma.rs new file mode 100644 index 0000000..338874e --- /dev/null +++ b/vendor/serde_json/tests/ui/unexpected_comma.rs @@ -0,0 +1,5 @@ +use serde_json::json; + +fn main() { + json!({ "a" , "b": true }); +} diff --git a/vendor/serde_json/tests/ui/unexpected_comma.stderr b/vendor/serde_json/tests/ui/unexpected_comma.stderr new file mode 100644 index 0000000..552f399 --- /dev/null +++ b/vendor/serde_json/tests/ui/unexpected_comma.stderr @@ -0,0 +1,7 @@ +error: no rules expected the token `,` + --> tests/ui/unexpected_comma.rs:4:17 + | +4 | json!({ "a" , "b": true }); + | ^ no rules expected this token in macro call + | + = note: while trying to match end of macro diff --git a/vendor/shlex/.cargo-checksum.json b/vendor/shlex/.cargo-checksum.json new file mode 100644 index 0000000..579ecbe --- /dev/null +++ b/vendor/shlex/.cargo-checksum.json @@ -0,0 +1 @@ +{"files":{"CHANGELOG.md":"879a16b3fef6fb3251fcac516fe73414109e3b7df5eb2ec4863a7551674038a0","Cargo.toml":"d7eb8c4bce681b4dd1dfc2c98c649754390775f38f4796d491948ddbb53aa2ef","LICENSE-APACHE":"553fffcd9b1cb158bc3e9edc35da85ca5c3b3d7d2e61c883ebcfa8a65814b583","LICENSE-MIT":"4455bf75a91154108304cb283e0fea9948c14f13e20d60887cf2552449dea3b1","README.md":"082e505bba5dffc5904af5602b45d01129173e617db62c81e6c11d71c964ea71","src/bytes.rs":"eadfffcdb7846d341ba451d6118d275b9d0f14a9554984ccfcdbe9a8d77ec5ee","src/lib.rs":"44c8fb929e1443f2446d26025a9bcfca0b329811bbc309b4a6afb8ec17d7de8d","src/quoting_warning.md":"566d6509211ddcd4afbd4f1117c5234567f6b6d01f5da60acfaef011362be045"},"package":"0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"} \ No newline at end of file diff --git a/vendor/shlex/CHANGELOG.md b/vendor/shlex/CHANGELOG.md new file mode 100644 index 0000000..95552b4 --- /dev/null +++ b/vendor/shlex/CHANGELOG.md @@ -0,0 +1,21 @@ +# 1.2.0 + +* Adds `bytes` module to support operating directly on byte strings. + +# 1.1.0 + +* Adds the `std` feature (enabled by default) +* Disabling the `std` feature makes the crate work in `#![no_std]` mode, assuming presence of the `alloc` crate + +# 1.0.0 + +* Adds the `join` convenience function. +* Fixes parsing of `'\\n'` to match the behavior of bash/Zsh/Python `shlex`. The result was previously `\n`, now it is `\\n`. + +# 0.1.1 + +* Adds handling of `#` comments. + +# 0.1.0 + +This is the initial release. diff --git a/vendor/shlex/Cargo.toml b/vendor/shlex/Cargo.toml new file mode 100644 index 0000000..2b66892 --- /dev/null +++ b/vendor/shlex/Cargo.toml @@ -0,0 +1,35 @@ +# 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] +rust-version = "1.46.0" +name = "shlex" +version = "1.3.0" +authors = [ + "comex ", + "Fenhl ", + "Adrian Taylor ", + "Alex Touchet ", + "Daniel Parks ", + "Garrett Berg ", +] +description = "Split a string into shell words, like Python's shlex." +readme = "README.md" +categories = [ + "command-line-interface", + "parser-implementations", +] +license = "MIT OR Apache-2.0" +repository = "https://github.com/comex/rust-shlex" + +[features] +default = ["std"] +std = [] diff --git a/vendor/shlex/LICENSE-APACHE b/vendor/shlex/LICENSE-APACHE new file mode 100644 index 0000000..3746504 --- /dev/null +++ b/vendor/shlex/LICENSE-APACHE @@ -0,0 +1,13 @@ +Copyright 2015 Nicholas Allegra (comex). + +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/shlex/LICENSE-MIT b/vendor/shlex/LICENSE-MIT new file mode 100644 index 0000000..5ec1fe1 --- /dev/null +++ b/vendor/shlex/LICENSE-MIT @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2015 Nicholas Allegra (comex). + +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/shlex/README.md b/vendor/shlex/README.md new file mode 100644 index 0000000..6400a6f --- /dev/null +++ b/vendor/shlex/README.md @@ -0,0 +1,39 @@ +[![ci badge]][ci link] [![crates.io badge]][crates.io link] [![docs.rs badge]][docs.rs link] + +[crates.io badge]: https://img.shields.io/crates/v/shlex.svg?style=flat-square +[crates.io link]: https://crates.io/crates/shlex +[docs.rs badge]: https://img.shields.io/badge/docs-online-dddddd.svg?style=flat-square +[docs.rs link]: https://docs.rs/shlex +[ci badge]: https://img.shields.io/github/actions/workflow/status/comex/rust-shlex/test.yml?branch=master&style=flat-square +[ci link]: https://github.com/comex/rust-shlex/actions + +Same idea as (but implementation not directly based on) the Python shlex +module. However, this implementation does not support any of the Python +module's customization because it makes parsing slower and is fairly useless. +You only get the default settings of shlex.split, which mimic the POSIX shell: + + +This implementation also deviates from the Python version in not treating \r +specially, which I believe is more compliant. + +This crate can be used on either normal Rust strings, or on byte strings with +the `bytes` module. The algorithms used are oblivious to UTF-8 high bytes, so +internally they all work on bytes directly as a micro-optimization. + +Disabling the `std` feature (which is enabled by default) will allow the crate +to work in `no_std` environments, where the `alloc` crate, and a global +allocator, are available. + +# LICENSE + +The source code in this repository 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. + +Unless you explicitly state otherwise, any contribution intentionally submitted +for inclusion in the work 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/shlex/src/bytes.rs b/vendor/shlex/src/bytes.rs new file mode 100644 index 0000000..af8daad --- /dev/null +++ b/vendor/shlex/src/bytes.rs @@ -0,0 +1,576 @@ +// Copyright 2015 Nicholas Allegra (comex). +// 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. + +//! [`Shlex`] and friends for byte strings. +//! +//! This is used internally by the [outer module](crate), and may be more +//! convenient if you are working with byte slices (`[u8]`) or types that are +//! wrappers around bytes, such as [`OsStr`](std::ffi::OsStr): +//! +//! ```rust +//! #[cfg(unix)] { +//! use shlex::bytes::quote; +//! use std::ffi::OsStr; +//! use std::os::unix::ffi::OsStrExt; +//! +//! // `\x80` is invalid in UTF-8. +//! let os_str = OsStr::from_bytes(b"a\x80b c"); +//! assert_eq!(quote(os_str.as_bytes()), &b"'a\x80b c'"[..]); +//! } +//! ``` +//! +//! (On Windows, `OsStr` uses 16 bit wide characters so this will not work.) + +extern crate alloc; +use alloc::vec::Vec; +use alloc::borrow::Cow; +#[cfg(test)] +use alloc::vec; +#[cfg(test)] +use alloc::borrow::ToOwned; +#[cfg(all(doc, not(doctest)))] +use crate::{self as shlex, quoting_warning}; + +use super::QuoteError; + +/// An iterator that takes an input byte string and splits it into the words using the same syntax as +/// the POSIX shell. +pub struct Shlex<'a> { + in_iter: core::slice::Iter<'a, u8>, + /// The number of newlines read so far, plus one. + pub line_no: usize, + /// An input string is erroneous if it ends while inside a quotation or right after an + /// unescaped backslash. Since Iterator does not have a mechanism to return an error, if that + /// happens, Shlex just throws out the last token, ends the iteration, and sets 'had_error' to + /// true; best to check it after you're done iterating. + pub had_error: bool, +} + +impl<'a> Shlex<'a> { + pub fn new(in_bytes: &'a [u8]) -> Self { + Shlex { + in_iter: in_bytes.iter(), + line_no: 1, + had_error: false, + } + } + + fn parse_word(&mut self, mut ch: u8) -> Option> { + let mut result: Vec = Vec::new(); + loop { + match ch as char { + '"' => if let Err(()) = self.parse_double(&mut result) { + self.had_error = true; + return None; + }, + '\'' => if let Err(()) = self.parse_single(&mut result) { + self.had_error = true; + return None; + }, + '\\' => if let Some(ch2) = self.next_char() { + if ch2 != '\n' as u8 { result.push(ch2); } + } else { + self.had_error = true; + return None; + }, + ' ' | '\t' | '\n' => { break; }, + _ => { result.push(ch as u8); }, + } + if let Some(ch2) = self.next_char() { ch = ch2; } else { break; } + } + Some(result) + } + + fn parse_double(&mut self, result: &mut Vec) -> Result<(), ()> { + loop { + if let Some(ch2) = self.next_char() { + match ch2 as char { + '\\' => { + if let Some(ch3) = self.next_char() { + match ch3 as char { + // \$ => $ + '$' | '`' | '"' | '\\' => { result.push(ch3); }, + // \ => nothing + '\n' => {}, + // \x => =x + _ => { result.push('\\' as u8); result.push(ch3); } + } + } else { + return Err(()); + } + }, + '"' => { return Ok(()); }, + _ => { result.push(ch2); }, + } + } else { + return Err(()); + } + } + } + + fn parse_single(&mut self, result: &mut Vec) -> Result<(), ()> { + loop { + if let Some(ch2) = self.next_char() { + match ch2 as char { + '\'' => { return Ok(()); }, + _ => { result.push(ch2); }, + } + } else { + return Err(()); + } + } + } + + fn next_char(&mut self) -> Option { + let res = self.in_iter.next().copied(); + if res == Some(b'\n') { self.line_no += 1; } + res + } +} + +impl<'a> Iterator for Shlex<'a> { + type Item = Vec; + fn next(&mut self) -> Option { + if let Some(mut ch) = self.next_char() { + // skip initial whitespace + loop { + match ch as char { + ' ' | '\t' | '\n' => {}, + '#' => { + while let Some(ch2) = self.next_char() { + if ch2 as char == '\n' { break; } + } + }, + _ => { break; } + } + if let Some(ch2) = self.next_char() { ch = ch2; } else { return None; } + } + self.parse_word(ch) + } else { // no initial character + None + } + } + +} + +/// Convenience function that consumes the whole byte string at once. Returns None if the input was +/// erroneous. +pub fn split(in_bytes: &[u8]) -> Option>> { + let mut shl = Shlex::new(in_bytes); + let res = shl.by_ref().collect(); + if shl.had_error { None } else { Some(res) } +} + +/// A more configurable interface to quote strings. If you only want the default settings you can +/// use the convenience functions [`try_quote`] and [`try_join`]. +/// +/// The string equivalent is [`shlex::Quoter`]. +#[derive(Default, Debug, Clone)] +pub struct Quoter { + allow_nul: bool, + // TODO: more options +} + +impl Quoter { + /// Create a new [`Quoter`] with default settings. + #[inline] + pub fn new() -> Self { + Self::default() + } + + /// Set whether to allow [nul bytes](quoting_warning#nul-bytes). By default they are not + /// allowed and will result in an error of [`QuoteError::Nul`]. + #[inline] + pub fn allow_nul(mut self, allow: bool) -> Self { + self.allow_nul = allow; + self + } + + /// Convenience function that consumes an iterable of words and turns it into a single byte string, + /// quoting words when necessary. Consecutive words will be separated by a single space. + pub fn join<'a, I: IntoIterator>(&self, words: I) -> Result, QuoteError> { + Ok(words.into_iter() + .map(|word| self.quote(word)) + .collect::>, QuoteError>>()? + .join(&b' ')) + } + + /// Given a single word, return a byte string suitable to encode it as a shell argument. + /// + /// If given valid UTF-8, this will never produce invalid UTF-8. This is because it only + /// ever inserts valid ASCII characters before or after existing ASCII characters (or + /// returns two single quotes if the input was an empty string). It will never modify a + /// multibyte UTF-8 character. + pub fn quote<'a>(&self, mut in_bytes: &'a [u8]) -> Result, QuoteError> { + if in_bytes.is_empty() { + // Empty string. Special case that isn't meaningful as only part of a word. + return Ok(b"''"[..].into()); + } + if !self.allow_nul && in_bytes.iter().any(|&b| b == b'\0') { + return Err(QuoteError::Nul); + } + let mut out: Vec = Vec::new(); + while !in_bytes.is_empty() { + // Pick a quoting strategy for some prefix of the input. Normally this will cover the + // entire input, but in some case we might need to divide the input into multiple chunks + // that are quoted differently. + let (cur_len, strategy) = quoting_strategy(in_bytes); + if cur_len == in_bytes.len() && strategy == QuotingStrategy::Unquoted && out.is_empty() { + // Entire string can be represented unquoted. Reuse the allocation. + return Ok(in_bytes.into()); + } + let (cur_chunk, rest) = in_bytes.split_at(cur_len); + assert!(rest.len() < in_bytes.len()); // no infinite loop + in_bytes = rest; + append_quoted_chunk(&mut out, cur_chunk, strategy); + } + Ok(out.into()) + } + +} + +#[derive(PartialEq)] +enum QuotingStrategy { + /// No quotes and no backslash escapes. (If backslash escapes would be necessary, we use a + /// different strategy instead.) + Unquoted, + /// Single quoted. + SingleQuoted, + /// Double quotes, potentially with backslash escapes. + DoubleQuoted, + // TODO: add $'xxx' and "$(printf 'xxx')" styles +} + +/// Is this ASCII byte okay to emit unquoted? +const fn unquoted_ok(c: u8) -> bool { + match c as char { + // Allowed characters: + '+' | '-' | '.' | '/' | ':' | '@' | ']' | '_' | + '0'..='9' | 'A'..='Z' | 'a'..='z' + => true, + + // Non-allowed characters: + // From POSIX https://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html + // "The application shall quote the following characters if they are to represent themselves:" + '|' | '&' | ';' | '<' | '>' | '(' | ')' | '$' | '`' | '\\' | '"' | '\'' | ' ' | '\t' | '\n' | + // "and the following may need to be quoted under certain circumstances[..]:" + '*' | '?' | '[' | '#' | '~' | '=' | '%' | + // Brace expansion. These ought to be in the POSIX list but aren't yet; + // see: https://www.austingroupbugs.net/view.php?id=1193 + '{' | '}' | + // Also quote comma, just to be safe in the extremely odd case that the user of this crate + // is intentionally placing a quoted string inside a brace expansion, e.g.: + // format!("echo foo{{a,b,{}}}" | shlex::quote(some_str)) + ',' | + // '\r' is allowed in a word by all real shells I tested, but is treated as a word + // separator by Python `shlex` | and might be translated to '\n' in interactive mode. + '\r' | + // '!' and '^' are treated specially in interactive mode; see quoting_warning. + '!' | '^' | + // Nul bytes and control characters. + '\x00' ..= '\x1f' | '\x7f' + => false, + '\u{80}' ..= '\u{10ffff}' => { + // This is unreachable since `unquoted_ok` is only called for 0..128. + // Non-ASCII bytes are handled separately in `quoting_strategy`. + // Can't call unreachable!() from `const fn` on old Rust, so... + unquoted_ok(c) + }, + } + // Note: The logic cited above for quoting comma might suggest that `..` should also be quoted, + // it as a special case of brace expansion). But it's not necessary. There are three cases: + // + // 1. The user wants comma-based brace expansion, but the untrusted string being `quote`d + // contains `..`, so they get something like `{foo,bar,3..5}`. + // => That's safe; both Bash and Zsh expand this to `foo bar 3..5` rather than + // `foo bar 3 4 5`. The presence of commas disables sequence expression expansion. + // + // 2. The user wants comma-based brace expansion where the contents of the braces are a + // variable number of `quote`d strings and nothing else. There happens to be exactly + // one string and it contains `..`, so they get something like `{3..5}`. + // => Then this will expand as a sequence expression, which is unintended. But I don't mind, + // because any such code is already buggy. Suppose the untrusted string *didn't* contain + // `,` or `..`, resulting in shell input like `{foo}`. Then the shell would interpret it + // as the literal string `{foo}` rather than brace-expanding it into `foo`. + // + // 3. The user wants a sequence expression and wants to supply an untrusted string as one of + // the endpoints or the increment. + // => Well, that's just silly, since the endpoints can only be numbers or single letters. +} + +/// Optimized version of `unquoted_ok`. +fn unquoted_ok_fast(c: u8) -> bool { + const UNQUOTED_OK_MASK: u128 = { + // Make a mask of all bytes in 0..<0x80 that pass. + let mut c = 0u8; + let mut mask = 0u128; + while c < 0x80 { + if unquoted_ok(c) { + mask |= 1u128 << c; + } + c += 1; + } + mask + }; + ((UNQUOTED_OK_MASK >> c) & 1) != 0 +} + +/// Is this ASCII byte okay to emit in single quotes? +fn single_quoted_ok(c: u8) -> bool { + match c { + // No single quotes in single quotes. + b'\'' => false, + // To work around a Bash bug, ^ is only allowed right after an opening single quote; see + // quoting_warning. + b'^' => false, + // Backslashes in single quotes are literal according to POSIX, but Fish treats them as an + // escape character. Ban them. Fish doesn't aim to be POSIX-compatible, but we *can* + // achieve Fish compatibility using double quotes, so we might as well. + b'\\' => false, + _ => true + } +} + +/// Is this ASCII byte okay to emit in double quotes? +fn double_quoted_ok(c: u8) -> bool { + match c { + // Work around Python `shlex` bug where parsing "\`" and "\$" doesn't strip the + // backslash, even though POSIX requires it. + b'`' | b'$' => false, + // '!' and '^' are treated specially in interactive mode; see quoting_warning. + b'!' | b'^' => false, + _ => true + } +} + +/// Given an input, return a quoting strategy that can cover some prefix of the string, along with +/// the size of that prefix. +/// +/// Precondition: input size is nonzero. (Empty strings are handled by the caller.) +/// Postcondition: returned size is nonzero. +#[cfg_attr(manual_codegen_check, inline(never))] +fn quoting_strategy(in_bytes: &[u8]) -> (usize, QuotingStrategy) { + const UNQUOTED_OK: u8 = 1; + const SINGLE_QUOTED_OK: u8 = 2; + const DOUBLE_QUOTED_OK: u8 = 4; + + let mut prev_ok = SINGLE_QUOTED_OK | DOUBLE_QUOTED_OK | UNQUOTED_OK; + let mut i = 0; + + if in_bytes[0] == b'^' { + // To work around a Bash bug, ^ is only allowed right after an opening single quote; see + // quoting_warning. + prev_ok = SINGLE_QUOTED_OK; + i = 1; + } + + while i < in_bytes.len() { + let c = in_bytes[i]; + let mut cur_ok = prev_ok; + + if c >= 0x80 { + // Normally, non-ASCII characters shouldn't require quoting, but see quoting_warning.md + // about \xa0. For now, just treat all non-ASCII characters as requiring quotes. This + // also ensures things are safe in the off-chance that you're in a legacy 8-bit locale that + // has additional characters satisfying `isblank`. + cur_ok &= !UNQUOTED_OK; + } else { + if !unquoted_ok_fast(c) { + cur_ok &= !UNQUOTED_OK; + } + if !single_quoted_ok(c){ + cur_ok &= !SINGLE_QUOTED_OK; + } + if !double_quoted_ok(c) { + cur_ok &= !DOUBLE_QUOTED_OK; + } + } + + if cur_ok == 0 { + // There are no quoting strategies that would work for both the previous characters and + // this one. So we have to end the chunk before this character. The caller will call + // `quoting_strategy` again to handle the rest of the string. + break; + } + + prev_ok = cur_ok; + i += 1; + } + + // Pick the best allowed strategy. + let strategy = if prev_ok & UNQUOTED_OK != 0 { + QuotingStrategy::Unquoted + } else if prev_ok & SINGLE_QUOTED_OK != 0 { + QuotingStrategy::SingleQuoted + } else if prev_ok & DOUBLE_QUOTED_OK != 0 { + QuotingStrategy::DoubleQuoted + } else { + unreachable!() + }; + debug_assert!(i > 0); + (i, strategy) +} + +fn append_quoted_chunk(out: &mut Vec, cur_chunk: &[u8], strategy: QuotingStrategy) { + match strategy { + QuotingStrategy::Unquoted => { + out.extend_from_slice(cur_chunk); + }, + QuotingStrategy::SingleQuoted => { + out.reserve(cur_chunk.len() + 2); + out.push(b'\''); + out.extend_from_slice(cur_chunk); + out.push(b'\''); + }, + QuotingStrategy::DoubleQuoted => { + out.reserve(cur_chunk.len() + 2); + out.push(b'"'); + for &c in cur_chunk.into_iter() { + if let b'$' | b'`' | b'"' | b'\\' = c { + // Add a preceding backslash. + // Note: We shouldn't actually get here for $ and ` because they don't pass + // `double_quoted_ok`. + out.push(b'\\'); + } + // Add the character itself. + out.push(c); + } + out.push(b'"'); + }, + } +} + +/// Convenience function that consumes an iterable of words and turns it into a single byte string, +/// quoting words when necessary. Consecutive words will be separated by a single space. +/// +/// Uses default settings except that nul bytes are passed through, which [may be +/// dangerous](quoting_warning#nul-bytes), leading to this function being deprecated. +/// +/// Equivalent to [`Quoter::new().allow_nul(true).join(words).unwrap()`](Quoter). +/// +/// (That configuration never returns `Err`, so this function does not panic.) +/// +/// The string equivalent is [shlex::join]. +#[deprecated(since = "1.3.0", note = "replace with `try_join(words)?` to avoid nul byte danger")] +pub fn join<'a, I: IntoIterator>(words: I) -> Vec { + Quoter::new().allow_nul(true).join(words).unwrap() +} + +/// Convenience function that consumes an iterable of words and turns it into a single byte string, +/// quoting words when necessary. Consecutive words will be separated by a single space. +/// +/// Uses default settings. The only error that can be returned is [`QuoteError::Nul`]. +/// +/// Equivalent to [`Quoter::new().join(words)`](Quoter). +/// +/// The string equivalent is [shlex::try_join]. +pub fn try_join<'a, I: IntoIterator>(words: I) -> Result, QuoteError> { + Quoter::new().join(words) +} + +/// Given a single word, return a string suitable to encode it as a shell argument. +/// +/// Uses default settings except that nul bytes are passed through, which [may be +/// dangerous](quoting_warning#nul-bytes), leading to this function being deprecated. +/// +/// Equivalent to [`Quoter::new().allow_nul(true).quote(in_bytes).unwrap()`](Quoter). +/// +/// (That configuration never returns `Err`, so this function does not panic.) +/// +/// The string equivalent is [shlex::quote]. +#[deprecated(since = "1.3.0", note = "replace with `try_quote(str)?` to avoid nul byte danger")] +pub fn quote(in_bytes: &[u8]) -> Cow<[u8]> { + Quoter::new().allow_nul(true).quote(in_bytes).unwrap() +} + +/// Given a single word, return a string suitable to encode it as a shell argument. +/// +/// Uses default settings. The only error that can be returned is [`QuoteError::Nul`]. +/// +/// Equivalent to [`Quoter::new().quote(in_bytes)`](Quoter). +/// +/// (That configuration never returns `Err`, so this function does not panic.) +/// +/// The string equivalent is [shlex::try_quote]. +pub fn try_quote(in_bytes: &[u8]) -> Result, QuoteError> { + Quoter::new().quote(in_bytes) +} + +#[cfg(test)] +const INVALID_UTF8: &[u8] = b"\xa1"; +#[cfg(test)] +const INVALID_UTF8_SINGLEQUOTED: &[u8] = b"'\xa1'"; + +#[test] +#[allow(invalid_from_utf8)] +fn test_invalid_utf8() { + // Check that our test string is actually invalid UTF-8. + assert!(core::str::from_utf8(INVALID_UTF8).is_err()); +} + +#[cfg(test)] +static SPLIT_TEST_ITEMS: &'static [(&'static [u8], Option<&'static [&'static [u8]]>)] = &[ + (b"foo$baz", Some(&[b"foo$baz"])), + (b"foo baz", Some(&[b"foo", b"baz"])), + (b"foo\"bar\"baz", Some(&[b"foobarbaz"])), + (b"foo \"bar\"baz", Some(&[b"foo", b"barbaz"])), + (b" foo \nbar", Some(&[b"foo", b"bar"])), + (b"foo\\\nbar", Some(&[b"foobar"])), + (b"\"foo\\\nbar\"", Some(&[b"foobar"])), + (b"'baz\\$b'", Some(&[b"baz\\$b"])), + (b"'baz\\\''", None), + (b"\\", None), + (b"\"\\", None), + (b"'\\", None), + (b"\"", None), + (b"'", None), + (b"foo #bar\nbaz", Some(&[b"foo", b"baz"])), + (b"foo #bar", Some(&[b"foo"])), + (b"foo#bar", Some(&[b"foo#bar"])), + (b"foo\"#bar", None), + (b"'\\n'", Some(&[b"\\n"])), + (b"'\\\\n'", Some(&[b"\\\\n"])), + (INVALID_UTF8, Some(&[INVALID_UTF8])), +]; + +#[test] +fn test_split() { + for &(input, output) in SPLIT_TEST_ITEMS { + assert_eq!(split(input), output.map(|o| o.iter().map(|&x| x.to_owned()).collect())); + } +} + +#[test] +fn test_lineno() { + let mut sh = Shlex::new(b"\nfoo\nbar"); + while let Some(word) = sh.next() { + if word == b"bar" { + assert_eq!(sh.line_no, 3); + } + } +} + +#[test] +#[allow(deprecated)] +fn test_quote() { + // Validate behavior with invalid UTF-8: + assert_eq!(quote(INVALID_UTF8), INVALID_UTF8_SINGLEQUOTED); + // Replicate a few tests from lib.rs. No need to replicate all of them. + assert_eq!(quote(b""), &b"''"[..]); + assert_eq!(quote(b"foobar"), &b"foobar"[..]); + assert_eq!(quote(b"foo bar"), &b"'foo bar'"[..]); + assert_eq!(quote(b"'\""), &b"\"'\\\"\""[..]); + assert_eq!(quote(b""), &b"''"[..]); +} + +#[test] +#[allow(deprecated)] +fn test_join() { + // Validate behavior with invalid UTF-8: + assert_eq!(join(vec![INVALID_UTF8]), INVALID_UTF8_SINGLEQUOTED); + // Replicate a few tests from lib.rs. No need to replicate all of them. + assert_eq!(join(vec![]), &b""[..]); + assert_eq!(join(vec![&b""[..]]), b"''"); +} diff --git a/vendor/shlex/src/lib.rs b/vendor/shlex/src/lib.rs new file mode 100644 index 0000000..aa5c306 --- /dev/null +++ b/vendor/shlex/src/lib.rs @@ -0,0 +1,358 @@ +// Copyright 2015 Nicholas Allegra (comex). +// 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. + +//! Parse strings like, and escape strings for, POSIX shells. +//! +//! Same idea as (but implementation not directly based on) the Python shlex module. +//! +//! Disabling the `std` feature (which is enabled by default) will allow the crate to work in +//! `no_std` environments, where the `alloc` crate, and a global allocator, are available. +//! +//! ## Warning +//! +//! The [`try_quote`]/[`try_join`] family of APIs does not quote control characters (because they +//! cannot be quoted portably). +//! +//! This is fully safe in noninteractive contexts, like shell scripts and `sh -c` arguments (or +//! even scripts `source`d from interactive shells). +//! +//! But if you are quoting for human consumption, you should keep in mind that ugly inputs produce +//! ugly outputs (which may not be copy-pastable). +//! +//! And if by chance you are piping the output of [`try_quote`]/[`try_join`] directly to the stdin +//! of an interactive shell, you should stop, because control characters can lead to arbitrary +//! command injection. +//! +//! For more information, and for information about more minor issues, please see [quoting_warning]. +//! +//! ## Compatibility +//! +//! This crate's quoting functionality tries to be compatible with **any POSIX-compatible shell**; +//! it's tested against `bash`, `zsh`, `dash`, Busybox `ash`, and `mksh`, plus `fish` (which is not +//! POSIX-compatible but close enough). +//! +//! It also aims to be compatible with Python `shlex` and C `wordexp`. + +#![cfg_attr(not(feature = "std"), no_std)] + +extern crate alloc; +use alloc::vec::Vec; +use alloc::borrow::Cow; +use alloc::string::String; +#[cfg(test)] +use alloc::vec; +#[cfg(test)] +use alloc::borrow::ToOwned; + +pub mod bytes; +#[cfg(all(doc, not(doctest)))] +#[path = "quoting_warning.md"] +pub mod quoting_warning; + +/// An iterator that takes an input string and splits it into the words using the same syntax as +/// the POSIX shell. +/// +/// See [`bytes::Shlex`]. +pub struct Shlex<'a>(bytes::Shlex<'a>); + +impl<'a> Shlex<'a> { + pub fn new(in_str: &'a str) -> Self { + Self(bytes::Shlex::new(in_str.as_bytes())) + } +} + +impl<'a> Iterator for Shlex<'a> { + type Item = String; + fn next(&mut self) -> Option { + self.0.next().map(|byte_word| { + // Safety: given valid UTF-8, bytes::Shlex will always return valid UTF-8. + unsafe { String::from_utf8_unchecked(byte_word) } + }) + } +} + +impl<'a> core::ops::Deref for Shlex<'a> { + type Target = bytes::Shlex<'a>; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +impl<'a> core::ops::DerefMut for Shlex<'a> { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.0 + } +} + +/// Convenience function that consumes the whole string at once. Returns None if the input was +/// erroneous. +pub fn split(in_str: &str) -> Option> { + let mut shl = Shlex::new(in_str); + let res = shl.by_ref().collect(); + if shl.had_error { None } else { Some(res) } +} + +/// Errors from [`Quoter::quote`], [`Quoter::join`], etc. (and their [`bytes`] counterparts). +/// +/// By default, the only error that can be returned is [`QuoteError::Nul`]. If you call +/// `allow_nul(true)`, then no errors can be returned at all. Any error variants added in the +/// future will not be enabled by default; they will be enabled through corresponding non-default +/// [`Quoter`] options. +/// +/// ...In theory. In the unlikely event that additional classes of inputs are discovered that, +/// like nul bytes, are fundamentally unsafe to quote even for non-interactive shells, the risk +/// will be mitigated by adding corresponding [`QuoteError`] variants that *are* enabled by +/// default. +#[non_exhaustive] +#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] +pub enum QuoteError { + /// The input contained a nul byte. In most cases, shells fundamentally [cannot handle strings + /// containing nul bytes](quoting_warning#nul-bytes), no matter how they are quoted. But if + /// you're sure you can handle nul bytes, you can call `allow_nul(true)` on the `Quoter` to let + /// them pass through. + Nul, +} + +impl core::fmt::Display for QuoteError { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + match self { + QuoteError::Nul => f.write_str("cannot shell-quote string containing nul byte"), + } + } +} + +#[cfg(feature = "std")] +impl std::error::Error for QuoteError {} + +/// A more configurable interface to quote strings. If you only want the default settings you can +/// use the convenience functions [`try_quote`] and [`try_join`]. +/// +/// The bytes equivalent is [`bytes::Quoter`]. +#[derive(Default, Debug, Clone)] +pub struct Quoter { + inner: bytes::Quoter, +} + +impl Quoter { + /// Create a new [`Quoter`] with default settings. + #[inline] + pub fn new() -> Self { + Self::default() + } + + /// Set whether to allow [nul bytes](quoting_warning#nul-bytes). By default they are not + /// allowed and will result in an error of [`QuoteError::Nul`]. + #[inline] + pub fn allow_nul(mut self, allow: bool) -> Self { + self.inner = self.inner.allow_nul(allow); + self + } + + /// Convenience function that consumes an iterable of words and turns it into a single string, + /// quoting words when necessary. Consecutive words will be separated by a single space. + pub fn join<'a, I: IntoIterator>(&self, words: I) -> Result { + // Safety: given valid UTF-8, bytes::join() will always return valid UTF-8. + self.inner.join(words.into_iter().map(|s| s.as_bytes())) + .map(|bytes| unsafe { String::from_utf8_unchecked(bytes) }) + } + + /// Given a single word, return a string suitable to encode it as a shell argument. + pub fn quote<'a>(&self, in_str: &'a str) -> Result, QuoteError> { + Ok(match self.inner.quote(in_str.as_bytes())? { + Cow::Borrowed(out) => { + // Safety: given valid UTF-8, bytes::quote() will always return valid UTF-8. + unsafe { core::str::from_utf8_unchecked(out) }.into() + } + Cow::Owned(out) => { + // Safety: given valid UTF-8, bytes::quote() will always return valid UTF-8. + unsafe { String::from_utf8_unchecked(out) }.into() + } + }) + } +} + +impl From for Quoter { + fn from(inner: bytes::Quoter) -> Quoter { + Quoter { inner } + } +} + +impl From for bytes::Quoter { + fn from(quoter: Quoter) -> bytes::Quoter { + quoter.inner + } +} + +/// Convenience function that consumes an iterable of words and turns it into a single string, +/// quoting words when necessary. Consecutive words will be separated by a single space. +/// +/// Uses default settings except that nul bytes are passed through, which [may be +/// dangerous](quoting_warning#nul-bytes), leading to this function being deprecated. +/// +/// Equivalent to [`Quoter::new().allow_nul(true).join(words).unwrap()`](Quoter). +/// +/// (That configuration never returns `Err`, so this function does not panic.) +/// +/// The bytes equivalent is [bytes::join]. +#[deprecated(since = "1.3.0", note = "replace with `try_join(words)?` to avoid nul byte danger")] +pub fn join<'a, I: IntoIterator>(words: I) -> String { + Quoter::new().allow_nul(true).join(words).unwrap() +} + +/// Convenience function that consumes an iterable of words and turns it into a single string, +/// quoting words when necessary. Consecutive words will be separated by a single space. +/// +/// Uses default settings. The only error that can be returned is [`QuoteError::Nul`]. +/// +/// Equivalent to [`Quoter::new().join(words)`](Quoter). +/// +/// The bytes equivalent is [bytes::try_join]. +pub fn try_join<'a, I: IntoIterator>(words: I) -> Result { + Quoter::new().join(words) +} + +/// Given a single word, return a string suitable to encode it as a shell argument. +/// +/// Uses default settings except that nul bytes are passed through, which [may be +/// dangerous](quoting_warning#nul-bytes), leading to this function being deprecated. +/// +/// Equivalent to [`Quoter::new().allow_nul(true).quote(in_str).unwrap()`](Quoter). +/// +/// (That configuration never returns `Err`, so this function does not panic.) +/// +/// The bytes equivalent is [bytes::quote]. +#[deprecated(since = "1.3.0", note = "replace with `try_quote(str)?` to avoid nul byte danger")] +pub fn quote(in_str: &str) -> Cow { + Quoter::new().allow_nul(true).quote(in_str).unwrap() +} + +/// Given a single word, return a string suitable to encode it as a shell argument. +/// +/// Uses default settings. The only error that can be returned is [`QuoteError::Nul`]. +/// +/// Equivalent to [`Quoter::new().quote(in_str)`](Quoter). +/// +/// (That configuration never returns `Err`, so this function does not panic.) +/// +/// The bytes equivalent is [bytes::try_quote]. +pub fn try_quote(in_str: &str) -> Result, QuoteError> { + Quoter::new().quote(in_str) +} + +#[cfg(test)] +static SPLIT_TEST_ITEMS: &'static [(&'static str, Option<&'static [&'static str]>)] = &[ + ("foo$baz", Some(&["foo$baz"])), + ("foo baz", Some(&["foo", "baz"])), + ("foo\"bar\"baz", Some(&["foobarbaz"])), + ("foo \"bar\"baz", Some(&["foo", "barbaz"])), + (" foo \nbar", Some(&["foo", "bar"])), + ("foo\\\nbar", Some(&["foobar"])), + ("\"foo\\\nbar\"", Some(&["foobar"])), + ("'baz\\$b'", Some(&["baz\\$b"])), + ("'baz\\\''", None), + ("\\", None), + ("\"\\", None), + ("'\\", None), + ("\"", None), + ("'", None), + ("foo #bar\nbaz", Some(&["foo", "baz"])), + ("foo #bar", Some(&["foo"])), + ("foo#bar", Some(&["foo#bar"])), + ("foo\"#bar", None), + ("'\\n'", Some(&["\\n"])), + ("'\\\\n'", Some(&["\\\\n"])), +]; + +#[test] +fn test_split() { + for &(input, output) in SPLIT_TEST_ITEMS { + assert_eq!(split(input), output.map(|o| o.iter().map(|&x| x.to_owned()).collect())); + } +} + +#[test] +fn test_lineno() { + let mut sh = Shlex::new("\nfoo\nbar"); + while let Some(word) = sh.next() { + if word == "bar" { + assert_eq!(sh.line_no, 3); + } + } +} + +#[test] +#[cfg_attr(not(feature = "std"), allow(unreachable_code, unused_mut))] +fn test_quote() { + // This is a list of (unquoted, quoted) pairs. + // But it's using a single long (raw) string literal with an ad-hoc format, just because it's + // hard to read if we have to put the test strings through Rust escaping on top of the escaping + // being tested. (Even raw string literals are noisy for short strings). + // Ad-hoc: "NL" is replaced with a literal newline; no other escape sequences. + let tests = r#" + <> => <''> + => + => <'foo bar'> + <"foo bar'"> => <"\"foo bar'\""> + <'foo bar'> => <"'foo bar'"> + <"> => <'"'> + <"'> => <"\"'"> + => <'hello!world'> + <'hello!world> => <"'hello"'!world'> + <'hello!> => <"'hello"'!'> + => <'hello ''^ world'> + => + => <'!world'"'"> + <{a, b}> => <'{a, b}'> + => <'NL'> + <^> => <'^'> + => + => <'NLx''^'> + => <'NL''^x'> + => <'NL ''^x'> + <{a,b}> => <'{a,b}'> + => <'a,b'> + + <'$> => <"'"'$'> + <"^> => <'"''^'> + "#; + let mut ok = true; + for test in tests.trim().split('\n') { + let parts: Vec = test + .replace("NL", "\n") + .split("=>") + .map(|part| part.trim().trim_start_matches('<').trim_end_matches('>').to_owned()) + .collect(); + assert!(parts.len() == 2); + let unquoted = &*parts[0]; + let quoted_expected = &*parts[1]; + let quoted_actual = try_quote(&parts[0]).unwrap(); + if quoted_expected != quoted_actual { + #[cfg(not(feature = "std"))] + panic!("FAIL: for input <{}>, expected <{}>, got <{}>", + unquoted, quoted_expected, quoted_actual); + #[cfg(feature = "std")] + println!("FAIL: for input <{}>, expected <{}>, got <{}>", + unquoted, quoted_expected, quoted_actual); + ok = false; + } + } + assert!(ok); +} + +#[test] +#[allow(deprecated)] +fn test_join() { + assert_eq!(join(vec![]), ""); + assert_eq!(join(vec![""]), "''"); + assert_eq!(join(vec!["a", "b"]), "a b"); + assert_eq!(join(vec!["foo bar", "baz"]), "'foo bar' baz"); +} + +#[test] +fn test_fallible() { + assert_eq!(try_join(vec!["\0"]), Err(QuoteError::Nul)); + assert_eq!(try_quote("\0"), Err(QuoteError::Nul)); +} diff --git a/vendor/shlex/src/quoting_warning.md b/vendor/shlex/src/quoting_warning.md new file mode 100644 index 0000000..fab9857 --- /dev/null +++ b/vendor/shlex/src/quoting_warning.md @@ -0,0 +1,365 @@ +// vim: textwidth=99 +/* +Meta note: This file is loaded as a .rs file by rustdoc only. +*/ +/*! + +A more detailed version of the [warning at the top level](super#warning) about the `quote`/`join` +family of APIs. + +In general, passing the output of these APIs to a shell should recover the original string(s). +This page lists cases where it fails to do so. + +In noninteractive contexts, there are only minor issues. 'Noninteractive' includes shell scripts +and `sh -c` arguments, or even scripts `source`d from interactive shells. The issues are: + +- [Nul bytes](#nul-bytes) + +- [Overlong commands](#overlong-commands) + +If you are writing directly to the stdin of an interactive (`-i`) shell (i.e., if you are +pretending to be a terminal), or if you are writing to a cooked-mode pty (even if the other end is +noninteractive), then there is a **severe** security issue: + +- [Control characters](#control-characters-interactive-contexts-only) + +Finally, there are some [solved issues](#solved-issues). + +# List of issues + +## Nul bytes + +For non-interactive shells, the most problematic input is nul bytes (bytes with value 0). The +non-deprecated functions all default to returning [`QuoteError::Nul`] when encountering them, but +the deprecated [`quote`] and [`join`] functions leave them as-is. + +In Unix, nul bytes can't appear in command arguments, environment variables, or filenames. It's +not a question of proper quoting; they just can't be used at all. This is a consequence of Unix's +system calls all being designed around nul-terminated C strings. + +Shells inherit that limitation. Most of them do not accept nul bytes in strings even internally. +Even when they do, it's pretty much useless or even dangerous, since you can't pass them to +external commands. + +In some cases, you might fail to pass the nul byte to the shell in the first place. For example, +the following code uses [`join`] to tunnel a command over an SSH connection: + +```rust +std::process::Command::new("ssh") + .arg("myhost") + .arg("--") + .arg(join(my_cmd_args)) +``` + +If any argument in `my_cmd_args` contains a nul byte, then `join(my_cmd_args)` will contain a nul +byte. But `join(my_cmd_args)` is itself being passed as an argument to a command (the ssh +command), and command arguments can't contain nul bytes! So this will simply result in the +`Command` failing to launch. + +Still, there are other ways to smuggle nul bytes into a shell. How the shell reacts depends on the +shell and the method of smuggling. For example, here is Bash 5.2.21 exhibiting three different +behaviors: + +- With ANSI-C quoting, the string is truncated at the first nul byte: + ```bash + $ echo $'foo\0bar' | hexdump -C + 00000000 66 6f 6f 0a |foo.| + ``` + +- With command substitution, nul bytes are removed with a warning: + ```bash + $ echo $(printf 'foo\0bar') | hexdump -C + bash: warning: command substitution: ignored null byte in input + 00000000 66 6f 6f 62 61 72 0a |foobar.| + ``` + +- When a nul byte appears directly in a shell script, it's removed with no warning: + ```bash + $ printf 'echo "foo\0bar"' | bash | hexdump -C + 00000000 66 6f 6f 62 61 72 0a |foobar.| + ``` + +Zsh, in contrast, actually allows nul bytes internally, in shell variables and even arguments to +builtin commands. But if a variable is exported to the environment, or if an argument is used for +an external command, then the child process will see it silently truncated at the first nul. This +might actually be more dangerous, depending on the use case. + +## Overlong commands + +If you pass a long string into a shell, several things might happen: + +- It might succeed, yet the shell might have trouble actually doing anything with it. For example: + + ```bash + x=$(printf '%010000000d' 0); /bin/echo $x + bash: /bin/echo: Argument list too long + ``` + +- If you're using certain shells (e.g. Busybox Ash) *and* using a pty for communication, then the + shell will impose a line length limit, ignoring all input past the limit. + +- If you're using a pty in cooked mode, then by default, if you write so many bytes as input that + it fills the kernel's internal buffer, the kernel will simply drop those bytes, instead of + blocking waiting for the shell to empty out the buffer. In other words, random bits of input can + be lost, which is obviously insecure. + +Future versions of this crate may add an option to [`Quoter`] to check the length for you. + +## Control characters (*interactive contexts only*) + +Control characters are the bytes from `\x00` to `\x1f`, plus `\x7f`. `\x00` (the nul byte) is +discussed [above](#nul-bytes), but what about the rest? Well, many of them correspond to terminal +keyboard shortcuts. For example, when you press Ctrl-A at a shell prompt, your terminal sends the +byte `\x01`. The shell sees that byte and (if not configured differently) takes the standard +action for Ctrl-A, which is to move the cursor to the beginning of the line. + +This means that it's quite dangerous to pipe bytes to an interactive shell. For example, here is a +program that tries to tell Bash to echo an arbitrary string, 'safely': +```rust +use std::process::{Command, Stdio}; +use std::io::Write; + +let evil_string = "\x01do_something_evil; "; +let quoted = shlex::try_quote(evil_string).unwrap(); +println!("quoted string is {:?}", quoted); + +let mut bash = Command::new("bash") + .arg("-i") // force interactive mode + .stdin(Stdio::piped()) + .spawn() + .unwrap(); +let stdin = bash.stdin.as_mut().unwrap(); +write!(stdin, "echo {}\n", quoted).unwrap(); +``` + +Here's the output of the program (with irrelevant bits removed): + +```text +quoted string is "'\u{1}do_something_evil; '" +/tmp comex$ do_something_evil; 'echo ' +bash: do_something_evil: command not found +bash: echo : command not found +``` + +Even though we quoted it, Bash still ran an arbitrary command! + +This is not because the quoting was insufficient, per se. In single quotes, all input is supposed +to be treated as raw data until the closing single quote. And in fact, this would work fine +without the `"-i"` argument. + +But line input is a separate stage from shell syntax parsing. After all, if you type a single +quote on the keyboard, you wouldn't expect it to disable all your keyboard shortcuts. So a control +character always has its designated effect, no matter if it's quoted or backslash-escaped. + +Also, some control characters are interpreted by the kernel tty layer instead, like CTRL-C to send +SIGINT. These can be an issue even with noninteractive shells, but only if using a pty for +communication, as opposed to a pipe. + +To be safe, you just have to avoid sending them. + +### Why not just use hex escapes? + +In any normal programming languages, this would be no big deal. + +Any normal language has a way to escape arbitrary characters in strings by writing out their +numeric values. For example, Rust lets you write them in hexadecimal, like `"\x4f"` (or +`"\u{1d546}"` for Unicode). In this way, arbitrary strings can be represented using only 'nice' +simple characters. Any remotely suspicious character can be replaced with a numeric escape +sequence, where the escape sequence itself consists only of alphanumeric characters and some +punctuation. The result may not be the most readable[^choices], but it's quite safe from being +misinterpreted or corrupted in transit. + +Shell is not normal. It has no numeric escape sequences. + +There are a few different ways to quote characters (unquoted, unquoted-with-backslash, single +quotes, double quotes), but all of them involve writing the character itself. If the input +contains a control character, the output must contain that same character. + +### Mitigation: terminal filters + +In practice, automating interactive shells like in the above example is pretty uncommon these days. +In most cases, the only way for a programmatically generated string to make its way to the input of +an interactive shell is if a human copies and pastes it into their terminal. + +And many terminals detect when you paste a string containing control characters. iTerm2 strips +them out; gnome-terminal replaces them with alternate characters[^gr]; Kitty outright prompts for +confirmation. This mitigates the risk. + +But it's not perfect. Some other terminals don't implement this check or implement it incorrectly. +Also, these checks tend to not filter the tab character, which could trigger tab completion. In +most cases that's a non-issue, because most shells support paste bracketing, which disables tab and +some other control characters[^bracketing] within pasted text. But in some cases paste bracketing +gets disabled. + +### Future possibility: ANSI-C quoting + +I said that shell syntax has no numeric escapes, but that only applies to *portable* shell syntax. +Bash and Zsh support an obscure alternate quoting style with the syntax `$'foo'`. It's called +["ANSI-C quoting"][ansic], and inside it you can use all the escape sequences supported by C, +including hex escapes: + +```bash +$ echo $'\x41\n\x42' +A +B +``` + +But other shells don't support it — including Dash, a popular choice for `/bin/sh`, and Busybox's +Ash, frequently seen on stripped-down embedded systems. This crate's quoting functionality [tries +to be compatible](crate#compatibility) with those shells, plus all other POSIX-compatible shells. +That makes ANSI-C quoting a no-go. + +Still, future versions of this crate may provide an option to enable ANSI-C quoting, at the cost of +reduced portability. + +### Future possibility: printf + +Another option would be to invoke the `printf` command, which is required by POSIX to support octal +escapes. For example, you could 'escape' the Rust string `"\x01"` into the shell syntax `"$(printf +'\001')"`. The shell will execute the command `printf` with the first argument being literally a +backslash followed by three digits; `printf` will output the actual byte with value 1; and the +shell will substitute that back into the original command. + +The problem is that 'escaping' a string into a command substitution just feels too surprising. If +nothing else, it only works with an actual shell; [other languages' shell parsing +routines](crate#compatibility) wouldn't understand it. Neither would this crate's own parser, +though that could be fixed. + +Future versions of this crate may provide an option to use `printf` for quoting. + +### Special note: newlines + +Did you know that `\r` and `\n` are control characters? They aren't as dangerous as other control +characters (if quoted properly). But there's still an issue with them in interactive contexts. + +Namely, in some cases, interactive shells and/or the tty layer will 'helpfully' translate between +different line ending conventions. The possibilities include replacing `\r` with `\n`, replacing +`\n` with `\r\n`, and others. This can't result in command injection, but it's still a lossy +transformation which can result in a failure to round-trip (i.e. the shell sees a different string +from what was originally passed to `quote`). + +Numeric escapes would solve this as well. + +# Solved issues + +## Solved: Past vulnerability (GHSA-r7qv-8r2h-pg27 / RUSTSEC-2024-XXX) + +Versions of this crate before 1.3.0 did not quote `{`, `}`, and `\xa0`. + +See: +- +- (TODO: Add Rustsec link) + +## Solved: `!` and `^` + +There are two non-control characters which have a special meaning in interactive contexts only: `!` and +`^`. Luckily, these can be escaped adequately. + +The `!` character triggers [history expansion][he]; the `^` character can trigger a variant of +history expansion known as [Quick Substitution][qs]. Both of these characters get expanded even +inside of double-quoted strings\! + +If we're in a double-quoted string, then we can't just escape these characters with a backslash. +Only a specific set of characters can be backslash-escaped inside double quotes; the set of +supported characters depends on the shell, but it often doesn't include `!` and `^`.[^escbs] +Trying to backslash-escape an unsupported character produces a literal backslash: +```bash +$ echo "\!" +\! +``` + +However, these characters don't get expanded in single-quoted strings, so this crate just +single-quotes them. + +But there's a Bash bug where `^` actually does get partially expanded in single-quoted strings: +```bash +$ echo ' +> ^a^b +> ' + +!!:s^a^b +``` + +To work around that, this crate forces `^` to appear right after an opening single quote. For +example, the string `"^` is quoted into `'"''^'` instead of `'"^'`. This restriction is overkill, +since `^` is only meaningful right after a newline, but it's a sufficient restriction (after all, a +`^` character can't be preceded by a newline if it's forced to be preceded by a single quote), and +for now it simplifies things. + +## Solved: `\xa0` + +The byte `\xa0` may be treated as a shell word separator, specifically on Bash on macOS when using +the default UTF-8 locale, only when the input is invalid UTF-8. This crate handles the issue by +always using quotes for arguments containing this byte. + +In fact, this crate always uses quotes for arguments containing any non-ASCII bytes. This may be +changed in the future, since it's a bit unfriendly to non-English users. But for now it +minimizes risk, especially considering the large number of different legacy single-byte locales +someone might hypothetically be running their shell in. + +### Demonstration + +```bash +$ echo -e 'ls a\xa0b' | bash +ls: a: No such file or directory +ls: b: No such file or directory +``` +The normal behavior would be to output a single line, e.g.: +```bash +$ echo -e 'ls a\xa0b' | bash +ls: cannot access 'a'$'\240''b': No such file or directory +``` +(The specific quoting in the error doesn't matter.) + +### Cause + +Just for fun, here's why this behavior occurs: + +Bash decides which bytes serve as word separators based on the libc function [`isblank`][isblank]. +On macOS on UTF-8 locales, this passes for `\xa0`, corresponding to U+00A0 NO-BREAK SPACE. + +This is doubly unique compared to the other systems I tested (Linux/glibc, Linux/musl, and +Windows/MSVC). First, the other systems don't allow bytes in the range [0x80, 0xFF] to pass +isfoo functions in UTF-8 locales, even if the corresponding Unicode codepoint +does pass, as determined by the wide-character equivalent function, iswfoo. +Second, the other systems don't treat U+00A0 as blank (even using `iswblank`). + +Meanwhile, Bash checks for multi-byte sequences and forbids them from being treated as special +characters, so the proper UTF-8 encoding of U+00A0, `b"\xc2\xa0"`, is not treated as a word +separator. Treatment as a word separator only happens for `b"\xa0"` alone, which is illegal UTF-8. + +[ansic]: https://www.gnu.org/software/bash/manual/html_node/ANSI_002dC-Quoting.html +[he]: https://www.gnu.org/software/bash/manual/html_node/History-Interaction.html +[qs]: https://www.gnu.org/software/bash/manual/html_node/Event-Designators.html +[isblank]: https://man7.org/linux/man-pages/man3/isblank.3p.html +[nul]: #nul-bytes + +[^choices]: This can lead to tough choices over which + characters to escape and which to leave as-is, especially when Unicode gets involved and you + have to balance the risk of confusion with the benefit of properly supporting non-English + languages. +
+
+ We don't have the luxury of those choices. + +[^gr]: For example, backspace (in Unicode lingo, U+0008 BACKSPACE) turns into U+2408 SYMBOL FOR BACKSPACE. + +[^bracketing]: It typically disables almost all handling of control characters by the shell proper, + but one necessary exception is the end-of-paste sequence itself (which starts with the control + character `\x1b`). In addition, paste bracketing does not suppress handling of control + characters by the kernel tty layer, such as `\x03` sending SIGINT (which typically clears the + currently typed command, making it dangerous in a similar way to `\x01`). + +[^escbs]: For example, Dash doesn't remove the backslash from `"\!"` because it simply doesn't know + anything about `!` as a special character: it doesn't support history expansion. On the other + end of the spectrum, Zsh supports history expansion and does remove the backslash — though only + in interactive mode. Bash's behavior is weirder. It supports history expansion, and if you + write `"\!"`, the backslash does prevent history expansion from occurring — but it doesn't get + removed! + +*/ + +// `use` declarations to make auto links work: +use ::{quote, join, Shlex, Quoter, QuoteError}; + +// TODO: add more about copy-paste and human readability. diff --git a/vendor/syn/.cargo-checksum.json b/vendor/syn/.cargo-checksum.json new file mode 100644 index 0000000..3a2b67a --- /dev/null +++ b/vendor/syn/.cargo-checksum.json @@ -0,0 +1 @@ +{"files":{"Cargo.toml":"93145cff820f7331bb6813f96ba91ba8eece1643bf1bb09f8bd670d52ab19159","LICENSE-APACHE":"62c7a1e35f56406896d7aa7ca52d0cc0d272ac022b5d2796e7d6905db8a3636a","LICENSE-MIT":"23f18e03dc49df91622fe2a76176497404e46ced8a715d9d2b67a7446571cca3","README.md":"ae6deb98ea51df4829c0327139a555cc115c6bcf6fb459db0ef0d6a96c4566ec","benches/file.rs":"0a0527c78d849148cbb6118b4d36f72da7d4add865ba1a410e0a1be9e8dbfe0e","benches/rust.rs":"a4b2ac626d36df1e344b1389384a559fb47da291b8ad3aa964d59d93279eebb1","src/attr.rs":"94089e45d40b1b4610e3167c0715c9075bcfc87e74cb7e306cbb0635786ea9b9","src/bigint.rs":"0299829b2f7a1a798fe2f7bc1680e4a10f9b6f4a852d09af4da2deab466c4242","src/buffer.rs":"00f28570908d311f3f568f3b116dc4f6aa3da556eb0bd5af8d6771f3301ab060","src/classify.rs":"00312dc6d51f634530f06b44365365a2588a3f6f40740224f64d0cde94839b5b","src/custom_keyword.rs":"322114e36ae43a2f8605506fb4568efdbc2986853e2fee74bd10a4ca0fb60c69","src/custom_punctuation.rs":"2ae2339c29b1aff3ab16157d51a3a07bfca594aa38586981534fe07a62cdd9d1","src/data.rs":"6f20b5ebbac7c3e9389cb0b5b0637f34d3ab721b6d6707b0eed274024ac78675","src/derive.rs":"f54f8cf9386a2d45186ff3c86ade5dae59e0e337b0198532449190ae8520cff8","src/discouraged.rs":"88b38a75d074d3f0b4186f2b4988844e8284a0c9d279d784327c6b595b9e33ea","src/drops.rs":"013385f1dd95663f1afab41abc1e2eea04181998644828935ca564c74d6462ae","src/error.rs":"3b03fd75eee8b0bb646eaf20f7e287345bdc7515ad5286024a2dd1e53c1e7bf2","src/export.rs":"b260cc49da1da3489e7755832bc8015cfad79e84f6c74e237f65ae25a2385e56","src/expr.rs":"fa075b29c787bb9990aedcfdf411e28e4ed178e7e757f813d5275b5cc4a892a0","src/ext.rs":"ed143b029af286e62ceb4310286a4ce894792dd588465face042b4199b39d329","src/file.rs":"378839f4e6a9f30d524a6a9213cc513711ddeb14e04d98b0c67644d81788919d","src/fixup.rs":"b312a6a527f81df17a94cb9f08def820584ca76cbef07893bbed492f2f0506af","src/gen/clone.rs":"c8d65438186665ed59084dbf1d6e5d78c1a4a88d515eba605c2a6fe2f6dfc293","src/gen/debug.rs":"d670460305ea3088211008e16590d0830a32c9520d5b22749f8c1d94eaae63d3","src/gen/eq.rs":"584ba47856dbb702ccf973e10a3c178146770cde542ffad5c1bc2b04b2aa3c40","src/gen/fold.rs":"e8ba8fe047a70a3285d55c6baa146c08be9554c5dbf0f8e6946496607b724f03","src/gen/hash.rs":"4b3f3251698412984b0a1c77b5b5f63eeb27bc783e270272e6f6dcaf83490146","src/gen/visit.rs":"7f80b4e6a7b33558824378fceb9f2e388453dac8b5cdaaa5e7b0faf8bb44bbdb","src/gen/visit_mut.rs":"126c0cede7870202ba4163791fa190bda49764c7f9e0a5983ad9ca49064a2e6d","src/generics.rs":"f532d7e4516c250e3eeda92e98ab2d1af19c9a368850abc8f56c230f1bbe534a","src/group.rs":"ddbff97e41315bdf9dfce215a8c00bb4d532827cf794246afde7308b39dc09ca","src/ident.rs":"d6061030fadae9c7dc847e1ee46178d9657d782aad108c7197e8cafe765b3eaa","src/item.rs":"89afdbcb9a5ef89a9cf3fb2033e0ac750dc27ef320c9f04e41c2870edf50ed00","src/lib.rs":"fd20ede898ffd7645154f4303e9d16073749bad09146c2b79fbca9e27abe50e5","src/lifetime.rs":"5787d5a5dc7e5332b03283a25ae0a9e826464242ca2d149b1a19e7cae9cee34d","src/lit.rs":"8fa6fa2d752bd1bf5a94cd5cbf9becbcba37d491876614ce62dba0f8fc745a3d","src/lookahead.rs":"eae3c1855dfd1f9bca5dd4afba07d41b15f8c108017f9eda3dc515567160a2af","src/mac.rs":"fdce8291f71adef3f69975f229156dca2309ca232ed943061afaf96220908ab8","src/macros.rs":"2a6e895dfe1c3a9a7237b5e23358ca5d8967e2beae6d094dda68d3659f9a5c84","src/meta.rs":"969d8ccbdbc6ea2e4928a21831b791c57447b231e1373149e4c63b46f3951801","src/op.rs":"a61757370f802e44efa3c4a1057ae2cd26e64e273f7d76c06d5ffb49602319e2","src/parse.rs":"fc010e04b49c36813ee50f37d974289ae7081b3f96c37051340040f460b375aa","src/parse_macro_input.rs":"e4e22b63d0496d06a4ca17742a22467ed93f08a739081324773828bad63175ee","src/parse_quote.rs":"6f4e5e28622205651bdb23fcf0f0526aef81a7921aaeac2e7a1a1e3b67916fe9","src/pat.rs":"1455a882df5defbf6b774a80f37fe24cf96d5ad1e5584c5204c0c9723883566b","src/path.rs":"1cd7f82a79d0978c3d017e545e7147f50d54a8a8348ed18b21359d5d5c7763aa","src/precedence.rs":"a0c3cd0d873e7c40b609ce3279838deb42cec4004bd4bf53276325428d7584fb","src/print.rs":"22910bf0521ab868ebd7c62601c55912d12cfb400c65723e08e5cfa3a2d111c0","src/punctuated.rs":"6e4a63b736f371bbb4cba83bb674e29aa25f9f214bc10e9acf785673a39d3fc5","src/restriction.rs":"a7152ec5a4ee4f55446019aa2b4d84f2238776f0e6ffc0c22adf3374b517fe56","src/sealed.rs":"6ece3b3dcb30f6bb98b93d83759ca7712ee8592bef9c0511141039c38765db0e","src/span.rs":"0a48e375e5c9768f6f64174a91ba6a255f4b021e2fb3548d8494e617f142601b","src/spanned.rs":"4b9bd65f60ab81922adfd0be8f03b6d50e98da3a5f525f242f9639aec4beac79","src/stmt.rs":"bb4cd196ce23c3fc07fefa47e67a0cd815db4f02ce1192625379d60bd657ffd2","src/thread.rs":"1f1deb1272525ab2af9a36aac4bce8f65b0e315adb1656641fd7075662f49222","src/token.rs":"3625e05bfaaf48adf7685669a59186386862572fa4550c5e94bf9a1febdb069e","src/tt.rs":"a58303a95d08d6bf3f3e09715b9b70a57b91b54774cfc1f00f2848034d2ff5c7","src/ty.rs":"1deae7fdaba88c0300ff562cb844f78742e379ece4254e54986e32721116126f","src/verbatim.rs":"87cbe82a90f48efb57ffd09141042698b3e011a21d0d5412154d80324b0a5ef0","src/whitespace.rs":"9cdcbfe9045b259046329a795bc1105ab5a871471a6d3f7318d275ee53f7a825","tests/common/eq.rs":"ad433c5911258010fc6ff2a93ad1f7f3acf90051969358f712fca3ef30d6461c","tests/common/mod.rs":"1f43ce65b273172c87640e87ee0775ecb6f19280fbf8f792570d019b61f9a32d","tests/common/parse.rs":"c173bd515ba1d53b3b676161849fa8df0ae3d5592445843cee65b6628b71ac32","tests/debug/gen.rs":"3ca161a049fe72ff73ead99fbfe78335fdb2ac7c41085fe8cd0c9a0b29995151","tests/debug/mod.rs":"b56136586267ae1812a937b69215dd053ada2c21717771d89dcd3ce52bcb27f5","tests/macros/mod.rs":"64b0da858096e7cf0f772e66bc1787a867e45897d7677de580c0a1f35c0f6852","tests/regression.rs":"e9565ea0efecb4136f099164ffcfa26e1996b0a27fb9c6659e90ad9bdd42e7b6","tests/regression/issue1108.rs":"f32db35244a674e22ff824ca9e5bbec2184e287b59f022db68c418b5878a2edc","tests/regression/issue1235.rs":"a2266b10c3f7c7af5734817ab0a3e8b309b51e7d177b63f26e67e6b744d280b0","tests/repo/mod.rs":"7d2c93eecb65204c8417db8ebe3e6875a56f1cd6975263ccca9440cf43832266","tests/repo/progress.rs":"c08d0314a7f3ecf760d471f27da3cd2a500aeb9f1c8331bffb2aa648f9fabf3f","tests/test_asyncness.rs":"8982f6bc4e36510f924e288247473403e72697389ce9dda4e4b5ab0a8e49259f","tests/test_attribute.rs":"b35550a43bbd187bb330997ba36f90c65d8fc489135b1d32ef4547f145cb7612","tests/test_derive_input.rs":"99c4e6e45e3322ea9e269b309059c8a00fda1dcc03aed41f6e7d8c7e0a72fa2b","tests/test_expr.rs":"d72fd1a47db706db419327bdcd8e06b26121056b96fb6c643c2244df343f1679","tests/test_generics.rs":"2fcc8575d695b568f3724b3b33d853b8fa6d9864eb816b5e3ca82420682e6155","tests/test_grouping.rs":"1bd63c8ca0b90bd493fb3f927079ab9ddf74d2a78da82db2f638e652d22305d5","tests/test_ident.rs":"d5850e817720e774cd397a46dbc5298c57933823c18e20805e84503fc9387e8f","tests/test_item.rs":"1b8412a5581adf93eaa215785a592f139af8511c954dee283d52dff2718a6cc2","tests/test_iterators.rs":"e7bd4e0743b852b9e0286489aee24fb08d48559bfa20ae55f3c7552ab69a5ba1","tests/test_lit.rs":"01b0acfe03cff16e7c1a45ceb7f4b637e5cbc6145840886ba981b7ed8e83691c","tests/test_meta.rs":"4ae570333f849ed8edec5dd957111a2deb721ede360f1e1ffeeab75380578ad4","tests/test_parse_buffer.rs":"0de6af13ba0345986b18d495063f9b75a1018e8569c34b277f9522c63a6c0941","tests/test_parse_quote.rs":"928176da6ebb449ef01a798f3352c9b181d3077c1266eb008df73876f4013c47","tests/test_parse_stream.rs":"b6b533432173123d6d01d8d2cb33714bc50b30b16ffbb6116f93937221ad4594","tests/test_pat.rs":"f6954a50e62a97ac2bc1ba0cb7a5a1fc53b7b01fb55ffe0176bee3fe1955d460","tests/test_path.rs":"d54350aa91508f8d301f5be3e3a34e03b0615b1a04e8fbbab9840da20161838b","tests/test_precedence.rs":"7e825e3845a96a274d99484f720db7ddf06205ba96cfcbef191749bcbce89620","tests/test_receiver.rs":"af64117acd66fbf42edc476f731ecd20c88009d9cb641dbd7a1d6384ae99ae73","tests/test_round_trip.rs":"48559ad63116f31fbbfd0d8501c5ace77d47f60a26b70359244bb0988fe65084","tests/test_shebang.rs":"98e8a6690c04e0aad2893b747593620b51836fe704f50f5c6fe352609837138a","tests/test_size.rs":"03efaf829b80b7db1f831474c1d3ce268914fc499d0e2a7eea03cad04a482974","tests/test_stmt.rs":"bbc305ea888254798b6faf285187d8bc7a955e4402d9a497d4b9d361e0436691","tests/test_token_trees.rs":"d012da9c3c861073711b006bf6ffdc073821fb9fb0a08733628cdae57124d1f5","tests/test_ty.rs":"aa14822fe99f3ac22eb056f5488a8110dfdb922e0008ea82b73bca8e1a613cd5","tests/test_unparenthesize.rs":"6c723cd6332b7d8be703fab20f085cef7716692eb07b1d75f2e590935656641d","tests/test_visibility.rs":"7bd239aef6f6d8173462dbd869064f3fdb9ba71644ac1f62c5d2fbb2568fb986","tests/zzz_stable.rs":"2a862e59cb446235ed99aec0e6ada8e16d3ecc30229b29d825b7c0bbc2602989"},"package":"89132cd0bf050864e1d38dc3bbc07a0eb8e7530af26344d3d2bbbef83499f590"} \ No newline at end of file diff --git a/vendor/syn/Cargo.toml b/vendor/syn/Cargo.toml new file mode 100644 index 0000000..c913341 --- /dev/null +++ b/vendor/syn/Cargo.toml @@ -0,0 +1,264 @@ +# 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] +edition = "2021" +rust-version = "1.61" +name = "syn" +version = "2.0.79" +authors = ["David Tolnay "] +build = false +include = [ + "/benches/**", + "/Cargo.toml", + "/LICENSE-APACHE", + "/LICENSE-MIT", + "/README.md", + "/src/**", + "/tests/**", +] +autobins = false +autoexamples = false +autotests = false +autobenches = false +description = "Parser for Rust source code" +documentation = "https://docs.rs/syn" +readme = "README.md" +keywords = [ + "macros", + "syn", +] +categories = [ + "development-tools::procedural-macro-helpers", + "parser-implementations", +] +license = "MIT OR Apache-2.0" +repository = "https://github.com/dtolnay/syn" + +[package.metadata.docs.rs] +all-features = true +rustdoc-args = ["--generate-link-to-definition"] +targets = ["x86_64-unknown-linux-gnu"] + +[package.metadata.playground] +features = [ + "full", + "visit", + "visit-mut", + "fold", + "extra-traits", +] + +[lib] +name = "syn" +path = "src/lib.rs" +doc-scrape-examples = false + +[[test]] +name = "regression" +path = "tests/regression.rs" + +[[test]] +name = "test_asyncness" +path = "tests/test_asyncness.rs" + +[[test]] +name = "test_attribute" +path = "tests/test_attribute.rs" + +[[test]] +name = "test_derive_input" +path = "tests/test_derive_input.rs" + +[[test]] +name = "test_expr" +path = "tests/test_expr.rs" + +[[test]] +name = "test_generics" +path = "tests/test_generics.rs" + +[[test]] +name = "test_grouping" +path = "tests/test_grouping.rs" + +[[test]] +name = "test_ident" +path = "tests/test_ident.rs" + +[[test]] +name = "test_item" +path = "tests/test_item.rs" + +[[test]] +name = "test_iterators" +path = "tests/test_iterators.rs" + +[[test]] +name = "test_lit" +path = "tests/test_lit.rs" + +[[test]] +name = "test_meta" +path = "tests/test_meta.rs" + +[[test]] +name = "test_parse_buffer" +path = "tests/test_parse_buffer.rs" + +[[test]] +name = "test_parse_quote" +path = "tests/test_parse_quote.rs" + +[[test]] +name = "test_parse_stream" +path = "tests/test_parse_stream.rs" + +[[test]] +name = "test_pat" +path = "tests/test_pat.rs" + +[[test]] +name = "test_path" +path = "tests/test_path.rs" + +[[test]] +name = "test_precedence" +path = "tests/test_precedence.rs" + +[[test]] +name = "test_receiver" +path = "tests/test_receiver.rs" + +[[test]] +name = "test_round_trip" +path = "tests/test_round_trip.rs" + +[[test]] +name = "test_shebang" +path = "tests/test_shebang.rs" + +[[test]] +name = "test_size" +path = "tests/test_size.rs" + +[[test]] +name = "test_stmt" +path = "tests/test_stmt.rs" + +[[test]] +name = "test_token_trees" +path = "tests/test_token_trees.rs" + +[[test]] +name = "test_ty" +path = "tests/test_ty.rs" + +[[test]] +name = "test_unparenthesize" +path = "tests/test_unparenthesize.rs" + +[[test]] +name = "test_visibility" +path = "tests/test_visibility.rs" + +[[test]] +name = "zzz_stable" +path = "tests/zzz_stable.rs" + +[[bench]] +name = "file" +path = "benches/file.rs" +required-features = [ + "full", + "parsing", +] + +[[bench]] +name = "rust" +path = "benches/rust.rs" +harness = false +required-features = [ + "full", + "parsing", +] + +[dependencies.proc-macro2] +version = "1.0.83" +default-features = false + +[dependencies.quote] +version = "1.0.35" +optional = true +default-features = false + +[dependencies.unicode-ident] +version = "1" + +[dev-dependencies.anyhow] +version = "1" + +[dev-dependencies.automod] +version = "1" + +[dev-dependencies.insta] +version = "1" + +[dev-dependencies.ref-cast] +version = "1" + +[dev-dependencies.rustversion] +version = "1" + +[dev-dependencies.syn-test-suite] +version = "0" + +[dev-dependencies.termcolor] +version = "1" + +[features] +clone-impls = [] +default = [ + "derive", + "parsing", + "printing", + "clone-impls", + "proc-macro", +] +derive = [] +extra-traits = [] +fold = [] +full = [] +parsing = [] +printing = ["dep:quote"] +proc-macro = [ + "proc-macro2/proc-macro", + "quote?/proc-macro", +] +test = ["syn-test-suite/all-features"] +visit = [] +visit-mut = [] + +[target."cfg(not(miri))".dev-dependencies.flate2] +version = "1" + +[target."cfg(not(miri))".dev-dependencies.rayon] +version = "1" + +[target."cfg(not(miri))".dev-dependencies.reqwest] +version = "0.12" +features = ["blocking"] + +[target."cfg(not(miri))".dev-dependencies.tar] +version = "0.4.16" + +[target."cfg(not(miri))".dev-dependencies.walkdir] +version = "2.3.2" diff --git a/vendor/syn/LICENSE-APACHE b/vendor/syn/LICENSE-APACHE new file mode 100644 index 0000000..1b5ec8b --- /dev/null +++ b/vendor/syn/LICENSE-APACHE @@ -0,0 +1,176 @@ + 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 diff --git a/vendor/syn/LICENSE-MIT b/vendor/syn/LICENSE-MIT new file mode 100644 index 0000000..31aa793 --- /dev/null +++ b/vendor/syn/LICENSE-MIT @@ -0,0 +1,23 @@ +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/syn/README.md b/vendor/syn/README.md new file mode 100644 index 0000000..16a393b --- /dev/null +++ b/vendor/syn/README.md @@ -0,0 +1,284 @@ +Parser for Rust source code +=========================== + +[github](https://github.com/dtolnay/syn) +[crates.io](https://crates.io/crates/syn) +[docs.rs](https://docs.rs/syn) +[build status](https://github.com/dtolnay/syn/actions?query=branch%3Amaster) + +Syn is a parsing library for parsing a stream of Rust tokens into a syntax tree +of Rust source code. + +Currently this library is geared toward use in Rust procedural macros, but +contains some APIs that may be useful more generally. + +- **Data structures** — Syn provides a complete syntax tree that can represent + any valid Rust source code. The syntax tree is rooted at [`syn::File`] which + represents a full source file, but there are other entry points that may be + useful to procedural macros including [`syn::Item`], [`syn::Expr`] and + [`syn::Type`]. + +- **Derives** — Of particular interest to derive macros is [`syn::DeriveInput`] + which is any of the three legal input items to a derive macro. An example + below shows using this type in a library that can derive implementations of a + user-defined trait. + +- **Parsing** — Parsing in Syn is built around [parser functions] with the + signature `fn(ParseStream) -> Result`. Every syntax tree node defined by + Syn is individually parsable and may be used as a building block for custom + syntaxes, or you may dream up your own brand new syntax without involving any + of our syntax tree types. + +- **Location information** — Every token parsed by Syn is associated with a + `Span` that tracks line and column information back to the source of that + token. These spans allow a procedural macro to display detailed error messages + pointing to all the right places in the user's code. There is an example of + this below. + +- **Feature flags** — Functionality is aggressively feature gated so your + procedural macros enable only what they need, and do not pay in compile time + for all the rest. + +[`syn::File`]: https://docs.rs/syn/2.0/syn/struct.File.html +[`syn::Item`]: https://docs.rs/syn/2.0/syn/enum.Item.html +[`syn::Expr`]: https://docs.rs/syn/2.0/syn/enum.Expr.html +[`syn::Type`]: https://docs.rs/syn/2.0/syn/enum.Type.html +[`syn::DeriveInput`]: https://docs.rs/syn/2.0/syn/struct.DeriveInput.html +[parser functions]: https://docs.rs/syn/2.0/syn/parse/index.html + +*Version requirement: Syn supports rustc 1.61 and up.* + +[*Release notes*](https://github.com/dtolnay/syn/releases) + +
+ +## Resources + +The best way to learn about procedural macros is by writing some. Consider +working through [this procedural macro workshop][workshop] to get familiar with +the different types of procedural macros. The workshop contains relevant links +into the Syn documentation as you work through each project. + +[workshop]: https://github.com/dtolnay/proc-macro-workshop + +
+ +## Example of a derive macro + +The canonical derive macro using Syn looks like this. We write an ordinary Rust +function tagged with a `proc_macro_derive` attribute and the name of the trait +we are deriving. Any time that derive appears in the user's code, the Rust +compiler passes their data structure as tokens into our macro. We get to execute +arbitrary Rust code to figure out what to do with those tokens, then hand some +tokens back to the compiler to compile into the user's crate. + +[`TokenStream`]: https://doc.rust-lang.org/proc_macro/struct.TokenStream.html + +```toml +[dependencies] +syn = "2.0" +quote = "1.0" + +[lib] +proc-macro = true +``` + +```rust +use proc_macro::TokenStream; +use quote::quote; +use syn::{parse_macro_input, DeriveInput}; + +#[proc_macro_derive(MyMacro)] +pub fn my_macro(input: TokenStream) -> TokenStream { + // Parse the input tokens into a syntax tree + let input = parse_macro_input!(input as DeriveInput); + + // Build the output, possibly using quasi-quotation + let expanded = quote! { + // ... + }; + + // Hand the output tokens back to the compiler + TokenStream::from(expanded) +} +``` + +The [`heapsize`] example directory shows a complete working implementation of a +derive macro. The example derives a `HeapSize` trait which computes an estimate +of the amount of heap memory owned by a value. + +[`heapsize`]: examples/heapsize + +```rust +pub trait HeapSize { + /// Total number of bytes of heap memory owned by `self`. + fn heap_size_of_children(&self) -> usize; +} +``` + +The derive macro allows users to write `#[derive(HeapSize)]` on data structures +in their program. + +```rust +#[derive(HeapSize)] +struct Demo<'a, T: ?Sized> { + a: Box, + b: u8, + c: &'a str, + d: String, +} +``` + +
+ +## Spans and error reporting + +The token-based procedural macro API provides great control over where the +compiler's error messages are displayed in user code. Consider the error the +user sees if one of their field types does not implement `HeapSize`. + +```rust +#[derive(HeapSize)] +struct Broken { + ok: String, + bad: std::thread::Thread, +} +``` + +By tracking span information all the way through the expansion of a procedural +macro as shown in the `heapsize` example, token-based macros in Syn are able to +trigger errors that directly pinpoint the source of the problem. + +```console +error[E0277]: the trait bound `std::thread::Thread: HeapSize` is not satisfied + --> src/main.rs:7:5 + | +7 | bad: std::thread::Thread, + | ^^^^^^^^^^^^^^^^^^^^^^^^ the trait `HeapSize` is not implemented for `std::thread::Thread` +``` + +
+ +## Parsing a custom syntax + +The [`lazy-static`] example directory shows the implementation of a +`functionlike!(...)` procedural macro in which the input tokens are parsed using +Syn's parsing API. + +[`lazy-static`]: examples/lazy-static + +The example reimplements the popular `lazy_static` crate from crates.io as a +procedural macro. + +```rust +lazy_static! { + static ref USERNAME: Regex = Regex::new("^[a-z0-9_-]{3,16}$").unwrap(); +} +``` + +The implementation shows how to trigger custom warnings and error messages on +the macro input. + +```console +warning: come on, pick a more creative name + --> src/main.rs:10:16 + | +10 | static ref FOO: String = "lazy_static".to_owned(); + | ^^^ +``` + +
+ +## Testing + +When testing macros, we often care not just that the macro can be used +successfully but also that when the macro is provided with invalid input it +produces maximally helpful error messages. Consider using the [`trybuild`] crate +to write tests for errors that are emitted by your macro or errors detected by +the Rust compiler in the expanded code following misuse of the macro. Such tests +help avoid regressions from later refactors that mistakenly make an error no +longer trigger or be less helpful than it used to be. + +[`trybuild`]: https://github.com/dtolnay/trybuild + +
+ +## Debugging + +When developing a procedural macro it can be helpful to look at what the +generated code looks like. Use `cargo rustc -- -Zunstable-options +--pretty=expanded` or the [`cargo expand`] subcommand. + +[`cargo expand`]: https://github.com/dtolnay/cargo-expand + +To show the expanded code for some crate that uses your procedural macro, run +`cargo expand` from that crate. To show the expanded code for one of your own +test cases, run `cargo expand --test the_test_case` where the last argument is +the name of the test file without the `.rs` extension. + +This write-up by Brandon W Maister discusses debugging in more detail: +[Debugging Rust's new Custom Derive system][debugging]. + +[debugging]: https://quodlibetor.github.io/posts/debugging-rusts-new-custom-derive-system/ + +
+ +## Optional features + +Syn puts a lot of functionality behind optional features in order to optimize +compile time for the most common use cases. The following features are +available. + +- **`derive`** *(enabled by default)* — Data structures for representing the + possible input to a derive macro, including structs and enums and types. +- **`full`** — Data structures for representing the syntax tree of all valid + Rust source code, including items and expressions. +- **`parsing`** *(enabled by default)* — Ability to parse input tokens into a + syntax tree node of a chosen type. +- **`printing`** *(enabled by default)* — Ability to print a syntax tree node as + tokens of Rust source code. +- **`visit`** — Trait for traversing a syntax tree. +- **`visit-mut`** — Trait for traversing and mutating in place a syntax tree. +- **`fold`** — Trait for transforming an owned syntax tree. +- **`clone-impls`** *(enabled by default)* — Clone impls for all syntax tree + types. +- **`extra-traits`** — Debug, Eq, PartialEq, Hash impls for all syntax tree + types. +- **`proc-macro`** *(enabled by default)* — Runtime dependency on the dynamic + library libproc_macro from rustc toolchain. + +
+ +## Proc macro shim + +Syn operates on the token representation provided by the [proc-macro2] crate +from crates.io rather than using the compiler's built in proc-macro crate +directly. This enables code using Syn to execute outside of the context of a +procedural macro, such as in unit tests or build.rs, and we avoid needing +incompatible ecosystems for proc macros vs non-macro use cases. + +In general all of your code should be written against proc-macro2 rather than +proc-macro. The one exception is in the signatures of procedural macro entry +points, which are required by the language to use `proc_macro::TokenStream`. + +The proc-macro2 crate will automatically detect and use the compiler's data +structures when a procedural macro is active. + +[proc-macro2]: https://docs.rs/proc-macro2/1.0/proc_macro2/ + +
+ +#### License + + +Licensed under either of
Apache License, Version +2.0 or MIT license at your option. + + +
+ + +Unless you explicitly state otherwise, any contribution intentionally submitted +for inclusion in this crate 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/syn/benches/file.rs b/vendor/syn/benches/file.rs new file mode 100644 index 0000000..b424723 --- /dev/null +++ b/vendor/syn/benches/file.rs @@ -0,0 +1,57 @@ +// $ cargo bench --features full,test --bench file + +#![feature(rustc_private, test)] +#![recursion_limit = "1024"] +#![allow( + clippy::items_after_statements, + clippy::manual_let_else, + clippy::match_like_matches_macro, + clippy::missing_panics_doc, + clippy::must_use_candidate, + clippy::uninlined_format_args +)] + +extern crate test; + +#[macro_use] +#[path = "../tests/macros/mod.rs"] +mod macros; + +#[allow(dead_code)] +#[path = "../tests/repo/mod.rs"] +mod repo; + +use proc_macro2::{Span, TokenStream}; +use std::fs; +use std::str::FromStr; +use syn::parse::{ParseStream, Parser}; +use test::Bencher; + +const FILE: &str = "tests/rust/library/core/src/str/mod.rs"; + +fn get_tokens() -> TokenStream { + repo::clone_rust(); + let content = fs::read_to_string(FILE).unwrap(); + TokenStream::from_str(&content).unwrap() +} + +#[bench] +fn baseline(b: &mut Bencher) { + let tokens = get_tokens(); + b.iter(|| drop(tokens.clone())); +} + +#[bench] +fn create_token_buffer(b: &mut Bencher) { + let tokens = get_tokens(); + fn immediate_fail(_input: ParseStream) -> syn::Result<()> { + Err(syn::Error::new(Span::call_site(), "")) + } + b.iter(|| immediate_fail.parse2(tokens.clone())); +} + +#[bench] +fn parse_file(b: &mut Bencher) { + let tokens = get_tokens(); + b.iter(|| syn::parse2::(tokens.clone())); +} diff --git a/vendor/syn/benches/rust.rs b/vendor/syn/benches/rust.rs new file mode 100644 index 0000000..09917e7 --- /dev/null +++ b/vendor/syn/benches/rust.rs @@ -0,0 +1,190 @@ +// $ cargo bench --features full,test --bench rust +// +// Syn only, useful for profiling: +// $ RUSTFLAGS='--cfg syn_only' cargo build --release --features full,test --bench rust + +#![cfg_attr(not(syn_only), feature(rustc_private))] +#![recursion_limit = "1024"] +#![allow( + clippy::arc_with_non_send_sync, + clippy::cast_lossless, + clippy::let_underscore_untyped, + clippy::manual_let_else, + clippy::match_like_matches_macro, + clippy::uninlined_format_args, + clippy::unnecessary_wraps +)] + +#[macro_use] +#[path = "../tests/macros/mod.rs"] +mod macros; + +#[allow(dead_code)] +#[path = "../tests/repo/mod.rs"] +mod repo; + +use std::fs; +use std::path::Path; +use std::time::{Duration, Instant}; + +#[cfg(not(syn_only))] +mod tokenstream_parse { + use proc_macro2::TokenStream; + use std::path::Path; + use std::str::FromStr; + + pub fn bench(_path: &Path, content: &str) -> Result<(), ()> { + TokenStream::from_str(content).map(drop).map_err(drop) + } +} + +mod syn_parse { + use std::path::Path; + + pub fn bench(_path: &Path, content: &str) -> Result<(), ()> { + syn::parse_file(content).map(drop).map_err(drop) + } +} + +#[cfg(not(syn_only))] +mod librustc_parse { + extern crate rustc_data_structures; + extern crate rustc_driver; + extern crate rustc_error_messages; + extern crate rustc_errors; + extern crate rustc_parse; + extern crate rustc_session; + extern crate rustc_span; + + use crate::repo; + use rustc_data_structures::sync::Lrc; + use rustc_error_messages::FluentBundle; + use rustc_errors::{emitter::Emitter, translation::Translate, DiagCtxt, DiagInner}; + use rustc_session::parse::ParseSess; + use rustc_span::source_map::{FilePathMapping, SourceMap}; + use rustc_span::FileName; + use std::path::Path; + + pub fn bench(path: &Path, content: &str) -> Result<(), ()> { + struct SilentEmitter; + + impl Emitter for SilentEmitter { + fn emit_diagnostic(&mut self, _diag: DiagInner) {} + fn source_map(&self) -> Option<&Lrc> { + None + } + } + + impl Translate for SilentEmitter { + fn fluent_bundle(&self) -> Option<&Lrc> { + None + } + fn fallback_fluent_bundle(&self) -> &FluentBundle { + panic!("silent emitter attempted to translate a diagnostic"); + } + } + + let edition = repo::edition(path).parse().unwrap(); + rustc_span::create_session_if_not_set_then(edition, |_| { + let source_map = Lrc::new(SourceMap::new(FilePathMapping::empty())); + let emitter = Box::new(SilentEmitter); + let handler = DiagCtxt::new(emitter); + let sess = ParseSess::with_dcx(handler, source_map); + let name = FileName::Custom("bench".to_owned()); + let mut parser = + rustc_parse::new_parser_from_source_str(&sess, name, content.to_owned()).unwrap(); + if let Err(diagnostic) = parser.parse_crate_mod() { + diagnostic.cancel(); + return Err(()); + }; + Ok(()) + }) + } +} + +#[cfg(not(syn_only))] +mod read_from_disk { + use std::path::Path; + + pub fn bench(_path: &Path, content: &str) -> Result<(), ()> { + let _ = content; + Ok(()) + } +} + +fn exec(mut codepath: impl FnMut(&Path, &str) -> Result<(), ()>) -> Duration { + let begin = Instant::now(); + let mut success = 0; + let mut total = 0; + + ["tests/rust/compiler", "tests/rust/library"] + .iter() + .flat_map(|dir| { + walkdir::WalkDir::new(dir) + .into_iter() + .filter_entry(repo::base_dir_filter) + }) + .for_each(|entry| { + let entry = entry.unwrap(); + let path = entry.path(); + if path.is_dir() { + return; + } + let content = fs::read_to_string(path).unwrap(); + let ok = codepath(path, &content).is_ok(); + success += ok as usize; + total += 1; + if !ok { + eprintln!("FAIL {}", path.display()); + } + }); + + assert_eq!(success, total); + begin.elapsed() +} + +fn main() { + repo::clone_rust(); + + macro_rules! testcases { + ($($(#[$cfg:meta])* $name:ident,)*) => { + [ + $( + $(#[$cfg])* + (stringify!($name), $name::bench as fn(&Path, &str) -> Result<(), ()>), + )* + ] + }; + } + + #[cfg(not(syn_only))] + { + let mut lines = 0; + let mut files = 0; + exec(|_path, content| { + lines += content.lines().count(); + files += 1; + Ok(()) + }); + eprintln!("\n{} lines in {} files", lines, files); + } + + for (name, f) in testcases!( + #[cfg(not(syn_only))] + read_from_disk, + #[cfg(not(syn_only))] + tokenstream_parse, + syn_parse, + #[cfg(not(syn_only))] + librustc_parse, + ) { + eprint!("{:20}", format!("{}:", name)); + let elapsed = exec(f); + eprintln!( + "elapsed={}.{:03}s", + elapsed.as_secs(), + elapsed.subsec_millis(), + ); + } + eprintln!(); +} diff --git a/vendor/syn/src/attr.rs b/vendor/syn/src/attr.rs new file mode 100644 index 0000000..579452b --- /dev/null +++ b/vendor/syn/src/attr.rs @@ -0,0 +1,824 @@ +#[cfg(feature = "parsing")] +use crate::error::Error; +#[cfg(feature = "parsing")] +use crate::error::Result; +use crate::expr::Expr; +use crate::mac::MacroDelimiter; +#[cfg(feature = "parsing")] +use crate::meta::{self, ParseNestedMeta}; +#[cfg(feature = "parsing")] +use crate::parse::{Parse, ParseStream, Parser}; +use crate::path::Path; +use crate::token; +use proc_macro2::TokenStream; +#[cfg(feature = "printing")] +use std::iter; +#[cfg(feature = "printing")] +use std::slice; + +ast_struct! { + /// An attribute, like `#[repr(transparent)]`. + /// + ///
+ /// + /// # Syntax + /// + /// Rust has six types of attributes. + /// + /// - Outer attributes like `#[repr(transparent)]`. These appear outside or + /// in front of the item they describe. + /// + /// - Inner attributes like `#![feature(proc_macro)]`. These appear inside + /// of the item they describe, usually a module. + /// + /// - Outer one-line doc comments like `/// Example`. + /// + /// - Inner one-line doc comments like `//! Please file an issue`. + /// + /// - Outer documentation blocks `/** Example */`. + /// + /// - Inner documentation blocks `/*! Please file an issue */`. + /// + /// The `style` field of type `AttrStyle` distinguishes whether an attribute + /// is outer or inner. + /// + /// Every attribute has a `path` that indicates the intended interpretation + /// of the rest of the attribute's contents. The path and the optional + /// additional contents are represented together in the `meta` field of the + /// attribute in three possible varieties: + /// + /// - Meta::Path — attributes whose information content conveys just a + /// path, for example the `#[test]` attribute. + /// + /// - Meta::List — attributes that carry arbitrary tokens after the + /// path, surrounded by a delimiter (parenthesis, bracket, or brace). For + /// example `#[derive(Copy)]` or `#[precondition(x < 5)]`. + /// + /// - Meta::NameValue — attributes with an `=` sign after the path, + /// followed by a Rust expression. For example `#[path = + /// "sys/windows.rs"]`. + /// + /// All doc comments are represented in the NameValue style with a path of + /// "doc", as this is how they are processed by the compiler and by + /// `macro_rules!` macros. + /// + /// ```text + /// #[derive(Copy, Clone)] + /// ~~~~~~Path + /// ^^^^^^^^^^^^^^^^^^^Meta::List + /// + /// #[path = "sys/windows.rs"] + /// ~~~~Path + /// ^^^^^^^^^^^^^^^^^^^^^^^Meta::NameValue + /// + /// #[test] + /// ^^^^Meta::Path + /// ``` + /// + ///
+ /// + /// # Parsing from tokens to Attribute + /// + /// This type does not implement the [`Parse`] trait and thus cannot be + /// parsed directly by [`ParseStream::parse`]. Instead use + /// [`ParseStream::call`] with one of the two parser functions + /// [`Attribute::parse_outer`] or [`Attribute::parse_inner`] depending on + /// which you intend to parse. + /// + /// [`Parse`]: crate::parse::Parse + /// [`ParseStream::parse`]: crate::parse::ParseBuffer::parse + /// [`ParseStream::call`]: crate::parse::ParseBuffer::call + /// + /// ``` + /// use syn::{Attribute, Ident, Result, Token}; + /// use syn::parse::{Parse, ParseStream}; + /// + /// // Parses a unit struct with attributes. + /// // + /// // #[path = "s.tmpl"] + /// // struct S; + /// struct UnitStruct { + /// attrs: Vec, + /// struct_token: Token![struct], + /// name: Ident, + /// semi_token: Token![;], + /// } + /// + /// impl Parse for UnitStruct { + /// fn parse(input: ParseStream) -> Result { + /// Ok(UnitStruct { + /// attrs: input.call(Attribute::parse_outer)?, + /// struct_token: input.parse()?, + /// name: input.parse()?, + /// semi_token: input.parse()?, + /// }) + /// } + /// } + /// ``` + /// + ///


+ /// + /// # Parsing from Attribute to structured arguments + /// + /// The grammar of attributes in Rust is very flexible, which makes the + /// syntax tree not that useful on its own. In particular, arguments of the + /// `Meta::List` variety of attribute are held in an arbitrary `tokens: + /// TokenStream`. Macros are expected to check the `path` of the attribute, + /// decide whether they recognize it, and then parse the remaining tokens + /// according to whatever grammar they wish to require for that kind of + /// attribute. Use [`parse_args()`] to parse those tokens into the expected + /// data structure. + /// + /// [`parse_args()`]: Attribute::parse_args + /// + ///


+ /// + /// # Doc comments + /// + /// The compiler transforms doc comments, such as `/// comment` and `/*! + /// comment */`, into attributes before macros are expanded. Each comment is + /// expanded into an attribute of the form `#[doc = r"comment"]`. + /// + /// As an example, the following `mod` items are expanded identically: + /// + /// ``` + /// # use syn::{ItemMod, parse_quote}; + /// let doc: ItemMod = parse_quote! { + /// /// Single line doc comments + /// /// We write so many! + /// /** + /// * Multi-line comments... + /// * May span many lines + /// */ + /// mod example { + /// //! Of course, they can be inner too + /// /*! And fit in a single line */ + /// } + /// }; + /// let attr: ItemMod = parse_quote! { + /// #[doc = r" Single line doc comments"] + /// #[doc = r" We write so many!"] + /// #[doc = r" + /// * Multi-line comments... + /// * May span many lines + /// "] + /// mod example { + /// #![doc = r" Of course, they can be inner too"] + /// #![doc = r" And fit in a single line "] + /// } + /// }; + /// assert_eq!(doc, attr); + /// ``` + #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))] + pub struct Attribute { + pub pound_token: Token![#], + pub style: AttrStyle, + pub bracket_token: token::Bracket, + pub meta: Meta, + } +} + +impl Attribute { + /// Returns the path that identifies the interpretation of this attribute. + /// + /// For example this would return the `test` in `#[test]`, the `derive` in + /// `#[derive(Copy)]`, and the `path` in `#[path = "sys/windows.rs"]`. + pub fn path(&self) -> &Path { + self.meta.path() + } + + /// Parse the arguments to the attribute as a syntax tree. + /// + /// This is similar to pulling out the `TokenStream` from `Meta::List` and + /// doing `syn::parse2::(meta_list.tokens)`, except that using + /// `parse_args` the error message has a more useful span when `tokens` is + /// empty. + /// + /// The surrounding delimiters are *not* included in the input to the + /// parser. + /// + /// ```text + /// #[my_attr(value < 5)] + /// ^^^^^^^^^ what gets parsed + /// ``` + /// + /// # Example + /// + /// ``` + /// use syn::{parse_quote, Attribute, Expr}; + /// + /// let attr: Attribute = parse_quote! { + /// #[precondition(value < 5)] + /// }; + /// + /// if attr.path().is_ident("precondition") { + /// let precondition: Expr = attr.parse_args()?; + /// // ... + /// } + /// # anyhow::Ok(()) + /// ``` + #[cfg(feature = "parsing")] + #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))] + pub fn parse_args(&self) -> Result { + self.parse_args_with(T::parse) + } + + /// Parse the arguments to the attribute using the given parser. + /// + /// # Example + /// + /// ``` + /// use syn::{parse_quote, Attribute}; + /// + /// let attr: Attribute = parse_quote! { + /// #[inception { #[brrrrrrraaaaawwwwrwrrrmrmrmmrmrmmmmm] }] + /// }; + /// + /// let bwom = attr.parse_args_with(Attribute::parse_outer)?; + /// + /// // Attribute does not have a Parse impl, so we couldn't directly do: + /// // let bwom: Attribute = attr.parse_args()?; + /// # anyhow::Ok(()) + /// ``` + #[cfg(feature = "parsing")] + #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))] + pub fn parse_args_with(&self, parser: F) -> Result { + match &self.meta { + Meta::Path(path) => Err(crate::error::new2( + path.segments.first().unwrap().ident.span(), + path.segments.last().unwrap().ident.span(), + format!( + "expected attribute arguments in parentheses: {}[{}(...)]", + parsing::DisplayAttrStyle(&self.style), + parsing::DisplayPath(path), + ), + )), + Meta::NameValue(meta) => Err(Error::new( + meta.eq_token.span, + format_args!( + "expected parentheses: {}[{}(...)]", + parsing::DisplayAttrStyle(&self.style), + parsing::DisplayPath(&meta.path), + ), + )), + Meta::List(meta) => meta.parse_args_with(parser), + } + } + + /// Parse the arguments to the attribute, expecting it to follow the + /// conventional structure used by most of Rust's built-in attributes. + /// + /// The [*Meta Item Attribute Syntax*][syntax] section in the Rust reference + /// explains the convention in more detail. Not all attributes follow this + /// convention, so [`parse_args()`][Self::parse_args] is available if you + /// need to parse arbitrarily goofy attribute syntax. + /// + /// [syntax]: https://doc.rust-lang.org/reference/attributes.html#meta-item-attribute-syntax + /// + /// # Example + /// + /// We'll parse a struct, and then parse some of Rust's `#[repr]` attribute + /// syntax. + /// + /// ``` + /// use syn::{parenthesized, parse_quote, token, ItemStruct, LitInt}; + /// + /// let input: ItemStruct = parse_quote! { + /// #[repr(C, align(4))] + /// pub struct MyStruct(u16, u32); + /// }; + /// + /// let mut repr_c = false; + /// let mut repr_transparent = false; + /// let mut repr_align = None::; + /// let mut repr_packed = None::; + /// for attr in &input.attrs { + /// if attr.path().is_ident("repr") { + /// attr.parse_nested_meta(|meta| { + /// // #[repr(C)] + /// if meta.path.is_ident("C") { + /// repr_c = true; + /// return Ok(()); + /// } + /// + /// // #[repr(transparent)] + /// if meta.path.is_ident("transparent") { + /// repr_transparent = true; + /// return Ok(()); + /// } + /// + /// // #[repr(align(N))] + /// if meta.path.is_ident("align") { + /// let content; + /// parenthesized!(content in meta.input); + /// let lit: LitInt = content.parse()?; + /// let n: usize = lit.base10_parse()?; + /// repr_align = Some(n); + /// return Ok(()); + /// } + /// + /// // #[repr(packed)] or #[repr(packed(N))], omitted N means 1 + /// if meta.path.is_ident("packed") { + /// if meta.input.peek(token::Paren) { + /// let content; + /// parenthesized!(content in meta.input); + /// let lit: LitInt = content.parse()?; + /// let n: usize = lit.base10_parse()?; + /// repr_packed = Some(n); + /// } else { + /// repr_packed = Some(1); + /// } + /// return Ok(()); + /// } + /// + /// Err(meta.error("unrecognized repr")) + /// })?; + /// } + /// } + /// # anyhow::Ok(()) + /// ``` + /// + /// # Alternatives + /// + /// In some cases, for attributes which have nested layers of structured + /// content, the following less flexible approach might be more convenient: + /// + /// ``` + /// # use syn::{parse_quote, ItemStruct}; + /// # + /// # let input: ItemStruct = parse_quote! { + /// # #[repr(C, align(4))] + /// # pub struct MyStruct(u16, u32); + /// # }; + /// # + /// use syn::punctuated::Punctuated; + /// use syn::{parenthesized, token, Error, LitInt, Meta, Token}; + /// + /// let mut repr_c = false; + /// let mut repr_transparent = false; + /// let mut repr_align = None::; + /// let mut repr_packed = None::; + /// for attr in &input.attrs { + /// if attr.path().is_ident("repr") { + /// let nested = attr.parse_args_with(Punctuated::::parse_terminated)?; + /// for meta in nested { + /// match meta { + /// // #[repr(C)] + /// Meta::Path(path) if path.is_ident("C") => { + /// repr_c = true; + /// } + /// + /// // #[repr(align(N))] + /// Meta::List(meta) if meta.path.is_ident("align") => { + /// let lit: LitInt = meta.parse_args()?; + /// let n: usize = lit.base10_parse()?; + /// repr_align = Some(n); + /// } + /// + /// /* ... */ + /// + /// _ => { + /// return Err(Error::new_spanned(meta, "unrecognized repr")); + /// } + /// } + /// } + /// } + /// } + /// # Ok(()) + /// ``` + #[cfg(feature = "parsing")] + #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))] + pub fn parse_nested_meta( + &self, + logic: impl FnMut(ParseNestedMeta) -> Result<()>, + ) -> Result<()> { + self.parse_args_with(meta::parser(logic)) + } + + /// Parses zero or more outer attributes from the stream. + /// + /// # Example + /// + /// See + /// [*Parsing from tokens to Attribute*](#parsing-from-tokens-to-attribute). + #[cfg(feature = "parsing")] + #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))] + pub fn parse_outer(input: ParseStream) -> Result> { + let mut attrs = Vec::new(); + while input.peek(Token![#]) { + attrs.push(input.call(parsing::single_parse_outer)?); + } + Ok(attrs) + } + + /// Parses zero or more inner attributes from the stream. + /// + /// # Example + /// + /// See + /// [*Parsing from tokens to Attribute*](#parsing-from-tokens-to-attribute). + #[cfg(feature = "parsing")] + #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))] + pub fn parse_inner(input: ParseStream) -> Result> { + let mut attrs = Vec::new(); + parsing::parse_inner(input, &mut attrs)?; + Ok(attrs) + } +} + +ast_enum! { + /// Distinguishes between attributes that decorate an item and attributes + /// that are contained within an item. + /// + /// # Outer attributes + /// + /// - `#[repr(transparent)]` + /// - `/// # Example` + /// - `/** Please file an issue */` + /// + /// # Inner attributes + /// + /// - `#![feature(proc_macro)]` + /// - `//! # Example` + /// - `/*! Please file an issue */` + #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))] + pub enum AttrStyle { + Outer, + Inner(Token![!]), + } +} + +ast_enum! { + /// Content of a compile-time structured attribute. + /// + /// ## Path + /// + /// A meta path is like the `test` in `#[test]`. + /// + /// ## List + /// + /// A meta list is like the `derive(Copy)` in `#[derive(Copy)]`. + /// + /// ## NameValue + /// + /// A name-value meta is like the `path = "..."` in `#[path = + /// "sys/windows.rs"]`. + /// + /// # Syntax tree enum + /// + /// This type is a [syntax tree enum]. + /// + /// [syntax tree enum]: crate::expr::Expr#syntax-tree-enums + #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))] + pub enum Meta { + Path(Path), + + /// A structured list within an attribute, like `derive(Copy, Clone)`. + List(MetaList), + + /// A name-value pair within an attribute, like `feature = "nightly"`. + NameValue(MetaNameValue), + } +} + +ast_struct! { + /// A structured list within an attribute, like `derive(Copy, Clone)`. + #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))] + pub struct MetaList { + pub path: Path, + pub delimiter: MacroDelimiter, + pub tokens: TokenStream, + } +} + +ast_struct! { + /// A name-value pair within an attribute, like `feature = "nightly"`. + #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))] + pub struct MetaNameValue { + pub path: Path, + pub eq_token: Token![=], + pub value: Expr, + } +} + +impl Meta { + /// Returns the path that begins this structured meta item. + /// + /// For example this would return the `test` in `#[test]`, the `derive` in + /// `#[derive(Copy)]`, and the `path` in `#[path = "sys/windows.rs"]`. + pub fn path(&self) -> &Path { + match self { + Meta::Path(path) => path, + Meta::List(meta) => &meta.path, + Meta::NameValue(meta) => &meta.path, + } + } + + /// Error if this is a `Meta::List` or `Meta::NameValue`. + #[cfg(feature = "parsing")] + #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))] + pub fn require_path_only(&self) -> Result<&Path> { + let error_span = match self { + Meta::Path(path) => return Ok(path), + Meta::List(meta) => meta.delimiter.span().open(), + Meta::NameValue(meta) => meta.eq_token.span, + }; + Err(Error::new(error_span, "unexpected token in attribute")) + } + + /// Error if this is a `Meta::Path` or `Meta::NameValue`. + #[cfg(feature = "parsing")] + #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))] + pub fn require_list(&self) -> Result<&MetaList> { + match self { + Meta::List(meta) => Ok(meta), + Meta::Path(path) => Err(crate::error::new2( + path.segments.first().unwrap().ident.span(), + path.segments.last().unwrap().ident.span(), + format!( + "expected attribute arguments in parentheses: `{}(...)`", + parsing::DisplayPath(path), + ), + )), + Meta::NameValue(meta) => Err(Error::new(meta.eq_token.span, "expected `(`")), + } + } + + /// Error if this is a `Meta::Path` or `Meta::List`. + #[cfg(feature = "parsing")] + #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))] + pub fn require_name_value(&self) -> Result<&MetaNameValue> { + match self { + Meta::NameValue(meta) => Ok(meta), + Meta::Path(path) => Err(crate::error::new2( + path.segments.first().unwrap().ident.span(), + path.segments.last().unwrap().ident.span(), + format!( + "expected a value for this attribute: `{} = ...`", + parsing::DisplayPath(path), + ), + )), + Meta::List(meta) => Err(Error::new(meta.delimiter.span().open(), "expected `=`")), + } + } +} + +impl MetaList { + /// See [`Attribute::parse_args`]. + #[cfg(feature = "parsing")] + #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))] + pub fn parse_args(&self) -> Result { + self.parse_args_with(T::parse) + } + + /// See [`Attribute::parse_args_with`]. + #[cfg(feature = "parsing")] + #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))] + pub fn parse_args_with(&self, parser: F) -> Result { + let scope = self.delimiter.span().close(); + crate::parse::parse_scoped(parser, scope, self.tokens.clone()) + } + + /// See [`Attribute::parse_nested_meta`]. + #[cfg(feature = "parsing")] + #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))] + pub fn parse_nested_meta( + &self, + logic: impl FnMut(ParseNestedMeta) -> Result<()>, + ) -> Result<()> { + self.parse_args_with(meta::parser(logic)) + } +} + +#[cfg(feature = "printing")] +pub(crate) trait FilterAttrs<'a> { + type Ret: Iterator; + + fn outer(self) -> Self::Ret; + #[cfg(feature = "full")] + fn inner(self) -> Self::Ret; +} + +#[cfg(feature = "printing")] +impl<'a> FilterAttrs<'a> for &'a [Attribute] { + type Ret = iter::Filter, fn(&&Attribute) -> bool>; + + fn outer(self) -> Self::Ret { + fn is_outer(attr: &&Attribute) -> bool { + match attr.style { + AttrStyle::Outer => true, + AttrStyle::Inner(_) => false, + } + } + self.iter().filter(is_outer) + } + + #[cfg(feature = "full")] + fn inner(self) -> Self::Ret { + fn is_inner(attr: &&Attribute) -> bool { + match attr.style { + AttrStyle::Inner(_) => true, + AttrStyle::Outer => false, + } + } + self.iter().filter(is_inner) + } +} + +impl From for Meta { + fn from(meta: Path) -> Meta { + Meta::Path(meta) + } +} + +impl From for Meta { + fn from(meta: MetaList) -> Meta { + Meta::List(meta) + } +} + +impl From for Meta { + fn from(meta: MetaNameValue) -> Meta { + Meta::NameValue(meta) + } +} + +#[cfg(feature = "parsing")] +pub(crate) mod parsing { + use crate::attr::{AttrStyle, Attribute, Meta, MetaList, MetaNameValue}; + use crate::error::Result; + use crate::expr::{Expr, ExprLit}; + use crate::lit::Lit; + use crate::parse::discouraged::Speculative as _; + use crate::parse::{Parse, ParseStream}; + use crate::path::Path; + use crate::{mac, token}; + use std::fmt::{self, Display}; + + pub(crate) fn parse_inner(input: ParseStream, attrs: &mut Vec) -> Result<()> { + while input.peek(Token![#]) && input.peek2(Token![!]) { + attrs.push(input.call(single_parse_inner)?); + } + Ok(()) + } + + pub(crate) fn single_parse_inner(input: ParseStream) -> Result { + let content; + Ok(Attribute { + pound_token: input.parse()?, + style: AttrStyle::Inner(input.parse()?), + bracket_token: bracketed!(content in input), + meta: content.parse()?, + }) + } + + pub(crate) fn single_parse_outer(input: ParseStream) -> Result { + let content; + Ok(Attribute { + pound_token: input.parse()?, + style: AttrStyle::Outer, + bracket_token: bracketed!(content in input), + meta: content.parse()?, + }) + } + + #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))] + impl Parse for Meta { + fn parse(input: ParseStream) -> Result { + let path = input.call(Path::parse_mod_style)?; + parse_meta_after_path(path, input) + } + } + + #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))] + impl Parse for MetaList { + fn parse(input: ParseStream) -> Result { + let path = input.call(Path::parse_mod_style)?; + parse_meta_list_after_path(path, input) + } + } + + #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))] + impl Parse for MetaNameValue { + fn parse(input: ParseStream) -> Result { + let path = input.call(Path::parse_mod_style)?; + parse_meta_name_value_after_path(path, input) + } + } + + pub(crate) fn parse_meta_after_path(path: Path, input: ParseStream) -> Result { + if input.peek(token::Paren) || input.peek(token::Bracket) || input.peek(token::Brace) { + parse_meta_list_after_path(path, input).map(Meta::List) + } else if input.peek(Token![=]) { + parse_meta_name_value_after_path(path, input).map(Meta::NameValue) + } else { + Ok(Meta::Path(path)) + } + } + + fn parse_meta_list_after_path(path: Path, input: ParseStream) -> Result { + let (delimiter, tokens) = mac::parse_delimiter(input)?; + Ok(MetaList { + path, + delimiter, + tokens, + }) + } + + fn parse_meta_name_value_after_path(path: Path, input: ParseStream) -> Result { + let eq_token: Token![=] = input.parse()?; + let ahead = input.fork(); + let lit: Option = ahead.parse()?; + let value = if let (Some(lit), true) = (lit, ahead.is_empty()) { + input.advance_to(&ahead); + Expr::Lit(ExprLit { + attrs: Vec::new(), + lit, + }) + } else if input.peek(Token![#]) && input.peek2(token::Bracket) { + return Err(input.error("unexpected attribute inside of attribute")); + } else { + input.parse()? + }; + Ok(MetaNameValue { + path, + eq_token, + value, + }) + } + + pub(super) struct DisplayAttrStyle<'a>(pub &'a AttrStyle); + + impl<'a> Display for DisplayAttrStyle<'a> { + fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str(match self.0 { + AttrStyle::Outer => "#", + AttrStyle::Inner(_) => "#!", + }) + } + } + + pub(super) struct DisplayPath<'a>(pub &'a Path); + + impl<'a> Display for DisplayPath<'a> { + fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + for (i, segment) in self.0.segments.iter().enumerate() { + if i > 0 || self.0.leading_colon.is_some() { + formatter.write_str("::")?; + } + write!(formatter, "{}", segment.ident)?; + } + Ok(()) + } + } +} + +#[cfg(feature = "printing")] +mod printing { + use crate::attr::{AttrStyle, Attribute, Meta, MetaList, MetaNameValue}; + use crate::path; + use crate::path::printing::PathStyle; + use proc_macro2::TokenStream; + use quote::ToTokens; + + #[cfg_attr(docsrs, doc(cfg(feature = "printing")))] + impl ToTokens for Attribute { + fn to_tokens(&self, tokens: &mut TokenStream) { + self.pound_token.to_tokens(tokens); + if let AttrStyle::Inner(b) = &self.style { + b.to_tokens(tokens); + } + self.bracket_token.surround(tokens, |tokens| { + self.meta.to_tokens(tokens); + }); + } + } + + #[cfg_attr(docsrs, doc(cfg(feature = "printing")))] + impl ToTokens for Meta { + fn to_tokens(&self, tokens: &mut TokenStream) { + match self { + Meta::Path(path) => path::printing::print_path(tokens, path, PathStyle::Mod), + Meta::List(meta_list) => meta_list.to_tokens(tokens), + Meta::NameValue(meta_name_value) => meta_name_value.to_tokens(tokens), + } + } + } + + #[cfg_attr(docsrs, doc(cfg(feature = "printing")))] + impl ToTokens for MetaList { + fn to_tokens(&self, tokens: &mut TokenStream) { + path::printing::print_path(tokens, &self.path, PathStyle::Mod); + self.delimiter.surround(tokens, self.tokens.clone()); + } + } + + #[cfg_attr(docsrs, doc(cfg(feature = "printing")))] + impl ToTokens for MetaNameValue { + fn to_tokens(&self, tokens: &mut TokenStream) { + path::printing::print_path(tokens, &self.path, PathStyle::Mod); + self.eq_token.to_tokens(tokens); + self.value.to_tokens(tokens); + } + } +} diff --git a/vendor/syn/src/bigint.rs b/vendor/syn/src/bigint.rs new file mode 100644 index 0000000..66aaa93 --- /dev/null +++ b/vendor/syn/src/bigint.rs @@ -0,0 +1,66 @@ +use std::ops::{AddAssign, MulAssign}; + +// For implementing base10_digits() accessor on LitInt. +pub(crate) struct BigInt { + digits: Vec, +} + +impl BigInt { + pub(crate) fn new() -> Self { + BigInt { digits: Vec::new() } + } + + pub(crate) fn to_string(&self) -> String { + let mut repr = String::with_capacity(self.digits.len()); + + let mut has_nonzero = false; + for digit in self.digits.iter().rev() { + has_nonzero |= *digit != 0; + if has_nonzero { + repr.push((*digit + b'0') as char); + } + } + + if repr.is_empty() { + repr.push('0'); + } + + repr + } + + fn reserve_two_digits(&mut self) { + let len = self.digits.len(); + let desired = + len + !self.digits.ends_with(&[0, 0]) as usize + !self.digits.ends_with(&[0]) as usize; + self.digits.resize(desired, 0); + } +} + +impl AddAssign for BigInt { + // Assumes increment <16. + fn add_assign(&mut self, mut increment: u8) { + self.reserve_two_digits(); + + let mut i = 0; + while increment > 0 { + let sum = self.digits[i] + increment; + self.digits[i] = sum % 10; + increment = sum / 10; + i += 1; + } + } +} + +impl MulAssign for BigInt { + // Assumes base <=16. + fn mul_assign(&mut self, base: u8) { + self.reserve_two_digits(); + + let mut carry = 0; + for digit in &mut self.digits { + let prod = *digit * base + carry; + *digit = prod % 10; + carry = prod / 10; + } + } +} diff --git a/vendor/syn/src/buffer.rs b/vendor/syn/src/buffer.rs new file mode 100644 index 0000000..c28440a --- /dev/null +++ b/vendor/syn/src/buffer.rs @@ -0,0 +1,431 @@ +//! A stably addressed token buffer supporting efficient traversal based on a +//! cheaply copyable cursor. + +// This module is heavily commented as it contains most of the unsafe code in +// Syn, and caution should be used when editing it. The public-facing interface +// is 100% safe but the implementation is fragile internally. + +use crate::Lifetime; +use proc_macro2::extra::DelimSpan; +use proc_macro2::{Delimiter, Group, Ident, Literal, Punct, Spacing, Span, TokenStream, TokenTree}; +use std::cmp::Ordering; +use std::marker::PhantomData; + +/// Internal type which is used instead of `TokenTree` to represent a token tree +/// within a `TokenBuffer`. +enum Entry { + // Mimicking types from proc-macro. + // Group entries contain the offset to the matching End entry. + Group(Group, usize), + Ident(Ident), + Punct(Punct), + Literal(Literal), + // End entries contain the offset (negative) to the start of the buffer, and + // offset (negative) to the matching Group entry. + End(isize, isize), +} + +/// A buffer that can be efficiently traversed multiple times, unlike +/// `TokenStream` which requires a deep copy in order to traverse more than +/// once. +pub struct TokenBuffer { + // NOTE: Do not implement clone on this - while the current design could be + // cloned, other designs which could be desirable may not be cloneable. + entries: Box<[Entry]>, +} + +impl TokenBuffer { + fn recursive_new(entries: &mut Vec, stream: TokenStream) { + for tt in stream { + match tt { + TokenTree::Ident(ident) => entries.push(Entry::Ident(ident)), + TokenTree::Punct(punct) => entries.push(Entry::Punct(punct)), + TokenTree::Literal(literal) => entries.push(Entry::Literal(literal)), + TokenTree::Group(group) => { + let group_start_index = entries.len(); + entries.push(Entry::End(0, 0)); // we replace this below + Self::recursive_new(entries, group.stream()); + let group_end_index = entries.len(); + let group_offset = group_end_index - group_start_index; + entries.push(Entry::End( + -(group_end_index as isize), + -(group_offset as isize), + )); + entries[group_start_index] = Entry::Group(group, group_offset); + } + } + } + } + + /// Creates a `TokenBuffer` containing all the tokens from the input + /// `proc_macro::TokenStream`. + #[cfg(feature = "proc-macro")] + #[cfg_attr(docsrs, doc(cfg(feature = "proc-macro")))] + pub fn new(stream: proc_macro::TokenStream) -> Self { + Self::new2(stream.into()) + } + + /// Creates a `TokenBuffer` containing all the tokens from the input + /// `proc_macro2::TokenStream`. + pub fn new2(stream: TokenStream) -> Self { + let mut entries = Vec::new(); + Self::recursive_new(&mut entries, stream); + entries.push(Entry::End(-(entries.len() as isize), 0)); + Self { + entries: entries.into_boxed_slice(), + } + } + + /// Creates a cursor referencing the first token in the buffer and able to + /// traverse until the end of the buffer. + pub fn begin(&self) -> Cursor { + let ptr = self.entries.as_ptr(); + unsafe { Cursor::create(ptr, ptr.add(self.entries.len() - 1)) } + } +} + +/// A cheaply copyable cursor into a `TokenBuffer`. +/// +/// This cursor holds a shared reference into the immutable data which is used +/// internally to represent a `TokenStream`, and can be efficiently manipulated +/// and copied around. +/// +/// An empty `Cursor` can be created directly, or one may create a `TokenBuffer` +/// object and get a cursor to its first token with `begin()`. +pub struct Cursor<'a> { + // The current entry which the `Cursor` is pointing at. + ptr: *const Entry, + // This is the only `Entry::End` object which this cursor is allowed to + // point at. All other `End` objects are skipped over in `Cursor::create`. + scope: *const Entry, + // Cursor is covariant in 'a. This field ensures that our pointers are still + // valid. + marker: PhantomData<&'a Entry>, +} + +impl<'a> Cursor<'a> { + /// Creates a cursor referencing a static empty TokenStream. + pub fn empty() -> Self { + // It's safe in this situation for us to put an `Entry` object in global + // storage, despite it not actually being safe to send across threads + // (`Ident` is a reference into a thread-local table). This is because + // this entry never includes a `Ident` object. + // + // This wrapper struct allows us to break the rules and put a `Sync` + // object in global storage. + struct UnsafeSyncEntry(Entry); + unsafe impl Sync for UnsafeSyncEntry {} + static EMPTY_ENTRY: UnsafeSyncEntry = UnsafeSyncEntry(Entry::End(0, 0)); + + Cursor { + ptr: &EMPTY_ENTRY.0, + scope: &EMPTY_ENTRY.0, + marker: PhantomData, + } + } + + /// This create method intelligently exits non-explicitly-entered + /// `None`-delimited scopes when the cursor reaches the end of them, + /// allowing for them to be treated transparently. + unsafe fn create(mut ptr: *const Entry, scope: *const Entry) -> Self { + // NOTE: If we're looking at a `End`, we want to advance the cursor + // past it, unless `ptr == scope`, which means that we're at the edge of + // our cursor's scope. We should only have `ptr != scope` at the exit + // from None-delimited groups entered with `ignore_none`. + while let Entry::End(..) = unsafe { &*ptr } { + if ptr == scope { + break; + } + ptr = unsafe { ptr.add(1) }; + } + + Cursor { + ptr, + scope, + marker: PhantomData, + } + } + + /// Get the current entry. + fn entry(self) -> &'a Entry { + unsafe { &*self.ptr } + } + + /// Bump the cursor to point at the next token after the current one. This + /// is undefined behavior if the cursor is currently looking at an + /// `Entry::End`. + /// + /// If the cursor is looking at an `Entry::Group`, the bumped cursor will + /// point at the first token in the group (with the same scope end). + unsafe fn bump_ignore_group(self) -> Cursor<'a> { + unsafe { Cursor::create(self.ptr.offset(1), self.scope) } + } + + /// While the cursor is looking at a `None`-delimited group, move it to look + /// at the first token inside instead. If the group is empty, this will move + /// the cursor past the `None`-delimited group. + /// + /// WARNING: This mutates its argument. + fn ignore_none(&mut self) { + while let Entry::Group(group, _) = self.entry() { + if group.delimiter() == Delimiter::None { + unsafe { *self = self.bump_ignore_group() }; + } else { + break; + } + } + } + + /// Checks whether the cursor is currently pointing at the end of its valid + /// scope. + pub fn eof(self) -> bool { + // We're at eof if we're at the end of our scope. + self.ptr == self.scope + } + + /// If the cursor is pointing at a `Group` with the given delimiter, returns + /// a cursor into that group and one pointing to the next `TokenTree`. + pub fn group(mut self, delim: Delimiter) -> Option<(Cursor<'a>, DelimSpan, Cursor<'a>)> { + // If we're not trying to enter a none-delimited group, we want to + // ignore them. We have to make sure to _not_ ignore them when we want + // to enter them, of course. For obvious reasons. + if delim != Delimiter::None { + self.ignore_none(); + } + + if let Entry::Group(group, end_offset) = self.entry() { + if group.delimiter() == delim { + let span = group.delim_span(); + let end_of_group = unsafe { self.ptr.add(*end_offset) }; + let inside_of_group = unsafe { Cursor::create(self.ptr.add(1), end_of_group) }; + let after_group = unsafe { Cursor::create(end_of_group, self.scope) }; + return Some((inside_of_group, span, after_group)); + } + } + + None + } + + pub(crate) fn any_group(self) -> Option<(Cursor<'a>, Delimiter, DelimSpan, Cursor<'a>)> { + if let Entry::Group(group, end_offset) = self.entry() { + let delimiter = group.delimiter(); + let span = group.delim_span(); + let end_of_group = unsafe { self.ptr.add(*end_offset) }; + let inside_of_group = unsafe { Cursor::create(self.ptr.add(1), end_of_group) }; + let after_group = unsafe { Cursor::create(end_of_group, self.scope) }; + return Some((inside_of_group, delimiter, span, after_group)); + } + + None + } + + pub(crate) fn any_group_token(self) -> Option<(Group, Cursor<'a>)> { + if let Entry::Group(group, end_offset) = self.entry() { + let end_of_group = unsafe { self.ptr.add(*end_offset) }; + let after_group = unsafe { Cursor::create(end_of_group, self.scope) }; + return Some((group.clone(), after_group)); + } + + None + } + + /// If the cursor is pointing at a `Ident`, returns it along with a cursor + /// pointing at the next `TokenTree`. + pub fn ident(mut self) -> Option<(Ident, Cursor<'a>)> { + self.ignore_none(); + match self.entry() { + Entry::Ident(ident) => Some((ident.clone(), unsafe { self.bump_ignore_group() })), + _ => None, + } + } + + /// If the cursor is pointing at a `Punct`, returns it along with a cursor + /// pointing at the next `TokenTree`. + pub fn punct(mut self) -> Option<(Punct, Cursor<'a>)> { + self.ignore_none(); + match self.entry() { + Entry::Punct(punct) if punct.as_char() != '\'' => { + Some((punct.clone(), unsafe { self.bump_ignore_group() })) + } + _ => None, + } + } + + /// If the cursor is pointing at a `Literal`, return it along with a cursor + /// pointing at the next `TokenTree`. + pub fn literal(mut self) -> Option<(Literal, Cursor<'a>)> { + self.ignore_none(); + match self.entry() { + Entry::Literal(literal) => Some((literal.clone(), unsafe { self.bump_ignore_group() })), + _ => None, + } + } + + /// If the cursor is pointing at a `Lifetime`, returns it along with a + /// cursor pointing at the next `TokenTree`. + pub fn lifetime(mut self) -> Option<(Lifetime, Cursor<'a>)> { + self.ignore_none(); + match self.entry() { + Entry::Punct(punct) if punct.as_char() == '\'' && punct.spacing() == Spacing::Joint => { + let next = unsafe { self.bump_ignore_group() }; + let (ident, rest) = next.ident()?; + let lifetime = Lifetime { + apostrophe: punct.span(), + ident, + }; + Some((lifetime, rest)) + } + _ => None, + } + } + + /// Copies all remaining tokens visible from this cursor into a + /// `TokenStream`. + pub fn token_stream(self) -> TokenStream { + let mut tts = Vec::new(); + let mut cursor = self; + while let Some((tt, rest)) = cursor.token_tree() { + tts.push(tt); + cursor = rest; + } + tts.into_iter().collect() + } + + /// If the cursor is pointing at a `TokenTree`, returns it along with a + /// cursor pointing at the next `TokenTree`. + /// + /// Returns `None` if the cursor has reached the end of its stream. + /// + /// This method does not treat `None`-delimited groups as transparent, and + /// will return a `Group(None, ..)` if the cursor is looking at one. + pub fn token_tree(self) -> Option<(TokenTree, Cursor<'a>)> { + let (tree, len) = match self.entry() { + Entry::Group(group, end_offset) => (group.clone().into(), *end_offset), + Entry::Literal(literal) => (literal.clone().into(), 1), + Entry::Ident(ident) => (ident.clone().into(), 1), + Entry::Punct(punct) => (punct.clone().into(), 1), + Entry::End(..) => return None, + }; + + let rest = unsafe { Cursor::create(self.ptr.add(len), self.scope) }; + Some((tree, rest)) + } + + /// Returns the `Span` of the current token, or `Span::call_site()` if this + /// cursor points to eof. + pub fn span(mut self) -> Span { + match self.entry() { + Entry::Group(group, _) => group.span(), + Entry::Literal(literal) => literal.span(), + Entry::Ident(ident) => ident.span(), + Entry::Punct(punct) => punct.span(), + Entry::End(_, offset) => { + self.ptr = unsafe { self.ptr.offset(*offset) }; + if let Entry::Group(group, _) = self.entry() { + group.span_close() + } else { + Span::call_site() + } + } + } + } + + /// Returns the `Span` of the token immediately prior to the position of + /// this cursor, or of the current token if there is no previous one. + #[cfg(any(feature = "full", feature = "derive"))] + pub(crate) fn prev_span(mut self) -> Span { + if start_of_buffer(self) < self.ptr { + self.ptr = unsafe { self.ptr.offset(-1) }; + } + self.span() + } + + /// Skip over the next token that is not a None-delimited group, without + /// cloning it. Returns `None` if this cursor points to eof. + /// + /// This method treats `'lifetimes` as a single token. + pub(crate) fn skip(mut self) -> Option> { + self.ignore_none(); + + let len = match self.entry() { + Entry::End(..) => return None, + + // Treat lifetimes as a single tt for the purposes of 'skip'. + Entry::Punct(punct) if punct.as_char() == '\'' && punct.spacing() == Spacing::Joint => { + match unsafe { &*self.ptr.add(1) } { + Entry::Ident(_) => 2, + _ => 1, + } + } + + Entry::Group(_, end_offset) => *end_offset, + _ => 1, + }; + + Some(unsafe { Cursor::create(self.ptr.add(len), self.scope) }) + } + + pub(crate) fn scope_delimiter(self) -> Delimiter { + match unsafe { &*self.scope } { + Entry::End(_, offset) => match unsafe { &*self.scope.offset(*offset) } { + Entry::Group(group, _) => group.delimiter(), + _ => Delimiter::None, + }, + _ => unreachable!(), + } + } +} + +impl<'a> Copy for Cursor<'a> {} + +impl<'a> Clone for Cursor<'a> { + fn clone(&self) -> Self { + *self + } +} + +impl<'a> Eq for Cursor<'a> {} + +impl<'a> PartialEq for Cursor<'a> { + fn eq(&self, other: &Self) -> bool { + self.ptr == other.ptr + } +} + +impl<'a> PartialOrd for Cursor<'a> { + fn partial_cmp(&self, other: &Self) -> Option { + if same_buffer(*self, *other) { + Some(cmp_assuming_same_buffer(*self, *other)) + } else { + None + } + } +} + +pub(crate) fn same_scope(a: Cursor, b: Cursor) -> bool { + a.scope == b.scope +} + +pub(crate) fn same_buffer(a: Cursor, b: Cursor) -> bool { + start_of_buffer(a) == start_of_buffer(b) +} + +fn start_of_buffer(cursor: Cursor) -> *const Entry { + unsafe { + match &*cursor.scope { + Entry::End(offset, _) => cursor.scope.offset(*offset), + _ => unreachable!(), + } + } +} + +pub(crate) fn cmp_assuming_same_buffer(a: Cursor, b: Cursor) -> Ordering { + a.ptr.cmp(&b.ptr) +} + +pub(crate) fn open_span_of_group(cursor: Cursor) -> Span { + match cursor.entry() { + Entry::Group(group, _) => group.span_open(), + _ => cursor.span(), + } +} diff --git a/vendor/syn/src/classify.rs b/vendor/syn/src/classify.rs new file mode 100644 index 0000000..42732e6 --- /dev/null +++ b/vendor/syn/src/classify.rs @@ -0,0 +1,389 @@ +#[cfg(feature = "full")] +use crate::expr::Expr; +#[cfg(any(feature = "printing", feature = "full"))] +use crate::generics::TypeParamBound; +#[cfg(any(feature = "printing", feature = "full"))] +use crate::path::{Path, PathArguments}; +#[cfg(any(feature = "printing", feature = "full"))] +use crate::punctuated::Punctuated; +#[cfg(any(feature = "printing", feature = "full"))] +use crate::ty::{ReturnType, Type}; +#[cfg(feature = "full")] +use proc_macro2::{Delimiter, TokenStream, TokenTree}; +#[cfg(any(feature = "printing", feature = "full"))] +use std::ops::ControlFlow; + +#[cfg(feature = "full")] +pub(crate) fn requires_semi_to_be_stmt(expr: &Expr) -> bool { + match expr { + Expr::Macro(expr) => !expr.mac.delimiter.is_brace(), + _ => requires_comma_to_be_match_arm(expr), + } +} + +#[cfg(feature = "full")] +pub(crate) fn requires_comma_to_be_match_arm(expr: &Expr) -> bool { + match expr { + Expr::If(_) + | Expr::Match(_) + | Expr::Block(_) | Expr::Unsafe(_) // both under ExprKind::Block in rustc + | Expr::While(_) + | Expr::Loop(_) + | Expr::ForLoop(_) + | Expr::TryBlock(_) + | Expr::Const(_) => false, + + Expr::Array(_) + | Expr::Assign(_) + | Expr::Async(_) + | Expr::Await(_) + | Expr::Binary(_) + | Expr::Break(_) + | Expr::Call(_) + | Expr::Cast(_) + | Expr::Closure(_) + | Expr::Continue(_) + | Expr::Field(_) + | Expr::Group(_) + | Expr::Index(_) + | Expr::Infer(_) + | Expr::Let(_) + | Expr::Lit(_) + | Expr::Macro(_) + | Expr::MethodCall(_) + | Expr::Paren(_) + | Expr::Path(_) + | Expr::Range(_) + | Expr::Reference(_) + | Expr::Repeat(_) + | Expr::Return(_) + | Expr::Struct(_) + | Expr::Try(_) + | Expr::Tuple(_) + | Expr::Unary(_) + | Expr::Yield(_) + | Expr::Verbatim(_) => true + } +} + +#[cfg(all(feature = "printing", feature = "full"))] +pub(crate) fn confusable_with_adjacent_block(mut expr: &Expr) -> bool { + let mut stack = Vec::new(); + + while let Some(next) = match expr { + Expr::Assign(e) => { + stack.push(&e.right); + Some(&e.left) + } + Expr::Await(e) => Some(&e.base), + Expr::Binary(e) => { + stack.push(&e.right); + Some(&e.left) + } + Expr::Break(e) => { + if let Some(Expr::Block(_)) = e.expr.as_deref() { + return true; + } + stack.pop() + } + Expr::Call(e) => Some(&e.func), + Expr::Cast(e) => Some(&e.expr), + Expr::Closure(e) => Some(&e.body), + Expr::Field(e) => Some(&e.base), + Expr::Index(e) => Some(&e.expr), + Expr::MethodCall(e) => Some(&e.receiver), + Expr::Range(e) => { + if let Some(Expr::Block(_)) = e.end.as_deref() { + return true; + } + match (&e.start, &e.end) { + (Some(start), end) => { + stack.extend(end); + Some(start) + } + (None, Some(end)) => Some(end), + (None, None) => stack.pop(), + } + } + Expr::Reference(e) => Some(&e.expr), + Expr::Return(e) => { + if e.expr.is_none() && stack.is_empty() { + return true; + } + stack.pop() + } + Expr::Struct(_) => return true, + Expr::Try(e) => Some(&e.expr), + Expr::Unary(e) => Some(&e.expr), + Expr::Yield(e) => { + if e.expr.is_none() && stack.is_empty() { + return true; + } + stack.pop() + } + + Expr::Array(_) + | Expr::Async(_) + | Expr::Block(_) + | Expr::Const(_) + | Expr::Continue(_) + | Expr::ForLoop(_) + | Expr::Group(_) + | Expr::If(_) + | Expr::Infer(_) + | Expr::Let(_) + | Expr::Lit(_) + | Expr::Loop(_) + | Expr::Macro(_) + | Expr::Match(_) + | Expr::Paren(_) + | Expr::Path(_) + | Expr::Repeat(_) + | Expr::TryBlock(_) + | Expr::Tuple(_) + | Expr::Unsafe(_) + | Expr::Verbatim(_) + | Expr::While(_) => stack.pop(), + } { + expr = next; + } + + false +} + +#[cfg(feature = "printing")] +pub(crate) fn trailing_unparameterized_path(mut ty: &Type) -> bool { + loop { + match ty { + Type::BareFn(t) => match &t.output { + ReturnType::Default => return false, + ReturnType::Type(_, ret) => ty = ret, + }, + Type::ImplTrait(t) => match last_type_in_bounds(&t.bounds) { + ControlFlow::Break(trailing_path) => return trailing_path, + ControlFlow::Continue(t) => ty = t, + }, + Type::Path(t) => match last_type_in_path(&t.path) { + ControlFlow::Break(trailing_path) => return trailing_path, + ControlFlow::Continue(t) => ty = t, + }, + Type::Ptr(t) => ty = &t.elem, + Type::Reference(t) => ty = &t.elem, + Type::TraitObject(t) => match last_type_in_bounds(&t.bounds) { + ControlFlow::Break(trailing_path) => return trailing_path, + ControlFlow::Continue(t) => ty = t, + }, + + Type::Array(_) + | Type::Group(_) + | Type::Infer(_) + | Type::Macro(_) + | Type::Never(_) + | Type::Paren(_) + | Type::Slice(_) + | Type::Tuple(_) + | Type::Verbatim(_) => return false, + } + } + + fn last_type_in_path(path: &Path) -> ControlFlow { + match &path.segments.last().unwrap().arguments { + PathArguments::None => ControlFlow::Break(true), + PathArguments::AngleBracketed(_) => ControlFlow::Break(false), + PathArguments::Parenthesized(arg) => match &arg.output { + ReturnType::Default => ControlFlow::Break(false), + ReturnType::Type(_, ret) => ControlFlow::Continue(ret), + }, + } + } + + fn last_type_in_bounds( + bounds: &Punctuated, + ) -> ControlFlow { + match bounds.last().unwrap() { + TypeParamBound::Trait(t) => last_type_in_path(&t.path), + TypeParamBound::Lifetime(_) | TypeParamBound::Verbatim(_) => ControlFlow::Break(false), + } + } +} + +/// Whether the expression's first token is the label of a loop/block. +#[cfg(all(feature = "printing", feature = "full"))] +pub(crate) fn expr_leading_label(mut expr: &Expr) -> bool { + loop { + match expr { + Expr::Block(e) => return e.label.is_some(), + Expr::ForLoop(e) => return e.label.is_some(), + Expr::Loop(e) => return e.label.is_some(), + Expr::While(e) => return e.label.is_some(), + + Expr::Assign(e) => expr = &e.left, + Expr::Await(e) => expr = &e.base, + Expr::Binary(e) => expr = &e.left, + Expr::Call(e) => expr = &e.func, + Expr::Cast(e) => expr = &e.expr, + Expr::Field(e) => expr = &e.base, + Expr::Index(e) => expr = &e.expr, + Expr::MethodCall(e) => expr = &e.receiver, + Expr::Range(e) => match &e.start { + Some(start) => expr = start, + None => return false, + }, + Expr::Try(e) => expr = &e.expr, + + Expr::Array(_) + | Expr::Async(_) + | Expr::Break(_) + | Expr::Closure(_) + | Expr::Const(_) + | Expr::Continue(_) + | Expr::Group(_) + | Expr::If(_) + | Expr::Infer(_) + | Expr::Let(_) + | Expr::Lit(_) + | Expr::Macro(_) + | Expr::Match(_) + | Expr::Paren(_) + | Expr::Path(_) + | Expr::Reference(_) + | Expr::Repeat(_) + | Expr::Return(_) + | Expr::Struct(_) + | Expr::TryBlock(_) + | Expr::Tuple(_) + | Expr::Unary(_) + | Expr::Unsafe(_) + | Expr::Verbatim(_) + | Expr::Yield(_) => return false, + } + } +} + +/// Whether the expression's last token is `}`. +#[cfg(feature = "full")] +pub(crate) fn expr_trailing_brace(mut expr: &Expr) -> bool { + loop { + match expr { + Expr::Async(_) + | Expr::Block(_) + | Expr::Const(_) + | Expr::ForLoop(_) + | Expr::If(_) + | Expr::Loop(_) + | Expr::Match(_) + | Expr::Struct(_) + | Expr::TryBlock(_) + | Expr::Unsafe(_) + | Expr::While(_) => return true, + + Expr::Assign(e) => expr = &e.right, + Expr::Binary(e) => expr = &e.right, + Expr::Break(e) => match &e.expr { + Some(e) => expr = e, + None => return false, + }, + Expr::Cast(e) => return type_trailing_brace(&e.ty), + Expr::Closure(e) => expr = &e.body, + Expr::Let(e) => expr = &e.expr, + Expr::Macro(e) => return e.mac.delimiter.is_brace(), + Expr::Range(e) => match &e.end { + Some(end) => expr = end, + None => return false, + }, + Expr::Reference(e) => expr = &e.expr, + Expr::Return(e) => match &e.expr { + Some(e) => expr = e, + None => return false, + }, + Expr::Unary(e) => expr = &e.expr, + Expr::Verbatim(e) => return tokens_trailing_brace(e), + Expr::Yield(e) => match &e.expr { + Some(e) => expr = e, + None => return false, + }, + + Expr::Array(_) + | Expr::Await(_) + | Expr::Call(_) + | Expr::Continue(_) + | Expr::Field(_) + | Expr::Group(_) + | Expr::Index(_) + | Expr::Infer(_) + | Expr::Lit(_) + | Expr::MethodCall(_) + | Expr::Paren(_) + | Expr::Path(_) + | Expr::Repeat(_) + | Expr::Try(_) + | Expr::Tuple(_) => return false, + } + } + + fn type_trailing_brace(mut ty: &Type) -> bool { + loop { + match ty { + Type::BareFn(t) => match &t.output { + ReturnType::Default => return false, + ReturnType::Type(_, ret) => ty = ret, + }, + Type::ImplTrait(t) => match last_type_in_bounds(&t.bounds) { + ControlFlow::Break(trailing_brace) => return trailing_brace, + ControlFlow::Continue(t) => ty = t, + }, + Type::Macro(t) => return t.mac.delimiter.is_brace(), + Type::Path(t) => match last_type_in_path(&t.path) { + Some(t) => ty = t, + None => return false, + }, + Type::Ptr(t) => ty = &t.elem, + Type::Reference(t) => ty = &t.elem, + Type::TraitObject(t) => match last_type_in_bounds(&t.bounds) { + ControlFlow::Break(trailing_brace) => return trailing_brace, + ControlFlow::Continue(t) => ty = t, + }, + Type::Verbatim(t) => return tokens_trailing_brace(t), + + Type::Array(_) + | Type::Group(_) + | Type::Infer(_) + | Type::Never(_) + | Type::Paren(_) + | Type::Slice(_) + | Type::Tuple(_) => return false, + } + } + } + + fn last_type_in_path(path: &Path) -> Option<&Type> { + match &path.segments.last().unwrap().arguments { + PathArguments::None | PathArguments::AngleBracketed(_) => None, + PathArguments::Parenthesized(arg) => match &arg.output { + ReturnType::Default => None, + ReturnType::Type(_, ret) => Some(ret), + }, + } + } + + fn last_type_in_bounds( + bounds: &Punctuated, + ) -> ControlFlow { + match bounds.last().unwrap() { + TypeParamBound::Trait(t) => match last_type_in_path(&t.path) { + Some(t) => ControlFlow::Continue(t), + None => ControlFlow::Break(false), + }, + TypeParamBound::Lifetime(_) => ControlFlow::Break(false), + TypeParamBound::Verbatim(t) => ControlFlow::Break(tokens_trailing_brace(t)), + } + } + + fn tokens_trailing_brace(tokens: &TokenStream) -> bool { + if let Some(TokenTree::Group(last)) = tokens.clone().into_iter().last() { + last.delimiter() == Delimiter::Brace + } else { + false + } + } +} diff --git a/vendor/syn/src/custom_keyword.rs b/vendor/syn/src/custom_keyword.rs new file mode 100644 index 0000000..cc4f632 --- /dev/null +++ b/vendor/syn/src/custom_keyword.rs @@ -0,0 +1,260 @@ +/// Define a type that supports parsing and printing a given identifier as if it +/// were a keyword. +/// +/// # Usage +/// +/// As a convention, it is recommended that this macro be invoked within a +/// module called `kw` or `keyword` and that the resulting parser be invoked +/// with a `kw::` or `keyword::` prefix. +/// +/// ``` +/// mod kw { +/// syn::custom_keyword!(whatever); +/// } +/// ``` +/// +/// The generated syntax tree node supports the following operations just like +/// any built-in keyword token. +/// +/// - [Peeking] — `input.peek(kw::whatever)` +/// +/// - [Parsing] — `input.parse::()?` +/// +/// - [Printing] — `quote!( ... #whatever_token ... )` +/// +/// - Construction from a [`Span`] — `let whatever_token = kw::whatever(sp)` +/// +/// - Field access to its span — `let sp = whatever_token.span` +/// +/// [Peeking]: crate::parse::ParseBuffer::peek +/// [Parsing]: crate::parse::ParseBuffer::parse +/// [Printing]: quote::ToTokens +/// [`Span`]: proc_macro2::Span +/// +/// # Example +/// +/// This example parses input that looks like `bool = true` or `str = "value"`. +/// The key must be either the identifier `bool` or the identifier `str`. If +/// `bool`, the value may be either `true` or `false`. If `str`, the value may +/// be any string literal. +/// +/// The symbols `bool` and `str` are not reserved keywords in Rust so these are +/// not considered keywords in the `syn::token` module. Like any other +/// identifier that is not a keyword, these can be declared as custom keywords +/// by crates that need to use them as such. +/// +/// ``` +/// use syn::{LitBool, LitStr, Result, Token}; +/// use syn::parse::{Parse, ParseStream}; +/// +/// mod kw { +/// syn::custom_keyword!(bool); +/// syn::custom_keyword!(str); +/// } +/// +/// enum Argument { +/// Bool { +/// bool_token: kw::bool, +/// eq_token: Token![=], +/// value: LitBool, +/// }, +/// Str { +/// str_token: kw::str, +/// eq_token: Token![=], +/// value: LitStr, +/// }, +/// } +/// +/// impl Parse for Argument { +/// fn parse(input: ParseStream) -> Result { +/// let lookahead = input.lookahead1(); +/// if lookahead.peek(kw::bool) { +/// Ok(Argument::Bool { +/// bool_token: input.parse::()?, +/// eq_token: input.parse()?, +/// value: input.parse()?, +/// }) +/// } else if lookahead.peek(kw::str) { +/// Ok(Argument::Str { +/// str_token: input.parse::()?, +/// eq_token: input.parse()?, +/// value: input.parse()?, +/// }) +/// } else { +/// Err(lookahead.error()) +/// } +/// } +/// } +/// ``` +#[macro_export] +macro_rules! custom_keyword { + ($ident:ident) => { + #[allow(non_camel_case_types)] + pub struct $ident { + #[allow(dead_code)] + pub span: $crate::__private::Span, + } + + #[doc(hidden)] + #[allow(dead_code, non_snake_case)] + pub fn $ident<__S: $crate::__private::IntoSpans<$crate::__private::Span>>( + span: __S, + ) -> $ident { + $ident { + span: $crate::__private::IntoSpans::into_spans(span), + } + } + + const _: () = { + impl $crate::__private::Default for $ident { + fn default() -> Self { + $ident { + span: $crate::__private::Span::call_site(), + } + } + } + + $crate::impl_parse_for_custom_keyword!($ident); + $crate::impl_to_tokens_for_custom_keyword!($ident); + $crate::impl_clone_for_custom_keyword!($ident); + $crate::impl_extra_traits_for_custom_keyword!($ident); + }; + }; +} + +// Not public API. +#[cfg(feature = "parsing")] +#[doc(hidden)] +#[macro_export] +macro_rules! impl_parse_for_custom_keyword { + ($ident:ident) => { + // For peek. + impl $crate::__private::CustomToken for $ident { + fn peek(cursor: $crate::buffer::Cursor) -> $crate::__private::bool { + if let $crate::__private::Some((ident, _rest)) = cursor.ident() { + ident == $crate::__private::stringify!($ident) + } else { + false + } + } + + fn display() -> &'static $crate::__private::str { + $crate::__private::concat!("`", $crate::__private::stringify!($ident), "`") + } + } + + impl $crate::parse::Parse for $ident { + fn parse(input: $crate::parse::ParseStream) -> $crate::parse::Result<$ident> { + input.step(|cursor| { + if let $crate::__private::Some((ident, rest)) = cursor.ident() { + if ident == $crate::__private::stringify!($ident) { + return $crate::__private::Ok(($ident { span: ident.span() }, rest)); + } + } + $crate::__private::Err(cursor.error($crate::__private::concat!( + "expected `", + $crate::__private::stringify!($ident), + "`", + ))) + }) + } + } + }; +} + +// Not public API. +#[cfg(not(feature = "parsing"))] +#[doc(hidden)] +#[macro_export] +macro_rules! impl_parse_for_custom_keyword { + ($ident:ident) => {}; +} + +// Not public API. +#[cfg(feature = "printing")] +#[doc(hidden)] +#[macro_export] +macro_rules! impl_to_tokens_for_custom_keyword { + ($ident:ident) => { + impl $crate::__private::ToTokens for $ident { + fn to_tokens(&self, tokens: &mut $crate::__private::TokenStream2) { + let ident = $crate::Ident::new($crate::__private::stringify!($ident), self.span); + $crate::__private::TokenStreamExt::append(tokens, ident); + } + } + }; +} + +// Not public API. +#[cfg(not(feature = "printing"))] +#[doc(hidden)] +#[macro_export] +macro_rules! impl_to_tokens_for_custom_keyword { + ($ident:ident) => {}; +} + +// Not public API. +#[cfg(feature = "clone-impls")] +#[doc(hidden)] +#[macro_export] +macro_rules! impl_clone_for_custom_keyword { + ($ident:ident) => { + impl $crate::__private::Copy for $ident {} + + #[allow(clippy::expl_impl_clone_on_copy)] + impl $crate::__private::Clone for $ident { + fn clone(&self) -> Self { + *self + } + } + }; +} + +// Not public API. +#[cfg(not(feature = "clone-impls"))] +#[doc(hidden)] +#[macro_export] +macro_rules! impl_clone_for_custom_keyword { + ($ident:ident) => {}; +} + +// Not public API. +#[cfg(feature = "extra-traits")] +#[doc(hidden)] +#[macro_export] +macro_rules! impl_extra_traits_for_custom_keyword { + ($ident:ident) => { + impl $crate::__private::Debug for $ident { + fn fmt(&self, f: &mut $crate::__private::Formatter) -> $crate::__private::FmtResult { + $crate::__private::Formatter::write_str( + f, + $crate::__private::concat!( + "Keyword [", + $crate::__private::stringify!($ident), + "]", + ), + ) + } + } + + impl $crate::__private::Eq for $ident {} + + impl $crate::__private::PartialEq for $ident { + fn eq(&self, _other: &Self) -> $crate::__private::bool { + true + } + } + + impl $crate::__private::Hash for $ident { + fn hash<__H: $crate::__private::Hasher>(&self, _state: &mut __H) {} + } + }; +} + +// Not public API. +#[cfg(not(feature = "extra-traits"))] +#[doc(hidden)] +#[macro_export] +macro_rules! impl_extra_traits_for_custom_keyword { + ($ident:ident) => {}; +} diff --git a/vendor/syn/src/custom_punctuation.rs b/vendor/syn/src/custom_punctuation.rs new file mode 100644 index 0000000..eef5f54 --- /dev/null +++ b/vendor/syn/src/custom_punctuation.rs @@ -0,0 +1,304 @@ +/// Define a type that supports parsing and printing a multi-character symbol +/// as if it were a punctuation token. +/// +/// # Usage +/// +/// ``` +/// syn::custom_punctuation!(LeftRightArrow, <=>); +/// ``` +/// +/// The generated syntax tree node supports the following operations just like +/// any built-in punctuation token. +/// +/// - [Peeking] — `input.peek(LeftRightArrow)` +/// +/// - [Parsing] — `input.parse::()?` +/// +/// - [Printing] — `quote!( ... #lrarrow ... )` +/// +/// - Construction from a [`Span`] — `let lrarrow = LeftRightArrow(sp)` +/// +/// - Construction from multiple [`Span`] — `let lrarrow = LeftRightArrow([sp, sp, sp])` +/// +/// - Field access to its spans — `let spans = lrarrow.spans` +/// +/// [Peeking]: crate::parse::ParseBuffer::peek +/// [Parsing]: crate::parse::ParseBuffer::parse +/// [Printing]: quote::ToTokens +/// [`Span`]: proc_macro2::Span +/// +/// # Example +/// +/// ``` +/// use proc_macro2::{TokenStream, TokenTree}; +/// use syn::parse::{Parse, ParseStream, Peek, Result}; +/// use syn::punctuated::Punctuated; +/// use syn::Expr; +/// +/// syn::custom_punctuation!(PathSeparator, ); +/// +/// // expr expr expr ... +/// struct PathSegments { +/// segments: Punctuated, +/// } +/// +/// impl Parse for PathSegments { +/// fn parse(input: ParseStream) -> Result { +/// let mut segments = Punctuated::new(); +/// +/// let first = parse_until(input, PathSeparator)?; +/// segments.push_value(syn::parse2(first)?); +/// +/// while input.peek(PathSeparator) { +/// segments.push_punct(input.parse()?); +/// +/// let next = parse_until(input, PathSeparator)?; +/// segments.push_value(syn::parse2(next)?); +/// } +/// +/// Ok(PathSegments { segments }) +/// } +/// } +/// +/// fn parse_until(input: ParseStream, end: E) -> Result { +/// let mut tokens = TokenStream::new(); +/// while !input.is_empty() && !input.peek(end) { +/// let next: TokenTree = input.parse()?; +/// tokens.extend(Some(next)); +/// } +/// Ok(tokens) +/// } +/// +/// fn main() { +/// let input = r#" a::b c::d::e "#; +/// let _: PathSegments = syn::parse_str(input).unwrap(); +/// } +/// ``` +#[macro_export] +macro_rules! custom_punctuation { + ($ident:ident, $($tt:tt)+) => { + pub struct $ident { + #[allow(dead_code)] + pub spans: $crate::custom_punctuation_repr!($($tt)+), + } + + #[doc(hidden)] + #[allow(dead_code, non_snake_case)] + pub fn $ident<__S: $crate::__private::IntoSpans<$crate::custom_punctuation_repr!($($tt)+)>>( + spans: __S, + ) -> $ident { + let _validate_len = 0 $(+ $crate::custom_punctuation_len!(strict, $tt))*; + $ident { + spans: $crate::__private::IntoSpans::into_spans(spans) + } + } + + const _: () = { + impl $crate::__private::Default for $ident { + fn default() -> Self { + $ident($crate::__private::Span::call_site()) + } + } + + $crate::impl_parse_for_custom_punctuation!($ident, $($tt)+); + $crate::impl_to_tokens_for_custom_punctuation!($ident, $($tt)+); + $crate::impl_clone_for_custom_punctuation!($ident, $($tt)+); + $crate::impl_extra_traits_for_custom_punctuation!($ident, $($tt)+); + }; + }; +} + +// Not public API. +#[cfg(feature = "parsing")] +#[doc(hidden)] +#[macro_export] +macro_rules! impl_parse_for_custom_punctuation { + ($ident:ident, $($tt:tt)+) => { + impl $crate::__private::CustomToken for $ident { + fn peek(cursor: $crate::buffer::Cursor) -> $crate::__private::bool { + $crate::__private::peek_punct(cursor, $crate::stringify_punct!($($tt)+)) + } + + fn display() -> &'static $crate::__private::str { + $crate::__private::concat!("`", $crate::stringify_punct!($($tt)+), "`") + } + } + + impl $crate::parse::Parse for $ident { + fn parse(input: $crate::parse::ParseStream) -> $crate::parse::Result<$ident> { + let spans: $crate::custom_punctuation_repr!($($tt)+) = + $crate::__private::parse_punct(input, $crate::stringify_punct!($($tt)+))?; + Ok($ident(spans)) + } + } + }; +} + +// Not public API. +#[cfg(not(feature = "parsing"))] +#[doc(hidden)] +#[macro_export] +macro_rules! impl_parse_for_custom_punctuation { + ($ident:ident, $($tt:tt)+) => {}; +} + +// Not public API. +#[cfg(feature = "printing")] +#[doc(hidden)] +#[macro_export] +macro_rules! impl_to_tokens_for_custom_punctuation { + ($ident:ident, $($tt:tt)+) => { + impl $crate::__private::ToTokens for $ident { + fn to_tokens(&self, tokens: &mut $crate::__private::TokenStream2) { + $crate::__private::print_punct($crate::stringify_punct!($($tt)+), &self.spans, tokens) + } + } + }; +} + +// Not public API. +#[cfg(not(feature = "printing"))] +#[doc(hidden)] +#[macro_export] +macro_rules! impl_to_tokens_for_custom_punctuation { + ($ident:ident, $($tt:tt)+) => {}; +} + +// Not public API. +#[cfg(feature = "clone-impls")] +#[doc(hidden)] +#[macro_export] +macro_rules! impl_clone_for_custom_punctuation { + ($ident:ident, $($tt:tt)+) => { + impl $crate::__private::Copy for $ident {} + + #[allow(clippy::expl_impl_clone_on_copy)] + impl $crate::__private::Clone for $ident { + fn clone(&self) -> Self { + *self + } + } + }; +} + +// Not public API. +#[cfg(not(feature = "clone-impls"))] +#[doc(hidden)] +#[macro_export] +macro_rules! impl_clone_for_custom_punctuation { + ($ident:ident, $($tt:tt)+) => {}; +} + +// Not public API. +#[cfg(feature = "extra-traits")] +#[doc(hidden)] +#[macro_export] +macro_rules! impl_extra_traits_for_custom_punctuation { + ($ident:ident, $($tt:tt)+) => { + impl $crate::__private::Debug for $ident { + fn fmt(&self, f: &mut $crate::__private::Formatter) -> $crate::__private::FmtResult { + $crate::__private::Formatter::write_str(f, $crate::__private::stringify!($ident)) + } + } + + impl $crate::__private::Eq for $ident {} + + impl $crate::__private::PartialEq for $ident { + fn eq(&self, _other: &Self) -> $crate::__private::bool { + true + } + } + + impl $crate::__private::Hash for $ident { + fn hash<__H: $crate::__private::Hasher>(&self, _state: &mut __H) {} + } + }; +} + +// Not public API. +#[cfg(not(feature = "extra-traits"))] +#[doc(hidden)] +#[macro_export] +macro_rules! impl_extra_traits_for_custom_punctuation { + ($ident:ident, $($tt:tt)+) => {}; +} + +// Not public API. +#[doc(hidden)] +#[macro_export] +macro_rules! custom_punctuation_repr { + ($($tt:tt)+) => { + [$crate::__private::Span; 0 $(+ $crate::custom_punctuation_len!(lenient, $tt))+] + }; +} + +// Not public API. +#[doc(hidden)] +#[macro_export] +#[rustfmt::skip] +macro_rules! custom_punctuation_len { + ($mode:ident, &) => { 1 }; + ($mode:ident, &&) => { 2 }; + ($mode:ident, &=) => { 2 }; + ($mode:ident, @) => { 1 }; + ($mode:ident, ^) => { 1 }; + ($mode:ident, ^=) => { 2 }; + ($mode:ident, :) => { 1 }; + ($mode:ident, ,) => { 1 }; + ($mode:ident, $) => { 1 }; + ($mode:ident, .) => { 1 }; + ($mode:ident, ..) => { 2 }; + ($mode:ident, ...) => { 3 }; + ($mode:ident, ..=) => { 3 }; + ($mode:ident, =) => { 1 }; + ($mode:ident, ==) => { 2 }; + ($mode:ident, =>) => { 2 }; + ($mode:ident, >=) => { 2 }; + ($mode:ident, >) => { 1 }; + ($mode:ident, <-) => { 2 }; + ($mode:ident, <=) => { 2 }; + ($mode:ident, <) => { 1 }; + ($mode:ident, -) => { 1 }; + ($mode:ident, -=) => { 2 }; + ($mode:ident, !=) => { 2 }; + ($mode:ident, !) => { 1 }; + ($mode:ident, |) => { 1 }; + ($mode:ident, |=) => { 2 }; + ($mode:ident, ||) => { 2 }; + ($mode:ident, ::) => { 2 }; + ($mode:ident, %) => { 1 }; + ($mode:ident, %=) => { 2 }; + ($mode:ident, +) => { 1 }; + ($mode:ident, +=) => { 2 }; + ($mode:ident, #) => { 1 }; + ($mode:ident, ?) => { 1 }; + ($mode:ident, ->) => { 2 }; + ($mode:ident, ;) => { 1 }; + ($mode:ident, <<) => { 2 }; + ($mode:ident, <<=) => { 3 }; + ($mode:ident, >>) => { 2 }; + ($mode:ident, >>=) => { 3 }; + ($mode:ident, /) => { 1 }; + ($mode:ident, /=) => { 2 }; + ($mode:ident, *) => { 1 }; + ($mode:ident, *=) => { 2 }; + ($mode:ident, ~) => { 1 }; + (lenient, $tt:tt) => { 0 }; + (strict, $tt:tt) => {{ $crate::custom_punctuation_unexpected!($tt); 0 }}; +} + +// Not public API. +#[doc(hidden)] +#[macro_export] +macro_rules! custom_punctuation_unexpected { + () => {}; +} + +// Not public API. +#[doc(hidden)] +#[macro_export] +macro_rules! stringify_punct { + ($($tt:tt)+) => { + $crate::__private::concat!($($crate::__private::stringify!($tt)),+) + }; +} diff --git a/vendor/syn/src/data.rs b/vendor/syn/src/data.rs new file mode 100644 index 0000000..9e73f02 --- /dev/null +++ b/vendor/syn/src/data.rs @@ -0,0 +1,501 @@ +use crate::attr::Attribute; +use crate::expr::{Expr, Index, Member}; +use crate::ident::Ident; +use crate::punctuated::{self, Punctuated}; +use crate::restriction::{FieldMutability, Visibility}; +use crate::token; +use crate::ty::Type; + +ast_struct! { + /// An enum variant. + #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))] + pub struct Variant { + pub attrs: Vec, + + /// Name of the variant. + pub ident: Ident, + + /// Content stored in the variant. + pub fields: Fields, + + /// Explicit discriminant: `Variant = 1` + pub discriminant: Option<(Token![=], Expr)>, + } +} + +ast_enum_of_structs! { + /// Data stored within an enum variant or struct. + /// + /// # Syntax tree enum + /// + /// This type is a [syntax tree enum]. + /// + /// [syntax tree enum]: crate::expr::Expr#syntax-tree-enums + #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))] + pub enum Fields { + /// Named fields of a struct or struct variant such as `Point { x: f64, + /// y: f64 }`. + Named(FieldsNamed), + + /// Unnamed fields of a tuple struct or tuple variant such as `Some(T)`. + Unnamed(FieldsUnnamed), + + /// Unit struct or unit variant such as `None`. + Unit, + } +} + +ast_struct! { + /// Named fields of a struct or struct variant such as `Point { x: f64, + /// y: f64 }`. + #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))] + pub struct FieldsNamed { + pub brace_token: token::Brace, + pub named: Punctuated, + } +} + +ast_struct! { + /// Unnamed fields of a tuple struct or tuple variant such as `Some(T)`. + #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))] + pub struct FieldsUnnamed { + pub paren_token: token::Paren, + pub unnamed: Punctuated, + } +} + +impl Fields { + /// Get an iterator over the borrowed [`Field`] items in this object. This + /// iterator can be used to iterate over a named or unnamed struct or + /// variant's fields uniformly. + pub fn iter(&self) -> punctuated::Iter { + match self { + Fields::Unit => crate::punctuated::empty_punctuated_iter(), + Fields::Named(f) => f.named.iter(), + Fields::Unnamed(f) => f.unnamed.iter(), + } + } + + /// Get an iterator over the mutably borrowed [`Field`] items in this + /// object. This iterator can be used to iterate over a named or unnamed + /// struct or variant's fields uniformly. + pub fn iter_mut(&mut self) -> punctuated::IterMut { + match self { + Fields::Unit => crate::punctuated::empty_punctuated_iter_mut(), + Fields::Named(f) => f.named.iter_mut(), + Fields::Unnamed(f) => f.unnamed.iter_mut(), + } + } + + /// Returns the number of fields. + pub fn len(&self) -> usize { + match self { + Fields::Unit => 0, + Fields::Named(f) => f.named.len(), + Fields::Unnamed(f) => f.unnamed.len(), + } + } + + /// Returns `true` if there are zero fields. + pub fn is_empty(&self) -> bool { + match self { + Fields::Unit => true, + Fields::Named(f) => f.named.is_empty(), + Fields::Unnamed(f) => f.unnamed.is_empty(), + } + } + + return_impl_trait! { + /// Get an iterator over the fields of a struct or variant as [`Member`]s. + /// This iterator can be used to iterate over a named or unnamed struct or + /// variant's fields uniformly. + /// + /// # Example + /// + /// The following is a simplistic [`Clone`] derive for structs. (A more + /// complete implementation would additionally want to infer trait bounds on + /// the generic type parameters.) + /// + /// ``` + /// # use quote::quote; + /// # + /// fn derive_clone(input: &syn::ItemStruct) -> proc_macro2::TokenStream { + /// let ident = &input.ident; + /// let members = input.fields.members(); + /// let (impl_generics, ty_generics, where_clause) = input.generics.split_for_impl(); + /// quote! { + /// impl #impl_generics Clone for #ident #ty_generics #where_clause { + /// fn clone(&self) -> Self { + /// Self { + /// #(#members: self.#members.clone()),* + /// } + /// } + /// } + /// } + /// } + /// ``` + /// + /// For structs with named fields, it produces an expression like `Self { a: + /// self.a.clone() }`. For structs with unnamed fields, `Self { 0: + /// self.0.clone() }`. And for unit structs, `Self {}`. + pub fn members(&self) -> impl Iterator + Clone + '_ [Members] { + Members { + fields: self.iter(), + index: 0, + } + } + } +} + +impl IntoIterator for Fields { + type Item = Field; + type IntoIter = punctuated::IntoIter; + + fn into_iter(self) -> Self::IntoIter { + match self { + Fields::Unit => Punctuated::::new().into_iter(), + Fields::Named(f) => f.named.into_iter(), + Fields::Unnamed(f) => f.unnamed.into_iter(), + } + } +} + +impl<'a> IntoIterator for &'a Fields { + type Item = &'a Field; + type IntoIter = punctuated::Iter<'a, Field>; + + fn into_iter(self) -> Self::IntoIter { + self.iter() + } +} + +impl<'a> IntoIterator for &'a mut Fields { + type Item = &'a mut Field; + type IntoIter = punctuated::IterMut<'a, Field>; + + fn into_iter(self) -> Self::IntoIter { + self.iter_mut() + } +} + +ast_struct! { + /// A field of a struct or enum variant. + #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))] + pub struct Field { + pub attrs: Vec, + + pub vis: Visibility, + + pub mutability: FieldMutability, + + /// Name of the field, if any. + /// + /// Fields of tuple structs have no names. + pub ident: Option, + + pub colon_token: Option, + + pub ty: Type, + } +} + +pub struct Members<'a> { + fields: punctuated::Iter<'a, Field>, + index: u32, +} + +impl<'a> Iterator for Members<'a> { + type Item = Member; + + fn next(&mut self) -> Option { + let field = self.fields.next()?; + let member = match &field.ident { + Some(ident) => Member::Named(ident.clone()), + None => { + #[cfg(all(feature = "parsing", feature = "printing"))] + let span = crate::spanned::Spanned::span(&field.ty); + #[cfg(not(all(feature = "parsing", feature = "printing")))] + let span = proc_macro2::Span::call_site(); + Member::Unnamed(Index { + index: self.index, + span, + }) + } + }; + self.index += 1; + Some(member) + } +} + +impl<'a> Clone for Members<'a> { + fn clone(&self) -> Self { + Members { + fields: self.fields.clone(), + index: self.index, + } + } +} + +#[cfg(feature = "parsing")] +pub(crate) mod parsing { + use crate::attr::Attribute; + use crate::data::{Field, Fields, FieldsNamed, FieldsUnnamed, Variant}; + use crate::error::Result; + use crate::expr::Expr; + use crate::ext::IdentExt as _; + use crate::ident::Ident; + #[cfg(not(feature = "full"))] + use crate::parse::discouraged::Speculative as _; + use crate::parse::{Parse, ParseStream}; + use crate::restriction::{FieldMutability, Visibility}; + use crate::token; + use crate::ty::Type; + use crate::verbatim; + + #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))] + impl Parse for Variant { + fn parse(input: ParseStream) -> Result { + let attrs = input.call(Attribute::parse_outer)?; + let _visibility: Visibility = input.parse()?; + let ident: Ident = input.parse()?; + let fields = if input.peek(token::Brace) { + Fields::Named(input.parse()?) + } else if input.peek(token::Paren) { + Fields::Unnamed(input.parse()?) + } else { + Fields::Unit + }; + let discriminant = if input.peek(Token![=]) { + let eq_token: Token![=] = input.parse()?; + #[cfg(feature = "full")] + let discriminant: Expr = input.parse()?; + #[cfg(not(feature = "full"))] + let discriminant = { + let begin = input.fork(); + let ahead = input.fork(); + let mut discriminant: Result = ahead.parse(); + if discriminant.is_ok() { + input.advance_to(&ahead); + } else if scan_lenient_discriminant(input).is_ok() { + discriminant = Ok(Expr::Verbatim(verbatim::between(&begin, input))); + } + discriminant? + }; + Some((eq_token, discriminant)) + } else { + None + }; + Ok(Variant { + attrs, + ident, + fields, + discriminant, + }) + } + } + + #[cfg(not(feature = "full"))] + pub(crate) fn scan_lenient_discriminant(input: ParseStream) -> Result<()> { + use crate::expr::Member; + use crate::lifetime::Lifetime; + use crate::lit::Lit; + use crate::lit::LitFloat; + use crate::op::{BinOp, UnOp}; + use crate::path::{self, AngleBracketedGenericArguments}; + use proc_macro2::Delimiter::{self, Brace, Bracket, Parenthesis}; + + let consume = |delimiter: Delimiter| { + Result::unwrap(input.step(|cursor| match cursor.group(delimiter) { + Some((_inside, _span, rest)) => Ok((true, rest)), + None => Ok((false, *cursor)), + })) + }; + + macro_rules! consume { + [$token:tt] => { + input.parse::>().unwrap().is_some() + }; + } + + let mut initial = true; + let mut depth = 0usize; + loop { + if initial { + if consume![&] { + input.parse::>()?; + } else if consume![if] || consume![match] || consume![while] { + depth += 1; + } else if input.parse::>()?.is_some() + || (consume(Brace) || consume(Bracket) || consume(Parenthesis)) + || (consume![async] || consume![const] || consume![loop] || consume![unsafe]) + && (consume(Brace) || break) + { + initial = false; + } else if consume![let] { + while !consume![=] { + if !((consume![|] || consume![ref] || consume![mut] || consume![@]) + || (consume![!] || input.parse::>()?.is_some()) + || (consume![..=] || consume![..] || consume![&] || consume![_]) + || (consume(Brace) || consume(Bracket) || consume(Parenthesis))) + { + path::parsing::qpath(input, true)?; + } + } + } else if input.parse::>()?.is_some() && !consume![:] { + break; + } else if input.parse::().is_err() { + path::parsing::qpath(input, true)?; + initial = consume![!] || depth == 0 && input.peek(token::Brace); + } + } else if input.is_empty() || input.peek(Token![,]) { + return Ok(()); + } else if depth > 0 && consume(Brace) { + if consume![else] && !consume(Brace) { + initial = consume![if] || break; + } else { + depth -= 1; + } + } else if input.parse::().is_ok() || (consume![..] | consume![=]) { + initial = true; + } else if consume![.] { + if input.parse::>()?.is_none() + && (input.parse::()?.is_named() && consume![::]) + { + AngleBracketedGenericArguments::do_parse(None, input)?; + } + } else if consume![as] { + input.parse::()?; + } else if !(consume(Brace) || consume(Bracket) || consume(Parenthesis)) { + break; + } + } + + Err(input.error("unsupported expression")) + } + + #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))] + impl Parse for FieldsNamed { + fn parse(input: ParseStream) -> Result { + let content; + Ok(FieldsNamed { + brace_token: braced!(content in input), + named: content.parse_terminated(Field::parse_named, Token![,])?, + }) + } + } + + #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))] + impl Parse for FieldsUnnamed { + fn parse(input: ParseStream) -> Result { + let content; + Ok(FieldsUnnamed { + paren_token: parenthesized!(content in input), + unnamed: content.parse_terminated(Field::parse_unnamed, Token![,])?, + }) + } + } + + impl Field { + /// Parses a named (braced struct) field. + #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))] + pub fn parse_named(input: ParseStream) -> Result { + let attrs = input.call(Attribute::parse_outer)?; + let vis: Visibility = input.parse()?; + + let unnamed_field = cfg!(feature = "full") && input.peek(Token![_]); + let ident = if unnamed_field { + input.call(Ident::parse_any) + } else { + input.parse() + }?; + + let colon_token: Token![:] = input.parse()?; + + let ty: Type = if unnamed_field + && (input.peek(Token![struct]) + || input.peek(Token![union]) && input.peek2(token::Brace)) + { + let begin = input.fork(); + input.call(Ident::parse_any)?; + input.parse::()?; + Type::Verbatim(verbatim::between(&begin, input)) + } else { + input.parse()? + }; + + Ok(Field { + attrs, + vis, + mutability: FieldMutability::None, + ident: Some(ident), + colon_token: Some(colon_token), + ty, + }) + } + + /// Parses an unnamed (tuple struct) field. + #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))] + pub fn parse_unnamed(input: ParseStream) -> Result { + Ok(Field { + attrs: input.call(Attribute::parse_outer)?, + vis: input.parse()?, + mutability: FieldMutability::None, + ident: None, + colon_token: None, + ty: input.parse()?, + }) + } + } +} + +#[cfg(feature = "printing")] +mod printing { + use crate::data::{Field, FieldsNamed, FieldsUnnamed, Variant}; + use crate::print::TokensOrDefault; + use proc_macro2::TokenStream; + use quote::{ToTokens, TokenStreamExt}; + + #[cfg_attr(docsrs, doc(cfg(feature = "printing")))] + impl ToTokens for Variant { + fn to_tokens(&self, tokens: &mut TokenStream) { + tokens.append_all(&self.attrs); + self.ident.to_tokens(tokens); + self.fields.to_tokens(tokens); + if let Some((eq_token, disc)) = &self.discriminant { + eq_token.to_tokens(tokens); + disc.to_tokens(tokens); + } + } + } + + #[cfg_attr(docsrs, doc(cfg(feature = "printing")))] + impl ToTokens for FieldsNamed { + fn to_tokens(&self, tokens: &mut TokenStream) { + self.brace_token.surround(tokens, |tokens| { + self.named.to_tokens(tokens); + }); + } + } + + #[cfg_attr(docsrs, doc(cfg(feature = "printing")))] + impl ToTokens for FieldsUnnamed { + fn to_tokens(&self, tokens: &mut TokenStream) { + self.paren_token.surround(tokens, |tokens| { + self.unnamed.to_tokens(tokens); + }); + } + } + + #[cfg_attr(docsrs, doc(cfg(feature = "printing")))] + impl ToTokens for Field { + fn to_tokens(&self, tokens: &mut TokenStream) { + tokens.append_all(&self.attrs); + self.vis.to_tokens(tokens); + if let Some(ident) = &self.ident { + ident.to_tokens(tokens); + TokensOrDefault(&self.colon_token).to_tokens(tokens); + } + self.ty.to_tokens(tokens); + } + } +} diff --git a/vendor/syn/src/derive.rs b/vendor/syn/src/derive.rs new file mode 100644 index 0000000..3443ecf --- /dev/null +++ b/vendor/syn/src/derive.rs @@ -0,0 +1,259 @@ +use crate::attr::Attribute; +use crate::data::{Fields, FieldsNamed, Variant}; +use crate::generics::Generics; +use crate::ident::Ident; +use crate::punctuated::Punctuated; +use crate::restriction::Visibility; +use crate::token; + +ast_struct! { + /// Data structure sent to a `proc_macro_derive` macro. + #[cfg_attr(docsrs, doc(cfg(feature = "derive")))] + pub struct DeriveInput { + pub attrs: Vec, + pub vis: Visibility, + pub ident: Ident, + pub generics: Generics, + pub data: Data, + } +} + +ast_enum! { + /// The storage of a struct, enum or union data structure. + /// + /// # Syntax tree enum + /// + /// This type is a [syntax tree enum]. + /// + /// [syntax tree enum]: crate::expr::Expr#syntax-tree-enums + #[cfg_attr(docsrs, doc(cfg(feature = "derive")))] + pub enum Data { + Struct(DataStruct), + Enum(DataEnum), + Union(DataUnion), + } +} + +ast_struct! { + /// A struct input to a `proc_macro_derive` macro. + #[cfg_attr(docsrs, doc(cfg(feature = "derive")))] + pub struct DataStruct { + pub struct_token: Token![struct], + pub fields: Fields, + pub semi_token: Option, + } +} + +ast_struct! { + /// An enum input to a `proc_macro_derive` macro. + #[cfg_attr(docsrs, doc(cfg(feature = "derive")))] + pub struct DataEnum { + pub enum_token: Token![enum], + pub brace_token: token::Brace, + pub variants: Punctuated, + } +} + +ast_struct! { + /// An untagged union input to a `proc_macro_derive` macro. + #[cfg_attr(docsrs, doc(cfg(feature = "derive")))] + pub struct DataUnion { + pub union_token: Token![union], + pub fields: FieldsNamed, + } +} + +#[cfg(feature = "parsing")] +pub(crate) mod parsing { + use crate::attr::Attribute; + use crate::data::{Fields, FieldsNamed, Variant}; + use crate::derive::{Data, DataEnum, DataStruct, DataUnion, DeriveInput}; + use crate::error::Result; + use crate::generics::{Generics, WhereClause}; + use crate::ident::Ident; + use crate::parse::{Parse, ParseStream}; + use crate::punctuated::Punctuated; + use crate::restriction::Visibility; + use crate::token; + + #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))] + impl Parse for DeriveInput { + fn parse(input: ParseStream) -> Result { + let attrs = input.call(Attribute::parse_outer)?; + let vis = input.parse::()?; + + let lookahead = input.lookahead1(); + if lookahead.peek(Token![struct]) { + let struct_token = input.parse::()?; + let ident = input.parse::()?; + let generics = input.parse::()?; + let (where_clause, fields, semi) = data_struct(input)?; + Ok(DeriveInput { + attrs, + vis, + ident, + generics: Generics { + where_clause, + ..generics + }, + data: Data::Struct(DataStruct { + struct_token, + fields, + semi_token: semi, + }), + }) + } else if lookahead.peek(Token![enum]) { + let enum_token = input.parse::()?; + let ident = input.parse::()?; + let generics = input.parse::()?; + let (where_clause, brace, variants) = data_enum(input)?; + Ok(DeriveInput { + attrs, + vis, + ident, + generics: Generics { + where_clause, + ..generics + }, + data: Data::Enum(DataEnum { + enum_token, + brace_token: brace, + variants, + }), + }) + } else if lookahead.peek(Token![union]) { + let union_token = input.parse::()?; + let ident = input.parse::()?; + let generics = input.parse::()?; + let (where_clause, fields) = data_union(input)?; + Ok(DeriveInput { + attrs, + vis, + ident, + generics: Generics { + where_clause, + ..generics + }, + data: Data::Union(DataUnion { + union_token, + fields, + }), + }) + } else { + Err(lookahead.error()) + } + } + } + + pub(crate) fn data_struct( + input: ParseStream, + ) -> Result<(Option, Fields, Option)> { + let mut lookahead = input.lookahead1(); + let mut where_clause = None; + if lookahead.peek(Token![where]) { + where_clause = Some(input.parse()?); + lookahead = input.lookahead1(); + } + + if where_clause.is_none() && lookahead.peek(token::Paren) { + let fields = input.parse()?; + + lookahead = input.lookahead1(); + if lookahead.peek(Token![where]) { + where_clause = Some(input.parse()?); + lookahead = input.lookahead1(); + } + + if lookahead.peek(Token![;]) { + let semi = input.parse()?; + Ok((where_clause, Fields::Unnamed(fields), Some(semi))) + } else { + Err(lookahead.error()) + } + } else if lookahead.peek(token::Brace) { + let fields = input.parse()?; + Ok((where_clause, Fields::Named(fields), None)) + } else if lookahead.peek(Token![;]) { + let semi = input.parse()?; + Ok((where_clause, Fields::Unit, Some(semi))) + } else { + Err(lookahead.error()) + } + } + + pub(crate) fn data_enum( + input: ParseStream, + ) -> Result<( + Option, + token::Brace, + Punctuated, + )> { + let where_clause = input.parse()?; + + let content; + let brace = braced!(content in input); + let variants = content.parse_terminated(Variant::parse, Token![,])?; + + Ok((where_clause, brace, variants)) + } + + pub(crate) fn data_union(input: ParseStream) -> Result<(Option, FieldsNamed)> { + let where_clause = input.parse()?; + let fields = input.parse()?; + Ok((where_clause, fields)) + } +} + +#[cfg(feature = "printing")] +mod printing { + use crate::attr::FilterAttrs; + use crate::data::Fields; + use crate::derive::{Data, DeriveInput}; + use crate::print::TokensOrDefault; + use proc_macro2::TokenStream; + use quote::ToTokens; + + #[cfg_attr(docsrs, doc(cfg(feature = "printing")))] + impl ToTokens for DeriveInput { + fn to_tokens(&self, tokens: &mut TokenStream) { + for attr in self.attrs.outer() { + attr.to_tokens(tokens); + } + self.vis.to_tokens(tokens); + match &self.data { + Data::Struct(d) => d.struct_token.to_tokens(tokens), + Data::Enum(d) => d.enum_token.to_tokens(tokens), + Data::Union(d) => d.union_token.to_tokens(tokens), + } + self.ident.to_tokens(tokens); + self.generics.to_tokens(tokens); + match &self.data { + Data::Struct(data) => match &data.fields { + Fields::Named(fields) => { + self.generics.where_clause.to_tokens(tokens); + fields.to_tokens(tokens); + } + Fields::Unnamed(fields) => { + fields.to_tokens(tokens); + self.generics.where_clause.to_tokens(tokens); + TokensOrDefault(&data.semi_token).to_tokens(tokens); + } + Fields::Unit => { + self.generics.where_clause.to_tokens(tokens); + TokensOrDefault(&data.semi_token).to_tokens(tokens); + } + }, + Data::Enum(data) => { + self.generics.where_clause.to_tokens(tokens); + data.brace_token.surround(tokens, |tokens| { + data.variants.to_tokens(tokens); + }); + } + Data::Union(data) => { + self.generics.where_clause.to_tokens(tokens); + data.fields.to_tokens(tokens); + } + } + } + } +} diff --git a/vendor/syn/src/discouraged.rs b/vendor/syn/src/discouraged.rs new file mode 100644 index 0000000..52d93e1 --- /dev/null +++ b/vendor/syn/src/discouraged.rs @@ -0,0 +1,225 @@ +//! Extensions to the parsing API with niche applicability. + +use crate::buffer::Cursor; +use crate::error::Result; +use crate::parse::{inner_unexpected, ParseBuffer, Unexpected}; +use proc_macro2::extra::DelimSpan; +use proc_macro2::Delimiter; +use std::cell::Cell; +use std::mem; +use std::rc::Rc; + +/// Extensions to the `ParseStream` API to support speculative parsing. +pub trait Speculative { + /// Advance this parse stream to the position of a forked parse stream. + /// + /// This is the opposite operation to [`ParseStream::fork`]. You can fork a + /// parse stream, perform some speculative parsing, then join the original + /// stream to the fork to "commit" the parsing from the fork to the main + /// stream. + /// + /// If you can avoid doing this, you should, as it limits the ability to + /// generate useful errors. That said, it is often the only way to parse + /// syntax of the form `A* B*` for arbitrary syntax `A` and `B`. The problem + /// is that when the fork fails to parse an `A`, it's impossible to tell + /// whether that was because of a syntax error and the user meant to provide + /// an `A`, or that the `A`s are finished and it's time to start parsing + /// `B`s. Use with care. + /// + /// Also note that if `A` is a subset of `B`, `A* B*` can be parsed by + /// parsing `B*` and removing the leading members of `A` from the + /// repetition, bypassing the need to involve the downsides associated with + /// speculative parsing. + /// + /// [`ParseStream::fork`]: ParseBuffer::fork + /// + /// # Example + /// + /// There has been chatter about the possibility of making the colons in the + /// turbofish syntax like `path::to::` no longer required by accepting + /// `path::to` in expression position. Specifically, according to [RFC + /// 2544], [`PathSegment`] parsing should always try to consume a following + /// `<` token as the start of generic arguments, and reset to the `<` if + /// that fails (e.g. the token is acting as a less-than operator). + /// + /// This is the exact kind of parsing behavior which requires the "fork, + /// try, commit" behavior that [`ParseStream::fork`] discourages. With + /// `advance_to`, we can avoid having to parse the speculatively parsed + /// content a second time. + /// + /// This change in behavior can be implemented in syn by replacing just the + /// `Parse` implementation for `PathSegment`: + /// + /// ``` + /// # use syn::ext::IdentExt; + /// use syn::parse::discouraged::Speculative; + /// # use syn::parse::{Parse, ParseStream}; + /// # use syn::{Ident, PathArguments, Result, Token}; + /// + /// pub struct PathSegment { + /// pub ident: Ident, + /// pub arguments: PathArguments, + /// } + /// # + /// # impl From for PathSegment + /// # where + /// # T: Into, + /// # { + /// # fn from(ident: T) -> Self { + /// # PathSegment { + /// # ident: ident.into(), + /// # arguments: PathArguments::None, + /// # } + /// # } + /// # } + /// + /// impl Parse for PathSegment { + /// fn parse(input: ParseStream) -> Result { + /// if input.peek(Token![super]) + /// || input.peek(Token![self]) + /// || input.peek(Token![Self]) + /// || input.peek(Token![crate]) + /// { + /// let ident = input.call(Ident::parse_any)?; + /// return Ok(PathSegment::from(ident)); + /// } + /// + /// let ident = input.parse()?; + /// if input.peek(Token![::]) && input.peek3(Token![<]) { + /// return Ok(PathSegment { + /// ident, + /// arguments: PathArguments::AngleBracketed(input.parse()?), + /// }); + /// } + /// if input.peek(Token![<]) && !input.peek(Token![<=]) { + /// let fork = input.fork(); + /// if let Ok(arguments) = fork.parse() { + /// input.advance_to(&fork); + /// return Ok(PathSegment { + /// ident, + /// arguments: PathArguments::AngleBracketed(arguments), + /// }); + /// } + /// } + /// Ok(PathSegment::from(ident)) + /// } + /// } + /// + /// # syn::parse_str::("a").unwrap(); + /// ``` + /// + /// # Drawbacks + /// + /// The main drawback of this style of speculative parsing is in error + /// presentation. Even if the lookahead is the "correct" parse, the error + /// that is shown is that of the "fallback" parse. To use the same example + /// as the turbofish above, take the following unfinished "turbofish": + /// + /// ```text + /// let _ = f<&'a fn(), for<'a> serde::>(); + /// ``` + /// + /// If this is parsed as generic arguments, we can provide the error message + /// + /// ```text + /// error: expected identifier + /// --> src.rs:L:C + /// | + /// L | let _ = f<&'a fn(), for<'a> serde::>(); + /// | ^ + /// ``` + /// + /// but if parsed using the above speculative parsing, it falls back to + /// assuming that the `<` is a less-than when it fails to parse the generic + /// arguments, and tries to interpret the `&'a` as the start of a labelled + /// loop, resulting in the much less helpful error + /// + /// ```text + /// error: expected `:` + /// --> src.rs:L:C + /// | + /// L | let _ = f<&'a fn(), for<'a> serde::>(); + /// | ^^ + /// ``` + /// + /// This can be mitigated with various heuristics (two examples: show both + /// forks' parse errors, or show the one that consumed more tokens), but + /// when you can control the grammar, sticking to something that can be + /// parsed LL(3) and without the LL(*) speculative parsing this makes + /// possible, displaying reasonable errors becomes much more simple. + /// + /// [RFC 2544]: https://github.com/rust-lang/rfcs/pull/2544 + /// [`PathSegment`]: crate::PathSegment + /// + /// # Performance + /// + /// This method performs a cheap fixed amount of work that does not depend + /// on how far apart the two streams are positioned. + /// + /// # Panics + /// + /// The forked stream in the argument of `advance_to` must have been + /// obtained by forking `self`. Attempting to advance to any other stream + /// will cause a panic. + fn advance_to(&self, fork: &Self); +} + +impl<'a> Speculative for ParseBuffer<'a> { + fn advance_to(&self, fork: &Self) { + if !crate::buffer::same_scope(self.cursor(), fork.cursor()) { + panic!("fork was not derived from the advancing parse stream"); + } + + let (self_unexp, self_sp) = inner_unexpected(self); + let (fork_unexp, fork_sp) = inner_unexpected(fork); + if !Rc::ptr_eq(&self_unexp, &fork_unexp) { + match (fork_sp, self_sp) { + // Unexpected set on the fork, but not on `self`, copy it over. + (Some((span, delimiter)), None) => { + self_unexp.set(Unexpected::Some(span, delimiter)); + } + // Unexpected unset. Use chain to propagate errors from fork. + (None, None) => { + fork_unexp.set(Unexpected::Chain(self_unexp)); + + // Ensure toplevel 'unexpected' tokens from the fork don't + // bubble up the chain by replacing the root `unexpected` + // pointer, only 'unexpected' tokens from existing group + // parsers should bubble. + fork.unexpected + .set(Some(Rc::new(Cell::new(Unexpected::None)))); + } + // Unexpected has been set on `self`. No changes needed. + (_, Some(_)) => {} + } + } + + // See comment on `cell` in the struct definition. + self.cell + .set(unsafe { mem::transmute::>(fork.cursor()) }); + } +} + +/// Extensions to the `ParseStream` API to support manipulating invisible +/// delimiters the same as if they were visible. +pub trait AnyDelimiter { + /// Returns the delimiter, the span of the delimiter token, and the nested + /// contents for further parsing. + fn parse_any_delimiter(&self) -> Result<(Delimiter, DelimSpan, ParseBuffer)>; +} + +impl<'a> AnyDelimiter for ParseBuffer<'a> { + fn parse_any_delimiter(&self) -> Result<(Delimiter, DelimSpan, ParseBuffer)> { + self.step(|cursor| { + if let Some((content, delimiter, span, rest)) = cursor.any_group() { + let scope = span.close(); + let nested = crate::parse::advance_step_cursor(cursor, content); + let unexpected = crate::parse::get_unexpected(self); + let content = crate::parse::new_parse_buffer(scope, nested, unexpected); + Ok(((delimiter, span, content), rest)) + } else { + Err(cursor.error("expected any delimiter")) + } + }) + } +} diff --git a/vendor/syn/src/drops.rs b/vendor/syn/src/drops.rs new file mode 100644 index 0000000..89b42d8 --- /dev/null +++ b/vendor/syn/src/drops.rs @@ -0,0 +1,58 @@ +use std::iter; +use std::mem::ManuallyDrop; +use std::ops::{Deref, DerefMut}; +use std::option; +use std::slice; + +#[repr(transparent)] +pub(crate) struct NoDrop(ManuallyDrop); + +impl NoDrop { + pub(crate) fn new(value: T) -> Self + where + T: TrivialDrop, + { + NoDrop(ManuallyDrop::new(value)) + } +} + +impl Deref for NoDrop { + type Target = T; + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +impl DerefMut for NoDrop { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.0 + } +} + +pub(crate) trait TrivialDrop {} + +impl TrivialDrop for iter::Empty {} +impl<'a, T> TrivialDrop for slice::Iter<'a, T> {} +impl<'a, T> TrivialDrop for slice::IterMut<'a, T> {} +impl<'a, T> TrivialDrop for option::IntoIter<&'a T> {} +impl<'a, T> TrivialDrop for option::IntoIter<&'a mut T> {} + +#[test] +fn test_needs_drop() { + use std::mem::needs_drop; + + struct NeedsDrop; + + impl Drop for NeedsDrop { + fn drop(&mut self) {} + } + + assert!(needs_drop::()); + + // Test each of the types with a handwritten TrivialDrop impl above. + assert!(!needs_drop::>()); + assert!(!needs_drop::>()); + assert!(!needs_drop::>()); + assert!(!needs_drop::>()); + assert!(!needs_drop::>()); +} diff --git a/vendor/syn/src/error.rs b/vendor/syn/src/error.rs new file mode 100644 index 0000000..6331054 --- /dev/null +++ b/vendor/syn/src/error.rs @@ -0,0 +1,467 @@ +#[cfg(feature = "parsing")] +use crate::buffer::Cursor; +use crate::thread::ThreadBound; +use proc_macro2::{ + Delimiter, Group, Ident, LexError, Literal, Punct, Spacing, Span, TokenStream, TokenTree, +}; +#[cfg(feature = "printing")] +use quote::ToTokens; +use std::fmt::{self, Debug, Display}; +use std::slice; +use std::vec; + +/// The result of a Syn parser. +pub type Result = std::result::Result; + +/// Error returned when a Syn parser cannot parse the input tokens. +/// +/// # Error reporting in proc macros +/// +/// The correct way to report errors back to the compiler from a procedural +/// macro is by emitting an appropriately spanned invocation of +/// [`compile_error!`] in the generated code. This produces a better diagnostic +/// message than simply panicking the macro. +/// +/// [`compile_error!`]: std::compile_error! +/// +/// When parsing macro input, the [`parse_macro_input!`] macro handles the +/// conversion to `compile_error!` automatically. +/// +/// [`parse_macro_input!`]: crate::parse_macro_input! +/// +/// ``` +/// # extern crate proc_macro; +/// # +/// use proc_macro::TokenStream; +/// use syn::parse::{Parse, ParseStream, Result}; +/// use syn::{parse_macro_input, ItemFn}; +/// +/// # const IGNORE: &str = stringify! { +/// #[proc_macro_attribute] +/// # }; +/// pub fn my_attr(args: TokenStream, input: TokenStream) -> TokenStream { +/// let args = parse_macro_input!(args as MyAttrArgs); +/// let input = parse_macro_input!(input as ItemFn); +/// +/// /* ... */ +/// # TokenStream::new() +/// } +/// +/// struct MyAttrArgs { +/// # _k: [(); { stringify! { +/// ... +/// # }; 0 }] +/// } +/// +/// impl Parse for MyAttrArgs { +/// fn parse(input: ParseStream) -> Result { +/// # stringify! { +/// ... +/// # }; +/// # unimplemented!() +/// } +/// } +/// ``` +/// +/// For errors that arise later than the initial parsing stage, the +/// [`.to_compile_error()`] or [`.into_compile_error()`] methods can be used to +/// perform an explicit conversion to `compile_error!`. +/// +/// [`.to_compile_error()`]: Error::to_compile_error +/// [`.into_compile_error()`]: Error::into_compile_error +/// +/// ``` +/// # extern crate proc_macro; +/// # +/// # use proc_macro::TokenStream; +/// # use syn::{parse_macro_input, DeriveInput}; +/// # +/// # const IGNORE: &str = stringify! { +/// #[proc_macro_derive(MyDerive)] +/// # }; +/// pub fn my_derive(input: TokenStream) -> TokenStream { +/// let input = parse_macro_input!(input as DeriveInput); +/// +/// // fn(DeriveInput) -> syn::Result +/// expand::my_derive(input) +/// .unwrap_or_else(syn::Error::into_compile_error) +/// .into() +/// } +/// # +/// # mod expand { +/// # use proc_macro2::TokenStream; +/// # use syn::{DeriveInput, Result}; +/// # +/// # pub fn my_derive(input: DeriveInput) -> Result { +/// # unimplemented!() +/// # } +/// # } +/// ``` +pub struct Error { + messages: Vec, +} + +struct ErrorMessage { + // Span is implemented as an index into a thread-local interner to keep the + // size small. It is not safe to access from a different thread. We want + // errors to be Send and Sync to play nicely with ecosystem crates for error + // handling, so pin the span we're given to its original thread and assume + // it is Span::call_site if accessed from any other thread. + span: ThreadBound, + message: String, +} + +// Cannot use std::ops::Range because that does not implement Copy, +// whereas ThreadBound requires a Copy impl as a way to ensure no Drop impls +// are involved. +struct SpanRange { + start: Span, + end: Span, +} + +#[cfg(test)] +struct _Test +where + Error: Send + Sync; + +impl Error { + /// Usually the [`ParseStream::error`] method will be used instead, which + /// automatically uses the correct span from the current position of the + /// parse stream. + /// + /// Use `Error::new` when the error needs to be triggered on some span other + /// than where the parse stream is currently positioned. + /// + /// [`ParseStream::error`]: crate::parse::ParseBuffer::error + /// + /// # Example + /// + /// ``` + /// use syn::{Error, Ident, LitStr, Result, Token}; + /// use syn::parse::ParseStream; + /// + /// // Parses input that looks like `name = "string"` where the key must be + /// // the identifier `name` and the value may be any string literal. + /// // Returns the string literal. + /// fn parse_name(input: ParseStream) -> Result { + /// let name_token: Ident = input.parse()?; + /// if name_token != "name" { + /// // Trigger an error not on the current position of the stream, + /// // but on the position of the unexpected identifier. + /// return Err(Error::new(name_token.span(), "expected `name`")); + /// } + /// input.parse::()?; + /// let s: LitStr = input.parse()?; + /// Ok(s) + /// } + /// ``` + pub fn new(span: Span, message: T) -> Self { + return new(span, message.to_string()); + + fn new(span: Span, message: String) -> Error { + Error { + messages: vec![ErrorMessage { + span: ThreadBound::new(SpanRange { + start: span, + end: span, + }), + message, + }], + } + } + } + + /// Creates an error with the specified message spanning the given syntax + /// tree node. + /// + /// Unlike the `Error::new` constructor, this constructor takes an argument + /// `tokens` which is a syntax tree node. This allows the resulting `Error` + /// to attempt to span all tokens inside of `tokens`. While you would + /// typically be able to use the `Spanned` trait with the above `Error::new` + /// constructor, implementation limitations today mean that + /// `Error::new_spanned` may provide a higher-quality error message on + /// stable Rust. + /// + /// When in doubt it's recommended to stick to `Error::new` (or + /// `ParseStream::error`)! + #[cfg(feature = "printing")] + #[cfg_attr(docsrs, doc(cfg(feature = "printing")))] + pub fn new_spanned(tokens: T, message: U) -> Self { + return new_spanned(tokens.into_token_stream(), message.to_string()); + + fn new_spanned(tokens: TokenStream, message: String) -> Error { + let mut iter = tokens.into_iter(); + let start = iter.next().map_or_else(Span::call_site, |t| t.span()); + let end = iter.last().map_or(start, |t| t.span()); + Error { + messages: vec![ErrorMessage { + span: ThreadBound::new(SpanRange { start, end }), + message, + }], + } + } + } + + /// The source location of the error. + /// + /// Spans are not thread-safe so this function returns `Span::call_site()` + /// if called from a different thread than the one on which the `Error` was + /// originally created. + pub fn span(&self) -> Span { + let SpanRange { start, end } = match self.messages[0].span.get() { + Some(span) => *span, + None => return Span::call_site(), + }; + start.join(end).unwrap_or(start) + } + + /// Render the error as an invocation of [`compile_error!`]. + /// + /// The [`parse_macro_input!`] macro provides a convenient way to invoke + /// this method correctly in a procedural macro. + /// + /// [`compile_error!`]: std::compile_error! + /// [`parse_macro_input!`]: crate::parse_macro_input! + pub fn to_compile_error(&self) -> TokenStream { + self.messages + .iter() + .map(ErrorMessage::to_compile_error) + .collect() + } + + /// Render the error as an invocation of [`compile_error!`]. + /// + /// [`compile_error!`]: std::compile_error! + /// + /// # Example + /// + /// ``` + /// # extern crate proc_macro; + /// # + /// use proc_macro::TokenStream; + /// use syn::{parse_macro_input, DeriveInput, Error}; + /// + /// # const _: &str = stringify! { + /// #[proc_macro_derive(MyTrait)] + /// # }; + /// pub fn derive_my_trait(input: TokenStream) -> TokenStream { + /// let input = parse_macro_input!(input as DeriveInput); + /// my_trait::expand(input) + /// .unwrap_or_else(Error::into_compile_error) + /// .into() + /// } + /// + /// mod my_trait { + /// use proc_macro2::TokenStream; + /// use syn::{DeriveInput, Result}; + /// + /// pub(crate) fn expand(input: DeriveInput) -> Result { + /// /* ... */ + /// # unimplemented!() + /// } + /// } + /// ``` + pub fn into_compile_error(self) -> TokenStream { + self.to_compile_error() + } + + /// Add another error message to self such that when `to_compile_error()` is + /// called, both errors will be emitted together. + pub fn combine(&mut self, another: Error) { + self.messages.extend(another.messages); + } +} + +impl ErrorMessage { + fn to_compile_error(&self) -> TokenStream { + let (start, end) = match self.span.get() { + Some(range) => (range.start, range.end), + None => (Span::call_site(), Span::call_site()), + }; + + // ::core::compile_error!($message) + TokenStream::from_iter([ + TokenTree::Punct({ + let mut punct = Punct::new(':', Spacing::Joint); + punct.set_span(start); + punct + }), + TokenTree::Punct({ + let mut punct = Punct::new(':', Spacing::Alone); + punct.set_span(start); + punct + }), + TokenTree::Ident(Ident::new("core", start)), + TokenTree::Punct({ + let mut punct = Punct::new(':', Spacing::Joint); + punct.set_span(start); + punct + }), + TokenTree::Punct({ + let mut punct = Punct::new(':', Spacing::Alone); + punct.set_span(start); + punct + }), + TokenTree::Ident(Ident::new("compile_error", start)), + TokenTree::Punct({ + let mut punct = Punct::new('!', Spacing::Alone); + punct.set_span(start); + punct + }), + TokenTree::Group({ + let mut group = Group::new(Delimiter::Brace, { + TokenStream::from_iter([TokenTree::Literal({ + let mut string = Literal::string(&self.message); + string.set_span(end); + string + })]) + }); + group.set_span(end); + group + }), + ]) + } +} + +#[cfg(feature = "parsing")] +pub(crate) fn new_at(scope: Span, cursor: Cursor, message: T) -> Error { + if cursor.eof() { + Error::new(scope, format!("unexpected end of input, {}", message)) + } else { + let span = crate::buffer::open_span_of_group(cursor); + Error::new(span, message) + } +} + +#[cfg(all(feature = "parsing", any(feature = "full", feature = "derive")))] +pub(crate) fn new2(start: Span, end: Span, message: T) -> Error { + return new2(start, end, message.to_string()); + + fn new2(start: Span, end: Span, message: String) -> Error { + Error { + messages: vec![ErrorMessage { + span: ThreadBound::new(SpanRange { start, end }), + message, + }], + } + } +} + +impl Debug for Error { + fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + if self.messages.len() == 1 { + formatter + .debug_tuple("Error") + .field(&self.messages[0]) + .finish() + } else { + formatter + .debug_tuple("Error") + .field(&self.messages) + .finish() + } + } +} + +impl Debug for ErrorMessage { + fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + Debug::fmt(&self.message, formatter) + } +} + +impl Display for Error { + fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str(&self.messages[0].message) + } +} + +impl Clone for Error { + fn clone(&self) -> Self { + Error { + messages: self.messages.clone(), + } + } +} + +impl Clone for ErrorMessage { + fn clone(&self) -> Self { + ErrorMessage { + span: self.span, + message: self.message.clone(), + } + } +} + +impl Clone for SpanRange { + fn clone(&self) -> Self { + *self + } +} + +impl Copy for SpanRange {} + +impl std::error::Error for Error {} + +impl From for Error { + fn from(err: LexError) -> Self { + Error::new(err.span(), err) + } +} + +impl IntoIterator for Error { + type Item = Error; + type IntoIter = IntoIter; + + fn into_iter(self) -> Self::IntoIter { + IntoIter { + messages: self.messages.into_iter(), + } + } +} + +pub struct IntoIter { + messages: vec::IntoIter, +} + +impl Iterator for IntoIter { + type Item = Error; + + fn next(&mut self) -> Option { + Some(Error { + messages: vec![self.messages.next()?], + }) + } +} + +impl<'a> IntoIterator for &'a Error { + type Item = Error; + type IntoIter = Iter<'a>; + + fn into_iter(self) -> Self::IntoIter { + Iter { + messages: self.messages.iter(), + } + } +} + +pub struct Iter<'a> { + messages: slice::Iter<'a, ErrorMessage>, +} + +impl<'a> Iterator for Iter<'a> { + type Item = Error; + + fn next(&mut self) -> Option { + Some(Error { + messages: vec![self.messages.next()?.clone()], + }) + } +} + +impl Extend for Error { + fn extend>(&mut self, iter: T) { + for err in iter { + self.combine(err); + } + } +} diff --git a/vendor/syn/src/export.rs b/vendor/syn/src/export.rs new file mode 100644 index 0000000..b9ea5c7 --- /dev/null +++ b/vendor/syn/src/export.rs @@ -0,0 +1,73 @@ +#[doc(hidden)] +pub use std::clone::Clone; +#[doc(hidden)] +pub use std::cmp::{Eq, PartialEq}; +#[doc(hidden)] +pub use std::concat; +#[doc(hidden)] +pub use std::default::Default; +#[doc(hidden)] +pub use std::fmt::Debug; +#[doc(hidden)] +pub use std::hash::{Hash, Hasher}; +#[doc(hidden)] +pub use std::marker::Copy; +#[doc(hidden)] +pub use std::option::Option::{None, Some}; +#[doc(hidden)] +pub use std::result::Result::{Err, Ok}; +#[doc(hidden)] +pub use std::stringify; + +#[doc(hidden)] +pub type Formatter<'a> = std::fmt::Formatter<'a>; +#[doc(hidden)] +pub type FmtResult = std::fmt::Result; + +#[doc(hidden)] +pub type bool = std::primitive::bool; +#[doc(hidden)] +pub type str = std::primitive::str; + +#[cfg(feature = "printing")] +#[doc(hidden)] +pub use quote; + +#[doc(hidden)] +pub type Span = proc_macro2::Span; +#[doc(hidden)] +pub type TokenStream2 = proc_macro2::TokenStream; + +#[cfg(feature = "parsing")] +#[doc(hidden)] +pub use crate::group::{parse_braces, parse_brackets, parse_parens}; + +#[doc(hidden)] +pub use crate::span::IntoSpans; + +#[cfg(all(feature = "parsing", feature = "printing"))] +#[doc(hidden)] +pub use crate::parse_quote::parse as parse_quote; + +#[cfg(feature = "parsing")] +#[doc(hidden)] +pub use crate::token::parsing::{peek_punct, punct as parse_punct}; + +#[cfg(feature = "printing")] +#[doc(hidden)] +pub use crate::token::printing::punct as print_punct; + +#[cfg(feature = "parsing")] +#[doc(hidden)] +pub use crate::token::private::CustomToken; + +#[cfg(feature = "proc-macro")] +#[doc(hidden)] +pub type TokenStream = proc_macro::TokenStream; + +#[cfg(feature = "printing")] +#[doc(hidden)] +pub use quote::{ToTokens, TokenStreamExt}; + +#[doc(hidden)] +pub struct private(pub(crate) ()); diff --git a/vendor/syn/src/expr.rs b/vendor/syn/src/expr.rs new file mode 100644 index 0000000..409131b --- /dev/null +++ b/vendor/syn/src/expr.rs @@ -0,0 +1,3932 @@ +use crate::attr::Attribute; +#[cfg(all(feature = "parsing", feature = "full"))] +use crate::error::Result; +#[cfg(feature = "full")] +use crate::generics::BoundLifetimes; +use crate::ident::Ident; +#[cfg(feature = "full")] +use crate::lifetime::Lifetime; +use crate::lit::Lit; +use crate::mac::Macro; +use crate::op::{BinOp, UnOp}; +#[cfg(all(feature = "parsing", feature = "full"))] +use crate::parse::ParseStream; +#[cfg(feature = "full")] +use crate::pat::Pat; +use crate::path::{AngleBracketedGenericArguments, Path, QSelf}; +use crate::punctuated::Punctuated; +#[cfg(feature = "full")] +use crate::stmt::Block; +use crate::token; +#[cfg(feature = "full")] +use crate::ty::ReturnType; +use crate::ty::Type; +use proc_macro2::{Span, TokenStream}; +#[cfg(feature = "printing")] +use quote::IdentFragment; +#[cfg(feature = "printing")] +use std::fmt::{self, Display}; +use std::hash::{Hash, Hasher}; +#[cfg(all(feature = "parsing", feature = "full"))] +use std::mem; + +ast_enum_of_structs! { + /// A Rust expression. + /// + /// *This type is available only if Syn is built with the `"derive"` or `"full"` + /// feature, but most of the variants are not available unless "full" is enabled.* + /// + /// # Syntax tree enums + /// + /// This type is a syntax tree enum. In Syn this and other syntax tree enums + /// are designed to be traversed using the following rebinding idiom. + /// + /// ``` + /// # use syn::Expr; + /// # + /// # fn example(expr: Expr) { + /// # const IGNORE: &str = stringify! { + /// let expr: Expr = /* ... */; + /// # }; + /// match expr { + /// Expr::MethodCall(expr) => { + /// /* ... */ + /// } + /// Expr::Cast(expr) => { + /// /* ... */ + /// } + /// Expr::If(expr) => { + /// /* ... */ + /// } + /// + /// /* ... */ + /// # _ => {} + /// # } + /// # } + /// ``` + /// + /// We begin with a variable `expr` of type `Expr` that has no fields + /// (because it is an enum), and by matching on it and rebinding a variable + /// with the same name `expr` we effectively imbue our variable with all of + /// the data fields provided by the variant that it turned out to be. So for + /// example above if we ended up in the `MethodCall` case then we get to use + /// `expr.receiver`, `expr.args` etc; if we ended up in the `If` case we get + /// to use `expr.cond`, `expr.then_branch`, `expr.else_branch`. + /// + /// This approach avoids repeating the variant names twice on every line. + /// + /// ``` + /// # use syn::{Expr, ExprMethodCall}; + /// # + /// # fn example(expr: Expr) { + /// // Repetitive; recommend not doing this. + /// match expr { + /// Expr::MethodCall(ExprMethodCall { method, args, .. }) => { + /// # } + /// # _ => {} + /// # } + /// # } + /// ``` + /// + /// In general, the name to which a syntax tree enum variant is bound should + /// be a suitable name for the complete syntax tree enum type. + /// + /// ``` + /// # use syn::{Expr, ExprField}; + /// # + /// # fn example(discriminant: ExprField) { + /// // Binding is called `base` which is the name I would use if I were + /// // assigning `*discriminant.base` without an `if let`. + /// if let Expr::Tuple(base) = *discriminant.base { + /// # } + /// # } + /// ``` + /// + /// A sign that you may not be choosing the right variable names is if you + /// see names getting repeated in your code, like accessing + /// `receiver.receiver` or `pat.pat` or `cond.cond`. + #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))] + #[non_exhaustive] + pub enum Expr { + /// A slice literal expression: `[a, b, c, d]`. + Array(ExprArray), + + /// An assignment expression: `a = compute()`. + Assign(ExprAssign), + + /// An async block: `async { ... }`. + Async(ExprAsync), + + /// An await expression: `fut.await`. + Await(ExprAwait), + + /// A binary operation: `a + b`, `a += b`. + Binary(ExprBinary), + + /// A blocked scope: `{ ... }`. + Block(ExprBlock), + + /// A `break`, with an optional label to break and an optional + /// expression. + Break(ExprBreak), + + /// A function call expression: `invoke(a, b)`. + Call(ExprCall), + + /// A cast expression: `foo as f64`. + Cast(ExprCast), + + /// A closure expression: `|a, b| a + b`. + Closure(ExprClosure), + + /// A const block: `const { ... }`. + Const(ExprConst), + + /// A `continue`, with an optional label. + Continue(ExprContinue), + + /// Access of a named struct field (`obj.k`) or unnamed tuple struct + /// field (`obj.0`). + Field(ExprField), + + /// A for loop: `for pat in expr { ... }`. + ForLoop(ExprForLoop), + + /// An expression contained within invisible delimiters. + /// + /// This variant is important for faithfully representing the precedence + /// of expressions and is related to `None`-delimited spans in a + /// `TokenStream`. + Group(ExprGroup), + + /// An `if` expression with an optional `else` block: `if expr { ... } + /// else { ... }`. + /// + /// The `else` branch expression may only be an `If` or `Block` + /// expression, not any of the other types of expression. + If(ExprIf), + + /// A square bracketed indexing expression: `vector[2]`. + Index(ExprIndex), + + /// The inferred value of a const generic argument, denoted `_`. + Infer(ExprInfer), + + /// A `let` guard: `let Some(x) = opt`. + Let(ExprLet), + + /// A literal in place of an expression: `1`, `"foo"`. + Lit(ExprLit), + + /// Conditionless loop: `loop { ... }`. + Loop(ExprLoop), + + /// A macro invocation expression: `format!("{}", q)`. + Macro(ExprMacro), + + /// A `match` expression: `match n { Some(n) => {}, None => {} }`. + Match(ExprMatch), + + /// A method call expression: `x.foo::(a, b)`. + MethodCall(ExprMethodCall), + + /// A parenthesized expression: `(a + b)`. + Paren(ExprParen), + + /// A path like `std::mem::replace` possibly containing generic + /// parameters and a qualified self-type. + /// + /// A plain identifier like `x` is a path of length 1. + Path(ExprPath), + + /// A range expression: `1..2`, `1..`, `..2`, `1..=2`, `..=2`. + Range(ExprRange), + + /// A referencing operation: `&a` or `&mut a`. + Reference(ExprReference), + + /// An array literal constructed from one repeated element: `[0u8; N]`. + Repeat(ExprRepeat), + + /// A `return`, with an optional value to be returned. + Return(ExprReturn), + + /// A struct literal expression: `Point { x: 1, y: 1 }`. + /// + /// The `rest` provides the value of the remaining fields as in `S { a: + /// 1, b: 1, ..rest }`. + Struct(ExprStruct), + + /// A try-expression: `expr?`. + Try(ExprTry), + + /// A try block: `try { ... }`. + TryBlock(ExprTryBlock), + + /// A tuple expression: `(a, b, c, d)`. + Tuple(ExprTuple), + + /// A unary operation: `!x`, `*x`. + Unary(ExprUnary), + + /// An unsafe block: `unsafe { ... }`. + Unsafe(ExprUnsafe), + + /// Tokens in expression position not interpreted by Syn. + Verbatim(TokenStream), + + /// A while loop: `while expr { ... }`. + While(ExprWhile), + + /// A yield expression: `yield expr`. + Yield(ExprYield), + + // For testing exhaustiveness in downstream code, use the following idiom: + // + // match expr { + // #![cfg_attr(test, deny(non_exhaustive_omitted_patterns))] + // + // Expr::Array(expr) => {...} + // Expr::Assign(expr) => {...} + // ... + // Expr::Yield(expr) => {...} + // + // _ => { /* some sane fallback */ } + // } + // + // This way we fail your tests but don't break your library when adding + // a variant. You will be notified by a test failure when a variant is + // added, so that you can add code to handle it, but your library will + // continue to compile and work for downstream users in the interim. + } +} + +ast_struct! { + /// A slice literal expression: `[a, b, c, d]`. + #[cfg_attr(docsrs, doc(cfg(feature = "full")))] + pub struct ExprArray #full { + pub attrs: Vec, + pub bracket_token: token::Bracket, + pub elems: Punctuated, + } +} + +ast_struct! { + /// An assignment expression: `a = compute()`. + #[cfg_attr(docsrs, doc(cfg(feature = "full")))] + pub struct ExprAssign #full { + pub attrs: Vec, + pub left: Box, + pub eq_token: Token![=], + pub right: Box, + } +} + +ast_struct! { + /// An async block: `async { ... }`. + #[cfg_attr(docsrs, doc(cfg(feature = "full")))] + pub struct ExprAsync #full { + pub attrs: Vec, + pub async_token: Token![async], + pub capture: Option, + pub block: Block, + } +} + +ast_struct! { + /// An await expression: `fut.await`. + #[cfg_attr(docsrs, doc(cfg(feature = "full")))] + pub struct ExprAwait #full { + pub attrs: Vec, + pub base: Box, + pub dot_token: Token![.], + pub await_token: Token![await], + } +} + +ast_struct! { + /// A binary operation: `a + b`, `a += b`. + #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))] + pub struct ExprBinary { + pub attrs: Vec, + pub left: Box, + pub op: BinOp, + pub right: Box, + } +} + +ast_struct! { + /// A blocked scope: `{ ... }`. + #[cfg_attr(docsrs, doc(cfg(feature = "full")))] + pub struct ExprBlock #full { + pub attrs: Vec, + pub label: Option
+ +Click to show Cargo.toml. +Run this code in the playground. + + +```toml +[dependencies] + +# The core APIs, including the Serialize and Deserialize traits. Always +# required when using Serde. The "derive" feature is only required when +# using #[derive(Serialize, Deserialize)] to make Serde work with structs +# and enums defined in your crate. +serde = { version = "1.0", features = ["derive"] } + +# Each data format lives in its own crate; the sample code below uses JSON +# but you may be using a different one. +serde_json = "1.0" +``` + +